cocci.cmi: commons/common.cmi parsing_cocci/ast_cocci.cmi
testing.cmi: commons/common.cmi parsing_cocci/ast_cocci.cmi
cocci.cmo: parsing_cocci/visitor_ast.cmi parsing_c/unparse_hrule.cmi \
- parsing_c/unparse_c2.cmi parsing_c/type_annoter_c.cmi \
- engine/transformation3.cmi python/pycocci.cmo \
+ parsing_c/unparse_c.cmi parsing_c/type_annoter_c.cmi \
+ engine/transformation_c.cmi python/pycocci.cmo \
engine/pretty_print_engine.cmi parsing_cocci/pretty_print_cocci.cmi \
popl09/popl.cmi parsing_c/parsing_hacks.cmi parsing_cocci/parse_cocci.cmi \
parsing_c/parse_c.cmi commons/ograph_extended.cmi engine/lib_engine.cmo \
parsing_c/flag_parsing_c.cmo ctl/flag_ctl.cmo flag_cocci.cmo \
globals/flag.cmo engine/ctltotex.cmi engine/ctlcocci_integration.cmi \
- parsing_c/control_flow_c.cmi parsing_c/compare_c.cmi commons/common.cmi \
- engine/asttomember.cmi engine/asttoctl2.cmi parsing_c/ast_to_flow.cmi \
+ parsing_c/cpp_ast_c.cmi parsing_c/control_flow_c.cmi \
+ parsing_c/compare_c.cmi commons/common.cmi engine/asttomember.cmi \
+ engine/asttoctl2.cmi parsing_c/ast_to_flow.cmi \
parsing_cocci/ast_cocci.cmi parsing_c/ast_c.cmo cocci.cmi
cocci.cmx: parsing_cocci/visitor_ast.cmx parsing_c/unparse_hrule.cmx \
- parsing_c/unparse_c2.cmx parsing_c/type_annoter_c.cmx \
- engine/transformation3.cmx python/pycocci.cmx \
+ parsing_c/unparse_c.cmx parsing_c/type_annoter_c.cmx \
+ engine/transformation_c.cmx python/pycocci.cmx \
engine/pretty_print_engine.cmx parsing_cocci/pretty_print_cocci.cmx \
popl09/popl.cmx parsing_c/parsing_hacks.cmx parsing_cocci/parse_cocci.cmx \
parsing_c/parse_c.cmx commons/ograph_extended.cmx engine/lib_engine.cmx \
parsing_c/flag_parsing_c.cmx ctl/flag_ctl.cmx flag_cocci.cmx \
globals/flag.cmx engine/ctltotex.cmx engine/ctlcocci_integration.cmx \
- parsing_c/control_flow_c.cmx parsing_c/compare_c.cmx commons/common.cmx \
- engine/asttomember.cmx engine/asttoctl2.cmx parsing_c/ast_to_flow.cmx \
+ parsing_c/cpp_ast_c.cmx parsing_c/control_flow_c.cmx \
+ parsing_c/compare_c.cmx commons/common.cmx engine/asttomember.cmx \
+ engine/asttoctl2.cmx parsing_c/ast_to_flow.cmx \
parsing_cocci/ast_cocci.cmx parsing_c/ast_c.cmx cocci.cmi
main.cmo: testing.cmi parsing_c/test_parsing_c.cmi python/pycocci.cmo \
parsing_c/parse_c.cmi extra/kbuild.cmi popl09/flag_popl.cmo \
parsing_cocci/flag_parsing_cocci.cmo parsing_c/flag_parsing_c.cmo \
- engine/flag_engine.cmo ctl/flag_ctl.cmo flag_cocci.cmo globals/flag.cmo \
+ engine/flag_matcher.cmo ctl/flag_ctl.cmo flag_cocci.cmo globals/flag.cmo \
engine/ctlcocci_integration.cmi globals/config.cmo commons/common.cmi \
cocci.cmi
main.cmx: testing.cmx parsing_c/test_parsing_c.cmx python/pycocci.cmx \
parsing_c/parse_c.cmx extra/kbuild.cmx popl09/flag_popl.cmx \
parsing_cocci/flag_parsing_cocci.cmx parsing_c/flag_parsing_c.cmx \
- engine/flag_engine.cmx ctl/flag_ctl.cmx flag_cocci.cmx globals/flag.cmx \
+ engine/flag_matcher.cmx ctl/flag_ctl.cmx flag_cocci.cmx globals/flag.cmx \
engine/ctlcocci_integration.cmx globals/config.cmx commons/common.cmx \
cocci.cmx
testing.cmo: parsing_cocci/pretty_print_cocci.cmi \
##############################################################################
# Top rules
##############################################################################
-eclipse: depend all
-configure:
- ./configure
-
all: rec $(EXEC)
opt: rec.opt $(EXEC).opt
all.opt: opt
+top: $(EXEC).top
rec:
set -e; for i in $(MAKESUBDIRS); \
clean::
set -e; for i in $(MAKESUBDIRS); do $(MAKE) -C $$i clean; done
+eclipse: depend all
+configure:
+ ./configure
$(EXEC): $(LIBS) $(OBJS)
$(OCAMLC) $(BYTECODE_STATIC) -o $@ $(SYSLIBS) $^
# cvs update -d -P
# touch **/*
# make licensify
+# remember to comment the -g -dtypes in this Makefile
# Procedure to do each time:
# cvs update
darcsweb:
# @echo pull from ~/public_html/darcs/c-coccinelle and c-commons and lib-xxx
+DARCSFORESTS=commons \
+ parsing_c parsing_cocci engine
+
+update_darcs:
+ darcs pull
+ set -e; for i in $(DARCSFORESTS); do cd $$i; darcs pull; cd ..; done
+
+#darcs diff -u
+diff_darcs:
+ set -e; for i in $(DARCSFORESTS); do cd $$i; darcs diff -u; cd ..; done
+
##############################################################################
# Developer rules
dependencygraph:
find -name "*.ml" |grep -v "scripts" | xargs ocamldep -I commons -I globals -I ctl -I parsing_cocci -I parsing_c -I engine -I popl09 -I extra > /tmp/dependfull.depend
- ocamldot -fullgraph /tmp/dependfull.depend > /tmp/dependfull.dot
+ ocamldot -lr /tmp/dependfull.depend > /tmp/dependfull.dot
dot -Tps /tmp/dependfull.dot > /tmp/dependfull.ps
+ ps2pdf /tmp/dependfull.ps /tmp/dependfull.pdf
##############################################################################
# Misc rules
-*- org -*-
+* 0.1.2
+
+** Bugfix:
+- better handling of ifdef on statements in control flow graph.
+- transform files even if they do not end in .c (thanks to Vegard Nossum)
+
+** Internals:
+- merge code of yacfe
+
* 0.1.1
-** better support for initializer, cf -test substruct
+** Langage:
+ - support for initializer at toplevel, cf -test substruct
* 0.1
let cprogram_of_file_cached file =
let (program2, _stat) = Parse_c.parse_cache file in
- program2
-
+ if !Flag_cocci.ifdef_to_if
+ then
+ program2 +> Parse_c.with_program2 (fun asts ->
+ Cpp_ast_c.cpp_ifdef_statementize asts
+ )
+ else program2
let cfile_of_program program2_with_ppmethod outf =
- Unparse_c2.pp_program program2_with_ppmethod outf
+ Unparse_c.pp_program program2_with_ppmethod outf
(* for memoization, contains only one entry, the one for the SP *)
let _hparse = Hashtbl.create 101
(* running information *)
+let get_celem celem : string =
+ match celem with
+ Ast_c.Definition ({Ast_c.f_name = funcs;},_) -> funcs
+ | Ast_c.Declaration
+ (Ast_c.DeclList ([{Ast_c.v_namei = Some ((s, _),_);}, _], _)) -> s
+ | _ -> ""
let show_or_not_celem2 prelude celem =
- if !Flag.show_trying then
+ let (tag,trying) =
(match celem with
- | Ast_c.Definition ((funcs,_,_,_c),_) ->
- pr2 (prelude ^ " function: " ^ funcs);
+ | Ast_c.Definition ({Ast_c.f_name = funcs;},_) ->
+ Flag.current_element := funcs;
+ (" function: ",funcs)
| Ast_c.Declaration
- (Ast_c.DeclList ([(Some ((s, _),_), typ, sto, _local), _], _)) ->
- pr2 (prelude ^ " variable " ^ s);
- | _ ->
- pr2 (prelude ^ " something else");
- )
+ (Ast_c.DeclList ([{Ast_c.v_namei = Some ((s, _),_);}, _], _)) ->
+ Flag.current_element := s;
+ (" variable ",s);
+ | _ ->
+ Flag.current_element := "something_else";
+ (" ","something else");
+ ) in
+ if !Flag.show_trying then pr2 (prelude ^ tag ^ trying)
+
let show_or_not_celem a b =
Common.profile_code "show_xxx" (fun () -> show_or_not_celem2 a b)
* serio.c is related we think to #include <linux/serio.h>
*)
-let includes_to_parse xs =
+let (includes_to_parse: (Common.filename * Parse_c.program2) list -> 'a) = fun xs ->
if !Flag_cocci.no_includes
then []
else
cs +> Common.map_filter (fun (c,_info_item) ->
match c with
- | Ast_c.Include ((x,ii),info_h_pos) ->
+ | Ast_c.CppTop (Ast_c.Include {Ast_c.i_include = ((x,ii));
+ i_rel_pos = info_h_pos;}) ->
(match x with
| Ast_c.Local xs ->
let f = Filename.concat dir (Common.join "/" xs) in
let rec update_include_rel_pos cs =
let only_include = cs +> Common.map_filter (fun c ->
match c with
- | Ast_c.Include ((x,_),(aref, inifdef)) ->
+ | Ast_c.CppTop (Ast_c.Include {Ast_c.i_include = ((x,_));
+ i_rel_pos = aref;
+ i_is_in_ifdef = inifdef}) ->
(match x with
| Ast_c.Wierd _ -> None
| _ ->
let last_env_toplevel_c_info xs =
(Common.last xs).env_typing_after
-let concat_headers_and_c ccs =
- (List.concat (ccs +> List.map (fun x -> x.asts)))
+let concat_headers_and_c (ccs: file_info list)
+ : (toplevel_c_info * string) list =
+ (List.concat (ccs +> List.map (fun x ->
+ x.asts +> List.map (fun x' ->
+ (x', x.fname)))))
let for_unparser xs =
xs +> List.map (fun x ->
- (x.ast_c, (x.fullstring, x.tokens_c)), Unparse_c2.PPviastr
+ (x.ast_c, (x.fullstring, x.tokens_c)), Unparse_c.PPviastr
)
+let gen_pdf_graph () =
+ (Ctl_engine.get_graph_files ()) +> List.iter (fun outfile ->
+ Printf.printf "Generation of %s%!" outfile;
+ let filename_stack = Ctl_engine.get_graph_comp_files outfile in
+ List.iter (fun filename ->
+ ignore (Unix.system ("dot " ^ filename ^ " -Tpdf -o " ^ filename ^ ".pdf;"))
+ ) filename_stack;
+ let (head,tail) = (List.hd filename_stack, List.tl filename_stack) in
+ ignore(Unix.system ("cp " ^ head ^ ".pdf " ^ outfile ^ ".pdf;"));
+ tail +> List.iter (fun filename ->
+ ignore(Unix.system ("mv " ^ outfile ^ ".pdf /tmp/tmp.pdf;"));
+ ignore(Unix.system ("pdftk " ^ filename ^ ".pdf /tmp/tmp.pdf cat output " ^ outfile ^ ".pdf"));
+ );
+ ignore(Unix.system ("rm /tmp/tmp.pdf;"));
+ List.iter (fun filename ->
+ ignore (Unix.system ("rm " ^ filename ^ " " ^ filename ^ ".pdf;"))
+ ) filename_stack;
+ Printf.printf " - Done\n")
+
+
(* --------------------------------------------------------------------- *)
let prepare_cocci ctls free_var_lists negated_pos_lists
used_after_lists positions_list astcocci =
| None ->
let file = Common.new_temp_file "cocci_small_output" ".c" in
cfile_of_program
- [(c.ast_c, (c.fullstring, c.tokens_c)), Unparse_c2.PPnormal]
+ [(c.ast_c, (c.fullstring, c.tokens_c)), Unparse_c.PPnormal]
file;
(* Common.command2 ("cat " ^ file); *)
-let prepare_c files =
+let prepare_c files : file_info list =
let cprograms = List.map cprogram_of_file_cached files in
let includes = includes_to_parse (zip files cprograms) in
else (cache, merge_env [(e, rules_that_have_matched)] newes)
end
-and apply_cocci_rule r rules_that_have_ever_matched es ccs =
+and apply_cocci_rule r rules_that_have_ever_matched es (ccs:file_info list ref) =
Common.profile_code r.rulename (fun () ->
show_or_not_rule_name r.ast_rule r.ruleid;
show_or_not_ctl_text r.ctl r.ast_rule r.ruleid;
(* looping over the functions and toplevel elements in
.c and .h *)
- concat_headers_and_c !ccs +> List.iter (fun c ->
+ concat_headers_and_c !ccs +> List.iter (fun (c,f) ->
if c.flow <> None
then
(* does also some side effects on c and r *)
let processed =
process_a_ctl_a_env_a_toplevel r relevant_bindings
- c in
+ c f in
match processed with
| None -> ()
| Some newbindings ->
| _ -> failwith "duplicate environment entries")
old_e new_e
-and bigloop2 rs ccs =
+and bigloop2 rs (ccs: file_info list) =
let es = ref [(Ast_c.emptyMetavarsBinding,[])] in
let ccs = ref ccs in
let rules_that_have_ever_matched = ref [] in
apply_python_rule r cache newes e rules_that_have_matched
rules_that_have_ever_matched
| "test" ->
- concat_headers_and_c !ccs +> List.iter (fun c ->
+ concat_headers_and_c !ccs +> List.iter (fun (c,_) ->
if c.flow <> None
then
Printf.printf "Flow: %s\r\nFlow!\r\n%!" c.fullstring);
(* does side effects on C ast and on Cocci info rule *)
-and process_a_ctl_a_env_a_toplevel2 r e c =
+and process_a_ctl_a_env_a_toplevel2 r e c f =
indent_do (fun () ->
show_or_not_celem "trying" c.ast_c;
+ Flag.currentfile := Some (f ^ ":" ^get_celem c.ast_c);
let (trans_info, returned_any_states, inherited_bindings, newbindings) =
Common.save_excursion Flag_ctl.loop_in_src_code (fun () ->
Flag_ctl.loop_in_src_code := !Flag_ctl.loop_in_src_code||c.contain_loop;
* trasformation au fichier concerne. *)
(* modify ast via side effect *)
- ignore(Transformation3.transform r.rulename r.dropped_isos
+ ignore(Transformation_c.transform r.rulename r.dropped_isos
inherited_bindings trans_info (Common.some c.flow));
with Timeout -> raise Timeout | UnixExit i -> raise (UnixExit i)
end;
end
)
-and process_a_ctl_a_env_a_toplevel a b c =
+and process_a_ctl_a_env_a_toplevel a b c f=
Common.profile_code "process_a_ctl_a_env_a_toplevel"
- (fun () -> process_a_ctl_a_env_a_toplevel2 a b c)
+ (fun () -> process_a_ctl_a_env_a_toplevel2 a b c f)
if !Flag.show_misc then Common.pr_xxxxxxxxxxxxxxxxx ();
if !Flag.show_misc then pr "Finished";
+ if !Flag_ctl.graphical_trace then gen_pdf_graph ();
if !Flag.show_misc then Common.pr_xxxxxxxxxxxxxxxxx();
c_infos' +> List.map (fun c_or_h ->
-Release coccinelle-0.1.1
+Release coccinelle-0.1.2
-** Language:
- - support for initializer at toplevel, cf -test substruct
+** Bugfix:
+ - better handling of ifdef on statements in control flow graph.
+ - transform files even if they do not end in .c (thanks to Vegard Nossum)
+
+** Internals:
+ - merge code of yacfe
oseti.cmx: seti.cmx oset.cmx ocollection.cmx
osetpt.cmo: ocamlextra/setPt.cmo oset.cmi ocollection.cmi
osetpt.cmx: ocamlextra/setPt.cmx oset.cmx ocollection.cmx
+parser_combinators.cmo: common.cmi parser_combinators.cmi
+parser_combinators.cmx: common.cmx parser_combinators.cmi
seti.cmo: common.cmi
seti.cmx: common.cmx
ocamlextra/ANSITerminal.cmo: ocamlextra/ANSITerminal.cmi
ocamlextra/dynArray.cmx: ocamlextra/enum.cmx ocamlextra/dynArray.cmi
ocamlextra/enum.cmo: ocamlextra/enum.cmi
ocamlextra/enum.cmx: ocamlextra/enum.cmi
-ocamlextra/parser_combinators.cmo: common.cmi \
- ocamlextra/parser_combinators.cmi
-ocamlextra/parser_combinators.cmx: common.cmx \
- ocamlextra/parser_combinators.cmi
ocamlextra/setb.cmo: ocamlextra/setb.cmi
ocamlextra/setb.cmx: ocamlextra/setb.cmi
ocamlextra/suffix_tree.cmo: ocamlextra/suffix_tree.cmi
oarray.ml \
ograph2way.ml ograph_extended.ml \
ofullcommon.ml \
- glimpse.ml
+ glimpse.ml parser_combinators.ml
# src from other authors, got from the web or caml hump
SRC=ocamlextra/dumper.ml
SRC+=ocamlextra/setPt.ml
SRC+=$(MYSRC)
SRC+=ocamlextra/enum.ml ocamlextra/dynArray.ml
-SRC+=ocamlextra/parser_combinators.ml
SRC+=ocamlextra/suffix_tree.ml ocamlextra/suffix_tree_ext.ml
SYSLIBS=str.cma unix.cma
MYMPISRC=distribution.ml
MPISYSLIBS=mpi.cma
-#ocamlmpi
-MPIINCLUDES=-I ../ocamlmpi -I ../../ocamlmpi -I +ocamlmpi
-MYMPISRC=distribution.ml
-MPISYSLIBS=mpi.cma
-
-
#-----------------------------------------------------------------------------
# Other stuff
#-----------------------------------------------------------------------------
* where I can not allow any exception to stop mount.lfs.
*
* src: Jane Street Core library.
+ * update: Normally no more needed in OCaml 3.11 as part of the
+ * default runtime.
*)
external print : unit -> unit = "print_exception_backtrace_stub" "noalloc"
Buffer.contents buf
+let foldl1 p = function x::xs -> List.fold_left p x xs | _ -> failwith "foldl1"
+
(*****************************************************************************)
(* Debugging/logging *)
(*****************************************************************************)
type prof = PALL | PNONE | PSOME of string list
let profile = ref PNONE
+let show_trace_profile = ref false
let check_profile category =
match !profile with
| PSOME l -> List.mem category l
let _profile_table = ref (Hashtbl.create 100)
+
+let adjust_profile_entry category difftime =
+ let (xtime, xcount) =
+ (try Hashtbl.find !_profile_table category
+ with Not_found ->
+ let xtime = ref 0.0 in
+ let xcount = ref 0 in
+ Hashtbl.add !_profile_table category (xtime, xcount);
+ (xtime, xcount)
+ ) in
+ xtime := !xtime +. difftime;
+ xcount := !xcount + 1;
+ ()
+
let profile_start category = failwith "todo"
let profile_end category = failwith "todo"
+
(* subtil: don't forget to give all argumens to f, otherwise partial app
* and will profile nothing.
*)
if not (check_profile category)
then f()
else begin
+ if !show_trace_profile then pr2 (spf "p: %s" category);
let t = Unix.gettimeofday () in
let res, prefix =
try Some (f ()), ""
in
let category = prefix ^ category in (* add a '*' to indicate timeout func *)
let t' = Unix.gettimeofday () in
- let (xtime, xcount) =
- (try Hashtbl.find !_profile_table category
- with Not_found ->
- let xtime = ref 0.0 in
- let xcount = ref 0 in
- Hashtbl.add !_profile_table category (xtime, xcount);
- (xtime, xcount)
- ) in
- xtime := !xtime +. (t' -. t);
- xcount := !xcount + 1;
+
+ adjust_profile_entry category (t' -. t);
(match res with
| Some res -> res
| None -> raise Timeout
);
end
+
+let _is_in_exclusif = ref (None: string option)
+
+let profile_code_exclusif category f =
+ if not (check_profile category)
+ then f()
+ else begin
+
+ match !_is_in_exclusif with
+ | Some s ->
+ failwith (spf "profile_code_exclusif: %s but already in %s " category s);
+ | None ->
+ _is_in_exclusif := (Some category);
+ finalize
+ (fun () ->
+ profile_code category f
+ )
+ (fun () ->
+ _is_in_exclusif := None
+ )
+
+ end
+
+let profile_code_inside_exclusif_ok category f =
+ failwith "Todo"
+
+
(* todo: also put % ? also add % to see if coherent numbers *)
let profile_diagnostic () =
if !profile = PNONE then "" else
write_value (func (get_value filename)) filename
+let read_value f = get_value f
+
(*****************************************************************************)
(* Counter *)
let _ = example (all_match "\\(@[A-Za-z]+\\)" "ca va @Et toi @Comment"
= ["@Et";"@Comment"])
-
+
+
+let global_replace_regexp re f_on_substr s =
+ let regexp = Str.regexp re in
+ Str.global_substitute regexp (fun _wholestr ->
+
+ let substr = Str.matched_string s in
+ f_on_substr substr
+ ) s
+
+
+let regexp_word_str =
+ "\\([a-zA-Z_][A-Za-z_0-9]*\\)"
+let regexp_word = Str.regexp regexp_word_str
+
+let regular_words s =
+ all_match regexp_word_str s
+
+let contain_regular_word s =
+ let xs = regular_words s in
+ List.length xs >= 1
+
(*****************************************************************************)
+
+
+
(* done in summer 2007 for julia
* Reference: P216 of gusfeld book
* For two strings S1 and S2, D(i,j) is defined to be the edit distance of S1[1..i] to S2[1..j]
let basename = Filename.basename
type filename = string (* TODO could check that exist :) type sux *)
+type dirname = string (* TODO could check that exist :) type sux *)
module BasicType = struct
type filename = string
+let is_more_recent d1 d2 =
+ let (Days n1) = rough_days_since_jesus d1 in
+ let (Days n2) = rough_days_since_jesus d2 in
+ (n1 > n2)
+
+
+let max_dmy d1 d2 =
+ if is_more_recent d1 d2
+ then d1
+ else d2
+
+let min_dmy d1 d2 =
+ if is_more_recent d1 d2
+ then d2
+ else d1
+
+
+let maximum_dmy ds =
+ foldl1 max_dmy ds
+
+let minimum_dmy ds =
+ foldl1 min_dmy ds
+
+
let rough_days_between_dates d1 d2 =
let (Days n1) = rough_days_since_jesus d1 in
let (Days n2) = rough_days_since_jesus d2 in
- if (n2 < n1)
- then pr2 (spf "wierd date, d1 < d2: %s vs %s "
- (string_of_date_dmy d1)
- (string_of_date_dmy d2));
-
Days (n2 - n1)
let _ = example
let _ = example
(exclude_but_keep_attached (fun x -> x = 3) [3;3;1;3;2;3;3;3] =
[(1,[3;3]);(2,[3])])
+
+let (group_by_post: ('a -> bool) -> 'a list -> ('a list * 'a) list * 'a list)=
+ fun f xs ->
+ let rec aux_filter grouped_acc acc = function
+ | [] ->
+ List.rev grouped_acc, List.rev acc
+ | x::xs ->
+ if f x
+ then
+ aux_filter ((List.rev acc,x)::grouped_acc) [] xs
+ else
+ aux_filter grouped_acc (x::acc) xs
+ in
+ aux_filter [] [] xs
+
+let _ = example
+ (group_by_post (fun x -> x = 3) [1;1;3;2;3;4;5;3;6;6;6] =
+ ([([1;1],3);([2],3);[4;5],3], [6;6;6]))
+
let rec (split_when: ('a -> bool) -> 'a list -> 'a list * 'a * 'a list) =
let or_list = List.fold_left (||) false
let and_list = List.fold_left (&&) true
+let avg_list xs =
+ let sum = sum_int xs in
+ (float_of_int sum) /. (float_of_int (List.length xs))
+
let snoc x xs = xs @ [x]
let cons x xs = x::xs
let exclude p xs =
List.filter (fun x -> not (p x)) xs
-let foldl1 p = function x::xs -> List.fold_left p x xs | _ -> failwith "foldl1"
+(* now in prelude
+*)
let fold_k f lastk acc xs =
let rec fold_k_aux acc = function
let assoc_option k l =
optionise (fun () -> List.assoc k l)
+let assoc_with_err_msg k l =
+ try List.assoc k l
+ with Not_found ->
+ pr2 (spf "pb assoc_with_err_msg: %s" (dump k));
+ raise Not_found
+
(*****************************************************************************)
(* Assoc int -> xxx with binary tree. Have a look too at Mapb.mli *)
(*****************************************************************************)
let string_of_parse_info x =
spf "%s at %s:%d:%d" x.str x.file x.line x.column
+let string_of_parse_info_bis x =
+ spf "%s:%d:%d" x.file x.line x.column
let (info_from_charpos2: int -> filename -> (int * int * string)) =
" <int> guess what";
"-disable_pr2_once", Arg.Set disable_pr2_once,
" to print more messages";
+ "-show_trace_profile", Arg.Set show_trace_profile,
+ " show trace";
]
let cmdline_flags_other () =
(* let _ = if not !Sys.interactive then (main ()) *)
+(* based on code found in cameleon from maxence guesdon *)
+let md5sum_of_string s =
+ let com = spf "echo %s | md5sum | cut -d\" \" -f 1"
+ (Filename.quote s)
+ in
+ match cmd_to_list com with
+ | [s] ->
+ (*pr2 s;*)
+ s
+ | _ -> failwith "md5sum_of_string wrong output"
+
+
(*****************************************************************************)
(* Misc/test *)
(*****************************************************************************)
type prof = PALL | PNONE | PSOME of string list
val profile : prof ref
+val show_trace_profile : bool ref
+
val verbose_level : int ref
(*###########################################################################*)
type filename = string
+type dirname = string
(* Trick in case you dont want to do an 'open Common' while still wanting
* more pervasive types than the one in Pervasives. Just do the selective
val profile_code : string -> (unit -> 'a) -> 'a
val profile_diagnostic : unit -> string
+val profile_code_exclusif : string -> (unit -> 'a) -> 'a
+val profile_code_inside_exclusif_ok : string -> (unit -> 'a) -> 'a
+
val report_if_take_time : int -> string -> (unit -> 'a) -> 'a
(* similar to profile_code but print some information during execution too *)
(* just wrappers around Marshall *)
val get_value : filename -> 'a
+val read_value : filename -> 'a (* alias *)
val write_value : 'a -> filename -> unit
val write_back : ('a -> 'b) -> filename -> unit
val do_n : int -> (unit -> unit) -> unit
val foldn : ('a -> int -> 'a) -> 'a -> int -> 'a
-val sum_float : float list -> float
-val sum_int : int list -> int
-
val pi : float
val pi2 : float
val pi4 : float
val edit_distance: string -> string -> int
+val md5sum_of_string : string -> string
+
(*****************************************************************************)
(* Regexp *)
(*****************************************************************************)
val regexp_alpha : Str.regexp
+val regexp_word : Str.regexp
val _memo_compiled_regexp : (string, Str.regexp) Hashtbl.t
val ( =~ ) : string -> string -> bool
val split_list_regexp : string -> string list -> (string * string list) list
val all_match : string (* regexp *) -> string -> string list
+val global_replace_regexp :
+ string (* regexp *) -> (string -> string) -> string -> string
+
+val regular_words: string -> string list
+val contain_regular_word: string -> bool
(*****************************************************************************)
(* Filenames *)
val string_of_unix_time_lfs : Unix.tm -> string
+val is_more_recent : date_dmy -> date_dmy -> bool
+val max_dmy : date_dmy -> date_dmy -> date_dmy
+val min_dmy : date_dmy -> date_dmy -> date_dmy
+val maximum_dmy : date_dmy list -> date_dmy
+val minimum_dmy : date_dmy list -> date_dmy
(*****************************************************************************)
(* Lines/Words/Strings *)
(* List *)
(*****************************************************************************)
+
(* tail recursive efficient map (but that also reverse the element!) *)
val map_eff_rev : ('a -> 'b) -> 'a list -> 'b list
(* tail recursive efficient map, use accumulator *)
val groupBy : ('a -> 'a -> bool) -> 'a list -> 'a list list
val exclude_but_keep_attached: ('a -> bool) -> 'a list -> ('a * 'a list) list
+val group_by_post: ('a -> bool) -> 'a list -> ('a list * 'a) list * 'a list
(* use hash internally to not be in O(n2) *)
val group_assoc_bykey_eff : ('a * 'b) list -> ('a * 'b list) list
val or_list : bool list -> bool
val and_list : bool list -> bool
+val sum_float : float list -> float
+val sum_int : int list -> int
+val avg_list: int list -> float
+
val return_when : ('a -> 'b option) -> 'a list -> 'b
val lookup_list2 : 'a -> ('a, 'b) assoc list -> 'b * int
val assoc_option : 'a -> ('a, 'b) assoc -> 'b option
+val assoc_with_err_msg : 'a -> ('a, 'b) assoc -> 'b
(*****************************************************************************)
(* Assoc, specialized. *)
}
val fake_parse_info : parse_info
val string_of_parse_info : parse_info -> string
+val string_of_parse_info_bis : parse_info -> string
(* array[i] will contain the (line x col) of the i char position *)
val full_charpos_to_pos : filename -> (int * int) array
method virtual null: bool (* can do default with: lenght(tolist)= 0 *)
+ method add2: 'a -> unit = fun a ->
+ o#add a +> ignore;
+ ()
+
+
method fold: 'b. ('b -> 'a -> 'b) -> 'b -> 'b = fun f a ->
let a = ref a in
method virtual mem : 'a -> bool
method virtual null : bool
+ (* effect version *)
+ method add2: 'a -> unit
method fold : ('c -> 'a -> 'c) -> 'c -> 'c
+let generate_ograph_generic g label fnode filename =
+ with_open_outfile filename (fun (pr,_) ->
+ pr "digraph misc {\n" ;
+ pr "size = \"10,10\";\n" ;
+ (match label with
+ None -> ()
+ | Some x -> pr (Printf.sprintf "label = \"%s\";\n" x));
+
+ let nodes = g#nodes in
+ nodes#iter (fun (k,node) ->
+ let (str,border_color,inner_color) = fnode (k, node) in
+ let color =
+ match inner_color with
+ None ->
+ (match border_color with
+ None -> ""
+ | Some x -> Printf.sprintf ", style=\"setlinewidth(3)\", color = %s" x)
+ | Some x ->
+ (match border_color with
+ None -> Printf.sprintf ", style=\"setlinewidth(3),filled\", fillcolor = %s" x
+ | Some x' -> Printf.sprintf ", style=\"setlinewidth(3),filled\", fillcolor = %s, color = %s" x x') in
+ (* so can see if nodes without arcs were created *)
+ pr (sprintf "%d [label=\"%s [%d]\"%s];\n" k str k color)
+ );
+
+ nodes#iter (fun (k,node) ->
+ let succ = g#successors k in
+ succ#iter (fun (j,edge) ->
+ pr (sprintf "%d -> %d;\n" k j);
+ );
+ );
+ pr "}\n" ;
+ );
+ ()
+
let generate_ograph_xxx g filename =
with_open_outfile filename (fun (pr,_) ->
let nodes = g#nodes in
nodes#iter (fun (k,(node, s)) ->
(* so can see if nodes without arcs were created *)
- pr (sprintf "%d [label=\"%s [%d]\"];" k s k);
+ pr (sprintf "%d [label=\"%s [%d]\"];\n" k s k)
);
nodes#iter (fun (k,node) ->
);
pr "}\n" ;
);
- let _status =
- Unix.system ("dot " ^ filename ^ " -Tps -o " ^ filename ^ ".ps;") in
()
-let launch_gv filename =
+
+let launch_gv_cmd filename =
+ let _status =
+ Unix.system ("dot " ^ filename ^ " -Tps -o " ^ filename ^ ".ps;") in
let _status = Unix.system ("gv " ^ filename ^ ".ps &")
in
(* zarb: I need this when I launch the program via eshell, otherwise gv
let print_ograph_extended g filename launchgv =
generate_ograph_xxx g filename;
- if launchgv then launch_gv filename
+ if launchgv then launch_gv_cmd filename
let print_ograph_mutable g filename launchgv =
generate_ograph_xxx g filename;
- if launchgv then launch_gv filename
+ if launchgv then launch_gv_cmd filename
+
+let print_ograph_mutable_generic g label fnode ~output_file ~launch_gv =
+ generate_ograph_generic g label fnode output_file;
+ if launch_gv then launch_gv_cmd output_file
nodei -> (nodei -> nodei list -> unit) -> ('node, 'edge) ograph_mutable ->
unit
+val print_ograph_mutable_generic :
+ ('node, 'edge) ograph_mutable ->
+ string option -> (* label for the entire graph *)
+ (* what string to print for a node and how to color it *)
+ ((nodei * 'node) -> (string * string option * string option)) ->
+ output_file:filename ->
+ launch_gv:bool ->
+ unit
+
val print_ograph_extended :
('node * string, 'edge) ograph_extended ->
filename (* output file *) ->
bool (* launch gv ? *) ->
unit
-
--- /dev/null
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+*
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+*
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
+*
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+(*external c_counter : unit -> int = "c_counter"*)
+let timeout = 800
+(* Optimize triples_conj by first extracting the intersection of the two sets,
+which can certainly be in the intersection *)
+let pTRIPLES_CONJ_OPT = ref true
+(* For complement, make NegState for the negation of a single state *)
+let pTRIPLES_COMPLEMENT_OPT = ref true
+(* For complement, do something special for the case where the environment
+and witnesses are empty *)
+let pTRIPLES_COMPLEMENT_SIMPLE_OPT = ref true
+(* "Double negate" the arguments of the path operators *)
+let pDOUBLE_NEGATE_OPT = ref true
+(* Only do pre_forall/pre_exists on new elements in fixpoint iteration *)
+let pNEW_INFO_OPT = ref true
+(* Filter the result of the label function to drop entries that aren't
+compatible with any of the available environments *)
+let pREQUIRED_ENV_OPT = ref true
+(* Memoize the raw result of the label function *)
+let pSATLABEL_MEMO_OPT = ref true
+(* Filter results according to the required states *)
+let pREQUIRED_STATES_OPT = ref true
+(* Drop negative witnesses at Uncheck *)
+let pUNCHECK_OPT = ref true
+let pANY_NEG_OPT = ref true
+let pLazyOpt = ref true
+
+(*
+let pTRIPLES_CONJ_OPT = ref false
+let pTRIPLES_COMPLEMENT_OPT = ref false
+let pTRIPLES_COMPLEMENT_SIMPLE_OPT = ref false
+let pDOUBLE_NEGATE_OPT = ref false
+let pNEW_INFO_OPT = ref false
+let pREQUIRED_ENV_OPT = ref false
+let pSATLABEL_MEMO_OPT = ref false
+let pREQUIRED_STATES_OPT = ref false
+let pUNCHECK_OPT = ref false
+let pANY_NEG_OPT = ref false
+let pLazyOpt = ref false
+*)
+
+
+let step_count = ref 0
+exception Steps
+let inc_step _ =
+ if not (!step_count = 0)
+ then
+ begin
+ step_count := !step_count - 1;
+ if !step_count = 0 then raise Steps
+ end
+
+let inc cell = cell := !cell + 1
+
+let satEU_calls = ref 0
+let satAW_calls = ref 0
+let satAU_calls = ref 0
+let satEF_calls = ref 0
+let satAF_calls = ref 0
+let satEG_calls = ref 0
+let satAG_calls = ref 0
+
+let triples = ref 0
+
+let ctr = ref 0
+let new_let _ =
+ let c = !ctr in
+ ctr := c + 1;
+ Printf.sprintf "_fresh_r_%d" c
+
+(* **********************************************************************
+ *
+ * Implementation of a Witness Tree model checking engine for CTL-FVex
+ *
+ *
+ * **********************************************************************)
+
+(* ********************************************************************** *)
+(* Module: SUBST (substitutions: meta. vars and values) *)
+(* ********************************************************************** *)
+
+module type SUBST =
+ sig
+ type value
+ type mvar
+ val eq_mvar: mvar -> mvar -> bool
+ val eq_val: value -> value -> bool
+ val merge_val: value -> value -> value
+ val print_mvar : mvar -> unit
+ val print_value : value -> unit
+ end
+;;
+
+(* ********************************************************************** *)
+(* Module: GRAPH (control flow graphs / model) *)
+(* ********************************************************************** *)
+
+module type GRAPH =
+ sig
+ type node
+ type cfg
+ val predecessors: cfg -> node -> node list
+ val successors: cfg -> node -> node list
+ val extract_is_loop : cfg -> node -> bool
+ val print_node : node -> unit
+ val size : cfg -> int
+ end
+;;
+
+module OGRAPHEXT_GRAPH =
+ struct
+ type node = int;;
+ type cfg = (string,unit) Ograph_extended.ograph_mutable;;
+ let predecessors cfg n = List.map fst ((cfg#predecessors n)#tolist);;
+ let print_node i = Format.print_string (Common.i_to_s i)
+ end
+;;
+
+(* ********************************************************************** *)
+(* Module: PREDICATE (predicates for CTL formulae) *)
+(* ********************************************************************** *)
+
+module type PREDICATE =
+sig
+ type t
+ val print_predicate : t -> unit
+end
+
+
+(* ********************************************************************** *)
+
+(* ---------------------------------------------------------------------- *)
+(* Misc. useful generic functions *)
+(* ---------------------------------------------------------------------- *)
+
+let head = List.hd
+
+let tail l =
+ match l with
+ [] -> []
+ | (x::xs) -> xs
+;;
+
+let foldl = List.fold_left;;
+
+let foldl1 f xs = foldl f (head xs) (tail xs)
+
+type 'a esc = ESC of 'a | CONT of 'a
+
+let foldr = List.fold_right;;
+
+let concat = List.concat;;
+
+let map = List.map;;
+
+let filter = List.filter;;
+
+let partition = List.partition;;
+
+let concatmap f l = List.concat (List.map f l);;
+
+let maybe f g opt =
+ match opt with
+ | None -> g
+ | Some x -> f x
+;;
+
+let some_map f opts = map (maybe (fun x -> Some (f x)) None) opts
+
+let some_tolist_alt opts = concatmap (maybe (fun x -> [x]) []) opts
+
+let rec some_tolist opts =
+ match opts with
+ | [] -> []
+ | (Some x)::rest -> x::(some_tolist rest)
+ | _::rest -> some_tolist rest
+;;
+
+let rec groupBy eq l =
+ match l with
+ [] -> []
+ | (x::xs) ->
+ let (xs1,xs2) = partition (fun x' -> eq x x') xs in
+ (x::xs1)::(groupBy eq xs2)
+;;
+
+let group l = groupBy (=) l;;
+
+let rec memBy eq x l =
+ match l with
+ [] -> false
+ | (y::ys) -> if (eq x y) then true else (memBy eq x ys)
+;;
+
+let rec nubBy eq ls =
+ match ls with
+ [] -> []
+ | (x::xs) when (memBy eq x xs) -> nubBy eq xs
+ | (x::xs) -> x::(nubBy eq xs)
+;;
+
+let rec nub ls =
+ match ls with
+ [] -> []
+ | (x::xs) when (List.mem x xs) -> nub xs
+ | (x::xs) -> x::(nub xs)
+;;
+
+let state_compare (s1,_,_) (s2,_,_) = compare s1 s2
+
+let setifyBy eq xs = nubBy eq xs;;
+
+let setify xs = nub xs;;
+
+let inner_setify xs = List.sort compare (nub xs);;
+
+let unionBy compare eq xs = function
+ [] -> xs
+ | ys ->
+ let rec loop = function
+ [] -> ys
+ | x::xs -> if memBy eq x ys then loop xs else x::(loop xs) in
+ List.sort compare (loop xs)
+;;
+
+let union xs ys = unionBy state_compare (=) xs ys;;
+
+let setdiff xs ys = filter (fun x -> not (List.mem x ys)) xs;;
+
+let subseteqBy eq xs ys = List.for_all (fun x -> memBy eq x ys) xs;;
+
+let subseteq xs ys = List.for_all (fun x -> List.mem x ys) xs;;
+let supseteq xs ys = subseteq ys xs
+
+let setequalBy eq xs ys = (subseteqBy eq xs ys) & (subseteqBy eq ys xs);;
+
+let setequal xs ys = (subseteq xs ys) & (subseteq ys xs);;
+
+(* Fix point calculation *)
+let rec fix eq f x =
+ let x' = f x in if (eq x' x) then x' else fix eq f x'
+;;
+
+(* Fix point calculation on set-valued functions *)
+let setfix f x = (fix subseteq f x) (*if new is a subset of old, stop*)
+let setgfix f x = (fix supseteq f x) (*if new is a supset of old, stop*)
+
+let get_states l = nub (List.map (function (s,_,_) -> s) l)
+
+(* ********************************************************************** *)
+(* Module: CTL_ENGINE *)
+(* ********************************************************************** *)
+
+module CTL_ENGINE =
+ functor (SUB : SUBST) ->
+ functor (G : GRAPH) ->
+ functor (P : PREDICATE) ->
+struct
+
+module A = Ast_ctl
+
+type substitution = (SUB.mvar, SUB.value) Ast_ctl.generic_substitution
+
+type ('pred,'anno) witness =
+ (G.node, substitution,
+ ('pred, SUB.mvar, 'anno) Ast_ctl.generic_ctl list)
+ Ast_ctl.generic_witnesstree
+
+type ('pred,'anno) triples =
+ (G.node * substitution * ('pred,'anno) witness list) list
+
+(* ---------------------------------------------------------------------- *)
+(* Pretty printing functions *)
+(* ---------------------------------------------------------------------- *)
+
+let (print_generic_substitution : substitution -> unit) = fun substxs ->
+ let print_generic_subst = function
+ A.Subst (mvar, v) ->
+ SUB.print_mvar mvar; Format.print_string " --> "; SUB.print_value v
+ | A.NegSubst (mvar, v) ->
+ SUB.print_mvar mvar; Format.print_string " -/-> "; SUB.print_value v in
+ Format.print_string "[";
+ Common.print_between (fun () -> Format.print_string ";" )
+ print_generic_subst substxs;
+ Format.print_string "]"
+
+let rec (print_generic_witness: ('pred, 'anno) witness -> unit) =
+ function
+ | A.Wit (state, subst, anno, childrens) ->
+ Format.print_string "wit ";
+ G.print_node state;
+ print_generic_substitution subst;
+ (match childrens with
+ [] -> Format.print_string "{}"
+ | _ ->
+ Format.force_newline(); Format.print_string " "; Format.open_box 0;
+ print_generic_witnesstree childrens; Format.close_box())
+ | A.NegWit(wit) ->
+ Format.print_string "!";
+ print_generic_witness wit
+
+and (print_generic_witnesstree: ('pred,'anno) witness list -> unit) =
+ fun witnesstree ->
+ Format.open_box 1;
+ Format.print_string "{";
+ Common.print_between
+ (fun () -> Format.print_string ";"; Format.force_newline() )
+ print_generic_witness witnesstree;
+ Format.print_string "}";
+ Format.close_box()
+
+and print_generic_triple (node,subst,tree) =
+ G.print_node node;
+ print_generic_substitution subst;
+ print_generic_witnesstree tree
+
+and (print_generic_algo : ('pred,'anno) triples -> unit) = fun xs ->
+ Format.print_string "<";
+ Common.print_between
+ (fun () -> Format.print_string ";"; Format.force_newline())
+ print_generic_triple xs;
+ Format.print_string ">"
+;;
+
+let print_state (str : string) (l : ('pred,'anno) triples) =
+ Printf.printf "%s\n" str;
+ List.iter (function x ->
+ print_generic_triple x; Format.print_newline(); flush stdout)
+ (List.sort compare l);
+ Printf.printf "\n"
+
+let print_required_states = function
+ None -> Printf.printf "no required states\n"
+ | Some states ->
+ Printf.printf "required states: ";
+ List.iter
+ (function x ->
+ G.print_node x; Format.print_string " "; Format.print_flush())
+ states;
+ Printf.printf "\n"
+
+let mkstates states = function
+ None -> states
+ | Some states -> states
+
+(* ---------------------------------------------------------------------- *)
+(* *)
+(* ---------------------------------------------------------------------- *)
+
+
+(* ************************* *)
+(* Substitutions *)
+(* ************************* *)
+
+let dom_sub sub =
+ match sub with
+ | A.Subst(x,_) -> x
+ | A.NegSubst(x,_) -> x
+;;
+
+let ran_sub sub =
+ match sub with
+ | A.Subst(_,x) -> x
+ | A.NegSubst(_,x) -> x
+;;
+
+let eq_subBy eqx eqv sub sub' =
+ match (sub,sub') with
+ | (A.Subst(x,v),A.Subst(x',v')) -> (eqx x x') && (eqv v v')
+ | (A.NegSubst(x,v),A.NegSubst(x',v')) -> (eqx x x') && (eqv v v')
+ | _ -> false
+;;
+
+(* NOTE: functor *)
+let eq_sub sub sub' = eq_subBy SUB.eq_mvar SUB.eq_val sub sub'
+
+let eq_subst th th' = setequalBy eq_sub th th';;
+
+let merge_subBy eqx (===) (>+<) sub sub' =
+ (* variable part is guaranteed to be the same *)
+ match (sub,sub') with
+ (A.Subst (x,v),A.Subst (x',v')) ->
+ if (v === v')
+ then Some [A.Subst(x, v >+< v')]
+ else None
+ | (A.NegSubst(x,v),A.Subst(x',v')) ->
+ if (not (v === v'))
+ then Some [A.Subst(x',v')]
+ else None
+ | (A.Subst(x,v),A.NegSubst(x',v')) ->
+ if (not (v === v'))
+ then Some [A.Subst(x,v)]
+ else None
+ | (A.NegSubst(x,v),A.NegSubst(x',v')) ->
+ if (v === v')
+ then
+ let merged = v >+< v' in
+ if merged = v && merged = v'
+ then Some [A.NegSubst(x,v >+< v')]
+ else
+ (* positions are compatible, but not identical. keep apart. *)
+ Some [A.NegSubst(x,v);A.NegSubst(x',v')]
+ else Some [A.NegSubst(x,v);A.NegSubst(x',v')]
+;;
+
+(* NOTE: functor *)
+let merge_sub sub sub' =
+ merge_subBy SUB.eq_mvar SUB.eq_val SUB.merge_val sub sub'
+
+let clean_substBy eq cmp theta = List.sort cmp (nubBy eq theta);;
+
+(* NOTE: we sort by using the generic "compare" on (meta-)variable
+ * names; we could also require a definition of compare for meta-variables
+ * or substitutions but that seems like overkill for sorting
+ *)
+let clean_subst theta =
+ let res =
+ clean_substBy eq_sub
+ (fun s s' ->
+ let res = compare (dom_sub s) (dom_sub s') in
+ if res = 0
+ then
+ match (s,s') with
+ (A.Subst(_,_),A.NegSubst(_,_)) -> -1
+ | (A.NegSubst(_,_),A.Subst(_,_)) -> 1
+ | _ -> compare (ran_sub s) (ran_sub s')
+ else res)
+ theta in
+ let rec loop = function
+ [] -> []
+ | (A.Subst(x,v)::A.NegSubst(y,v')::rest) when SUB.eq_mvar x y ->
+ loop (A.Subst(x,v)::rest)
+ | x::xs -> x::(loop xs) in
+ loop res
+
+let top_subst = [];; (* Always TRUE subst. *)
+
+(* Split a theta in two parts: one with (only) "x" and one without *)
+(* NOTE: functor *)
+let split_subst theta x =
+ partition (fun sub -> SUB.eq_mvar (dom_sub sub) x) theta;;
+
+exception SUBST_MISMATCH
+let conj_subst theta theta' =
+ match (theta,theta') with
+ | ([],_) -> Some theta'
+ | (_,[]) -> Some theta
+ | _ ->
+ let rec classify = function
+ [] -> []
+ | [x] -> [(dom_sub x,[x])]
+ | x::xs ->
+ (match classify xs with
+ ((nm,y)::ys) as res ->
+ if dom_sub x = nm
+ then (nm,x::y)::ys
+ else (dom_sub x,[x])::res
+ | _ -> failwith "not possible") in
+ let merge_all theta theta' =
+ foldl
+ (function rest ->
+ function sub ->
+ foldl
+ (function rest ->
+ function sub' ->
+ match (merge_sub sub sub') with
+ Some subs -> subs @ rest
+ | _ -> raise SUBST_MISMATCH)
+ rest theta')
+ [] theta in
+ let rec loop = function
+ ([],ctheta') ->
+ List.concat (List.map (function (_,ths) -> ths) ctheta')
+ | (ctheta,[]) ->
+ List.concat (List.map (function (_,ths) -> ths) ctheta)
+ | ((x,ths)::xs,(y,ths')::ys) ->
+ (match compare x y with
+ 0 -> (merge_all ths ths') @ loop (xs,ys)
+ | -1 -> ths @ loop (xs,((y,ths')::ys))
+ | 1 -> ths' @ loop (((x,ths)::xs),ys)
+ | _ -> failwith "not possible") in
+ try Some (clean_subst(loop (classify theta, classify theta')))
+ with SUBST_MISMATCH -> None
+;;
+
+(* theta' must be a subset of theta *)
+let conj_subst_none theta theta' =
+ match (theta,theta') with
+ | (_,[]) -> Some theta
+ | ([],_) -> None
+ | _ ->
+ let rec classify = function
+ [] -> []
+ | [x] -> [(dom_sub x,[x])]
+ | x::xs ->
+ (match classify xs with
+ ((nm,y)::ys) as res ->
+ if dom_sub x = nm
+ then (nm,x::y)::ys
+ else (dom_sub x,[x])::res
+ | _ -> failwith "not possible") in
+ let merge_all theta theta' =
+ foldl
+ (function rest ->
+ function sub ->
+ foldl
+ (function rest ->
+ function sub' ->
+ match (merge_sub sub sub') with
+ Some subs -> subs @ rest
+ | _ -> raise SUBST_MISMATCH)
+ rest theta')
+ [] theta in
+ let rec loop = function
+ (ctheta,[]) ->
+ List.concat (List.map (function (_,ths) -> ths) ctheta)
+ | ([],ctheta') -> raise SUBST_MISMATCH
+ | ((x,ths)::xs,(y,ths')::ys) ->
+ (match compare x y with
+ 0 -> (merge_all ths ths') @ loop (xs,ys)
+ | -1 -> ths @ loop (xs,((y,ths')::ys))
+ | 1 -> raise SUBST_MISMATCH
+ | _ -> failwith "not possible") in
+ try Some (clean_subst(loop (classify theta, classify theta')))
+ with SUBST_MISMATCH -> None
+;;
+
+let negate_sub sub =
+ match sub with
+ | A.Subst(x,v) -> A.NegSubst (x,v)
+ | A.NegSubst(x,v) -> A.Subst(x,v)
+;;
+
+(* Turn a (big) theta into a list of (small) thetas *)
+let negate_subst theta = (map (fun sub -> [negate_sub sub]) theta);;
+
+
+(* ************************* *)
+(* Witnesses *)
+(* ************************* *)
+
+(* Always TRUE witness *)
+let top_wit = ([] : (('pred, 'anno) witness list));;
+
+let eq_wit wit wit' = wit = wit';;
+
+let union_wit wit wit' = (*List.sort compare (wit' @ wit) for popl*)
+ let res = unionBy compare (=) wit wit' in
+ let anynegwit = (* if any is neg, then all are *)
+ List.exists (function A.NegWit _ -> true | A.Wit _ -> false) in
+ if anynegwit res
+ then List.filter (function A.NegWit _ -> true | A.Wit _ -> false) res
+ else res
+
+let negate_wit wit = A.NegWit wit (*
+ match wit with
+ | A.Wit(s,th,anno,ws) -> A.NegWitWit(s,th,anno,ws)
+ | A.NegWitWit(s,th,anno,ws) -> A.Wit(s,th,anno,ws)*)
+;;
+
+let negate_wits wits =
+ List.sort compare (map (fun wit -> [negate_wit wit]) wits);;
+
+let unwitify trips =
+ let anynegwit = (* if any is neg, then all are *)
+ List.exists (function A.NegWit _ -> true | A.Wit _ -> false) in
+ setify
+ (List.fold_left
+ (function prev ->
+ function (s,th,wit) ->
+ if anynegwit wit then prev else (s,th,top_wit)::prev)
+ [] trips)
+
+(* ************************* *)
+(* Triples *)
+(* ************************* *)
+
+(* Triples are equal when the constituents are equal *)
+let eq_trip (s,th,wit) (s',th',wit') =
+ (s = s') && (eq_wit wit wit') && (eq_subst th th');;
+
+let triples_top states = map (fun s -> (s,top_subst,top_wit)) states;;
+
+let normalize trips =
+ List.map
+ (function (st,th,wit) -> (st,List.sort compare th,List.sort compare wit))
+ trips
+
+
+(* conj opt doesn't work ((1,[],{{x=3}}) v (1,[],{{x=4}})) & (1,[],{{x=4}}) =
+(1,[],{{x=3},{x=4}}), not (1,[],{{x=4}}) *)
+let triples_conj trips trips' =
+ let (trips,shared,trips') =
+ if false && !pTRIPLES_CONJ_OPT (* see comment above *)
+ then
+ let (shared,trips) =
+ List.partition (function t -> List.mem t trips') trips in
+ let trips' =
+ List.filter (function t -> not(List.mem t shared)) trips' in
+ (trips,shared,trips')
+ else (trips,[],trips') in
+ foldl (* returns a set - setify inlined *)
+ (function rest ->
+ function (s1,th1,wit1) ->
+ foldl
+ (function rest ->
+ function (s2,th2,wit2) ->
+ if (s1 = s2) then
+ (match (conj_subst th1 th2) with
+ Some th ->
+ let t = (s1,th,union_wit wit1 wit2) in
+ if List.mem t rest then rest else t::rest
+ | _ -> rest)
+ else rest)
+ rest trips')
+ shared trips
+;;
+
+(* ignore the state in the right argument. always pretend it is the same as
+the left one *)
+(* env on right has to be a subset of env on left *)
+let triples_conj_none trips trips' =
+ let (trips,shared,trips') =
+ if false && !pTRIPLES_CONJ_OPT (* see comment above *)
+ then
+ let (shared,trips) =
+ List.partition (function t -> List.mem t trips') trips in
+ let trips' =
+ List.filter (function t -> not(List.mem t shared)) trips' in
+ (trips,shared,trips')
+ else (trips,[],trips') in
+ foldl (* returns a set - setify inlined *)
+ (function rest ->
+ function (s1,th1,wit1) ->
+ foldl
+ (function rest ->
+ function (s2,th2,wit2) ->
+ match (conj_subst_none th1 th2) with
+ Some th ->
+ let t = (s1,th,union_wit wit1 wit2) in
+ if List.mem t rest then rest else t::rest
+ | _ -> rest)
+ rest trips')
+ shared trips
+;;
+
+exception AW
+
+let triples_conj_AW trips trips' =
+ let (trips,shared,trips') =
+ if false && !pTRIPLES_CONJ_OPT
+ then
+ let (shared,trips) =
+ List.partition (function t -> List.mem t trips') trips in
+ let trips' =
+ List.filter (function t -> not(List.mem t shared)) trips' in
+ (trips,shared,trips')
+ else (trips,[],trips') in
+ foldl (* returns a set - setify inlined *)
+ (function rest ->
+ function (s1,th1,wit1) ->
+ foldl
+ (function rest ->
+ function (s2,th2,wit2) ->
+ if (s1 = s2) then
+ (match (conj_subst th1 th2) with
+ Some th ->
+ let t = (s1,th,union_wit wit1 wit2) in
+ if List.mem t rest then rest else t::rest
+ | _ -> raise AW)
+ else rest)
+ rest trips')
+ shared trips
+;;
+
+(* *************************** *)
+(* NEGATION (NegState style) *)
+(* *************************** *)
+
+(* Constructive negation at the state level *)
+type ('a) state =
+ PosState of 'a
+ | NegState of 'a list
+;;
+
+let compatible_states = function
+ (PosState s1, PosState s2) ->
+ if s1 = s2 then Some (PosState s1) else None
+ | (PosState s1, NegState s2) ->
+ if List.mem s1 s2 then None else Some (PosState s1)
+ | (NegState s1, PosState s2) ->
+ if List.mem s2 s1 then None else Some (PosState s2)
+ | (NegState s1, NegState s2) -> Some (NegState (s1 @ s2))
+;;
+
+(* Conjunction on triples with "special states" *)
+let triples_state_conj trips trips' =
+ let (trips,shared,trips') =
+ if !pTRIPLES_CONJ_OPT
+ then
+ let (shared,trips) =
+ List.partition (function t -> List.mem t trips') trips in
+ let trips' =
+ List.filter (function t -> not(List.mem t shared)) trips' in
+ (trips,shared,trips')
+ else (trips,[],trips') in
+ foldl
+ (function rest ->
+ function (s1,th1,wit1) ->
+ foldl
+ (function rest ->
+ function (s2,th2,wit2) ->
+ match compatible_states(s1,s2) with
+ Some s ->
+ (match (conj_subst th1 th2) with
+ Some th ->
+ let t = (s,th,union_wit wit1 wit2) in
+ if List.mem t rest then rest else t::rest
+ | _ -> rest)
+ | _ -> rest)
+ rest trips')
+ shared trips
+;;
+
+let triple_negate (s,th,wits) =
+ let negstates = (NegState [s],top_subst,top_wit) in
+ let negths = map (fun th -> (PosState s,th,top_wit)) (negate_subst th) in
+ let negwits = map (fun nwit -> (PosState s,th,nwit)) (negate_wits wits) in
+ negstates :: (negths @ negwits) (* all different *)
+
+(* FIX ME: it is not necessary to do full conjunction *)
+let triples_complement states (trips : ('pred, 'anno) triples) =
+ if !pTRIPLES_COMPLEMENT_OPT
+ then
+ (let cleanup (s,th,wit) =
+ match s with
+ PosState s' -> [(s',th,wit)]
+ | NegState ss ->
+ assert (th=top_subst);
+ assert (wit=top_wit);
+ map (fun st -> (st,top_subst,top_wit)) (setdiff states ss) in
+ let (simple,complex) =
+ if !pTRIPLES_COMPLEMENT_SIMPLE_OPT
+ then
+ let (simple,complex) =
+ List.partition (function (s,[],[]) -> true | _ -> false) trips in
+ let simple =
+ [(NegState(List.map (function (s,_,_) -> s) simple),
+ top_subst,top_wit)] in
+ (simple,complex)
+ else ([(NegState [],top_subst,top_wit)],trips) in
+ let rec compl trips =
+ match trips with
+ [] -> simple
+ | (t::ts) -> triples_state_conj (triple_negate t) (compl ts) in
+ let compld = (compl complex) in
+ let compld = concatmap cleanup compld in
+ compld)
+ else
+ let negstates (st,th,wits) =
+ map (function st -> (st,top_subst,top_wit)) (setdiff states [st]) in
+ let negths (st,th,wits) =
+ map (function th -> (st,th,top_wit)) (negate_subst th) in
+ let negwits (st,th,wits) =
+ map (function nwit -> (st,th,nwit)) (negate_wits wits) in
+ match trips with
+ [] -> map (function st -> (st,top_subst,top_wit)) states
+ | x::xs ->
+ setify
+ (foldl
+ (function prev ->
+ function cur ->
+ triples_conj (negstates cur @ negths cur @ negwits cur) prev)
+ (negstates x @ negths x @ negwits x) xs)
+;;
+
+let triple_negate (s,th,wits) =
+ let negths = map (fun th -> (s,th,top_wit)) (negate_subst th) in
+ let negwits = map (fun nwit -> (s,th,nwit)) (negate_wits wits) in
+ ([s], negths @ negwits) (* all different *)
+
+let print_compl_state str (n,p) =
+ Printf.printf "%s neg: " str;
+ List.iter
+ (function x -> G.print_node x; Format.print_flush(); Printf.printf " ")
+ n;
+ Printf.printf "\n";
+ print_state "pos" p
+
+let triples_complement states (trips : ('pred, 'anno) triples) =
+ if trips = []
+ then map (function st -> (st,top_subst,top_wit)) states
+ else
+ let cleanup (neg,pos) =
+ let keep_pos =
+ List.filter (function (s,_,_) -> List.mem s neg) pos in
+ (map (fun st -> (st,top_subst,top_wit)) (setdiff states neg)) @
+ keep_pos in
+ let trips = List.sort state_compare trips in
+ let all_negated = List.map triple_negate trips in
+ let merge_one (neg1,pos1) (neg2,pos2) =
+ let (pos1conj,pos1keep) =
+ List.partition (function (s,_,_) -> List.mem s neg2) pos1 in
+ let (pos2conj,pos2keep) =
+ List.partition (function (s,_,_) -> List.mem s neg1) pos2 in
+ (Common.union_set neg1 neg2,
+ (triples_conj pos1conj pos2conj) @ pos1keep @ pos2keep) in
+ let rec inner_loop = function
+ x1::x2::rest -> (merge_one x1 x2) :: (inner_loop rest)
+ | l -> l in
+ let rec outer_loop = function
+ [x] -> x
+ | l -> outer_loop (inner_loop l) in
+ cleanup (outer_loop all_negated)
+
+(* ********************************** *)
+(* END OF NEGATION (NegState style) *)
+(* ********************************** *)
+
+(* now this is always true, so we could get rid of it *)
+let something_dropped = ref true
+
+let triples_union trips trips' =
+ (*unionBy compare eq_trip trips trips';;*)
+ (* returns -1 is t1 > t2, 1 if t2 >= t1, and 0 otherwise *)
+(*
+The following does not work. Suppose we have ([x->3],{A}) and ([],{A,B}).
+Then, the following says that since the first is a more restrictive
+environment and has fewer witnesses, then it should be dropped. But having
+fewer witnesses is not necessarily less informative than having more,
+because fewer witnesses can mean the absence of the witness-causing thing.
+So the fewer witnesses have to be kept around.
+subseteq changed to = to make it hopefully work
+*)
+ if !pNEW_INFO_OPT
+ then
+ begin
+ something_dropped := false;
+ if trips = trips'
+ then (something_dropped := true; trips)
+ else
+ let subsumes (s1,th1,wit1) (s2,th2,wit2) =
+ if s1 = s2
+ then
+ (match conj_subst th1 th2 with
+ Some conj ->
+ if conj = th1
+ then if (*subseteq*) wit1 = wit2 then 1 else 0
+ else
+ if conj = th2
+ then if (*subseteq*) wit2 = wit1 then (-1) else 0
+ else 0
+ | None -> 0)
+ else 0 in
+ let rec first_loop second = function
+ [] -> second
+ | x::xs -> first_loop (second_loop x second) xs
+ and second_loop x = function
+ [] -> [x]
+ | (y::ys) as all ->
+ match subsumes x y with
+ 1 -> something_dropped := true; all
+ | (-1) -> second_loop x ys
+ | _ -> y::(second_loop x ys) in
+ first_loop trips trips'
+ end
+ else unionBy compare eq_trip trips trips'
+
+
+let triples_witness x unchecked not_keep trips =
+ let anyneg = (* if any is neg, then all are *)
+ List.exists (function A.NegSubst _ -> true | A.Subst _ -> false) in
+ let anynegwit = (* if any is neg, then all are *)
+ List.exists (function A.NegWit _ -> true | A.Wit _ -> false) in
+ let allnegwit = (* if any is neg, then all are *)
+ List.for_all (function A.NegWit _ -> true | A.Wit _ -> false) in
+ let negtopos =
+ List.map (function A.NegWit w -> w | A.Wit _ -> failwith "bad wit")in
+ let res =
+ List.fold_left
+ (function prev ->
+ function (s,th,wit) as t ->
+ let (th_x,newth) = split_subst th x in
+ match th_x with
+ [] ->
+ (* one consider whether if not not_keep is true, then we should
+ fail. but it could be that the variable is a used_after and
+ then it is the later rule that should fail and not this one *)
+ if not not_keep && !Flag_ctl.verbose_ctl_engine
+ then
+ (SUB.print_mvar x; Format.print_flush();
+ print_state ": empty witness from" [t]);
+ t::prev
+ | l when anyneg l && !pANY_NEG_OPT -> prev
+ (* see tests/nestseq for how neg bindings can come up even
+ without eg partial matches
+ (* negated substitution only allowed with negwits.
+ just dropped *)
+ if anynegwit wit && allnegwit wit (* nonempty negwit list *)
+ then prev
+ else
+ (print_generic_substitution l; Format.print_newline();
+ failwith"unexpected negative binding with positive witnesses")*)
+ | _ ->
+ let new_triple =
+ if unchecked or not_keep
+ then (s,newth,wit)
+ else
+ if anynegwit wit && allnegwit wit
+ then (s,newth,[A.NegWit(A.Wit(s,th_x,[],negtopos wit))])
+ else (s,newth,[A.Wit(s,th_x,[],wit)]) in
+ new_triple::prev)
+ [] trips in
+ if unchecked || !Flag_ctl.partial_match (* the only way to have a NegWit *)
+ then setify res
+ else List.rev res
+;;
+
+
+(* ---------------------------------------------------------------------- *)
+(* SAT - Model Checking Algorithm for CTL-FVex *)
+(* *)
+(* TODO: Implement _all_ operators (directly) *)
+(* ---------------------------------------------------------------------- *)
+
+
+(* ************************************* *)
+(* The SAT algorithm and special helpers *)
+(* ************************************* *)
+
+let rec pre_exist dir (grp,_,_) y reqst =
+ let check s =
+ match reqst with None -> true | Some reqst -> List.mem s reqst in
+ let exp (s,th,wit) =
+ concatmap
+ (fun s' -> if check s' then [(s',th,wit)] else [])
+ (match dir with
+ A.FORWARD -> G.predecessors grp s
+ | A.BACKWARD -> G.successors grp s) in
+ setify (concatmap exp y)
+;;
+
+exception Empty
+
+let pre_forall dir (grp,_,states) y all reqst =
+ let check s =
+ match reqst with
+ None -> true | Some reqst -> List.mem s reqst in
+ let pred =
+ match dir with
+ A.FORWARD -> G.predecessors | A.BACKWARD -> G.successors in
+ let succ =
+ match dir with
+ A.FORWARD -> G.successors | A.BACKWARD -> G.predecessors in
+ let neighbors =
+ List.map
+ (function p -> (p,succ grp p))
+ (setify
+ (concatmap
+ (function (s,_,_) -> List.filter check (pred grp s)) y)) in
+ (* would a hash table be more efficient? *)
+ let all = List.sort state_compare all in
+ let rec up_nodes child s = function
+ [] -> []
+ | (s1,th,wit)::xs ->
+ (match compare s1 child with
+ -1 -> up_nodes child s xs
+ | 0 -> (s,th,wit)::(up_nodes child s xs)
+ | _ -> []) in
+ let neighbor_triples =
+ List.fold_left
+ (function rest ->
+ function (s,children) ->
+ try
+ (List.map
+ (function child ->
+ match up_nodes child s all with [] -> raise Empty | l -> l)
+ children) :: rest
+ with Empty -> rest)
+ [] neighbors in
+ match neighbor_triples with
+ [] -> []
+ | _ ->
+ (*normalize*)
+ (foldl1 (@) (List.map (foldl1 triples_conj) neighbor_triples))
+
+let pre_forall_AW dir (grp,_,states) y all reqst =
+ let check s =
+ match reqst with
+ None -> true | Some reqst -> List.mem s reqst in
+ let pred =
+ match dir with
+ A.FORWARD -> G.predecessors | A.BACKWARD -> G.successors in
+ let succ =
+ match dir with
+ A.FORWARD -> G.successors | A.BACKWARD -> G.predecessors in
+ let neighbors =
+ List.map
+ (function p -> (p,succ grp p))
+ (setify
+ (concatmap
+ (function (s,_,_) -> List.filter check (pred grp s)) y)) in
+ (* would a hash table be more efficient? *)
+ let all = List.sort state_compare all in
+ let rec up_nodes child s = function
+ [] -> []
+ | (s1,th,wit)::xs ->
+ (match compare s1 child with
+ -1 -> up_nodes child s xs
+ | 0 -> (s,th,wit)::(up_nodes child s xs)
+ | _ -> []) in
+ let neighbor_triples =
+ List.fold_left
+ (function rest ->
+ function (s,children) ->
+ (List.map
+ (function child ->
+ match up_nodes child s all with [] -> raise AW | l -> l)
+ children) :: rest)
+ [] neighbors in
+ match neighbor_triples with
+ [] -> []
+ | _ -> foldl1 (@) (List.map (foldl1 triples_conj_AW) neighbor_triples)
+
+(* drop_negwits will call setify *)
+let satEX dir m s reqst = pre_exist dir m s reqst;;
+
+let satAX dir m s reqst = pre_forall dir m s s reqst
+;;
+
+(* E[phi1 U phi2] == phi2 \/ (phi1 /\ EXE[phi1 U phi2]) *)
+let satEU dir ((_,_,states) as m) s1 s2 reqst =
+ inc satEU_calls;
+ if s1 = []
+ then s2
+ else
+ (*let ctr = ref 0 in*)
+ if !pNEW_INFO_OPT
+ then
+ let rec f y new_info =
+ inc_step();
+ match new_info with
+ [] -> y
+ | new_info ->
+ ctr := !ctr + 1;
+ let first = triples_conj s1 (pre_exist dir m new_info reqst) in
+ let res = triples_union first y in
+ let new_info = setdiff res y in
+ (*Printf.printf "iter %d res %d new_info %d\n"
+ !ctr (List.length res) (List.length new_info);
+ flush stdout;*)
+ f res new_info in
+ f s2 s2
+ else
+ let f y =
+ inc_step();
+ let pre = pre_exist dir m y reqst in
+ triples_union s2 (triples_conj s1 pre) in
+ setfix f s2
+;;
+
+(* EF phi == E[true U phi] *)
+let satEF dir m s2 reqst =
+ inc satEF_calls;
+ (*let ctr = ref 0 in*)
+ if !pNEW_INFO_OPT
+ then
+ let rec f y new_info =
+ inc_step();
+ match new_info with
+ [] -> y
+ | new_info ->
+ (*ctr := !ctr + 1;
+ print_state (Printf.sprintf "iteration %d\n" !ctr) y;*)
+ let first = pre_exist dir m new_info reqst in
+ let res = triples_union first y in
+ let new_info = setdiff res y in
+ (*Printf.printf "EF %s iter %d res %d new_info %d\n"
+ (if dir = A.BACKWARD then "reachable" else "real ef")
+ !ctr (List.length res) (List.length new_info);
+ print_state "new info" new_info;
+ flush stdout;*)
+ f res new_info in
+ f s2 s2
+ else
+ let f y =
+ inc_step();
+ let pre = pre_exist dir m y reqst in
+ triples_union s2 pre in
+ setfix f s2
+
+
+type ('pred,'anno) auok =
+ AUok of ('pred,'anno) triples | AUfailed of ('pred,'anno) triples
+
+(* A[phi1 U phi2] == phi2 \/ (phi1 /\ AXA[phi1 U phi2]) *)
+let satAU dir ((cfg,_,states) as m) s1 s2 reqst =
+ inc satAU_calls;
+ if s1 = []
+ then AUok s2
+ else
+ (*let ctr = ref 0 in*)
+ let pre_forall =
+ if !Flag_ctl.loop_in_src_code
+ then pre_forall_AW
+ else pre_forall in
+ if !pNEW_INFO_OPT
+ then
+ let rec f y newinfo =
+ inc_step();
+ match newinfo with
+ [] -> AUok y
+ | new_info ->
+ (*ctr := !ctr + 1;
+ print_state (Printf.sprintf "iteration %d\n" !ctr) y;
+ flush stdout;*)
+ let pre =
+ try Some (pre_forall dir m new_info y reqst)
+ with AW -> None in
+ match pre with
+ None -> AUfailed y
+ | Some pre ->
+ match triples_conj s1 pre with
+ [] -> AUok y
+ | first ->
+ (*print_state "s1" s1;
+ print_state "pre" pre;
+ print_state "first" first;*)
+ let res = triples_union first y in
+ let new_info =
+ if not !something_dropped
+ then first
+ else setdiff res y in
+ (*Printf.printf
+ "iter %d res %d new_info %d\n"
+ !ctr (List.length res) (List.length new_info);
+ flush stdout;*)
+ f res new_info in
+ f s2 s2
+ else
+ if !Flag_ctl.loop_in_src_code
+ then AUfailed s2
+ else
+ (*let setfix =
+ fix (function s1 -> function s2 ->
+ let s1 = List.map (function (s,th,w) -> (s,th,nub w)) s1 in
+ let s2 = List.map (function (s,th,w) -> (s,th,nub w)) s2 in
+ subseteq s1 s2) in for popl *)
+ let f y =
+ inc_step();
+ let pre = pre_forall dir m y y reqst in
+ triples_union s2 (triples_conj s1 pre) in
+ AUok (setfix f s2)
+;;
+
+
+(* reqst could be the states of s1 *)
+ (*
+ let lstates = mkstates states reqst in
+ let initial_removed =
+ triples_complement lstates (triples_union s1 s2) in
+ let initial_base = triples_conj s1 (triples_complement lstates s2) in
+ let rec loop base removed =
+ let new_removed =
+ triples_conj base (pre_exist dir m removed reqst) in
+ let new_base =
+ triples_conj base (triples_complement lstates new_removed) in
+ if supseteq new_base base
+ then triples_union base s2
+ else loop new_base new_removed in
+ loop initial_base initial_removed *)
+
+let satAW dir ((grp,_,states) as m) s1 s2 reqst =
+ inc satAW_calls;
+ if s1 = []
+ then s2
+ else
+ (*
+ This works extremely badly when the region is small and the end of the
+ region is very ambiguous, eg free(x) ... x
+ see free.c
+ if !pNEW_INFO_OPT
+ then
+ let get_states l = setify(List.map (function (s,_,_) -> s) l) in
+ let ostates = Common.union_set (get_states s1) (get_states s2) in
+ let succ =
+ (match dir with
+ A.FORWARD -> G.successors grp
+ | A.BACKWARD -> G.predecessors grp) in
+ let states =
+ List.fold_left Common.union_set ostates (List.map succ ostates) in
+ let negphi = triples_complement states s1 in
+ let negpsi = triples_complement states s2 in
+ triples_complement ostates
+ (satEU dir m negpsi (triples_conj negphi negpsi) (Some ostates))
+ else
+ *)
+ (*let ctr = ref 0 in*)
+ let f y =
+ inc_step();
+ (*ctr := !ctr + 1;
+ Printf.printf "iter %d y %d\n" !ctr (List.length y);
+ print_state "y" y;
+ flush stdout;*)
+ let pre = pre_forall dir m y y reqst in
+ let conj = triples_conj s1 pre in (* or triples_conj_AW *)
+ triples_union s2 conj in
+ setgfix f (triples_union s1 s2)
+;;
+
+let satAF dir m s reqst =
+ inc satAF_calls;
+ if !pNEW_INFO_OPT
+ then
+ let rec f y newinfo =
+ inc_step();
+ match newinfo with
+ [] -> y
+ | new_info ->
+ let first = pre_forall dir m new_info y reqst in
+ let res = triples_union first y in
+ let new_info = setdiff res y in
+ f res new_info in
+ f s s
+ else
+ let f y =
+ inc_step();
+ let pre = pre_forall dir m y y reqst in
+ triples_union s pre in
+ setfix f s
+
+let satAG dir ((_,_,states) as m) s reqst =
+ inc satAG_calls;
+ let f y =
+ inc_step();
+ let pre = pre_forall dir m y y reqst in
+ triples_conj y pre in
+ setgfix f s
+
+let satEG dir ((_,_,states) as m) s reqst =
+ inc satEG_calls;
+ let f y =
+ inc_step();
+ let pre = pre_exist dir m y reqst in
+ triples_conj y pre in
+ setgfix f s
+
+(* **************************************************************** *)
+(* Inner And - a way of dealing with multiple matches within a node *)
+(* **************************************************************** *)
+(* applied to the result of matching a node. collect witnesses when the
+states and environments are the same *)
+
+let inner_and trips =
+ let rec loop = function
+ [] -> ([],[])
+ | (s,th,w)::trips ->
+ let (cur,acc) = loop trips in
+ (match cur with
+ (s',_,_)::_ when s = s' ->
+ let rec loop' = function
+ [] -> [(s,th,w)]
+ | ((_,th',w') as t')::ts' ->
+ (match conj_subst th th' with
+ Some th'' -> (s,th'',union_wit w w')::ts'
+ | None -> t'::(loop' ts')) in
+ (loop' cur,acc)
+ | _ -> ([(s,th,w)],cur@acc)) in
+ let (cur,acc) =
+ loop (List.sort state_compare trips) (* is this sort needed? *) in
+ cur@acc
+
+(* *************** *)
+(* Partial matches *)
+(* *************** *)
+
+let filter_conj states unwanted partial_matches =
+ let x =
+ triples_conj (triples_complement states (unwitify unwanted))
+ partial_matches in
+ triples_conj (unwitify x) (triples_complement states x)
+
+let strict_triples_conj strict states trips trips' =
+ let res = triples_conj trips trips' in
+ if !Flag_ctl.partial_match && strict = A.STRICT
+ then
+ let fail_left = filter_conj states trips trips' in
+ let fail_right = filter_conj states trips' trips in
+ let ors = triples_union fail_left fail_right in
+ triples_union res ors
+ else res
+
+let strict_triples_conj_none strict states trips trips' =
+ let res = triples_conj_none trips trips' in
+ if !Flag_ctl.partial_match && strict = A.STRICT
+ then
+ let fail_left = filter_conj states trips trips' in
+ let fail_right = filter_conj states trips' trips in
+ let ors = triples_union fail_left fail_right in
+ triples_union res ors
+ else res
+
+let left_strict_triples_conj strict states trips trips' =
+ let res = triples_conj trips trips' in
+ if !Flag_ctl.partial_match && strict = A.STRICT
+ then
+ let fail_left = filter_conj states trips trips' in
+ triples_union res fail_left
+ else res
+
+let strict_A1 strict op failop dir ((_,_,states) as m) trips required_states =
+ let res = op dir m trips required_states in
+ if !Flag_ctl.partial_match && strict = A.STRICT
+ then
+ let states = mkstates states required_states in
+ let fail = filter_conj states res (failop dir m trips required_states) in
+ triples_union res fail
+ else res
+
+let strict_A2 strict op failop dir ((_,_,states) as m) trips trips'
+ required_states =
+ let res = op dir m trips trips' required_states in
+ if !Flag_ctl.partial_match && strict = A.STRICT
+ then
+ let states = mkstates states required_states in
+ let fail = filter_conj states res (failop dir m trips' required_states) in
+ triples_union res fail
+ else res
+
+let strict_A2au strict op failop dir ((_,_,states) as m) trips trips'
+ required_states =
+ match op dir m trips trips' required_states with
+ AUok res ->
+ if !Flag_ctl.partial_match && strict = A.STRICT
+ then
+ let states = mkstates states required_states in
+ let fail =
+ filter_conj states res (failop dir m trips' required_states) in
+ AUok (triples_union res fail)
+ else AUok res
+ | AUfailed res -> AUfailed res
+
+(* ********************* *)
+(* Environment functions *)
+(* ********************* *)
+
+let drop_wits required_states s phi =
+ match required_states with
+ None -> s
+ | Some states -> List.filter (function (s,_,_) -> List.mem s states) s
+
+
+let print_required required =
+ List.iter
+ (function l ->
+ Format.print_string "{";
+ List.iter
+ (function reqd ->
+ print_generic_substitution reqd; Format.print_newline())
+ l;
+ Format.print_string "}";
+ Format.print_newline())
+ required
+
+exception Too_long
+
+let extend_required trips required =
+ if !Flag_ctl.partial_match
+ then required
+ else
+ if !pREQUIRED_ENV_OPT
+ then
+ (* make it a set *)
+ let envs =
+ List.fold_left
+ (function rest ->
+ function (_,t,_) -> if List.mem t rest then rest else t::rest)
+ [] trips in
+ let envs = if List.mem [] envs then [] else envs in
+ match (envs,required) with
+ ([],_) -> required
+ | (envs,hd::tl) ->
+ (try
+ let hdln = List.length hd + 5 (* let it grow a little bit *) in
+ let (_,merged) =
+ let add x (ln,y) =
+ if List.mem x y
+ then (ln,y)
+ else if ln + 1 > hdln then raise Too_long else (ln+1,x::y) in
+ foldl
+ (function rest ->
+ function t ->
+ foldl
+ (function rest ->
+ function r ->
+ match conj_subst t r with
+ None -> rest | Some th -> add th rest)
+ rest hd)
+ (0,[]) envs in
+ merged :: tl
+ with Too_long -> envs :: required)
+ | (envs,_) -> envs :: required
+ else required
+
+let drop_required v required =
+ if !pREQUIRED_ENV_OPT
+ then
+ let res =
+ inner_setify
+ (List.map
+ (function l ->
+ inner_setify
+ (List.map (List.filter (function sub -> not(dom_sub sub = v))) l))
+ required) in
+ (* check whether an entry has become useless *)
+ List.filter (function l -> not (List.exists (function x -> x = []) l)) res
+ else required
+
+(* no idea how to write this function ... *)
+let memo_label =
+ (Hashtbl.create(50) : (P.t, (G.node * substitution) list) Hashtbl.t)
+
+let satLabel label required p =
+ let triples =
+ if !pSATLABEL_MEMO_OPT
+ then
+ try
+ let states_subs = Hashtbl.find memo_label p in
+ List.map (function (st,th) -> (st,th,[])) states_subs
+ with
+ Not_found ->
+ let triples = setify(label p) in
+ Hashtbl.add memo_label p
+ (List.map (function (st,th,_) -> (st,th)) triples);
+ triples
+ else setify(label p) in
+ normalize
+ (if !pREQUIRED_ENV_OPT
+ then
+ foldl
+ (function rest ->
+ function ((s,th,_) as t) ->
+ if List.for_all
+ (List.exists (function th' -> not(conj_subst th th' = None)))
+ required
+ then t::rest
+ else rest)
+ [] triples
+ else triples)
+
+let get_required_states l =
+ if !pREQUIRED_STATES_OPT && not !Flag_ctl.partial_match
+ then
+ Some(inner_setify (List.map (function (s,_,_) -> s) l))
+ else None
+
+let get_children_required_states dir (grp,_,_) required_states =
+ if !pREQUIRED_STATES_OPT && not !Flag_ctl.partial_match
+ then
+ match required_states with
+ None -> None
+ | Some states ->
+ let fn =
+ match dir with
+ A.FORWARD -> G.successors
+ | A.BACKWARD -> G.predecessors in
+ Some (inner_setify (List.concat (List.map (fn grp) states)))
+ else None
+
+let reachable_table =
+ (Hashtbl.create(50) : (G.node * A.direction, G.node list) Hashtbl.t)
+
+(* like satEF, but specialized for get_reachable *)
+let reachsatEF dir (grp,_,_) s2 =
+ let dirop =
+ match dir with A.FORWARD -> G.successors | A.BACKWARD -> G.predecessors in
+ let union = unionBy compare (=) in
+ let rec f y = function
+ [] -> y
+ | new_info ->
+ let (pre_collected,new_info) =
+ List.partition (function Common.Left x -> true | _ -> false)
+ (List.map
+ (function x ->
+ try Common.Left (Hashtbl.find reachable_table (x,dir))
+ with Not_found -> Common.Right x)
+ new_info) in
+ let y =
+ List.fold_left
+ (function rest ->
+ function Common.Left x -> union x rest
+ | _ -> failwith "not possible")
+ y pre_collected in
+ let new_info =
+ List.map
+ (function Common.Right x -> x | _ -> failwith "not possible")
+ new_info in
+ let first = inner_setify (concatmap (dirop grp) new_info) in
+ let new_info = setdiff first y in
+ let res = new_info @ y in
+ f res new_info in
+ List.rev(f s2 s2) (* put root first *)
+
+let get_reachable dir m required_states =
+ match required_states with
+ None -> None
+ | Some states ->
+ Some
+ (List.fold_left
+ (function rest ->
+ function cur ->
+ if List.mem cur rest
+ then rest
+ else
+ Common.union_set
+ (try Hashtbl.find reachable_table (cur,dir)
+ with
+ Not_found ->
+ let states = reachsatEF dir m [cur] in
+ Hashtbl.add reachable_table (cur,dir) states;
+ states)
+ rest)
+ [] states)
+
+let ctr = ref 0
+let new_var _ =
+ let c = !ctr in
+ ctr := !ctr + 1;
+ Printf.sprintf "_c%d" c
+
+(* **************************** *)
+(* End of environment functions *)
+(* **************************** *)
+
+type ('code,'value) cell = Frozen of 'code | Thawed of 'value
+
+let rec satloop unchecked required required_states
+ ((grp,label,states) as m) phi env =
+ let rec loop unchecked required required_states phi =
+ (*Common.profile_code "satloop" (fun _ -> *)
+ let res =
+ match phi with
+ A.False -> []
+ | A.True -> triples_top states
+ | A.Pred(p) -> satLabel label required p
+ | A.Uncheck(phi1) ->
+ let unchecked = if !pUNCHECK_OPT then true else false in
+ loop unchecked required required_states phi1
+ | A.Not(phi) ->
+ let phires = loop unchecked required required_states phi in
+ (*let phires =
+ List.map (function (s,th,w) -> (s,th,[])) phires in*)
+ triples_complement (mkstates states required_states)
+ phires
+ | A.Or(phi1,phi2) ->
+ triples_union
+ (loop unchecked required required_states phi1)
+ (loop unchecked required required_states phi2)
+ | A.SeqOr(phi1,phi2) ->
+ let res1 = loop unchecked required required_states phi1 in
+ let res2 = loop unchecked required required_states phi2 in
+ let res1neg = unwitify res1 in
+ triples_union res1
+ (triples_conj
+ (triples_complement (mkstates states required_states) res1neg)
+ res2)
+ | A.And(strict,phi1,phi2) ->
+ (* phi1 is considered to be more likely to be [], because of the
+ definition of asttoctl. Could use heuristics such as the size of
+ the term *)
+ let pm = !Flag_ctl.partial_match in
+ (match (pm,loop unchecked required required_states phi1) with
+ (false,[]) when !pLazyOpt -> []
+ | (_,phi1res) ->
+ let new_required = extend_required phi1res required in
+ let new_required_states = get_required_states phi1res in
+ (match (pm,loop unchecked new_required new_required_states phi2)
+ with
+ (false,[]) when !pLazyOpt -> []
+ | (_,phi2res) ->
+ strict_triples_conj strict
+ (mkstates states required_states)
+ phi1res phi2res))
+ | A.AndAny(dir,strict,phi1,phi2) ->
+ (* phi2 can appear anywhere that is reachable *)
+ let pm = !Flag_ctl.partial_match in
+ (match (pm,loop unchecked required required_states phi1) with
+ (false,[]) -> []
+ | (_,phi1res) ->
+ let new_required = extend_required phi1res required in
+ let new_required_states = get_required_states phi1res in
+ let new_required_states =
+ get_reachable dir m new_required_states in
+ (match (pm,loop unchecked new_required new_required_states phi2)
+ with
+ (false,[]) -> phi1res
+ | (_,phi2res) ->
+ (match phi1res with
+ [] -> (* !Flag_ctl.partial_match must be true *)
+ if phi2res = []
+ then []
+ else
+ let s = mkstates states required_states in
+ List.fold_left
+ (function a -> function b ->
+ strict_triples_conj strict s a [b])
+ [List.hd phi2res] (List.tl phi2res)
+ | [(state,_,_)] ->
+ let phi2res =
+ List.map (function (s,e,w) -> [(state,e,w)]) phi2res in
+ let s = mkstates states required_states in
+ List.fold_left
+ (function a -> function b ->
+ strict_triples_conj strict s a b)
+ phi1res phi2res
+ | _ ->
+ failwith
+ "only one result allowed for the left arg of AndAny")))
+ | A.HackForStmt(dir,strict,phi1,phi2) ->
+ (* phi2 can appear anywhere that is reachable *)
+ let pm = !Flag_ctl.partial_match in
+ (match (pm,loop unchecked required required_states phi1) with
+ (false,[]) -> []
+ | (_,phi1res) ->
+ let new_required = extend_required phi1res required in
+ let new_required_states = get_required_states phi1res in
+ let new_required_states =
+ get_reachable dir m new_required_states in
+ (match (pm,loop unchecked new_required new_required_states phi2)
+ with
+ (false,[]) -> phi1res
+ | (_,phi2res) ->
+ (* if there is more than one state, something about the
+ environment has to ensure that the right triples of
+ phi2 get associated with the triples of phi1.
+ the asttoctl2 has to ensure that that is the case.
+ these should thus be structural properties.
+ env of phi2 has to be a proper subset of env of phi1
+ to ensure all end up being consistent. no new triples
+ should be generated. strict_triples_conj_none takes
+ care of this.
+ *)
+ let s = mkstates states required_states in
+ List.fold_left
+ (function acc ->
+ function (st,th,_) as phi2_elem ->
+ let inverse =
+ triples_complement [st] [(st,th,[])] in
+ strict_triples_conj_none strict s acc
+ (phi2_elem::inverse))
+ phi1res phi2res))
+ | A.InnerAnd(phi) ->
+ inner_and(loop unchecked required required_states phi)
+ | A.EX(dir,phi) ->
+ let new_required_states =
+ get_children_required_states dir m required_states in
+ satEX dir m (loop unchecked required new_required_states phi)
+ required_states
+ | A.AX(dir,strict,phi) ->
+ let new_required_states =
+ get_children_required_states dir m required_states in
+ let res = loop unchecked required new_required_states phi in
+ strict_A1 strict satAX satEX dir m res required_states
+ | A.EF(dir,phi) ->
+ let new_required_states = get_reachable dir m required_states in
+ satEF dir m (loop unchecked required new_required_states phi)
+ new_required_states
+ | A.AF(dir,strict,phi) ->
+ if !Flag_ctl.loop_in_src_code
+ then
+ loop unchecked required required_states
+ (A.AU(dir,strict,A.True,phi))
+ else
+ let new_required_states = get_reachable dir m required_states in
+ let res = loop unchecked required new_required_states phi in
+ strict_A1 strict satAF satEF dir m res new_required_states
+ | A.EG(dir,phi) ->
+ let new_required_states = get_reachable dir m required_states in
+ satEG dir m (loop unchecked required new_required_states phi)
+ new_required_states
+ | A.AG(dir,strict,phi) ->
+ let new_required_states = get_reachable dir m required_states in
+ let res = loop unchecked required new_required_states phi in
+ strict_A1 strict satAG satEF dir m res new_required_states
+ | A.EU(dir,phi1,phi2) ->
+ let new_required_states = get_reachable dir m required_states in
+ (match loop unchecked required new_required_states phi2 with
+ [] when !pLazyOpt -> []
+ | s2 ->
+ let new_required = extend_required s2 required in
+ let s1 = loop unchecked new_required new_required_states phi1 in
+ satEU dir m s1 s2 new_required_states)
+ | A.AW(dir,strict,phi1,phi2) ->
+ let new_required_states = get_reachable dir m required_states in
+ (match loop unchecked required new_required_states phi2 with
+ [] when !pLazyOpt -> []
+ | s2 ->
+ let new_required = extend_required s2 required in
+ let s1 = loop unchecked new_required new_required_states phi1 in
+ strict_A2 strict satAW satEF dir m s1 s2 new_required_states)
+ | A.AU(dir,strict,phi1,phi2) ->
+ (*Printf.printf "using AU\n"; flush stdout;*)
+ let new_required_states = get_reachable dir m required_states in
+ (match loop unchecked required new_required_states phi2 with
+ [] when !pLazyOpt -> []
+ | s2 ->
+ let new_required = extend_required s2 required in
+ let s1 = loop unchecked new_required new_required_states phi1 in
+ let res =
+ strict_A2au strict satAU satEF dir m s1 s2 new_required_states in
+ match res with
+ AUok res -> res
+ | AUfailed tmp_res ->
+ (* found a loop, have to try AW *)
+ (* the formula is
+ A[E[phi1 U phi2] & phi1 W phi2]
+ the and is nonstrict *)
+ (* tmp_res is bigger than s2, so perhaps closer to s1 *)
+ (*Printf.printf "using AW\n"; flush stdout;*)
+ let s1 =
+ triples_conj (satEU dir m s1 tmp_res new_required_states)
+ s1 in
+ strict_A2 strict satAW satEF dir m s1 s2 new_required_states)
+ | A.Implies(phi1,phi2) ->
+ loop unchecked required required_states (A.Or(A.Not phi1,phi2))
+ | A.Exists (keep,v,phi) ->
+ let new_required = drop_required v required in
+ triples_witness v unchecked (not keep)
+ (loop unchecked new_required required_states phi)
+ | A.Let(v,phi1,phi2) ->
+ (* should only be used when the properties unchecked, required,
+ and required_states are known to be the same or at least
+ compatible between all the uses. this is not checked. *)
+ let res = loop unchecked required required_states phi1 in
+ satloop unchecked required required_states m phi2 ((v,res) :: env)
+ | A.LetR(dir,v,phi1,phi2) ->
+ (* should only be used when the properties unchecked, required,
+ and required_states are known to be the same or at least
+ compatible between all the uses. this is not checked. *)
+ let new_required_states = get_reachable dir m required_states in
+ let res = loop unchecked required new_required_states phi1 in
+ satloop unchecked required required_states m phi2 ((v,res) :: env)
+ | A.Ref(v) ->
+ let res = List.assoc v env in
+ if unchecked
+ then List.map (function (s,th,_) -> (s,th,[])) res
+ else res
+ | A.XX(phi) -> failwith "should have been removed" in
+ if !Flag_ctl.bench > 0 then triples := !triples + (List.length res);
+ drop_wits required_states res phi (* ) *) in
+
+ loop unchecked required required_states phi
+;;
+
+
+(* SAT with tracking *)
+let rec sat_verbose_loop unchecked required required_states annot maxlvl lvl
+ ((_,label,states) as m) phi env =
+ let anno res children = (annot lvl phi res children,res) in
+ let satv unchecked required required_states phi0 env =
+ sat_verbose_loop unchecked required required_states annot maxlvl (lvl+1)
+ m phi0 env in
+ if (lvl > maxlvl) && (maxlvl > -1) then
+ anno (satloop unchecked required required_states m phi env) []
+ else
+ let (child,res) =
+ match phi with
+ A.False -> anno [] []
+ | A.True -> anno (triples_top states) []
+ | A.Pred(p) ->
+ Printf.printf "label\n"; flush stdout;
+ anno (satLabel label required p) []
+ | A.Uncheck(phi1) ->
+ let unchecked = if !pUNCHECK_OPT then true else false in
+ let (child1,res1) = satv unchecked required required_states phi1 env in
+ Printf.printf "uncheck\n"; flush stdout;
+ anno res1 [child1]
+ | A.Not(phi1) ->
+ let (child,res) =
+ satv unchecked required required_states phi1 env in
+ Printf.printf "not\n"; flush stdout;
+ anno (triples_complement (mkstates states required_states) res) [child]
+ | A.Or(phi1,phi2) ->
+ let (child1,res1) =
+ satv unchecked required required_states phi1 env in
+ let (child2,res2) =
+ satv unchecked required required_states phi2 env in
+ Printf.printf "or\n"; flush stdout;
+ anno (triples_union res1 res2) [child1; child2]
+ | A.SeqOr(phi1,phi2) ->
+ let (child1,res1) =
+ satv unchecked required required_states phi1 env in
+ let (child2,res2) =
+ satv unchecked required required_states phi2 env in
+ let res1neg =
+ List.map (function (s,th,_) -> (s,th,[])) res1 in
+ Printf.printf "seqor\n"; flush stdout;
+ anno (triples_union res1
+ (triples_conj
+ (triples_complement (mkstates states required_states)
+ res1neg)
+ res2))
+ [child1; child2]
+ | A.And(strict,phi1,phi2) ->
+ let pm = !Flag_ctl.partial_match in
+ (match (pm,satv unchecked required required_states phi1 env) with
+ (false,(child1,[])) ->
+ Printf.printf "and\n"; flush stdout; anno [] [child1]
+ | (_,(child1,res1)) ->
+ let new_required = extend_required res1 required in
+ let new_required_states = get_required_states res1 in
+ (match (pm,satv unchecked new_required new_required_states phi2
+ env) with
+ (false,(child2,[])) ->
+ Printf.printf "and\n"; flush stdout; anno [] [child1;child2]
+ | (_,(child2,res2)) ->
+ Printf.printf "and\n"; flush stdout;
+ let res =
+ strict_triples_conj strict
+ (mkstates states required_states)
+ res1 res2 in
+ anno res [child1; child2]))
+ | A.AndAny(dir,strict,phi1,phi2) ->
+ let pm = !Flag_ctl.partial_match in
+ (match (pm,satv unchecked required required_states phi1 env) with
+ (false,(child1,[])) ->
+ Printf.printf "and\n"; flush stdout; anno [] [child1]
+ | (_,(child1,res1)) ->
+ let new_required = extend_required res1 required in
+ let new_required_states = get_required_states res1 in
+ let new_required_states =
+ get_reachable dir m new_required_states in
+ (match (pm,satv unchecked new_required new_required_states phi2
+ env) with
+ (false,(child2,[])) ->
+ Printf.printf "andany\n"; flush stdout;
+ anno res1 [child1;child2]
+ | (_,(child2,res2)) ->
+ (match res1 with
+ [] -> (* !Flag_ctl.partial_match must be true *)
+ if res2 = []
+ then anno [] [child1; child2]
+ else
+ let res =
+ let s = mkstates states required_states in
+ List.fold_left
+ (function a -> function b ->
+ strict_triples_conj strict s a [b])
+ [List.hd res2] (List.tl res2) in
+ anno res [child1; child2]
+ | [(state,_,_)] ->
+ let res2 =
+ List.map (function (s,e,w) -> [(state,e,w)]) res2 in
+ Printf.printf "andany\n"; flush stdout;
+ let res =
+ let s = mkstates states required_states in
+ List.fold_left
+ (function a -> function b ->
+ strict_triples_conj strict s a b)
+ res1 res2 in
+ anno res [child1; child2]
+ | _ ->
+ failwith
+ "only one result allowed for the left arg of AndAny")))
+ | A.HackForStmt(dir,strict,phi1,phi2) ->
+ let pm = !Flag_ctl.partial_match in
+ (match (pm,satv unchecked required required_states phi1 env) with
+ (false,(child1,[])) ->
+ Printf.printf "and\n"; flush stdout; anno [] [child1]
+ | (_,(child1,res1)) ->
+ let new_required = extend_required res1 required in
+ let new_required_states = get_required_states res1 in
+ let new_required_states =
+ get_reachable dir m new_required_states in
+ (match (pm,satv unchecked new_required new_required_states phi2
+ env) with
+ (false,(child2,[])) ->
+ Printf.printf "andany\n"; flush stdout;
+ anno res1 [child1;child2]
+ | (_,(child2,res2)) ->
+ let res =
+ let s = mkstates states required_states in
+ List.fold_left
+ (function acc ->
+ function (st,th,_) as phi2_elem ->
+ let inverse =
+ triples_complement [st] [(st,th,[])] in
+ strict_triples_conj_none strict s acc
+ (phi2_elem::inverse))
+ res1 res2 in
+ anno res [child1; child2]))
+ | A.InnerAnd(phi1) ->
+ let (child1,res1) = satv unchecked required required_states phi1 env in
+ Printf.printf "uncheck\n"; flush stdout;
+ anno (inner_and res1) [child1]
+ | A.EX(dir,phi1) ->
+ let new_required_states =
+ get_children_required_states dir m required_states in
+ let (child,res) =
+ satv unchecked required new_required_states phi1 env in
+ Printf.printf "EX\n"; flush stdout;
+ anno (satEX dir m res required_states) [child]
+ | A.AX(dir,strict,phi1) ->
+ let new_required_states =
+ get_children_required_states dir m required_states in
+ let (child,res) =
+ satv unchecked required new_required_states phi1 env in
+ Printf.printf "AX\n"; flush stdout;
+ let res = strict_A1 strict satAX satEX dir m res required_states in
+ anno res [child]
+ | A.EF(dir,phi1) ->
+ let new_required_states = get_reachable dir m required_states in
+ let (child,res) =
+ satv unchecked required new_required_states phi1 env in
+ Printf.printf "EF\n"; flush stdout;
+ anno (satEF dir m res new_required_states) [child]
+ | A.AF(dir,strict,phi1) ->
+ if !Flag_ctl.loop_in_src_code
+ then
+ satv unchecked required required_states
+ (A.AU(dir,strict,A.True,phi1))
+ env
+ else
+ (let new_required_states = get_reachable dir m required_states in
+ let (child,res) =
+ satv unchecked required new_required_states phi1 env in
+ Printf.printf "AF\n"; flush stdout;
+ let res =
+ strict_A1 strict satAF satEF dir m res new_required_states in
+ anno res [child])
+ | A.EG(dir,phi1) ->
+ let new_required_states = get_reachable dir m required_states in
+ let (child,res) =
+ satv unchecked required new_required_states phi1 env in
+ Printf.printf "EG\n"; flush stdout;
+ anno (satEG dir m res new_required_states) [child]
+ | A.AG(dir,strict,phi1) ->
+ let new_required_states = get_reachable dir m required_states in
+ let (child,res) =
+ satv unchecked required new_required_states phi1 env in
+ Printf.printf "AG\n"; flush stdout;
+ let res = strict_A1 strict satAG satEF dir m res new_required_states in
+ anno res [child]
+
+ | A.EU(dir,phi1,phi2) ->
+ let new_required_states = get_reachable dir m required_states in
+ (match satv unchecked required new_required_states phi2 env with
+ (child2,[]) ->
+ Printf.printf "EU\n"; flush stdout;
+ anno [] [child2]
+ | (child2,res2) ->
+ let new_required = extend_required res2 required in
+ let (child1,res1) =
+ satv unchecked new_required new_required_states phi1 env in
+ Printf.printf "EU\n"; flush stdout;
+ anno (satEU dir m res1 res2 new_required_states) [child1; child2])
+ | A.AW(dir,strict,phi1,phi2) ->
+ failwith "should not be used" (*
+ let new_required_states = get_reachable dir m required_states in
+ (match satv unchecked required new_required_states phi2 env with
+ (child2,[]) ->
+ Printf.printf "AW %b\n" unchecked; flush stdout; anno [] [child2]
+ | (child2,res2) ->
+ let new_required = extend_required res2 required in
+ let (child1,res1) =
+ satv unchecked new_required new_required_states phi1 env in
+ Printf.printf "AW %b\n" unchecked; flush stdout;
+ let res =
+ strict_A2 strict satAW satEF dir m res1 res2
+ new_required_states in
+ anno res [child1; child2]) *)
+ | A.AU(dir,strict,phi1,phi2) ->
+ let new_required_states = get_reachable dir m required_states in
+ (match satv unchecked required new_required_states phi2 env with
+ (child2,[]) ->
+ Printf.printf "AU\n"; flush stdout; anno [] [child2]
+ | (child2,s2) ->
+ let new_required = extend_required s2 required in
+ let (child1,s1) =
+ satv unchecked new_required new_required_states phi1 env in
+ Printf.printf "AU\n"; flush stdout;
+ let res =
+ strict_A2au strict satAU satEF dir m s1 s2 new_required_states in
+ (match res with
+ AUok res ->
+ anno res [child1; child2]
+ | AUfailed tmp_res ->
+ (* found a loop, have to try AW *)
+ (* the formula is
+ A[E[phi1 U phi2] & phi1 W phi2]
+ the and is nonstrict *)
+ (* tmp_res is bigger than s2, so perhaps closer to s1 *)
+ Printf.printf "AW\n"; flush stdout;
+ let s1 =
+ triples_conj (satEU dir m s1 tmp_res new_required_states) s1 in
+ let res =
+ strict_A2 strict satAW satEF dir m s1 s2 new_required_states in
+ anno res [child1; child2]))
+ | A.Implies(phi1,phi2) ->
+ satv unchecked required required_states
+ (A.Or(A.Not phi1,phi2))
+ env
+ | A.Exists (keep,v,phi1) ->
+ let new_required = drop_required v required in
+ let (child,res) =
+ satv unchecked new_required required_states phi1 env in
+ Printf.printf "exists\n"; flush stdout;
+ anno (triples_witness v unchecked (not keep) res) [child]
+ | A.Let(v,phi1,phi2) ->
+ let (child1,res1) =
+ satv unchecked required required_states phi1 env in
+ let (child2,res2) =
+ satv unchecked required required_states phi2 ((v,res1) :: env) in
+ anno res2 [child1;child2]
+ | A.LetR(dir,v,phi1,phi2) ->
+ let new_required_states = get_reachable dir m required_states in
+ let (child1,res1) =
+ satv unchecked required new_required_states phi1 env in
+ let (child2,res2) =
+ satv unchecked required required_states phi2 ((v,res1) :: env) in
+ anno res2 [child1;child2]
+ | A.Ref(v) ->
+ Printf.printf "Ref\n"; flush stdout;
+ let res = List.assoc v env in
+ let res =
+ if unchecked
+ then List.map (function (s,th,_) -> (s,th,[])) res
+ else res in
+ anno res []
+ | A.XX(phi) -> failwith "should have been removed" in
+ let res1 = drop_wits required_states res phi in
+ if not(res1 = res)
+ then
+ begin
+ print_required_states required_states;
+ print_state "after drop_wits" res1 end;
+ (child,res1)
+
+;;
+
+let sat_verbose annotate maxlvl lvl m phi =
+ sat_verbose_loop false [] None annotate maxlvl lvl m phi []
+
+(* Type for annotations collected in a tree *)
+type ('a) witAnnoTree = WitAnno of ('a * ('a witAnnoTree) list);;
+
+let sat_annotree annotate m phi =
+ let tree_anno l phi res chld = WitAnno(annotate l phi res,chld) in
+ sat_verbose_loop false [] None tree_anno (-1) 0 m phi []
+;;
+
+(*
+let sat m phi = satloop m phi []
+;;
+*)
+
+let simpleanno l phi res =
+ let pp s =
+ Format.print_string ("\n" ^ s ^ "\n------------------------------\n");
+ print_generic_algo (List.sort compare res);
+ Format.print_string "\n------------------------------\n\n" in
+ let pp_dir = function
+ A.FORWARD -> ()
+ | A.BACKWARD -> pp "^" in
+ match phi with
+ | A.False -> pp "False"
+ | A.True -> pp "True"
+ | A.Pred(p) -> pp ("Pred" ^ (Common.dump p))
+ | A.Not(phi) -> pp "Not"
+ | A.Exists(_,v,phi) -> pp ("Exists " ^ (Common.dump(v)))
+ | A.And(_,phi1,phi2) -> pp "And"
+ | A.AndAny(dir,_,phi1,phi2) -> pp "AndAny"
+ | A.HackForStmt(dir,_,phi1,phi2) -> pp "HackForStmt"
+ | A.Or(phi1,phi2) -> pp "Or"
+ | A.SeqOr(phi1,phi2) -> pp "SeqOr"
+ | A.Implies(phi1,phi2) -> pp "Implies"
+ | A.AF(dir,_,phi1) -> pp "AF"; pp_dir dir
+ | A.AX(dir,_,phi1) -> pp "AX"; pp_dir dir
+ | A.AG(dir,_,phi1) -> pp "AG"; pp_dir dir
+ | A.AW(dir,_,phi1,phi2)-> pp "AW"; pp_dir dir
+ | A.AU(dir,_,phi1,phi2)-> pp "AU"; pp_dir dir
+ | A.EF(dir,phi1) -> pp "EF"; pp_dir dir
+ | A.EX(dir,phi1) -> pp "EX"; pp_dir dir
+ | A.EG(dir,phi1) -> pp "EG"; pp_dir dir
+ | A.EU(dir,phi1,phi2) -> pp "EU"; pp_dir dir
+ | A.Let (x,phi1,phi2) -> pp ("Let"^" "^x)
+ | A.LetR (dir,x,phi1,phi2) -> pp ("LetR"^" "^x); pp_dir dir
+ | A.Ref(s) -> pp ("Ref("^s^")")
+ | A.Uncheck(s) -> pp "Uncheck"
+ | A.InnerAnd(s) -> pp "InnerAnd"
+ | A.XX(phi1) -> pp "XX"
+;;
+
+
+(* pad: Rene, you can now use the module pretty_print_ctl.ml to
+ print a ctl formula more accurately if you want.
+ Use the print_xxx provided in the different module to call
+ Pretty_print_ctl.pp_ctl.
+ *)
+
+let simpleanno2 l phi res =
+ begin
+ Pretty_print_ctl.pp_ctl (P.print_predicate, SUB.print_mvar) false phi;
+ Format.print_newline ();
+ Format.print_string "----------------------------------------------------";
+ Format.print_newline ();
+ print_generic_algo (List.sort compare res);
+ Format.print_newline ();
+ Format.print_string "----------------------------------------------------";
+ Format.print_newline ();
+ Format.print_newline ();
+ end
+
+
+(* ---------------------------------------------------------------------- *)
+(* Benchmarking *)
+(* ---------------------------------------------------------------------- *)
+
+type optentry = bool ref * string
+type options = {label : optentry; unch : optentry;
+ conj : optentry; compl1 : optentry; compl2 : optentry;
+ newinfo : optentry;
+ reqenv : optentry; reqstates : optentry}
+
+let options =
+ {label = (pSATLABEL_MEMO_OPT,"satlabel_memo_opt");
+ unch = (pUNCHECK_OPT,"uncheck_opt");
+ conj = (pTRIPLES_CONJ_OPT,"triples_conj_opt");
+ compl1 = (pTRIPLES_COMPLEMENT_OPT,"triples_complement_opt");
+ compl2 = (pTRIPLES_COMPLEMENT_SIMPLE_OPT,"triples_complement_simple_opt");
+ newinfo = (pNEW_INFO_OPT,"new_info_opt");
+ reqenv = (pREQUIRED_ENV_OPT,"required_env_opt");
+ reqstates = (pREQUIRED_STATES_OPT,"required_states_opt")}
+
+let baseline =
+ [("none ",[]);
+ ("label ",[options.label]);
+ ("unch ",[options.unch]);
+ ("unch and label ",[options.label;options.unch])]
+
+let conjneg =
+ [("conj ", [options.conj]);
+ ("compl1 ", [options.compl1]);
+ ("compl12 ", [options.compl1;options.compl2]);
+ ("conj/compl12 ", [options.conj;options.compl1;options.compl2]);
+ ("conj unch satl ", [options.conj;options.unch;options.label]);
+(*
+ ("compl1 unch satl ", [options.compl1;options.unch;options.label]);
+ ("compl12 unch satl ",
+ [options.compl1;options.compl2;options.unch;options.label]); *)
+ ("conj/compl12 unch satl ",
+ [options.conj;options.compl1;options.compl2;options.unch;options.label])]
+
+let path =
+ [("newinfo ", [options.newinfo]);
+ ("newinfo unch satl ", [options.newinfo;options.unch;options.label])]
+
+let required =
+ [("reqenv ", [options.reqenv]);
+ ("reqstates ", [options.reqstates]);
+ ("reqenv/states ", [options.reqenv;options.reqstates]);
+(* ("reqenv unch satl ", [options.reqenv;options.unch;options.label]);
+ ("reqstates unch satl ",
+ [options.reqstates;options.unch;options.label]);*)
+ ("reqenv/states unch satl ",
+ [options.reqenv;options.reqstates;options.unch;options.label])]
+
+let all_options =
+ [options.label;options.unch;options.conj;options.compl1;options.compl2;
+ options.newinfo;options.reqenv;options.reqstates]
+
+let all =
+ [("all ",all_options)]
+
+let all_options_but_path =
+ [options.label;options.unch;options.conj;options.compl1;options.compl2;
+ options.reqenv;options.reqstates]
+
+let all_but_path = ("all but path ",all_options_but_path)
+
+let counters =
+ [(satAW_calls, "satAW", ref 0);
+ (satAU_calls, "satAU", ref 0);
+ (satEF_calls, "satEF", ref 0);
+ (satAF_calls, "satAF", ref 0);
+ (satEG_calls, "satEG", ref 0);
+ (satAG_calls, "satAG", ref 0);
+ (satEU_calls, "satEU", ref 0)]
+
+let perms =
+ map
+ (function (opt,x) ->
+ (opt,x,ref 0.0,ref 0,
+ List.map (function _ -> (ref 0, ref 0, ref 0)) counters))
+ [List.hd all;all_but_path]
+ (*(all@baseline@conjneg@path@required)*)
+
+exception Out
+
+let rec iter fn = function
+ 1 -> fn()
+ | n -> let _ = fn() in
+ (Hashtbl.clear reachable_table;
+ Hashtbl.clear memo_label;
+ triples := 0;
+ iter fn (n-1))
+
+let copy_to_stderr fl =
+ let i = open_in fl in
+ let rec loop _ =
+ Printf.fprintf stderr "%s\n" (input_line i);
+ loop() in
+ try loop() with _ -> ();
+ close_in i
+
+let bench_sat (_,_,states) fn =
+ List.iter (function (opt,_) -> opt := false) all_options;
+ let answers =
+ concatmap
+ (function (name,options,time,trips,counter_info) ->
+ let iterct = !Flag_ctl.bench in
+ if !time > float_of_int timeout then time := -100.0;
+ if not (!time = -100.0)
+ then
+ begin
+ Hashtbl.clear reachable_table;
+ Hashtbl.clear memo_label;
+ List.iter (function (opt,_) -> opt := true) options;
+ List.iter (function (calls,_,save_calls) -> save_calls := !calls)
+ counters;
+ triples := 0;
+ let res =
+ let bef = Sys.time() in
+ try
+ Common.timeout_function timeout
+ (fun () ->
+ let bef = Sys.time() in
+ let res = iter fn iterct in
+ let aft = Sys.time() in
+ time := !time +. (aft -. bef);
+ trips := !trips + !triples;
+ List.iter2
+ (function (calls,_,save_calls) ->
+ function (current_calls,current_cfg,current_max_cfg) ->
+ current_calls :=
+ !current_calls + (!calls - !save_calls);
+ if (!calls - !save_calls) > 0
+ then
+ (let st = List.length states in
+ current_cfg := !current_cfg + st;
+ if st > !current_max_cfg
+ then current_max_cfg := st))
+ counters counter_info;
+ [res])
+ with
+ Common.Timeout ->
+ begin
+ let aft = Sys.time() in
+ time := -100.0;
+ Printf.fprintf stderr "Timeout at %f on: %s\n"
+ (aft -. bef) name;
+ []
+ end in
+ List.iter (function (opt,_) -> opt := false) options;
+ res
+ end
+ else [])
+ perms in
+ Printf.fprintf stderr "\n";
+ match answers with
+ [] -> []
+ | res::rest ->
+ (if not(List.for_all (function x -> x = res) rest)
+ then
+ (List.iter (print_state "a state") answers;
+ Printf.printf "something doesn't work\n");
+ res)
+
+let print_bench _ =
+ let iterct = !Flag_ctl.bench in
+ if iterct > 0
+ then
+ (List.iter
+ (function (name,options,time,trips,counter_info) ->
+ Printf.fprintf stderr "%s Numbers: %f %d "
+ name (!time /. (float_of_int iterct)) !trips;
+ List.iter
+ (function (calls,cfg,max_cfg) ->
+ Printf.fprintf stderr "%d %d %d " (!calls / iterct) !cfg !max_cfg)
+ counter_info;
+ Printf.fprintf stderr "\n")
+ perms)
+
+(* ---------------------------------------------------------------------- *)
+(* preprocessing: ignore irrelevant functions *)
+
+let preprocess (cfg,_,_) label = function
+ [] -> true (* no information, try everything *)
+ | l ->
+ let sz = G.size cfg in
+ let verbose_output pred = function
+ [] ->
+ Printf.printf "did not find:\n";
+ P.print_predicate pred; Format.print_newline()
+ | _ ->
+ Printf.printf "found:\n";
+ P.print_predicate pred; Format.print_newline();
+ Printf.printf "but it was not enough\n" in
+ let get_any verbose x =
+ let res =
+ try Hashtbl.find memo_label x
+ with
+ Not_found ->
+ (let triples = label x in
+ let filtered =
+ List.map (function (st,th,_) -> (st,th)) triples in
+ Hashtbl.add memo_label x filtered;
+ filtered) in
+ if verbose then verbose_output x res;
+ not([] = res) in
+ let get_all l =
+ (* don't bother testing when there are more patterns than nodes *)
+ if List.length l > sz-2
+ then false
+ else List.for_all (get_any false) l in
+ if List.exists get_all l
+ then true
+ else
+ (if !Flag_ctl.verbose_match
+ then
+ List.iter (List.iter (function x -> let _ = get_any true x in ()))
+ l;
+ false)
+
+let filter_partial_matches trips =
+ if !Flag_ctl.partial_match
+ then
+ let anynegwit = (* if any is neg, then all are *)
+ List.exists (function A.NegWit _ -> true | A.Wit _ -> false) in
+ let (bad,good) =
+ List.partition (function (s,th,wit) -> anynegwit wit) trips in
+ (match bad with
+ [] -> ()
+ | _ -> print_state "partial matches" bad; Format.print_newline());
+ good
+ else trips
+
+(* ---------------------------------------------------------------------- *)
+(* Main entry point for engine *)
+let sat m phi reqopt =
+ try
+ (match !Flag_ctl.steps with
+ None -> step_count := 0
+ | Some x -> step_count := x);
+ Hashtbl.clear reachable_table;
+ Hashtbl.clear memo_label;
+ let (x,label,states) = m in
+ if (!Flag_ctl.bench > 0) or (preprocess m label reqopt)
+ then
+ ((* to drop when Yoann initialized this flag *)
+ if List.exists (G.extract_is_loop x) states
+ then Flag_ctl.loop_in_src_code := true;
+ let m = (x,label,List.sort compare states) in
+ let res =
+ if(!Flag_ctl.verbose_ctl_engine)
+ then
+ let fn _ = snd (sat_annotree simpleanno2 m phi) in
+ if !Flag_ctl.bench > 0
+ then bench_sat m fn
+ else fn()
+ else
+ let fn _ = satloop false [] None m phi [] in
+ if !Flag_ctl.bench > 0
+ then bench_sat m fn
+ else Common.profile_code "ctl" (fun _ -> fn()) in
+ let res = filter_partial_matches res in
+ (*
+ Printf.printf "steps: start %d, stop %d\n"
+ (match !Flag_ctl.steps with Some x -> x | _ -> 0)
+ !step_count;
+ Printf.printf "triples: %d\n" !triples;
+ print_state "final result" res;
+ *)
+ res)
+ else
+ (if !Flag_ctl.verbose_ctl_engine
+ then Common.pr2 "missing something required";
+ [])
+ with Steps -> []
+;;
+
+(* ********************************************************************** *)
+(* End of Module: CTL_ENGINE *)
+(* ********************************************************************** *)
+end
+;;
+
--- /dev/null
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+*
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+*
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
+*
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+(*external c_counter : unit -> int = "c_counter"*)
+let timeout = 800
+(* Optimize triples_conj by first extracting the intersection of the two sets,
+which can certainly be in the intersection *)
+let pTRIPLES_CONJ_OPT = ref true
+(* For complement, make NegState for the negation of a single state *)
+let pTRIPLES_COMPLEMENT_OPT = ref true
+(* For complement, do something special for the case where the environment
+and witnesses are empty *)
+let pTRIPLES_COMPLEMENT_SIMPLE_OPT = ref true
+(* "Double negate" the arguments of the path operators *)
+let pDOUBLE_NEGATE_OPT = ref true
+(* Only do pre_forall/pre_exists on new elements in fixpoint iteration *)
+let pNEW_INFO_OPT = ref true
+(* Filter the result of the label function to drop entries that aren't
+compatible with any of the available environments *)
+let pREQUIRED_ENV_OPT = ref true
+(* Memoize the raw result of the label function *)
+let pSATLABEL_MEMO_OPT = ref true
+(* Filter results according to the required states *)
+let pREQUIRED_STATES_OPT = ref true
+(* Drop negative witnesses at Uncheck *)
+let pUNCHECK_OPT = ref true
+let pANY_NEG_OPT = ref true
+let pLazyOpt = ref true
+
+(*
+let pTRIPLES_CONJ_OPT = ref false
+let pTRIPLES_COMPLEMENT_OPT = ref false
+let pTRIPLES_COMPLEMENT_SIMPLE_OPT = ref false
+let pDOUBLE_NEGATE_OPT = ref false
+let pNEW_INFO_OPT = ref false
+let pREQUIRED_ENV_OPT = ref false
+let pSATLABEL_MEMO_OPT = ref false
+let pREQUIRED_STATES_OPT = ref false
+let pUNCHECK_OPT = ref false
+let pANY_NEG_OPT = ref false
+let pLazyOpt = ref false
+*)
+
+
+let step_count = ref 0
+exception Steps
+let inc_step _ =
+ if not (!step_count = 0)
+ then
+ begin
+ step_count := !step_count - 1;
+ if !step_count = 0 then raise Steps
+ end
+
+let inc cell = cell := !cell + 1
+
+let satEU_calls = ref 0
+let satAW_calls = ref 0
+let satAU_calls = ref 0
+let satEF_calls = ref 0
+let satAF_calls = ref 0
+let satEG_calls = ref 0
+let satAG_calls = ref 0
+
+let triples = ref 0
+
+let ctr = ref 0
+let new_let _ =
+ let c = !ctr in
+ ctr := c + 1;
+ Printf.sprintf "_fresh_r_%d" c
+
+(* **********************************************************************
+ *
+ * Implementation of a Witness Tree model checking engine for CTL-FVex
+ *
+ *
+ * **********************************************************************)
+
+(* ********************************************************************** *)
+(* Module: SUBST (substitutions: meta. vars and values) *)
+(* ********************************************************************** *)
+
+module type SUBST =
+ sig
+ type value
+ type mvar
+ val eq_mvar: mvar -> mvar -> bool
+ val eq_val: value -> value -> bool
+ val merge_val: value -> value -> value
+ val print_mvar : mvar -> unit
+ val print_value : value -> unit
+ end
+;;
+
+(* ********************************************************************** *)
+(* Module: GRAPH (control flow graphs / model) *)
+(* ********************************************************************** *)
+
+module type GRAPH =
+ sig
+ type node
+ type cfg
+ val predecessors: cfg -> node -> node list
+ val successors: cfg -> node -> node list
+ val extract_is_loop : cfg -> node -> bool
+ val print_node : node -> unit
+ val size : cfg -> int
+ end
+;;
+
+module OGRAPHEXT_GRAPH =
+ struct
+ type node = int;;
+ type cfg = (string,unit) Ograph_extended.ograph_mutable;;
+ let predecessors cfg n = List.map fst ((cfg#predecessors n)#tolist);;
+ let print_node i = Format.print_string (Common.i_to_s i)
+ end
+;;
+
+(* ********************************************************************** *)
+(* Module: PREDICATE (predicates for CTL formulae) *)
+(* ********************************************************************** *)
+
+module type PREDICATE =
+sig
+ type t
+ val print_predicate : t -> unit
+end
+
+
+(* ********************************************************************** *)
+
+(* ---------------------------------------------------------------------- *)
+(* Misc. useful generic functions *)
+(* ---------------------------------------------------------------------- *)
+
+let head = List.hd
+
+let tail l =
+ match l with
+ [] -> []
+ | (x::xs) -> xs
+;;
+
+let foldl = List.fold_left;;
+
+let foldl1 f xs = foldl f (head xs) (tail xs)
+
+type 'a esc = ESC of 'a | CONT of 'a
+
+let foldr = List.fold_right;;
+
+let concat = List.concat;;
+
+let map = List.map;;
+
+let filter = List.filter;;
+
+let partition = List.partition;;
+
+let concatmap f l = List.concat (List.map f l);;
+
+let maybe f g opt =
+ match opt with
+ | None -> g
+ | Some x -> f x
+;;
+
+let some_map f opts = map (maybe (fun x -> Some (f x)) None) opts
+
+let some_tolist_alt opts = concatmap (maybe (fun x -> [x]) []) opts
+
+let rec some_tolist opts =
+ match opts with
+ | [] -> []
+ | (Some x)::rest -> x::(some_tolist rest)
+ | _::rest -> some_tolist rest
+;;
+
+let rec groupBy eq l =
+ match l with
+ [] -> []
+ | (x::xs) ->
+ let (xs1,xs2) = partition (fun x' -> eq x x') xs in
+ (x::xs1)::(groupBy eq xs2)
+;;
+
+let group l = groupBy (=) l;;
+
+let rec memBy eq x l =
+ match l with
+ [] -> false
+ | (y::ys) -> if (eq x y) then true else (memBy eq x ys)
+;;
+
+let rec nubBy eq ls =
+ match ls with
+ [] -> []
+ | (x::xs) when (memBy eq x xs) -> nubBy eq xs
+ | (x::xs) -> x::(nubBy eq xs)
+;;
+
+let rec nub ls =
+ match ls with
+ [] -> []
+ | (x::xs) when (List.mem x xs) -> nub xs
+ | (x::xs) -> x::(nub xs)
+;;
+
+let state_compare (s1,_,_) (s2,_,_) = compare s1 s2
+
+let setifyBy eq xs = nubBy eq xs;;
+
+let setify xs = nub xs;;
+
+let inner_setify xs = List.sort compare (nub xs);;
+
+let unionBy compare eq xs = function
+ [] -> xs
+ | ys ->
+ let rec loop = function
+ [] -> ys
+ | x::xs -> if memBy eq x ys then loop xs else x::(loop xs) in
+ List.sort compare (loop xs)
+;;
+
+let union xs ys = unionBy state_compare (=) xs ys;;
+
+let setdiff xs ys = filter (fun x -> not (List.mem x ys)) xs;;
+
+let subseteqBy eq xs ys = List.for_all (fun x -> memBy eq x ys) xs;;
+
+let subseteq xs ys = List.for_all (fun x -> List.mem x ys) xs;;
+let supseteq xs ys = subseteq ys xs
+
+let setequalBy eq xs ys = (subseteqBy eq xs ys) & (subseteqBy eq ys xs);;
+
+let setequal xs ys = (subseteq xs ys) & (subseteq ys xs);;
+
+(* Fix point calculation *)
+let rec fix eq f x =
+ let x' = f x in if (eq x' x) then x' else fix eq f x'
+;;
+
+(* Fix point calculation on set-valued functions *)
+let setfix f x = (fix subseteq f x) (*if new is a subset of old, stop*)
+let setgfix f x = (fix supseteq f x) (*if new is a supset of old, stop*)
+
+let get_states l = nub (List.map (function (s,_,_) -> s) l)
+
+(* ********************************************************************** *)
+(* Module: CTL_ENGINE *)
+(* ********************************************************************** *)
+
+module CTL_ENGINE =
+ functor (SUB : SUBST) ->
+ functor (G : GRAPH) ->
+ functor (P : PREDICATE) ->
+struct
+
+module A = Ast_ctl
+
+type substitution = (SUB.mvar, SUB.value) Ast_ctl.generic_substitution
+
+type ('pred,'anno) witness =
+ (G.node, substitution,
+ ('pred, SUB.mvar, 'anno) Ast_ctl.generic_ctl list)
+ Ast_ctl.generic_witnesstree
+
+type ('pred,'anno) triples =
+ (G.node * substitution * ('pred,'anno) witness list) list
+
+(* ---------------------------------------------------------------------- *)
+(* Pretty printing functions *)
+(* ---------------------------------------------------------------------- *)
+
+let (print_generic_substitution : substitution -> unit) = fun substxs ->
+ let print_generic_subst = function
+ A.Subst (mvar, v) ->
+ SUB.print_mvar mvar; Format.print_string " --> "; SUB.print_value v
+ | A.NegSubst (mvar, v) ->
+ SUB.print_mvar mvar; Format.print_string " -/-> "; SUB.print_value v in
+ Format.print_string "[";
+ Common.print_between (fun () -> Format.print_string ";" )
+ print_generic_subst substxs;
+ Format.print_string "]"
+
+let rec (print_generic_witness: ('pred, 'anno) witness -> unit) =
+ function
+ | A.Wit (state, subst, anno, childrens) ->
+ Format.print_string "wit ";
+ G.print_node state;
+ print_generic_substitution subst;
+ (match childrens with
+ [] -> Format.print_string "{}"
+ | _ ->
+ Format.force_newline(); Format.print_string " "; Format.open_box 0;
+ print_generic_witnesstree childrens; Format.close_box())
+ | A.NegWit(wit) ->
+ Format.print_string "!";
+ print_generic_witness wit
+
+and (print_generic_witnesstree: ('pred,'anno) witness list -> unit) =
+ fun witnesstree ->
+ Format.open_box 1;
+ Format.print_string "{";
+ Common.print_between
+ (fun () -> Format.print_string ";"; Format.force_newline() )
+ print_generic_witness witnesstree;
+ Format.print_string "}";
+ Format.close_box()
+
+and print_generic_triple (node,subst,tree) =
+ G.print_node node;
+ print_generic_substitution subst;
+ print_generic_witnesstree tree
+
+and (print_generic_algo : ('pred,'anno) triples -> unit) = fun xs ->
+ Format.print_string "<";
+ Common.print_between
+ (fun () -> Format.print_string ";"; Format.force_newline())
+ print_generic_triple xs;
+ Format.print_string ">"
+;;
+
+let print_state (str : string) (l : ('pred,'anno) triples) =
+ Printf.printf "%s\n" str;
+ List.iter (function x ->
+ print_generic_triple x; Format.print_newline(); flush stdout)
+ (List.sort compare l);
+ Printf.printf "\n"
+
+let print_required_states = function
+ None -> Printf.printf "no required states\n"
+ | Some states ->
+ Printf.printf "required states: ";
+ List.iter
+ (function x ->
+ G.print_node x; Format.print_string " "; Format.print_flush())
+ states;
+ Printf.printf "\n"
+
+let mkstates states = function
+ None -> states
+ | Some states -> states
+
+(* ---------------------------------------------------------------------- *)
+(* *)
+(* ---------------------------------------------------------------------- *)
+
+
+(* ************************* *)
+(* Substitutions *)
+(* ************************* *)
+
+let dom_sub sub =
+ match sub with
+ | A.Subst(x,_) -> x
+ | A.NegSubst(x,_) -> x
+;;
+
+let ran_sub sub =
+ match sub with
+ | A.Subst(_,x) -> x
+ | A.NegSubst(_,x) -> x
+;;
+
+let eq_subBy eqx eqv sub sub' =
+ match (sub,sub') with
+ | (A.Subst(x,v),A.Subst(x',v')) -> (eqx x x') && (eqv v v')
+ | (A.NegSubst(x,v),A.NegSubst(x',v')) -> (eqx x x') && (eqv v v')
+ | _ -> false
+;;
+
+(* NOTE: functor *)
+let eq_sub sub sub' = eq_subBy SUB.eq_mvar SUB.eq_val sub sub'
+
+let eq_subst th th' = setequalBy eq_sub th th';;
+
+let merge_subBy eqx (===) (>+<) sub sub' =
+ (* variable part is guaranteed to be the same *)
+ match (sub,sub') with
+ (A.Subst (x,v),A.Subst (x',v')) ->
+ if (v === v')
+ then Some [A.Subst(x, v >+< v')]
+ else None
+ | (A.NegSubst(x,v),A.Subst(x',v')) ->
+ if (not (v === v'))
+ then Some [A.Subst(x',v')]
+ else None
+ | (A.Subst(x,v),A.NegSubst(x',v')) ->
+ if (not (v === v'))
+ then Some [A.Subst(x,v)]
+ else None
+ | (A.NegSubst(x,v),A.NegSubst(x',v')) ->
+ if (v === v')
+ then
+ let merged = v >+< v' in
+ if merged = v && merged = v'
+ then Some [A.NegSubst(x,v >+< v')]
+ else
+ (* positions are compatible, but not identical. keep apart. *)
+ Some [A.NegSubst(x,v);A.NegSubst(x',v')]
+ else Some [A.NegSubst(x,v);A.NegSubst(x',v')]
+;;
+
+(* NOTE: functor *)
+let merge_sub sub sub' =
+ merge_subBy SUB.eq_mvar SUB.eq_val SUB.merge_val sub sub'
+
+let clean_substBy eq cmp theta = List.sort cmp (nubBy eq theta);;
+
+(* NOTE: we sort by using the generic "compare" on (meta-)variable
+ * names; we could also require a definition of compare for meta-variables
+ * or substitutions but that seems like overkill for sorting
+ *)
+let clean_subst theta =
+ let res =
+ clean_substBy eq_sub
+ (fun s s' ->
+ let res = compare (dom_sub s) (dom_sub s') in
+ if res = 0
+ then
+ match (s,s') with
+ (A.Subst(_,_),A.NegSubst(_,_)) -> -1
+ | (A.NegSubst(_,_),A.Subst(_,_)) -> 1
+ | _ -> compare (ran_sub s) (ran_sub s')
+ else res)
+ theta in
+ let rec loop = function
+ [] -> []
+ | (A.Subst(x,v)::A.NegSubst(y,v')::rest) when SUB.eq_mvar x y ->
+ loop (A.Subst(x,v)::rest)
+ | x::xs -> x::(loop xs) in
+ loop res
+
+let top_subst = [];; (* Always TRUE subst. *)
+
+(* Split a theta in two parts: one with (only) "x" and one without *)
+(* NOTE: functor *)
+let split_subst theta x =
+ partition (fun sub -> SUB.eq_mvar (dom_sub sub) x) theta;;
+
+exception SUBST_MISMATCH
+let conj_subst theta theta' =
+ match (theta,theta') with
+ | ([],_) -> Some theta'
+ | (_,[]) -> Some theta
+ | _ ->
+ let rec classify = function
+ [] -> []
+ | [x] -> [(dom_sub x,[x])]
+ | x::xs ->
+ (match classify xs with
+ ((nm,y)::ys) as res ->
+ if dom_sub x = nm
+ then (nm,x::y)::ys
+ else (dom_sub x,[x])::res
+ | _ -> failwith "not possible") in
+ let merge_all theta theta' =
+ foldl
+ (function rest ->
+ function sub ->
+ foldl
+ (function rest ->
+ function sub' ->
+ match (merge_sub sub sub') with
+ Some subs -> subs @ rest
+ | _ -> raise SUBST_MISMATCH)
+ rest theta')
+ [] theta in
+ let rec loop = function
+ ([],ctheta') ->
+ List.concat (List.map (function (_,ths) -> ths) ctheta')
+ | (ctheta,[]) ->
+ List.concat (List.map (function (_,ths) -> ths) ctheta)
+ | ((x,ths)::xs,(y,ths')::ys) ->
+ (match compare x y with
+ 0 -> (merge_all ths ths') @ loop (xs,ys)
+ | -1 -> ths @ loop (xs,((y,ths')::ys))
+ | 1 -> ths' @ loop (((x,ths)::xs),ys)
+ | _ -> failwith "not possible") in
+ try Some (clean_subst(loop (classify theta, classify theta')))
+ with SUBST_MISMATCH -> None
+;;
+
+(* theta' must be a subset of theta *)
+let conj_subst_none theta theta' =
+ match (theta,theta') with
+ | (_,[]) -> Some theta
+ | ([],_) -> None
+ | _ ->
+ let rec classify = function
+ [] -> []
+ | [x] -> [(dom_sub x,[x])]
+ | x::xs ->
+ (match classify xs with
+ ((nm,y)::ys) as res ->
+ if dom_sub x = nm
+ then (nm,x::y)::ys
+ else (dom_sub x,[x])::res
+ | _ -> failwith "not possible") in
+ let merge_all theta theta' =
+ foldl
+ (function rest ->
+ function sub ->
+ foldl
+ (function rest ->
+ function sub' ->
+ match (merge_sub sub sub') with
+ Some subs -> subs @ rest
+ | _ -> raise SUBST_MISMATCH)
+ rest theta')
+ [] theta in
+ let rec loop = function
+ (ctheta,[]) ->
+ List.concat (List.map (function (_,ths) -> ths) ctheta)
+ | ([],ctheta') -> raise SUBST_MISMATCH
+ | ((x,ths)::xs,(y,ths')::ys) ->
+ (match compare x y with
+ 0 -> (merge_all ths ths') @ loop (xs,ys)
+ | -1 -> ths @ loop (xs,((y,ths')::ys))
+ | 1 -> raise SUBST_MISMATCH
+ | _ -> failwith "not possible") in
+ try Some (clean_subst(loop (classify theta, classify theta')))
+ with SUBST_MISMATCH -> None
+;;
+
+let negate_sub sub =
+ match sub with
+ | A.Subst(x,v) -> A.NegSubst (x,v)
+ | A.NegSubst(x,v) -> A.Subst(x,v)
+;;
+
+(* Turn a (big) theta into a list of (small) thetas *)
+let negate_subst theta = (map (fun sub -> [negate_sub sub]) theta);;
+
+
+(* ************************* *)
+(* Witnesses *)
+(* ************************* *)
+
+(* Always TRUE witness *)
+let top_wit = ([] : (('pred, 'anno) witness list));;
+
+let eq_wit wit wit' = wit = wit';;
+
+let union_wit wit wit' = (*List.sort compare (wit' @ wit) for popl*)
+ let res = unionBy compare (=) wit wit' in
+ let anynegwit = (* if any is neg, then all are *)
+ List.exists (function A.NegWit _ -> true | A.Wit _ -> false) in
+ if anynegwit res
+ then List.filter (function A.NegWit _ -> true | A.Wit _ -> false) res
+ else res
+
+let negate_wit wit = A.NegWit wit (*
+ match wit with
+ | A.Wit(s,th,anno,ws) -> A.NegWitWit(s,th,anno,ws)
+ | A.NegWitWit(s,th,anno,ws) -> A.Wit(s,th,anno,ws)*)
+;;
+
+let negate_wits wits =
+ List.sort compare (map (fun wit -> [negate_wit wit]) wits);;
+
+let unwitify trips =
+ let anynegwit = (* if any is neg, then all are *)
+ List.exists (function A.NegWit _ -> true | A.Wit _ -> false) in
+ setify
+ (List.fold_left
+ (function prev ->
+ function (s,th,wit) ->
+ if anynegwit wit then prev else (s,th,top_wit)::prev)
+ [] trips)
+
+(* ************************* *)
+(* Triples *)
+(* ************************* *)
+
+(* Triples are equal when the constituents are equal *)
+let eq_trip (s,th,wit) (s',th',wit') =
+ (s = s') && (eq_wit wit wit') && (eq_subst th th');;
+
+let triples_top states = map (fun s -> (s,top_subst,top_wit)) states;;
+
+let normalize trips =
+ List.map
+ (function (st,th,wit) -> (st,List.sort compare th,List.sort compare wit))
+ trips
+
+
+(* conj opt doesn't work ((1,[],{{x=3}}) v (1,[],{{x=4}})) & (1,[],{{x=4}}) =
+(1,[],{{x=3},{x=4}}), not (1,[],{{x=4}}) *)
+let triples_conj trips trips' =
+ let (trips,shared,trips') =
+ if false && !pTRIPLES_CONJ_OPT (* see comment above *)
+ then
+ let (shared,trips) =
+ List.partition (function t -> List.mem t trips') trips in
+ let trips' =
+ List.filter (function t -> not(List.mem t shared)) trips' in
+ (trips,shared,trips')
+ else (trips,[],trips') in
+ foldl (* returns a set - setify inlined *)
+ (function rest ->
+ function (s1,th1,wit1) ->
+ foldl
+ (function rest ->
+ function (s2,th2,wit2) ->
+ if (s1 = s2) then
+ (match (conj_subst th1 th2) with
+ Some th ->
+ let t = (s1,th,union_wit wit1 wit2) in
+ if List.mem t rest then rest else t::rest
+ | _ -> rest)
+ else rest)
+ rest trips')
+ shared trips
+;;
+
+(* ignore the state in the right argument. always pretend it is the same as
+the left one *)
+(* env on right has to be a subset of env on left *)
+let triples_conj_none trips trips' =
+ let (trips,shared,trips') =
+ if false && !pTRIPLES_CONJ_OPT (* see comment above *)
+ then
+ let (shared,trips) =
+ List.partition (function t -> List.mem t trips') trips in
+ let trips' =
+ List.filter (function t -> not(List.mem t shared)) trips' in
+ (trips,shared,trips')
+ else (trips,[],trips') in
+ foldl (* returns a set - setify inlined *)
+ (function rest ->
+ function (s1,th1,wit1) ->
+ foldl
+ (function rest ->
+ function (s2,th2,wit2) ->
+ match (conj_subst_none th1 th2) with
+ Some th ->
+ let t = (s1,th,union_wit wit1 wit2) in
+ if List.mem t rest then rest else t::rest
+ | _ -> rest)
+ rest trips')
+ shared trips
+;;
+
+exception AW
+
+let triples_conj_AW trips trips' =
+ let (trips,shared,trips') =
+ if false && !pTRIPLES_CONJ_OPT
+ then
+ let (shared,trips) =
+ List.partition (function t -> List.mem t trips') trips in
+ let trips' =
+ List.filter (function t -> not(List.mem t shared)) trips' in
+ (trips,shared,trips')
+ else (trips,[],trips') in
+ foldl (* returns a set - setify inlined *)
+ (function rest ->
+ function (s1,th1,wit1) ->
+ foldl
+ (function rest ->
+ function (s2,th2,wit2) ->
+ if (s1 = s2) then
+ (match (conj_subst th1 th2) with
+ Some th ->
+ let t = (s1,th,union_wit wit1 wit2) in
+ if List.mem t rest then rest else t::rest
+ | _ -> raise AW)
+ else rest)
+ rest trips')
+ shared trips
+;;
+
+(* *************************** *)
+(* NEGATION (NegState style) *)
+(* *************************** *)
+
+(* Constructive negation at the state level *)
+type ('a) state =
+ PosState of 'a
+ | NegState of 'a list
+;;
+
+let compatible_states = function
+ (PosState s1, PosState s2) ->
+ if s1 = s2 then Some (PosState s1) else None
+ | (PosState s1, NegState s2) ->
+ if List.mem s1 s2 then None else Some (PosState s1)
+ | (NegState s1, PosState s2) ->
+ if List.mem s2 s1 then None else Some (PosState s2)
+ | (NegState s1, NegState s2) -> Some (NegState (s1 @ s2))
+;;
+
+(* Conjunction on triples with "special states" *)
+let triples_state_conj trips trips' =
+ let (trips,shared,trips') =
+ if !pTRIPLES_CONJ_OPT
+ then
+ let (shared,trips) =
+ List.partition (function t -> List.mem t trips') trips in
+ let trips' =
+ List.filter (function t -> not(List.mem t shared)) trips' in
+ (trips,shared,trips')
+ else (trips,[],trips') in
+ foldl
+ (function rest ->
+ function (s1,th1,wit1) ->
+ foldl
+ (function rest ->
+ function (s2,th2,wit2) ->
+ match compatible_states(s1,s2) with
+ Some s ->
+ (match (conj_subst th1 th2) with
+ Some th ->
+ let t = (s,th,union_wit wit1 wit2) in
+ if List.mem t rest then rest else t::rest
+ | _ -> rest)
+ | _ -> rest)
+ rest trips')
+ shared trips
+;;
+
+let triple_negate (s,th,wits) =
+ let negstates = (NegState [s],top_subst,top_wit) in
+ let negths = map (fun th -> (PosState s,th,top_wit)) (negate_subst th) in
+ let negwits = map (fun nwit -> (PosState s,th,nwit)) (negate_wits wits) in
+ negstates :: (negths @ negwits) (* all different *)
+
+(* FIX ME: it is not necessary to do full conjunction *)
+let triples_complement states (trips : ('pred, 'anno) triples) =
+ if !pTRIPLES_COMPLEMENT_OPT
+ then
+ (let cleanup (s,th,wit) =
+ match s with
+ PosState s' -> [(s',th,wit)]
+ | NegState ss ->
+ assert (th=top_subst);
+ assert (wit=top_wit);
+ map (fun st -> (st,top_subst,top_wit)) (setdiff states ss) in
+ let (simple,complex) =
+ if !pTRIPLES_COMPLEMENT_SIMPLE_OPT
+ then
+ let (simple,complex) =
+ List.partition (function (s,[],[]) -> true | _ -> false) trips in
+ let simple =
+ [(NegState(List.map (function (s,_,_) -> s) simple),
+ top_subst,top_wit)] in
+ (simple,complex)
+ else ([(NegState [],top_subst,top_wit)],trips) in
+ let rec compl trips =
+ match trips with
+ [] -> simple
+ | (t::ts) -> triples_state_conj (triple_negate t) (compl ts) in
+ let compld = (compl complex) in
+ let compld = concatmap cleanup compld in
+ compld)
+ else
+ let negstates (st,th,wits) =
+ map (function st -> (st,top_subst,top_wit)) (setdiff states [st]) in
+ let negths (st,th,wits) =
+ map (function th -> (st,th,top_wit)) (negate_subst th) in
+ let negwits (st,th,wits) =
+ map (function nwit -> (st,th,nwit)) (negate_wits wits) in
+ match trips with
+ [] -> map (function st -> (st,top_subst,top_wit)) states
+ | x::xs ->
+ setify
+ (foldl
+ (function prev ->
+ function cur ->
+ triples_conj (negstates cur @ negths cur @ negwits cur) prev)
+ (negstates x @ negths x @ negwits x) xs)
+;;
+
+let triple_negate (s,th,wits) =
+ let negths = map (fun th -> (s,th,top_wit)) (negate_subst th) in
+ let negwits = map (fun nwit -> (s,th,nwit)) (negate_wits wits) in
+ ([s], negths @ negwits) (* all different *)
+
+let print_compl_state str (n,p) =
+ Printf.printf "%s neg: " str;
+ List.iter
+ (function x -> G.print_node x; Format.print_flush(); Printf.printf " ")
+ n;
+ Printf.printf "\n";
+ print_state "pos" p
+
+let triples_complement states (trips : ('pred, 'anno) triples) =
+ if trips = []
+ then map (function st -> (st,top_subst,top_wit)) states
+ else
+ let cleanup (neg,pos) =
+ let keep_pos =
+ List.filter (function (s,_,_) -> List.mem s neg) pos in
+ (map (fun st -> (st,top_subst,top_wit)) (setdiff states neg)) @
+ keep_pos in
+ let trips = List.sort state_compare trips in
+ let all_negated = List.map triple_negate trips in
+ let merge_one (neg1,pos1) (neg2,pos2) =
+ let (pos1conj,pos1keep) =
+ List.partition (function (s,_,_) -> List.mem s neg2) pos1 in
+ let (pos2conj,pos2keep) =
+ List.partition (function (s,_,_) -> List.mem s neg1) pos2 in
+ (Common.union_set neg1 neg2,
+ (triples_conj pos1conj pos2conj) @ pos1keep @ pos2keep) in
+ let rec inner_loop = function
+ x1::x2::rest -> (merge_one x1 x2) :: (inner_loop rest)
+ | l -> l in
+ let rec outer_loop = function
+ [x] -> x
+ | l -> outer_loop (inner_loop l) in
+ cleanup (outer_loop all_negated)
+
+(* ********************************** *)
+(* END OF NEGATION (NegState style) *)
+(* ********************************** *)
+
+(* now this is always true, so we could get rid of it *)
+let something_dropped = ref true
+
+let triples_union trips trips' =
+ (*unionBy compare eq_trip trips trips';;*)
+ (* returns -1 is t1 > t2, 1 if t2 >= t1, and 0 otherwise *)
+(*
+The following does not work. Suppose we have ([x->3],{A}) and ([],{A,B}).
+Then, the following says that since the first is a more restrictive
+environment and has fewer witnesses, then it should be dropped. But having
+fewer witnesses is not necessarily less informative than having more,
+because fewer witnesses can mean the absence of the witness-causing thing.
+So the fewer witnesses have to be kept around.
+subseteq changed to = to make it hopefully work
+*)
+ if !pNEW_INFO_OPT
+ then
+ begin
+ something_dropped := false;
+ if trips = trips'
+ then (something_dropped := true; trips)
+ else
+ let subsumes (s1,th1,wit1) (s2,th2,wit2) =
+ if s1 = s2
+ then
+ (match conj_subst th1 th2 with
+ Some conj ->
+ if conj = th1
+ then if (*subseteq*) wit1 = wit2 then 1 else 0
+ else
+ if conj = th2
+ then if (*subseteq*) wit2 = wit1 then (-1) else 0
+ else 0
+ | None -> 0)
+ else 0 in
+ let rec first_loop second = function
+ [] -> second
+ | x::xs -> first_loop (second_loop x second) xs
+ and second_loop x = function
+ [] -> [x]
+ | (y::ys) as all ->
+ match subsumes x y with
+ 1 -> something_dropped := true; all
+ | (-1) -> second_loop x ys
+ | _ -> y::(second_loop x ys) in
+ first_loop trips trips'
+ end
+ else unionBy compare eq_trip trips trips'
+
+
+let triples_witness x unchecked not_keep trips =
+ let anyneg = (* if any is neg, then all are *)
+ List.exists (function A.NegSubst _ -> true | A.Subst _ -> false) in
+ let anynegwit = (* if any is neg, then all are *)
+ List.exists (function A.NegWit _ -> true | A.Wit _ -> false) in
+ let allnegwit = (* if any is neg, then all are *)
+ List.for_all (function A.NegWit _ -> true | A.Wit _ -> false) in
+ let negtopos =
+ List.map (function A.NegWit w -> w | A.Wit _ -> failwith "bad wit")in
+ let res =
+ List.fold_left
+ (function prev ->
+ function (s,th,wit) as t ->
+ let (th_x,newth) = split_subst th x in
+ match th_x with
+ [] ->
+ (* one consider whether if not not_keep is true, then we should
+ fail. but it could be that the variable is a used_after and
+ then it is the later rule that should fail and not this one *)
+ if not not_keep && !Flag_ctl.verbose_ctl_engine
+ then
+ (SUB.print_mvar x; Format.print_flush();
+ print_state ": empty witness from" [t]);
+ t::prev
+ | l when anyneg l && !pANY_NEG_OPT -> prev
+ (* see tests/nestseq for how neg bindings can come up even
+ without eg partial matches
+ (* negated substitution only allowed with negwits.
+ just dropped *)
+ if anynegwit wit && allnegwit wit (* nonempty negwit list *)
+ then prev
+ else
+ (print_generic_substitution l; Format.print_newline();
+ failwith"unexpected negative binding with positive witnesses")*)
+ | _ ->
+ let new_triple =
+ if unchecked or not_keep
+ then (s,newth,wit)
+ else
+ if anynegwit wit && allnegwit wit
+ then (s,newth,[A.NegWit(A.Wit(s,th_x,[],negtopos wit))])
+ else (s,newth,[A.Wit(s,th_x,[],wit)]) in
+ new_triple::prev)
+ [] trips in
+ if unchecked || !Flag_ctl.partial_match (* the only way to have a NegWit *)
+ then setify res
+ else List.rev res
+;;
+
+
+(* ---------------------------------------------------------------------- *)
+(* SAT - Model Checking Algorithm for CTL-FVex *)
+(* *)
+(* TODO: Implement _all_ operators (directly) *)
+(* ---------------------------------------------------------------------- *)
+
+
+(* ************************************* *)
+(* The SAT algorithm and special helpers *)
+(* ************************************* *)
+
+let rec pre_exist dir (grp,_,_) y reqst =
+ let check s =
+ match reqst with None -> true | Some reqst -> List.mem s reqst in
+ let exp (s,th,wit) =
+ concatmap
+ (fun s' -> if check s' then [(s',th,wit)] else [])
+ (match dir with
+ A.FORWARD -> G.predecessors grp s
+ | A.BACKWARD -> G.successors grp s) in
+ setify (concatmap exp y)
+;;
+
+exception Empty
+
+let pre_forall dir (grp,_,states) y all reqst =
+ let check s =
+ match reqst with
+ None -> true | Some reqst -> List.mem s reqst in
+ let pred =
+ match dir with
+ A.FORWARD -> G.predecessors | A.BACKWARD -> G.successors in
+ let succ =
+ match dir with
+ A.FORWARD -> G.successors | A.BACKWARD -> G.predecessors in
+ let neighbors =
+ List.map
+ (function p -> (p,succ grp p))
+ (setify
+ (concatmap
+ (function (s,_,_) -> List.filter check (pred grp s)) y)) in
+ (* would a hash table be more efficient? *)
+ let all = List.sort state_compare all in
+ let rec up_nodes child s = function
+ [] -> []
+ | (s1,th,wit)::xs ->
+ (match compare s1 child with
+ -1 -> up_nodes child s xs
+ | 0 -> (s,th,wit)::(up_nodes child s xs)
+ | _ -> []) in
+ let neighbor_triples =
+ List.fold_left
+ (function rest ->
+ function (s,children) ->
+ try
+ (List.map
+ (function child ->
+ match up_nodes child s all with [] -> raise Empty | l -> l)
+ children) :: rest
+ with Empty -> rest)
+ [] neighbors in
+ match neighbor_triples with
+ [] -> []
+ | _ ->
+ (*normalize*)
+ (foldl1 (@) (List.map (foldl1 triples_conj) neighbor_triples))
+
+let pre_forall_AW dir (grp,_,states) y all reqst =
+ let check s =
+ match reqst with
+ None -> true | Some reqst -> List.mem s reqst in
+ let pred =
+ match dir with
+ A.FORWARD -> G.predecessors | A.BACKWARD -> G.successors in
+ let succ =
+ match dir with
+ A.FORWARD -> G.successors | A.BACKWARD -> G.predecessors in
+ let neighbors =
+ List.map
+ (function p -> (p,succ grp p))
+ (setify
+ (concatmap
+ (function (s,_,_) -> List.filter check (pred grp s)) y)) in
+ (* would a hash table be more efficient? *)
+ let all = List.sort state_compare all in
+ let rec up_nodes child s = function
+ [] -> []
+ | (s1,th,wit)::xs ->
+ (match compare s1 child with
+ -1 -> up_nodes child s xs
+ | 0 -> (s,th,wit)::(up_nodes child s xs)
+ | _ -> []) in
+ let neighbor_triples =
+ List.fold_left
+ (function rest ->
+ function (s,children) ->
+ (List.map
+ (function child ->
+ match up_nodes child s all with [] -> raise AW | l -> l)
+ children) :: rest)
+ [] neighbors in
+ match neighbor_triples with
+ [] -> []
+ | _ -> foldl1 (@) (List.map (foldl1 triples_conj_AW) neighbor_triples)
+
+(* drop_negwits will call setify *)
+let satEX dir m s reqst = pre_exist dir m s reqst;;
+
+let satAX dir m s reqst = pre_forall dir m s s reqst
+;;
+
+(* E[phi1 U phi2] == phi2 \/ (phi1 /\ EXE[phi1 U phi2]) *)
+let satEU dir ((_,_,states) as m) s1 s2 reqst =
+ inc satEU_calls;
+ if s1 = []
+ then s2
+ else
+ (*let ctr = ref 0 in*)
+ if !pNEW_INFO_OPT
+ then
+ let rec f y new_info =
+ inc_step();
+ match new_info with
+ [] -> y
+ | new_info ->
+ ctr := !ctr + 1;
+ let first = triples_conj s1 (pre_exist dir m new_info reqst) in
+ let res = triples_union first y in
+ let new_info = setdiff res y in
+ (*Printf.printf "iter %d res %d new_info %d\n"
+ !ctr (List.length res) (List.length new_info);
+ flush stdout;*)
+ f res new_info in
+ f s2 s2
+ else
+ let f y =
+ inc_step();
+ let pre = pre_exist dir m y reqst in
+ triples_union s2 (triples_conj s1 pre) in
+ setfix f s2
+;;
+
+(* EF phi == E[true U phi] *)
+let satEF dir m s2 reqst =
+ inc satEF_calls;
+ (*let ctr = ref 0 in*)
+ if !pNEW_INFO_OPT
+ then
+ let rec f y new_info =
+ inc_step();
+ match new_info with
+ [] -> y
+ | new_info ->
+ (*ctr := !ctr + 1;
+ print_state (Printf.sprintf "iteration %d\n" !ctr) y;*)
+ let first = pre_exist dir m new_info reqst in
+ let res = triples_union first y in
+ let new_info = setdiff res y in
+ (*Printf.printf "EF %s iter %d res %d new_info %d\n"
+ (if dir = A.BACKWARD then "reachable" else "real ef")
+ !ctr (List.length res) (List.length new_info);
+ print_state "new info" new_info;
+ flush stdout;*)
+ f res new_info in
+ f s2 s2
+ else
+ let f y =
+ inc_step();
+ let pre = pre_exist dir m y reqst in
+ triples_union s2 pre in
+ setfix f s2
+
+
+type ('pred,'anno) auok =
+ AUok of ('pred,'anno) triples | AUfailed of ('pred,'anno) triples
+
+(* A[phi1 U phi2] == phi2 \/ (phi1 /\ AXA[phi1 U phi2]) *)
+let satAU dir ((cfg,_,states) as m) s1 s2 reqst =
+ inc satAU_calls;
+ if s1 = []
+ then AUok s2
+ else
+ (*let ctr = ref 0 in*)
+ let pre_forall =
+ if !Flag_ctl.loop_in_src_code
+ then pre_forall_AW
+ else pre_forall in
+ if !pNEW_INFO_OPT
+ then
+ let rec f y newinfo =
+ inc_step();
+ match newinfo with
+ [] -> AUok y
+ | new_info ->
+ (*ctr := !ctr + 1;
+ print_state (Printf.sprintf "iteration %d\n" !ctr) y;
+ flush stdout;*)
+ let pre =
+ try Some (pre_forall dir m new_info y reqst)
+ with AW -> None in
+ match pre with
+ None -> AUfailed y
+ | Some pre ->
+ match triples_conj s1 pre with
+ [] -> AUok y
+ | first ->
+ (*print_state "s1" s1;
+ print_state "pre" pre;
+ print_state "first" first;*)
+ let res = triples_union first y in
+ let new_info =
+ if not !something_dropped
+ then first
+ else setdiff res y in
+ (*Printf.printf
+ "iter %d res %d new_info %d\n"
+ !ctr (List.length res) (List.length new_info);
+ flush stdout;*)
+ f res new_info in
+ f s2 s2
+ else
+ if !Flag_ctl.loop_in_src_code
+ then AUfailed s2
+ else
+ (*let setfix =
+ fix (function s1 -> function s2 ->
+ let s1 = List.map (function (s,th,w) -> (s,th,nub w)) s1 in
+ let s2 = List.map (function (s,th,w) -> (s,th,nub w)) s2 in
+ subseteq s1 s2) in for popl *)
+ let f y =
+ inc_step();
+ let pre = pre_forall dir m y y reqst in
+ triples_union s2 (triples_conj s1 pre) in
+ AUok (setfix f s2)
+;;
+
+
+(* reqst could be the states of s1 *)
+ (*
+ let lstates = mkstates states reqst in
+ let initial_removed =
+ triples_complement lstates (triples_union s1 s2) in
+ let initial_base = triples_conj s1 (triples_complement lstates s2) in
+ let rec loop base removed =
+ let new_removed =
+ triples_conj base (pre_exist dir m removed reqst) in
+ let new_base =
+ triples_conj base (triples_complement lstates new_removed) in
+ if supseteq new_base base
+ then triples_union base s2
+ else loop new_base new_removed in
+ loop initial_base initial_removed *)
+
+let satAW dir ((grp,_,states) as m) s1 s2 reqst =
+ inc satAW_calls;
+ if s1 = []
+ then s2
+ else
+ (*
+ This works extremely badly when the region is small and the end of the
+ region is very ambiguous, eg free(x) ... x
+ see free.c
+ if !pNEW_INFO_OPT
+ then
+ let get_states l = setify(List.map (function (s,_,_) -> s) l) in
+ let ostates = Common.union_set (get_states s1) (get_states s2) in
+ let succ =
+ (match dir with
+ A.FORWARD -> G.successors grp
+ | A.BACKWARD -> G.predecessors grp) in
+ let states =
+ List.fold_left Common.union_set ostates (List.map succ ostates) in
+ let negphi = triples_complement states s1 in
+ let negpsi = triples_complement states s2 in
+ triples_complement ostates
+ (satEU dir m negpsi (triples_conj negphi negpsi) (Some ostates))
+ else
+ *)
+ (*let ctr = ref 0 in*)
+ let f y =
+ inc_step();
+ (*ctr := !ctr + 1;
+ Printf.printf "iter %d y %d\n" !ctr (List.length y);
+ print_state "y" y;
+ flush stdout;*)
+ let pre = pre_forall dir m y y reqst in
+ let conj = triples_conj s1 pre in (* or triples_conj_AW *)
+ triples_union s2 conj in
+ setgfix f (triples_union s1 s2)
+;;
+
+let satAF dir m s reqst =
+ inc satAF_calls;
+ if !pNEW_INFO_OPT
+ then
+ let rec f y newinfo =
+ inc_step();
+ match newinfo with
+ [] -> y
+ | new_info ->
+ let first = pre_forall dir m new_info y reqst in
+ let res = triples_union first y in
+ let new_info = setdiff res y in
+ f res new_info in
+ f s s
+ else
+ let f y =
+ inc_step();
+ let pre = pre_forall dir m y y reqst in
+ triples_union s pre in
+ setfix f s
+
+let satAG dir ((_,_,states) as m) s reqst =
+ inc satAG_calls;
+ let f y =
+ inc_step();
+ let pre = pre_forall dir m y y reqst in
+ triples_conj y pre in
+ setgfix f s
+
+let satEG dir ((_,_,states) as m) s reqst =
+ inc satEG_calls;
+ let f y =
+ inc_step();
+ let pre = pre_exist dir m y reqst in
+ triples_conj y pre in
+ setgfix f s
+
+(* **************************************************************** *)
+(* Inner And - a way of dealing with multiple matches within a node *)
+(* **************************************************************** *)
+(* applied to the result of matching a node. collect witnesses when the
+states and environments are the same *)
+
+let inner_and trips =
+ let rec loop = function
+ [] -> ([],[])
+ | (s,th,w)::trips ->
+ let (cur,acc) = loop trips in
+ (match cur with
+ (s',_,_)::_ when s = s' ->
+ let rec loop' = function
+ [] -> [(s,th,w)]
+ | ((_,th',w') as t')::ts' ->
+ (match conj_subst th th' with
+ Some th'' -> (s,th'',union_wit w w')::ts'
+ | None -> t'::(loop' ts')) in
+ (loop' cur,acc)
+ | _ -> ([(s,th,w)],cur@acc)) in
+ let (cur,acc) =
+ loop (List.sort state_compare trips) (* is this sort needed? *) in
+ cur@acc
+
+(* *************** *)
+(* Partial matches *)
+(* *************** *)
+
+let filter_conj states unwanted partial_matches =
+ let x =
+ triples_conj (triples_complement states (unwitify unwanted))
+ partial_matches in
+ triples_conj (unwitify x) (triples_complement states x)
+
+let strict_triples_conj strict states trips trips' =
+ let res = triples_conj trips trips' in
+ if !Flag_ctl.partial_match && strict = A.STRICT
+ then
+ let fail_left = filter_conj states trips trips' in
+ let fail_right = filter_conj states trips' trips in
+ let ors = triples_union fail_left fail_right in
+ triples_union res ors
+ else res
+
+let strict_triples_conj_none strict states trips trips' =
+ let res = triples_conj_none trips trips' in
+ if !Flag_ctl.partial_match && strict = A.STRICT
+ then
+ let fail_left = filter_conj states trips trips' in
+ let fail_right = filter_conj states trips' trips in
+ let ors = triples_union fail_left fail_right in
+ triples_union res ors
+ else res
+
+let left_strict_triples_conj strict states trips trips' =
+ let res = triples_conj trips trips' in
+ if !Flag_ctl.partial_match && strict = A.STRICT
+ then
+ let fail_left = filter_conj states trips trips' in
+ triples_union res fail_left
+ else res
+
+let strict_A1 strict op failop dir ((_,_,states) as m) trips required_states =
+ let res = op dir m trips required_states in
+ if !Flag_ctl.partial_match && strict = A.STRICT
+ then
+ let states = mkstates states required_states in
+ let fail = filter_conj states res (failop dir m trips required_states) in
+ triples_union res fail
+ else res
+
+let strict_A2 strict op failop dir ((_,_,states) as m) trips trips'
+ required_states =
+ let res = op dir m trips trips' required_states in
+ if !Flag_ctl.partial_match && strict = A.STRICT
+ then
+ let states = mkstates states required_states in
+ let fail = filter_conj states res (failop dir m trips' required_states) in
+ triples_union res fail
+ else res
+
+let strict_A2au strict op failop dir ((_,_,states) as m) trips trips'
+ required_states =
+ match op dir m trips trips' required_states with
+ AUok res ->
+ if !Flag_ctl.partial_match && strict = A.STRICT
+ then
+ let states = mkstates states required_states in
+ let fail =
+ filter_conj states res (failop dir m trips' required_states) in
+ AUok (triples_union res fail)
+ else AUok res
+ | AUfailed res -> AUfailed res
+
+(* ********************* *)
+(* Environment functions *)
+(* ********************* *)
+
+let drop_wits required_states s phi =
+ match required_states with
+ None -> s
+ | Some states -> List.filter (function (s,_,_) -> List.mem s states) s
+
+
+let print_required required =
+ List.iter
+ (function l ->
+ Format.print_string "{";
+ List.iter
+ (function reqd ->
+ print_generic_substitution reqd; Format.print_newline())
+ l;
+ Format.print_string "}";
+ Format.print_newline())
+ required
+
+exception Too_long
+
+let extend_required trips required =
+ if !Flag_ctl.partial_match
+ then required
+ else
+ if !pREQUIRED_ENV_OPT
+ then
+ (* make it a set *)
+ let envs =
+ List.fold_left
+ (function rest ->
+ function (_,t,_) -> if List.mem t rest then rest else t::rest)
+ [] trips in
+ let envs = if List.mem [] envs then [] else envs in
+ match (envs,required) with
+ ([],_) -> required
+ | (envs,hd::tl) ->
+ (try
+ let hdln = List.length hd + 5 (* let it grow a little bit *) in
+ let (_,merged) =
+ let add x (ln,y) =
+ if List.mem x y
+ then (ln,y)
+ else if ln + 1 > hdln then raise Too_long else (ln+1,x::y) in
+ foldl
+ (function rest ->
+ function t ->
+ foldl
+ (function rest ->
+ function r ->
+ match conj_subst t r with
+ None -> rest | Some th -> add th rest)
+ rest hd)
+ (0,[]) envs in
+ merged :: tl
+ with Too_long -> envs :: required)
+ | (envs,_) -> envs :: required
+ else required
+
+let drop_required v required =
+ if !pREQUIRED_ENV_OPT
+ then
+ let res =
+ inner_setify
+ (List.map
+ (function l ->
+ inner_setify
+ (List.map (List.filter (function sub -> not(dom_sub sub = v))) l))
+ required) in
+ (* check whether an entry has become useless *)
+ List.filter (function l -> not (List.exists (function x -> x = []) l)) res
+ else required
+
+(* no idea how to write this function ... *)
+let memo_label =
+ (Hashtbl.create(50) : (P.t, (G.node * substitution) list) Hashtbl.t)
+
+let satLabel label required p =
+ let triples =
+ if !pSATLABEL_MEMO_OPT
+ then
+ try
+ let states_subs = Hashtbl.find memo_label p in
+ List.map (function (st,th) -> (st,th,[])) states_subs
+ with
+ Not_found ->
+ let triples = setify(label p) in
+ Hashtbl.add memo_label p
+ (List.map (function (st,th,_) -> (st,th)) triples);
+ triples
+ else setify(label p) in
+ normalize
+ (if !pREQUIRED_ENV_OPT
+ then
+ foldl
+ (function rest ->
+ function ((s,th,_) as t) ->
+ if List.for_all
+ (List.exists (function th' -> not(conj_subst th th' = None)))
+ required
+ then t::rest
+ else rest)
+ [] triples
+ else triples)
+
+let get_required_states l =
+ if !pREQUIRED_STATES_OPT && not !Flag_ctl.partial_match
+ then
+ Some(inner_setify (List.map (function (s,_,_) -> s) l))
+ else None
+
+let get_children_required_states dir (grp,_,_) required_states =
+ if !pREQUIRED_STATES_OPT && not !Flag_ctl.partial_match
+ then
+ match required_states with
+ None -> None
+ | Some states ->
+ let fn =
+ match dir with
+ A.FORWARD -> G.successors
+ | A.BACKWARD -> G.predecessors in
+ Some (inner_setify (List.concat (List.map (fn grp) states)))
+ else None
+
+let reachable_table =
+ (Hashtbl.create(50) : (G.node * A.direction, G.node list) Hashtbl.t)
+
+(* like satEF, but specialized for get_reachable *)
+let reachsatEF dir (grp,_,_) s2 =
+ let dirop =
+ match dir with A.FORWARD -> G.successors | A.BACKWARD -> G.predecessors in
+ let union = unionBy compare (=) in
+ let rec f y = function
+ [] -> y
+ | new_info ->
+ let (pre_collected,new_info) =
+ List.partition (function Common.Left x -> true | _ -> false)
+ (List.map
+ (function x ->
+ try Common.Left (Hashtbl.find reachable_table (x,dir))
+ with Not_found -> Common.Right x)
+ new_info) in
+ let y =
+ List.fold_left
+ (function rest ->
+ function Common.Left x -> union x rest
+ | _ -> failwith "not possible")
+ y pre_collected in
+ let new_info =
+ List.map
+ (function Common.Right x -> x | _ -> failwith "not possible")
+ new_info in
+ let first = inner_setify (concatmap (dirop grp) new_info) in
+ let new_info = setdiff first y in
+ let res = new_info @ y in
+ f res new_info in
+ List.rev(f s2 s2) (* put root first *)
+
+let get_reachable dir m required_states =
+ match required_states with
+ None -> None
+ | Some states ->
+ Some
+ (List.fold_left
+ (function rest ->
+ function cur ->
+ if List.mem cur rest
+ then rest
+ else
+ Common.union_set
+ (try Hashtbl.find reachable_table (cur,dir)
+ with
+ Not_found ->
+ let states = reachsatEF dir m [cur] in
+ Hashtbl.add reachable_table (cur,dir) states;
+ states)
+ rest)
+ [] states)
+
+let ctr = ref 0
+let new_var _ =
+ let c = !ctr in
+ ctr := !ctr + 1;
+ Printf.sprintf "_c%d" c
+
+(* **************************** *)
+(* End of environment functions *)
+(* **************************** *)
+
+type ('code,'value) cell = Frozen of 'code | Thawed of 'value
+
+let rec satloop unchecked required required_states
+ ((grp,label,states) as m) phi env =
+ let rec loop unchecked required required_states phi =
+ (*Common.profile_code "satloop" (fun _ -> *)
+ let res =
+ match phi with
+ A.False -> []
+ | A.True -> triples_top states
+ | A.Pred(p) -> satLabel label required p
+ | A.Uncheck(phi1) ->
+ let unchecked = if !pUNCHECK_OPT then true else false in
+ loop unchecked required required_states phi1
+ | A.Not(phi) ->
+ let phires = loop unchecked required required_states phi in
+ (*let phires =
+ List.map (function (s,th,w) -> (s,th,[])) phires in*)
+ triples_complement (mkstates states required_states)
+ phires
+ | A.Or(phi1,phi2) ->
+ triples_union
+ (loop unchecked required required_states phi1)
+ (loop unchecked required required_states phi2)
+ | A.SeqOr(phi1,phi2) ->
+ let res1 = loop unchecked required required_states phi1 in
+ let res2 = loop unchecked required required_states phi2 in
+ let res1neg = unwitify res1 in
+ triples_union res1
+ (triples_conj
+ (triples_complement (mkstates states required_states) res1neg)
+ res2)
+ | A.And(strict,phi1,phi2) ->
+ (* phi1 is considered to be more likely to be [], because of the
+ definition of asttoctl. Could use heuristics such as the size of
+ the term *)
+ let pm = !Flag_ctl.partial_match in
+ (match (pm,loop unchecked required required_states phi1) with
+ (false,[]) when !pLazyOpt -> []
+ | (_,phi1res) ->
+ let new_required = extend_required phi1res required in
+ let new_required_states = get_required_states phi1res in
+ (match (pm,loop unchecked new_required new_required_states phi2)
+ with
+ (false,[]) when !pLazyOpt -> []
+ | (_,phi2res) ->
+ strict_triples_conj strict
+ (mkstates states required_states)
+ phi1res phi2res))
+ | A.AndAny(dir,strict,phi1,phi2) ->
+ (* phi2 can appear anywhere that is reachable *)
+ let pm = !Flag_ctl.partial_match in
+ (match (pm,loop unchecked required required_states phi1) with
+ (false,[]) -> []
+ | (_,phi1res) ->
+ let new_required = extend_required phi1res required in
+ let new_required_states = get_required_states phi1res in
+ let new_required_states =
+ get_reachable dir m new_required_states in
+ (match (pm,loop unchecked new_required new_required_states phi2)
+ with
+ (false,[]) -> phi1res
+ | (_,phi2res) ->
+ (match phi1res with
+ [] -> (* !Flag_ctl.partial_match must be true *)
+ if phi2res = []
+ then []
+ else
+ let s = mkstates states required_states in
+ List.fold_left
+ (function a -> function b ->
+ strict_triples_conj strict s a [b])
+ [List.hd phi2res] (List.tl phi2res)
+ | [(state,_,_)] ->
+ let phi2res =
+ List.map (function (s,e,w) -> [(state,e,w)]) phi2res in
+ let s = mkstates states required_states in
+ List.fold_left
+ (function a -> function b ->
+ strict_triples_conj strict s a b)
+ phi1res phi2res
+ | _ ->
+ failwith
+ "only one result allowed for the left arg of AndAny")))
+ | A.HackForStmt(dir,strict,phi1,phi2) ->
+ (* phi2 can appear anywhere that is reachable *)
+ let pm = !Flag_ctl.partial_match in
+ (match (pm,loop unchecked required required_states phi1) with
+ (false,[]) -> []
+ | (_,phi1res) ->
+ let new_required = extend_required phi1res required in
+ let new_required_states = get_required_states phi1res in
+ let new_required_states =
+ get_reachable dir m new_required_states in
+ (match (pm,loop unchecked new_required new_required_states phi2)
+ with
+ (false,[]) -> phi1res
+ | (_,phi2res) ->
+ (* if there is more than one state, something about the
+ environment has to ensure that the right triples of
+ phi2 get associated with the triples of phi1.
+ the asttoctl2 has to ensure that that is the case.
+ these should thus be structural properties.
+ env of phi2 has to be a proper subset of env of phi1
+ to ensure all end up being consistent. no new triples
+ should be generated. strict_triples_conj_none takes
+ care of this.
+ *)
+ let s = mkstates states required_states in
+ List.fold_left
+ (function acc ->
+ function (st,th,_) as phi2_elem ->
+ let inverse =
+ triples_complement [st] [(st,th,[])] in
+ strict_triples_conj_none strict s acc
+ (phi2_elem::inverse))
+ phi1res phi2res))
+ | A.InnerAnd(phi) ->
+ inner_and(loop unchecked required required_states phi)
+ | A.EX(dir,phi) ->
+ let new_required_states =
+ get_children_required_states dir m required_states in
+ satEX dir m (loop unchecked required new_required_states phi)
+ required_states
+ | A.AX(dir,strict,phi) ->
+ let new_required_states =
+ get_children_required_states dir m required_states in
+ let res = loop unchecked required new_required_states phi in
+ strict_A1 strict satAX satEX dir m res required_states
+ | A.EF(dir,phi) ->
+ let new_required_states = get_reachable dir m required_states in
+ satEF dir m (loop unchecked required new_required_states phi)
+ new_required_states
+ | A.AF(dir,strict,phi) ->
+ if !Flag_ctl.loop_in_src_code
+ then
+ loop unchecked required required_states
+ (A.AU(dir,strict,A.True,phi))
+ else
+ let new_required_states = get_reachable dir m required_states in
+ let res = loop unchecked required new_required_states phi in
+ strict_A1 strict satAF satEF dir m res new_required_states
+ | A.EG(dir,phi) ->
+ let new_required_states = get_reachable dir m required_states in
+ satEG dir m (loop unchecked required new_required_states phi)
+ new_required_states
+ | A.AG(dir,strict,phi) ->
+ let new_required_states = get_reachable dir m required_states in
+ let res = loop unchecked required new_required_states phi in
+ strict_A1 strict satAG satEF dir m res new_required_states
+ | A.EU(dir,phi1,phi2) ->
+ let new_required_states = get_reachable dir m required_states in
+ (match loop unchecked required new_required_states phi2 with
+ [] when !pLazyOpt -> []
+ | s2 ->
+ let new_required = extend_required s2 required in
+ let s1 = loop unchecked new_required new_required_states phi1 in
+ satEU dir m s1 s2 new_required_states)
+ | A.AW(dir,strict,phi1,phi2) ->
+ let new_required_states = get_reachable dir m required_states in
+ (match loop unchecked required new_required_states phi2 with
+ [] when !pLazyOpt -> []
+ | s2 ->
+ let new_required = extend_required s2 required in
+ let s1 = loop unchecked new_required new_required_states phi1 in
+ strict_A2 strict satAW satEF dir m s1 s2 new_required_states)
+ | A.AU(dir,strict,phi1,phi2) ->
+ (*Printf.printf "using AU\n"; flush stdout;*)
+ let new_required_states = get_reachable dir m required_states in
+ (match loop unchecked required new_required_states phi2 with
+ [] when !pLazyOpt -> []
+ | s2 ->
+ let new_required = extend_required s2 required in
+ let s1 = loop unchecked new_required new_required_states phi1 in
+ let res =
+ strict_A2au strict satAU satEF dir m s1 s2 new_required_states in
+ match res with
+ AUok res -> res
+ | AUfailed tmp_res ->
+ (* found a loop, have to try AW *)
+ (* the formula is
+ A[E[phi1 U phi2] & phi1 W phi2]
+ the and is nonstrict *)
+ (* tmp_res is bigger than s2, so perhaps closer to s1 *)
+ (*Printf.printf "using AW\n"; flush stdout;*)
+ let s1 =
+ triples_conj (satEU dir m s1 tmp_res new_required_states)
+ s1 in
+ strict_A2 strict satAW satEF dir m s1 s2 new_required_states)
+ | A.Implies(phi1,phi2) ->
+ loop unchecked required required_states (A.Or(A.Not phi1,phi2))
+ | A.Exists (keep,v,phi) ->
+ let new_required = drop_required v required in
+ triples_witness v unchecked (not keep)
+ (loop unchecked new_required required_states phi)
+ | A.Let(v,phi1,phi2) ->
+ (* should only be used when the properties unchecked, required,
+ and required_states are known to be the same or at least
+ compatible between all the uses. this is not checked. *)
+ let res = loop unchecked required required_states phi1 in
+ satloop unchecked required required_states m phi2 ((v,res) :: env)
+ | A.LetR(dir,v,phi1,phi2) ->
+ (* should only be used when the properties unchecked, required,
+ and required_states are known to be the same or at least
+ compatible between all the uses. this is not checked. *)
+ let new_required_states = get_reachable dir m required_states in
+ let res = loop unchecked required new_required_states phi1 in
+ satloop unchecked required required_states m phi2 ((v,res) :: env)
+ | A.Ref(v) ->
+ let res = List.assoc v env in
+ if unchecked
+ then List.map (function (s,th,_) -> (s,th,[])) res
+ else res
+ | A.XX(phi) -> failwith "should have been removed" in
+ if !Flag_ctl.bench > 0 then triples := !triples + (List.length res);
+ drop_wits required_states res phi (* ) *) in
+
+ loop unchecked required required_states phi
+;;
+
+
+(* SAT with tracking *)
+let rec sat_verbose_loop unchecked required required_states annot maxlvl lvl
+ ((_,label,states) as m) phi env =
+ let anno res children = (annot lvl phi res children,res) in
+ let satv unchecked required required_states phi0 env =
+ sat_verbose_loop unchecked required required_states annot maxlvl (lvl+1)
+ m phi0 env in
+ if (lvl > maxlvl) && (maxlvl > -1) then
+ anno (satloop unchecked required required_states m phi env) []
+ else
+ let (child,res) =
+ match phi with
+ A.False -> anno [] []
+ | A.True -> anno (triples_top states) []
+ | A.Pred(p) ->
+ Printf.printf "label\n"; flush stdout;
+ anno (satLabel label required p) []
+ | A.Uncheck(phi1) ->
+ let unchecked = if !pUNCHECK_OPT then true else false in
+ let (child1,res1) = satv unchecked required required_states phi1 env in
+ Printf.printf "uncheck\n"; flush stdout;
+ anno res1 [child1]
+ | A.Not(phi1) ->
+ let (child,res) =
+ satv unchecked required required_states phi1 env in
+ Printf.printf "not\n"; flush stdout;
+ anno (triples_complement (mkstates states required_states) res) [child]
+ | A.Or(phi1,phi2) ->
+ let (child1,res1) =
+ satv unchecked required required_states phi1 env in
+ let (child2,res2) =
+ satv unchecked required required_states phi2 env in
+ Printf.printf "or\n"; flush stdout;
+ anno (triples_union res1 res2) [child1; child2]
+ | A.SeqOr(phi1,phi2) ->
+ let (child1,res1) =
+ satv unchecked required required_states phi1 env in
+ let (child2,res2) =
+ satv unchecked required required_states phi2 env in
+ let res1neg =
+ List.map (function (s,th,_) -> (s,th,[])) res1 in
+ Printf.printf "seqor\n"; flush stdout;
+ anno (triples_union res1
+ (triples_conj
+ (triples_complement (mkstates states required_states)
+ res1neg)
+ res2))
+ [child1; child2]
+ | A.And(strict,phi1,phi2) ->
+ let pm = !Flag_ctl.partial_match in
+ (match (pm,satv unchecked required required_states phi1 env) with
+ (false,(child1,[])) ->
+ Printf.printf "and\n"; flush stdout; anno [] [child1]
+ | (_,(child1,res1)) ->
+ let new_required = extend_required res1 required in
+ let new_required_states = get_required_states res1 in
+ (match (pm,satv unchecked new_required new_required_states phi2
+ env) with
+ (false,(child2,[])) ->
+ Printf.printf "and\n"; flush stdout; anno [] [child1;child2]
+ | (_,(child2,res2)) ->
+ Printf.printf "and\n"; flush stdout;
+ let res =
+ strict_triples_conj strict
+ (mkstates states required_states)
+ res1 res2 in
+ anno res [child1; child2]))
+ | A.AndAny(dir,strict,phi1,phi2) ->
+ let pm = !Flag_ctl.partial_match in
+ (match (pm,satv unchecked required required_states phi1 env) with
+ (false,(child1,[])) ->
+ Printf.printf "and\n"; flush stdout; anno [] [child1]
+ | (_,(child1,res1)) ->
+ let new_required = extend_required res1 required in
+ let new_required_states = get_required_states res1 in
+ let new_required_states =
+ get_reachable dir m new_required_states in
+ (match (pm,satv unchecked new_required new_required_states phi2
+ env) with
+ (false,(child2,[])) ->
+ Printf.printf "andany\n"; flush stdout;
+ anno res1 [child1;child2]
+ | (_,(child2,res2)) ->
+ (match res1 with
+ [] -> (* !Flag_ctl.partial_match must be true *)
+ if res2 = []
+ then anno [] [child1; child2]
+ else
+ let res =
+ let s = mkstates states required_states in
+ List.fold_left
+ (function a -> function b ->
+ strict_triples_conj strict s a [b])
+ [List.hd res2] (List.tl res2) in
+ anno res [child1; child2]
+ | [(state,_,_)] ->
+ let res2 =
+ List.map (function (s,e,w) -> [(state,e,w)]) res2 in
+ Printf.printf "andany\n"; flush stdout;
+ let res =
+ let s = mkstates states required_states in
+ List.fold_left
+ (function a -> function b ->
+ strict_triples_conj strict s a b)
+ res1 res2 in
+ anno res [child1; child2]
+ | _ ->
+ failwith
+ "only one result allowed for the left arg of AndAny")))
+ | A.HackForStmt(dir,strict,phi1,phi2) ->
+ let pm = !Flag_ctl.partial_match in
+ (match (pm,satv unchecked required required_states phi1 env) with
+ (false,(child1,[])) ->
+ Printf.printf "and\n"; flush stdout; anno [] [child1]
+ | (_,(child1,res1)) ->
+ let new_required = extend_required res1 required in
+ let new_required_states = get_required_states res1 in
+ let new_required_states =
+ get_reachable dir m new_required_states in
+ (match (pm,satv unchecked new_required new_required_states phi2
+ env) with
+ (false,(child2,[])) ->
+ Printf.printf "andany\n"; flush stdout;
+ anno res1 [child1;child2]
+ | (_,(child2,res2)) ->
+ let res =
+ let s = mkstates states required_states in
+ List.fold_left
+ (function acc ->
+ function (st,th,_) as phi2_elem ->
+ let inverse =
+ triples_complement [st] [(st,th,[])] in
+ strict_triples_conj_none strict s acc
+ (phi2_elem::inverse))
+ res1 res2 in
+ anno res [child1; child2]))
+ | A.InnerAnd(phi1) ->
+ let (child1,res1) = satv unchecked required required_states phi1 env in
+ Printf.printf "uncheck\n"; flush stdout;
+ anno (inner_and res1) [child1]
+ | A.EX(dir,phi1) ->
+ let new_required_states =
+ get_children_required_states dir m required_states in
+ let (child,res) =
+ satv unchecked required new_required_states phi1 env in
+ Printf.printf "EX\n"; flush stdout;
+ anno (satEX dir m res required_states) [child]
+ | A.AX(dir,strict,phi1) ->
+ let new_required_states =
+ get_children_required_states dir m required_states in
+ let (child,res) =
+ satv unchecked required new_required_states phi1 env in
+ Printf.printf "AX\n"; flush stdout;
+ let res = strict_A1 strict satAX satEX dir m res required_states in
+ anno res [child]
+ | A.EF(dir,phi1) ->
+ let new_required_states = get_reachable dir m required_states in
+ let (child,res) =
+ satv unchecked required new_required_states phi1 env in
+ Printf.printf "EF\n"; flush stdout;
+ anno (satEF dir m res new_required_states) [child]
+ | A.AF(dir,strict,phi1) ->
+ if !Flag_ctl.loop_in_src_code
+ then
+ satv unchecked required required_states
+ (A.AU(dir,strict,A.True,phi1))
+ env
+ else
+ (let new_required_states = get_reachable dir m required_states in
+ let (child,res) =
+ satv unchecked required new_required_states phi1 env in
+ Printf.printf "AF\n"; flush stdout;
+ let res =
+ strict_A1 strict satAF satEF dir m res new_required_states in
+ anno res [child])
+ | A.EG(dir,phi1) ->
+ let new_required_states = get_reachable dir m required_states in
+ let (child,res) =
+ satv unchecked required new_required_states phi1 env in
+ Printf.printf "EG\n"; flush stdout;
+ anno (satEG dir m res new_required_states) [child]
+ | A.AG(dir,strict,phi1) ->
+ let new_required_states = get_reachable dir m required_states in
+ let (child,res) =
+ satv unchecked required new_required_states phi1 env in
+ Printf.printf "AG\n"; flush stdout;
+ let res = strict_A1 strict satAG satEF dir m res new_required_states in
+ anno res [child]
+
+ | A.EU(dir,phi1,phi2) ->
+ let new_required_states = get_reachable dir m required_states in
+ (match satv unchecked required new_required_states phi2 env with
+ (child2,[]) ->
+ Printf.printf "EU\n"; flush stdout;
+ anno [] [child2]
+ | (child2,res2) ->
+ let new_required = extend_required res2 required in
+ let (child1,res1) =
+ satv unchecked new_required new_required_states phi1 env in
+ Printf.printf "EU\n"; flush stdout;
+ anno (satEU dir m res1 res2 new_required_states) [child1; child2])
+ | A.AW(dir,strict,phi1,phi2) ->
+ failwith "should not be used" (*
+ let new_required_states = get_reachable dir m required_states in
+ (match satv unchecked required new_required_states phi2 env with
+ (child2,[]) ->
+ Printf.printf "AW %b\n" unchecked; flush stdout; anno [] [child2]
+ | (child2,res2) ->
+ let new_required = extend_required res2 required in
+ let (child1,res1) =
+ satv unchecked new_required new_required_states phi1 env in
+ Printf.printf "AW %b\n" unchecked; flush stdout;
+ let res =
+ strict_A2 strict satAW satEF dir m res1 res2
+ new_required_states in
+ anno res [child1; child2]) *)
+ | A.AU(dir,strict,phi1,phi2) ->
+ let new_required_states = get_reachable dir m required_states in
+ (match satv unchecked required new_required_states phi2 env with
+ (child2,[]) ->
+ Printf.printf "AU\n"; flush stdout; anno [] [child2]
+ | (child2,s2) ->
+ let new_required = extend_required s2 required in
+ let (child1,s1) =
+ satv unchecked new_required new_required_states phi1 env in
+ Printf.printf "AU\n"; flush stdout;
+ let res =
+ strict_A2au strict satAU satEF dir m s1 s2 new_required_states in
+ (match res with
+ AUok res ->
+ anno res [child1; child2]
+ | AUfailed tmp_res ->
+ (* found a loop, have to try AW *)
+ (* the formula is
+ A[E[phi1 U phi2] & phi1 W phi2]
+ the and is nonstrict *)
+ (* tmp_res is bigger than s2, so perhaps closer to s1 *)
+ Printf.printf "AW\n"; flush stdout;
+ let s1 =
+ triples_conj (satEU dir m s1 tmp_res new_required_states) s1 in
+ let res =
+ strict_A2 strict satAW satEF dir m s1 s2 new_required_states in
+ anno res [child1; child2]))
+ | A.Implies(phi1,phi2) ->
+ satv unchecked required required_states
+ (A.Or(A.Not phi1,phi2))
+ env
+ | A.Exists (keep,v,phi1) ->
+ let new_required = drop_required v required in
+ let (child,res) =
+ satv unchecked new_required required_states phi1 env in
+ Printf.printf "exists\n"; flush stdout;
+ anno (triples_witness v unchecked (not keep) res) [child]
+ | A.Let(v,phi1,phi2) ->
+ let (child1,res1) =
+ satv unchecked required required_states phi1 env in
+ let (child2,res2) =
+ satv unchecked required required_states phi2 ((v,res1) :: env) in
+ anno res2 [child1;child2]
+ | A.LetR(dir,v,phi1,phi2) ->
+ let new_required_states = get_reachable dir m required_states in
+ let (child1,res1) =
+ satv unchecked required new_required_states phi1 env in
+ let (child2,res2) =
+ satv unchecked required required_states phi2 ((v,res1) :: env) in
+ anno res2 [child1;child2]
+ | A.Ref(v) ->
+ Printf.printf "Ref\n"; flush stdout;
+ let res = List.assoc v env in
+ let res =
+ if unchecked
+ then List.map (function (s,th,_) -> (s,th,[])) res
+ else res in
+ anno res []
+ | A.XX(phi) -> failwith "should have been removed" in
+ let res1 = drop_wits required_states res phi in
+ if not(res1 = res)
+ then
+ begin
+ print_required_states required_states;
+ print_state "after drop_wits" res1 end;
+ (child,res1)
+
+;;
+
+let sat_verbose annotate maxlvl lvl m phi =
+ sat_verbose_loop false [] None annotate maxlvl lvl m phi []
+
+(* Type for annotations collected in a tree *)
+type ('a) witAnnoTree = WitAnno of ('a * ('a witAnnoTree) list);;
+
+let sat_annotree annotate m phi =
+ let tree_anno l phi res chld = WitAnno(annotate l phi res,chld) in
+ sat_verbose_loop false [] None tree_anno (-1) 0 m phi []
+;;
+
+(*
+let sat m phi = satloop m phi []
+;;
+*)
+
+let simpleanno l phi res =
+ let pp s =
+ Format.print_string ("\n" ^ s ^ "\n------------------------------\n");
+ print_generic_algo (List.sort compare res);
+ Format.print_string "\n------------------------------\n\n" in
+ let pp_dir = function
+ A.FORWARD -> ()
+ | A.BACKWARD -> pp "^" in
+ match phi with
+ | A.False -> pp "False"
+ | A.True -> pp "True"
+ | A.Pred(p) -> pp ("Pred" ^ (Common.dump p))
+ | A.Not(phi) -> pp "Not"
+ | A.Exists(_,v,phi) -> pp ("Exists " ^ (Common.dump(v)))
+ | A.And(_,phi1,phi2) -> pp "And"
+ | A.AndAny(dir,_,phi1,phi2) -> pp "AndAny"
+ | A.HackForStmt(dir,_,phi1,phi2) -> pp "HackForStmt"
+ | A.Or(phi1,phi2) -> pp "Or"
+ | A.SeqOr(phi1,phi2) -> pp "SeqOr"
+ | A.Implies(phi1,phi2) -> pp "Implies"
+ | A.AF(dir,_,phi1) -> pp "AF"; pp_dir dir
+ | A.AX(dir,_,phi1) -> pp "AX"; pp_dir dir
+ | A.AG(dir,_,phi1) -> pp "AG"; pp_dir dir
+ | A.AW(dir,_,phi1,phi2)-> pp "AW"; pp_dir dir
+ | A.AU(dir,_,phi1,phi2)-> pp "AU"; pp_dir dir
+ | A.EF(dir,phi1) -> pp "EF"; pp_dir dir
+ | A.EX(dir,phi1) -> pp "EX"; pp_dir dir
+ | A.EG(dir,phi1) -> pp "EG"; pp_dir dir
+ | A.EU(dir,phi1,phi2) -> pp "EU"; pp_dir dir
+ | A.Let (x,phi1,phi2) -> pp ("Let"^" "^x)
+ | A.LetR (dir,x,phi1,phi2) -> pp ("LetR"^" "^x); pp_dir dir
+ | A.Ref(s) -> pp ("Ref("^s^")")
+ | A.Uncheck(s) -> pp "Uncheck"
+ | A.InnerAnd(s) -> pp "InnerAnd"
+ | A.XX(phi1) -> pp "XX"
+;;
+
+
+(* pad: Rene, you can now use the module pretty_print_ctl.ml to
+ print a ctl formula more accurately if you want.
+ Use the print_xxx provided in the different module to call
+ Pretty_print_ctl.pp_ctl.
+ *)
+
+let simpleanno2 l phi res =
+ begin
+ Pretty_print_ctl.pp_ctl (P.print_predicate, SUB.print_mvar) false phi;
+ Format.print_newline ();
+ Format.print_string "----------------------------------------------------";
+ Format.print_newline ();
+ print_generic_algo (List.sort compare res);
+ Format.print_newline ();
+ Format.print_string "----------------------------------------------------";
+ Format.print_newline ();
+ Format.print_newline ();
+ end
+
+
+(* ---------------------------------------------------------------------- *)
+(* Benchmarking *)
+(* ---------------------------------------------------------------------- *)
+
+type optentry = bool ref * string
+type options = {label : optentry; unch : optentry;
+ conj : optentry; compl1 : optentry; compl2 : optentry;
+ newinfo : optentry;
+ reqenv : optentry; reqstates : optentry}
+
+let options =
+ {label = (pSATLABEL_MEMO_OPT,"satlabel_memo_opt");
+ unch = (pUNCHECK_OPT,"uncheck_opt");
+ conj = (pTRIPLES_CONJ_OPT,"triples_conj_opt");
+ compl1 = (pTRIPLES_COMPLEMENT_OPT,"triples_complement_opt");
+ compl2 = (pTRIPLES_COMPLEMENT_SIMPLE_OPT,"triples_complement_simple_opt");
+ newinfo = (pNEW_INFO_OPT,"new_info_opt");
+ reqenv = (pREQUIRED_ENV_OPT,"required_env_opt");
+ reqstates = (pREQUIRED_STATES_OPT,"required_states_opt")}
+
+let baseline =
+ [("none ",[]);
+ ("label ",[options.label]);
+ ("unch ",[options.unch]);
+ ("unch and label ",[options.label;options.unch])]
+
+let conjneg =
+ [("conj ", [options.conj]);
+ ("compl1 ", [options.compl1]);
+ ("compl12 ", [options.compl1;options.compl2]);
+ ("conj/compl12 ", [options.conj;options.compl1;options.compl2]);
+ ("conj unch satl ", [options.conj;options.unch;options.label]);
+(*
+ ("compl1 unch satl ", [options.compl1;options.unch;options.label]);
+ ("compl12 unch satl ",
+ [options.compl1;options.compl2;options.unch;options.label]); *)
+ ("conj/compl12 unch satl ",
+ [options.conj;options.compl1;options.compl2;options.unch;options.label])]
+
+let path =
+ [("newinfo ", [options.newinfo]);
+ ("newinfo unch satl ", [options.newinfo;options.unch;options.label])]
+
+let required =
+ [("reqenv ", [options.reqenv]);
+ ("reqstates ", [options.reqstates]);
+ ("reqenv/states ", [options.reqenv;options.reqstates]);
+(* ("reqenv unch satl ", [options.reqenv;options.unch;options.label]);
+ ("reqstates unch satl ",
+ [options.reqstates;options.unch;options.label]);*)
+ ("reqenv/states unch satl ",
+ [options.reqenv;options.reqstates;options.unch;options.label])]
+
+let all_options =
+ [options.label;options.unch;options.conj;options.compl1;options.compl2;
+ options.newinfo;options.reqenv;options.reqstates]
+
+let all =
+ [("all ",all_options)]
+
+let all_options_but_path =
+ [options.label;options.unch;options.conj;options.compl1;options.compl2;
+ options.reqenv;options.reqstates]
+
+let all_but_path = ("all but path ",all_options_but_path)
+
+let counters =
+ [(satAW_calls, "satAW", ref 0);
+ (satAU_calls, "satAU", ref 0);
+ (satEF_calls, "satEF", ref 0);
+ (satAF_calls, "satAF", ref 0);
+ (satEG_calls, "satEG", ref 0);
+ (satAG_calls, "satAG", ref 0);
+ (satEU_calls, "satEU", ref 0)]
+
+let perms =
+ map
+ (function (opt,x) ->
+ (opt,x,ref 0.0,ref 0,
+ List.map (function _ -> (ref 0, ref 0, ref 0)) counters))
+ [List.hd all;all_but_path]
+ (*(all@baseline@conjneg@path@required)*)
+
+exception Out
+
+let rec iter fn = function
+ 1 -> fn()
+ | n -> let _ = fn() in
+ (Hashtbl.clear reachable_table;
+ Hashtbl.clear memo_label;
+ triples := 0;
+ iter fn (n-1))
+
+let copy_to_stderr fl =
+ let i = open_in fl in
+ let rec loop _ =
+ Printf.fprintf stderr "%s\n" (input_line i);
+ loop() in
+ try loop() with _ -> ();
+ close_in i
+
+let bench_sat (_,_,states) fn =
+ List.iter (function (opt,_) -> opt := false) all_options;
+ let answers =
+ concatmap
+ (function (name,options,time,trips,counter_info) ->
+ let iterct = !Flag_ctl.bench in
+ if !time > float_of_int timeout then time := -100.0;
+ if not (!time = -100.0)
+ then
+ begin
+ Hashtbl.clear reachable_table;
+ Hashtbl.clear memo_label;
+ List.iter (function (opt,_) -> opt := true) options;
+ List.iter (function (calls,_,save_calls) -> save_calls := !calls)
+ counters;
+ triples := 0;
+ let res =
+ let bef = Sys.time() in
+ try
+ Common.timeout_function timeout
+ (fun () ->
+ let bef = Sys.time() in
+ let res = iter fn iterct in
+ let aft = Sys.time() in
+ time := !time +. (aft -. bef);
+ trips := !trips + !triples;
+ List.iter2
+ (function (calls,_,save_calls) ->
+ function (current_calls,current_cfg,current_max_cfg) ->
+ current_calls :=
+ !current_calls + (!calls - !save_calls);
+ if (!calls - !save_calls) > 0
+ then
+ (let st = List.length states in
+ current_cfg := !current_cfg + st;
+ if st > !current_max_cfg
+ then current_max_cfg := st))
+ counters counter_info;
+ [res])
+ with
+ Common.Timeout ->
+ begin
+ let aft = Sys.time() in
+ time := -100.0;
+ Printf.fprintf stderr "Timeout at %f on: %s\n"
+ (aft -. bef) name;
+ []
+ end in
+ List.iter (function (opt,_) -> opt := false) options;
+ res
+ end
+ else [])
+ perms in
+ Printf.fprintf stderr "\n";
+ match answers with
+ [] -> []
+ | res::rest ->
+ (if not(List.for_all (function x -> x = res) rest)
+ then
+ (List.iter (print_state "a state") answers;
+ Printf.printf "something doesn't work\n");
+ res)
+
+let print_bench _ =
+ let iterct = !Flag_ctl.bench in
+ if iterct > 0
+ then
+ (List.iter
+ (function (name,options,time,trips,counter_info) ->
+ Printf.fprintf stderr "%s Numbers: %f %d "
+ name (!time /. (float_of_int iterct)) !trips;
+ List.iter
+ (function (calls,cfg,max_cfg) ->
+ Printf.fprintf stderr "%d %d %d " (!calls / iterct) !cfg !max_cfg)
+ counter_info;
+ Printf.fprintf stderr "\n")
+ perms)
+
+(* ---------------------------------------------------------------------- *)
+(* preprocessing: ignore irrelevant functions *)
+
+let preprocess (cfg,_,_) label = function
+ [] -> true (* no information, try everything *)
+ | l ->
+ let sz = G.size cfg in
+ let verbose_output pred = function
+ [] ->
+ Printf.printf "did not find:\n";
+ P.print_predicate pred; Format.print_newline()
+ | _ ->
+ Printf.printf "found:\n";
+ P.print_predicate pred; Format.print_newline();
+ Printf.printf "but it was not enough\n" in
+ let get_any verbose x =
+ let res =
+ try Hashtbl.find memo_label x
+ with
+ Not_found ->
+ (let triples = label x in
+ let filtered =
+ List.map (function (st,th,_) -> (st,th)) triples in
+ Hashtbl.add memo_label x filtered;
+ filtered) in
+ if verbose then verbose_output x res;
+ not([] = res) in
+ let get_all l =
+ (* don't bother testing when there are more patterns than nodes *)
+ if List.length l > sz-2
+ then false
+ else List.for_all (get_any false) l in
+ if List.exists get_all l
+ then true
+ else
+ (if !Flag_ctl.verbose_match
+ then
+ List.iter (List.iter (function x -> let _ = get_any true x in ()))
+ l;
+ false)
+
+let filter_partial_matches trips =
+ if !Flag_ctl.partial_match
+ then
+ let anynegwit = (* if any is neg, then all are *)
+ List.exists (function A.NegWit _ -> true | A.Wit _ -> false) in
+ let (bad,good) =
+ List.partition (function (s,th,wit) -> anynegwit wit) trips in
+ (match bad with
+ [] -> ()
+ | _ -> print_state "partial matches" bad; Format.print_newline());
+ good
+ else trips
+
+(* ---------------------------------------------------------------------- *)
+(* Main entry point for engine *)
+let sat m phi reqopt =
+ try
+ (match !Flag_ctl.steps with
+ None -> step_count := 0
+ | Some x -> step_count := x);
+ Hashtbl.clear reachable_table;
+ Hashtbl.clear memo_label;
+ let (x,label,states) = m in
+ if (!Flag_ctl.bench > 0) or (preprocess m label reqopt)
+ then
+ ((* to drop when Yoann initialized this flag *)
+ if List.exists (G.extract_is_loop x) states
+ then Flag_ctl.loop_in_src_code := true;
+ let m = (x,label,List.sort compare states) in
+ let res =
+ if(!Flag_ctl.verbose_ctl_engine)
+ then
+ let fn _ = snd (sat_annotree simpleanno2 m phi) in
+ if !Flag_ctl.bench > 0
+ then bench_sat m fn
+ else fn()
+ else
+ let fn _ = satloop false [] None m phi [] in
+ if !Flag_ctl.bench > 0
+ then bench_sat m fn
+ else Common.profile_code "ctl" (fun _ -> fn()) in
+ let res = filter_partial_matches res in
+ (*
+ Printf.printf "steps: start %d, stop %d\n"
+ (match !Flag_ctl.steps with Some x -> x | _ -> 0)
+ !step_count;
+ Printf.printf "triples: %d\n" !triples;
+ print_state "final result" res;
+ *)
+ res)
+ else
+ (if !Flag_ctl.verbose_ctl_engine
+ then Common.pr2 "missing something required";
+ [])
+ with Steps -> []
+;;
+
+(* ********************************************************************** *)
+(* End of Module: CTL_ENGINE *)
+(* ********************************************************************** *)
+end
+;;
+
*)
-let debug_engine = ref false
+(* option -verbose_ctl_engine *)
+let verbose_ctl_engine = ref false
-(* false = simpler formulas, only for debugging *)
-let useEU = ref true
+(* cheap partial matches using assttomember *)
+let verbose_match = ref false
-let disallow_nested_exps = ref false
+let partial_match = ref false
-(* if this flag is not set, then break and continue are also error exits *)
-let only_return_is_error_exit = ref false
+let poswits_only = ref false
+
+let loop_in_src_code = ref false
+
+let bench = ref 0
+
+let steps = ref (None : int option)
-(* a hack to allow adding code in some more sgrep-like uses *)
-let allow_inconsistent_paths = ref false
--- /dev/null
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+*
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+*
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
+*
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+(* option -verbose_ctl_engine *)
+let verbose_ctl_engine = ref false
+
+(* cheap partial matches using assttomember *)
+let verbose_match = ref false
+
+let partial_match = ref false
+
+let poswits_only = ref false
+
+let loop_in_src_code = ref false
+
+let bench = ref 0
+
+let steps = ref (None : int option)
+
+let graphical_trace = ref false
let pANY_NEG_OPT = ref true
let pLazyOpt = ref true
+(* Nico: This stack is use for graphical traces *)
+let graph_stack = ref ([] : string list)
+let graph_hash = (Hashtbl.create 101)
+
(*
let pTRIPLES_CONJ_OPT = ref false
let pTRIPLES_COMPLEMENT_OPT = ref false
val extract_is_loop : cfg -> node -> bool
val print_node : node -> unit
val size : cfg -> int
+ val print_graph : cfg -> string option ->
+ (node * string) list -> (node * string) list -> string -> unit
end
;;
(* Misc. useful generic functions *)
(* ---------------------------------------------------------------------- *)
+let get_graph_files () = !graph_stack
+let get_graph_comp_files outfile = Hashtbl.find_all graph_hash outfile
+
let head = List.hd
let tail l =
let mkstates states = function
None -> states
| Some states -> states
-
+
+let print_graph grp required_states res str = function
+ A.Exists (keep,v,phi) -> ()
+ | phi ->
+ if !Flag_ctl.graphical_trace && not !Flag_ctl.checking_reachability
+ then
+ match phi with
+ | A.Exists (keep,v,phi) -> ()
+ | _ ->
+ let label =
+ Printf.sprintf "%s%s"
+ (String.escaped
+ (Common.format_to_string
+ (function _ ->
+ Pretty_print_ctl.pp_ctl
+ (P.print_predicate, SUB.print_mvar)
+ false phi)))
+ str in
+ let file = (match !Flag.currentfile with
+ None -> "graphical_trace"
+ | Some f -> f
+ ) in
+ (if not (List.mem file !graph_stack) then
+ graph_stack := file :: !graph_stack);
+ let filename = Filename.temp_file (file^":") ".dot" in
+ Hashtbl.add graph_hash file filename;
+ G.print_graph grp
+ (if !Flag_ctl.gt_without_label then None else (Some label))
+ (match required_states with
+ None -> []
+ | Some required_states ->
+ (List.map (function s -> (s,"blue")) required_states))
+ (List.map (function (s,_,_) -> (s,"\"#FF8080\"")) res) filename
+
+let print_graph_c grp required_states res ctr phi =
+ let str = "iter: "^(string_of_int !ctr) in
+ print_graph grp required_states res str phi
+
(* ---------------------------------------------------------------------- *)
(* *)
(* ---------------------------------------------------------------------- *)
;;
(* E[phi1 U phi2] == phi2 \/ (phi1 /\ EXE[phi1 U phi2]) *)
-let satEU dir ((_,_,states) as m) s1 s2 reqst =
+let satEU dir ((_,_,states) as m) s1 s2 reqst print_graph =
+ let ctr = ref 0 in
inc satEU_calls;
if s1 = []
then s2
[] -> y
| new_info ->
ctr := !ctr + 1;
+ print_graph y ctr;
let first = triples_conj s1 (pre_exist dir m new_info reqst) in
let res = triples_union first y in
let new_info = setdiff res y in
else
let f y =
inc_step();
+ ctr := !ctr + 1;
+ print_graph y ctr;
let pre = pre_exist dir m y reqst in
triples_union s2 (triples_conj s1 pre) in
setfix f s2
AUok of ('pred,'anno) triples | AUfailed of ('pred,'anno) triples
(* A[phi1 U phi2] == phi2 \/ (phi1 /\ AXA[phi1 U phi2]) *)
-let satAU dir ((cfg,_,states) as m) s1 s2 reqst =
+let satAU dir ((cfg,_,states) as m) s1 s2 reqst print_graph =
+ let ctr = ref 0 in
inc satAU_calls;
if s1 = []
then AUok s2
match newinfo with
[] -> AUok y
| new_info ->
- (*ctr := !ctr + 1;
- print_state (Printf.sprintf "iteration %d\n" !ctr) y;
+ ctr := !ctr + 1;
+ (*print_state (Printf.sprintf "iteration %d\n" !ctr) y;
flush stdout;*)
+ print_graph y ctr;
let pre =
try Some (pre_forall dir m new_info y reqst)
with AW -> None in
subseteq s1 s2) in for popl *)
let f y =
inc_step();
+ ctr := !ctr + 1;
+ print_graph y ctr;
let pre = pre_forall dir m y y reqst in
triples_union s2 (triples_conj s1 pre) in
AUok (setfix f s2)
else res
let strict_A2au strict op failop dir ((_,_,states) as m) trips trips'
- required_states =
- match op dir m trips trips' required_states with
+ required_states print_graph =
+ match op dir m trips trips' required_states print_graph with
AUok res ->
if !Flag_ctl.partial_match && strict = A.STRICT
then
| s2 ->
let new_required = extend_required s2 required in
let s1 = loop unchecked new_required new_required_states phi1 in
- satEU dir m s1 s2 new_required_states)
+ satEU dir m s1 s2 new_required_states
+ (fun y ctr -> print_graph_c grp new_required_states y ctr phi))
| A.AW(dir,strict,phi1,phi2) ->
let new_required_states = get_reachable dir m required_states in
(match loop unchecked required new_required_states phi2 with
let new_required = extend_required s2 required in
let s1 = loop unchecked new_required new_required_states phi1 in
let res =
- strict_A2au strict satAU satEF dir m s1 s2 new_required_states in
+ strict_A2au strict satAU satEF dir m s1 s2 new_required_states
+ (fun y ctr ->
+ print_graph_c grp new_required_states y ctr phi) in
match res with
AUok res -> res
| AUfailed tmp_res ->
(* tmp_res is bigger than s2, so perhaps closer to s1 *)
(*Printf.printf "using AW\n"; flush stdout;*)
let s1 =
- triples_conj (satEU dir m s1 tmp_res new_required_states)
+ triples_conj
+ (satEU dir m s1 tmp_res new_required_states
+ (* no graph, for the moment *)
+ (fun y str -> ()))
s1 in
strict_A2 strict satAW satEF dir m s1 s2 new_required_states)
| A.Implies(phi1,phi2) ->
(* should only be used when the properties unchecked, required,
and required_states are known to be the same or at least
compatible between all the uses. this is not checked. *)
+ (* doesn't seem to be used any more *)
let new_required_states = get_reachable dir m required_states in
let res = loop unchecked required new_required_states phi1 in
satloop unchecked required required_states m phi2 ((v,res) :: env)
else res
| A.XX(phi) -> failwith "should have been removed" in
if !Flag_ctl.bench > 0 then triples := !triples + (List.length res);
- drop_wits required_states res phi (* ) *) in
+ let res = drop_wits required_states res phi (* ) *) in
+ print_graph grp required_states res "" phi;
+ res in
loop unchecked required required_states phi
;;
let (child1,res1) =
satv unchecked new_required new_required_states phi1 env in
Printf.printf "EU\n"; flush stdout;
- anno (satEU dir m res1 res2 new_required_states) [child1; child2])
+ anno (satEU dir m res1 res2 new_required_states (fun y str -> ()))
+ [child1; child2])
| A.AW(dir,strict,phi1,phi2) ->
failwith "should not be used" (*
let new_required_states = get_reachable dir m required_states in
satv unchecked new_required new_required_states phi1 env in
Printf.printf "AU\n"; flush stdout;
let res =
- strict_A2au strict satAU satEF dir m s1 s2 new_required_states in
+ strict_A2au strict satAU satEF dir m s1 s2 new_required_states
+ (fun y str -> ()) in
(match res with
AUok res ->
anno res [child1; child2]
(* tmp_res is bigger than s2, so perhaps closer to s1 *)
Printf.printf "AW\n"; flush stdout;
let s1 =
- triples_conj (satEU dir m s1 tmp_res new_required_states) s1 in
+ triples_conj
+ (satEU dir m s1 tmp_res new_required_states
+ (* no graph, for the moment *)
+ (fun y str -> ()))
+ s1 in
let res =
strict_A2 strict satAW satEF dir m s1 s2 new_required_states in
anno res [child1; child2]))
val extract_is_loop : cfg -> node -> bool
val print_node : node -> unit
val size : cfg -> int
+ val print_graph : cfg -> string option ->
+ (node * string) list -> (node * string) list -> string -> unit
end
module OGRAPHEXT_GRAPH :
val print_bench : unit -> unit
end
+
+val get_graph_files : unit -> string list
+val get_graph_comp_files : string -> string list
+
let steps = ref (None : int option)
+let graphical_trace = ref false
+let gt_without_label = ref false
+
+let checking_reachability = ref false
--- /dev/null
+# Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+# Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+# This file is part of Coccinelle.
+#
+# Coccinelle is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, according to version 2 of the License.
+#
+# Coccinelle is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
+#
+# The authors reserve the right to distribute this or future versions of
+# Coccinelle under other licenses.
+
+
+##############################################################################
+# Variables
+##############################################################################
+#TARGET=matcher
+TARGET=cocciengine
+CTLTARGET=engine
+
+SRC= flag_matcher.ml lib_engine.ml pretty_print_engine.ml \
+ check_exhaustive_pattern.ml \
+ check_reachability.ml \
+ c_vs_c.ml isomorphisms_c_c.ml \
+ cocci_vs_c.ml pattern_c.ml sgrep.ml transformation_c.ml \
+ asttomember.ml asttoctl2.ml ctltotex.ml \
+ postprocess_transinfo.ml ctlcocci_integration.ml
+
+#c_vs_c.ml
+#SRC= flag_matcher.ml \
+# c_vs_c.ml cocci_vs_c.ml \
+# lib_engine.ml \
+# pattern_c.ml transformation_c.ml
+
+#LIBS=../commons/commons.cma ../parsing_c/parsing_c.cma
+#INCLUDES= -I ../commons -I ../parsing_c
+INCLUDES = -I ../commons -I ../commons/ocamlextra -I ../globals \
+ -I ../ctl -I ../parsing_cocci -I ../parsing_c
+LIBS=../commons/commons.cma ../globals/globals.cma \
+ ../ctl/ctl.cma ../parsing_c/c_parser.cma ../parsing_cocci/cocci_parser.cma
+
+SYSLIBS= str.cma unix.cma
+
+
+# just to test asttoctl
+# CTLSOURCES = lib_engine.ml pretty_print_engine.ml asttoctl.ml ctltotex.ml \
+# main.ml
+
+##############################################################################
+# Generic variables
+##############################################################################
+
+#for warning: -w A
+#for profiling: -p -inline 0 with OCAMLOPT
+OCAMLCFLAGS ?= -g -dtypes
+
+OCAMLC=ocamlc$(OPTBIN) $(OCAMLCFLAGS) $(INCLUDES)
+OCAMLOPT=ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
+OCAMLLEX=ocamllex$(OPTBIN) #-ml
+OCAMLYACC=ocamlyacc -v
+OCAMLDEP=ocamldep$(OPTBIN) $(INCLUDES)
+OCAMLMKTOP=ocamlmktop -g -custom $(INCLUDES)
+
+
+OBJS = $(SRC:.ml=.cmo)
+OPTOBJS = $(SRC:.ml=.cmx)
+
+
+##############################################################################
+# Top rules
+##############################################################################
+all: $(TARGET).cma
+all.opt: $(TARGET).cmxa
+
+$(TARGET).cma: $(OBJS)
+ $(OCAMLC) -a -o $(TARGET).cma $(OBJS)
+
+$(TARGET).cmxa: $(OPTOBJS) $(LIBS:.cma=.cmxa)
+ $(OCAMLOPT) -a -o $(TARGET).cmxa $(OPTOBJS)
+
+$(TARGET).top: $(OBJS) $(LIBS)
+ $(OCAMLMKTOP) -o $(TARGET).top $(SYSLIBS) $(LIBS) $(OBJS)
+
+clean::
+ rm -f $(TARGET).top
+
+
+
+##############################################################################
+# Pad's rules
+##############################################################################
+
+##############################################################################
+# Generic rules
+##############################################################################
+
+.SUFFIXES: .ml .mli .cmo .cmi .cmx
+
+.ml.cmo:
+ $(OCAMLC) -c $<
+.mli.cmi:
+ $(OCAMLC) -c $<
+.ml.cmx:
+ $(OCAMLOPT) -c $<
+
+.ml.mldepend:
+ $(OCAMLC) -i $<
+
+clean::
+ rm -f *.cm[ioxa] *.o *.a *.cmxa *.annot
+clean::
+ rm -f *~ .*~ gmon.out #*#
+
+beforedepend::
+
+depend:: beforedepend
+ $(OCAMLDEP) *.mli *.ml > .depend
+
+-include .depend
+++ /dev/null
-(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-*
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-*
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
-*
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
-
-(* for MINUS and CONTEXT, pos is always None in this file *)
-(*search for require*)
-(* true = don't see all matched nodes, only modified ones *)
-let onlyModif = ref true(*false*)
-
-type ex = Exists | Forall | ReverseForall
-let exists = ref Forall
-
-module Ast = Ast_cocci
-module V = Visitor_ast
-module CTL = Ast_ctl
-
-let warning s = Printf.fprintf stderr "warning: %s\n" s
-
-type cocci_predicate = Lib_engine.predicate * Ast.meta_name Ast_ctl.modif
-type formula =
- (cocci_predicate,Ast.meta_name, Wrapper_ctl.info) Ast_ctl.generic_ctl
-
-let union = Common.union_set
-let intersect l1 l2 = List.filter (function x -> List.mem x l2) l1
-let subset l1 l2 = List.for_all (function x -> List.mem x l2) l1
-
-let foldl1 f xs = List.fold_left f (List.hd xs) (List.tl xs)
-let foldr1 f xs =
- let xs = List.rev xs in List.fold_left f (List.hd xs) (List.tl xs)
-
-let used_after = ref ([] : Ast.meta_name list)
-let guard_to_strict guard = if guard then CTL.NONSTRICT else CTL.STRICT
-
-let saved = ref ([] : Ast.meta_name list)
-
-let string2var x = ("",x)
-
-(* --------------------------------------------------------------------- *)
-(* predicates matching various nodes in the graph *)
-
-let ctl_and s x y =
- match (x,y) with
- (CTL.False,_) | (_,CTL.False) -> CTL.False
- | (CTL.True,a) | (a,CTL.True) -> a
- | _ -> CTL.And(s,x,y)
-
-let ctl_or x y =
- match (x,y) with
- (CTL.True,_) | (_,CTL.True) -> CTL.True
- | (CTL.False,a) | (a,CTL.False) -> a
- | _ -> CTL.Or(x,y)
-
-let ctl_or_fl x y =
- match (x,y) with
- (CTL.True,_) | (_,CTL.True) -> CTL.True
- | (CTL.False,a) | (a,CTL.False) -> a
- | _ -> CTL.Or(y,x)
-
-let ctl_seqor x y =
- match (x,y) with
- (CTL.True,_) | (_,CTL.True) -> CTL.True
- | (CTL.False,a) | (a,CTL.False) -> a
- | _ -> CTL.SeqOr(x,y)
-
-let ctl_not = function
- CTL.True -> CTL.False
- | CTL.False -> CTL.True
- | x -> CTL.Not(x)
-
-let ctl_ax s = function
- CTL.True -> CTL.True
- | CTL.False -> CTL.False
- | x ->
- match !exists with
- Exists -> CTL.EX(CTL.FORWARD,x)
- | Forall -> CTL.AX(CTL.FORWARD,s,x)
- | ReverseForall -> failwith "not supported"
-
-let ctl_ax_absolute s = function
- CTL.True -> CTL.True
- | CTL.False -> CTL.False
- | x -> CTL.AX(CTL.FORWARD,s,x)
-
-let ctl_ex = function
- CTL.True -> CTL.True
- | CTL.False -> CTL.False
- | x -> CTL.EX(CTL.FORWARD,x)
-
-(* This stays being AX even for sgrep_mode, because it is used to identify
-the structure of the term, not matching the pattern. *)
-let ctl_back_ax = function
- CTL.True -> CTL.True
- | CTL.False -> CTL.False
- | x -> CTL.AX(CTL.BACKWARD,CTL.NONSTRICT,x)
-
-let ctl_back_ex = function
- CTL.True -> CTL.True
- | CTL.False -> CTL.False
- | x -> CTL.EX(CTL.BACKWARD,x)
-
-let ctl_ef = function
- CTL.True -> CTL.True
- | CTL.False -> CTL.False
- | x -> CTL.EF(CTL.FORWARD,x)
-
-let ctl_ag s = function
- CTL.True -> CTL.True
- | CTL.False -> CTL.False
- | x -> CTL.AG(CTL.FORWARD,s,x)
-
-let ctl_au s x y =
- match (x,!exists) with
- (CTL.True,Exists) -> CTL.EF(CTL.FORWARD,y)
- | (CTL.True,Forall) -> CTL.AF(CTL.FORWARD,s,y)
- | (CTL.True,ReverseForall) -> failwith "not supported"
- | (_,Exists) -> CTL.EU(CTL.FORWARD,x,y)
- | (_,Forall) -> CTL.AU(CTL.FORWARD,s,x,y)
- | (_,ReverseForall) -> failwith "not supported"
-
-let ctl_anti_au s x y = (* only for ..., where the quantifier is changed *)
- CTL.XX
- (match (x,!exists) with
- (CTL.True,Exists) -> CTL.AF(CTL.FORWARD,s,y)
- | (CTL.True,Forall) -> CTL.EF(CTL.FORWARD,y)
- | (CTL.True,ReverseForall) -> failwith "not supported"
- | (_,Exists) -> CTL.AU(CTL.FORWARD,s,x,y)
- | (_,Forall) -> CTL.EU(CTL.FORWARD,x,y)
- | (_,ReverseForall) -> failwith "not supported")
-
-let ctl_uncheck = function
- CTL.True -> CTL.True
- | CTL.False -> CTL.False
- | x -> CTL.Uncheck x
-
-let label_pred_maker = function
- None -> CTL.True
- | Some (label_var,used) ->
- used := true;
- CTL.Pred(Lib_engine.PrefixLabel(label_var),CTL.Control)
-
-let bclabel_pred_maker = function
- None -> CTL.True
- | Some (label_var,used) ->
- used := true;
- CTL.Pred(Lib_engine.BCLabel(label_var),CTL.Control)
-
-let predmaker guard pred label =
- ctl_and (guard_to_strict guard) (CTL.Pred pred) (label_pred_maker label)
-
-let aftpred = predmaker false (Lib_engine.After, CTL.Control)
-let retpred = predmaker false (Lib_engine.Return, CTL.Control)
-let funpred = predmaker false (Lib_engine.FunHeader, CTL.Control)
-let toppred = predmaker false (Lib_engine.Top, CTL.Control)
-let exitpred = predmaker false (Lib_engine.ErrorExit, CTL.Control)
-let endpred = predmaker false (Lib_engine.Exit, CTL.Control)
-let gotopred = predmaker false (Lib_engine.Goto, CTL.Control)
-let inlooppred = predmaker false (Lib_engine.InLoop, CTL.Control)
-let truepred = predmaker false (Lib_engine.TrueBranch, CTL.Control)
-let falsepred = predmaker false (Lib_engine.FalseBranch, CTL.Control)
-let fallpred = predmaker false (Lib_engine.FallThrough, CTL.Control)
-
-let aftret label_var f = ctl_or (aftpred label_var) (exitpred label_var)
-
-let letctr = ref 0
-let get_let_ctr _ =
- let cur = !letctr in
- letctr := cur + 1;
- Printf.sprintf "r%d" cur
-
-(* --------------------------------------------------------------------- *)
-(* --------------------------------------------------------------------- *)
-(* Eliminate OptStm *)
-
-(* for optional thing with nothing after, should check that the optional thing
-never occurs. otherwise the matching stops before it occurs *)
-let elim_opt =
- let mcode x = x in
- let donothing r k e = k e in
-
- let fvlist l =
- List.fold_left Common.union_set [] (List.map Ast.get_fvs l) in
-
- let mfvlist l =
- List.fold_left Common.union_set [] (List.map Ast.get_mfvs l) in
-
- let freshlist l =
- List.fold_left Common.union_set [] (List.map Ast.get_fresh l) in
-
- let inheritedlist l =
- List.fold_left Common.union_set [] (List.map Ast.get_inherited l) in
-
- let savedlist l =
- List.fold_left Common.union_set [] (List.map Ast.get_saved l) in
-
- let varlists l =
- (fvlist l, mfvlist l, freshlist l, inheritedlist l, savedlist l) in
-
- let rec dots_list unwrapped wrapped =
- match (unwrapped,wrapped) with
- ([],_) -> []
-
- | (Ast.Dots(_,_,_,_)::Ast.OptStm(stm)::(Ast.Dots(_,_,_,_) as u)::urest,
- d0::s::d1::rest)
- | (Ast.Nest(_,_,_,_,_)::Ast.OptStm(stm)::(Ast.Dots(_,_,_,_) as u)::urest,
- d0::s::d1::rest) ->
- let l = Ast.get_line stm in
- let new_rest1 = stm :: (dots_list (u::urest) (d1::rest)) in
- let new_rest2 = dots_list urest rest in
- let (fv_rest1,mfv_rest1,fresh_rest1,inherited_rest1,s1) =
- varlists new_rest1 in
- let (fv_rest2,mfv_rest2,fresh_rest2,inherited_rest2,s2) =
- varlists new_rest2 in
- [d0;
- {(Ast.make_term
- (Ast.Disj
- [{(Ast.make_term(Ast.DOTS(new_rest1))) with
- Ast.node_line = l;
- Ast.free_vars = fv_rest1;
- Ast.minus_free_vars = mfv_rest1;
- Ast.fresh_vars = fresh_rest1;
- Ast.inherited = inherited_rest1;
- Ast.saved_witness = s1};
- {(Ast.make_term(Ast.DOTS(new_rest2))) with
- Ast.node_line = l;
- Ast.free_vars = fv_rest2;
- Ast.minus_free_vars = mfv_rest2;
- Ast.fresh_vars = fresh_rest2;
- Ast.inherited = inherited_rest2;
- Ast.saved_witness = s2}])) with
- Ast.node_line = l;
- Ast.free_vars = fv_rest1;
- Ast.minus_free_vars = mfv_rest1;
- Ast.fresh_vars = fresh_rest1;
- Ast.inherited = inherited_rest1;
- Ast.saved_witness = s1}]
-
- | (Ast.OptStm(stm)::urest,_::rest) ->
- let l = Ast.get_line stm in
- let new_rest1 = dots_list urest rest in
- let new_rest2 = stm::new_rest1 in
- let (fv_rest1,mfv_rest1,fresh_rest1,inherited_rest1,s1) =
- varlists new_rest1 in
- let (fv_rest2,mfv_rest2,fresh_rest2,inherited_rest2,s2) =
- varlists new_rest2 in
- [{(Ast.make_term
- (Ast.Disj
- [{(Ast.make_term(Ast.DOTS(new_rest2))) with
- Ast.node_line = l;
- Ast.free_vars = fv_rest2;
- Ast.minus_free_vars = mfv_rest2;
- Ast.fresh_vars = fresh_rest2;
- Ast.inherited = inherited_rest2;
- Ast.saved_witness = s2};
- {(Ast.make_term(Ast.DOTS(new_rest1))) with
- Ast.node_line = l;
- Ast.free_vars = fv_rest1;
- Ast.minus_free_vars = mfv_rest1;
- Ast.fresh_vars = fresh_rest1;
- Ast.inherited = inherited_rest1;
- Ast.saved_witness = s1}])) with
- Ast.node_line = l;
- Ast.free_vars = fv_rest2;
- Ast.minus_free_vars = mfv_rest2;
- Ast.fresh_vars = fresh_rest2;
- Ast.inherited = inherited_rest2;
- Ast.saved_witness = s2}]
-
- | ([Ast.Dots(_,_,_,_);Ast.OptStm(stm)],[d1;_]) ->
- let l = Ast.get_line stm in
- let fv_stm = Ast.get_fvs stm in
- let mfv_stm = Ast.get_mfvs stm in
- let fresh_stm = Ast.get_fresh stm in
- let inh_stm = Ast.get_inherited stm in
- let saved_stm = Ast.get_saved stm in
- let fv_d1 = Ast.get_fvs d1 in
- let mfv_d1 = Ast.get_mfvs d1 in
- let fresh_d1 = Ast.get_fresh d1 in
- let inh_d1 = Ast.get_inherited d1 in
- let saved_d1 = Ast.get_saved d1 in
- let fv_both = Common.union_set fv_stm fv_d1 in
- let mfv_both = Common.union_set mfv_stm mfv_d1 in
- let fresh_both = Common.union_set fresh_stm fresh_d1 in
- let inh_both = Common.union_set inh_stm inh_d1 in
- let saved_both = Common.union_set saved_stm saved_d1 in
- [d1;
- {(Ast.make_term
- (Ast.Disj
- [{(Ast.make_term(Ast.DOTS([stm]))) with
- Ast.node_line = l;
- Ast.free_vars = fv_stm;
- Ast.minus_free_vars = mfv_stm;
- Ast.fresh_vars = fresh_stm;
- Ast.inherited = inh_stm;
- Ast.saved_witness = saved_stm};
- {(Ast.make_term(Ast.DOTS([d1]))) with
- Ast.node_line = l;
- Ast.free_vars = fv_d1;
- Ast.minus_free_vars = mfv_d1;
- Ast.fresh_vars = fresh_d1;
- Ast.inherited = inh_d1;
- Ast.saved_witness = saved_d1}])) with
- Ast.node_line = l;
- Ast.free_vars = fv_both;
- Ast.minus_free_vars = mfv_both;
- Ast.fresh_vars = fresh_both;
- Ast.inherited = inh_both;
- Ast.saved_witness = saved_both}]
-
- | ([Ast.Nest(_,_,_,_,_);Ast.OptStm(stm)],[d1;_]) ->
- let l = Ast.get_line stm in
- let rw = Ast.rewrap stm in
- let rwd = Ast.rewrap stm in
- let dots = Ast.Dots(Ast.make_mcode "...",[],[],[]) in
- [d1;rw(Ast.Disj
- [rwd(Ast.DOTS([stm]));
- {(Ast.make_term(Ast.DOTS([rw dots])))
- with Ast.node_line = l}])]
-
- | (_::urest,stm::rest) -> stm :: (dots_list urest rest)
- | _ -> failwith "not possible" in
-
- let stmtdotsfn r k d =
- let d = k d in
- Ast.rewrap d
- (match Ast.unwrap d with
- Ast.DOTS(l) -> Ast.DOTS(dots_list (List.map Ast.unwrap l) l)
- | Ast.CIRCLES(l) -> failwith "elimopt: not supported"
- | Ast.STARS(l) -> failwith "elimopt: not supported") in
-
- V.rebuilder
- mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
- mcode
- donothing donothing stmtdotsfn donothing
- donothing donothing donothing donothing donothing donothing donothing
- donothing donothing donothing donothing donothing
-
-(* --------------------------------------------------------------------- *)
-(* after management *)
-(* We need Guard for the following case:
-<...
- a
- <...
- b
- ...>
-...>
-foo();
-
-Here the inner <... b ...> should not go past foo. But foo is not the
-"after" of the body of the outer nest, because we don't want to search for
-it in the case where the body of the outer nest ends in something other
-than dots or a nest. *)
-
-(* what is the difference between tail and end??? *)
-
-type after = After of formula | Guard of formula | Tail | End | VeryEnd
-
-let a2n = function After x -> Guard x | a -> a
-
-let print_ctl x =
- let pp_pred (x,_) = Pretty_print_engine.pp_predicate x in
- let pp_meta (_,x) = Common.pp x in
- Pretty_print_ctl.pp_ctl (pp_pred,pp_meta) false x;
- Format.print_newline()
-
-let print_after = function
- After ctl -> Printf.printf "After:\n"; print_ctl ctl
- | Guard ctl -> Printf.printf "Guard:\n"; print_ctl ctl
- | Tail -> Printf.printf "Tail\n"
- | VeryEnd -> Printf.printf "Very End\n"
- | End -> Printf.printf "End\n"
-
-(* --------------------------------------------------------------------- *)
-(* Top-level code *)
-
-let fresh_var _ = string2var "_v"
-let fresh_pos _ = string2var "_pos" (* must be a constant *)
-
-let fresh_metavar _ = "_S"
-
-(* fvinfo is going to end up being from the whole associated statement.
- it would be better if it were just the free variables in d, but free_vars.ml
- doesn't keep track of free variables on + code *)
-let make_meta_rule_elem d fvinfo =
- let nm = fresh_metavar() in
- Ast.make_meta_rule_elem nm d fvinfo
-
-let get_unquantified quantified vars =
- List.filter (function x -> not (List.mem x quantified)) vars
-
-let make_seq guard l =
- let s = guard_to_strict guard in
- foldr1 (function rest -> function cur -> ctl_and s cur (ctl_ax s rest)) l
-
-let make_seq_after2 guard first rest =
- let s = guard_to_strict guard in
- match rest with
- After rest -> ctl_and s first (ctl_ax s (ctl_ax s rest))
- | _ -> first
-
-let make_seq_after guard first rest =
- match rest with
- After rest -> make_seq guard [first;rest]
- | _ -> first
-
-let opt_and guard first rest =
- let s = guard_to_strict guard in
- match first with
- None -> rest
- | Some first -> ctl_and s first rest
-
-let and_after guard first rest =
- let s = guard_to_strict guard in
- match rest with After rest -> ctl_and s first rest | _ -> first
-
-let contains_modif =
- let bind x y = x or y in
- let option_default = false in
- let mcode r (_,_,kind,_) =
- match kind with
- Ast.MINUS(_,_) -> true
- | Ast.PLUS -> failwith "not possible"
- | Ast.CONTEXT(_,info) -> not (info = Ast.NOTHING) in
- let do_nothing r k e = k e in
- let rule_elem r k re =
- let res = k re in
- match Ast.unwrap re with
- Ast.FunHeader(bef,_,fninfo,name,lp,params,rp) ->
- bind (mcode r ((),(),bef,Ast.NoMetaPos)) res
- | Ast.Decl(bef,_,decl) -> bind (mcode r ((),(),bef,Ast.NoMetaPos)) res
- | _ -> res in
- let recursor =
- V.combiner bind option_default
- mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
- mcode
- do_nothing do_nothing do_nothing do_nothing
- do_nothing do_nothing do_nothing do_nothing do_nothing do_nothing
- do_nothing rule_elem do_nothing do_nothing do_nothing do_nothing in
- recursor.V.combiner_rule_elem
-
-(* code is not a DisjRuleElem *)
-let make_match label guard code =
- let v = fresh_var() in
- let matcher = Lib_engine.Match(code) in
- if contains_modif code && not guard
- then CTL.Exists(true,v,predmaker guard (matcher,CTL.Modif v) label)
- else
- let iso_info = !Flag.track_iso_usage && not (Ast.get_isos code = []) in
- (match (iso_info,!onlyModif,guard,
- intersect !used_after (Ast.get_fvs code)) with
- (false,true,_,[]) | (_,_,true,_) ->
- predmaker guard (matcher,CTL.Control) label
- | _ -> CTL.Exists(true,v,predmaker guard (matcher,CTL.UnModif v) label))
-
-let make_raw_match label guard code =
- predmaker guard (Lib_engine.Match(code),CTL.Control) label
-
-let rec seq_fvs quantified = function
- [] -> []
- | fv1::fvs ->
- let t1fvs = get_unquantified quantified fv1 in
- let termfvs =
- List.fold_left Common.union_set []
- (List.map (get_unquantified quantified) fvs) in
- let bothfvs = Common.inter_set t1fvs termfvs in
- let t1onlyfvs = Common.minus_set t1fvs bothfvs in
- let new_quantified = Common.union_set bothfvs quantified in
- (t1onlyfvs,bothfvs)::(seq_fvs new_quantified fvs)
-
-let quantify guard =
- List.fold_right
- (function cur ->
- function code -> CTL.Exists (not guard && List.mem cur !saved,cur,code))
-
-let non_saved_quantify =
- List.fold_right
- (function cur -> function code -> CTL.Exists (false,cur,code))
-
-let intersectll lst nested_list =
- List.filter (function x -> List.exists (List.mem x) nested_list) lst
-
-(* --------------------------------------------------------------------- *)
-(* Count depth of braces. The translation of a closed brace appears deeply
-nested within the translation of the sequence term, so the name of the
-paren var has to take into account the names of the nested braces. On the
-other hand the close brace does not escape, so we don't have to take into
-account other paren variable names. *)
-
-(* called repetitively, which is inefficient, but less trouble than adding a
-new field to Seq and FunDecl *)
-let count_nested_braces s =
- let bind x y = max x y in
- let option_default = 0 in
- let stmt_count r k s =
- match Ast.unwrap s with
- Ast.Seq(_,_,_,_) | Ast.FunDecl(_,_,_,_,_) -> (k s) + 1
- | _ -> k s in
- let donothing r k e = k e in
- let mcode r x = 0 in
- let recursor = V.combiner bind option_default
- mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
- mcode
- donothing donothing donothing donothing
- donothing donothing donothing donothing donothing donothing
- donothing donothing stmt_count donothing donothing donothing in
- let res = string_of_int (recursor.V.combiner_statement s) in
- string2var ("p"^res)
-
-let labelctr = ref 0
-let get_label_ctr _ =
- let cur = !labelctr in
- labelctr := cur + 1;
- string2var (Printf.sprintf "l%d" cur)
-
-(* --------------------------------------------------------------------- *)
-(* annotate dots with before and after neighbors *)
-
-let print_bef_aft = function
- Ast.WParen (re,n) ->
- Printf.printf "bef/aft\n";
- Pretty_print_cocci.rule_elem "" re;
- Format.print_newline()
- | Ast.Other s ->
- Printf.printf "bef/aft\n";
- Pretty_print_cocci.statement "" s;
- Format.print_newline()
- | Ast.Other_dots d ->
- Printf.printf "bef/aft\n";
- Pretty_print_cocci.statement_dots d;
- Format.print_newline()
-
-(* [] can only occur if we are in a disj, where it comes from a ? In that
-case, we want to use a, which accumulates all of the previous patterns in
-their entirety. *)
-let rec get_before_elem sl a =
- match Ast.unwrap sl with
- Ast.DOTS(x) ->
- let rec loop sl a =
- match sl with
- [] -> ([],Common.Right a)
- | [e] ->
- let (e,ea) = get_before_e e a in
- ([e],Common.Left ea)
- | e::sl ->
- let (e,ea) = get_before_e e a in
- let (sl,sla) = loop sl ea in
- (e::sl,sla) in
- let (l,a) = loop x a in
- (Ast.rewrap sl (Ast.DOTS(l)),a)
- | Ast.CIRCLES(x) -> failwith "not supported"
- | Ast.STARS(x) -> failwith "not supported"
-
-and get_before sl a =
- match get_before_elem sl a with
- (term,Common.Left x) -> (term,x)
- | (term,Common.Right x) -> (term,x)
-
-and get_before_whencode wc =
- List.map
- (function
- Ast.WhenNot w -> let (w,_) = get_before w [] in Ast.WhenNot w
- | Ast.WhenAlways w -> let (w,_) = get_before_e w [] in Ast.WhenAlways w
- | Ast.WhenModifier(x) -> Ast.WhenModifier(x))
- wc
-
-and get_before_e s a =
- match Ast.unwrap s with
- Ast.Dots(d,w,_,aft) ->
- (Ast.rewrap s (Ast.Dots(d,get_before_whencode w,a,aft)),a)
- | Ast.Nest(stmt_dots,w,multi,_,aft) ->
- let w = get_before_whencode w in
- let (sd,_) = get_before stmt_dots a in
- let a =
- List.filter
- (function
- Ast.Other a ->
- let unifies =
- Unify_ast.unify_statement_dots
- (Ast.rewrap s (Ast.DOTS([a]))) stmt_dots in
- (match unifies with
- Unify_ast.MAYBE -> false
- | _ -> true)
- | Ast.Other_dots a ->
- let unifies = Unify_ast.unify_statement_dots a stmt_dots in
- (match unifies with
- Unify_ast.MAYBE -> false
- | _ -> true)
- | _ -> true)
- a in
- (Ast.rewrap s (Ast.Nest(sd,w,multi,a,aft)),[Ast.Other_dots stmt_dots])
- | Ast.Disj(stmt_dots_list) ->
- let (dsl,dsla) =
- List.split (List.map (function e -> get_before e a) stmt_dots_list) in
- (Ast.rewrap s (Ast.Disj(dsl)),List.fold_left Common.union_set [] dsla)
- | Ast.Atomic(ast) ->
- (match Ast.unwrap ast with
- Ast.MetaStmt(_,_,_,_) -> (s,[])
- | _ -> (s,[Ast.Other s]))
- | Ast.Seq(lbrace,decls,body,rbrace) ->
- let index = count_nested_braces s in
- let (de,dea) = get_before decls [Ast.WParen(lbrace,index)] in
- let (bd,_) = get_before body dea in
- (Ast.rewrap s (Ast.Seq(lbrace,de,bd,rbrace)),
- [Ast.WParen(rbrace,index)])
- | Ast.Define(header,body) ->
- let (body,_) = get_before body [] in
- (Ast.rewrap s (Ast.Define(header,body)), [Ast.Other s])
- | Ast.IfThen(ifheader,branch,aft) ->
- let (br,_) = get_before_e branch [] in
- (Ast.rewrap s (Ast.IfThen(ifheader,br,aft)), [Ast.Other s])
- | Ast.IfThenElse(ifheader,branch1,els,branch2,aft) ->
- let (br1,_) = get_before_e branch1 [] in
- let (br2,_) = get_before_e branch2 [] in
- (Ast.rewrap s (Ast.IfThenElse(ifheader,br1,els,br2,aft)),[Ast.Other s])
- | Ast.While(header,body,aft) ->
- let (bd,_) = get_before_e body [] in
- (Ast.rewrap s (Ast.While(header,bd,aft)),[Ast.Other s])
- | Ast.For(header,body,aft) ->
- let (bd,_) = get_before_e body [] in
- (Ast.rewrap s (Ast.For(header,bd,aft)),[Ast.Other s])
- | Ast.Do(header,body,tail) ->
- let (bd,_) = get_before_e body [] in
- (Ast.rewrap s (Ast.Do(header,bd,tail)),[Ast.Other s])
- | Ast.Iterator(header,body,aft) ->
- let (bd,_) = get_before_e body [] in
- (Ast.rewrap s (Ast.Iterator(header,bd,aft)),[Ast.Other s])
- | Ast.Switch(header,lb,cases,rb) ->
- let cases =
- List.map
- (function case_line ->
- match Ast.unwrap case_line with
- Ast.CaseLine(header,body) ->
- let (body,_) = get_before body [] in
- Ast.rewrap case_line (Ast.CaseLine(header,body))
- | Ast.OptCase(case_line) -> failwith "not supported")
- cases in
- (Ast.rewrap s (Ast.Switch(header,lb,cases,rb)),[Ast.Other s])
- | Ast.FunDecl(header,lbrace,decls,body,rbrace) ->
- let (de,dea) = get_before decls [] in
- let (bd,_) = get_before body dea in
- (Ast.rewrap s (Ast.FunDecl(header,lbrace,de,bd,rbrace)),[])
- | _ -> failwith "get_before_e: not supported"
-
-let rec get_after sl a =
- match Ast.unwrap sl with
- Ast.DOTS(x) ->
- let rec loop sl =
- match sl with
- [] -> ([],a)
- | e::sl ->
- let (sl,sla) = loop sl in
- let (e,ea) = get_after_e e sla in
- (e::sl,ea) in
- let (l,a) = loop x in
- (Ast.rewrap sl (Ast.DOTS(l)),a)
- | Ast.CIRCLES(x) -> failwith "not supported"
- | Ast.STARS(x) -> failwith "not supported"
-
-and get_after_whencode a wc =
- List.map
- (function
- Ast.WhenNot w -> let (w,_) = get_after w a (*?*) in Ast.WhenNot w
- | Ast.WhenAlways w -> let (w,_) = get_after_e w a in Ast.WhenAlways w
- | Ast.WhenModifier(x) -> Ast.WhenModifier(x))
- wc
-
-and get_after_e s a =
- match Ast.unwrap s with
- Ast.Dots(d,w,bef,_) ->
- (Ast.rewrap s (Ast.Dots(d,get_after_whencode a w,bef,a)),a)
- | Ast.Nest(stmt_dots,w,multi,bef,_) ->
- let w = get_after_whencode a w in
- let (sd,_) = get_after stmt_dots a in
- let a =
- List.filter
- (function
- Ast.Other a ->
- let unifies =
- Unify_ast.unify_statement_dots
- (Ast.rewrap s (Ast.DOTS([a]))) stmt_dots in
- (match unifies with
- Unify_ast.MAYBE -> false
- | _ -> true)
- | Ast.Other_dots a ->
- let unifies = Unify_ast.unify_statement_dots a stmt_dots in
- (match unifies with
- Unify_ast.MAYBE -> false
- | _ -> true)
- | _ -> true)
- a in
- (Ast.rewrap s (Ast.Nest(sd,w,multi,bef,a)),[Ast.Other_dots stmt_dots])
- | Ast.Disj(stmt_dots_list) ->
- let (dsl,dsla) =
- List.split (List.map (function e -> get_after e a) stmt_dots_list) in
- (Ast.rewrap s (Ast.Disj(dsl)),List.fold_left Common.union_set [] dsla)
- | Ast.Atomic(ast) ->
- (match Ast.unwrap ast with
- Ast.MetaStmt(nm,keep,Ast.SequencibleAfterDots _,i) ->
- (* check "after" information for metavar optimization *)
- (* if the error is not desired, could just return [], then
- the optimization (check for EF) won't take place *)
- List.iter
- (function
- Ast.Other x ->
- (match Ast.unwrap x with
- Ast.Dots(_,_,_,_) | Ast.Nest(_,_,_,_,_) ->
- failwith
- "dots/nest not allowed before and after stmt metavar"
- | _ -> ())
- | Ast.Other_dots x ->
- (match Ast.undots x with
- x::_ ->
- (match Ast.unwrap x with
- Ast.Dots(_,_,_,_) | Ast.Nest(_,_,_,_,_) ->
- failwith
- ("dots/nest not allowed before and after stmt "^
- "metavar")
- | _ -> ())
- | _ -> ())
- | _ -> ())
- a;
- (Ast.rewrap s
- (Ast.Atomic
- (Ast.rewrap s
- (Ast.MetaStmt(nm,keep,Ast.SequencibleAfterDots a,i)))),[])
- | Ast.MetaStmt(_,_,_,_) -> (s,[])
- | _ -> (s,[Ast.Other s]))
- | Ast.Seq(lbrace,decls,body,rbrace) ->
- let index = count_nested_braces s in
- let (bd,bda) = get_after body [Ast.WParen(rbrace,index)] in
- let (de,_) = get_after decls bda in
- (Ast.rewrap s (Ast.Seq(lbrace,de,bd,rbrace)),
- [Ast.WParen(lbrace,index)])
- | Ast.Define(header,body) ->
- let (body,_) = get_after body a in
- (Ast.rewrap s (Ast.Define(header,body)), [Ast.Other s])
- | Ast.IfThen(ifheader,branch,aft) ->
- let (br,_) = get_after_e branch a in
- (Ast.rewrap s (Ast.IfThen(ifheader,br,aft)),[Ast.Other s])
- | Ast.IfThenElse(ifheader,branch1,els,branch2,aft) ->
- let (br1,_) = get_after_e branch1 a in
- let (br2,_) = get_after_e branch2 a in
- (Ast.rewrap s (Ast.IfThenElse(ifheader,br1,els,br2,aft)),[Ast.Other s])
- | Ast.While(header,body,aft) ->
- let (bd,_) = get_after_e body a in
- (Ast.rewrap s (Ast.While(header,bd,aft)),[Ast.Other s])
- | Ast.For(header,body,aft) ->
- let (bd,_) = get_after_e body a in
- (Ast.rewrap s (Ast.For(header,bd,aft)),[Ast.Other s])
- | Ast.Do(header,body,tail) ->
- let (bd,_) = get_after_e body a in
- (Ast.rewrap s (Ast.Do(header,bd,tail)),[Ast.Other s])
- | Ast.Iterator(header,body,aft) ->
- let (bd,_) = get_after_e body a in
- (Ast.rewrap s (Ast.Iterator(header,bd,aft)),[Ast.Other s])
- | Ast.Switch(header,lb,cases,rb) ->
- let cases =
- List.map
- (function case_line ->
- match Ast.unwrap case_line with
- Ast.CaseLine(header,body) ->
- let (body,_) = get_after body [] in
- Ast.rewrap case_line (Ast.CaseLine(header,body))
- | Ast.OptCase(case_line) -> failwith "not supported")
- cases in
- (Ast.rewrap s (Ast.Switch(header,lb,cases,rb)),[Ast.Other s])
- | Ast.FunDecl(header,lbrace,decls,body,rbrace) ->
- let (bd,bda) = get_after body [] in
- let (de,_) = get_after decls bda in
- (Ast.rewrap s (Ast.FunDecl(header,lbrace,de,bd,rbrace)),[])
- | _ -> failwith "get_after_e: not supported"
-
-let preprocess_dots sl =
- let (sl,_) = get_before sl [] in
- let (sl,_) = get_after sl [] in
- sl
-
-let preprocess_dots_e sl =
- let (sl,_) = get_before_e sl [] in
- let (sl,_) = get_after_e sl [] in
- sl
-
-(* --------------------------------------------------------------------- *)
-(* various return_related things *)
-
-let rec ends_in_return stmt_list =
- match Ast.unwrap stmt_list with
- Ast.DOTS(x) ->
- (match List.rev x with
- x::_ ->
- (match Ast.unwrap x with
- Ast.Atomic(x) ->
- (match Ast.unwrap x with
- Ast.Return(_,_) | Ast.ReturnExpr(_,_,_) -> true
- | _ -> false)
- | Ast.Disj(disjs) -> List.for_all ends_in_return disjs
- | _ -> false)
- | _ -> false)
- | Ast.CIRCLES(x) -> failwith "not supported"
- | Ast.STARS(x) -> failwith "not supported"
-
-(* --------------------------------------------------------------------- *)
-(* expressions *)
-
-let exptymatch l make_match make_guard_match =
- let pos = fresh_pos() in
- let matches_guard_matches =
- List.map
- (function x ->
- let pos = Ast.make_mcode pos in
- (make_match (Ast.set_pos x (Some pos)),
- make_guard_match (Ast.set_pos x (Some pos))))
- l in
- let (matches,guard_matches) = List.split matches_guard_matches in
- let rec suffixes = function
- [] -> []
- | x::xs -> xs::(suffixes xs) in
- let prefixes = List.rev (suffixes (List.rev guard_matches)) in
- let info = (* not null *)
- List.map2
- (function matcher ->
- function negates ->
- CTL.Exists
- (false,pos,
- ctl_and CTL.NONSTRICT matcher
- (ctl_not
- (ctl_uncheck (List.fold_left ctl_or_fl CTL.False negates)))))
- matches prefixes in
- CTL.InnerAnd(List.fold_left ctl_or_fl CTL.False (List.rev info))
-
-(* code might be a DisjRuleElem, in which case we break it apart
- code might contain an Exp or Ty
- this one pushes the quantifier inwards *)
-let do_re_matches label guard res quantified minus_quantified =
- let make_guard_match x =
- let stmt_fvs = Ast.get_mfvs x in
- let fvs = get_unquantified minus_quantified stmt_fvs in
- non_saved_quantify fvs (make_match None true x) in
- let make_match x =
- let stmt_fvs = Ast.get_fvs x in
- let fvs = get_unquantified quantified stmt_fvs in
- quantify guard fvs (make_match None guard x) in
- ctl_and CTL.NONSTRICT (label_pred_maker label)
- (match List.map Ast.unwrap res with
- [] -> failwith "unexpected empty disj"
- | Ast.Exp(e)::rest -> exptymatch res make_match make_guard_match
- | Ast.Ty(t)::rest -> exptymatch res make_match make_guard_match
- | all ->
- if List.exists (function Ast.Exp(_) | Ast.Ty(_) -> true | _ -> false)
- all
- then failwith "unexpected exp or ty";
- List.fold_left ctl_seqor CTL.False
- (List.rev (List.map make_match res)))
-
-(* code might be a DisjRuleElem, in which case we break it apart
- code doesn't contain an Exp or Ty
- this one is for use when it is not practical to push the quantifier inwards
- *)
-let header_match label guard code : ('a, Ast.meta_name, 'b) CTL.generic_ctl =
- match Ast.unwrap code with
- Ast.DisjRuleElem(res) ->
- let make_match = make_match None guard in
- let orop = if guard then ctl_or else ctl_seqor in
- ctl_and CTL.NONSTRICT (label_pred_maker label)
- (List.fold_left orop CTL.False (List.map make_match res))
- | _ -> make_match label guard code
-
-(* --------------------------------------------------------------------- *)
-(* control structures *)
-
-let end_control_structure fvs header body after_pred
- after_checks no_after_checks (afvs,afresh,ainh,aft) after label guard =
- (* aft indicates what is added after the whole if, which has to be added
- to the endif node *)
- let (aft_needed,after_branch) =
- match aft with
- Ast.CONTEXT(_,Ast.NOTHING) ->
- (false,make_seq_after2 guard after_pred after)
- | _ ->
- let match_endif =
- make_match label guard
- (make_meta_rule_elem aft (afvs,afresh,ainh)) in
- (true,
- make_seq_after guard after_pred
- (After(make_seq_after guard match_endif after))) in
- let body = body after_branch in
- let s = guard_to_strict guard in
- (* the code *)
- quantify guard fvs
- (ctl_and s header
- (opt_and guard
- (match (after,aft_needed) with
- (After _,_) (* pattern doesn't end here *)
- | (_,true) (* + code added after *) -> after_checks
- | _ -> no_after_checks)
- (ctl_ax_absolute s body)))
-
-let ifthen ifheader branch ((afvs,_,_,_) as aft) after
- quantified minus_quantified label llabel slabel recurse make_match guard =
-(* "if (test) thn" becomes:
- if(test) & AX((TrueBranch & AX thn) v FallThrough v After)
-
- "if (test) thn; after" becomes:
- if(test) & AX((TrueBranch & AX thn) v FallThrough v (After & AXAX after))
- & EX After
-*)
- (* free variables *)
- let (efvs,bfvs) =
- match seq_fvs quantified
- [Ast.get_fvs ifheader;Ast.get_fvs branch;afvs] with
- [(efvs,b1fvs);(_,b2fvs);_] -> (efvs,Common.union_set b1fvs b2fvs)
- | _ -> failwith "not possible" in
- let new_quantified = Common.union_set bfvs quantified in
- let (mefvs,mbfvs) =
- match seq_fvs minus_quantified
- [Ast.get_mfvs ifheader;Ast.get_mfvs branch;[]] with
- [(efvs,b1fvs);(_,b2fvs);_] -> (efvs,Common.union_set b1fvs b2fvs)
- | _ -> failwith "not possible" in
- let new_mquantified = Common.union_set mbfvs minus_quantified in
- (* if header *)
- let if_header = quantify guard efvs (make_match ifheader) in
- (* then branch and after *)
- let lv = get_label_ctr() in
- let used = ref false in
- let true_branch =
- make_seq guard
- [truepred label; recurse branch Tail new_quantified new_mquantified
- (Some (lv,used)) llabel slabel guard] in
- let after_pred = aftpred label in
- let or_cases after_branch =
- ctl_or true_branch (ctl_or (fallpred label) after_branch) in
- let (if_header,wrapper) =
- if !used
- then
- let label_pred = CTL.Pred (Lib_engine.Label(lv),CTL.Control) in
- (ctl_and CTL.NONSTRICT(*???*) if_header label_pred,
- (function body -> quantify true [lv] body))
- else (if_header,function x -> x) in
- wrapper
- (end_control_structure bfvs if_header or_cases after_pred
- (Some(ctl_ex after_pred)) None aft after label guard)
-
-let ifthenelse ifheader branch1 els branch2 ((afvs,_,_,_) as aft) after
- quantified minus_quantified label llabel slabel recurse make_match guard =
-(* "if (test) thn else els" becomes:
- if(test) & AX((TrueBranch & AX thn) v
- (FalseBranch & AX (else & AX els)) v After)
- & EX FalseBranch
-
- "if (test) thn else els; after" becomes:
- if(test) & AX((TrueBranch & AX thn) v
- (FalseBranch & AX (else & AX els)) v
- (After & AXAX after))
- & EX FalseBranch
- & EX After
-*)
- (* free variables *)
- let (e1fvs,b1fvs,s1fvs) =
- match seq_fvs quantified
- [Ast.get_fvs ifheader;Ast.get_fvs branch1;afvs] with
- [(e1fvs,b1fvs);(s1fvs,b1afvs);_] ->
- (e1fvs,Common.union_set b1fvs b1afvs,s1fvs)
- | _ -> failwith "not possible" in
- let (e2fvs,b2fvs,s2fvs) =
- (* fvs on else? *)
- match seq_fvs quantified
- [Ast.get_fvs ifheader;Ast.get_fvs branch2;afvs] with
- [(e2fvs,b2fvs);(s2fvs,b2afvs);_] ->
- (e2fvs,Common.union_set b2fvs b2afvs,s2fvs)
- | _ -> failwith "not possible" in
- let bothfvs = union (union b1fvs b2fvs) (intersect s1fvs s2fvs) in
- let exponlyfvs = intersect e1fvs e2fvs in
- let new_quantified = union bothfvs quantified in
- (* minus free variables *)
- let (me1fvs,mb1fvs,ms1fvs) =
- match seq_fvs minus_quantified
- [Ast.get_mfvs ifheader;Ast.get_mfvs branch1;[]] with
- [(e1fvs,b1fvs);(s1fvs,b1afvs);_] ->
- (e1fvs,Common.union_set b1fvs b1afvs,s1fvs)
- | _ -> failwith "not possible" in
- let (me2fvs,mb2fvs,ms2fvs) =
- (* fvs on else? *)
- match seq_fvs minus_quantified
- [Ast.get_mfvs ifheader;Ast.get_mfvs branch2;[]] with
- [(e2fvs,b2fvs);(s2fvs,b2afvs);_] ->
- (e2fvs,Common.union_set b2fvs b2afvs,s2fvs)
- | _ -> failwith "not possible" in
- let mbothfvs = union (union mb1fvs mb2fvs) (intersect ms1fvs ms2fvs) in
- let new_mquantified = union mbothfvs minus_quantified in
- (* if header *)
- let if_header = quantify guard exponlyfvs (make_match ifheader) in
- (* then and else branches *)
- let lv = get_label_ctr() in
- let used = ref false in
- let true_branch =
- make_seq guard
- [truepred label; recurse branch1 Tail new_quantified new_mquantified
- (Some (lv,used)) llabel slabel guard] in
- let false_branch =
- make_seq guard
- [falsepred label; make_match els;
- recurse branch2 Tail new_quantified new_mquantified
- (Some (lv,used)) llabel slabel guard] in
- let after_pred = aftpred label in
- let or_cases after_branch =
- ctl_or true_branch (ctl_or false_branch after_branch) in
- let s = guard_to_strict guard in
- let (if_header,wrapper) =
- if !used
- then
- let label_pred = CTL.Pred (Lib_engine.Label(lv),CTL.Control) in
- (ctl_and CTL.NONSTRICT(*???*) if_header label_pred,
- (function body -> quantify true [lv] body))
- else (if_header,function x -> x) in
- wrapper
- (end_control_structure bothfvs if_header or_cases after_pred
- (Some(ctl_and s (ctl_ex (falsepred label)) (ctl_ex after_pred)))
- (Some(ctl_ex (falsepred label)))
- aft after label guard)
-
-let forwhile header body ((afvs,_,_,_) as aft) after
- quantified minus_quantified label recurse make_match guard =
- let process _ =
- (* the translation in this case is similar to that of an if with no else *)
- (* free variables *)
- let (efvs,bfvs) =
- match seq_fvs quantified [Ast.get_fvs header;Ast.get_fvs body;afvs] with
- [(efvs,b1fvs);(_,b2fvs);_] -> (efvs,Common.union_set b1fvs b2fvs)
- | _ -> failwith "not possible" in
- let new_quantified = Common.union_set bfvs quantified in
- (* minus free variables *)
- let (mefvs,mbfvs) =
- match seq_fvs minus_quantified
- [Ast.get_mfvs header;Ast.get_mfvs body;[]] with
- [(efvs,b1fvs);(_,b2fvs);_] -> (efvs,Common.union_set b1fvs b2fvs)
- | _ -> failwith "not possible" in
- let new_mquantified = Common.union_set mbfvs minus_quantified in
- (* loop header *)
- let header = quantify guard efvs (make_match header) in
- let lv = get_label_ctr() in
- let used = ref false in
- let body =
- make_seq guard
- [inlooppred label;
- recurse body Tail new_quantified new_mquantified
- (Some (lv,used)) (Some (lv,used)) None guard] in
- let after_pred = fallpred label in
- let or_cases after_branch = ctl_or body after_branch in
- let (header,wrapper) =
- if !used
- then
- let label_pred = CTL.Pred (Lib_engine.Label(lv),CTL.Control) in
- (ctl_and CTL.NONSTRICT(*???*) header label_pred,
- (function body -> quantify true [lv] body))
- else (header,function x -> x) in
- wrapper
- (end_control_structure bfvs header or_cases after_pred
- (Some(ctl_ex after_pred)) None aft after label guard) in
- match (Ast.unwrap body,aft) with
- (Ast.Atomic(re),(_,_,_,Ast.CONTEXT(_,Ast.NOTHING))) ->
- (match Ast.unwrap re with
- Ast.MetaStmt((_,_,Ast.CONTEXT(_,Ast.NOTHING),_),
- Type_cocci.Unitary,_,false) ->
- let (efvs) =
- match seq_fvs quantified [Ast.get_fvs header] with
- [(efvs,_)] -> efvs
- | _ -> failwith "not possible" in
- quantify guard efvs (make_match header)
- | _ -> process())
- | _ -> process()
-
-(* --------------------------------------------------------------------- *)
-(* statement metavariables *)
-
-(* issue: an S metavariable that is not an if branch/loop body
- should not match an if branch/loop body, so check that the labels
- of the nodes before the first node matched by the S are different
- from the label of the first node matched by the S *)
-let sequencibility body label_pred process_bef_aft = function
- Ast.Sequencible | Ast.SequencibleAfterDots [] ->
- body
- (function x ->
- (ctl_and CTL.NONSTRICT (ctl_not (ctl_back_ax label_pred)) x))
- | Ast.SequencibleAfterDots l ->
- (* S appears after some dots. l is the code that comes after the S.
- want to search for that first, because S can match anything, while
- the stuff after is probably more restricted *)
- let afts = List.map process_bef_aft l in
- let ors = foldl1 ctl_or afts in
- ctl_and CTL.NONSTRICT
- (ctl_ef (ctl_and CTL.NONSTRICT ors (ctl_back_ax label_pred)))
- (body
- (function x ->
- ctl_and CTL.NONSTRICT (ctl_not (ctl_back_ax label_pred)) x))
- | Ast.NotSequencible -> body (function x -> x)
-
-let svar_context_with_add_after stmt s label quantified d ast
- seqible after process_bef_aft guard fvinfo =
- let label_var = (*fresh_label_var*) string2var "_lab" in
- let label_pred =
- CTL.Pred (Lib_engine.Label(label_var),CTL.Control) in
- let prelabel_pred =
- CTL.Pred (Lib_engine.PrefixLabel(label_var),CTL.Control) in
- let matcher d = make_match None guard (make_meta_rule_elem d fvinfo) in
- let full_metamatch = matcher d in
- let first_metamatch =
- matcher
- (match d with
- Ast.CONTEXT(pos,Ast.BEFOREAFTER(bef,_)) ->
- Ast.CONTEXT(pos,Ast.BEFORE(bef))
- | Ast.CONTEXT(pos,_) -> Ast.CONTEXT(pos,Ast.NOTHING)
- | Ast.MINUS(_,_) | Ast.PLUS -> failwith "not possible") in
- let middle_metamatch =
- matcher
- (match d with
- Ast.CONTEXT(pos,_) -> Ast.CONTEXT(pos,Ast.NOTHING)
- | Ast.MINUS(_,_) | Ast.PLUS -> failwith "not possible") in
- let last_metamatch =
- matcher
- (match d with
- Ast.CONTEXT(pos,Ast.BEFOREAFTER(_,aft)) ->
- Ast.CONTEXT(pos,Ast.AFTER(aft))
- | Ast.CONTEXT(_,_) -> d
- | Ast.MINUS(_,_) | Ast.PLUS -> failwith "not possible") in
-
- let rest_nodes =
- ctl_and CTL.NONSTRICT middle_metamatch prelabel_pred in
- let left_or = (* the whole statement is one node *)
- make_seq guard
- [full_metamatch; and_after guard (ctl_not prelabel_pred) after] in
- let right_or = (* the statement covers multiple nodes *)
- make_seq guard
- [first_metamatch;
- ctl_au CTL.NONSTRICT
- rest_nodes
- (make_seq guard
- [ctl_and CTL.NONSTRICT last_metamatch label_pred;
- and_after guard
- (ctl_not prelabel_pred) after])] in
- let body f =
- ctl_and CTL.NONSTRICT label_pred
- (f (ctl_and CTL.NONSTRICT
- (make_raw_match label false ast) (ctl_or left_or right_or))) in
- let stmt_fvs = Ast.get_fvs stmt in
- let fvs = get_unquantified quantified stmt_fvs in
- quantify guard (label_var::fvs)
- (sequencibility body label_pred process_bef_aft seqible)
-
-let svar_minus_or_no_add_after stmt s label quantified d ast
- seqible after process_bef_aft guard fvinfo =
- let label_var = (*fresh_label_var*) string2var "_lab" in
- let label_pred =
- CTL.Pred (Lib_engine.Label(label_var),CTL.Control) in
- let prelabel_pred =
- CTL.Pred (Lib_engine.PrefixLabel(label_var),CTL.Control) in
- let matcher d = make_match None guard (make_meta_rule_elem d fvinfo) in
- let pure_d =
- (* don't have to put anything before the beginning, so don't have to
- distinguish the first node. so don't have to bother about paths,
- just use the label. label ensures that found nodes match up with
- what they should because it is in the lhs of the andany. *)
- match d with
- Ast.MINUS(pos,[]) -> true
- | Ast.CONTEXT(pos,Ast.NOTHING) -> true
- | _ -> false in
- let ender =
- match (pure_d,after) with
- (true,Tail) | (true,End) | (true,VeryEnd) ->
- (* the label sharing makes it safe to use AndAny *)
- CTL.HackForStmt(CTL.FORWARD,CTL.NONSTRICT,
- ctl_and CTL.NONSTRICT label_pred
- (make_raw_match label false ast),
- ctl_and CTL.NONSTRICT (matcher d) prelabel_pred)
- | _ ->
- (* more safe but less efficient *)
- let first_metamatch = matcher d in
- let rest_metamatch =
- matcher
- (match d with
- Ast.MINUS(pos,_) -> Ast.MINUS(pos,[])
- | Ast.CONTEXT(pos,_) -> Ast.CONTEXT(pos,Ast.NOTHING)
- | Ast.PLUS -> failwith "not possible") in
- let rest_nodes = ctl_and CTL.NONSTRICT rest_metamatch prelabel_pred in
- let last_node = and_after guard (ctl_not prelabel_pred) after in
- (ctl_and CTL.NONSTRICT (make_raw_match label false ast)
- (make_seq guard
- [first_metamatch;
- ctl_au CTL.NONSTRICT rest_nodes last_node])) in
- let body f = ctl_and CTL.NONSTRICT label_pred (f ender) in
- let stmt_fvs = Ast.get_fvs stmt in
- let fvs = get_unquantified quantified stmt_fvs in
- quantify guard (label_var::fvs)
- (sequencibility body label_pred process_bef_aft seqible)
-
-(* --------------------------------------------------------------------- *)
-(* dots and nests *)
-
-let dots_au is_strict toend label s wrapcode x seq_after y quantifier =
- let matchgoto = gotopred None in
- let matchbreak =
- make_match None false
- (wrapcode
- (Ast.Break(Ast.make_mcode "break",Ast.make_mcode ";"))) in
- let matchcontinue =
- make_match None false
- (wrapcode
- (Ast.Continue(Ast.make_mcode "continue",Ast.make_mcode ";"))) in
- let stop_early v =
- if !exists = Exists
- then CTL.False
- else if toend
- then CTL.Or(aftpred label,exitpred label)
- else if is_strict
- then aftpred label
- else
- let lv = get_label_ctr() in
- let labelpred = CTL.Pred(Lib_engine.Label lv,CTL.Control) in
- let preflabelpred = label_pred_maker (Some (lv,ref true)) in
- ctl_or (aftpred label)
- (quantify false [lv]
- (ctl_and CTL.NONSTRICT
- (ctl_and CTL.NONSTRICT (truepred label) labelpred)
- (ctl_au CTL.NONSTRICT
- (ctl_and CTL.NONSTRICT (ctl_not v) preflabelpred)
- (ctl_and CTL.NONSTRICT preflabelpred
- (ctl_or (retpred None)
- (if !Flag_engine.only_return_is_error_exit
- then CTL.True
- else
- (ctl_or matchcontinue
- (ctl_and CTL.NONSTRICT
- (ctl_or matchgoto matchbreak)
- (ctl_ag s (ctl_not seq_after)))))))))) in
- let v = get_let_ctr() in
- let op = if quantifier = !exists then ctl_au else ctl_anti_au in
- op s x (CTL.Let(v,y,ctl_or (CTL.Ref v) (stop_early (CTL.Ref v))))
-
-let rec dots_and_nests plus nest whencodes bef aft dotcode after label
- process_bef_aft statement_list statement guard wrapcode =
- let ctl_and_ns = ctl_and CTL.NONSTRICT in
- (* proces bef_aft *)
- let shortest l =
- List.fold_left ctl_or_fl CTL.False (List.map process_bef_aft l) in
- let bef_aft = (* to be negated *)
- try
- let _ =
- List.find
- (function Ast.WhenModifier(Ast.WhenAny) -> true | _ -> false)
- whencodes in
- CTL.False
- with Not_found -> shortest (Common.union_set bef aft) in
- let is_strict =
- List.exists
- (function Ast.WhenModifier(Ast.WhenStrict) -> true | _ -> false)
- whencodes in
- let check_quantifier quant other =
- if List.exists
- (function Ast.WhenModifier(x) -> x = quant | _ -> false)
- whencodes
- then
- if List.exists
- (function Ast.WhenModifier(x) -> x = other | _ -> false)
- whencodes
- then failwith "inconsistent annotation on dots"
- else true
- else false in
- let quantifier =
- if check_quantifier Ast.WhenExists Ast.WhenForall
- then Exists
- else
- if check_quantifier Ast.WhenExists Ast.WhenForall
- then Forall
- else !exists in
- (* the following is used when we find a goto, etc and consider accepting
- without finding the rest of the pattern *)
- let aft = shortest aft in
- (* process whencode *)
- let labelled = label_pred_maker label in
- let whencodes arg =
- let (poswhen,negwhen) =
- List.fold_left
- (function (poswhen,negwhen) ->
- function
- Ast.WhenNot whencodes ->
- (poswhen,ctl_or (statement_list whencodes) negwhen)
- | Ast.WhenAlways stm ->
- (ctl_and CTL.NONSTRICT (statement stm) poswhen,negwhen)
- | Ast.WhenModifier(_) -> (poswhen,negwhen))
- (CTL.True,bef_aft) (List.rev whencodes) in
- let poswhen = ctl_and_ns arg poswhen in
- let negwhen =
-(* if !exists
- then*)
- (* add in After, because it's not part of the program *)
- ctl_or (aftpred label) negwhen
- (*else negwhen*) in
- ctl_and_ns poswhen (ctl_not negwhen) in
- (* process dot code, if any *)
- let dotcode =
- match (dotcode,guard) with
- (None,_) | (_,true) -> CTL.True
- | (Some dotcode,_) -> dotcode in
- (* process nest code, if any *)
- (* whencode goes in the negated part of the nest; if no nest, just goes
- on the "true" in between code *)
- let plus_var = if plus then get_label_ctr() else string2var "" in
- let plus_var2 = if plus then get_label_ctr() else string2var "" in
- let ornest =
- match (nest,guard && not plus) with
- (None,_) | (_,true) -> whencodes CTL.True
- | (Some nest,false) ->
- let v = get_let_ctr() in
- let is_plus x =
- if plus
- then
- (* the idea is that BindGood is sort of a witness; a witness to
- having found the subterm in at least one place. If there is
- not a witness, then there is a risk that it will get thrown
- away, if it is merged with a node that has an empty
- environment. See tests/nestplus. But this all seems
- rather suspicious *)
- CTL.And(CTL.NONSTRICT,x,
- CTL.Exists(true,plus_var2,
- CTL.Pred(Lib_engine.BindGood(plus_var),
- CTL.Modif plus_var2)))
- else x in
- CTL.Let(v,nest,
- CTL.Or(is_plus (CTL.Ref v),
- whencodes (CTL.Not(ctl_uncheck (CTL.Ref v))))) in
- let plus_modifier x =
- if plus
- then
- CTL.Exists
- (false,plus_var,
- (CTL.And
- (CTL.NONSTRICT,x,
- CTL.Not(CTL.Pred(Lib_engine.BindBad(plus_var),CTL.Control)))))
- else x in
-
- let ender =
- match after with
- After f -> f
- | Guard f -> ctl_uncheck f
- | VeryEnd ->
- let exit = endpred label in
- let errorexit = exitpred label in
- ctl_or exit errorexit
- (* not at all sure what the next two mean... *)
- | End -> CTL.True
- | Tail ->
- (match label with
- Some (lv,used) -> used := true;
- ctl_or (CTL.Pred(Lib_engine.Label lv,CTL.Control))
- (ctl_back_ex (ctl_or (retpred label) (gotopred label)))
- | None -> endpred label)
- (* was the following, but not clear why sgrep should allow
- incomplete patterns
- let exit = endpred label in
- let errorexit = exitpred label in
- if !exists
- then ctl_or exit errorexit (* end anywhere *)
- else exit (* end at the real end of the function *) *) in
- plus_modifier
- (dots_au is_strict ((after = Tail) or (after = VeryEnd))
- label (guard_to_strict guard) wrapcode
- (ctl_and_ns dotcode (ctl_and_ns ornest labelled))
- aft ender quantifier)
-
-(* --------------------------------------------------------------------- *)
-(* the main translation loop *)
-
-let rec statement_list stmt_list after quantified minus_quantified
- label llabel slabel dots_before guard =
- let isdots x =
- (* include Disj to be on the safe side *)
- match Ast.unwrap x with
- Ast.Dots _ | Ast.Nest _ | Ast.Disj _ -> true | _ -> false in
- let compute_label l e db = if db or isdots e then l else None in
- match Ast.unwrap stmt_list with
- Ast.DOTS(x) ->
- let rec loop quantified minus_quantified dots_before label llabel slabel
- = function
- ([],_,_) -> (match after with After f -> f | _ -> CTL.True)
- | ([e],_,_) ->
- statement e after quantified minus_quantified
- (compute_label label e dots_before)
- llabel slabel guard
- | (e::sl,fv::fvs,mfv::mfvs) ->
- let shared = intersectll fv fvs in
- let unqshared = get_unquantified quantified shared in
- let new_quantified = Common.union_set unqshared quantified in
- let minus_shared = intersectll mfv mfvs in
- let munqshared =
- get_unquantified minus_quantified minus_shared in
- let new_mquantified =
- Common.union_set munqshared minus_quantified in
- quantify guard unqshared
- (statement e
- (After
- (let (label1,llabel1,slabel1) =
- match Ast.unwrap e with
- Ast.Atomic(re) ->
- (match Ast.unwrap re with
- Ast.Goto _ -> (None,None,None)
- | _ -> (label,llabel,slabel))
- | _ -> (label,llabel,slabel) in
- loop new_quantified new_mquantified (isdots e)
- label1 llabel1 slabel1
- (sl,fvs,mfvs)))
- new_quantified new_mquantified
- (compute_label label e dots_before) llabel slabel guard)
- | _ -> failwith "not possible" in
- loop quantified minus_quantified dots_before
- label llabel slabel
- (x,List.map Ast.get_fvs x,List.map Ast.get_mfvs x)
- | Ast.CIRCLES(x) -> failwith "not supported"
- | Ast.STARS(x) -> failwith "not supported"
-
-(* llabel is the label of the enclosing loop and slabel is the label of the
- enclosing switch *)
-and statement stmt after quantified minus_quantified
- label llabel slabel guard =
- let ctl_au = ctl_au CTL.NONSTRICT in
- let ctl_ax = ctl_ax CTL.NONSTRICT in
- let ctl_and = ctl_and CTL.NONSTRICT in
- let make_seq = make_seq guard in
- let make_seq_after = make_seq_after guard in
- let real_make_match = make_match in
- let make_match = header_match label guard in
-
- let dots_done = ref false in (* hack for dots cases we can easily handle *)
-
- let term =
- match Ast.unwrap stmt with
- Ast.Atomic(ast) ->
- (match Ast.unwrap ast with
- (* the following optimisation is not a good idea, because when S
- is alone, we would like it not to match a declaration.
- this makes more matching for things like when (...) S, but perhaps
- that matching is not so costly anyway *)
- (*Ast.MetaStmt(_,Type_cocci.Unitary,_,false) when guard -> CTL.True*)
- | Ast.MetaStmt((s,_,(Ast.CONTEXT(_,Ast.BEFOREAFTER(_,_)) as d),_),
- keep,seqible,_)
- | Ast.MetaStmt((s,_,(Ast.CONTEXT(_,Ast.AFTER(_)) as d),_),
- keep,seqible,_)->
- svar_context_with_add_after stmt s label quantified d ast seqible
- after
- (process_bef_aft quantified minus_quantified
- label llabel slabel true)
- guard
- (Ast.get_fvs stmt, Ast.get_fresh stmt, Ast.get_inherited stmt)
-
- | Ast.MetaStmt((s,_,d,_),keep,seqible,_) ->
- svar_minus_or_no_add_after stmt s label quantified d ast seqible
- after
- (process_bef_aft quantified minus_quantified
- label llabel slabel true)
- guard
- (Ast.get_fvs stmt, Ast.get_fresh stmt, Ast.get_inherited stmt)
-
- | _ ->
- let term =
- match Ast.unwrap ast with
- Ast.DisjRuleElem(res) ->
- do_re_matches label guard res quantified minus_quantified
- | Ast.Exp(_) | Ast.Ty(_) ->
- let stmt_fvs = Ast.get_fvs stmt in
- let fvs = get_unquantified quantified stmt_fvs in
- CTL.InnerAnd(quantify guard fvs (make_match ast))
- | _ ->
- let stmt_fvs = Ast.get_fvs stmt in
- let fvs = get_unquantified quantified stmt_fvs in
- quantify guard fvs (make_match ast) in
- match Ast.unwrap ast with
- Ast.Break(brk,semi) ->
- (match (llabel,slabel) with
- (_,Some(lv,used)) -> (* use switch label if there is one *)
- ctl_and term (bclabel_pred_maker slabel)
- | _ -> ctl_and term (bclabel_pred_maker llabel))
- | Ast.Continue(brk,semi) -> ctl_and term (bclabel_pred_maker llabel)
- | Ast.Return((_,info,retmc,pos),(_,_,semmc,_)) ->
- (* discard pattern that comes after return *)
- let normal_res = make_seq_after term after in
- (* the following code tries to propagate the modifications on
- return; to a close brace, in the case where the final return
- is absent *)
- let new_mc =
- match (retmc,semmc) with
- (Ast.MINUS(_,l1),Ast.MINUS(_,l2)) when !Flag.sgrep_mode2 ->
- (* in sgrep mode, we can propagate the - *)
- Some (Ast.MINUS(Ast.NoPos,l1@l2))
- | (Ast.MINUS(_,l1),Ast.MINUS(_,l2))
- | (Ast.CONTEXT(_,Ast.BEFORE(l1)),
- Ast.CONTEXT(_,Ast.AFTER(l2))) ->
- Some (Ast.CONTEXT(Ast.NoPos,Ast.BEFORE(l1@l2)))
- | (Ast.CONTEXT(_,Ast.BEFORE(_)),Ast.CONTEXT(_,Ast.NOTHING))
- | (Ast.CONTEXT(_,Ast.NOTHING),Ast.CONTEXT(_,Ast.NOTHING)) ->
- Some retmc
- | (Ast.CONTEXT(_,Ast.NOTHING),Ast.CONTEXT(_,Ast.AFTER(l))) ->
- Some (Ast.CONTEXT(Ast.NoPos,Ast.BEFORE(l)))
- | _ -> None in
- let ret = Ast.make_mcode "return" in
- let edots =
- Ast.rewrap ast (Ast.Edots(Ast.make_mcode "...",None)) in
- let semi = Ast.make_mcode ";" in
- let simple_return =
- make_match(Ast.rewrap ast (Ast.Return(ret,semi))) in
- let return_expr =
- make_match(Ast.rewrap ast (Ast.ReturnExpr(ret,edots,semi))) in
- (match new_mc with
- Some new_mc ->
- let exit = endpred None in
- let mod_rbrace =
- Ast.rewrap ast (Ast.SeqEnd (("}",info,new_mc,pos))) in
- let stripped_rbrace =
- Ast.rewrap ast (Ast.SeqEnd(Ast.make_mcode "}")) in
- ctl_or normal_res
- (ctl_and (make_match mod_rbrace)
- (ctl_and
- (ctl_back_ax
- (ctl_not
- (ctl_uncheck
- (ctl_or simple_return return_expr))))
- (ctl_au
- (make_match stripped_rbrace)
- (* error exit not possible; it is in the middle
- of code, so a return is needed *)
- exit)))
- | _ ->
- (* some change in the middle of the return, so have to
- find an actual return *)
- normal_res)
- | _ ->
- (* should try to deal with the dots_bef_aft problem elsewhere,
- but don't have the courage... *)
- let term =
- if guard
- then term
- else
- do_between_dots stmt term End
- quantified minus_quantified label llabel slabel guard in
- dots_done := true;
- make_seq_after term after)
- | Ast.Seq(lbrace,decls,body,rbrace) ->
- let (lbfvs,b1fvs,b2fvs,b3fvs,rbfvs) =
- match
- seq_fvs quantified
- [Ast.get_fvs lbrace;Ast.get_fvs decls;
- Ast.get_fvs body;Ast.get_fvs rbrace]
- with
- [(lbfvs,b1fvs);(_,b2fvs);(_,b3fvs);(rbfvs,_)] ->
- (lbfvs,b1fvs,b2fvs,b3fvs,rbfvs)
- | _ -> failwith "not possible" in
- let (mlbfvs,mb1fvs,mb2fvs,mb3fvs,mrbfvs) =
- match
- seq_fvs minus_quantified
- [Ast.get_mfvs lbrace;Ast.get_mfvs decls;
- Ast.get_mfvs body;Ast.get_mfvs rbrace]
- with
- [(lbfvs,b1fvs);(_,b2fvs);(_,b3fvs);(rbfvs,_)] ->
- (lbfvs,b1fvs,b2fvs,b3fvs,rbfvs)
- | _ -> failwith "not possible" in
- let pv = count_nested_braces stmt in
- let lv = get_label_ctr() in
- let paren_pred = CTL.Pred(Lib_engine.Paren pv,CTL.Control) in
- let label_pred = CTL.Pred(Lib_engine.Label lv,CTL.Control) in
- let start_brace =
- ctl_and
- (quantify guard lbfvs (make_match lbrace))
- (ctl_and paren_pred label_pred) in
- let end_brace =
- (* label is not needed; paren_pred is enough *)
- ctl_and
- (quantify guard rbfvs (real_make_match None guard rbrace))
- paren_pred in
- let new_quantified2 =
- Common.union_set b1fvs (Common.union_set b2fvs quantified) in
- let new_quantified3 = Common.union_set b3fvs new_quantified2 in
- let new_mquantified2 =
- Common.union_set mb1fvs (Common.union_set mb2fvs minus_quantified) in
- let new_mquantified3 = Common.union_set mb3fvs new_mquantified2 in
- let pattern_as_given =
- let new_quantified2 = Common.union_set [pv] new_quantified2 in
- let new_quantified3 = Common.union_set [pv] new_quantified3 in
- quantify true [pv;lv]
- (quantify guard b1fvs
- (make_seq
- [start_brace;
- quantify guard b2fvs
- (statement_list decls
- (After
- (quantify guard b3fvs
- (statement_list body
- (After (make_seq_after end_brace after))
- new_quantified3 new_mquantified3
- (Some (lv,ref true)) (* label mostly useful *)
- llabel slabel true guard)))
- new_quantified2 new_mquantified2
- (Some (lv,ref true)) llabel slabel false guard)])) in
- if ends_in_return body
- then
- (* matching error handling code *)
- (* Cases:
- 1. The pattern as given
- 2. A goto, and then some close braces, and then the pattern as
- given, but without the braces (only possible if there are no
- decls, and open and close braces are unmodified)
- 3. Part of the pattern as given, then a goto, and then the rest
- of the pattern. For this case, we just check that all paths have
- a goto within the current braces. checking for a goto at every
- point in the pattern seems expensive and not worthwhile. *)
- let pattern2 =
- let empty_rbrace =
- match Ast.unwrap rbrace with
- Ast.SeqEnd((data,info,_,pos)) ->
- Ast.rewrap rbrace(Ast.SeqEnd(Ast.make_mcode data))
- | _ -> failwith "unexpected close brace" in
- let body = preprocess_dots body in (* redo, to drop braces *)
- make_seq
- [gotopred label;
- ctl_au
- (make_match empty_rbrace)
- (ctl_ax (* skip the destination label *)
- (quantify guard b3fvs
- (statement_list body End
- new_quantified3 new_mquantified3 None llabel slabel
- true guard)))] in
- let pattern3 =
- let new_quantified2 = Common.union_set [pv] new_quantified2 in
- let new_quantified3 = Common.union_set [pv] new_quantified3 in
- quantify true [pv;lv]
- (quantify guard b1fvs
- (make_seq
- [start_brace;
- ctl_and
- (CTL.AU (* want AF even for sgrep *)
- (CTL.FORWARD,CTL.STRICT,
- CTL.Pred(Lib_engine.PrefixLabel(lv),CTL.Control),
- ctl_and (* brace must be eventually after goto *)
- (gotopred (Some (lv,ref true)))
- (* want AF even for sgrep *)
- (CTL.AF(CTL.FORWARD,CTL.STRICT,end_brace))))
- (quantify guard b2fvs
- (statement_list decls
- (After
- (quantify guard b3fvs
- (statement_list body Tail
- (*After
- (make_seq_after
- nopv_end_brace after)*)
- new_quantified3 new_mquantified3
- None llabel slabel true guard)))
- new_quantified2 new_mquantified2
- (Some (lv,ref true))
- llabel slabel false guard))])) in
- ctl_or pattern_as_given
- (match Ast.unwrap decls with
- Ast.DOTS([]) -> ctl_or pattern2 pattern3
- | Ast.DOTS(l) -> pattern3
- | _ -> failwith "circles and stars not supported")
- else pattern_as_given
- | Ast.IfThen(ifheader,branch,aft) ->
- ifthen ifheader branch aft after quantified minus_quantified
- label llabel slabel statement make_match guard
-
- | Ast.IfThenElse(ifheader,branch1,els,branch2,aft) ->
- ifthenelse ifheader branch1 els branch2 aft after quantified
- minus_quantified label llabel slabel statement make_match guard
-
- | Ast.While(header,body,aft) | Ast.For(header,body,aft)
- | Ast.Iterator(header,body,aft) ->
- forwhile header body aft after quantified minus_quantified
- label statement make_match guard
-
- | Ast.Disj(stmt_dots_list) -> (* list shouldn't be empty *)
- ctl_and
- (label_pred_maker label)
- (List.fold_left ctl_seqor CTL.False
- (List.map
- (function sl ->
- statement_list sl after quantified minus_quantified label
- llabel slabel true guard)
- stmt_dots_list))
-
- | Ast.Nest(stmt_dots,whencode,multi,bef,aft) ->
- (* label in recursive call is None because label check is already
- wrapped around the corresponding code *)
-
- let bfvs =
- match seq_fvs quantified [Ast.get_wcfvs whencode;Ast.get_fvs stmt_dots]
- with
- [(wcfvs,bothfvs);(bdfvs,_)] -> bothfvs
- | _ -> failwith "not possible" in
-
- (* no minus version because when code doesn't contain any minus code *)
- let new_quantified = Common.union_set bfvs quantified in
-
- quantify guard bfvs
- (let dots_pattern =
- statement_list stmt_dots (a2n after) new_quantified minus_quantified
- None llabel slabel true guard in
- dots_and_nests multi
- (Some dots_pattern) whencode bef aft None after label
- (process_bef_aft new_quantified minus_quantified
- None llabel slabel true)
- (function x ->
- statement_list x Tail new_quantified minus_quantified None
- llabel slabel true true)
- (function x ->
- statement x Tail new_quantified minus_quantified None
- llabel slabel true)
- guard (function x -> Ast.set_fvs [] (Ast.rewrap stmt x)))
-
- | Ast.Dots((_,i,d,_),whencodes,bef,aft) ->
- let dot_code =
- match d with
- Ast.MINUS(_,_) ->
- (* no need for the fresh metavar, but ... is a bit wierd as a
- variable name *)
- Some(make_match (make_meta_rule_elem d ([],[],[])))
- | _ -> None in
- dots_and_nests false None whencodes bef aft dot_code after label
- (process_bef_aft quantified minus_quantified None llabel slabel true)
- (function x ->
- statement_list x Tail quantified minus_quantified
- None llabel slabel true true)
- (function x ->
- statement x Tail quantified minus_quantified None llabel slabel true)
- guard (function x -> Ast.set_fvs [] (Ast.rewrap stmt x))
-
- | Ast.Switch(header,lb,cases,rb) ->
- let rec intersect_all = function
- [] -> []
- | [x] -> x
- | x::xs -> intersect x (intersect_all xs) in
- let rec union_all l = List.fold_left union [] l in
- (* start normal variables *)
- let header_fvs = Ast.get_fvs header in
- let lb_fvs = Ast.get_fvs lb in
- let case_fvs = List.map Ast.get_fvs cases in
- let rb_fvs = Ast.get_fvs rb in
- let (all_efvs,all_b1fvs,all_lbfvs,all_b2fvs,
- all_casefvs,all_b3fvs,all_rbfvs) =
- List.fold_left
- (function (all_efvs,all_b1fvs,all_lbfvs,all_b2fvs,
- all_casefvs,all_b3fvs,all_rbfvs) ->
- function case_fvs ->
- match seq_fvs quantified [header_fvs;lb_fvs;case_fvs;rb_fvs] with
- [(efvs,b1fvs);(lbfvs,b2fvs);(casefvs,b3fvs);(rbfvs,_)] ->
- (efvs::all_efvs,b1fvs::all_b1fvs,lbfvs::all_lbfvs,
- b2fvs::all_b2fvs,casefvs::all_casefvs,b3fvs::all_b3fvs,
- rbfvs::all_rbfvs)
- | _ -> failwith "not possible")
- ([],[],[],[],[],[],[]) case_fvs in
- let (all_efvs,all_b1fvs,all_lbfvs,all_b2fvs,
- all_casefvs,all_b3fvs,all_rbfvs) =
- (List.rev all_efvs,List.rev all_b1fvs,List.rev all_lbfvs,
- List.rev all_b2fvs,List.rev all_casefvs,List.rev all_b3fvs,
- List.rev all_rbfvs) in
- let exponlyfvs = intersect_all all_efvs in
- let lbonlyfvs = intersect_all all_lbfvs in
-(* don't do anything with right brace. Hope there is no + code on it *)
-(* let rbonlyfvs = intersect_all all_rbfvs in*)
- let b1fvs = union_all all_b1fvs in
- let new1_quantified = union b1fvs quantified in
- let b2fvs = union (union_all all_b1fvs) (intersect_all all_casefvs) in
- let new2_quantified = union b2fvs new1_quantified in
-(* let b3fvs = union_all all_b3fvs in*)
- (* ------------------- start minus free variables *)
- let header_mfvs = Ast.get_mfvs header in
- let lb_mfvs = Ast.get_mfvs lb in
- let case_mfvs = List.map Ast.get_mfvs cases in
- let rb_mfvs = Ast.get_mfvs rb in
- let (all_mefvs,all_mb1fvs,all_mlbfvs,all_mb2fvs,
- all_mcasefvs,all_mb3fvs,all_mrbfvs) =
- List.fold_left
- (function (all_efvs,all_b1fvs,all_lbfvs,all_b2fvs,
- all_casefvs,all_b3fvs,all_rbfvs) ->
- function case_mfvs ->
- match
- seq_fvs quantified
- [header_mfvs;lb_mfvs;case_mfvs;rb_mfvs] with
- [(efvs,b1fvs);(lbfvs,b2fvs);(casefvs,b3fvs);(rbfvs,_)] ->
- (efvs::all_efvs,b1fvs::all_b1fvs,lbfvs::all_lbfvs,
- b2fvs::all_b2fvs,casefvs::all_casefvs,b3fvs::all_b3fvs,
- rbfvs::all_rbfvs)
- | _ -> failwith "not possible")
- ([],[],[],[],[],[],[]) case_mfvs in
- let (all_mefvs,all_mb1fvs,all_mlbfvs,all_mb2fvs,
- all_mcasefvs,all_mb3fvs,all_mrbfvs) =
- (List.rev all_mefvs,List.rev all_mb1fvs,List.rev all_mlbfvs,
- List.rev all_mb2fvs,List.rev all_mcasefvs,List.rev all_mb3fvs,
- List.rev all_mrbfvs) in
-(* don't do anything with right brace. Hope there is no + code on it *)
-(* let rbonlyfvs = intersect_all all_rbfvs in*)
- let mb1fvs = union_all all_mb1fvs in
- let new1_mquantified = union mb1fvs quantified in
- let mb2fvs = union (union_all all_mb1fvs) (intersect_all all_mcasefvs) in
- let new2_mquantified = union mb2fvs new1_mquantified in
-(* let b3fvs = union_all all_b3fvs in*)
- (* ------------------- end collection of free variables *)
- let switch_header = quantify guard exponlyfvs (make_match header) in
- let lb = quantify guard lbonlyfvs (make_match lb) in
-(* let rb = quantify guard rbonlyfvs (make_match rb) in*)
- let case_headers =
- List.map
- (function case_line ->
- match Ast.unwrap case_line with
- Ast.CaseLine(header,body) ->
- let e1fvs =
- match seq_fvs new2_quantified [Ast.get_fvs header] with
- [(e1fvs,_)] -> e1fvs
- | _ -> failwith "not possible" in
- quantify guard e1fvs (real_make_match label true header)
- | Ast.OptCase(case_line) -> failwith "not supported")
- cases in
- let no_header =
- ctl_not (List.fold_left ctl_or_fl CTL.False case_headers) in
- let lv = get_label_ctr() in
- let used = ref false in
- let case_code =
- List.map
- (function case_line ->
- match Ast.unwrap case_line with
- Ast.CaseLine(header,body) ->
- let (e1fvs,b1fvs,s1fvs) =
- let fvs = [Ast.get_fvs header;Ast.get_fvs body] in
- match seq_fvs new2_quantified fvs with
- [(e1fvs,b1fvs);(s1fvs,_)] -> (e1fvs,b1fvs,s1fvs)
- | _ -> failwith "not possible" in
- let (me1fvs,mb1fvs,ms1fvs) =
- let fvs = [Ast.get_mfvs header;Ast.get_mfvs body] in
- match seq_fvs new2_mquantified fvs with
- [(e1fvs,b1fvs);(s1fvs,_)] -> (e1fvs,b1fvs,s1fvs)
- | _ -> failwith "not possible" in
- let case_header =
- quantify guard e1fvs (make_match header) in
- let new3_quantified = union b1fvs new2_quantified in
- let new3_mquantified = union mb1fvs new2_mquantified in
- let body =
- statement_list body Tail
- new3_quantified new3_mquantified label llabel
- (Some (lv,used)) true(*?*) guard in
- quantify guard b1fvs (make_seq [case_header; body])
- | Ast.OptCase(case_line) -> failwith "not supported")
- cases in
- let default_required =
- if List.exists
- (function case ->
- match Ast.unwrap case with
- Ast.CaseLine(header,_) ->
- (match Ast.unwrap header with
- Ast.Default(_,_) -> true
- | _ -> false)
- | _ -> false)
- cases
- then function x -> x
- else function x -> ctl_or (fallpred label) x in
- let after_pred = aftpred label in
- let body after_branch =
- ctl_or
- (default_required
- (quantify guard b2fvs
- (make_seq
- [ctl_and lb
- (List.fold_left ctl_and CTL.True
- (List.map ctl_ex case_headers));
- List.fold_left ctl_or_fl no_header case_code])))
- after_branch in
- let aft =
- (rb_fvs,Ast.get_fresh rb,Ast.get_inherited rb,
- match Ast.unwrap rb with
- Ast.SeqEnd(rb) -> Ast.get_mcodekind rb
- | _ -> failwith "not possible") in
- let (switch_header,wrapper) =
- if !used
- then
- let label_pred = CTL.Pred (Lib_engine.Label(lv),CTL.Control) in
- (ctl_and switch_header label_pred,
- (function body -> quantify true [lv] body))
- else (switch_header,function x -> x) in
- wrapper
- (end_control_structure b1fvs switch_header body
- after_pred (Some(ctl_ex after_pred)) None aft after label guard)
- | Ast.FunDecl(header,lbrace,decls,body,rbrace) ->
- let (hfvs,b1fvs,lbfvs,b2fvs,b3fvs,b4fvs,rbfvs) =
- match
- seq_fvs quantified
- [Ast.get_fvs header;Ast.get_fvs lbrace;Ast.get_fvs decls;
- Ast.get_fvs body;Ast.get_fvs rbrace]
- with
- [(hfvs,b1fvs);(lbfvs,b2fvs);(_,b3fvs);(_,b4fvs);(rbfvs,_)] ->
- (hfvs,b1fvs,lbfvs,b2fvs,b3fvs,b4fvs,rbfvs)
- | _ -> failwith "not possible" in
- let (mhfvs,mb1fvs,mlbfvs,mb2fvs,mb3fvs,mb4fvs,mrbfvs) =
- match
- seq_fvs quantified
- [Ast.get_mfvs header;Ast.get_mfvs lbrace;Ast.get_mfvs decls;
- Ast.get_mfvs body;Ast.get_mfvs rbrace]
- with
- [(hfvs,b1fvs);(lbfvs,b2fvs);(_,b3fvs);(_,b4fvs);(rbfvs,_)] ->
- (hfvs,b1fvs,lbfvs,b2fvs,b3fvs,b4fvs,rbfvs)
- | _ -> failwith "not possible" in
- let function_header = quantify guard hfvs (make_match header) in
- let start_brace = quantify guard lbfvs (make_match lbrace) in
- let stripped_rbrace =
- match Ast.unwrap rbrace with
- Ast.SeqEnd((data,info,_,_)) ->
- Ast.rewrap rbrace(Ast.SeqEnd (Ast.make_mcode data))
- | _ -> failwith "unexpected close brace" in
- let end_brace =
- let exit = CTL.Pred (Lib_engine.Exit,CTL.Control) in
- let errorexit = CTL.Pred (Lib_engine.ErrorExit,CTL.Control) in
- let fake_brace = CTL.Pred (Lib_engine.FakeBrace,CTL.Control) in
- ctl_and
- (quantify guard rbfvs (make_match rbrace))
- (ctl_and
- (* the following finds the beginning of the fake braces,
- if there are any, not completely sure how this works.
- sse the examples sw and return *)
- (ctl_back_ex (ctl_not fake_brace))
- (ctl_au (make_match stripped_rbrace) (ctl_or exit errorexit))) in
- let new_quantified3 =
- Common.union_set b1fvs
- (Common.union_set b2fvs (Common.union_set b3fvs quantified)) in
- let new_quantified4 = Common.union_set b4fvs new_quantified3 in
- let new_mquantified3 =
- Common.union_set mb1fvs
- (Common.union_set mb2fvs
- (Common.union_set mb3fvs minus_quantified)) in
- let new_mquantified4 = Common.union_set mb4fvs new_mquantified3 in
- let fn_nest =
- match (Ast.undots decls,Ast.undots body,contains_modif rbrace) with
- ([],[body],false) ->
- (match Ast.unwrap body with
- Ast.Nest(stmt_dots,[],multi,_,_) ->
- if multi
- then None (* not sure how to optimize this case *)
- else Some (Common.Left stmt_dots)
- | Ast.Dots(_,whencode,_,_) -> Some (Common.Right whencode)
- | _ -> None)
- | _ -> None in
- let body_code =
- match fn_nest with
- Some (Common.Left stmt_dots) ->
- (* special case for function header + body - header is unambiguous
- and unique, so we can just look for the nested body anywhere
- else in the CFG *)
- CTL.AndAny
- (CTL.FORWARD,guard_to_strict guard,start_brace,
- statement_list stmt_dots
- (* discards match on right brace, but don't need it *)
- (Guard (make_seq_after end_brace after))
- new_quantified4 new_mquantified4
- None llabel slabel true guard)
- | Some (Common.Right whencode) ->
- (* try to be more efficient for the case where the body is just
- ... Perhaps this is too much of a special case, but useful
- for dropping a parameter and checking that it is never used. *)
- make_seq
- [start_brace;
- match whencode with
- [] -> CTL.True
- | _ ->
- let leftarg =
- ctl_and
- (ctl_not
- (List.fold_left
- (function prev ->
- function
- Ast.WhenAlways(s) -> prev
- | Ast.WhenNot(sl) ->
- let x =
- statement_list sl Tail
- new_quantified4 new_mquantified4
- label llabel slabel true true in
- ctl_or prev x
- | Ast.WhenModifier(Ast.WhenAny) -> CTL.False
- | Ast.WhenModifier(_) -> prev)
- CTL.False whencode))
- (List.fold_left
- (function prev ->
- function
- Ast.WhenAlways(s) ->
- let x =
- statement s Tail
- new_quantified4 new_mquantified4
- label llabel slabel true in
- ctl_and prev x
- | Ast.WhenNot(sl) -> prev
- | Ast.WhenModifier(Ast.WhenAny) -> CTL.True
- | Ast.WhenModifier(_) -> prev)
- CTL.True whencode) in
- ctl_au leftarg (make_match stripped_rbrace)]
- | None ->
- make_seq
- [start_brace;
- quantify guard b3fvs
- (statement_list decls
- (After
- (quantify guard b4fvs
- (statement_list body
- (After (make_seq_after end_brace after))
- new_quantified4 new_mquantified4
- None llabel slabel true guard)))
- new_quantified3 new_mquantified3 None llabel slabel
- false guard)] in
- quantify guard b1fvs
- (make_seq [function_header; quantify guard b2fvs body_code])
- | Ast.Define(header,body) ->
- let (hfvs,bfvs,bodyfvs) =
- match seq_fvs quantified [Ast.get_fvs header;Ast.get_fvs body]
- with
- [(hfvs,b1fvs);(bodyfvs,_)] -> (hfvs,b1fvs,bodyfvs)
- | _ -> failwith "not possible" in
- let (mhfvs,mbfvs,mbodyfvs) =
- match seq_fvs minus_quantified [Ast.get_mfvs header;Ast.get_mfvs body]
- with
- [(hfvs,b1fvs);(bodyfvs,_)] -> (hfvs,b1fvs,bodyfvs)
- | _ -> failwith "not possible" in
- let define_header = quantify guard hfvs (make_match header) in
- let body_code =
- statement_list body after
- (Common.union_set bfvs quantified)
- (Common.union_set mbfvs minus_quantified)
- None llabel slabel true guard in
- quantify guard bfvs (make_seq [define_header; body_code])
- | Ast.OptStm(stm) ->
- failwith "OptStm should have been compiled away\n"
- | Ast.UniqueStm(stm) -> failwith "arities not yet supported"
- | _ -> failwith "not supported" in
- if guard or !dots_done
- then term
- else
- do_between_dots stmt term after quantified minus_quantified
- label llabel slabel guard
-
-(* term is the translation of stmt *)
-and do_between_dots stmt term after quantified minus_quantified
- label llabel slabel guard =
- match Ast.get_dots_bef_aft stmt with
- Ast.AddingBetweenDots (brace_term,n)
- | Ast.DroppingBetweenDots (brace_term,n) ->
- let match_brace =
- statement brace_term after quantified minus_quantified
- label llabel slabel guard in
- let v = Printf.sprintf "_r_%d" n in
- let case1 = ctl_and CTL.NONSTRICT (CTL.Ref v) match_brace in
- let case2 = ctl_and CTL.NONSTRICT (ctl_not (CTL.Ref v)) term in
- CTL.Let
- (v,ctl_or
- (ctl_back_ex (ctl_or (truepred label) (inlooppred label)))
- (ctl_back_ex (ctl_back_ex (falsepred label))),
- ctl_or case1 case2)
- | Ast.NoDots -> term
-
-(* un_process_bef_aft is because we don't want to do transformation in this
- code, and thus don't case about braces before or after it *)
-and process_bef_aft quantified minus_quantified label llabel slabel guard =
- function
- Ast.WParen (re,n) ->
- let paren_pred = CTL.Pred (Lib_engine.Paren n,CTL.Control) in
- let s = guard_to_strict guard in
- quantify true (get_unquantified quantified [n])
- (ctl_and s (make_raw_match None guard re) paren_pred)
- | Ast.Other s ->
- statement s Tail quantified minus_quantified label llabel slabel guard
- | Ast.Other_dots d ->
- statement_list d Tail quantified minus_quantified
- label llabel slabel true guard
-
-(* --------------------------------------------------------------------- *)
-(* cleanup: convert AX to EX for pdots.
-Concretely: AX(A[...] & E[...]) becomes AX(A[...]) & EX(E[...])
-This is what we wanted in the first place, but it wasn't possible to make
-because the AX and its argument are not created in the same place.
-Rather clunky... *)
-(* also cleanup XX, which is a marker for the case where the programmer
-specifies to change the quantifier on .... Assumed to only occur after one AX
-or EX, or at top level. *)
-
-let rec cleanup c =
- let c = match c with CTL.XX(c) -> c | _ -> c in
- match c with
- CTL.False -> CTL.False
- | CTL.True -> CTL.True
- | CTL.Pred(p) -> CTL.Pred(p)
- | CTL.Not(phi) -> CTL.Not(cleanup phi)
- | CTL.Exists(keep,v,phi) -> CTL.Exists(keep,v,cleanup phi)
- | CTL.AndAny(dir,s,phi1,phi2) ->
- CTL.AndAny(dir,s,cleanup phi1,cleanup phi2)
- | CTL.HackForStmt(dir,s,phi1,phi2) ->
- CTL.HackForStmt(dir,s,cleanup phi1,cleanup phi2)
- | CTL.And(s,phi1,phi2) -> CTL.And(s,cleanup phi1,cleanup phi2)
- | CTL.Or(phi1,phi2) -> CTL.Or(cleanup phi1,cleanup phi2)
- | CTL.SeqOr(phi1,phi2) -> CTL.SeqOr(cleanup phi1,cleanup phi2)
- | CTL.Implies(phi1,phi2) -> CTL.Implies(cleanup phi1,cleanup phi2)
- | CTL.AF(dir,s,phi1) -> CTL.AF(dir,s,cleanup phi1)
- | CTL.AX(CTL.FORWARD,s,
- CTL.Let(v1,e1,
- CTL.And(CTL.NONSTRICT,CTL.AU(CTL.FORWARD,s2,e2,e3),
- CTL.EU(CTL.FORWARD,e4,e5)))) ->
- CTL.Let(v1,e1,
- CTL.And(CTL.NONSTRICT,
- CTL.AX(CTL.FORWARD,s,CTL.AU(CTL.FORWARD,s2,e2,e3)),
- CTL.EX(CTL.FORWARD,CTL.EU(CTL.FORWARD,e4,e5))))
- | CTL.AX(dir,s,CTL.XX(phi)) -> CTL.EX(dir,CTL.XX(cleanup phi))
- | CTL.EX(dir,CTL.XX((CTL.AU(_,s,_,_)) as phi)) ->
- CTL.AX(dir,s,CTL.XX(cleanup phi))
- | CTL.XX(phi) -> failwith "bad XX"
- | CTL.AX(dir,s,phi1) -> CTL.AX(dir,s,cleanup phi1)
- | CTL.AG(dir,s,phi1) -> CTL.AG(dir,s,cleanup phi1)
- | CTL.EF(dir,phi1) -> CTL.EF(dir,cleanup phi1)
- | CTL.EX(dir,phi1) -> CTL.EX(dir,cleanup phi1)
- | CTL.EG(dir,phi1) -> CTL.EG(dir,cleanup phi1)
- | CTL.AW(dir,s,phi1,phi2) -> CTL.AW(dir,s,cleanup phi1,cleanup phi2)
- | CTL.AU(dir,s,phi1,phi2) -> CTL.AU(dir,s,cleanup phi1,cleanup phi2)
- | CTL.EU(dir,phi1,phi2) -> CTL.EU(dir,cleanup phi1,cleanup phi2)
- | CTL.Let (x,phi1,phi2) -> CTL.Let (x,cleanup phi1,cleanup phi2)
- | CTL.LetR (dir,x,phi1,phi2) -> CTL.LetR (dir,x,cleanup phi1,cleanup phi2)
- | CTL.Ref(s) -> CTL.Ref(s)
- | CTL.Uncheck(phi1) -> CTL.Uncheck(cleanup phi1)
- | CTL.InnerAnd(phi1) -> CTL.InnerAnd(cleanup phi1)
-
-(* --------------------------------------------------------------------- *)
-(* Function declaration *)
-
-let top_level name (ua,pos) t =
- let ua = List.filter (function (nm,_) -> nm = name) ua in
- used_after := ua;
- saved := Ast.get_saved t;
- let quantified = Common.minus_set ua pos in
- quantify false quantified
- (match Ast.unwrap t with
- Ast.FILEINFO(old_file,new_file) -> failwith "not supported fileinfo"
- | Ast.DECL(stmt) ->
- let unopt = elim_opt.V.rebuilder_statement stmt in
- let unopt = preprocess_dots_e unopt in
- cleanup(statement unopt VeryEnd quantified [] None None None false)
- | Ast.CODE(stmt_dots) ->
- let unopt = elim_opt.V.rebuilder_statement_dots stmt_dots in
- let unopt = preprocess_dots unopt in
- let starts_with_dots =
- match Ast.undots stmt_dots with
- d::ds ->
- (match Ast.unwrap d with
- Ast.Dots(_,_,_,_) | Ast.Circles(_,_,_,_)
- | Ast.Stars(_,_,_,_) -> true
- | _ -> false)
- | _ -> false in
- let starts_with_brace =
- match Ast.undots stmt_dots with
- d::ds ->
- (match Ast.unwrap d with
- Ast.Seq(_) -> true
- | _ -> false)
- | _ -> false in
- let res =
- statement_list unopt VeryEnd quantified [] None None None
- false false in
- cleanup
- (if starts_with_dots
- then
- (* EX because there is a loop on enter/top *)
- ctl_and CTL.NONSTRICT (toppred None) (ctl_ex res)
- else if starts_with_brace
- then
- ctl_and CTL.NONSTRICT
- (ctl_not(CTL.EX(CTL.BACKWARD,(funpred None)))) res
- else res)
- | Ast.ERRORWORDS(exps) -> failwith "not supported errorwords")
-
-(* --------------------------------------------------------------------- *)
-(* Entry points *)
-
-let asttoctlz (name,(_,_,exists_flag),l) used_after positions =
- letctr := 0;
- labelctr := 0;
- (match exists_flag with
- Ast.Exists -> exists := Exists
- | Ast.Forall -> exists := Forall
- | Ast.ReverseForall -> exists := ReverseForall
- | Ast.Undetermined ->
- exists := if !Flag.sgrep_mode2 then Exists else Forall);
-
- let (l,used_after) =
- List.split
- (List.filter
- (function (t,_) ->
- match Ast.unwrap t with Ast.ERRORWORDS(exps) -> false | _ -> true)
- (List.combine l (List.combine used_after positions))) in
- let res = List.map2 (top_level name) used_after l in
- exists := Forall;
- res
-
-let asttoctl r used_after positions =
- match r with
- Ast.ScriptRule _ -> []
- | Ast.CocciRule (a,b,c,_) -> asttoctlz (a,b,c) used_after positions
-
-let pp_cocci_predicate (pred,modif) =
- Pretty_print_engine.pp_predicate pred
-
-let cocci_predicate_to_string (pred,modif) =
- Pretty_print_engine.predicate_to_string pred
(wrapcode
(Ast.Continue(Ast.make_mcode "continue",Ast.make_mcode ";"))) in
let stop_early v =
- if !exists = Exists
+ if quantifier = Exists
then CTL.False
else if toend
then CTL.Or(aftpred label,exitpred label)
(ctl_and CTL.NONSTRICT (ctl_not v) preflabelpred)
(ctl_and CTL.NONSTRICT preflabelpred
(ctl_or (retpred None)
- (if !Flag_engine.only_return_is_error_exit
+ (if !Flag_matcher.only_return_is_error_exit
then CTL.True
else
(ctl_or matchcontinue
if multi
then None (* not sure how to optimize this case *)
else Some (Common.Left stmt_dots)
- | Ast.Dots(_,whencode,_,_) -> Some (Common.Right whencode)
+ | Ast.Dots(_,whencode,_,_) when
+ (List.for_all
+ (* flow sensitive, so not optimizable *)
+ (function Ast.WhenNotTrue(_) | Ast.WhenNotFalse(_) ->
+ false
+ | _ -> true) whencode) ->
+ Some (Common.Right whencode)
| _ -> None)
| _ -> None in
let body_code =
new_quantified4 new_mquantified4
label llabel slabel true true in
ctl_or prev x
+ | Ast.WhenNotTrue(_) | Ast.WhenNotFalse(_) ->
+ failwith "unexpected"
| Ast.WhenModifier(Ast.WhenAny) -> CTL.False
| Ast.WhenModifier(_) -> prev)
CTL.False whencode))
label llabel slabel true in
ctl_and prev x
| Ast.WhenNot(sl) -> prev
+ | Ast.WhenNotTrue(_) | Ast.WhenNotFalse(_) ->
+ failwith "unexpected"
| Ast.WhenModifier(Ast.WhenAny) -> CTL.True
| Ast.WhenModifier(_) -> prev)
CTL.True whencode) in
--- /dev/null
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+*
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+*
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
+*
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+open Common
+
+open Ast_c
+
+(* For the moment I do only eq_type and not eq_expr, etc. The reason
+ * for eq_type is related to the typedef and struct isomorphism. Sometimes
+ * one use the typedef and sometimes the structname.
+ *
+ * TODO: should use the isomorphisms engine of julia.
+ * Maybe I can transform my ast_c in ast_cocci, and use julia's code ?
+ * Maybe I can add some Disj in my ast_c ?
+ *)
+
+
+module type PARAM =
+ sig
+ type tin
+ type 'x tout
+
+ type 'a matcher = 'a -> 'a -> tin -> 'a tout
+
+ val (>>=):
+ (tin -> 'a tout) ->
+ ('a -> (tin -> 'b tout)) ->
+ (tin -> 'b tout)
+
+ val (>&&>) : bool -> (tin -> 'x tout) -> (tin -> 'x tout)
+
+ val return : 'a -> tin -> 'a tout
+ val fail : tin -> 'a tout
+end
+
+
+module C_VS_C =
+ functor (X : PARAM) ->
+struct
+
+type 'a matcher = 'a -> 'a -> X.tin -> 'a X.tout
+
+let (>>=) = X.(>>=)
+let (>&&>) = X.(>&&>)
+let return = X.return
+let fail = X.fail
+
+let (option: 'a matcher -> ('a option matcher)) = fun f t1 t2 ->
+ match (t1,t2) with
+ | (Some t1, Some t2) ->
+ f t1 t2 >>= (fun t ->
+ return (Some t)
+ )
+ | (None, None) -> return None
+ | _ -> fail
+
+
+let rec fullType a b =
+ let ((qua,iiqa), tya) = a in
+ let ((qub,iiqb), tyb) = b in
+ (qua.const =:= qub.const && qua.volatile =:= qub.volatile) >&&>
+
+ let (qu,iiq) = (qua, iiqa) in
+ typeC tya tyb >>= (fun ty ->
+ return ((qu,iiq), ty)
+ )
+
+and typeC tya tyb =
+ let (a, iia) = tya in
+ let (b, iib) = tyb in
+
+ let iix = iia in
+
+ match a, b with
+ | BaseType a, BaseType b ->
+ a =*= b >&&> return (BaseType a, iix)
+ | Pointer a, Pointer b ->
+ fullType a b >>= (fun x -> return (Pointer x, iix))
+
+ | StructUnionName (sua, sa), StructUnionName (sub, sb) ->
+ (sua =*= sub && sa =$= sb) >&&>
+ return (StructUnionName (sua, sa), iix)
+
+ | TypeName (sa, opta), TypeName (sb, optb) ->
+ (* assert compatible opta optb ? *)
+ (*option fullType opta optb*)
+ sa =$= sb >&&>
+ let opt =
+ (match opta, optb with
+ | None, None -> None
+ | Some x, _
+ | _, Some x
+ -> Some x
+ )
+ in
+ return (TypeName (sa, opt), iix)
+
+
+ | Array (ea, a), Array (eb,b) ->
+ let get_option f = function Some x -> Some (f x) | None -> None in
+ let ea = get_option Lib_parsing_c.al_expr ea in
+ let eb = get_option Lib_parsing_c.al_expr eb in
+ ea =*= eb >&&> fullType a b >>= (fun x -> return (Array (ea, x), iix))
+
+ | FunctionType (returna, paramsa), FunctionType (returnb, paramsb) ->
+ let (tsa, (ba,iihas3dotsa)) = paramsa in
+ let (tsb, (bb,iihas3dotsb)) = paramsb in
+
+ let bx = ba in
+ let iihas3dotsx = iihas3dotsa in
+
+ (ba = bb && List.length tsa = List.length tsb) >&&>
+ fullType returna returnb >>= (fun returnx ->
+
+ Common.zip tsa tsb +> List.fold_left
+ (fun acc ((parama,iia),(paramb,iib))->
+ let iix = iia in
+ acc >>= (fun xs ->
+
+ let (((ba, saopt, ta), ii_b_sa)) = parama in
+ let (((bb, sbopt, tb), ii_b_sb)) = paramb in
+
+ let bx = ba in
+ let sxopt = saopt in
+ let ii_b_sx = ii_b_sa in
+
+ (ba =:= bb && saopt =*= sbopt) >&&>
+ fullType ta tb >>= (fun tx ->
+ let paramx = (((bx, sxopt, tx), ii_b_sx)) in
+ return ((paramx,iix)::xs)
+ )
+ )
+ ) (return [])
+ >>= (fun tsx ->
+ let paramsx = (List.rev tsx, (bx, iihas3dotsx)) in
+ return (FunctionType (returnx, paramsx), iix)
+ ))
+
+ | Enum (saopt, enuma), Enum (sbopt, enumb) ->
+ (saopt =*= sbopt &&
+ List.length enuma = List.length enumb &&
+ Common.zip enuma enumb +> List.for_all (fun
+ ((((sa, eopta),ii_s_eqa), iicommaa), (((sb, eoptb),ii_s_eqb),iicommab))
+ ->
+ sa =$= sb &&
+ eopta =*= eoptb
+ )
+ ) >&&>
+ return (Enum (saopt, enuma), iix)
+
+ | EnumName sa, EnumName sb -> sa =$= sb >&&> return (EnumName sa, iix)
+
+ | ParenType a, ParenType b ->
+ (* iso here ? *)
+ fullType a b >>= (fun x ->
+ return (ParenType x, iix)
+ )
+
+ | TypeOfExpr ea, TypeOfExpr eb ->
+ let ea = Lib_parsing_c.al_expr ea in
+ let eb = Lib_parsing_c.al_expr eb in
+ ea =*= eb >&&> return (TypeOfExpr ea, iix)
+
+ | TypeOfType a, TypeOfType b ->
+ fullType a b >>= (fun x -> return (TypeOfType x, iix))
+
+(* | TypeOfType a, b ->
+ | a, TypeOfType b ->
+*)
+
+
+ | StructUnion (sua, saopt, sta), StructUnion (sub, sbopt, stb) ->
+ (sua =*= sub && saopt =*= sbopt && List.length sta = List.length stb)
+ >&&>
+ Common.zip sta stb +> List.fold_left
+ (fun acc ((xfielda, iia), (xfieldb, iib)) ->
+ let iix = iia in
+ acc >>= (fun xs ->
+ match xfielda, xfieldb with
+ | EmptyField, EmptyField -> return ((EmptyField, iix)::xs)
+
+ | DeclarationField (FieldDeclList (fa, iipta)),
+ DeclarationField (FieldDeclList (fb, iiptb)) ->
+ let iipt = iipta in (* TODO ?*)
+ (List.length fa =|= List.length fb) >&&>
+
+ Common.zip fa fb +> List.fold_left
+ (fun acc2 ((fielda,iia),(fieldb,iib))->
+ let iix = iia in
+ acc2 >>= (fun xs ->
+ let (fa, ii2a) = fielda in
+ let (fb, ii2b) = fieldb in
+ let ii2x = ii2a in
+ match fa, fb with
+ | Simple (saopt, ta), Simple (sbopt, tb) ->
+ saopt =*= sbopt >&&>
+ fullType ta tb >>= (fun tx ->
+ return (((Simple (saopt, tx), ii2x), iix)::xs)
+ )
+
+ | BitField (sopta, ta, ea), BitField (soptb, tb, eb) ->
+ (sopta =*= soptb && ea =*= eb) >&&>
+ fullType ta tb >>= (fun tx ->
+ return (((BitField (sopta,tx,ea), ii2x), iix)::xs)
+ )
+ | _,_ -> fail
+ )
+ ) (return [])
+ >>= (fun fx ->
+ return (((DeclarationField
+ (FieldDeclList (List.rev fx,iipt))), iix)::xs)
+ )
+ | _ -> fail
+ )
+
+
+ ) (return [])
+ >>= (fun stx ->
+ return (StructUnion (sua, saopt, List.rev stx), iix)
+ )
+
+
+
+ (* choose the lub.
+ * subtil: in the return must put iia, not iix, and in following case
+ * must put iib and not iix, because we want the token corresponding
+ * to the typedef.
+ *)
+ | TypeName (s, Some a), _ ->
+ fullType a (Ast_c.nQ, tyb) >>= (fun x ->
+ return (TypeName (s, Some x), iia)
+ )
+
+ | _, TypeName (s, Some b) ->
+ fullType b (Ast_c.nQ, tya) >>= (fun x ->
+ return (TypeName (s, Some x), iib) (* subtil: *)
+ )
+
+ | _, _ -> fail
+
+
+
+end
+
+module XEQ = struct
+ type tin = unit
+ type 'a tout = 'a option
+
+ type 'a matcher = 'a -> 'a -> tin -> 'a tout
+
+ let return x = fun tin -> Some x
+ let fail = fun tin -> None
+
+ let (>>=) m f = fun tin ->
+ match m tin with
+ | None -> None
+ | Some x -> f x tin
+
+ let (>&&>) b m = fun tin ->
+ if b then m tin
+ else fail tin
+
+end
+
+module EQ = C_VS_C (XEQ)
+
+
+let eq_type2 a b = EQ.fullType a b () <> None
+let merge_type2 a b = Common.some (EQ.fullType a b ())
+
+let eq_type a b =
+ Common.profile_code "C_vs_c" (fun () -> eq_type2 a b)
+
+let merge_type a b =
+ Common.profile_code "C_vs_c" (fun () -> merge_type2 a b)
+++ /dev/null
-(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-*
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-*
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
-*
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
-
-
-(* Just to warn me when there is some news in the types in
- * ast_cocci.ml or even ast_c.ml, so that I can then adjust my code in
- * pattern.ml or transformation.ml.
- *
- * For the moment I do it only for myself (pad), that is I check only
- * for news in ast_cocci.ml, because I already know when I add stuff in
- * my code in ast_c.ml or control_flow_c.ml. *)
-
-module A = Ast_cocci
-module B = Ast_c
-module F = Control_flow_c
-
-(* dependencies_to_adjust: pattern.ml, transformaton.ml *)
-
-let dumb_astcocci_rule_elem = function
- | A.MetaRuleElem _ -> ()
- | A.MetaStmt (ida,_,_,_) -> ()
- | A.MetaStmtList _ -> ()
- | A.Exp expr -> ()
- | A.TopExp expr -> ()
- | A.Ty ty -> ()
- | A.FunHeader (bef,allminus, fninfo, ida, _, paramsa, _) -> ()
- | A.Decl (bef,allminus,decla) -> ()
- | A.SeqStart _ -> ()
- | A.SeqEnd _ -> ()
- | A.ExprStatement (ea, _) -> ()
- | A.IfHeader (_,_, ea, _) -> ()
- | A.Else _ -> ()
- | A.WhileHeader (_, _, ea, _) -> ()
- | A.DoHeader _ -> ()
- | A.WhileTail (_,_,ea,_,_) -> ()
- | A.ForHeader (_, _, ea1opt, _, ea2opt, _, ea3opt, _) -> ()
- | A.IteratorHeader (ia1, ia2, ea, ia3) -> ()
- | A.SwitchHeader _ -> ()
- | A.Break _ -> ()
- | A.Continue _ -> ()
- | A.Label _ -> ()
- | A.Goto(_,_,_) -> ()
- | A.Return _ -> ()
- | A.ReturnExpr (_, ea, _) -> ()
- | A.DefineHeader _ -> ()
- | A.Include _ -> ()
- | A.Default _ -> ()
- | A.Case _ -> ()
- | A.DisjRuleElem _ -> failwith "not possible - compiled away in asttoctl"
-
-let dumb_astcocci_decl = function
- | A.UnInit (stg, typa, sa, _) -> ()
- | A.Init (stg, typa, sa, _, expa, _) -> ()
- | A.TyDecl (typa, _) -> ()
- | A.MacroDecl(fn, _, eas, _, _) -> ()
- | A.Ddots(dots,whencode) -> ()
- | A.MetaDecl _ -> ()
- | A.Typedef(d,ty1,ty2,pv) -> ()
- | A.DisjDecl xs -> ()
- | A.OptDecl _ | A.UniqueDecl _ -> ()
-
-let dumb_astcocci_initialiser = function
- A.Init(stg,ty,id,eq,ini,sem) -> ()
- | A.UnInit(stg,ty,id,sem) -> ()
- | A.MacroDecl(fn, _, eas, _, _) -> ()
- | A.TyDecl(ty,sem) -> ()
- | A.Typedef(d,ty1,ty2,pv) -> ()
- | A.DisjDecl(decls) -> ()
- | A.Ddots(dots,whencode) -> ()
- | A.MetaDecl(name,_,_) -> ()
- | A.OptDecl(decl) -> ()
- | A.UniqueDecl(decl) -> ()
-
-let dumb_astcocci_expr = function
- | A.MetaExpr (ida,_,_, opttypa, _, _) -> ()
- | A.Edots (_,_) -> ()
- | A.MetaErr _ -> ()
- | A.Ident ida -> ()
- | A.Constant (A.String sa,_,_,_) -> ()
- | A.Constant (A.Char sa,_,_,_) -> ()
- | A.Constant (A.Int sa,_,_,_) -> ()
- | A.Constant (A.Float sa,_,_,_) -> ()
- | A.FunCall (ea1, _, eas, _) -> ()
- | A.Assignment (ea1, opa, ea2, _) -> ()
- | A.CondExpr (ea1,_,ea2opt,_,ea3) -> ()
- | A.Postfix (ea, opa) -> ()
- | A.Infix (ea, opa) -> ()
- | A.Unary (ea, opa) -> ()
- | A.Binary (ea1, opa, ea2) -> ()
- | A.Nested (ea1, opa, ea2) -> ()
- | A.ArrayAccess (ea1, _, ea2, _) -> ()
- | A.RecordAccess (ea, _, ida) -> ()
- | A.RecordPtAccess (ea, _, ida) -> ()
- | A.Cast (_, typa, _, ea) -> ()
- | A.SizeOfExpr (_, ea) -> ()
- | A.SizeOfType (_, _, typa, _) -> ()
- | A.TypeExp (typa) -> ()
- | A.Paren (_, ea, _) -> ()
- | A.NestExpr _ -> ()
- | A.MetaExprList _ -> ()
- | A.EComma _ -> ()
- | A.Ecircles _ -> ()
- | A.Estars _ -> ()
- | A.DisjExpr eas -> ()
- | A.UniqueExp _ -> ()
- | A.OptExp _ -> ()
-
-let dumb_astcocci_fulltype = function
- A.Type(cv,ty) -> ()
- | A.DisjType(types) -> ()
- | A.OptType(ty) -> ()
- | A.UniqueType(ty) -> ()
-
-let dumb_astcocci_type = function
- | A.MetaType(ida,_,_) -> ()
- | A.BaseType (basea, signaopt) -> ()
- | A.ImplicitInt (signa) -> ()
- | A.Pointer (typa, _) -> ()
- | A.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> ()
- | A.FunctionType _ -> ()
- | A.Array (typa, _, eaopt, _) -> ()
- | A.StructUnionName(sa, sua) -> ()
- | A.StructUnionDef(ty, lb, decls, rb) -> ()
- | A.TypeName sa -> ()
-
-
-(* ------------------------------------------------------------------------- *)
-(* for C *)
-(*
- | (Ident (_) | Constant _ | FunCall (_,_) | CondExpr (_,_,_)
- | Sequence (_,_)
- | Assignment (_,_,_)
- | Postfix (_,_) | Infix (_,_) | Unary (_,_) | Binary (_,_,_)
- | ArrayAccess (_,_) | RecordAccess (_,_) | RecordPtAccess (_,_)
- | SizeOfExpr (_) | SizeOfType (_) | Cast (_,_)
- | StatementExpr (_) | Constructor
- | ParenExpr (_) | MacroCall (_) | MacroCall2 (_)
- ),_ ->
-
- | ( Labeled (Label (_,_)) | Labeled (Case (_,_))
- | Labeled (CaseRange (_,_,_)) | Labeled (Default _)
- | Compound _ | ExprStatement _
- | Selection (If (_, _, _)) | Selection (Switch (_, _))
- | Iteration (While (_, _)) | Iteration (DoWhile (_, _))
- | Iteration (For ((_,_), (_,_), (_, _), _))
- | Jump (Goto _) | Jump ((Continue|Break|Return)) | Jump (ReturnExpr _)
- | Decl _ | Asm | Selection (IfCpp (_,_))
- ), _ ->
-*)
-
-(* for control flow nodes
-
- | ( F.ExprStatement (_, _)
- | F.IfHeader (_, _) | F.SwitchHeader (_, _)
- | F.WhileHeader (_, _) | (* F.DoHeader (_, _) | *) F.DoWhileTail (_, _)
- | F.ForHeader (_, _)
- | F.Return (_, _) | F.ReturnExpr (_, _)
- (* no counter part in cocci *)
- | F.Label (_, _)
- | F.Case (_,_) | (* F.CaseRange (_, _) | *) F.Default (_, _)
- | F.Goto (_, _) | F.Continue (_, _) | F.Break (_, _)
- ) -> raise Impossible
-
-*)
--- /dev/null
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+*
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+*
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
+*
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+(* ---------------------------------------------------------------- *)
+(* code to check for ambiguities *)
+
+(* Idea: for each node that is said to be modified in any witness tree, we
+ check that all backward paths end up at the root of some witness tree
+ that says that the node should be modified. We then give a warning, if
+ the node itself appears more than once in such a path, because then there
+ could be some instances that are modified and some that are not. An
+ example is as follows:
+
+ f(); ... g(); ... - h();
+
+ with C code: f(); while(E) { h(); g(); } g(); h();
+
+ Then the h() in the while loop matches both the first ... and the - h();
+
+ Concretely, if a node 47 is in the witness tree rooted at 1 and the
+ witness tree rooted at 2, then we give an error if 47 is not in the set
+ of nodes satisfying AF[1v2] and give a warning if 47 is in the set of
+ nodes satisfying EXEF(47 & EXEF(1v2)). (Note that the root of a witness
+ tree here is the node causing the pattern to match; there might not be
+ any witnesses associated with this node.)
+
+ Another try on the exists formula:
+ !(1v2) & EXE[!(1v2) U 47]
+ The first !(1v2) is to discard immediately cases where the beginning and
+ end of the path are the same. Afterwards, it would only seem necessary to
+ serach up to the next occurrence of 47 (leaf), ensuring that there are not
+ 1s or 2s (starting points) along the way. Then the second 47 would be in
+ the path, but possible not transformed.
+ *)
+
+module G = Ograph_extended
+module CTL = Ast_ctl
+
+(* Step 1: for each tree, make a mapping from the modified nodes to the root
+of the tree *)
+
+let modified = (Hashtbl.create(25) : (G.nodei, G.nodei list ref) Hashtbl.t)
+
+let build_modified (n,_,wits) =
+ let rec loop = function
+ CTL.Wit(st,[CTL.Subst(x,Wrapper_ctl.PredVal(CTL.Modif(v)))],anno,wit) ->
+ let cell =
+ try Hashtbl.find modified st
+ with Not_found ->
+ let cell = ref [] in Hashtbl.add modified st cell; cell in
+ cell := n :: !cell;
+ List.iter loop wit
+ | CTL.Wit(st,_,anno,wit) -> List.iter loop wit
+ | CTL.NegWit(wit) -> () in
+ List.iter loop wits
+
+(* Step 2: For each node in the hash table, create the error and warning
+ formulas *)
+
+type 'a nodes = Node of 'a | After
+
+let create_formulas _ =
+ Hashtbl.fold
+ (function node ->
+ function roots ->
+ function acc ->
+ (*let exef f =
+ wrap
+ (Ast_ctl.EX
+ (Ast_ctl.BACKWARD,wrap(Ast_ctl.EF(Ast_ctl.BACKWARD,f)))) in*)
+ let match_node = Ast_ctl.Pred(Node(node)) in
+ let match_roots =
+ List.map (function n -> Ast_ctl.Pred(Node(n)))
+ (List.sort compare !roots) in
+ let roots =
+ List.fold_left
+ (function prev -> function cur -> Ast_ctl.Or(prev,cur))
+ (List.hd match_roots) (List.tl match_roots) in
+ (node,
+ Ast_ctl.AF(Ast_ctl.BACKWARD,Ast_ctl.NONSTRICT,
+ Ast_ctl.Or(roots,Ast_ctl.Pred(After))),
+ Ast_ctl.And
+ (Ast_ctl.NONSTRICT,
+ Ast_ctl.Not(roots),
+ Ast_ctl.EX
+ (Ast_ctl.BACKWARD,
+ Ast_ctl.EU(Ast_ctl.BACKWARD,roots,match_node))))
+ (*exef
+ (wrap(Ast_ctl.And(Ast_ctl.NONSTRICT,match_node,exef(roots))))*)
+ :: acc)
+ modified []
+
+(* Step 3: check the formula on the control-flow graph *)
+
+module PRED =
+ struct
+ type t = Ograph_extended.nodei nodes
+ let print_predicate = function
+ After -> Format.print_string "after"
+ | Node x -> Format.print_string (string_of_int x)
+ end
+
+module ENV =
+ struct
+ type value = unit
+ type mvar = unit
+ let eq_mvar x x' = failwith "should not be invoked"
+ let eq_val v v' = failwith "should not be invoked"
+ let merge_val v v' = failwith "should not be invoked"
+
+ let print_mvar s = failwith "should not be invoked"
+ let print_value x = failwith "should not be invoked"
+ end
+
+
+module CFG =
+ struct
+ type node = Ograph_extended.nodei
+ type cfg =
+ (Control_flow_c.node, Control_flow_c.edge)
+ Ograph_extended.ograph_mutable
+ let predecessors cfg n = List.map fst ((cfg#predecessors n)#tolist)
+ let successors cfg n = List.map fst ((cfg#successors n)#tolist)
+ let extract_is_loop cfg n =
+ Control_flow_c.extract_is_loop (cfg#nodes#find n)
+ let print_node i = Format.print_string (string_of_int i)
+ let size cfg = cfg#nodes#length
+ end
+
+module ENGINE = Ctl_engine.CTL_ENGINE (ENV) (CFG) (PRED)
+
+let test_formula state formula cfg =
+ let label = function
+ Node pred -> [(pred,[],[])]
+ | After ->
+ List.concat
+ (List.map
+ (fun (nodei, node) ->
+ match Control_flow_c.unwrap node with
+ Control_flow_c.AfterNode -> [(nodei,[],[])]
+ | _ -> [])
+ cfg#nodes#tolist) in
+ let verbose = !Flag_ctl.verbose_ctl_engine in
+ let pm = !Flag_ctl.partial_match in
+ Flag_ctl.verbose_ctl_engine := false;
+ Flag_ctl.partial_match := false;
+ let res =
+ ENGINE.sat (cfg,label,List.map fst cfg#nodes#tolist)
+ (CTL.And(CTL.NONSTRICT,CTL.Pred(Node(state)),formula))
+ [[Node(state)]] in
+ Flag_ctl.verbose_ctl_engine := verbose;
+ Flag_ctl.partial_match := pm;
+ match res with [] -> false | _ -> true
+
+(* ---------------------------------------------------------------- *)
+(* Entry point *)
+
+(* The argument is a list of triples with a node name, an empty environment
+and a witness tree *)
+
+type witness =
+ (Ograph_extended.nodei, unit,
+ (Ograph_extended.nodei, unit, unit) Ast_ctl.generic_ctl list)
+ Ast_ctl.generic_witnesstree
+
+type ('a,'b,'c,'d,'e) triples =
+ (Ograph_extended.nodei * 'a *
+ (Ograph_extended.nodei,
+ ('b, ('c, 'd) Wrapper_ctl.wrapped_binding) CTL.generic_subst list, 'e)
+ CTL.generic_witnesstree list) list
+
+let check_reachability triples cfg =
+ Hashtbl.clear modified;
+ List.iter build_modified triples;
+ let formulas = create_formulas() in
+ List.iter
+ (function (node,af_formula,ef_formula) ->
+ if test_formula node af_formula cfg
+ then
+ if test_formula node ef_formula cfg
+ then
+ Printf.printf "warning: node %d may be inconsistently modified\n"
+ node
+ else ()
+ else
+ failwith
+ (Printf.sprintf
+ "node %d reachable by inconsistent control-flow paths" node))
+ formulas
+++ /dev/null
-(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-*
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-*
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
-*
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
-
-open Common
-
-module A = Ast_cocci
-module B = Ast_c
-
-module F = Control_flow_c
-
-(*****************************************************************************)
-(* Wrappers *)
-(*****************************************************************************)
-
-(*****************************************************************************)
-(* Helpers *)
-(*****************************************************************************)
-
-type sequence = Ordered | Unordered
-
-let seqstyle eas =
- match A.unwrap eas with
- | A.DOTS _ -> Ordered
- | A.CIRCLES _ -> Unordered
- | A.STARS _ -> failwith "not handling stars"
-
-let (redots : 'a A.dots -> 'a list -> 'a A.dots)=fun eas easundots ->
- A.rewrap eas (
- match A.unwrap eas with
- | A.DOTS _ -> A.DOTS easundots
- | A.CIRCLES _ -> A.CIRCLES easundots
- | A.STARS _ -> A.STARS easundots
- )
-
-
-let (need_unordered_initialisers : B.initialiser B.wrap2 list -> bool) =
- fun ibs ->
- ibs +> List.exists (fun (ib, icomma) ->
- match B.unwrap ib with
- | B.InitDesignators _
- | B.InitFieldOld _
- | B.InitIndexOld _
- -> true
- | B.InitExpr _
- | B.InitList _
- -> false
- )
-
-(* For the #include <linux/...> in the .cocci, need to find where is
- * the '+' attached to this element, to later find the first concrete
- * #include <linux/xxx.h> or last one in the serie of #includes in the
- * .c.
- *)
-type include_requirement =
- | IncludeMcodeBefore
- | IncludeMcodeAfter
- | IncludeNothing
-
-
-
-(* todo? put in semantic_c.ml *)
-type info_ident =
- | Function
- | LocalFunction (* entails Function *)
- | DontKnow
-
-
-let term mc = A.unwrap_mcode mc
-let mcodekind mc = A.get_mcodekind mc
-
-
-let mcode_contain_plus = function
- | A.CONTEXT (_,A.NOTHING) -> false
- | A.CONTEXT _ -> true
- | A.MINUS (_,[]) -> false
- | A.MINUS (_,x::xs) -> true
- | A.PLUS -> raise Impossible
-
-let mcode_simple_minus = function
- | A.MINUS (_,[]) -> true
- | _ -> false
-
-
-(* In transformation.ml sometime I build some mcodekind myself and
- * julia has put None for the pos. But there is no possible raise
- * NoMatch in those cases because it is for the minusall trick or for
- * the distribute, so either have to build those pos, in fact a range,
- * because for the distribute have to erase a fullType with one
- * mcodekind, or add an argument to tag_with_mck such as "safe" that
- * don't do the check_pos. Hence this DontCarePos constructor. *)
-
-let minusizer =
- ("fake","fake"),
- {A.line = 0; column =0; A.strbef=[]; A.straft=[];},
- (A.MINUS(A.DontCarePos, [])),
- A.NoMetaPos
-
-let generalize_mcode ia =
- let (s1, i, mck, pos) = ia in
- let new_mck =
- match mck with
- | A.PLUS -> raise Impossible
- | A.CONTEXT (A.NoPos,x) ->
- A.CONTEXT (A.DontCarePos,x)
- | A.MINUS (A.NoPos,x) ->
- A.MINUS (A.DontCarePos,x)
- | _ -> raise Impossible in
- (s1, i, new_mck, pos)
-
-
-
-(*---------------------------------------------------------------------------*)
-
-(* 0x0 is equivalent to 0, value format isomorphism *)
-let equal_c_int s1 s2 =
- try
- int_of_string s1 = int_of_string s2
- with Failure("int_of_string") ->
- s1 =$= s2
-
-
-
-(*---------------------------------------------------------------------------*)
-(* Normally A should reuse some types of Ast_c, so those
- * functions should not exist.
- *
- * update: but now Ast_c depends on A, so can't make too
- * A depends on Ast_c, so have to stay with those equal_xxx
- * functions.
- *)
-
-let equal_unaryOp a b =
- match a, b with
- | A.GetRef , B.GetRef -> true
- | A.DeRef , B.DeRef -> true
- | A.UnPlus , B.UnPlus -> true
- | A.UnMinus , B.UnMinus -> true
- | A.Tilde , B.Tilde -> true
- | A.Not , B.Not -> true
- | _, _ -> false
-
-let equal_arithOp a b =
- match a, b with
- | A.Plus , B.Plus -> true
- | A.Minus , B.Minus -> true
- | A.Mul , B.Mul -> true
- | A.Div , B.Div -> true
- | A.Mod , B.Mod -> true
- | A.DecLeft , B.DecLeft -> true
- | A.DecRight , B.DecRight -> true
- | A.And , B.And -> true
- | A.Or , B.Or -> true
- | A.Xor , B.Xor -> true
- | _ , _ -> false
-
-let equal_logicalOp a b =
- match a, b with
- | A.Inf , B.Inf -> true
- | A.Sup , B.Sup -> true
- | A.InfEq , B.InfEq -> true
- | A.SupEq , B.SupEq -> true
- | A.Eq , B.Eq -> true
- | A.NotEq , B.NotEq -> true
- | A.AndLog , B.AndLog -> true
- | A.OrLog , B.OrLog -> true
- | _ , _ -> false
-
-let equal_assignOp a b =
- match a, b with
- | A.SimpleAssign, B.SimpleAssign -> true
- | A.OpAssign a, B.OpAssign b -> equal_arithOp a b
- | _ -> false
-
-let equal_fixOp a b =
- match a, b with
- | A.Dec, B.Dec -> true
- | A.Inc, B.Inc -> true
- | _ -> false
-
-let equal_binaryOp a b =
- match a, b with
- | A.Arith a, B.Arith b -> equal_arithOp a b
- | A.Logical a, B.Logical b -> equal_logicalOp a b
- | _ -> false
-
-let equal_structUnion a b =
- match a, b with
- | A.Struct, B.Struct -> true
- | A.Union, B.Union -> true
- | _, _ -> false
-
-let equal_sign a b =
- match a, b with
- | A.Signed, B.Signed -> true
- | A.Unsigned, B.UnSigned -> true
- | _, _ -> false
-
-let equal_storage a b =
- match a, b with
- | A.Static , B.Sto B.Static
- | A.Auto , B.Sto B.Auto
- | A.Register , B.Sto B.Register
- | A.Extern , B.Sto B.Extern
- -> true
- | _ -> false
-
-(*---------------------------------------------------------------------------*)
-
-let equal_metavarval valu valu' =
- match valu, valu' with
- | Ast_c.MetaIdVal a, Ast_c.MetaIdVal b -> a =$= b
- | Ast_c.MetaFuncVal a, Ast_c.MetaFuncVal b -> a =$= b
- | Ast_c.MetaLocalFuncVal a, Ast_c.MetaLocalFuncVal b ->
- (* do something more ? *)
- a =$= b
-
- (* al_expr before comparing !!! and accept when they match.
- * Note that here we have Astc._expression, so it is a match
- * modulo isomorphism (there is no metavariable involved here,
- * just isomorphisms). => TODO call isomorphism_c_c instead of
- * =*=. Maybe would be easier to transform ast_c in ast_cocci
- * and call the iso engine of julia. *)
- | Ast_c.MetaExprVal a, Ast_c.MetaExprVal b ->
- Lib_parsing_c.al_expr a =*= Lib_parsing_c.al_expr b
- | Ast_c.MetaExprListVal a, Ast_c.MetaExprListVal b ->
- Lib_parsing_c.al_arguments a =*= Lib_parsing_c.al_arguments b
-
- | Ast_c.MetaStmtVal a, Ast_c.MetaStmtVal b ->
- Lib_parsing_c.al_statement a =*= Lib_parsing_c.al_statement b
- | Ast_c.MetaTypeVal a, Ast_c.MetaTypeVal b ->
- (* old: Lib_parsing_c.al_type a =*= Lib_parsing_c.al_type b *)
- C_vs_c.eq_type a b
-
- | Ast_c.MetaListlenVal a, Ast_c.MetaListlenVal b -> a =|= b
-
- | Ast_c.MetaParamVal a, Ast_c.MetaParamVal b ->
- Lib_parsing_c.al_param a =*= Lib_parsing_c.al_param b
- | Ast_c.MetaParamListVal a, Ast_c.MetaParamListVal b ->
- Lib_parsing_c.al_params a =*= Lib_parsing_c.al_params b
-
- | Ast_c.MetaPosVal (posa1,posa2), Ast_c.MetaPosVal (posb1,posb2) ->
- Ast_cocci.equal_pos posa1 posb1 && Ast_cocci.equal_pos posa2 posb2
-
- | Ast_c.MetaPosValList l1, Ast_c.MetaPosValList l2 ->
- List.exists
- (function (fla,posa1,posa2) ->
- List.exists
- (function (flb,posb1,posb2) ->
- fla = flb &&
- Ast_c.equal_posl posa1 posb1 && Ast_c.equal_posl posa2 posb2)
- l2)
- l1
- | _ -> raise Impossible
-
-
-
-(*---------------------------------------------------------------------------*)
-(* could put in ast_c.ml, next to the split/unsplit_comma *)
-let split_signb_baseb_ii (baseb, ii) =
- let iis = ii +> List.map (fun info -> (B.str_of_info info), info) in
- match baseb, iis with
-
- | B.Void, ["void",i1] -> None, [i1]
-
- | B.FloatType (B.CFloat),["float",i1] -> None, [i1]
- | B.FloatType (B.CDouble),["double",i1] -> None, [i1]
- | B.FloatType (B.CLongDouble),["long",i1;"double",i2] -> None,[i1;i2]
-
- | B.IntType (B.CChar), ["char",i1] -> None, [i1]
-
-
- | B.IntType (B.Si (sign, base)), xs ->
- (match sign, base, xs with
- | B.Signed, B.CChar2, ["signed",i1;"char",i2] ->
- Some (B.Signed, i1), [i2]
- | B.UnSigned, B.CChar2, ["unsigned",i1;"char",i2] ->
- Some (B.UnSigned, i1), [i2]
-
- | B.Signed, B.CShort, ["short",i1] ->
- None, [i1]
- | B.Signed, B.CShort, ["signed",i1;"short",i2] ->
- Some (B.Signed, i1), [i2]
- | B.UnSigned, B.CShort, ["unsigned",i1;"short",i2] ->
- Some (B.UnSigned, i1), [i2]
- | B.Signed, B.CShort, ["short",i1;"int",i2] ->
- None, [i1;i2]
-
- | B.Signed, B.CInt, ["int",i1] ->
- None, [i1]
- | B.Signed, B.CInt, ["signed",i1;"int",i2] ->
- Some (B.Signed, i1), [i2]
- | B.UnSigned, B.CInt, ["unsigned",i1;"int",i2] ->
- Some (B.UnSigned, i1), [i2]
-
- | B.Signed, B.CInt, ["signed",i1;] ->
- Some (B.Signed, i1), []
- | B.UnSigned, B.CInt, ["unsigned",i1;] ->
- Some (B.UnSigned, i1), []
-
- | B.Signed, B.CLong, ["long",i1] ->
- None, [i1]
- | B.Signed, B.CLong, ["long",i1;"int",i2] ->
- None, [i1;i2]
- | B.Signed, B.CLong, ["signed",i1;"long",i2] ->
- Some (B.Signed, i1), [i2]
- | B.UnSigned, B.CLong, ["unsigned",i1;"long",i2] ->
- Some (B.UnSigned, i1), [i2]
-
- | B.Signed, B.CLongLong, ["long",i1;"long",i2] -> None, [i1;i2]
- | B.Signed, B.CLongLong, ["signed",i1;"long",i2;"long",i3] ->
- Some (B.Signed, i1), [i2;i3]
- | B.UnSigned, B.CLongLong, ["unsigned",i1;"long",i2;"long",i3] ->
- Some (B.UnSigned, i1), [i2;i3]
-
-
- | B.UnSigned, B.CShort, ["unsigned",i1;"short",i2; "int", i3] ->
- Some (B.UnSigned, i1), [i2;i3]
-
-
-
- | _ -> failwith "strange type1, maybe because of weird order"
- )
- | _ -> failwith "strange type2, maybe because of weird order"
-
-(*---------------------------------------------------------------------------*)
-
-let rec unsplit_icomma xs =
- match xs with
- | [] -> []
- | x::y::xs ->
- (match A.unwrap y with
- | A.IComma mcode ->
- (x, y)::unsplit_icomma xs
- | _ -> failwith "wrong ast_cocci in initializer"
- )
- | _ ->
- failwith ("wrong ast_cocci in initializer, should have pair " ^
- "number of Icomma")
-
-
-
-let resplit_initialiser ibs iicomma =
- match iicomma, ibs with
- | [], [] -> []
- | [], _ ->
- failwith "should have a iicomma, do you generate fakeInfo in parser?"
- | _, [] ->
- failwith "shouldn't have a iicomma"
- | [iicomma], x::xs ->
- let elems = List.map fst (x::xs) in
- let commas = List.map snd (x::xs) +> List.flatten in
- let commas = commas @ [iicomma] in
- zip elems commas
- | _ -> raise Impossible
-
-
-
-let rec split_icomma xs =
- match xs with
- | [] -> []
- | (x,y)::xs -> x::y::split_icomma xs
-
-let rec unsplit_initialiser ibs_unsplit =
- match ibs_unsplit with
- | [] -> [], [] (* empty iicomma *)
- | (x, commax)::xs ->
- let (xs, lastcomma) = unsplit_initialiser_bis commax xs in
- (x, [])::xs, lastcomma
-
-and unsplit_initialiser_bis comma_before = function
- | [] -> [], [comma_before]
- | (x, commax)::xs ->
- let (xs, lastcomma) = unsplit_initialiser_bis commax xs in
- (x, [comma_before])::xs, lastcomma
-
-
-
-
-(*---------------------------------------------------------------------------*)
-(* coupling: same in type_annotater_c.ml *)
-let structdef_to_struct_name ty =
- match ty with
- | qu, (B.StructUnion (su, sopt, fields), iis) ->
- (match sopt,iis with
- | Some s , [i1;i2;i3;i4] ->
- qu, (B.StructUnionName (su, s), [i1;i2])
- | None, _ ->
- ty
-
- | x -> raise Impossible
- )
- | _ -> raise Impossible
-
-(*---------------------------------------------------------------------------*)
-let initialisation_to_affectation decl =
- match decl with
- | B.MacroDecl _ -> F.Decl decl
- | B.DeclList (xs, iis) ->
-
- (* todo?: should not do that if the variable is an array cos
- * will have x[] = , mais de toute facon ca sera pas un InitExp
- *)
- (match xs with
- | [] -> raise Impossible
- | [x] ->
- let ((var, returnType, storage, local),iisep) = x in
-
- (match var with
- | Some ((s, ini), iis::iini) ->
- (match ini with
- | Some (B.InitExpr e, ii_empty2) ->
- let local =
- match local with
- Ast_c.NotLocalDecl -> Ast_c.NotLocalVar
- | Ast_c.LocalDecl -> Ast_c.LocalVar (iis.Ast_c.pinfo) in
-
- let typ =
- ref (Some ((Lib_parsing_c.al_type returnType),local),
- Ast_c.NotTest) in
- let id = (B.Ident s, typ),[iis] in
- F.DefineExpr
- ((B.Assignment (id, B.SimpleAssign, e),
- Ast_c.noType()), iini)
- | _ -> F.Decl decl
- )
- | _ -> F.Decl decl
- )
- | x::xs ->
- pr2_once "TODO: initialisation_to_affectation for multi vars";
- (* todo? do a fold_left and generate 'x = a, y = b' etc, use
- * the Sequence expression operator of C and make an
- * ExprStatement from that.
- *)
- F.Decl decl
- )
-
-
-
-
-
-(*****************************************************************************)
-(* Functor parameter combinators *)
-(*****************************************************************************)
-(* monad like stuff
- * src: papers on parser combinators in haskell (cf a pearl by meijer in ICFP)
- *
- * version0: was not tagging the SP, so just tag the C
- * val (>>=):
- * (tin -> 'c tout) -> ('c -> (tin -> 'b tout)) -> (tin -> 'b tout)
- * val return : 'b -> tin -> 'b tout
- * val fail : tin -> 'b tout
- *
- * version1: now also tag the SP so return a ('a * 'b)
- *)
-
-type mode = PatternMode | TransformMode
-
-module type PARAM =
- sig
- type tin
- type 'x tout
-
-
- type ('a, 'b) matcher = 'a -> 'b -> tin -> ('a * 'b) tout
-
- val mode : mode
-
- val (>>=):
- (tin -> ('a * 'b) tout) ->
- ('a -> 'b -> (tin -> ('c * 'd) tout)) ->
- (tin -> ('c * 'd) tout)
-
- val return : ('a * 'b) -> tin -> ('a *'b) tout
- val fail : tin -> ('a * 'b) tout
-
- val (>||>) :
- (tin -> 'x tout) ->
- (tin -> 'x tout) ->
- (tin -> 'x tout)
-
- val (>|+|>) :
- (tin -> 'x tout) ->
- (tin -> 'x tout) ->
- (tin -> 'x tout)
-
- val (>&&>) : (tin -> bool) -> (tin -> 'x tout) -> (tin -> 'x tout)
-
- val tokenf : ('a A.mcode, B.info) matcher
- val tokenf_mck : (A.mcodekind, B.info) matcher
-
- val distrf_e :
- (A.meta_name A.mcode, B.expression) matcher
- val distrf_args :
- (A.meta_name A.mcode, (Ast_c.argument, Ast_c.il) either list) matcher
- val distrf_type :
- (A.meta_name A.mcode, Ast_c.fullType) matcher
- val distrf_params :
- (A.meta_name A.mcode,
- (Ast_c.parameterType, Ast_c.il) either list) matcher
- val distrf_param :
- (A.meta_name A.mcode, Ast_c.parameterType) matcher
- val distrf_ini :
- (A.meta_name A.mcode, Ast_c.initialiser) matcher
- val distrf_node :
- (A.meta_name A.mcode, Control_flow_c.node) matcher
-
- val distrf_define_params :
- (A.meta_name A.mcode, (string Ast_c.wrap, Ast_c.il) either list)
- matcher
-
- val distrf_struct_fields :
- (A.meta_name A.mcode, B.field B.wrap list) matcher
-
- val distrf_cst :
- (A.meta_name A.mcode, (B.constant, string) either B.wrap) matcher
-
- val cocciExp :
- (A.expression, B.expression) matcher -> (A.expression, F.node) matcher
-
- val cocciExpExp :
- (A.expression, B.expression) matcher ->
- (A.expression, B.expression) matcher
-
- val cocciTy :
- (A.fullType, B.fullType) matcher -> (A.fullType, F.node) matcher
-
- val envf :
- A.keep_binding -> A.inherited ->
- A.meta_name A.mcode * Ast_c.metavar_binding_kind *
- (unit -> Common.filename * Ast_c.posl * Ast_c.posl) ->
- (unit -> tin -> 'x tout) -> (tin -> 'x tout)
-
- val check_constraints :
- ('a, 'b) matcher -> 'a list -> 'b ->
- (unit -> tin -> 'x tout) -> (tin -> 'x tout)
-
- val all_bound : A.meta_name list -> (tin -> bool)
-
- val optional_storage_flag : (bool -> tin -> 'x tout) -> (tin -> 'x tout)
- val optional_qualifier_flag : (bool -> tin -> 'x tout) -> (tin -> 'x tout)
- val value_format_flag: (bool -> tin -> 'x tout) -> (tin -> 'x tout)
-
-
- end
-
-(*****************************************************************************)
-(* Functor code, "Cocci vs C" *)
-(*****************************************************************************)
-
-module COCCI_VS_C =
- functor (X : PARAM) ->
-struct
-
-type ('a, 'b) matcher = 'a -> 'b -> X.tin -> ('a * 'b) X.tout
-
-let (>>=) = X.(>>=)
-let return = X.return
-let fail = X.fail
-
-let (>||>) = X.(>||>)
-let (>|+|>) = X.(>|+|>)
-let (>&&>) = X.(>&&>)
-
-let tokenf = X.tokenf
-
-(* should be raise Impossible when called from transformation.ml *)
-let fail2 () =
- match X.mode with
- | PatternMode -> fail
- | TransformMode -> raise Impossible
-
-
-let (option: ('a,'b) matcher -> ('a option,'b option) matcher)= fun f t1 t2 ->
- match (t1,t2) with
- | (Some t1, Some t2) ->
- f t1 t2 >>= (fun t1 t2 ->
- return (Some t1, Some t2)
- )
- | (None, None) -> return (None, None)
- | _ -> fail
-
-(* Dots are sometimes used as metavariables, since like metavariables they
-can match other things. But they no longer have the same type. Perhaps these
-functions could be avoided by introducing an appropriate level of polymorphism,
-but I don't know how to declare polymorphism across functors *)
-let dots2metavar (_,info,mcodekind,pos) = (("","..."),info,mcodekind,pos)
-let metavar2dots (_,info,mcodekind,pos) = ("...",info,mcodekind,pos)
-
-(*---------------------------------------------------------------------------*)
-(* toc:
- * - expression
- * - ident
- * - arguments
- * - parameters
- * - declaration
- * - initialisers
- * - type
- * - node
- *)
-
-(*---------------------------------------------------------------------------*)
-let rec (expression: (A.expression, Ast_c.expression) matcher) =
- fun ea eb ->
- X.all_bound (A.get_inherited ea) >&&>
- let wa x = A.rewrap ea x in
- match A.unwrap ea, eb with
-
- (* general case: a MetaExpr can match everything *)
- | A.MetaExpr (ida,constraints,keep,opttypa,form,inherited),
- (((expr, opttypb), ii) as expb) ->
-
- (* old: before have a MetaConst. Now we factorize and use 'form' to
- * differentiate between different cases *)
- let rec matches_id = function
- B.Ident(c) -> true
- | B.Cast(ty,e) -> matches_id (B.unwrap_expr e)
- | _ -> false in
- let form_ok =
- match (form,expr) with
- (A.ANY,_) -> true
- | (A.CONST,e) ->
- let rec matches = function
- B.Constant(c) -> true
- | B.Ident idb when idb =~ "^[A-Z_][A-Z_0-9]*$" ->
- pr2_once ("warning: I consider " ^ idb ^ " as a constant");
- true
- | B.Cast(ty,e) -> matches (B.unwrap_expr e)
- | B.Unary(e,B.UnMinus) -> matches (B.unwrap_expr e)
- | B.SizeOfExpr(exp) -> true
- | B.SizeOfType(ty) -> true
- | _ -> false in
- matches e
- | (A.LocalID,e) ->
- (matches_id e) &&
- (match !opttypb with
- (Some (_,Ast_c.LocalVar _),_) -> true
- | _ -> false)
- | (A.ID,e) -> matches_id e in
-
- if form_ok
- then
- (let (opttypb,_testb) = !opttypb in
- match opttypa, opttypb with
- | None, _ -> return ((),())
- | Some _, None ->
- pr2_once ("Missing type information. Certainly a pb in " ^
- "annotate_typer.ml");
- fail
-
- | Some tas, Some tb ->
- tas +> List.fold_left (fun acc ta ->
- acc >|+|> compatible_type ta tb) fail
- ) >>=
- (fun () () ->
- X.check_constraints expression constraints eb
- (fun () ->
- let max_min _ =
- Lib_parsing_c.lin_col_by_pos (Lib_parsing_c.ii_of_expr expb) in
- X.envf keep inherited (ida, Ast_c.MetaExprVal expb, max_min)
- (fun () ->
- X.distrf_e ida expb >>= (fun ida expb ->
- return (
- A.MetaExpr (ida,constraints,keep,opttypa,form,inherited)+>
- A.rewrap ea,
- expb
- ))
- )))
- else fail
-
- (* old:
- * | A.MetaExpr(ida,false,opttypa,_inherited), expb ->
- * D.distribute_mck (mcodekind ida) D.distribute_mck_e expb binding
- *
- * but bug! because if have not tagged SP, then transform without doing
- * any checks. Hopefully now have tagged SP technique.
- *)
-
-
- (* old:
- * | A.Edots _, _ -> raise Impossible.
- *
- * In fact now can also have the Edots inside normal expression, not
- * just in arg lists. in 'x[...];' less: in if(<... x ... y ...>)
- *)
- | A.Edots (mcode, None), expb ->
- X.distrf_e (dots2metavar mcode) expb >>= (fun mcode expb ->
- return (
- A.Edots (metavar2dots mcode, None) +> A.rewrap ea ,
- expb
- ))
-
-
- | A.Edots (_, Some expr), _ -> failwith "not handling when on Edots"
-
-
- | A.Ident ida, ((B.Ident idb, typ),ii) ->
- let ib1 = tuple_of_list1 ii in
- ident DontKnow ida (idb, ib1) >>= (fun ida (idb, ib1) ->
- return (
- ((A.Ident ida)) +> wa,
- ((B.Ident idb, typ),[ib1])
- ))
-
-
-
-
- | A.MetaErr _, _ -> failwith "not handling MetaErr"
-
- (* todo?: handle some isomorphisms in int/float ? can have different
- * format : 1l can match a 1.
- *
- * todo: normally string can contain some metavar too, so should
- * recurse on the string
- *)
- | A.Constant (ia1), ((B.Constant (ib) , typ),ii) ->
- (* for everything except the String case where can have multi elems *)
- let do1 () =
- let ib1 = tuple_of_list1 ii in
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- return (
- ((A.Constant ia1)) +> wa,
- ((B.Constant (ib), typ),[ib1])
- ))
- in
- (match term ia1, ib with
- | A.Int x, B.Int y ->
- X.value_format_flag (fun use_value_equivalence ->
- if use_value_equivalence
- then
- if equal_c_int x y
- then do1()
- else fail
- else
- if x =$= y
- then do1()
- else fail
- )
- | A.Char x, B.Char (y,_) when x =$= y (* todo: use kind ? *)
- -> do1()
- | A.Float x, B.Float (y,_) when x =$= y (* todo: use floatType ? *)
- -> do1()
-
- | A.String sa, B.String (sb,_kind) when sa =$= sb ->
- (match ii with
- | [ib1] ->
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- return (
- ((A.Constant ia1)) +> wa,
- ((B.Constant (ib), typ),[ib1])
- ))
- | _ -> fail (* multi string, not handled *)
- )
- | _, _ -> fail
- )
-
-
- | A.FunCall (ea, ia1, eas, ia2), ((B.FunCall (eb, ebs), typ),ii) ->
- (* todo: do special case to allow IdMetaFunc, cos doing the
- * recursive call will be too late, match_ident will not have the
- * info whether it was a function. todo: but how detect when do
- * x.field = f; how know that f is a Func ? By having computed
- * some information before the matching!
- *
- * Allow match with FunCall containing types. Now ast_cocci allow
- * type in parameter, and morover ast_cocci allow f(...) and those
- * ... could match type.
- *)
- let (ib1, ib2) = tuple_of_list2 ii in
- expression ea eb >>= (fun ea eb ->
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- tokenf ia2 ib2 >>= (fun ia2 ib2 ->
- arguments (seqstyle eas) (A.undots eas) ebs >>= (fun easundots ebs ->
- let eas = redots eas easundots in
- return (
- ((A.FunCall (ea, ia1, eas, ia2)) +> wa,
- ((B.FunCall (eb, ebs),typ), [ib1;ib2])
- ))))))
-
-
-
-
- | A.Assignment (ea1, opa, ea2, simple),
- ((B.Assignment (eb1, opb, eb2), typ),ii) ->
- let (opbi) = tuple_of_list1 ii in
- if equal_assignOp (term opa) opb
- then
- expression ea1 eb1 >>= (fun ea1 eb1 ->
- expression ea2 eb2 >>= (fun ea2 eb2 ->
- tokenf opa opbi >>= (fun opa opbi ->
- return (
- ((A.Assignment (ea1, opa, ea2, simple))) +> wa,
- ((B.Assignment (eb1, opb, eb2), typ), [opbi])
- ))))
- else fail
-
- | A.CondExpr(ea1,ia1,ea2opt,ia2,ea3),((B.CondExpr(eb1,eb2opt,eb3),typ),ii) ->
- let (ib1, ib2) = tuple_of_list2 ii in
- expression ea1 eb1 >>= (fun ea1 eb1 ->
- option expression ea2opt eb2opt >>= (fun ea2opt eb2opt ->
- expression ea3 eb3 >>= (fun ea3 eb3 ->
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- tokenf ia2 ib2 >>= (fun ia2 ib2 ->
- return (
- ((A.CondExpr(ea1,ia1,ea2opt,ia2,ea3))) +> wa,
- ((B.CondExpr (eb1, eb2opt, eb3),typ), [ib1;ib2])
- ))))))
-
- (* todo?: handle some isomorphisms here ? *)
- | A.Postfix (ea, opa), ((B.Postfix (eb, opb), typ),ii) ->
- let opbi = tuple_of_list1 ii in
- if equal_fixOp (term opa) opb
- then
- expression ea eb >>= (fun ea eb ->
- tokenf opa opbi >>= (fun opa opbi ->
- return (
- ((A.Postfix (ea, opa))) +> wa,
- ((B.Postfix (eb, opb), typ),[opbi])
- )))
- else fail
-
-
- | A.Infix (ea, opa), ((B.Infix (eb, opb), typ),ii) ->
- let opbi = tuple_of_list1 ii in
- if equal_fixOp (term opa) opb
- then
- expression ea eb >>= (fun ea eb ->
- tokenf opa opbi >>= (fun opa opbi ->
- return (
- ((A.Infix (ea, opa))) +> wa,
- ((B.Infix (eb, opb), typ),[opbi])
- )))
- else fail
-
- | A.Unary (ea, opa), ((B.Unary (eb, opb), typ),ii) ->
- let opbi = tuple_of_list1 ii in
- if equal_unaryOp (term opa) opb
- then
- expression ea eb >>= (fun ea eb ->
- tokenf opa opbi >>= (fun opa opbi ->
- return (
- ((A.Unary (ea, opa))) +> wa,
- ((B.Unary (eb, opb), typ),[opbi])
- )))
- else fail
-
- | A.Binary (ea1, opa, ea2), ((B.Binary (eb1, opb, eb2), typ),ii) ->
- let opbi = tuple_of_list1 ii in
- if equal_binaryOp (term opa) opb
- then
- expression ea1 eb1 >>= (fun ea1 eb1 ->
- expression ea2 eb2 >>= (fun ea2 eb2 ->
- tokenf opa opbi >>= (fun opa opbi ->
- return (
- ((A.Binary (ea1, opa, ea2))) +> wa,
- ((B.Binary (eb1, opb, eb2), typ),[opbi]
- )))))
- else fail
-
- | A.Nested (ea1, opa, ea2), eb ->
- let rec loop eb =
- (if A.get_test_exp ea1 && not (Ast_c.is_test eb) then fail
- else expression ea1 eb) >|+|>
- (match eb with
- ((B.Binary (eb1, opb, eb2), typ),ii)
- when equal_binaryOp (term opa) opb ->
- let opbi = tuple_of_list1 ii in
- let left_to_right =
- (expression ea1 eb1 >>= (fun ea1 eb1 ->
- expression ea2 eb2 >>= (fun ea2 eb2 ->
- tokenf opa opbi >>= (fun opa opbi ->
- return (
- ((A.Nested (ea1, opa, ea2))) +> wa,
- ((B.Binary (eb1, opb, eb2), typ),[opbi]
- )))))) in
- let right_to_left =
- (expression ea2 eb1 >>= (fun ea2 eb1 ->
- expression ea1 eb2 >>= (fun ea1 eb2 ->
- tokenf opa opbi >>= (fun opa opbi ->
- return (
- ((A.Nested (ea1, opa, ea2))) +> wa,
- ((B.Binary (eb1, opb, eb2), typ),[opbi]
- )))))) in
- let in_left =
- (loop eb1 >>= (fun ea1 eb1 ->
- expression ea2 eb2 >>= (fun ea2 eb2 ->
- tokenf opa opbi >>= (fun opa opbi ->
- return (
- ((A.Nested (ea1, opa, ea2))) +> wa,
- ((B.Binary (eb1, opb, eb2), typ),[opbi]
- )))))) in
- let in_right =
- (expression ea2 eb1 >>= (fun ea2 eb1 ->
- loop eb2 >>= (fun ea1 eb2 ->
- tokenf opa opbi >>= (fun opa opbi ->
- return (
- ((A.Nested (ea1, opa, ea2))) +> wa,
- ((B.Binary (eb1, opb, eb2), typ),[opbi]
- )))))) in
- left_to_right >|+|> right_to_left >|+|> in_left >|+|> in_right
- | _ -> fail) in
- loop eb
-
- (* todo?: handle some isomorphisms here ? (with pointers = Unary Deref) *)
- | A.ArrayAccess (ea1, ia1, ea2, ia2),((B.ArrayAccess (eb1, eb2), typ),ii) ->
- let (ib1, ib2) = tuple_of_list2 ii in
- expression ea1 eb1 >>= (fun ea1 eb1 ->
- expression ea2 eb2 >>= (fun ea2 eb2 ->
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- tokenf ia2 ib2 >>= (fun ia2 ib2 ->
- return (
- ((A.ArrayAccess (ea1, ia1, ea2, ia2))) +> wa,
- ((B.ArrayAccess (eb1, eb2),typ), [ib1;ib2])
- )))))
-
- (* todo?: handle some isomorphisms here ? *)
- | A.RecordAccess (ea, ia1, ida), ((B.RecordAccess (eb, idb), typ),ii) ->
- let (ib1, ib2) = tuple_of_list2 ii in
- ident DontKnow ida (idb, ib2) >>= (fun ida (idb, ib2) ->
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- expression ea eb >>= (fun ea eb ->
- return (
- ((A.RecordAccess (ea, ia1, ida))) +> wa,
- ((B.RecordAccess (eb, idb), typ), [ib1;ib2])
- ))))
-
-
-
- | A.RecordPtAccess (ea,ia1,ida),((B.RecordPtAccess (eb, idb), typ), ii) ->
- let (ib1, ib2) = tuple_of_list2 ii in
- ident DontKnow ida (idb, ib2) >>= (fun ida (idb, ib2) ->
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- expression ea eb >>= (fun ea eb ->
- return (
- ((A.RecordPtAccess (ea, ia1, ida))) +> wa,
- ((B.RecordPtAccess (eb, idb), typ), [ib1;ib2])
- ))))
-
-
- (* todo?: handle some isomorphisms here ?
- * todo?: do some iso-by-absence on cast ?
- * by trying | ea, B.Case (typb, eb) -> match_e_e ea eb ?
- *)
-
- | A.Cast (ia1, typa, ia2, ea), ((B.Cast (typb, eb), typ),ii) ->
- let (ib1, ib2) = tuple_of_list2 ii in
- fullType typa typb >>= (fun typa typb ->
- expression ea eb >>= (fun ea eb ->
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- tokenf ia2 ib2 >>= (fun ia2 ib2 ->
- return (
- ((A.Cast (ia1, typa, ia2, ea))) +> wa,
- ((B.Cast (typb, eb),typ),[ib1;ib2])
- )))))
-
- | A.SizeOfExpr (ia1, ea), ((B.SizeOfExpr (eb), typ),ii) ->
- let ib1 = tuple_of_list1 ii in
- expression ea eb >>= (fun ea eb ->
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- return (
- ((A.SizeOfExpr (ia1, ea))) +> wa,
- ((B.SizeOfExpr (eb), typ),[ib1])
- )))
-
- | A.SizeOfType (ia1, ia2, typa, ia3), ((B.SizeOfType typb, typ),ii) ->
- let (ib1,ib2,ib3) = tuple_of_list3 ii in
- fullType typa typb >>= (fun typa typb ->
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- tokenf ia2 ib2 >>= (fun ia2 ib2 ->
- tokenf ia3 ib3 >>= (fun ia3 ib3 ->
- return (
- ((A.SizeOfType (ia1, ia2, typa, ia3))) +> wa,
- ((B.SizeOfType (typb),typ),[ib1;ib2;ib3])
- )))))
-
-
- (* todo? iso ? allow all the combinations ? *)
- | A.Paren (ia1, ea, ia2), ((B.ParenExpr (eb), typ),ii) ->
- let (ib1, ib2) = tuple_of_list2 ii in
- expression ea eb >>= (fun ea eb ->
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- tokenf ia2 ib2 >>= (fun ia2 ib2 ->
- return (
- ((A.Paren (ia1, ea, ia2))) +> wa,
- ((B.ParenExpr (eb), typ), [ib1;ib2])
- ))))
-
- | A.NestExpr(exps,None,true), eb ->
- (match A.unwrap exps with
- A.DOTS [exp] ->
- X.cocciExpExp expression exp eb >>= (fun exp eb ->
- return (
- (A.NestExpr(A.rewrap exps (A.DOTS [exp]),None,true)) +> wa,
- eb
- )
- )
- | _ ->
- failwith
- "for nestexpr, only handling the case with dots and only one exp")
-
- | A.NestExpr _, _ ->
- failwith "only handling multi and no when code in a nest expr"
-
- (* only in arg lists or in define body *)
- | A.TypeExp _, _ -> fail
-
- (* only in arg lists *)
- | A.MetaExprList _, _
- | A.EComma _, _
- | A.Ecircles _, _
- | A.Estars _, _
- ->
- raise Impossible
-
- | A.DisjExpr eas, eb ->
- eas +> List.fold_left (fun acc ea -> acc >|+|> (expression ea eb)) fail
-
- | A.UniqueExp _,_ | A.OptExp _,_ ->
- failwith "not handling Opt/Unique/Multi on expr"
-
- (* Because of Exp cant put a raise Impossible; have to put a fail *)
-
- (* have not a counter part in coccinelle, for the moment *)
- | _, ((B.Sequence _,_),_)
- | _, ((B.StatementExpr _,_),_)
- | _, ((B.Constructor _,_),_)
- -> fail
-
- | _, _ -> fail
-
-
-
-(* ------------------------------------------------------------------------- *)
-and (ident: info_ident -> (A.ident, string * Ast_c.info) matcher) =
- fun infoidb ida ((idb, iib) as ib) ->
- X.all_bound (A.get_inherited ida) >&&>
- match A.unwrap ida with
- | A.Id sa ->
- if (term sa) =$= idb then
- tokenf sa iib >>= (fun sa iib ->
- return (
- ((A.Id sa)) +> A.rewrap ida,
- (idb, iib)
- ))
- else fail
-
-
- | A.MetaId(mida,constraints,keep,inherited) ->
- X.check_constraints (ident infoidb) constraints ib
- (fun () ->
- let max_min _ = Lib_parsing_c.lin_col_by_pos [iib] in
- (* use drop_pos for ids so that the pos is not added a second time in
- the call to tokenf *)
- X.envf keep inherited (A.drop_pos mida, Ast_c.MetaIdVal (idb), max_min)
- (fun () ->
- tokenf mida iib >>= (fun mida iib ->
- return (
- ((A.MetaId (mida, constraints, keep, inherited)) +> A.rewrap ida,
- (idb, iib)
- )))
- ))
-
- | A.MetaFunc(mida,constraints,keep,inherited) ->
- let is_function _ =
- X.check_constraints (ident infoidb) constraints ib
- (fun () ->
- let max_min _ = Lib_parsing_c.lin_col_by_pos [iib] in
- X.envf keep inherited (A.drop_pos mida,Ast_c.MetaFuncVal idb,max_min)
- (fun () ->
- tokenf mida iib >>= (fun mida iib ->
- return (
- ((A.MetaFunc(mida,constraints,keep,inherited)))+>A.rewrap ida,
- (idb, iib)
- ))
- )) in
- (match infoidb with
- | LocalFunction | Function -> is_function()
- | DontKnow ->
- failwith "MetaFunc, need more semantic info about id"
- (* the following implementation could possibly be useful, if one
- follows the convention that a macro is always in capital letters
- and that a macro is not a function.
- (if idb =~ "^[A-Z_][A-Z_0-9]*$" then fail else is_function())*)
- )
-
- | A.MetaLocalFunc(mida,constraints,keep,inherited) ->
- (match infoidb with
- | LocalFunction ->
- X.check_constraints (ident infoidb) constraints ib
- (fun () ->
- let max_min _ = Lib_parsing_c.lin_col_by_pos [iib] in
- X.envf keep inherited
- (A.drop_pos mida,Ast_c.MetaLocalFuncVal idb, max_min)
- (fun () ->
- tokenf mida iib >>= (fun mida iib ->
- return (
- ((A.MetaLocalFunc(mida,constraints,keep,inherited)))
- +> A.rewrap ida,
- (idb, iib)
- ))
- ))
- | Function -> fail
- | DontKnow -> failwith "MetaLocalFunc, need more semantic info about id"
- )
-
- | A.OptIdent _ | A.UniqueIdent _ ->
- failwith "not handling Opt/Unique for ident"
-
-
-
-(* ------------------------------------------------------------------------- *)
-and (arguments: sequence ->
- (A.expression list, Ast_c.argument Ast_c.wrap2 list) matcher) =
- fun seqstyle eas ebs ->
- match seqstyle with
- | Unordered -> failwith "not handling ooo"
- | Ordered ->
- arguments_bis eas (Ast_c.split_comma ebs) >>= (fun eas ebs_splitted ->
- return (eas, (Ast_c.unsplit_comma ebs_splitted))
- )
-(* because '...' can match nothing, need to take care when have
- * ', ...' or '...,' as in f(..., X, Y, ...). It must match
- * f(1,2) for instance.
- * So I have added special cases such as (if startxs = []) and code
- * in the Ecomma matching rule.
- *
- * old: Must do some try, for instance when f(...,X,Y,...) have to
- * test the transfo for all the combinaitions and if multiple transfo
- * possible ? pb ? => the type is to return a expression option ? use
- * some combinators to help ?
- * update: with the tag-SP approach, no more a problem.
- *)
-
-and arguments_bis = fun eas ebs ->
- match eas, ebs with
- | [], [] -> return ([], [])
- | [], eb::ebs -> fail
- | ea::eas, ebs ->
- X.all_bound (A.get_inherited ea) >&&>
- (match A.unwrap ea, ebs with
- | A.Edots (mcode, optexpr), ys ->
- (* todo: if optexpr, then a WHEN and so may have to filter yys *)
- if optexpr <> None then failwith "not handling when in argument";
-
- (* '...' can take more or less the beginnings of the arguments *)
- let startendxs = Common.zip (Common.inits ys) (Common.tails ys) in
- startendxs +> List.fold_left (fun acc (startxs, endxs) ->
- acc >||> (
-
- (* allow '...', and maybe its associated ',' to match nothing.
- * for the associated ',' see below how we handle the EComma
- * to match nothing.
- *)
- (if startxs = []
- then
- if mcode_contain_plus (mcodekind mcode)
- then fail
- (* failwith "I have no token that I could accroche myself on" *)
- else return (dots2metavar mcode, [])
- else
- (* subtil: we dont want the '...' to match until the
- * comma. cf -test pb_params_iso. We would get at
- * "already tagged" error.
- * this is because both f (... x, ...) and f (..., x, ...)
- * would match a f(x,3) with our "optional-comma" strategy.
- *)
- (match Common.last startxs with
- | Right _ -> fail
- | Left _ ->
- X.distrf_args (dots2metavar mcode) startxs
- )
- )
- >>= (fun mcode startxs ->
- let mcode = metavar2dots mcode in
- arguments_bis eas endxs >>= (fun eas endxs ->
- return (
- (A.Edots (mcode, optexpr) +> A.rewrap ea) ::eas,
- startxs ++ endxs
- )))
- )
- ) fail
-
- | A.EComma ia1, Right ii::ebs ->
- let ib1 = tuple_of_list1 ii in
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- arguments_bis eas ebs >>= (fun eas ebs ->
- return (
- (A.EComma ia1 +> A.rewrap ea)::eas,
- (Right [ib1])::ebs
- )
- ))
- | A.EComma ia1, ebs ->
- (* allow ',' to maching nothing. optional comma trick *)
- if mcode_contain_plus (mcodekind ia1)
- then fail
- else arguments_bis eas ebs
-
- | A.MetaExprList(ida,leninfo,keep,inherited),ys ->
- let startendxs = Common.zip (Common.inits ys) (Common.tails ys) in
- startendxs +> List.fold_left (fun acc (startxs, endxs) ->
- acc >||> (
- let ok =
- if startxs = []
- then
- if mcode_contain_plus (mcodekind ida)
- then false
- (* failwith "no token that I could accroche myself on" *)
- else true
- else
- (match Common.last startxs with
- | Right _ -> false
- | Left _ -> true
- )
- in
- if not ok
- then fail
- else
- let startxs' = Ast_c.unsplit_comma startxs in
- let len = List.length startxs' in
-
- (match leninfo with
- | Some (lenname,lenkeep,leninherited) ->
- let max_min _ = failwith "no pos" in
- X.envf lenkeep leninherited
- (lenname, Ast_c.MetaListlenVal (len), max_min)
- | None -> function f -> f()
- )
- (fun () ->
- let max_min _ =
- Lib_parsing_c.lin_col_by_pos
- (Lib_parsing_c.ii_of_args startxs) in
- X.envf keep inherited
- (ida, Ast_c.MetaExprListVal startxs', max_min)
- (fun () ->
- if startxs = []
- then return (ida, [])
- else X.distrf_args ida (Ast_c.split_comma startxs')
- )
- >>= (fun ida startxs ->
- arguments_bis eas endxs >>= (fun eas endxs ->
- return (
- (A.MetaExprList(ida,leninfo,keep,inherited))
- +> A.rewrap ea::eas,
- startxs ++ endxs
- ))
- )
- )
- )) fail
-
-
- | _unwrapx, (Left eb)::ebs ->
- argument ea eb >>= (fun ea eb ->
- arguments_bis eas ebs >>= (fun eas ebs ->
- return (ea::eas, Left eb::ebs)
- ))
- | _unwrapx, (Right y)::ys -> raise Impossible
- | _unwrapx, [] -> fail
- )
-
-
-and argument arga argb =
- X.all_bound (A.get_inherited arga) >&&>
- match A.unwrap arga, argb with
- | A.TypeExp tya, Right (B.ArgType (((b, sopt, tyb), ii_b_s))) ->
-
- if b || sopt <> None
- then
- (* failwith "the argument have a storage and ast_cocci does not have"*)
- fail
- else
- fullType tya tyb >>= (fun tya tyb ->
- return (
- (A.TypeExp tya) +> A.rewrap arga,
- (Right (B.ArgType (((b, sopt, tyb), ii_b_s))))
- ))
-
- | A.TypeExp tya, _ -> fail
- | _, Right (B.ArgType (tyb, sto_iisto)) -> fail
- | _, Left argb ->
- expression arga argb >>= (fun arga argb ->
- return (arga, Left argb)
- )
- | _, Right (B.ArgAction y) -> fail
-
-
-(* ------------------------------------------------------------------------- *)
-(* todo? facto code with argument ? *)
-and (parameters: sequence ->
- (A.parameterTypeDef list, Ast_c.parameterType Ast_c.wrap2 list)
- matcher) =
- fun seqstyle eas ebs ->
- match seqstyle with
- | Unordered -> failwith "not handling ooo"
- | Ordered ->
- parameters_bis eas (Ast_c.split_comma ebs) >>= (fun eas ebs_splitted ->
- return (eas, (Ast_c.unsplit_comma ebs_splitted))
- )
-
-
-and parameters_bis eas ebs =
- match eas, ebs with
- | [], [] -> return ([], [])
- | [], eb::ebs -> fail
- | ea::eas, ebs ->
- (* the management of positions is inlined into each case, because
- sometimes there is a Param and sometimes a ParamList *)
- X.all_bound (A.get_inherited ea) >&&>
- (match A.unwrap ea, ebs with
- | A.Pdots (mcode), ys ->
-
- (* '...' can take more or less the beginnings of the arguments *)
- let startendxs = Common.zip (Common.inits ys) (Common.tails ys) in
- startendxs +> List.fold_left (fun acc (startxs, endxs) ->
- acc >||> (
-
- (if startxs = []
- then
- if mcode_contain_plus (mcodekind mcode)
- then fail
- (* failwith "I have no token that I could accroche myself on"*)
- else return (dots2metavar mcode, [])
- else
- (match Common.last startxs with
- | Right _ -> fail
- | Left _ ->
- X.distrf_params (dots2metavar mcode) startxs
- )
- ) >>= (fun mcode startxs ->
- let mcode = metavar2dots mcode in
- parameters_bis eas endxs >>= (fun eas endxs ->
- return (
- (A.Pdots (mcode) +> A.rewrap ea) ::eas,
- startxs ++ endxs
- )))
- )
- ) fail
-
- | A.PComma ia1, Right ii::ebs ->
- let ib1 = tuple_of_list1 ii in
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- parameters_bis eas ebs >>= (fun eas ebs ->
- return (
- (A.PComma ia1 +> A.rewrap ea)::eas,
- (Right [ib1])::ebs
- )
- ))
-
- | A.PComma ia1, ebs ->
- (* try optional comma trick *)
- if mcode_contain_plus (mcodekind ia1)
- then fail
- else parameters_bis eas ebs
-
-
- | A.MetaParamList(ida,leninfo,keep,inherited),ys->
- let startendxs = Common.zip (Common.inits ys) (Common.tails ys) in
- startendxs +> List.fold_left (fun acc (startxs, endxs) ->
- acc >||> (
- let ok =
- if startxs = []
- then
- if mcode_contain_plus (mcodekind ida)
- then false
- (* failwith "I have no token that I could accroche myself on" *)
- else true
- else
- (match Common.last startxs with
- | Right _ -> false
- | Left _ -> true
- )
- in
- if not ok
- then fail
- else
- let startxs' = Ast_c.unsplit_comma startxs in
- let len = List.length startxs' in
-
- (match leninfo with
- Some (lenname,lenkeep,leninherited) ->
- let max_min _ = failwith "no pos" in
- X.envf lenkeep leninherited
- (lenname, Ast_c.MetaListlenVal (len), max_min)
- | None -> function f -> f()
- )
- (fun () ->
- let max_min _ =
- Lib_parsing_c.lin_col_by_pos
- (Lib_parsing_c.ii_of_params startxs) in
- X.envf keep inherited
- (ida, Ast_c.MetaParamListVal startxs', max_min)
- (fun () ->
- if startxs = []
- then return (ida, [])
- else X.distrf_params ida (Ast_c.split_comma startxs')
- ) >>= (fun ida startxs ->
- parameters_bis eas endxs >>= (fun eas endxs ->
- return (
- (A.MetaParamList(ida,leninfo,keep,inherited))
- +> A.rewrap ea::eas,
- startxs ++ endxs
- ))
- )
- ))
- ) fail
-
-
- | A.VoidParam ta, ys ->
- (match eas, ebs with
- | [], [Left eb] ->
- let ((hasreg, idbopt, tb), ii_b_s) = eb in
- if idbopt = None && null ii_b_s
- then
- match tb with
- | (qub, (B.BaseType B.Void,_)) ->
- fullType ta tb >>= (fun ta tb ->
- return (
- [(A.VoidParam ta) +> A.rewrap ea],
- [Left ((hasreg, idbopt, tb), ii_b_s)]
- ))
- | _ -> fail
- else fail
- | _ -> fail
- )
-
- | (A.OptParam _ | A.UniqueParam _), _ ->
- failwith "handling Opt/Unique for Param"
-
- | A.Pcircles (_), ys -> raise Impossible (* in Ordered mode *)
-
-
- | A.MetaParam (ida,keep,inherited), (Left eb)::ebs ->
- (* todo: use quaopt, hasreg ? *)
- let max_min _ =
- Lib_parsing_c.lin_col_by_pos (Lib_parsing_c.ii_of_param eb) in
- X.envf keep inherited (ida,Ast_c.MetaParamVal eb,max_min) (fun () ->
- X.distrf_param ida eb
- ) >>= (fun ida eb ->
- parameters_bis eas ebs >>= (fun eas ebs ->
- return (
- (A.MetaParam(ida,keep,inherited))+> A.rewrap ea::eas,
- (Left eb)::ebs
- )))
-
-
- | A.Param (typa, idaopt), (Left eb)::ebs ->
- (*this should succeed if the C code has a name, and fail otherwise*)
- parameter (idaopt, typa) eb >>= (fun (idaopt, typa) eb ->
- parameters_bis eas ebs >>= (fun eas ebs ->
- return (
- (A.Param (typa, idaopt))+> A.rewrap ea :: eas,
- (Left eb)::ebs
- )))
-
- | _unwrapx, (Right y)::ys -> raise Impossible
- | _unwrapx, [] -> fail
- )
-
-
-
-
-
-and parameter = fun (idaopt, typa) ((hasreg, idbopt, typb), ii_b_s) ->
- fullType typa typb >>= (fun typa typb ->
- match idaopt, Ast_c.split_register_param (hasreg, idbopt, ii_b_s) with
- | Some ida, Left (idb, iihasreg, iidb) ->
- (* todo: if minus on ida, should also minus the iihasreg ? *)
- ident DontKnow ida (idb,iidb) >>= (fun ida (idb,iidb) ->
- return (
- (Some ida, typa),
- ((hasreg, Some idb, typb), iihasreg++[iidb])
- ))
-
- | None, Right iihasreg ->
- return (
- (None, typa),
- ((hasreg, None, typb), iihasreg)
- )
-
-
- (* why handle this case ? because of transform_proto ? we may not
- * have an ident in the proto.
- * If have some plus on ida ? do nothing about ida ?
- *)
- (* not anymore !!! now that julia is handling the proto.
- | _, Right iihasreg ->
- return (
- (idaopt, typa),
- ((hasreg, None, typb), iihasreg)
- )
- *)
-
- | Some _, Right _ -> fail
- | None, Left _ -> fail
- )
-
-
-
-
-(* ------------------------------------------------------------------------- *)
-and (declaration: (A.mcodekind * bool * A.declaration,B.declaration) matcher) =
- fun (mckstart, allminus, decla) declb ->
- X.all_bound (A.get_inherited decla) >&&>
- match A.unwrap decla, declb with
-
- (* Un MetaDecl est introduit dans l'asttoctl pour sauter au dessus
- * de toutes les declarations qui sont au debut d'un fonction et
- * commencer le reste du match au premier statement. Alors, ca matche
- * n'importe quelle declaration. On n'a pas besoin d'ajouter
- * quoi que ce soit dans l'environnement. C'est une sorte de DDots.
- *
- * When the SP want to remove the whole function, the minus is not
- * on the MetaDecl but on the MetaRuleElem. So there should
- * be no transform of MetaDecl, just matching are allowed.
- *)
-
- | A.MetaDecl(ida,_keep,_inherited), _ -> (* keep ? inherited ? *)
- (* todo: should not happen in transform mode *)
- return ((mckstart, allminus, decla), declb)
-
-
-
- | _, (B.DeclList ([var], iiptvirgb::iifakestart::iisto)) ->
- onedecl allminus decla (var,iiptvirgb,iisto) >>=
- (fun decla (var,iiptvirgb,iisto)->
- X.tokenf_mck mckstart iifakestart >>= (fun mckstart iifakestart ->
- return (
- (mckstart, allminus, decla),
- (B.DeclList ([var], iiptvirgb::iifakestart::iisto))
- )))
-
- | _, (B.DeclList (xs, iiptvirgb::iifakestart::iisto)) ->
- if X.mode = PatternMode
- then
- xs +> List.fold_left (fun acc var ->
- acc >||> (
- X.tokenf_mck mckstart iifakestart >>= (fun mckstart iifakestart ->
- onedecl allminus decla (var, iiptvirgb, iisto) >>=
- (fun decla (var, iiptvirgb, iisto) ->
- return (
- (mckstart, allminus, decla),
- (B.DeclList ([var], iiptvirgb::iifakestart::iisto))
- )))))
- fail
- else
- failwith "More that one variable in decl. Have to split to transform."
-
- | A.MacroDecl (sa,lpa,eas,rpa,enda), B.MacroDecl ((sb,ebs),ii) ->
- let (iisb, lpb, rpb, iiendb, iifakestart, iistob) =
- (match ii with
- | iisb::lpb::rpb::iiendb::iifakestart::iisto ->
- (iisb,lpb,rpb,iiendb, iifakestart,iisto)
- | _ -> raise Impossible
- ) in
- (if allminus
- then minusize_list iistob
- else return ((), iistob)
- ) >>= (fun () iistob ->
-
- X.tokenf_mck mckstart iifakestart >>= (fun mckstart iifakestart ->
- ident DontKnow sa (sb, iisb) >>= (fun sa (sb, iisb) ->
- tokenf lpa lpb >>= (fun lpa lpb ->
- tokenf rpa rpb >>= (fun rpa rpb ->
- tokenf enda iiendb >>= (fun enda iiendb ->
- arguments (seqstyle eas) (A.undots eas) ebs >>= (fun easundots ebs ->
- let eas = redots eas easundots in
-
- return (
- (mckstart, allminus,
- (A.MacroDecl (sa,lpa,eas,rpa,enda)) +> A.rewrap decla),
- (B.MacroDecl ((sb,ebs),
- [iisb;lpb;rpb;iiendb;iifakestart] ++ iistob))
- ))))))))
-
- | _ -> fail
-
-
-
-and onedecl = fun allminus decla (declb, iiptvirgb, iistob) ->
- X.all_bound (A.get_inherited decla) >&&>
- match A.unwrap decla, declb with
-
- (* kind of typedef iso, we must unfold, it's for the case
- * T { }; that we want to match against typedef struct { } xx_t;
- *)
- | A.TyDecl (tya0, ptvirga),
- ((Some ((idb, None),[iidb]), typb0, (B.StoTypedef, inl), local), iivirg) ->
-
- (match A.unwrap tya0, typb0 with
- | A.Type(cv1,tya1), ((qu,il),typb1) ->
-
- (match A.unwrap tya1, typb1 with
- | A.StructUnionDef(tya2, lba, declsa, rba),
- (B.StructUnion (sub, sbopt, declsb), ii) ->
-
- let (iisub, iisbopt, lbb, rbb) =
- match sbopt with
- | None ->
- let (iisub, lbb, rbb) = tuple_of_list3 ii in
- (iisub, [], lbb, rbb)
- | Some s ->
- pr2 (sprintf
- "warning: both a typedef (%s) and struct name introduction (%s)"
- idb s
- );
- pr2 "warning: I will consider only the typedef";
- let (iisub, iisb, lbb, rbb) = tuple_of_list4 ii in
- (iisub, [iisb], lbb, rbb)
- in
- let structnameb =
- structdef_to_struct_name
- (Ast_c.nQ, (B.StructUnion (sub, sbopt, declsb), ii))
- in
- let fake_typeb =
- Ast_c.nQ,((B.TypeName (idb, Some
- (Lib_parsing_c.al_type structnameb))), [iidb])
- in
-
- tokenf ptvirga iiptvirgb >>= (fun ptvirga iiptvirgb ->
- tokenf lba lbb >>= (fun lba lbb ->
- tokenf rba rbb >>= (fun rba rbb ->
- struct_fields (A.undots declsa) declsb >>=(fun undeclsa declsb ->
- let declsa = redots declsa undeclsa in
-
- (match A.unwrap tya2 with
- | A.Type(cv3, tya3) ->
- (match A.unwrap tya3 with
- | A.MetaType(ida,keep, inherited) ->
-
- fullType tya2 fake_typeb >>= (fun tya2 fake_typeb ->
- let tya1 =
- A.StructUnionDef(tya2,lba,declsa,rba)+> A.rewrap tya1 in
- let tya0 = A.Type(cv1, tya1) +> A.rewrap tya0 in
-
-
- let typb1 = B.StructUnion (sub,sbopt, declsb),
- [iisub] @ iisbopt @ [lbb;rbb] in
- let typb0 = ((qu, il), typb1) in
-
- match fake_typeb with
- | _nQ, ((B.TypeName (idb,_typ)), [iidb]) ->
-
- return (
- (A.TyDecl (tya0, ptvirga)) +> A.rewrap decla,
- (((Some ((idb, None),[iidb]), typb0, (B.StoTypedef, inl),
- local),
- iivirg),iiptvirgb,iistob)
- )
- | _ -> raise Impossible
- )
-
- | A.StructUnionName(sua, sa) ->
-
- fullType tya2 structnameb >>= (fun tya2 structnameb ->
-
- let tya1 = A.StructUnionDef(tya2,lba,declsa,rba)+> A.rewrap tya1
- in
- let tya0 = A.Type(cv1, tya1) +> A.rewrap tya0 in
-
- match structnameb with
- | _nQ, (B.StructUnionName (sub, s), [iisub;iisbopt]) ->
-
- let typb1 = B.StructUnion (sub,sbopt, declsb),
- [iisub;iisbopt;lbb;rbb] in
- let typb0 = ((qu, il), typb1) in
-
- return (
- (A.TyDecl (tya0, ptvirga)) +> A.rewrap decla,
- (((Some ((idb, None),[iidb]), typb0,
- (B.StoTypedef, inl), local),
- iivirg),iiptvirgb,iistob)
- )
- | _ -> raise Impossible
- )
- | _ -> raise Impossible
- )
- | _ -> fail
- )))))
- | _ -> fail
- )
- | _ -> fail
- )
-
- | A.UnInit (stoa, typa, ida, ptvirga),
- ((Some ((idb, _),[iidb]), typb, (B.StoTypedef,_), _local), iivirg) ->
- fail
-
- | A.Init (stoa, typa, ida, eqa, inia, ptvirga),
- ((Some ((idb, _),[iidb]), typb, (B.StoTypedef,_), _local), iivirg) ->
- fail
-
-
-
- (* could handle iso here but handled in standard.iso *)
- | A.UnInit (stoa, typa, ida, ptvirga),
- ((Some ((idb, None),[iidb]), typb, stob, local), iivirg) ->
- tokenf ptvirga iiptvirgb >>= (fun ptvirga iiptvirgb ->
- fullType typa typb >>= (fun typa typb ->
- ident DontKnow ida (idb, iidb) >>= (fun ida (idb, iidb) ->
- storage_optional_allminus allminus stoa (stob, iistob) >>=
- (fun stoa (stob, iistob) ->
- return (
- (A.UnInit (stoa, typa, ida, ptvirga)) +> A.rewrap decla,
- (((Some ((idb,None),[iidb]),typb,stob,local),iivirg),
- iiptvirgb,iistob)
- )))))
-
- | A.Init (stoa, typa, ida, eqa, inia, ptvirga),
- ((Some((idb,Some inib),[iidb;iieqb]),typb,stob,local),iivirg)
- ->
- tokenf ptvirga iiptvirgb >>= (fun ptvirga iiptvirgb ->
- tokenf eqa iieqb >>= (fun eqa iieqb ->
- fullType typa typb >>= (fun typa typb ->
- ident DontKnow ida (idb, iidb) >>= (fun ida (idb, iidb) ->
- storage_optional_allminus allminus stoa (stob, iistob) >>=
- (fun stoa (stob, iistob) ->
- initialiser inia inib >>= (fun inia inib ->
- return (
- (A.Init (stoa, typa, ida, eqa, inia, ptvirga)) +> A.rewrap decla,
- (((Some((idb,Some inib),[iidb;iieqb]),typb,stob,local),iivirg),
- iiptvirgb,iistob)
- )))))))
-
- (* do iso-by-absence here ? allow typedecl and var ? *)
- | A.TyDecl (typa, ptvirga), ((None, typb, stob, local), iivirg) ->
- if stob = (B.NoSto, false)
- then
- tokenf ptvirga iiptvirgb >>= (fun ptvirga iiptvirgb ->
- fullType typa typb >>= (fun typa typb ->
- return (
- (A.TyDecl (typa, ptvirga)) +> A.rewrap decla,
- (((None, typb, stob, local), iivirg), iiptvirgb, iistob)
- )))
- else fail
-
-
- | A.Typedef (stoa, typa, ida, ptvirga),
- ((Some ((idb, None),[iidb]),typb,(B.StoTypedef,inline),local),iivirg) ->
-
- tokenf ptvirga iiptvirgb >>= (fun ptvirga iiptvirgb ->
- fullType typa typb >>= (fun typa typb ->
- (match iistob with
- | [iitypedef] ->
- tokenf stoa iitypedef >>= (fun stoa iitypedef ->
- return (stoa, [iitypedef])
- )
- | _ -> failwith "wierd, have both typedef and inline or nothing";
- ) >>= (fun stoa iistob ->
- (match A.unwrap ida with
- | A.MetaType(_,_,_) ->
-
- let fake_typeb =
- Ast_c.nQ, ((B.TypeName (idb, Ast_c.noTypedefDef())), [iidb])
- in
- fullTypebis ida fake_typeb >>= (fun ida fake_typeb ->
- match fake_typeb with
- | _nQ, ((B.TypeName (idb,_typ)), [iidb]) ->
- return (ida, (idb, iidb))
- | _ -> raise Impossible
- )
-
- | A.TypeName sa ->
- if (term sa) =$= idb
- then
- tokenf sa iidb >>= (fun sa iidb ->
- return (
- (A.TypeName sa) +> A.rewrap ida,
- (idb, iidb)
- ))
- else fail
- | _ -> raise Impossible
-
- ) >>= (fun ida (idb, iidb) ->
- return (
- (A.Typedef (stoa, typa, ida, ptvirga)) +> A.rewrap decla,
- (((Some ((idb, None),[iidb]), typb, (B.StoTypedef,inline),local),
- iivirg),
- iiptvirgb, iistob)
- )
- ))))
-
-
- | _, ((None, typb, sto, _local), _) ->
- (* old: failwith "no variable in this declaration, wierd" *)
- fail
-
-
-
- | A.DisjDecl declas, declb ->
- declas +> List.fold_left (fun acc decla ->
- acc >|+|>
- (* (declaration (mckstart, allminus, decla) declb) *)
- (onedecl allminus decla (declb,iiptvirgb, iistob))
- ) fail
-
-
-
- (* only in struct type decls *)
- | A.Ddots(dots,whencode), _ ->
- raise Impossible
-
- | A.OptDecl _, _ | A.UniqueDecl _, _ ->
- failwith "not handling Opt/Unique Decl"
-
-
- | _, _ -> fail
-
-
-
-(* ------------------------------------------------------------------------- *)
-
-and (initialiser: (A.initialiser, Ast_c.initialiser) matcher) = fun ia ib ->
- X.all_bound (A.get_inherited ia) >&&>
- match (A.unwrap ia,ib) with
-
- | (A.InitExpr expa, ib) ->
- (match A.unwrap expa, ib with
- | A.Edots (mcode, None), ib ->
- X.distrf_ini (dots2metavar mcode) ib >>= (fun mcode ib ->
- return (
- A.InitExpr
- (A.Edots (metavar2dots mcode, None) +> A.rewrap expa)
- +> A.rewrap ia,
- ib
- ))
-
- | A.Edots (_, Some expr), _ -> failwith "not handling when on Edots"
-
- | _, (B.InitExpr expb, ii) ->
- assert (null ii);
- expression expa expb >>= (fun expa expb ->
- return (
- (A.InitExpr expa) +> A.rewrap ia,
- (B.InitExpr expb, ii)
- ))
- | _ -> fail
- )
-
- | (A.InitList (ia1, ias, ia2, []), (B.InitList ibs, ii)) ->
- (match ii with
- | ib1::ib2::iicommaopt ->
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- tokenf ia2 ib2 >>= (fun ia2 ib2 ->
- initialisers ias (ibs, iicommaopt) >>= (fun ias (ibs,iicommaopt) ->
- return (
- (A.InitList (ia1, ias, ia2, [])) +> A.rewrap ia,
- (B.InitList ibs, ib1::ib2::iicommaopt)
- ))))
-
- | _ -> raise Impossible
- )
-
- | (A.InitList (i1, ias, i2, whencode),(B.InitList ibs, _ii)) ->
- failwith "TODO: not handling whencode in initialisers"
-
-
- | (A.InitGccDotName (ia1, ida, ia2, inia),
- (B.InitDesignators ([B.DesignatorField idb,ii1], inib), ii2))->
-
- let (iidot, iidb) = tuple_of_list2 ii1 in
- let iieq = tuple_of_list1 ii2 in
-
- tokenf ia1 iidot >>= (fun ia1 iidot ->
- tokenf ia2 iieq >>= (fun ia2 iieq ->
- ident DontKnow ida (idb, iidb) >>= (fun ida (idb, iidb) ->
- initialiser inia inib >>= (fun inia inib ->
- return (
- (A.InitGccDotName (ia1, ida, ia2, inia)) +> A.rewrap ia,
- (B.InitDesignators
- ([B.DesignatorField idb, [iidot;iidb]], inib), [iieq])
- )))))
-
-
- | (A.InitGccIndex (ia1,ea,ia2,ia3,inia),
- (B.InitDesignators ([B.DesignatorIndex eb, ii1], inib), ii2)) ->
-
- let (ib1, ib2) = tuple_of_list2 ii1 in
- let ib3 = tuple_of_list1 ii2 in
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- tokenf ia2 ib2 >>= (fun ia2 ib2 ->
- tokenf ia3 ib3 >>= (fun ia3 ib3 ->
- expression ea eb >>= (fun ea eb ->
- initialiser inia inib >>= (fun inia inib ->
- return (
- (A.InitGccIndex (ia1,ea,ia2,ia3,inia)) +> A.rewrap ia,
- (B.InitDesignators
- ([B.DesignatorIndex eb, [ib1;ib2]], inib), [ib3])
- ))))))
-
-
- | (A.InitGccRange (ia1,e1a,ia2,e2a,ia3,ia4,inia),
- (B.InitDesignators ([B.DesignatorRange (e1b, e2b), ii1], inib), ii2)) ->
-
- let (ib1, ib2, ib3) = tuple_of_list3 ii1 in
- let (ib4) = tuple_of_list1 ii2 in
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- tokenf ia2 ib2 >>= (fun ia2 ib2 ->
- tokenf ia3 ib3 >>= (fun ia3 ib3 ->
- tokenf ia4 ib4 >>= (fun ia4 ib4 ->
- expression e1a e1b >>= (fun e1a e1b ->
- expression e2a e2b >>= (fun e2a e2b ->
- initialiser inia inib >>= (fun inia inib ->
- return (
- (A.InitGccRange (ia1,e1a,ia2,e2a,ia3,ia4,inia)) +> A.rewrap ia,
- (B.InitDesignators
- ([B.DesignatorRange (e1b, e2b),[ib1;ib2;ib3]], inib), [ib4])
- ))))))))
-
-
-
-
- | (A.InitGccName (ida, ia1, inia), (B.InitFieldOld (idb, inib), ii)) ->
- (match ii with
- | [iidb;iicolon] ->
- ident DontKnow ida (idb, iidb) >>= (fun ida (idb, iidb) ->
- initialiser inia inib >>= (fun inia inib ->
- tokenf ia1 iicolon >>= (fun ia1 iicolon ->
- return (
- (A.InitGccName (ida, ia1, inia)) +> A.rewrap ia,
- (B.InitFieldOld (idb, inib), [iidb;iicolon])
- ))))
- | _ -> fail
- )
-
-
-
- | A.IComma(comma), _ ->
- raise Impossible
-
- | A.UniqueIni _,_ | A.OptIni _,_ ->
- failwith "not handling Opt/Unique on initialisers"
-
- | _, _ -> fail
-
-
-
-
-
-and initialisers = fun ias (ibs, iicomma) ->
- let ias_unsplit = unsplit_icomma ias in
- let ibs_split = resplit_initialiser ibs iicomma in
-
- let f =
- if need_unordered_initialisers ibs
- then initialisers_unordered2
- else initialisers_ordered2
- in
- f ias_unsplit ibs_split >>=
- (fun ias_unsplit ibs_split ->
- return (
- split_icomma ias_unsplit,
- unsplit_initialiser ibs_split
- )
- )
-
-(* todo: one day julia will reput a IDots *)
-and initialisers_ordered2 = fun ias ibs ->
- match ias, ibs with
- | [], [] -> return ([], [])
- | (x, xcomma)::xs, (y, commay)::ys ->
- (match A.unwrap xcomma with
- | A.IComma commax ->
- tokenf commax commay >>= (fun commax commay ->
- initialiser x y >>= (fun x y ->
- initialisers_ordered2 xs ys >>= (fun xs ys ->
- return (
- (x, (A.IComma commax) +> A.rewrap xcomma)::xs,
- (y, commay)::ys
- )
- )))
- | _ -> raise Impossible (* unsplit_iicomma wrong *)
- )
- | _ -> fail
-
-
-
-and initialisers_unordered2 = fun ias ibs ->
-
- match ias, ibs with
- | [], ys -> return ([], ys)
- | (x,xcomma)::xs, ys ->
-
- let permut = Common.uncons_permut_lazy ys in
- permut +> List.fold_left (fun acc ((e, pos), rest) ->
- acc >||>
- (
- (match A.unwrap xcomma, e with
- | A.IComma commax, (y, commay) ->
- tokenf commax commay >>= (fun commax commay ->
- initialiser x y >>= (fun x y ->
- return (
- (x, (A.IComma commax) +> A.rewrap xcomma),
- (y, commay))
- )
- )
- | _ -> raise Impossible (* unsplit_iicomma wrong *)
- )
- >>= (fun x e ->
- let rest = Lazy.force rest in
- initialisers_unordered2 xs rest >>= (fun xs rest ->
- return (
- x::xs,
- Common.insert_elem_pos (e, pos) rest
- ))))
- ) fail
-
-
-(* ------------------------------------------------------------------------- *)
-and (struct_fields: (A.declaration list, B.field B.wrap list) matcher) =
- fun eas ebs ->
- match eas, ebs with
- | [], [] -> return ([], [])
- | [], eb::ebs -> fail
- | ea::eas, ebs ->
- X.all_bound (A.get_inherited ea) >&&>
- (match A.unwrap ea, ebs with
- | A.Ddots (mcode, optwhen), ys ->
- if optwhen <> None then failwith "not handling when in argument";
-
- (* '...' can take more or less the beginnings of the arguments *)
- let startendxs = Common.zip (Common.inits ys) (Common.tails ys) in
- startendxs +> List.fold_left (fun acc (startxs, endxs) ->
- acc >||> (
-
- (if startxs = []
- then
- if mcode_contain_plus (mcodekind mcode)
- then fail
- (* failwith "I have no token that I could accroche myself on" *)
- else return (dots2metavar mcode, [])
- else
-
- X.distrf_struct_fields (dots2metavar mcode) startxs
- ) >>= (fun mcode startxs ->
- let mcode = metavar2dots mcode in
- struct_fields eas endxs >>= (fun eas endxs ->
- return (
- (A.Ddots (mcode, optwhen) +> A.rewrap ea) ::eas,
- startxs ++ endxs
- )))
- )
- ) fail
- | _unwrapx, eb::ebs ->
- struct_field ea eb >>= (fun ea eb ->
- struct_fields eas ebs >>= (fun eas ebs ->
- return (ea::eas, eb::ebs)
- ))
-
- | _unwrapx, [] -> fail
- )
-
-and (struct_field: (A.declaration, B.field B.wrap) matcher) = fun fa fb ->
- let (xfield, ii) = fb in
- let iiptvirgb = tuple_of_list1 ii in
-
- match xfield with
- | B.FieldDeclList onefield_multivars ->
-
- (match onefield_multivars with
- | [] -> raise Impossible
- | [onevar,iivirg] ->
- assert (null iivirg);
- (match onevar with
- | B.BitField (sopt, typb, expr), ii ->
- pr2_once "warning: bitfield not handled by ast_cocci";
- fail
- | B.Simple (None, typb), ii ->
- pr2_once "warning: unamed struct field not handled by ast_cocci";
- fail
- | B.Simple (Some idb, typb), ii ->
- let (iidb) = tuple_of_list1 ii in
-
- (* build a declaration from a struct field *)
- let allminus = false in
- let iisto = [] in
- let stob = B.NoSto, false in
- let fake_var =
- ((Some ((idb, None),[iidb]), typb, stob, Ast_c.NotLocalDecl),
- iivirg)
- in
- onedecl allminus fa (fake_var,iiptvirgb,iisto) >>=
- (fun fa (var,iiptvirgb,iisto) ->
-
- match fake_var with
- | ((Some ((idb, None),[iidb]), typb, stob, local), iivirg) ->
- let onevar = B.Simple (Some idb, typb), [iidb] in
-
- return (
- (fa),
- (B.FieldDeclList [onevar, iivirg], [iiptvirgb])
- )
- | _ -> raise Impossible
- )
- )
-
- | x::y::xs ->
- pr2_once "PB: More that one variable in decl. Have to split";
- fail
- )
- | B.EmptyField -> fail
-
-
-
-(* ------------------------------------------------------------------------- *)
-and (fullType: (A.fullType, Ast_c.fullType) matcher) =
- fun typa typb ->
- X.optional_qualifier_flag (fun optional_qualifier ->
- X.all_bound (A.get_inherited typa) >&&>
- match A.unwrap typa, typb with
- | A.Type(cv,ty1), ((qu,il),ty2) ->
-
- if qu.B.const && qu.B.volatile
- then
- pr2_once
- ("warning: the type is both const & volatile but cocci " ^
- "does not handle that");
-
- (* Drop out the const/volatile part that has been matched.
- * This is because a SP can contain const T v; in which case
- * later in match_t_t when we encounter a T, we must not add in
- * the environment the whole type.
- *)
-
-
- (match cv with
- (* "iso-by-absence" *)
- | None ->
- let do_stuff () =
- fullTypebis ty1 ((qu,il), ty2) >>= (fun ty1 fullty2 ->
- return (
- (A.Type(None, ty1)) +> A.rewrap typa,
- fullty2
- ))
- in
- (match optional_qualifier, qu.B.const || qu.B.volatile with
- | false, false -> do_stuff ()
- | false, true -> fail
- | true, false -> do_stuff ()
- | true, true ->
- if !Flag.show_misc
- then pr2_once "USING optional_qualifier builtin isomorphism";
- do_stuff()
- )
-
-
- | Some x ->
- (* todo: can be __const__ ? can be const & volatile so
- * should filter instead ?
- *)
- (match term x, il with
- | A.Const, [i1] when qu.B.const ->
-
- tokenf x i1 >>= (fun x i1 ->
- fullTypebis ty1 (Ast_c.nQ,ty2) >>= (fun ty1 (_, ty2) ->
- return (
- (A.Type(Some x, ty1)) +> A.rewrap typa,
- ((qu, [i1]), ty2)
- )))
-
- | A.Volatile, [i1] when qu.B.volatile ->
- tokenf x i1 >>= (fun x i1 ->
- fullTypebis ty1 (Ast_c.nQ,ty2) >>= (fun ty1 (_, ty2) ->
- return (
- (A.Type(Some x, ty1)) +> A.rewrap typa,
- ((qu, [i1]), ty2)
- )))
-
- | _ -> fail
- )
- )
-
- | A.DisjType typas, typb ->
- typas +>
- List.fold_left (fun acc typa -> acc >|+|> (fullType typa typb)) fail
-
- | A.OptType(_), _ | A.UniqueType(_), _
- -> failwith "not handling Opt/Unique on type"
- )
-
-
-(*
- * Why not (A.typeC, Ast_c.typeC) matcher ?
- * because when there is MetaType, we want that T record the whole type,
- * including the qualifier, and so this type (and the new_il function in
- * preceding function).
-*)
-
-and (fullTypebis: (A.typeC, Ast_c.fullType) matcher) =
- fun ta tb ->
- X.all_bound (A.get_inherited ta) >&&>
- match A.unwrap ta, tb with
-
- (* cas general *)
- | A.MetaType(ida,keep, inherited), typb ->
- let max_min _ =
- Lib_parsing_c.lin_col_by_pos (Lib_parsing_c.ii_of_type typb) in
- X.envf keep inherited (ida, B.MetaTypeVal typb, max_min) (fun () ->
- X.distrf_type ida typb >>= (fun ida typb ->
- return (
- A.MetaType(ida,keep, inherited) +> A.rewrap ta,
- typb
- ))
- )
- | unwrap, (qub, typb) ->
- typeC ta typb >>= (fun ta typb ->
- return (ta, (qub, typb))
- )
-
-
-and (typeC: (A.typeC, Ast_c.typeC) matcher) =
- fun ta tb ->
- match A.unwrap ta, tb with
- | A.BaseType (basea, signaopt), (B.BaseType baseb, ii) ->
- (* In ii there is a list, sometimes of length 1 or 2 or 3.
- * And even if in baseb we have a Signed Int, that does not mean
- * that ii is of length 2, cos Signed is the default, so if in signa
- * we have Signed explicitely ? we cant "accrocher" this mcode to
- * something :( So for the moment when there is signed in cocci,
- * we force that there is a signed in c too (done in pattern.ml).
- *)
- let signbopt, iibaseb = split_signb_baseb_ii (baseb, ii) in
-
-
- (* handle some iso on type ? (cf complex C rule for possible implicit
- casting) *)
- (match term basea, baseb with
- | A.VoidType, B.Void
- | A.FloatType, B.FloatType (B.CFloat)
- | A.DoubleType, B.FloatType (B.CDouble) ->
- assert (signaopt = None);
- let (ibaseb) = tuple_of_list1 ii in
- tokenf basea ibaseb >>= (fun basea ibaseb ->
- return (
- (A.BaseType (basea, signaopt)) +> A.rewrap ta,
- (B.BaseType baseb, [ibaseb])
- ))
-
- | A.CharType, B.IntType B.CChar when signaopt = None ->
- let ibaseb = tuple_of_list1 ii in
- tokenf basea ibaseb >>= (fun basea ibaseb ->
- return (
- (A.BaseType (basea, signaopt)) +> A.rewrap ta,
- (B.BaseType (B.IntType B.CChar), [ibaseb])
- ))
-
- | A.CharType,B.IntType (B.Si (_sign, B.CChar2)) when signaopt <> None ->
- let ibaseb = tuple_of_list1 iibaseb in
- sign signaopt signbopt >>= (fun signaopt iisignbopt ->
- tokenf basea ibaseb >>= (fun basea ibaseb ->
- return (
- (A.BaseType (basea, signaopt)) +> A.rewrap ta,
- (B.BaseType (baseb), iisignbopt ++ [ibaseb])
- )))
-
- | A.ShortType, B.IntType (B.Si (_, B.CShort))
- | A.IntType, B.IntType (B.Si (_, B.CInt))
- | A.LongType, B.IntType (B.Si (_, B.CLong)) ->
- (match iibaseb with
- | [] ->
- (* iso-by-presence ? *)
- (* when unsigned int in SP, allow have just unsigned in C ? *)
- if mcode_contain_plus (mcodekind basea)
- then fail
- else
-
- sign signaopt signbopt >>= (fun signaopt iisignbopt ->
- return (
- (A.BaseType (basea, signaopt)) +> A.rewrap ta,
- (B.BaseType (baseb), iisignbopt ++ [])
- ))
-
-
- | [x;y] ->
- pr2_once
- "warning: long int or short int not handled by ast_cocci";
- fail
-
- | [ibaseb] ->
- sign signaopt signbopt >>= (fun signaopt iisignbopt ->
- tokenf basea ibaseb >>= (fun basea ibaseb ->
- return (
- (A.BaseType (basea, signaopt)) +> A.rewrap ta,
- (B.BaseType (baseb), iisignbopt ++ [ibaseb])
- )))
- | _ -> raise Impossible
-
- )
-
-
- | _, B.IntType (B.Si (_, B.CLongLong))
- | _, B.FloatType B.CLongDouble
- ->
- pr2_once
- "warning: long long or long double not handled by ast_cocci";
- fail
-
-
- | _, _ -> fail
-
-
- )
-
- | A.ImplicitInt (signa), (B.BaseType baseb, ii) ->
- let signbopt, iibaseb = split_signb_baseb_ii (baseb, ii) in
- (match iibaseb, baseb with
- | [], B.IntType (B.Si (_sign, B.CInt)) ->
- sign (Some signa) signbopt >>= (fun signaopt iisignbopt ->
- match signaopt with
- | None -> raise Impossible
- | Some signa ->
- return (
- (A.ImplicitInt (signa)) +> A.rewrap ta,
- (B.BaseType baseb, iisignbopt)
- )
- )
- | _ -> fail
- )
-
-
-
- (* todo? iso with array *)
- | A.Pointer (typa, iamult), (B.Pointer typb, ii) ->
- let (ibmult) = tuple_of_list1 ii in
- fullType typa typb >>= (fun typa typb ->
- tokenf iamult ibmult >>= (fun iamult ibmult ->
- return (
- (A.Pointer (typa, iamult)) +> A.rewrap ta,
- (B.Pointer typb, [ibmult])
- )))
-
- | A.FunctionType(allminus,tyaopt,lpa,paramsa,rpa),
- (B.FunctionType(tyb, (paramsb, (isvaargs, iidotsb))), ii) ->
-
- let (lpb, rpb) = tuple_of_list2 ii in
- if isvaargs
- then
- pr2_once
- ("Not handling well variable length arguments func. "^
- "You have been warned");
- tokenf lpa lpb >>= (fun lpa lpb ->
- tokenf rpa rpb >>= (fun rpa rpb ->
- fullType_optional_allminus allminus tyaopt tyb >>= (fun tyaopt tyb ->
- parameters (seqstyle paramsa) (A.undots paramsa) paramsb >>=
- (fun paramsaundots paramsb ->
- let paramsa = redots paramsa paramsaundots in
- return (
- (A.FunctionType(allminus,tyaopt,lpa,paramsa,rpa) +> A.rewrap ta,
- (B.FunctionType(tyb, (paramsb, (isvaargs, iidotsb))), [lpb;rpb])
- )
- )))))
-
-
-
-
-
- | A.FunctionPointer(tya,lp1a,stara,rp1a,lp2a,paramsa,rp2a),
- (B.ParenType t1, ii) ->
- let (lp1b, rp1b) = tuple_of_list2 ii in
- let (qu1b, t1b) = t1 in
- (match t1b with
- | B.Pointer t2, ii ->
- let (starb) = tuple_of_list1 ii in
- let (qu2b, t2b) = t2 in
- (match t2b with
- | B.FunctionType (tyb, (paramsb, (isvaargs, iidotsb))), ii ->
- let (lp2b, rp2b) = tuple_of_list2 ii in
-
- if isvaargs
- then
- pr2_once
- ("Not handling well variable length arguments func. "^
- "You have been warned");
-
- fullType tya tyb >>= (fun tya tyb ->
- tokenf lp1a lp1b >>= (fun lp1a lp1b ->
- tokenf rp1a rp1b >>= (fun rp1a rp1b ->
- tokenf lp2a lp2b >>= (fun lp2a lp2b ->
- tokenf rp2a rp2b >>= (fun rp2a rp2b ->
- tokenf stara starb >>= (fun stara starb ->
- parameters (seqstyle paramsa) (A.undots paramsa) paramsb >>=
- (fun paramsaundots paramsb ->
- let paramsa = redots paramsa paramsaundots in
-
- let t2 =
- (qu2b,
- (B.FunctionType (tyb, (paramsb, (isvaargs, iidotsb))),
- [lp2b;rp2b]))
- in
- let t1 =
- (qu1b,
- (B.Pointer t2, [starb]))
- in
-
- return (
- (A.FunctionPointer(tya,lp1a,stara,rp1a,lp2a,paramsa,rp2a))
- +> A.rewrap ta,
- (B.ParenType t1, [lp1b;rp1b])
- )
- )))))))
-
-
-
- | _ -> fail
- )
- | _ -> fail
- )
-
-
-
- (* todo: handle the iso on optionnal size specifification ? *)
- | A.Array (typa, ia1, eaopt, ia2), (B.Array (ebopt, typb), ii) ->
- let (ib1, ib2) = tuple_of_list2 ii in
- fullType typa typb >>= (fun typa typb ->
- option expression eaopt ebopt >>= (fun eaopt ebopt ->
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- tokenf ia2 ib2 >>= (fun ia2 ib2 ->
- return (
- (A.Array (typa, ia1, eaopt, ia2)) +> A.rewrap ta,
- (B.Array (ebopt, typb), [ib1;ib2])
- )))))
-
-
- (* todo: could also match a Struct that has provided a name *)
- (* This is for the case where the SmPL code contains "struct x", without
- a definition. In this case, the name field is always present.
- This case is also called from the case for A.StructUnionDef when
- a name is present in the C code. *)
- | A.StructUnionName(sua, Some sa), (B.StructUnionName (sub, sb), ii) ->
- (* sa is now an ident, not an mcode, old: ... && (term sa) =$= sb *)
- let (ib1, ib2) = tuple_of_list2 ii in
- if equal_structUnion (term sua) sub
- then
- ident DontKnow sa (sb, ib2) >>= (fun sa (sb, ib2) ->
- tokenf sua ib1 >>= (fun sua ib1 ->
- return (
- (A.StructUnionName (sua, Some sa)) +> A.rewrap ta,
- (B.StructUnionName (sub, sb), [ib1;ib2])
- )))
- else fail
-
-
- | A.StructUnionDef(ty, lba, declsa, rba),
- (B.StructUnion (sub, sbopt, declsb), ii) ->
-
- let (ii_sub_sb, lbb, rbb) =
- match ii with
- [iisub; lbb; rbb] -> (Common.Left iisub,lbb,rbb)
- | [iisub; iisb; lbb; rbb] -> (Common.Right (iisub,iisb),lbb,rbb)
- | _ -> failwith "list of length 3 or 4 expected" in
-
- let process_type =
- match (sbopt,ii_sub_sb) with
- (None,Common.Left iisub) ->
- (* the following doesn't reconstruct the complete SP code, just
- the part that matched *)
- let rec loop s =
- match A.unwrap s with
- A.Type(None,ty) ->
- (match A.unwrap ty with
- A.StructUnionName(sua, None) ->
- tokenf sua iisub >>= (fun sua iisub ->
- let ty =
- A.Type(None,
- A.StructUnionName(sua, None) +> A.rewrap ty)
- +> A.rewrap s in
- return (ty,[iisub]))
- | _ -> fail)
- | A.DisjType(disjs) ->
- disjs +>
- List.fold_left (fun acc disj -> acc >|+|> (loop disj)) fail
- | _ -> fail in
- loop ty
-
- | (Some sb,Common.Right (iisub,iisb)) ->
-
- (* build a StructUnionName from a StructUnion *)
- let fake_su = B.nQ, (B.StructUnionName (sub, sb), [iisub;iisb]) in
-
- fullType ty fake_su >>= (fun ty fake_su ->
- match fake_su with
- | _nQ, (B.StructUnionName (sub, sb), [iisub;iisb]) ->
- return (ty, [iisub; iisb])
- | _ -> raise Impossible)
- | _ -> fail in
-
- process_type
- >>= (fun ty ii_sub_sb ->
-
- tokenf lba lbb >>= (fun lba lbb ->
- tokenf rba rbb >>= (fun rba rbb ->
- struct_fields (A.undots declsa) declsb >>=(fun undeclsa declsb ->
- let declsa = redots declsa undeclsa in
-
- return (
- (A.StructUnionDef(ty, lba, declsa, rba)) +> A.rewrap ta,
- (B.StructUnion (sub, sbopt, declsb),ii_sub_sb@[lbb;rbb])
- )))))
-
-
- (* todo? handle isomorphisms ? because Unsigned Int can be match on a
- * uint in the C code. But some CEs consists in renaming some types,
- * so we don't want apply isomorphisms every time.
- *)
- | A.TypeName sa, (B.TypeName (sb,typb), ii) ->
- let (isb) = tuple_of_list1 ii in
- if (term sa) =$= sb
- then
- tokenf sa isb >>= (fun sa isb ->
- return (
- (A.TypeName sa) +> A.rewrap ta,
- (B.TypeName (sb,typb), [isb])
- ))
- else fail
-
- | _, (B.TypeOfExpr e, ii) -> fail
- | _, (B.TypeOfType e, ii) -> fail
-
- | _, _ -> fail
-
-(* todo: iso on sign, if not mentioned then free. tochange?
- * but that require to know if signed int because explicit
- * signed int, or because implicit signed int.
- *)
-
-and sign signa signb =
- match signa, signb with
- | None, None -> return (None, [])
- | Some signa, Some (signb, ib) ->
- if equal_sign (term signa) signb
- then tokenf signa ib >>= (fun signa ib ->
- return (Some signa, [ib])
- )
- else fail
- | _, _ -> fail
-
-
-and minusize_list iixs =
- iixs +> List.fold_left (fun acc ii ->
- acc >>= (fun xs ys ->
- tokenf minusizer ii >>= (fun minus ii ->
- return (minus::xs, ii::ys)
- ))) (return ([],[]))
- >>= (fun _xsminys ys ->
- return ((), List.rev ys)
- )
-
-and storage_optional_allminus allminus stoa (stob, iistob) =
- (* "iso-by-absence" for storage, and return type. *)
- X.optional_storage_flag (fun optional_storage ->
- match stoa, stob with
- | None, (stobis, inline) ->
- let do_minus () =
- if allminus
- then
- minusize_list iistob >>= (fun () iistob ->
- return (None, (stob, iistob))
- )
- else return (None, (stob, iistob))
- in
-
- (match optional_storage, stobis with
- | false, B.NoSto -> do_minus ()
- | false, _ -> fail
- | true, B.NoSto -> do_minus ()
- | true, _ ->
- if !Flag.show_misc
- then pr2_once "USING optional_storage builtin isomorphism";
- do_minus()
- )
-
- | Some x, ((stobis, inline)) ->
- if equal_storage (term x) stobis
- then
- match iistob with
- | [i1] ->
- tokenf x i1 >>= (fun x i1 ->
- return (Some x, ((stobis, inline), [i1]))
- )
- (* or if have inline ? have to do a split_storage_inline a la
- * split_signb_baseb_ii *)
- | _ -> raise Impossible
- else fail
- )
-
-
-
-
-
-and fullType_optional_allminus allminus tya retb =
- match tya with
- | None ->
- if allminus
- then
- X.distrf_type minusizer retb >>= (fun _x retb ->
- return (None, retb)
- )
-
- else return (None, retb)
- | Some tya ->
- fullType tya retb >>= (fun tya retb ->
- return (Some tya, retb)
- )
-
-
-
-(*---------------------------------------------------------------------------*)
-and compatible_type a (b,_local) =
- let ok = return ((),()) in
-
- let rec loop = function
- | Type_cocci.BaseType (a, signa), (qua, (B.BaseType b,ii)) ->
- (match a, b with
- | Type_cocci.VoidType, B.Void ->
- assert (signa = None);
- ok
- | Type_cocci.CharType, B.IntType B.CChar when signa = None ->
- ok
- | Type_cocci.CharType, B.IntType (B.Si (signb, B.CChar2)) ->
- compatible_sign signa signb
- | Type_cocci.ShortType, B.IntType (B.Si (signb, B.CShort)) ->
- compatible_sign signa signb
- | Type_cocci.IntType, B.IntType (B.Si (signb, B.CInt)) ->
- compatible_sign signa signb
- | Type_cocci.LongType, B.IntType (B.Si (signb, B.CLong)) ->
- compatible_sign signa signb
- | _, B.IntType (B.Si (signb, B.CLongLong)) ->
- pr2_once "no longlong in cocci";
- fail
- | Type_cocci.FloatType, B.FloatType B.CFloat ->
- assert (signa = None);
- ok
- | Type_cocci.DoubleType, B.FloatType B.CDouble ->
- assert (signa = None);
- ok
- | _, B.FloatType B.CLongDouble ->
- pr2_once "no longdouble in cocci";
- fail
- | Type_cocci.BoolType, _ -> failwith "no booltype in C"
- | _ -> fail
-
- )
- | Type_cocci.Pointer a, (qub, (B.Pointer b, ii)) ->
- loop (a,b)
- | Type_cocci.FunctionPointer a, _ ->
- failwith
- "TODO: function pointer type doesn't store enough information to determine compatability"
- | Type_cocci.Array a, (qub, (B.Array (eopt, b),ii)) ->
- (* no size info for cocci *)
- loop (a,b)
- | Type_cocci.StructUnionName (sua, _, sa),
- (qub, (B.StructUnionName (sub, sb),ii)) ->
- if equal_structUnion_type_cocci sua sub && sa = sb
- then ok
- else fail
-
- | Type_cocci.TypeName sa, (qub, (B.TypeName (sb,_typb), ii)) ->
- if sa = sb
- then ok
- else fail
-
- | Type_cocci.ConstVol (qua, a), (qub, b) ->
- if (fst qub).B.const && (fst qub).B.volatile
- then
- begin
- pr2_once ("warning: the type is both const & volatile but cocci " ^
- "does not handle that");
- fail
- end
- else
- if
- (match qua with
- | Type_cocci.Const -> (fst qub).B.const
- | Type_cocci.Volatile -> (fst qub).B.volatile
- )
- then loop (a,(Ast_c.nQ, b))
- else fail
-
- | Type_cocci.MetaType (ida,keep,inherited), typb ->
- let max_min _ =
- Lib_parsing_c.lin_col_by_pos (Lib_parsing_c.ii_of_type typb) in
- X.envf keep inherited (A.make_mcode ida, B.MetaTypeVal typb, max_min)
- (fun () -> ok
- )
-
- (* subtil: must be after the MetaType case *)
- | a, (qub, (B.TypeName (sb,Some b), ii)) ->
- (* kind of typedef iso *)
- loop (a,b)
-
-
-
-
-
- (* for metavariables of type expression *^* *)
- | Type_cocci.Unknown , _ -> ok
-
- | _ -> fail in
- loop (a,b)
-
-and compatible_sign signa signb =
- let ok = return ((),()) in
- match signa, signb with
- | None, B.Signed
- | Some Type_cocci.Signed, B.Signed
- | Some Type_cocci.Unsigned, B.UnSigned
- -> ok
- | _ -> fail
-
-
-and equal_structUnion_type_cocci a b =
- match a, b with
- | Type_cocci.Struct, B.Struct -> true
- | Type_cocci.Union, B.Union -> true
- | _, _ -> false
-
-
-
-(*---------------------------------------------------------------------------*)
-and inc_file (a, before_after) (b, h_rel_pos) =
-
- let rec aux_inc (ass, bss) passed =
- match ass, bss with
- | [], [] -> true
- | [A.IncDots], _ ->
- let passed = List.rev passed in
-
- (match before_after, !h_rel_pos with
- | IncludeNothing, _ -> true
- | IncludeMcodeBefore, Some x ->
- List.mem passed (x.Ast_c.first_of)
-
- | IncludeMcodeAfter, Some x ->
- List.mem passed (x.Ast_c.last_of)
-
- (* no info, maybe cos of a #include <xx.h> that was already in a .h *)
- | _, None -> false
- )
-
- | (A.IncPath x)::xs, y::ys -> x = y && aux_inc (xs, ys) (x::passed)
- | _ -> failwith "IncDots not in last place or other pb"
-
- in
-
- match a, b with
- | A.Local ass, B.Local bss ->
- aux_inc (ass, bss) []
- | A.NonLocal ass, B.NonLocal bss ->
- aux_inc (ass, bss) []
- | _ -> false
-
-
-
-(*---------------------------------------------------------------------------*)
-
-and (define_params: sequence ->
- (A.define_param list, (string B.wrap) B.wrap2 list) matcher) =
- fun seqstyle eas ebs ->
- match seqstyle with
- | Unordered -> failwith "not handling ooo"
- | Ordered ->
- define_paramsbis eas (Ast_c.split_comma ebs) >>= (fun eas ebs_splitted ->
- return (eas, (Ast_c.unsplit_comma ebs_splitted))
- )
-
-(* todo? facto code with argument and parameters ? *)
-and define_paramsbis = fun eas ebs ->
- match eas, ebs with
- | [], [] -> return ([], [])
- | [], eb::ebs -> fail
- | ea::eas, ebs ->
- X.all_bound (A.get_inherited ea) >&&>
- (match A.unwrap ea, ebs with
- | A.DPdots (mcode), ys ->
-
- (* '...' can take more or less the beginnings of the arguments *)
- let startendxs = Common.zip (Common.inits ys) (Common.tails ys) in
- startendxs +> List.fold_left (fun acc (startxs, endxs) ->
- acc >||> (
-
- (if startxs = []
- then
- if mcode_contain_plus (mcodekind mcode)
- then fail
- (* failwith "I have no token that I could accroche myself on" *)
- else return (dots2metavar mcode, [])
- else
- (match Common.last startxs with
- | Right _ -> fail
- | Left _ ->
- X.distrf_define_params (dots2metavar mcode) startxs
- )
- ) >>= (fun mcode startxs ->
- let mcode = metavar2dots mcode in
- define_paramsbis eas endxs >>= (fun eas endxs ->
- return (
- (A.DPdots (mcode) +> A.rewrap ea) ::eas,
- startxs ++ endxs
- )))
- )
- ) fail
-
- | A.DPComma ia1, Right ii::ebs ->
- let ib1 = tuple_of_list1 ii in
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- define_paramsbis eas ebs >>= (fun eas ebs ->
- return (
- (A.DPComma ia1 +> A.rewrap ea)::eas,
- (Right [ib1])::ebs
- )
- ))
-
- | A.DPComma ia1, ebs ->
- if mcode_contain_plus (mcodekind ia1)
- then fail
- else
- (define_paramsbis eas ebs) (* try optional comma trick *)
-
- | (A.OptDParam _ | A.UniqueDParam _), _ ->
- failwith "handling Opt/Unique for define parameters"
-
- | A.DPcircles (_), ys -> raise Impossible (* in Ordered mode *)
-
- | A.DParam ida, (Left (idb, ii))::ebs ->
- let ib1 = tuple_of_list1 ii in
- ident DontKnow ida (idb, ib1) >>= (fun ida (idb, ib1) ->
- define_paramsbis eas ebs >>= (fun eas ebs ->
- return (
- (A.DParam ida)+> A.rewrap ea :: eas,
- (Left (idb, [ib1]))::ebs
- )))
-
- | _unwrapx, (Right y)::ys -> raise Impossible
- | _unwrapx, [] -> fail
- )
-
-
-
-(*****************************************************************************)
-(* Entry points *)
-(*****************************************************************************)
-
-(* no global solution for positions here, because for a statement metavariable
-we want a MetaStmtVal, and for the others, it's not clear what we want *)
-
-let rec (rule_elem_node: (A.rule_elem, Control_flow_c.node) matcher) =
- fun re node ->
- let rewrap x =
- x >>= (fun a b -> return (A.rewrap re a, F.rewrap node b))
- in
- X.all_bound (A.get_inherited re) >&&>
-
- rewrap (
- match A.unwrap re, F.unwrap node with
-
- (* note: the order of the clauses is important. *)
-
- | _, F.Enter | _, F.Exit | _, F.ErrorExit -> fail2()
-
- (* the metaRuleElem contains just '-' information. We dont need to add
- * stuff in the environment. If we need stuff in environment, because
- * there is a + S somewhere, then this will be done via MetaStmt, not
- * via MetaRuleElem.
- * Can match TrueNode/FalseNode/... so must be placed before those cases.
- *)
-
- | A.MetaRuleElem(mcode,keep,inherited), unwrap_node ->
- let default = A.MetaRuleElem(mcode,keep,inherited), unwrap_node in
- (match unwrap_node with
- | F.CaseNode _
- | F.TrueNode | F.FalseNode | F.AfterNode | F.FallThroughNode
- | F.InLoopNode ->
- if X.mode = PatternMode
- then return default
- else
- if mcode_contain_plus (mcodekind mcode)
- then failwith "try add stuff on fake node"
- (* minusize or contextize a fake node is ok *)
- else return default
-
- | F.EndStatement None ->
- if X.mode = PatternMode then return default
- else
- (* DEAD CODE NOW ? only useful in -no_cocci_vs_c_3 ?
- if mcode_contain_plus (mcodekind mcode)
- then
- let fake_info = Ast_c.fakeInfo() in
- distrf distrf_node (mcodekind mcode)
- (F.EndStatement (Some fake_info))
- else return unwrap_node
- *)
- raise Todo
-
- | F.EndStatement (Some i1) ->
- tokenf mcode i1 >>= (fun mcode i1 ->
- return (
- A.MetaRuleElem (mcode,keep, inherited),
- F.EndStatement (Some i1)
- ))
-
- | F.FunHeader _ ->
- if X.mode = PatternMode then return default
- else failwith "a MetaRuleElem can't transform a headfunc"
- | _n ->
- if X.mode = PatternMode then return default
- else
- X.distrf_node (generalize_mcode mcode) node >>= (fun mcode node ->
- return (
- A.MetaRuleElem(mcode,keep, inherited),
- F.unwrap node
- ))
- )
-
-
- (* rene cant have found that a state containing a fake/exit/... should be
- * transformed
- * TODO: and F.Fake ?
- *)
- | _, F.EndStatement _ | _, F.CaseNode _
- | _, F.TrueNode | _, F.FalseNode | _, F.AfterNode | _, F.FallThroughNode
- | _, F.InLoopNode
- -> fail2()
-
- (* really ? diff between pattern.ml and transformation.ml *)
- | _, F.Fake -> fail2()
-
-
- (* cas general: a Meta can match everything. It matches only
- * "header"-statement. We transform only MetaRuleElem, not MetaStmt.
- * So can't have been called in transform.
- *)
- | A.MetaStmt (ida,keep,metainfoMaybeTodo,inherited), F.Decl(_) -> fail
-
- | A.MetaStmt (ida,keep,metainfoMaybeTodo,inherited), unwrap_node ->
- (* todo: should not happen in transform mode *)
-
- (match Control_flow_c.extract_fullstatement node with
- | Some stb ->
- let max_min _ =
- Lib_parsing_c.lin_col_by_pos (Lib_parsing_c.ii_of_stmt stb) in
- X.envf keep inherited (ida, Ast_c.MetaStmtVal stb, max_min)
- (fun () ->
- (* no need tag ida, we can't be called in transform-mode *)
- return (
- A.MetaStmt (ida, keep, metainfoMaybeTodo, inherited),
- unwrap_node
- )
- )
- | None -> fail
- )
-
- (* not me?: *)
- | A.MetaStmtList _, _ ->
- failwith "not handling MetaStmtList"
-
- | A.TopExp ea, F.DefineExpr eb ->
- expression ea eb >>= (fun ea eb ->
- return (
- A.TopExp ea,
- F.DefineExpr eb
- ))
-
- | A.TopExp ea, F.DefineType eb ->
- (match A.unwrap ea with
- A.TypeExp(ft) ->
- fullType ft eb >>= (fun ft eb ->
- return (
- A.TopExp (A.rewrap ea (A.TypeExp(ft))),
- F.DefineType eb
- ))
- | _ -> fail)
-
-
-
- (* It is important to put this case before the one that fails because
- * of the lack of the counter part of a C construct in SmPL (for instance
- * there is not yet a CaseRange in SmPL). Even if SmPL don't handle
- * yet certain constructs, those constructs may contain expression
- * that we still want and can transform.
- *)
-
- | A.Exp exp, nodeb ->
-
- (* kind of iso, initialisation vs affectation *)
- let node =
- match A.unwrap exp, nodeb with
- | A.Assignment (ea, op, eb, true), F.Decl decl ->
- initialisation_to_affectation decl +> F.rewrap node
- | _ -> node
- in
-
-
- (* Now keep fullstatement inside the control flow node,
- * so that can then get in a MetaStmtVar the fullstatement to later
- * pp back when the S is in a +. But that means that
- * Exp will match an Ifnode even if there is no such exp
- * inside the condition of the Ifnode (because the exp may
- * be deeper, in the then branch). So have to not visit
- * all inside a node anymore.
- *
- * update: j'ai choisi d'accrocher au noeud du CFG Ã la
- * fois le fullstatement et le partialstatement et appeler le
- * visiteur que sur le partialstatement.
- *)
- let expfn =
- match Ast_cocci.get_pos re with
- | None -> expression
- | Some pos ->
- (fun ea eb ->
- let (max,min) =
- Lib_parsing_c.max_min_by_pos (Lib_parsing_c.ii_of_expr eb) in
- let keep = Type_cocci.Unitary in
- let inherited = false in
- let max_min _ = failwith "no pos" in
- X.envf keep inherited (pos, B.MetaPosVal (min,max), max_min)
- (fun () ->
- expression ea eb
- )
- )
- in
- X.cocciExp expfn exp node >>= (fun exp node ->
- return (
- A.Exp exp,
- F.unwrap node
- )
- )
-
-
-
- | A.Ty ty, nodeb ->
- X.cocciTy fullType ty node >>= (fun ty node ->
- return (
- A.Ty ty,
- F.unwrap node
- )
- )
-
-
- | A.FunHeader (mckstart, allminus, fninfoa, ida, oparen, paramsa, cparen),
- F.FunHeader ((idb, (retb, (paramsb, (isvaargs, iidotsb))), stob), ii) ->
-
- (* fninfoa records the order in which the SP specified the various
- information, but this isn't taken into account in the matching.
- Could this be a problem for transformation? *)
- let stoa =
- match
- List.filter (function A.FStorage(s) -> true | _ -> false) fninfoa
- with [A.FStorage(s)] -> Some s | _ -> None in
- let tya =
- match List.filter (function A.FType(s) -> true | _ -> false) fninfoa
- with [A.FType(t)] -> Some t | _ -> None in
-
- (match List.filter (function A.FInline(i) -> true | _ -> false) fninfoa
- with [A.FInline(i)] -> failwith "not checking inline" | _ -> ());
-
- (match List.filter (function A.FAttr(a) -> true | _ -> false) fninfoa
- with [A.FAttr(a)] -> failwith "not checking attributes" | _ -> ());
-
- (match ii with
- | iidb::ioparenb::icparenb::iifakestart::iistob ->
-
- (* maybe important to put ident as the first tokens to transform.
- * It's related to transform_proto. So don't change order
- * between the >>=.
- *)
- ident LocalFunction ida (idb, iidb) >>= (fun ida (idb, iidb) ->
- X.tokenf_mck mckstart iifakestart >>= (fun mckstart iifakestart ->
- tokenf oparen ioparenb >>= (fun oparen ioparenb ->
- tokenf cparen icparenb >>= (fun cparen icparenb ->
- parameters (seqstyle paramsa)
- (A.undots paramsa) paramsb >>=
- (fun paramsaundots paramsb ->
- let paramsa = redots paramsa paramsaundots in
- storage_optional_allminus allminus
- stoa (stob, iistob) >>= (fun stoa (stob, iistob) ->
- (
- if isvaargs
- then
- pr2_once
- ("Not handling well variable length arguments func. "^
- "You have been warned");
- if allminus
- then minusize_list iidotsb
- else return ((),iidotsb)
- ) >>= (fun () iidotsb ->
-
- fullType_optional_allminus allminus tya retb >>= (fun tya retb ->
-
- let fninfoa =
- (match stoa with Some st -> [A.FStorage st] | None -> []) ++
- (match tya with Some t -> [A.FType t] | None -> [])
-
- in
-
- return (
- A.FunHeader(mckstart,allminus,fninfoa,ida,oparen,
- paramsa,cparen),
- F.FunHeader ((idb, (retb, (paramsb, (isvaargs, iidotsb))),
- stob),
- iidb::ioparenb::icparenb::iifakestart::iistob)
- )
- ))))))))
- | _ -> raise Impossible
- )
-
-
-
-
-
-
- | A.Decl (mckstart,allminus,decla), F.Decl declb ->
- declaration (mckstart,allminus,decla) declb >>=
- (fun (mckstart,allminus,decla) declb ->
- return (
- A.Decl (mckstart,allminus,decla),
- F.Decl declb
- ))
-
-
- | A.SeqStart mcode, F.SeqStart (st, level, i1) ->
- tokenf mcode i1 >>= (fun mcode i1 ->
- return (
- A.SeqStart mcode,
- F.SeqStart (st, level, i1)
- ))
-
- | A.SeqEnd mcode, F.SeqEnd (level, i1) ->
- tokenf mcode i1 >>= (fun mcode i1 ->
- return (
- A.SeqEnd mcode,
- F.SeqEnd (level, i1)
- ))
-
- | A.ExprStatement (ea, ia1), F.ExprStatement (st, (Some eb, ii)) ->
- let ib1 = tuple_of_list1 ii in
- expression ea eb >>= (fun ea eb ->
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- return (
- A.ExprStatement (ea, ia1),
- F.ExprStatement (st, (Some eb, [ib1]))
- )
- ))
-
-
- | A.IfHeader (ia1,ia2, ea, ia3), F.IfHeader (st, (eb,ii)) ->
- let (ib1, ib2, ib3) = tuple_of_list3 ii in
- expression ea eb >>= (fun ea eb ->
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- tokenf ia2 ib2 >>= (fun ia2 ib2 ->
- tokenf ia3 ib3 >>= (fun ia3 ib3 ->
- return (
- A.IfHeader (ia1, ia2, ea, ia3),
- F.IfHeader (st, (eb,[ib1;ib2;ib3]))
- )))))
-
- | A.Else ia, F.Else ib ->
- tokenf ia ib >>= (fun ia ib ->
- return (A.Else ia, F.Else ib)
- )
-
- | A.WhileHeader (ia1, ia2, ea, ia3), F.WhileHeader (st, (eb, ii)) ->
- let (ib1, ib2, ib3) = tuple_of_list3 ii in
- expression ea eb >>= (fun ea eb ->
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- tokenf ia2 ib2 >>= (fun ia2 ib2 ->
- tokenf ia3 ib3 >>= (fun ia3 ib3 ->
- return (
- A.WhileHeader (ia1, ia2, ea, ia3),
- F.WhileHeader (st, (eb, [ib1;ib2;ib3]))
- )))))
-
- | A.DoHeader ia, F.DoHeader (st, ib) ->
- tokenf ia ib >>= (fun ia ib ->
- return (
- A.DoHeader ia,
- F.DoHeader (st, ib)
- ))
- | A.WhileTail (ia1,ia2,ea,ia3,ia4), F.DoWhileTail (eb, ii) ->
- let (ib1, ib2, ib3, ib4) = tuple_of_list4 ii in
- expression ea eb >>= (fun ea eb ->
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- tokenf ia2 ib2 >>= (fun ia2 ib2 ->
- tokenf ia3 ib3 >>= (fun ia3 ib3 ->
- tokenf ia4 ib4 >>= (fun ia4 ib4 ->
- return (
- A.WhileTail (ia1,ia2,ea,ia3,ia4),
- F.DoWhileTail (eb, [ib1;ib2;ib3;ib4])
- ))))))
- | A.IteratorHeader (ia1, ia2, eas, ia3), F.MacroIterHeader (st, ((s,ebs),ii))
- ->
- let (ib1, ib2, ib3) = tuple_of_list3 ii in
-
- ident DontKnow ia1 (s, ib1) >>= (fun ia1 (s, ib1) ->
- tokenf ia2 ib2 >>= (fun ia2 ib2 ->
- tokenf ia3 ib3 >>= (fun ia3 ib3 ->
- arguments (seqstyle eas) (A.undots eas) ebs >>= (fun easundots ebs ->
- let eas = redots eas easundots in
- return (
- A.IteratorHeader (ia1, ia2, eas, ia3),
- F.MacroIterHeader (st, ((s,ebs), [ib1;ib2;ib3]))
- )))))
-
-
-
- | A.ForHeader (ia1, ia2, ea1opt, ia3, ea2opt, ia4, ea3opt, ia5),
- F.ForHeader (st, (((eb1opt,ib3s), (eb2opt,ib4s), (eb3opt,ib4vide)), ii))
- ->
- assert (null ib4vide);
- let (ib1, ib2, ib5) = tuple_of_list3 ii in
- let ib3 = tuple_of_list1 ib3s in
- let ib4 = tuple_of_list1 ib4s in
-
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- tokenf ia2 ib2 >>= (fun ia2 ib2 ->
- tokenf ia3 ib3 >>= (fun ia3 ib3 ->
- tokenf ia4 ib4 >>= (fun ia4 ib4 ->
- tokenf ia5 ib5 >>= (fun ia5 ib5 ->
- option expression ea1opt eb1opt >>= (fun ea1opt eb1opt ->
- option expression ea2opt eb2opt >>= (fun ea2opt eb2opt ->
- option expression ea3opt eb3opt >>= (fun ea3opt eb3opt ->
- return (
- A.ForHeader (ia1, ia2, ea1opt, ia3, ea2opt, ia4, ea3opt, ia5),
- F.ForHeader (st, (((eb1opt,[ib3]), (eb2opt,[ib4]), (eb3opt,[])),
- [ib1;ib2;ib5]))
-
- )))))))))
-
-
- | A.SwitchHeader(ia1,ia2,ea,ia3), F.SwitchHeader (st, (eb,ii)) ->
- let (ib1, ib2, ib3) = tuple_of_list3 ii in
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- tokenf ia2 ib2 >>= (fun ia2 ib2 ->
- tokenf ia3 ib3 >>= (fun ia3 ib3 ->
- expression ea eb >>= (fun ea eb ->
- return (
- A.SwitchHeader(ia1,ia2,ea,ia3),
- F.SwitchHeader (st, (eb,[ib1;ib2;ib3]))
- )))))
-
- | A.Break (ia1, ia2), F.Break (st, ((),ii)) ->
- let (ib1, ib2) = tuple_of_list2 ii in
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- tokenf ia2 ib2 >>= (fun ia2 ib2 ->
- return (
- A.Break (ia1, ia2),
- F.Break (st, ((),[ib1;ib2]))
- )))
-
- | A.Continue (ia1, ia2), F.Continue (st, ((),ii)) ->
- let (ib1, ib2) = tuple_of_list2 ii in
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- tokenf ia2 ib2 >>= (fun ia2 ib2 ->
- return (
- A.Continue (ia1, ia2),
- F.Continue (st, ((),[ib1;ib2]))
- )))
-
- | A.Return (ia1, ia2), F.Return (st, ((),ii)) ->
- let (ib1, ib2) = tuple_of_list2 ii in
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- tokenf ia2 ib2 >>= (fun ia2 ib2 ->
- return (
- A.Return (ia1, ia2),
- F.Return (st, ((),[ib1;ib2]))
- )))
-
- | A.ReturnExpr (ia1, ea, ia2), F.ReturnExpr (st, (eb, ii)) ->
- let (ib1, ib2) = tuple_of_list2 ii in
- tokenf ia1 ib1 >>= (fun ia1 ib1 ->
- tokenf ia2 ib2 >>= (fun ia2 ib2 ->
- expression ea eb >>= (fun ea eb ->
- return (
- A.ReturnExpr (ia1, ea, ia2),
- F.ReturnExpr (st, (eb, [ib1;ib2]))
- ))))
-
-
-
- | A.Include(incla,filea), F.Include ((fileb, ii), (h_rel_pos, inifdef)) ->
-
- let include_requirment =
- match mcodekind incla, mcodekind filea with
- | A.CONTEXT (_, A.BEFORE _), _ ->
- IncludeMcodeBefore
- | _, A.CONTEXT (_, A.AFTER _) ->
- IncludeMcodeAfter
- | _ ->
- IncludeNothing
- in
-
- let (inclb, iifileb) = tuple_of_list2 ii in
- if inc_file (term filea, include_requirment) (fileb, h_rel_pos)
- then
- tokenf incla inclb >>= (fun incla inclb ->
- tokenf filea iifileb >>= (fun filea iifileb ->
- return (
- A.Include(incla, filea),
- F.Include ((fileb, [inclb;iifileb]), (h_rel_pos, inifdef))
- )))
- else fail
-
-
-
- | A.DefineHeader(definea,ida,params), F.DefineHeader ((idb, ii), defkind) ->
- let (defineb, iidb, ieol) = tuple_of_list3 ii in
- ident DontKnow ida (idb, iidb) >>= (fun ida (idb, iidb) ->
- tokenf definea defineb >>= (fun definea defineb ->
- (match A.unwrap params, defkind with
- | A.NoParams, B.DefineVar ->
- return (
- A.NoParams +> A.rewrap params,
- B.DefineVar
- )
- | A.DParams(lpa,eas,rpa), (B.DefineFunc (ebs, ii)) ->
- let (lpb, rpb) = tuple_of_list2 ii in
- tokenf lpa lpb >>= (fun lpa lpb ->
- tokenf rpa rpb >>= (fun rpa rpb ->
-
- define_params (seqstyle eas) (A.undots eas) ebs >>=
- (fun easundots ebs ->
- let eas = redots eas easundots in
- return (
- A.DParams (lpa,eas,rpa) +> A.rewrap params,
- B.DefineFunc (ebs,[lpb;rpb])
- )
- )))
- | _ -> fail
- ) >>= (fun params defkind ->
- return (
- A.DefineHeader (definea, ida, params),
- F.DefineHeader ((idb,[defineb;iidb;ieol]),defkind)
- ))
- ))
-
-
- | A.Default(def,colon), F.Default (st, ((),ii)) ->
- let (ib1, ib2) = tuple_of_list2 ii in
- tokenf def ib1 >>= (fun def ib1 ->
- tokenf colon ib2 >>= (fun colon ib2 ->
- return (
- A.Default(def,colon),
- F.Default (st, ((),[ib1;ib2]))
- )))
-
-
-
- | A.Case(case,ea,colon), F.Case (st, (eb,ii)) ->
- let (ib1, ib2) = tuple_of_list2 ii in
- tokenf case ib1 >>= (fun case ib1 ->
- expression ea eb >>= (fun ea eb ->
- tokenf colon ib2 >>= (fun colon ib2 ->
- return (
- A.Case(case,ea,colon),
- F.Case (st, (eb,[ib1;ib2]))
- ))))
-
- (* only occurs in the predicates generated by asttomember *)
- | A.DisjRuleElem eas, _ ->
- (eas +>
- List.fold_left (fun acc ea -> acc >|+|> (rule_elem_node ea node)) fail)
- >>= (fun ea eb -> return (A.unwrap ea,F.unwrap eb))
-
- | _, F.ExprStatement (_, (None, ii)) -> fail (* happen ? *)
-
- | A.Label(id,dd), F.Label (st,(s,ii)) ->
- let (ib1,ib2) = tuple_of_list2 ii in
- let (string_of_id,rebuild) =
- match A.unwrap id with
- A.Id(s) -> (s,function s -> A.rewrap id (A.Id(s)))
- | _ -> failwith "labels with metavariables not supported" in
- if (term string_of_id) =$= s
- then
- tokenf string_of_id ib1 >>= (fun string_of_id ib1 ->
- tokenf dd ib2 >>= (fun dd ib2 ->
- return (
- A.Label(rebuild string_of_id,dd),
- F.Label (st,(s,[ib1;ib2]))
- )))
- else fail
-
- | A.Goto(goto,id,sem), F.Goto (st,(s,ii)) ->
- let (ib1,ib2,ib3) = tuple_of_list3 ii in
- tokenf goto ib1 >>= (fun goto ib1 ->
- ident DontKnow id (s, ib2) >>= (fun id (s, ib2) ->
- tokenf sem ib3 >>= (fun sem ib3 ->
- return(
- A.Goto(goto,id,sem),
- F.Goto (st,(s,[ib1;ib2;ib3]))
- ))))
-
- (* have not a counter part in coccinelle, for the moment *)
- (* todo?: print a warning at least ? *)
- | _, F.CaseRange _
- | _, F.Asm _
- | _, F.Ifdef _
- | _, F.MacroTop _
- -> fail2()
-
-
- | _, _ -> fail
- )
-end
-
(* Debugging functions *)
(*****************************************************************************)
let show_or_not_predicate pred =
- if !Flag_engine.debug_engine then begin
+ if !Flag_matcher.debug_engine then begin
indent_do (fun () ->
adjust_pp_with_indent_and_header "labeling: pred = " (fun () ->
Pretty_print_engine.pp_predicate pred;
end
let show_or_not_nodes nodes =
- if !Flag_engine.debug_engine then begin
+ if !Flag_matcher.debug_engine then begin
indent_do (fun () ->
adjust_pp_with_indent_and_header "labeling: result = " (fun () ->
Common.pp_do_in_box (fun () ->
| Lib_engine.Match (re), _unwrapnode ->
let substs =
- Pattern3.match_re_node dropped_isos re node binding
+ Pattern_c.match_re_node dropped_isos re node binding
+> List.map (fun (re', subst) ->
Lib_engine.Match (re'), subst
)
Lib_engine.model ->
(Lib_engine.ctlcocci * (pred list list)) ->
(Lib_engine.mvar list*Lib_engine.metavars_binding) ->
- (Lib_engine.transformation_info * bool * Lib_engine.metavars_binding list)) =
+ (Lib_engine.transformation_info * bool * Lib_engine.metavars_binding *
+ Lib_engine.metavars_binding list)) =
fun (flow, label, states) ctl (used_after, binding) ->
let binding2 = metavars_binding_to_binding2 binding in
let (triples,(trans_info2, returned_any_states, used_after_envs)) =
WRAPPED_ENGINE.satbis (flow, label, states) ctl (used_after, binding2)
in
if not (!Flag_parsing_cocci.sgrep_mode || !Flag.sgrep_mode2 ||
- !Flag_engine.allow_inconsistent_paths)
+ !Flag_matcher.allow_inconsistent_paths)
then Check_reachability.check_reachability triples flow;
let (trans_info2,used_after_fresh_envs) =
Postprocess_transinfo.process used_after binding2 trans_info2 in
let trans_info = satbis_to_trans_info trans_info2 in
let newbindings = List.map metavars_binding2_to_binding used_after_envs in
let newbindings = List.map coalesce_positions newbindings in
- (trans_info, returned_any_states, newbindings)
+ (trans_info, returned_any_states, binding, newbindings)
let mysat a b c =
Common.profile_code "mysat" (fun () -> mysat2 a b c)
+++ /dev/null
-(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-*
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-*
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
-*
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
-
-open Common
-
-(*****************************************************************************)
-(* The functor argument *)
-(*****************************************************************************)
-
-(* info passed recursively in monad in addition to binding *)
-type xinfo = {
- optional_storage_iso : bool;
- optional_qualifier_iso : bool;
- value_format_iso : bool;
-}
-
-module XMATCH = struct
-
- (* ------------------------------------------------------------------------*)
- (* Combinators history *)
- (* ------------------------------------------------------------------------*)
- (*
- * version0:
- * type ('a, 'b) matcher = 'a -> 'b -> bool
- *
- * version1: same but with a global variable holding the current binding
- * BUT bug
- * - can have multiple possibilities
- * - globals sux
- * - sometimes have to undo, cos if start match, then it binds,
- * and if later it does not match, then must undo the first binds.
- * ex: when match parameters, can try to match, but then we found far
- * later that the last argument of a function does not match
- * => have to uando the binding !!!
- * (can handle that too with a global, by saving the
- * global, ... but sux)
- * => better not use global
- *
- * version2:
- * type ('a, 'b) matcher = binding -> 'a -> 'b -> binding list
- *
- * Empty list mean failure (let matchfailure = []).
- * To be able to have pretty code, have to use partial application
- * powa, and so the type is in fact
- *
- * version3:
- * type ('a, 'b) matcher = 'a -> 'b -> binding -> binding list
- *
- * Then by defining the correct combinators, can have quite pretty code (that
- * looks like the clean code of version0).
- *
- * opti: return a lazy list of possible matchs ?
- *
- * version4: type tin = Lib_engine.metavars_binding
- *)
-
- (* ------------------------------------------------------------------------*)
- (* Standard type and operators *)
- (* ------------------------------------------------------------------------*)
-
- type tin = {
- extra: xinfo;
- binding: Lib_engine.metavars_binding;
- }
- (* 'x is a ('a * 'b) but in fact dont care about 'b, we just tag the SP *)
- (* opti? use set instead of list *)
- type 'x tout = ('x * Lib_engine.metavars_binding) list
-
- type ('a, 'b) matcher = 'a -> 'b -> tin -> ('a * 'b) tout
-
- (* was >&&> *)
- let (>>=) m1 m2 = fun tin ->
- let xs = m1 tin in
- let xxs = xs +> List.map (fun ((a,b), binding) ->
- m2 a b {extra = tin.extra; binding = binding}
- ) in
- List.flatten xxs
-
- (* Je compare les bindings retournés par les differentes branches.
- * Si la deuxieme branche amene a des bindings qui sont deja presents
- * dans la premiere branche, alors je ne les accepte pas.
- *
- * update: still useful now that julia better handle Exp directly via
- * ctl tricks using positions ?
- *)
- let (>|+|>) m1 m2 = fun tin ->
-(* CHOICE
- let xs = m1 tin in
- if null xs
- then m2 tin
- else xs
-*)
- let res1 = m1 tin in
- let res2 = m2 tin in
- let list_bindings_already = List.map snd res1 in
- res1 ++
- (res2 +> List.filter (fun (x, binding) ->
- not
- (list_bindings_already +> List.exists (fun already ->
- Lib_engine.equal_binding binding already))
- ))
-
-
-
-
- let (>||>) m1 m2 = fun tin ->
-(* CHOICE
- let xs = m1 tin in
- if null xs
- then m2 tin
- else xs
-*)
- (* opti? use set instead of list *)
- m1 tin ++ m2 tin
-
-
- let return res = fun tin ->
- [res, tin.binding]
-
- let fail = fun tin ->
- []
-
- let (>&&>) f m = fun tin ->
- if f tin
- then m tin
- else fail tin
-
-
- let mode = Cocci_vs_c_3.PatternMode
-
- (* ------------------------------------------------------------------------*)
- (* Exp *)
- (* ------------------------------------------------------------------------*)
- let cocciExp = fun expf expa node -> fun tin ->
-
- let globals = ref [] in
- let bigf = {
- (* julia's style *)
- Visitor_c.default_visitor_c with
- Visitor_c.kexpr = (fun (k, bigf) expb ->
- match expf expa expb tin with
- | [] -> (* failed *) k expb
- | xs ->
- globals := xs @ !globals;
- if not !Flag_engine.disallow_nested_exps then k expb (* CHOICE *)
- );
- (* pad's style.
- * push2 expr globals; k expr
- * ...
- * !globals +> List.fold_left (fun acc e -> acc >||> match_e_e expr e)
- * (return false)
- *
- *)
- }
- in
- Visitor_c.vk_node bigf node;
- !globals +> List.map (fun ((a, _exp), binding) ->
- (a, node), binding
- )
-
- (* same as cocciExp, but for expressions in an expression, not expressions
- in a node *)
- let cocciExpExp = fun expf expa expb -> fun tin ->
-
- let globals = ref [] in
- let bigf = {
- (* julia's style *)
- Visitor_c.default_visitor_c with
- Visitor_c.kexpr = (fun (k, bigf) expb ->
- match expf expa expb tin with
- | [] -> (* failed *) k expb
- | xs ->
- globals := xs @ !globals;
- if not !Flag_engine.disallow_nested_exps then k expb (* CHOICE *)
- );
- (* pad's style.
- * push2 expr globals; k expr
- * ...
- * !globals +> List.fold_left (fun acc e -> acc >||> match_e_e expr e)
- * (return false)
- *
- *)
- }
- in
- Visitor_c.vk_expr bigf expb;
- !globals +> List.map (fun ((a, _exp), binding) ->
- (a, expb), binding
- )
-
- let cocciTy = fun expf expa node -> fun tin ->
-
- let globals = ref [] in
- let bigf = {
- Visitor_c.default_visitor_c with
- Visitor_c.ktype = (fun (k, bigf) expb ->
- match expf expa expb tin with
- | [] -> (* failed *) k expb
- | xs -> globals := xs @ !globals);
-
- }
- in
- Visitor_c.vk_node bigf node;
- !globals +> List.map (fun ((a, _exp), binding) ->
- (a, node), binding
- )
-
-
- (* ------------------------------------------------------------------------*)
- (* Distribute mcode *)
- (* ------------------------------------------------------------------------*)
- let tag_mck_pos mck posmck =
- match mck with
- | Ast_cocci.PLUS -> Ast_cocci.PLUS
- | Ast_cocci.CONTEXT (pos, xs) ->
- assert (pos = Ast_cocci.NoPos || pos = Ast_cocci.DontCarePos);
- Ast_cocci.CONTEXT (posmck, xs)
- | Ast_cocci.MINUS (pos, xs) ->
- assert (pos = Ast_cocci.NoPos || pos = Ast_cocci.DontCarePos);
- Ast_cocci.MINUS (posmck, xs)
-
-
- let tag_mck_pos_mcode (x,info,mck,pos) posmck stuff = fun tin ->
- [((x, info, tag_mck_pos mck posmck, pos),stuff), tin.binding]
-
-
- let distrf (ii_of_x_f) =
- fun mcode x -> fun tin ->
- let (max, min) = Lib_parsing_c.max_min_by_pos (ii_of_x_f x)
- in
- let posmck = Ast_cocci.FixPos (min, max) (* subtil: and not max, min !!*)
- in
- tag_mck_pos_mcode mcode posmck x tin
-
- let distrf_e = distrf (Lib_parsing_c.ii_of_expr)
- let distrf_args = distrf (Lib_parsing_c.ii_of_args)
- let distrf_type = distrf (Lib_parsing_c.ii_of_type)
- let distrf_param = distrf (Lib_parsing_c.ii_of_param)
- let distrf_params = distrf (Lib_parsing_c.ii_of_params)
- let distrf_ini = distrf (Lib_parsing_c.ii_of_ini)
- let distrf_node = distrf (Lib_parsing_c.ii_of_node)
- let distrf_struct_fields = distrf (Lib_parsing_c.ii_of_struct_fields)
- let distrf_cst = distrf (Lib_parsing_c.ii_of_cst)
- let distrf_define_params = distrf (Lib_parsing_c.ii_of_define_params)
-
-
- (* ------------------------------------------------------------------------*)
- (* Constraints on metavariable values *)
- (* ------------------------------------------------------------------------*)
- let check_constraints matcher constraints exp = fun f tin ->
- let rec loop = function
- [] -> f () tin (* success *)
- | c::cs ->
- match matcher c exp tin with
- [] (* failure *) -> loop cs
- | _ (* success *) -> fail tin in
- loop constraints
-
- let check_pos_constraints constraints pvalu f tin =
- check_constraints
- (fun c exp tin ->
- let success = [[]] in
- let failure = [] in
- (match Common.optionise (fun () -> tin.binding +> List.assoc c) with
- Some valu' ->
- if Cocci_vs_c_3.equal_metavarval exp valu'
- then success else failure
- | None ->
- (* if the variable is not there, it puts no constraints *)
- (* not sure this is still useful *)
- failure))
- constraints pvalu f tin
-
- (* ------------------------------------------------------------------------*)
- (* Environment *)
- (* ------------------------------------------------------------------------*)
- (* pre: if have declared a new metavar that hide another one, then
- * must be passed with a binding that deleted this metavar
- *
- * Here we dont use the keep argument of julia. cf f(X,X), J'ai
- * besoin de garder le X en interne, meme si julia s'en fout elle du
- * X et qu'elle a mis X a DontSaved.
- *)
- let check_add_metavars_binding strip _keep inherited = fun (k, valu) tin ->
- (match Common.optionise (fun () -> tin.binding +> List.assoc k) with
- | Some (valu') ->
- if Cocci_vs_c_3.equal_metavarval valu valu'
- then Some tin.binding
- else None
-
- | None ->
- if inherited
- then None
- else
- let valu' =
- match valu with
- Ast_c.MetaIdVal a -> Ast_c.MetaIdVal a
- | Ast_c.MetaFuncVal a -> Ast_c.MetaFuncVal a
- | Ast_c.MetaLocalFuncVal a -> Ast_c.MetaLocalFuncVal a (*more?*)
- | Ast_c.MetaExprVal a ->
- Ast_c.MetaExprVal
- (if strip
- then Lib_parsing_c.al_expr a
- else Lib_parsing_c.semi_al_expr a)
- | Ast_c.MetaExprListVal a ->
- Ast_c.MetaExprListVal
- (if strip
- then Lib_parsing_c.al_arguments a
- else Lib_parsing_c.semi_al_arguments a)
-
- | Ast_c.MetaStmtVal a ->
- Ast_c.MetaStmtVal
- (if strip
- then Lib_parsing_c.al_statement a
- else Lib_parsing_c.semi_al_statement a)
- | Ast_c.MetaTypeVal a ->
- Ast_c.MetaTypeVal
- (if strip
- then Lib_parsing_c.al_type a
- else Lib_parsing_c.semi_al_type a)
-
- | Ast_c.MetaListlenVal a -> Ast_c.MetaListlenVal a
-
- | Ast_c.MetaParamVal a -> failwith "not handling MetaParamVal"
- | Ast_c.MetaParamListVal a ->
- Ast_c.MetaParamListVal
- (if strip
- then Lib_parsing_c.al_params a
- else Lib_parsing_c.semi_al_params a)
-
- | Ast_c.MetaPosVal (pos1,pos2) -> Ast_c.MetaPosVal (pos1,pos2)
- | Ast_c.MetaPosValList l -> Ast_c.MetaPosValList l
- in Some (tin.binding +> Common.insert_assoc (k, valu'))
- )
-
- let envf keep inherited = fun (k, valu, get_max_min) f tin ->
- let x = Ast_cocci.unwrap_mcode k in
- match check_add_metavars_binding true keep inherited (x, valu) tin with
- | Some binding ->
- let new_tin = {extra = tin.extra; binding = binding} in
- (match Ast_cocci.get_pos_var k with
- Ast_cocci.MetaPos(name,constraints,per,keep,inherited) ->
- let pvalu =
- let (file,min,max) = get_max_min() in
- Ast_c.MetaPosValList[(file,min,max)] in
- (* check constraints. success means that there is a match with
- one of the constraints, which will ultimately result in
- failure. *)
- check_pos_constraints constraints pvalu
- (function () ->
- (* constraints are satisfied, now see if we are compatible
- with existing bindings *)
- function new_tin ->
- let x = Ast_cocci.unwrap_mcode name in
- (match
- check_add_metavars_binding false keep inherited (x, pvalu)
- new_tin with
- | Some binding ->
- f () {extra = new_tin.extra; binding = binding}
- | None -> fail tin))
- new_tin
- | Ast_cocci.NoMetaPos -> f () new_tin)
- | None -> fail tin
-
- (* ------------------------------------------------------------------------*)
- (* Environment, allbounds *)
- (* ------------------------------------------------------------------------*)
- (* all referenced inherited variables have to be bound. This would
- * be naturally checked for the minus or context ones in the
- * matching process, but have to check the plus ones as well. The
- * result of get_inherited contains all of these, but the potential
- * redundant checking for the minus and context ones is probably not
- * a big deal. If it's a problem, could fix free_vars to distinguish
- * between + variables and the other ones. *)
-
- let (all_bound : Ast_cocci.meta_name list -> tin -> bool) = fun l tin ->
- l +> List.for_all (fun inhvar ->
- match Common.optionise (fun () -> tin.binding +> List.assoc inhvar) with
- | Some _ -> true
- | None -> false
- )
-
- let optional_storage_flag f = fun tin ->
- f (tin.extra.optional_storage_iso) tin
-
- let optional_qualifier_flag f = fun tin ->
- f (tin.extra.optional_qualifier_iso) tin
-
- let value_format_flag f = fun tin ->
- f (tin.extra.value_format_iso) tin
-
-
- (* ------------------------------------------------------------------------*)
- (* Tokens *)
- (* ------------------------------------------------------------------------*)
- let tokenf ia ib = fun tin ->
- let pos = Ast_c.info_to_fixpos ib in
- let posmck = Ast_cocci.FixPos (pos, pos) in
- let finish tin = tag_mck_pos_mcode ia posmck ib tin in
- match Ast_cocci.get_pos_var ia with
- Ast_cocci.MetaPos(name,constraints,per,keep,inherited) ->
- let mpos = Lib_parsing_c.lin_col_by_pos [ib] in
- let pvalu = Ast_c.MetaPosValList [mpos] in
- check_pos_constraints constraints pvalu
- (function () ->
- (* constraints are satisfied, now see if we are compatible
- with existing bindings *)
- function new_tin ->
- let x = Ast_cocci.unwrap_mcode name in
- (match
- check_add_metavars_binding false keep inherited (x, pvalu) tin
- with
- Some binding -> finish {extra = tin.extra; binding = binding}
- | None -> fail tin))
- tin
- | _ -> finish tin
-
- let tokenf_mck mck ib = fun tin ->
- let pos = Ast_c.info_to_fixpos ib in
- let posmck = Ast_cocci.FixPos (pos, pos) in
- [(tag_mck_pos mck posmck, ib), tin.binding]
-
-end
-
-(*****************************************************************************)
-(* Entry point *)
-(*****************************************************************************)
-module MATCH = Cocci_vs_c_3.COCCI_VS_C (XMATCH)
-
-
-let match_re_node2 dropped_isos a b binding =
-
- let tin = {
- XMATCH.extra = {
- optional_storage_iso = not(List.mem "optional_storage" dropped_isos);
- optional_qualifier_iso = not(List.mem "optional_qualifier" dropped_isos);
- value_format_iso = not(List.mem "value_format" dropped_isos);
- };
- XMATCH.binding = binding;
- } in
-
- MATCH.rule_elem_node a b tin
- (* take only the tagged-SP, the 'a' *)
- +> List.map (fun ((a,_b), binding) -> a, binding)
-
-
-let match_re_node a b c d =
- Common.profile_code "Pattern3.match_re_node"
- (fun () -> match_re_node2 a b c d)
+++ /dev/null
-(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-*
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-*
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
-*
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
-
-open Common
-
-(*****************************************************************************)
-(* The functor argument *)
-(*****************************************************************************)
-
-(* info passed recursively in monad in addition to binding *)
-type xinfo = {
- optional_storage_iso : bool;
- optional_qualifier_iso : bool;
- value_format_iso : bool;
-}
-
-module XMATCH = struct
-
- (* ------------------------------------------------------------------------*)
- (* Combinators history *)
- (* ------------------------------------------------------------------------*)
- (*
- * version0:
- * type ('a, 'b) matcher = 'a -> 'b -> bool
- *
- * version1: same but with a global variable holding the current binding
- * BUT bug
- * - can have multiple possibilities
- * - globals sux
- * - sometimes have to undo, cos if start match, then it binds,
- * and if later it does not match, then must undo the first binds.
- * ex: when match parameters, can try to match, but then we found far
- * later that the last argument of a function does not match
- * => have to uando the binding !!!
- * (can handle that too with a global, by saving the
- * global, ... but sux)
- * => better not use global
- *
- * version2:
- * type ('a, 'b) matcher = binding -> 'a -> 'b -> binding list
- *
- * Empty list mean failure (let matchfailure = []).
- * To be able to have pretty code, have to use partial application
- * powa, and so the type is in fact
- *
- * version3:
- * type ('a, 'b) matcher = 'a -> 'b -> binding -> binding list
- *
- * Then by defining the correct combinators, can have quite pretty code (that
- * looks like the clean code of version0).
- *
- * opti: return a lazy list of possible matchs ?
- *
- * version4: type tin = Lib_engine.metavars_binding
- *)
-
- (* ------------------------------------------------------------------------*)
- (* Standard type and operators *)
- (* ------------------------------------------------------------------------*)
-
- type tin = {
- extra: xinfo;
- binding: Lib_engine.metavars_binding;
- binding0: Lib_engine.metavars_binding; (* inherited bindings *)
- }
- (* 'x is a ('a * 'b) but in fact dont care about 'b, we just tag the SP *)
- (* opti? use set instead of list *)
- type 'x tout = ('x * Lib_engine.metavars_binding) list
-
- type ('a, 'b) matcher = 'a -> 'b -> tin -> ('a * 'b) tout
-
- (* was >&&> *)
- let (>>=) m1 m2 = fun tin ->
- let xs = m1 tin in
- let xxs = xs +> List.map (fun ((a,b), binding) ->
- m2 a b {tin with binding = binding}
- ) in
- List.flatten xxs
-
- (* Je compare les bindings retournés par les differentes branches.
- * Si la deuxieme branche amene a des bindings qui sont deja presents
- * dans la premiere branche, alors je ne les accepte pas.
- *
- * update: still useful now that julia better handle Exp directly via
- * ctl tricks using positions ?
- *)
- let (>|+|>) m1 m2 = fun tin ->
-(* CHOICE
- let xs = m1 tin in
- if null xs
- then m2 tin
- else xs
-*)
- let res1 = m1 tin in
- let res2 = m2 tin in
- let list_bindings_already = List.map snd res1 in
- res1 ++
- (res2 +> List.filter (fun (x, binding) ->
- not
- (list_bindings_already +> List.exists (fun already ->
- Lib_engine.equal_binding binding already))
- ))
-
-
-
-
- let (>||>) m1 m2 = fun tin ->
-(* CHOICE
- let xs = m1 tin in
- if null xs
- then m2 tin
- else xs
-*)
- (* opti? use set instead of list *)
- m1 tin ++ m2 tin
-
-
- let return res = fun tin ->
- [res, tin.binding]
-
- let fail = fun tin ->
- []
-
- let (>&&>) f m = fun tin ->
- if f tin
- then m tin
- else fail tin
-
-
- let mode = Cocci_vs_c_3.PatternMode
-
- (* ------------------------------------------------------------------------*)
- (* Exp *)
- (* ------------------------------------------------------------------------*)
- let cocciExp = fun expf expa node -> fun tin ->
-
- let globals = ref [] in
- let bigf = {
- (* julia's style *)
- Visitor_c.default_visitor_c with
- Visitor_c.kexpr = (fun (k, bigf) expb ->
- match expf expa expb tin with
- | [] -> (* failed *) k expb
- | xs ->
- globals := xs @ !globals;
- if not !Flag_engine.disallow_nested_exps then k expb (* CHOICE *)
- );
- (* pad's style.
- * push2 expr globals; k expr
- * ...
- * !globals +> List.fold_left (fun acc e -> acc >||> match_e_e expr e)
- * (return false)
- *
- *)
- }
- in
- Visitor_c.vk_node bigf node;
- !globals +> List.map (fun ((a, _exp), binding) ->
- (a, node), binding
- )
-
- (* same as cocciExp, but for expressions in an expression, not expressions
- in a node *)
- let cocciExpExp = fun expf expa expb -> fun tin ->
-
- let globals = ref [] in
- let bigf = {
- (* julia's style *)
- Visitor_c.default_visitor_c with
- Visitor_c.kexpr = (fun (k, bigf) expb ->
- match expf expa expb tin with
- | [] -> (* failed *) k expb
- | xs ->
- globals := xs @ !globals;
- if not !Flag_engine.disallow_nested_exps then k expb (* CHOICE *)
- );
- (* pad's style.
- * push2 expr globals; k expr
- * ...
- * !globals +> List.fold_left (fun acc e -> acc >||> match_e_e expr e)
- * (return false)
- *
- *)
- }
- in
- Visitor_c.vk_expr bigf expb;
- !globals +> List.map (fun ((a, _exp), binding) ->
- (a, expb), binding
- )
-
- let cocciTy = fun expf expa node -> fun tin ->
-
- let globals = ref [] in
- let bigf = {
- Visitor_c.default_visitor_c with
- Visitor_c.ktype = (fun (k, bigf) expb ->
- match expf expa expb tin with
- | [] -> (* failed *) k expb
- | xs -> globals := xs @ !globals);
-
- }
- in
- Visitor_c.vk_node bigf node;
- !globals +> List.map (fun ((a, _exp), binding) ->
- (a, node), binding
- )
-
-
- (* ------------------------------------------------------------------------*)
- (* Distribute mcode *)
- (* ------------------------------------------------------------------------*)
- let tag_mck_pos mck posmck =
- match mck with
- | Ast_cocci.PLUS -> Ast_cocci.PLUS
- | Ast_cocci.CONTEXT (pos, xs) ->
- assert (pos = Ast_cocci.NoPos || pos = Ast_cocci.DontCarePos);
- Ast_cocci.CONTEXT (posmck, xs)
- | Ast_cocci.MINUS (pos, xs) ->
- assert (pos = Ast_cocci.NoPos || pos = Ast_cocci.DontCarePos);
- Ast_cocci.MINUS (posmck, xs)
-
-
- let tag_mck_pos_mcode (x,info,mck,pos) posmck stuff = fun tin ->
- [((x, info, tag_mck_pos mck posmck, pos),stuff), tin.binding]
-
-
- let distrf (ii_of_x_f) =
- fun mcode x -> fun tin ->
- let (max, min) = Lib_parsing_c.max_min_by_pos (ii_of_x_f x)
- in
- let posmck = Ast_cocci.FixPos (min, max) (* subtil: and not max, min !!*)
- in
- tag_mck_pos_mcode mcode posmck x tin
-
- let distrf_e = distrf (Lib_parsing_c.ii_of_expr)
- let distrf_args = distrf (Lib_parsing_c.ii_of_args)
- let distrf_type = distrf (Lib_parsing_c.ii_of_type)
- let distrf_param = distrf (Lib_parsing_c.ii_of_param)
- let distrf_params = distrf (Lib_parsing_c.ii_of_params)
- let distrf_ini = distrf (Lib_parsing_c.ii_of_ini)
- let distrf_node = distrf (Lib_parsing_c.ii_of_node)
- let distrf_struct_fields = distrf (Lib_parsing_c.ii_of_struct_fields)
- let distrf_cst = distrf (Lib_parsing_c.ii_of_cst)
- let distrf_define_params = distrf (Lib_parsing_c.ii_of_define_params)
-
-
- (* ------------------------------------------------------------------------*)
- (* Constraints on metavariable values *)
- (* ------------------------------------------------------------------------*)
- let check_constraints matcher constraints exp = fun f tin ->
- let rec loop = function
- [] -> f () tin (* success *)
- | c::cs ->
- match matcher c exp tin with
- [] (* failure *) -> loop cs
- | _ (* success *) -> fail tin in
- loop constraints
-
- let check_pos_constraints constraints pvalu f tin =
- check_constraints
- (fun c exp tin ->
- let success = [[]] in
- let failure = [] in
- (* relies on the fact that constraints on pos variables must refer to
- inherited variables *)
- (match Common.optionise (fun () -> tin.binding0 +> List.assoc c) with
- Some valu' ->
- if Cocci_vs_c_3.equal_metavarval exp valu'
- then success else failure
- | None ->
- (* if the variable is not there, it puts no constraints *)
- (* not sure this is still useful *)
- failure))
- constraints pvalu f tin
-
- (* ------------------------------------------------------------------------*)
- (* Environment *)
- (* ------------------------------------------------------------------------*)
- (* pre: if have declared a new metavar that hide another one, then
- * must be passed with a binding that deleted this metavar
- *
- * Here we dont use the keep argument of julia. cf f(X,X), J'ai
- * besoin de garder le X en interne, meme si julia s'en fout elle du
- * X et qu'elle a mis X a DontSaved.
- *)
- let check_add_metavars_binding strip _keep inherited = fun (k, valu) tin ->
- if inherited
- then
- match Common.optionise (fun () -> tin.binding0 +> List.assoc k) with
- | Some (valu') ->
- if Cocci_vs_c_3.equal_metavarval valu valu'
- then Some tin.binding
- else None
- | None -> None
- else
- match Common.optionise (fun () -> tin.binding +> List.assoc k) with
- | Some (valu') ->
- if Cocci_vs_c_3.equal_metavarval valu valu'
- then Some tin.binding
- else None
-
- | None ->
- let valu' =
- match valu with
- Ast_c.MetaIdVal a -> Ast_c.MetaIdVal a
- | Ast_c.MetaFuncVal a -> Ast_c.MetaFuncVal a
- | Ast_c.MetaLocalFuncVal a -> Ast_c.MetaLocalFuncVal a (*more?*)
- | Ast_c.MetaExprVal a ->
- Ast_c.MetaExprVal
- (if strip
- then Lib_parsing_c.al_expr a
- else Lib_parsing_c.semi_al_expr a)
- | Ast_c.MetaExprListVal a ->
- Ast_c.MetaExprListVal
- (if strip
- then Lib_parsing_c.al_arguments a
- else Lib_parsing_c.semi_al_arguments a)
-
- | Ast_c.MetaStmtVal a ->
- Ast_c.MetaStmtVal
- (if strip
- then Lib_parsing_c.al_statement a
- else Lib_parsing_c.semi_al_statement a)
- | Ast_c.MetaTypeVal a ->
- Ast_c.MetaTypeVal
- (if strip
- then Lib_parsing_c.al_type a
- else Lib_parsing_c.semi_al_type a)
-
- | Ast_c.MetaListlenVal a -> Ast_c.MetaListlenVal a
-
- | Ast_c.MetaParamVal a -> failwith "not handling MetaParamVal"
- | Ast_c.MetaParamListVal a ->
- Ast_c.MetaParamListVal
- (if strip
- then Lib_parsing_c.al_params a
- else Lib_parsing_c.semi_al_params a)
-
- | Ast_c.MetaPosVal (pos1,pos2) -> Ast_c.MetaPosVal (pos1,pos2)
- | Ast_c.MetaPosValList l -> Ast_c.MetaPosValList l
- in Some (tin.binding +> Common.insert_assoc (k, valu'))
-
- let envf keep inherited = fun (k, valu, get_max_min) f tin ->
- let x = Ast_cocci.unwrap_mcode k in
- match check_add_metavars_binding true keep inherited (x, valu) tin with
- | Some binding ->
- let new_tin = {tin with binding = binding} in
- (match Ast_cocci.get_pos_var k with
- Ast_cocci.MetaPos(name,constraints,per,keep,inherited) ->
- let pvalu =
- let (file,min,max) = get_max_min() in
- Ast_c.MetaPosValList[(file,min,max)] in
- (* check constraints. success means that there is a match with
- one of the constraints, which will ultimately result in
- failure. *)
- check_pos_constraints constraints pvalu
- (function () ->
- (* constraints are satisfied, now see if we are compatible
- with existing bindings *)
- function new_tin ->
- let x = Ast_cocci.unwrap_mcode name in
- (match
- check_add_metavars_binding false keep inherited (x, pvalu)
- new_tin with
- | Some binding ->
- f () {new_tin with binding = binding}
- | None -> fail tin))
- new_tin
- | Ast_cocci.NoMetaPos -> f () new_tin)
- | None -> fail tin
-
- (* ------------------------------------------------------------------------*)
- (* Environment, allbounds *)
- (* ------------------------------------------------------------------------*)
- (* all referenced inherited variables have to be bound. This would
- * be naturally checked for the minus or context ones in the
- * matching process, but have to check the plus ones as well. The
- * result of get_inherited contains all of these, but the potential
- * redundant checking for the minus and context ones is probably not
- * a big deal. If it's a problem, could fix free_vars to distinguish
- * between + variables and the other ones. *)
-
- let (all_bound : Ast_cocci.meta_name list -> tin -> bool) = fun l tin ->
- l +> List.for_all (fun inhvar ->
- match Common.optionise (fun () -> tin.binding0 +> List.assoc inhvar) with
- | Some _ -> true
- | None -> false
- )
-
- let optional_storage_flag f = fun tin ->
- f (tin.extra.optional_storage_iso) tin
-
- let optional_qualifier_flag f = fun tin ->
- f (tin.extra.optional_qualifier_iso) tin
-
- let value_format_flag f = fun tin ->
- f (tin.extra.value_format_iso) tin
-
-
- (* ------------------------------------------------------------------------*)
- (* Tokens *)
- (* ------------------------------------------------------------------------*)
- let tokenf ia ib = fun tin ->
- let pos = Ast_c.info_to_fixpos ib in
- let posmck = Ast_cocci.FixPos (pos, pos) in
- let finish tin = tag_mck_pos_mcode ia posmck ib tin in
- match Ast_cocci.get_pos_var ia with
- Ast_cocci.MetaPos(name,constraints,per,keep,inherited) ->
- let mpos = Lib_parsing_c.lin_col_by_pos [ib] in
- let pvalu = Ast_c.MetaPosValList [mpos] in
- check_pos_constraints constraints pvalu
- (function () ->
- (* constraints are satisfied, now see if we are compatible
- with existing bindings *)
- function new_tin ->
- let x = Ast_cocci.unwrap_mcode name in
- (match
- check_add_metavars_binding false keep inherited (x, pvalu) tin
- with
- Some binding -> finish {tin with binding = binding}
- | None -> fail tin))
- tin
- | _ -> finish tin
-
- let tokenf_mck mck ib = fun tin ->
- let pos = Ast_c.info_to_fixpos ib in
- let posmck = Ast_cocci.FixPos (pos, pos) in
- [(tag_mck_pos mck posmck, ib), tin.binding]
-
-end
-
-(*****************************************************************************)
-(* Entry point *)
-(*****************************************************************************)
-module MATCH = Cocci_vs_c_3.COCCI_VS_C (XMATCH)
-
-
-let match_re_node2 dropped_isos a b binding0 =
-
- let tin = {
- XMATCH.extra = {
- optional_storage_iso = not(List.mem "optional_storage" dropped_isos);
- optional_qualifier_iso = not(List.mem "optional_qualifier" dropped_isos);
- value_format_iso = not(List.mem "value_format" dropped_isos);
- };
- XMATCH.binding = [];
- XMATCH.binding0 = binding0;
- } in
-
- MATCH.rule_elem_node a b tin
- (* take only the tagged-SP, the 'a' *)
- +> List.map (fun ((a,_b), binding) -> a, binding)
-
-
-let match_re_node a b c d =
- Common.profile_code "Pattern3.match_re_node"
- (fun () -> match_re_node2 a b c d)
--- /dev/null
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+*
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+*
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
+*
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+(* two goals: first drop from the environments things that are not used,
+ and second prompt for the names of fresh variables that are used *)
+
+(* have to add in the whole inherited env because inherited variables are
+not returned by get_fvs. It would be better if that were the case, but
+since at the moment I think we can only inherit one value per variable,
+perhaps it doesn't matter - these bindings will always be the same no matter
+how we reached a particular match *)
+
+module Ast = Ast_cocci
+
+let extra_counter = ref 0
+let get_extra _ =
+ let ctr = !extra_counter in
+ extra_counter := !extra_counter + 1;
+ "__extra_counter__"^(string_of_int ctr)
+
+let read_fresh_id () =
+ try
+ let s = read_line () in
+ match Parse_c.tokens_string s with
+ [Parser_c.TIdent _; Parser_c.EOF _] -> s
+ | _ -> failwith ("wrong fresh id: " ^ s)
+ with End_of_file -> get_extra()
+
+let get_vars = function
+ Lib_engine.Match(re) -> (Ast.get_fvs re, Ast.get_fresh re)
+ | _ -> ([],[])
+
+let string2val str = Lib_engine.NormalMetaVal(Ast_c.MetaIdVal(str))
+
+(* ----------------------------------------------------------------------- *)
+(* Get values for fresh variables *)
+
+let process_tree inherited_env l =
+ let (all_fresh,local_freshs,new_triples) =
+ List.fold_left
+ (function (all_fresh,local_freshs,new_triples) ->
+ function (node,env,pred) ->
+ let (other,fresh) = get_vars pred in
+ let env = List.filter (function (x,_) -> List.mem x other) env in
+ (Common.union_set fresh all_fresh,
+ fresh::local_freshs,
+ (node,env@inherited_env,pred)::new_triples))
+ ([],[],[]) l in
+ let local_freshs = List.rev local_freshs in
+ let new_triples = List.rev new_triples in
+ let fresh_env =
+ List.map
+ (function ((r,n) as fresh) ->
+ Printf.printf "%s: name for %s: " r n; (* not debugging code!!! *)
+ flush stdout;
+ (fresh,string2val(read_fresh_id())))
+ all_fresh in
+ let (_,res) =
+ List.split
+ (List.fold_left
+ (function freshs_node_env_preds ->
+ function (fresh,_) as elem ->
+ List.map
+ (function (freshs,((node,env,pred) as cur)) ->
+ if List.mem fresh freshs
+ then (freshs,(node,elem::env,pred))
+ else (freshs,cur))
+ freshs_node_env_preds)
+ (List.combine local_freshs new_triples)
+ fresh_env) in
+ (List.rev res, fresh_env)
+
+(* ----------------------------------------------------------------------- *)
+(* Create the environment to be used afterwards *)
+
+let collect_used_after used_after envs =
+ List.map (List.filter (function (v,vl) -> List.mem v used_after)) envs
+
+(* ----------------------------------------------------------------------- *)
+(* entry point *)
+
+let process used_after inherited_env l =
+ extra_counter := 0;
+ let (trees, fresh_envs) =
+ List.split (List.map (process_tree inherited_env) l) in
+ (Common.uniq(List.concat trees), collect_used_after used_after fresh_envs)
--- /dev/null
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+*
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+*
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
+*
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+open Common.Infix
+
+open Lib_engine
+
+
+let pp = Common.pp
+
+let pp_meta (_,x) = pp x
+
+let rec pp_binding_kind = function
+ | Ast_c.MetaIdVal s -> pp ("id " ^ s)
+ | Ast_c.MetaFuncVal s -> pp ("func " ^ s)
+ | Ast_c.MetaLocalFuncVal s -> pp ("localfunc " ^ s)
+ | Ast_c.MetaExprVal expr ->
+ Pretty_print_c.pp_expression_simple expr
+ | Ast_c.MetaExprListVal expr_list -> pp "<<exprlist>>"
+ | Ast_c.MetaTypeVal typ ->
+ Pretty_print_c.pp_type_simple typ
+ | Ast_c.MetaStmtVal statement ->
+ Pretty_print_c.pp_statement_simple statement
+ | Ast_c.MetaParamVal params -> pp "<<param>>"
+ | Ast_c.MetaParamListVal params -> pp "<<paramlist>>"
+ | Ast_c.MetaListlenVal n -> pp (string_of_int n)
+ | Ast_c.MetaPosVal (pos1, pos2) ->
+ let print_pos = function
+ Ast_cocci.Real x -> string_of_int x
+ | Ast_cocci.Virt(x,off) -> Printf.sprintf "%d+%d" x off in
+ pp (Common.sprintf ("pos(%s,%s)") (print_pos pos1) (print_pos pos2))
+ | Ast_c.MetaPosValList l ->
+ pp (Common.sprintf ("poss[%s]")
+ (String.concat ", "
+ (List.map
+ (function (fl,(minl,minc),(maxl,maxc)) ->
+ Printf.sprintf "(%s,(%d,%d),(%d,%d))"
+ fl minl minc maxl maxc)
+ l)))
+
+and pp_binding subst =
+ begin
+ pp "[";
+ Common.print_between (fun () -> pp ";"; Format.print_cut() )
+ (fun ((_,s), kind) -> pp s; pp " --> "; pp_binding_kind kind)
+ subst;
+ pp "]";
+ end
+
+
+let pp_binding_kind2 = function
+ | ParenVal s -> pp "pv("; pp_meta s; pp ")"
+ | NormalMetaVal x -> pp_binding_kind x
+ | LabelVal xs ->
+ begin
+ pp "labelval";
+ pp "(";
+ Common.print_between (fun () -> pp ",") Format.print_int xs;
+ pp ")";
+ end
+ | GoodVal -> pp "goodval"
+ | BadVal -> pp "badval"
+
+
+let rec pp_predicate = function
+ | InLoop -> pp "InLoop"
+ | TrueBranch -> pp "TrueBranch"
+ | FalseBranch -> pp "FalseBranch"
+ | After -> pp "After"
+ | FallThrough -> pp "FallThrough"
+ | Return -> pp "Return"
+ | FunHeader -> pp "FunHeader"
+ | Top -> pp "Top"
+ | ErrorExit -> pp "ErrorExit"
+ | Exit -> pp "Exit"
+ | Goto -> pp "Goto"
+ | Paren s -> pp "Paren("; pp_meta s; pp ")"
+ | Match (re) -> Pretty_print_cocci.print_rule_elem re
+ | Label s -> pp "Label("; pp_meta s; pp ")"
+ | BCLabel s -> pp "BreakContinueLabel("; pp_meta s; pp ")"
+ | PrefixLabel s -> pp "PrefixLabel("; pp_meta s; pp ")"
+ | BindGood s -> pp "BindGood("; pp_meta s; pp ")"
+ | BindBad s -> pp "BindBad("; pp_meta s; pp ")"
+ | FakeBrace -> pp "FakeBrace"
+
+and pp_binding2 subst =
+ begin
+ pp "[";
+ Common.print_between (fun () -> pp ";";Format.print_cut(); )
+ (fun (s, kind) -> pp s; pp " --> "; pp_binding_kind2 kind)
+ subst;
+ pp "]";
+ end
+
+and pp_binding2_ctlsubst subst =
+ begin
+ pp "[";
+ Common.print_between (fun () -> pp ";"; Format.print_cut(); )
+ (function
+ Ast_ctl.Subst (s, kind) ->
+ pp_meta s; pp " --> "; pp_binding_kind2 kind;
+ | Ast_ctl.NegSubst (s, kind) ->
+ pp_meta s; pp " -/-> "; pp_binding_kind2 kind;
+ )
+ subst;
+ pp "]";
+ end
+
+let predicate_to_string pred =
+ Common.format_to_string (function _ -> pp_predicate pred)
+
+
+let pp_pred_smodif = fun (pred, smodif) ->
+ begin
+ pp_predicate pred;
+(*
+ (match smodif with
+ | Ast_ctl.Modif x | Ast_ctl.UnModif x -> pp " with <modifTODO>"
+ | Ast_ctl.Control -> ()
+ )
+*)
+ end
+
+
+let pp_ctlcocci show_plus inline_let_def ctl =
+ begin
+ if show_plus
+ then begin
+ Pretty_print_cocci.print_plus_flag := true;
+ Pretty_print_cocci.print_minus_flag := true;
+ end
+ else begin
+ Pretty_print_cocci.print_plus_flag := false;
+ Pretty_print_cocci.print_minus_flag := false;
+ end;
+ Common.pp_do_in_box (fun () ->
+ Pretty_print_ctl.pp_ctl (pp_pred_smodif,(fun s -> pp_meta s))
+ inline_let_def ctl;
+ );
+ end
+
+
+++ /dev/null
-(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-*
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-*
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
-*
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
-
-open Common
-
-module F = Control_flow_c
-
-(*****************************************************************************)
-(* The functor argument *)
-(*****************************************************************************)
-
-(* info passed recursively in monad in addition to binding *)
-type xinfo = {
- optional_storage_iso : bool;
- optional_qualifier_iso : bool;
- value_format_iso : bool;
- current_rule_name : string; (* used for errors *)
-}
-
-module XTRANS = struct
-
- (* ------------------------------------------------------------------------*)
- (* Combinators history *)
- (* ------------------------------------------------------------------------*)
- (*
- * version0:
- * type ('a, 'b) transformer =
- * 'a -> 'b -> Lib_engine.metavars_binding -> 'b
- * exception NoMatch
- *
- * version1:
- * type ('a, 'b) transformer =
- * 'a -> 'b -> Lib_engine.metavars_binding -> 'b option
- * use an exception monad
- *
- * version2:
- * type tin = Lib_engine.metavars_binding
- *)
-
- (* ------------------------------------------------------------------------*)
- (* Standard type and operators *)
- (* ------------------------------------------------------------------------*)
-
- type tin = {
- extra: xinfo;
- binding: Lib_engine.metavars_binding;
- }
- type 'x tout = 'x option
-
- type ('a, 'b) matcher = 'a -> 'b -> tin -> ('a * 'b) tout
-
- let (>>=) m f = fun tin ->
- match m tin with
- | None -> None
- | Some (a,b) -> f a b tin
-
- let return = fun x -> fun tin ->
- Some x
-
- (* can have fail in transform now that the process is deterministic ? *)
- let fail = fun tin ->
- None
-
- let (>||>) m1 m2 = fun tin ->
- match m1 tin with
- | None -> m2 tin
- | Some x -> Some x (* stop as soon as have found something *)
-
- let (>|+|>) m1 m2 = m1 >||> m2
-
- let (>&&>) f m = fun tin ->
- if f tin then m tin else fail tin
-
- let optional_storage_flag f = fun tin ->
- f (tin.extra.optional_storage_iso) tin
-
- let optional_qualifier_flag f = fun tin ->
- f (tin.extra.optional_qualifier_iso) tin
-
- let value_format_flag f = fun tin ->
- f (tin.extra.value_format_iso) tin
-
- let mode = Cocci_vs_c_3.TransformMode
-
- (* ------------------------------------------------------------------------*)
- (* Exp *)
- (* ------------------------------------------------------------------------*)
- let cocciExp = fun expf expa node -> fun tin ->
-
- let bigf = {
- Visitor_c.default_visitor_c_s with
- Visitor_c.kexpr_s = (fun (k, bigf) expb ->
- match expf expa expb tin with
- | None -> (* failed *) k expb
- | Some (x, expb) -> expb);
- }
- in
- Some (expa, Visitor_c.vk_node_s bigf node)
-
-
- (* same as cocciExp, but for expressions in an expression, not expressions
- in a node *)
- let cocciExpExp = fun expf expa expb -> fun tin ->
-
- let bigf = {
- Visitor_c.default_visitor_c_s with
- Visitor_c.kexpr_s = (fun (k, bigf) expb ->
- match expf expa expb tin with
- | None -> (* failed *) k expb
- | Some (x, expb) -> expb);
- }
- in
- Some (expa, Visitor_c.vk_expr_s bigf expb)
-
-
- let cocciTy = fun expf expa node -> fun tin ->
-
- let bigf = {
- Visitor_c.default_visitor_c_s with
- Visitor_c.ktype_s = (fun (k, bigf) expb ->
- match expf expa expb tin with
- | None -> (* failed *) k expb
- | Some (x, expb) -> expb);
- }
- in
- Some (expa, Visitor_c.vk_node_s bigf node)
-
-
- (* ------------------------------------------------------------------------*)
- (* Tokens *)
- (* ------------------------------------------------------------------------*)
- let check_pos info mck pos =
- match mck with
- | Ast_cocci.PLUS -> raise Impossible
- | Ast_cocci.CONTEXT (Ast_cocci.FixPos (i1,i2),_)
- | Ast_cocci.MINUS (Ast_cocci.FixPos (i1,i2),_) ->
- pos <= i2 && pos >= i1
- | Ast_cocci.CONTEXT (Ast_cocci.DontCarePos,_)
- | Ast_cocci.MINUS (Ast_cocci.DontCarePos,_) ->
- true
- | _ ->
- match info with
- Some info ->
- failwith
- (Printf.sprintf
- "wierd: dont have position info for the mcodekind in line %d column %d"
- info.Ast_cocci.line info.Ast_cocci.column)
- | None ->
- failwith "wierd: dont have position info for the mcodekind"
-
-
- let tag_with_mck mck ib = fun tin ->
-
- let cocciinforef = ib.Ast_c.cocci_tag in
- let (oldmcode, oldenv) = !cocciinforef in
-
- let mck =
- if !Flag_parsing_cocci.sgrep_mode
- then Sgrep.process_sgrep ib mck
- else mck
- in
- (match mck, Ast_c.pinfo_of_info ib with
- | _, Ast_c.AbstractLineTok _ -> raise Impossible
- | Ast_cocci.MINUS(_), Ast_c.ExpandedTok _ ->
- failwith ("try to delete an expanded token: " ^ (Ast_c.str_of_info ib))
- | _ -> ()
- );
-
- match (oldmcode,mck) with
- | (Ast_cocci.CONTEXT(_,Ast_cocci.NOTHING), _)
- | (_, Ast_cocci.CONTEXT(_,Ast_cocci.NOTHING))
- ->
- cocciinforef := (mck, tin.binding);
- ib
-
- | _ ->
- if (oldmcode, oldenv) = (mck, tin.binding)
- then begin
- if !Flag.show_misc
- then pr2 "already tagged but with same mcode, so safe";
- ib
- end
- else
- if !Flag.sgrep_mode2
- then ib (* safe *)
- else
- begin
- Format.set_formatter_out_channel stderr;
- Common.pr2 "SP mcode ";
- Pretty_print_cocci.print_mcodekind oldmcode;
- Format.print_newline();
- Common.pr2 "C code mcode ";
- Pretty_print_cocci.print_mcodekind mck;
- Format.print_newline();
- Format.print_flush();
- failwith
- (Common.sprintf "%s: already tagged token:\n%s"
- tin.extra.current_rule_name
- (Common.error_message (Ast_c.file_of_info ib)
- (Ast_c.str_of_info ib, Ast_c.opos_of_info ib)))
- end
-
- let tokenf ia ib = fun tin ->
- let (_,i,mck,_) = ia in
- let pos = Ast_c.info_to_fixpos ib in
- if check_pos (Some i) mck pos
- then return (ia, tag_with_mck mck ib tin) tin
- else fail tin
-
- let tokenf_mck mck ib = fun tin ->
- let pos = Ast_c.info_to_fixpos ib in
- if check_pos None mck pos
- then return (mck, tag_with_mck mck ib tin) tin
- else fail tin
-
-
- (* ------------------------------------------------------------------------*)
- (* Distribute mcode *)
- (* ------------------------------------------------------------------------*)
-
- (* When in the SP we attach something to a metavariable, or delete it, as in
- * - S
- * + foo();
- * we have to minusize all the token that compose S in the C code, and
- * attach the 'foo();' to the right token, the one at the very right.
- *)
-
- type 'a distributer =
- (Ast_c.info -> Ast_c.info) * (* what to do on left *)
- (Ast_c.info -> Ast_c.info) * (* what to do on middle *)
- (Ast_c.info -> Ast_c.info) * (* what to do on right *)
- (Ast_c.info -> Ast_c.info) -> (* what to do on both *)
- 'a -> 'a
-
- let distribute_mck mcodekind distributef expr tin =
- match mcodekind with
- | Ast_cocci.MINUS (pos,any_xxs) ->
- distributef (
- (fun ib -> tag_with_mck (Ast_cocci.MINUS (pos,any_xxs)) ib tin),
- (fun ib -> tag_with_mck (Ast_cocci.MINUS (pos,[])) ib tin),
- (fun ib -> tag_with_mck (Ast_cocci.MINUS (pos,[])) ib tin),
- (fun ib -> tag_with_mck (Ast_cocci.MINUS (pos,any_xxs)) ib tin)
- ) expr
- | Ast_cocci.CONTEXT (pos,any_befaft) ->
- (match any_befaft with
- | Ast_cocci.NOTHING -> expr
-
- | Ast_cocci.BEFORE xxs ->
- distributef (
- (fun ib -> tag_with_mck
- (Ast_cocci.CONTEXT (pos,Ast_cocci.BEFORE xxs)) ib tin),
- (fun x -> x),
- (fun x -> x),
- (fun ib -> tag_with_mck
- (Ast_cocci.CONTEXT (pos,Ast_cocci.BEFORE xxs)) ib tin)
- ) expr
- | Ast_cocci.AFTER xxs ->
- distributef (
- (fun x -> x),
- (fun x -> x),
- (fun ib -> tag_with_mck
- (Ast_cocci.CONTEXT (pos,Ast_cocci.AFTER xxs)) ib tin),
- (fun ib -> tag_with_mck
- (Ast_cocci.CONTEXT (pos,Ast_cocci.AFTER xxs)) ib tin)
- ) expr
-
- | Ast_cocci.BEFOREAFTER (xxs, yys) ->
- distributef (
- (fun ib -> tag_with_mck
- (Ast_cocci.CONTEXT (pos,Ast_cocci.BEFORE xxs)) ib tin),
- (fun x -> x),
- (fun ib -> tag_with_mck
- (Ast_cocci.CONTEXT (pos,Ast_cocci.AFTER yys)) ib tin),
- (fun ib -> tag_with_mck
- (Ast_cocci.CONTEXT (pos,Ast_cocci.BEFOREAFTER (xxs,yys)))
- ib tin)
- ) expr
-
- )
- | Ast_cocci.PLUS -> raise Impossible
-
-
- (* use new strategy, collect ii, sort, recollect and tag *)
-
- let mk_bigf (maxpos, minpos) (lop,mop,rop,bop) =
- let bigf = {
- Visitor_c.default_visitor_c_s with
- Visitor_c.kinfo_s = (fun (k,bigf) i ->
- let pos = Ast_c.info_to_fixpos i in
- match () with
- | _ when Ast_cocci.equal_pos pos maxpos &&
- Ast_cocci.equal_pos pos minpos -> bop i
- | _ when Ast_cocci.equal_pos pos maxpos -> rop i
- | _ when Ast_cocci.equal_pos pos minpos -> lop i
- | _ -> mop i
- )
- } in
- bigf
-
- let distribute_mck_expr (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
- Visitor_c.vk_expr_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
-
- let distribute_mck_args (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
- Visitor_c.vk_args_splitted_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
-
- let distribute_mck_type (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
- Visitor_c.vk_type_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
-
- let distribute_mck_ini (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
- Visitor_c.vk_ini_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
-
- let distribute_mck_param (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
- Visitor_c.vk_param_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
-
- let distribute_mck_params (maxpos, minpos) = fun (lop,mop,rop,bop) ->fun x ->
- Visitor_c.vk_params_splitted_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop))
- x
-
- let distribute_mck_node (maxpos, minpos) = fun (lop,mop,rop,bop) ->fun x ->
- Visitor_c.vk_node_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop))
- x
-
- let distribute_mck_struct_fields (maxpos, minpos) =
- fun (lop,mop,rop,bop) ->fun x ->
- Visitor_c.vk_struct_fields_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop))
- x
-
- let distribute_mck_cst (maxpos, minpos) =
- fun (lop,mop,rop,bop) ->fun x ->
- Visitor_c.vk_cst_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop))
- x
-
-
- let distribute_mck_define_params (maxpos, minpos) = fun (lop,mop,rop,bop) ->
- fun x ->
- Visitor_c.vk_define_params_splitted_s
- (mk_bigf (maxpos, minpos) (lop,mop,rop,bop))
- x
-
- let get_pos mck =
- match mck with
- | Ast_cocci.PLUS -> raise Impossible
- | Ast_cocci.CONTEXT (Ast_cocci.FixPos (i1,i2),_)
- | Ast_cocci.MINUS (Ast_cocci.FixPos (i1,i2),_) ->
- Ast_cocci.FixPos (i1,i2)
- | Ast_cocci.CONTEXT (Ast_cocci.DontCarePos,_)
- | Ast_cocci.MINUS (Ast_cocci.DontCarePos,_) ->
- Ast_cocci.DontCarePos
- | _ -> failwith "wierd: dont have position info for the mcodekind"
-
- let distrf (ii_of_x_f, distribute_mck_x_f) =
- fun ia x -> fun tin ->
- let mck = Ast_cocci.get_mcodekind ia in
- let (max, min) = Lib_parsing_c.max_min_by_pos (ii_of_x_f x)
- in
- if
- (* bug: check_pos mck max && check_pos mck min
- *
- * if do that then if have - f(...); and in C f(1,2); then we
- * would get a "already tagged" because the '...' would sucess in
- * transformaing both '1' and '1,2'. So being in the range is not
- * enough. We must be equal exactly to the range!
- *)
- (match get_pos mck with
- | Ast_cocci.DontCarePos -> true
- | Ast_cocci.FixPos (i1, i2) ->
- i1 = min && i2 = max
- | _ -> raise Impossible
- )
-
- then
- return (
- ia,
- distribute_mck mck (distribute_mck_x_f (max,min)) x tin
- ) tin
- else fail tin
-
-
- let distrf_e = distrf (Lib_parsing_c.ii_of_expr, distribute_mck_expr)
- let distrf_args = distrf (Lib_parsing_c.ii_of_args, distribute_mck_args)
- let distrf_type = distrf (Lib_parsing_c.ii_of_type, distribute_mck_type)
- let distrf_param = distrf (Lib_parsing_c.ii_of_param, distribute_mck_param)
- let distrf_params = distrf (Lib_parsing_c.ii_of_params,distribute_mck_params)
- let distrf_ini = distrf (Lib_parsing_c.ii_of_ini,distribute_mck_ini)
- let distrf_node = distrf (Lib_parsing_c.ii_of_node,distribute_mck_node)
- let distrf_struct_fields =
- distrf (Lib_parsing_c.ii_of_struct_fields, distribute_mck_struct_fields)
- let distrf_cst =
- distrf (Lib_parsing_c.ii_of_cst, distribute_mck_cst)
- let distrf_define_params =
- distrf (Lib_parsing_c.ii_of_define_params,distribute_mck_define_params)
-
-
- (* ------------------------------------------------------------------------*)
- (* Environment *)
- (* ------------------------------------------------------------------------*)
- let meta_name_to_str (s1, s2) =
- s1 ^ "." ^ s2
-
- let envf keep _inherited = fun (s, value, _) f tin ->
- let s = Ast_cocci.unwrap_mcode s in
- let v =
- if keep = Type_cocci.Saved
- then (
- try Some (List.assoc s tin.binding)
- with Not_found ->
- pr2(sprintf
- "Don't find value for metavariable %s in the environment"
- (meta_name_to_str s));
- None)
- else
- (* not raise Impossible! *)
- Some (value)
- in
- match v with
- | None -> fail tin
- | Some (value') ->
-
- (* Ex: in cocci_vs_c someone wants to add a binding. Here in
- * transformation3 the value for this var may be already in the
- * env, because for instance its value were fixed in a previous
- * SmPL rule. So here we want to check that this is the same value.
- * If forget to do the check, what can happen ? Because of Exp
- * and other disjunctive feature of cocci_vs_c (>||>), we
- * may accept a match at a wrong position. Maybe later this
- * will be detected via the pos system on tokens, but maybe
- * not. So safer to keep the check.
- *)
-
- (*f () tin*)
- if Cocci_vs_c_3.equal_metavarval value value'
- then f () tin
- else fail tin
-
-
- let check_constraints matcher constraints exp = fun f tin -> f () tin
-
- (* ------------------------------------------------------------------------*)
- (* Environment, allbounds *)
- (* ------------------------------------------------------------------------*)
- let (all_bound : Ast_cocci.meta_name list -> tin -> bool) = fun l tin ->
- true (* in transform we don't care ? *)
-
-end
-
-(*****************************************************************************)
-(* Entry point *)
-(*****************************************************************************)
-module TRANS = Cocci_vs_c_3.COCCI_VS_C (XTRANS)
-
-
-let transform_re_node a b tin =
- match TRANS.rule_elem_node a b tin with
- | None -> raise Impossible
- | Some (_sp, b') -> b'
-
-
-let (transform2: string (* rule name *) -> string list (* dropped_isos *) ->
- Lib_engine.transformation_info -> F.cflow -> F.cflow) =
- fun rule_name dropped_isos xs cflow ->
-
- let extra = {
- optional_storage_iso = not(List.mem "optional_storage" dropped_isos);
- optional_qualifier_iso = not(List.mem "optional_qualifier" dropped_isos);
- value_format_iso = not(List.mem "value_format" dropped_isos);
- current_rule_name = rule_name;
- } in
-
- (* find the node, transform, update the node, and iter for all elements *)
-
- xs +> List.fold_left (fun acc (nodei, binding, rule_elem) ->
- (* subtil: not cflow#nodes but acc#nodes *)
- let node = acc#nodes#assoc nodei in
-
- if !Flag.show_misc
- then pr2 "transform one node";
-
- let tin = {
- XTRANS.extra = extra;
- XTRANS.binding = binding;
- } in
-
- let node' = transform_re_node rule_elem node tin in
-
- (* assert that have done something. But with metaruleElem sometimes
- dont modify fake nodes. So special case before on Fake nodes. *)
- (match F.unwrap node with
- | F.Enter | F.Exit | F.ErrorExit
- | F.EndStatement _ | F.CaseNode _
- | F.Fake
- | F.TrueNode | F.FalseNode | F.AfterNode | F.FallThroughNode
- -> ()
- | _ -> () (* assert (not (node =*= node')); *)
- );
-
- (* useless, we dont go back from flow to ast now *)
- (* let node' = lastfix_comma_struct node' in *)
-
- acc#replace_node (nodei, node');
- acc
- ) cflow
-
-
-
-let transform a b c d =
- Common.profile_code "Transformation3.transform"
- (fun () -> transform2 a b c d)
+++ /dev/null
-(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-*
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-*
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
-*
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
-
-open Common
-
-module F = Control_flow_c
-
-(*****************************************************************************)
-(* The functor argument *)
-(*****************************************************************************)
-
-(* info passed recursively in monad in addition to binding *)
-type xinfo = {
- optional_storage_iso : bool;
- optional_qualifier_iso : bool;
- value_format_iso : bool;
- current_rule_name : string; (* used for errors *)
-}
-
-module XTRANS = struct
-
- (* ------------------------------------------------------------------------*)
- (* Combinators history *)
- (* ------------------------------------------------------------------------*)
- (*
- * version0:
- * type ('a, 'b) transformer =
- * 'a -> 'b -> Lib_engine.metavars_binding -> 'b
- * exception NoMatch
- *
- * version1:
- * type ('a, 'b) transformer =
- * 'a -> 'b -> Lib_engine.metavars_binding -> 'b option
- * use an exception monad
- *
- * version2:
- * type tin = Lib_engine.metavars_binding
- *)
-
- (* ------------------------------------------------------------------------*)
- (* Standard type and operators *)
- (* ------------------------------------------------------------------------*)
-
- type tin = {
- extra: xinfo;
- binding: Lib_engine.metavars_binding;
- binding0: Lib_engine.metavars_binding; (* inherited variable *)
- }
- type 'x tout = 'x option
-
- type ('a, 'b) matcher = 'a -> 'b -> tin -> ('a * 'b) tout
-
- let (>>=) m f = fun tin ->
- match m tin with
- | None -> None
- | Some (a,b) -> f a b tin
-
- let return = fun x -> fun tin ->
- Some x
-
- (* can have fail in transform now that the process is deterministic ? *)
- let fail = fun tin ->
- None
-
- let (>||>) m1 m2 = fun tin ->
- match m1 tin with
- | None -> m2 tin
- | Some x -> Some x (* stop as soon as have found something *)
-
- let (>|+|>) m1 m2 = m1 >||> m2
-
- let (>&&>) f m = fun tin ->
- if f tin then m tin else fail tin
-
- let optional_storage_flag f = fun tin ->
- f (tin.extra.optional_storage_iso) tin
-
- let optional_qualifier_flag f = fun tin ->
- f (tin.extra.optional_qualifier_iso) tin
-
- let value_format_flag f = fun tin ->
- f (tin.extra.value_format_iso) tin
-
- let mode = Cocci_vs_c_3.TransformMode
-
- (* ------------------------------------------------------------------------*)
- (* Exp *)
- (* ------------------------------------------------------------------------*)
- let cocciExp = fun expf expa node -> fun tin ->
-
- let bigf = {
- Visitor_c.default_visitor_c_s with
- Visitor_c.kexpr_s = (fun (k, bigf) expb ->
- match expf expa expb tin with
- | None -> (* failed *) k expb
- | Some (x, expb) -> expb);
- }
- in
- Some (expa, Visitor_c.vk_node_s bigf node)
-
-
- (* same as cocciExp, but for expressions in an expression, not expressions
- in a node *)
- let cocciExpExp = fun expf expa expb -> fun tin ->
-
- let bigf = {
- Visitor_c.default_visitor_c_s with
- Visitor_c.kexpr_s = (fun (k, bigf) expb ->
- match expf expa expb tin with
- | None -> (* failed *) k expb
- | Some (x, expb) -> expb);
- }
- in
- Some (expa, Visitor_c.vk_expr_s bigf expb)
-
-
- let cocciTy = fun expf expa node -> fun tin ->
-
- let bigf = {
- Visitor_c.default_visitor_c_s with
- Visitor_c.ktype_s = (fun (k, bigf) expb ->
- match expf expa expb tin with
- | None -> (* failed *) k expb
- | Some (x, expb) -> expb);
- }
- in
- Some (expa, Visitor_c.vk_node_s bigf node)
-
-
- (* ------------------------------------------------------------------------*)
- (* Tokens *)
- (* ------------------------------------------------------------------------*)
- let check_pos info mck pos =
- match mck with
- | Ast_cocci.PLUS -> raise Impossible
- | Ast_cocci.CONTEXT (Ast_cocci.FixPos (i1,i2),_)
- | Ast_cocci.MINUS (Ast_cocci.FixPos (i1,i2),_) ->
- pos <= i2 && pos >= i1
- | Ast_cocci.CONTEXT (Ast_cocci.DontCarePos,_)
- | Ast_cocci.MINUS (Ast_cocci.DontCarePos,_) ->
- true
- | _ ->
- match info with
- Some info ->
- failwith
- (Printf.sprintf
- "wierd: dont have position info for the mcodekind in line %d column %d"
- info.Ast_cocci.line info.Ast_cocci.column)
- | None ->
- failwith "wierd: dont have position info for the mcodekind"
-
-
- let tag_with_mck mck ib = fun tin ->
-
- let cocciinforef = ib.Ast_c.cocci_tag in
- let (oldmcode, oldenv) = !cocciinforef in
-
- let mck =
- if !Flag_parsing_cocci.sgrep_mode
- then Sgrep.process_sgrep ib mck
- else mck
- in
- (match mck, Ast_c.pinfo_of_info ib with
- | _, Ast_c.AbstractLineTok _ -> raise Impossible
- | Ast_cocci.MINUS(_), Ast_c.ExpandedTok _ ->
- failwith ("try to delete an expanded token: " ^ (Ast_c.str_of_info ib))
- | _ -> ()
- );
-
- match (oldmcode,mck) with
- | (Ast_cocci.CONTEXT(_,Ast_cocci.NOTHING), _)
- | (_, Ast_cocci.CONTEXT(_,Ast_cocci.NOTHING))
- ->
- cocciinforef := (mck, tin.binding);
- ib
-
- | _ ->
- if (oldmcode, oldenv) = (mck, tin.binding)
- then begin
- if !Flag.show_misc
- then pr2 "already tagged but with same mcode, so safe";
- ib
- end
- else
- if !Flag.sgrep_mode2
- then ib (* safe *)
- else
- begin
- Format.set_formatter_out_channel stderr;
- Common.pr2 "SP mcode ";
- Pretty_print_cocci.print_mcodekind oldmcode;
- Format.print_newline();
- Common.pr2 "C code mcode ";
- Pretty_print_cocci.print_mcodekind mck;
- Format.print_newline();
- Format.print_flush();
- failwith
- (Common.sprintf "%s: already tagged token:\n%s"
- tin.extra.current_rule_name
- (Common.error_message (Ast_c.file_of_info ib)
- (Ast_c.str_of_info ib, Ast_c.opos_of_info ib)))
- end
-
- let tokenf ia ib = fun tin ->
- let (_,i,mck,_) = ia in
- let pos = Ast_c.info_to_fixpos ib in
- if check_pos (Some i) mck pos
- then return (ia, tag_with_mck mck ib tin) tin
- else fail tin
-
- let tokenf_mck mck ib = fun tin ->
- let pos = Ast_c.info_to_fixpos ib in
- if check_pos None mck pos
- then return (mck, tag_with_mck mck ib tin) tin
- else fail tin
-
-
- (* ------------------------------------------------------------------------*)
- (* Distribute mcode *)
- (* ------------------------------------------------------------------------*)
-
- (* When in the SP we attach something to a metavariable, or delete it, as in
- * - S
- * + foo();
- * we have to minusize all the token that compose S in the C code, and
- * attach the 'foo();' to the right token, the one at the very right.
- *)
-
- type 'a distributer =
- (Ast_c.info -> Ast_c.info) * (* what to do on left *)
- (Ast_c.info -> Ast_c.info) * (* what to do on middle *)
- (Ast_c.info -> Ast_c.info) * (* what to do on right *)
- (Ast_c.info -> Ast_c.info) -> (* what to do on both *)
- 'a -> 'a
-
- let distribute_mck mcodekind distributef expr tin =
- match mcodekind with
- | Ast_cocci.MINUS (pos,any_xxs) ->
- distributef (
- (fun ib -> tag_with_mck (Ast_cocci.MINUS (pos,any_xxs)) ib tin),
- (fun ib -> tag_with_mck (Ast_cocci.MINUS (pos,[])) ib tin),
- (fun ib -> tag_with_mck (Ast_cocci.MINUS (pos,[])) ib tin),
- (fun ib -> tag_with_mck (Ast_cocci.MINUS (pos,any_xxs)) ib tin)
- ) expr
- | Ast_cocci.CONTEXT (pos,any_befaft) ->
- (match any_befaft with
- | Ast_cocci.NOTHING -> expr
-
- | Ast_cocci.BEFORE xxs ->
- distributef (
- (fun ib -> tag_with_mck
- (Ast_cocci.CONTEXT (pos,Ast_cocci.BEFORE xxs)) ib tin),
- (fun x -> x),
- (fun x -> x),
- (fun ib -> tag_with_mck
- (Ast_cocci.CONTEXT (pos,Ast_cocci.BEFORE xxs)) ib tin)
- ) expr
- | Ast_cocci.AFTER xxs ->
- distributef (
- (fun x -> x),
- (fun x -> x),
- (fun ib -> tag_with_mck
- (Ast_cocci.CONTEXT (pos,Ast_cocci.AFTER xxs)) ib tin),
- (fun ib -> tag_with_mck
- (Ast_cocci.CONTEXT (pos,Ast_cocci.AFTER xxs)) ib tin)
- ) expr
-
- | Ast_cocci.BEFOREAFTER (xxs, yys) ->
- distributef (
- (fun ib -> tag_with_mck
- (Ast_cocci.CONTEXT (pos,Ast_cocci.BEFORE xxs)) ib tin),
- (fun x -> x),
- (fun ib -> tag_with_mck
- (Ast_cocci.CONTEXT (pos,Ast_cocci.AFTER yys)) ib tin),
- (fun ib -> tag_with_mck
- (Ast_cocci.CONTEXT (pos,Ast_cocci.BEFOREAFTER (xxs,yys)))
- ib tin)
- ) expr
-
- )
- | Ast_cocci.PLUS -> raise Impossible
-
-
- (* use new strategy, collect ii, sort, recollect and tag *)
-
- let mk_bigf (maxpos, minpos) (lop,mop,rop,bop) =
- let bigf = {
- Visitor_c.default_visitor_c_s with
- Visitor_c.kinfo_s = (fun (k,bigf) i ->
- let pos = Ast_c.info_to_fixpos i in
- match () with
- | _ when Ast_cocci.equal_pos pos maxpos &&
- Ast_cocci.equal_pos pos minpos -> bop i
- | _ when Ast_cocci.equal_pos pos maxpos -> rop i
- | _ when Ast_cocci.equal_pos pos minpos -> lop i
- | _ -> mop i
- )
- } in
- bigf
-
- let distribute_mck_expr (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
- Visitor_c.vk_expr_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
-
- let distribute_mck_args (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
- Visitor_c.vk_args_splitted_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
-
- let distribute_mck_type (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
- Visitor_c.vk_type_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
-
- let distribute_mck_ini (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
- Visitor_c.vk_ini_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
-
- let distribute_mck_param (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
- Visitor_c.vk_param_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
-
- let distribute_mck_params (maxpos, minpos) = fun (lop,mop,rop,bop) ->fun x ->
- Visitor_c.vk_params_splitted_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop))
- x
-
- let distribute_mck_node (maxpos, minpos) = fun (lop,mop,rop,bop) ->fun x ->
- Visitor_c.vk_node_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop))
- x
-
- let distribute_mck_struct_fields (maxpos, minpos) =
- fun (lop,mop,rop,bop) ->fun x ->
- Visitor_c.vk_struct_fields_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop))
- x
-
- let distribute_mck_cst (maxpos, minpos) =
- fun (lop,mop,rop,bop) ->fun x ->
- Visitor_c.vk_cst_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop))
- x
-
-
- let distribute_mck_define_params (maxpos, minpos) = fun (lop,mop,rop,bop) ->
- fun x ->
- Visitor_c.vk_define_params_splitted_s
- (mk_bigf (maxpos, minpos) (lop,mop,rop,bop))
- x
-
- let get_pos mck =
- match mck with
- | Ast_cocci.PLUS -> raise Impossible
- | Ast_cocci.CONTEXT (Ast_cocci.FixPos (i1,i2),_)
- | Ast_cocci.MINUS (Ast_cocci.FixPos (i1,i2),_) ->
- Ast_cocci.FixPos (i1,i2)
- | Ast_cocci.CONTEXT (Ast_cocci.DontCarePos,_)
- | Ast_cocci.MINUS (Ast_cocci.DontCarePos,_) ->
- Ast_cocci.DontCarePos
- | _ -> failwith "wierd: dont have position info for the mcodekind"
-
- let distrf (ii_of_x_f, distribute_mck_x_f) =
- fun ia x -> fun tin ->
- let mck = Ast_cocci.get_mcodekind ia in
- let (max, min) = Lib_parsing_c.max_min_by_pos (ii_of_x_f x)
- in
- if
- (* bug: check_pos mck max && check_pos mck min
- *
- * if do that then if have - f(...); and in C f(1,2); then we
- * would get a "already tagged" because the '...' would sucess in
- * transformaing both '1' and '1,2'. So being in the range is not
- * enough. We must be equal exactly to the range!
- *)
- (match get_pos mck with
- | Ast_cocci.DontCarePos -> true
- | Ast_cocci.FixPos (i1, i2) ->
- i1 = min && i2 = max
- | _ -> raise Impossible
- )
-
- then
- return (
- ia,
- distribute_mck mck (distribute_mck_x_f (max,min)) x tin
- ) tin
- else fail tin
-
-
- let distrf_e = distrf (Lib_parsing_c.ii_of_expr, distribute_mck_expr)
- let distrf_args = distrf (Lib_parsing_c.ii_of_args, distribute_mck_args)
- let distrf_type = distrf (Lib_parsing_c.ii_of_type, distribute_mck_type)
- let distrf_param = distrf (Lib_parsing_c.ii_of_param, distribute_mck_param)
- let distrf_params = distrf (Lib_parsing_c.ii_of_params,distribute_mck_params)
- let distrf_ini = distrf (Lib_parsing_c.ii_of_ini,distribute_mck_ini)
- let distrf_node = distrf (Lib_parsing_c.ii_of_node,distribute_mck_node)
- let distrf_struct_fields =
- distrf (Lib_parsing_c.ii_of_struct_fields, distribute_mck_struct_fields)
- let distrf_cst =
- distrf (Lib_parsing_c.ii_of_cst, distribute_mck_cst)
- let distrf_define_params =
- distrf (Lib_parsing_c.ii_of_define_params,distribute_mck_define_params)
-
-
- (* ------------------------------------------------------------------------*)
- (* Environment *)
- (* ------------------------------------------------------------------------*)
- let meta_name_to_str (s1, s2) =
- s1 ^ "." ^ s2
-
- let envf keep _inherited = fun (s, value, _) f tin ->
- let s = Ast_cocci.unwrap_mcode s in
- let v =
- if keep = Type_cocci.Saved
- then (
- try Some (List.assoc s tin.binding)
- with Not_found ->
- pr2(sprintf
- "Don't find value for metavariable %s in the environment"
- (meta_name_to_str s));
- None)
- else
- (* not raise Impossible! *)
- Some (value)
- in
- match v with
- | None -> fail tin
- | Some (value') ->
-
- (* Ex: in cocci_vs_c someone wants to add a binding. Here in
- * transformation3 the value for this var may be already in the
- * env, because for instance its value were fixed in a previous
- * SmPL rule. So here we want to check that this is the same value.
- * If forget to do the check, what can happen ? Because of Exp
- * and other disjunctive feature of cocci_vs_c (>||>), we
- * may accept a match at a wrong position. Maybe later this
- * will be detected via the pos system on tokens, but maybe
- * not. So safer to keep the check.
- *)
-
- (*f () tin*)
- if Cocci_vs_c_3.equal_metavarval value value'
- then f () tin
- else fail tin
-
-
- let check_constraints matcher constraints exp = fun f tin -> f () tin
-
- (* ------------------------------------------------------------------------*)
- (* Environment, allbounds *)
- (* ------------------------------------------------------------------------*)
- let (all_bound : Ast_cocci.meta_name list -> tin -> bool) = fun l tin ->
- true (* in transform we don't care ? *)
-
-end
-
-(*****************************************************************************)
-(* Entry point *)
-(*****************************************************************************)
-module TRANS = Cocci_vs_c_3.COCCI_VS_C (XTRANS)
-
-
-let transform_re_node a b tin =
- match TRANS.rule_elem_node a b tin with
- | None -> raise Impossible
- | Some (_sp, b') -> b'
-
-let (transform2: string (* rule name *) -> string list (* dropped_isos *) ->
- Lib_engine.metavars_binding (* inherited bindings *) ->
- Lib_engine.transformation_info -> F.cflow -> F.cflow) =
- fun rule_name dropped_isos binding0 xs cflow ->
-
- let extra = {
- optional_storage_iso = not(List.mem "optional_storage" dropped_isos);
- optional_qualifier_iso = not(List.mem "optional_qualifier" dropped_isos);
- value_format_iso = not(List.mem "value_format" dropped_isos);
- current_rule_name = rule_name;
- } in
-
- (* find the node, transform, update the node, and iter for all elements *)
-
- xs +> List.fold_left (fun acc (nodei, binding, rule_elem) ->
- (* subtil: not cflow#nodes but acc#nodes *)
- let node = acc#nodes#assoc nodei in
-
- if !Flag.show_misc
- then pr2 "transform one node";
-
- let tin = {
- XTRANS.extra = extra;
- XTRANS.binding = binding0@binding;
- XTRANS.binding0 = []; (* not used - everything constant for trans *)
- } in
-
- let node' = transform_re_node rule_elem node tin in
-
- (* assert that have done something. But with metaruleElem sometimes
- dont modify fake nodes. So special case before on Fake nodes. *)
- (match F.unwrap node with
- | F.Enter | F.Exit | F.ErrorExit
- | F.EndStatement _ | F.CaseNode _
- | F.Fake
- | F.TrueNode | F.FalseNode | F.AfterNode | F.FallThroughNode
- -> ()
- | _ -> () (* assert (not (node =*= node')); *)
- );
-
- (* useless, we dont go back from flow to ast now *)
- (* let node' = lastfix_comma_struct node' in *)
-
- acc#replace_node (nodei, node');
- acc
- ) cflow
-
-
-
-let transform a b c d e =
- Common.profile_code "Transformation3.transform"
- (fun () -> transform2 a b c d e)
c_vs_c.cmi: ../parsing_c/ast_c.cmo
check_reachability.cmi: ../ctl/wrapper_ctl.cmi ../commons/ograph_extended.cmi \
../parsing_c/control_flow_c.cmi ../ctl/ast_ctl.cmo
-cocci_vs_c_3.cmi: ../parsing_c/control_flow_c.cmi ../commons/common.cmi \
+cocci_vs_c.cmi: ../parsing_c/control_flow_c.cmi ../commons/common.cmi \
../parsing_cocci/ast_cocci.cmi ../parsing_c/ast_c.cmo
ctlcocci_integration.cmi: ../commons/ograph_extended.cmi lib_engine.cmo \
../parsing_c/control_flow_c.cmi ../ctl/ast_ctl.cmo \
../parsing_cocci/ast_cocci.cmi
ctltotex.cmi: ../ctl/wrapper_ctl.cmi lib_engine.cmo ../ctl/ast_ctl.cmo \
../parsing_cocci/ast_cocci.cmi
-pattern3.cmi: lib_engine.cmo ../parsing_c/control_flow_c.cmi \
+pattern_c.cmi: lib_engine.cmo ../parsing_c/control_flow_c.cmi \
../parsing_cocci/ast_cocci.cmi
postprocess_transinfo.cmi: ../commons/ograph_extended.cmi lib_engine.cmo \
../parsing_cocci/ast_cocci.cmi
pretty_print_engine.cmi: lib_engine.cmo ../ctl/ast_ctl.cmo \
../parsing_c/ast_c.cmo
-transformation3.cmi: lib_engine.cmo ../parsing_c/control_flow_c.cmi
+transformation_c.cmi: lib_engine.cmo ../parsing_c/control_flow_c.cmi
asttoctl.cmo: ../ctl/wrapper_ctl.cmi ../parsing_cocci/visitor_ast.cmi \
../parsing_cocci/unify_ast.cmi pretty_print_engine.cmi lib_engine.cmo \
../parsing_cocci/free_vars.cmi ../commons/common.cmi ../ctl/ast_ctl.cmo \
asttoctl2.cmo: ../ctl/wrapper_ctl.cmi ../parsing_cocci/visitor_ast.cmi \
../parsing_cocci/unify_ast.cmi ../parsing_cocci/type_cocci.cmi \
pretty_print_engine.cmi ../ctl/pretty_print_ctl.cmi \
- ../parsing_cocci/pretty_print_cocci.cmi lib_engine.cmo flag_engine.cmo \
+ ../parsing_cocci/pretty_print_cocci.cmi lib_engine.cmo flag_matcher.cmo \
../globals/flag.cmo ../commons/common.cmi ../ctl/ast_ctl.cmo \
../parsing_cocci/ast_cocci.cmi asttoctl2.cmi
asttoctl2.cmx: ../ctl/wrapper_ctl.cmx ../parsing_cocci/visitor_ast.cmx \
../parsing_cocci/unify_ast.cmx ../parsing_cocci/type_cocci.cmx \
pretty_print_engine.cmx ../ctl/pretty_print_ctl.cmx \
- ../parsing_cocci/pretty_print_cocci.cmx lib_engine.cmx flag_engine.cmx \
+ ../parsing_cocci/pretty_print_cocci.cmx lib_engine.cmx flag_matcher.cmx \
../globals/flag.cmx ../commons/common.cmx ../ctl/ast_ctl.cmx \
../parsing_cocci/ast_cocci.cmx asttoctl2.cmi
asttomember.cmo: ../parsing_cocci/visitor_ast.cmi \
check_reachability.cmx: ../ctl/wrapper_ctl.cmx ../commons/ograph_extended.cmx \
../ctl/flag_ctl.cmx ../ctl/ctl_engine.cmx ../parsing_c/control_flow_c.cmx \
../ctl/ast_ctl.cmx check_reachability.cmi
-cocci_vs_c_3.cmo: ../parsing_cocci/type_cocci.cmi \
- ../parsing_c/lib_parsing_c.cmo ../globals/flag.cmo \
+cocci_vs_c.cmo: ../parsing_cocci/type_cocci.cmi \
+ ../parsing_c/lib_parsing_c.cmo flag_matcher.cmo \
../parsing_c/control_flow_c.cmi ../commons/common.cmi c_vs_c.cmi \
- ../parsing_cocci/ast_cocci.cmi ../parsing_c/ast_c.cmo cocci_vs_c_3.cmi
-cocci_vs_c_3.cmx: ../parsing_cocci/type_cocci.cmx \
- ../parsing_c/lib_parsing_c.cmx ../globals/flag.cmx \
+ ../parsing_cocci/ast_cocci.cmi ../parsing_c/ast_c.cmo cocci_vs_c.cmi
+cocci_vs_c.cmx: ../parsing_cocci/type_cocci.cmx \
+ ../parsing_c/lib_parsing_c.cmx flag_matcher.cmx \
../parsing_c/control_flow_c.cmx ../commons/common.cmx c_vs_c.cmx \
- ../parsing_cocci/ast_cocci.cmx ../parsing_c/ast_c.cmx cocci_vs_c_3.cmi
+ ../parsing_cocci/ast_cocci.cmx ../parsing_c/ast_c.cmx cocci_vs_c.cmi
ctlcocci_integration.cmo: ../ctl/wrapper_ctl.cmi pretty_print_engine.cmi \
../parsing_cocci/pretty_print_cocci.cmi postprocess_transinfo.cmi \
- pattern3.cmi ../commons/ograph_extended.cmi lib_engine.cmo \
- ../parsing_cocci/flag_parsing_cocci.cmo flag_engine.cmo \
+ pattern_c.cmi ../commons/ograph_extended.cmi lib_engine.cmo \
+ ../parsing_cocci/flag_parsing_cocci.cmo flag_matcher.cmo \
../globals/flag.cmo ../parsing_c/control_flow_c.cmi ../commons/common.cmi \
check_reachability.cmi c_vs_c.cmi ../ctl/ast_ctl.cmo \
../parsing_cocci/ast_cocci.cmi ../parsing_c/ast_c.cmo \
ctlcocci_integration.cmi
ctlcocci_integration.cmx: ../ctl/wrapper_ctl.cmx pretty_print_engine.cmx \
../parsing_cocci/pretty_print_cocci.cmx postprocess_transinfo.cmx \
- pattern3.cmx ../commons/ograph_extended.cmx lib_engine.cmx \
- ../parsing_cocci/flag_parsing_cocci.cmx flag_engine.cmx \
+ pattern_c.cmx ../commons/ograph_extended.cmx lib_engine.cmx \
+ ../parsing_cocci/flag_parsing_cocci.cmx flag_matcher.cmx \
../globals/flag.cmx ../parsing_c/control_flow_c.cmx ../commons/common.cmx \
check_reachability.cmx c_vs_c.cmx ../ctl/ast_ctl.cmx \
../parsing_cocci/ast_cocci.cmx ../parsing_c/ast_c.cmx \
../parsing_cocci/ast_cocci.cmx ../parsing_c/ast_c.cmx
main.cmo: ../parsing_cocci/parse_cocci.cmi ctltotex.cmi asttoctl.cmi
main.cmx: ../parsing_cocci/parse_cocci.cmx ctltotex.cmx asttoctl.cmx
-pattern3.cmo: ../parsing_c/visitor_c.cmi ../parsing_c/lib_parsing_c.cmo \
- lib_engine.cmo flag_engine.cmo ../commons/common.cmi cocci_vs_c_3.cmi \
- ../parsing_cocci/ast_cocci.cmi ../parsing_c/ast_c.cmo pattern3.cmi
-pattern3.cmx: ../parsing_c/visitor_c.cmx ../parsing_c/lib_parsing_c.cmx \
- lib_engine.cmx flag_engine.cmx ../commons/common.cmx cocci_vs_c_3.cmx \
- ../parsing_cocci/ast_cocci.cmx ../parsing_c/ast_c.cmx pattern3.cmi
+pattern_c.cmo: ../parsing_c/visitor_c.cmi ../parsing_c/lib_parsing_c.cmo \
+ lib_engine.cmo flag_matcher.cmo ../commons/common.cmi cocci_vs_c.cmi \
+ ../parsing_cocci/ast_cocci.cmi ../parsing_c/ast_c.cmo pattern_c.cmi
+pattern_c.cmx: ../parsing_c/visitor_c.cmx ../parsing_c/lib_parsing_c.cmx \
+ lib_engine.cmx flag_matcher.cmx ../commons/common.cmx cocci_vs_c.cmx \
+ ../parsing_cocci/ast_cocci.cmx ../parsing_c/ast_c.cmx pattern_c.cmi
postprocess_transinfo.cmo: ../parsing_c/parser_c.cmi ../parsing_c/parse_c.cmi \
lib_engine.cmo ../commons/common.cmi ../parsing_cocci/ast_cocci.cmi \
../parsing_c/ast_c.cmo postprocess_transinfo.cmi
pretty_print_engine.cmi
sgrep.cmo: ../parsing_cocci/ast_cocci.cmi ../parsing_c/ast_c.cmo
sgrep.cmx: ../parsing_cocci/ast_cocci.cmx ../parsing_c/ast_c.cmx
-transformation3.cmo: ../parsing_c/visitor_c.cmi \
- ../parsing_cocci/type_cocci.cmi sgrep.cmo \
- ../parsing_cocci/pretty_print_cocci.cmi ../parsing_c/lib_parsing_c.cmo \
- lib_engine.cmo ../parsing_cocci/flag_parsing_cocci.cmo \
- ../globals/flag.cmo ../parsing_c/control_flow_c.cmi ../commons/common.cmi \
- cocci_vs_c_3.cmi ../parsing_cocci/ast_cocci.cmi ../parsing_c/ast_c.cmo \
- transformation3.cmi
-transformation3.cmx: ../parsing_c/visitor_c.cmx \
- ../parsing_cocci/type_cocci.cmx sgrep.cmx \
- ../parsing_cocci/pretty_print_cocci.cmx ../parsing_c/lib_parsing_c.cmx \
- lib_engine.cmx ../parsing_cocci/flag_parsing_cocci.cmx \
- ../globals/flag.cmx ../parsing_c/control_flow_c.cmx ../commons/common.cmx \
- cocci_vs_c_3.cmx ../parsing_cocci/ast_cocci.cmx ../parsing_c/ast_c.cmx \
- transformation3.cmi
+transformation_c.cmo: ../parsing_c/visitor_c.cmi \
+ ../parsing_cocci/type_cocci.cmi ../parsing_c/lib_parsing_c.cmo \
+ lib_engine.cmo flag_matcher.cmo ../parsing_c/control_flow_c.cmi \
+ ../commons/common.cmi cocci_vs_c.cmi ../parsing_cocci/ast_cocci.cmi \
+ ../parsing_c/ast_c.cmo transformation_c.cmi
+transformation_c.cmx: ../parsing_c/visitor_c.cmx \
+ ../parsing_cocci/type_cocci.cmx ../parsing_c/lib_parsing_c.cmx \
+ lib_engine.cmx flag_matcher.cmx ../parsing_c/control_flow_c.cmx \
+ ../commons/common.cmx cocci_vs_c.cmx ../parsing_cocci/ast_cocci.cmx \
+ ../parsing_c/ast_c.cmx transformation_c.cmi
# Coccinelle under other licenses.
+##############################################################################
+# Variables
+##############################################################################
+#TARGET=matcher
TARGET=cocciengine
CTLTARGET=engine
-SOURCES = flag_engine.ml lib_engine.ml pretty_print_engine.ml \
- check_exhaustive_pattern.ml \
- check_reachability.ml \
- c_vs_c.ml isomorphisms_c_c.ml \
- cocci_vs_c_3.ml pattern3.ml sgrep.ml transformation3.ml \
- asttomember.ml asttoctl2.ml ctltotex.ml \
- postprocess_transinfo.ml ctlcocci_integration.ml
+SRC= flag_matcher.ml lib_engine.ml pretty_print_engine.ml \
+ check_exhaustive_pattern.ml \
+ check_reachability.ml \
+ c_vs_c.ml isomorphisms_c_c.ml \
+ cocci_vs_c.ml pattern_c.ml sgrep.ml transformation_c.ml \
+ asttomember.ml asttoctl2.ml ctltotex.ml \
+ postprocess_transinfo.ml ctlcocci_integration.ml
+
+#c_vs_c.ml
+#SRC= flag_matcher.ml \
+# c_vs_c.ml cocci_vs_c.ml \
+# lib_engine.ml \
+# pattern_c.ml transformation_c.ml
+
+#LIBS=../commons/commons.cma ../parsing_c/parsing_c.cma
+#INCLUDES= -I ../commons -I ../parsing_c
+INCLUDES = -I ../commons -I ../commons/ocamlextra -I ../globals \
+ -I ../ctl -I ../parsing_cocci -I ../parsing_c
+LIBS=../commons/commons.cma ../globals/globals.cma \
+ ../ctl/ctl.cma ../parsing_c/parsing_c.cma ../parsing_cocci/cocci_parser.cma
+
+SYSLIBS= str.cma unix.cma
+
# just to test asttoctl
# CTLSOURCES = lib_engine.ml pretty_print_engine.ml asttoctl.ml ctltotex.ml \
# main.ml
-INCLUDES = -I ../commons -I ../commons/ocamlextra -I ../globals \
- -I ../ctl -I ../parsing_c -I ../parsing_cocci
-
-SYSLIBS = str.cma unix.cma
-LIBS=../commons/commons.cma ../globals/globals.cma \
- ../ctl/ctl.cma ../parsing_c/c_parser.cma ../parsing_cocci/cocci_parser.cma
-
+##############################################################################
+# Generic variables
+##############################################################################
-# The Caml compilers.
+#for warning: -w A
+#for profiling: -p -inline 0 with OCAMLOPT
OCAMLCFLAGS ?= -g -dtypes
-OCAMLC =ocamlc$(OPTBIN) $(OCAMLCFLAGS) $(INCLUDES)
-OCAMLOPT = ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
-OCAMLDEP = ocamldep$(OPTBIN) $(INCLUDES)
-
-EXEC=$(TARGET).byte
-LIB=$(TARGET).cma
-OPTLIB=$(LIB:.cma=.cmxa)
-
-CTLEXEC=$(CTLTARGET)
-OBJS = $(SOURCES:.ml=.cmo)
-OPTOBJS = $(OBJS:.cmo=.cmx)
+OCAMLC=ocamlc$(OPTBIN) $(OCAMLCFLAGS) $(INCLUDES)
+OCAMLOPT=ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
+OCAMLLEX=ocamllex$(OPTBIN) #-ml
+OCAMLYACC=ocamlyacc -v
+OCAMLDEP=ocamldep$(OPTBIN) $(INCLUDES)
+OCAMLMKTOP=ocamlmktop -g -custom $(INCLUDES)
-CTLOBJS = $(CTLSOURCES:.ml=.cmo)
-CTLOPTOBJS = $(CTLOBJS:.cmo=.cmx)
+OBJS = $(SRC:.ml=.cmo)
+OPTOBJS = $(SRC:.ml=.cmx)
-#all: $(EXEC) $(LIB)
-all: $(LIB)
-all.opt: $(OPTLIB)
+##############################################################################
+# Top rules
+##############################################################################
+all: $(TARGET).cma
+all.opt: $(TARGET).cmxa
-ctl: $(CTLEXEC)
+$(TARGET).cma: $(OBJS)
+ $(OCAMLC) -a -o $(TARGET).cma $(OBJS)
+$(TARGET).cmxa: $(OPTOBJS) $(LIBS:.cma=.cmxa)
+ $(OCAMLOPT) -a -o $(TARGET).cmxa $(OPTOBJS)
-$(LIB): $(OBJS)
- $(OCAMLC) -a -o $(LIB) $(OBJS)
+$(TARGET).top: $(OBJS) $(LIBS)
+ $(OCAMLMKTOP) -o $(TARGET).top $(SYSLIBS) $(LIBS) $(OBJS)
-# clean rule for LIB
clean::
- rm -f $(LIB)
+ rm -f $(TARGET).top
-$(OPTLIB): $(OPTOBJS)
- $(OCAMLOPT) -a -o $(OPTLIB) $(OPTOBJS)
+##############################################################################
+# Pad's rules
+##############################################################################
-$(EXEC): $(OBJS) main.cmo $(LIBS)
- $(OCAMLC) -o $(EXEC) $(SYSLIBS) $(LIBS) $(OBJS) main.cmo
+##############################################################################
+# Generic rules
+##############################################################################
-$(CTLEXEC): $(CTLOBJS) $(LIBS)
- $(OCAMLC) -o $(CTLEXEC) $(SYSLIBS) $(LIBS) $(CTLOBJS)
-
-
-# clean rule for LIB.opt
-clean::
- rm -f $(OPTLIB) $(LIB:.cma=.a)
- rm -f $(TARGET) rm -f $(TARGET).byte
- rm -f $(CTLTARGET)
-
-
-.SUFFIXES:
.SUFFIXES: .ml .mli .cmo .cmi .cmx
.ml.cmo:
$(OCAMLC) -c $<
-
.mli.cmi:
$(OCAMLC) -c $<
-
.ml.cmx:
$(OCAMLOPT) -c $<
+.ml.mldepend:
+ $(OCAMLC) -i $<
-# clean rule for others files
clean::
- rm -f *.cm[iox] *.o *.annot
- rm -f *~ .*~ #*#
-
-beforedepend:
+ rm -f *.cm[ioxa] *.o *.a *.cmxa *.annot
+clean::
+ rm -f *~ .*~ gmon.out #*#
-depend: beforedepend
- $(OCAMLDEP) *.mli *.ml > .depend
+beforedepend::
-.depend:
- $(OCAMLDEP) *.mli *.ml > .depend
+depend:: beforedepend
+ $(OCAMLDEP) *.mli *.ml > .depend
-include .depend
make_match None false
(wrapcode
(Ast.Continue(Ast.make_mcode "continue",Ast.make_mcode ";"))) in
- let stop_early v =
+ let stop_early =
if quantifier = Exists
- then CTL.False
+ then Common.Left(CTL.False)
else if toend
- then CTL.Or(aftpred label,exitpred label)
+ then Common.Left(CTL.Or(aftpred label,exitpred label))
else if is_strict
- then aftpred label
+ then Common.Left(aftpred label)
else
- let lv = get_label_ctr() in
- let labelpred = CTL.Pred(Lib_engine.Label lv,CTL.Control) in
- let preflabelpred = label_pred_maker (Some (lv,ref true)) in
- ctl_or (aftpred label)
- (quantify false [lv]
- (ctl_and CTL.NONSTRICT
- (ctl_and CTL.NONSTRICT (truepred label) labelpred)
- (ctl_au CTL.NONSTRICT
- (ctl_and CTL.NONSTRICT (ctl_not v) preflabelpred)
- (ctl_and CTL.NONSTRICT preflabelpred
- (ctl_or (retpred None)
- (if !Flag_engine.only_return_is_error_exit
- then CTL.True
- else
- (ctl_or matchcontinue
- (ctl_and CTL.NONSTRICT
- (ctl_or matchgoto matchbreak)
- (ctl_ag s (ctl_not seq_after)))))))))) in
- let v = get_let_ctr() in
+ Common.Right
+ (function v ->
+ let lv = get_label_ctr() in
+ let labelpred = CTL.Pred(Lib_engine.Label lv,CTL.Control) in
+ let preflabelpred = label_pred_maker (Some (lv,ref true)) in
+ ctl_or (aftpred label)
+ (quantify false [lv]
+ (ctl_and CTL.NONSTRICT
+ (ctl_and CTL.NONSTRICT (truepred label) labelpred)
+ (ctl_au CTL.NONSTRICT
+ (ctl_and CTL.NONSTRICT (ctl_not v) preflabelpred)
+ (ctl_and CTL.NONSTRICT preflabelpred
+ (ctl_or (retpred None)
+ (if !Flag_matcher.only_return_is_error_exit
+ then CTL.True
+ else
+ (ctl_or matchcontinue
+ (ctl_and CTL.NONSTRICT
+ (ctl_or matchgoto matchbreak)
+ (ctl_ag s (ctl_not seq_after))))))))))) in
let op = if quantifier = !exists then ctl_au else ctl_anti_au in
- op s x (CTL.Let(v,y,ctl_or (CTL.Ref v) (stop_early (CTL.Ref v))))
+ let v = get_let_ctr() in
+ op s x
+ (match stop_early with
+ Common.Left x -> ctl_or y x
+ | Common.Right stop_early ->
+ CTL.Let(v,y,ctl_or (CTL.Ref v) (stop_early (CTL.Ref v))))
let rec dots_and_nests plus nest whencodes bef aft dotcode after label
process_bef_aft statement_list statement guard quantified wrapcode =
let sxopt = saopt in
let ii_b_sx = ii_b_sa in
+ (* todo? iso on name or argument ? *)
(ba =:= bb && saopt =*= sbopt) >&&>
fullType ta tb >>= (fun tx ->
let paramx = (((bx, sxopt, tx), ii_b_sx)) in
match xfielda, xfieldb with
| EmptyField, EmptyField -> return ((EmptyField, iix)::xs)
- | FieldDeclList fa, FieldDeclList fb ->
+ | DeclarationField (FieldDeclList (fa, iipta)),
+ DeclarationField (FieldDeclList (fb, iiptb)) ->
+ let iipt = iipta in (* TODO ?*)
(List.length fa =|= List.length fb) >&&>
Common.zip fa fb +> List.fold_left
)
) (return [])
>>= (fun fx ->
- return ((FieldDeclList (List.rev fx), iix)::xs)
+ return (((DeclarationField
+ (FieldDeclList (List.rev fx,iipt))), iix)::xs)
)
| _ -> fail
)
Control_flow_c.extract_is_loop (cfg#nodes#find n)
let print_node i = Format.print_string (string_of_int i)
let size cfg = cfg#nodes#length
+ let print_graph cfg label border_nodes fill_nodes filename = ()
end
module ENGINE = Ctl_engine.CTL_ENGINE (ENV) (CFG) (PRED)
cfg#nodes#tolist) in
let verbose = !Flag_ctl.verbose_ctl_engine in
let pm = !Flag_ctl.partial_match in
+(* let gt = !Flag_ctl.graphical_trace in *)
Flag_ctl.verbose_ctl_engine := false;
Flag_ctl.partial_match := false;
+ Flag_ctl.checking_reachability := true;
+(* Flag_ctl.graphical_trace := ""; *)
let res =
ENGINE.sat (cfg,label,List.map fst cfg#nodes#tolist)
(CTL.And(CTL.NONSTRICT,CTL.Pred(Node(state)),formula))
[[Node(state)]] in
Flag_ctl.verbose_ctl_engine := verbose;
Flag_ctl.partial_match := pm;
+ Flag_ctl.checking_reachability := false;
+(* Flag_ctl.graphical_trace := gt; *)
match res with [] -> false | _ -> true
(* ---------------------------------------------------------------- *)
-(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-*
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-*
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
-*
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
+(* Copyright (C) 2006, 2007, 2008 Yoann Padioleau
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License (GPL)
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * file license.txt for more details.
+ *
+ * This file was part of Coccinelle.
+ *)
open Common
module F = Control_flow_c
+module Flag = Flag_matcher
+
(*****************************************************************************)
(* Wrappers *)
(*****************************************************************************)
A.CONTEXT (A.DontCarePos,x)
| A.MINUS (A.NoPos,x) ->
A.MINUS (A.DontCarePos,x)
- | _ -> raise Impossible in
+
+ | A.CONTEXT ((A.FixPos _|A.DontCarePos), _)
+ | A.MINUS ((A.FixPos _|A.DontCarePos), _)
+ ->
+ raise Impossible
+ in
(s1, i, new_mck, pos)
| A.UnMinus , B.UnMinus -> true
| A.Tilde , B.Tilde -> true
| A.Not , B.Not -> true
- | _, _ -> false
+ | _, B.GetRefLabel -> false (* todo cocci? *)
+ | _, (B.Not|B.Tilde|B.UnMinus|B.UnPlus|B.DeRef|B.GetRef) -> false
+
+
let equal_arithOp a b =
match a, b with
| A.And , B.And -> true
| A.Or , B.Or -> true
| A.Xor , B.Xor -> true
- | _ , _ -> false
+ | _, (B.Xor|B.Or|B.And|B.DecRight|B.DecLeft|B.Mod|B.Div|B.Mul|B.Minus|B.Plus)
+ -> false
let equal_logicalOp a b =
match a, b with
| A.NotEq , B.NotEq -> true
| A.AndLog , B.AndLog -> true
| A.OrLog , B.OrLog -> true
- | _ , _ -> false
+ | _, (B.OrLog|B.AndLog|B.NotEq|B.Eq|B.SupEq|B.InfEq|B.Sup|B.Inf)
+ -> false
let equal_assignOp a b =
match a, b with
| A.SimpleAssign, B.SimpleAssign -> true
| A.OpAssign a, B.OpAssign b -> equal_arithOp a b
- | _ -> false
+ | _, (B.OpAssign _|B.SimpleAssign) -> false
let equal_fixOp a b =
match a, b with
| A.Dec, B.Dec -> true
| A.Inc, B.Inc -> true
- | _ -> false
+ | _, (B.Inc|B.Dec) -> false
let equal_binaryOp a b =
match a, b with
| A.Arith a, B.Arith b -> equal_arithOp a b
| A.Logical a, B.Logical b -> equal_logicalOp a b
- | _ -> false
+ | _, (B.Logical _ | B.Arith _) -> false
let equal_structUnion a b =
match a, b with
| A.Struct, B.Struct -> true
| A.Union, B.Union -> true
- | _, _ -> false
+ | _, (B.Struct|B.Union) -> false
let equal_sign a b =
match a, b with
| A.Signed, B.Signed -> true
| A.Unsigned, B.UnSigned -> true
- | _, _ -> false
+ | _, (B.UnSigned|B.Signed) -> false
let equal_storage a b =
match a, b with
| A.Register , B.Sto B.Register
| A.Extern , B.Sto B.Extern
-> true
- | _ -> false
+ | _, (B.NoSto | B.StoTypedef) -> false
+ | _, (B.Sto (B.Register|B.Static|B.Auto|B.Extern)) -> false
+
(*---------------------------------------------------------------------------*)
| Ast_c.MetaPosValList l1, Ast_c.MetaPosValList l2 ->
List.exists
- (function (fla,posa1,posa2) ->
+ (function (fla,cea,posa1,posa2) ->
List.exists
- (function (flb,posb1,posb2) ->
- fla = flb &&
+ (function (flb,ceb,posb1,posb2) ->
+ fla = flb && cea = ceb &&
Ast_c.equal_posl posa1 posb1 && Ast_c.equal_posl posa2 posb2)
l2)
l1
- | _ -> raise Impossible
+ | (B.MetaPosValList _|B.MetaListlenVal _|B.MetaPosVal _|B.MetaStmtVal _
+ |B.MetaTypeVal _
+ |B.MetaParamListVal _|B.MetaParamVal _|B.MetaExprListVal _
+ |B.MetaExprVal _|B.MetaLocalFuncVal _|B.MetaFuncVal _|B.MetaIdVal _
+ ), _
+ -> raise Impossible
(*---------------------------------------------------------------------------*)
(match xs with
| [] -> raise Impossible
| [x] ->
- let ((var, returnType, storage, local),iisep) = x in
+ let ({B.v_namei = var;
+ B.v_type = returnType;
+ B.v_storage = storage;
+ B.v_local = local},
+ iisep) = x in
(match var with
| Some ((s, ini), iis::iini) ->
matcher
val distrf_struct_fields :
- (A.meta_name A.mcode, B.field B.wrap list) matcher
+ (A.meta_name A.mcode, B.field list) matcher
val distrf_cst :
(A.meta_name A.mcode, (B.constant, string) either B.wrap) matcher
val envf :
A.keep_binding -> A.inherited ->
A.meta_name A.mcode * Ast_c.metavar_binding_kind *
- (unit -> Common.filename * Ast_c.posl * Ast_c.posl) ->
+ (unit -> Common.filename * string * Ast_c.posl * Ast_c.posl) ->
(unit -> tin -> 'x tout) -> (tin -> 'x tout)
val check_constraints :
- | A.MetaErr _, _ -> failwith "not handling MetaErr"
+ | A.MetaErr _, _ -> failwith "not handling MetaErr"
(* todo?: handle some isomorphisms in int/float ? can have different
* format : 1l can match a 1.
))
| _ -> fail (* multi string, not handled *)
)
- | _, _ -> fail
+
+ | _, B.MultiString -> (* todo cocci? *) fail
+ | _, (B.String _ | B.Float _ | B.Char _ | B.Int _) -> fail
)
failwith
"for nestexpr, only handling the case with dots and only one exp")
- | A.NestExpr _, _ ->
+ | A.NestExpr _, _ ->
failwith "only handling multi and no when code in a nest expr"
(* only in arg lists or in define body *)
- | A.TypeExp _, _ -> fail
+ | A.TypeExp _, _ -> fail
(* only in arg lists *)
- | A.MetaExprList _, _
- | A.EComma _, _
- | A.Ecircles _, _
- | A.Estars _, _
+ | A.MetaExprList _, _
+ | A.EComma _, _
+ | A.Ecircles _, _
+ | A.Estars _, _
->
raise Impossible
| _, ((B.Constructor _,_),_)
-> fail
- | _, _ -> fail
+
+ | _,
+ (((B.Cast (_, _)|B.ParenExpr _|B.SizeOfType _|B.SizeOfExpr _|
+ B.RecordPtAccess (_, _)|
+ B.RecordAccess (_, _)|B.ArrayAccess (_, _)|
+ B.Binary (_, _, _)|B.Unary (_, _)|
+ B.Infix (_, _)|B.Postfix (_, _)|
+ B.Assignment (_, _, _)|B.CondExpr (_, _, _)|
+ B.FunCall (_, _)|B.Constant _|B.Ident _),
+ _),_)
+ -> fail
+
+
+
(B.MacroDecl ((sb,ebs),
[iisb;lpb;rpb;iiendb;iifakestart] ++ iistob))
))))))))
-
- | _ -> fail
+
+ | _, (B.MacroDecl _ |B.DeclList _) -> fail
* T { }; that we want to match against typedef struct { } xx_t;
*)
| A.TyDecl (tya0, ptvirga),
- ((Some ((idb, None),[iidb]), typb0, (B.StoTypedef, inl), local), iivirg) ->
+ ({B.v_namei = Some ((idb, None),[iidb]);
+ B.v_type = typb0;
+ B.v_storage = (B.StoTypedef, inl);
+ B.v_local = local;
+ B.v_attr = attrs;
+ }, iivirg) ->
(match A.unwrap tya0, typb0 with
| A.Type(cv1,tya1), ((qu,il),typb1) ->
return (
(A.TyDecl (tya0, ptvirga)) +> A.rewrap decla,
- (((Some ((idb, None),[iidb]), typb0, (B.StoTypedef, inl),
- local),
+ (({B.v_namei = Some ((idb, None),[iidb]);
+ B.v_type = typb0;
+ B.v_storage = (B.StoTypedef, inl);
+ B.v_local = local;
+ B.v_attr = attrs;
+ },
iivirg),iiptvirgb,iistob)
)
| _ -> raise Impossible
return (
(A.TyDecl (tya0, ptvirga)) +> A.rewrap decla,
- (((Some ((idb, None),[iidb]), typb0,
- (B.StoTypedef, inl), local),
+ (({B.v_namei = Some ((idb, None),[iidb]);
+ B.v_type = typb0;
+ B.v_storage = (B.StoTypedef, inl);
+ B.v_local = local;
+ B.v_attr = attrs;
+ },
iivirg),iiptvirgb,iistob)
)
| _ -> raise Impossible
)
| A.UnInit (stoa, typa, ida, ptvirga),
- ((Some ((idb, _),[iidb]), typb, (B.StoTypedef,_), _local), iivirg) ->
+ ({B.v_namei = Some ((idb, _),[iidb]);
+ B.v_storage = (B.StoTypedef,_);
+ }, iivirg) ->
fail
| A.Init (stoa, typa, ida, eqa, inia, ptvirga),
- ((Some ((idb, _),[iidb]), typb, (B.StoTypedef,_), _local), iivirg) ->
+ ({B.v_namei = Some ((idb, _),[iidb]);
+ B.v_storage = (B.StoTypedef,_);
+ }, iivirg) ->
fail
(* could handle iso here but handled in standard.iso *)
| A.UnInit (stoa, typa, ida, ptvirga),
- ((Some ((idb, None),[iidb]), typb, stob, local), iivirg) ->
+ ({B.v_namei = Some ((idb, None),[iidb]);
+ B.v_type = typb;
+ B.v_storage = stob;
+ B.v_local = local;
+ B.v_attr = attrs;
+ }, iivirg) ->
+
tokenf ptvirga iiptvirgb >>= (fun ptvirga iiptvirgb ->
fullType typa typb >>= (fun typa typb ->
ident DontKnow ida (idb, iidb) >>= (fun ida (idb, iidb) ->
(fun stoa (stob, iistob) ->
return (
(A.UnInit (stoa, typa, ida, ptvirga)) +> A.rewrap decla,
- (((Some ((idb,None),[iidb]),typb,stob,local),iivirg),
+ (({B.v_namei = Some ((idb,None),[iidb]);
+ B.v_type = typb;
+ B.v_storage = stob;
+ B.v_local = local;
+ B.v_attr = attrs;
+ },iivirg),
iiptvirgb,iistob)
)))))
| A.Init (stoa, typa, ida, eqa, inia, ptvirga),
- ((Some((idb,Some inib),[iidb;iieqb]),typb,stob,local),iivirg)
+ ({B.v_namei = Some((idb,Some inib),[iidb;iieqb]);
+ B.v_type = typb;
+ B.v_storage = stob;
+ B.v_local = local;
+ B.v_attr = attrs;
+ },iivirg)
->
tokenf ptvirga iiptvirgb >>= (fun ptvirga iiptvirgb ->
tokenf eqa iieqb >>= (fun eqa iieqb ->
initialiser inia inib >>= (fun inia inib ->
return (
(A.Init (stoa, typa, ida, eqa, inia, ptvirga)) +> A.rewrap decla,
- (((Some((idb,Some inib),[iidb;iieqb]),typb,stob,local),iivirg),
+ (({B.v_namei = Some((idb,Some inib),[iidb;iieqb]);
+ B.v_type = typb;
+ B.v_storage = stob;
+ B.v_local = local;
+ B.v_attr = attrs;
+ },iivirg),
iiptvirgb,iistob)
)))))))
(* do iso-by-absence here ? allow typedecl and var ? *)
- | A.TyDecl (typa, ptvirga), ((None, typb, stob, local), iivirg) ->
+ | A.TyDecl (typa, ptvirga),
+ ({B.v_namei = None; B.v_type = typb;
+ B.v_storage = stob;
+ B.v_local = local;
+ B.v_attr = attrs;
+ }, iivirg) ->
+
if stob = (B.NoSto, false)
then
tokenf ptvirga iiptvirgb >>= (fun ptvirga iiptvirgb ->
fullType typa typb >>= (fun typa typb ->
return (
(A.TyDecl (typa, ptvirga)) +> A.rewrap decla,
- (((None, typb, stob, local), iivirg), iiptvirgb, iistob)
+ (({B.v_namei = None;
+ B.v_type = typb;
+ B.v_storage = stob;
+ B.v_local = local;
+ B.v_attr = attrs;
+ }, iivirg), iiptvirgb, iistob)
)))
else fail
| A.Typedef (stoa, typa, ida, ptvirga),
- ((Some ((idb, None),[iidb]),typb,(B.StoTypedef,inline),local),iivirg) ->
+ ({B.v_namei = Some ((idb, None),[iidb]);
+ B.v_type = typb;
+ B.v_storage = (B.StoTypedef,inline);
+ B.v_local = local;
+ B.v_attr = attrs;
+ },iivirg) ->
tokenf ptvirga iiptvirgb >>= (fun ptvirga iiptvirgb ->
fullType typa typb >>= (fun typa typb ->
) >>= (fun ida (idb, iidb) ->
return (
(A.Typedef (stoa, typa, ida, ptvirga)) +> A.rewrap decla,
- (((Some ((idb, None),[iidb]), typb, (B.StoTypedef,inline),local),
+ (({B.v_namei = Some ((idb, None),[iidb]);
+ B.v_type = typb;
+ B.v_storage = (B.StoTypedef,inline);
+ B.v_local = local;
+ B.v_attr = attrs;
+ },
iivirg),
iiptvirgb, iistob)
)
))))
- | _, ((None, typb, sto, _local), _) ->
+ | _, ({B.v_namei = None;}, _) ->
(* old: failwith "no variable in this declaration, wierd" *)
fail
| A.Ddots(dots,whencode), _ ->
raise Impossible
- | A.OptDecl _, _ | A.UniqueDecl _, _ ->
+ | A.OptDecl _, _ | A.UniqueDecl _, _ ->
failwith "not handling Opt/Unique Decl"
+ | _, ({B.v_namei=Some _}, _)
+ -> fail
- | _, _ -> fail
| A.UniqueIni _,_ | A.OptIni _,_ ->
failwith "not handling Opt/Unique on initialisers"
-
- | _, _ -> fail
+
+ | _, (B.InitIndexOld (_, _), _) -> fail
+ | _, (B.InitFieldOld (_, _), _) -> fail
+
+ | _, ((B.InitDesignators (_, _)|B.InitList _|B.InitExpr _), _)
+ -> fail
+
(* ------------------------------------------------------------------------- *)
-and (struct_fields: (A.declaration list, B.field B.wrap list) matcher) =
+and (struct_fields: (A.declaration list, B.field list) matcher) =
fun eas ebs ->
match eas, ebs with
| [], [] -> return ([], [])
| _unwrapx, [] -> fail
)
-and (struct_field: (A.declaration, B.field B.wrap) matcher) = fun fa fb ->
- let (xfield, ii) = fb in
- let iiptvirgb = tuple_of_list1 ii in
+and (struct_field: (A.declaration, B.field) matcher) = fun fa fb ->
+ let (xfield, iifield) = fb in
match xfield with
- | B.FieldDeclList onefield_multivars ->
+ | B.DeclarationField (B.FieldDeclList (onefield_multivars,iiptvirg)) ->
+
+ let iiptvirgb = tuple_of_list1 iiptvirg in
(match onefield_multivars with
| [] -> raise Impossible
let iisto = [] in
let stob = B.NoSto, false in
let fake_var =
- ((Some ((idb, None),[iidb]), typb, stob, Ast_c.NotLocalDecl),
+ ({B.v_namei = Some ((idb, None),[iidb]);
+ B.v_type = typb;
+ B.v_storage = stob;
+ B.v_local = Ast_c.NotLocalDecl;
+ B.v_attr = Ast_c.noattr;
+ },
iivirg)
in
onedecl allminus fa (fake_var,iiptvirgb,iisto) >>=
(fun fa (var,iiptvirgb,iisto) ->
match fake_var with
- | ((Some ((idb, None),[iidb]), typb, stob, local), iivirg) ->
+ | ({B.v_namei = Some ((idb, None),[iidb]);
+ B.v_type = typb;
+ B.v_storage = stob;
+ }, iivirg) ->
let onevar = B.Simple (Some idb, typb), [iidb] in
return (
(fa),
- (B.FieldDeclList [onevar, iivirg], [iiptvirgb])
+ ((B.DeclarationField
+ (B.FieldDeclList ([onevar, iivirg], [iiptvirgb]))),
+ iifield)
)
| _ -> raise Impossible
)
pr2_once "PB: More that one variable in decl. Have to split";
fail
)
- | B.EmptyField -> fail
+ | B.EmptyField ->
+ let _iiptvirgb = tuple_of_list1 iifield in
+ fail
+
+ | B.MacroStructDeclTodo -> fail
+ | B.CppDirectiveStruct directive -> fail
+ | B.IfdefStruct directive -> fail
pr2_once
"warning: long long or long double not handled by ast_cocci";
fail
-
-
- | _, _ -> fail
-
+
+ | _, (B.Void|B.FloatType _|B.IntType _) -> fail
+
)
| _, (B.TypeOfExpr e, ii) -> fail
| _, (B.TypeOfType e, ii) -> fail
-
- | _, _ -> fail
+
+ | _, (B.ParenType e, ii) -> fail (* todo ?*)
+ | _, (B.EnumName _, _) -> fail (* todo cocci ?*)
+ | _, (B.Enum _, _) -> fail (* todo cocci ?*)
+
+ | _,
+ ((B.TypeName (_, _)|B.StructUnionName (_, _)|
+ B.StructUnion (_, _, _)|
+ B.FunctionType _|B.Array (_, _)|B.Pointer _|
+ B.BaseType _),
+ _)
+ -> fail
+
(* todo: iso on sign, if not mentioned then free. tochange?
* but that require to know if signed int because explicit
pr2_once "no longdouble in cocci";
fail
| Type_cocci.BoolType, _ -> failwith "no booltype in C"
- | _ -> fail
-
+
+
+ | _, (B.Void|B.FloatType _|B.IntType _) -> fail
)
+
+
+
| Type_cocci.Pointer a, (qub, (B.Pointer b, ii)) ->
loop (a,b)
| Type_cocci.FunctionPointer a, _ ->
(* for metavariables of type expression *^* *)
| Type_cocci.Unknown , _ -> ok
- | _ -> fail in
+ | (_,
+ (_,
+ ((
+ B.TypeOfType _|B.TypeOfExpr _|B.ParenType _|
+ B.EnumName _|B.StructUnion (_, _, _)|B.Enum (_, _)
+ ),
+ _))) -> fail
+
+ | (_,
+ (_,
+ ((
+ B.StructUnionName (_, _)|
+ B.FunctionType _|
+ B.Array (_, _)|B.Pointer _|B.TypeName _|
+ B.BaseType _
+ ),
+ _))) -> fail
+
+
+ in
loop (a,b)
and compatible_sign signa signb =
match a, b with
| Type_cocci.Struct, B.Struct -> true
| Type_cocci.Union, B.Union -> true
- | _, _ -> false
+ | _, (B.Struct | B.Union) -> false
| A.FunHeader (mckstart, allminus, fninfoa, ida, oparen, paramsa, cparen),
- F.FunHeader ((idb, (retb, (paramsb, (isvaargs, iidotsb))), stob), ii) ->
+ F.FunHeader ({B.f_name = idb;
+ f_type = (retb, (paramsb, (isvaargs, iidotsb)));
+ f_storage = stob;
+ f_attr = attrs;
+ f_body = body;
+ }, ii) ->
+ assert (null body);
(* fninfoa records the order in which the SP specified the various
information, but this isn't taken into account in the matching.
return (
A.FunHeader(mckstart,allminus,fninfoa,ida,oparen,
paramsa,cparen),
- F.FunHeader ((idb, (retb, (paramsb, (isvaargs, iidotsb))),
- stob),
+ F.FunHeader ({B.f_name = idb;
+ f_type = (retb, (paramsb, (isvaargs, iidotsb)));
+ f_storage = stob;
+ f_attr = attrs;
+ f_body = body;
+ },
iidb::ioparenb::icparenb::iifakestart::iistob)
)
))))))))
- | A.Include(incla,filea), F.Include ((fileb, ii), (h_rel_pos, inifdef)) ->
-
+ | A.Include(incla,filea),
+ F.Include {B.i_include = (fileb, ii);
+ B.i_rel_pos = h_rel_pos;
+ B.i_is_in_ifdef = inifdef;
+ B.i_content = copt;
+ } ->
+ assert (copt = None);
+
let include_requirment =
match mcodekind incla, mcodekind filea with
| A.CONTEXT (_, A.BEFORE _), _ ->
tokenf filea iifileb >>= (fun filea iifileb ->
return (
A.Include(incla, filea),
- F.Include ((fileb, [inclb;iifileb]), (h_rel_pos, inifdef))
+ F.Include {B.i_include = (fileb, [inclb;iifileb]);
+ B.i_rel_pos = h_rel_pos;
+ B.i_is_in_ifdef = inifdef;
+ B.i_content = copt;
+ }
)))
else fail
(* todo?: print a warning at least ? *)
| _, F.CaseRange _
| _, F.Asm _
- | _, F.Ifdef _
| _, F.MacroTop _
-> fail2()
+ | _, (F.IfdefEndif _|F.IfdefElse _|F.IfdefHeader _)
+ -> fail2 ()
+
+ | _,
+ (F.MacroStmt (_, _)| F.DefineDoWhileZeroHeader _| F.EndNode|F.TopNode)
+ -> fail
+ | _,
+ (F.Label (_, _)|F.Break (_, _)|F.Continue (_, _)|F.Default (_, _)|
+ F.Case (_, _)|F.Include _|F.Goto _|F.ExprStatement _|
+ F.DefineType _|F.DefineExpr _|F.DefineTodo|
+ F.DefineHeader (_, _)|F.ReturnExpr (_, _)|F.Return (_, _)|F.MacroIterHeader (_, _)|
+ F.SwitchHeader (_, _)|F.ForHeader (_, _)|F.DoWhileTail _|F.DoHeader (_, _)|
+ F.WhileHeader (_, _)|F.Else _|F.IfHeader (_, _)|
+ F.SeqEnd (_, _)|F.SeqStart (_, _, _)|
+ F.Decl _|F.FunHeader _)
+ -> fail
+
- | _, _ -> fail
)
end
matcher
val distrf_struct_fields :
- (Ast_cocci.meta_name Ast_cocci.mcode, Ast_c.field Ast_c.wrap list)
+ (Ast_cocci.meta_name Ast_cocci.mcode, Ast_c.field list)
matcher
val distrf_cst :
Ast_cocci.inherited ->
Ast_cocci.meta_name Ast_cocci.mcode * Ast_c.metavar_binding_kind *
(* pos info, if needed *)
- (unit -> Common.filename * Ast_c.posl * Ast_c.posl) ->
+ (unit -> Common.filename * string * Ast_c.posl * Ast_c.posl) ->
(unit -> tin -> 'x tout) -> (tin -> 'x tout)
val check_constraints :
(* Debugging functions *)
(*****************************************************************************)
let show_or_not_predicate pred =
- if !Flag_engine.debug_engine then begin
+ if !Flag_matcher.debug_engine then begin
indent_do (fun () ->
adjust_pp_with_indent_and_header "labeling: pred = " (fun () ->
Pretty_print_engine.pp_predicate pred;
end
let show_or_not_nodes nodes =
- if !Flag_engine.debug_engine then begin
+ if !Flag_matcher.debug_engine then begin
indent_do (fun () ->
adjust_pp_with_indent_and_header "labeling: result = " (fun () ->
Common.pp_do_in_box (fun () ->
| Lib_engine.Match (re), _unwrapnode ->
let substs =
- Pattern3.match_re_node dropped_isos re node binding
+ Pattern_c.match_re_node dropped_isos re node binding
+> List.map (fun (re', subst) ->
Lib_engine.Match (re'), subst
)
module CFG =
struct
- type node = int
+ type node = Ograph_extended.nodei
type cfg = (F.node, F.edge) Ograph_extended.ograph_mutable
let predecessors cfg n = List.map fst ((cfg#predecessors n)#tolist)
let successors cfg n = List.map fst ((cfg#successors n)#tolist)
Control_flow_c.extract_is_loop (cfg#nodes#find n)
let print_node i = Format.print_string (i_to_s i)
let size cfg = cfg#nodes#length
+
+ (* In ctl_engine, we use 'node' for the node but in the Ograph_extended
+ * terminology, this 'node' is in fact an index to access the real
+ * node information (that ctl/ wants to abstract away to be more generic),
+ * the 'Ograph_extended.nodei'.
+ *)
+ let print_graph cfg label border_colors fill_colors filename =
+ Ograph_extended.print_ograph_mutable_generic cfg label
+ (fun (nodei, (node: F.node)) ->
+ (* the string julia wants to put ? *)
+ let bc = try Some(List.assoc nodei border_colors) with _ -> None in
+ let fc = try Some(List.assoc nodei fill_colors) with _ -> None in
+ (* the string yoann put as debug information in the cfg *)
+ let str = snd node in
+ (str,bc,fc)
+ )
+ ~output_file:filename
+ ~launch_gv:false
end
WRAPPED_ENGINE.satbis (flow, label, states) ctl (used_after, binding2)
in
if not (!Flag_parsing_cocci.sgrep_mode || !Flag.sgrep_mode2 ||
- !Flag_engine.allow_inconsistent_paths)
+ !Flag_matcher.allow_inconsistent_paths)
then Check_reachability.check_reachability triples flow;
let (trans_info2,used_after_fresh_envs) =
Postprocess_transinfo.process used_after binding2 trans_info2 in
-(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-*
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-*
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
-*
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
-
-let debug_engine = ref false
-
-(* false = simpler formulas, only for debugging *)
-let useEU = ref true
-
-let disallow_nested_exps = ref false
-
-(* if this flag is not set, then break and continue are also error exits *)
-let only_return_is_error_exit = ref false
-
-(* a hack to allow adding code in some more sgrep-like uses *)
-let allow_inconsistent_paths = ref false
+let debug_engine = ref false
+
+(* false = simpler formulas, only for debugging *)
+let useEU = ref true
+
+let disallow_nested_exps = ref false
+
+(* if this flag is not set, then break and continue are also error exits *)
+let only_return_is_error_exit = ref false
+
+(* a hack to allow adding code in some more sgrep-like uses *)
+let allow_inconsistent_paths = ref false
--- /dev/null
+let debug_engine = ref false
+
+(* false = simpler formulas, only for debugging *)
+let useEU = ref true
+
+let disallow_nested_exps = ref false
+
+(* if this flag is not set, then break and continue are also error exits *)
+let only_return_is_error_exit = ref false
+
+(* a hack to allow adding code in some more sgrep-like uses *)
+let allow_inconsistent_paths = ref false
+
+let show_misc = ref true
| BindBad of Ast_cocci.meta_name
| FakeBrace
+(* coccionly: *)
type ctlcocci = (predicate, Ast_cocci.meta_name) Wrapper_ctl.wrapped_ctl
(*****************************************************************************)
(* the CTL model related types *)
(*****************************************************************************)
+(* coccionly: *)
type label_ctlcocci =
predicate ->
(nodei *
-(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-*
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-*
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
-*
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
-
+(* Copyright (C) 2006, 2007 Yoann Padioleau
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License (GPL)
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * file license.txt for more details.
+ *
+ * This file was part of Coccinelle.
+ *)
open Common
+module Flag_engine = Flag_matcher
(*****************************************************************************)
(* The functor argument *)
(*****************************************************************************)
else fail tin
- let mode = Cocci_vs_c_3.PatternMode
+ let mode = Cocci_vs_c.PatternMode
(* ------------------------------------------------------------------------*)
(* Exp *)
inherited variables *)
(match Common.optionise (fun () -> tin.binding0 +> List.assoc c) with
Some valu' ->
- if Cocci_vs_c_3.equal_metavarval exp valu'
+ if Cocci_vs_c.equal_metavarval exp valu'
then success else failure
| None ->
(* if the variable is not there, it puts no constraints *)
then
match Common.optionise (fun () -> tin.binding0 +> List.assoc k) with
| Some (valu') ->
- if Cocci_vs_c_3.equal_metavarval valu valu'
+ if Cocci_vs_c.equal_metavarval valu valu'
then Some tin.binding
else None
| None -> None
else
match Common.optionise (fun () -> tin.binding +> List.assoc k) with
| Some (valu') ->
- if Cocci_vs_c_3.equal_metavarval valu valu'
+ if Cocci_vs_c.equal_metavarval valu valu'
then Some tin.binding
else None
(match Ast_cocci.get_pos_var k with
Ast_cocci.MetaPos(name,constraints,per,keep,inherited) ->
let pvalu =
- let (file,min,max) = get_max_min() in
- Ast_c.MetaPosValList[(file,min,max)] in
+ let (file,current_element,min,max) = get_max_min() in
+ Ast_c.MetaPosValList[(file,current_element,min,max)] in
(* check constraints. success means that there is a match with
one of the constraints, which will ultimately result in
failure. *)
(*****************************************************************************)
(* Entry point *)
(*****************************************************************************)
-module MATCH = Cocci_vs_c_3.COCCI_VS_C (XMATCH)
+module MATCH = Cocci_vs_c.COCCI_VS_C (XMATCH)
let match_re_node2 dropped_isos a b binding0 =
let read_fresh_id () =
try
let s = read_line () in
- match Parse_c.tokens_string s with
+ match Parse_c.tokens_of_string s with
[Parser_c.TIdent _; Parser_c.EOF _] -> s
| _ -> failwith ("wrong fresh id: " ^ s)
with End_of_file -> get_extra()
pp (Common.sprintf ("poss[%s]")
(String.concat ", "
(List.map
- (function (fl,(minl,minc),(maxl,maxc)) ->
- Printf.sprintf "(%s,(%d,%d),(%d,%d))"
- fl minl minc maxl maxc)
+ (function (fl,ce,(minl,minc),(maxl,maxc)) ->
+ Printf.sprintf "(%s,%s,(%d,%d),(%d,%d))"
+ fl ce minl minc maxl maxc)
l)))
and pp_binding subst =
-(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-*
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-*
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
-*
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
-
+(* Copyright (C) 2006, 2007 Yoann Padioleau
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License (GPL)
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * file license.txt for more details.
+ *
+ * This file was part of Coccinelle.
+ *)
open Common
module F = Control_flow_c
+module Flag = Flag_matcher
(*****************************************************************************)
(* The functor argument *)
(*****************************************************************************)
let value_format_flag f = fun tin ->
f (tin.extra.value_format_iso) tin
- let mode = Cocci_vs_c_3.TransformMode
+ let mode = Cocci_vs_c.TransformMode
(* ------------------------------------------------------------------------*)
(* Exp *)
let (oldmcode, oldenv) = !cocciinforef in
let mck =
+ (* coccionly:
if !Flag_parsing_cocci.sgrep_mode
then Sgrep.process_sgrep ib mck
- else mck
+ else
+ *)
+ mck
in
(match mck, Ast_c.pinfo_of_info ib with
| _, Ast_c.AbstractLineTok _ -> raise Impossible
ib
end
else
+ (* coccionly:
if !Flag.sgrep_mode2
then ib (* safe *)
else
- begin
+ *)
+ begin
+ (* coccionly:
Format.set_formatter_out_channel stderr;
Common.pr2 "SP mcode ";
Pretty_print_cocci.print_mcodekind oldmcode;
Pretty_print_cocci.print_mcodekind mck;
Format.print_newline();
Format.print_flush();
+ *)
failwith
(Common.sprintf "%s: already tagged token:\n%s"
tin.extra.current_rule_name
*)
(*f () tin*)
- if Cocci_vs_c_3.equal_metavarval value value'
+ if Cocci_vs_c.equal_metavarval value value'
then f () tin
else fail tin
(*****************************************************************************)
(* Entry point *)
(*****************************************************************************)
-module TRANS = Cocci_vs_c_3.COCCI_VS_C (XTRANS)
+module TRANS = Cocci_vs_c.COCCI_VS_C (XTRANS)
let transform_re_node a b tin =
-c_info.cmi: ../commons/ograph_extended.cmi ../commons/common.cmi \
- ../parsing_c/ast_c.cmo
classic_patch.cmi: ../commons/common.cmi
kbuild.cmi: ../commons/common.cmi
maintainers.cmi: ../commons/common.cmi
-c_info.cmo: ../parsing_c/visitor_c.cmi ../commons/ograph_extended.cmi \
- ../globals/flag.cmo ../commons/common.cmi ../parsing_c/ast_c.cmo \
- c_info.cmi
-c_info.cmx: ../parsing_c/visitor_c.cmx ../commons/ograph_extended.cmx \
- ../globals/flag.cmx ../commons/common.cmx ../parsing_c/ast_c.cmx \
- c_info.cmi
classic_patch.cmo: ../commons/common.cmi classic_patch.cmi
classic_patch.cmx: ../commons/common.cmx classic_patch.cmi
kbuild.cmo: ../commons/common.cmi kbuild.cmi
let popl = ref false
+let ifdef_to_if = ref false
+
let all_includes = ref false
let include_path = ref "include"
(* if true then when have a #include "../../xx.h", we look also for xx.h in
--- /dev/null
+let version = "0.1.1"
+
+let path =
+ try (Sys.getenv "COCCINELLE_HOME")
+ with Not_found->"/usr/local/share/coccinelle"
+
+let std_iso = ref (Filename.concat path "standard.iso")
+let std_h = ref (Filename.concat path "standard.h")
-let version = "0.1.1"
+let version = "0.1.2"
let path =
try (Sys.getenv "COCCINELLE_HOME")
let patch = ref (None : string option)
let make_hrule = ref (None : string (*dir*) option)
+
+let currentfile = ref (None : string option)
+
+let current_element = ref ""
+
the SmPL parser pre-generated)
- Python and its development files (python-dev)
(unless you run configure with the --without-python option)
-
+ - pdftk and graphviz (with PDF support) if you want to use
+ the -graphical_trace option
Then simply type
./configure
Flag_parsing_cocci.show_iso_failures;
Flag_ctl.verbose_ctl_engine;
Flag_ctl.verbose_match;
- Flag_engine.debug_engine;
+ Flag_matcher.debug_engine;
Flag_parsing_c.debug_unparsing;
Flag_parsing_c.verbose_type;
Flag_parsing_c.verbose_parsing;
Flag_parsing_cocci.show_iso_failures;
Flag_ctl.verbose_ctl_engine;
Flag_ctl.verbose_match;
- Flag_engine.debug_engine;
+ Flag_matcher.debug_engine;
Flag_parsing_c.debug_unparsing;
Flag_parsing_c.verbose_type;
Flag_parsing_c.verbose_parsing;
" guess what";
"-date", Arg.Unit (fun () ->
- pr2 "version: $Date: 2008/10/11 16:22:38 $";
+ pr2 "version: $Date: 2008/11/18 20:37:55 $";
raise (Common.UnixExit 0)
),
" guess what";
"",
[
"-verbose_ctl_engine", Arg.Set Flag_ctl.verbose_ctl_engine, " ";
- "-verbose_match", Arg.Set Flag_ctl.verbose_match, " ";
- "-verbose_engine", Arg.Set Flag_engine.debug_engine, " ";
+ "-verbose_match", Arg.Set Flag_ctl.verbose_match, " ";
+ "-verbose_engine", Arg.Set Flag_matcher.debug_engine, " ";
+ "-graphical_trace", Arg.Set Flag_ctl.graphical_trace, " generate a pdf file representing the matching process";
+ "-gt_without_label", Arg.Set Flag_ctl.gt_without_label, " remove graph label (requires option -graphical_trace)";
"-no_parse_error_msg", Arg.Clear Flag_parsing_c.verbose_parsing, " ";
"-no_type_error_msg", Arg.Clear Flag_parsing_c.verbose_type, " ";
"-filter_msg", Arg.Set Flag_parsing_c.filter_msg ,
" filter some cpp message when the macro is a \"known\" cpp construct";
"-filter_define_error",Arg.Set Flag_parsing_c.filter_define_error," ";
- "-filter_classic_passed",Arg.Set Flag_parsing_c.filter_classic_passed," ";
+ "-filter_passed_level", Arg.Set_int Flag_parsing_c.filter_passed_level," ";
"-debug_cfg", Arg.Set Flag_parsing_c.debug_cfg , " ";
"-debug_unparsing", Arg.Set Flag_parsing_c.debug_unparsing, " ";
"-loop", Arg.Set Flag_ctl.loop_in_src_code, " ";
"-l1", Arg.Clear Flag_parsing_c.label_strategy_2, " ";
- "-ifdef", Arg.Set Flag_parsing_c.ifdef_to_if,
- " convert ifdef to if (buggy!)";
+ "-ifdef_to_if", Arg.Set Flag_cocci.ifdef_to_if,
+ " convert ifdef to if (experimental)";
+
"-noif0_passing", Arg.Clear Flag_parsing_c.if0_passing,
" ";
"-noadd_typedef_root", Arg.Clear Flag_parsing_c.add_typedef_root, " ";
(* could use Flag_parsing_c.options_algo instead *)
- "-disallow_nested_exps", Arg.Set Flag_engine.disallow_nested_exps,
+ "-disallow_nested_exps", Arg.Set Flag_matcher.disallow_nested_exps,
"disallow an expresion pattern from matching a term and its subterm";
"-disable_worth_trying_opt", Arg.Clear Flag_cocci.worth_trying_opt,
" ";
"-only_return_is_error_exit",
- Arg.Set Flag_engine.only_return_is_error_exit,
+ Arg.Set Flag_matcher.only_return_is_error_exit,
"if this flag is not set, then break and continue are also error exits";
(* the following is a hack to make it easier to add code in sgrep-like
code, essentially to compensate for the fact that we don't have
any way of printing things out *)
"-allow_inconsistent_paths",
- Arg.Set Flag_engine.allow_inconsistent_paths,
+ Arg.Set Flag_matcher.allow_inconsistent_paths,
"if this flag is set don't check for inconsistent paths; dangerous";
];
then k()
else
let newin =
- let (dir, base, ext) = Common.dbe_of_filename cfile in
- let varfile = Common.filename_of_dbe (dir, base, "var") in
- if ext = "c" && Common.lfile_exists varfile
- then Some varfile
- else None in
+ try
+ let (dir, base, ext) = Common.dbe_of_filename cfile in
+ let varfile = Common.filename_of_dbe (dir, base, "var") in
+ if ext = "c" && Common.lfile_exists varfile
+ then Some varfile
+ else None
+ with Invalid_argument("Filename.chop_extension") -> None
+ in
Common.redirect_stdin_opt newin k
let glimpse_filter (coccifile, isofile) dir =
ast_to_flow.cmi: control_flow_c.cmi ../commons/common.cmi ast_c.cmo
compare_c.cmi: ../commons/common.cmi
control_flow_c.cmi: ../commons/ograph_extended.cmi ast_c.cmo
+cpp_ast_c.cmi: ../commons/common.cmi ast_c.cmo
lexer_parser.cmi: ../commons/common.cmi
-parse_c.cmi: parsing_hacks.cmi parser_c.cmi ../commons/common.cmi ast_c.cmo
+parse_c.cmi: parsing_stat.cmo parsing_hacks.cmi parser_c.cmi \
+ ../commons/common.cmi ast_c.cmo
parser_c.cmi: ast_c.cmo
parsing_hacks.cmi: parser_c.cmi ../commons/common.cmi
-pretty_print_c.cmi: ast_c.cmo
+pretty_print_c.cmi: control_flow_c.cmi ast_c.cmo
test_parsing_c.cmi: ../commons/common.cmi
token_helpers.cmi: parser_c.cmi ../commons/common.cmi ast_c.cmo
type_annoter_c.cmi: ../commons/common.cmi ast_c.cmo
+unparse_c.cmi: parse_c.cmi ../commons/common.cmi
unparse_c2.cmi: parse_c.cmi ../commons/common.cmi
+unparse_cocci.cmi: pretty_print_c.cmi ../parsing_cocci/ast_cocci.cmi \
+ ast_c.cmo
unparse_cocci2.cmi: pretty_print_c.cmi ../parsing_cocci/ast_cocci.cmi \
ast_c.cmo
unparse_hrule.cmi: parse_c.cmi ../commons/common.cmi
../commons/common.cmi ast_c.cmo control_flow_c.cmi
control_flow_c.cmx: ../commons/ograph_extended.cmx flag_parsing_c.cmx \
../commons/common.cmx ast_c.cmx control_flow_c.cmi
+cpp_ast_c.cmo: visitor_c.cmi parse_c.cmi flag_parsing_c.cmo \
+ ../commons/common.cmi ast_c.cmo cpp_ast_c.cmi
+cpp_ast_c.cmx: visitor_c.cmx parse_c.cmx flag_parsing_c.cmx \
+ ../commons/common.cmx ast_c.cmx cpp_ast_c.cmi
flag_parsing_c.cmo: ../commons/common.cmi
flag_parsing_c.cmx: ../commons/common.cmx
lexer_c.cmo: parser_c.cmi flag_parsing_c.cmo ../commons/common.cmi ast_c.cmo
../parsing_cocci/ast_cocci.cmi ast_c.cmo
lib_parsing_c.cmx: visitor_c.cmx ../commons/common.cmx \
../parsing_cocci/ast_cocci.cmx ast_c.cmx
-parse_c.cmo: visitor_c.cmi token_helpers.cmi semantic_c.cmo parsing_hacks.cmi \
- parser_c.cmi lexer_parser.cmi lexer_c.cmo flag_parsing_c.cmo \
- ../globals/config.cmo ../commons/common.cmi ast_c.cmo parse_c.cmi
-parse_c.cmx: visitor_c.cmx token_helpers.cmx semantic_c.cmx parsing_hacks.cmx \
- parser_c.cmx lexer_parser.cmx lexer_c.cmx flag_parsing_c.cmx \
- ../globals/config.cmx ../commons/common.cmx ast_c.cmx parse_c.cmi
-parser_c.cmo: semantic_c.cmo lexer_parser.cmi flag_parsing_c.cmo \
- ../commons/common.cmi ast_c.cmo parser_c.cmi
-parser_c.cmx: semantic_c.cmx lexer_parser.cmx flag_parsing_c.cmx \
- ../commons/common.cmx ast_c.cmx parser_c.cmi
-parsing_hacks.cmo: token_helpers.cmi parser_c.cmi lexer_parser.cmi \
- flag_parsing_c.cmo ../commons/common.cmi ast_c.cmo parsing_hacks.cmi
-parsing_hacks.cmx: token_helpers.cmx parser_c.cmx lexer_parser.cmx \
- flag_parsing_c.cmx ../commons/common.cmx ast_c.cmx parsing_hacks.cmi
-pretty_print_c.cmo: flag_parsing_c.cmo ../commons/common.cmi ast_c.cmo \
- pretty_print_c.cmi
-pretty_print_c.cmx: flag_parsing_c.cmx ../commons/common.cmx ast_c.cmx \
- pretty_print_c.cmi
+parse_c.cmo: visitor_c.cmi token_helpers.cmi semantic_c.cmo parsing_stat.cmo \
+ parsing_hacks.cmi parser_c.cmi lexer_parser.cmi lexer_c.cmo \
+ flag_parsing_c.cmo ../commons/common.cmi ast_c.cmo parse_c.cmi
+parse_c.cmx: visitor_c.cmx token_helpers.cmx semantic_c.cmx parsing_stat.cmx \
+ parsing_hacks.cmx parser_c.cmx lexer_parser.cmx lexer_c.cmx \
+ flag_parsing_c.cmx ../commons/common.cmx ast_c.cmx parse_c.cmi
+parser_c.cmo: semantic_c.cmo parsing_stat.cmo lexer_parser.cmi \
+ flag_parsing_c.cmo ../commons/common.cmi ast_c.cmo parser_c.cmi
+parser_c.cmx: semantic_c.cmx parsing_stat.cmx lexer_parser.cmx \
+ flag_parsing_c.cmx ../commons/common.cmx ast_c.cmx parser_c.cmi
+parsing_hacks.cmo: token_helpers.cmi parsing_stat.cmo parser_c.cmi \
+ lexer_parser.cmi flag_parsing_c.cmo ../commons/common.cmi ast_c.cmo \
+ parsing_hacks.cmi
+parsing_hacks.cmx: token_helpers.cmx parsing_stat.cmx parser_c.cmx \
+ lexer_parser.cmx flag_parsing_c.cmx ../commons/common.cmx ast_c.cmx \
+ parsing_hacks.cmi
+parsing_stat.cmo: ../commons/common.cmi
+parsing_stat.cmx: ../commons/common.cmx
+pretty_print_c.cmo: flag_parsing_c.cmo control_flow_c.cmi \
+ ../commons/common.cmi ast_c.cmo pretty_print_c.cmi
+pretty_print_c.cmx: flag_parsing_c.cmx control_flow_c.cmx \
+ ../commons/common.cmx ast_c.cmx pretty_print_c.cmi
semantic_c.cmo: ../commons/common.cmi
semantic_c.cmx: ../commons/common.cmx
-test_parsing_c.cmo: unparse_c2.cmi type_annoter_c.cmi parse_c.cmi \
- ../commons/ograph_extended.cmi flag_parsing_c.cmo compare_c.cmi \
- ../commons/common.cmi ast_to_flow.cmi ast_c.cmo test_parsing_c.cmi
-test_parsing_c.cmx: unparse_c2.cmx type_annoter_c.cmx parse_c.cmx \
- ../commons/ograph_extended.cmx flag_parsing_c.cmx compare_c.cmx \
- ../commons/common.cmx ast_to_flow.cmx ast_c.cmx test_parsing_c.cmi
+test_parsing_c.cmo: unparse_c.cmi type_annoter_c.cmi parsing_stat.cmo \
+ parse_c.cmi ../commons/ograph_extended.cmi flag_parsing_c.cmo \
+ compare_c.cmi ../commons/common.cmi ast_to_flow.cmi ast_c.cmo \
+ test_parsing_c.cmi
+test_parsing_c.cmx: unparse_c.cmx type_annoter_c.cmx parsing_stat.cmx \
+ parse_c.cmx ../commons/ograph_extended.cmx flag_parsing_c.cmx \
+ compare_c.cmx ../commons/common.cmx ast_to_flow.cmx ast_c.cmx \
+ test_parsing_c.cmi
token_helpers.cmo: parser_c.cmi ../commons/common.cmi ast_c.cmo \
token_helpers.cmi
token_helpers.cmx: parser_c.cmx ../commons/common.cmx ast_c.cmx \
flag_parsing_c.cmo ../commons/common.cmi ast_c.cmo type_annoter_c.cmi
type_annoter_c.cmx: visitor_c.cmx parse_c.cmx lib_parsing_c.cmx \
flag_parsing_c.cmx ../commons/common.cmx ast_c.cmx type_annoter_c.cmi
+unparse_c.cmo: visitor_c.cmi unparse_cocci.cmi token_helpers.cmi \
+ pretty_print_c.cmi parser_c.cmi flag_parsing_c.cmo ../commons/common.cmi \
+ ../parsing_cocci/ast_cocci.cmi ast_c.cmo unparse_c.cmi
+unparse_c.cmx: visitor_c.cmx unparse_cocci.cmx token_helpers.cmx \
+ pretty_print_c.cmx parser_c.cmx flag_parsing_c.cmx ../commons/common.cmx \
+ ../parsing_cocci/ast_cocci.cmx ast_c.cmx unparse_c.cmi
unparse_c2.cmo: visitor_c.cmi unparse_cocci2.cmi token_helpers.cmi \
pretty_print_c.cmi parser_c.cmi flag_parsing_c.cmo ../commons/common.cmi \
../parsing_cocci/ast_cocci.cmi ast_c.cmo unparse_c2.cmi
unparse_c2.cmx: visitor_c.cmx unparse_cocci2.cmx token_helpers.cmx \
pretty_print_c.cmx parser_c.cmx flag_parsing_c.cmx ../commons/common.cmx \
../parsing_cocci/ast_cocci.cmx ast_c.cmx unparse_c2.cmi
+unparse_cocci.cmo: pretty_print_c.cmi ../commons/common.cmi \
+ ../parsing_cocci/ast_cocci.cmi ast_c.cmo unparse_cocci.cmi
+unparse_cocci.cmx: pretty_print_c.cmx ../commons/common.cmx \
+ ../parsing_cocci/ast_cocci.cmx ast_c.cmx unparse_cocci.cmi
unparse_cocci2.cmo: pretty_print_c.cmi ../commons/common.cmi \
../parsing_cocci/ast_cocci.cmi ast_c.cmo unparse_cocci2.cmi
unparse_cocci2.cmx: pretty_print_c.cmx ../commons/common.cmx \
../parsing_cocci/ast_cocci.cmx ast_c.cmx unparse_cocci2.cmi
-unparse_hrule.cmo: unparse_c2.cmi token_helpers.cmi pretty_print_c.cmi \
+unparse_hrule.cmo: unparse_c.cmi token_helpers.cmi pretty_print_c.cmi \
parser_c.cmi ../commons/common.cmi ../parsing_cocci/ast_cocci.cmi \
ast_c.cmo unparse_hrule.cmi
-unparse_hrule.cmx: unparse_c2.cmx token_helpers.cmx pretty_print_c.cmx \
+unparse_hrule.cmx: unparse_c.cmx token_helpers.cmx pretty_print_c.cmx \
parser_c.cmx ../commons/common.cmx ../parsing_cocci/ast_cocci.cmx \
ast_c.cmx unparse_hrule.cmi
visitor_c.cmo: control_flow_c.cmi ../commons/common.cmi ast_c.cmo \
##############################################################################
TARGET=parsing_c
-SRC= \
- flag_parsing_c.ml ast_c.ml control_flow_c.ml semantic_c.ml \
+
+# - type_cocci.ml ast_cocci.ml # + unparse_hrule
+SRC= flag_parsing_c.ml parsing_stat.ml \
+ ast_c.ml control_flow_c.ml \
visitor_c.ml lib_parsing_c.ml \
ast_to_flow.ml \
- lexer_parser.ml parser_c.ml lexer_c.ml \
- token_helpers.ml parsing_hacks.ml parse_c.ml \
- compare_c.ml type_annoter_c.ml pretty_print_c.ml \
- unparse_cocci2.ml unparse_c2.ml unparse_hrule.ml \
+ pretty_print_c.ml \
+ semantic_c.ml lexer_parser.ml parser_c.ml lexer_c.ml \
+ token_helpers.ml parsing_hacks.ml \
+ unparse_cocci.ml unparse_c.ml unparse_hrule.ml \
+ parse_c.ml \
+ cpp_ast_c.ml \
+ compare_c.ml type_annoter_c.ml \
test_parsing_c.ml
-SYSLIBS= str.cma unix.cma
-# parsing_c now depends on cocci_parser because in addition to decorate the
-# token in Ast_c with some parse info, we now also make some place to
+# ast_cocci.ml and unparse_cocci.ml should be deleted in the futur
+# to make parsing_c really independent of coccinelle.
+# control_flow_c have also coccinelle dependencies.
+# old: parsing_c now depends on cocci_parser because in addition to decorate
+# the token in Ast_c with some parse info, we now also make some place to
# welcome some mcodekind of Ast_cocci.
LIBS=../commons/commons.cma ../globals/globals.cma \
../parsing_cocci/cocci_parser.cma
-INCLUDES= -I ../commons -I ../commons/ocamlextra \
- -I ../globals -I ../parsing_cocci
+INCLUDES= -I ../commons -I ../globals -I ../parsing_cocci
+#LIBS=../commons/commons.cma
+#INCLUDES= -I ../commons
+SYSLIBS= str.cma unix.cma
##############################################################################
# Generic variables
beforedepend:: parser_c.ml parser_c.mli
+##############################################################################
+# Pad's rules
+##############################################################################
+# visitor_c.ml lib_parsing_c.ml \
+# type_annoter_c.ml \
+# statistics_c.ml \
+# pretty_print_c.ml unparse_c.ml \
+# test_parsing_c.ml
+#toreput: compare_c.ml ast_to_flow.ml
+
+COREPARSING= flag_parsing_c.ml parsing_stat.ml \
+ ast_cocci.ml \
+ ast_c.ml control_flow_c.ml \
+ semantic_c.ml lexer_parser.ml parser_c.mly lexer_c.mll \
+ token_helpers.ml parsing_hacks.ml parse_c.ml \
+
+locparsing:
+ wc -l $(COREPARSING)
+
+locindiv:
+ wc -l lexer_c.mll
+ wc -l parser_c.mly
+ wc -l parsing_hacks.ml
+ wc -l ast_c.ml
+ wc -l parse_c.ml
+
+
##############################################################################
# Generic rules
##############################################################################
-(* Copyright (C) 2002-2008 Yoann Padioleau
+(* Copyright (C) 2002, 2006, 2007, 2008 Yoann Padioleau
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License (GPL)
(* The AST C related types *)
(*****************************************************************************)
-(* Cocci: Each token will be decorated in the future by the mcodekind
+(* To allow some transformations over the AST, we keep as much information
+ * as possible in the AST such as the tokens content and their locations.
+ * Those info are called 'info' (how original) and can be tagged.
+ * For instance one tag may say that the unparser should remove this token.
+ *
+ * Update: Now I use a ref! in those 'info' so take care.
+ *
+ * Sometimes we want to add someting at the beginning or at the end
+ * of a construct. For 'function' and 'decl' we want to add something
+ * to their left and for 'if' 'while' et 'for' and so on at their right.
+ * We want some kinds of "virtual placeholders" that represent the start or
+ * end of a construct. We use fakeInfo for that purpose.
+ * To identify those cases I have added a fakestart/fakeend comment.
+ *
+ * convention: I often use 'ii' for the name of a list of info.
+ *
+ * update: I now allow ifdefs in the ast but there must be only between
+ * "sequencable" elements. They can be put in a type only if this type
+ * is used only in a list, like at toplevel, used in 'toplevel list',
+ * or inside compound, used in 'statement list'. I must not allow
+ * ifdef anywhere. For instance I can not make ifdef a statement
+ * cos some instruction like If accept only one statement and the
+ * ifdef directive must not take the place of a legitimate instruction.
+ * We had a similar phenomena in SmPL where we have the notion
+ * of statement and sequencable statement too. Once you have
+ * such a type of sequencable thing, then s/xx list/xx_sequencable list/
+ * and introduce the ifdef.
+ *
+ * update: those ifdefs are either passed, or present in the AST but in
+ * a flat form. To structure those flat ifdefs you have to run
+ * a transformation that will put in a tree the statements inside
+ * ifdefs branches. Cf cpp_ast_c.ml. This is for instance the difference
+ * between a IfdefStmt (flat) and IfdefStmt2 (tree structured).
+ *
+ * Some stuff are tagged semantic: which means that they are computed
+ * after parsing.
+ *
+ * cocci: Each token will be decorated in the future by the mcodekind
* of cocci. It is the job of the pretty printer to look at this
* information and decide to print or not the token (and also the
* pending '+' associated sometimes with the token).
* because the pending '+' may contain metavariables that refer to some
* C code.
*
- * Update: Now I use a ref! so take care.
- *
- * Sometimes we want to add someting at the beginning or at the end
- * of a construct. For 'function' and 'decl' we want add something
- * to their left and for 'if' 'while' et 'for' and so on at their right.
- * We want some kinds of "virtual placeholders" that represent the start or
- * end of a construct. We use fakeInfo for that purpose.
- * To identify those cases I have added a fakestart/fakeend comment.
- *
- * convention: I often use 'ii' for the name of a list of info.
*
+ * All of this means that some elements in this AST are present only if
+ * some annotation/transformation has been done on the original AST returned
+ * by the parser. Cf type_annotater, comment_annotater, cpp_ast_c, etc.
*)
(* forunparser: *)
type posl = int * int (* lin-col, for MetaPosValList, for position variables *)
+
+(* the virtual position is set in Parsing_hacks.insert_virtual_positions *)
type virtual_position = Common.parse_info * int (* character offset *)
+
type parse_info =
(* Present both in ast and list of tokens *)
| OriginTok of Common.parse_info
type info = {
pinfo : parse_info;
+ (* this tag can be changed, which is how we can express some progra
+ * transformations by tagging the tokens involved in this transformation.
+ *)
cocci_tag: (Ast_cocci.mcodekind * metavars_binding) ref;
- comments_tag: comments_around ref; (* set in comment_annotater.ml *)
+ (* set in comment_annotater.ml *)
+ comments_tag: comments_around ref;
(* todo? token_info : sometimes useful to know what token it was *)
}
and il = info list
* Constructor.
*
* Some stuff are tagged semantic: which means that they are computed
- * after parsing. *)
+ * after parsing.
+*)
and fullType = typeQualifier * typeC
| ParenType of fullType (* forunparser: *)
- (* gccext: TypeOfType may seems useless, why declare a __typeof__(int)
- * x; ? But when used with macro, it allows to fix a problem of C which
+ (* gccext: TypeOfType may seems useless; why declare a
+ * __typeof__(int) x; ?
+ * But when used with macro, it allows to fix a problem of C which
* is that type declaration can be spread around the ident. Indeed it
- * may be difficult to have a macro such as '#define macro(type,
- * ident) type ident;' because when you want to do a macro(char[256],
- * x), then it will generate invalid code, but with a '#define
- * macro(type, ident) __typeof(type) ident;' it will work. *)
+ * may be difficult to have a macro such as
+ * '#define macro(type, ident) type ident;'
+ * because when you want to do a
+ * macro(char[256], x),
+ * then it will generate invalid code, but with a
+ * '#define macro(type, ident) __typeof(type) ident;'
+ * it will work. *)
| TypeOfExpr of expression
| TypeOfType of fullType
+
+ (* cppext: IfdefType TODO *)
(* -------------------------------------- *)
and baseType = Void
(* -------------------------------------- *)
and structUnion = Struct | Union
- and structType = (field wrap) list (* ; *)
+ and structType = field list
+ and field = fieldbis wrap
+ and fieldbis =
+ | DeclarationField of field_declaration
+ | EmptyField (* gccext: *)
+ (* cppext: *)
+ | MacroStructDeclTodo
+
+ (* cppext: *)
+ | CppDirectiveStruct of cpp_directive
+ | IfdefStruct of ifdef_directive (* * field list list *)
+
(* before unparser, I didn't have a FieldDeclList but just a Field. *)
- and field = FieldDeclList of fieldkind wrap2 list (* , *)
- | EmptyField (* gccext: *)
+ and field_declaration =
+ | FieldDeclList of fieldkind wrap2 list (* , *) wrap (* ; *)
(* At first I thought that a bitfield could be only Signed/Unsigned.
* But it seems that gcc allow char i:4. C rule must say that you
and typeQualifier = typeQualifierbis wrap
and typeQualifierbis = {const: bool; volatile: bool}
+(* gccext: cppext: *)
+and attribute = attributebis wrap
+ and attributebis =
+ | Attribute of string
(* ------------------------------------------------------------------------- *)
(* C expression *)
(* ------------------------------------------------------------------------- *)
and expression = (expressionbis * exp_info ref (* semantic: *)) wrap
-and local = LocalVar of parse_info | NotLocalVar
-and test = Test | NotTest
-and exp_type = fullType * local
-and exp_info = exp_type option * test
-and expressionbis =
+ and exp_info = exp_type option * test
+ and exp_type = fullType * local
+ and local = LocalVar of parse_info | NotLocalVar (* cocci: *)
+ and test = Test | NotTest (* cocci: *)
+
+ and expressionbis =
(* Ident can be a enumeration constant, a simple variable, a name of a func.
* With cppext, Ident can also be the name of a macro. Sparse says
(* forunparser: *)
| ParenExpr of expression
+ (* cppext: IfdefExpr TODO *)
+
(* cppext: normmally just expression *)
and argument = (expression, wierd_argument) either
and wierd_argument =
| ArgType of parameterType
| ArgAction of action_macro
and action_macro =
+ (* todo: ArgStatement of statement, possibly have ghost token *)
| ActMisc of il
and constant =
| String of (string * isWchar)
- | MultiString (* can contain MacroString *)
+ | MultiString (* can contain MacroString, todo: more info *)
| Char of (string * isWchar) (* normally it is equivalent to Int *)
| Int of (string (* * intType*))
| Float of (string * floatType)
and isWchar = IsWchar | IsChar
- (* gccext: GetRefLabel, via &&label notation *)
- and unaryOp = GetRef | DeRef | UnPlus | UnMinus | Tilde | Not | GetRefLabel
+
+ and unaryOp = GetRef | DeRef | UnPlus | UnMinus | Tilde | Not
+ | GetRefLabel (* gccext: GetRefLabel, via &&label notation *)
and assignOp = SimpleAssign | OpAssign of arithOp
and fixOp = Dec | Inc
and constExpression = expression (* => int *)
+
(* ------------------------------------------------------------------------- *)
(* C statement *)
(* ------------------------------------------------------------------------- *)
* old: compound = (declaration list * statement list)
* old: (declaration, statement) either list
* Simplify cocci to just have statement list, by integrating Decl in stmt.
+ *
+ * update: now introduce also the _sequencable to allow ifdef in the middle.
*)
- and compound = statement list
+ and compound = statement_sequencable list
+
+ (* cppext: easier to put at statement_list level than statement level *)
+ and statement_sequencable =
+ | StmtElem of statement
+ (* cppext: *)
+ | CppDirectiveStmt of cpp_directive
+ | IfdefStmt of ifdef_directive
+
+ (* this will be build in cpp_ast_c from the previous flat IfdefStmt *)
+ | IfdefStmt2 of ifdef_directive list * (statement_sequencable list) list
and exprStatement = expression option
and selection =
| If of expression * statement * statement
| Switch of expression * statement
- | Ifdef of statement list * statement list (* cppext: *)
+
and iteration =
| While of expression * statement
| DoWhile of statement * expression
| For of exprStatement wrap * exprStatement wrap * exprStatement wrap *
statement
+ (* cppext: *)
| MacroIteration of string * argument wrap2 list * statement
and jump = Goto of string
*
* Before I had Typedef constructor, but why make this special case and not
* have StructDef, EnumDef, ... so that 'struct t {...} v' will generate 2
- * declarations ? So I try to generalise and not have not Typedef too. This
+ * declarations ? So I try to generalise and not have Typedef either. This
* requires more work in parsing. Better to separate concern.
*
* Before the need for unparser, I didn't have a DeclList but just a Decl.
| MacroDecl of (string * argument wrap2 list) wrap
and onedecl =
- ((string * initialiser option) wrap (* s = *) option) *
- fullType * storage * local_decl
- and storage = storagebis * bool (* inline or not, gccext: *)
+ { v_namei: (string * initialiser option) wrap (* s = *) option;
+ v_type: fullType;
+ v_storage: storage;
+ v_local: local_decl; (* cocci: *)
+ v_attr: attribute list; (* gccext: *)
+ }
+ and storage = storagebis * bool (* gccext: inline or not *)
and storagebis = NoSto | StoTypedef | Sto of storageClass
and storageClass = Auto | Static | Register | Extern
* as 'f(void) {', there is no name too, so I simplified and reused the
* same functionType type for both declaration and function definition.
*)
-and definition = (string * functionType * storage * compound)
- wrap (* s ( ) { } fakestart sto *)
+and definition = definitionbis wrap (* s ( ) { } fakestart sto *)
+ and definitionbis =
+ { f_name: string;
+ f_type: functionType;
+ f_storage: storage;
+ f_body: compound;
+ f_attr: attribute list; (* gccext: *)
+ }
+ (* cppext: IfdefFunHeader TODO *)
(* ------------------------------------------------------------------------- *)
-(* #define and #include body *)
+(* cppext: cpp directives, #ifdef, #define and #include body *)
(* ------------------------------------------------------------------------- *)
+and cpp_directive =
+ | Include of includ
+ | Define of define
+ | Undef of string wrap
+ | PragmaAndCo of il
+
+(* to specialize if someone need more info *)
+and ifdef_directive = (* or and 'a ifdefed = 'a list wrap *)
+ | IfdefDirective of (ifdefkind * matching_tag) wrap
+ and ifdefkind =
+ | Ifdef (* todo? of string ? of formula_cpp *)
+ | IfdefElseif (* same *)
+ | IfdefElse (* same *)
+ | IfdefEndif
+ (* set in Parsing_hacks.set_ifdef_parenthize_info. It internally use
+ * a global so it means if you parse same file twice you may get
+ * different id. I try now to avoid this pb by resetting it each
+ * time I parse a file.
+ *)
+ and matching_tag =
+ IfdefTag of (int (* tag *) * int (* total with this tag *))
-(* cppext *)
and define = string wrap * define_body (* #define s *)
and define_body = define_kind * define_val
and define_kind =
| DefineVar
- | DefineFunc of ((string wrap) wrap2 list) wrap
+ | DefineFunc of ((string wrap) wrap2 list) wrap (* () *)
and define_val =
| DefineExpr of expression
| DefineStmt of statement
| DefineType of fullType
- | DefineDoWhileZero of statement wrap (* do { } while(0) *)
+ | DefineDoWhileZero of (statement * expression) wrap (* do { } while(0) *)
| DefineFunction of definition
+ | DefineInit of initialiser (* in practice only { } with possible ',' *)
+ (* TODO DefineMulti of define_val list *)
+
| DefineText of string wrap
| DefineEmpty
+ | DefineTodo
-and includ = inc_file wrap (* #include s *) *
- (include_rel_pos option ref * bool (* is in ifdef, cf -test incl *) )
+
+and includ =
+ { i_include: inc_file wrap; (* #include s *)
+ (* cocci: computed in ? *)
+ i_rel_pos: include_rel_pos option ref;
+ (* cocci: cf -test incl *)
+ i_is_in_ifdef: bool;
+ (* cf cpp_ast_c.ml. set to None at parsing time. *)
+ i_content: (Common.filename (* full path *) * program) option;
+ }
and inc_file =
| Local of inc_elem list
| NonLocal of inc_elem list
| Wierd of string (* ex: #include SYSTEM_H *)
and inc_elem = string
-(* Cocci: to tag the first of #include <xx/> and last of #include <yy/>
- *
- * The first_of and last_of store the list of prefixes that was
- * introduced by the include. On #include <a/b/x>, if the include was
- * the first in the file, it would give in first_of the following
- * prefixes a/b/c; a/b/; a/ ; <empty>
- *
- * This is set after parsing, in cocci.ml, in update_rel_pos.
- *)
+ (* cocci: to tag the first of #include <xx/> and last of #include <yy/>
+ *
+ * The first_of and last_of store the list of prefixes that was
+ * introduced by the include. On #include <a/b/x>, if the include was
+ * the first in the file, it would give in first_of the following
+ * prefixes a/b/c; a/b/; a/ ; <empty>
+ *
+ * This is set after parsing, in cocci.ml, in update_rel_pos.
+ *)
and include_rel_pos = {
- first_of : string list list;
- last_of : string list list;
+ first_of : string list list;
+ last_of : string list list;
}
+
+
+
+
+
(* ------------------------------------------------------------------------- *)
(* The toplevels elements *)
(* ------------------------------------------------------------------------- *)
| Definition of definition
(* cppext: *)
- | Include of includ
- | Define of define
+ | CppTop of cpp_directive
+ | IfdefTop of ifdef_directive (* * toplevel list *)
+
(* cppext: *)
| MacroTop of string * argument wrap2 list * il
| EmptyDef of il (* gccext: allow redundant ';' *)
| NotParsedCorrectly of il
-
| FinalDef of info (* EOF *)
(* ------------------------------------------------------------------------- *)
* variables accessible via SmPL whereas the position can be one day
* so I think it's better to put MetaPosVal here *)
| MetaPosVal of (Ast_cocci.fixpos * Ast_cocci.fixpos) (* max, min *)
- | MetaPosValList of (Common.filename * posl * posl) list (* min, max *)
+ | MetaPosValList of
+ (Common.filename * string (*element*) * posl * posl) list (* min, max *)
| MetaListlenVal of int
(* C comments *)
(*****************************************************************************)
-(* I often use m for comments as I can not use c (already use for c stuff)
- * and com is too long.
+(* convention: I often use "m" for comments as I can not use "c"
+ * (already use for c stuff) and "com" is too long.
*)
(* this type will be associated to each token *)
(*****************************************************************************)
-(* Cpp constructs, put it comments in lexer *)
+(* Cpp constructs put it comments in lexer or parsing_hack *)
(*****************************************************************************)
(* This type is not in the Ast but is associated with the TCommentCpp token.
* it also in lexer_parser.
*)
type cppcommentkind =
- CppDirective | CppAttr | CppMacro | CppOther
+ | CppDirective
+ | CppAttr
+ | CppMacro
+ | CppPassingNormal (* ifdef 0, cplusplus, etc *)
+ | CppPassingCosWouldGetError (* expr passsing *)
comments_tag = ref emptyComments;
}
+let noii = []
+let noattr = []
+let noi_content = (None: ((Common.filename * program) option))
(*****************************************************************************)
(* Wrappers *)
| FakeTok (_,_) -> failwith "no position information"
| AbstractLineTok pi -> pi
-let is_fake ii =
- match ii.pinfo with
- FakeTok (_,_) -> true
- | _ -> false
-
let str_of_info ii =
match ii.pinfo with
OriginTok pi -> pi.Common.str
let pinfo_of_info ii = ii.pinfo
let parse_info_of_info ii = get_pi ii.pinfo
+let is_fake ii =
+ match ii.pinfo with
+ FakeTok (_,_) -> true
+ | _ -> false
+
+let is_origintok ii =
+ match ii.pinfo with
+ | OriginTok pi -> true
+ | _ -> false
+
type posrv = Real of Common.parse_info | Virt of virtual_position
+
let compare_pos ii1 ii2 =
let get_pos = function
OriginTok pi -> Real pi
Ast_cocci.Virt (pi.Common.charpos,offset)
| AbstractLineTok pi -> failwith "unexpected abstract"
+(* cocci: *)
let is_test (e : expression) =
let (_,info) = unwrap e in
let (_,test) = !info in
| _, None, ii -> Right ii
| _ -> raise Impossible
+
+
+(*****************************************************************************)
+(* Helpers, could also be put in lib_parsing_c.ml instead *)
+(*****************************************************************************)
+
+let rec stmt_elems_of_sequencable xs =
+ xs +> Common.map (fun x ->
+ match x with
+ | StmtElem e -> [e]
+ | CppDirectiveStmt _
+ | IfdefStmt _
+ ->
+ pr2 ("stmt_elems_of_sequencable: filter a directive");
+ []
+ | IfdefStmt2 (_ifdef, xxs) ->
+ pr2 ("stmt_elems_of_sequencable: IfdefStm2 TODO?");
+ xxs +> List.map (fun xs ->
+ let xs' = stmt_elems_of_sequencable xs in
+ xs'
+ ) +> List.flatten
+ ) +> List.flatten
+
+
+
+
+let s_of_inc_file inc_file =
+ match inc_file with
+ | Local xs -> xs +> Common.join "/"
+ | NonLocal xs -> xs +> Common.join "/"
+ | Wierd s -> s
+
+let s_of_inc_file_bis inc_file =
+ match inc_file with
+ | Local xs -> "\"" ^ xs +> Common.join "/" ^ "\""
+ | NonLocal xs -> "<" ^ xs +> Common.join "/" ^ ">"
+ | Wierd s -> s
+
+let fieldname_of_fieldkind fieldkind =
+ match unwrap fieldkind with
+ | Simple (sopt, ft) -> sopt
+ | BitField (sopt, ft, expr) -> sopt
+
* todo?: steal code from CIL ? (but seems complicated ... again) *)
(*****************************************************************************)
+(*****************************************************************************)
+(* Types *)
+(*****************************************************************************)
+
type error =
| DeadCode of Common.parse_info option
| CaseNoSwitch of Common.parse_info
!g +> add_arc_opt (starti, newi);
let starti = Some newi in
- statxs +> List.fold_left (fun starti statement ->
- if !Flag_parsing_c.label_strategy_2
- then incr counter_for_labels;
-
- let newxi' =
- if !Flag_parsing_c.label_strategy_2
- then { newxi with labels = xi.labels @ [ !counter_for_labels ] }
- else newxi
- in
- aux_statement (starti, newxi') statement
- ) starti
+ aux_statement_list starti (xi, newxi) statxs
(* braces: *)
+> Common.fmap (fun starti ->
end)
- | Selection (Ast_c.Ifdef (st1s, st2s)), ii ->
- let (ii,iifakeend) =
- match ii with
- | [i1;i2;i3;i4] -> [i1;i2;i3], i4
- | [i1;i2;i3] -> [i1;i2], i3
- | _ -> raise Impossible
- in
-
- let newi = !g +> add_node (Ifdef (stmt, ((), ii))) lbl "ifcpp" in
- !g +> add_arc_opt (starti, newi);
- let newfakethen = !g +> add_node TrueNode lbl "[then]" in
- let newfakeelse = !g +> add_node FalseNode lbl "[else]" in
-
- !g#add_arc ((newi, newfakethen), Direct);
- !g#add_arc ((newi, newfakeelse), Direct);
-
- let aux_statement_list (starti, newxi) statxs =
- statxs +> List.fold_left (fun starti statement ->
- aux_statement (starti, newxi) statement
- ) starti
- in
-
-
- let finalthen = aux_statement_list (Some newfakethen, xi_lbl) st1s in
- let finalelse = aux_statement_list (Some newfakeelse, xi_lbl) st2s in
-
- (match finalthen, finalelse with
- | (None, None) -> None
- | _ ->
- let lasti =
- !g +> add_node (EndStatement (Some iifakeend)) lbl "[endifcpp]"
- in
- begin
- !g +> add_arc_opt (finalthen, lasti);
- !g +> add_arc_opt (finalelse, lasti);
- Some lasti
- end
- )
-
-
(* ------------------------- *)
| Selection (Ast_c.Switch (e, st)), ii ->
let (i1,i2,i3, iifakeend) = tuple_of_list4 ii in
let finalthen =
match st with
| Ast_c.Compound statxs, ii ->
+ let statxs = Ast_c.stmt_elems_of_sequencable statxs in
(* todo? we should not allow to match a stmt that corresponds
* to a compound of a switch, so really SeqStart (stmt, ...)
| Ast_c.Decl decl, ii ->
let s =
match decl with
- | (Ast_c.DeclList ([(Some ((s, _),_), typ, sto, _), _], _)) ->
+ | (Ast_c.DeclList
+ ([{v_namei = Some ((s, _),_); v_type = typ; v_storage = sto}, _], _)) ->
"decl:" ^ s
| _ -> "decl_novar_or_multivar"
in
+
+
+
+and aux_statement_list starti (xi, newxi) statxs =
+ statxs
+ +> List.fold_left (fun starti statement_seq ->
+ if !Flag_parsing_c.label_strategy_2
+ then incr counter_for_labels;
+
+ let newxi' =
+ if !Flag_parsing_c.label_strategy_2
+ then { newxi with labels = xi.labels @ [ !counter_for_labels ] }
+ else newxi
+ in
+
+ match statement_seq with
+ | Ast_c.StmtElem statement ->
+ aux_statement (starti, newxi') statement
+
+ | Ast_c.CppDirectiveStmt directive ->
+ pr2_once ("ast_to_flow: filter a directive");
+ starti
+
+ | Ast_c.IfdefStmt ifdef ->
+ pr2_once ("ast_to_flow: filter a directive");
+ starti
+
+ | Ast_c.IfdefStmt2 (ifdefs, xxs) ->
+
+ let (head, body, tail) = Common.head_middle_tail ifdefs in
+
+ let newi = !g +> add_node (IfdefHeader (head)) newxi'.labels "[ifdef]" in
+ let taili = !g +> add_node (IfdefEndif (tail)) newxi'.labels "[endif]" in
+ !g +> add_arc_opt (starti, newi);
+
+ let elsenodes =
+ body +> List.map (fun elseif ->
+ let elsei =
+ !g +> add_node (IfdefElse (elseif)) newxi'.labels "[elseif]" in
+ !g#add_arc ((newi, elsei), Direct);
+ elsei
+ ) in
+
+ let finalxs =
+ Common.zip (newi::elsenodes) xxs +> List.map (fun (start_nodei, xs)->
+ let finalthen =
+ aux_statement_list (Some start_nodei) (newxi, newxi) xs in
+ !g +> add_arc_opt (finalthen, taili);
+ )
+ in
+ Some taili
+
+ ) starti
+
+
(*****************************************************************************)
(* Definition of function *)
(*****************************************************************************)
let lbl_start = [!counter_for_labels] in
- let ((funcs, functype, sto, compound), ii) = funcdef in
+ let ({f_name = funcs;
+ f_type = functype;
+ f_storage= sto;
+ f_body= compound;
+ f_attr= attrs;
+ }, ii) = funcdef in
let iifunheader, iicompound =
(match ii with
| is::ioparen::icparen::iobrace::icbrace::iifake::isto ->
let topstatement = Ast_c.Compound compound, iicompound in
- let headi = !g +> add_node (FunHeader ((funcs, functype, sto), iifunheader))
- lbl_start ("function " ^ funcs) in
+ let headi = !g +> add_node
+ (FunHeader ({
+ Ast_c.f_name = funcs;
+ f_type = functype;
+ f_storage = sto;
+ f_attr = attrs;
+ f_body = [] (* empty body *)
+ }, iifunheader))
+ lbl_start ("function " ^ funcs) in
let enteri = !g +> add_node Enter lbl_0 "[enter]" in
let exiti = !g +> add_node Exit lbl_0 "[exit]" in
let errorexiti = !g +> add_node ErrorExit lbl_0 "[errorexit]" in
let topi = !g +> add_node TopNode lbl_0 "[top]" in
match e with
- | Ast_c.Definition (((funcs, _, _, c),_) as def) ->
+ | Ast_c.Definition ((defbis,_) as def) ->
+ let _funcs = defbis.f_name in
+ let _c = defbis.f_body in
(* if !Flag.show_misc then pr2 ("build info function " ^ funcs); *)
aux_definition topi def;
Some !g
| Ast_c.Declaration _
- | Ast_c.Include _
+ | Ast_c.CppTop (Ast_c.Include _)
| Ast_c.MacroTop _
->
let (elem, str) =
match e with
| Ast_c.Declaration decl ->
(Control_flow_c.Decl decl), "decl"
- | Ast_c.Include (a,b) ->
- (Control_flow_c.Include (a,b)), "#include"
+ | Ast_c.CppTop (Ast_c.Include inc) ->
+ (Control_flow_c.Include inc), "#include"
| Ast_c.MacroTop (s, args, ii) ->
let (st, (e, ii)) = specialdeclmacro_to_stmt (s, args, ii) in
(Control_flow_c.ExprStatement (st, (Some e, ii))), "macrotoplevel"
!g#add_arc ((ei, endi),Direct);
Some !g
- | Ast_c.Define ((id,ii), (defkind, defval)) ->
+ | Ast_c.CppTop (Ast_c.Define ((id,ii), (defkind, defval))) ->
let s = ("#define " ^ id) in
let headeri = !g+>add_node (DefineHeader ((id, ii), defkind)) lbl_0 s in
!g#add_arc ((topi, headeri),Direct);
)
- | Ast_c.DefineDoWhileZero (st, ii) ->
+ | Ast_c.DefineDoWhileZero ((st,_e), ii) ->
let headerdoi =
!g +> add_node (DefineDoWhileZeroHeader ((),ii)) lbl_0 "do0" in
!g#add_arc ((headeri, headerdoi), Direct);
| Ast_c.DefineEmpty ->
let endi = !g +> add_node EndNode lbl_0 "[end]" in
!g#add_arc ((headeri, endi),Direct);
+ | Ast_c.DefineInit _ ->
+ raise Todo
+ | Ast_c.DefineTodo ->
+ raise Todo
);
Some !g
);
Visitor_c.ktoplevel_s = (fun (k,bigf) p ->
match p with
- | Define _ ->
+ | CppTop (Define _) ->
raise Todo
(*
let (i1, i2, i3) = Common.tuple_of_list3 ii in
| EmptyDef a, EmptyDef b -> if not (a =*= b) then incr error
| MacroTop (a1,b1,c1), MacroTop (a2,b2,c2) ->
if not ((a1,b1,c1) =*= (a2,b2,c2)) then incr error
- | Include (a,_), Include (b,_) -> if not (a =*= b) then incr error
- | Define _, Define _ ->
+ | CppTop (Include {i_include = a}), CppTop (Include {i_include = b}) ->
+ if not (a =*= b) then incr error
+ | CppTop Define _, CppTop Define _ ->
raise Todo
(* if not (a =*= b) then incr error *)
| NotParsedCorrectly a, NotParsedCorrectly b ->
| _, NotParsedCorrectly b ->
incr pb_notparsed
| FinalDef a, FinalDef b -> if not (a =*= b) then incr error
- | _, _ -> incr error
+
+ | IfdefTop a, IfdefTop b -> if not (a =*= b) then incr error
+
+ | (FinalDef _|EmptyDef _|
+ MacroTop (_, _, _)|IfdefTop _|
+ CppTop _|Definition _|Declaration _), _ -> incr error
+
);
(match () with
| _ when !pb_notparsed > 0 && !error = 0 ->
(*****************************************************************************)
+(* ---------------------------------------------------------------------- *)
(* The string is for debugging. Used by Ograph_extended.print_graph.
* The int list are Labels. Trick used for CTL engine. Must not
* transform that in a triple or record because print_graph would
}
and node2 =
+ (* ------------------------ *)
(* For CTL to work, we need that some nodes loop over itself. We
* need that every nodes have a successor. Julia also want to go back
* indefinitely. So must tag some nodes as the beginning and end of
| TopNode
| EndNode
- | FunHeader of (string * functionType * storage) wrap
+ (* ------------------------ *)
+ | FunHeader of definition (* but empty body *)
| Decl of declaration
+ (* ------------------------ *)
(* flow_to_ast: cocci: Need the { and } in the control flow graph also
* because the coccier can express patterns containing such { }.
*
| Return of statement * unit wrap
| ReturnExpr of statement * expression wrap
+ (* ------------------------ *)
+ | IfdefHeader of ifdef_directive
+ | IfdefElse of ifdef_directive
+ | IfdefEndif of ifdef_directive
+
(* ------------------------ *)
| DefineHeader of string wrap * define_kind
| DefineExpr of expression
| DefineType of fullType
| DefineDoWhileZeroHeader of unit wrap
+ | DefineTodo
- | Include of inc_file wrap * (include_rel_pos option ref * bool)
+ | Include of includ
(* obsolete? *)
| MacroTop of string * argument wrap2 list * il
| Asm of statement * asmbody wrap
| MacroStmt of statement * unit wrap
- | Ifdef of statement * unit wrap
-
(* ------------------------ *)
(* some control nodes *)
| Enter
| MacroStmt (st, _) -> Some st
| MacroIterHeader (st, _) -> Some st
- | Ifdef _ -> None (* other ? *)
-
| Include _
| DefineHeader _ | DefineType _ | DefineExpr _ | DefineDoWhileZeroHeader _
+ | DefineTodo
| MacroTop _
-> None
+ | IfdefHeader _ | IfdefElse _ | IfdefEndif _
+ -> None
+
| SeqStart (st,_,_)
| ExprStatement (st, _)
| IfHeader (st, _)
| TopNode
| EndNode
- | FunHeader of (string * functionType * storage) wrap
+ | FunHeader of definition (* but empty body *)
| Decl of declaration
| SeqStart of statement * int * info
| ReturnExpr of statement * expression wrap
+ (* ------------------------ *)
+ | IfdefHeader of ifdef_directive
+ | IfdefElse of ifdef_directive
+ | IfdefEndif of ifdef_directive
+
(* ------------------------ *)
| DefineHeader of string wrap * define_kind
| DefineType of fullType
| DefineDoWhileZeroHeader of unit wrap
- | Include of inc_file wrap * (include_rel_pos option ref * bool)
+ | DefineTodo
+
+ | Include of includ
| MacroTop of string * argument wrap2 list * il
| Asm of statement * asmbody wrap
| MacroStmt of statement * unit wrap
- | Ifdef of statement * unit wrap
-
(* ------------------------ *)
| Enter
parsing_c library - Yoann Padioleau
-Copyright (C) 2002-2008 Yoann Padioleau
+Copyright (C) 2002, 2005, 2006, 2007, 2008 Yoann Padioleau
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License (GPL)
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
file license.txt for more details.
-
-
-The contents of some files in this directory was derived from external
-sources with compatible licenses. The original copyright and license
-notice was preserved in the affected files.
-
--- /dev/null
+open Common
+
+open Ast_c
+
+(*****************************************************************************)
+(* Cpp Ast Manipulations *)
+(*****************************************************************************)
+
+(*
+ * cpp-include-expander-builtin.
+ *
+ * alternative1: parse and call cpp tour a tour ?
+ * alternative2: apply cpp at the very end. Process that go through ast
+ * and do the stuff such as #include, macro expand,
+ * ifdef.
+ *
+ * But need keep those info in ast at least, even bad
+ * macro for instance, and for parse error region ? maybe can
+ * get another chance ?
+ * I think it's better to do the cpp-include-expander in a different step
+ * rather than embedding it in the parser. The parser is already too complex.
+ * Also keep with the tradition to try to parse as-is.
+ *
+ * todo? but maybe could discover new info that could help reparse
+ * the ParseError in original file. Try again parsing it by
+ * putting it in a minifile ?
+ *
+ *
+ * todo? maybe can do some pass that work at the ifdef level and for instance
+ * try to paren them, so have in Ast some stuff that are not
+ * present at parsing time but that can then be constructed after
+ * some processing (a little bit like my type for expression filler,
+ * or position info filler, or include relative position filler).
+ *
+ * ??add such info about what was done somewhere ? could build new
+ * ??ast each time but too tedious (maybe need delta-programming!)
+ *
+ *
+ * TODO: macro expand,
+ * TODO: handle ifdef
+ *
+ *
+ *
+ * cpp_ifdef_statementize: again better to separate concern and in parser
+ * just add the directives in a flat way (IfdefStmt) and later do more
+ * processing and transform them in a tree with some IfdefStmt2.
+ *)
+
+
+
+(*****************************************************************************)
+(* Types *)
+(*****************************************************************************)
+
+type cpp_option =
+ | I of Common.filename
+ | D of string * string option
+
+
+
+let i_of_cpp_options xs =
+ xs +> Common.map_filter (function
+ | I f -> Some f
+ | D _ -> None
+ )
+
+let cpp_option_of_cmdline (xs, ys) =
+ (xs +> List.map (fun s -> I s)) ++
+ (ys +> List.map (fun s ->
+ if s =~ "\\([A-Z][A-Z0-9_]*\\)=\\(.*\\)"
+ then
+ let (def, value) = matched2 s in
+ D (def, Some value)
+ else
+ D (s, None)
+ ))
+
+(*****************************************************************************)
+(* Helpers *)
+(*****************************************************************************)
+
+(* may return a list of match ? *)
+let find_header_file cppopts dirname inc_file =
+ match inc_file with
+ | Local f ->
+ let finalfile =
+ Filename.concat dirname (Ast_c.s_of_inc_file inc_file) in
+ if Sys.file_exists finalfile
+ then [finalfile]
+ else []
+ | NonLocal f ->
+ i_of_cpp_options cppopts +> Common.map_filter (fun dirname ->
+ let finalfile =
+ Filename.concat dirname (Ast_c.s_of_inc_file inc_file) in
+ if Sys.file_exists finalfile
+ then Some finalfile
+ else None
+ )
+ | Wierd s ->
+ pr2 ("CPPAST: wierd include not handled:" ^ s);
+ []
+
+
+let trace_cpp_process depth mark inc_file =
+ pr2 (spf "%s>%s %s"
+ (Common.repeat "-" depth +> Common.join "")
+ mark
+ (s_of_inc_file_bis inc_file));
+ ()
+
+
+(*****************************************************************************)
+(* Main entry *)
+(*****************************************************************************)
+
+
+let (cpp_expand_include:
+ cpp_option list -> Common.dirname -> Ast_c.program -> Ast_c.program) =
+ fun iops dirname ast ->
+
+ pr2_xxxxxxxxxxxxxxxxx();
+ let already_included = ref [] in
+
+ let rec aux stack dirname ast =
+ let depth = List.length stack in
+
+ ast +> Visitor_c.vk_program_s { Visitor_c.default_visitor_c_s with
+ Visitor_c.kcppdirective_s = (fun (k, bigf) cpp ->
+ match cpp with
+ | Include {i_include = (inc_file, ii);
+ i_rel_pos = h_rel_pos;
+ i_is_in_ifdef = b;
+ i_content = copt;
+ }
+ ->
+ (match find_header_file iops dirname inc_file with
+ | [file] ->
+ if List.mem file !already_included
+ then begin
+ (* pr2 ("already included: " ^ file); *)
+ trace_cpp_process depth "*" inc_file;
+ k cpp
+ end else begin
+ trace_cpp_process depth "" inc_file;
+ Common.push2 file already_included;
+ (* CONFIG *)
+ Flag_parsing_c.verbose_parsing := false;
+ Flag_parsing_c.verbose_lexing := false;
+ let (ast2, _stat) = Parse_c.parse_c_and_cpp file in
+
+ let ast = Parse_c.program_of_program2 ast2 in
+ let dirname' = Filename.dirname file in
+
+ (* recurse *)
+ let ast' = aux (file::stack) dirname' ast in
+
+ Include {i_include = (inc_file, ii);
+ i_rel_pos = h_rel_pos;
+ i_is_in_ifdef = b;
+ i_content = Some (file, ast');
+ }
+ end
+ | [] ->
+ trace_cpp_process depth "!!" inc_file;
+ pr2 "CPPAST: file not found";
+ k cpp
+ | x::y::zs ->
+ trace_cpp_process depth "!!" inc_file;
+ pr2 "CPPAST: too much candidates";
+ k cpp
+ )
+ | _ -> k cpp
+ );
+ }
+ in
+ aux [] dirname ast
+
+
+
+(*
+let unparse_showing_include_content ?
+*)
+
+
+(*****************************************************************************)
+(* Ifdef-statementize *)
+(*****************************************************************************)
+
+
+let is_ifdef_and_same_tag tag x =
+ match x with
+ | IfdefStmt (IfdefDirective ((_, tag2),_)) ->
+ tag = tag2
+ | StmtElem _ | CppDirectiveStmt _ -> false
+ | IfdefStmt2 _ -> raise Impossible
+
+
+
+(* What if I skipped in the parser only some of the ifdef elements
+ * of the same tag. Once I passed one, I should pass all of them and so
+ * at least should detect here that one tag is not "valid". Maybe in the parser
+ * can return or marked some tags as "partially_passed_ifdef_tag".
+ * Maybe could do in ast_c a MatchingTag of int * bool ref (* one_was_passed *)
+ * where the ref will be shared by the ifdefs with the same matching tag
+ * indice. Or simply count the number of directives with the same tag and
+ * put this information in the tag. Hence the total_with_this_tag below.
+ *)
+let should_ifdefize tag ifdefs_directives xxs =
+ let IfdefTag (_tag, total_with_this_tag) = tag in
+
+ if total_with_this_tag <> List.length ifdefs_directives
+ then begin
+ pr2 "CPPASTC: can not ifdefize, some of its directives were passed";
+ false
+ end else
+ (* todo? put more condition ? dont ifdefize declaration ? *)
+ true
+
+
+
+
+
+(* return a triple, (ifdefs directive * grouped xs * remaining sequencable)
+ * XXX1 XXX2 elsif YYY1 else ZZZ1 endif WWW1 WWW2
+ * => [elsif, else, endif], [XXX1 XXX2; YYY1; ZZZ1], [WWW1 WWW2]
+ *)
+let group_ifdef tag xs =
+ let (xxs, xs) = group_by_post (is_ifdef_and_same_tag tag) xs in
+
+ xxs +> List.map snd +> List.map (fun x ->
+ match x with
+ | IfdefStmt y -> y
+ | StmtElem _ | CppDirectiveStmt _ | IfdefStmt2 _ -> raise Impossible
+ ),
+ xxs +> List.map fst,
+ xs
+
+
+let rec cpp_ifdef_statementize ast =
+ Visitor_c.vk_program_s { Visitor_c.default_visitor_c_s with
+ Visitor_c.kstatementseq_list_s = (fun (k, bigf) xs ->
+
+ let rec aux xs =
+ match xs with
+ | [] -> []
+ | stseq::xs ->
+ (match stseq with
+ | StmtElem st ->
+ Visitor_c.vk_statement_sequencable_s bigf stseq::aux xs
+ | CppDirectiveStmt directive ->
+ Visitor_c.vk_statement_sequencable_s bigf stseq::aux xs
+ | IfdefStmt ifdef ->
+ (match ifdef with
+ | IfdefDirective ((Ifdef,tag),ii) ->
+
+ let (restifdefs, xxs, xs') = group_ifdef tag xs in
+ if should_ifdefize tag (ifdef::restifdefs) xxs
+ then
+ let res = IfdefStmt2 (ifdef::restifdefs, xxs) in
+ Visitor_c.vk_statement_sequencable_s bigf res::aux xs'
+ else
+ Visitor_c.vk_statement_sequencable_s bigf stseq::aux xs
+
+ | IfdefDirective (((IfdefElseif|IfdefElse|IfdefEndif),b),ii) ->
+ pr2 "wierd: first directive is not a ifdef";
+ (* maybe not wierd, just that should_ifdefize
+ * returned false *)
+ Visitor_c.vk_statement_sequencable_s bigf stseq::aux xs
+ )
+
+ | IfdefStmt2 (ifdef, xxs) ->
+ failwith "already applied cpp_ifdef_statementize"
+ )
+ in
+ aux xs
+ );
+ } ast
--- /dev/null
+type cpp_option =
+ | I of Common.filename
+ | D of string * string option
+
+val cpp_option_of_cmdline:
+ Common.dirname list (* -I *) * string list (* -D *) -> cpp_option list
+
+val cpp_expand_include:
+ cpp_option list -> Common.dirname (* start point for relative paths *) ->
+ Ast_c.program -> Ast_c.program
+
+
+val cpp_ifdef_statementize: Ast_c.program -> Ast_c.program
+
again for many other things too long to enumerate.
Inspiration:
- - C grammar found on the web
+ - C yacc grammar published in 1985 by Jeff Lee:
+ lex: http://www.lysator.liu.se/c/ANSI-C-grammar-l.html
+ yacc: http://www.lysator.liu.se/c/ANSI-C-grammar-y.html
+
- FrontC of hughes casse ?
- CIL ?
- EDG ?
(*****************************************************************************)
(* convenient globals to pass to parse_c.init_defs *)
(*****************************************************************************)
-let path = Filename.concat (Sys.getenv "HOME") "coccinelle"
-let std_h = ref (Filename.concat path "standard.h")
+let path = ref
+ (try (Sys.getenv "YACFE_HOME")
+ with Not_found-> "/home/pad/c-yacfe"
+ )
+let std_h = ref (Filename.concat !path "data/standard.h")
+let common_h = ref (Filename.concat !path "data/common_macros.h")
+
let cmdline_flags_macrofile () =
[
"-macro_file", Arg.Set_string std_h,
" <file> (default=" ^ !std_h ^ ")";
- "-D", Arg.Set_string std_h,
- " short option of -macro_file";
+ ]
+
+
+(*****************************************************************************)
+(* used only by cpp_ast_c, not by the parser *)
+(*****************************************************************************)
+let cpp_i_opts = ref []
+let cpp_d_opts = ref []
+
+let cmdline_flags_cpp () = [
+ "-D", Arg.String (fun s -> Common.push2 s cpp_d_opts),
+ " <x=y>";
+ "-I", Arg.String (fun s -> Common.push2 s cpp_i_opts),
+ " <dir>"
]
(*****************************************************************************)
let verbose_type = ref true
let filter_msg = ref false
+let filter_msg_define_error = ref false
+
let filter_define_error = ref false
-let filter_classic_passed = ref false
+
+let filter_passed_level = ref 0
let pretty_print_type_info = ref false
"-filter_msg", Arg.Set filter_msg ,
" filter some cpp message when the macro is a \"known\" cpp construct";
- "-filter_define_error",Arg.Set filter_define_error," ";
- "-filter_classic_passed",Arg.Set filter_classic_passed," ";
+ "-filter_msg_define_error",Arg.Set filter_msg_define_error,
+ " filter the error msg";
+
+ "-filter_define_error",Arg.Set filter_define_error,
+ " filter the error, which will not be added in the stat";
+ "-filter_passed_level",Arg.Set_int filter_passed_level," ";
]
(* change algo *)
(*****************************************************************************)
-let ifdef_to_if = ref false
-let if0_passing = ref true
-let add_typedef_root = ref true
-
(* cocci specific *)
let label_strategy_2 = ref false
let cmdline_flags_algos () =
[
- "-ifdef", Arg.Set ifdef_to_if,
- " convert ifdef to if (buggy!)";
+ "-l1", Arg.Clear label_strategy_2, " ";
+ ]
+
+(*****************************************************************************)
+(* Disable parsing feature (for CC09 and also to see if useful) *)
+(*****************************************************************************)
+
+let cpp_directive_passing = ref false
+let ifdef_directive_passing = ref false
+
+let disable_two_pass = ref false
+let disable_add_typedef = ref false
+
+let if0_passing = ref true
+let add_typedef_root = ref true
+
+let cmdline_flags_parsing_algos () = [
+
+ "-directive_passing", Arg.Set cpp_directive_passing,
+ " pass most cpp directives, especially when inside function";
+ "-ifdef_passing", Arg.Set ifdef_directive_passing,
+ " pass ifdef directives ";
+
"-noif0_passing", Arg.Clear if0_passing,
" ";
"-noadd_typedef_root", Arg.Clear add_typedef_root, " ";
+ "-noadd_typedef", Arg.Set disable_add_typedef, " ";
- "-l1", Arg.Clear label_strategy_2, " ";
- ]
+ "-disable_two_pass", Arg.Set disable_two_pass, " ";
+]
(*****************************************************************************)
(* other *)
{
-(* Copyright (C) 2002-2008 Yoann Padioleau
+(* Copyright (C) 2002, 2006, 2007, 2008 Yoann Padioleau
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License (GPL)
comments_tag = ref Ast_c.emptyComments;
}
+(* must generate a new ref each time, otherwise share *)
+let no_ifdef_mark () = ref (None: (int * int) option)
+
let tok_add_s s ii = Ast_c.rewrap_str ((Ast_c.str_of_info ii) ^ s) ii
(* opti: less convenient, but using a hash is faster than using a match *)
let keyword_table = Common.hash_of_list [
+ (* c: *)
"void", (fun ii -> Tvoid ii);
"char", (fun ii -> Tchar ii);
"short", (fun ii -> Tshort ii);
"inline", (fun ii -> Tinline ii);
"__inline__", (fun ii -> Tinline ii);
"__inline", (fun ii -> Tinline ii);
- "INLINE", (fun ii -> Tinline ii);
- "_INLINE_", (fun ii -> Tinline ii);
- "__INLINE__", (fun ii -> Tinline ii);
"__attribute__", (fun ii -> Tattribute ii);
"__attribute", (fun ii -> Tattribute ii);
"typeof", (fun ii -> Ttypeof ii);
"__typeof__", (fun ii -> Ttypeof ii);
+ "__typeof", (fun ii -> Ttypeof ii);
+
+ (* gccext: alias *)
"__signed__", (fun ii -> Tsigned ii);
"__const__", (fun ii -> Tconst ii);
"__volatile__", (fun ii -> Tvolatile ii);
"__volatile", (fun ii -> Tvolatile ii);
+
+
+ (* c99: *)
+ (* no just "restrict" ? maybe for backward compatibility they avoided
+ * to use restrict which people may have used in their program already
+ *)
+ "__restrict", (fun ii -> Trestrict ii);
+ "__restrict__", (fun ii -> Trestrict ii);
]
(* C++ comment are allowed via gccext, but normally they are deleted by cpp.
* So need this here only when dont call cpp before.
+ * note that we don't keep the trailing \n; it will be in another token.
*)
| "//" [^'\r' '\n' '\011']* { TComment (tokinfo lexbuf) }
(* misc *)
(* ---------------------- *)
- (* #pragma pack
- * #pragma GCC set_debug_pwd
- * #pragma alloc_text
- * #pragma options align=packed
- * #pragma options align=reset
- * #pragma options align=power
- * #pragma pack(2)
- * etc
- *)
- | "#pragma" sp [^'\n']* '\n'
- { TCommentCpp (CppDirective, tokinfo lexbuf) }
-
- | "#" [' ' '\t']* "ident" [' ' '\t']+ [^'\n']+ '\n'
-
- | "#" [' ' '\t']* "line" [' ' '\t']+ [^'\n']+ '\n'
+ (* bugfix: I want now to keep comments for the cComment study
+ * so cant do: sp [^'\n']+ '\n'
+ * http://gcc.gnu.org/onlinedocs/gcc/Pragmas.html
+ *)
- | "#" [' ' '\t']* "error" [' ' '\t']+ [^'\n']* '\n'
- | "#" [' ' '\t']* "warning" [' ' '\t']+ [^'\n']* '\n'
- | "#" [' ' '\t']* "abort" [' ' '\t']+ [^'\n']* '\n'
+ | "#" spopt "pragma" sp [^'\n']* '\n'
+ | "#" spopt "ident" sp [^'\n']* '\n'
+ | "#" spopt "line" sp [^'\n']* '\n'
+ | "#" spopt "error" sp [^'\n']* '\n'
+ | "#" spopt "warning" sp [^'\n']* '\n'
+ | "#" spopt "abort" sp [^'\n']* '\n'
+ { TCppDirectiveOther (tokinfo lexbuf) }
- { TCommentCpp (CppDirective, tokinfo lexbuf) }
+ | "#" [' ' '\t']* '\n'
+ { TCppDirectiveOther (tokinfo lexbuf) }
(* only after cpp, ex: # 1 "include/linux/module.h" 1 *)
| "#" sp pent sp '"' [^ '"']* '"' (spopt pent)* spopt '\n'
- { TCommentCpp (CppDirective, tokinfo lexbuf) }
+ { TCppDirectiveOther (tokinfo lexbuf) }
- (* in drivers/char/tpqic02.c, in old version of the kernel *)
- | "#" [' ' '\t']* "error" { TCommentCpp (CppDirective,tokinfo lexbuf) }
-
-
- | "#" [' ' '\t']* '\n' { TCommentCpp (CppDirective,tokinfo lexbuf) }
-
(* ---------------------- *)
(* #define, #undef *)
*)
| "#" [' ' '\t']* "define" { TDefine (tokinfo lexbuf) }
- | "#" [' ' '\t']* "undef" [' ' '\t']+ id
- { let info = tokinfo lexbuf in
- TCommentCpp (CppDirective,info +> tok_add_s (cpp_eat_until_nl lexbuf))
- }
-
-
- (* could generate separate token for #, ## and then exten grammar,
- * but there can be ident in many different places, in expression
- * but also in declaration, in function name. So having 3 tokens
- * for an ident does not work well with how we add info in
- * ast_c. So better to generate just one token, just one info,
- * even if have later to reanalyse those tokens and unsplit.
+ (* note: in some cases can have stuff after the ident as in #undef XXX 50,
+ * but I currently don't handle it cos I think it's bad code.
*)
-
- | ((id as s) "...")
- { TDefParamVariadic (s, tokinfo lexbuf) }
-
- (* cppext: string concatenation *)
- | id ([' ''\t']* "##" [' ''\t']* id)+
- { let info = tokinfo lexbuf in
- TIdent (tok lexbuf, info)
- }
-
- (* cppext: stringification *)
- | "#" id
- { let info = tokinfo lexbuf in
- TIdent (tok lexbuf, info)
- }
-
- (* cppext: gccext: ##args for variadic macro *)
- | "##" [' ''\t']* id
- { let info = tokinfo lexbuf in
- TIdent (tok lexbuf, info)
+ | (("#" [' ' '\t']* "undef" [' ' '\t']+) as _undef) (id as id)
+ { let info = tokinfo lexbuf in
+ TUndef (id, info)
+ (*+> tok_add_s (cpp_eat_until_nl lexbuf))*)
}
- (* only in cpp directives normally *)
- | "\\" '\n' { TCppEscapedNewline (tokinfo lexbuf) }
-
(* ---------------------- *)
(* #include *)
(* ---------------------- *)
(* The difference between a local "" and standard <> include is computed
- * later in parser_c.mly. So redo a little bit of lexing there. Ugly but
+ * later in parser_c.mly. So redo a little bit of lexing there; ugly but
* simpler to generate a single token here. *)
| (("#" [' ''\t']* "include" [' ' '\t']*) as includes)
(('"' ([^ '"']+) '"' |
'<' [^ '>']+ '>' |
['A'-'Z''_']+
) as filename)
- {
- let info = tokinfo lexbuf in
+ { let info = tokinfo lexbuf in
+ TInclude (includes, filename, Ast_c.noInIfdef(), info)
+ }
+ (* gccext: found in glibc *)
+ | (("#" [' ''\t']* "include_next" [' ' '\t']*) as includes)
+ (('"' ([^ '"']+) '"' |
+ '<' [^ '>']+ '>' |
+ ['A'-'Z''_']+
+ ) as filename)
+ { let info = tokinfo lexbuf in
TInclude (includes, filename, Ast_c.noInIfdef(), info)
}
-
- (* linuxext: special_for_no_exn: in atm/ambassador.c *)
- | "#include UCODE(" [^'\n']+ '\n'
- { TCommentCpp (CppDirective, tokinfo lexbuf) }
-
(* ---------------------- *)
(* #ifdef *)
(* ---------------------- *)
+ (* The ifdef_mark will be set later in Parsing_hacks.set_ifdef_parenthize_info
+ * when working on the ifdef view.
+ *)
+
(* '0'+ because sometimes it is a #if 000 *)
| "#" [' ' '\t']* "if" [' ' '\t']* '0'+ (* [^'\n']* '\n' *)
{ let info = tokinfo lexbuf in
- TIfdefBool (false, info +> tok_add_s (cpp_eat_until_nl lexbuf))
+ TIfdefBool (false, no_ifdef_mark(), info)
+ (* +> tok_add_s (cpp_eat_until_nl lexbuf)*)
}
- | "#" [' ' '\t']* "if" [' ' '\t']* '1' [^'\n']* '\n'
+ | "#" [' ' '\t']* "if" [' ' '\t']* '1' (* [^'\n']* '\n' *)
{ let info = tokinfo lexbuf in
- TIfdefBool (true, info)
+ TIfdefBool (true, no_ifdef_mark(), info)
}
+
+ (* DO NOT cherry pick to lexer_cplusplus !!! often used for the extern "C" { *)
+ | "#" [' ' '\t']* "if" sp "defined" sp "(" spopt "__cplusplus" spopt ")" [^'\n']* '\n'
+ { let info = tokinfo lexbuf in
+ TIfdefMisc (false, no_ifdef_mark(), info)
+ }
+ (* DO NOT cherry pick to lexer_cplusplus !!! *)
| "#" [' ' '\t']* "ifdef" [' ' '\t']* "__cplusplus" [^'\n']* '\n'
{ let info = tokinfo lexbuf in
- TIfdefMisc (false, info)
+ TIfdefMisc (false, no_ifdef_mark(), info)
}
+ (* in glibc *)
+ | "#" spopt ("ifdef"|"if") sp "__STDC__"
+ { let info = tokinfo lexbuf in
+ TIfdefVersion (true, no_ifdef_mark(),
+ info +> tok_add_s (cpp_eat_until_nl lexbuf))
+ }
+
+
+ (* linuxext: different possible variations (we do not manage all of them):
- (* linuxext: different possible variations (we not manage all of them):
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,2)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
*)
- (* linuxext: *)
+ (* linuxext: must be before the generic rules for if and ifdef *)
| "#" spopt "if" sp "("? "LINUX_VERSION_CODE" sp (">=" | ">") sp
{ let info = tokinfo lexbuf in
- TIfdefVersion (true, info +> tok_add_s (cpp_eat_until_nl lexbuf))
+ TIfdefVersion (true, no_ifdef_mark(),
+ info +> tok_add_s (cpp_eat_until_nl lexbuf))
}
(* linuxext: *)
| "#" spopt "if" sp "!" "("? "LINUX_VERSION_CODE" sp (">=" | ">") sp
| "#" spopt "if" sp ['(']? "LINUX_VERSION_CODE" sp ("<=" | "<") sp
{ let info = tokinfo lexbuf in
- TIfdefVersion (false, info +> tok_add_s (cpp_eat_until_nl lexbuf))
+ TIfdefVersion (false, no_ifdef_mark(),
+ info +> tok_add_s (cpp_eat_until_nl lexbuf))
}
+
+
(* can have some ifdef 0 hence the letter|digit even at beginning of word *)
| "#" [' ''\t']* "ifdef" [' ''\t']+ (letter|digit) ((letter|digit)*) [' ''\t']*
- { TIfdef (tokinfo lexbuf) }
+ { TIfdef (no_ifdef_mark(), tokinfo lexbuf) }
| "#" [' ''\t']* "ifndef" [' ''\t']+ (letter|digit) ((letter|digit)*) [' ''\t']*
- { TIfdef (tokinfo lexbuf) }
+ { TIfdef (no_ifdef_mark(), tokinfo lexbuf) }
| "#" [' ''\t']* "if" [' ' '\t']+
{ let info = tokinfo lexbuf in
- TIfdef (info +> tok_add_s (cpp_eat_until_nl lexbuf))
+ TIfdef (no_ifdef_mark(), info +> tok_add_s (cpp_eat_until_nl lexbuf))
}
| "#" [' ' '\t']* "if" '('
{ let info = tokinfo lexbuf in
- TIfdef (info +> tok_add_s (cpp_eat_until_nl lexbuf))
+ TIfdef (no_ifdef_mark(), info +> tok_add_s (cpp_eat_until_nl lexbuf))
}
| "#" [' ' '\t']* "elif" [' ' '\t']+
{ let info = tokinfo lexbuf in
- TIfdefelif (info +> tok_add_s (cpp_eat_until_nl lexbuf))
+ TIfdefelif (no_ifdef_mark(), info +> tok_add_s (cpp_eat_until_nl lexbuf))
}
- (* can have #endif LINUX *)
- | "#" [' ' '\t']* "endif" [^'\n']* '\n' { TEndif (tokinfo lexbuf) }
+ (* bugfix: can have #endif LINUX but at the same time if I eat everything
+ * until next line, I may miss some TComment which for some tools
+ * are important such as aComment
+ *)
+ | "#" [' ' '\t']* "endif" (*[^'\n']* '\n'*) {
+ TEndif (no_ifdef_mark(), tokinfo lexbuf)
+ }
(* can be at eof *)
- | "#" [' ' '\t']* "endif" { TEndif (tokinfo lexbuf) }
+ (*| "#" [' ' '\t']* "endif" { TEndif (tokinfo lexbuf) }*)
+
+ | "#" [' ' '\t']* "else" [' ' '\t' '\n']
+ { TIfdefelse (no_ifdef_mark(), tokinfo lexbuf) }
+
+
+
+
+ (* ---------------------- *)
+ (* #define body *)
+ (* ---------------------- *)
+
+ (* only in cpp directives normally *)
+ | "\\" '\n' { TCppEscapedNewline (tokinfo lexbuf) }
+
+
+ | ((id as s) "...")
+ { TDefParamVariadic (s, tokinfo lexbuf) }
+
+
+ (* could generate separate token for #, ## and then extend grammar,
+ * but there can be ident in many different places, in expression
+ * but also in declaration, in function name. So having 3 tokens
+ * for an ident does not work well with how we add info in
+ * ast_c. So better to generate just one token, for now, just one info,
+ * even if have later to reanalyse those tokens and unsplit.
+ *
+ * todo: our heuristics in parsing_hacks rely on TIdent. So maybe
+ * an easier solution would be to augment the TIdent type such as
+ * TIdent of string * info * cpp_ident_additionnal_info
+ *)
+
- | "#" [' ' '\t']* "else" [' ' '\t' '\n'] { TIfdefelse (tokinfo lexbuf) }
- (* there is a file in 2.6 that have this *)
- | "##" [' ' '\t']* "else" [' ' '\t' '\n'] { TIfdefelse (tokinfo lexbuf) }
+ (* cppext: string concatenation of idents *)
+ | id ([' ''\t']* "##" [' ''\t']* id)+
+ { let info = tokinfo lexbuf in
+ TIdent (tok lexbuf, info)
+ }
+
+ (* cppext: stringification.
+ * bugfix: this case must be after the other cases such as #endif
+ * otherwise take precedent.
+ *)
+ | "#" spopt id
+ { let info = tokinfo lexbuf in
+ TIdent (tok lexbuf, info)
+ }
+ (* cppext: gccext: ##args for variadic macro *)
+ | "##" spopt id
+ { let info = tokinfo lexbuf in
+ TIdent (tok lexbuf, info)
+ }
with
| Some f -> f info
- (* parse_typedef_fix. note: now this is no more useful, cos
- * as we use tokens_all, it first parse all as an ident and
- * later transform an indent in a typedef. so this job is
- * now done in parse_c.ml.
- *
+ (* parse_typedef_fix.
* if Lexer_parser.is_typedef s
* then TypedefIdent (s, info)
* else TIdent (s, info)
+ *
+ * update: now this is no more useful, cos
+ * as we use tokens_all, it first parse all as an ident and
+ * later transform an indent in a typedef. so the typedef job is
+ * now done in parse_c.ml.
*)
| None -> TIdent (s, info)
- )
- }
+ )
+ }
+ (* gccext: apparently gcc allows dollar in variable names. found such
+ * thing a few time in linux and in glibc. No need look in keyword_table
+ * here.
+ *)
+ | (letter | '$') (letter | digit | '$') *
+ {
+ let info = tokinfo lexbuf in
+ let s = tok lexbuf in
+ pr2 ("LEXER: identifier with dollar: " ^ s);
+ TIdent (s, info)
+ }
+
(* ----------------------------------------------------------------------- *)
(* C constant *)
| ['0'] ['0'-'9']+
{ pr2 ("LEXER: " ^ error_radix "octal" ^ tok lexbuf);
- TCommentMisc (tokinfo lexbuf)
+ TUnknown (tokinfo lexbuf)
}
| ("0x" |"0X") ['0'-'9' 'a'-'z' 'A'-'Z']+
{ pr2 ("LEXER: " ^ error_radix "hexa" ^ tok lexbuf);
- TCommentMisc (tokinfo lexbuf)
+ TUnknown (tokinfo lexbuf)
}
x ^ string lexbuf
}
+ | eof { pr2 "LEXER: WIERD end of file in string"; ""}
+
(* Bug if add following code, cos match also the '"' that is needed
* to finish the string, and so go until end of file.
*)
(* cpp recognize C comments, so when #define xx (yy) /* comment \n ... */
* then he has already erased the /* comment. So:
- * - dont eat the start of the comment otherwiseafterwards we are in the middle
+ * - dont eat the start of the comment otherwise afterwards we are in the middle
* of a comment and so will problably get a parse error somewhere.
* - have to recognize comments in cpp_eat_until_nl.
*)
+type context =
+ | InTopLevel
+ | InFunction
+ | InStruct
+ | InParameter
+ | InInitializer
+ | InEnum
+
+let is_top_or_struct = function
+ | InTopLevel
+ | InStruct
+ -> true
+ | _ -> false
+
type lexer_hint = {
- mutable parameterDeclaration: bool;
- mutable structDefinition: int; (* depth in struct def, 0 = not in struct *)
- mutable toplevel: bool;
- }
+ mutable context_stack: context Common.stack;
+ }
let default_hint () = {
- parameterDeclaration = false;
- structDefinition = 0;
- toplevel = false;
+ context_stack = [InTopLevel];
}
let _lexer_hint = ref (default_hint())
+let current_context () = List.hd !_lexer_hint.context_stack
+let push_context ctx =
+ !_lexer_hint.context_stack <- ctx::!_lexer_hint.context_stack
+let pop_context () =
+ !_lexer_hint.context_stack <- List.tl !_lexer_hint.context_stack
+
+
let lexer_reset_typedef () =
begin
_handle_typedef := true;
_typedef := Common.empty_scoped_h_env ();
- _lexer_hint := { (default_hint ()) with toplevel = true; } ;
+ _lexer_hint := (default_hint ());
end
val restore_typedef_state : unit -> unit
+type context =
+ | InTopLevel
+ | InFunction
+ | InStruct
+ | InParameter
+ | InInitializer
+ | InEnum
+
+val is_top_or_struct : context -> bool
+
type lexer_hint = {
- mutable parameterDeclaration: bool;
- mutable structDefinition: int; (* depth in struct def, 0 = not in struct *)
-(* mutable statements: bool; *)
- mutable toplevel: bool;
- }
+ mutable context_stack: context Common.stack;
+ }
val _lexer_hint : lexer_hint ref
+val current_context: unit -> context
+val push_context: context -> unit
+val pop_context: unit -> unit
val default_hint : unit -> lexer_hint
-(* Copyright (C) 2002-2008 Yoann Padioleau
+(* Copyright (C) 2007, 2008 Yoann Padioleau
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License (GPL)
let ii_of_param = extract_info_visitor Visitor_c.vk_param
let ii_of_params = extract_info_visitor Visitor_c.vk_params_splitted
let ii_of_struct_fields = extract_info_visitor Visitor_c.vk_struct_fields
-let ii_of_struct_field = extract_info_visitor Visitor_c.vk_struct_field
+(*let ii_of_struct_field = extract_info_visitor Visitor_c.vk_struct_field*)
+let ii_of_struct_fieldkinds = extract_info_visitor Visitor_c.vk_struct_fieldkinds
let ii_of_cst = extract_info_visitor Visitor_c.vk_cst
let ii_of_define_params =
extract_info_visitor Visitor_c.vk_define_params_splitted
+let ii_of_toplevel = extract_info_visitor Visitor_c.vk_toplevel
+(*****************************************************************************)
let max_min_ii_by_pos xs =
match xs with
| [] -> failwith "empty list, max_min_ii_by_pos"
let (i2, i1) = max_min_ii_by_pos xs in
let posf x = Ast_c.col_of_info x in
let mposf x = Ast_c.col_of_info x + String.length (Ast_c.str_of_info x) in
- (Ast_c.file_of_info i1,
+ (Ast_c.file_of_info i1,!Flag.current_element,
(Ast_c.line_of_info i1, posf i1), (Ast_c.line_of_info i2, mposf i2))
-(* Copyright (C) 2002-2008 Yoann Padioleau
+(* Copyright (C) 2006, 2007, 2008 Yoann Padioleau
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License (GPL)
module TH = Token_helpers
module LP = Lexer_parser
+module Stat = Parsing_stat
+
(*****************************************************************************)
(* Wrappers *)
(*****************************************************************************)
let pr2 s =
if !Flag_parsing_c.verbose_parsing
then Common.pr2 s
+
+let pr2_once s =
+ if !Flag_parsing_c.verbose_parsing
+ then Common.pr2_once s
(*****************************************************************************)
(* Helpers *)
let print_bad line_error (start_line, end_line) filelines =
- if !Flag_parsing_c.verbose_parsing
- then
begin
pr2 ("badcount: " ^ i_to_s (end_line - start_line));
+
for i = start_line to end_line do
+ let line = filelines.(i) in
+
if i = line_error
- then pr2 ("BAD:!!!!!" ^ " " ^ filelines.(i))
- else pr2 ("bad:" ^ " " ^ filelines.(i))
+ then pr2 ("BAD:!!!!!" ^ " " ^ line)
+ else pr2 ("bad:" ^ " " ^ line)
done
end
-(*****************************************************************************)
-(* Stat *)
-(*****************************************************************************)
-type parsing_stat = {
- filename: filename;
- mutable have_timeout: bool;
-
- mutable correct: int;
- mutable bad: int;
-
- mutable commentized: int; (* by our cpp commentizer *)
-
- (* if want to know exactly what was passed through, uncomment:
- *
- * mutable passing_through_lines: int;
- *
- * it differs from bad by starting from the error to
- * the synchro point instead of starting from start of
- * function to end of function.
- *)
-
- }
-
-let default_stat file = {
- filename = file;
- have_timeout = false;
- correct = 0; bad = 0;
- commentized = 0;
- }
-
-(* todo: stat per dir ? give in terms of func_or_decl numbers:
- * nbfunc_or_decl pbs / nbfunc_or_decl total ?/
- *
- * note: cela dit si y'a des fichiers avec des #ifdef dont on connait pas les
- * valeurs alors on parsera correctement tout le fichier et pourtant y'aura
- * aucune def et donc aucune couverture en fait.
- * ==> TODO evaluer les parties non parsé ?
- *)
-
-let print_parsing_stat_list = fun statxs ->
- let total = (List.length statxs) in
- let perfect =
- statxs
- +> List.filter (function
- {have_timeout = false; bad = 0} -> true | _ -> false)
- +> List.length
- in
- pr2 "\n\n\n---------------------------------------------------------------";
- pr2 "pbs with files:";
- statxs
- +> List.filter (function
- | {have_timeout = true} -> true
- | {bad = n} when n > 0 -> true
- | _ -> false)
- +> List.iter (function
- {filename = file; have_timeout = timeout; bad = n} ->
- pr2 (file ^ " " ^ (if timeout then "TIMEOUT" else i_to_s n));
- );
-
- pr2 "\n\n\n";
- pr2 "files with lots of tokens passed/commentized:";
- let threshold_passed = 100 in
- statxs
- +> List.filter (function
- | {commentized = n} when n > threshold_passed -> true
- | _ -> false)
- +> List.iter (function
- {filename = file; commentized = n} ->
- pr2 (file ^ " " ^ (i_to_s n));
- );
-
- pr2 "\n\n\n---------------------------------------------------------------";
- pr2 (
- (sprintf "NB total files = %d; " total) ^
- (sprintf "perfect = %d; " perfect) ^
- (sprintf "pbs = %d; " (statxs +> List.filter (function
- {have_timeout = b; bad = n} when n > 0 -> true | _ -> false)
- +> List.length)) ^
- (sprintf "timeout = %d; " (statxs +> List.filter (function
- {have_timeout = true; bad = n} -> true | _ -> false)
- +> List.length)) ^
- (sprintf "=========> %d" ((100 * perfect) / total)) ^ "%"
-
- );
- let good = statxs +> List.fold_left (fun acc {correct = x} -> acc+x) 0 in
- let bad = statxs +> List.fold_left (fun acc {bad = x} -> acc+x) 0 in
- let passed = statxs +> List.fold_left (fun acc {commentized = x} -> acc+x) 0
- in
- let gf, badf = float_of_int good, float_of_int bad in
- let passedf = float_of_int passed in
- pr2 (
- (sprintf "nb good = %d, nb passed = %d " good passed) ^
- (sprintf "=========> %f" (100.0 *. (passedf /. gf)) ^ "%")
- );
- pr2 (
- (sprintf "nb good = %d, nb bad = %d " good bad) ^
- (sprintf "=========> %f" (100.0 *. (gf /. (gf +. badf))) ^ "%"
- )
- )
-
(*****************************************************************************)
(* Stats on what was passed/commentized *)
let commentized xs = xs +> Common.map_filter (function
| Parser_c.TCommentCpp (cppkind, ii) ->
- if !Flag_parsing_c.filter_classic_passed
- then
- (match cppkind with
+ let s = Ast_c.str_of_info ii in
+ let legal_passing =
+ match !Flag_parsing_c.filter_passed_level with
+ | 0 -> false
+ | 1 ->
+ List.mem cppkind [Ast_c.CppAttr]
+ ||
+ (s =~ "__.*")
+ | 2 ->
+ List.mem cppkind [Ast_c.CppAttr;Ast_c.CppPassingNormal]
+ ||
+ (s =~ "__.*")
+ | 3 ->
+ List.mem cppkind [Ast_c.CppAttr;Ast_c.CppPassingNormal;Ast_c.CppDirective]
+ ||
+ (s =~ "__.*")
+ | 4 ->
+ List.mem cppkind [Ast_c.CppAttr;Ast_c.CppPassingNormal;Ast_c.CppMacro]
+ ||
+ (s =~ "__.*")
+
+
+ | 5 ->
+ List.mem cppkind [Ast_c.CppAttr;Ast_c.CppPassingNormal;Ast_c.CppDirective;Ast_c.CppMacro]
+ ||
+ (s =~ "__.*")
+
+
+
+
+ | _ -> failwith "not valid level passing number"
+ in
+ if legal_passing then None else Some (ii.Ast_c.pinfo)
+
+ (*
| Ast_c.CppOther ->
- let s = Ast_c.str_of_info ii in
(match s with
| s when s =~ "KERN_.*" -> None
| s when s =~ "__.*" -> None
- | _ -> Some (ii.Ast_c.pinfo)
+ | _ ->
+ Some (ii.Ast_c.pinfo)
)
-
- | Ast_c.CppDirective | Ast_c.CppAttr | Ast_c.CppMacro
- -> None
- )
- else Some (ii.Ast_c.pinfo)
+ *)
+
| Parser_c.TCommentMisc ii
| Parser_c.TAction ii
| e -> raise e
)
-let tokens a =
- Common.profile_code "C parsing.tokens" (fun () -> tokens2 a)
+let time_lexing ?(profile=true) a =
+ if profile
+ then Common.profile_code_exclusif "LEXING" (fun () -> tokens2 a)
+ else tokens2 a
+let tokens ?profile a =
+ Common.profile_code "C parsing.tokens" (fun () -> time_lexing ?profile a)
-let tokens_string string =
+let tokens_of_string string =
let lexbuf = Lexing.from_string string in
try
let rec tokens_s_aux () =
*)
let parse_gen parsefunc s =
- let toks = tokens_string s +> List.filter TH.is_not_comment in
+ let toks = tokens_of_string s +> List.filter TH.is_not_comment in
(* Why use this lexing scheme ? Why not classically give lexer func
end
);
- (* third phase, update ast *)
+ (* third phase, update ast.
+ * todo? but normally should try to handle correctly scope ? maybe sometime
+ * sizeof(id) and even if id was for a long time an identifier, maybe
+ * a few time, because of the scope it's actually really a type.
+ *)
if (null !ident_to_type)
then xs
else
pr2 "ERROR-RECOV: end of file while in recovery mode";
already_passed, []
| (Parser_c.TDefEOL i as v)::xs ->
- pr2 ("ERROR-RECOV: found sync end of #define "^i_to_s(TH.line_of_tok v));
+ pr2 ("ERROR-RECOV: found sync end of #define, line "^i_to_s(TH.line_of_tok v));
v::already_passed, xs
| v::xs ->
find_next_synchro_define xs (v::already_passed)
(* Include/Define hacks *)
(*****************************************************************************)
+(* Sometimes I prefer to generate a single token for a list of things in the
+ * lexer so that if I have to passed them, like for passing TInclude then
+ * it's easy. Also if I don't do a single token, then I need to
+ * parse the rest which may not need special stuff, like detecting
+ * end of line which the parser is not really ready for. So for instance
+ * could I parse a #include <a/b/c/xxx.h> as 2 or more tokens ? just
+ * lex #include ? so then need recognize <a/b/c/xxx.h> as one token ?
+ * but this kind of token is valid only after a #include and the
+ * lexing and parsing rules are different for such tokens so not that
+ * easy to parse such things in parser_c.mly. Hence the following hacks.
+ *
+ * less?: maybe could get rid of this like I get rid of some of fix_define.
+ *)
+
(* ------------------------------------------------------------------------- *)
(* helpers *)
(* ------------------------------------------------------------------------- *)
Parser_c.TCommentCpp (Ast_c.CppDirective, TH.info_of_tok x)
::xs
| _ ->
- Parser_c.TCommentCpp (Ast_c.CppOther, TH.info_of_tok x)
- ::comment_until_defeol xs
+ let x' =
+ (* bugfix: otherwise may lose a TComment token *)
+ if TH.is_real_comment x
+ then x
+ else Parser_c.TCommentCpp (Ast_c.CppPassingNormal (*good?*), TH.info_of_tok x)
+ in
+ x'::comment_until_defeol xs
)
let drop_until_defeol xs =
]
(*****************************************************************************)
-(* Parsing default define, standard.h *)
+(* Parsing default define macros, usually in a standard.h file *)
(*****************************************************************************)
-let parse_cpp_define_file file =
- let toks = tokens file in
+let parse_cpp_define_file2 file =
+ let toks = tokens ~profile:false file in
let toks = Parsing_hacks.fix_tokens_define toks in
Parsing_hacks.extract_cpp_define toks
+let parse_cpp_define_file a =
+ Common.profile_code_exclusif "HACK" (fun () -> parse_cpp_define_file2 a)
+
+(* can not be put in parsing_hack, cos then mutually recursive problem as
+ * we also want to parse the standard.h file.
+ *)
+let init_defs std_h =
+ if not (Common.lfile_exists std_h)
+ then pr2 ("warning: Can't find default macro file: " ^ std_h)
+ else begin
+ pr2 ("init_defs: " ^ std_h);
+ Parsing_hacks._defs := Common.hash_of_list (parse_cpp_define_file std_h);
+ end
+
(*****************************************************************************)
(* Main entry point *)
type program2 = toplevel2 list
and toplevel2 = Ast_c.toplevel * info_item
+let program_of_program2 xs =
+ xs +> List.map fst
+
+let with_program2 f program2 =
+ program2
+ +> Common.unzip
+ +> (fun (program, infos) ->
+ f program, infos
+ )
+ +> Common.uncurry Common.zip
+
+
(* The use of local refs (remaining_tokens, passed_tokens, ...) makes
* possible error recovery. Indeed, they allow to skip some tokens and
* provide enough context information for powerful lex trick.
*
* - passed_tokens_last_ckp stores the passed tokens since last
- * checkpoint. Used for NotParsedCorrectly and also for build the
+ * checkpoint. Used for NotParsedCorrectly and also to build the
* info_item attached to each program_element.
* - passed_tokens_clean is used for lookahead, in fact for lookback.
* - remaining_tokens_clean is used for lookahead. Now remaining_tokens
* At the end of lexer_function call, cur_tok overlap with passed_tok.
*
* convention: I use "tr" for "tokens refs"
+ *
+ * I now also need this lexing trick because the lexer return comment
+ * tokens.
*)
type tokens_state = {
mutable passed : Parser_c.token list;
mutable passed_clean : Parser_c.token list;
}
+let clone_tokens_stat tr =
+ { rest = tr.rest;
+ rest_clean = tr.rest_clean;
+ current = tr.current;
+ passed = tr.passed;
+ passed_clean = tr.passed_clean;
+ }
+let copy_tokens_stat ~src ~dst =
+ dst.rest <- src.rest;
+ dst.rest_clean <- src.rest_clean;
+ dst.current <- src.current;
+ dst.passed <- src.passed;
+ dst.passed_clean <- src.passed_clean;
+ ()
+
+let rec filter_noise n xs =
+ match n, xs with
+ | _, [] -> []
+ | 0, xs -> xs
+ | n, x::xs ->
+ (match x with
+ | Parser_c.TMacroAttr _ ->
+ filter_noise (n-1) xs
+ | _ ->
+ x::filter_noise (n-1) xs
+ )
+
+let clean_for_lookahead xs =
+ match xs with
+ | [] -> []
+ | [x] -> [x]
+ | x::xs ->
+ x::filter_noise 10 xs
+
-(* Hacked lex. This function use refs passed by parse_print_error_heuristic *)
-let rec lexer_function tr = fun lexbuf ->
+
+(* Hacked lex. This function use refs passed by parse_print_error_heuristic
+ * tr means token refs.
+ *)
+let rec lexer_function ~pass tr = fun lexbuf ->
match tr.rest with
| [] -> pr2 "ALREADY AT END"; tr.current
| v::xs ->
if TH.is_comment v
then begin
tr.passed <- v::tr.passed;
- lexer_function tr lexbuf
+ lexer_function ~pass tr lexbuf
end
else begin
let x = List.hd tr.rest_clean in
assert (x = v);
(match v with
+ (* fix_define1. Why not in parsing_hacks lookahead and do passing like
+ * I do for some ifdef directives ? Because here I also need to
+ * generate some tokens sometimes.
+ *)
| Parser_c.TDefine (tok) ->
- if not !LP._lexer_hint.LP.toplevel
+ if not (LP.current_context () = LP.InTopLevel) &&
+ (!Flag_parsing_c.cpp_directive_passing || (pass = 2))
then begin
+ incr Stat.nDefinePassing;
pr2_once ("CPP-DEFINE: inside function, I treat it as comment");
let v' = Parser_c.TCommentCpp (Ast_c.CppDirective,TH.info_of_tok v)
in
tr.passed <- v'::tr.passed;
tr.rest <- comment_until_defeol tr.rest;
tr.rest_clean <- drop_until_defeol tr.rest_clean;
- lexer_function tr lexbuf
+ lexer_function ~pass tr lexbuf
end
else begin
tr.passed <- v::tr.passed;
end
| Parser_c.TInclude (includes, filename, inifdef, info) ->
- if not !LP._lexer_hint.LP.toplevel
+ if not (LP.current_context () = LP.InTopLevel) &&
+ (!Flag_parsing_c.cpp_directive_passing || (pass = 2))
then begin
+ incr Stat.nIncludePassing;
pr2_once ("CPP-INCLUDE: inside function, I treat it as comment");
let v = Parser_c.TCommentCpp(Ast_c.CppDirective, info) in
tr.passed <- v::tr.passed;
- lexer_function tr lexbuf
+ lexer_function ~pass tr lexbuf
end
else begin
let (v,new_tokens) =
(* typedef_fix1 *)
let v = match v with
| Parser_c.TIdent (s, ii) ->
- if LP.is_typedef s
+ if
+ LP.is_typedef s &&
+ not (!Flag_parsing_c.disable_add_typedef) &&
+ pass = 1
then Parser_c.TypedefIdent (s, ii)
else Parser_c.TIdent (s, ii)
| x -> x
in
- let v = Parsing_hacks.lookahead (v::tr.rest_clean) tr.passed_clean in
+ let v = Parsing_hacks.lookahead ~pass
+ (clean_for_lookahead (v::tr.rest_clean))
+ tr.passed_clean in
tr.passed <- v::tr.passed;
- (* the lookahead may have change the status of the token and
+ (* the lookahead may have changed the status of the token and
* consider it as a comment, for instance some #include are
- * turned into comments hence this code. *)
+ * turned into comments, hence this code. *)
match v with
- | Parser_c.TCommentCpp _ -> lexer_function tr lexbuf
+ | Parser_c.TCommentCpp _ -> lexer_function ~pass tr lexbuf
| v ->
tr.passed_clean <- v::tr.passed_clean;
v
+let get_one_elem ~pass tr (file, filelines) =
+
+ if not (LP.is_enabled_typedef()) && !Flag_parsing_c.debug_typedef
+ then pr2 "TYPEDEF:_handle_typedef=false. Not normal if dont come from exn";
+
+ (* normally have to do that only when come from an exception in which
+ * case the dt() may not have been done
+ * TODO but if was in scoped scope ? have to let only the last scope
+ * so need do a LP.lexer_reset_typedef ();
+ *)
+ LP.enable_typedef();
+ LP._lexer_hint := (LP.default_hint ());
+ LP.save_typedef_state();
+
+ tr.passed <- [];
+
+ let lexbuf_fake = Lexing.from_function (fun buf n -> raise Impossible) in
+
+ (try
+ (* -------------------------------------------------- *)
+ (* Call parser *)
+ (* -------------------------------------------------- *)
+ Common.profile_code_exclusif "YACC" (fun () ->
+ Left (Parser_c.celem (lexer_function ~pass tr) lexbuf_fake)
+ )
+ with e -> begin
+ if (pass = 1 && !Flag_parsing_c.disable_two_pass)|| (pass = 2)
+ then begin
+ (match e with
+ (* Lexical is not anymore launched I think *)
+ | Lexer_c.Lexical s ->
+ pr2 ("lexical error " ^s^ "\n =" ^ error_msg_tok tr.current)
+ | Parsing.Parse_error ->
+ pr2 ("parse error \n = " ^ error_msg_tok tr.current)
+ | Semantic_c.Semantic (s, i) ->
+ pr2 ("semantic error " ^s^ "\n ="^ error_msg_tok tr.current)
+ | e -> raise e
+ )
+ end;
+ LP.restore_typedef_state();
+
+ (* must keep here, before the code that adjusts the tr fields *)
+ let line_error = TH.line_of_tok tr.current in
+
+
+ (* error recovery, go to next synchro point *)
+ let (passed', rest') = find_next_synchro tr.rest tr.passed in
+ tr.rest <- rest';
+ tr.passed <- passed';
+
+ tr.current <- List.hd passed';
+ tr.passed_clean <- []; (* enough ? *)
+ (* with error recovery, rest and rest_clean may not be in sync *)
+ tr.rest_clean <- (tr.rest +> List.filter TH.is_not_comment);
+
+
+ let info_of_bads = Common.map_eff_rev TH.info_of_tok tr.passed in
+ Right (info_of_bads, line_error)
+ end
+ )
+
+
+
+
(* note: as now we go in 2 passes, there is first all the error message of
- * the lexer, and then the error of the parser. It is no more
+ * the lexer, and then the error of the parser. It is not anymore
* interwinded.
*
* !!!This function use refs, and is not reentrant !!! so take care.
* It use globals defined in Lexer_parser and also the _defs global
- * in parsing_hack.ml.
+ * in parsing_hack.ml.
+ *
+ * This function uses internally some semi globals in the
+ * tokens_stat record and parsing_stat record.
*)
let parse_print_error_heuristic2 file =
+ let filelines = (""::Common.cat file) +> Array.of_list in
+ let stat = Parsing_stat.default_stat file in
+
(* -------------------------------------------------- *)
(* call lexer and get all the tokens *)
(* -------------------------------------------------- *)
LP.lexer_reset_typedef();
- let toks = tokens file in
+ Parsing_hacks.ifdef_paren_cnt := 0;
+ let toks_orig = tokens file in
- let toks = Parsing_hacks.fix_tokens_define toks in
+ let toks = Parsing_hacks.fix_tokens_define toks_orig in
let toks = Parsing_hacks.fix_tokens_cpp toks in
- let filelines = (""::Common.cat file) +> Array.of_list in
- let stat = default_stat file in
-
let tr = {
rest = toks;
rest_clean = (toks +> List.filter TH.is_not_comment);
passed = [];
passed_clean = [];
} in
- let lexbuf_fake = Lexing.from_function (fun buf n -> raise Impossible) in
- let rec loop () =
- if not (LP.is_enabled_typedef()) && !Flag_parsing_c.debug_typedef
- then pr2 "TYPEDEF:_handle_typedef=false. Not normal if dont come from exn";
- (* normally have to do that only when come from an exception in which
- * case the dt() may not have been done
- * TODO but if was in scoped scope ? have to let only the last scope
- * so need do a LP.lexer_reset_typedef ();
- *)
- LP.enable_typedef();
- LP._lexer_hint := { (LP.default_hint ()) with LP.toplevel = true; };
- LP.save_typedef_state();
+
+ let rec loop tr =
(* todo?: I am not sure that it represents current_line, cos maybe
* tr.current partipated in the previous parsing phase, so maybe tr.current
* is not the first token of the next parsing phase. Same with checkpoint2.
* It would be better to record when we have a } or ; in parser.mly,
* cos we know that they are the last symbols of external_declaration2.
+ *
+ * bugfix: may not be equal to 'file' as after macro expansions we can
+ * start to parse a new entity from the body of a macro, for instance
+ * when parsing a define_machine() body, cf standard.h
*)
let checkpoint = TH.line_of_tok tr.current in
+ let checkpoint_file = TH.file_of_tok tr.current in
- tr.passed <- [];
- let was_define = ref false in
-
+ let tr_save = clone_tokens_stat tr in
+
+ (* call the parser *)
let elem =
- (try
- (* -------------------------------------------------- *)
- (* Call parser *)
- (* -------------------------------------------------- *)
- Parser_c.celem (lexer_function tr) lexbuf_fake
- with e ->
- begin
- (match e with
- (* Lexical is no more launched I think *)
- | Lexer_c.Lexical s ->
- pr2 ("lexical error " ^s^ "\n =" ^ error_msg_tok tr.current)
- | Parsing.Parse_error ->
- pr2 ("parse error \n = " ^ error_msg_tok tr.current)
- | Semantic_c.Semantic (s, i) ->
- pr2 ("semantic error " ^s^ "\n ="^ error_msg_tok tr.current)
- | e -> raise e
- );
- LP.restore_typedef_state();
- let line_error = TH.line_of_tok tr.current in
-
- (* error recovery, go to next synchro point *)
- let (passed', rest') = find_next_synchro tr.rest tr.passed in
- tr.rest <- rest';
- tr.passed <- passed';
-
- tr.current <- List.hd passed';
- tr.passed_clean <- []; (* enough ? *)
- (* with error recovery, rest and rest_clean may not be in sync *)
- tr.rest_clean <- (tr.rest +> List.filter TH.is_not_comment);
-
- let checkpoint2 = TH.line_of_tok tr.current in (* <> line_error *)
-
- (* was a define ? *)
+ let pass1 = get_one_elem ~pass:1 tr (file, filelines) in
+ match pass1 with
+ | Left e -> Left e
+ | Right res ->
+ if !Flag_parsing_c.disable_two_pass
+ then Right res
+ else begin
+ pr2 "parsing pass2: try again";
+ copy_tokens_stat ~src:tr_save ~dst: tr;
+ let pass2 = get_one_elem ~pass:2 tr (file, filelines) in
+ pass2
+ end
+ in
+
+
+ (* again not sure if checkpoint2 corresponds to end of bad region *)
+ let checkpoint2 = TH.line_of_tok tr.current in (* <> line_error *)
+ let checkpoint2_file = TH.file_of_tok tr.current in
+
+ let was_define =
+ (match elem with
+ | Left _ -> false
+ | Right (_, line_error) ->
+ let was_define =
let xs = tr.passed +> List.rev +> List.filter TH.is_not_comment in
if List.length xs >= 2
then
(match Common.head_middle_tail xs with
| Parser_c.TDefine _, _, Parser_c.TDefEOL _ ->
- was_define := true
- | _ -> ()
+ true
+ | _ -> false
)
- else pr2 "WIERD: lenght list of error recovery tokens < 2 ";
-
- if !was_define && !Flag_parsing_c.filter_define_error
- then ()
- else print_bad line_error (checkpoint, checkpoint2) filelines;
-
+ else begin
+ pr2 "WIERD: length list of error recovery tokens < 2 ";
+ false
+ end
+ in
+ (if was_define && !Flag_parsing_c.filter_msg_define_error
+ then ()
+ else
+ (* bugfix: *)
+ if (checkpoint_file = checkpoint2_file) && checkpoint_file = file
+ then print_bad line_error (checkpoint, checkpoint2) filelines
+ else pr2 "PB: bad: but on tokens not from original file"
+ );
+ was_define
+ ) in
+
- let info_of_bads = Common.map_eff_rev TH.info_of_tok tr.passed in
- Ast_c.NotParsedCorrectly info_of_bads
- end
- )
+ let diffline =
+ if (checkpoint_file = checkpoint2_file) && (checkpoint_file = file)
+ then (checkpoint2 - checkpoint)
+ else 0
+ (* TODO? so if error come in middle of something ? where the
+ * start token was from original file but synchro found in body
+ * of macro ? then can have wrong number of lines stat.
+ * Maybe simpler just to look at tr.passed and count
+ * the lines in the token from the correct file ?
+ *)
in
-
- (* again not sure if checkpoint2 corresponds to end of bad region *)
- let checkpoint2 = TH.line_of_tok tr.current in
- let diffline = (checkpoint2 - checkpoint) in
let info = mk_info_item file (List.rev tr.passed) in
- stat.commentized <- stat.commentized + count_lines_commentized (snd info);
+ (* some stat updates *)
+ stat.Stat.commentized <-
+ stat.Stat.commentized + count_lines_commentized (snd info);
+
+ let elem =
+ match elem with
+ | Left e -> e
+ | Right (info_of_bads, _line_error) ->
+ Ast_c.NotParsedCorrectly info_of_bads
+ in
(match elem with
| Ast_c.NotParsedCorrectly xs ->
- if !was_define && !Flag_parsing_c.filter_define_error
- then stat.correct <- stat.correct + diffline
- else stat.bad <- stat.bad + diffline
- | _ -> stat.correct <- stat.correct + diffline
+ if was_define && !Flag_parsing_c.filter_define_error
+ then stat.Stat.correct <- stat.Stat.correct + diffline
+ else stat.Stat.bad <- stat.Stat.bad + diffline
+ | _ -> stat.Stat.correct <- stat.Stat.correct + diffline
);
(match elem with
| Ast_c.FinalDef x -> [(Ast_c.FinalDef x, info)]
- | xs -> (xs, info):: loop () (* recurse *)
+ | xs -> (xs, info):: loop tr (* recurse *)
)
in
- let v = loop() in
+ let v = loop tr in
+
let v = consistency_checking v in
(v, stat)
+let time_total_parsing a =
+ Common.profile_code "TOTAL" (fun () -> parse_print_error_heuristic2 a)
+
let parse_print_error_heuristic a =
- Common.profile_code "C parsing" (fun () -> parse_print_error_heuristic2 a)
+ Common.profile_code "C parsing" (fun () -> time_total_parsing a)
+
(* alias *)
let parse_c_and_cpp a = parse_print_error_heuristic a
let parse_cache file =
if not !Flag_parsing_c.use_cache then parse_print_error_heuristic file
else
+ let _ = pr2 "TOFIX" in
let need_no_changed_files =
(* should use Sys.argv.(0), would be safer. *)
- [Config.path ^ "/parsing_c/c_parser.cma";
- (* we may also depend now on the semantic patch because
- the SP may use macro and so we will disable some of the
- macro expansions from standard.h.
- *)
- !Config.std_h;
+
+ [
+ (* TOFIX
+ Config.path ^ "/parsing_c/c_parser.cma";
+ (* we may also depend now on the semantic patch because
+ the SP may use macro and so we will disable some of the
+ macro expansions from standard.h.
+ *)
+ !Config.std_h;
+ *)
]
in
let need_no_changed_variables =
(*****************************************************************************)
+(* Some special cases *)
(*****************************************************************************)
-(* can not be put in parsing_hack, cos then mutually recursive problem as
- * we also want to parse the standard.h file.
- *)
-let init_defs std_h =
- if not (Common.lfile_exists std_h)
- then pr2 ("warning: Can't find default macro file: " ^ std_h)
- else
- Parsing_hacks._defs := Common.hash_of_list (parse_cpp_define_file std_h)
- ;
+let (cstatement_of_string: string -> Ast_c.statement) = fun s ->
+ Common.write_file ("/tmp/__cocci.c") ("void main() { \n" ^ s ^ "\n}");
+ let program = parse_c_and_cpp ("/tmp/__cocci.c") +> fst in
+ program +> Common.find_some (fun (e,_) ->
+ match e with
+ | Ast_c.Definition ({Ast_c.f_body = [Ast_c.StmtElem st]},_) -> Some st
+ | _ -> None
+ )
+
+let (cexpression_of_string: string -> Ast_c.expression) = fun s ->
+ Common.write_file ("/tmp/__cocci.c") ("void main() { \n" ^ s ^ ";\n}");
+ let program = parse_c_and_cpp ("/tmp/__cocci.c") +> fst in
+ program +> Common.find_some (fun (e,_) ->
+ match e with
+ | Ast_c.Definition ({Ast_c.f_body = compound},_) ->
+ (match compound with
+ | [Ast_c.StmtElem (Ast_c.ExprStatement (Some e),ii)] -> Some e
+ | _ -> None
+ )
+ | _ -> None
+ )
-(* Copyright (C) 2002-2008 Yoann Padioleau
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License (GPL)
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * file license.txt for more details.
- *)
open Common
(* The main function is parse_c_and_cpp. It uses globals in Lexer_Parser and
* from a standard.h macro file. Cf also init_defs below.
*)
-(* the token list contains now also the comment-tokens *)
-type info_item = (string * Parser_c.token list)
-
+(* ---------------------------------------------------------------------- *)
type program2 = toplevel2 list
- and toplevel2 = Ast_c.toplevel * info_item
+ and toplevel2 = Ast_c.toplevel * info_item
-type parsing_stat = {
- filename: filename;
- mutable have_timeout: bool;
- mutable correct: int;
- mutable bad: int;
- mutable commentized: int;
- }
+ (* the token list contains now also the comment-tokens *)
+ and info_item = (string * Parser_c.token list)
+(* ---------------------------------------------------------------------- *)
(* This is the main function *)
val parse_print_error_heuristic:
- filename (*cfile*) -> (program2 * parsing_stat)
-val parse_c_and_cpp : (* alias of previous func *)
- filename (*cfile*) -> (program2 * parsing_stat)
+ filename (*cfile*) -> (program2 * Parsing_stat.parsing_stat)
+(* alias of previous func *)
+val parse_c_and_cpp :
+ filename (*cfile*) -> (program2 * Parsing_stat.parsing_stat)
+(* use some .ast_raw memoized version, and take care if obsolete *)
+val parse_cache:
+ filename (*cfile*) -> (program2 * Parsing_stat.parsing_stat)
+
+
+(* ---------------------------------------------------------------------- *)
val parse_cpp_define_file :
- filename -> (string, Parsing_hacks.define_body) assoc
+ filename -> (string, Parsing_hacks.define_def) assoc
val init_defs : filename -> unit
-
-val tokens: filename -> Parser_c.token list
-val tokens_string: string -> Parser_c.token list
+(* ---------------------------------------------------------------------- *)
+(* used also for the standard.h file *)
+val tokens: ?profile:bool -> filename -> Parser_c.token list
+val tokens_of_string: string -> Parser_c.token list
val parse: filename -> Ast_c.program
val parse_print_error: filename -> Ast_c.program
val parse_gen:
((Lexing.lexbuf -> Parser_c.token) -> Lexing.lexbuf -> 'a) -> string -> 'a
-(* easy way to build complex Ast elements from simple strings *)
+
+
+(* ---------------------------------------------------------------------- *)
+(* Easy way to build complex Ast elements from simple strings.
+ * Can also be useful when called from the ocaml toplevel to test.
+ *)
val type_of_string : string -> Ast_c.fullType
val statement_of_string : string -> Ast_c.statement
+(* similar but use parse_c_and_cpp and a /tmp/__cocci.c and extract the part *)
+val cstatement_of_string : string -> Ast_c.statement
+val cexpression_of_string : string -> Ast_c.expression
+
-(* use some .ast_raw memoized version, and take care if obsolete *)
-val parse_cache:
- filename (*cfile*) -> (program2 * parsing_stat)
+(* ---------------------------------------------------------------------- *)
+(* a few helpers *)
+val program_of_program2 : program2 -> Ast_c.program
+val with_program2: (Ast_c.program -> Ast_c.program) -> program2 -> program2
-val print_parsing_stat_list: parsing_stat list -> unit
val print_commentized : Parser_c.token list -> unit
%{
-(* Copyright (C) 2002-2008 Yoann Padioleau
+(* Copyright (C) 2002, 2006, 2007, 2008 Yoann Padioleau
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License (GPL)
open Semantic_c (* Semantic exn *)
+module Stat = Parsing_stat
(*****************************************************************************)
(* Wrappers *)
| ((Middle3 Long,ii), ({typeD = ((a,Some LongLong ,c),ii2)} as v)) ->
warning "triplicate 'long'" v
+
| ((Middle3 _,ii), ({typeD = ((a,Some _,c),ii2)} as _v)) ->
raise (Semantic ("both long and short specified", fake_pi))
| ((Middle3 x,ii), ({typeD = ((a,None,c),ii2)} as v)) ->
| ((
(s,iis),
(nQ, (FunctionType (fullt, (params,bool)),iifunc)),
- (st,iist)
+ (st,iist),
+ attrs
),
- (cp,iicp)) ->
+ (cp,iicp)
+ )
+ ->
let iistart = Ast_c.fakeInfo () in
assert (nQ =*= nullQualif);
(match params with
(* failwith "internal errror: fixOldCDecl not good" *)
));
(* it must be nullQualif,cos parser construct only this*)
- (s, (fullt, (params, bool)), st, cp),
+ {f_name = s;
+ f_type = (fullt, (params, bool));
+ f_storage = st;
+ f_body = cp;
+ f_attr = attrs;
+ },
([iis]++iifunc++iicp++[iistart]++iist)
| _ ->
raise
let fix_add_params_ident = function
- | ((s, (nQ, (FunctionType (fullt, (params, bool)),_)), st)) ->
+ | ((s, (nQ, (FunctionType (fullt, (params, bool)),_)), st, _attrs)) ->
(match params with
| [((reg, None, ((_qua, (BaseType Void,_)))),_), _] -> ()
%}
/*(*****************************************************************************)*/
+/*(* Tokens *)*/
+/*(*************************************************************************)*/
/*
(*
%token <Ast_c.info> TUnknown /*(* unrecognized token *)*/
/*(* coupling: Token_helpers.is_real_comment *)*/
-%token <Ast_c.info> TComment TCommentSpace TCommentNewline
-
-/*(* cppext: extra tokens *)*/
-
-%token <Ast_c.info> TDefine
-%token <(string * Ast_c.info)> TDefParamVariadic
-/*(* disappear after fix_tokens_define *)*/
-%token <Ast_c.info> TCppEscapedNewline
-/*(* appear after fix_tokens_define *)*/
-%token <Ast_c.info> TOParDefine
-%token <(string * Ast_c.info)> TIdentDefine /*(* same *)*/
-%token <Ast_c.info> TDefEOL /*(* same *)*/
-
-/*(* used only in lexer_c, then transformed in comment or splitted in tokens *)*/
-%token <(string * string * bool ref * Ast_c.info)> TInclude
-/*(* tokens coming from above, generated in parse_c from TInclude, etc *)*/
-%token <(Ast_c.info * bool ref)> TIncludeStart
-%token <(string * Ast_c.info)> TIncludeFilename
-
-
-/*(* coupling: Token_helpers.is_cpp_instruction *)*/
-%token <Ast_c.info> TIfdef TIfdefelse TIfdefelif TEndif
-%token <(bool * Ast_c.info)> TIfdefBool TIfdefMisc TIfdefVersion
-
-
-%token <Ast_c.info> TCommentMisc
-%token <(Ast_c.cppcommentkind * Ast_c.info)> TCommentCpp
-
-/*(* appear after fix_tokens_cpp *)*/
-
-%token <Ast_c.info> TMacroStmt
-/*(* no need value for the moment *)*/
-%token <Ast_c.info> TMacroString
-%token <(string * Ast_c.info)> TMacroDecl
-%token <Ast_c.info> TMacroDeclConst
-%token <(string * Ast_c.info)> TMacroIterator
-/*(* %token <(string * Ast_c.info)> TMacroTop *)*/
-/*(* appear after parsing_hack *)*/
-%token <Ast_c.info> TCParEOL
-
-%token <Ast_c.info> TAction
-
+%token <Ast_c.info> TCommentSpace TCommentNewline TComment
+/*(*-----------------------------------------*)*/
/*(* the normal tokens *)*/
+/*(*-----------------------------------------*)*/
%token <string * Ast_c.info> TInt
%token <(string * Ast_c.floatType) * Ast_c.info> TFloat
%token <(string * Ast_c.isWchar) * Ast_c.info> TChar
%token <(string * Ast_c.isWchar) * Ast_c.info> TString
-%token <string * Ast_c.info> TIdent TypedefIdent
+%token <string * Ast_c.info> TIdent
+/*(* appears mostly after some fix_xxx in parsing_hack *)*/
+%token <string * Ast_c.info> TypedefIdent
/*
(* Some tokens like TOPar and TCPar are used as synchronisation stuff,
* in parsing_hack.ml. So if define special tokens like TOParDefine and
- * TCParEOL, then take care to also modify in Token_helpers
+ * TCParEOL, then take care to also modify in Token_helpers.
*)
*/
Tgoto Tdefault
Tsizeof
+/*(* C99 *)*/
+%token <Ast_c.info>
+ Trestrict
+
+/*(*-----------------------------------------*)*/
/*(* gccext: extra tokens *)*/
+/*(*-----------------------------------------*)*/
%token <Ast_c.info> Tasm
%token <Ast_c.info> Tattribute
%token <Ast_c.info> Tinline
%token <Ast_c.info> Ttypeof
+/*(*-----------------------------------------*)*/
+/*(* cppext: extra tokens *)*/
+/*(*-----------------------------------------*)*/
+/*(* coupling with Token_helpers.is_cpp_token *)*/
+
+
+/*(*---------------*)*/
+/*(* define *)*/
+/*(*---------------*)*/
+
+%token <Ast_c.info> TDefine
+%token <(string * Ast_c.info)> TDefParamVariadic
+
+/*(* disappear after fix_tokens_define *)*/
+%token <Ast_c.info> TCppEscapedNewline
+
+/*(* appear after fix_tokens_define *)*/
+%token <Ast_c.info> TOParDefine
+%token <Ast_c.info> TOBraceDefineInit
+
+%token <(string * Ast_c.info)> TIdentDefine /*(* same *)*/
+%token <Ast_c.info> TDefEOL /*(* same *)*/
+
+
+/*(*---------------*)*/
+/*(* include *)*/
+/*(*---------------*)*/
+
+
+/*(* used only in lexer_c, then transformed in comment or splitted in tokens *)*/
+%token <(string * string * bool ref * Ast_c.info)> TInclude
+
+/*(* tokens coming from above, generated in parse_c from TInclude, etc *)*/
+%token <(Ast_c.info * bool ref)> TIncludeStart
+%token <(string * Ast_c.info)> TIncludeFilename
+
+
+/*(*---------------*)*/
+/*(* ifdef *)*/
+/*(*---------------*)*/
+
+/*(* coupling: Token_helpers.is_cpp_instruction *)*/
+%token <((int * int) option ref * Ast_c.info)>
+ TIfdef TIfdefelse TIfdefelif TEndif
+%token <(bool * (int * int) option ref * Ast_c.info)>
+ TIfdefBool TIfdefMisc TIfdefVersion
+
+/*(*---------------*)*/
+/*(* other *)*/
+/*(*---------------*)*/
+
+
+%token <string * Ast_c.info> TUndef
+
+%token <Ast_c.info> TCppDirectiveOther
+
+/*(*---------------*)*/
+/*(* macro use *)*/
+/*(*---------------*)*/
+
+/*(* appear after fix_tokens_cpp, cf also parsing_hacks#hint *)*/
+
+%token <(string * Ast_c.info)> TMacroAttr
+%token <(string * Ast_c.info)> TMacroStmt
+/*(* no need value for the moment *)*/
+%token <(string * Ast_c.info)> TMacroString
+%token <(string * Ast_c.info)> TMacroDecl
+%token <Ast_c.info> TMacroDeclConst
+%token <(string * Ast_c.info)> TMacroStructDecl
+%token <(string * Ast_c.info)> TMacroIterator
+/*(* %token <(string * Ast_c.info)> TMacroTop *)*/
+
+%token <(string * Ast_c.info)> TMacroAttrStorage
+
+
+/*(*---------------*)*/
+/*(* other *)*/
+/*(*---------------*)*/
+
+/*(* appear after parsing_hack *)*/
+%token <Ast_c.info> TCParEOL
+
+%token <Ast_c.info> TAction
+
+
+%token <Ast_c.info> TCommentMisc
+%token <(Ast_c.cppcommentkind * Ast_c.info)> TCommentCpp
+
+/*(*-----------------------------------------*)*/
%token <Ast_c.info> EOF
+/*(*-----------------------------------------*)*/
+
+/*(* must be at the top so that it has the lowest priority *)*/
+%nonassoc SHIFTHERE
-/* operator precedence */
-%nonassoc Tif
%nonassoc Telse
%left TOrLog
%left TPlus TMinus
%left TMul TDiv TMod
+/*(*************************************************************************)*/
+/*(* Rules type declaration *)*/
+/*(*************************************************************************)*/
+
%start main celem statement expr type_name
%type <Ast_c.program> main
%type <Ast_c.toplevel> celem
/*(*************************************************************************)*/
/*
(* TOC:
+ * toplevel (obsolete)
+ *
+ * ident
* expression
* statement
- * declaration, types, initializers, struct, enum
- * xxx_list, xxx_opt
+ * types with
+ * - left part (type_spec, qualif),
+ * - right part (declarator, abstract declarator)
+ * - aux part (parameters)
+ * declaration, storage, initializers
+ * struct
+ * enum
* cpp directives
* celem (=~ main)
+ *
+ * generic workarounds (obrace, cbrace for context setting)
+ * xxx_list, xxx_opt
*)
*/
/*(*************************************************************************)*/
+/*(*************************************************************************)*/
+/*(* toplevel *)*/
+/*(*************************************************************************)*/
/*(* no more used; now that use error recovery *)*/
main: translation_unit EOF { $1 }
translation_unit:
| external_declaration
- { !LP._lexer_hint.toplevel <- true; [$1] }
+ { !LP._lexer_hint.context_stack <- [LP.InTopLevel]; [$1] }
| translation_unit external_declaration
- { !LP._lexer_hint.toplevel <- true; $1 ++ [$2] }
+ { !LP._lexer_hint.context_stack <- [LP.InTopLevel]; $1 ++ [$2] }
+
+
+
+/*(*************************************************************************)*/
+/*(* ident *)*/
+/*(*************************************************************************)*/
+
+/*(* Why this ? Why not s/ident/TIdent ? cos there is multiple namespaces in C,
+ * so a label can have the same name that a typedef, same for field and tags
+ * hence sometimes the use of ident instead of TIdent.
+ *)*/
+ident:
+ | TIdent { $1 }
+ | TypedefIdent { $1 }
+identifier:
+ | TIdent { $1 }
/*(*************************************************************************)*/
/*(* expr *)*/
{ mk_e(Constructor ($2, List.rev $5)) ([$1;$3;$4;$7] ++ $6) }
primary_expr:
- | TIdent { mk_e(Ident (fst $1)) [snd $1] }
+ | identifier { mk_e(Ident (fst $1)) [snd $1] }
| TInt { mk_e(Constant (Int (fst $1))) [snd $1] }
| TFloat { mk_e(Constant (Float (fst $1))) [snd $1] }
| TString { mk_e(Constant (String (fst $1))) [snd $1] }
| TChar { mk_e(Constant (Char (fst $1))) [snd $1] }
| TOPar expr TCPar { mk_e(ParenExpr ($2)) [$1;$3] } /*(* forunparser: *)*/
- /*(* gccext: cppext: *)*/
+ /*(* gccext: cppext: TODO better ast ? *)*/
+ | TMacroString { mk_e(Constant (MultiString)) [snd $1] }
| string_elem string_list { mk_e(Constant (MultiString)) ($1 ++ $2) }
/*(* gccext: allow statement as expressions via ({ statement }) *)*/
+/*(*----------------------------*)*/
+/*(* cppext: *)*/
+/*(*----------------------------*)*/
/*(* cppext: *)*/
+/*(* to avoid conflicts have to introduce a _not_empty (ne) version *)*/
argument_ne:
| assign_expr { Left $1 }
| parameter_decl { Right (ArgType $1) }
| action_higherordermacro_ne { Right (ArgAction $1) }
+
argument:
| assign_expr { Left $1 }
| parameter_decl { Right (ArgType $1) }
+ /*(* had conflicts before, but julia fixed them *)*/
| action_higherordermacro { Right (ArgAction $1) }
action_higherordermacro_ne:
else ActMisc $1
}
+
action_higherordermacro:
| taction_list
{ if null $1
/*(* workarounds *)*/
/*(*----------------------------*)*/
-/*(* Why this ? Why not s/ident/TIdent ? cos there is multiple namespaces in C,
- * so a label can have the same name that a typedef, same for field and tags
- * hence sometimes the use of ident instead of TIdent.
- *)*/
-ident:
- | TIdent { $1 }
- | TypedefIdent { $1 }
-
-identifier:
- | TIdent { $1 }
-
/*(* would like evalInt $1 but require too much info *)*/
const_expr: cond_expr { $1 }
| Tasm Tvolatile TOPar asmbody TCPar TPtVirg { Asm $4, [$1;$2;$3;$5;$6] }
/*(* cppext: *)*/
- | TMacroStmt { MacroStmt, [$1] }
- | TMacroStmt TPtVirg { MacroStmt, [$1;$2] }
+ | TMacroStmt { MacroStmt, [snd $1] }
end_labeled:
/*(* gccext: allow toto: }
- * generate each 30 shift/Reduce conflicts, mais ca va, ca fait ce qu'il
- * faut
+ * was generating each 30 shift/Reduce conflicts,
+ * mais ca va, ca fait ce qu'il faut.
+ * update: julia fixed the problem by introducing end_labeled
+ * and modifying below stat_or_decl_list
*)*/
| ident TDotDot
{ Label (fst $1, (ExprStatement None, [])), [snd $1; $2] }
compound: tobrace compound2 tcbrace { $2, [$1; $3] }
-tobrace: TOBrace { LP.new_scope (); $1 }
-tcbrace: TCBrace { LP.del_scope (); $1 }
-
-/*(* old:
-compound2:
- | { ([],[]) }
- | statement_list { ([], $1) }
- | decl_list { ($1, []) }
- | decl_list statement_list { ($1,$2) }
-
-statement_list: stat_or_decl_list { $1 }
-*)*/
-
/*
(* cppext: because of cpp, some stuff looks like declaration but are in
| { ([]) }
| stat_or_decl_list { $1 }
-stat_or_decl:
- | decl { Decl ($1 Ast_c.LocalDecl), [] }
- | statement { $1 }
- /*(* cppext: if -ifdef_to_if is enabled for parsing_hack *)*/
- | TIfdef stat_or_decl_list TIfdefelse stat_or_decl_list TEndif
- { Selection (Ifdef ($2, $4)), [$1;$3;$5;fakeInfo()] }
- | TIfdef stat_or_decl_list TEndif
- { Selection (Ifdef ($2, [])), [$1;$3;fakeInfo()] }
+stat_or_decl_list:
+ | stat_or_decl { [$1] }
+ /*(* gccext: to avoid conflicts, cf end_labeled above *)*/
+ | end_labeled { [StmtElem (Labeled (fst $1), snd $1)] }
+ /*(* old: conflicts | stat_or_decl_list stat_or_decl { $1 ++ [$2] } *)*/
+ | stat_or_decl stat_or_decl_list { $1 :: $2 }
+
+stat_or_decl:
+ | decl { StmtElem (Decl ($1 Ast_c.LocalDecl), []) }
+ | statement { StmtElem $1 }
/*(* gccext: *)*/
- | function_definition { NestedFunc $1, [] }
+ | function_definition { StmtElem (NestedFunc $1, []) }
+ /* (* cppext: *)*/
+ | cpp_directive
+ { CppDirectiveStmt $1 }
+ | cpp_ifdef_directive/*(* stat_or_decl_list ...*)*/
+ { IfdefStmt $1 }
| expr TPtVirg { Some $1, [$2] }
selection:
- | Tif TOPar expr TCPar statement %prec Tif
+ | Tif TOPar expr TCPar statement %prec SHIFTHERE
{ If ($3, $5, (ExprStatement None, [])), [$1;$2;$4] }
| Tif TOPar expr TCPar statement Telse statement
{ If ($3, $5, $7), [$1;$2;$4;$6] }
{ For ($3,$4,(None, []),$6), [$1;$2;$5]}
| Tfor TOPar expr_statement expr_statement expr TCPar statement
{ For ($3,$4,(Some $5, []),$7), [$1;$2;$6] }
-/*(* c++ext: for(int i = 0; i < n; i++)
- | Tfor TOPar decl expr_statement expr TCPar statement
- { pr2 "DECL in for";
- While ($5, $7), [] (* fake ast *)
+ /*(* c++ext: for(int i = 0; i < n; i++)*)*/
+ | Tfor TOPar decl expr_statement expr_opt TCPar statement
+ {
+ (* pr2 "DECL in for"; *)
+ MacroIteration ("toto", [], $7),[] (* TODOfake ast, TODO need decl2 ? *)
}
-*)*/
/*(* cppext: *)*/
| TMacroIterator TOPar argument_list_ne TCPar statement
{ MacroIteration (fst $1, $3, $5), [snd $1;$2;$4] }
string_elem:
| TString { [snd $1] }
/*(* cppext: ex= printk (KERN_INFO "xxx" UTS_RELEASE) *)*/
- | TMacroString { [$1] }
+ | TMacroString { [snd $1] }
asmbody:
asm_expr: assign_expr { $1 }
-
-
/*(*************************************************************************)*/
-/*(* declaration, types, initializers *)*/
+/*(* types *)*/
/*(*************************************************************************)*/
+
-decl2:
- | decl_spec TPtVirg
- { function local ->
- let (returnType,storage) = fixDeclSpecForDecl $1 in
- let iistart = Ast_c.fakeInfo () in
- DeclList ([(None, returnType, unwrap storage, local),[]],
- ($2::iistart::snd storage))
- }
- | decl_spec init_declarator_list TPtVirg
- { function local ->
- let (returnType,storage) = fixDeclSpecForDecl $1 in
- let iistart = Ast_c.fakeInfo () in
- DeclList (
- ($2 +> List.map (fun ((((s,iis),f), ini), iivirg) ->
- let ini, iini =
- match ini with
- | None -> None, []
- | Some (ini, iini) -> Some ini, [iini]
- in
- if fst (unwrap storage) = StoTypedef
- then LP.add_typedef s;
- (Some ((s, ini), iis::iini), f returnType, unwrap storage, local),
- iivirg
- )
- ), ($3::iistart::snd storage))
- }
- /*(* cppext: *)*/
-
- | TMacroDecl TOPar argument_list TCPar TPtVirg
- { function _ ->
- MacroDecl ((fst $1, $3), [snd $1;$2;$4;$5;fakeInfo()]) }
- | Tstatic TMacroDecl TOPar argument_list TCPar TPtVirg
- { function _ ->
- MacroDecl ((fst $2, $4), [snd $2;$3;$5;$6;fakeInfo();$1]) }
- | Tstatic TMacroDeclConst TMacroDecl TOPar argument_list TCPar TPtVirg
- { function _ ->
- MacroDecl ((fst $3, $5), [snd $3;$4;$6;$7;fakeInfo();$1;$2])}
-
-
-
-decl_spec2:
- | storage_class_spec { {nullDecl with storageD = (fst $1, [snd $1]) } }
- | type_spec { addTypeD ($1,nullDecl) }
- | type_qualif { {nullDecl with qualifD = (fst $1, [snd $1]) } }
- | Tinline { {nullDecl with inlineD = (true, [$1]) } }
- | storage_class_spec decl_spec2 { addStorageD ($1, $2) }
- | type_spec decl_spec2 { addTypeD ($1, $2) }
- | type_qualif decl_spec2 { addQualifD ($1, $2) }
- | Tinline decl_spec2 { addInlineD ((true, $1), $2) }
-
-/*(* can simplify by putting all in _opt ? must have at least one otherwise
- * decl_list is ambiguous ? (no cos have ';' between decl)
- *)*/
-
-
-storage_class_spec:
- | Tstatic { Sto Static, $1 }
- | Textern { Sto Extern, $1 }
- | Tauto { Sto Auto, $1 }
- | Tregister { Sto Register,$1 }
- | Ttypedef { StoTypedef, $1 }
-
+/*(*-----------------------------------------------------------------------*)*/
+/*(* Type spec, left part of a type *)*/
+/*(*-----------------------------------------------------------------------*)*/
type_spec2:
| Tvoid { Right3 (BaseType Void), [$1] }
| Tchar { Right3 (BaseType (IntType CChar)), [$1]}
| Ttypeof TOPar assign_expr TCPar { Right3 (TypeOfExpr ($3)), [$1;$2;$4] }
| Ttypeof TOPar type_name TCPar { Right3 (TypeOfType ($3)), [$1;$2;$4] }
-
-type_qualif:
- | Tconst { {const=true ; volatile=false}, $1 }
- | Tvolatile { {const=false ; volatile=true}, $1 }
-
-
-
/*(*----------------------------*)*/
/*(* workarounds *)*/
/*(*----------------------------*)*/
-decl: decl2 { et "decl" (); $1 }
-decl_spec: decl_spec2 { dt "declspec" (); $1 }
type_spec: type_spec2 { dt "type" (); $1 }
+/*(*-----------------------------------------------------------------------*)*/
+/*(* Qualifiers *)*/
+/*(*-----------------------------------------------------------------------*)*/
-
-
+type_qualif:
+ | Tconst { {const=true ; volatile=false}, $1 }
+ | Tvolatile { {const=false ; volatile=true}, $1 }
+ /*(* C99 *)*/
+ | Trestrict { (* TODO *) {const=false ; volatile=false}, $1 }
/*(*-----------------------------------------------------------------------*)*/
-/*(* for struct and also typename *)*/
-/*(* cant put decl_spec cos no storage is allowed for field struct *)*/
-spec_qualif_list2:
- | type_spec { addTypeD ($1, nullDecl) }
- | type_qualif { {nullDecl with qualifD = (fst $1,[snd $1])}}
- | type_spec spec_qualif_list { addTypeD ($1,$2) }
- | type_qualif spec_qualif_list { addQualifD ($1,$2) }
-
-spec_qualif_list: spec_qualif_list2 { dt "spec_qualif" (); $1 }
-
+/*(* gccext: attributes *)*/
/*(*-----------------------------------------------------------------------*)*/
-init_declarator: init_declarator2 { dt "init" (); $1 }
-
-init_declarator2:
- | declaratori { ($1, None) }
- | declaratori teq initialize { ($1, Some ($3, $2)) }
+attribute:
+ | Tattribute TOPar /*stuff*/ TCPar { raise Todo }
+ /*(* cppext: *)*/
+ | TMacroAttr { Attribute (fst $1), [snd $1] }
-/*(*----------------------------*)*/
-/*(* workarounds *)*/
-/*(*----------------------------*)*/
-declaratori:
- | declarator
- { LP.add_ident (fst (fst $1)); $1 }
- /*(* gccext: *)*/
- | declarator gcc_asm_decl
- { LP.add_ident (fst (fst $1)); $1 }
+attribute_storage:
+ | TMacroAttrStorage { $1 }
-teq: TEq { et "teq" (); $1 }
+type_qualif_attr:
+ | type_qualif { $1 }
+ | TMacroAttr { {const=false ; volatile=false}, snd $1 (*TODO*) }
-
-
-/*(*----------------------------*)*/
-/*(* gccext: *)*/
-/*(*----------------------------*)*/
-
-gcc_asm_decl:
- | Tasm TOPar asmbody TCPar { }
- | Tasm Tvolatile TOPar asmbody TCPar { }
-
-
-
-
-
-/*(*-----------------------------------------------------------------------*)*/
+/*(*-----------------------------------------------------------------------*)*/
+/*(* Declarator, right part of a type + second part of decl (the ident) *)*/
+/*(*-----------------------------------------------------------------------*)*/
/*
(* declarator return a couple:
| TMul pointer { fun x ->(nQ, (Pointer ($2 x),[$1]))}
| TMul type_qualif_list pointer { fun x ->($2.qualifD, (Pointer ($3 x),[$1]))}
-type_qualif_list:
- | type_qualif { {nullDecl with qualifD = (fst $1,[snd $1])} }
- | type_qualif_list type_qualif { addQualifD ($2,$1) }
direct_d:
- | identifier
+ | identifier
{ ($1, fun x -> x) }
| TOPar declarator TCPar /*(* forunparser: old: $2 *)*/
{ (fst $2, fun x -> (nQ, (ParenType ((snd $2) x), [$1;$3]))) }
{ (fst $1,fun x->(snd $1) (nQ,(FunctionType (x, $3), [$2;$4]))) }
+/*(*----------------------------*)*/
+/*(* workarounds *)*/
+/*(*----------------------------*)*/
+
+tocro: TOCro { et "tocro" ();$1 }
+tccro: TCCro { dt "tccro" ();$1 }
+
+/*(*-----------------------------------------------------------------------*)*/
+abstract_declarator:
+ | pointer { $1 }
+ | direct_abstract_declarator { $1 }
+ | pointer direct_abstract_declarator { fun x -> x +> $2 +> $1 }
+
+direct_abstract_declarator:
+ | TOPar abstract_declarator TCPar /*(* forunparser: old: $2 *)*/
+ { (fun x -> (nQ, (ParenType ($2 x), [$1;$3]))) }
+
+ | TOCro TCCro
+ { fun x -> (nQ, (Array (None, x), [$1;$2]))}
+ | TOCro const_expr TCCro
+ { fun x -> (nQ, (Array (Some $2, x), [$1;$3]))}
+ | direct_abstract_declarator TOCro TCCro
+ { fun x ->$1 (nQ, (Array (None, x), [$2;$3])) }
+ | direct_abstract_declarator TOCro const_expr TCCro
+ { fun x ->$1 (nQ, (Array (Some $3,x), [$2;$4])) }
+ | TOPar TCPar
+ { fun x -> (nQ, (FunctionType (x, ([], (false, []))), [$1;$2])) }
+ | TOPar parameter_type_list TCPar
+ { fun x -> (nQ, (FunctionType (x, $2), [$1;$3]))}
+ | direct_abstract_declarator TOPar TCPar
+ { fun x ->$1 (nQ, (FunctionType (x, (([], (false, [])))),[$2;$3])) }
+ | direct_abstract_declarator TOPar parameter_type_list TCPar
+ { fun x -> $1 (nQ, (FunctionType (x, $3), [$2;$4])) }
+
+/*(*-----------------------------------------------------------------------*)*/
+/*(* Parameters (use decl_spec not type_spec just for 'register') *)*/
+/*(*-----------------------------------------------------------------------*)*/
parameter_type_list:
| parameter_list { ($1, (false, []))}
| parameter_list TComma TEllipsis { ($1, (true, [$2;$3])) }
(hasreg, Some (fst (fst $2)), ((snd $2) returnType)),
(iihasreg ++ [snd (fst $2)])
}
- | decl_spec abstract_declarator
+ | decl_spec abstract_declaratorp
{ let ((returnType,hasreg), iihasreg) = fixDeclSpecForParam $1
in (hasreg, None, ($2 returnType)), (iihasreg ++ [])
}
/*(* workarounds *)*/
/*(*----------------------------*)*/
-tocro: TOCro { et "tocro" ();$1 }
-tccro: TCCro { dt "tccro" ();$1 }
+parameter_decl: parameter_decl2 { et "param" (); $1 }
-topar: TOPar
- { LP.new_scope ();et "topar" ();
- !LP._lexer_hint.parameterDeclaration <- true; $1
- }
-tcpar: TCPar
- { LP.del_scope ();dt "tcpar" ();
- !LP._lexer_hint.parameterDeclaration <- false; $1
- }
+declaratorp:
+ | declarator { LP.add_ident (fst (fst $1)); $1 }
+ /*(* gccext: *)*/
+ | attributes declarator { LP.add_ident (fst (fst $2)); $2 }
+ | declarator attributes { LP.add_ident (fst (fst $1)); $1 }
-parameter_decl: parameter_decl2 { et "param" (); $1 }
+abstract_declaratorp:
+ | abstract_declarator { $1 }
+ /*(* gccext: *)*/
+ | attributes abstract_declarator { $2 }
+
+/*(*-----------------------------------------------------------------------*)*/
+/*(* helper type rules *)*/
+/*(*-----------------------------------------------------------------------*)*/
+
+/*(* for struct and also typename *)*/
+/*(* cant put decl_spec cos no storage is allowed for field struct *)*/
+spec_qualif_list2:
+ | type_spec { addTypeD ($1, nullDecl) }
+ | type_qualif { {nullDecl with qualifD = (fst $1,[snd $1])}}
+ | type_spec spec_qualif_list { addTypeD ($1,$2) }
+ | type_qualif spec_qualif_list { addQualifD ($1,$2) }
+
+spec_qualif_list: spec_qualif_list2 { dt "spec_qualif" (); $1 }
+
+
+/*(* for pointers in direct_declarator and abstract_declarator *)*/
+type_qualif_list:
+ | type_qualif_attr { {nullDecl with qualifD = (fst $1,[snd $1])} }
+ | type_qualif_list type_qualif_attr { addQualifD ($2,$1) }
-declaratorp: declarator
- { LP.add_ident (fst (fst $1)); $1 }
+
+
+
+/*(*-----------------------------------------------------------------------*)*/
+/*(* xxx_type_id *)*/
/*(*-----------------------------------------------------------------------*)*/
+
type_name:
| spec_qualif_list
{ let (returnType, _) = fixDeclSpecForDecl $1 in returnType }
- | spec_qualif_list abstract_declarator
+ | spec_qualif_list abstract_declaratort
{ let (returnType, _) = fixDeclSpecForDecl $1 in $2 returnType }
-abstract_declarator:
- | pointer { $1 }
- | direct_abstract_declarator { $1 }
- | pointer direct_abstract_declarator { fun x -> x +> $2 +> $1 }
-direct_abstract_declarator:
- | TOPar abstract_declarator TCPar /*(* forunparser: old: $2 *)*/
- { (fun x -> (nQ, (ParenType ($2 x), [$1;$3]))) }
+abstract_declaratort:
+ | abstract_declarator { $1 }
+ /*(* gccext: *)*/
+ | attributes abstract_declarator { $2 }
+
+
+/*(*************************************************************************)*/
+/*(* declaration and initializers *)*/
+/*(*************************************************************************)*/
+
+decl2:
+ | decl_spec TPtVirg
+ { function local ->
+ let (returnType,storage) = fixDeclSpecForDecl $1 in
+ let iistart = Ast_c.fakeInfo () in
+ DeclList ([{v_namei = None; v_type = returnType;
+ v_storage = unwrap storage; v_local = local;
+ v_attr = Ast_c.noattr;
+ },[]],
+ ($2::iistart::snd storage))
+ }
+ | decl_spec init_declarator_list TPtVirg
+ { function local ->
+ let (returnType,storage) = fixDeclSpecForDecl $1 in
+ let iistart = Ast_c.fakeInfo () in
+ DeclList (
+ ($2 +> List.map (fun (((((s,iis),f),attrs), ini), iivirg) ->
+ let ini, iini =
+ match ini with
+ | None -> None, []
+ | Some (ini, iini) -> Some ini, [iini]
+ in
+ if fst (unwrap storage) = StoTypedef
+ then LP.add_typedef s;
+ {v_namei = Some ((s, ini), iis::iini);
+ v_type = f returnType;
+ v_storage = unwrap storage;
+ v_local = local;
+ v_attr = attrs;
+ },
+ iivirg
+ )
+ ), ($3::iistart::snd storage))
+ }
+ /*(* cppext: *)*/
+
+ | TMacroDecl TOPar argument_list TCPar TPtVirg
+ { function _ ->
+ MacroDecl ((fst $1, $3), [snd $1;$2;$4;$5;fakeInfo()]) }
+ | Tstatic TMacroDecl TOPar argument_list TCPar TPtVirg
+ { function _ ->
+ MacroDecl ((fst $2, $4), [snd $2;$3;$5;$6;fakeInfo();$1]) }
+ | Tstatic TMacroDeclConst TMacroDecl TOPar argument_list TCPar TPtVirg
+ { function _ ->
+ MacroDecl ((fst $3, $5), [snd $3;$4;$6;$7;fakeInfo();$1;$2])}
+
+
+/*(*-----------------------------------------------------------------------*)*/
+decl_spec2:
+ | storage_class_spec { {nullDecl with storageD = (fst $1, [snd $1]) } }
+ | type_spec { addTypeD ($1,nullDecl) }
+ | type_qualif { {nullDecl with qualifD = (fst $1, [snd $1]) } }
+ | Tinline { {nullDecl with inlineD = (true, [$1]) } }
+ | storage_class_spec decl_spec2 { addStorageD ($1, $2) }
+ | type_spec decl_spec2 { addTypeD ($1, $2) }
+ | type_qualif decl_spec2 { addQualifD ($1, $2) }
+ | Tinline decl_spec2 { addInlineD ((true, $1), $2) }
+
+/*(* can simplify by putting all in _opt ? must have at least one otherwise
+ * decl_list is ambiguous ? (no cos have ';' between decl)
+ *)*/
+
+
+storage_class_spec2:
+ | Tstatic { Sto Static, $1 }
+ | Textern { Sto Extern, $1 }
+ | Tauto { Sto Auto, $1 }
+ | Tregister { Sto Register,$1 }
+ | Ttypedef { StoTypedef, $1 }
+
+storage_class_spec:
+ /*(* gccext: *)*/
+ | storage_class_spec2 { $1 }
+ | storage_class_spec2 attributes_storage { $1 (* TODO *) }
+
+
+
+/*(*----------------------------*)*/
+/*(* workarounds *)*/
+/*(*----------------------------*)*/
+
+decl: decl2 { et "decl" (); $1 }
+decl_spec: decl_spec2 { dt "declspec" (); $1 }
+
+/*(*-----------------------------------------------------------------------*)*/
+/*(* declarators (right part of type and variable) *)*/
+/*(*-----------------------------------------------------------------------*)*/
+init_declarator2:
+ | declaratori { ($1, None) }
+ | declaratori teq initialize { ($1, Some ($3, $2)) }
+
+
+
+/*(*----------------------------*)*/
+/*(* workarounds *)*/
+/*(*----------------------------*)*/
+teq: TEq { et "teq" (); $1 }
+
+init_declarator: init_declarator2 { dt "init" (); $1 }
+
+
+/*(*----------------------------*)*/
+/*(* gccext: *)*/
+/*(*----------------------------*)*/
+
+declaratori:
+ | declarator { LP.add_ident (fst (fst $1)); $1, Ast_c.noattr }
+ /*(* gccext: *)*/
+ | declarator gcc_asm_decl { LP.add_ident (fst (fst $1)); $1, Ast_c.noattr }
+ /*(* gccext: *)*/
+ | attributes declarator { LP.add_ident (fst (fst $2)); $2, $1 }
+ | declarator attributes { LP.add_ident (fst (fst $1)); $1, Ast_c.noattr (* TODO *) }
+
+
+
+gcc_asm_decl:
+ | Tasm TOPar asmbody TCPar { }
+ | Tasm Tvolatile TOPar asmbody TCPar { }
+
- | TOCro TCCro
- { fun x -> (nQ, (Array (None, x), [$1;$2]))}
- | TOCro const_expr TCCro
- { fun x -> (nQ, (Array (Some $2, x), [$1;$3]))}
- | direct_abstract_declarator TOCro TCCro
- { fun x ->$1 (nQ, (Array (None, x), [$2;$3])) }
- | direct_abstract_declarator TOCro const_expr TCCro
- { fun x ->$1 (nQ, (Array (Some $3,x), [$2;$4])) }
- | TOPar TCPar
- { fun x -> (nQ, (FunctionType (x, ([], (false, []))), [$1;$2])) }
- | TOPar parameter_type_list TCPar
- { fun x -> (nQ, (FunctionType (x, $2), [$1;$3]))}
- | direct_abstract_declarator TOPar TCPar
- { fun x ->$1 (nQ, (FunctionType (x, (([], (false, [])))),[$2;$3])) }
- | direct_abstract_declarator TOPar parameter_type_list TCPar
- { fun x -> $1 (nQ, (FunctionType (x, $3), [$2;$4])) }
-
/*(*-----------------------------------------------------------------------*)*/
initialize:
| assign_expr
{ InitExpr $1, [] }
- | tobrace_ini initialize_list gcc_comma_opt_struct TCBrace
+ | tobrace_ini initialize_list gcc_comma_opt_struct tcbrace_ini
{ InitList (List.rev $2), [$1;$4]++$3 }
- | tobrace_ini TCBrace
+ | tobrace_ini tcbrace_ini
{ InitList [], [$1;$2] } /*(* gccext: *)*/
initialize2:
| cond_expr
{ InitExpr $1, [] }
- | tobrace_ini initialize_list gcc_comma_opt_struct TCBrace
+ | tobrace_ini initialize_list gcc_comma_opt_struct tcbrace_ini
{ InitList (List.rev $2), [$1;$4]++$3 }
- | tobrace_ini TCBrace
+ | tobrace_ini tcbrace_ini
{ InitList [], [$1;$2] }
/*(* gccext: labeled elements, a.k.a designators *)*/
/*(* gccext: old format *)*/
| ident TDotDot initialize2
{ InitFieldOld (fst $1, $3), [snd $1; $2] } /*(* in old kernel *)*/
+/* conflict
| TOCro const_expr TCCro initialize2
{ InitIndexOld ($2, $4), [$1;$3] }
+*/
+
+
/*(* they can be nested, can have a .x.[3].y *)*/
designator:
| /*(* empty *)*/ { [Ast_c.fakeInfo() +> Ast_c.rewrap_str ","] }
-tobrace_ini: TOBrace { !LP._lexer_hint.toplevel <- false; $1 }
-/*(*-----------------------------------------------------------------------*)*/
+/*(*************************************************************************)*/
+/*(* struct *)*/
+/*(*************************************************************************)*/
+
s_or_u_spec2:
| struct_or_union ident tobrace_struct struct_decl_list_gcc tcbrace_struct
{ StructUnion (fst $1, Some (fst $2), $4), [snd $1;snd $2;$3;$5] }
struct_or_union2:
| Tstruct { Struct, $1 }
| Tunion { Union, $1 }
+ /*(* gccext: *)*/
+ | Tstruct attributes { Struct, $1 (* TODO *) }
+ | Tunion attributes { Union, $1 (* TODO *) }
struct_decl2:
+ | field_declaration { DeclarationField $1, noii }
+ | TPtVirg { EmptyField, [$1] }
+ | TMacroStructDecl { MacroStructDeclTodo, [] }
+
+ /*(* cppext: *)*/
+ | cpp_directive
+ { CppDirectiveStruct $1, noii }
+ | cpp_ifdef_directive/*(* struct_decl_list ... *)*/
+ { IfdefStruct $1, noii }
+
+
+field_declaration:
| spec_qualif_list struct_declarator_list TPtVirg
{
let (returnType,storage) = fixDeclSpecForDecl $1 in
FieldDeclList ($2 +> (List.map (fun (f, iivirg) ->
f returnType, iivirg))
- ), [$3]
+ ,[$3])
(* dont need to check if typedef or func initialised cos
* grammar dont allow typedef nor initialiser in struct
*)
}
-
| spec_qualif_list TPtVirg
{
(* gccext: allow empty elements if it is a structdef or enumdef *)
if fst (unwrap storage) <> NoSto
then internal_error "parsing dont allow this";
- FieldDeclList [(Simple (None, returnType), []) , []], [$2]
+ FieldDeclList ([(Simple (None, returnType), []) , []], [$2])
}
- | TPtVirg { EmptyField, [$1] }
+
+
/*(*----------------------------*)*/
/*(* workarounds *)*/
/*(*----------------------------*)*/
-tobrace_struct: TOBrace
- { !LP._lexer_hint.toplevel <- false;
- !LP._lexer_hint.structDefinition <- !LP._lexer_hint.structDefinition +1;
- $1
- }
-tcbrace_struct: TCBrace
- {
- !LP._lexer_hint.structDefinition <- !LP._lexer_hint.structDefinition -1;
- $1
- }
+declaratorsd:
+ | declarator { (*also ? LP.add_ident (fst (fst $1)); *) $1 }
+ /*(* gccext: *)*/
+ | attributes declarator { $2 }
+ | declarator attributes { $1 }
-declaratorsd: declarator
- { (*also ? LP.add_ident (fst (fst $1)); *) $1 }
| /*(* empty *)*/ { [] } /*(* gccext: allow empty struct *)*/
-/*(*-----------------------------------------------------------------------*)*/
+/*(*************************************************************************)*/
+/*(* enum *)*/
+/*(*************************************************************************)*/
enum_spec:
- | Tenum tobrace_enum enumerator_list gcc_comma_opt TCBrace
+ | Tenum tobrace_enum enumerator_list gcc_comma_opt tcbrace_enum
{ Enum (None, $3), [$1;$2;$5] ++ $4 }
- | Tenum ident tobrace_enum enumerator_list gcc_comma_opt TCBrace
+ | Tenum ident tobrace_enum enumerator_list gcc_comma_opt tcbrace_enum
{ Enum (Some (fst $2), $4), [$1; snd $2; $3;$6] ++ $5 }
| Tenum ident
{ EnumName (fst $2), [$1; snd $2] }
idente: ident { LP.add_ident (fst $1); $1 }
-tobrace_enum: TOBrace { !LP._lexer_hint.toplevel <- false; $1 }
-
/*(*************************************************************************)*/
-/*(* xxx_list, xxx_opt *)*/
+/*(* function *)*/
/*(*************************************************************************)*/
+function_definition: function_def { fixFunc $1 }
-
-/*(*
decl_list:
| decl { [$1] }
| decl_list decl { $1 ++ [$2] }
-statement_list:
- | statement { [$1] }
- | statement_list statement { $1 ++ [$2] }
-*)*/
+function_def:
+ | start_fun compound { LP.del_scope(); ($1, $2) }
+ | start_fun decl_list compound {
+ pr2 "OLD STYLE DECL NOT WELL SUPPORTED";
+ (* TODO: undo the typedef added ? *)
+ LP.del_scope();
+ ($1, $3)
+ }
+
+start_fun: start_fun2
+ { LP.new_scope();
+ fix_add_params_ident $1;
+ (* toreput? !LP._lexer_hint.toplevel <- false; *)
+ $1
+ }
+
+start_fun2: decl_spec declaratorfd
+ { let (returnType,storage) = fixDeclSpecForFuncDef $1 in
+ let (id, attrs) = $2 in
+ (fst id, fixOldCDecl ((snd id) returnType) , storage, attrs)
+ }
+
+/*(*----------------------------*)*/
+/*(* workarounds *)*/
+/*(*----------------------------*)*/
+
+declaratorfd:
+ | declarator { et "declaratorfd" (); $1, Ast_c.noattr }
+ /*(* gccext: *)*/
+ | attributes declarator { et "declaratorfd" (); $2, $1 }
+ | declarator attributes { et "declaratorfd" (); $1, Ast_c.noattr }
+
+
+
+/*(*************************************************************************)*/
+/*(* cpp directives *)*/
+/*(*************************************************************************)*/
+
+cpp_directive:
+ | TIncludeStart TIncludeFilename
+ {
+ let (i1, in_ifdef) = $1 in
+ let (s, i2) = $2 in
+
+ (* redo some lexing work :( *)
+ let inc_file =
+ match () with
+ | _ when s =~ "^\"\\(.*\\)\"$" ->
+ Local (Common.split "/" (matched1 s))
+ | _ when s =~ "^\\<\\(.*\\)\\>$" ->
+ NonLocal (Common.split "/" (matched1 s))
+ | _ ->
+ Wierd s
+ in
+ Include { i_include = (inc_file, [i1;i2]);
+ i_rel_pos = Ast_c.noRelPos();
+ i_is_in_ifdef = !in_ifdef;
+ i_content = Ast_c.noi_content;
+ }
+ }
+
+ | TDefine TIdentDefine define_val TDefEOL
+ { Define ((fst $2, [$1; snd $2;$4]), (DefineVar, $3)) }
+
+ /*
+ (* The TOParDefine is introduced to avoid ambiguity with previous rules.
+ * A TOParDefine is a TOPar that was just next to the ident.
+ *)*/
+ | TDefine TIdentDefine TOParDefine param_define_list TCPar define_val TDefEOL
+ { Define
+ ((fst $2, [$1; snd $2;$7]),
+ (DefineFunc ($4, [$3;$5]), $6))
+ }
+
+ | TUndef { Undef (fst $1, [snd $1]) }
+ | TCppDirectiveOther { PragmaAndCo ([$1]) }
+
+/*(* perhaps better to use assign_expr ? but in that case need
+ * do a assign_expr_of_string in parse_c
+ *)*/
+define_val:
+ | expr { DefineExpr $1 }
+ | statement { DefineStmt $1 }
+ | decl { DefineStmt (Decl ($1 Ast_c.NotLocalDecl), []) }
+
+/*(*old: | TypedefIdent { DefineType (nQ,(TypeName(fst $1,noTypedefDef()),[snd $1]))}*)*/
+ | spec_qualif_list { DefineTodo }
+ | function_definition { DefineFunction $1 }
+
+ | TOBraceDefineInit initialize_list gcc_comma_opt_struct TCBrace comma_opt
+ { DefineInit (InitList (List.rev $2), [$1;$4]++$3++$5) }
+
+ /*(* note: had a conflict before when were putting TInt instead of expr *)*/
+ | Tdo statement Twhile TOPar expr TCPar
+ {
+ (* TOREPUT
+ if fst $5 <> "0"
+ then pr2 "WIERD: in macro and have not a while(0)";
+ *)
+ DefineDoWhileZero (($2,$5), [$1;$3;$4;$6])
+ }
+
+ /*(* a few special cases *)*/
+ | stat_or_decl stat_or_decl_list { DefineTodo }
+/*
+ | statement statement { DefineTodo }
+ | decl function_definition { DefineTodo }
+*/
+
+ | Tasm TOPar asmbody TCPar { DefineTodo }
+ | Tasm Tvolatile TOPar asmbody TCPar { DefineTodo }
+
+
+ /*(* aliases macro *)*/
+ | TMacroAttr { DefineTodo }
+ | storage_class_spec { DefineTodo }
+ | Tinline { DefineTodo }
+
+ | /*(* empty *)*/ { DefineEmpty }
+
+
+param_define:
+ | TIdent { fst $1, [snd $1] }
+ | TypedefIdent { fst $1, [snd $1] }
+ | TDefParamVariadic { fst $1, [snd $1] }
+ | TEllipsis { "...", [$1] }
+ /*(* they reuse keywords :( *)*/
+ | Tregister { "register", [$1] }
+
+
+
+
+cpp_ifdef_directive:
+ | TIfdef
+ { let (tag,ii) = $1 in
+ IfdefDirective ((Ifdef, IfdefTag (Common.some !tag)), [ii]) }
+ | TIfdefelse
+ { let (tag,ii) = $1 in
+ IfdefDirective ((IfdefElse, IfdefTag (Common.some !tag)), [ii]) }
+ | TIfdefelif
+ { let (tag,ii) = $1 in
+ IfdefDirective ((IfdefElseif, IfdefTag (Common.some !tag)), [ii]) }
+ | TEndif
+ { let (tag,ii) = $1 in
+ IfdefDirective ((IfdefEndif, IfdefTag (Common.some !tag)), [ii]) }
+
+ | TIfdefBool
+ { let (_b, tag,ii) = $1 in
+ IfdefDirective ((Ifdef, IfdefTag (Common.some !tag)), [ii]) }
+ | TIfdefMisc
+ { let (_b, tag,ii) = $1 in
+ IfdefDirective ((Ifdef, IfdefTag (Common.some !tag)), [ii]) }
+ | TIfdefVersion
+ { let (_b, tag,ii) = $1 in
+ IfdefDirective ((Ifdef, IfdefTag (Common.some !tag)), [ii]) }
+
+
+/*(* cppext: *)*/
+cpp_other:
+ /*(* no conflict ? no need for a TMacroTop ? apparently not as at toplevel
+ * the rule are slightly different, they cant be statement and so expr
+ * at the top, only decl or function definition.
+ *)*/
+ | identifier TOPar argument_list TCPar TPtVirg
+ { MacroTop (fst $1, $3, [snd $1;$2;$4;$5]) }
+
+ /*(* TCParEOL to fix the end-of-stream bug of ocamlyacc *)*/
+ | identifier TOPar argument_list TCParEOL
+ { MacroTop (fst $1, $3, [snd $1;$2;$4;fakeInfo()]) }
+
+ /*(* ex: EXPORT_NO_SYMBOLS; *)*/
+ | identifier TPtVirg { EmptyDef [snd $1;$2] }
+
+
+
+/*(*************************************************************************)*/
+/*(* celem *)*/
+/*(*************************************************************************)*/
+
+external_declaration:
+ | function_definition { Definition $1 }
+ | decl { Declaration ($1 Ast_c.NotLocalDecl) }
+
+
+celem:
+ | external_declaration { $1 }
+
+ /*(* cppext: *)*/
+ | cpp_directive
+ { CppTop $1 }
+ | cpp_other
+ { $1 }
+ | cpp_ifdef_directive /* (*external_declaration_list ...*)*/
+ { IfdefTop $1 }
+
+ /*(* can have asm declaration at toplevel *)*/
+ | Tasm TOPar asmbody TCPar TPtVirg { EmptyDef [$1;$2;$4;$5] }
+
+ /*
+ (* in ~/kernels/src/linux-2.5.2/drivers/isdn/hisax/isdnl3.c sometimes
+ * the function ends with }; instead of just }
+ * can also remove this rule and report "parse error" pb to morton
+ *)*/
+ | TPtVirg { EmptyDef [$1] }
+
+
+ | EOF { FinalDef $1 }
+
+
+
+
+/*(*************************************************************************)*/
+/*(* some generic workarounds *)*/
+/*(*************************************************************************)*/
+
+tobrace: TOBrace { LP.push_context LP.InFunction; LP.new_scope (); $1 }
+tcbrace: TCBrace { LP.pop_context(); LP.del_scope (); $1 }
+
+tobrace_enum: TOBrace { LP.push_context LP.InEnum; $1 }
+tcbrace_enum: TCBrace { LP.pop_context (); $1 }
+
+tobrace_ini: TOBrace { LP.push_context LP.InInitializer; $1 }
+tcbrace_ini: TCBrace { LP.pop_context (); $1 }
+
+tobrace_struct: TOBrace { LP.push_context LP.InStruct; $1}
+tcbrace_struct: TCBrace { LP.pop_context (); $1 }
+
+
+
+
+topar: TOPar
+ { LP.new_scope ();et "topar" ();
+ LP.push_context LP.InParameter;
+ $1
+ }
+tcpar: TCPar
+ { LP.del_scope ();dt "tcpar" ();
+ LP.pop_context ();
+ $1
+ }
+
+
+
+
+/*(*************************************************************************)*/
+/*(* xxx_list, xxx_opt *)*/
+/*(*************************************************************************)*/
+
+
+/*(* old:
+compound2:
+ | { ([],[]) }
+ | statement_list { ([], $1) }
+ | decl_list { ($1, []) }
+ | decl_list statement_list { ($1,$2) }
+
+statement_list: stat_or_decl_list { $1 }
+*)*/
+
+
+/*(*
+decl_list:
+ | decl { [$1] }
+ | decl_list decl { $1 ++ [$2] }
+
+statement_list:
+ | statement { [$1] }
+ | statement_list statement { $1 ++ [$2] }
+*)*/
-stat_or_decl_list:
- | stat_or_decl { [$1] }
- | end_labeled { [Labeled (fst $1), snd $1] }
- | stat_or_decl stat_or_decl_list { $1 :: $2 }
| colon_option_list TComma colon_option { $1 ++ [$3, [$2]] }
-
argument_list_ne:
| argument_ne { [$1, []] }
| argument_list_ne TComma argument { $1 ++ [$3, [$2]] }
| TAction taction_list_ne { $1 :: $2 }
taction_list:
+/*old: was generating conflict, hence now taction_list_ne
+ | (* empty *) { [] }
+ | TAction { [$1] }
+ | taction_list TAction { $1 ++ [$2] }
+*/
| { [] }
| TAction taction_list { $1 :: $2 }
| designator { [$1] }
| designator_list designator { $1 ++ [$2] }
+attribute_list:
+ | attribute { [$1] }
+ | attribute_list attribute { $1 ++ [$2] }
+
+attribute_storage_list:
+ | attribute_storage { [$1] }
+ | attribute_storage_list attribute_storage { $1 ++ [$2] }
+
+
+attributes: attribute_list { $1 }
+
+attributes_storage: attribute_storage_list { $1 }
+
/*(* gccext: which allow a trailing ',' in enum, as in perl *)*/
gcc_comma_opt:
| TComma { [$1] }
| /*(* empty *)*/ { [] }
+comma_opt:
+ | TComma { [$1] }
+ | /*(* empty *)*/ { [] }
+
/*(*
gcc_opt_virg:
| TPtVirg { }
*)*/
-/*(*************************************************************************)*/
-/*(* cpp directives *)*/
-/*(*************************************************************************)*/
-
-/*(* cppext: *)*/
-cpp_directive:
-
- | identifier TOPar argument_list TCPar TPtVirg
- { MacroTop (fst $1, $3, [snd $1;$2;$4;$5]) }
-
- /*(* TCParEOL to fix the end-of-stream bug of ocamlyacc *)*/
- | identifier TOPar argument_list TCParEOL
- { MacroTop (fst $1, $3, [snd $1;$2;$4;fakeInfo()]) }
-
- /*(* ex: EXPORT_NO_SYMBOLS; *)*/
- | identifier TPtVirg { EmptyDef [snd $1;$2] }
-
- | TIncludeStart TIncludeFilename
- {
- let (i1, in_ifdef) = $1 in
- let (s, i2) = $2 in
-
- (* redo some lexing work :( *)
- let inc_file =
- match () with
- | _ when s =~ "^\"\\(.*\\)\"$" ->
- Local (Common.split "/" (matched1 s))
- | _ when s =~ "^\\<\\(.*\\)\\>$" ->
- NonLocal (Common.split "/" (matched1 s))
- | _ ->
- Wierd s
- in
- Include ((inc_file, [i1;i2]), (Ast_c.noRelPos(), !in_ifdef))
- }
-
- | TDefine TIdentDefine define_val TDefEOL
- { Define ((fst $2, [$1; snd $2;$4]), (DefineVar, $3)) }
-
- /*
- (* The TOParDefine is introduced to avoid ambiguity with previous rules.
- * A TOParDefine is a TOPar that was just next to the ident.
- *)*/
- | TDefine TIdentDefine TOParDefine param_define_list TCPar define_val TDefEOL
- { Define
- ((fst $2, [$1; snd $2;$7]),
- (DefineFunc ($4, [$3;$5]), $6))
- }
-
-
-/*(* perhaps better to use assign_expr ? but in that case need
- * do a assign_expr_of_string in parse_c
- *)*/
-define_val:
- | expr { DefineExpr $1 }
- | statement { DefineStmt $1 }
- | decl { DefineStmt (Decl ($1 Ast_c.NotLocalDecl), []) }
- | TypedefIdent { DefineType (nQ,(TypeName(fst $1,noTypedefDef()),[snd $1]))}
- | function_definition { DefineFunction $1 }
-
- | Tdo statement Twhile TOPar TInt TCPar
- {
- if fst $5 <> "0"
- then pr2 "WIERD: in macro and have not a while(0)";
- DefineDoWhileZero ($2, [$1;$3;$4;snd $5;$6])
- }
- | /*(* empty *)*/ { DefineEmpty }
-
-param_define:
- | identifier { fst $1, [snd $1] }
- | TypedefIdent { fst $1, [snd $1] }
- | TDefParamVariadic { fst $1, [snd $1] }
- | TEllipsis { "...", [$1] }
- /*(* they reuse keywords :( *)*/
- | Tregister { "register", [$1] }
-
-
-/*(*************************************************************************)*/
-/*(* celem *)*/
-/*(*************************************************************************)*/
-
-external_declaration:
- | function_definition { Definition $1 }
- | decl { Declaration ($1 Ast_c.NotLocalDecl) }
-
-function_definition: function_def { fixFunc $1 }
-
-function_def: start_fun compound { LP.del_scope(); ($1, $2) }
-
-start_fun: start_fun2
- { LP.new_scope();
- fix_add_params_ident $1;
- !LP._lexer_hint.toplevel <- false;
- $1
- }
-
-start_fun2: decl_spec declaratorfd
- { let (returnType,storage) = fixDeclSpecForFuncDef $1 in
- (fst $2, fixOldCDecl ((snd $2) returnType) , storage)
- }
-
-celem:
- | external_declaration { $1 }
- | cpp_directive { $1 }
-
- /*(* can have asm declaration at toplevel *)*/
- | Tasm TOPar asmbody TCPar TPtVirg { EmptyDef [] }
-
- /*
- (* in ~/kernels/src/linux-2.5.2/drivers/isdn/hisax/isdnl3.c sometimes
- * the function ends with }; instead of just }
- * can also remove this rule and report "parse error" pb to morton
- *)*/
- | TPtVirg { EmptyDef [$1] }
-
-
- | EOF { FinalDef $1 }
-
-
-/*(*----------------------------*)*/
-/*(* workarounds *)*/
-/*(*----------------------------*)*/
-declaratorfd: declarator { et "declaratorfd" (); $1 }
-
+expr_opt:
+ | expr { Some $1 }
+ | /*(* empty *)*/ { None }
-(* Copyright (C) 2002-2008 Yoann Padioleau
+(* Copyright (C) 2007, 2008 Yoann Padioleau
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License (GPL)
module TH = Token_helpers
module LP = Lexer_parser
-open Parser_c
+module Stat = Parsing_stat
-let acc_map f l =
- let rec loop acc = function
- [] -> List.rev acc
- | x::xs -> loop ((f x)::acc) xs in
- loop [] l
+open Parser_c
(*****************************************************************************)
(* Some debugging functions *)
then Common.pr2_once ("CPP-" ^ s)
-(* In the following, there are some harcoded names of types or macros
- * but they are not used by our heuristics! They are just here to
- * enable to detect false positive by printing only the typedef/macros
- * that we don't know yet. If we print everything, then we can easily
- * get lost with too much verbose tracing information. So those
- * functions "filter" some messages. So our heuristics are still good,
- * there is no more (or not that much) hardcoded linux stuff.
- *)
-
let msg_gen cond is_known printer s =
if cond
then
then printer s
-
-
-
-(* note: cant use partial application with let msg_typedef =
- * because it would compute msg_typedef at compile time when
- * the flag debug_typedef is always false
+(* In the following, there are some harcoded names of types or macros
+ * but they are not used by our heuristics! They are just here to
+ * enable to detect false positive by printing only the typedef/macros
+ * that we don't know yet. If we print everything, then we can easily
+ * get lost with too much verbose tracing information. So those
+ * functions "filter" some messages. So our heuristics are still good,
+ * there is no more (or not that much) hardcoded linux stuff.
*)
-let msg_typedef s =
- msg_gen (!Flag_parsing_c.debug_typedef)
+
+let is_known_typdef =
(fun s ->
(match s with
| "u_char" | "u_short" | "u_int" | "u_long"
| _ -> false
)
)
+
+(* note: cant use partial application with let msg_typedef =
+ * because it would compute msg_typedef at compile time when
+ * the flag debug_typedef is always false
+ *)
+let msg_typedef s =
+ incr Stat.nTypedefInfer;
+ msg_gen (!Flag_parsing_c.debug_typedef)
+ is_known_typdef
(fun s ->
pr2_cpp ("TYPEDEF: promoting: " ^ s)
)
s
+let msg_maybe_dangereous_typedef s =
+ if not (is_known_typdef s)
+ then
+ pr2 ("PB MAYBE: dangerous typedef inference, maybe not a typedef: " ^ s)
let msg_declare_macro s =
+ incr Stat.nMacroDecl;
msg_gen (!Flag_parsing_c.debug_cpp)
(fun s ->
(match s with
let msg_foreach s =
+ incr Stat.nIteratorHeuristic;
pr2_cpp ("MACRO: found foreach: " ^ s)
+(* ??
let msg_debug_macro s =
pr2_cpp ("MACRO: found debug-macro: " ^ s)
+*)
let msg_macro_noptvirg s =
+ incr Stat.nMacroStmt;
pr2_cpp ("MACRO: found macro with param noptvirg: " ^ s)
let msg_macro_toplevel_noptvirg s =
+ incr Stat.nMacroStmt;
pr2_cpp ("MACRO: found toplevel macro noptvirg: " ^ s)
-
let msg_macro_noptvirg_single s =
+ incr Stat.nMacroStmt;
pr2_cpp ("MACRO: found single-macro noptvirg: " ^ s)
+
+
let msg_macro_higher_order s =
+ incr Stat.nMacroHigherOrder;
msg_gen (!Flag_parsing_c.debug_cpp)
(fun s ->
(match s with
let msg_stringification s =
+ incr Stat.nMacroString;
msg_gen (!Flag_parsing_c.debug_cpp)
(fun s ->
(match s with
(fun s -> pr2_cpp ("MACRO: found string-macro " ^ s))
s
+let msg_stringification_params s =
+ incr Stat.nMacroString;
+ pr2_cpp ("MACRO: string-macro with params : " ^ s)
+
+
+
+let msg_apply_known_macro s =
+ incr Stat.nMacroExpand;
+ pr2_cpp ("MACRO: found known macro = " ^ s)
+
+let msg_apply_known_macro_hint s =
+ incr Stat.nMacroHint;
+ pr2_cpp ("MACRO: found known macro hint = " ^ s)
+
+
+let msg_ifdef_bool_passing is_ifdef_positif =
+ incr Stat.nIfdefZero; (* of Version ? *)
+ if is_ifdef_positif
+ then pr2_cpp "commenting parts of a #if 1 or #if LINUX_VERSION"
+ else pr2_cpp "commenting a #if 0 or #if LINUX_VERSION or __cplusplus"
+
+
+let msg_ifdef_mid_something () =
+ incr Stat.nIfdefExprPassing;
+ pr2_cpp "found ifdef-mid-something"
+
+let msg_ifdef_funheaders () =
+ incr Stat.nIfdefFunheader;
+ ()
+
+let msg_ifdef_passing () =
+ pr2_cpp("IFDEF: or related outside function. I treat it as comment");
+ incr Stat.nIfdefPassing;
+ ()
+
+let msg_attribute s =
+ incr Stat.nMacroAttribute;
+ pr2_cpp("ATTR:" ^ s)
+
+
+
(*****************************************************************************)
-(* CPP handling: macros, ifdefs, macros defs *)
+(* The regexp and basic view definitions *)
(*****************************************************************************)
(* opti: better to built then once and for all, especially regexp_foreach *)
let regexp_typedef = Str.regexp
".*_t$"
-
let false_typedef = [
"printk";
]
-type define_body = (unit,string list) either * Parser_c.token list
-let (_defs : (string, define_body) Hashtbl.t ref) =
+let ok_typedef s = not (List.mem s false_typedef)
+
+let not_annot s =
+ not (s ==~ regexp_annot)
+
+
+(* ------------------------------------------------------------------------- *)
+(* cpp part 1 for standard.h *)
+(* ------------------------------------------------------------------------- *)
+
+type define_def = string * define_param * define_body
+ and define_param =
+ | NoParam
+ | Params of string list
+ and define_body =
+ | DefineBody of Parser_c.token list
+ | DefineHint of parsinghack_hint
+
+ and parsinghack_hint =
+ | HintIterator
+ | HintDeclarator
+ | HintMacroString
+ | HintMacroStatement
+ | HintAttribute
+
+
+(* cf also data/test.h *)
+let assoc_hint_string = [
+ "YACFE_ITERATOR" , HintIterator;
+ "YACFE_DECLARATOR" , HintDeclarator;
+ "YACFE_STRING" , HintMacroString;
+ "YACFE_STATEMENT" , HintMacroStatement;
+ "YACFE_ATTRIBUTE" , HintAttribute;
+ "MACROSTATEMENT" , HintMacroStatement; (* backward compatibility *)
+]
+
+
+let (parsinghack_hint_of_string: string -> parsinghack_hint option) = fun s ->
+ Common.assoc_option s assoc_hint_string
+
+let (is_parsinghack_hint: string -> bool) = fun s ->
+ parsinghack_hint_of_string s <> None
+
+let (token_from_parsinghack_hint:
+ (string * Ast_c.info) -> parsinghack_hint -> Parser_c.token) =
+ fun (s,ii) hint ->
+ match hint with
+ | HintIterator ->
+ Parser_c.TMacroIterator (s, ii)
+ | HintDeclarator ->
+ Parser_c.TMacroDecl (s, ii)
+ | HintMacroString ->
+ Parser_c.TMacroString (s, ii)
+ | HintMacroStatement ->
+ Parser_c.TMacroStmt (s, ii)
+ | HintAttribute ->
+ Parser_c.TMacroAttr (s, ii)
+
+
+
+let (_defs : (string, define_def) Hashtbl.t ref) =
ref (Hashtbl.create 101)
| TIfdef _ ->
let body, extra, xs = mk_ifdef_parameters [x] [] xs in
Ifdef (body, extra)::mk_ifdef xs
- | TIfdefBool (b,_) ->
+ | TIfdefBool (b,_, _) ->
let body, extra, xs = mk_ifdef_parameters [x] [] xs in
(* if not passing, then consider a #if 0 as an ordinary #ifdef *)
then Ifdefbool (b, body, extra)::mk_ifdef xs
else Ifdef(body, extra)::mk_ifdef xs
- | TIfdefMisc (b,_) | TIfdefVersion (b,_) ->
+ | TIfdefMisc (b,_,_) | TIfdefVersion (b,_,_) ->
let body, extra, xs = mk_ifdef_parameters [x] [] xs in
Ifdefbool (b, body, extra)::mk_ifdef xs
mk_ifdef_parameters
extras (Ifdef (body, extrasnest)::acc_before_sep) xs
- | TIfdefBool (b,_) ->
+ | TIfdefBool (b,_,_) ->
let body, extrasnest, xs = mk_ifdef_parameters [x] [] xs in
if !Flag_parsing_c.if0_passing
extras (Ifdef (body, extrasnest)::acc_before_sep) xs
- | TIfdefMisc (b,_) | TIfdefVersion (b,_) ->
+ | TIfdefMisc (b,_,_) | TIfdefVersion (b,_,_) ->
let body, extrasnest, xs = mk_ifdef_parameters [x] [] xs in
mk_ifdef_parameters
extras (Ifdefbool (b, body, extrasnest)::acc_before_sep) xs
end
+(*****************************************************************************)
+(* Helpers *)
+(*****************************************************************************)
+
+(* To expand the parameter of the macro. The env corresponds to the actual
+ * code that is binded to the parameters of the macro.
+ * TODO? recurse ? fixpoint ? the expansion may also contain macro.
+ * Or to macro expansion in a strict manner, that is process first
+ * the parameters, expands macro in params, and then process enclosing
+ * macro call.
+ *)
+let rec (cpp_engine: (string , Parser_c.token list) assoc ->
+ Parser_c.token list -> Parser_c.token list) =
+ fun env xs ->
+ xs +> List.map (fun tok ->
+ match tok with
+ | TIdent (s,i1) when List.mem_assoc s env -> Common.assoc s env
+ | x -> [x]
+ )
+ +> List.flatten
+
+
+
+
+(* ------------------------------------------------------------------------- *)
+(* the pair is the status of '()' and '{}', ex: (-1,0)
+ * if too much ')' and good '{}'
+ * could do for [] too ?
+ * could do for ',' if encounter ',' at "toplevel", not inside () or {}
+ * then if have ifdef, then certainly can lead to a problem.
+ *)
+let (count_open_close_stuff_ifdef_clause: ifdef_grouped list -> (int * int)) =
+ fun xs ->
+ let cnt_paren, cnt_brace = ref 0, ref 0 in
+ xs +> iter_token_ifdef (fun x ->
+ (match x.tok with
+ | x when TH.is_opar x -> incr cnt_paren
+ | TOBrace _ -> incr cnt_brace
+ | x when TH.is_cpar x -> decr cnt_paren
+ | TCBrace _ -> decr cnt_brace
+ | _ -> ()
+ )
+ );
+ !cnt_paren, !cnt_brace
+
+
+(* ------------------------------------------------------------------------- *)
+let forLOOKAHEAD = 30
+
+
+(* look if there is a '{' just after the closing ')', and handling the
+ * possibility to have nested expressions inside nested parenthesis
+ *
+ * todo: use indentation instead of premier(statement) ?
+ *)
+let rec is_really_foreach xs =
+ let rec is_foreach_aux = function
+ | [] -> false, []
+ | TCPar _::TOBrace _::xs -> true, xs
+ (* the following attempts to handle the cases where there is a
+ single statement in the body of the loop. undoubtedly more
+ cases are needed.
+ todo: premier(statement) - suivant(funcall)
+ *)
+ | TCPar _::TIdent _::xs -> true, xs
+ | TCPar _::Tif _::xs -> true, xs
+ | TCPar _::Twhile _::xs -> true, xs
+ | TCPar _::Tfor _::xs -> true, xs
+ | TCPar _::Tswitch _::xs -> true, xs
+ | TCPar _::Treturn _::xs -> true, xs
+
+
+ | TCPar _::xs -> false, xs
+ | TOPar _::xs ->
+ let (_, xs') = is_foreach_aux xs in
+ is_foreach_aux xs'
+ | x::xs -> is_foreach_aux xs
+ in
+ is_foreach_aux xs +> fst
+
+
+(* ------------------------------------------------------------------------- *)
+let set_ifdef_token_parenthize_info cnt x =
+ match x with
+ | TIfdef (tag, _)
+ | TIfdefelse (tag, _)
+ | TIfdefelif (tag, _)
+ | TEndif (tag, _)
+
+ | TIfdefBool (_, tag, _)
+ | TIfdefMisc (_, tag, _)
+ | TIfdefVersion (_, tag, _)
+ ->
+ tag := Some cnt;
+
+ | _ -> raise Impossible
+
+
+
+let ifdef_paren_cnt = ref 0
+
+
+let rec set_ifdef_parenthize_info xs =
+ xs +> List.iter (function
+ | NotIfdefLine xs -> ()
+ | Ifdefbool (_, xxs, info_ifdef)
+ | Ifdef (xxs, info_ifdef) ->
+
+ incr ifdef_paren_cnt;
+ let total_directives = List.length info_ifdef in
+
+ info_ifdef +> List.iter (fun x ->
+ set_ifdef_token_parenthize_info (!ifdef_paren_cnt, total_directives)
+ x.tok);
+ xxs +> List.iter set_ifdef_parenthize_info
+ )
+
+
+(*****************************************************************************)
+(* CPP handling: macros, ifdefs, macros defs *)
+(*****************************************************************************)
+
(* ------------------------------------------------------------------------- *)
(* ifdef keeping/passing *)
(* ------------------------------------------------------------------------- *)
xs +> List.iter (function
| NotIfdefLine _ -> ()
| Ifdefbool (is_ifdef_positif, xxs, info_ifdef_stmt) ->
-
- if is_ifdef_positif
- then pr2_cpp "commenting parts of a #if 1 or #if LINUX_VERSION"
- else pr2_cpp "commenting a #if 0 or #if LINUX_VERSION or __cplusplus";
+
+ msg_ifdef_bool_passing is_ifdef_positif;
(match xxs with
| [] -> raise Impossible
if is_ifdef_positif
then xxs +> List.iter
- (iter_token_ifdef (set_as_comment Ast_c.CppOther))
+ (iter_token_ifdef (set_as_comment Ast_c.CppPassingNormal))
else begin
- firstclause +> iter_token_ifdef (set_as_comment Ast_c.CppOther);
+ firstclause +> iter_token_ifdef (set_as_comment Ast_c.CppPassingNormal);
(match List.rev xxs with
(* keep only last *)
| last::startxs ->
startxs +> List.iter
- (iter_token_ifdef (set_as_comment Ast_c.CppOther))
+ (iter_token_ifdef (set_as_comment Ast_c.CppPassingNormal))
| [] -> (* not #else *) ()
);
end
-(* the pair is the status of '()' and '{}', ex: (-1,0)
- * if too much ')' and good '{}'
- * could do for [] too ?
- * could do for ',' if encounter ',' at "toplevel", not inside () or {}
- * then if have ifdef, then certainly can lead to a problem.
- *)
-let (count_open_close_stuff_ifdef_clause: ifdef_grouped list -> (int * int)) =
- fun xs ->
- let cnt_paren, cnt_brace = ref 0, ref 0 in
- xs +> iter_token_ifdef (fun x ->
- (match x.tok with
- | x when TH.is_opar x -> incr cnt_paren
- | TOBrace _ -> incr cnt_brace
- | x when TH.is_cpar x -> decr cnt_paren
- | TCBrace _ -> decr cnt_brace
- | _ -> ()
- )
- );
- !cnt_paren, !cnt_brace
-
let thresholdIfdefSizeMid = 6
(* infer ifdef involving not-closed expressions/statements *)
)
*)
then begin
- pr2_cpp "found ifdef-mid-something";
+ msg_ifdef_mid_something();
+
(* keep only first, treat the rest as comment *)
info_ifdef_stmt +> List.iter (set_as_comment Ast_c.CppDirective);
(second::rest) +> List.iter
- (iter_token_ifdef (set_as_comment Ast_c.CppOther));
+ (iter_token_ifdef (set_as_comment Ast_c.CppPassingCosWouldGetError));
end
);
List.length ifdefblock2 <= thresholdFunheaderLimit
->
find_ifdef_funheaders xs;
+
+ msg_ifdef_funheaders ();
info_ifdef_stmt +> List.iter (set_as_comment Ast_c.CppDirective);
let all_toks = [xline2] @ line2 in
- all_toks +> List.iter (set_as_comment Ast_c.CppOther) ;
- ifdefblock2 +> iter_token_ifdef (set_as_comment Ast_c.CppOther);
+ all_toks +> List.iter (set_as_comment Ast_c.CppPassingCosWouldGetError) ;
+ ifdefblock2 +> iter_token_ifdef (set_as_comment Ast_c.CppPassingCosWouldGetError);
(* ifdef with nested ifdef *)
| Ifdef
::xs
->
find_ifdef_funheaders xs;
+
+ msg_ifdef_funheaders ();
info_ifdef_stmt +> List.iter (set_as_comment Ast_c.CppDirective);
info_ifdef_stmt2 +> List.iter (set_as_comment Ast_c.CppDirective);
let all_toks = [xline2;xline3] @ line2 @ line3 in
- all_toks +> List.iter (set_as_comment Ast_c.CppOther);
+ all_toks +> List.iter (set_as_comment Ast_c.CppPassingCosWouldGetError);
(* ifdef with elseif *)
| Ifdef
::xs
->
find_ifdef_funheaders xs;
+
+ msg_ifdef_funheaders ();
info_ifdef_stmt +> List.iter (set_as_comment Ast_c.CppDirective);
let all_toks = [xline2;xline3] @ line2 @ line3 in
- all_toks +> List.iter (set_as_comment Ast_c.CppOther)
+ all_toks +> List.iter (set_as_comment Ast_c.CppPassingCosWouldGetError)
-
+ (* recurse *)
| Ifdef (xxs,info_ifdef_stmt)::xs
| Ifdefbool (_, xxs,info_ifdef_stmt)::xs ->
List.iter find_ifdef_funheaders xxs;
-
+(* ?? *)
let rec adjust_inifdef_include xs =
xs +> List.iter (function
| NotIfdefLine _ -> ()
(* ------------------------------------------------------------------------- *)
-(* cpp-builtin part1, macro, using standard.h or other defs *)
+(* cpp-builtin part2, macro, using standard.h or other defs *)
(* ------------------------------------------------------------------------- *)
(* Thanks to this function many stuff are not anymore hardcoded in ocaml code
* (but they are now hardcoded in standard.h ...)
- *)
-
-let rec (cpp_engine: (string , Parser_c.token list) assoc ->
- Parser_c.token list -> Parser_c.token list) = fun env xs ->
- xs +> List.map (fun tok ->
- match tok with
- | TIdent (s,i1) when List.mem_assoc s env -> Common.assoc s env
- | x -> [x]
- )
- +> List.flatten
-
-(* no need to take care to not substitute the macro name itself
+ *
+ *
+ *
+ * No need to take care to not substitute the macro name itself
* that occurs in the macro definition because the macro name is
* after fix_token_define a TDefineIdent, no more a TIdent.
*)
match xs with
| [] -> ()
+ (* old: "but could do more, could reuse same original token
+ * so that have in the Ast a Dbg, not a MACROSTATEMENT"
+ *
+ * | PToken ({tok = TIdent (s,i1)} as id)::xs
+ * when s = "MACROSTATEMENT" ->
+ *
+ * msg_macro_statement_hint s;
+ * id.tok <- TMacroStmt(TH.info_of_tok id.tok);
+ * find_macro_paren xs
+ *
+ * let msg_macro_statement_hint s =
+ * incr Stat.nMacroHint;
+ * ()
+ *
+ *)
+
(* recognized macro of standard.h (or other) *)
| PToken ({tok = TIdent (s,i1)} as id)::Parenthised (xxs,info_parens)::xs
when Hashtbl.mem !_defs s ->
- pr2_cpp ("MACRO: found known macro = " ^ s);
- (match Hashtbl.find !_defs s with
- | Left (), bodymacro ->
- pr2 ("macro without param used before parenthize, wierd: " ^ s);
- (* ex: PRINTP("NCR53C400 card%s detected\n" ANDP(((struct ... *)
- set_as_comment (Ast_c.CppMacro) id;
- id.new_tokens_before <- bodymacro;
- | Right params, bodymacro ->
- if List.length params = List.length xxs
- then
- let xxs' = xxs +> List.map (fun x ->
- (tokens_of_paren_ordered x) +> List.map (fun x ->
- TH.visitor_info_of_tok Ast_c.make_expanded x.tok
- )
- ) in
- id.new_tokens_before <-
- cpp_engine (Common.zip params xxs') bodymacro
-
- else begin
- pr2 ("macro with wrong number of arguments, wierd: " ^ s);
- id.new_tokens_before <- bodymacro;
- end;
- (* important to do that after have apply the macro, otherwise
- * will pass as argument to the macro some tokens that
- * are all TCommentCpp
- *)
- [Parenthised (xxs, info_parens)] +>
- iter_token_paren (set_as_comment Ast_c.CppMacro);
- set_as_comment Ast_c.CppMacro id;
+
+ msg_apply_known_macro s;
+ let (s, params, body) = Hashtbl.find !_defs s in
-
+ (match params with
+ | NoParam ->
+ pr2 ("WIERD: macro without param used before parenthize: " ^ s);
+ (* ex: PRINTP("NCR53C400 card%s detected\n" ANDP(((struct ... *)
+ (match body with
+ | DefineBody bodymacro ->
+ set_as_comment (Ast_c.CppMacro) id;
+ id.new_tokens_before <- bodymacro;
+ | DefineHint hint ->
+ msg_apply_known_macro_hint s;
+ id.tok <- token_from_parsinghack_hint (s,i1) hint;
+ )
+ | Params params ->
+ if List.length params != List.length xxs
+ then begin
+ pr2 ("WIERD: macro with wrong number of arguments: " ^ s);
+ (* old: id.new_tokens_before <- bodymacro; *)
+ ()
+ end
+ else
+ (match body with
+ | DefineBody bodymacro ->
+ let xxs' = xxs +> List.map (fun x ->
+ (tokens_of_paren_ordered x) +> List.map (fun x ->
+ TH.visitor_info_of_tok Ast_c.make_expanded x.tok
+ )
+ ) in
+ id.new_tokens_before <-
+ cpp_engine (Common.zip params xxs') bodymacro;
+
+ (* important to do that after have apply the macro, otherwise
+ * will pass as argument to the macro some tokens that
+ * are all TCommentCpp
+ *)
+ [Parenthised (xxs, info_parens)] +>
+ iter_token_paren (set_as_comment Ast_c.CppMacro);
+ set_as_comment Ast_c.CppMacro id;
+
+ | DefineHint (HintMacroStatement as hint) ->
+ (* important to do that after have apply the macro, otherwise
+ * will pass as argument to the macro some tokens that
+ * are all TCommentCpp
+ *)
+ msg_apply_known_macro_hint s;
+ id.tok <- token_from_parsinghack_hint (s,i1) hint;
+ [Parenthised (xxs, info_parens)] +>
+ iter_token_paren (set_as_comment Ast_c.CppMacro);
+
+
+ | DefineHint hint ->
+ msg_apply_known_macro_hint s;
+ id.tok <- token_from_parsinghack_hint (s,i1) hint;
+ )
);
apply_macro_defs xs
| PToken ({tok = TIdent (s,i1)} as id)::xs
when Hashtbl.mem !_defs s ->
- pr2_cpp ("MACRO: found known macro = " ^ s);
- (match Hashtbl.find !_defs s with
- | Right params, bodymacro ->
- pr2 ("macro with params but no parens found, wierd: " ^ s);
+
+ msg_apply_known_macro s;
+ let (_s, params, body) = Hashtbl.find !_defs s in
+
+ (match params with
+ | Params params ->
+ pr2 ("WIERD: macro with params but no parens found: " ^ s);
(* dont apply the macro, perhaps a redefinition *)
()
- | Left (), bodymacro ->
- (* special case when 1-1 substitution, we reuse the token *)
- (match bodymacro with
- | [newtok] ->
+ | NoParam ->
+ (match body with
+ | DefineBody [newtok] ->
+ (* special case when 1-1 substitution, we reuse the token *)
id.tok <- (newtok +> TH.visitor_info_of_tok (fun _ ->
TH.info_of_tok id.tok))
-
- | _ ->
+ | DefineBody bodymacro ->
set_as_comment Ast_c.CppMacro id;
id.new_tokens_before <- bodymacro;
+ | DefineHint hint ->
+ msg_apply_known_macro_hint s;
+ id.tok <- token_from_parsinghack_hint (s,i1) hint;
)
);
apply_macro_defs xs
| Parenthised(xxs, info_parens)::xs ->
xxs +> List.iter (fun xs ->
if xs +> List.exists
- (function PToken({tok = TString _}) -> true | _ -> false) &&
+ (function PToken({tok = (TString _| TMacroString _)}) -> true | _ -> false) &&
xs +> List.for_all
- (function PToken({tok = TString _}) | PToken({tok = TIdent _}) ->
+ (function PToken({tok = (TString _| TMacroString _)}) | PToken({tok = TIdent _}) ->
true | _ -> false)
then
xs +> List.iter (fun tok ->
match tok with
| PToken({tok = TIdent (s,_)} as id) ->
msg_stringification s;
- id.tok <- TMacroString (TH.info_of_tok id.tok);
+ id.tok <- TMacroString (s, TH.info_of_tok id.tok);
| _ -> ()
)
else
set_as_comment Ast_c.CppAttr id;
find_macro_paren xs
+(*
+ (* attribute cpp, __xxx id() *)
+ | PToken ({tok = TIdent (s,i1)} as id)
+ ::PToken ({tok = TIdent (s2, i2)})
+ ::Parenthised(xxs,info_parens)
+ ::xs when s ==~ regexp_annot
+ ->
+ msg_attribute s;
+ id.tok <- TMacroAttr (s, i1);
+ find_macro_paren (Parenthised(xxs,info_parens)::xs)
+
+ (* attribute cpp, id __xxx = *)
+ | PToken ({tok = TIdent (s,i1)})
+ ::PToken ({tok = TIdent (s2, i2)} as id)
+ ::xs when s2 ==~ regexp_annot
+ ->
+ msg_attribute s2;
+ id.tok <- TMacroAttr (s2, i2);
+ find_macro_paren (xs)
+*)
+
+ (* storage attribute *)
+ | PToken ({tok = (Tstatic _ | Textern _)} as tok1)
+ ::PToken ({tok = TMacroAttr (s,i1)} as attr)::xs
+ ->
+ pr2_cpp ("storage attribute: " ^ s);
+ attr.tok <- TMacroAttrStorage (s,i1);
+ (* recurse, may have other storage attributes *)
+ find_macro_paren (PToken (tok1)::xs)
+
+
(* stringification
*
* the order of the matching clause is important
*)
(* string macro with params, before case *)
- | PToken ({tok = TString _})::PToken ({tok = TIdent (s,_)} as id)
+ | PToken ({tok = (TString _| TMacroString _)})::PToken ({tok = TIdent (s,_)} as id)
::Parenthised (xxs, info_parens)
::xs ->
- pr2_cpp ("MACRO: string-macro with params : " ^ s);
- id.tok <- TMacroString (TH.info_of_tok id.tok);
+
+ msg_stringification_params s;
+ id.tok <- TMacroString (s, TH.info_of_tok id.tok);
[Parenthised (xxs, info_parens)] +>
iter_token_paren (set_as_comment Ast_c.CppMacro);
find_macro_paren xs
(* after case *)
| PToken ({tok = TIdent (s,_)} as id)
::Parenthised (xxs, info_parens)
- ::PToken ({tok = TString _})
+ ::PToken ({tok = (TString _ | TMacroString _)})
::xs ->
- pr2_cpp ("MACRO: string-macro with params : " ^ s);
- id.tok <- TMacroString (TH.info_of_tok id.tok);
+
+ msg_stringification_params s;
+ id.tok <- TMacroString (s, TH.info_of_tok id.tok);
[Parenthised (xxs, info_parens)] +>
iter_token_paren (set_as_comment Ast_c.CppMacro);
find_macro_paren xs
*)
(* string macro variable, before case *)
- | PToken ({tok = TString _})::PToken ({tok = TIdent (s,_)} as id)
+ | PToken ({tok = (TString _ | TMacroString _)})::PToken ({tok = TIdent (s,_)} as id)
::xs ->
+
msg_stringification s;
- id.tok <- TMacroString (TH.info_of_tok id.tok);
+ id.tok <- TMacroString (s, TH.info_of_tok id.tok);
find_macro_paren xs
(* after case *)
- | PToken ({tok = TIdent (s,_)} as id)::PToken ({tok = TString _})
+ | PToken ({tok = TIdent (s,_)} as id)
+ ::PToken ({tok = (TString _ | TMacroString _)})
::xs ->
+
msg_stringification s;
- id.tok <- TMacroString (TH.info_of_tok id.tok);
+ id.tok <- TMacroString (s, TH.info_of_tok id.tok);
find_macro_paren xs
-
- (* cooperating with standard.h *)
- | PToken ({tok = TIdent (s,i1)} as id)::xs
- when s = "MACROSTATEMENT" ->
- id.tok <- TMacroStmt(TH.info_of_tok id.tok);
- find_macro_paren xs
-
+
(* recurse *)
))
::xs
when (s ==~ regexp_macro) ->
+
msg_declare_macro s;
let info = TH.info_of_tok macro.tok in
macro.tok <- TMacroDecl (Ast_c.str_of_info info, info);
))
::xs
when (s ==~ regexp_macro) ->
+
msg_declare_macro s;
let info = TH.info_of_tok macro.tok in
macro.tok <- TMacroDecl (Ast_c.str_of_info info, info);
)
::xs
when (s ==~ regexp_macro) ->
+
msg_declare_macro s;
let info = TH.info_of_tok macro.tok in
macro.tok <- TMacroDecl (Ast_c.str_of_info info, info);
in
if condition
then begin
+
msg_macro_toplevel_noptvirg s;
(* just to avoid the end-of-stream pb of ocamlyacc *)
let tcpar = Common.last info_parens in
if col1 = 0 then ()
else begin
msg_macro_noptvirg s;
- macro.tok <- TMacroStmt (TH.info_of_tok macro.tok);
+ macro.tok <- TMacroStmt (s, TH.info_of_tok macro.tok);
[Parenthised (xxs, info_parens)] +>
iter_token_paren (set_as_comment Ast_c.CppMacro);
end;
if condition
then begin
msg_macro_noptvirg_single s;
- macro.tok <- TMacroStmt (TH.info_of_tok macro.tok);
+ macro.tok <- TMacroStmt (s, TH.info_of_tok macro.tok);
end;
find_macro_lineparen (line2::xs)
find_macro_lineparen xs
+
+(* ------------------------------------------------------------------------- *)
+(* define tobrace init *)
+(* ------------------------------------------------------------------------- *)
+
+let rec find_define_init_brace_paren xs =
+ let rec aux xs =
+ match xs with
+ | [] -> ()
+
+ (* mainly for firefox *)
+ | (PToken {tok = TDefine _})
+ ::(PToken {tok = TIdentDefine (s,_)})
+ ::(PToken ({tok = TOBrace i1} as tokbrace))
+ ::(PToken tok2)
+ ::(PToken tok3)
+ ::xs ->
+ let is_init =
+ match tok2.tok, tok3.tok with
+ | TInt _, TComma _ -> true
+ | TString _, TComma _ -> true
+ | TIdent _, TComma _ -> true
+ | _ -> false
+
+ in
+ if is_init
+ then begin
+ pr2_cpp("found define initializer: " ^s);
+ tokbrace.tok <- TOBraceDefineInit i1;
+ end;
+
+ aux xs
+
+ (* mainly for linux, especially in sound/ *)
+ | (PToken {tok = TDefine _})
+ ::(PToken {tok = TIdentDefine (s,_)})
+ ::(Parenthised(xxx, info_parens))
+ ::(PToken ({tok = TOBrace i1} as tokbrace))
+ ::(PToken tok2)
+ ::(PToken tok3)
+ ::xs ->
+ let is_init =
+ match tok2.tok, tok3.tok with
+ | TInt _, TComma _ -> true
+ | TDot _, TIdent _ -> true
+ | TIdent _, TComma _ -> true
+ | _ -> false
+
+ in
+ if is_init
+ then begin
+ pr2_cpp("found define initializer with param: " ^ s);
+ tokbrace.tok <- TOBraceDefineInit i1;
+ end;
+
+ aux xs
+
+
+
+ (* recurse *)
+ | (PToken x)::xs -> aux xs
+ | (Parenthised (xxs, info_parens))::xs ->
+ (* not need for tobrace init:
+ * xxs +> List.iter aux;
+ *)
+ aux xs
+ in
+ aux xs
+
+
(* ------------------------------------------------------------------------- *)
(* action *)
(* ------------------------------------------------------------------------- *)
| _ -> x::skip_fake xs in
skip_fake l
+(* ------------------------------------------------------------------------- *)
let fix_tokens_cpp2 tokens =
let tokens2 = ref (tokens +> acc_map mk_token_extended) in
not (TH.is_comment x.tok) (* could filter also #define/#include *)
) in
let ifdef_grouped = mk_ifdef cleaner in
+ set_ifdef_parenthize_info ifdef_grouped;
+
find_ifdef_funheaders ifdef_grouped;
find_ifdef_bool ifdef_grouped;
find_ifdef_mid ifdef_grouped;
let paren_grouped = mk_parenthised cleaner in
let line_paren_grouped = mk_line_parenthised paren_grouped in
+ find_define_init_brace_paren paren_grouped;
find_string_macro_paren paren_grouped;
find_macro_lineparen line_paren_grouped;
find_macro_paren paren_grouped;
insert_virtual_positions (!tokens2 +> acc_map (fun x -> x.tok))
end
+let time_hack1 a =
+ Common.profile_code_exclusif "HACK" (fun () -> fix_tokens_cpp2 a)
+
let fix_tokens_cpp a =
- Common.profile_code "C parsing.fix_cpp" (fun () -> fix_tokens_cpp2 a)
+ Common.profile_code "C parsing.fix_cpp" (fun () -> time_hack1 a)
let acc = (TIdentDefine (s,i2)) :: acc in
define_ident acc xs
| _ ->
- pr2 "wierd #define body";
+ pr2 "WIERD: wierd #define body";
define_ident acc xs
)
| x::xs ->
(*****************************************************************************)
-(* for the cpp-builtin *)
+(* for the cpp-builtin, standard.h, part 0 *)
(*****************************************************************************)
+let macro_body_to_maybe_hint body =
+ match body with
+ | [] -> DefineBody body
+ | [TIdent (s,i1)] ->
+ (match parsinghack_hint_of_string s with
+ | Some hint -> DefineHint hint
+ | None -> DefineBody body
+ )
+ | xs -> DefineBody body
+
+
let rec define_parse xs =
match xs with
| [] -> []
) in
let body = body +> List.map
(TH.visitor_info_of_tok Ast_c.make_expanded) in
- let def = (s, (Right params, body)) in
+ let def = (s, (s, Params params, macro_body_to_maybe_hint body)) in
def::define_parse xs
| TDefine i1::TIdentDefine (s,i2)::xs ->
xs +> Common.split_when (function TDefEOL _ -> true | _ -> false) in
let body = body +> List.map
(TH.visitor_info_of_tok Ast_c.make_expanded) in
- let def = (s, (Left (), body)) in
+ let def = (s, (s, NoParam, macro_body_to_maybe_hint body)) in
def::define_parse xs
| TDefine i1::_ ->
+ pr2_gen i1;
raise Impossible
| x::xs -> define_parse xs
* todo?: maybe could try to get rid of this technique. Maybe a better
* set_context() would make possible to move this code using a fix_xx
* technique.
- *)
-
-open Lexer_parser (* for the fields of lexer_hint type *)
-
-let not_struct_enum = function
- | (Parser_c.Tstruct _ | Parser_c.Tunion _ | Parser_c.Tenum _)::_ -> false
- | _ -> true
-
-
-let not_annot s =
- not (s ==~ regexp_annot)
-
-
-let forLOOKAHEAD = 30
-
-
-(* look if there is a '{' just after the closing ')', and handling the
- * possibility to have nested expressions inside nested parenthesis
- *)
-let rec is_really_foreach xs =
- let rec is_foreach_aux = function
- | [] -> false, []
- | TCPar _::TOBrace _::xs -> true, xs
- (* the following attempts to handle the cases where there is a
- single statement in the body of the loop. undoubtedly more
- cases are needed.
- todo: premier(statement) - suivant(funcall)
- *)
- | TCPar _::TIdent _::xs -> true, xs
- | TCPar _::Tif _::xs -> true, xs
- | TCPar _::Twhile _::xs -> true, xs
- | TCPar _::Tfor _::xs -> true, xs
- | TCPar _::Tswitch _::xs -> true, xs
-
- | TCPar _::xs -> false, xs
- | TOPar _::xs ->
- let (_, xs') = is_foreach_aux xs in
- is_foreach_aux xs'
- | x::xs -> is_foreach_aux xs
- in
- is_foreach_aux xs +> fst
-
-
-let ok_typedef s = not (List.mem s false_typedef)
-
-
-
-(* LALR(k) trick. We can do stuff by adding cases in lexer_c.mll, but
+ *
+ * LALR(k) trick. We can do stuff by adding cases in lexer_c.mll, but
* it is more general to do it via my LALR(k) tech. Because here we can
* transform some token give some context information. So sometimes it
* makes sense to transform a token in one context, sometimes not, and
*
*)
+open Lexer_parser (* for the fields of lexer_hint type *)
+
+let not_struct_enum = function
+ | (Parser_c.Tstruct _ | Parser_c.Tunion _ | Parser_c.Tenum _)::_ -> false
+ | _ -> true
-let lookahead2 next before =
+
+let lookahead2 ~pass next before =
match (next, before) with
(* [,(] xx [,)] AND param decl *)
| (TIdent (s, i1)::(TComma _|TCPar _)::_ , (TComma _ |TOPar _)::_ )
- when not_struct_enum before && !LP._lexer_hint.parameterDeclaration
+ when not_struct_enum before && (LP.current_context() = LP.InParameter)
&& ok_typedef s
->
msg_typedef s; LP.add_typedef_root s;
(* xx const * USELESS because of next rule ? *)
- | (TIdent (s, i1)::(Tconst _|Tvolatile _)::TMul _::_ , _ )
+ | (TIdent (s, i1)::(Tconst _|Tvolatile _|Trestrict _)::TMul _::_ , _ )
when not_struct_enum before
(* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
&& ok_typedef s
TypedefIdent (s, i1)
(* xx const *)
- | (TIdent (s, i1)::(Tconst _|Tvolatile _)::_ , _ )
+ | (TIdent (s, i1)::(Tconst _|Tvolatile _|Trestrict _)::_ , _ )
when not_struct_enum before
&& ok_typedef s
(* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
(* xx * const *)
- | (TIdent (s, i1)::TMul _::(Tconst _ | Tvolatile _)::_ , _ )
+ | (TIdent (s, i1)::TMul _::(Tconst _ | Tvolatile _|Trestrict _)::_ , _ )
when not_struct_enum before
&& ok_typedef s
->
(* ( const xx) *)
- | (TIdent (s, i1)::TCPar _::_, (Tconst _ | Tvolatile _)::TOPar _::_) when
+ | (TIdent (s, i1)::TCPar _::_, (Tconst _ | Tvolatile _|Trestrict _)::TOPar _::_) when
ok_typedef s ->
msg_typedef s; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* ( xx ) [sizeof, ~] *)
- | (TIdent (s, i1)::TCPar _::(Tsizeof _|TTilde _)::_ , TOPar _::_ )
+ | (TIdent (s, i1)::TCPar _::(Tsizeof _|TTilde _)::_ , TOPar _::_ )
when not_struct_enum before
&& ok_typedef s
->
(* [(,] xx [ AND parameterdeclaration *)
| (TIdent (s, i1)::TOCro _::_, (TComma _ |TOPar _)::_)
- when !LP._lexer_hint.parameterDeclaration
+ when (LP.current_context() = LP.InParameter)
&& ok_typedef s
->
msg_typedef s; LP.add_typedef_root s;
(* static xx * yy *)
| (TIdent (s, i1)::TMul _::TIdent (s2, i2)::_ ,
- (Tregister _|Tstatic _ |Tvolatile _|Tconst _)::_) when
+ (Tregister _|Tstatic _ |Tvolatile _|Tconst _|Trestrict _)::_) when
ok_typedef s
->
msg_typedef s; LP.add_typedef_root s;
(* xx * yy, AND in paramdecl *)
| (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TComma _::_ , _)
- when not_struct_enum before && !LP._lexer_hint.parameterDeclaration
+ when not_struct_enum before && (LP.current_context() = LP.InParameter)
&& ok_typedef s
->
| (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TPtVirg _::_ , TEq _::_) ->
TIdent (s, i1)
| (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TPtVirg _::_ , _)
- when not_struct_enum before && !LP._lexer_hint.toplevel ->
+ when not_struct_enum before && (LP.is_top_or_struct (LP.current_context ()))
+ ->
msg_typedef s; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* xx * yy , AND in Toplevel *)
| (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TComma _::_ , _)
- when not_struct_enum before && !LP._lexer_hint.toplevel
+ when not_struct_enum before && (LP.current_context () = LP.InTopLevel)
&& ok_typedef s
->
(* xx * yy ( AND in Toplevel *)
| (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TOPar _::_ , _)
- when not_struct_enum before && !LP._lexer_hint.toplevel
+ when not_struct_enum before
+ && (LP.is_top_or_struct (LP.current_context ()))
&& ok_typedef s
->
msg_typedef s; LP.add_typedef_root s;
(* todo? enough ? cos in struct def we can have some expression ! *)
| (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TOCro _::_ , _)
when not_struct_enum before &&
- (!LP._lexer_hint.structDefinition > 0 || !LP._lexer_hint.toplevel)
+ (LP.is_top_or_struct (LP.current_context ()))
&& ok_typedef s
->
msg_typedef s; LP.add_typedef_root s;
(* u16: 10; in struct *)
| (TIdent (s, i1)::TDotDot _::_ , (TOBrace _ | TPtVirg _)::_)
- when (!LP._lexer_hint.structDefinition > 0 || !LP._lexer_hint.toplevel)
+ when (LP.is_top_or_struct (LP.current_context ()))
&& ok_typedef s
->
msg_typedef s; LP.add_typedef_root s;
(* xx * yy) AND in paramdecl *)
| (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TCPar _::_ , _)
- when not_struct_enum before && !LP._lexer_hint.parameterDeclaration
+ when not_struct_enum before && (LP.current_context () = LP.InParameter)
&& ok_typedef s
->
msg_typedef s; LP.add_typedef_root s;
&& ok_typedef s
->
msg_typedef s; LP.add_typedef_root s;
- pr2 ("PB MAYBE: dangerous typedef inference, maybe not a typedef: " ^ s);
+ msg_maybe_dangereous_typedef s;
TypedefIdent (s, i1)
(* ----------------------------------- *)
+ (* old: why not do like for other rules and start with TIdent ?
+ * why do TOPar :: TIdent :: ..., _ and not TIdent :: ..., TOPAr::_ ?
+ * new: prefer now start with TIdent because otherwise the add_typedef_root
+ * may have no effect if in second pass or if have disable the add_typedef.
+ *)
(* (xx) yy *)
- | (TOPar info::TIdent (s, i1)::TCPar i2::(TIdent (_,i3)|TInt (_,i3))::_ ,
- x::_)
+ | (TIdent (s, i1)::TCPar i2::(TIdent (_,i3)|TInt (_,i3))::_ ,
+ (TOPar info)::x::_)
when not (TH.is_stuff_taking_parenthized x) &&
Ast_c.line_of_info i2 = Ast_c.line_of_info i3
&& ok_typedef s
->
msg_typedef s; LP.add_typedef_root s;
- TOPar info
+ (*TOPar info*)
+ TypedefIdent (s, i1)
(* (xx) ( yy) *)
- | (TOPar info::TIdent (s, i1)::TCPar _::TOPar _::_ , x::_)
+ | (TIdent (s, i1)::TCPar _::TOPar _::_ , (TOPar info)::x::_)
when not (TH.is_stuff_taking_parenthized x)
&& ok_typedef s
->
msg_typedef s; LP.add_typedef_root s;
- TOPar info
+ (* TOPar info *)
+ TypedefIdent (s, i1)
(* (xx * ) yy *)
- | (TOPar info::TIdent (s, i1)::TMul _::TCPar _::TIdent (s2, i2)::_ , _) when
+ | (TIdent (s, i1)::TMul _::TCPar _::TIdent (s2, i2)::_ , (TOPar info)::_) when
ok_typedef s
->
msg_typedef s; LP.add_typedef_root s;
- TOPar info
+ (*TOPar info*)
+ TypedefIdent (s,i1)
+
(* (xx){ ... } constructor *)
| (TIdent (s, i1)::TCPar _::TOBrace _::_ , TOPar _::x::_)
(*-------------------------------------------------------------*)
(* CPP *)
(*-------------------------------------------------------------*)
- | ((TIfdef ii |TIfdefelse ii |TIfdefelif ii |TEndif ii |
- TIfdefBool (_,ii)|TIfdefMisc(_,ii)|TIfdefVersion(_,ii))
+ | ((TIfdef (_,ii) |TIfdefelse (_,ii) |TIfdefelif (_,ii) |TEndif (_,ii) |
+ TIfdefBool (_,_,ii)|TIfdefMisc(_,_,ii)|TIfdefVersion(_,_,ii))
as x)
::_, _
->
+ (*
if not !Flag_parsing_c.ifdef_to_if
then TCommentCpp (Ast_c.CppDirective, ii)
else
- if not !LP._lexer_hint.toplevel
- then x
- else begin
- pr2_cpp("IFDEF: or related outside function. I treat it as comment");
+ *)
+ (* not !LP._lexer_hint.toplevel *)
+ if !Flag_parsing_c.ifdef_directive_passing
+ || (pass = 2)
+ then begin
+
+ if (LP.current_context () = LP.InInitializer)
+ then begin
+ pr2 "In Initializer passing"; (* cheat: dont count in stat *)
+ incr Stat.nIfdefInitializer;
+
+ end
+ else msg_ifdef_passing ()
+ ;
+
TCommentCpp (Ast_c.CppDirective, ii)
end
+ else x
+ | (TUndef (id, ii) as x)::_, _
+ ->
+ if (pass = 2)
+ then begin
+ pr2_once ("CPP-UNDEF: I treat it as comment");
+ TCommentCpp (Ast_c.CppDirective, ii)
+ end
+ else x
(* If ident contain a for_each, then certainly a macro. But to be
* sure should look if there is a '{' after the ')', but it requires
* to count the '('. Because this can be expensive, we do that only
* when the token contains "for_each".
*)
- | (TIdent (s, i1)::TOPar _::rest, _) when not !LP._lexer_hint.toplevel
+ | (TIdent (s, i1)::TOPar _::rest, _) when not (LP.current_context () = LP.InTopLevel)
(* otherwise a function such as static void loopback_enable(int i) {
* will be considered as a loop
*)
| v::xs, _ -> v
| _ -> raise Impossible
-let lookahead a b =
- Common.profile_code "C parsing.lookahead" (fun () -> lookahead2 a b)
+let lookahead ~pass a b =
+ Common.profile_code "C parsing.lookahead" (fun () -> lookahead2 ~pass a b)
open Common
-(* Try detect some cpp idioms so can parse as is files by adjusting or
+(* Try detect some cpp idioms so can parse as-is files by adjusting or
* commenting some tokens. Parsing hack style. Sometime use indentation info,
- * Sometimes do some kind of lalr(k) by finding patterns. Often try to
+ * sometimes do some kind of lalr(k) by finding patterns. Often try to
* work on better token representation, like ifdef-paren-ized, brace-ized,
* paren-ized, so can do easier pattern matching to more easily match
* complex cpp idiom pattern. Also try to get context info such as
* end-of-line token.
*)
-(* the either is to differentialte macro-variables from macro-functions *)
-type define_body = (unit,string list) either * Parser_c.token list
+(* corresponds to what is in the yacfe configuration file (e.g. standard.h) *)
+type define_def = string * define_param * define_body
+ and define_param =
+ | NoParam
+ | Params of string list
+ and define_body =
+ | DefineBody of Parser_c.token list
+ | DefineHint of parsinghack_hint
-val _defs : (string, define_body) Hashtbl.t ref
+ (* strongly corresponds to the TMacroXxx in the grammar and lexer and the
+ * MacroXxx in the ast.
+ *)
+ and parsinghack_hint =
+ | HintIterator
+ | HintDeclarator
+ | HintMacroString
+ | HintMacroStatement
+ | HintAttribute
+val _defs : (string, define_def) Hashtbl.t ref
+
+(* can reset it *)
+val ifdef_paren_cnt: int ref
val fix_tokens_define : Parser_c.token list -> Parser_c.token list
-val extract_cpp_define : Parser_c.token list -> (string, define_body) assoc
+val extract_cpp_define : Parser_c.token list -> (string, define_def) assoc
val fix_tokens_cpp : Parser_c.token list -> Parser_c.token list
(* next stream tokens -> passed stream tokens -> final next token *)
-val lookahead : Parser_c.token list -> Parser_c.token list -> Parser_c.token
+val lookahead :
+ pass:int ->
+ Parser_c.token list -> Parser_c.token list -> Parser_c.token
--- /dev/null
+open Common
+
+(* if do .mli:
+val print_parsing_stat_list: parsing_stat list -> unit
+*)
+
+(*****************************************************************************)
+(* Stat *)
+(*****************************************************************************)
+type parsing_stat = {
+ filename: filename;
+ mutable have_timeout: bool;
+
+ mutable correct: int;
+ mutable bad: int;
+
+ mutable commentized: int; (* by our cpp commentizer *)
+
+ (* if want to know exactly what was passed through, uncomment:
+ *
+ * mutable passing_through_lines: int;
+ *
+ * it differs from bad by starting from the error to
+ * the synchro point instead of starting from start of
+ * function to end of function.
+ *)
+
+ }
+
+let default_stat file = {
+ filename = file;
+ have_timeout = false;
+ correct = 0; bad = 0;
+ commentized = 0;
+ }
+
+(* todo: stat per dir ? give in terms of func_or_decl numbers:
+ * nbfunc_or_decl pbs / nbfunc_or_decl total ?/
+ *
+ * note: cela dit si y'a des fichiers avec des #ifdef dont on connait pas les
+ * valeurs alors on parsera correctement tout le fichier et pourtant y'aura
+ * aucune def et donc aucune couverture en fait.
+ * ==> TODO evaluer les parties non parsé ?
+ *)
+
+let print_parsing_stat_list ?(verbose=false) = fun statxs ->
+ let total = List.length statxs in
+ let perfect =
+ statxs
+ +> List.filter (function
+ {have_timeout = false; bad = 0} -> true | _ -> false)
+ +> List.length
+ in
+
+ if verbose then begin
+ pr "\n\n\n---------------------------------------------------------------";
+ pr "pbs with files:";
+ statxs
+ +> List.filter (function
+ | {have_timeout = true} -> true
+ | {bad = n} when n > 0 -> true
+ | _ -> false)
+ +> List.iter (function
+ {filename = file; have_timeout = timeout; bad = n} ->
+ pr (file ^ " " ^ (if timeout then "TIMEOUT" else i_to_s n));
+ );
+
+ pr "\n\n\n";
+ pr "files with lots of tokens passed/commentized:";
+ let threshold_passed = 100 in
+ statxs
+ +> List.filter (function
+ | {commentized = n} when n > threshold_passed -> true
+ | _ -> false)
+ +> List.iter (function
+ {filename = file; commentized = n} ->
+ pr (file ^ " " ^ (i_to_s n));
+ );
+
+ pr "\n\n\n---------------------------------------------------------------";
+ end;
+
+ pr (
+ (sprintf "NB total files = %d; " total) ^
+ (sprintf "perfect = %d; " perfect) ^
+ (sprintf "pbs = %d; " (statxs +> List.filter (function
+ {have_timeout = b; bad = n} when n > 0 -> true | _ -> false)
+ +> List.length)) ^
+ (sprintf "timeout = %d; " (statxs +> List.filter (function
+ {have_timeout = true; bad = n} -> true | _ -> false)
+ +> List.length)) ^
+ (sprintf "=========> %d" ((100 * perfect) / total)) ^ "%"
+
+ );
+ let good = statxs +> List.fold_left (fun acc {correct = x} -> acc+x) 0 in
+ let bad = statxs +> List.fold_left (fun acc {bad = x} -> acc+x) 0 in
+ let passed = statxs +> List.fold_left (fun acc {commentized = x} -> acc+x) 0
+ in
+ let gf, badf = float_of_int good, float_of_int bad in
+ let passedf = float_of_int passed in
+ pr (
+ (sprintf "nb good = %d, nb passed = %d " good passed) ^
+ (sprintf "=========> %f" (100.0 *. (passedf /. gf)) ^ "%")
+ );
+ pr (
+ (sprintf "nb good = %d, nb bad = %d " good bad) ^
+ (sprintf "=========> %f" (100.0 *. (gf /. (gf +. badf))) ^ "%"
+ )
+ )
+
+(*****************************************************************************)
+(* Stat *)
+(*****************************************************************************)
+
+(* coupling: if you add a new var, modify also assoc_stat_number below *)
+
+let nTypedefInfer = ref 0
+
+let nIncludeGrammar = ref 0
+let nIncludeHack = ref 0
+
+let nIteratorGrammar = ref 0
+let nIteratorHeuristic = ref 0
+
+let nMacroTopDecl = ref 0
+let nMacroStructDecl = ref 0
+let nMacroDecl = ref 0
+let nMacroStmt = ref 0
+let nMacroString = ref 0
+let nMacroHigherOrder = ref 0 (* actions *)
+let nMacrohigherTypeGrammar = ref 0
+let nMacroAttribute = ref 0
+
+let nIfdefTop = ref 0
+let nIfdefStmt = ref 0
+let nIfdefStruct = ref 0
+let nIfdefInitializer = ref 0
+(* nIfdefExpr, nIfdefType *)
+
+let nIfdefFunheader = ref 0
+
+let nIfdefExprPassing = ref 0
+let nIfdefPassing = ref 0
+
+let nIncludePassing = ref 0
+let nDefinePassing = ref 0
+
+let nIfdefZero = ref 0
+let nIfdefVersion = ref 0
+
+
+
+let nGccTypeof = ref 0
+let nGccLongLong = ref 0
+let nGccAsm = ref 0
+let nGccInline = ref 0
+let nGccAttribute = ref 0
+let nGccCaseRange = ref 0
+let nGccMixDecl = ref 0
+let nGccDesignator = ref 0
+let nGccStmtExpr = ref 0
+let nGccConstructor = ref 0
+let nGccEmptyStruct = ref 0
+let nGccNestedFunc = ref 0
+
+let nGccMisc = ref 0
+
+
+
+let nDefineHack = ref 0
+
+let nDefineConstant = ref 0
+let nDefineStmt = ref 0
+let nDefineExpr = ref 0
+(* both below require some heuristic support *)
+let nDefineWhile0 = ref 0
+let nDefineInit = ref 0
+
+let nDefineOther = ref 0
+
+let nUndef = ref 0
+let nPragmaAndCo = ref 0
+
+(* let nDirectiveTop = ref 0 *)
+let nDirectiveStmt = ref 0
+let nDirectiveStruct = ref 0
+let nDirectiveInitializer = ref 0
+
+
+(* from standard.h *)
+let nMacroHint = ref 0
+let nMacroExpand = ref 0
+
+let nNotParsedCorrectly = ref 0
+
+let assoc_stat_number =
+ [
+ "nTypedefInfer", nTypedefInfer;
+
+ "nIteratorHeuristic", nIteratorHeuristic;
+
+ "nMacroTopDecl", nMacroTopDecl;
+ "nMacroStructDecl", nMacroStructDecl;
+ "nMacroDecl", nMacroDecl;
+ "nMacroStmt", nMacroStmt;
+ "nMacroString", nMacroString;
+ "nMacroHigherOrder", nMacroHigherOrder;
+ "nMacroAttribute", nMacroAttribute;
+
+ "nMacrohigherTypeGrammar", nMacrohigherTypeGrammar;
+
+ "nIfdefTop", nIfdefTop;
+ "nIfdefStmt", nIfdefStmt;
+ "nIfdefStruct", nIfdefStruct;
+ "nIfdefInitializer", nIfdefInitializer;
+
+ "nIfdefFunheader", nIfdefFunheader;
+ "nIfdefZero", nIfdefZero;
+ "nIfdefVersion", nIfdefVersion;
+ "nIfdefExprPassing", nIfdefExprPassing;
+ "nIfdefPassing", nIfdefPassing;
+
+ "nIncludePassing", nIncludePassing;
+ "nDefinePassing", nDefinePassing;
+
+ "nMacroExpand", nMacroExpand;
+ "nMacroHint", nMacroHint;
+
+
+ "nGccTypeof", nGccTypeof;
+ "nGccLongLong", nGccLongLong;
+ "nGccAsm", nGccAsm;
+ "nGccInline", nGccInline;
+ "nGccAttribute", nGccAttribute;
+ "nGccCaseRange", nGccCaseRange;
+ "nGccMixDecl", nGccMixDecl;
+ "nGccDesignator", nGccDesignator;
+ "nGccStmtExpr", nGccStmtExpr;
+ "nGccConstructor", nGccConstructor;
+ "nGccEmptyStruct", nGccEmptyStruct;
+ "nGccNestedFunc", nGccNestedFunc;
+
+ "nGccMisc", nGccMisc;
+
+
+ "nDefineHack", nDefineHack;
+
+ "nDefineConstant", nDefineConstant;
+ "nDefineStmt", nDefineStmt;
+ "nDefineExpr", nDefineExpr;
+ "nDefineInit", nDefineInit;
+ "nDefineOther", nDefineOther;
+
+ "nUndef", nUndef;
+ "nPragmaAndCo", nPragmaAndCo;
+
+ "nDirectiveStmt", nDirectiveStmt;
+ "nDirectiveStruct", nDirectiveStruct;
+ "nDirectiveInitializer", nDirectiveInitializer;
+
+ "nNotParsedCorrectly", nNotParsedCorrectly;
+
+
+ (* less *)
+ "nIncludeGrammar", nIncludeGrammar;
+ "nIncludeHack", nIncludeHack;
+
+ "nIteratorGrammar", nIteratorGrammar;
+ ]
+
+let print_stat_numbers () =
+ assoc_stat_number +> List.iter (fun (k, vref) ->
+ pr2 (spf "%-30s -> %d" k !vref);
+ )
-(* Copyright (C) 2002-2008 Yoann Padioleau
+(* Copyright (C) 2006, 2007, 2008 Yoann Padioleau
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License (GPL)
type pr_elem_func = Ast_c.info -> unit
type pr_space_func = unit -> unit
+module F = Control_flow_c
+
(*****************************************************************************)
(* This module is used by unparse_c, but because unparse_c have also
let rec pp_expression_gen pr_elem pr_space =
(* subtil: dont try to shorten the def of pp_statement by omitting e,
otherwise get infinite funcall and huge memory consumption *)
- let pp_statement e = pp_statement_gen pr_elem pr_space e in
+ let _pp_statement e = pp_statement_gen pr_elem pr_space e in
+
let rec pp_expression = fun ((exp, typ), ii) ->
(match exp, ii with
| Ident (c), [i] -> pr_elem i
| StatementExpr (statxs, [ii1;ii2]), [i1;i2] ->
pr_elem i1;
pr_elem ii1;
- statxs +> List.iter pp_statement;
+ statxs +> List.iter (pp_statement_seq_gen pr_elem pr_space);
pr_elem ii2;
pr_elem i2;
| Constructor (t, xs), lp::rp::i1::i2::iicommaopt ->
| ParenExpr (_)
),_ -> raise Impossible
);
+
if !Flag_parsing_c.pretty_print_type_info
then begin
pr_elem (Ast_c.fakeInfo() +> Ast_c.rewrap_str "/*");
pp_statement st
| Labeled (Default st), [i1;i2] -> pr_elem i1; pr_elem i2; pp_statement st
| Compound statxs, [i1;i2] ->
- pr_elem i1; statxs +> List.iter pp_statement; pr_elem i2;
+ pr_elem i1;
+ statxs +> List.iter (pp_statement_seq_gen pr_elem pr_space);
+ pr_elem i2;
| ExprStatement (None), [i] -> pr_elem i;
| ExprStatement (None), [] -> ()
| MacroStmt, ii ->
ii +> List.iter pr_elem ;
- | Selection (Ifdef (st1s, st2s)), i1::i2::is ->
- pr_elem i1;
- st1s +> List.iter pp_statement;
- (match (st2s, is) with
- | [], [iifakend] -> pr_elem i2; pr_elem iifakend
- | x::xs, [i3;iifakend] ->
- pr_elem i2;
- st2s +> List.iter pp_statement;
- pr_elem i3;
- pr_elem iifakend
-
- | _ -> raise Impossible
- )
| ( Labeled (Label (_,_)) | Labeled (Case (_,_))
| Labeled (CaseRange (_,_,_)) | Labeled (Default _)
| Compound _ | ExprStatement _
| Iteration (MacroIteration (_,_,_))
| Jump (Goto _) | Jump ((Continue|Break|Return)) | Jump (ReturnExpr _)
| Jump (GotoComputed _)
- | Decl _ | Selection (Ifdef (_,_))
+ | Decl _
), _ -> raise Impossible
in
pp_statement
+and pp_statement_seq_gen pr_elem pr_space stseq =
+ match stseq with
+ | StmtElem st ->
+ pp_statement_gen pr_elem pr_space st
+ | IfdefStmt ifdef -> pp_ifdef_gen pr_elem pr_space ifdef
+ | CppDirectiveStmt cpp -> pp_directive_gen pr_elem pr_space cpp
+ | IfdefStmt2 (ifdef, xxs) ->
+ pp_ifdef_tree_sequence pr_elem pr_space ifdef xxs
+
+(* ifdef XXX elsif YYY elsif ZZZ endif *)
+and pp_ifdef_tree_sequence pr_elem pr_space ifdef xxs =
+ match ifdef with
+ | if1::ifxs ->
+ pp_ifdef_gen pr_elem pr_space if1;
+ pp_ifdef_tree_sequence_aux pr_elem pr_space ifxs xxs
+ | _ -> raise Impossible
+
+(* XXX elsif YYY elsif ZZZ endif *)
+and pp_ifdef_tree_sequence_aux pr_elem pr_space ifdefs xxs =
+ Common.zip ifdefs xxs +> List.iter (fun (ifdef, xs) ->
+ xs +> List.iter (pp_statement_seq_gen pr_elem pr_space);
+ pp_ifdef_gen pr_elem pr_space ifdef;
+ )
+
+
+
+
+(* ---------------------- *)
and pp_asmbody_gen pr_elem pr_space (string_list, colon_list) =
string_list +> List.iter pr_elem ;
colon_list +> List.iter (fun (Colon xs, ii) ->
pr_elem iopar;
pp_expression_gen pr_elem pr_space e;
pr_elem icpar
- | _ -> raise Impossible
+ | (ColonExpr _), _ -> raise Impossible
)
))
(* ---------------------- *)
+
+(*
+pp_type_with_ident_gen
+pp_base_type_gen
+pp_type_with_ident_rest_gen
+pp_type_left_gen
+pp_type_right_gen
+pp_type_gen
+
+pp_decl_gen
+*)
and (pp_type_with_ident_gen:
pr_elem_func -> pr_space_func ->
- (string * info) option -> (storage * il) option -> fullType -> unit) =
+ (string * info) option -> (storage * il) option ->
+ fullType -> attribute list ->
+ unit) =
fun pr_elem pr_space ->
- fun ident sto ((qu, iiqu), (ty, iity)) ->
+ fun ident sto ((qu, iiqu), (ty, iity)) attrs ->
pp_base_type_gen pr_elem pr_space ((qu, iiqu), (ty, iity)) sto;
pp_type_with_ident_rest_gen pr_elem pr_space ident
- ((qu, iiqu), (ty, iity))
+ ((qu, iiqu), (ty, iity)) attrs
and (pp_base_type_gen:
);
fields +> List.iter
- (fun (xfield, iipttvirg) ->
+ (fun (xfield, iipttvirg_when_emptyfield) ->
match xfield with
- | FieldDeclList onefield_multivars ->
+ | DeclarationField (FieldDeclList (onefield_multivars, iiptvirg)) ->
(match onefield_multivars with
| x::xs ->
(* handling the first var. Special case, with the
| x -> raise Impossible)
in
pp_type_with_ident_gen pr_elem pr_space
- identinfo None typ;
+ identinfo None typ Ast_c.noattr;
| (BitField (sopt, typ, expr), ii), iivirg ->
(* first var cant have a preceding ',' *)
pp_expression expr
| (Some s, [is;idot]) ->
pp_type_with_ident_gen
- pr_elem pr_space (Some (s, is)) None typ;
+ pr_elem pr_space
+ (Some (s, is)) None typ Ast_c.noattr;
pr_elem idot;
pp_expression expr
| x -> raise Impossible
)
-
- );
+ ); (* match x, first onefield_multivars *)
(* for other vars *)
xs +> List.iter (function
| x -> raise Impossible)
in
pp_type_with_ident_rest_gen pr_elem pr_space
- identinfo typ;
+ identinfo typ Ast_c.noattr;
| (BitField (sopt, typ, expr), ii), iivirg ->
iivirg +> List.iter pr_elem;
(match sopt, ii with
| (Some s, [is;idot]) ->
pp_type_with_ident_rest_gen
- pr_elem pr_space (Some (s, is)) typ;
+ pr_elem pr_space
+ (Some (s, is)) typ Ast_c.noattr;
pr_elem idot;
pp_expression expr
| x -> raise Impossible
);
- );
+ ); (* iter other vars *)
+
+ | [] -> raise Impossible
+ ); (* onefield_multivars *)
+ assert (List.length iiptvirg = 1);
+ iiptvirg +> List.iter pr_elem;
+
+
+ | MacroStructDeclTodo -> pr2 "MacroTodo"
+
- assert (List.length iipttvirg = 1);
- iipttvirg +> List.iter pr_elem;
- | x -> raise Impossible
- )
- | EmptyField -> ()
+ | EmptyField ->
+ iipttvirg_when_emptyfield +> List.iter pr_elem
+
+ | CppDirectiveStruct cpp -> pp_directive_gen pr_elem pr_space cpp
+ | IfdefStruct ifdef -> pp_ifdef_gen pr_elem pr_space ifdef
);
(match sopt,iis with
| _ -> raise Impossible
)
+ | (Pointer _ | (*ParenType _ |*) Array _ | FunctionType _
+ (* | StructUnion _ | Enum _ | BaseType _ *)
+ (* | StructUnionName _ | EnumName _ | TypeName _ *)
+ (* | TypeOfExpr _ | TypeOfType _ *)
+ ), _ -> raise Impossible
+
+
- | x -> raise Impossible
in
pp_base_type
int before *j *)
and (pp_type_with_ident_rest_gen:
pr_elem_func -> pr_space_func ->
- (string * info) option -> fullType -> unit) =
+ (string * info) option ->
+ fullType -> attribute list ->
+ unit) =
fun pr_elem pr_space ->
- fun ident (((qu, iiqu), (ty, iity)) as fullt) ->
- let print_ident ident = do_option (fun (s, iis) -> pr_elem iis) ident
+
+ fun ident (((qu, iiqu), (ty, iity)) as fullt) attrs ->
+ let print_ident ident = Common.do_option (fun (s, iis) ->
+ (* XXX attrs +> pp_attributes pr_elem pr_space; *)
+ pr_elem iis
+ ) ident
in
match ty, iity with
(* bug: pp_type_with_ident_rest None t; print_ident ident *)
pr_elem i;
iiqu +> List.iter pr_elem; (* le const est forcement apres le '*' *)
- pp_type_with_ident_rest_gen pr_elem pr_space ident t;
+ pp_type_with_ident_rest_gen pr_elem pr_space ident t attrs;
(* ugly special case ... todo? maybe sufficient in practice *)
| (ParenType (q1, (Pointer (q2, (FunctionType t, ii3)) ,
| (ParenType t, [i1;i2]) ->
pr2 "PB PARENTYPE ZARB, I forget about the ()";
- pp_type_with_ident_rest_gen pr_elem pr_space ident t;
+ pp_type_with_ident_rest_gen pr_elem pr_space ident t attrs;
| (Array (eopt, t), [i1;i2]) ->
print_ident ident;
pp_type_right_gen pr_elem pr_space fullt;
+
- | x -> raise Impossible
+ | (FunctionType _ | Array _ | ParenType _ | Pointer _
+ ), _ -> raise Impossible
and (pp_type_left_gen: pr_elem_func -> pr_space_func -> fullType -> unit) =
| (StructUnionName (s, structunion), iis) -> ()
| (EnumName s, iis) -> ()
| (TypeName (s,_typ), iis) -> ()
- | x -> raise Impossible
+
+ | TypeOfType _, _ -> ()
+ | TypeOfExpr _, _ -> ()
+
+ | (FunctionType _ | Array _ | Pointer _
+ ), _ -> raise Impossible
in
pp_type_left
pp_type_gen pr_elem pr_space t
| false, Some s, [i1] ->
- pp_type_with_ident_gen pr_elem pr_space (Some (s, i1)) None t;
+ pp_type_with_ident_gen pr_elem pr_space
+ (Some (s, i1)) None t Ast_c.noattr;
| true, Some s, [i1;i2] ->
pr_elem i1;
- pp_type_with_ident_gen pr_elem pr_space (Some (s, i2)) None t;
+ pp_type_with_ident_gen pr_elem pr_space
+ (Some (s, i2)) None t Ast_c.noattr;
| _ -> raise Impossible
| (StructUnionName (s, structunion), iis) -> ()
| (EnumName s, iis) -> ()
| (TypeName (s,_typ), iis) -> ()
- | x -> raise Impossible
+
+ | TypeOfType _, _ -> ()
+ | TypeOfExpr _, _ -> ()
+
+ | (FunctionType _ | Array _ | Pointer _
+ ), _ -> raise Impossible
+
in
pp_type_right
and pp_type_gen pr_elem pr_space t =
- pp_type_with_ident_gen pr_elem pr_space None None t
+ pp_type_with_ident_gen pr_elem pr_space
+ None None t Ast_c.noattr
(* ---------------------- *)
and pp_decl_gen pr_elem pr_space = function
- | DeclList ((((var, returnType, storage, _local),[])::xs),
+ | DeclList ((({v_namei = var; v_type = returnType;
+ v_storage = storage; v_attr = attrs;
+ },[])::xs),
iivirg::ifakestart::iisto) ->
pr_elem ifakestart;
| Some ((s, ini), iis::iini) ->
pp_type_with_ident_gen pr_elem pr_space
(Some (s, iis)) (Some (storage, iisto))
- returnType;
+ returnType attrs;
ini +> do_option (fun init ->
List.iter pr_elem iini; pp_init_gen pr_elem pr_space init);
| None -> pp_type_gen pr_elem pr_space returnType
(* for other vars, we just call pp_type_with_ident_rest. *)
xs +> List.iter (function
- | ((Some ((s, ini), iis::iini), returnType, storage2, _local), iivirg) ->
+ | ({v_namei = Some ((s, ini), iis::iini);
+ v_type = returnType;
+ v_storage = storage2;
+ v_attr = attrs;
+ }, iivirg) ->
+
assert (storage2 = storage);
iivirg +> List.iter pr_elem;
pp_type_with_ident_rest_gen pr_elem pr_space
- (Some (s, iis)) returnType;
+ (Some (s, iis)) returnType attrs;
ini +> do_option (fun (init) ->
List.iter pr_elem iini; pp_init_gen pr_elem pr_space init);
pr_elem rp;
pr_elem iiend;
- | x -> raise Impossible
+ | (DeclList (_, _) | (MacroDecl _)) -> raise Impossible
(* ---------------------- *)
| InitIndexOld (expression, initialiser), [i1;i2] -> (* [1] in oldgcc *)
pr_elem i1; pp_expression expression; pr_elem i2;
pp_init initialiser
- | x -> raise Impossible
+
+ | (InitIndexOld _ | InitFieldOld _ | InitDesignators _
+ | InitList _ | InitExpr _
+ ), _ -> raise Impossible
in
pp_init
| DesignatorRange (e1, e2), [iocro;iellipsis;iccro] ->
pr_elem iocro; pp_expression e1; pr_elem iellipsis;
pp_expression e2; pr_elem iccro;
- | x -> raise Impossible
-
+ | (DesignatorField _ | DesignatorIndex _ | DesignatorRange _
+ ), _ -> raise Impossible
+
+(* ---------------------- *)
+and pp_attributes pr_elem pr_space attrs =
+ attrs +> List.iter (fun (attr, ii) ->
+ ii +> List.iter pr_elem;
+ );
(* ---------------------- *)
and pp_def_gen pr_elem pr_space def =
- match def with
- | ((s, (returnt, (paramst, (b, iib))), sto, statxs),
- is::iifunc1::iifunc2::i1::i2::ifakestart::isto) ->
+ let defbis, ii = def in
+ match ii with
+ | is::iifunc1::iifunc2::i1::i2::ifakestart::isto ->
+
+ let {f_name = s;
+ f_type = (returnt, (paramst, (b, iib)));
+ f_storage = sto;
+ f_body = statxs;
+ f_attr = attrs;
+ } = defbis
+ in
pr_elem ifakestart;
pp_type_with_ident_gen pr_elem pr_space None (Some (sto, isto))
- returnt;
+ returnt Ast_c.noattr;
+
+ pp_attributes pr_elem pr_space attrs;
pr_elem is;
+
+
pr_elem iifunc1;
(* not anymore, cf tests/optional_name_parameter and
pr_elem iifunc2;
pr_elem i1;
- statxs +> List.iter (pp_statement_gen pr_elem pr_space);
+ statxs +> List.iter (pp_statement_seq_gen pr_elem pr_space);
pr_elem i2;
| _ -> raise Impossible
+(* ---------------------- *)
+
+and pp_ifdef_gen pr_elem pr_space ifdef =
+ match ifdef with
+ | IfdefDirective (ifdef, ii) ->
+ List.iter pr_elem ii
-let pp_program_gen pr_elem pr_space progelem =
- match progelem with
- | Declaration decl -> pp_decl_gen pr_elem pr_space decl
- | Definition def -> pp_def_gen pr_elem pr_space def
- | Include ((s, [i1;i2]),h_rel_pos) ->
+and pp_directive_gen pr_elem pr_space directive =
+ match directive with
+ | Include {i_include = (s, ii);} ->
+ let (i1,i2) = Common.tuple_of_list2 ii in
pr_elem i1; pr_elem i2
- | Define ((s,[idefine;iident;ieol]), (defkind, defval)) ->
+ | Define ((s,ii), (defkind, defval)) ->
+ let (idefine,iident,ieol) = Common.tuple_of_list3 ii in
pr_elem idefine;
pr_elem iident;
let define_val = function
| DefineExpr e -> pp_expression_gen pr_elem pr_space e
| DefineStmt st -> pp_statement_gen pr_elem pr_space st
- | DefineDoWhileZero (st, ii) ->
+ | DefineDoWhileZero ((st,e), ii) ->
(match ii with
- | [ido;iwhile;iopar;iint;icpar] ->
+ | [ido;iwhile;iopar;icpar] ->
pr_elem ido;
pp_statement_gen pr_elem pr_space st;
- pr_elem iwhile; pr_elem iopar; pr_elem iint; pr_elem icpar
+ pr_elem iwhile; pr_elem iopar;
+ pp_expression_gen pr_elem pr_space e;
+ pr_elem icpar
| _ -> raise Impossible
)
| DefineFunction def -> pp_def_gen pr_elem pr_space def
| DefineType ty -> pp_type_gen pr_elem pr_space ty
| DefineText (s, ii) -> List.iter pr_elem ii
| DefineEmpty -> ()
+ | DefineInit ini ->
+ pp_init_gen pr_elem pr_space ini
+
+ | DefineTodo -> pr2 "DefineTodo"
in
(match defkind with
| DefineVar -> ()
define_val defval;
pr_elem ieol
+ | Undef (s, ii) ->
+ List.iter pr_elem ii
+ | PragmaAndCo (ii) ->
+ List.iter pr_elem ii
+
+
+
+
+let pp_program_gen pr_elem pr_space progelem =
+ match progelem with
+ | Declaration decl -> pp_decl_gen pr_elem pr_space decl
+ | Definition def -> pp_def_gen pr_elem pr_space def
+
+ | CppTop directive -> pp_directive_gen pr_elem pr_space directive
+
| MacroTop (s, es, [i1;i2;i3;i4]) ->
pr_elem i1;
assert (List.length ii >= 1);
ii +> List.iter pr_elem
| FinalDef info -> pr_elem (Ast_c.rewrap_str "" info)
+
+ | IfdefTop ifdefdir ->
+ pp_ifdef_gen pr_elem pr_space ifdefdir
+
+ | (MacroTop _)
+ -> raise Impossible
- | _ -> raise Impossible
-
+
+
+
+let pp_flow_gen pr_elem pr_space n =
+ match F.unwrap n with
+ | F.FunHeader ({f_name =idb;
+ f_type = (rett, (paramst,(isvaargs,iidotsb)));
+ f_storage = stob;
+ f_body = body;
+ f_attr = attrs},ii) ->
+
+ assert(null body);
+ (*
+ iif ii;
+ iif iidotsb;
+ attrs +> List.iter (vk_attribute bigf);
+ vk_type bigf rett;
+ paramst +> List.iter (fun (param, iicomma) ->
+ vk_param bigf param;
+ iif iicomma;
+ );
+ *)
+ pr2 "Def";
+
+
+ | F.Decl decl ->
+ (* vk_decl bigf decl *)
+ pr2 "Decl"
+
+ | F.ExprStatement (st, (eopt, ii)) ->
+ pp_statement_gen pr_elem pr_space (ExprStatement eopt, ii)
+
+ | F.IfHeader (_, (e,ii))
+ | F.SwitchHeader (_, (e,ii))
+ | F.WhileHeader (_, (e,ii))
+ | F.DoWhileTail (e,ii) ->
+ (*
+ iif ii;
+ vk_expr bigf e
+ *)
+ pr2 "XXX";
+
+
+ | F.ForHeader (_st, (((e1opt,i1), (e2opt,i2), (e3opt,i3)), ii)) ->
+ (*
+ iif i1; iif i2; iif i3;
+ iif ii;
+ e1opt +> do_option (vk_expr bigf);
+ e2opt +> do_option (vk_expr bigf);
+ e3opt +> do_option (vk_expr bigf);
+ *)
+ pr2 "XXX";
+
+ | F.MacroIterHeader (_s, ((s,es), ii)) ->
+ (*
+ iif ii;
+ vk_argument_list bigf es;
+ *)
+ pr2 "XXX";
+
+
+ | F.ReturnExpr (_st, (e,ii)) ->
+ (* iif ii; vk_expr bigf e*)
+ pr2 "XXX";
+
+
+ | F.Case (_st, (e,ii)) ->
+ (* iif ii; vk_expr bigf e *)
+ pr2 "XXX";
+
+ | F.CaseRange (_st, ((e1, e2),ii)) ->
+ (* iif ii; vk_expr bigf e1; vk_expr bigf e2 *)
+ pr2 "XXX";
+
+
+
+ | F.CaseNode i -> ()
+
+ | F.DefineExpr e ->
+ (* vk_expr bigf e *)
+ pr2 "XXX";
+
+ | F.DefineType ft ->
+ (* vk_type bigf ft *)
+ pr2 "XXX";
+
+ | F.DefineHeader ((s,ii), (defkind)) ->
+ (*
+ iif ii;
+ vk_define_kind bigf defkind;
+ *)
+ pr2 "XXX";
+
+
+ | F.DefineDoWhileZeroHeader (((),ii)) ->
+ (* iif ii *)
+ pr2 "XXX";
+
+
+ | F.Include {i_include = (s, ii);} ->
+ (* iif ii; *)
+ pr2 "XXX";
+
+
+ | F.MacroTop (s, args, ii) ->
+ (* iif ii;
+ vk_argument_list bigf args *)
+ pr2 "XXX";
+
+
+ | F.Break (st,((),ii)) ->
+ (* iif ii *)
+ pr2 "XXX";
+ | F.Continue (st,((),ii)) ->
+ (* iif ii *)
+ pr2 "XXX";
+ | F.Default (st,((),ii)) ->
+ (* iif ii *)
+ pr2 "XXX";
+ | F.Return (st,((),ii)) ->
+ (* iif ii *)
+ pr2 "XXX";
+ | F.Goto (st, (s,ii)) ->
+ (* iif ii *)
+ pr2 "XXX";
+ | F.Label (st, (s,ii)) ->
+ (* iif ii *)
+ pr2 "XXX";
+ | F.EndStatement iopt ->
+ (* do_option infof iopt *)
+ pr2 "XXX";
+ | F.DoHeader (st, info) ->
+ (* infof info *)
+ pr2 "XXX";
+ | F.Else info ->
+ (* infof info *)
+ pr2 "XXX";
+ | F.SeqEnd (i, info) ->
+ (* infof info *)
+ pr2 "XXX";
+ | F.SeqStart (st, i, info) ->
+ (* infof info *)
+ pr2 "XXX";
+
+ | F.MacroStmt (st, ((),ii)) ->
+ (* iif ii *)
+ pr2 "XXX";
+ | F.Asm (st, (asmbody,ii)) ->
+ (*
+ iif ii;
+ vk_asmbody bigf asmbody
+ *)
+ pr2 "XXX";
+
+
+ | F.IfdefHeader (info) ->
+ pp_ifdef_gen pr_elem pr_space info
+ | F.IfdefElse (info) ->
+ pp_ifdef_gen pr_elem pr_space info
+ | F.IfdefEndif (info) ->
+ pp_ifdef_gen pr_elem pr_space info
+
+
+ | (
+ F.TopNode|F.EndNode|
+ F.ErrorExit|F.Exit|F.Enter|
+ F.FallThroughNode|F.AfterNode|F.FalseNode|F.TrueNode|F.InLoopNode|
+ F.Fake
+ ) ->
+ pr2 "YYY"
+
+
+
+
+
let pp_expression_simple = pp_expression_gen pr_elem pr_space
let pp_statement_simple = pp_statement_gen pr_elem pr_space
let pp_type_simple = pp_type_gen pr_elem pr_space
+let pp_toplevel_simple = pp_program_gen pr_elem pr_space
+let pp_flow_simple = pp_flow_gen pr_elem pr_space
+
val pp_type_with_ident_gen :
pr_elem_func -> pr_space_func ->
(string * Ast_c.info) option ->
- (Ast_c.storage * Ast_c.il) option -> Ast_c.fullType -> unit
+ (Ast_c.storage * Ast_c.il) option -> Ast_c.fullType -> Ast_c.attribute list ->
+ unit
val pp_program_gen : pr_elem_func -> pr_space_func -> Ast_c.toplevel -> unit
val pp_expression_simple : Ast_c.expression -> unit
val pp_statement_simple : Ast_c.statement -> unit
val pp_type_simple : Ast_c.fullType -> unit
+val pp_toplevel_simple : Ast_c.toplevel -> unit
+val pp_flow_simple: Control_flow_c.node -> unit
let xs = if !Flag.dir then
process_output_to_list ("find " ^ x ^" -name \"*.c\"") else x::xs in
*)
- let fullxs = Common.files_of_dir_or_files ext xs in
+ let fullxs = Common.files_of_dir_or_files_no_vcs ext xs in
let stat_list = ref [] in
let newscore = Common.empty_score () in
- (*cocci: Common.check_stack_nbfiles (List.length fullxs); *)
+ Common.check_stack_nbfiles (List.length fullxs);
fullxs +> List.iter (fun file ->
if not (file =~ (".*\\."^ext))
Common.push2 stat stat_list;
let s =
sprintf "bad = %d, timeout = %B"
- stat.Parse_c.bad stat.Parse_c.have_timeout
+ stat.Parsing_stat.bad stat.Parsing_stat.have_timeout
in
- if stat.Parse_c.bad = 0 && not stat.Parse_c.have_timeout
+ if stat.Parsing_stat.bad = 0 && not stat.Parsing_stat.have_timeout
then Hashtbl.add newscore file (Common.Ok)
else Hashtbl.add newscore file (Common.Pb s)
);
if not (null !stat_list)
- then Parse_c.print_parsing_stat_list !stat_list;
+ then Parsing_stat.print_parsing_stat_list !stat_list;
dirname_opt +> Common.do_option (fun dirname ->
pr2 "--------------------------------";
(* ---------------------------------------------------------------------- *)
(* file can be "foo.c" or "foo.c:main" *)
let test_cfg file =
-
let (file, specific_func) =
if file =~ "\\(.*\\.c\\):\\(.*\\)"
then
let toprocess =
match specific_func, e with
| None, _ -> true
- | Some s, Ast_c.Definition (((funcs, _, _, c),_)) ->
- s = funcs
+ | Some s, Ast_c.Definition (defbis,_) ->
+ s = defbis.Ast_c.f_name
| _, _ -> false
in
*)
flow
in
- Ograph_extended.print_ograph_mutable flow' ("/tmp/output.dot") true
+ let filename = Filename.temp_file "output" ".dot" in
+ Ograph_extended.print_ograph_mutable flow' (filename) true
)
with Ast_to_flow.Error (x) -> Ast_to_flow.report_error x
)
-
(* ---------------------------------------------------------------------- *)
let test_parse_unparse infile =
if not (infile =~ ".*\\.c")
then pr2 "warning: seems not a .c file";
-(* for cocci: to remove one day
let (program2, _stat) = Parse_c.parse_print_error_heuristic infile in
let program2_with_ppmethod =
- program2 +> List.map (fun x -> x, Unparse_c2.PPnormal)
+ program2 +> List.map (fun x -> x, Unparse_c.PPnormal)
in
- Unparse_c2.pp_program program2_with_ppmethod tmpfile;
+ Unparse_c.pp_program program2_with_ppmethod tmpfile;
Common.command2 ("cat " ^ tmpfile);
(* if want see diff of space => no -b -B *)
Common.command2 (spf "diff -u -p %s %s" infile tmpfile);
(* +> Transformation.test_simple_trans1;*)
-*)
()
)
+> Common.uncurry Common.zip
in
-(* for cocci: to remove one day *)
let program2_with_ppmethod =
- program2 +> List.map (fun x -> x, Unparse_c2.PPnormal)
+ program2 +> List.map (fun x -> x, Unparse_c.PPnormal)
in
- Unparse_c2.pp_program program2_with_ppmethod tmpfile;
+ Unparse_c.pp_program program2_with_ppmethod tmpfile;
Common.command2 ("cat " ^ tmpfile);
();;
open Common.BasicType
val test_tokens_c : filename -> unit
+
(* parse and handle some regression information when called with dirmode *)
val test_parse_c : filename list -> unit
val test_parse_h : filename list -> unit
let is_space = function
| TCommentSpace _ -> true
+ | TCommentNewline _ -> true
| _ -> false
+let is_whitespace = is_space
+
let is_comment_or_space = function
| TComment _ -> true
| TCommentSpace _ -> true
-
+ | TCommentNewline _ -> true
| _ -> false
+let is_real_comment = is_comment_or_space
let is_just_comment = function
| TComment _ -> true
| _ -> false
-
-
-
-
let is_comment = function
- | TComment _ | TCommentSpace _ | TCommentNewline _
+ | TComment _
+ | TCommentSpace _ | TCommentNewline _
| TCommentCpp _
| TCommentMisc _ -> true
| _ -> false
-let is_real_comment = function
- | TComment _ | TCommentSpace _ | TCommentNewline _
- -> true
- | _ -> false
let is_fake_comment = function
| TCommentCpp _ | TCommentMisc _
not (is_comment x)
+
+
+
let is_cpp_instruction = function
- | TInclude _ | TDefine _
- | TIfdef _ | TIfdefelse _ | TIfdefelif _
- | TEndif _
+ | TInclude _
+ | TDefine _
+ | TIfdef _ | TIfdefelse _ | TIfdefelif _ | TEndif _
| TIfdefBool _ | TIfdefMisc _ | TIfdefVersion _
+ | TUndef _
+ | TCppDirectiveOther _
+ -> true
+ | _ -> false
+
+
+let is_gcc_token = function
+ | Tasm _
+ | Tinline _
+ | Tattribute _
+ | Ttypeof _
-> true
| _ -> false
| TCPar _ | TCParEOL _ -> true
| _ -> false
+
+let is_obrace = function
+ | TOBrace _ | TOBraceDefineInit _ -> true
+ | _ -> false
+
+let is_cbrace = function
+ | TCBrace _ -> true
+ | _ -> false
+
+
+
+
let is_eof = function
| EOF x -> true
| _ -> false
+
+
let is_statement = function
| Tfor _ | Tdo _ | Tif _ | Twhile _ | Treturn _
| Tbreak _ | Telse _ | Tswitch _ | Tcase _ | Tcontinue _
| TDefine (ii) -> ii
| TInclude (includes, filename, inifdef, i1) -> i1
+ | TUndef (s, ii) -> ii
+ | TCppDirectiveOther (ii) -> ii
+
| TIncludeStart (i1, inifdef) -> i1
| TIncludeFilename (s, i1) -> i1
| TCppEscapedNewline (ii) -> ii
| TDefParamVariadic (s, i1) -> i1
+ | TOBraceDefineInit (i1) -> i1
+
| TUnknown (i) -> i
- | TMacroStmt (i) -> i
- | TMacroString (i) -> i
+ | TMacroAttr (s, i) -> i
+ | TMacroAttrStorage (s, i) -> i
+ | TMacroStmt (s, i) -> i
+ | TMacroString (s, i) -> i
| TMacroDecl (s, i) -> i
+ | TMacroStructDecl (s, i) -> i
| TMacroDeclConst (i) -> i
| TMacroIterator (s,i) -> i
(* | TMacroTop (s,i) -> i *)
| TCommentCpp (cppkind, i) -> i
| TCommentMisc (i) -> i
- | TIfdef (i) -> i
- | TIfdefelse (i) -> i
- | TIfdefelif (i) -> i
- | TEndif (i) -> i
- | TIfdefBool (b, i) -> i
- | TIfdefMisc (b, i) -> i
- | TIfdefVersion (b, i) -> i
+ | TIfdef (_, i) -> i
+ | TIfdefelse (_, i) -> i
+ | TIfdefelif (_, i) -> i
+ | TEndif (_, i) -> i
+ | TIfdefBool (b, _, i) -> i
+ | TIfdefMisc (b, _, i) -> i
+ | TIfdefVersion (b, _, i) -> i
| TOPar (i) -> i
| TCPar (i) -> i
| Tstatic (i) -> i
| Tconst (i) -> i
| Tvolatile (i) -> i
+
+ | Trestrict (i) -> i
+
| Tstruct (i) -> i
| Tenum (i) -> i
| Ttypedef (i) -> i
+
(* used by tokens to complete the parse_info with filename, line, col infos *)
let visitor_info_of_tok f = function
| TString ((s, isWchar), i) -> TString ((s, isWchar), f i)
| TDefine (i1) -> TDefine(f i1)
+ | TUndef (s,i1) -> TUndef(s, f i1)
+ | TCppDirectiveOther (i1) -> TCppDirectiveOther(f i1)
+
| TInclude (includes, filename, inifdef, i1) ->
TInclude (includes, filename, inifdef, f i1)
| TDefParamVariadic (s, i1) -> TDefParamVariadic (s, f i1)
+ | TOBraceDefineInit (i1) -> TOBraceDefineInit (f i1)
+
| TUnknown (i) -> TUnknown (f i)
- | TMacroStmt (i) -> TMacroStmt (f i)
- | TMacroString (i) -> TMacroString (f i)
- | TMacroDecl (s,i) -> TMacroDecl (s, f i)
+ | TMacroAttr (s, i) -> TMacroAttr (s, f i)
+ | TMacroAttrStorage (s, i) -> TMacroAttrStorage (s, f i)
+ | TMacroStmt (s, i) -> TMacroStmt (s, f i)
+ | TMacroString (s, i) -> TMacroString (s, f i)
+ | TMacroDecl (s, i) -> TMacroDecl (s, f i)
+ | TMacroStructDecl (s, i) -> TMacroStructDecl (s, f i)
| TMacroDeclConst (i) -> TMacroDeclConst (f i)
- | TMacroIterator (s,i) -> TMacroIterator (s,f i)
+ | TMacroIterator (s, i) -> TMacroIterator (s, f i)
(* | TMacroTop (s,i) -> TMacroTop (s,f i) *)
| TCParEOL (i) -> TCParEOL (f i)
| TCommentNewline (i) -> TCommentNewline (f i)
| TCommentCpp (cppkind, i) -> TCommentCpp (cppkind, f i)
| TCommentMisc (i) -> TCommentMisc (f i)
- | TIfdef (i) -> TIfdef (f i)
- | TIfdefelse (i) -> TIfdefelse (f i)
- | TIfdefelif (i) -> TIfdefelif (f i)
- | TEndif (i) -> TEndif (f i)
- | TIfdefBool (b, i) -> TIfdefBool (b, f i)
- | TIfdefMisc (b, i) -> TIfdefMisc (b, f i)
- | TIfdefVersion (b, i) -> TIfdefVersion (b, f i)
+
+ | TIfdef (t, i) -> TIfdef (t, f i)
+ | TIfdefelse (t, i) -> TIfdefelse (t, f i)
+ | TIfdefelif (t, i) -> TIfdefelif (t, f i)
+ | TEndif (t, i) -> TEndif (t, f i)
+ | TIfdefBool (b, t, i) -> TIfdefBool (b, t, f i)
+ | TIfdefMisc (b, t, i) -> TIfdefMisc (b, t, f i)
+ | TIfdefVersion (b, t, i) -> TIfdefVersion (b, t, f i)
| TOPar (i) -> TOPar (f i)
| TCPar (i) -> TCPar (f i)
| Tstatic (i) -> Tstatic (f i)
| Tconst (i) -> Tconst (f i)
| Tvolatile (i) -> Tvolatile (f i)
+
+ | Trestrict (i) -> Trestrict (f i)
+
| Tstruct (i) -> Tstruct (f i)
| Tenum (i) -> Tenum (f i)
| Ttypedef (i) -> Ttypedef (f i)
val is_not_comment : Parser_c.token -> bool
val is_cpp_instruction : Parser_c.token -> bool
+val is_gcc_token : Parser_c.token -> bool
+
val is_eof : Parser_c.token -> bool
val is_statement : Parser_c.token -> bool
val is_start_of_something : Parser_c.token -> bool
val is_opar : Parser_c.token -> bool
val is_cpar : Parser_c.token -> bool
+val is_obrace : Parser_c.token -> bool
+val is_cbrace : Parser_c.token -> bool
+
val info_of_tok : Parser_c.token -> Ast_c.info
-(* Copyright (C) 2002-2008 Yoann Padioleau
+(* Copyright (C) 2007, 2008 Yoann Padioleau
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License (GPL)
fun fld (su, fields) ->
fields +> Common.find_some (fun x ->
match Ast_c.unwrap x with
- | FieldDeclList onefield_multivars ->
+ | DeclarationField (FieldDeclList (onefield_multivars, iiptvirg)) ->
Common.optionise (fun () ->
onefield_multivars +> Common.find_some (fun fieldkind ->
)
)
| EmptyField -> None
+ | MacroStructDeclTodo -> pr2 "DeclTodo"; None
+ | CppDirectiveStruct _
+ | IfdefStruct _ -> pr2 "StructCpp"; None
)
Visitor_c.kdecl = (fun (k, bigf) d ->
(match d with
| (DeclList (xs, ii)) ->
- xs +> List.iter (fun ((var, t, sto, local), iicomma) ->
+ xs +> List.iter (fun ({v_namei = var; v_type = t;
+ v_storage = sto; v_local = local}, iicomma) ->
+
let local =
match local with
Ast_c.NotLocalDecl -> Ast_c.NotLocalVar
_notyped_var := Hashtbl.create 100;
match elem with
| Definition def ->
- let (funcs, ((returnt, (paramst, b)) as ftyp), sto, statxs),ii = def
+ let {f_name = funcs;
+ f_type = ((returnt, (paramst, b)) as ftyp);
+ f_storage = sto;
+ f_body = statxs},ii = def
in
let (i1, i2) =
match ii with
-(* Copyright (C) 2002-2008 Yoann Padioleau
+(* Copyright (C) 2006, 2007, 2008 Yoann Padioleau
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License (GPL)
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* file license.txt for more details.
+ *
+ *
+ * Modifications by Julia Lawall for better newline handling.
*)
open Common
let mcode_contain_plus = function
| Ast_cocci.CONTEXT (_,Ast_cocci.NOTHING) -> false
| Ast_cocci.CONTEXT _ -> true
+(* patch: when need full coccinelle transformation *)
| Ast_cocci.MINUS (_,[]) -> false
| Ast_cocci.MINUS (_,x::xs) -> true
| Ast_cocci.PLUS -> raise Impossible
let is_fake = function Fake1 _ -> true | _ -> false in
let is_whitespace = function
T1(Parser_c.TCommentSpace _)
+ (* patch: cocci *)
| T1(Parser_c.TCommentNewline _) -> true
| _ -> false in
let rec loop toks =
bef @ fake :: (loop aft)
| (Ast_cocci.CONTEXT(_,Ast_cocci.BEFOREAFTER _),_) ->
failwith "fake node should not be before-after"
- | _ -> bef @ fake :: (loop aft))
+ | _ -> bef @ fake :: (loop aft) (* old: was removed when have simpler yacfe *)
+ )
| None -> toks
| _ -> raise Impossible in
loop toks
let args_pp = (env, pr_cocci, pr_c, pr_space, indent, unindent) in
+ (* old: when for yacfe with partial cocci:
+ * add_elem t false;
+ *)
+ (* patch: when need full coccinelle transformation *)
match mcode with
| Ast_cocci.MINUS (_,any_xxs) ->
(* Why adding ? because I want to have all the information, the whole
* set of tokens, so I can then process and remove the
* is_between_two_minus for instance *)
add_elem t true;
- Unparse_cocci2.pp_list_list_any args_pp any_xxs Unparse_cocci2.InPlace
+ Unparse_cocci.pp_list_list_any args_pp any_xxs Unparse_cocci.InPlace
| Ast_cocci.CONTEXT (_,any_befaft) ->
(match any_befaft with
| Ast_cocci.NOTHING ->
add_elem t false
| Ast_cocci.BEFORE xxs ->
- Unparse_cocci2.pp_list_list_any args_pp xxs Unparse_cocci2.Before;
+ Unparse_cocci.pp_list_list_any args_pp xxs Unparse_cocci.Before;
add_elem t false
| Ast_cocci.AFTER xxs ->
add_elem t false;
- Unparse_cocci2.pp_list_list_any args_pp xxs Unparse_cocci2.After;
+ Unparse_cocci.pp_list_list_any args_pp xxs Unparse_cocci.After;
| Ast_cocci.BEFOREAFTER (xxs, yys) ->
- Unparse_cocci2.pp_list_list_any args_pp xxs Unparse_cocci2.Before;
+ Unparse_cocci.pp_list_list_any args_pp xxs Unparse_cocci.Before;
add_elem t false;
- Unparse_cocci2.pp_list_list_any args_pp yys Unparse_cocci2.After;
+ Unparse_cocci.pp_list_list_any args_pp yys Unparse_cocci.After;
)
| Ast_cocci.PLUS -> raise Impossible
| T2 (t,_b,_i) ->
(match t with
| Parser_c.TCommentSpace _ (* only whitespace *)
+ (* patch: coccinelle *)
| Parser_c.TCommentNewline _ (* newline plus whitespace *)
| Parser_c.TComment _
| Parser_c.TCommentCpp (Ast_c.CppAttr, _)
| Parser_c.TCommentMisc _
| Parser_c.TCommentCpp (Ast_c.CppDirective, _)
- | Parser_c.TCommentCpp (Ast_c.CppOther, _)
+ | Parser_c.TCommentCpp (Ast_c.CppPassingCosWouldGetError, _)
-> false
| _ -> false
| _ -> false
let is_minusable_comment_or_plus = function
+(* patch: coccinelle *)
T2(Parser_c.TCommentNewline _,_b,_i) -> false
| x -> is_minusable_comment x or all_coccis x
let str = TH.str_of_tok t in
(match t with
| Parser_c.TCommentSpace _
+(* patch: coccinelle *)
| Parser_c.TCommentNewline _ -> ()
| Parser_c.TComment _
| _ -> raise Impossible
);
T2 (t, true, idx)
+(* patch: coccinelle *)
| T2 (Parser_c.TCommentNewline _,true,idx) as x -> x
| _ -> raise Impossible
(*This drops the space before each completely minused block (no plus code).*)
let rec adjust_before_minus = function
[] -> []
+(* patch: coccinelle *)
| (T2(Parser_c.TCommentNewline c,_b,_i) as x)::((T2(_,true,_)::_) as xs) ->
let minus_or_comment = function
T2(_,true,_) -> true
[] -> ()
| ((T2 (tok,_,_)) as x)::xs when str_of_token2 x = "{" ->
find_first_tab true xs
+(* patch: coccinelle *)
| ((T2 (Parser_c.TCommentNewline s, _, _)) as x)::_
when started ->
let s = str_of_token2 x +> new_tabbing in
let rec aux started xs =
match xs with
| [] -> []
+(* patch: coccinelle *)
| ((T2 (tok,_,_)) as x)::(T2 (Parser_c.TCommentNewline s, _, _))::
(Cocci2 "{")::xs when started && str_of_token2 x = ")" ->
(* to be done for if, etc, but not for a function header *)
let pp_program a b =
Common.profile_code "C unparsing" (fun () -> pp_program2 a b)
+
+let pp_program_default xs outfile =
+ let xs' = xs +> List.map (fun x -> x, PPnormal) in
+ pp_program xs' outfile
(* program -> output filename (often "/tmp/output.c") -> unit *)
val pp_program :
(Parse_c.toplevel2 * ppmethod) list -> filename -> unit
+
+val pp_program_default: Parse_c.program2 -> filename -> unit
il)
| _ -> failwith "function must have named parameters"
-let print_metavariables pr (s, (_, (paramst, (b, iib))), _, _) header_req =
+let print_metavariables pr defn header_req =
+ let {Ast_c.f_name = s; f_type = (_, (paramst, (b, iib))); } = defn in
(if header_req
then pr "@depends on header@\n"
else pr "@@\n");
((_,Some param,_),_) -> pr param
| _ -> failwith "function must have named parameters"
-let pp_def_gen pr (s, (_, (paramst, (b, iib))), _, _) isexp =
+let pp_def_gen pr defn isexp =
+ let {Ast_c.f_name = s; f_type = (_, (paramst, (b, iib))); } = defn in
pr s; pr "(";
(if b then failwith "not handling variable argument functions");
(match paramst with
let pp_program (e,(str, toks_e)) outdir srcfile isexp =
match e with
- Ast_c.Definition(((name,_,_,_) as defn),_) ->
+ Ast_c.Definition(({Ast_c.f_name = name;} as defn),_) ->
(* generate the - code *)
drop_header_toks toks_e;
let toks_e = strip_comments toks_e in
let tmp_file = Common.new_temp_file "cocci_small_output" ".c" in
- Unparse_c2.pp_program [((e,(str, toks_e)), Unparse_c2.PPnormal)]
+ Unparse_c.pp_program [((e,(str, toks_e)), Unparse_c.PPnormal)]
tmp_file;
let outfile = outdir ^ "/" ^ name in
let outfile =
-(* Copyright (C) 2002-2008 Yoann Padioleau
+(* Copyright (C) 2006, 2007, 2008 Yoann Padioleau
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License (GPL)
(* Visitor based on continuation. Cleaner than the one based on mutable
- * pointer functions. src: based on a (vague) idea from Remy Douence.
+ * pointer functions that I had before.
+ * src: based on a (vague) idea from Remy Douence.
*
*
*
*
* Note that I don't visit necesserally in the order of the token
* found in the original file. So don't assume such hypothesis!
+ *
+ * todo? parameter ? onedecl ?
*)
type visitor_c =
{
kdef: (definition -> unit) * visitor_c -> definition -> unit;
kini: (initialiser -> unit) * visitor_c -> initialiser -> unit;
- kinfo: (info -> unit) * visitor_c -> info -> unit;
+ kcppdirective: (cpp_directive -> unit) * visitor_c -> cpp_directive -> unit;
+ kdefineval : (define_val -> unit) * visitor_c -> define_val -> unit;
+ kstatementseq: (statement_sequencable -> unit) * visitor_c -> statement_sequencable -> unit;
(* CFG *)
knode: (F.node -> unit) * visitor_c -> F.node -> unit;
(* AST *)
ktoplevel: (toplevel -> unit) * visitor_c -> toplevel -> unit;
+
+ kinfo: (info -> unit) * visitor_c -> info -> unit;
}
let default_visitor_c =
kinfo = (fun (k,_) ii -> k ii);
knode = (fun (k,_) n -> k n);
ktoplevel = (fun (k,_) p -> k p);
+ kcppdirective = (fun (k,_) p -> k p);
+ kdefineval = (fun (k,_) p -> k p);
+ kstatementseq = (fun (k,_) p -> k p);
}
+
+(* ------------------------------------------------------------------------ *)
+
+
let rec vk_expr = fun bigf expr ->
let iif ii = vk_ii bigf ii in
| Constant (c) -> ()
| FunCall (e, es) ->
exprf e;
- es +> List.iter (fun (e, ii) ->
- iif ii;
- vk_argument bigf e
- );
+ vk_argument_list bigf es;
| CondExpr (e1, e2, e3) ->
exprf e1; do_option (exprf) e2; exprf e3
| Sequence (e1, e2) -> exprf e1; exprf e2;
*)
| StatementExpr ((statxs, is)) ->
iif is;
- statxs +> List.iter (vk_statement bigf);
+ statxs +> List.iter (vk_statement_sequencable bigf);
(* TODO, we will certainly have to then do a special visitor for
* initializer
in exprf expr
-and vk_argument = fun bigf arg ->
- let rec do_action = function
- | (ActMisc ii) -> vk_ii bigf ii
- in
- match arg with
- | Left e -> (vk_expr bigf) e
- | Right (ArgType param) -> vk_param bigf param
- | Right (ArgAction action) -> do_action action
-and vk_statement = fun bigf st ->
+and vk_statement = fun bigf (st: Ast_c.statement) ->
let iif ii = vk_ii bigf ii in
let rec statf x = bigf.kstatement (k,bigf) x
vk_expr bigf e; vk_expr bigf e2; statf st;
| Labeled (Default st) -> statf st;
- | Compound statxs -> statxs +> List.iter (vk_statement bigf)
+ | Compound statxs ->
+ statxs +> List.iter (vk_statement_sequencable bigf)
| ExprStatement (eopt) -> do_option (vk_expr bigf) eopt;
| Selection (If (e, st1, st2)) ->
vk_expr bigf e; statf st1; statf st2;
- | Selection (Ifdef (st1s, st2s)) ->
- st1s +> List.iter (vk_statement bigf);
- st2s +> List.iter (vk_statement bigf)
| Selection (Switch (e, st)) ->
vk_expr bigf e; statf st;
| Iteration (While (e, st)) ->
statf st;
| Iteration (MacroIteration (s, es, st)) ->
- es +> List.iter (fun (e, ii) ->
- iif ii;
- vk_argument bigf e
- );
+ vk_argument_list bigf es;
statf st;
| Jump (Goto s) -> ()
in statf st
-and vk_asmbody = fun bigf (string_list, colon_list) ->
- let iif ii = vk_ii bigf ii in
+and vk_statement_sequencable = fun bigf stseq ->
+ let f = bigf.kstatementseq in
+
+ let rec k stseq =
+ match stseq with
+ | StmtElem st -> vk_statement bigf st
+ | CppDirectiveStmt directive ->
+ vk_cpp_directive bigf directive
+ | IfdefStmt ifdef ->
+ vk_ifdef_directive bigf ifdef
+ | IfdefStmt2 (ifdef, xxs) ->
+ ifdef +> List.iter (vk_ifdef_directive bigf);
+ xxs +> List.iter (fun xs ->
+ xs +> List.iter (vk_statement_sequencable bigf)
+ )
+
+ in f (k, bigf) stseq
+
- iif string_list;
- colon_list +> List.iter (fun (Colon xs, ii) ->
- iif ii;
- xs +> List.iter (fun (x,iicomma) ->
- iif iicomma;
- (match x with
- | ColonMisc, ii -> iif ii
- | ColonExpr e, ii ->
- vk_expr bigf e;
- iif ii
- )
- ))
and vk_type = fun bigf t ->
let iif ii = vk_ii bigf ii in
(match paramst with
| (ts, (b,iihas3dots)) ->
iif iihas3dots;
- ts +> List.iter (fun (param,iicomma) ->
- vk_param bigf param;
- iif iicomma;
-
- )
+ vk_param_list bigf ts
)
| Enum (sopt, enumt) ->
in typef t
+
+and vk_attribute = fun bigf attr ->
+ let iif ii = vk_ii bigf ii in
+ match attr with
+ | Attribute s, ii ->
+ iif ii
+
+
+(* ------------------------------------------------------------------------ *)
+
and vk_decl = fun bigf d ->
let iif ii = vk_ii bigf ii in
| DeclList (xs,ii) -> iif ii; List.iter aux xs
| MacroDecl ((s, args),ii) ->
iif ii;
- args +> List.iter (fun (e, ii) ->
- iif ii;
- vk_argument bigf e
- );
+ vk_argument_list bigf args;
- and aux ((var, t, _sto, _local), iicomma) =
+ and aux ({v_namei = var; v_type = t;
+ v_storage = _sto; v_attr = attrs}, iicomma) =
iif iicomma;
vk_type bigf t;
+ attrs +> List.iter (vk_attribute bigf);
var +> do_option (fun ((s, ini), ii_s_ini) ->
iif ii_s_ini;
ini +> do_option (vk_ini bigf)
| InitIndexOld (e1, e) ->
vk_expr bigf e1; inif e
+
in inif ini
| DesignatorIndex e -> vk_expr bigf e
| DesignatorRange (e1, e2) -> vk_expr bigf e1; vk_expr bigf e2
+
+(* ------------------------------------------------------------------------ *)
+
and vk_struct_fields = fun bigf fields ->
let iif ii = vk_ii bigf ii in
fields +> List.iter (fun (xfield, ii) ->
iif ii;
match xfield with
- | FieldDeclList onefield_multivars ->
- vk_struct_field bigf onefield_multivars
+ | DeclarationField
+ (FieldDeclList (onefield_multivars, iiptvirg)) ->
+ vk_struct_fieldkinds bigf onefield_multivars;
+ iif iiptvirg;
| EmptyField -> ()
+ | MacroStructDeclTodo ->
+ pr2 "MacroStructDeclTodo";
+ ()
+
+ | CppDirectiveStruct directive ->
+ vk_cpp_directive bigf directive
+ | IfdefStruct ifdef ->
+ vk_ifdef_directive bigf ifdef
+
)
-and vk_struct_field = fun bigf onefield_multivars ->
+and vk_struct_fieldkinds = fun bigf onefield_multivars ->
let iif ii = vk_ii bigf ii in
onefield_multivars +> List.iter (fun (field, iicomma) ->
iif iicomma;
vk_type bigf t
)
+(* ------------------------------------------------------------------------ *)
and vk_def = fun bigf d ->
let f = bigf.kdef in
let rec k d =
match d with
- | (s, (returnt, (paramst, (b, iib))), sto, statxs), ii ->
+ | {f_name = s;
+ f_type = (returnt, (paramst, (b, iib)));
+ f_storage = sto;
+ f_body = statxs;
+ f_attr = attrs;
+ }, ii
+ ->
iif ii;
iif iib;
+ attrs +> List.iter (vk_attribute bigf);
vk_type bigf returnt;
paramst +> List.iter (fun (param,iicomma) ->
vk_param bigf param;
iif iicomma;
);
- statxs +> List.iter (vk_statement bigf)
+ statxs +> List.iter (vk_statement_sequencable bigf)
in f (k, bigf) d
| Definition def -> (vk_def bigf def)
| EmptyDef ii -> iif ii
| MacroTop (s, xs, ii) ->
- xs +> List.iter (fun (elem, iicomma) ->
- vk_argument bigf elem; iif iicomma
- );
- iif ii
+ vk_argument_list bigf xs;
+ iif ii
+
+ | CppTop top -> vk_cpp_directive bigf top
+ | IfdefTop ifdefdir -> vk_ifdef_directive bigf ifdefdir
- | Include ((s, ii), h_rel_pos) -> iif ii;
+ | NotParsedCorrectly ii -> iif ii
+ | FinalDef info -> vk_info bigf info
+ in f (k, bigf) p
+
+and vk_program = fun bigf xs ->
+ xs +> List.iter (vk_toplevel bigf)
+
+and vk_ifdef_directive bigf directive =
+ let iif ii = vk_ii bigf ii in
+ match directive with
+ | IfdefDirective (ifkind, ii) -> iif ii
+
+
+and vk_cpp_directive bigf directive =
+ let iif ii = vk_ii bigf ii in
+ let f = bigf.kcppdirective in
+ let rec k directive =
+ match directive with
+ | Include {i_include = (s, ii);
+ i_content = copt;
+ }
+ ->
+ (* go inside ? *)
+ iif ii;
+ copt +> Common.do_option (fun (file, asts) ->
+ vk_program bigf asts
+ );
| Define ((s,ii), (defkind, defval)) ->
iif ii;
vk_define_kind bigf defkind;
vk_define_val bigf defval
+ | Undef (s, ii) ->
+ iif ii
+ | PragmaAndCo (ii) ->
+ iif ii
+ in f (k, bigf) directive
- | NotParsedCorrectly ii -> iif ii
- | FinalDef info -> vk_info bigf info
- in f (k, bigf) p
and vk_define_kind bigf defkind =
match defkind with
)
and vk_define_val bigf defval =
+ let f = bigf.kdefineval in
+
+ let rec k defval =
match defval with
| DefineExpr e ->
vk_expr bigf e
| DefineStmt stmt -> vk_statement bigf stmt
- | DefineDoWhileZero (stmt, ii) ->
+ | DefineDoWhileZero ((stmt, e), ii) ->
vk_statement bigf stmt;
+ vk_expr bigf e;
vk_ii bigf ii
| DefineFunction def -> vk_def bigf def
| DefineType ty -> vk_type bigf ty
| DefineText (s, ii) -> vk_ii bigf ii
| DefineEmpty -> ()
+ | DefineInit ini -> vk_ini bigf ini
+
+ | DefineTodo ->
+ pr2 "DefineTodo";
+ ()
+ in f (k, bigf) defval
+
* be deeper, in the then branch). So have to not visit
* all inside a node anymore.
*
- * update: j'ai choisi d'accrocher au noeud du CFG Ã la
+ * update: j'ai choisi d'accrocher au noeud du CFG a la
* fois le fullstatement et le partialstatement et appeler le
* visiteur que sur le partialstatement.
*)
let rec k n =
match F.unwrap n with
- | F.FunHeader ((idb, (rett, (paramst,(isvaargs,iidotsb))), stob),ii) ->
+ | F.FunHeader ({f_name =idb;
+ f_type = (rett, (paramst,(isvaargs,iidotsb)));
+ f_storage = stob;
+ f_body = body;
+ f_attr = attrs},ii) ->
+
+ assert(null body);
+ iif ii;
+ iif iidotsb;
+ attrs +> List.iter (vk_attribute bigf);
vk_type bigf rett;
paramst +> List.iter (fun (param, iicomma) ->
vk_param bigf param;
e3opt +> do_option (vk_expr bigf);
| F.MacroIterHeader (_s, ((s,es), ii)) ->
iif ii;
- es +> List.iter (fun (e, ii) ->
- iif ii;
- vk_argument bigf e
- );
+ vk_argument_list bigf es;
| F.ReturnExpr (_st, (e,ii)) -> iif ii; vk_expr bigf e
vk_define_kind bigf defkind;
| F.DefineDoWhileZeroHeader (((),ii)) -> iif ii
+ | F.DefineTodo ->
+ pr2 "DefineTodo";
+ ()
+
- | F.Include ((s, ii),h_rel_pos) -> iif ii
+ | F.Include {i_include = (s, ii);} -> iif ii;
| F.MacroTop (s, args, ii) ->
iif ii;
- args +> List.iter (fun (e, ii) -> vk_argument bigf e; iif ii)
+ vk_argument_list bigf args
- | F.Ifdef (st, ((),ii)) -> iif ii
+ | F.IfdefHeader (info) -> vk_ifdef_directive bigf info
+ | F.IfdefElse (info) -> vk_ifdef_directive bigf info
+ | F.IfdefEndif (info) -> vk_ifdef_directive bigf info
| F.Break (st,((),ii)) -> iif ii
| F.Continue (st,((),ii)) -> iif ii
| F.Return (st,((),ii)) -> iif ii
| F.Goto (st, (s,ii)) -> iif ii
| F.Label (st, (s,ii)) -> iif ii
- | F.EndStatement iopt -> do_option infof iopt
+
| F.DoHeader (st, info) -> infof info
+
| F.Else info -> infof info
+ | F.EndStatement iopt -> do_option infof iopt
+
| F.SeqEnd (i, info) -> infof info
| F.SeqStart (st, i, info) -> infof info
List.iter (vk_info bigf) ii
+(* ------------------------------------------------------------------------ *)
+and vk_argument = fun bigf arg ->
+ let rec do_action = function
+ | (ActMisc ii) -> vk_ii bigf ii
+ in
+ match arg with
+ | Left e -> (vk_expr bigf) e
+ | Right (ArgType param) -> vk_param bigf param
+ | Right (ArgAction action) -> do_action action
+
+and vk_argument_list = fun bigf es ->
+ let iif ii = vk_ii bigf ii in
+ es +> List.iter (fun (e, ii) ->
+ iif ii;
+ vk_argument bigf e
+ )
+
+
+
and vk_param = fun bigf (((b, s, t), ii_b_s)) ->
let iif ii = vk_ii bigf ii in
iif ii_b_s;
vk_type bigf t
+and vk_param_list = fun bigf ts ->
+ let iif ii = vk_ii bigf ii in
+ ts +> List.iter (fun (param,iicomma) ->
+ vk_param bigf param;
+ iif iicomma;
+ )
+
+
+
+(* ------------------------------------------------------------------------ *)
+and vk_asmbody = fun bigf (string_list, colon_list) ->
+ let iif ii = vk_ii bigf ii in
+
+ iif string_list;
+ colon_list +> List.iter (fun (Colon xs, ii) ->
+ iif ii;
+ xs +> List.iter (fun (x,iicomma) ->
+ iif iicomma;
+ (match x with
+ | ColonMisc, ii -> iif ii
+ | ColonExpr e, ii ->
+ vk_expr bigf e;
+ iif ii
+ )
+ ))
+
+(* ------------------------------------------------------------------------ *)
let vk_args_splitted = fun bigf args_splitted ->
let iif ii = vk_ii bigf ii in
args_splitted +> List.iter (function
| Right ii -> iif ii
)
-
+(* ------------------------------------------------------------------------ *)
let vk_cst = fun bigf (cst, ii) ->
let iif ii = vk_ii bigf ii in
iif ii;
(*****************************************************************************)
(* "syntetisized attributes" style *)
(*****************************************************************************)
+
+(* TODO port the xxs_s to new cpp construct too *)
+
type 'a inout = 'a -> 'a
(* _s for synthetizized attributes
kexpr_s: (expression inout * visitor_c_s) -> expression inout;
kstatement_s: (statement inout * visitor_c_s) -> statement inout;
ktype_s: (fullType inout * visitor_c_s) -> fullType inout;
- kini_s: (initialiser inout * visitor_c_s) -> initialiser inout;
kdecl_s: (declaration inout * visitor_c_s) -> declaration inout;
kdef_s: (definition inout * visitor_c_s) -> definition inout;
- ktoplevel_s: (toplevel inout * visitor_c_s) -> toplevel inout;
- knode_s: (F.node inout * visitor_c_s) -> F.node inout;
+ kini_s: (initialiser inout * visitor_c_s) -> initialiser inout;
+ kcppdirective_s: (cpp_directive inout * visitor_c_s) -> cpp_directive inout;
kdefineval_s: (define_val inout * visitor_c_s) -> define_val inout;
+ kstatementseq_s: (statement_sequencable inout * visitor_c_s) -> statement_sequencable inout;
+ kstatementseq_list_s: (statement_sequencable list inout * visitor_c_s) -> statement_sequencable list inout;
+
+ knode_s: (F.node inout * visitor_c_s) -> F.node inout;
+
+ ktoplevel_s: (toplevel inout * visitor_c_s) -> toplevel inout;
kinfo_s: (info inout * visitor_c_s) -> info inout;
}
knode_s = (fun (k,_) n -> k n);
kinfo_s = (fun (k,_) i -> k i);
kdefineval_s = (fun (k,_) x -> k x);
+ kstatementseq_s = (fun (k,_) x -> k x);
+ kstatementseq_list_s = (fun (k,_) x -> k x);
+ kcppdirective_s = (fun (k,_) x -> k x);
}
let rec vk_expr_s = fun bigf expr ->
| StatementExpr (statxs, is) ->
StatementExpr (
- statxs +> List.map (vk_statement_s bigf),
+ vk_statement_sequencable_list_s bigf statxs,
iif is)
| Constructor (t, initxs) ->
Constructor
statf st))
| Labeled (Default st) -> Labeled (Default (statf st))
| Compound statxs ->
- Compound (statxs +> List.map (vk_statement_s bigf))
+ Compound (vk_statement_sequencable_list_s bigf statxs)
| ExprStatement (None) -> ExprStatement (None)
| ExprStatement (Some e) -> ExprStatement (Some ((vk_expr_s bigf) e))
| Selection (If (e, st1, st2)) ->
Selection (If ((vk_expr_s bigf) e, statf st1, statf st2))
- | Selection (Ifdef (st1s, st2s)) ->
- Selection (Ifdef
- (st1s +> List.map (vk_statement_s bigf),
- st2s +> List.map (vk_statement_s bigf)))
| Selection (Switch (e, st)) ->
Selection (Switch ((vk_expr_s bigf) e, statf st))
| Iteration (While (e, st)) ->
st', vk_ii_s bigf ii
in statf st
+
+and vk_statement_sequencable_s = fun bigf stseq ->
+ let f = bigf.kstatementseq_s in
+ let k stseq =
+
+ match stseq with
+ | StmtElem st ->
+ StmtElem (vk_statement_s bigf st)
+ | CppDirectiveStmt directive ->
+ CppDirectiveStmt (vk_cpp_directive_s bigf directive)
+ | IfdefStmt ifdef ->
+ IfdefStmt (vk_ifdef_directive_s bigf ifdef)
+ | IfdefStmt2 (ifdef, xxs) ->
+ let ifdef' = List.map (vk_ifdef_directive_s bigf) ifdef in
+ let xxs' = xxs +> List.map (fun xs ->
+ xs +> List.map (vk_statement_sequencable_s bigf)
+ )
+ in
+ IfdefStmt2(ifdef', xxs')
+ in f (k, bigf) stseq
+
+and vk_statement_sequencable_list_s = fun bigf statxs ->
+ let f = bigf.kstatementseq_list_s in
+ let k xs =
+ xs +> List.map (vk_statement_sequencable_s bigf)
+ in
+ f (k, bigf) statxs
+
+
+
and vk_asmbody_s = fun bigf (string_list, colon_list) ->
let iif ii = vk_ii_s bigf ii in
in typef t
+and vk_attribute_s = fun bigf attr ->
+ let iif ii = vk_ii_s bigf ii in
+ match attr with
+ | Attribute s, ii ->
+ Attribute s, iif ii
+
+
+
and vk_decl_s = fun bigf d ->
let f = bigf.kdecl_s in
let iif ii = vk_ii_s bigf ii in
iif ii)
- and aux ((var, t, sto, local), iicomma) =
- ((var +> map_option (fun ((s, ini), ii_s_ini) ->
+ and aux ({v_namei = var; v_type = t;
+ v_storage = sto; v_local= local; v_attr = attrs}, iicomma) =
+ {v_namei =
+ (var +> map_option (fun ((s, ini), ii_s_ini) ->
(s, ini +> map_option (fun init -> vk_ini_s bigf init)),
iif ii_s_ini
- )
- ),
- vk_type_s bigf t,
- sto, local),
- iif iicomma
+ )
+ );
+ v_type = vk_type_s bigf t;
+ v_storage = sto;
+ v_local = local;
+ v_attr = attrs +> List.map (vk_attribute_s bigf);
+ },
+ iif iicomma
in f (k, bigf) d
| InitFieldOld (s, e) -> InitFieldOld (s, inif e)
| InitIndexOld (e1, e) -> InitIndexOld (vk_expr_s bigf e1, inif e)
+
in ini', vk_ii_s bigf ii
in inif ini
+and vk_struct_fieldkinds_s = fun bigf onefield_multivars ->
+ let iif ii = vk_ii_s bigf ii in
+
+ onefield_multivars +> List.map (fun (field, iicomma) ->
+ (match field with
+ | Simple (s, t), iis -> Simple (s, vk_type_s bigf t), iif iis
+ | BitField (sopt, t, expr), iis ->
+ BitField (sopt, vk_type_s bigf t, vk_expr_s bigf expr),
+ iif iis
+ ), iif iicomma
+ )
+
and vk_struct_fields_s = fun bigf fields ->
let iif ii = vk_ii_s bigf ii in
fields +> List.map (fun (xfield, iiptvirg) ->
(match xfield with
- | FieldDeclList onefield_multivars ->
- FieldDeclList (
- onefield_multivars +> List.map (fun (field, iicomma) ->
- (match field with
- | Simple (s, t), iis -> Simple (s, vk_type_s bigf t), iif iis
- | BitField (sopt, t, expr), iis ->
- BitField (sopt, vk_type_s bigf t, vk_expr_s bigf expr),
- iif iis
- ), iif iicomma
- )
- )
+ | (DeclarationField (FieldDeclList (onefield_multivars, iiptvirg))) ->
+ DeclarationField
+ (FieldDeclList
+ (vk_struct_fieldkinds_s bigf onefield_multivars, iif iiptvirg))
| EmptyField -> EmptyField
+ | MacroStructDeclTodo ->
+ pr2 "MacroStructDeclTodo";
+ MacroStructDeclTodo
+
+ | CppDirectiveStruct directive ->
+ CppDirectiveStruct (vk_cpp_directive_s bigf directive)
+ | IfdefStruct ifdef ->
+ IfdefStruct (vk_ifdef_directive_s bigf ifdef)
+
), iif iiptvirg
)
let iif ii = vk_ii_s bigf ii in
let rec k d =
match d with
- | (s, (returnt, (paramst, (b, iib))), sto, statxs), ii ->
- (s,
- (vk_type_s bigf returnt,
- (paramst +> List.map (fun (param, iicomma) ->
- (vk_param_s bigf param, iif iicomma)
- ),
- (b, iif iib))),
- sto,
- statxs +> List.map (vk_statement_s bigf)
- ),
+ | {f_name = s;
+ f_type = (returnt, (paramst, (b, iib)));
+ f_storage = sto;
+ f_body = statxs;
+ f_attr = attrs;
+ }, ii
+ ->
+ {f_name = s;
+ f_type =
+ (vk_type_s bigf returnt,
+ (paramst +> List.map (fun (param, iicomma) ->
+ (vk_param_s bigf param, iif iicomma)
+ ), (b, iif iib)));
+ f_storage = sto;
+ f_body =
+ vk_statement_sequencable_list_s bigf statxs;
+ f_attr =
+ attrs +> List.map (vk_attribute_s bigf)
+ },
iif ii
in f (k, bigf) d
),
iif ii
)
- | Include ((s, ii), h_rel_pos) -> Include ((s, iif ii), h_rel_pos)
- | Define ((s,ii), (defkind, defval)) ->
- Define ((s, iif ii),
- (vk_define_kind_s bigf defkind, vk_define_val_s bigf defval))
+ | CppTop top -> CppTop (vk_cpp_directive_s bigf top)
+ | IfdefTop ifdefdir -> IfdefTop (vk_ifdef_directive_s bigf ifdefdir)
| NotParsedCorrectly ii -> NotParsedCorrectly (iif ii)
| FinalDef info -> FinalDef (vk_info_s bigf info)
in f (k, bigf) p
+and vk_program_s = fun bigf xs ->
+ xs +> List.map (vk_toplevel_s bigf)
+
+
+and vk_cpp_directive_s = fun bigf top ->
+ let iif ii = vk_ii_s bigf ii in
+ let f = bigf.kcppdirective_s in
+ let rec k top =
+ match top with
+ (* go inside ? *)
+ | Include {i_include = (s, ii);
+ i_rel_pos = h_rel_pos;
+ i_is_in_ifdef = b;
+ i_content = copt;
+ }
+ -> Include {i_include = (s, iif ii);
+ i_rel_pos = h_rel_pos;
+ i_is_in_ifdef = b;
+ i_content = copt +> Common.map_option (fun (file, asts) ->
+ file, vk_program_s bigf asts
+ );
+ }
+ | Define ((s,ii), (defkind, defval)) ->
+ Define ((s, iif ii),
+ (vk_define_kind_s bigf defkind, vk_define_val_s bigf defval))
+ | Undef (s, ii) -> Undef (s, iif ii)
+ | PragmaAndCo (ii) -> PragmaAndCo (iif ii)
+
+ in f (k, bigf) top
+
+and vk_ifdef_directive_s = fun bigf ifdef ->
+ let iif ii = vk_ii_s bigf ii in
+ match ifdef with
+ | IfdefDirective (ifkind, ii) -> IfdefDirective (ifkind, iif ii)
+
+
+
and vk_define_kind_s = fun bigf defkind ->
match defkind with
| DefineVar -> DefineVar
match x with
| DefineExpr e -> DefineExpr (vk_expr_s bigf e)
| DefineStmt st -> DefineStmt (vk_statement_s bigf st)
- | DefineDoWhileZero (st,ii) ->
- DefineDoWhileZero (vk_statement_s bigf st, iif ii)
+ | DefineDoWhileZero ((st,e),ii) ->
+ let st' = vk_statement_s bigf st in
+ let e' = vk_expr_s bigf e in
+ DefineDoWhileZero ((st',e'), iif ii)
| DefineFunction def -> DefineFunction (vk_def_s bigf def)
| DefineType ty -> DefineType (vk_type_s bigf ty)
| DefineText (s, ii) -> DefineText (s, iif ii)
| DefineEmpty -> DefineEmpty
+ | DefineInit ini -> DefineInit (vk_ini_s bigf ini)
+
+ | DefineTodo ->
+ pr2 "DefineTodo";
+ DefineTodo
in
f (k, bigf) x
and k node =
F.rewrap node (
match F.unwrap node with
- | F.FunHeader ((idb, (rett, (paramst,(isvaargs,iidotsb))), stob),ii) ->
+ | F.FunHeader ({f_name = idb;
+ f_type =(rett, (paramst,(isvaargs,iidotsb)));
+ f_storage = stob;
+ f_body = body;
+ f_attr = attrs;
+ },ii) ->
+ assert(null body);
+
F.FunHeader
- ((idb,
- (vk_type_s bigf rett,
- (paramst +> List.map (fun (param, iicomma) ->
- (vk_param_s bigf param, iif iicomma)
- ), (isvaargs,iif iidotsb))), stob),iif ii)
+ ({f_name =idb;
+ f_type =
+ (vk_type_s bigf rett,
+ (paramst +> List.map (fun (param, iicomma) ->
+ (vk_param_s bigf param, iif iicomma)
+ ), (isvaargs,iif iidotsb)));
+ f_storage = stob;
+ f_body = body;
+ f_attr =
+ attrs +> List.map (vk_attribute_s bigf)
+ },
+ iif ii)
| F.Decl declb -> F.Decl (vk_decl_s bigf declb)
| F.DefineType ft -> F.DefineType (vk_type_s bigf ft)
| F.DefineDoWhileZeroHeader ((),ii) ->
F.DefineDoWhileZeroHeader ((),iif ii)
+ | F.DefineTodo -> F.DefineTodo
+
+ | F.Include {i_include = (s, ii);
+ i_rel_pos = h_rel_pos;
+ i_is_in_ifdef = b;
+ i_content = copt;
+ }
+ ->
+ assert (copt = None);
+ F.Include {i_include = (s, iif ii);
+ i_rel_pos = h_rel_pos;
+ i_is_in_ifdef = b;
+ i_content = copt;
+ }
- | F.Include ((s, ii), h_rel_pos) -> F.Include ((s, iif ii), h_rel_pos)
- | F.Ifdef (st, ((),ii)) -> F.Ifdef (st, ((),iif ii))
| F.MacroTop (s, args, ii) ->
F.MacroTop
(s,
| F.SeqEnd (i, info) -> F.SeqEnd (i, infof info)
| F.SeqStart (st, i, info) -> F.SeqStart (st, i, infof info)
+ | F.IfdefHeader (info) -> F.IfdefHeader (vk_ifdef_directive_s bigf info)
+ | F.IfdefElse (info) -> F.IfdefElse (vk_ifdef_directive_s bigf info)
+ | F.IfdefEndif (info) -> F.IfdefEndif (vk_ifdef_directive_s bigf info)
+
| (
(
F.TopNode|F.EndNode|
kdecl : (declaration -> unit) * visitor_c -> declaration -> unit;
kdef : (definition -> unit) * visitor_c -> definition -> unit;
kini : (initialiser -> unit) * visitor_c -> initialiser -> unit;
- kinfo : (info -> unit) * visitor_c -> info -> unit;
+ kcppdirective: (cpp_directive -> unit) * visitor_c -> cpp_directive -> unit;
+ kdefineval : (define_val -> unit) * visitor_c -> define_val -> unit;
+ kstatementseq: (statement_sequencable -> unit) * visitor_c -> statement_sequencable -> unit;
knode :
(Control_flow_c.node -> unit) * visitor_c -> Control_flow_c.node -> unit;
ktoplevel: (toplevel -> unit) * visitor_c -> toplevel -> unit;
+ kinfo : (info -> unit) * visitor_c -> info -> unit;
}
val default_visitor_c : visitor_c
val vk_def : visitor_c -> definition -> unit
val vk_node : visitor_c -> Control_flow_c.node -> unit
val vk_info : visitor_c -> info -> unit
-val vk_toplevel : visitor_c -> toplevel -> unit
+val vk_toplevel : visitor_c -> toplevel -> unit
+val vk_program : visitor_c -> program -> unit
val vk_argument : visitor_c -> argument -> unit
val vk_params_splitted :
visitor_c -> (parameterType, il) Common.either list -> unit
-val vk_struct_fields : visitor_c -> field wrap list -> unit
-val vk_struct_field : visitor_c -> fieldkind wrap list -> unit
+val vk_struct_fields : visitor_c -> field list -> unit
+val vk_struct_fieldkinds : visitor_c -> fieldkind wrap list -> unit
val vk_cst : visitor_c -> ((constant, string) Common.either wrap) -> unit
kexpr_s : expression inout * visitor_c_s -> expression inout;
kstatement_s : statement inout * visitor_c_s -> statement inout;
ktype_s : fullType inout * visitor_c_s -> fullType inout;
- kini_s : initialiser inout * visitor_c_s -> initialiser inout;
kdecl_s : declaration inout * visitor_c_s -> declaration inout;
kdef_s : definition inout * visitor_c_s -> definition inout;
- ktoplevel_s : toplevel inout * visitor_c_s -> toplevel inout;
+ kini_s : initialiser inout * visitor_c_s -> initialiser inout;
+ kcppdirective_s : (cpp_directive inout * visitor_c_s) -> cpp_directive inout;
+ kdefineval_s : (define_val inout * visitor_c_s) -> define_val inout;
+ kstatementseq_s: (statement_sequencable inout * visitor_c_s) -> statement_sequencable inout;
+ kstatementseq_list_s:
+ (statement_sequencable list inout * visitor_c_s) -> statement_sequencable list inout;
knode_s :
Control_flow_c.node inout * visitor_c_s -> Control_flow_c.node inout;
- kdefineval_s : (define_val inout * visitor_c_s) -> define_val inout;
+ ktoplevel_s : toplevel inout * visitor_c_s -> toplevel inout;
kinfo_s : info inout * visitor_c_s -> info inout;
}
val vk_expr_s : visitor_c_s -> expression -> expression
val vk_argument_s : visitor_c_s -> argument -> argument
val vk_statement_s : visitor_c_s -> statement -> statement
+val vk_statement_sequencable_s : visitor_c_s -> statement_sequencable -> statement_sequencable
val vk_type_s : visitor_c_s -> fullType -> fullType
val vk_decl_s : visitor_c_s -> declaration -> declaration
val vk_ini_s : visitor_c_s -> initialiser -> initialiser
val vk_toplevel_s : visitor_c_s -> toplevel -> toplevel
val vk_info_s : visitor_c_s -> info -> info
val vk_node_s : visitor_c_s -> Control_flow_c.node -> Control_flow_c.node
+val vk_program_s : visitor_c_s -> program -> program
val vk_arguments_s :
visitor_c_s ->
(string Ast_c.wrap, il) Common.either list ->
(string Ast_c.wrap, il) Common.either list
-val vk_struct_fields_s : visitor_c_s ->
- field wrap list -> field wrap list
+val vk_struct_fields_s : visitor_c_s -> field list -> field list
val vk_cst_s : visitor_c_s -> ((constant, string) Common.either wrap) inout
--- /dev/null
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+*
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+*
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
+*
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+module Ast = Ast_cocci
+
+(* --------------------------------------------------------------------- *)
+(* Modified code *)
+
+type arity = OPT | UNIQUE | NONE
+
+type token_info =
+ { tline_start : int; tline_end : int;
+ left_offset : int; right_offset : int }
+let default_token_info =
+ { tline_start = -1; tline_end = -1; left_offset = -1; right_offset = -1 }
+
+(* MIXED is like CONTEXT, since sometimes MIXED things have to revert to
+CONTEXT - see insert_plus.ml *)
+type mcodekind =
+ MINUS of (Ast.anything list list * token_info) ref
+ | PLUS
+ | CONTEXT of (Ast.anything Ast.befaft * token_info * token_info) ref
+ | MIXED of (Ast.anything Ast.befaft * token_info * token_info) ref
+
+type info = { line_start : int; line_end : int;
+ logical_start : int; logical_end : int;
+ attachable_start : bool; attachable_end : bool;
+ mcode_start : mcodekind list; mcode_end : mcodekind list;
+ column : int; offset : int;
+ (* the following are only for + code *)
+ strings_before : string list; strings_after : string list }
+
+type 'a mcode = 'a * arity * info * mcodekind * meta_pos ref (* pos, - only *)
+(* int ref is an index *)
+and 'a wrap =
+ { node : 'a;
+ info : info;
+ index : int ref;
+ mcodekind : mcodekind ref;
+ exp_ty : Type_cocci.typeC option ref; (* only for expressions *)
+ bef_aft : dots_bef_aft; (* only for statements *)
+ true_if_arg : bool; (* true if "arg_exp", only for exprs *)
+ true_if_test : bool; (* true if "test position", only for exprs *)
+ true_if_test_exp : bool;(* true if "test_exp from iso", only for exprs *)
+ (*nonempty if this represents the use of an iso*)
+ iso_info : (string*anything) list }
+
+and dots_bef_aft =
+ NoDots | AddingBetweenDots of statement | DroppingBetweenDots of statement
+
+(* for iso metavariables, true if they can only match nonmodified terms with
+ all metavariables unitary
+ for SP metavariables, true if the metavariable is unitary (valid up to
+ isomorphism phase only)
+ In SP, the only options are impure and context
+*)
+and pure = Impure | Pure | Context | PureContext (* pure and only context *)
+
+(* --------------------------------------------------------------------- *)
+(* --------------------------------------------------------------------- *)
+(* Dots *)
+
+and 'a base_dots =
+ DOTS of 'a list
+ | CIRCLES of 'a list
+ | STARS of 'a list
+
+and 'a dots = 'a base_dots wrap
+
+(* --------------------------------------------------------------------- *)
+(* Identifier *)
+
+and base_ident =
+ Id of string mcode
+ | MetaId of Ast.meta_name mcode * ident list * pure
+ | MetaFunc of Ast.meta_name mcode * ident list * pure
+ | MetaLocalFunc of Ast.meta_name mcode * ident list * pure
+ | OptIdent of ident
+ | UniqueIdent of ident
+
+and ident = base_ident wrap
+
+(* --------------------------------------------------------------------- *)
+(* Expression *)
+
+and base_expression =
+ Ident of ident
+ | Constant of Ast.constant mcode
+ | FunCall of expression * string mcode (* ( *) *
+ expression dots * string mcode (* ) *)
+ | Assignment of expression * Ast.assignOp mcode * expression *
+ bool (* true if it can match an initialization *)
+ | CondExpr of expression * string mcode (* ? *) * expression option *
+ string mcode (* : *) * expression
+ | Postfix of expression * Ast.fixOp mcode
+ | Infix of expression * Ast.fixOp mcode
+ | Unary of expression * Ast.unaryOp mcode
+ | Binary of expression * Ast.binaryOp mcode * expression
+ | Nested of expression * Ast.binaryOp mcode * expression
+ | Paren of string mcode (* ( *) * expression *
+ string mcode (* ) *)
+ | ArrayAccess of expression * string mcode (* [ *) * expression *
+ string mcode (* ] *)
+ | RecordAccess of expression * string mcode (* . *) * ident
+ | RecordPtAccess of expression * string mcode (* -> *) * ident
+ | Cast of string mcode (* ( *) * typeC * string mcode (* ) *) *
+ expression
+ | SizeOfExpr of string mcode (* sizeof *) * expression
+ | SizeOfType of string mcode (* sizeof *) * string mcode (* ( *) *
+ typeC * string mcode (* ) *)
+ | TypeExp of typeC (* type name used as an expression, only in args *)
+ | MetaErr of Ast.meta_name mcode * expression list * pure
+ | MetaExpr of Ast.meta_name mcode * expression list *
+ Type_cocci.typeC list option * Ast.form * pure
+ | MetaExprList of Ast.meta_name mcode (* only in arg lists *) *
+ listlen * pure
+ | EComma of string mcode (* only in arg lists *)
+ | DisjExpr of string mcode * expression list *
+ string mcode list (* the |s *) * string mcode
+ | NestExpr of string mcode * expression dots * string mcode *
+ expression option * Ast.multi
+ | Edots of string mcode (* ... *) * expression option
+ | Ecircles of string mcode (* ooo *) * expression option
+ | Estars of string mcode (* *** *) * expression option
+ | OptExp of expression
+ | UniqueExp of expression
+
+and expression = base_expression wrap
+
+and listlen = Ast.meta_name mcode option
+
+(* --------------------------------------------------------------------- *)
+(* Types *)
+
+and base_typeC =
+ ConstVol of Ast.const_vol mcode * typeC
+ | BaseType of Ast.baseType mcode * Ast.sign mcode option
+ | ImplicitInt of Ast.sign mcode
+ | Pointer of typeC * string mcode (* * *)
+ | FunctionPointer of typeC *
+ string mcode(* ( *)*string mcode(* * *)*string mcode(* ) *)*
+ string mcode (* ( *)*parameter_list*string mcode(* ) *)
+ | FunctionType of typeC option *
+ string mcode (* ( *) * parameter_list *
+ string mcode (* ) *)
+ | Array of typeC * string mcode (* [ *) *
+ expression option * string mcode (* ] *)
+ | StructUnionName of Ast.structUnion mcode * ident option (* name *)
+ | StructUnionDef of typeC (* either StructUnionName or metavar *) *
+ string mcode (* { *) * declaration dots * string mcode (* } *)
+ | TypeName of string mcode
+ | MetaType of Ast.meta_name mcode * pure
+ | DisjType of string mcode * typeC list * (* only after iso *)
+ string mcode list (* the |s *) * string mcode
+ | OptType of typeC
+ | UniqueType of typeC
+
+and typeC = base_typeC wrap
+
+(* --------------------------------------------------------------------- *)
+(* Variable declaration *)
+(* Even if the Cocci program specifies a list of declarations, they are
+ split out into multiple declarations of a single variable each. *)
+
+and base_declaration =
+ Init of Ast.storage mcode option * typeC * ident * string mcode (*=*) *
+ initialiser * string mcode (*;*)
+ | UnInit of Ast.storage mcode option * typeC * ident * string mcode (* ; *)
+ | TyDecl of typeC * string mcode (* ; *)
+ | MacroDecl of ident (* name *) * string mcode (* ( *) *
+ expression dots * string mcode (* ) *) * string mcode (* ; *)
+ | Typedef of string mcode (* typedef *) * typeC * typeC * string mcode (*;*)
+ | DisjDecl of string mcode * declaration list *
+ string mcode list (* the |s *) * string mcode
+ (* Ddots is for a structure declaration *)
+ | Ddots of string mcode (* ... *) * declaration option (* whencode *)
+ | OptDecl of declaration
+ | UniqueDecl of declaration
+
+and declaration = base_declaration wrap
+
+(* --------------------------------------------------------------------- *)
+(* Initializers *)
+
+and base_initialiser =
+ InitExpr of expression
+ | InitList of string mcode (*{*) * initialiser_list * string mcode (*}*)
+ | InitGccDotName of
+ string mcode (*.*) * ident (* name *) * string mcode (*=*) *
+ initialiser (* gccext: *)
+ | InitGccName of ident (* name *) * string mcode (*:*) *
+ initialiser
+ | InitGccIndex of
+ string mcode (*[*) * expression * string mcode (*]*) *
+ string mcode (*=*) * initialiser
+ | InitGccRange of
+ string mcode (*[*) * expression * string mcode (*...*) *
+ expression * string mcode (*]*) * string mcode (*=*) * initialiser
+ | IComma of string mcode (* , *)
+ | Idots of string mcode (* ... *) * initialiser option (* whencode *)
+ | OptIni of initialiser
+ | UniqueIni of initialiser
+
+and initialiser = base_initialiser wrap
+
+and initialiser_list = initialiser dots
+
+(* --------------------------------------------------------------------- *)
+(* Parameter *)
+
+and base_parameterTypeDef =
+ VoidParam of typeC
+ | Param of typeC * ident option
+ | MetaParam of Ast.meta_name mcode * pure
+ | MetaParamList of Ast.meta_name mcode * listlen * pure
+ | PComma of string mcode
+ | Pdots of string mcode (* ... *)
+ | Pcircles of string mcode (* ooo *)
+ | OptParam of parameterTypeDef
+ | UniqueParam of parameterTypeDef
+
+and parameterTypeDef = base_parameterTypeDef wrap
+
+and parameter_list = parameterTypeDef dots
+
+(* --------------------------------------------------------------------- *)
+(* #define Parameters *)
+
+and base_define_param =
+ DParam of ident
+ | DPComma of string mcode
+ | DPdots of string mcode (* ... *)
+ | DPcircles of string mcode (* ooo *)
+ | OptDParam of define_param
+ | UniqueDParam of define_param
+
+and define_param = base_define_param wrap
+
+and base_define_parameters =
+ NoParams
+ | DParams of string mcode(*( *) * define_param dots * string mcode(* )*)
+
+and define_parameters = base_define_parameters wrap
+
+(* --------------------------------------------------------------------- *)
+(* Statement*)
+
+and base_statement =
+ Decl of (info * mcodekind) (* before the decl *) * declaration
+ | Seq of string mcode (* { *) * statement dots *
+ string mcode (* } *)
+ | ExprStatement of expression * string mcode (*;*)
+ | IfThen of string mcode (* if *) * string mcode (* ( *) *
+ expression * string mcode (* ) *) *
+ statement * (info * mcodekind) (* after info *)
+ | IfThenElse of string mcode (* if *) * string mcode (* ( *) *
+ expression * string mcode (* ) *) *
+ statement * string mcode (* else *) * statement *
+ (info * mcodekind)
+ | While of string mcode (* while *) * string mcode (* ( *) *
+ expression * string mcode (* ) *) *
+ statement * (info * mcodekind) (* after info *)
+ | Do of string mcode (* do *) * statement *
+ string mcode (* while *) * string mcode (* ( *) *
+ expression * string mcode (* ) *) *
+ string mcode (* ; *)
+ | For of string mcode (* for *) * string mcode (* ( *) *
+ expression option * string mcode (*;*) *
+ expression option * string mcode (*;*) *
+ expression option * string mcode (* ) *) * statement *
+ (info * mcodekind) (* after info *)
+ | Iterator of ident (* name *) * string mcode (* ( *) *
+ expression dots * string mcode (* ) *) *
+ statement * (info * mcodekind) (* after info *)
+ | Switch of string mcode (* switch *) * string mcode (* ( *) *
+ expression * string mcode (* ) *) * string mcode (* { *) *
+ case_line dots * string mcode (* } *)
+ | Break of string mcode (* break *) * string mcode (* ; *)
+ | Continue of string mcode (* continue *) * string mcode (* ; *)
+ | Label of ident * string mcode (* : *)
+ | Goto of string mcode (* goto *) * ident * string mcode (* ; *)
+ | Return of string mcode (* return *) * string mcode (* ; *)
+ | ReturnExpr of string mcode (* return *) * expression *
+ string mcode (* ; *)
+ | MetaStmt of Ast.meta_name mcode * pure
+ | MetaStmtList of Ast.meta_name mcode(*only in statement lists*) * pure
+ | Exp of expression (* only in dotted statement lists *)
+ | TopExp of expression (* for macros body *)
+ | Ty of typeC (* only at top level *)
+ | TopInit of initialiser (* only at top level *)
+ | Disj of string mcode * statement dots list *
+ string mcode list (* the |s *) * string mcode
+ | Nest of string mcode * statement dots * string mcode *
+ (statement dots,statement) whencode list * Ast.multi
+ | Dots of string mcode (* ... *) *
+ (statement dots,statement) whencode list
+ | Circles of string mcode (* ooo *) *
+ (statement dots,statement) whencode list
+ | Stars of string mcode (* *** *) *
+ (statement dots,statement) whencode list
+ | FunDecl of (info * mcodekind) (* before the function decl *) *
+ fninfo list * ident (* name *) *
+ string mcode (* ( *) * parameter_list * string mcode (* ) *) *
+ string mcode (* { *) * statement dots *
+ string mcode (* } *)
+ | Include of string mcode (* #include *) * Ast.inc_file mcode (* file *)
+ | Define of string mcode (* #define *) * ident (* name *) *
+ define_parameters (*params*) * statement dots
+ | OptStm of statement
+ | UniqueStm of statement
+
+and fninfo =
+ FStorage of Ast.storage mcode
+ | FType of typeC
+ | FInline of string mcode
+ | FAttr of string mcode
+
+and ('a,'b) whencode =
+ WhenNot of 'a
+ | WhenAlways of 'b
+ | WhenModifier of Ast.when_modifier
+ | WhenNotTrue of expression
+ | WhenNotFalse of expression
+
+and statement = base_statement wrap
+
+and base_case_line =
+ Default of string mcode (* default *) * string mcode (*:*) * statement dots
+ | Case of string mcode (* case *) * expression * string mcode (*:*) *
+ statement dots
+ | OptCase of case_line
+
+and case_line = base_case_line wrap
+
+(* --------------------------------------------------------------------- *)
+(* Positions *)
+
+and meta_pos =
+ MetaPos of Ast.meta_name mcode * Ast.meta_name list * Ast.meta_collect
+ | NoMetaPos
+
+(* --------------------------------------------------------------------- *)
+(* Top-level code *)
+
+and base_top_level =
+ DECL of statement
+ | CODE of statement dots
+ | FILEINFO of string mcode (* old file *) * string mcode (* new file *)
+ | ERRORWORDS of expression list
+ | OTHER of statement (* temporary, disappears after top_level.ml *)
+
+and top_level = base_top_level wrap
+and rule = top_level list
+
+and parsed_rule =
+ CocciRule of
+ (rule * Ast.metavar list *
+ (string list * string list * Ast.dependency * string * Ast.exists)) *
+ (rule * Ast.metavar list)
+ | ScriptRule of
+ string * Ast.dependency * (string * Ast.meta_name) list * string
+
+(* --------------------------------------------------------------------- *)
+
+and anything =
+ DotsExprTag of expression dots
+ | DotsInitTag of initialiser dots
+ | DotsParamTag of parameterTypeDef dots
+ | DotsStmtTag of statement dots
+ | DotsDeclTag of declaration dots
+ | DotsCaseTag of case_line dots
+ | IdentTag of ident
+ | ExprTag of expression
+ | ArgExprTag of expression (* for isos *)
+ | TestExprTag of expression (* for isos *)
+ | TypeCTag of typeC
+ | ParamTag of parameterTypeDef
+ | InitTag of initialiser
+ | DeclTag of declaration
+ | StmtTag of statement
+ | CaseLineTag of case_line
+ | TopTag of top_level
+ | IsoWhenTag of Ast.when_modifier
+ | IsoWhenTTag of expression
+ | IsoWhenFTag of expression
+ | MetaPosTag of meta_pos
+
+let dotsExpr x = DotsExprTag x
+let dotsParam x = DotsParamTag x
+let dotsInit x = DotsInitTag x
+let dotsStmt x = DotsStmtTag x
+let dotsDecl x = DotsDeclTag x
+let dotsCase x = DotsCaseTag x
+let ident x = IdentTag x
+let expr x = ExprTag x
+let typeC x = TypeCTag x
+let param x = ParamTag x
+let ini x = InitTag x
+let decl x = DeclTag x
+let stmt x = StmtTag x
+let case_line x = CaseLineTag x
+let top x = TopTag x
+
+(* --------------------------------------------------------------------- *)
+(* Avoid cluttering the parser. Calculated in compute_lines.ml. *)
+
+let default_info _ = (* why is this a function? *)
+ { line_start = -1; line_end = -1;
+ logical_start = -1; logical_end = -1;
+ attachable_start = true; attachable_end = true;
+ mcode_start = []; mcode_end = [];
+ column = -1; offset = -1; strings_before = []; strings_after = [] }
+
+let default_befaft _ =
+ MIXED(ref (Ast.NOTHING,default_token_info,default_token_info))
+let context_befaft _ =
+ CONTEXT(ref (Ast.NOTHING,default_token_info,default_token_info))
+
+let wrap x =
+ { node = x;
+ info = default_info();
+ index = ref (-1);
+ mcodekind = ref (default_befaft());
+ exp_ty = ref None;
+ bef_aft = NoDots;
+ true_if_arg = false;
+ true_if_test = false;
+ true_if_test_exp = false;
+ iso_info = [] }
+let context_wrap x =
+ { node = x;
+ info = default_info();
+ index = ref (-1);
+ mcodekind = ref (context_befaft());
+ exp_ty = ref None;
+ bef_aft = NoDots;
+ true_if_arg = false;
+ true_if_test = false;
+ true_if_test_exp = false;
+ iso_info = [] }
+let unwrap x = x.node
+let unwrap_mcode (x,_,_,_,_) = x
+let rewrap model x = { model with node = x }
+let rewrap_mcode (_,arity,info,mcodekind,pos) x = (x,arity,info,mcodekind,pos)
+let copywrap model x =
+ { model with node = x; index = ref !(model.index);
+ mcodekind = ref !(model.mcodekind); exp_ty = ref !(model.exp_ty)}
+let get_pos (_,_,_,_,x) = !x
+let get_pos_ref (_,_,_,_,x) = x
+let set_pos pos (m,arity,info,mcodekind,_) = (m,arity,info,mcodekind,ref pos)
+let get_info x = x.info
+let set_info x info = {x with info = info}
+let get_line x = x.info.line_start
+let get_line_end x = x.info.line_end
+let get_index x = !(x.index)
+let set_index x i = x.index := i
+let get_mcodekind x = !(x.mcodekind)
+let get_mcode_mcodekind (_,_,_,mcodekind,_) = mcodekind
+let get_mcodekind_ref x = x.mcodekind
+let set_mcodekind x mk = x.mcodekind := mk
+let set_type x t = x.exp_ty := t
+let get_type x = !(x.exp_ty)
+let get_dots_bef_aft x = x.bef_aft
+let set_dots_bef_aft x dots_bef_aft = {x with bef_aft = dots_bef_aft}
+let get_arg_exp x = x.true_if_arg
+let set_arg_exp x = {x with true_if_arg = true}
+let get_test_pos x = x.true_if_test
+let set_test_pos x = {x with true_if_test = true}
+let get_test_exp x = x.true_if_test_exp
+let set_test_exp x = {x with true_if_test_exp = true}
+let get_iso x = x.iso_info
+let set_iso x i = if !Flag.track_iso_usage then {x with iso_info = i} else x
+let set_mcode_data data (_,ar,info,mc,pos) = (data,ar,info,mc,pos)
+
+(* --------------------------------------------------------------------- *)
+
+(* unique indices, for mcode and tree nodes *)
+let index_counter = ref 0
+let fresh_index _ = let cur = !index_counter in index_counter := cur + 1; cur
+
+(* --------------------------------------------------------------------- *)
+
+let undots d =
+ match unwrap d with
+ | DOTS e -> e
+ | CIRCLES e -> e
+ | STARS e -> e
+
+(* --------------------------------------------------------------------- *)
+
+let rec ast0_type_to_type ty =
+ match unwrap ty with
+ ConstVol(cv,ty) -> Type_cocci.ConstVol(const_vol cv,ast0_type_to_type ty)
+ | BaseType(bty,None) ->
+ Type_cocci.BaseType(baseType bty,None)
+ | BaseType(bty,Some sgn) ->
+ Type_cocci.BaseType(baseType bty,Some (sign sgn))
+ | ImplicitInt(sgn) ->
+ let bty = Type_cocci.IntType in
+ Type_cocci.BaseType(bty,Some (sign sgn))
+ | Pointer(ty,_) -> Type_cocci.Pointer(ast0_type_to_type ty)
+ | FunctionPointer(ty,_,_,_,_,params,_) ->
+ Type_cocci.FunctionPointer(ast0_type_to_type ty)
+ | FunctionType _ -> failwith "not supported"
+ | Array(ety,_,_,_) -> Type_cocci.Array(ast0_type_to_type ety)
+ | StructUnionName(su,Some tag) ->
+ (match unwrap tag with
+ Id(tag) ->
+ Type_cocci.StructUnionName(structUnion su,false,unwrap_mcode tag)
+ | MetaId(tag,_,_) ->
+ (Printf.printf
+ "warning: struct/union with a metavariable name detected.\n";
+ Printf.printf
+ "For type checking assuming the name of the metavariable is the name of the type\n";
+ let (rule,tag) = unwrap_mcode tag in
+ Type_cocci.StructUnionName(structUnion su,true,rule^tag))
+ | _ -> failwith "unexpected struct/union type name")
+ | StructUnionName(su,None) -> failwith "nameless structure - what to do???"
+ | StructUnionDef(ty,_,_,_) -> ast0_type_to_type ty
+ | TypeName(name) -> Type_cocci.TypeName(unwrap_mcode name)
+ | MetaType(name,_) ->
+ Type_cocci.MetaType(unwrap_mcode name,Type_cocci.Unitary,false)
+ | DisjType(_,types,_,_) -> failwith "unexpected DisjType"
+ | OptType(ty) | UniqueType(ty) ->
+ ast0_type_to_type ty
+
+and baseType t =
+ match unwrap_mcode t with
+ Ast.VoidType -> Type_cocci.VoidType
+ | Ast.CharType -> Type_cocci.CharType
+ | Ast.ShortType -> Type_cocci.ShortType
+ | Ast.IntType -> Type_cocci.IntType
+ | Ast.DoubleType -> Type_cocci.DoubleType
+ | Ast.FloatType -> Type_cocci.FloatType
+ | Ast.LongType -> Type_cocci.LongType
+
+and structUnion t =
+ match unwrap_mcode t with
+ Ast.Struct -> Type_cocci.Struct
+ | Ast.Union -> Type_cocci.Union
+
+and sign t =
+ match unwrap_mcode t with
+ Ast.Signed -> Type_cocci.Signed
+ | Ast.Unsigned -> Type_cocci.Unsigned
+
+and const_vol t =
+ match unwrap_mcode t with
+ Ast.Const -> Type_cocci.Const
+ | Ast.Volatile -> Type_cocci.Volatile
+
+(* --------------------------------------------------------------------- *)
+(* this function is a rather minimal attempt. the problem is that information
+has been lost. but since it is only used for metavariable types in the isos,
+perhaps it doesn't matter *)
+let make_mcode x = (x,NONE,default_info(),context_befaft(),ref NoMetaPos)
+let make_mcode_info x info = (x,NONE,info,context_befaft(),ref NoMetaPos)
+
+exception TyConv
+
+let rec reverse_type ty =
+ match ty with
+ Type_cocci.ConstVol(cv,ty) ->
+ ConstVol(reverse_const_vol cv,wrap(reverse_type ty))
+ | Type_cocci.BaseType(bty,None) ->
+ BaseType(reverse_baseType bty,None)
+ | Type_cocci.BaseType(bty,Some sgn) ->
+ BaseType(reverse_baseType bty,Some (reverse_sign sgn))
+ | Type_cocci.Pointer(ty) ->
+ Pointer(wrap(reverse_type ty),make_mcode "*")
+ | Type_cocci.StructUnionName(su,mv,tag) ->
+ if mv
+ then
+ (* not right... *)
+ StructUnionName(reverse_structUnion su,
+ Some(wrap(MetaId(make_mcode ("",tag),[],Impure))))
+ else
+ StructUnionName(reverse_structUnion su,
+ Some (wrap(Id(make_mcode tag))))
+ | Type_cocci.TypeName(name) -> TypeName(make_mcode name)
+ | Type_cocci.MetaType(name,_,_) ->
+ MetaType(make_mcode name,Impure(*not really right*))
+ | _ -> raise TyConv
+
+and reverse_baseType t =
+ make_mcode
+ (match t with
+ Type_cocci.VoidType -> Ast.VoidType
+ | Type_cocci.CharType -> Ast.CharType
+ | Type_cocci.BoolType -> Ast.IntType
+ | Type_cocci.ShortType -> Ast.ShortType
+ | Type_cocci.IntType -> Ast.IntType
+ | Type_cocci.DoubleType -> Ast.DoubleType
+ | Type_cocci.FloatType -> Ast.FloatType
+ | Type_cocci.LongType -> Ast.LongType)
+
+and reverse_structUnion t =
+ make_mcode
+ (match t with
+ Type_cocci.Struct -> Ast.Struct
+ | Type_cocci.Union -> Ast.Union)
+
+and reverse_sign t =
+ make_mcode
+ (match t with
+ Type_cocci.Signed -> Ast.Signed
+ | Type_cocci.Unsigned -> Ast.Unsigned)
+
+and reverse_const_vol t =
+ make_mcode
+ (match t with
+ Type_cocci.Const -> Ast.Const
+ | Type_cocci.Volatile -> Ast.Volatile)
+
+(* --------------------------------------------------------------------- *)
+
+let lub_pure x y =
+ match (x,y) with
+ (Impure,_) | (_,Impure) -> Impure
+ | (Pure,Context) | (Context,Pure) -> Impure
+ | (Pure,_) | (_,Pure) -> Pure
+ | (_,Context) | (Context,_) -> Context
+ | _ -> PureContext
+
+(* --------------------------------------------------------------------- *)
+
+let rule_name = ref "" (* for the convenience of the parser *)
--- /dev/null
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+*
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+*
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
+*
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+(* Detects subtrees that are all minus/plus and nodes that are "binding
+context nodes". The latter is a node whose structure and immediate tokens
+are the same in the minus and plus trees, and such that for every child,
+the set of context nodes in the child subtree is the same in the minus and
+plus subtrees. *)
+
+module Ast = Ast_cocci
+module Ast0 = Ast0_cocci
+module V0 = Visitor_ast0
+module U = Unparse_ast0
+
+(* --------------------------------------------------------------------- *)
+(* Generic access to code *)
+
+let set_mcodekind x mcodekind =
+ match x with
+ Ast0.DotsExprTag(d) -> Ast0.set_mcodekind d mcodekind
+ | Ast0.DotsInitTag(d) -> Ast0.set_mcodekind d mcodekind
+ | Ast0.DotsParamTag(d) -> Ast0.set_mcodekind d mcodekind
+ | Ast0.DotsStmtTag(d) -> Ast0.set_mcodekind d mcodekind
+ | Ast0.DotsDeclTag(d) -> Ast0.set_mcodekind d mcodekind
+ | Ast0.DotsCaseTag(d) -> Ast0.set_mcodekind d mcodekind
+ | Ast0.IdentTag(d) -> Ast0.set_mcodekind d mcodekind
+ | Ast0.ExprTag(d) -> Ast0.set_mcodekind d mcodekind
+ | Ast0.ArgExprTag(d) | Ast0.TestExprTag(d) ->
+ failwith "not possible - iso only"
+ | Ast0.TypeCTag(d) -> Ast0.set_mcodekind d mcodekind
+ | Ast0.ParamTag(d) -> Ast0.set_mcodekind d mcodekind
+ | Ast0.DeclTag(d) -> Ast0.set_mcodekind d mcodekind
+ | Ast0.InitTag(d) -> Ast0.set_mcodekind d mcodekind
+ | Ast0.StmtTag(d) -> Ast0.set_mcodekind d mcodekind
+ | Ast0.CaseLineTag(d) -> Ast0.set_mcodekind d mcodekind
+ | Ast0.TopTag(d) -> Ast0.set_mcodekind d mcodekind
+ | Ast0.IsoWhenTag(_) -> failwith "only within iso phase"
+ | Ast0.IsoWhenTTag(_) -> failwith "only within iso phase"
+ | Ast0.IsoWhenFTag(_) -> failwith "only within iso phase"
+ | Ast0.MetaPosTag(p) -> failwith "metapostag only within iso phase"
+
+let set_index x index =
+ match x with
+ Ast0.DotsExprTag(d) -> Ast0.set_index d index
+ | Ast0.DotsInitTag(d) -> Ast0.set_index d index
+ | Ast0.DotsParamTag(d) -> Ast0.set_index d index
+ | Ast0.DotsStmtTag(d) -> Ast0.set_index d index
+ | Ast0.DotsDeclTag(d) -> Ast0.set_index d index
+ | Ast0.DotsCaseTag(d) -> Ast0.set_index d index
+ | Ast0.IdentTag(d) -> Ast0.set_index d index
+ | Ast0.ExprTag(d) -> Ast0.set_index d index
+ | Ast0.ArgExprTag(d) | Ast0.TestExprTag(d) ->
+ failwith "not possible - iso only"
+ | Ast0.TypeCTag(d) -> Ast0.set_index d index
+ | Ast0.ParamTag(d) -> Ast0.set_index d index
+ | Ast0.InitTag(d) -> Ast0.set_index d index
+ | Ast0.DeclTag(d) -> Ast0.set_index d index
+ | Ast0.StmtTag(d) -> Ast0.set_index d index
+ | Ast0.CaseLineTag(d) -> Ast0.set_index d index
+ | Ast0.TopTag(d) -> Ast0.set_index d index
+ | Ast0.IsoWhenTag(_) -> failwith "only within iso phase"
+ | Ast0.IsoWhenTTag(_) -> failwith "only within iso phase"
+ | Ast0.IsoWhenFTag(_) -> failwith "only within iso phase"
+ | Ast0.MetaPosTag(p) -> failwith "metapostag only within iso phase"
+
+let get_index = function
+ Ast0.DotsExprTag(d) -> Index.expression_dots d
+ | Ast0.DotsInitTag(d) -> Index.initialiser_dots d
+ | Ast0.DotsParamTag(d) -> Index.parameter_dots d
+ | Ast0.DotsStmtTag(d) -> Index.statement_dots d
+ | Ast0.DotsDeclTag(d) -> Index.declaration_dots d
+ | Ast0.DotsCaseTag(d) -> Index.case_line_dots d
+ | Ast0.IdentTag(d) -> Index.ident d
+ | Ast0.ExprTag(d) -> Index.expression d
+ | Ast0.ArgExprTag(d) | Ast0.TestExprTag(d) ->
+ failwith "not possible - iso only"
+ | Ast0.TypeCTag(d) -> Index.typeC d
+ | Ast0.ParamTag(d) -> Index.parameterTypeDef d
+ | Ast0.InitTag(d) -> Index.initialiser d
+ | Ast0.DeclTag(d) -> Index.declaration d
+ | Ast0.StmtTag(d) -> Index.statement d
+ | Ast0.CaseLineTag(d) -> Index.case_line d
+ | Ast0.TopTag(d) -> Index.top_level d
+ | Ast0.IsoWhenTag(_) -> failwith "only within iso phase"
+ | Ast0.IsoWhenTTag(_) -> failwith "only within iso phase"
+ | Ast0.IsoWhenFTag(_) -> failwith "only within iso phase"
+ | Ast0.MetaPosTag(p) -> failwith "metapostag only within iso phase"
+
+(* --------------------------------------------------------------------- *)
+(* Collect the line numbers of the plus code. This is used for disjunctions.
+It is not completely clear why this is necessary, but it seems like an easy
+fix for whatever is the problem that is discussed in disj_cases *)
+
+let plus_lines = ref ([] : int list)
+
+let insert n =
+ let rec loop = function
+ [] -> [n]
+ | x::xs ->
+ match compare n x with
+ 1 -> x::(loop xs)
+ | 0 -> x::xs
+ | -1 -> n::x::xs
+ | _ -> failwith "not possible" in
+ plus_lines := loop !plus_lines
+
+let find n min max =
+ let rec loop = function
+ [] -> (min,max)
+ | [x] -> if n < x then (min,x) else (x,max)
+ | x1::x2::rest ->
+ if n < x1
+ then (min,x1)
+ else if n > x1 && n < x2 then (x1,x2) else loop (x2::rest) in
+ loop !plus_lines
+
+let collect_plus_lines top =
+ plus_lines := [];
+ let bind x y = () in
+ let option_default = () in
+ let donothing r k e = k e in
+ let mcode (_,_,info,mcodekind,_) =
+ match mcodekind with
+ Ast0.PLUS -> insert info.Ast0.line_start
+ | _ -> () in
+ let fn =
+ V0.combiner bind option_default
+ mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+ mcode
+ donothing donothing donothing donothing donothing donothing
+ donothing donothing donothing donothing donothing donothing donothing
+ donothing donothing in
+ fn.V0.combiner_top_level top
+
+(* --------------------------------------------------------------------- *)
+
+type kind = Neutral | AllMarked | NotAllMarked (* marked means + or - *)
+
+(* --------------------------------------------------------------------- *)
+(* The first part analyzes each of the minus tree and the plus tree
+separately *)
+
+(* ints are unique token indices (offset field) *)
+type node =
+ Token (* tokens *) of kind * int (* unique index *) * Ast0.mcodekind *
+ int list (* context tokens *)
+ | Recursor (* children *) of kind *
+ int list (* indices of all tokens at the level below *) *
+ Ast0.mcodekind list (* tokens at the level below *) *
+ int list
+ | Bind (* neighbors *) of kind *
+ int list (* indices of all tokens at current level *) *
+ Ast0.mcodekind list (* tokens at current level *) *
+ int list (* indices of all tokens at the level below *) *
+ Ast0.mcodekind list (* tokens at the level below *)
+ * int list list
+
+let kind2c = function
+ Neutral -> "neutral"
+ | AllMarked -> "allmarked"
+ | NotAllMarked -> "notallmarked"
+
+let node2c = function
+ Token(k,_,_,_) -> Printf.sprintf "token %s\n" (kind2c k)
+ | Recursor(k,_,_,_) -> Printf.sprintf "recursor %s\n" (kind2c k)
+ | Bind(k,_,_,_,_,_) -> Printf.sprintf "bind %s\n" (kind2c k)
+
+(* goal: detect negative in both tokens and recursors, or context only in
+tokens *)
+let bind c1 c2 =
+ let lub = function
+ (k1,k2) when k1 = k2 -> k1
+ | (Neutral,AllMarked) -> AllMarked
+ | (AllMarked,Neutral) -> AllMarked
+ | _ -> NotAllMarked in
+ match (c1,c2) with
+ (* token/token *)
+ (* there are tokens at this level, so ignore the level below *)
+ (Token(k1,i1,t1,l1),Token(k2,i2,t2,l2)) ->
+ Bind(lub(k1,k2),[i1;i2],[t1;t2],[],[],[l1;l2])
+
+ (* token/recursor *)
+ (* there are tokens at this level, so ignore the level below *)
+ | (Token(k1,i1,t1,l1),Recursor(k2,_,_,l2)) ->
+ Bind(lub(k1,k2),[i1],[t1],[],[],[l1;l2])
+ | (Recursor(k1,_,_,l1),Token(k2,i2,t2,l2)) ->
+ Bind(lub(k1,k2),[i2],[t2],[],[],[l1;l2])
+
+ (* token/bind *)
+ (* there are tokens at this level, so ignore the level below *)
+ | (Token(k1,i1,t1,l1),Bind(k2,i2,t2,_,_,l2)) ->
+ Bind(lub(k1,k2),i1::i2,t1::t2,[],[],l1::l2)
+ | (Bind(k1,i1,t1,_,_,l1),Token(k2,i2,t2,l2)) ->
+ Bind(lub(k1,k2),i1@[i2],t1@[t2],[],[],l1@[l2])
+
+ (* recursor/bind *)
+ | (Recursor(k1,bi1,bt1,l1),Bind(k2,i2,t2,bi2,bt2,l2)) ->
+ Bind(lub(k1,k2),i2,t2,bi1@bi2,bt1@bt2,l1::l2)
+ | (Bind(k1,i1,t1,bi1,bt1,l1),Recursor(k2,bi2,bt2,l2)) ->
+ Bind(lub(k1,k2),i1,t1,bi1@bi2,bt1@bt2,l1@[l2])
+
+ (* recursor/recursor and bind/bind - not likely to ever occur *)
+ | (Recursor(k1,bi1,bt1,l1),Recursor(k2,bi2,bt2,l2)) ->
+ Bind(lub(k1,k2),[],[],bi1@bi2,bt1@bt2,[l1;l2])
+ | (Bind(k1,i1,t1,bi1,bt1,l1),Bind(k2,i2,t2,bi2,bt2,l2)) ->
+ Bind(lub(k1,k2),i1@i2,t1@t2,bi1@bi2,bt1@bt2,l1@l2)
+
+
+let option_default = (*Bind(Neutral,[],[],[],[],[])*)
+ Recursor(Neutral,[],[],[])
+
+let mcode (_,_,info,mcodekind,pos) =
+ let offset = info.Ast0.offset in
+ match mcodekind with
+ Ast0.MINUS(_) -> Token(AllMarked,offset,mcodekind,[])
+ | Ast0.PLUS -> Token(AllMarked,offset,mcodekind,[])
+ | Ast0.CONTEXT(_) -> Token(NotAllMarked,offset,mcodekind,[offset])
+ | _ -> failwith "not possible"
+
+let neutral_mcode (_,_,info,mcodekind,pos) =
+ let offset = info.Ast0.offset in
+ match mcodekind with
+ Ast0.MINUS(_) -> Token(Neutral,offset,mcodekind,[])
+ | Ast0.PLUS -> Token(Neutral,offset,mcodekind,[])
+ | Ast0.CONTEXT(_) -> Token(Neutral,offset,mcodekind,[offset])
+ | _ -> failwith "not possible"
+
+let is_context = function Ast0.CONTEXT(_) -> true | _ -> false
+
+let union_all l = List.fold_left Common.union_set [] l
+
+(* is minus is true when we are processing minus code that might be
+intermingled with plus code. it is used in disj_cases *)
+let classify is_minus all_marked table code =
+ let mkres builder k il tl bil btl l e =
+ (if k = AllMarked
+ then Ast0.set_mcodekind e (all_marked()) (* definitive *)
+ else
+ let check_index il tl =
+ if List.for_all is_context tl
+ then
+ (let e1 = builder e in
+ let index = (get_index e1)@il in
+ try
+ let _ = Hashtbl.find table index in
+ failwith
+ (Printf.sprintf "%d: index %s already used\n"
+ (Ast0.get_info e).Ast0.line_start
+ (String.concat " " (List.map string_of_int index)))
+ with Not_found -> Hashtbl.add table index (e1,l)) in
+ if il = [] then check_index bil btl else check_index il tl);
+ if il = []
+ then Recursor(k, bil, btl, union_all l)
+ else Recursor(k, il, tl, union_all l) in
+
+ let compute_result builder e = function
+ Bind(k,il,tl,bil,btl,l) -> mkres builder k il tl bil btl l e
+ | Token(k,il,tl,l) -> mkres builder k [il] [tl] [] [] [l] e
+ | Recursor(k,bil,btl,l) -> mkres builder k [] [] bil btl [l] e in
+
+ let make_not_marked = function
+ Bind(k,il,tl,bil,btl,l) -> Bind(NotAllMarked,il,tl,bil,btl,l)
+ | Token(k,il,tl,l) -> Token(NotAllMarked,il,tl,l)
+ | Recursor(k,bil,btl,l) -> Recursor(NotAllMarked,bil,btl,l) in
+
+ let do_nothing builder r k e = compute_result builder e (k e) in
+
+ let disj_cases disj starter code fn ender =
+ (* neutral_mcode used so starter and ender don't have an affect on
+ whether the code is considered all plus/minus, but so that they are
+ consider in the index list, which is needed to make a disj with
+ something in one branch and nothing in the other different from code
+ that just has the something (starter/ender enough, mids not needed
+ for this). Cannot agglomerate + code over | boundaries, because two -
+ cases might have different + code, and don't want to put the + code
+ together into one unit. *)
+ let make_not_marked =
+ if is_minus
+ then
+ (let min = Ast0.get_line disj in
+ let max = Ast0.get_line_end disj in
+ let (plus_min,plus_max) = find min (min-1) (max+1) in
+ if max > plus_max then make_not_marked else (function x -> x))
+ else make_not_marked in
+ bind (neutral_mcode starter)
+ (bind (List.fold_right bind
+ (List.map make_not_marked (List.map fn code))
+ option_default)
+ (neutral_mcode ender)) in
+
+ (* no whencode in plus tree so have to drop it *)
+ (* need special cases for dots, nests, and disjs *)
+ let expression r k e =
+ compute_result Ast0.expr e
+ (match Ast0.unwrap e with
+ Ast0.NestExpr(starter,exp,ender,whencode,multi) ->
+ k (Ast0.rewrap e (Ast0.NestExpr(starter,exp,ender,None,multi)))
+ | Ast0.Edots(dots,whencode) ->
+ k (Ast0.rewrap e (Ast0.Edots(dots,None)))
+ | Ast0.Ecircles(dots,whencode) ->
+ k (Ast0.rewrap e (Ast0.Ecircles(dots,None)))
+ | Ast0.Estars(dots,whencode) ->
+ k (Ast0.rewrap e (Ast0.Estars(dots,None)))
+ | Ast0.DisjExpr(starter,expr_list,_,ender) ->
+ disj_cases e starter expr_list r.V0.combiner_expression ender
+ | _ -> k e) in
+
+ (* not clear why we have the next two cases, since DisjDecl and
+ DisjType shouldn't have been constructed yet, as they only come from isos *)
+ let declaration r k e =
+ compute_result Ast0.decl e
+ (match Ast0.unwrap e with
+ Ast0.DisjDecl(starter,decls,_,ender) ->
+ disj_cases e starter decls r.V0.combiner_declaration ender
+ | Ast0.Ddots(dots,whencode) ->
+ k (Ast0.rewrap e (Ast0.Ddots(dots,None)))
+ (* Need special cases for the following so that the type will be
+ considered as a unit, rather than distributed around the
+ declared variable. This needs to be done because of the call to
+ compute_result, ie the processing of each term should make a
+ side-effect on the complete term structure as well as collecting
+ some information about it. So we have to visit each complete
+ term structure. In (all?) other such cases, we visit the terms
+ using rebuilder, which just visits the subterms, rather than
+ reordering their components. *)
+ | Ast0.Init(stg,ty,id,eq,ini,sem) ->
+ bind (match stg with Some stg -> mcode stg | _ -> option_default)
+ (bind (r.V0.combiner_typeC ty)
+ (bind (r.V0.combiner_ident id)
+ (bind (mcode eq)
+ (bind (r.V0.combiner_initialiser ini) (mcode sem)))))
+ | Ast0.UnInit(stg,ty,id,sem) ->
+ bind (match stg with Some stg -> mcode stg | _ -> option_default)
+ (bind (r.V0.combiner_typeC ty)
+ (bind (r.V0.combiner_ident id) (mcode sem)))
+ | _ -> k e) in
+
+ let param r k e =
+ compute_result Ast0.param e
+ (match Ast0.unwrap e with
+ Ast0.Param(ty,Some id) ->
+ (* needed for the same reason as in the Init and UnInit cases *)
+ bind (r.V0.combiner_typeC ty) (r.V0.combiner_ident id)
+ | _ -> k e) in
+
+ let typeC r k e =
+ compute_result Ast0.typeC e
+ (match Ast0.unwrap e with
+ Ast0.DisjType(starter,types,_,ender) ->
+ disj_cases e starter types r.V0.combiner_typeC ender
+ | _ -> k e) in
+
+ let initialiser r k i =
+ compute_result Ast0.ini i
+ (match Ast0.unwrap i with
+ Ast0.Idots(dots,whencode) ->
+ k (Ast0.rewrap i (Ast0.Idots(dots,None)))
+ | _ -> k i) in
+
+ let statement r k s =
+ compute_result Ast0.stmt s
+ (match Ast0.unwrap s with
+ Ast0.Nest(started,stm_dots,ender,whencode,multi) ->
+ k (Ast0.rewrap s (Ast0.Nest(started,stm_dots,ender,[],multi)))
+ | Ast0.Dots(dots,whencode) ->
+ k (Ast0.rewrap s (Ast0.Dots(dots,[])))
+ | Ast0.Circles(dots,whencode) ->
+ k (Ast0.rewrap s (Ast0.Circles(dots,[])))
+ | Ast0.Stars(dots,whencode) ->
+ k (Ast0.rewrap s (Ast0.Stars(dots,[])))
+ | Ast0.Disj(starter,statement_dots_list,_,ender) ->
+ disj_cases s starter statement_dots_list r.V0.combiner_statement_dots
+ ender
+(* Why? There is nothing there
+ (* cases for everything with extra mcode *)
+ | Ast0.FunDecl((info,bef),_,_,_,_,_,_,_,_)
+ | Ast0.Decl((info,bef),_) ->
+ bind (mcode ((),(),info,bef)) (k s)
+ | Ast0.IfThen(_,_,_,_,_,(info,aft))
+ | Ast0.IfThenElse(_,_,_,_,_,_,_,(info,aft))
+ | Ast0.While(_,_,_,_,_,(info,aft)) ->
+ | Ast0.For(_,_,_,_,_,_,_,_,_,(info,aft)) ->
+ bind (k s) (mcode ((),(),info,aft))
+ | Ast0.Iterator(_,_,_,_,_,(info,aft))
+*)
+ | _ -> k s
+
+) in
+
+ let do_top builder r k e = compute_result builder e (k e) in
+
+ let combiner =
+ V0.combiner bind option_default
+ mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+ mcode
+ (do_nothing Ast0.dotsExpr) (do_nothing Ast0.dotsInit)
+ (do_nothing Ast0.dotsParam) (do_nothing Ast0.dotsStmt)
+ (do_nothing Ast0.dotsDecl) (do_nothing Ast0.dotsCase)
+ (do_nothing Ast0.ident) expression typeC initialiser param declaration
+ statement (do_nothing Ast0.case_line) (do_top Ast0.top) in
+ combiner.V0.combiner_top_level code
+
+(* --------------------------------------------------------------------- *)
+(* Traverse the hash tables and find corresponding context nodes that have
+the same context children *)
+
+(* this is just a sanity check - really only need to look at the top-level
+ structure *)
+let equal_mcode (_,_,info1,_,_) (_,_,info2,_,_) =
+ info1.Ast0.offset = info2.Ast0.offset
+
+let equal_option e1 e2 =
+ match (e1,e2) with
+ (Some x, Some y) -> equal_mcode x y
+ | (None, None) -> true
+ | _ -> false
+
+let dots fn d1 d2 =
+ match (Ast0.unwrap d1,Ast0.unwrap d2) with
+ (Ast0.DOTS(l1),Ast0.DOTS(l2)) -> List.length l1 = List.length l2
+ | (Ast0.CIRCLES(l1),Ast0.CIRCLES(l2)) -> List.length l1 = List.length l2
+ | (Ast0.STARS(l1),Ast0.STARS(l2)) -> List.length l1 = List.length l2
+ | _ -> false
+
+let rec equal_ident i1 i2 =
+ match (Ast0.unwrap i1,Ast0.unwrap i2) with
+ (Ast0.Id(name1),Ast0.Id(name2)) -> equal_mcode name1 name2
+ | (Ast0.MetaId(name1,_,_),Ast0.MetaId(name2,_,_)) ->
+ equal_mcode name1 name2
+ | (Ast0.MetaFunc(name1,_,_),Ast0.MetaFunc(name2,_,_)) ->
+ equal_mcode name1 name2
+ | (Ast0.MetaLocalFunc(name1,_,_),Ast0.MetaLocalFunc(name2,_,_)) ->
+ equal_mcode name1 name2
+ | (Ast0.OptIdent(_),Ast0.OptIdent(_)) -> true
+ | (Ast0.UniqueIdent(_),Ast0.UniqueIdent(_)) -> true
+ | _ -> false
+
+let rec equal_expression e1 e2 =
+ match (Ast0.unwrap e1,Ast0.unwrap e2) with
+ (Ast0.Ident(_),Ast0.Ident(_)) -> true
+ | (Ast0.Constant(const1),Ast0.Constant(const2)) -> equal_mcode const1 const2
+ | (Ast0.FunCall(_,lp1,_,rp1),Ast0.FunCall(_,lp2,_,rp2)) ->
+ equal_mcode lp1 lp2 && equal_mcode rp1 rp2
+ | (Ast0.Assignment(_,op1,_,_),Ast0.Assignment(_,op2,_,_)) ->
+ equal_mcode op1 op2
+ | (Ast0.CondExpr(_,why1,_,colon1,_),Ast0.CondExpr(_,why2,_,colon2,_)) ->
+ equal_mcode why1 why2 && equal_mcode colon1 colon2
+ | (Ast0.Postfix(_,op1),Ast0.Postfix(_,op2)) -> equal_mcode op1 op2
+ | (Ast0.Infix(_,op1),Ast0.Infix(_,op2)) -> equal_mcode op1 op2
+ | (Ast0.Unary(_,op1),Ast0.Unary(_,op2)) -> equal_mcode op1 op2
+ | (Ast0.Binary(_,op1,_),Ast0.Binary(_,op2,_)) -> equal_mcode op1 op2
+ | (Ast0.Paren(lp1,_,rp1),Ast0.Paren(lp2,_,rp2)) ->
+ equal_mcode lp1 lp2 && equal_mcode rp1 rp2
+ | (Ast0.ArrayAccess(_,lb1,_,rb1),Ast0.ArrayAccess(_,lb2,_,rb2)) ->
+ equal_mcode lb1 lb2 && equal_mcode rb1 rb2
+ | (Ast0.RecordAccess(_,pt1,_),Ast0.RecordAccess(_,pt2,_)) ->
+ equal_mcode pt1 pt2
+ | (Ast0.RecordPtAccess(_,ar1,_),Ast0.RecordPtAccess(_,ar2,_)) ->
+ equal_mcode ar1 ar2
+ | (Ast0.Cast(lp1,_,rp1,_),Ast0.Cast(lp2,_,rp2,_)) ->
+ equal_mcode lp1 lp2 && equal_mcode rp1 rp2
+ | (Ast0.SizeOfExpr(szf1,_),Ast0.SizeOfExpr(szf2,_)) ->
+ equal_mcode szf1 szf2
+ | (Ast0.SizeOfType(szf1,lp1,_,rp1),Ast0.SizeOfType(szf2,lp2,_,rp2)) ->
+ equal_mcode szf1 szf2 && equal_mcode lp1 lp2 && equal_mcode rp1 rp2
+ | (Ast0.TypeExp(_),Ast0.TypeExp(_)) -> true
+ | (Ast0.MetaErr(name1,_,_),Ast0.MetaErr(name2,_,_))
+ | (Ast0.MetaExpr(name1,_,_,_,_),Ast0.MetaExpr(name2,_,_,_,_))
+ | (Ast0.MetaExprList(name1,_,_),Ast0.MetaExprList(name2,_,_)) ->
+ equal_mcode name1 name2
+ | (Ast0.EComma(cm1),Ast0.EComma(cm2)) -> equal_mcode cm1 cm2
+ | (Ast0.DisjExpr(starter1,_,mids1,ender1),
+ Ast0.DisjExpr(starter2,_,mids2,ender2)) ->
+ equal_mcode starter1 starter2 &&
+ List.for_all2 equal_mcode mids1 mids2 &&
+ equal_mcode ender1 ender2
+ | (Ast0.NestExpr(starter1,_,ender1,_,m1),
+ Ast0.NestExpr(starter2,_,ender2,_,m2)) ->
+ equal_mcode starter1 starter2 && equal_mcode ender1 ender2 && m1 = m2
+ | (Ast0.Edots(dots1,_),Ast0.Edots(dots2,_))
+ | (Ast0.Ecircles(dots1,_),Ast0.Ecircles(dots2,_))
+ | (Ast0.Estars(dots1,_),Ast0.Estars(dots2,_)) -> equal_mcode dots1 dots2
+ | (Ast0.OptExp(_),Ast0.OptExp(_)) -> true
+ | (Ast0.UniqueExp(_),Ast0.UniqueExp(_)) -> true
+ | _ -> false
+
+let rec equal_typeC t1 t2 =
+ match (Ast0.unwrap t1,Ast0.unwrap t2) with
+ (Ast0.ConstVol(cv1,_),Ast0.ConstVol(cv2,_)) -> equal_mcode cv1 cv2
+ | (Ast0.BaseType(ty1,sign1),Ast0.BaseType(ty2,sign2)) ->
+ equal_mcode ty1 ty2 && equal_option sign1 sign2
+ | (Ast0.ImplicitInt(sign1),Ast0.ImplicitInt(sign2)) ->
+ equal_mcode sign1 sign2
+ | (Ast0.Pointer(_,star1),Ast0.Pointer(_,star2)) ->
+ equal_mcode star1 star2
+ | (Ast0.Array(_,lb1,_,rb1),Ast0.Array(_,lb2,_,rb2)) ->
+ equal_mcode lb1 lb2 && equal_mcode rb1 rb2
+ | (Ast0.StructUnionName(kind1,_),Ast0.StructUnionName(kind2,_)) ->
+ equal_mcode kind1 kind2
+ | (Ast0.FunctionType(ty1,lp1,p1,rp1),Ast0.FunctionType(ty2,lp2,p2,rp2)) ->
+ equal_mcode lp1 lp2 && equal_mcode rp1 rp2
+ | (Ast0.StructUnionDef(_,lb1,_,rb1),
+ Ast0.StructUnionDef(_,lb2,_,rb2)) ->
+ equal_mcode lb1 lb2 && equal_mcode rb1 rb2
+ | (Ast0.TypeName(name1),Ast0.TypeName(name2)) -> equal_mcode name1 name2
+ | (Ast0.MetaType(name1,_),Ast0.MetaType(name2,_)) ->
+ equal_mcode name1 name2
+ | (Ast0.DisjType(starter1,_,mids1,ender1),
+ Ast0.DisjType(starter2,_,mids2,ender2)) ->
+ equal_mcode starter1 starter2 &&
+ List.for_all2 equal_mcode mids1 mids2 &&
+ equal_mcode ender1 ender2
+ | (Ast0.OptType(_),Ast0.OptType(_)) -> true
+ | (Ast0.UniqueType(_),Ast0.UniqueType(_)) -> true
+ | _ -> false
+
+let equal_declaration d1 d2 =
+ match (Ast0.unwrap d1,Ast0.unwrap d2) with
+ (Ast0.Init(stg1,_,_,eq1,_,sem1),Ast0.Init(stg2,_,_,eq2,_,sem2)) ->
+ equal_option stg1 stg2 && equal_mcode eq1 eq2 && equal_mcode sem1 sem2
+ | (Ast0.UnInit(stg1,_,_,sem1),Ast0.UnInit(stg2,_,_,sem2)) ->
+ equal_option stg1 stg2 && equal_mcode sem1 sem2
+ | (Ast0.MacroDecl(nm1,lp1,_,rp1,sem1),Ast0.MacroDecl(nm2,lp2,_,rp2,sem2)) ->
+ equal_mcode lp1 lp2 && equal_mcode rp1 rp2 && equal_mcode sem1 sem2
+ | (Ast0.TyDecl(_,sem1),Ast0.TyDecl(_,sem2)) -> equal_mcode sem1 sem2
+ | (Ast0.Ddots(dots1,_),Ast0.Ddots(dots2,_)) -> equal_mcode dots1 dots2
+ | (Ast0.OptDecl(_),Ast0.OptDecl(_)) -> true
+ | (Ast0.UniqueDecl(_),Ast0.UniqueDecl(_)) -> true
+ | (Ast0.DisjDecl _,_) | (_,Ast0.DisjDecl _) ->
+ failwith "DisjDecl not expected here"
+ | _ -> false
+
+let equal_initialiser i1 i2 =
+ match (Ast0.unwrap i1,Ast0.unwrap i2) with
+ (Ast0.InitExpr(_),Ast0.InitExpr(_)) -> true
+ | (Ast0.InitList(lb1,_,rb1),Ast0.InitList(lb2,_,rb2)) ->
+ (equal_mcode lb1 lb2) && (equal_mcode rb1 rb2)
+ | (Ast0.InitGccDotName(dot1,_,eq1,_),Ast0.InitGccDotName(dot2,_,eq2,_)) ->
+ (equal_mcode dot1 dot2) && (equal_mcode eq1 eq2)
+ | (Ast0.InitGccName(_,eq1,_),Ast0.InitGccName(_,eq2,_)) ->
+ equal_mcode eq1 eq2
+ | (Ast0.InitGccIndex(lb1,_,rb1,eq1,_),Ast0.InitGccIndex(lb2,_,rb2,eq2,_)) ->
+ (equal_mcode lb1 lb2) && (equal_mcode rb1 rb2) && (equal_mcode eq1 eq2)
+ | (Ast0.InitGccRange(lb1,_,dots1,_,rb1,eq1,_),
+ Ast0.InitGccRange(lb2,_,dots2,_,rb2,eq2,_)) ->
+ (equal_mcode lb1 lb2) && (equal_mcode dots1 dots2) &&
+ (equal_mcode rb1 rb2) && (equal_mcode eq1 eq2)
+ | (Ast0.IComma(cm1),Ast0.IComma(cm2)) -> equal_mcode cm1 cm2
+ | (Ast0.Idots(d1,_),Ast0.Idots(d2,_)) -> equal_mcode d1 d2
+ | (Ast0.OptIni(_),Ast0.OptIni(_)) -> true
+ | (Ast0.UniqueIni(_),Ast0.UniqueIni(_)) -> true
+ | _ -> false
+
+let equal_parameterTypeDef p1 p2 =
+ match (Ast0.unwrap p1,Ast0.unwrap p2) with
+ (Ast0.VoidParam(_),Ast0.VoidParam(_)) -> true
+ | (Ast0.Param(_,_),Ast0.Param(_,_)) -> true
+ | (Ast0.MetaParam(name1,_),Ast0.MetaParam(name2,_))
+ | (Ast0.MetaParamList(name1,_,_),Ast0.MetaParamList(name2,_,_)) ->
+ equal_mcode name1 name2
+ | (Ast0.PComma(cm1),Ast0.PComma(cm2)) -> equal_mcode cm1 cm2
+ | (Ast0.Pdots(dots1),Ast0.Pdots(dots2))
+ | (Ast0.Pcircles(dots1),Ast0.Pcircles(dots2)) -> equal_mcode dots1 dots2
+ | (Ast0.OptParam(_),Ast0.OptParam(_)) -> true
+ | (Ast0.UniqueParam(_),Ast0.UniqueParam(_)) -> true
+ | _ -> false
+
+let rec equal_statement s1 s2 =
+ match (Ast0.unwrap s1,Ast0.unwrap s2) with
+ (Ast0.FunDecl(_,fninfo1,_,lp1,_,rp1,lbrace1,_,rbrace1),
+ Ast0.FunDecl(_,fninfo2,_,lp2,_,rp2,lbrace2,_,rbrace2)) ->
+ (List.length fninfo1) = (List.length fninfo2) &&
+ List.for_all2 equal_fninfo fninfo1 fninfo2 &&
+ equal_mcode lp1 lp2 && equal_mcode rp1 rp2 &&
+ equal_mcode lbrace1 lbrace2 && equal_mcode rbrace1 rbrace2
+ | (Ast0.Decl(_,_),Ast0.Decl(_,_)) -> true
+ | (Ast0.Seq(lbrace1,_,rbrace1),Ast0.Seq(lbrace2,_,rbrace2)) ->
+ equal_mcode lbrace1 lbrace2 && equal_mcode rbrace1 rbrace2
+ | (Ast0.ExprStatement(_,sem1),Ast0.ExprStatement(_,sem2)) ->
+ equal_mcode sem1 sem2
+ | (Ast0.IfThen(iff1,lp1,_,rp1,_,_),Ast0.IfThen(iff2,lp2,_,rp2,_,_)) ->
+ equal_mcode iff1 iff2 && equal_mcode lp1 lp2 && equal_mcode rp1 rp2
+ | (Ast0.IfThenElse(iff1,lp1,_,rp1,_,els1,_,_),
+ Ast0.IfThenElse(iff2,lp2,_,rp2,_,els2,_,_)) ->
+ equal_mcode iff1 iff2 &&
+ equal_mcode lp1 lp2 && equal_mcode rp1 rp2 && equal_mcode els1 els2
+ | (Ast0.While(whl1,lp1,_,rp1,_,_),Ast0.While(whl2,lp2,_,rp2,_,_)) ->
+ equal_mcode whl1 whl2 && equal_mcode lp1 lp2 && equal_mcode rp1 rp2
+ | (Ast0.Do(d1,_,whl1,lp1,_,rp1,sem1),Ast0.Do(d2,_,whl2,lp2,_,rp2,sem2)) ->
+ equal_mcode whl1 whl2 && equal_mcode d1 d2 &&
+ equal_mcode lp1 lp2 && equal_mcode rp1 rp2 && equal_mcode sem1 sem2
+ | (Ast0.For(fr1,lp1,_,sem11,_,sem21,_,rp1,_,_),
+ Ast0.For(fr2,lp2,_,sem12,_,sem22,_,rp2,_,_)) ->
+ equal_mcode fr1 fr2 && equal_mcode lp1 lp2 &&
+ equal_mcode sem11 sem12 && equal_mcode sem21 sem22 &&
+ equal_mcode rp1 rp2
+ | (Ast0.Iterator(nm1,lp1,_,rp1,_,_),Ast0.Iterator(nm2,lp2,_,rp2,_,_)) ->
+ equal_mcode lp1 lp2 && equal_mcode rp1 rp2
+ | (Ast0.Switch(switch1,lp1,_,rp1,lb1,case1,rb1),
+ Ast0.Switch(switch2,lp2,_,rp2,lb2,case2,rb2)) ->
+ equal_mcode switch1 switch2 && equal_mcode lp1 lp2 &&
+ equal_mcode rp1 rp2 && equal_mcode lb1 lb2 &&
+ equal_mcode rb1 rb2
+ | (Ast0.Break(br1,sem1),Ast0.Break(br2,sem2)) ->
+ equal_mcode br1 br2 && equal_mcode sem1 sem2
+ | (Ast0.Continue(cont1,sem1),Ast0.Continue(cont2,sem2)) ->
+ equal_mcode cont1 cont2 && equal_mcode sem1 sem2
+ | (Ast0.Label(_,dd1),Ast0.Label(_,dd2)) ->
+ equal_mcode dd1 dd2
+ | (Ast0.Goto(g1,_,sem1),Ast0.Goto(g2,_,sem2)) ->
+ equal_mcode g1 g2 && equal_mcode sem1 sem2
+ | (Ast0.Return(ret1,sem1),Ast0.Return(ret2,sem2)) ->
+ equal_mcode ret1 ret2 && equal_mcode sem1 sem2
+ | (Ast0.ReturnExpr(ret1,_,sem1),Ast0.ReturnExpr(ret2,_,sem2)) ->
+ equal_mcode ret1 ret2 && equal_mcode sem1 sem2
+ | (Ast0.MetaStmt(name1,_),Ast0.MetaStmt(name2,_))
+ | (Ast0.MetaStmtList(name1,_),Ast0.MetaStmtList(name2,_)) ->
+ equal_mcode name1 name2
+ | (Ast0.Disj(starter1,_,mids1,ender1),Ast0.Disj(starter2,_,mids2,ender2)) ->
+ equal_mcode starter1 starter2 &&
+ List.for_all2 equal_mcode mids1 mids2 &&
+ equal_mcode ender1 ender2
+ | (Ast0.Nest(starter1,_,ender1,_,m1),Ast0.Nest(starter2,_,ender2,_,m2)) ->
+ equal_mcode starter1 starter2 && equal_mcode ender1 ender2 && m1 = m2
+ | (Ast0.Exp(_),Ast0.Exp(_)) -> true
+ | (Ast0.TopExp(_),Ast0.TopExp(_)) -> true
+ | (Ast0.Ty(_),Ast0.Ty(_)) -> true
+ | (Ast0.TopInit(_),Ast0.TopInit(_)) -> true
+ | (Ast0.Dots(d1,_),Ast0.Dots(d2,_))
+ | (Ast0.Circles(d1,_),Ast0.Circles(d2,_))
+ | (Ast0.Stars(d1,_),Ast0.Stars(d2,_)) -> equal_mcode d1 d2
+ | (Ast0.Include(inc1,name1),Ast0.Include(inc2,name2)) ->
+ equal_mcode inc1 inc2 && equal_mcode name1 name2
+ | (Ast0.Define(def1,_,_,_),Ast0.Define(def2,_,_,_)) ->
+ equal_mcode def1 def2
+ | (Ast0.OptStm(_),Ast0.OptStm(_)) -> true
+ | (Ast0.UniqueStm(_),Ast0.UniqueStm(_)) -> true
+ | _ -> false
+
+and equal_fninfo x y =
+ match (x,y) with
+ (Ast0.FStorage(s1),Ast0.FStorage(s2)) -> equal_mcode s1 s2
+ | (Ast0.FType(_),Ast0.FType(_)) -> true
+ | (Ast0.FInline(i1),Ast0.FInline(i2)) -> equal_mcode i1 i2
+ | (Ast0.FAttr(i1),Ast0.FAttr(i2)) -> equal_mcode i1 i2
+ | _ -> false
+
+let equal_case_line c1 c2 =
+ match (Ast0.unwrap c1,Ast0.unwrap c2) with
+ (Ast0.Default(def1,colon1,_),Ast0.Default(def2,colon2,_)) ->
+ equal_mcode def1 def2 && equal_mcode colon1 colon2
+ | (Ast0.Case(case1,_,colon1,_),Ast0.Case(case2,_,colon2,_)) ->
+ equal_mcode case1 case2 && equal_mcode colon1 colon2
+ | (Ast0.OptCase(_),Ast0.OptCase(_)) -> true
+ | _ -> false
+
+let rec equal_top_level t1 t2 =
+ match (Ast0.unwrap t1,Ast0.unwrap t2) with
+ (Ast0.DECL(_),Ast0.DECL(_)) -> true
+ | (Ast0.FILEINFO(old_file1,new_file1),Ast0.FILEINFO(old_file2,new_file2)) ->
+ equal_mcode old_file1 old_file2 && equal_mcode new_file1 new_file2
+ | (Ast0.CODE(_),Ast0.CODE(_)) -> true
+ | (Ast0.ERRORWORDS(_),Ast0.ERRORWORDS(_)) -> true
+ | _ -> false
+
+let root_equal e1 e2 =
+ match (e1,e2) with
+ (Ast0.DotsExprTag(d1),Ast0.DotsExprTag(d2)) -> dots equal_expression d1 d2
+ | (Ast0.DotsParamTag(d1),Ast0.DotsParamTag(d2)) ->
+ dots equal_parameterTypeDef d1 d2
+ | (Ast0.DotsStmtTag(d1),Ast0.DotsStmtTag(d2)) -> dots equal_statement d1 d2
+ | (Ast0.DotsDeclTag(d1),Ast0.DotsDeclTag(d2)) -> dots equal_declaration d1 d2
+ | (Ast0.DotsCaseTag(d1),Ast0.DotsCaseTag(d2)) -> dots equal_case_line d1 d2
+ | (Ast0.IdentTag(i1),Ast0.IdentTag(i2)) -> equal_ident i1 i2
+ | (Ast0.ExprTag(e1),Ast0.ExprTag(e2)) -> equal_expression e1 e2
+ | (Ast0.ArgExprTag(d),_) -> failwith "not possible - iso only"
+ | (Ast0.TypeCTag(t1),Ast0.TypeCTag(t2)) -> equal_typeC t1 t2
+ | (Ast0.ParamTag(p1),Ast0.ParamTag(p2)) -> equal_parameterTypeDef p1 p2
+ | (Ast0.InitTag(d1),Ast0.InitTag(d2)) -> equal_initialiser d1 d2
+ | (Ast0.DeclTag(d1),Ast0.DeclTag(d2)) -> equal_declaration d1 d2
+ | (Ast0.StmtTag(s1),Ast0.StmtTag(s2)) -> equal_statement s1 s2
+ | (Ast0.TopTag(t1),Ast0.TopTag(t2)) -> equal_top_level t1 t2
+ | (Ast0.IsoWhenTag(_),_) | (_,Ast0.IsoWhenTag(_))
+ | (Ast0.IsoWhenTTag(_),_) | (_,Ast0.IsoWhenTTag(_))
+ | (Ast0.IsoWhenFTag(_),_) | (_,Ast0.IsoWhenFTag(_)) ->
+ failwith "only within iso phase"
+ | _ -> false
+
+let default_context _ =
+ Ast0.CONTEXT(ref(Ast.NOTHING,
+ Ast0.default_token_info,Ast0.default_token_info))
+
+let traverse minus_table plus_table =
+ Hashtbl.iter
+ (function key ->
+ function (e,l) ->
+ try
+ let (plus_e,plus_l) = Hashtbl.find plus_table key in
+ if root_equal e plus_e &&
+ List.for_all (function x -> x)
+ (List.map2 Common.equal_set l plus_l)
+ then
+ let i = Ast0.fresh_index() in
+ (set_index e i; set_index plus_e i;
+ set_mcodekind e (default_context());
+ set_mcodekind plus_e (default_context()))
+ with Not_found -> ())
+ minus_table
+
+(* --------------------------------------------------------------------- *)
+(* contextify the whencode *)
+
+let contextify_all =
+ let bind x y = () in
+ let option_default = () in
+ let mcode x = () in
+ let do_nothing r k e = Ast0.set_mcodekind e (default_context()); k e in
+
+ V0.combiner bind option_default
+ mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+ mcode
+ do_nothing do_nothing do_nothing do_nothing do_nothing do_nothing
+ do_nothing do_nothing do_nothing do_nothing do_nothing do_nothing
+ do_nothing do_nothing do_nothing
+
+let contextify_whencode =
+ let bind x y = () in
+ let option_default = () in
+ let mcode x = () in
+ let do_nothing r k e = k e in
+
+ let expression r k e =
+ k e;
+ match Ast0.unwrap e with
+ Ast0.NestExpr(_,_,_,Some whencode,_)
+ | Ast0.Edots(_,Some whencode)
+ | Ast0.Ecircles(_,Some whencode)
+ | Ast0.Estars(_,Some whencode) ->
+ contextify_all.V0.combiner_expression whencode
+ | _ -> () in
+
+ let initialiser r k i =
+ match Ast0.unwrap i with
+ Ast0.Idots(dots,Some whencode) ->
+ contextify_all.V0.combiner_initialiser whencode
+ | _ -> k i in
+
+ let whencode = function
+ Ast0.WhenNot sd -> contextify_all.V0.combiner_statement_dots sd
+ | Ast0.WhenAlways s -> contextify_all.V0.combiner_statement s
+ | Ast0.WhenModifier(_) -> ()
+ | Ast0.WhenNotTrue(e) -> contextify_all.V0.combiner_expression e
+ | Ast0.WhenNotFalse(e) -> contextify_all.V0.combiner_expression e in
+
+ let statement r k (s : Ast0.statement) =
+ k s;
+ match Ast0.unwrap s with
+ Ast0.Nest(_,_,_,whn,_)
+ | Ast0.Dots(_,whn) | Ast0.Circles(_,whn) | Ast0.Stars(_,whn) ->
+ List.iter whencode whn
+ | _ -> () in
+
+ let combiner =
+ V0.combiner bind option_default
+ mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+ mcode
+ do_nothing do_nothing do_nothing do_nothing do_nothing do_nothing
+ do_nothing
+ expression
+ do_nothing initialiser do_nothing do_nothing statement do_nothing
+ do_nothing in
+ combiner.V0.combiner_top_level
+
+(* --------------------------------------------------------------------- *)
+
+(* the first int list is the tokens in the node, the second is the tokens
+in the descendents *)
+let minus_table =
+ (Hashtbl.create(50) : (int list, Ast0.anything * int list list) Hashtbl.t)
+let plus_table =
+ (Hashtbl.create(50) : (int list, Ast0.anything * int list list) Hashtbl.t)
+
+let iscode t =
+ match Ast0.unwrap t with
+ Ast0.DECL(_) -> true
+ | Ast0.FILEINFO(_) -> true
+ | Ast0.ERRORWORDS(_) -> false
+ | Ast0.CODE(_) -> true
+ | Ast0.OTHER(_) -> failwith "unexpected top level code"
+
+(* ------------------------------------------------------------------- *)
+(* alignment of minus and plus *)
+
+let concat = function
+ [] -> []
+ | [s] -> [s]
+ | l ->
+ let rec loop = function
+ [] -> []
+ | x::rest ->
+ (match Ast0.unwrap x with
+ Ast0.DECL(s) -> let stms = loop rest in s::stms
+ | Ast0.CODE(ss) ->
+ let stms = loop rest in
+ (match Ast0.unwrap ss with
+ Ast0.DOTS(d) -> d@stms
+ | _ -> failwith "no dots allowed in pure plus code")
+ | _ -> failwith "plus code is being discarded") in
+ let res =
+ Compute_lines.statement_dots
+ (Ast0.rewrap (List.hd l) (Ast0.DOTS (loop l))) in
+ [Ast0.rewrap res (Ast0.CODE res)]
+
+let collect_up_to m plus =
+ let minfo = Ast0.get_info m in
+ let mend = minfo.Ast0.logical_end in
+ let rec loop = function
+ [] -> ([],[])
+ | p::plus ->
+ let pinfo = Ast0.get_info p in
+ let pstart = pinfo.Ast0.logical_start in
+ if pstart > mend
+ then ([],p::plus)
+ else let (plus,rest) = loop plus in (p::plus,rest) in
+ let (plus,rest) = loop plus in
+ (concat plus,rest)
+
+let realign minus plus =
+ let rec loop = function
+ ([],_) -> failwith "not possible, some context required"
+ | ([m],p) -> ([m],concat p)
+ | (m::minus,plus) ->
+ let (p,plus) = collect_up_to m plus in
+ let (minus,plus) = loop (minus,plus) in
+ (m::minus,p@plus) in
+ loop (minus,plus)
+
+(* ------------------------------------------------------------------- *)
+(* check compatible: check that at the top level the minus and plus code is
+of the same kind. Could go further and make the correspondence between the
+code between ...s. *)
+
+let isonly f l = match Ast0.undots l with [s] -> f s | _ -> false
+
+let isall f l = List.for_all (isonly f) l
+
+let rec is_exp s =
+ match Ast0.unwrap s with
+ Ast0.Exp(e) -> true
+ | Ast0.Disj(_,stmts,_,_) -> isall is_exp stmts
+ | _ -> false
+
+let rec is_ty s =
+ match Ast0.unwrap s with
+ Ast0.Ty(e) -> true
+ | Ast0.Disj(_,stmts,_,_) -> isall is_ty stmts
+ | _ -> false
+
+let rec is_decl s =
+ match Ast0.unwrap s with
+ Ast0.Decl(_,e) -> true
+ | Ast0.FunDecl(_,_,_,_,_,_,_,_,_) -> true
+ | Ast0.Disj(_,stmts,_,_) -> isall is_decl stmts
+ | _ -> false
+
+let rec is_fndecl s =
+ match Ast0.unwrap s with
+ Ast0.FunDecl(_,_,_,_,_,_,_,_,_) -> true
+ | Ast0.Disj(_,stmts,_,_) -> isall is_fndecl stmts
+ | _ -> false
+
+let rec is_toplevel s =
+ match Ast0.unwrap s with
+ Ast0.Decl(_,e) -> true
+ | Ast0.FunDecl(_,_,_,_,_,_,_,_,_) -> true
+ | Ast0.Disj(_,stmts,_,_) -> isall is_toplevel stmts
+ | Ast0.ExprStatement(fc,_) ->
+ (match Ast0.unwrap fc with
+ Ast0.FunCall(_,_,_,_) -> true
+ | _ -> false)
+ | Ast0.Include(_,_) -> true
+ | Ast0.Define(_,_,_,_) -> true
+ | _ -> false
+
+let check_compatible m p =
+ let fail _ =
+ failwith
+ (Printf.sprintf
+ "incompatible minus and plus code starting on lines %d and %d"
+ (Ast0.get_line m) (Ast0.get_line p)) in
+ match (Ast0.unwrap m, Ast0.unwrap p) with
+ (Ast0.DECL(decl1),Ast0.DECL(decl2)) ->
+ if not (is_decl decl1 && is_decl decl2)
+ then fail()
+ | (Ast0.DECL(decl1),Ast0.CODE(code2)) ->
+ let v1 = is_decl decl1 in
+ let v2 = List.for_all is_toplevel (Ast0.undots code2) in
+ if !Flag.make_hrule = None && v1 && not v2 then fail()
+ | (Ast0.CODE(code1),Ast0.DECL(decl2)) ->
+ let v1 = List.for_all is_toplevel (Ast0.undots code1) in
+ let v2 = is_decl decl2 in
+ if v1 && not v2 then fail()
+ | (Ast0.CODE(code1),Ast0.CODE(code2)) ->
+ let testers = [is_exp;is_ty] in
+ List.iter
+ (function tester ->
+ let v1 = isonly tester code1 in
+ let v2 = isonly tester code2 in
+ if (v1 && not v2) or (!Flag.make_hrule = None && v2 && not v1)
+ then fail())
+ testers;
+ let v1 = isonly is_fndecl code1 in
+ let v2 = List.for_all is_toplevel (Ast0.undots code2) in
+ if !Flag.make_hrule = None && v1 && not v2 then fail()
+ | (Ast0.FILEINFO(_,_),Ast0.FILEINFO(_,_)) -> ()
+ | (Ast0.OTHER(_),Ast0.OTHER(_)) -> ()
+ | _ -> fail()
+
+(* ------------------------------------------------------------------- *)
+
+(* returns a list of corresponding minus and plus trees *)
+let context_neg minus plus =
+ Hashtbl.clear minus_table;
+ Hashtbl.clear plus_table;
+ List.iter contextify_whencode minus;
+ let (minus,plus) = realign minus plus in
+ let rec loop = function
+ ([],[]) -> []
+ | ([],l) ->
+ failwith (Printf.sprintf "%d plus things remaining" (List.length l))
+ | (minus,[]) ->
+ plus_lines := [];
+ let _ =
+ List.map
+ (function m ->
+ classify true
+ (function _ -> Ast0.MINUS(ref([],Ast0.default_token_info)))
+ minus_table m)
+ minus in
+ []
+ | (((m::minus) as mall),((p::plus) as pall)) ->
+ let minfo = Ast0.get_info m in
+ let pinfo = Ast0.get_info p in
+ let mstart = minfo.Ast0.logical_start in
+ let mend = minfo.Ast0.logical_end in
+ let pstart = pinfo.Ast0.logical_start in
+ let pend = pinfo.Ast0.logical_end in
+ if (iscode m or iscode p) &&
+ (mend + 1 = pstart or pend + 1 = mstart or (* adjacent *)
+ (mstart <= pstart && mend >= pstart) or
+ (pstart <= mstart && pend >= mstart)) (* overlapping or nested *)
+ then
+ begin
+ (* ensure that the root of each tree has a unique index,
+ although it might get overwritten if the node is a context
+ node *)
+ let i = Ast0.fresh_index() in
+ Ast0.set_index m i; Ast0.set_index p i;
+ check_compatible m p;
+ collect_plus_lines p;
+ let _ =
+ classify true
+ (function _ -> Ast0.MINUS(ref([],Ast0.default_token_info)))
+ minus_table m in
+ let _ = classify false (function _ -> Ast0.PLUS) plus_table p in
+ traverse minus_table plus_table;
+ (m,p)::loop(minus,plus)
+ end
+ else
+ if not(iscode m or iscode p)
+ then loop(minus,plus)
+ else
+ if mstart < pstart
+ then
+ begin
+ plus_lines := [];
+ let _ =
+ classify true
+ (function _ -> Ast0.MINUS(ref([],Ast0.default_token_info)))
+ minus_table m in
+ loop(minus,pall)
+ end
+ else loop(mall,plus) in
+ loop(minus,plus)
--- /dev/null
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+*
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+*
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
+*
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+(* Potential problem: offset of mcode is not updated when an iso is
+instantiated, implying that a term may end up with many mcodes with the
+same offset. On the other hand, at the moment offset only seems to be used
+before this phase. Furthermore add_dot_binding relies on the offset to
+remain the same between matching an iso and instantiating it with bindings. *)
+
+(* --------------------------------------------------------------------- *)
+(* match a SmPL expression against a SmPL abstract syntax tree,
+either - or + *)
+
+module Ast = Ast_cocci
+module Ast0 = Ast0_cocci
+module V0 = Visitor_ast0
+
+let current_rule = ref ""
+
+(* --------------------------------------------------------------------- *)
+
+type isomorphism =
+ Ast_cocci.metavar list * Ast0_cocci.anything list list * string (* name *)
+
+let strip_info =
+ let mcode (term,_,_,_,_) =
+ (term,Ast0.NONE,Ast0.default_info(),Ast0.PLUS,ref Ast0.NoMetaPos) in
+ let donothing r k e =
+ let x = k e in
+ {(Ast0.wrap (Ast0.unwrap x)) with
+ Ast0.mcodekind = ref Ast0.PLUS;
+ Ast0.true_if_test = x.Ast0.true_if_test} in
+ V0.rebuilder
+ mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+ mcode
+ donothing donothing donothing donothing donothing donothing
+ donothing donothing donothing donothing donothing donothing donothing
+ donothing donothing
+
+let anything_equal = function
+ (Ast0.DotsExprTag(d1),Ast0.DotsExprTag(d2)) ->
+ failwith "not a possible variable binding" (*not sure why these are pbs*)
+ | (Ast0.DotsInitTag(d1),Ast0.DotsInitTag(d2)) ->
+ failwith "not a possible variable binding"
+ | (Ast0.DotsParamTag(d1),Ast0.DotsParamTag(d2)) ->
+ failwith "not a possible variable binding"
+ | (Ast0.DotsStmtTag(d1),Ast0.DotsStmtTag(d2)) ->
+ (strip_info.V0.rebuilder_statement_dots d1) =
+ (strip_info.V0.rebuilder_statement_dots d2)
+ | (Ast0.DotsDeclTag(d1),Ast0.DotsDeclTag(d2)) ->
+ failwith "not a possible variable binding"
+ | (Ast0.DotsCaseTag(d1),Ast0.DotsCaseTag(d2)) ->
+ failwith "not a possible variable binding"
+ | (Ast0.IdentTag(d1),Ast0.IdentTag(d2)) ->
+ (strip_info.V0.rebuilder_ident d1) = (strip_info.V0.rebuilder_ident d2)
+ | (Ast0.ExprTag(d1),Ast0.ExprTag(d2)) ->
+ (strip_info.V0.rebuilder_expression d1) =
+ (strip_info.V0.rebuilder_expression d2)
+ | (Ast0.ArgExprTag(_),_) | (_,Ast0.ArgExprTag(_)) ->
+ failwith "not possible - only in isos1"
+ | (Ast0.TestExprTag(_),_) | (_,Ast0.TestExprTag(_)) ->
+ failwith "not possible - only in isos1"
+ | (Ast0.TypeCTag(d1),Ast0.TypeCTag(d2)) ->
+ (strip_info.V0.rebuilder_typeC d1) =
+ (strip_info.V0.rebuilder_typeC d2)
+ | (Ast0.InitTag(d1),Ast0.InitTag(d2)) ->
+ (strip_info.V0.rebuilder_initialiser d1) =
+ (strip_info.V0.rebuilder_initialiser d2)
+ | (Ast0.ParamTag(d1),Ast0.ParamTag(d2)) ->
+ (strip_info.V0.rebuilder_parameter d1) =
+ (strip_info.V0.rebuilder_parameter d2)
+ | (Ast0.DeclTag(d1),Ast0.DeclTag(d2)) ->
+ (strip_info.V0.rebuilder_declaration d1) =
+ (strip_info.V0.rebuilder_declaration d2)
+ | (Ast0.StmtTag(d1),Ast0.StmtTag(d2)) ->
+ (strip_info.V0.rebuilder_statement d1) =
+ (strip_info.V0.rebuilder_statement d2)
+ | (Ast0.CaseLineTag(d1),Ast0.CaseLineTag(d2)) ->
+ (strip_info.V0.rebuilder_case_line d1) =
+ (strip_info.V0.rebuilder_case_line d2)
+ | (Ast0.TopTag(d1),Ast0.TopTag(d2)) ->
+ (strip_info.V0.rebuilder_top_level d1) =
+ (strip_info.V0.rebuilder_top_level d2)
+ | (Ast0.IsoWhenTTag(_),_) | (_,Ast0.IsoWhenTTag(_)) ->
+ failwith "only for isos within iso phase"
+ | (Ast0.IsoWhenFTag(_),_) | (_,Ast0.IsoWhenFTag(_)) ->
+ failwith "only for isos within iso phase"
+ | (Ast0.IsoWhenTag(_),_) | (_,Ast0.IsoWhenTag(_)) ->
+ failwith "only for isos within iso phase"
+ | _ -> false
+
+let term (var1,_,_,_,_) = var1
+let dot_term (var1,_,info,_,_) = ("", var1 ^ (string_of_int info.Ast0.offset))
+
+
+type reason =
+ NotPure of Ast0.pure * (string * string) * Ast0.anything
+ | NotPureLength of (string * string)
+ | ContextRequired of Ast0.anything
+ | NonMatch
+ | Braces of Ast0.statement
+ | Position of string * string
+
+let interpret_reason name line reason printer =
+ Printf.printf
+ "warning: iso %s does not match the code below on line %d\n" name line;
+ printer(); Format.print_newline();
+ match reason with
+ NotPure(Ast0.Pure,(_,var),nonpure) ->
+ Printf.printf
+ "pure metavariable %s is matched against the following nonpure code:\n"
+ var;
+ Unparse_ast0.unparse_anything nonpure
+ | NotPure(Ast0.Context,(_,var),nonpure) ->
+ Printf.printf
+ "context metavariable %s is matched against the following\nnoncontext code:\n"
+ var;
+ Unparse_ast0.unparse_anything nonpure
+ | NotPure(Ast0.PureContext,(_,var),nonpure) ->
+ Printf.printf
+ "pure context metavariable %s is matched against the following\nnonpure or noncontext code:\n"
+ var;
+ Unparse_ast0.unparse_anything nonpure
+ | NotPureLength((_,var)) ->
+ Printf.printf
+ "pure metavariable %s is matched against too much or too little code\n"
+ var;
+ | ContextRequired(term) ->
+ Printf.printf
+ "the following code matched is not uniformly minus or context,\nor contains a disjunction:\n";
+ Unparse_ast0.unparse_anything term
+ | Braces(s) ->
+ Printf.printf "braces must be all minus (plus code allowed) or all\ncontext (plus code not allowed in the body) to match:\n";
+ Unparse_ast0.statement "" s;
+ Format.print_newline()
+ | Position(rule,name) ->
+ Printf.printf "position variable %s.%s conflicts with an isomorphism\n"
+ rule name;
+ | _ -> failwith "not possible"
+
+type 'a either = OK of 'a | Fail of reason
+
+let add_binding var exp bindings =
+ let var = term var in
+ let attempt bindings =
+ try
+ let cur = List.assoc var bindings in
+ if anything_equal(exp,cur) then [bindings] else []
+ with Not_found -> [((var,exp)::bindings)] in
+ match List.concat(List.map attempt bindings) with
+ [] -> Fail NonMatch
+ | x -> OK x
+
+let add_dot_binding var exp bindings =
+ let var = dot_term var in
+ let attempt bindings =
+ try
+ let cur = List.assoc var bindings in
+ if anything_equal(exp,cur) then [bindings] else []
+ with Not_found -> [((var,exp)::bindings)] in
+ match List.concat(List.map attempt bindings) with
+ [] -> Fail NonMatch
+ | x -> OK x
+
+(* multi-valued *)
+let add_multi_dot_binding var exp bindings =
+ let var = dot_term var in
+ let attempt bindings = [((var,exp)::bindings)] in
+ match List.concat(List.map attempt bindings) with
+ [] -> Fail NonMatch
+ | x -> OK x
+
+let rec nub ls =
+ match ls with
+ [] -> []
+ | (x::xs) when (List.mem x xs) -> nub xs
+ | (x::xs) -> x::(nub xs)
+
+(* --------------------------------------------------------------------- *)
+
+let init_env = [[]]
+
+let debug str m binding =
+ let res = m binding in
+ (match res with
+ None -> Printf.printf "%s: failed\n" str
+ | Some binding ->
+ List.iter
+ (function binding ->
+ Printf.printf "%s: %s\n" str
+ (String.concat " " (List.map (function (x,_) -> x) binding)))
+ binding);
+ res
+
+let conjunct_bindings
+ (m1 : 'binding -> 'binding either)
+ (m2 : 'binding -> 'binding either)
+ (binding : 'binding) : 'binding either =
+ match m1 binding with Fail(reason) -> Fail(reason) | OK binding -> m2 binding
+
+let rec conjunct_many_bindings = function
+ [] -> failwith "not possible"
+ | [x] -> x
+ | x::xs -> conjunct_bindings x (conjunct_many_bindings xs)
+
+let mcode_equal (x,_,_,_,_) (y,_,_,_,_) = x = y
+
+let return b binding = if b then OK binding else Fail NonMatch
+let return_false reason binding = Fail reason
+
+let match_option f t1 t2 =
+ match (t1,t2) with
+ (Some t1, Some t2) -> f t1 t2
+ | (None, None) -> return true
+ | _ -> return false
+
+let bool_match_option f t1 t2 =
+ match (t1,t2) with
+ (Some t1, Some t2) -> f t1 t2
+ | (None, None) -> true
+ | _ -> false
+
+(* context_required is for the example
+ if (
++ (int * )
+ x == NULL)
+ where we can't change x == NULL to eg NULL == x. So there can either be
+ nothing attached to the root or the term has to be all removed.
+ if would be nice if we knew more about the relationship between the - and +
+ code, because in the case where the + code is a separate statement in a
+ sequence, this is not a problem. Perhaps something could be done in
+ insert_plus
+
+ The example seems strange. Why isn't the cast attached to x?
+ *)
+let is_context e =
+ !Flag.sgrep_mode2 or (* everything is context for sgrep *)
+ (match Ast0.get_mcodekind e with
+ Ast0.CONTEXT(cell) -> true
+ | _ -> false)
+
+(* needs a special case when there is a Disj or an empty DOTS
+ the following stops at the statement level, and gives true if one
+ statement is replaced by another *)
+let rec is_pure_context s =
+ !Flag.sgrep_mode2 or (* everything is context for sgrep *)
+ (match Ast0.unwrap s with
+ Ast0.Disj(starter,statement_dots_list,mids,ender) ->
+ List.for_all
+ (function x ->
+ match Ast0.undots x with
+ [s] -> is_pure_context s
+ | _ -> false (* could we do better? *))
+ statement_dots_list
+ | _ ->
+ (match Ast0.get_mcodekind s with
+ Ast0.CONTEXT(mc) ->
+ (match !mc with
+ (Ast.NOTHING,_,_) -> true
+ | _ -> false)
+ | Ast0.MINUS(mc) ->
+ (match !mc with
+ (* do better for the common case of replacing a stmt by another one *)
+ ([[Ast.StatementTag(s)]],_) ->
+ (match Ast.unwrap s with
+ Ast.IfThen(_,_,_) -> false (* potentially dangerous *)
+ | _ -> true)
+ | (_,_) -> false)
+ | _ -> false))
+
+let is_minus e =
+ match Ast0.get_mcodekind e with Ast0.MINUS(cell) -> true | _ -> false
+
+let match_list matcher is_list_matcher do_list_match la lb =
+ let rec loop = function
+ ([],[]) -> return true
+ | ([x],lb) when is_list_matcher x -> do_list_match x lb
+ | (x::xs,y::ys) -> conjunct_bindings (matcher x y) (loop (xs,ys))
+ | _ -> return false in
+ loop (la,lb)
+
+let match_maker checks_needed context_required whencode_allowed =
+
+ let check_mcode pmc cmc binding =
+ if checks_needed
+ then
+ match Ast0.get_pos cmc with
+ (Ast0.MetaPos (name,_,_)) as x ->
+ (match Ast0.get_pos pmc with
+ Ast0.MetaPos (name1,_,_) ->
+ add_binding name1 (Ast0.MetaPosTag x) binding
+ | Ast0.NoMetaPos ->
+ let (rule,name) = Ast0.unwrap_mcode name in
+ Fail (Position(rule,name)))
+ | Ast0.NoMetaPos -> OK binding
+ else OK binding in
+
+ let match_dots matcher is_list_matcher do_list_match d1 d2 =
+ match (Ast0.unwrap d1, Ast0.unwrap d2) with
+ (Ast0.DOTS(la),Ast0.DOTS(lb))
+ | (Ast0.CIRCLES(la),Ast0.CIRCLES(lb))
+ | (Ast0.STARS(la),Ast0.STARS(lb)) ->
+ match_list matcher is_list_matcher (do_list_match d2) la lb
+ | _ -> return false in
+
+ let is_elist_matcher el =
+ match Ast0.unwrap el with Ast0.MetaExprList(_,_,_) -> true | _ -> false in
+
+ let is_plist_matcher pl =
+ match Ast0.unwrap pl with Ast0.MetaParamList(_,_,_) -> true | _ -> false in
+
+ let is_slist_matcher pl =
+ match Ast0.unwrap pl with Ast0.MetaStmtList(_,_) -> true | _ -> false in
+
+ let no_list _ = false in
+
+ let build_dots pattern data =
+ match Ast0.unwrap pattern with
+ Ast0.DOTS(_) -> Ast0.rewrap pattern (Ast0.DOTS(data))
+ | Ast0.CIRCLES(_) -> Ast0.rewrap pattern (Ast0.CIRCLES(data))
+ | Ast0.STARS(_) -> Ast0.rewrap pattern (Ast0.STARS(data)) in
+
+ let pure_sp_code =
+ let bind = Ast0.lub_pure in
+ let option_default = Ast0.Context in
+ let pure_mcodekind = function
+ Ast0.CONTEXT(mc) ->
+ (match !mc with
+ (Ast.NOTHING,_,_) -> Ast0.PureContext
+ | _ -> Ast0.Context)
+ | Ast0.MINUS(mc) ->
+ (match !mc with ([],_) -> Ast0.Pure | _ -> Ast0.Impure)
+ | _ -> Ast0.Impure in
+ let donothing r k e =
+ bind (pure_mcodekind (Ast0.get_mcodekind e)) (k e) in
+
+ let mcode m = pure_mcodekind (Ast0.get_mcode_mcodekind m) in
+
+ (* a case for everything that has a metavariable *)
+ (* pure is supposed to match only unitary metavars, not anything that
+ contains only unitary metavars *)
+ let ident r k i =
+ bind (bind (pure_mcodekind (Ast0.get_mcodekind i)) (k i))
+ (match Ast0.unwrap i with
+ Ast0.MetaId(name,_,pure) | Ast0.MetaFunc(name,_,pure)
+ | Ast0.MetaLocalFunc(name,_,pure) -> pure
+ | _ -> Ast0.Impure) in
+
+ let expression r k e =
+ bind (bind (pure_mcodekind (Ast0.get_mcodekind e)) (k e))
+ (match Ast0.unwrap e with
+ Ast0.MetaErr(name,_,pure)
+ | Ast0.MetaExpr(name,_,_,_,pure) | Ast0.MetaExprList(name,_,pure) ->
+ pure
+ | _ -> Ast0.Impure) in
+
+ let typeC r k t =
+ bind (bind (pure_mcodekind (Ast0.get_mcodekind t)) (k t))
+ (match Ast0.unwrap t with
+ Ast0.MetaType(name,pure) -> pure
+ | _ -> Ast0.Impure) in
+
+ let param r k p =
+ bind (bind (pure_mcodekind (Ast0.get_mcodekind p)) (k p))
+ (match Ast0.unwrap p with
+ Ast0.MetaParam(name,pure) | Ast0.MetaParamList(name,_,pure) -> pure
+ | _ -> Ast0.Impure) in
+
+ let stmt r k s =
+ bind (bind (pure_mcodekind (Ast0.get_mcodekind s)) (k s))
+ (match Ast0.unwrap s with
+ Ast0.MetaStmt(name,pure) | Ast0.MetaStmtList(name,pure) -> pure
+ | _ -> Ast0.Impure) in
+
+ V0.combiner bind option_default
+ mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+ mcode
+ donothing donothing donothing donothing donothing donothing
+ ident expression typeC donothing param donothing stmt donothing
+ donothing in
+
+ let add_pure_list_binding name pure is_pure builder1 builder2 lst =
+ match (checks_needed,pure) with
+ (true,Ast0.Pure) | (true,Ast0.Context) | (true,Ast0.PureContext) ->
+ (match lst with
+ [x] ->
+ if (Ast0.lub_pure (is_pure x) pure) = pure
+ then add_binding name (builder1 lst)
+ else return_false (NotPure (pure,term name,builder1 lst))
+ | _ -> return_false (NotPureLength (term name)))
+ | (false,_) | (_,Ast0.Impure) -> add_binding name (builder2 lst) in
+
+ let add_pure_binding name pure is_pure builder x =
+ match (checks_needed,pure) with
+ (true,Ast0.Pure) | (true,Ast0.Context) | (true,Ast0.PureContext) ->
+ if (Ast0.lub_pure (is_pure x) pure) = pure
+ then add_binding name (builder x)
+ else return_false (NotPure (pure,term name, builder x))
+ | (false,_) | (_,Ast0.Impure) -> add_binding name (builder x) in
+
+ let do_elist_match builder el lst =
+ match Ast0.unwrap el with
+ Ast0.MetaExprList(name,lenname,pure) ->
+ (*how to handle lenname? should it be an option type and always None?*)
+ failwith "expr list pattern not supported in iso"
+ (*add_pure_list_binding name pure
+ pure_sp_code.V0.combiner_expression
+ (function lst -> Ast0.ExprTag(List.hd lst))
+ (function lst -> Ast0.DotsExprTag(build_dots builder lst))
+ lst*)
+ | _ -> failwith "not possible" in
+
+ let do_plist_match builder pl lst =
+ match Ast0.unwrap pl with
+ Ast0.MetaParamList(name,lename,pure) ->
+ failwith "param list pattern not supported in iso"
+ (*add_pure_list_binding name pure
+ pure_sp_code.V0.combiner_parameter
+ (function lst -> Ast0.ParamTag(List.hd lst))
+ (function lst -> Ast0.DotsParamTag(build_dots builder lst))
+ lst*)
+ | _ -> failwith "not possible" in
+
+ let do_slist_match builder sl lst =
+ match Ast0.unwrap sl with
+ Ast0.MetaStmtList(name,pure) ->
+ add_pure_list_binding name pure
+ pure_sp_code.V0.combiner_statement
+ (function lst -> Ast0.StmtTag(List.hd lst))
+ (function lst -> Ast0.DotsStmtTag(build_dots builder lst))
+ lst
+ | _ -> failwith "not possible" in
+
+ let do_nolist_match _ _ = failwith "not possible" in
+
+ let rec match_ident pattern id =
+ match Ast0.unwrap pattern with
+ Ast0.MetaId(name,_,pure) ->
+ (add_pure_binding name pure pure_sp_code.V0.combiner_ident
+ (function id -> Ast0.IdentTag id) id)
+ | Ast0.MetaFunc(name,_,pure) -> failwith "metafunc not supported"
+ | Ast0.MetaLocalFunc(name,_,pure) -> failwith "metalocalfunc not supported"
+ | up ->
+ if not(checks_needed) or not(context_required) or is_context id
+ then
+ match (up,Ast0.unwrap id) with
+ (Ast0.Id(namea),Ast0.Id(nameb)) ->
+ if mcode_equal namea nameb
+ then check_mcode namea nameb
+ else return false
+ | (Ast0.OptIdent(ida),Ast0.OptIdent(idb))
+ | (Ast0.UniqueIdent(ida),Ast0.UniqueIdent(idb)) ->
+ match_ident ida idb
+ | (_,Ast0.OptIdent(idb))
+ | (_,Ast0.UniqueIdent(idb)) -> match_ident pattern idb
+ | _ -> return false
+ else return_false (ContextRequired (Ast0.IdentTag id)) in
+
+ (* should we do something about matching metavars against ...? *)
+ let rec match_expr pattern expr =
+ match Ast0.unwrap pattern with
+ Ast0.MetaExpr(name,_,ty,form,pure) ->
+ let form_ok =
+ match (form,expr) with
+ (Ast.ANY,_) -> true
+ | (Ast.CONST,e) ->
+ let rec matches e =
+ match Ast0.unwrap e with
+ Ast0.Constant(c) -> true
+ | Ast0.Cast(lp,ty,rp,e) -> matches e
+ | Ast0.SizeOfExpr(se,exp) -> true
+ | Ast0.SizeOfType(se,lp,ty,rp) -> true
+ | Ast0.MetaExpr(nm,_,_,Ast.CONST,p) ->
+ (Ast0.lub_pure p pure) = pure
+ | _ -> false in
+ matches e
+ | (Ast.ID,e) | (Ast.LocalID,e) ->
+ let rec matches e =
+ match Ast0.unwrap e with
+ Ast0.Ident(c) -> true
+ | Ast0.Cast(lp,ty,rp,e) -> matches e
+ | Ast0.MetaExpr(nm,_,_,Ast.ID,p) ->
+ (Ast0.lub_pure p pure) = pure
+ | _ -> false in
+ matches e in
+ if form_ok
+ then
+ match ty with
+ Some ts ->
+ if List.exists
+ (function Type_cocci.MetaType(_,_,_) -> true | _ -> false)
+ ts
+ then
+ (match ts with
+ [Type_cocci.MetaType(tyname,_,_)] ->
+ let expty =
+ match (Ast0.unwrap expr,Ast0.get_type expr) with
+ (* easier than updating type inferencer to manage multiple
+ types *)
+ (Ast0.MetaExpr(_,_,Some tts,_,_),_) -> Some tts
+ | (_,Some ty) -> Some [ty]
+ | _ -> None in
+ (match expty with
+ Some expty ->
+ let tyname = Ast0.rewrap_mcode name tyname in
+ (function bindings ->
+ let attempts =
+ List.map
+ (function expty ->
+ (try
+ conjunct_bindings
+ (add_pure_binding tyname Ast0.Impure
+ (function _ -> Ast0.Impure)
+ (function ty -> Ast0.TypeCTag ty)
+ (Ast0.rewrap expr
+ (Ast0.reverse_type expty)))
+ (add_pure_binding name pure
+ pure_sp_code.V0.combiner_expression
+ (function expr -> Ast0.ExprTag expr)
+ expr)
+ bindings
+ with Ast0.TyConv ->
+ Printf.printf "warning: unconvertible type";
+ return false bindings))
+ expty in
+ match
+ List.concat
+ (List.map (function Fail _ -> [] | OK x -> x)
+ attempts)
+ with
+ [] -> Fail NonMatch
+ | x -> OK x)
+ | _ ->
+ (*Printf.printf
+ "warning: type metavar can only match one type";*)
+ return false)
+ | _ ->
+ failwith
+ "mixture of metatype and other types not supported")
+ else
+ let expty = Ast0.get_type expr in
+ if List.exists (function t -> Type_cocci.compatible t expty) ts
+ then
+ add_pure_binding name pure
+ pure_sp_code.V0.combiner_expression
+ (function expr -> Ast0.ExprTag expr)
+ expr
+ else return false
+ | None ->
+ add_pure_binding name pure pure_sp_code.V0.combiner_expression
+ (function expr -> Ast0.ExprTag expr)
+ expr
+ else return false
+ | Ast0.MetaErr(namea,_,pure) -> failwith "metaerr not supported"
+ | Ast0.MetaExprList(_,_,_) -> failwith "metaexprlist not supported"
+ | up ->
+ if not(checks_needed) or not(context_required) or is_context expr
+ then
+ match (up,Ast0.unwrap expr) with
+ (Ast0.Ident(ida),Ast0.Ident(idb)) ->
+ match_ident ida idb
+ | (Ast0.Constant(consta),Ast0.Constant(constb)) ->
+ if mcode_equal consta constb
+ then check_mcode consta constb
+ else return false
+ | (Ast0.FunCall(fna,lp1,argsa,rp1),Ast0.FunCall(fnb,lp,argsb,rp)) ->
+ conjunct_many_bindings
+ [check_mcode lp1 lp; check_mcode rp1 rp; match_expr fna fnb;
+ match_dots match_expr is_elist_matcher do_elist_match
+ argsa argsb]
+ | (Ast0.Assignment(lefta,opa,righta,_),
+ Ast0.Assignment(leftb,opb,rightb,_)) ->
+ if mcode_equal opa opb
+ then
+ conjunct_many_bindings
+ [check_mcode opa opb; match_expr lefta leftb;
+ match_expr righta rightb]
+ else return false
+ | (Ast0.CondExpr(exp1a,lp1,exp2a,rp1,exp3a),
+ Ast0.CondExpr(exp1b,lp,exp2b,rp,exp3b)) ->
+ conjunct_many_bindings
+ [check_mcode lp1 lp; check_mcode rp1 rp;
+ match_expr exp1a exp1b; match_option match_expr exp2a exp2b;
+ match_expr exp3a exp3b]
+ | (Ast0.Postfix(expa,opa),Ast0.Postfix(expb,opb)) ->
+ if mcode_equal opa opb
+ then
+ conjunct_bindings (check_mcode opa opb) (match_expr expa expb)
+ else return false
+ | (Ast0.Infix(expa,opa),Ast0.Infix(expb,opb)) ->
+ if mcode_equal opa opb
+ then
+ conjunct_bindings (check_mcode opa opb) (match_expr expa expb)
+ else return false
+ | (Ast0.Unary(expa,opa),Ast0.Unary(expb,opb)) ->
+ if mcode_equal opa opb
+ then
+ conjunct_bindings (check_mcode opa opb) (match_expr expa expb)
+ else return false
+ | (Ast0.Binary(lefta,opa,righta),Ast0.Binary(leftb,opb,rightb)) ->
+ if mcode_equal opa opb
+ then
+ conjunct_many_bindings
+ [check_mcode opa opb; match_expr lefta leftb;
+ match_expr righta rightb]
+ else return false
+ | (Ast0.Paren(lp1,expa,rp1),Ast0.Paren(lp,expb,rp)) ->
+ conjunct_many_bindings
+ [check_mcode lp1 lp; check_mcode rp1 rp; match_expr expa expb]
+ | (Ast0.ArrayAccess(exp1a,lb1,exp2a,rb1),
+ Ast0.ArrayAccess(exp1b,lb,exp2b,rb)) ->
+ conjunct_many_bindings
+ [check_mcode lb1 lb; check_mcode rb1 rb;
+ match_expr exp1a exp1b; match_expr exp2a exp2b]
+ | (Ast0.RecordAccess(expa,opa,fielda),
+ Ast0.RecordAccess(expb,op,fieldb))
+ | (Ast0.RecordPtAccess(expa,opa,fielda),
+ Ast0.RecordPtAccess(expb,op,fieldb)) ->
+ conjunct_many_bindings
+ [check_mcode opa op; match_expr expa expb;
+ match_ident fielda fieldb]
+ | (Ast0.Cast(lp1,tya,rp1,expa),Ast0.Cast(lp,tyb,rp,expb)) ->
+ conjunct_many_bindings
+ [check_mcode lp1 lp; check_mcode rp1 rp;
+ match_typeC tya tyb; match_expr expa expb]
+ | (Ast0.SizeOfExpr(szf1,expa),Ast0.SizeOfExpr(szf,expb)) ->
+ conjunct_bindings (check_mcode szf1 szf) (match_expr expa expb)
+ | (Ast0.SizeOfType(szf1,lp1,tya,rp1),
+ Ast0.SizeOfType(szf,lp,tyb,rp)) ->
+ conjunct_many_bindings
+ [check_mcode lp1 lp; check_mcode rp1 rp;
+ check_mcode szf1 szf; match_typeC tya tyb]
+ | (Ast0.TypeExp(tya),Ast0.TypeExp(tyb)) ->
+ match_typeC tya tyb
+ | (Ast0.EComma(cm1),Ast0.EComma(cm)) -> check_mcode cm1 cm
+ | (Ast0.DisjExpr(_,expsa,_,_),_) ->
+ failwith "not allowed in the pattern of an isomorphism"
+ | (Ast0.NestExpr(_,exp_dotsa,_,_,_),_) ->
+ failwith "not allowed in the pattern of an isomorphism"
+ | (Ast0.Edots(d,None),Ast0.Edots(d1,None))
+ | (Ast0.Ecircles(d,None),Ast0.Ecircles(d1,None))
+ | (Ast0.Estars(d,None),Ast0.Estars(d1,None)) -> check_mcode d d1
+ | (Ast0.Edots(ed,None),Ast0.Edots(ed1,Some wc))
+ | (Ast0.Ecircles(ed,None),Ast0.Ecircles(ed1,Some wc))
+ | (Ast0.Estars(ed,None),Ast0.Estars(ed1,Some wc)) ->
+ (* hope that mcode of edots is unique somehow *)
+ conjunct_bindings (check_mcode ed ed1)
+ (let (edots_whencode_allowed,_,_) = whencode_allowed in
+ if edots_whencode_allowed
+ then add_dot_binding ed (Ast0.ExprTag wc)
+ else
+ (Printf.printf
+ "warning: not applying iso because of whencode";
+ return false))
+ | (Ast0.Edots(_,Some _),_) | (Ast0.Ecircles(_,Some _),_)
+ | (Ast0.Estars(_,Some _),_) ->
+ failwith "whencode not allowed in a pattern1"
+ | (Ast0.OptExp(expa),Ast0.OptExp(expb))
+ | (Ast0.UniqueExp(expa),Ast0.UniqueExp(expb)) -> match_expr expa expb
+ | (_,Ast0.OptExp(expb))
+ | (_,Ast0.UniqueExp(expb)) -> match_expr pattern expb
+ | _ -> return false
+ else return_false (ContextRequired (Ast0.ExprTag expr))
+
+(* the special case for function types prevents the eg T X; -> T X = E; iso
+ from applying, which doesn't seem very relevant, but it also avoids a
+ mysterious bug that is obtained with eg int attach(...); *)
+ and match_typeC pattern t =
+ match Ast0.unwrap pattern with
+ Ast0.MetaType(name,pure) ->
+ (match Ast0.unwrap t with
+ Ast0.FunctionType(tya,lp1a,paramsa,rp1a) -> return false
+ | _ ->
+ add_pure_binding name pure pure_sp_code.V0.combiner_typeC
+ (function ty -> Ast0.TypeCTag ty)
+ t)
+ | up ->
+ if not(checks_needed) or not(context_required) or is_context t
+ then
+ match (up,Ast0.unwrap t) with
+ (Ast0.ConstVol(cva,tya),Ast0.ConstVol(cvb,tyb)) ->
+ if mcode_equal cva cvb
+ then
+ conjunct_bindings (check_mcode cva cvb) (match_typeC tya tyb)
+ else return false
+ | (Ast0.BaseType(tya,signa),Ast0.BaseType(tyb,signb)) ->
+ if (mcode_equal tya tyb &&
+ bool_match_option mcode_equal signa signb)
+ then
+ conjunct_bindings (check_mcode tya tyb)
+ (match_option check_mcode signa signb)
+ else return false
+ | (Ast0.ImplicitInt(signa),Ast0.ImplicitInt(signb)) ->
+ if mcode_equal signa signb
+ then check_mcode signa signb
+ else return false
+ | (Ast0.Pointer(tya,star1),Ast0.Pointer(tyb,star)) ->
+ conjunct_bindings (check_mcode star1 star) (match_typeC tya tyb)
+ | (Ast0.FunctionPointer(tya,lp1a,stara,rp1a,lp2a,paramsa,rp2a),
+ Ast0.FunctionPointer(tyb,lp1b,starb,rp1b,lp2b,paramsb,rp2b)) ->
+ conjunct_many_bindings
+ [check_mcode stara starb; check_mcode lp1a lp1b;
+ check_mcode rp1a rp1b; check_mcode lp2a lp2b;
+ check_mcode rp2a rp2b; match_typeC tya tyb;
+ match_dots match_param is_plist_matcher
+ do_plist_match paramsa paramsb]
+ | (Ast0.FunctionType(tya,lp1a,paramsa,rp1a),
+ Ast0.FunctionType(tyb,lp1b,paramsb,rp1b)) ->
+ conjunct_many_bindings
+ [check_mcode lp1a lp1b; check_mcode rp1a rp1b;
+ match_option match_typeC tya tyb;
+ match_dots match_param is_plist_matcher do_plist_match
+ paramsa paramsb]
+ | (Ast0.Array(tya,lb1,sizea,rb1),Ast0.Array(tyb,lb,sizeb,rb)) ->
+ conjunct_many_bindings
+ [check_mcode lb1 lb; check_mcode rb1 rb;
+ match_typeC tya tyb; match_option match_expr sizea sizeb]
+ | (Ast0.StructUnionName(kinda,Some namea),
+ Ast0.StructUnionName(kindb,Some nameb)) ->
+ if mcode_equal kinda kindb
+ then
+ conjunct_bindings (check_mcode kinda kindb)
+ (match_ident namea nameb)
+ else return false
+ | (Ast0.StructUnionDef(tya,lb1,declsa,rb1),
+ Ast0.StructUnionDef(tyb,lb,declsb,rb)) ->
+ conjunct_many_bindings
+ [check_mcode lb1 lb; check_mcode rb1 rb;
+ match_typeC tya tyb;
+ match_dots match_decl no_list do_nolist_match declsa declsb]
+ | (Ast0.TypeName(namea),Ast0.TypeName(nameb)) ->
+ if mcode_equal namea nameb
+ then check_mcode namea nameb
+ else return false
+ | (Ast0.DisjType(_,typesa,_,_),Ast0.DisjType(_,typesb,_,_)) ->
+ failwith "not allowed in the pattern of an isomorphism"
+ | (Ast0.OptType(tya),Ast0.OptType(tyb))
+ | (Ast0.UniqueType(tya),Ast0.UniqueType(tyb)) -> match_typeC tya tyb
+ | (_,Ast0.OptType(tyb))
+ | (_,Ast0.UniqueType(tyb)) -> match_typeC pattern tyb
+ | _ -> return false
+ else return_false (ContextRequired (Ast0.TypeCTag t))
+
+ and match_decl pattern d =
+ if not(checks_needed) or not(context_required) or is_context d
+ then
+ match (Ast0.unwrap pattern,Ast0.unwrap d) with
+ (Ast0.Init(stga,tya,ida,eq1,inia,sc1),
+ Ast0.Init(stgb,tyb,idb,eq,inib,sc)) ->
+ if bool_match_option mcode_equal stga stgb
+ then
+ conjunct_many_bindings
+ [check_mcode eq1 eq; check_mcode sc1 sc;
+ match_option check_mcode stga stgb;
+ match_typeC tya tyb; match_ident ida idb;
+ match_init inia inib]
+ else return false
+ | (Ast0.UnInit(stga,tya,ida,sc1),Ast0.UnInit(stgb,tyb,idb,sc)) ->
+ if bool_match_option mcode_equal stga stgb
+ then
+ conjunct_many_bindings
+ [check_mcode sc1 sc; match_option check_mcode stga stgb;
+ match_typeC tya tyb; match_ident ida idb]
+ else return false
+ | (Ast0.MacroDecl(namea,lp1,argsa,rp1,sc1),
+ Ast0.MacroDecl(nameb,lp,argsb,rp,sc)) ->
+ conjunct_many_bindings
+ [match_ident namea nameb;
+ check_mcode lp1 lp; check_mcode rp1 rp;
+ check_mcode sc1 sc;
+ match_dots match_expr is_elist_matcher do_elist_match
+ argsa argsb]
+ | (Ast0.TyDecl(tya,sc1),Ast0.TyDecl(tyb,sc)) ->
+ conjunct_bindings (check_mcode sc1 sc) (match_typeC tya tyb)
+ | (Ast0.Typedef(stga,tya,ida,sc1),Ast0.Typedef(stgb,tyb,idb,sc)) ->
+ conjunct_bindings (check_mcode sc1 sc)
+ (conjunct_bindings (match_typeC tya tyb) (match_typeC ida idb))
+ | (Ast0.DisjDecl(_,declsa,_,_),Ast0.DisjDecl(_,declsb,_,_)) ->
+ failwith "not allowed in the pattern of an isomorphism"
+ | (Ast0.Ddots(d1,None),Ast0.Ddots(d,None)) -> check_mcode d1 d
+ | (Ast0.Ddots(dd,None),Ast0.Ddots(d,Some wc)) ->
+ conjunct_bindings (check_mcode dd d)
+ (* hope that mcode of ddots is unique somehow *)
+ (let (ddots_whencode_allowed,_,_) = whencode_allowed in
+ if ddots_whencode_allowed
+ then add_dot_binding dd (Ast0.DeclTag wc)
+ else
+ (Printf.printf "warning: not applying iso because of whencode";
+ return false))
+ | (Ast0.Ddots(_,Some _),_) ->
+ failwith "whencode not allowed in a pattern1"
+
+ | (Ast0.OptDecl(decla),Ast0.OptDecl(declb))
+ | (Ast0.UniqueDecl(decla),Ast0.UniqueDecl(declb)) ->
+ match_decl decla declb
+ | (_,Ast0.OptDecl(declb))
+ | (_,Ast0.UniqueDecl(declb)) ->
+ match_decl pattern declb
+ | _ -> return false
+ else return_false (ContextRequired (Ast0.DeclTag d))
+
+ and match_init pattern i =
+ if not(checks_needed) or not(context_required) or is_context i
+ then
+ match (Ast0.unwrap pattern,Ast0.unwrap i) with
+ (Ast0.InitExpr(expa),Ast0.InitExpr(expb)) ->
+ match_expr expa expb
+ | (Ast0.InitList(lb1,initlista,rb1),Ast0.InitList(lb,initlistb,rb)) ->
+ conjunct_many_bindings
+ [check_mcode lb1 lb; check_mcode rb1 rb;
+ match_dots match_init no_list do_nolist_match
+ initlista initlistb]
+ | (Ast0.InitGccDotName(d1,namea,e1,inia),
+ Ast0.InitGccDotName(d,nameb,e,inib)) ->
+ conjunct_many_bindings
+ [check_mcode d1 d; check_mcode e1 e;
+ match_ident namea nameb; match_init inia inib]
+ | (Ast0.InitGccName(namea,c1,inia),Ast0.InitGccName(nameb,c,inib)) ->
+ conjunct_many_bindings
+ [check_mcode c1 c; match_ident namea nameb;
+ match_init inia inib]
+ | (Ast0.InitGccIndex(lb1,expa,rb1,e1,inia),
+ Ast0.InitGccIndex(lb2,expb,rb2,e2,inib)) ->
+ conjunct_many_bindings
+ [check_mcode lb1 lb2; check_mcode rb1 rb2; check_mcode e1 e2;
+ match_expr expa expb; match_init inia inib]
+ | (Ast0.InitGccRange(lb1,exp1a,d1,exp2a,rb1,e1,inia),
+ Ast0.InitGccRange(lb2,exp1b,d2,exp2b,rb2,e2,inib)) ->
+ conjunct_many_bindings
+ [check_mcode lb1 lb2; check_mcode d1 d2;
+ check_mcode rb1 rb2; check_mcode e1 e2;
+ match_expr exp1a exp1b; match_expr exp2a exp2b;
+ match_init inia inib]
+ | (Ast0.IComma(c1),Ast0.IComma(c)) -> check_mcode c1 c
+ | (Ast0.Idots(d1,None),Ast0.Idots(d,None)) -> check_mcode d1 d
+ | (Ast0.Idots(id,None),Ast0.Idots(d,Some wc)) ->
+ conjunct_bindings (check_mcode id d)
+ (* hope that mcode of edots is unique somehow *)
+ (let (_,idots_whencode_allowed,_) = whencode_allowed in
+ if idots_whencode_allowed
+ then add_dot_binding id (Ast0.InitTag wc)
+ else
+ (Printf.printf "warning: not applying iso because of whencode";
+ return false))
+ | (Ast0.Idots(_,Some _),_) ->
+ failwith "whencode not allowed in a pattern2"
+ | (Ast0.OptIni(ia),Ast0.OptIni(ib))
+ | (Ast0.UniqueIni(ia),Ast0.UniqueIni(ib)) -> match_init ia ib
+ | (_,Ast0.OptIni(ib))
+ | (_,Ast0.UniqueIni(ib)) -> match_init pattern ib
+ | _ -> return false
+ else return_false (ContextRequired (Ast0.InitTag i))
+
+ and match_param pattern p =
+ match Ast0.unwrap pattern with
+ Ast0.MetaParam(name,pure) ->
+ add_pure_binding name pure pure_sp_code.V0.combiner_parameter
+ (function p -> Ast0.ParamTag p)
+ p
+ | Ast0.MetaParamList(name,_,pure) -> failwith "metaparamlist not supported"
+ | up ->
+ if not(checks_needed) or not(context_required) or is_context p
+ then
+ match (up,Ast0.unwrap p) with
+ (Ast0.VoidParam(tya),Ast0.VoidParam(tyb)) -> match_typeC tya tyb
+ | (Ast0.Param(tya,ida),Ast0.Param(tyb,idb)) ->
+ conjunct_bindings (match_typeC tya tyb)
+ (match_option match_ident ida idb)
+ | (Ast0.PComma(c1),Ast0.PComma(c)) -> check_mcode c1 c
+ | (Ast0.Pdots(d1),Ast0.Pdots(d))
+ | (Ast0.Pcircles(d1),Ast0.Pcircles(d)) -> check_mcode d1 d
+ | (Ast0.OptParam(parama),Ast0.OptParam(paramb))
+ | (Ast0.UniqueParam(parama),Ast0.UniqueParam(paramb)) ->
+ match_param parama paramb
+ | (_,Ast0.OptParam(paramb))
+ | (_,Ast0.UniqueParam(paramb)) -> match_param pattern paramb
+ | _ -> return false
+ else return_false (ContextRequired (Ast0.ParamTag p))
+
+ and match_statement pattern s =
+ match Ast0.unwrap pattern with
+ Ast0.MetaStmt(name,pure) ->
+ (match Ast0.unwrap s with
+ Ast0.Dots(_,_) | Ast0.Circles(_,_) | Ast0.Stars(_,_) ->
+ return false (* ... is not a single statement *)
+ | _ ->
+ add_pure_binding name pure pure_sp_code.V0.combiner_statement
+ (function ty -> Ast0.StmtTag ty)
+ s)
+ | Ast0.MetaStmtList(name,pure) -> failwith "metastmtlist not supported"
+ | up ->
+ if not(checks_needed) or not(context_required) or is_context s
+ then
+ match (up,Ast0.unwrap s) with
+ (Ast0.FunDecl(_,fninfoa,namea,lp1,paramsa,rp1,lb1,bodya,rb1),
+ Ast0.FunDecl(_,fninfob,nameb,lp,paramsb,rp,lb,bodyb,rb)) ->
+ conjunct_many_bindings
+ [check_mcode lp1 lp; check_mcode rp1 rp;
+ check_mcode lb1 lb; check_mcode rb1 rb;
+ match_fninfo fninfoa fninfob; match_ident namea nameb;
+ match_dots match_param is_plist_matcher do_plist_match
+ paramsa paramsb;
+ match_dots match_statement is_slist_matcher do_slist_match
+ bodya bodyb]
+ | (Ast0.Decl(_,decla),Ast0.Decl(_,declb)) ->
+ match_decl decla declb
+ | (Ast0.Seq(lb1,bodya,rb1),Ast0.Seq(lb,bodyb,rb)) ->
+ (* seqs can only match if they are all minus (plus code
+ allowed) or all context (plus code not allowed in the body).
+ we could be more permissive if the expansions of the isos are
+ also all seqs, but this would be hard to check except at top
+ level, and perhaps not worth checking even in that case.
+ Overall, the issue is that braces are used where single
+ statements are required, and something not satisfying these
+ conditions can cause a single statement to become a
+ non-single statement after the transformation.
+
+ example: if { ... -foo(); ... }
+ if we let the sequence convert to just -foo();
+ then we produce invalid code. For some reason,
+ single_statement can't deal with this case, perhaps because
+ it starts introducing too many braces? don't remember the
+ exact problem...
+ *)
+ conjunct_bindings (check_mcode lb1 lb)
+ (conjunct_bindings (check_mcode rb1 rb)
+ (if not(checks_needed) or is_minus s or
+ (is_context s &&
+ List.for_all is_pure_context (Ast0.undots bodyb))
+ then
+ match_dots match_statement is_slist_matcher do_slist_match
+ bodya bodyb
+ else return_false (Braces(s))))
+ | (Ast0.ExprStatement(expa,sc1),Ast0.ExprStatement(expb,sc)) ->
+ conjunct_bindings (check_mcode sc1 sc) (match_expr expa expb)
+ | (Ast0.IfThen(if1,lp1,expa,rp1,branch1a,_),
+ Ast0.IfThen(if2,lp2,expb,rp2,branch1b,_)) ->
+ conjunct_many_bindings
+ [check_mcode if1 if2; check_mcode lp1 lp2;
+ check_mcode rp1 rp2;
+ match_expr expa expb;
+ match_statement branch1a branch1b]
+ | (Ast0.IfThenElse(if1,lp1,expa,rp1,branch1a,e1,branch2a,_),
+ Ast0.IfThenElse(if2,lp2,expb,rp2,branch1b,e2,branch2b,_)) ->
+ conjunct_many_bindings
+ [check_mcode if1 if2; check_mcode lp1 lp2;
+ check_mcode rp1 rp2; check_mcode e1 e2;
+ match_expr expa expb;
+ match_statement branch1a branch1b;
+ match_statement branch2a branch2b]
+ | (Ast0.While(w1,lp1,expa,rp1,bodya,_),
+ Ast0.While(w,lp,expb,rp,bodyb,_)) ->
+ conjunct_many_bindings
+ [check_mcode w1 w; check_mcode lp1 lp;
+ check_mcode rp1 rp; match_expr expa expb;
+ match_statement bodya bodyb]
+ | (Ast0.Do(d1,bodya,w1,lp1,expa,rp1,_),
+ Ast0.Do(d,bodyb,w,lp,expb,rp,_)) ->
+ conjunct_many_bindings
+ [check_mcode d1 d; check_mcode w1 w; check_mcode lp1 lp;
+ check_mcode rp1 rp; match_statement bodya bodyb;
+ match_expr expa expb]
+ | (Ast0.For(f1,lp1,e1a,sc1a,e2a,sc2a,e3a,rp1,bodya,_),
+ Ast0.For(f,lp,e1b,sc1b,e2b,sc2b,e3b,rp,bodyb,_)) ->
+ conjunct_many_bindings
+ [check_mcode f1 f; check_mcode lp1 lp; check_mcode sc1a sc1b;
+ check_mcode sc2a sc2b; check_mcode rp1 rp;
+ match_option match_expr e1a e1b;
+ match_option match_expr e2a e2b;
+ match_option match_expr e3a e3b;
+ match_statement bodya bodyb]
+ | (Ast0.Iterator(nma,lp1,argsa,rp1,bodya,_),
+ Ast0.Iterator(nmb,lp,argsb,rp,bodyb,_)) ->
+ conjunct_many_bindings
+ [match_ident nma nmb;
+ check_mcode lp1 lp; check_mcode rp1 rp;
+ match_dots match_expr is_elist_matcher do_elist_match
+ argsa argsb;
+ match_statement bodya bodyb]
+ | (Ast0.Switch(s1,lp1,expa,rp1,lb1,casesa,rb1),
+ Ast0.Switch(s,lp,expb,rp,lb,casesb,rb)) ->
+ conjunct_many_bindings
+ [check_mcode s1 s; check_mcode lp1 lp; check_mcode rp1 rp;
+ check_mcode lb1 lb; check_mcode rb1 rb;
+ match_expr expa expb;
+ match_dots match_case_line no_list do_nolist_match
+ casesa casesb]
+ | (Ast0.Break(b1,sc1),Ast0.Break(b,sc))
+ | (Ast0.Continue(b1,sc1),Ast0.Continue(b,sc)) ->
+ conjunct_bindings (check_mcode b1 b) (check_mcode sc1 sc)
+ | (Ast0.Label(l1,c1),Ast0.Label(l2,c)) ->
+ conjunct_bindings (match_ident l1 l2) (check_mcode c1 c)
+ | (Ast0.Goto(g1,l1,sc1),Ast0.Goto(g,l2,sc)) ->
+ conjunct_many_bindings
+ [check_mcode g1 g; check_mcode sc1 sc; match_ident l1 l2]
+ | (Ast0.Return(r1,sc1),Ast0.Return(r,sc)) ->
+ conjunct_bindings (check_mcode r1 r) (check_mcode sc1 sc)
+ | (Ast0.ReturnExpr(r1,expa,sc1),Ast0.ReturnExpr(r,expb,sc)) ->
+ conjunct_many_bindings
+ [check_mcode r1 r; check_mcode sc1 sc; match_expr expa expb]
+ | (Ast0.Disj(_,statement_dots_lista,_,_),_) ->
+ failwith "disj not supported in patterns"
+ | (Ast0.Nest(_,stmt_dotsa,_,_,_),_) ->
+ failwith "nest not supported in patterns"
+ | (Ast0.Exp(expa),Ast0.Exp(expb)) -> match_expr expa expb
+ | (Ast0.TopExp(expa),Ast0.TopExp(expb)) -> match_expr expa expb
+ | (Ast0.Exp(expa),Ast0.TopExp(expb)) -> match_expr expa expb
+ | (Ast0.TopInit(inita),Ast0.TopInit(initb)) -> match_init inita initb
+ | (Ast0.Ty(tya),Ast0.Ty(tyb)) -> match_typeC tya tyb
+ | (Ast0.Dots(d,[]),Ast0.Dots(d1,wc))
+ | (Ast0.Circles(d,[]),Ast0.Circles(d1,wc))
+ | (Ast0.Stars(d,[]),Ast0.Stars(d1,wc)) ->
+ (match wc with
+ [] -> check_mcode d d1
+ | _ ->
+ let (_,_,dots_whencode_allowed) = whencode_allowed in
+ if dots_whencode_allowed
+ then
+ conjunct_bindings (check_mcode d d1)
+ (List.fold_left
+ (function prev ->
+ function
+ | Ast0.WhenNot wc ->
+ conjunct_bindings prev
+ (add_multi_dot_binding d
+ (Ast0.DotsStmtTag wc))
+ | Ast0.WhenAlways wc ->
+ conjunct_bindings prev
+ (add_multi_dot_binding d (Ast0.StmtTag wc))
+ | Ast0.WhenNotTrue wc ->
+ conjunct_bindings prev
+ (add_multi_dot_binding d
+ (Ast0.IsoWhenTTag wc))
+ | Ast0.WhenNotFalse wc ->
+ conjunct_bindings prev
+ (add_multi_dot_binding d
+ (Ast0.IsoWhenFTag wc))
+ | Ast0.WhenModifier(x) ->
+ conjunct_bindings prev
+ (add_multi_dot_binding d
+ (Ast0.IsoWhenTag x)))
+ (return true) wc)
+ else
+ (Printf.printf
+ "warning: not applying iso because of whencode";
+ return false))
+ | (Ast0.Dots(_,_::_),_) | (Ast0.Circles(_,_::_),_)
+ | (Ast0.Stars(_,_::_),_) ->
+ failwith "whencode not allowed in a pattern3"
+ | (Ast0.OptStm(rea),Ast0.OptStm(reb))
+ | (Ast0.UniqueStm(rea),Ast0.UniqueStm(reb)) ->
+ match_statement rea reb
+ | (_,Ast0.OptStm(reb))
+ | (_,Ast0.UniqueStm(reb)) -> match_statement pattern reb
+ | _ -> return false
+ else return_false (ContextRequired (Ast0.StmtTag s))
+
+ (* first should provide a subset of the information in the second *)
+ and match_fninfo patterninfo cinfo =
+ let patterninfo = List.sort compare patterninfo in
+ let cinfo = List.sort compare cinfo in
+ let rec loop = function
+ (Ast0.FStorage(sta)::resta,Ast0.FStorage(stb)::restb) ->
+ if mcode_equal sta stb
+ then conjunct_bindings (check_mcode sta stb) (loop (resta,restb))
+ else return false
+ | (Ast0.FType(tya)::resta,Ast0.FType(tyb)::restb) ->
+ conjunct_bindings (match_typeC tya tyb) (loop (resta,restb))
+ | (Ast0.FInline(ia)::resta,Ast0.FInline(ib)::restb) ->
+ if mcode_equal ia ib
+ then conjunct_bindings (check_mcode ia ib) (loop (resta,restb))
+ else return false
+ | (Ast0.FAttr(ia)::resta,Ast0.FAttr(ib)::restb) ->
+ if mcode_equal ia ib
+ then conjunct_bindings (check_mcode ia ib) (loop (resta,restb))
+ else return false
+ | (x::resta,((y::_) as restb)) ->
+ (match compare x y with
+ -1 -> return false
+ | 1 -> loop (resta,restb)
+ | _ -> failwith "not possible")
+ | _ -> return false in
+ loop (patterninfo,cinfo)
+
+ and match_case_line pattern c =
+ if not(checks_needed) or not(context_required) or is_context c
+ then
+ match (Ast0.unwrap pattern,Ast0.unwrap c) with
+ (Ast0.Default(d1,c1,codea),Ast0.Default(d,c,codeb)) ->
+ conjunct_many_bindings
+ [check_mcode d1 d; check_mcode c1 c;
+ match_dots match_statement is_slist_matcher do_slist_match
+ codea codeb]
+ | (Ast0.Case(ca1,expa,c1,codea),Ast0.Case(ca,expb,c,codeb)) ->
+ conjunct_many_bindings
+ [check_mcode ca1 ca; check_mcode c1 c; match_expr expa expb;
+ match_dots match_statement is_slist_matcher do_slist_match
+ codea codeb]
+ | (Ast0.OptCase(ca),Ast0.OptCase(cb)) -> match_case_line ca cb
+ | (_,Ast0.OptCase(cb)) -> match_case_line pattern cb
+ | _ -> return false
+ else return_false (ContextRequired (Ast0.CaseLineTag c)) in
+
+ let match_statement_dots x y =
+ match_dots match_statement is_slist_matcher do_slist_match x y in
+
+ (match_expr, match_decl, match_statement, match_typeC,
+ match_statement_dots)
+
+let match_expr dochecks context_required whencode_allowed =
+ let (fn,_,_,_,_) = match_maker dochecks context_required whencode_allowed in
+ fn
+
+let match_decl dochecks context_required whencode_allowed =
+ let (_,fn,_,_,_) = match_maker dochecks context_required whencode_allowed in
+ fn
+
+let match_statement dochecks context_required whencode_allowed =
+ let (_,_,fn,_,_) = match_maker dochecks context_required whencode_allowed in
+ fn
+
+let match_typeC dochecks context_required whencode_allowed =
+ let (_,_,_,fn,_) = match_maker dochecks context_required whencode_allowed in
+ fn
+
+let match_statement_dots dochecks context_required whencode_allowed =
+ let (_,_,_,_,fn) = match_maker dochecks context_required whencode_allowed in
+ fn
+
+(* --------------------------------------------------------------------- *)
+(* make an entire tree MINUS *)
+
+let make_minus =
+ let mcode (term,arity,info,mcodekind,pos) =
+ let new_mcodekind =
+ match mcodekind with
+ Ast0.CONTEXT(mc) ->
+ (match !mc with
+ (Ast.NOTHING,_,_) -> Ast0.MINUS(ref([],Ast0.default_token_info))
+ | _ -> failwith "make_minus: unexpected befaft")
+ | Ast0.MINUS(mc) -> mcodekind (* in the part copied from the src term *)
+ | _ -> failwith "make_minus mcode: unexpected mcodekind" in
+ (term,arity,info,new_mcodekind,pos) in
+
+ let update_mc mcodekind e =
+ match !mcodekind with
+ Ast0.CONTEXT(mc) ->
+ (match !mc with
+ (Ast.NOTHING,_,_) ->
+ mcodekind := Ast0.MINUS(ref([],Ast0.default_token_info))
+ | _ -> failwith "make_minus: unexpected befaft")
+ | Ast0.MINUS(_mc) -> () (* in the part copied from the src term *)
+ | Ast0.PLUS -> failwith "make_minus donothing: unexpected plus mcodekind"
+ | _ -> failwith "make_minus donothing: unexpected mcodekind" in
+
+ let donothing r k e =
+ let mcodekind = Ast0.get_mcodekind_ref e in
+ let e = k e in update_mc mcodekind e; e in
+
+ (* special case for whencode, because it isn't processed by contextneg,
+ since it doesn't appear in the + code *)
+ (* cases for dots and nests *)
+ let expression r k e =
+ let mcodekind = Ast0.get_mcodekind_ref e in
+ match Ast0.unwrap e with
+ Ast0.Edots(d,whencode) ->
+ (*don't recurse because whencode hasn't been processed by context_neg*)
+ update_mc mcodekind e; Ast0.rewrap e (Ast0.Edots(mcode d,whencode))
+ | Ast0.Ecircles(d,whencode) ->
+ (*don't recurse because whencode hasn't been processed by context_neg*)
+ update_mc mcodekind e; Ast0.rewrap e (Ast0.Ecircles(mcode d,whencode))
+ | Ast0.Estars(d,whencode) ->
+ (*don't recurse because whencode hasn't been processed by context_neg*)
+ update_mc mcodekind e; Ast0.rewrap e (Ast0.Estars(mcode d,whencode))
+ | Ast0.NestExpr(starter,expr_dots,ender,whencode,multi) ->
+ update_mc mcodekind e;
+ Ast0.rewrap e
+ (Ast0.NestExpr(mcode starter,
+ r.V0.rebuilder_expression_dots expr_dots,
+ mcode ender,whencode,multi))
+ | _ -> donothing r k e in
+
+ let declaration r k e =
+ let mcodekind = Ast0.get_mcodekind_ref e in
+ match Ast0.unwrap e with
+ Ast0.Ddots(d,whencode) ->
+ (*don't recurse because whencode hasn't been processed by context_neg*)
+ update_mc mcodekind e; Ast0.rewrap e (Ast0.Ddots(mcode d,whencode))
+ | _ -> donothing r k e in
+
+ let statement r k e =
+ let mcodekind = Ast0.get_mcodekind_ref e in
+ match Ast0.unwrap e with
+ Ast0.Dots(d,whencode) ->
+ (*don't recurse because whencode hasn't been processed by context_neg*)
+ update_mc mcodekind e; Ast0.rewrap e (Ast0.Dots(mcode d,whencode))
+ | Ast0.Circles(d,whencode) ->
+ update_mc mcodekind e; Ast0.rewrap e (Ast0.Circles(mcode d,whencode))
+ | Ast0.Stars(d,whencode) ->
+ update_mc mcodekind e; Ast0.rewrap e (Ast0.Stars(mcode d,whencode))
+ | Ast0.Nest(starter,stmt_dots,ender,whencode,multi) ->
+ update_mc mcodekind e;
+ Ast0.rewrap e
+ (Ast0.Nest(mcode starter,r.V0.rebuilder_statement_dots stmt_dots,
+ mcode ender,whencode,multi))
+ | _ -> donothing r k e in
+
+ let initialiser r k e =
+ let mcodekind = Ast0.get_mcodekind_ref e in
+ match Ast0.unwrap e with
+ Ast0.Idots(d,whencode) ->
+ (*don't recurse because whencode hasn't been processed by context_neg*)
+ update_mc mcodekind e; Ast0.rewrap e (Ast0.Idots(mcode d,whencode))
+ | _ -> donothing r k e in
+
+ let dots r k e =
+ let info = Ast0.get_info e in
+ let mcodekind = Ast0.get_mcodekind_ref e in
+ match Ast0.unwrap e with
+ Ast0.DOTS([]) ->
+ (* if context is - this should be - as well. There are no tokens
+ here though, so the bottom-up minusifier in context_neg leaves it
+ as mixed. It would be better to fix context_neg, but that would
+ require a special case for each term with a dots subterm. *)
+ (match !mcodekind with
+ Ast0.MIXED(mc) ->
+ (match !mc with
+ (Ast.NOTHING,_,_) ->
+ mcodekind := Ast0.MINUS(ref([],Ast0.default_token_info));
+ e
+ | _ -> failwith "make_minus: unexpected befaft")
+ (* code already processed by an enclosing iso *)
+ | Ast0.MINUS(mc) -> e
+ | _ ->
+ failwith
+ (Printf.sprintf
+ "%d: make_minus donothingxxx: unexpected mcodekind"
+ info.Ast0.line_start))
+ | _ -> donothing r k e in
+
+ V0.rebuilder
+ mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+ mcode
+ dots dots dots dots dots dots
+ donothing expression donothing initialiser donothing declaration
+ statement donothing donothing
+
+(* --------------------------------------------------------------------- *)
+(* rebuild mcode cells in an instantiated alt *)
+
+(* mcodes will be side effected later with plus code, so we have to copy
+ them on instantiating an isomorphism. One could wonder whether it would
+ be better not to use side-effects, but they are convenient for insert_plus
+ where is it useful to manipulate a list of the mcodes but side-effect a
+ tree *)
+(* hmm... Insert_plus is called before Iso_pattern... *)
+let rebuild_mcode start_line =
+ let copy_mcodekind = function
+ Ast0.CONTEXT(mc) -> Ast0.CONTEXT(ref (!mc))
+ | Ast0.MINUS(mc) -> Ast0.MINUS(ref (!mc))
+ | Ast0.MIXED(mc) -> Ast0.MIXED(ref (!mc))
+ | Ast0.PLUS ->
+ (* this function is used elsewhere where we need to rebuild the
+ indices, and so we allow PLUS code as well *)
+ Ast0.PLUS in
+
+ let mcode (term,arity,info,mcodekind,pos) =
+ let info =
+ match start_line with
+ Some x -> {info with Ast0.line_start = x; Ast0.line_end = x}
+ | None -> info in
+ (term,arity,info,copy_mcodekind mcodekind,pos) in
+
+ let copy_one x =
+ let old_info = Ast0.get_info x in
+ let info =
+ match start_line with
+ Some x -> {old_info with Ast0.line_start = x; Ast0.line_end = x}
+ | None -> old_info in
+ {x with Ast0.info = info; Ast0.index = ref(Ast0.get_index x);
+ Ast0.mcodekind = ref (copy_mcodekind (Ast0.get_mcodekind x))} in
+
+ let donothing r k e = copy_one (k e) in
+
+ (* case for control operators (if, etc) *)
+ let statement r k e =
+ let s = k e in
+ let res =
+ copy_one
+ (Ast0.rewrap s
+ (match Ast0.unwrap s with
+ Ast0.Decl((info,mc),decl) ->
+ Ast0.Decl((info,copy_mcodekind mc),decl)
+ | Ast0.IfThen(iff,lp,tst,rp,branch,(info,mc)) ->
+ Ast0.IfThen(iff,lp,tst,rp,branch,(info,copy_mcodekind mc))
+ | Ast0.IfThenElse(iff,lp,tst,rp,branch1,els,branch2,(info,mc)) ->
+ Ast0.IfThenElse(iff,lp,tst,rp,branch1,els,branch2,
+ (info,copy_mcodekind mc))
+ | Ast0.While(whl,lp,exp,rp,body,(info,mc)) ->
+ Ast0.While(whl,lp,exp,rp,body,(info,copy_mcodekind mc))
+ | Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,(info,mc)) ->
+ Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,
+ (info,copy_mcodekind mc))
+ | Ast0.Iterator(nm,lp,args,rp,body,(info,mc)) ->
+ Ast0.Iterator(nm,lp,args,rp,body,(info,copy_mcodekind mc))
+ | Ast0.FunDecl
+ ((info,mc),fninfo,name,lp,params,rp,lbrace,body,rbrace) ->
+ Ast0.FunDecl
+ ((info,copy_mcodekind mc),
+ fninfo,name,lp,params,rp,lbrace,body,rbrace)
+ | s -> s)) in
+ Ast0.set_dots_bef_aft res
+ (match Ast0.get_dots_bef_aft res with
+ Ast0.NoDots -> Ast0.NoDots
+ | Ast0.AddingBetweenDots s ->
+ Ast0.AddingBetweenDots(r.V0.rebuilder_statement s)
+ | Ast0.DroppingBetweenDots s ->
+ Ast0.DroppingBetweenDots(r.V0.rebuilder_statement s)) in
+
+ V0.rebuilder
+ mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+ mcode
+ donothing donothing donothing donothing donothing donothing
+ donothing donothing donothing donothing donothing
+ donothing statement donothing donothing
+
+(* --------------------------------------------------------------------- *)
+(* The problem of whencode. If an isomorphism contains dots in multiple
+ rules, then the code that is matched cannot contain whencode, because we
+ won't know which dots it goes with. Should worry about nests, but they
+ aren't allowed in isomorphisms for the moment. *)
+
+let count_edots =
+ let mcode x = 0 in
+ let option_default = 0 in
+ let bind x y = x + y in
+ let donothing r k e = k e in
+ let exprfn r k e =
+ match Ast0.unwrap e with
+ Ast0.Edots(_,_) | Ast0.Ecircles(_,_) | Ast0.Estars(_,_) -> 1
+ | _ -> 0 in
+
+ V0.combiner bind option_default
+ mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+ mcode
+ donothing donothing donothing donothing donothing donothing
+ donothing exprfn donothing donothing donothing donothing donothing
+ donothing donothing
+
+let count_idots =
+ let mcode x = 0 in
+ let option_default = 0 in
+ let bind x y = x + y in
+ let donothing r k e = k e in
+ let initfn r k e =
+ match Ast0.unwrap e with Ast0.Idots(_,_) -> 1 | _ -> 0 in
+
+ V0.combiner bind option_default
+ mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+ mcode
+ donothing donothing donothing donothing donothing donothing
+ donothing donothing donothing initfn donothing donothing donothing
+ donothing donothing
+
+let count_dots =
+ let mcode x = 0 in
+ let option_default = 0 in
+ let bind x y = x + y in
+ let donothing r k e = k e in
+ let stmtfn r k e =
+ match Ast0.unwrap e with
+ Ast0.Dots(_,_) | Ast0.Circles(_,_) | Ast0.Stars(_,_) -> 1
+ | _ -> 0 in
+
+ V0.combiner bind option_default
+ mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+ mcode
+ donothing donothing donothing donothing donothing donothing
+ donothing donothing donothing donothing donothing donothing stmtfn
+ donothing donothing
+
+(* --------------------------------------------------------------------- *)
+
+let lookup name bindings mv_bindings =
+ try Common.Left (List.assoc (term name) bindings)
+ with
+ Not_found ->
+ (* failure is not possible anymore *)
+ Common.Right (List.assoc (term name) mv_bindings)
+
+(* mv_bindings is for the fresh metavariables that are introduced by the
+isomorphism *)
+let instantiate bindings mv_bindings =
+ let mcode x =
+ match Ast0.get_pos x with
+ Ast0.MetaPos(name,_,_) ->
+ (try
+ match lookup name bindings mv_bindings with
+ Common.Left(Ast0.MetaPosTag(id)) -> Ast0.set_pos id x
+ | _ -> failwith "not possible"
+ with Not_found -> Ast0.set_pos Ast0.NoMetaPos x)
+ | _ -> x in
+ let donothing r k e = k e in
+
+ (* cases where metavariables can occur *)
+ let identfn r k e =
+ let e = k e in
+ match Ast0.unwrap e with
+ Ast0.MetaId(name,constraints,pure) ->
+ (rebuild_mcode None).V0.rebuilder_ident
+ (match lookup name bindings mv_bindings with
+ Common.Left(Ast0.IdentTag(id)) -> id
+ | Common.Left(_) -> failwith "not possible 1"
+ | Common.Right(new_mv) ->
+ Ast0.rewrap e
+ (Ast0.MetaId
+ (Ast0.set_mcode_data new_mv name,constraints,pure)))
+ | Ast0.MetaFunc(name,_,pure) -> failwith "metafunc not supported"
+ | Ast0.MetaLocalFunc(name,_,pure) -> failwith "metalocalfunc not supported"
+ | _ -> e in
+
+ (* case for list metavariables *)
+ let rec elist r same_dots = function
+ [] -> []
+ | [x] ->
+ (match Ast0.unwrap x with
+ Ast0.MetaExprList(name,lenname,pure) ->
+ failwith "meta_expr_list in iso not supported"
+ (*match lookup name bindings mv_bindings with
+ Common.Left(Ast0.DotsExprTag(exp)) ->
+ (match same_dots exp with
+ Some l -> l
+ | None -> failwith "dots put in incompatible context")
+ | Common.Left(Ast0.ExprTag(exp)) -> [exp]
+ | Common.Left(_) -> failwith "not possible 1"
+ | Common.Right(new_mv) ->
+ failwith "MetaExprList in SP not supported"*)
+ | _ -> [r.V0.rebuilder_expression x])
+ | x::xs -> (r.V0.rebuilder_expression x)::(elist r same_dots xs) in
+
+ let rec plist r same_dots = function
+ [] -> []
+ | [x] ->
+ (match Ast0.unwrap x with
+ Ast0.MetaParamList(name,lenname,pure) ->
+ failwith "meta_param_list in iso not supported"
+ (*match lookup name bindings mv_bindings with
+ Common.Left(Ast0.DotsParamTag(param)) ->
+ (match same_dots param with
+ Some l -> l
+ | None -> failwith "dots put in incompatible context")
+ | Common.Left(Ast0.ParamTag(param)) -> [param]
+ | Common.Left(_) -> failwith "not possible 1"
+ | Common.Right(new_mv) ->
+ failwith "MetaExprList in SP not supported"*)
+ | _ -> [r.V0.rebuilder_parameter x])
+ | x::xs -> (r.V0.rebuilder_parameter x)::(plist r same_dots xs) in
+
+ let rec slist r same_dots = function
+ [] -> []
+ | [x] ->
+ (match Ast0.unwrap x with
+ Ast0.MetaStmtList(name,pure) ->
+ (match lookup name bindings mv_bindings with
+ Common.Left(Ast0.DotsStmtTag(stm)) ->
+ (match same_dots stm with
+ Some l -> l
+ | None -> failwith "dots put in incompatible context")
+ | Common.Left(Ast0.StmtTag(stm)) -> [stm]
+ | Common.Left(_) -> failwith "not possible 1"
+ | Common.Right(new_mv) ->
+ failwith "MetaExprList in SP not supported")
+ | _ -> [r.V0.rebuilder_statement x])
+ | x::xs -> (r.V0.rebuilder_statement x)::(slist r same_dots xs) in
+
+ let same_dots d =
+ match Ast0.unwrap d with Ast0.DOTS(l) -> Some l |_ -> None in
+ let same_circles d =
+ match Ast0.unwrap d with Ast0.CIRCLES(l) -> Some l |_ -> None in
+ let same_stars d =
+ match Ast0.unwrap d with Ast0.STARS(l) -> Some l |_ -> None in
+
+ let dots list_fn r k d =
+ Ast0.rewrap d
+ (match Ast0.unwrap d with
+ Ast0.DOTS(l) -> Ast0.DOTS(list_fn r same_dots l)
+ | Ast0.CIRCLES(l) -> Ast0.CIRCLES(list_fn r same_circles l)
+ | Ast0.STARS(l) -> Ast0.STARS(list_fn r same_stars l)) in
+
+ let exprfn r k old_e = (* need to keep the original code for ! optim *)
+ let e = k old_e in
+ let e1 =
+ match Ast0.unwrap e with
+ Ast0.MetaExpr(name,constraints,x,form,pure) ->
+ (rebuild_mcode None).V0.rebuilder_expression
+ (match lookup name bindings mv_bindings with
+ Common.Left(Ast0.ExprTag(exp)) -> exp
+ | Common.Left(_) -> failwith "not possible 1"
+ | Common.Right(new_mv) ->
+ let new_types =
+ match x with
+ None -> None
+ | Some types ->
+ let rec renamer = function
+ Type_cocci.MetaType(name,keep,inherited) ->
+ (match
+ lookup (name,(),(),(),None) bindings mv_bindings
+ with
+ Common.Left(Ast0.TypeCTag(t)) ->
+ Ast0.ast0_type_to_type t
+ | Common.Left(_) ->
+ failwith "iso pattern: unexpected type"
+ | Common.Right(new_mv) ->
+ Type_cocci.MetaType(new_mv,keep,inherited))
+ | Type_cocci.ConstVol(cv,ty) ->
+ Type_cocci.ConstVol(cv,renamer ty)
+ | Type_cocci.Pointer(ty) ->
+ Type_cocci.Pointer(renamer ty)
+ | Type_cocci.FunctionPointer(ty) ->
+ Type_cocci.FunctionPointer(renamer ty)
+ | Type_cocci.Array(ty) ->
+ Type_cocci.Array(renamer ty)
+ | t -> t in
+ Some(List.map renamer types) in
+ Ast0.rewrap e
+ (Ast0.MetaExpr
+ (Ast0.set_mcode_data new_mv name,constraints,
+ new_types,form,pure)))
+ | Ast0.MetaErr(namea,_,pure) -> failwith "metaerr not supported"
+ | Ast0.MetaExprList(namea,lenname,pure) ->
+ failwith "metaexprlist not supported"
+ | Ast0.Unary(exp,unop) ->
+ (match Ast0.unwrap_mcode unop with
+ Ast.Not ->
+ let was_meta =
+ (* k e doesn't change the outer structure of the term,
+ only the metavars *)
+ match Ast0.unwrap old_e with
+ Ast0.Unary(exp,_) ->
+ (match Ast0.unwrap exp with
+ Ast0.MetaExpr(name,constraints,x,form,pure) -> true
+ | _ -> false)
+ | _ -> failwith "not possible" in
+ let nomodif e =
+ let mc = Ast0.get_mcodekind exp in
+ match mc with
+ Ast0.MINUS(x) ->
+ (match !x with
+ ([],_) -> true
+ | _ -> false)
+ | Ast0.CONTEXT(x) | Ast0.MIXED(x) ->
+ (match !x with
+ (Ast.NOTHING,_,_) -> true
+ | _ -> false)
+ | _ -> failwith "plus not possible" in
+ if was_meta && nomodif exp && nomodif e
+ then
+ let rec negate e (*for rewrapping*) res (*code to process*) =
+ match Ast0.unwrap res with
+ Ast0.Unary(e1,op) when Ast0.unwrap_mcode op = Ast.Not ->
+ Ast0.rewrap e (Ast0.unwrap e1)
+ | Ast0.Edots(_,_) -> Ast0.rewrap e (Ast0.unwrap res)
+ | Ast0.Paren(lp,e,rp) ->
+ Ast0.rewrap res (Ast0.Paren(lp,negate e e,rp))
+ | Ast0.Binary(e1,op,e2) ->
+ let reb nop = Ast0.rewrap_mcode op (Ast.Logical(nop)) in
+ let invop =
+ match Ast0.unwrap_mcode op with
+ Ast.Logical(Ast.Inf) ->
+ Ast0.Binary(e1,reb Ast.SupEq,e2)
+ | Ast.Logical(Ast.Sup) ->
+ Ast0.Binary(e1,reb Ast.InfEq,e2)
+ | Ast.Logical(Ast.InfEq) ->
+ Ast0.Binary(e1,reb Ast.Sup,e2)
+ | Ast.Logical(Ast.SupEq) ->
+ Ast0.Binary(e1,reb Ast.Inf,e2)
+ | Ast.Logical(Ast.Eq) ->
+ Ast0.Binary(e1,reb Ast.NotEq,e2)
+ | Ast.Logical(Ast.NotEq) ->
+ Ast0.Binary(e1,reb Ast.Eq,e2)
+ | Ast.Logical(Ast.AndLog) ->
+ Ast0.Binary(negate e1 e1,reb Ast.OrLog,
+ negate e2 e2)
+ | Ast.Logical(Ast.OrLog) ->
+ Ast0.Binary(negate e1 e1,reb Ast.AndLog,
+ negate e2 e2)
+ | _ -> Ast0.Unary(res,Ast0.rewrap_mcode op Ast.Not) in
+ Ast0.rewrap e invop
+ | Ast0.DisjExpr(lp,exps,mids,rp) ->
+ (* use res because it is the transformed argument *)
+ let exps = List.map (function e -> negate e e) exps in
+ Ast0.rewrap res (Ast0.DisjExpr(lp,exps,mids,rp))
+ | _ ->
+ (*use e, because this might be the toplevel expression*)
+ Ast0.rewrap e
+ (Ast0.Unary(res,Ast0.rewrap_mcode unop Ast.Not)) in
+ negate e exp
+ else e
+ | _ -> e)
+ | Ast0.Edots(d,_) ->
+ (try
+ (match List.assoc (dot_term d) bindings with
+ Ast0.ExprTag(exp) -> Ast0.rewrap e (Ast0.Edots(d,Some exp))
+ | _ -> failwith "unexpected binding")
+ with Not_found -> e)
+ | Ast0.Ecircles(d,_) ->
+ (try
+ (match List.assoc (dot_term d) bindings with
+ Ast0.ExprTag(exp) -> Ast0.rewrap e (Ast0.Ecircles(d,Some exp))
+ | _ -> failwith "unexpected binding")
+ with Not_found -> e)
+ | Ast0.Estars(d,_) ->
+ (try
+ (match List.assoc (dot_term d) bindings with
+ Ast0.ExprTag(exp) -> Ast0.rewrap e (Ast0.Estars(d,Some exp))
+ | _ -> failwith "unexpected binding")
+ with Not_found -> e)
+ | _ -> e in
+ if Ast0.get_test_exp old_e then Ast0.set_test_exp e1 else e1 in
+
+ let tyfn r k e =
+ let e = k e in
+ match Ast0.unwrap e with
+ Ast0.MetaType(name,pure) ->
+ (rebuild_mcode None).V0.rebuilder_typeC
+ (match lookup name bindings mv_bindings with
+ Common.Left(Ast0.TypeCTag(ty)) -> ty
+ | Common.Left(_) -> failwith "not possible 1"
+ | Common.Right(new_mv) ->
+ Ast0.rewrap e
+ (Ast0.MetaType(Ast0.set_mcode_data new_mv name,pure)))
+ | _ -> e in
+
+ let declfn r k e =
+ let e = k e in
+ match Ast0.unwrap e with
+ Ast0.Ddots(d,_) ->
+ (try
+ (match List.assoc (dot_term d) bindings with
+ Ast0.DeclTag(exp) -> Ast0.rewrap e (Ast0.Ddots(d,Some exp))
+ | _ -> failwith "unexpected binding")
+ with Not_found -> e)
+ | _ -> e in
+
+ let paramfn r k e =
+ let e = k e in
+ match Ast0.unwrap e with
+ Ast0.MetaParam(name,pure) ->
+ (rebuild_mcode None).V0.rebuilder_parameter
+ (match lookup name bindings mv_bindings with
+ Common.Left(Ast0.ParamTag(param)) -> param
+ | Common.Left(_) -> failwith "not possible 1"
+ | Common.Right(new_mv) ->
+ Ast0.rewrap e
+ (Ast0.MetaParam(Ast0.set_mcode_data new_mv name, pure)))
+ | Ast0.MetaParamList(name,lenname,pure) ->
+ failwith "metaparamlist not supported"
+ | _ -> e in
+
+ let whenfn (_,v) =
+ match v with
+ Ast0.DotsStmtTag(stms) -> Ast0.WhenNot stms
+ | Ast0.StmtTag(stm) -> Ast0.WhenAlways stm
+ | Ast0.IsoWhenTTag(stm) -> Ast0.WhenNotTrue stm
+ | Ast0.IsoWhenFTag(stm) -> Ast0.WhenNotFalse stm
+ | Ast0.IsoWhenTag(x) -> Ast0.WhenModifier(x)
+ | _ -> failwith "unexpected binding" in
+
+ let stmtfn r k e =
+ let e = k e in
+ match Ast0.unwrap e with
+ Ast0.MetaStmt(name,pure) ->
+ (rebuild_mcode None).V0.rebuilder_statement
+ (match lookup name bindings mv_bindings with
+ Common.Left(Ast0.StmtTag(stm)) -> stm
+ | Common.Left(_) -> failwith "not possible 1"
+ | Common.Right(new_mv) ->
+ Ast0.rewrap e
+ (Ast0.MetaStmt(Ast0.set_mcode_data new_mv name,pure)))
+ | Ast0.MetaStmtList(name,pure) -> failwith "metastmtlist not supported"
+ | Ast0.Dots(d,_) ->
+ Ast0.rewrap e
+ (Ast0.Dots
+ (d,
+ List.map whenfn
+ (List.filter (function (x,v) -> x = (dot_term d)) bindings)))
+ | Ast0.Circles(d,_) ->
+ Ast0.rewrap e
+ (Ast0.Circles
+ (d,
+ List.map whenfn
+ (List.filter (function (x,v) -> x = (dot_term d)) bindings)))
+ | Ast0.Stars(d,_) ->
+ Ast0.rewrap e
+ (Ast0.Stars
+ (d,
+ List.map whenfn
+ (List.filter (function (x,v) -> x = (dot_term d)) bindings)))
+ | _ -> e in
+
+ V0.rebuilder
+ mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+ mcode
+ (dots elist) donothing (dots plist) (dots slist) donothing donothing
+ identfn exprfn tyfn donothing paramfn declfn stmtfn donothing donothing
+
+(* --------------------------------------------------------------------- *)
+
+let is_minus e =
+ match Ast0.get_mcodekind e with Ast0.MINUS(cell) -> true | _ -> false
+
+let context_required e = not(is_minus e) && not !Flag.sgrep_mode2
+
+let disj_fail bindings e =
+ match bindings with
+ Some x -> Printf.fprintf stderr "no disj available at this type"; e
+ | None -> e
+
+(* isomorphism code is by default CONTEXT *)
+let merge_plus model_mcode e_mcode =
+ match model_mcode with
+ Ast0.MINUS(mc) ->
+ (* add the replacement information at the root *)
+ (match e_mcode with
+ Ast0.MINUS(emc) ->
+ emc :=
+ (match (!mc,!emc) with
+ (([],_),(x,t)) | ((x,_),([],t)) -> (x,t)
+ | _ -> failwith "how can we combine minuses?")
+ | _ -> failwith "not possible 6")
+ | Ast0.CONTEXT(mc) ->
+ (match e_mcode with
+ Ast0.CONTEXT(emc) ->
+ (* keep the logical line info as in the model *)
+ let (mba,tb,ta) = !mc in
+ let (eba,_,_) = !emc in
+ (* merging may be required when a term is replaced by a subterm *)
+ let merged =
+ match (mba,eba) with
+ (x,Ast.NOTHING) | (Ast.NOTHING,x) -> x
+ | (Ast.BEFORE(b1),Ast.BEFORE(b2)) -> Ast.BEFORE(b1@b2)
+ | (Ast.BEFORE(b),Ast.AFTER(a)) -> Ast.BEFOREAFTER(b,a)
+ | (Ast.BEFORE(b1),Ast.BEFOREAFTER(b2,a)) ->
+ Ast.BEFOREAFTER(b1@b2,a)
+ | (Ast.AFTER(a),Ast.BEFORE(b)) -> Ast.BEFOREAFTER(b,a)
+ | (Ast.AFTER(a1),Ast.AFTER(a2)) ->Ast.AFTER(a2@a1)
+ | (Ast.AFTER(a1),Ast.BEFOREAFTER(b,a2)) -> Ast.BEFOREAFTER(b,a2@a1)
+ | (Ast.BEFOREAFTER(b1,a),Ast.BEFORE(b2)) ->
+ Ast.BEFOREAFTER(b1@b2,a)
+ | (Ast.BEFOREAFTER(b,a1),Ast.AFTER(a2)) ->
+ Ast.BEFOREAFTER(b,a2@a1)
+ | (Ast.BEFOREAFTER(b1,a1),Ast.BEFOREAFTER(b2,a2)) ->
+ Ast.BEFOREAFTER(b1@b2,a2@a1) in
+ emc := (merged,tb,ta)
+ | Ast0.MINUS(emc) ->
+ let (anything_bef_aft,_,_) = !mc in
+ let (anythings,t) = !emc in
+ emc :=
+ (match anything_bef_aft with
+ Ast.BEFORE(b) -> (b@anythings,t)
+ | Ast.AFTER(a) -> (anythings@a,t)
+ | Ast.BEFOREAFTER(b,a) -> (b@anythings@a,t)
+ | Ast.NOTHING -> (anythings,t))
+ | _ -> failwith "not possible 7")
+ | Ast0.MIXED(_) -> failwith "not possible 8"
+ | Ast0.PLUS -> failwith "not possible 9"
+
+let copy_plus printer minusify model e =
+ if !Flag.sgrep_mode2
+ then e (* no plus code, can cause a "not possible" error, so just avoid it *)
+ else
+ let e =
+ match Ast0.get_mcodekind model with
+ Ast0.MINUS(mc) -> minusify e
+ | Ast0.CONTEXT(mc) -> e
+ | _ -> failwith "not possible: copy_plus\n" in
+ merge_plus (Ast0.get_mcodekind model) (Ast0.get_mcodekind e);
+ e
+
+let copy_minus printer minusify model e =
+ match Ast0.get_mcodekind model with
+ Ast0.MINUS(mc) -> minusify e
+ | Ast0.CONTEXT(mc) -> e
+ | Ast0.MIXED(_) ->
+ if !Flag.sgrep_mode2
+ then e
+ else failwith "not possible 8"
+ | Ast0.PLUS -> failwith "not possible 9"
+
+let whencode_allowed prev_ecount prev_icount prev_dcount
+ ecount icount dcount rest =
+ (* actually, if ecount or dcount is 0, the flag doesn't matter, because it
+ won't be tested *)
+ let other_ecount = (* number of edots *)
+ List.fold_left (function rest -> function (_,ec,ic,dc) -> ec + rest)
+ prev_ecount rest in
+ let other_icount = (* number of dots *)
+ List.fold_left (function rest -> function (_,ec,ic,dc) -> ic + rest)
+ prev_icount rest in
+ let other_dcount = (* number of dots *)
+ List.fold_left (function rest -> function (_,ec,ic,dc) -> dc + rest)
+ prev_dcount rest in
+ (ecount = 0 or other_ecount = 0, icount = 0 or other_icount = 0,
+ dcount = 0 or other_dcount = 0)
+
+(* copy the befores and afters to the instantiated code *)
+let extra_copy_stmt_plus model e =
+ (if not !Flag.sgrep_mode2 (* sgrep has no plus code, so nothing to do *)
+ then
+ (match Ast0.unwrap model with
+ Ast0.FunDecl((info,bef),_,_,_,_,_,_,_,_)
+ | Ast0.Decl((info,bef),_) ->
+ (match Ast0.unwrap e with
+ Ast0.FunDecl((info,bef1),_,_,_,_,_,_,_,_)
+ | Ast0.Decl((info,bef1),_) ->
+ merge_plus bef bef1
+ | _ -> merge_plus bef (Ast0.get_mcodekind e))
+ | Ast0.IfThen(_,_,_,_,_,(info,aft))
+ | Ast0.IfThenElse(_,_,_,_,_,_,_,(info,aft))
+ | Ast0.While(_,_,_,_,_,(info,aft))
+ | Ast0.For(_,_,_,_,_,_,_,_,_,(info,aft))
+ | Ast0.Iterator(_,_,_,_,_,(info,aft)) ->
+ (match Ast0.unwrap e with
+ Ast0.IfThen(_,_,_,_,_,(info,aft1))
+ | Ast0.IfThenElse(_,_,_,_,_,_,_,(info,aft1))
+ | Ast0.While(_,_,_,_,_,(info,aft1))
+ | Ast0.For(_,_,_,_,_,_,_,_,_,(info,aft1))
+ | Ast0.Iterator(_,_,_,_,_,(info,aft1)) ->
+ merge_plus aft aft1
+ | _ -> merge_plus aft (Ast0.get_mcodekind e))
+ | _ -> ()));
+ e
+
+let extra_copy_other_plus model e = e
+
+(* --------------------------------------------------------------------- *)
+
+let mv_count = ref 0
+let new_mv (_,s) =
+ let ct = !mv_count in
+ mv_count := !mv_count + 1;
+ "_"^s^"_"^(string_of_int ct)
+
+let get_name = function
+ Ast.MetaIdDecl(ar,nm) ->
+ (nm,function nm -> Ast.MetaIdDecl(ar,nm))
+ | Ast.MetaFreshIdDecl(ar,nm) ->
+ (nm,function nm -> Ast.MetaFreshIdDecl(ar,nm))
+ | Ast.MetaTypeDecl(ar,nm) ->
+ (nm,function nm -> Ast.MetaTypeDecl(ar,nm))
+ | Ast.MetaListlenDecl(nm) ->
+ failwith "should not be rebuilt"
+ | Ast.MetaParamDecl(ar,nm) ->
+ (nm,function nm -> Ast.MetaParamDecl(ar,nm))
+ | Ast.MetaParamListDecl(ar,nm,nm1) ->
+ (nm,function nm -> Ast.MetaParamListDecl(ar,nm,nm1))
+ | Ast.MetaConstDecl(ar,nm,ty) ->
+ (nm,function nm -> Ast.MetaConstDecl(ar,nm,ty))
+ | Ast.MetaErrDecl(ar,nm) ->
+ (nm,function nm -> Ast.MetaErrDecl(ar,nm))
+ | Ast.MetaExpDecl(ar,nm,ty) ->
+ (nm,function nm -> Ast.MetaExpDecl(ar,nm,ty))
+ | Ast.MetaIdExpDecl(ar,nm,ty) ->
+ (nm,function nm -> Ast.MetaIdExpDecl(ar,nm,ty))
+ | Ast.MetaLocalIdExpDecl(ar,nm,ty) ->
+ (nm,function nm -> Ast.MetaLocalIdExpDecl(ar,nm,ty))
+ | Ast.MetaExpListDecl(ar,nm,nm1) ->
+ (nm,function nm -> Ast.MetaExpListDecl(ar,nm,nm1))
+ | Ast.MetaStmDecl(ar,nm) ->
+ (nm,function nm -> Ast.MetaStmDecl(ar,nm))
+ | Ast.MetaStmListDecl(ar,nm) ->
+ (nm,function nm -> Ast.MetaStmListDecl(ar,nm))
+ | Ast.MetaFuncDecl(ar,nm) ->
+ (nm,function nm -> Ast.MetaFuncDecl(ar,nm))
+ | Ast.MetaLocalFuncDecl(ar,nm) ->
+ (nm,function nm -> Ast.MetaLocalFuncDecl(ar,nm))
+ | Ast.MetaPosDecl(ar,nm) ->
+ (nm,function nm -> Ast.MetaPosDecl(ar,nm))
+ | Ast.MetaDeclarerDecl(ar,nm) ->
+ (nm,function nm -> Ast.MetaDeclarerDecl(ar,nm))
+ | Ast.MetaIteratorDecl(ar,nm) ->
+ (nm,function nm -> Ast.MetaIteratorDecl(ar,nm))
+
+let make_new_metavars metavars bindings =
+ let new_metavars =
+ List.filter
+ (function mv ->
+ let (s,_) = get_name mv in
+ try let _ = List.assoc s bindings in false with Not_found -> true)
+ metavars in
+ List.split
+ (List.map
+ (function mv ->
+ let (s,rebuild) = get_name mv in
+ let new_s = (!current_rule,new_mv s) in
+ (rebuild new_s, (s,new_s)))
+ new_metavars)
+
+(* --------------------------------------------------------------------- *)
+
+let do_nothing x = x
+
+let mkdisj matcher metavars alts e instantiater mkiso disj_maker minusify
+ rebuild_mcodes name printer extra_plus update_others =
+ let call_instantiate bindings mv_bindings alts =
+ List.concat
+ (List.map
+ (function (a,_,_,_) ->
+ nub
+ (* no need to create duplicates when the bindings have no effect *)
+ (List.map
+ (function bindings ->
+ Ast0.set_iso
+ (copy_plus printer minusify e
+ (extra_plus e
+ (instantiater bindings mv_bindings
+ (rebuild_mcodes a))))
+ (Common.union_set [(name,mkiso a)] (Ast0.get_iso e)))
+ bindings))
+ alts) in
+ let rec inner_loop all_alts prev_ecount prev_icount prev_dcount = function
+ [] -> Common.Left (prev_ecount, prev_icount, prev_dcount)
+ | ((pattern,ecount,icount,dcount)::rest) ->
+ let wc =
+ whencode_allowed prev_ecount prev_icount prev_dcount
+ ecount dcount icount rest in
+ (match matcher true (context_required e) wc pattern e init_env with
+ Fail(reason) ->
+ if reason = NonMatch || not !Flag_parsing_cocci.show_iso_failures
+ then ()
+ else
+ (match matcher false false wc pattern e init_env with
+ OK _ ->
+ interpret_reason name (Ast0.get_line e) reason
+ (function () -> printer e)
+ | _ -> ());
+ inner_loop all_alts (prev_ecount + ecount) (prev_icount + icount)
+ (prev_dcount + dcount) rest
+ | OK (bindings : (((string * string) * 'a) list list)) ->
+ let all_alts =
+ (* apply update_others to all patterns other than the matched
+ one. This is used to desigate the others as test
+ expressions in the TestExpression case *)
+ (List.map
+ (function (x,e,i,d) as all ->
+ if x = pattern
+ then all
+ else (update_others x,e,i,d))
+ (List.hd all_alts)) ::
+ (List.map
+ (List.map (function (x,e,i,d) -> (update_others x,e,i,d)))
+ (List.tl all_alts)) in
+ (match List.concat all_alts with
+ [x] -> Common.Left (prev_ecount, prev_icount, prev_dcount)
+ | all_alts ->
+ let (new_metavars,mv_bindings) =
+ make_new_metavars metavars (nub(List.concat bindings)) in
+ Common.Right
+ (new_metavars,
+ call_instantiate bindings mv_bindings all_alts))) in
+ let rec outer_loop prev_ecount prev_icount prev_dcount = function
+ [] | [[_]] (*only one alternative*) -> ([],e) (* nothing matched *)
+ | (alts::rest) as all_alts ->
+ match inner_loop all_alts prev_ecount prev_icount prev_dcount alts with
+ Common.Left(prev_ecount, prev_icount, prev_dcount) ->
+ outer_loop prev_ecount prev_icount prev_dcount rest
+ | Common.Right (new_metavars,res) ->
+ (new_metavars,
+ copy_minus printer minusify e (disj_maker res)) in
+ outer_loop 0 0 0 alts
+
+(* no one should ever look at the information stored in these mcodes *)
+let disj_starter lst =
+ let old_info = Ast0.get_info(List.hd lst) in
+ let info =
+ { old_info with
+ Ast0.line_end = old_info.Ast0.line_start;
+ Ast0.logical_end = old_info.Ast0.logical_start;
+ Ast0.attachable_start = false; Ast0.attachable_end = false;
+ Ast0.mcode_start = []; Ast0.mcode_end = [];
+ Ast0.strings_before = []; Ast0.strings_after = [] } in
+ Ast0.make_mcode_info "(" info
+
+let disj_ender lst =
+ let old_info = Ast0.get_info(List.hd lst) in
+ let info =
+ { old_info with
+ Ast0.line_start = old_info.Ast0.line_end;
+ Ast0.logical_start = old_info.Ast0.logical_end;
+ Ast0.attachable_start = false; Ast0.attachable_end = false;
+ Ast0.mcode_start = []; Ast0.mcode_end = [];
+ Ast0.strings_before = []; Ast0.strings_after = [] } in
+ Ast0.make_mcode_info ")" info
+
+let disj_mid _ = Ast0.make_mcode "|"
+
+let make_disj_type tl =
+ let mids =
+ match tl with
+ [] -> failwith "bad disjunction"
+ | x::xs -> List.map disj_mid xs in
+ Ast0.context_wrap (Ast0.DisjType(disj_starter tl,tl,mids,disj_ender tl))
+let make_disj_stmt_list tl =
+ let mids =
+ match tl with
+ [] -> failwith "bad disjunction"
+ | x::xs -> List.map disj_mid xs in
+ Ast0.context_wrap (Ast0.Disj(disj_starter tl,tl,mids,disj_ender tl))
+let make_disj_expr model el =
+ let mids =
+ match el with
+ [] -> failwith "bad disjunction"
+ | x::xs -> List.map disj_mid xs in
+ let update_arg x =
+ if Ast0.get_arg_exp model then Ast0.set_arg_exp x else x in
+ let update_test x =
+ let x = if Ast0.get_test_pos model then Ast0.set_test_pos x else x in
+ if Ast0.get_test_exp model then Ast0.set_test_exp x else x in
+ let el = List.map update_arg (List.map update_test el) in
+ Ast0.context_wrap (Ast0.DisjExpr(disj_starter el,el,mids,disj_ender el))
+let make_disj_decl dl =
+ let mids =
+ match dl with
+ [] -> failwith "bad disjunction"
+ | x::xs -> List.map disj_mid xs in
+ Ast0.context_wrap (Ast0.DisjDecl(disj_starter dl,dl,mids,disj_ender dl))
+let make_disj_stmt sl =
+ let dotify x = Ast0.context_wrap (Ast0.DOTS[x]) in
+ let mids =
+ match sl with
+ [] -> failwith "bad disjunction"
+ | x::xs -> List.map disj_mid xs in
+ Ast0.context_wrap
+ (Ast0.Disj(disj_starter sl,List.map dotify sl,mids,disj_ender sl))
+
+let transform_type (metavars,alts,name) e =
+ match alts with
+ (Ast0.TypeCTag(_)::_)::_ ->
+ (* start line is given to any leaves in the iso code *)
+ let start_line = Some ((Ast0.get_info e).Ast0.line_start) in
+ let alts =
+ List.map
+ (List.map
+ (function
+ Ast0.TypeCTag(p) ->
+ (p,count_edots.V0.combiner_typeC p,
+ count_idots.V0.combiner_typeC p,
+ count_dots.V0.combiner_typeC p)
+ | _ -> failwith "invalid alt"))
+ alts in
+ mkdisj match_typeC metavars alts e
+ (function b -> function mv_b ->
+ (instantiate b mv_b).V0.rebuilder_typeC)
+ (function t -> Ast0.TypeCTag t)
+ make_disj_type make_minus.V0.rebuilder_typeC
+ (rebuild_mcode start_line).V0.rebuilder_typeC
+ name Unparse_ast0.typeC extra_copy_other_plus do_nothing
+ | _ -> ([],e)
+
+
+let transform_expr (metavars,alts,name) e =
+ let process update_others =
+ (* start line is given to any leaves in the iso code *)
+ let start_line = Some ((Ast0.get_info e).Ast0.line_start) in
+ let alts =
+ List.map
+ (List.map
+ (function
+ Ast0.ExprTag(p) | Ast0.ArgExprTag(p) | Ast0.TestExprTag(p) ->
+ (p,count_edots.V0.combiner_expression p,
+ count_idots.V0.combiner_expression p,
+ count_dots.V0.combiner_expression p)
+ | _ -> failwith "invalid alt"))
+ alts in
+ mkdisj match_expr metavars alts e
+ (function b -> function mv_b ->
+ (instantiate b mv_b).V0.rebuilder_expression)
+ (function e -> Ast0.ExprTag e)
+ (make_disj_expr e) make_minus.V0.rebuilder_expression
+ (rebuild_mcode start_line).V0.rebuilder_expression
+ name Unparse_ast0.expression extra_copy_other_plus update_others in
+ match alts with
+ (Ast0.ExprTag(_)::_)::_ -> process do_nothing
+ | (Ast0.ArgExprTag(_)::_)::_ when Ast0.get_arg_exp e -> process do_nothing
+ | (Ast0.TestExprTag(_)::_)::_ when Ast0.get_test_pos e ->
+ process Ast0.set_test_exp
+ | _ -> ([],e)
+
+let transform_decl (metavars,alts,name) e =
+ match alts with
+ (Ast0.DeclTag(_)::_)::_ ->
+ (* start line is given to any leaves in the iso code *)
+ let start_line = Some (Ast0.get_info e).Ast0.line_start in
+ let alts =
+ List.map
+ (List.map
+ (function
+ Ast0.DeclTag(p) ->
+ (p,count_edots.V0.combiner_declaration p,
+ count_idots.V0.combiner_declaration p,
+ count_dots.V0.combiner_declaration p)
+ | _ -> failwith "invalid alt"))
+ alts in
+ mkdisj match_decl metavars alts e
+ (function b -> function mv_b ->
+ (instantiate b mv_b).V0.rebuilder_declaration)
+ (function d -> Ast0.DeclTag d)
+ make_disj_decl
+ make_minus.V0.rebuilder_declaration
+ (rebuild_mcode start_line).V0.rebuilder_declaration
+ name Unparse_ast0.declaration extra_copy_other_plus do_nothing
+ | _ -> ([],e)
+
+let transform_stmt (metavars,alts,name) e =
+ match alts with
+ (Ast0.StmtTag(_)::_)::_ ->
+ (* start line is given to any leaves in the iso code *)
+ let start_line = Some (Ast0.get_info e).Ast0.line_start in
+ let alts =
+ List.map
+ (List.map
+ (function
+ Ast0.StmtTag(p) ->
+ (p,count_edots.V0.combiner_statement p,
+ count_idots.V0.combiner_statement p,
+ count_dots.V0.combiner_statement p)
+ | _ -> failwith "invalid alt"))
+ alts in
+ mkdisj match_statement metavars alts e
+ (function b -> function mv_b ->
+ (instantiate b mv_b).V0.rebuilder_statement)
+ (function s -> Ast0.StmtTag s)
+ make_disj_stmt make_minus.V0.rebuilder_statement
+ (rebuild_mcode start_line).V0.rebuilder_statement
+ name (Unparse_ast0.statement "") extra_copy_stmt_plus do_nothing
+ | _ -> ([],e)
+
+(* sort of a hack, because there is no disj at top level *)
+let transform_top (metavars,alts,name) e =
+ match Ast0.unwrap e with
+ Ast0.DECL(declstm) ->
+ (try
+ let strip alts =
+ List.map
+ (List.map
+ (function
+ Ast0.DotsStmtTag(d) ->
+ (match Ast0.unwrap d with
+ Ast0.DOTS([s]) -> Ast0.StmtTag(s)
+ | _ -> raise (Failure ""))
+ | _ -> raise (Failure "")))
+ alts in
+ let (mv,s) = transform_stmt (metavars,strip alts,name) declstm in
+ (mv,Ast0.rewrap e (Ast0.DECL(s)))
+ with Failure _ -> ([],e))
+ | Ast0.CODE(stmts) ->
+ let (mv,res) =
+ match alts with
+ (Ast0.DotsStmtTag(_)::_)::_ ->
+ (* start line is given to any leaves in the iso code *)
+ let start_line = Some ((Ast0.get_info e).Ast0.line_start) in
+ let alts =
+ List.map
+ (List.map
+ (function
+ Ast0.DotsStmtTag(p) ->
+ (p,count_edots.V0.combiner_statement_dots p,
+ count_idots.V0.combiner_statement_dots p,
+ count_dots.V0.combiner_statement_dots p)
+ | _ -> failwith "invalid alt"))
+ alts in
+ mkdisj match_statement_dots metavars alts stmts
+ (function b -> function mv_b ->
+ (instantiate b mv_b).V0.rebuilder_statement_dots)
+ (function s -> Ast0.DotsStmtTag s)
+ (function x ->
+ Ast0.rewrap e (Ast0.DOTS([make_disj_stmt_list x])))
+ make_minus.V0.rebuilder_statement_dots
+ (rebuild_mcode start_line).V0.rebuilder_statement_dots
+ name Unparse_ast0.statement_dots extra_copy_other_plus do_nothing
+ | _ -> ([],stmts) in
+ (mv,Ast0.rewrap e (Ast0.CODE res))
+ | _ -> ([],e)
+
+(* --------------------------------------------------------------------- *)
+
+let transform (alts : isomorphism) t =
+ (* the following ugliness is because rebuilder only returns a new term *)
+ let extra_meta_decls = ref ([] : Ast_cocci.metavar list) in
+ let mcode x = x in
+ let donothing r k e = k e in
+ let exprfn r k e =
+ let (extra_meta,exp) = transform_expr alts (k e) in
+ extra_meta_decls := extra_meta @ !extra_meta_decls;
+ exp in
+
+ let declfn r k e =
+ let (extra_meta,dec) = transform_decl alts (k e) in
+ extra_meta_decls := extra_meta @ !extra_meta_decls;
+ dec in
+
+ let stmtfn r k e =
+ let (extra_meta,stm) = transform_stmt alts (k e) in
+ extra_meta_decls := extra_meta @ !extra_meta_decls;
+ stm in
+
+ let typefn r k e =
+ let (extra_meta,ty) = transform_type alts (k e) in
+ extra_meta_decls := extra_meta @ !extra_meta_decls;
+ ty in
+
+ let topfn r k e =
+ let (extra_meta,ty) = transform_top alts (k e) in
+ extra_meta_decls := extra_meta @ !extra_meta_decls;
+ ty in
+
+ let res =
+ V0.rebuilder
+ mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+ mcode
+ donothing donothing donothing donothing donothing donothing
+ donothing exprfn typefn donothing donothing declfn stmtfn
+ donothing topfn in
+ let res = res.V0.rebuilder_top_level t in
+ (!extra_meta_decls,res)
+
+(* --------------------------------------------------------------------- *)
+
+(* should be done by functorizing the parser to use wrap or context_wrap *)
+let rewrap =
+ let mcode (x,a,i,mc,pos) = (x,a,i,Ast0.context_befaft(),pos) in
+ let donothing r k e = Ast0.context_wrap(Ast0.unwrap(k e)) in
+ V0.rebuilder
+ mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+ mcode
+ donothing donothing donothing donothing donothing donothing
+ donothing donothing donothing donothing donothing donothing donothing
+ donothing donothing
+
+let rewrap_anything = function
+ Ast0.DotsExprTag(d) ->
+ Ast0.DotsExprTag(rewrap.V0.rebuilder_expression_dots d)
+ | Ast0.DotsInitTag(d) ->
+ Ast0.DotsInitTag(rewrap.V0.rebuilder_initialiser_list d)
+ | Ast0.DotsParamTag(d) ->
+ Ast0.DotsParamTag(rewrap.V0.rebuilder_parameter_list d)
+ | Ast0.DotsStmtTag(d) ->
+ Ast0.DotsStmtTag(rewrap.V0.rebuilder_statement_dots d)
+ | Ast0.DotsDeclTag(d) ->
+ Ast0.DotsDeclTag(rewrap.V0.rebuilder_declaration_dots d)
+ | Ast0.DotsCaseTag(d) ->
+ Ast0.DotsCaseTag(rewrap.V0.rebuilder_case_line_dots d)
+ | Ast0.IdentTag(d) -> Ast0.IdentTag(rewrap.V0.rebuilder_ident d)
+ | Ast0.ExprTag(d) -> Ast0.ExprTag(rewrap.V0.rebuilder_expression d)
+ | Ast0.ArgExprTag(d) -> Ast0.ArgExprTag(rewrap.V0.rebuilder_expression d)
+ | Ast0.TestExprTag(d) -> Ast0.TestExprTag(rewrap.V0.rebuilder_expression d)
+ | Ast0.TypeCTag(d) -> Ast0.TypeCTag(rewrap.V0.rebuilder_typeC d)
+ | Ast0.InitTag(d) -> Ast0.InitTag(rewrap.V0.rebuilder_initialiser d)
+ | Ast0.ParamTag(d) -> Ast0.ParamTag(rewrap.V0.rebuilder_parameter d)
+ | Ast0.DeclTag(d) -> Ast0.DeclTag(rewrap.V0.rebuilder_declaration d)
+ | Ast0.StmtTag(d) -> Ast0.StmtTag(rewrap.V0.rebuilder_statement d)
+ | Ast0.CaseLineTag(d) -> Ast0.CaseLineTag(rewrap.V0.rebuilder_case_line d)
+ | Ast0.TopTag(d) -> Ast0.TopTag(rewrap.V0.rebuilder_top_level d)
+ | Ast0.IsoWhenTag(_) | Ast0.IsoWhenTTag(_) | Ast0.IsoWhenFTag(_) ->
+ failwith "only for isos within iso phase"
+ | Ast0.MetaPosTag(p) -> Ast0.MetaPosTag(p)
+
+(* --------------------------------------------------------------------- *)
+
+let apply_isos isos rule rule_name =
+ if isos = []
+ then ([],rule)
+ else
+ begin
+ current_rule := rule_name;
+ let isos =
+ List.map
+ (function (metavars,iso,name) ->
+ (metavars,List.map (List.map rewrap_anything) iso,name))
+ isos in
+ let (extra_meta,rule) =
+ List.split
+ (List.map
+ (function t ->
+ List.fold_left
+ (function (extra_meta,t) -> function iso ->
+ let (new_extra_meta,t) = transform iso t in
+ (new_extra_meta@extra_meta,t))
+ ([],t) isos)
+ rule) in
+ (List.concat extra_meta, Compute_lines.compute_lines rule)
+ end
--- /dev/null
+/*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+*
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+*
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
+*
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*/
+
+
+%{
+
+(* Not clear how to allow function declarations to specify a return type
+and how to allow both to be specified as static, because they are in
+different rules. The rules seem to have to be combined, which would allow
+functions to be declared as local variables *)
+
+(* Not clear how to let a function have a parameter of type void. At the
+moment, void is allowed to be the type of a variable, which is wrong, and a
+parameter needs both a type and an identifier *)
+module Ast0 = Ast0_cocci
+module Ast = Ast_cocci
+module P = Parse_aux
+%}
+
+%token EOF
+
+%token TIdentifier TExpression TStatement TFunction TLocal TType TParameter
+%token TIdExpression
+%token Tlist TFresh TConstant TError TWords TWhy0 TPlus0 TBang0
+%token TPure TContext
+%token TTypedef TDeclarer TIterator TName TPosition TPosAny
+%token TUsing TDisable TExtends TDepends TOn TEver TNever TExists TForall TScript
+%token TReverse TNothing
+%token<string> TRuleName
+
+%token<Data.clt> Tchar Tshort Tint Tdouble Tfloat Tlong
+%token<Data.clt> Tvoid Tstruct Tunion
+%token<Data.clt> Tunsigned Tsigned
+
+%token<Data.clt> Tstatic Tauto Tregister Textern Tinline Ttypedef
+%token<Data.clt> Tconst Tvolatile
+%token<string * Data.clt> Tattr
+
+%token <Data.clt> TIf TElse TWhile TFor TDo TSwitch TCase TDefault TReturn
+%token <Data.clt> TBreak TContinue TGoto TSizeof TFunDecl
+%token <string * Data.clt> TIdent TTypeId TDeclarerId TIteratorId
+
+%token <Parse_aux.idinfo> TMetaId TMetaFunc TMetaLocalFunc
+%token <Parse_aux.idinfo> TMetaIterator TMetaDeclarer
+%token <Parse_aux.expinfo> TMetaErr
+%token <Parse_aux.info> TMetaParam TMetaStm TMetaStmList TMetaType
+%token <Parse_aux.list_info> TMetaParamList TMetaExpList
+%token <Parse_aux.typed_info> TMetaExp TMetaIdExp TMetaLocalIdExp TMetaConst
+%token <Parse_aux.pos_info> TMetaPos
+
+%token TArob TArobArob TPArob
+%token <string> TScriptData
+
+%token <Data.clt> TEllipsis TOEllipsis TCEllipsis TPOEllipsis TPCEllipsis
+%token <Data.clt> TWhen TWhenTrue TWhenFalse TAny TStrict TLineEnd
+
+%token <Data.clt> TWhy TDotDot TBang TOPar TOPar0
+%token <Data.clt> TMid0 TCPar TCPar0
+
+%token <string> TPragma TPathIsoFile
+%token <string * Data.clt> TIncludeL TIncludeNL
+%token <Data.clt * token> TDefine
+%token <Data.clt * token * int> TDefineParam
+%token <string * Data.clt> TMinusFile TPlusFile
+
+%token <Data.clt> TInc TDec
+
+%token <string * Data.clt> TString TChar TFloat TInt
+
+%token <Data.clt> TOrLog
+%token <Data.clt> TAndLog
+%token <Data.clt> TOr
+%token <Data.clt> TXor
+%token <Data.clt> TAnd
+%token <Data.clt> TEqEq TNotEq
+%token <Ast_cocci.logicalOp * Data.clt> TLogOp /* TInf TSup TInfEq TSupEq */
+%token <Ast_cocci.arithOp * Data.clt> TShOp /* TShl TShr */
+%token <Ast_cocci.arithOp * Data.clt> TDmOp /* TDiv TMod */
+%token <Data.clt> TPlus TMinus
+%token <Data.clt> TMul TTilde
+
+%token <Data.clt> TOBrace TCBrace TOInit
+%token <Data.clt> TOCro TCCro
+
+%token <Data.clt> TPtrOp
+
+%token TMPtVirg
+%token <Data.clt> TEq TDot TComma TPtVirg
+%token <Ast_cocci.assignOp * Data.clt> TAssign
+
+%token TIso TRightIso TIsoExpression TIsoStatement TIsoDeclaration TIsoType
+%token TIsoTopLevel TIsoArgExpression TIsoTestExpression
+
+%token TInvalid
+
+/* operator precedence */
+%nonassoc TIf
+%nonassoc TElse
+
+%left TOrLog
+%left TAndLog
+%left TOr
+%left TXor
+%left TAnd
+%left TEqEq TNotEq
+%left TLogOp /* TInf TSup TInfEq TSupEq */
+%left TShOp /* TShl TShr */
+%left TPlus TMinus
+%left TMul TDmOp /* TDiv TMod */
+
+%start reinit
+%type <unit> reinit
+
+%start minus_main
+%type <Ast0_cocci.rule> minus_main
+
+%start minus_exp_main
+%type <Ast0_cocci.rule> minus_exp_main
+
+%start plus_main
+%type <Ast0_cocci.rule> plus_main
+
+%start plus_exp_main
+%type <Ast0_cocci.rule> plus_exp_main
+
+%start include_main
+%type <(string,string) Common.either list> include_main
+
+%start iso_rule_name
+%type <Ast_cocci.rulename>
+iso_rule_name
+
+%start rule_name
+%type <Ast_cocci.rulename>
+rule_name
+
+%start meta_main
+%type <(Ast_cocci.metavar,Ast_cocci.metavar) Common.either list> meta_main
+
+%start <string * (string * string)> script_meta_main
+
+%start iso_main
+%type <Ast0_cocci.anything list list> iso_main
+
+%start iso_meta_main
+%type <(Ast_cocci.metavar,Ast_cocci.metavar) Common.either list> iso_meta_main
+
+%start never_used
+%type <unit> never_used
+
+%%
+
+reinit: { }
+minus_main: minus_body EOF { $1 } | m=minus_body TArobArob { m }
+| m=minus_body TArob { m }
+plus_main: plus_body EOF { $1 } | p=plus_body TArobArob { p }
+| p=plus_body TArob { p }
+minus_exp_main: minus_exp_body EOF { $1 } | m=minus_exp_body TArobArob { m }
+| m=minus_exp_body TArob { m }
+plus_exp_main: plus_exp_body EOF { $1 } | p=plus_exp_body TArobArob { p }
+| p=plus_exp_body TArob { p }
+meta_main: m=metadec { m (!Ast0.rule_name) }
+iso_meta_main: m=metadec { m "" }
+
+/*****************************************************************************
+*
+*
+*****************************************************************************/
+
+pure:
+ TPure { Ast0.Pure }
+| TContext { Ast0.Context }
+| TPure TContext { Ast0.PureContext }
+| TContext TPure { Ast0.PureContext }
+| /* empty */ { Ast0.Impure }
+
+iso_rule_name:
+ nm=pure_ident TArob { P.make_iso_rule_name_result (P.id2name nm) }
+
+rule_name:
+ nm=ioption(pure_ident) extends d=depends i=loption(choose_iso)
+ a=loption(disable) e=exists ee=is_expression TArob
+ { P.make_cocci_rule_name_result nm d i a e ee }
+ | TScript TDotDot lang=pure_ident d=depends TArob
+ { P.make_script_rule_name_result lang d }
+
+extends:
+ /* empty */ { () }
+| TExtends parent=TRuleName
+ { !Data.install_bindings (parent) }
+
+depends:
+ /* empty */ { Ast.NoDep }
+| TDepends TOn parents=dep { parents }
+
+dep:
+ pnrule { $1 }
+| dep TAndLog dep { Ast.AndDep($1, $3) }
+| dep TOrLog dep { Ast.OrDep ($1, $3) }
+
+pnrule:
+ TRuleName { Ast.Dep $1 }
+| TBang TRuleName { Ast.AntiDep $2 }
+| TEver TRuleName { Ast.EverDep $2 }
+| TNever TRuleName { Ast.NeverDep $2 }
+| TOPar dep TCPar { $2 }
+
+choose_iso:
+ TUsing separated_nonempty_list(TComma,TString) { List.map P.id2name $2 }
+
+disable:
+ TDisable separated_nonempty_list(TComma,pure_ident) { List.map P.id2name $2 }
+
+exists:
+ TExists { Ast.Exists }
+| TForall { Ast.Forall }
+| TReverse TForall { Ast.ReverseForall }
+| { Ast.Undetermined }
+
+is_expression: // for more flexible parsing of top level expressions
+ { false }
+| TExpression { true }
+
+include_main:
+ list(incl) TArob { $1 }
+| list(incl) TArobArob { $1 }
+
+incl:
+ TUsing TString { Common.Left(P.id2name $2) }
+| TUsing TPathIsoFile { Common.Right $2 }
+
+metadec:
+ ar=arity ispure=pure
+ kindfn=metakind ids=comma_list(pure_ident_or_meta_ident) TMPtVirg
+ { P.create_metadec ar ispure kindfn ids }
+| ar=arity ispure=pure
+ kindfn=metakind_atomic
+ ids=comma_list(pure_ident_or_meta_ident_with_not_eq(not_eq)) TMPtVirg
+ { P.create_metadec_ne ar ispure kindfn ids }
+| ar=arity ispure=pure
+ kindfn=metakind_atomic_expi
+ ids=comma_list(pure_ident_or_meta_ident_with_not_eq(not_eqe)) TMPtVirg
+ { P.create_metadec_ne ar ispure kindfn ids }
+| ar=arity ispure=pure
+ kindfn=metakind_atomic_expe
+ ids=comma_list(pure_ident_or_meta_ident_with_not_eq(not_ceq)) TMPtVirg
+ { P.create_metadec_ne ar ispure kindfn ids }
+| ar=arity TPosition a=option(TPosAny)
+ ids=comma_list(pure_ident_or_meta_ident_with_not_eq(not_pos)) TMPtVirg
+ { let kindfn arity name pure check_meta constraints =
+ let tok = check_meta(Ast.MetaPosDecl(arity,name)) in
+ let any = match a with None -> Ast.PER | Some _ -> Ast.ALL in
+ !Data.add_pos_meta name constraints any; tok in
+ P.create_metadec_ne ar false kindfn ids }
+| ar=arity ispure=pure
+ TParameter Tlist TOCro id=pure_ident_or_meta_ident TCCro
+ ids=comma_list(pure_ident_or_meta_ident) TMPtVirg
+ { P.create_len_metadec ar ispure
+ (fun lenname arity name pure check_meta ->
+ let tok =
+ check_meta(Ast.MetaParamListDecl(arity,name,Some lenname)) in
+ !Data.add_paramlist_meta name (Some lenname) pure; tok)
+ id ids }
+| ar=arity ispure=pure
+ TExpression Tlist TOCro id=pure_ident_or_meta_ident TCCro
+ ids=comma_list(pure_ident_or_meta_ident) TMPtVirg
+ { P.create_len_metadec ar ispure
+ (fun lenname arity name pure check_meta ->
+ let tok =
+ check_meta(Ast.MetaExpListDecl(arity,name,Some lenname)) in
+ !Data.add_explist_meta name (Some lenname) pure; tok)
+ id ids }
+
+%inline metakind:
+ TFresh TIdentifier
+ { (fun arity name pure check_meta ->
+ let tok = check_meta(Ast.MetaFreshIdDecl(arity,name)) in
+ !Data.add_id_meta name [] pure; tok) }
+| TParameter
+ { (fun arity name pure check_meta ->
+ let tok = check_meta(Ast.MetaParamDecl(arity,name)) in
+ !Data.add_param_meta name pure; tok) }
+| TParameter Tlist
+ { (fun arity name pure check_meta ->
+ let tok = check_meta(Ast.MetaParamListDecl(arity,name,None)) in
+ !Data.add_paramlist_meta name None pure; tok) }
+| TExpression Tlist
+ { (fun arity name pure check_meta ->
+ let tok = check_meta(Ast.MetaExpListDecl(arity,name,None)) in
+ !Data.add_explist_meta name None pure; tok) }
+| TType
+ { (fun arity name pure check_meta ->
+ let tok = check_meta(Ast.MetaTypeDecl(arity,name)) in
+ !Data.add_type_meta name pure; tok) }
+| TStatement
+ { (fun arity name pure check_meta ->
+ let tok = check_meta(Ast.MetaStmDecl(arity,name)) in
+ !Data.add_stm_meta name pure; tok) }
+| TStatement Tlist
+ { (fun arity name pure check_meta ->
+ let tok = check_meta(Ast.MetaStmListDecl(arity,name)) in
+ !Data.add_stmlist_meta name pure; tok) }
+| TTypedef
+ { (fun arity (_,name) pure check_meta ->
+ if arity = Ast.NONE && pure = Ast0.Impure
+ then (!Data.add_type_name name; [])
+ else raise (Semantic_cocci.Semantic "bad typedef")) }
+| TDeclarer TName
+ { (fun arity (_,name) pure check_meta ->
+ if arity = Ast.NONE && pure = Ast0.Impure
+ then (!Data.add_declarer_name name; [])
+ else raise (Semantic_cocci.Semantic "bad declarer")) }
+| TIterator TName
+ { (fun arity (_,name) pure check_meta ->
+ if arity = Ast.NONE && pure = Ast0.Impure
+ then (!Data.add_iterator_name name; [])
+ else raise (Semantic_cocci.Semantic "bad iterator")) }
+
+
+%inline metakind_atomic:
+ TIdentifier
+ { (fun arity name pure check_meta constraints ->
+ let tok = check_meta(Ast.MetaIdDecl(arity,name)) in
+ !Data.add_id_meta name constraints pure; tok) }
+| TFunction
+ { (fun arity name pure check_meta constraints ->
+ let tok = check_meta(Ast.MetaFuncDecl(arity,name)) in
+ !Data.add_func_meta name constraints pure; tok) }
+| TLocal TFunction
+ { (fun arity name pure check_meta constraints ->
+ let tok = check_meta(Ast.MetaLocalFuncDecl(arity,name)) in
+ !Data.add_local_func_meta name constraints pure;
+ tok) }
+| TDeclarer
+ { (fun arity name pure check_meta constraints ->
+ let tok = check_meta(Ast.MetaDeclarerDecl(arity,name)) in
+ !Data.add_declarer_meta name constraints pure; tok) }
+| TIterator
+ { (fun arity name pure check_meta constraints ->
+ let tok = check_meta(Ast.MetaIteratorDecl(arity,name)) in
+ !Data.add_iterator_meta name constraints pure; tok) }
+
+%inline metakind_atomic_expi:
+ TError
+ { (fun arity name pure check_meta constraints ->
+ let tok = check_meta(Ast.MetaErrDecl(arity,name)) in
+ !Data.add_err_meta name constraints pure; tok) }
+| l=option(TLocal) TIdExpression ty=ioption(meta_exp_type)
+ { (fun arity name pure check_meta constraints ->
+ match l with
+ None ->
+ !Data.add_idexp_meta ty name constraints pure;
+ check_meta(Ast.MetaIdExpDecl(arity,name,ty))
+ | Some _ ->
+ !Data.add_local_idexp_meta ty name constraints pure;
+ check_meta(Ast.MetaLocalIdExpDecl(arity,name,ty))) }
+| l=option(TLocal) TIdExpression m=nonempty_list(TMul)
+ { (fun arity name pure check_meta constraints ->
+ let ty = Some [P.ty_pointerify Type_cocci.Unknown m] in
+ match l with
+ None ->
+ !Data.add_idexp_meta ty name constraints pure;
+ check_meta(Ast.MetaIdExpDecl(arity,name,ty))
+ | Some _ ->
+ !Data.add_local_idexp_meta ty name constraints pure;
+ check_meta(Ast.MetaLocalIdExpDecl(arity,name,ty))) }
+| TExpression m=nonempty_list(TMul)
+ { (fun arity name pure check_meta constraints ->
+ let ty = Some [P.ty_pointerify Type_cocci.Unknown m] in
+ let tok = check_meta(Ast.MetaExpDecl(arity,name,ty)) in
+ !Data.add_exp_meta ty name constraints pure; tok) }
+| vl=meta_exp_type TOCro TCCro
+ { (fun arity name pure check_meta constraints ->
+ let ty = Some (List.map (function x -> Type_cocci.Array x) vl) in
+ let tok = check_meta(Ast.MetaExpDecl(arity,name,ty)) in
+ !Data.add_exp_meta ty name constraints pure; tok) }
+| TConstant ty=ioption(meta_exp_type)
+ { (fun arity name pure check_meta constraints ->
+ let tok = check_meta(Ast.MetaConstDecl(arity,name,ty)) in
+ !Data.add_const_meta ty name constraints pure; tok) }
+
+%inline metakind_atomic_expe:
+ TExpression
+ { (fun arity name pure check_meta constraints ->
+ let tok = check_meta(Ast.MetaExpDecl(arity,name,None)) in
+ !Data.add_exp_meta None name constraints pure; tok) }
+| vl=meta_exp_type // no error if use $1 but doesn't type check
+ { (fun arity name pure check_meta constraints ->
+ let ty = Some vl in
+ List.iter
+ (function c ->
+ match Ast0.unwrap c with
+ Ast0.Constant(_) ->
+ if not
+ (List.exists
+ (function
+ Type_cocci.BaseType(Type_cocci.IntType,_) -> true
+ | Type_cocci.BaseType(Type_cocci.ShortType,_) -> true
+ | Type_cocci.BaseType(Type_cocci.LongType,_) -> true
+ | _ -> false)
+ vl)
+ then failwith "metavariable with int constraint must be an int"
+ | _ -> ())
+ constraints;
+ let tok = check_meta(Ast.MetaExpDecl(arity,name,ty)) in
+ !Data.add_exp_meta ty name constraints pure; tok) }
+
+
+meta_exp_type:
+ t=ctype
+ { [Ast0_cocci.ast0_type_to_type t] }
+| TOBrace t=comma_list(ctype) TCBrace m=list(TMul)
+ { List.map
+ (function x -> P.ty_pointerify (Ast0_cocci.ast0_type_to_type x) m)
+ t }
+
+arity: TBang0 { Ast.UNIQUE }
+ | TWhy0 { Ast.OPT }
+ | TPlus0 { Ast.MULTI }
+ | /* empty */ { Ast.NONE }
+
+generic_ctype:
+ q=ctype_qualif
+ { Ast0.wrap(Ast0.ImplicitInt(q)) }
+ | q=ioption(ctype_qualif) ty=Tchar
+ { Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.CharType ty, q)) }
+ | q=ioption(ctype_qualif) ty=Tshort
+ { Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.ShortType ty, q)) }
+ | q=ioption(ctype_qualif) ty=Tint
+ { Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.IntType ty, q)) }
+ | t=Tdouble
+ { Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.DoubleType t, None)) }
+ | t=Tfloat
+ { Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.FloatType t, None)) }
+ | q=ioption(ctype_qualif) ty=Tlong
+ { Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.LongType ty, q)) }
+ | s=struct_or_union i=ident
+ { Ast0.wrap(Ast0.StructUnionName(s, Some i)) }
+ | s=struct_or_union i=ioption(ident)
+ l=TOBrace d=struct_decl_list r=TCBrace
+ { (if i = None && !Data.in_iso
+ then failwith "structures must be named in the iso file");
+ Ast0.wrap(Ast0.StructUnionDef(Ast0.wrap(Ast0.StructUnionName(s, i)),
+ P.clt2mcode "{" l,
+ d, P.clt2mcode "}" r)) }
+ | s=TMetaType l=TOBrace d=struct_decl_list r=TCBrace
+ { let (nm,pure,clt) = s in
+ let ty =
+ Ast0.wrap(Ast0.MetaType(P.clt2mcode nm clt,pure)) in
+ Ast0.wrap
+ (Ast0.StructUnionDef(ty,P.clt2mcode "{" l,d,P.clt2mcode "}" r)) }
+ | r=TRuleName TDot p=TIdent
+ { let nm = (r,P.id2name p) in
+ (* this is only possible when we are in a metavar decl. Otherwise,
+ it will be represented already as a MetaType *)
+ let _ = P.check_meta(Ast.MetaTypeDecl(Ast.NONE,nm)) in
+ Ast0.wrap(Ast0.MetaType(P.clt2mcode nm (P.id2clt p),
+ Ast0.Impure (*will be ignored*))) }
+ | p=TTypeId
+ { Ast0.wrap(Ast0.TypeName(P.id2mcode p)) }
+ | p=TMetaType
+ { let (nm,pure,clt) = p in
+ Ast0.wrap(Ast0.MetaType(P.clt2mcode nm clt,pure)) }
+
+struct_or_union:
+ s=Tstruct { P.clt2mcode Ast.Struct s }
+ | u=Tunion { P.clt2mcode Ast.Union u }
+
+struct_decl:
+ TNothing { [] }
+ | t=ctype d=d_ident pv=TPtVirg
+ { let (id,fn) = d in
+ [Ast0.wrap(Ast0.UnInit(None,fn t,id,P.clt2mcode ";" pv))] }
+ | t=fn_ctype lp1=TOPar st=TMul d=d_ident rp1=TCPar
+ lp2=TOPar p=decl_list(name_opt_decl) rp2=TCPar pv=TPtVirg
+ { let (id,fn) = d in
+ let t =
+ Ast0.wrap
+ (Ast0.FunctionPointer
+ (t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
+ P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
+ [Ast0.wrap(Ast0.UnInit(None,fn t,id,P.clt2mcode ";" pv))] }
+ | cv=ioption(const_vol) i=pure_ident d=d_ident pv=TPtVirg
+ { let (id,fn) = d in
+ let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
+ [Ast0.wrap(Ast0.UnInit(None,fn idtype,id,P.clt2mcode ";" pv))] }
+
+struct_decl_list:
+ struct_decl_list_start { Ast0.wrap(Ast0.DOTS($1)) }
+
+struct_decl_list_start:
+ struct_decl { $1 }
+| struct_decl struct_decl_list_start { $1@$2 }
+| d=edots_when(TEllipsis,struct_decl) r=continue_struct_decl_list
+ { (P.mkddots "..." d)::r }
+
+continue_struct_decl_list:
+ /* empty */ { [] }
+| struct_decl struct_decl_list_start { $1@$2 }
+| struct_decl { $1 }
+
+ctype:
+ cv=ioption(const_vol) ty=generic_ctype m=list(TMul)
+ { P.pointerify (P.make_cv cv ty) m }
+ | cv=ioption(const_vol) t=Tvoid m=nonempty_list(TMul)
+ { let ty =
+ Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.VoidType t, None)) in
+ P.pointerify (P.make_cv cv ty) m }
+ | lp=TOPar0 t=midzero_list(ctype,ctype) rp=TCPar0
+ /* more hacks */
+ { let (mids,code) = t in
+ Ast0.wrap
+ (Ast0.DisjType(P.clt2mcode "(" lp,code,mids, P.clt2mcode ")" rp)) }
+
+
+fn_ctype: // allows metavariables
+ ty=generic_ctype m=list(TMul) { P.pointerify ty m }
+ | t=Tvoid m=list(TMul)
+ { P.pointerify
+ (Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.VoidType t, None)))
+ m }
+
+ctype_qualif:
+ Tunsigned { P.clt2mcode Ast.Unsigned $1 }
+ | Tsigned { P.clt2mcode Ast.Signed $1 }
+
+/*****************************************************************************/
+
+/* have to inline everything to avoid conflicts? switch to proper
+declarations, statements, and expressions for the subterms */
+
+minus_body:
+ f=loption(filespec)
+ b=loption(minus_start)
+ ew=loption(error_words)
+ { match f@b@ew with
+ [] -> raise (Semantic_cocci.Semantic "minus slice can't be empty")
+ | code -> Top_level.top_level code }
+
+plus_body:
+ f=loption(filespec)
+ b=loption(plus_start)
+ ew=loption(error_words)
+ { Top_level.top_level (f@b@ew) }
+
+minus_exp_body:
+ f=loption(filespec)
+ b=top_eexpr
+ ew=loption(error_words)
+ { match f@[b]@ew with
+ [] -> raise (Semantic_cocci.Semantic "minus slice can't be empty")
+ | code -> Top_level.top_level code }
+
+plus_exp_body:
+ f=loption(filespec)
+ b=top_eexpr
+ ew=loption(error_words)
+ { Top_level.top_level (f@[b]@ew) }
+
+filespec:
+ TMinusFile TPlusFile
+ { [Ast0.wrap
+ (Ast0.FILEINFO(P.id2mcode $1,
+ P.id2mcode $2))] }
+
+includes:
+ TIncludeL
+ { Ast0.wrap
+ (Ast0.Include(P.clt2mcode "#include" (P.drop_aft (P.id2clt $1)),
+ let (arity,ln,lln,offset,col,strbef,straft,pos) =
+ P.id2clt $1 in
+ let clt =
+ (arity,ln,lln,offset,0,strbef,straft,pos) in
+ P.clt2mcode
+ (Ast.Local (Parse_aux.str2inc (P.id2name $1)))
+ (P.drop_bef clt))) }
+| TIncludeNL
+ { Ast0.wrap
+ (Ast0.Include(P.clt2mcode "#include" (P.drop_aft (P.id2clt $1)),
+ let (arity,ln,lln,offset,col,strbef,straft,pos) =
+ P.id2clt $1 in
+ let clt =
+ (arity,ln,lln,offset,0,strbef,straft,pos) in
+ P.clt2mcode
+ (Ast.NonLocal (Parse_aux.str2inc (P.id2name $1)))
+ (P.drop_bef clt))) }
+| d=defineop t=ctype TLineEnd
+ { let ty = Ast0.wrap(Ast0.TopExp(Ast0.wrap(Ast0.TypeExp(t)))) in
+ d (Ast0.wrap(Ast0.DOTS([ty]))) }
+| defineop b=toplevel_seq_start(toplevel_after_dots) TLineEnd
+ { let body =
+ match b with
+ [e] ->
+ (match Ast0.unwrap e with
+ Ast0.Exp(e1) ->
+ [Ast0.rewrap e (Ast0.TopExp(Ast0.set_arg_exp (e1)))]
+ | _ -> b)
+ | _ -> b in
+ $1 (Ast0.wrap(Ast0.DOTS(body))) }
+
+defineop:
+ TDefine
+ { let (clt,ident) = $1 in
+ function body ->
+ Ast0.wrap
+ (Ast0.Define
+ (P.clt2mcode "#define" clt,
+ (match ident with
+ TMetaId((nm,constraints,pure,clt)) ->
+ Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure))
+ | TIdent(nm_pure) ->
+ Ast0.wrap(Ast0.Id(P.id2mcode nm_pure))
+ | _ ->
+ raise
+ (Semantic_cocci.Semantic
+ "unexpected name for a #define")),
+ Ast0.wrap Ast0.NoParams,
+ body)) }
+| TDefineParam define_param_list_option TCPar
+ { let (clt,ident,parenoff) = $1 in
+ let (arity,line,lline,offset,col,strbef,straft,pos) = clt in
+ let lp =
+ P.clt2mcode "(" (arity,line,lline,parenoff,0,[],[],Ast0.NoMetaPos) in
+ function body ->
+ Ast0.wrap
+ (Ast0.Define
+ (P.clt2mcode "#define" clt,
+ (match ident with
+ TMetaId((nm,constraints,pure,clt)) ->
+ Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure))
+ | TIdent(nm_pure) ->
+ Ast0.wrap(Ast0.Id(P.id2mcode nm_pure))
+ | _ ->
+ raise
+ (Semantic_cocci.Semantic
+ "unexpected name for a #define")),
+ Ast0.wrap (Ast0.DParams (lp,$2,P.clt2mcode ")" $3)),body)) }
+
+/* ---------------------------------------------------------------------- */
+
+define_param_list: define_param_list_start
+ {let circle x =
+ match Ast0.unwrap x with Ast0.DPcircles(_) -> true | _ -> false in
+ if List.exists circle $1
+ then Ast0.wrap(Ast0.CIRCLES($1))
+ else Ast0.wrap(Ast0.DOTS($1)) }
+
+define_param_list_start:
+ ident { [Ast0.wrap(Ast0.DParam $1)] }
+ | ident TComma define_param_list_start
+ { Ast0.wrap(Ast0.DParam $1)::
+ Ast0.wrap(Ast0.DPComma(P.clt2mcode "," $2))::$3 }
+ | d=TEllipsis r=list(dp_comma_args(TEllipsis))
+ { (P.mkdpdots "..." d)::
+ (List.concat (List.map (function x -> x (P.mkdpdots "...")) r)) }
+
+dp_comma_args(dotter):
+ c=TComma d=dotter
+ { function dot_builder ->
+ [Ast0.wrap(Ast0.DPComma(P.clt2mcode "," c)); dot_builder d] }
+| TComma ident
+ { function dot_builder ->
+ [Ast0.wrap(Ast0.DPComma(P.clt2mcode "," $1));
+ Ast0.wrap(Ast0.DParam $2)] }
+
+define_param_list_option: define_param_list { $1 }
+ | /* empty */ { Ast0.wrap(Ast0.DOTS([])) }
+
+/*****************************************************************************/
+
+funproto:
+ s=ioption(storage) t=ctype
+ id=func_ident lp=TOPar d=decl_list(name_opt_decl) rp=TCPar pt=TPtVirg
+ { Ast0.wrap
+ (Ast0.UnInit
+ (s,
+ Ast0.wrap
+ (Ast0.FunctionType(Some t,
+ P.clt2mcode "(" lp, d, P.clt2mcode ")" rp)),
+ id, P.clt2mcode ";" pt)) }
+| s=ioption(storage) t=Tvoid
+ id=func_ident lp=TOPar d=decl_list(name_opt_decl) rp=TCPar pt=TPtVirg
+ { let t = Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.VoidType t, None)) in
+ Ast0.wrap
+ (Ast0.UnInit
+ (s,
+ Ast0.wrap
+ (Ast0.FunctionType(Some t,
+ P.clt2mcode "(" lp, d, P.clt2mcode ")" rp)),
+ id, P.clt2mcode ";" pt)) }
+
+
+fundecl:
+ f=fninfo
+ TFunDecl i=func_ident lp=TOPar d=decl_list(decl) rp=TCPar
+ lb=TOBrace b=fun_start rb=TCBrace
+ { Ast0.wrap(Ast0.FunDecl((Ast0.default_info(),Ast0.context_befaft()),
+ f, i,
+ P.clt2mcode "(" lp, d,
+ P.clt2mcode ")" rp,
+ P.clt2mcode "{" lb, b,
+ P.clt2mcode "}" rb)) }
+
+fninfo:
+ /* empty */ { [] }
+ | storage fninfo
+ { try
+ let _ =
+ List.find (function Ast0.FStorage(_) -> true | _ -> false) $2 in
+ raise (Semantic_cocci.Semantic "duplicate storage")
+ with Not_found -> (Ast0.FStorage($1))::$2 }
+ | t=fn_ctype r=fninfo_nt { (Ast0.FType(t))::r }
+ | Tinline fninfo
+ { try
+ let _ = List.find (function Ast0.FInline(_) -> true | _ -> false) $2 in
+ raise (Semantic_cocci.Semantic "duplicate inline")
+ with Not_found -> (Ast0.FInline(P.clt2mcode "inline" $1))::$2 }
+ | Tattr fninfo
+ { try
+ let _ = List.find (function Ast0.FAttr(_) -> true | _ -> false) $2 in
+ raise (Semantic_cocci.Semantic "multiple attributes")
+ with Not_found -> (Ast0.FAttr(P.id2mcode $1))::$2 }
+
+fninfo_nt:
+ /* empty */ { [] }
+ | storage fninfo_nt
+ { try
+ let _ =
+ List.find (function Ast0.FStorage(_) -> true | _ -> false) $2 in
+ raise (Semantic_cocci.Semantic "duplicate storage")
+ with Not_found -> (Ast0.FStorage($1))::$2 }
+ | Tinline fninfo_nt
+ { try
+ let _ = List.find (function Ast0.FInline(_) -> true | _ -> false) $2 in
+ raise (Semantic_cocci.Semantic "duplicate inline")
+ with Not_found -> (Ast0.FInline(P.clt2mcode "inline" $1))::$2 }
+ | Tattr fninfo_nt
+ { try
+ let _ = List.find (function Ast0.FAttr(_) -> true | _ -> false) $2 in
+ raise (Semantic_cocci.Semantic "duplicate init")
+ with Not_found -> (Ast0.FAttr(P.id2mcode $1))::$2 }
+
+storage:
+ s=Tstatic { P.clt2mcode Ast.Static s }
+ | s=Tauto { P.clt2mcode Ast.Auto s }
+ | s=Tregister { P.clt2mcode Ast.Register s }
+ | s=Textern { P.clt2mcode Ast.Extern s }
+
+decl: t=ctype i=ident
+ { Ast0.wrap(Ast0.Param(t, Some i)) }
+ | t=fn_ctype lp=TOPar s=TMul i=ident rp=TCPar
+ lp1=TOPar d=decl_list(name_opt_decl) rp1=TCPar
+ { let fnptr =
+ Ast0.wrap
+ (Ast0.FunctionPointer
+ (t,P.clt2mcode "(" lp,P.clt2mcode "*" s,P.clt2mcode ")" rp,
+ P.clt2mcode "(" lp1,d,P.clt2mcode ")" rp1)) in
+ Ast0.wrap(Ast0.Param(fnptr, Some i)) }
+ | t=Tvoid
+ { let ty = Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.VoidType t, None)) in
+ Ast0.wrap(Ast0.VoidParam(ty)) }
+ | TMetaParam
+ { let (nm,pure,clt) = $1 in
+ Ast0.wrap(Ast0.MetaParam(P.clt2mcode nm clt,pure)) }
+
+name_opt_decl:
+ decl { $1 }
+ | t=ctype { Ast0.wrap(Ast0.Param(t, None)) }
+ | t=fn_ctype lp=TOPar s=TMul rp=TCPar
+ lp1=TOPar d=decl_list(name_opt_decl) rp1=TCPar
+ { let fnptr =
+ Ast0.wrap
+ (Ast0.FunctionPointer
+ (t,P.clt2mcode "(" lp,P.clt2mcode "*" s,P.clt2mcode ")" rp,
+ P.clt2mcode "(" lp1,d,P.clt2mcode ")" rp1)) in
+ Ast0.wrap(Ast0.Param(fnptr, None)) }
+
+const_vol:
+ Tconst { P.clt2mcode Ast.Const $1 }
+ | Tvolatile { P.clt2mcode Ast.Volatile $1 }
+
+/*****************************************************************************/
+
+statement:
+ includes { $1 } /* shouldn't be allowed to be a single_statement... */
+| TMetaStm
+ { P.meta_stm $1 }
+| expr TPtVirg
+ { P.exp_stm $1 $2 }
+| TIf TOPar eexpr TCPar single_statement %prec TIf
+ { P.ifthen $1 $2 $3 $4 $5 }
+| TIf TOPar eexpr TCPar single_statement TElse single_statement
+ { P.ifthenelse $1 $2 $3 $4 $5 $6 $7 }
+| TFor TOPar option(eexpr) TPtVirg option(eexpr) TPtVirg
+ option(eexpr) TCPar single_statement
+ { P.forloop $1 $2 $3 $4 $5 $6 $7 $8 $9 }
+| TWhile TOPar eexpr TCPar single_statement
+ { P.whileloop $1 $2 $3 $4 $5 }
+| TDo single_statement TWhile TOPar eexpr TCPar TPtVirg
+ { P.doloop $1 $2 $3 $4 $5 $6 $7 }
+| iter_ident TOPar eexpr_list_option TCPar single_statement
+ { P.iterator $1 $2 $3 $4 $5 }
+| TSwitch TOPar eexpr TCPar TOBrace list(case_line) TCBrace
+ { P.switch $1 $2 $3 $4 $5 $6 $7 }
+| TReturn eexpr TPtVirg { P.ret_exp $1 $2 $3 }
+| TReturn TPtVirg { P.ret $1 $2 }
+| TBreak TPtVirg { P.break $1 $2 }
+| TContinue TPtVirg { P.cont $1 $2 }
+| ident TDotDot { P.label $1 $2 }
+| TGoto ident TPtVirg { P.goto $1 $2 $3 }
+| TOBrace fun_start TCBrace
+ { P.seq $1 $2 $3 }
+
+stm_dots:
+ TEllipsis w=list(whenppdecs)
+ { Ast0.wrap(Ast0.Dots(P.clt2mcode "..." $1, List.concat w)) }
+| TOEllipsis w=list(whenppdecs) b=nest_start c=TCEllipsis
+ { Ast0.wrap(Ast0.Nest(P.clt2mcode "<..." $1, b,
+ P.clt2mcode "...>" c, List.concat w, false)) }
+| TPOEllipsis w=list(whenppdecs) b=nest_start c=TPCEllipsis
+ { Ast0.wrap(Ast0.Nest(P.clt2mcode "<+..." $1, b,
+ P.clt2mcode "...+>" c, List.concat w, true)) }
+
+whenppdecs: w=whens(when_start,rule_elem_statement)
+ { w }
+
+/* a statement that fits into a single rule_elem. should nests be included?
+what about statement metavariables? */
+rule_elem_statement:
+ one_decl_var
+ { Ast0.wrap(Ast0.Decl((Ast0.default_info(),Ast0.context_befaft()),$1)) }
+| expr TPtVirg { P.exp_stm $1 $2 }
+| TReturn eexpr TPtVirg { P.ret_exp $1 $2 $3 }
+| TReturn TPtVirg { P.ret $1 $2 }
+| TBreak TPtVirg { P.break $1 $2 }
+| TContinue TPtVirg { P.cont $1 $2 }
+| TOPar0 midzero_list(rule_elem_statement,rule_elem_statement) TCPar0
+ { let (mids,code) = $2 in
+ Ast0.wrap
+ (Ast0.Disj(P.clt2mcode "(" $1,
+ List.map (function x -> Ast0.wrap(Ast0.DOTS([x]))) code,
+ mids, P.clt2mcode ")" $3)) }
+
+/* a statement on its own */
+single_statement:
+ statement { $1 }
+ | TOPar0 midzero_list(statement,statement) TCPar0
+ /* degenerate case, elements are single statements and thus don't
+ contain dots */
+ { let (mids,code) = $2 in
+ Ast0.wrap
+ (Ast0.Disj(P.clt2mcode "(" $1,
+ List.map (function x -> Ast0.wrap(Ast0.DOTS([x]))) code,
+ mids, P.clt2mcode ")" $3)) }
+
+case_line:
+ TDefault TDotDot fun_start
+ { Ast0.wrap(Ast0.Default(P.clt2mcode "default" $1,P.clt2mcode ":" $2,$3)) }
+ | TCase eexpr TDotDot fun_start
+ { Ast0.wrap(Ast0.Case(P.clt2mcode "case" $1,$2,P.clt2mcode ":" $3,$4)) }
+
+/* In the following, an identifier as a type is not fully supported. Indeed,
+the language is ambiguous: what is foo * bar; */
+/* The AST DisjDecl cannot be generated because it would be ambiguous with
+a disjunction on a statement with a declaration in each branch */
+decl_var:
+ t=ctype pv=TPtVirg
+ { [Ast0.wrap(Ast0.TyDecl(t,P.clt2mcode ";" pv))] }
+ | s=ioption(storage) t=ctype d=comma_list(d_ident) pv=TPtVirg
+ { List.map
+ (function (id,fn) ->
+ Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv)))
+ d }
+ | f=funproto { [f] }
+ | s=ioption(storage) t=ctype d=d_ident q=TEq e=initialize pv=TPtVirg
+ {let (id,fn) = d in
+ [Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv))]}
+ /* type is a typedef name */
+ | s=ioption(storage) cv=ioption(const_vol) i=pure_ident
+ d=comma_list(d_ident) pv=TPtVirg
+ { List.map
+ (function (id,fn) ->
+ let idtype =
+ P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
+ Ast0.wrap(Ast0.UnInit(s,fn idtype,id,P.clt2mcode ";" pv)))
+ d }
+ | s=ioption(storage) cv=ioption(const_vol) i=pure_ident d=d_ident q=TEq
+ e=initialize pv=TPtVirg
+ { let (id,fn) = d in
+ !Data.add_type_name (P.id2name i);
+ let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
+ [Ast0.wrap(Ast0.Init(s,fn idtype,id,P.clt2mcode "=" q,e,
+ P.clt2mcode ";" pv))] }
+ /* function pointer type */
+ | s=ioption(storage)
+ t=fn_ctype lp1=TOPar st=TMul d=d_ident rp1=TCPar
+ lp2=TOPar p=decl_list(name_opt_decl) rp2=TCPar
+ pv=TPtVirg
+ { let (id,fn) = d in
+ let t =
+ Ast0.wrap
+ (Ast0.FunctionPointer
+ (t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
+ P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
+ [Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv))] }
+ | decl_ident TOPar eexpr_list_option TCPar TPtVirg
+ { [Ast0.wrap(Ast0.MacroDecl($1,P.clt2mcode "(" $2,$3,
+ P.clt2mcode ")" $4,P.clt2mcode ";" $5))] }
+ | s=ioption(storage)
+ t=fn_ctype lp1=TOPar st=TMul d=d_ident rp1=TCPar
+ lp2=TOPar p=decl_list(name_opt_decl) rp2=TCPar
+ q=TEq e=initialize pv=TPtVirg
+ { let (id,fn) = d in
+ let t =
+ Ast0.wrap
+ (Ast0.FunctionPointer
+ (t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
+ P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
+ [Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv))]}
+ | s=Ttypedef t=ctype id=typedef_ident pv=TPtVirg
+ { let s = P.clt2mcode "typedef" s in
+ [Ast0.wrap(Ast0.Typedef(s,t,id,P.clt2mcode ";" pv))] }
+
+one_decl_var:
+ t=ctype pv=TPtVirg
+ { Ast0.wrap(Ast0.TyDecl(t,P.clt2mcode ";" pv)) }
+ | s=ioption(storage) t=ctype d=d_ident pv=TPtVirg
+ { let (id,fn) = d in
+ Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv)) }
+ | f=funproto { f }
+ | s=ioption(storage) t=ctype d=d_ident q=TEq e=initialize pv=TPtVirg
+ { let (id,fn) = d in
+ Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv)) }
+ /* type is a typedef name */
+ | s=ioption(storage) cv=ioption(const_vol) i=pure_ident
+ d=d_ident pv=TPtVirg
+ { let (id,fn) = d in
+ let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
+ Ast0.wrap(Ast0.UnInit(s,fn idtype,id,P.clt2mcode ";" pv)) }
+ | s=ioption(storage) cv=ioption(const_vol) i=pure_ident d=d_ident q=TEq
+ e=initialize pv=TPtVirg
+ { let (id,fn) = d in
+ !Data.add_type_name (P.id2name i);
+ let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
+ Ast0.wrap(Ast0.Init(s,fn idtype,id,P.clt2mcode "=" q,e,
+ P.clt2mcode ";" pv)) }
+ /* function pointer type */
+ | s=ioption(storage)
+ t=fn_ctype lp1=TOPar st=TMul d=d_ident rp1=TCPar
+ lp2=TOPar p=decl_list(name_opt_decl) rp2=TCPar
+ pv=TPtVirg
+ { let (id,fn) = d in
+ let t =
+ Ast0.wrap
+ (Ast0.FunctionPointer
+ (t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
+ P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
+ Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv)) }
+ | decl_ident TOPar eexpr_list_option TCPar TPtVirg
+ { Ast0.wrap(Ast0.MacroDecl($1,P.clt2mcode "(" $2,$3,
+ P.clt2mcode ")" $4,P.clt2mcode ";" $5)) }
+ | s=ioption(storage)
+ t=fn_ctype lp1=TOPar st=TMul d=d_ident rp1=TCPar
+ lp2=TOPar p=decl_list(name_opt_decl) rp2=TCPar
+ q=TEq e=initialize pv=TPtVirg
+ { let (id,fn) = d in
+ let t =
+ Ast0.wrap
+ (Ast0.FunctionPointer
+ (t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
+ P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
+ Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv))}
+
+
+d_ident:
+ ident list(array_dec)
+ { ($1,
+ function t ->
+ List.fold_right
+ (function (l,i,r) ->
+ function rest ->
+ Ast0.wrap
+ (Ast0.Array(rest,P.clt2mcode "[" l,i,P.clt2mcode "]" r)))
+ $2 t) }
+
+array_dec: l=TOCro i=option(eexpr) r=TCCro { (l,i,r) }
+
+initialize:
+ eexpr
+ { Ast0.wrap(Ast0.InitExpr($1)) }
+ | TOBrace initialize_list TCBrace
+ { Ast0.wrap(Ast0.InitList(P.clt2mcode "{" $1,$2,P.clt2mcode "}" $3)) }
+ | TOBrace TCBrace
+ { Ast0.wrap
+ (Ast0.InitList(P.clt2mcode "{" $1,Ast0.wrap(Ast0.DOTS []),
+ P.clt2mcode "}" $2)) }
+
+initialize2:
+ /*arithexpr and not eexpr because can have ambiguity with comma*/
+ /*dots and nests probably not allowed at top level, haven't looked into why*/
+ arith_expr(eexpr,invalid) { Ast0.wrap(Ast0.InitExpr($1)) }
+| TOBrace initialize_list TCBrace
+ { Ast0.wrap(Ast0.InitList(P.clt2mcode "{" $1,$2,P.clt2mcode "}" $3)) }
+| TOBrace TCBrace
+ { Ast0.wrap
+ (Ast0.InitList(P.clt2mcode "{" $1,Ast0.wrap(Ast0.DOTS []),
+ P.clt2mcode "}" $2)) }
+ /* gccext:, labeled elements */
+| TDot ident TEq initialize2
+ { Ast0.wrap(Ast0.InitGccDotName(P.clt2mcode "." $1,$2,P.clt2mcode "=" $3,$4)) }
+| ident TDotDot initialize2
+ { Ast0.wrap(Ast0.InitGccName($1,P.clt2mcode ":" $2,$3)) } /* in old kernel */
+| TOCro eexpr TCCro TEq initialize2
+ { Ast0.wrap(Ast0.InitGccIndex(P.clt2mcode "[" $1,$2,P.clt2mcode "]" $3,
+ P.clt2mcode "=" $4,$5)) }
+| TOCro eexpr TEllipsis eexpr TCCro TEq initialize2
+ { Ast0.wrap(Ast0.InitGccRange(P.clt2mcode "[" $1,$2,P.clt2mcode "..." $3,
+ $4,P.clt2mcode "]" $5,P.clt2mcode "=" $6,$7)) }
+
+initialize_list:
+ initialize_list_start { Ast0.wrap(Ast0.DOTS($1)) }
+
+initialize_list_start:
+ initialize2 TComma { [$1;Ast0.wrap(Ast0.IComma(P.clt2mcode "," $2))] }
+| initialize2 TComma initialize_list_start
+ { $1::Ast0.wrap(Ast0.IComma(P.clt2mcode "," $2))::$3 }
+| d=edots_when(TEllipsis,initialize)
+ r=comma_initializers(edots_when(TEllipsis,initialize))
+ { (P.mkidots "..." d)::
+ (List.concat(List.map (function x -> x (P.mkidots "...")) r)) }
+
+comma_initializers(dotter):
+ /* empty */ { [] }
+| d=dotter r=comma_initializers2(dotter)
+ { (function dot_builder -> [dot_builder d])::r }
+| i=initialize2 c=TComma r=comma_initializers(dotter)
+ { (function dot_builder -> [i; Ast0.wrap(Ast0.IComma(P.clt2mcode "," c))])::
+ r }
+
+comma_initializers2(dotter):
+ /* empty */ { [] }
+| i=initialize2 c=TComma r=comma_initializers(dotter)
+ { (function dot_builder -> [i; Ast0.wrap(Ast0.IComma(P.clt2mcode "," c))])::
+ r }
+
+/* a statement that is part of a list */
+decl_statement:
+ TMetaStmList
+ { let (nm,pure,clt) = $1 in
+ [Ast0.wrap(Ast0.MetaStmt(P.clt2mcode nm clt,pure))] }
+ | decl_var
+ { List.map
+ (function x ->
+ Ast0.wrap
+ (Ast0.Decl((Ast0.default_info(),Ast0.context_befaft()),x)))
+ $1 }
+ | statement { [$1] }
+ /* this doesn't allow expressions at top level, because the parser doesn't
+ know whether there is one. If there is one, this is not sequencible.
+ If there is not one, then it is. It seems complicated to get around
+ this at the parser level. We would have to have a check afterwards to
+ allow this. One case where this would be useful is for a when. Now
+ we allow a sequence of whens, so one can be on only statements and
+ one can be on only expressions. */
+ | TOPar0 t=midzero_list(fun_start,fun_start) TCPar0
+ { let (mids,code) = t in
+ if List.for_all
+ (function x ->
+ match Ast0.unwrap x with Ast0.DOTS([]) -> true | _ -> false)
+ code
+ then []
+ else
+ [Ast0.wrap(Ast0.Disj(P.clt2mcode "(" $1, code, mids,
+ P.clt2mcode ")" $3))] }
+
+/* a statement that is part of a list */
+decl_statement_expr:
+ TMetaStmList
+ { let (nm,pure,clt) = $1 in
+ [Ast0.wrap(Ast0.MetaStmt(P.clt2mcode nm clt,pure))] }
+ | decl_var
+ { List.map
+ (function x ->
+ Ast0.wrap
+ (Ast0.Decl((Ast0.default_info(),Ast0.context_befaft()),x)))
+ $1 }
+ | statement { [$1] }
+ /* this doesn't allow expressions at top level, because the parser doesn't
+ know whether there is one. If there is one, this is not sequencible.
+ If there is not one, then it is. It seems complicated to get around
+ this at the parser level. We would have to have a check afterwards to
+ allow this. One case where this would be useful is for a when. Now
+ we allow a sequence of whens, so one can be on only statements and
+ one can be on only expressions. */
+ | TOPar0 t=midzero_list(fun_after_stm,fun_after_dots_or) TCPar0
+ { let (mids,code) = t in
+ if List.for_all (function [] -> true | _ -> false) code
+ then []
+ else
+ let dot_code =
+ List.map (function x -> Ast0.wrap(Ast0.DOTS x)) code in
+ [Ast0.wrap(Ast0.Disj(P.clt2mcode "(" $1, dot_code, mids,
+ P.clt2mcode ")" $3))] }
+
+/*****************************************************************************/
+
+/* The following cannot contain <... ...> at the top level. This can only
+be allowed as an expression when the expression is delimited on both sides
+by expression-specific markers. In that case, the rule eexpr is used, which
+allows <... ...> anywhere. Hopefully, this will not be too much of a problem
+in practice. */
+expr: basic_expr(expr,invalid) { $1 }
+/* allows ... and nests */
+eexpr: basic_expr(eexpr,dot_expressions) { $1 }
+/* allows nests but not .... */
+dexpr: basic_expr(eexpr,nest_expressions) { $1 }
+
+top_eexpr:
+ eexpr { Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Exp($1)))) }
+
+invalid:
+ TInvalid { raise (Semantic_cocci.Semantic "not matchable") }
+
+dot_expressions:
+ TEllipsis { Ast0.wrap(Ast0.Edots(P.clt2mcode "..." $1,None)) }
+| nest_expressions { $1 }
+
+nest_expressions:
+ TOEllipsis w=option(whenexp) e=expr_dots(TEllipsis) c=TCEllipsis
+ { Ast0.wrap(Ast0.NestExpr(P.clt2mcode "<..." $1,
+ Ast0.wrap(Ast0.DOTS(e (P.mkedots "..."))),
+ P.clt2mcode "...>" c, w, false)) }
+| TPOEllipsis w=option(whenexp) e=expr_dots(TEllipsis) c=TPCEllipsis
+ { Ast0.wrap(Ast0.NestExpr(P.clt2mcode "<+..." $1,
+ Ast0.wrap(Ast0.DOTS(e (P.mkedots "..."))),
+ P.clt2mcode "...+>" c, w, true)) }
+
+whenexp: TWhen TNotEq w=eexpr TLineEnd { w }
+
+basic_expr(recurser,primary_extra):
+ assign_expr(recurser,primary_extra) { $1 }
+
+assign_expr(r,pe):
+ cond_expr(r,pe) { $1 }
+ | unary_expr(r,pe) TAssign assign_expr_bis
+ { let (op,clt) = $2 in
+ Ast0.wrap(Ast0.Assignment($1,P.clt2mcode op clt,
+ Ast0.set_arg_exp $3,false)) }
+ | unary_expr(r,pe) TEq assign_expr_bis
+ { Ast0.wrap
+ (Ast0.Assignment
+ ($1,P.clt2mcode Ast.SimpleAssign $2,Ast0.set_arg_exp $3,false)) }
+
+assign_expr_bis:
+ cond_expr(eexpr,dot_expressions) { $1 }
+ | unary_expr(eexpr,dot_expressions) TAssign assign_expr_bis
+ { let (op,clt) = $2 in
+ Ast0.wrap(Ast0.Assignment($1,P.clt2mcode op clt,
+ Ast0.set_arg_exp $3,false)) }
+ | unary_expr(eexpr,dot_expressions) TEq assign_expr_bis
+ { Ast0.wrap
+ (Ast0.Assignment
+ ($1,P.clt2mcode Ast.SimpleAssign $2,Ast0.set_arg_exp $3,false)) }
+
+cond_expr(r,pe):
+ arith_expr(r,pe) { $1 }
+ | l=arith_expr(r,pe) w=TWhy t=option(eexpr) dd=TDotDot r=cond_expr(r,pe)
+ { Ast0.wrap(Ast0.CondExpr (l, P.clt2mcode "?" w, t,
+ P.clt2mcode ":" dd, r)) }
+
+arith_expr(r,pe):
+ cast_expr(r,pe) { $1 }
+ | arith_expr(r,pe) TMul arith_expr(r,pe)
+ { P.arith_op Ast.Mul $1 $2 $3 }
+ | arith_expr(r,pe) TDmOp arith_expr(r,pe)
+ { let (op,clt) = $2 in P.arith_op op $1 clt $3 }
+ | arith_expr(r,pe) TPlus arith_expr(r,pe)
+ { P.arith_op Ast.Plus $1 $2 $3 }
+ | arith_expr(r,pe) TMinus arith_expr(r,pe)
+ { P.arith_op Ast.Minus $1 $2 $3 }
+ | arith_expr(r,pe) TShOp arith_expr(r,pe)
+ { let (op,clt) = $2 in P.arith_op op $1 clt $3 }
+ | arith_expr(r,pe) TLogOp arith_expr(r,pe)
+ { let (op,clt) = $2 in P.logic_op op $1 clt $3 }
+ | arith_expr(r,pe) TEqEq arith_expr(r,pe)
+ { P.logic_op Ast.Eq $1 $2 $3 }
+ | arith_expr(r,pe) TNotEq arith_expr(r,pe)
+ { P.logic_op Ast.NotEq $1 $2 $3 }
+ | arith_expr(r,pe) TAnd arith_expr(r,pe)
+ { P.arith_op Ast.And $1 $2 $3 }
+ | arith_expr(r,pe) TOr arith_expr(r,pe)
+ { P.arith_op Ast.Or $1 $2 $3 }
+ | arith_expr(r,pe) TXor arith_expr(r,pe)
+ { P.arith_op Ast.Xor $1 $2 $3 }
+ | arith_expr(r,pe) TAndLog arith_expr(r,pe)
+ { P.logic_op Ast.AndLog $1 $2 $3 }
+ | arith_expr(r,pe) TOrLog arith_expr(r,pe)
+ { P.logic_op Ast.OrLog $1 $2 $3 }
+
+cast_expr(r,pe):
+ unary_expr(r,pe) { $1 }
+ | lp=TOPar t=ctype rp=TCPar e=cast_expr(r,pe)
+ { Ast0.wrap(Ast0.Cast (P.clt2mcode "(" lp, t,
+ P.clt2mcode ")" rp, e)) }
+
+unary_expr(r,pe):
+ postfix_expr(r,pe) { $1 }
+ | TInc unary_expr(r,pe)
+ { Ast0.wrap(Ast0.Infix ($2, P.clt2mcode Ast.Inc $1)) }
+ | TDec unary_expr(r,pe)
+ { Ast0.wrap(Ast0.Infix ($2, P.clt2mcode Ast.Dec $1)) }
+ | unary_op unary_expr(r,pe)
+ { let mcode = $1 in Ast0.wrap(Ast0.Unary($2, mcode)) }
+ | TBang unary_expr(r,pe)
+ { let mcode = P.clt2mcode Ast.Not $1 in
+ Ast0.wrap(Ast0.Unary($2, mcode)) }
+ | TSizeof unary_expr(r,pe)
+ { Ast0.wrap(Ast0.SizeOfExpr (P.clt2mcode "sizeof" $1, $2)) }
+ | s=TSizeof lp=TOPar t=ctype rp=TCPar
+ { Ast0.wrap(Ast0.SizeOfType (P.clt2mcode "sizeof" s,
+ P.clt2mcode "(" lp,t,
+ P.clt2mcode ")" rp)) }
+
+unary_op: TAnd { P.clt2mcode Ast.GetRef $1 }
+ | TMul { P.clt2mcode Ast.DeRef $1 }
+ | TPlus { P.clt2mcode Ast.UnPlus $1 }
+ | TMinus { P.clt2mcode Ast.UnMinus $1 }
+ | TTilde { P.clt2mcode Ast.Tilde $1 }
+
+postfix_expr(r,pe):
+ primary_expr(r,pe) { $1 }
+ | postfix_expr(r,pe) TOCro eexpr TCCro
+ { Ast0.wrap(Ast0.ArrayAccess ($1,P.clt2mcode "[" $2,$3,
+ P.clt2mcode "]" $4)) }
+ | postfix_expr(r,pe) TDot ident
+ { Ast0.wrap(Ast0.RecordAccess($1, P.clt2mcode "." $2, $3)) }
+ | postfix_expr(r,pe) TPtrOp ident
+ { Ast0.wrap(Ast0.RecordPtAccess($1, P.clt2mcode "->" $2,
+ $3)) }
+ | postfix_expr(r,pe) TInc
+ { Ast0.wrap(Ast0.Postfix ($1, P.clt2mcode Ast.Inc $2)) }
+ | postfix_expr(r,pe) TDec
+ { Ast0.wrap(Ast0.Postfix ($1, P.clt2mcode Ast.Dec $2)) }
+ | postfix_expr(r,pe) TOPar eexpr_list_option TCPar
+ { Ast0.wrap(Ast0.FunCall($1,P.clt2mcode "(" $2,
+ $3,
+ P.clt2mcode ")" $4)) }
+
+primary_expr(recurser,primary_extra):
+ func_ident { Ast0.wrap(Ast0.Ident($1)) }
+ | TInt
+ { let (x,clt) = $1 in
+ Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) }
+ | TFloat
+ { let (x,clt) = $1 in
+ Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Float x) clt)) }
+ | TString
+ { let (x,clt) = $1 in
+ Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.String x) clt)) }
+ | TChar
+ { let (x,clt) = $1 in
+ Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Char x) clt)) }
+ | TMetaConst
+ { let (nm,constraints,pure,ty,clt) = $1 in
+ Ast0.wrap
+ (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.CONST,pure)) }
+ | TMetaErr
+ { let (nm,constraints,pure,clt) = $1 in
+ Ast0.wrap(Ast0.MetaErr(P.clt2mcode nm clt,constraints,pure)) }
+ | TMetaExp
+ { let (nm,constraints,pure,ty,clt) = $1 in
+ Ast0.wrap
+ (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ANY,pure)) }
+ | TMetaIdExp
+ { let (nm,constraints,pure,ty,clt) = $1 in
+ Ast0.wrap
+ (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ID,pure)) }
+ | TMetaLocalIdExp
+ { let (nm,constraints,pure,ty,clt) = $1 in
+ Ast0.wrap
+ (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.LocalID,pure)) }
+ | TOPar eexpr TCPar
+ { Ast0.wrap(Ast0.Paren(P.clt2mcode "(" $1,$2,
+ P.clt2mcode ")" $3)) }
+ | TOPar0 midzero_list(recurser,eexpr) TCPar0
+ { let (mids,code) = $2 in
+ Ast0.wrap(Ast0.DisjExpr(P.clt2mcode "(" $1,
+ code, mids,
+ P.clt2mcode ")" $3)) }
+ | primary_extra { $1 }
+
+expr_dots(dotter):
+ r=no_dot_start_end(dexpr,edots_when(dotter,eexpr)) { r }
+
+// used in NEST
+no_dot_start_end(grammar,dotter):
+ g=grammar dg=list(pair(dotter,grammar))
+ { function dot_builder ->
+ g :: (List.concat(List.map (function (d,g) -> [dot_builder d;g]) dg)) }
+
+/*****************************************************************************/
+
+pure_ident:
+ TIdent { $1 }
+
+meta_ident:
+ TRuleName TDot pure_ident { (Some $1,P.id2name $3) }
+
+pure_ident_or_meta_ident:
+ pure_ident { (None,P.id2name $1) }
+ | meta_ident { $1 }
+ | Tlist { (None,"list") }
+ | TError { (None,"error") }
+ | TType { (None,"type") }
+
+pure_ident_or_meta_ident_with_not_eq(not_eq):
+ i=pure_ident_or_meta_ident l=loption(not_eq) { (i,l) }
+
+not_eq:
+ TNotEq i=pure_ident
+ { (if !Data.in_iso
+ then failwith "constraints not allowed in iso file");
+ [Ast0.wrap(Ast0.Id(P.id2mcode i))] }
+ | TNotEq TOBrace l=comma_list(pure_ident) TCBrace
+ { (if !Data.in_iso
+ then failwith "constraints not allowed in iso file");
+ List.map (function i -> Ast0.wrap(Ast0.Id(P.id2mcode i))) l }
+
+not_eqe:
+ TNotEq i=pure_ident
+ { (if !Data.in_iso
+ then failwith "constraints not allowed in iso file");
+ [Ast0.wrap(Ast0.Ident(Ast0.wrap(Ast0.Id(P.id2mcode i))))] }
+ | TNotEq TOBrace l=comma_list(pure_ident) TCBrace
+ { (if !Data.in_iso
+ then failwith "constraints not allowed in iso file");
+ List.map
+ (function i ->
+ Ast0.wrap(Ast0.Ident(Ast0.wrap(Ast0.Id(P.id2mcode i)))))
+ l }
+
+not_ceq:
+ TNotEq i=ident_or_const
+ { (if !Data.in_iso
+ then failwith "constraints not allowed in iso file");
+ [i] }
+ | TNotEq TOBrace l=comma_list(ident_or_const) TCBrace
+ { (if !Data.in_iso
+ then failwith "constraints not allowed in iso file");
+ l }
+
+ident_or_const:
+ i=pure_ident { Ast0.wrap(Ast0.Ident(Ast0.wrap(Ast0.Id(P.id2mcode i)))) }
+ | TInt
+ { let (x,clt) = $1 in
+ Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) }
+
+not_pos:
+ TNotEq i=meta_ident
+ { (if !Data.in_iso
+ then failwith "constraints not allowed in iso file");
+ match i with
+ (None,_) -> failwith "constraint must be an inherited variable"
+ | (Some rule,name) ->
+ let i = (rule,name) in
+ P.check_meta(Ast.MetaPosDecl(Ast.NONE,i));
+ [i] }
+ | TNotEq TOBrace l=comma_list(meta_ident) TCBrace
+ { (if !Data.in_iso
+ then failwith "constraints not allowed in iso file");
+ List.map
+ (function
+ (None,_) ->
+ failwith "constraint must be an inherited variable"
+ | (Some rule,name) ->
+ let i = (rule,name) in
+ P.check_meta(Ast.MetaPosDecl(Ast.NONE,i));
+ i)
+ l }
+
+func_ident: pure_ident
+ { Ast0.wrap(Ast0.Id(P.id2mcode $1)) }
+ | TMetaId
+ { let (nm,constraints,pure,clt) = $1 in
+ Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) }
+ | TMetaFunc
+ { let (nm,constraints,pure,clt) = $1 in
+ Ast0.wrap(Ast0.MetaFunc(P.clt2mcode nm clt,constraints,pure)) }
+ | TMetaLocalFunc
+ { let (nm,constraints,pure,clt) = $1 in
+ Ast0.wrap
+ (Ast0.MetaLocalFunc(P.clt2mcode nm clt,constraints,pure)) }
+
+ident: pure_ident
+ { Ast0.wrap(Ast0.Id(P.id2mcode $1)) }
+ | TMetaId
+ { let (nm,constraints,pure,clt) = $1 in
+ Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) }
+
+decl_ident:
+ TDeclarerId
+ { Ast0.wrap(Ast0.Id(P.id2mcode $1)) }
+ | TMetaDeclarer
+ { let (nm,constraints,pure,clt) = $1 in
+ Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) }
+
+iter_ident:
+ TIteratorId
+ { Ast0.wrap(Ast0.Id(P.id2mcode $1)) }
+ | TMetaIterator
+ { let (nm,constraints,pure,clt) = $1 in
+ Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) }
+
+typedef_ident:
+ pure_ident
+ { Ast0.wrap(Ast0.TypeName(P.id2mcode $1)) }
+ | TMetaType
+ { let (nm,pure,clt) = $1 in
+ Ast0.wrap(Ast0.MetaType(P.clt2mcode nm clt,pure)) }
+
+/*****************************************************************************/
+
+decl_list(decl):
+ decl_list_start(decl)
+ {let circle x =
+ match Ast0.unwrap x with Ast0.Pcircles(_) -> true | _ -> false in
+ if List.exists circle $1
+ then Ast0.wrap(Ast0.CIRCLES($1))
+ else Ast0.wrap(Ast0.DOTS($1)) }
+
+decl_list_start(decl):
+ one_dec(decl) { [$1] }
+| one_dec(decl) TComma decl_list_start(decl)
+ { $1::Ast0.wrap(Ast0.PComma(P.clt2mcode "," $2))::$3 }
+| TEllipsis list(comma_decls(TEllipsis,decl))
+ { Ast0.wrap(Ast0.Pdots(P.clt2mcode "..." $1))::
+ (List.concat(List.map (function x -> x (P.mkpdots "...")) $2)) }
+
+one_dec(decl):
+ decl { $1 }
+| TMetaParamList
+ { let (nm,lenname,pure,clt) = $1 in
+ let nm = P.clt2mcode nm clt in
+ let lenname =
+ match lenname with
+ Some nm -> Some(P.clt2mcode nm clt)
+ | None -> None in
+ Ast0.wrap(Ast0.MetaParamList(nm,lenname,pure)) }
+
+comma_decls(dotter,decl):
+ TComma dotter
+ { function dot_builder ->
+ [Ast0.wrap(Ast0.PComma(P.clt2mcode "," $1));
+ dot_builder $2] }
+| TComma one_dec(decl)
+ { function dot_builder ->
+ [Ast0.wrap(Ast0.PComma(P.clt2mcode "," $1)); $2] }
+
+/* ---------------------------------------------------------------------- */
+
+error_words:
+ TError TWords TEq TOCro cl=comma_list(dexpr) TCCro
+ { [Ast0.wrap(Ast0.ERRORWORDS(cl))] }
+
+/* ---------------------------------------------------------------------- */
+/* sequences of statements and expressions */
+
+/* There are number of cases that must be considered:
+
+1. Top level:
+ Dots and nests allowed at the beginning or end
+ Expressions allowed at the beginning or end
+ One function allowed, by itself
+2. A function body:
+ Dots and nests allowed at the beginning or end
+ Expressions not allowed at the beginning or end
+ Functions not allowed
+3. The body of a nest:
+ Dots and nests not allowed at the beginning or end
+ Expressions allowed at the beginning or end
+ Functions not allowed
+4. Whencode:
+ Dots and nests not allowed at the beginning but allowed at the end
+ Expressions allowed at the beginning or end
+ Functions not allowed
+
+These are implemented by the rules minus_toplevel_sequence,
+plus_toplevel_sequence, function_body_sequence, nest_body_sequence, and
+when_body_sequence.
+*/
+/* ------------------------------------------------------------------------ */
+/* Minus top level */
+
+/* doesn't allow only ... */
+minus_start:
+ fundecl { [Ast0.wrap(Ast0.DECL($1))] }
+| ctype { [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Ty($1))))] }
+| top_init { [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.TopInit($1))))] }
+| toplevel_seq_start(toplevel_after_dots_init)
+ { List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) $1 }
+
+toplevel_seq_start(after_dots_init):
+ stm_dots after_dots_init { $1::$2 }
+| expr toplevel_after_exp { (Ast0.wrap(Ast0.Exp($1)))::$2 }
+| decl_statement_expr toplevel_after_stm { $1@$2 }
+
+toplevel_after_dots_init:
+ TNothing toplevel_after_exp {$2}
+| expr toplevel_after_exp {(Ast0.wrap(Ast0.Exp($1)))::$2}
+| decl_statement_expr toplevel_after_stm {$1@$2}
+
+toplevel_after_exp:
+ /* empty */ {[]}
+| stm_dots toplevel_after_dots {$1::$2}
+
+toplevel_after_dots:
+ /* empty */ {[]}
+| TNothing toplevel_after_exp {$2}
+| expr toplevel_after_exp {(Ast0.wrap(Ast0.Exp($1)))::$2}
+| decl_statement_expr toplevel_after_stm {$1@$2}
+
+toplevel_after_stm:
+ /* empty */ {[]}
+| stm_dots toplevel_after_dots {$1::$2}
+| decl_statement toplevel_after_stm {$1@$2}
+
+top_init:
+ TOInit initialize_list TCBrace
+ { Ast0.wrap(Ast0.InitList(P.clt2mcode "{" $1,$2,P.clt2mcode "}" $3)) }
+
+/* ------------------------------------------------------------------------ */
+/* Plus top level */
+
+/* does allow only ... also allows multiple top-level functions */
+plus_start:
+ ctype { [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Ty($1))))] }
+| top_init { [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.TopInit($1))))] }
+| stm_dots plus_after_dots
+ { (Ast0.wrap(Ast0.OTHER($1)))::$2 }
+| expr plus_after_exp
+ { (Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Exp($1)))))::$2 }
+| fundecl plus_after_stm { Ast0.wrap(Ast0.DECL($1))::$2 }
+| decl_statement_expr plus_after_stm
+ { (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) $1)@$2 }
+
+plus_after_exp:
+ /* empty */ {[]}
+| stm_dots plus_after_dots { (Ast0.wrap(Ast0.OTHER($1)))::$2 }
+
+plus_after_dots:
+ /* empty */ {[]}
+| TNothing plus_after_exp {$2}
+| expr plus_after_exp
+ { (Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Exp($1)))))::$2 }
+| fundecl plus_after_stm { Ast0.wrap(Ast0.DECL($1))::$2 }
+| decl_statement_expr plus_after_stm
+ { (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) $1)@$2 }
+
+plus_after_stm:
+ /* empty */ {[]}
+| stm_dots plus_after_dots { (Ast0.wrap(Ast0.OTHER($1)))::$2 }
+| fundecl plus_after_stm { Ast0.wrap(Ast0.DECL($1))::$2 }
+| decl_statement plus_after_stm
+ { (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) $1)@$2 }
+
+/* ------------------------------------------------------------------------ */
+/* Function body */
+
+fun_start:
+ fun_after_stm { Ast0.wrap(Ast0.DOTS($1)) }
+
+fun_after_stm:
+ /* empty */ {[]}
+| stm_dots fun_after_dots {$1::$2}
+| decl_statement fun_after_stm {$1@$2}
+
+fun_after_dots:
+ /* empty */ {[]}
+| TNothing fun_after_exp {$2}
+| expr fun_after_exp {Ast0.wrap(Ast0.Exp($1))::$2}
+| decl_statement_expr fun_after_stm {$1@$2}
+
+fun_after_exp:
+ stm_dots fun_after_dots {$1::$2}
+
+/* hack to allow mixing statements and expressions in an or */
+fun_after_dots_or:
+ /* empty */ {[]}
+| TNothing fun_after_exp_or {$2}
+| expr fun_after_exp_or {Ast0.wrap(Ast0.Exp($1))::$2}
+| decl_statement_expr fun_after_stm {$1@$2}
+
+fun_after_exp_or:
+ /* empty */ {[]}
+| stm_dots fun_after_dots {$1::$2}
+
+/* ------------------------------------------------------------------------ */
+/* Nest body */
+
+nest_start:
+ nest_after_dots { Ast0.wrap(Ast0.DOTS($1)) }
+
+nest_after_dots:
+ decl_statement_expr nest_after_stm {$1@$2}
+| TNothing nest_after_exp {$2}
+| expr nest_after_exp {(Ast0.wrap(Ast0.Exp($1)))::$2}
+
+nest_after_stm:
+ /* empty */ {[]}
+| stm_dots nest_after_dots {$1::$2}
+| decl_statement nest_after_stm {$1@$2}
+
+nest_after_exp:
+ /* empty */ {[]}
+| stm_dots nest_after_dots {$1::$2}
+
+/* ------------------------------------------------------------------------ */
+/*Whencode*/
+
+when_start:
+ expr toplevel_after_exp
+ { Ast0.wrap(Ast0.DOTS((Ast0.wrap(Ast0.Exp($1)))::$2)) }
+| decl_statement toplevel_after_stm
+ { Ast0.wrap(Ast0.DOTS($1@$2)) }
+
+/* ---------------------------------------------------------------------- */
+
+eexpr_list:
+ eexpr_list_start
+ {let circle x =
+ match Ast0.unwrap x with Ast0.Ecircles(_) -> true | _ -> false in
+ let star x =
+ match Ast0.unwrap x with Ast0.Estars(_) -> true | _ -> false in
+ if List.exists circle $1
+ then Ast0.wrap(Ast0.CIRCLES($1))
+ else
+ if List.exists star $1
+ then Ast0.wrap(Ast0.STARS($1))
+ else Ast0.wrap(Ast0.DOTS($1)) }
+
+/* arg expr. may contain a type or a explist metavariable */
+aexpr:
+ eexpr
+ { Ast0.set_arg_exp $1 }
+ | TMetaExpList
+ { let (nm,lenname,pure,clt) = $1 in
+ let nm = P.clt2mcode nm clt in
+ let lenname =
+ match lenname with
+ Some nm -> Some(P.clt2mcode nm clt)
+ | None -> None in
+ Ast0.wrap(Ast0.MetaExprList(nm,lenname,pure)) }
+ | ctype
+ { Ast0.set_arg_exp(Ast0.wrap(Ast0.TypeExp($1))) }
+
+eexpr_list_start:
+ aexpr { [$1] }
+ | aexpr TComma eexpr_list_start
+ { $1::Ast0.wrap(Ast0.EComma(P.clt2mcode "," $2))::$3 }
+
+comma_args(dotter):
+ c=TComma d=dotter
+ { function dot_builder ->
+ [Ast0.wrap(Ast0.EComma(P.clt2mcode "," c)); dot_builder d] }
+| TComma aexpr
+ { function dot_builder ->
+ [Ast0.wrap(Ast0.EComma(P.clt2mcode "," $1)); $2] }
+
+eexpr_list_option: eexpr_list { $1 }
+ | /* empty */ { Ast0.wrap(Ast0.DOTS([])) }
+
+/****************************************************************************/
+
+// non-empty lists - drop separator
+comma_list(elem):
+ separated_nonempty_list(TComma,elem) { $1 }
+
+midzero_list(elem,aft):
+ a=elem b=list(mzl(aft))
+ { let (mids,code) = List.split b in (mids,(a::code)) }
+
+mzl(elem):
+ a=TMid0 b=elem { (P.clt2mcode "|" a, b) }
+
+edots_when(dotter,when_grammar):
+ d=dotter { (d,None) }
+ | d=dotter TWhen TNotEq w=when_grammar TLineEnd { (d,Some w) }
+
+whens(when_grammar,simple_when_grammar):
+ TWhen TNotEq w=when_grammar TLineEnd { [Ast0.WhenNot w] }
+ | TWhen TEq w=simple_when_grammar TLineEnd { [Ast0.WhenAlways w] }
+ | TWhen comma_list(any_strict) TLineEnd
+ { List.map (function x -> Ast0.WhenModifier(x)) $2 }
+ | TWhenTrue TNotEq e = eexpr TLineEnd { [Ast0.WhenNotTrue e] }
+ | TWhenFalse TNotEq e = eexpr TLineEnd { [Ast0.WhenNotFalse e] }
+
+any_strict:
+ TAny { Ast.WhenAny }
+ | TStrict { Ast.WhenStrict }
+ | TForall { Ast.WhenForall }
+ | TExists { Ast.WhenExists }
+
+/*****************************************************************************
+*
+*
+*****************************************************************************/
+
+iso_main:
+ TIsoExpression e1=dexpr el=list(iso(dexpr)) EOF
+ { P.iso_adjust (function x -> Ast0.ExprTag x) e1 el }
+| TIsoArgExpression e1=dexpr el=list(iso(dexpr)) EOF
+ { P.iso_adjust (function x -> Ast0.ArgExprTag x) e1 el }
+| TIsoTestExpression e1=dexpr el=list(iso(dexpr)) EOF
+ { P.iso_adjust (function x -> Ast0.TestExprTag x) e1 el }
+| TIsoStatement s1=single_statement sl=list(iso(single_statement)) EOF
+ { P.iso_adjust (function x -> Ast0.StmtTag x) s1 sl }
+| TIsoType t1=ctype tl=list(iso(ctype)) EOF
+ { P.iso_adjust (function x -> Ast0.TypeCTag x) t1 tl }
+| TIsoTopLevel e1=nest_start el=list(iso(nest_start)) EOF
+ { P.iso_adjust (function x -> Ast0.DotsStmtTag x) e1 el }
+| TIsoDeclaration d1=decl_var dl=list(iso(decl_var)) EOF
+ { let check_one = function
+ [x] -> x
+ | _ ->
+ raise
+ (Semantic_cocci.Semantic
+ "only one variable per declaration in an isomorphism rule") in
+ let d1 = check_one d1 in
+ let dl =
+ List.map
+ (function
+ Common.Left x -> Common.Left(check_one x)
+ | Common.Right x -> Common.Right(check_one x))
+ dl in
+ P.iso_adjust (function x -> Ast0.DeclTag x) d1 dl }
+
+iso(term):
+ TIso t=term { Common.Left t }
+ | TRightIso t=term { Common.Right t }
+
+/*****************************************************************************
+*
+*
+*****************************************************************************/
+
+never_used: TPragma { () }
+ | TPArob TMetaPos { () }
+ | TScriptData { () }
+
+script_meta_main: py=pure_ident TShOp TRuleName TDot cocci=pure_ident TMPtVirg
+ { (P.id2name py, ($3, P.id2name cocci)) }
--- /dev/null
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+*
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+*
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
+*
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+(* find unitary metavariables *)
+module Ast0 = Ast0_cocci
+module Ast = Ast_cocci
+module V0 = Visitor_ast0
+
+let set_minus s minus = List.filter (function n -> not (List.mem n minus)) s
+
+let rec nub = function
+ [] -> []
+ | (x::xs) when (List.mem x xs) -> nub xs
+ | (x::xs) -> x::(nub xs)
+
+(* ----------------------------------------------------------------------- *)
+(* Find the variables that occur free and occur free in a unitary way *)
+
+(* take everything *)
+let minus_checker name = let id = Ast0.unwrap_mcode name in [id]
+
+(* take only what is in the plus code *)
+let plus_checker (nm,_,_,mc,_) =
+ match mc with Ast0.PLUS -> [nm] | _ -> []
+
+let get_free checker t =
+ let bind x y = x @ y in
+ let option_default = [] in
+ let donothing r k e = k e in
+ let mcode _ = option_default in
+
+ (* considers a single list *)
+ let collect_unitary_nonunitary free_usage =
+ let free_usage = List.sort compare free_usage in
+ let rec loop1 todrop = function
+ [] -> []
+ | (x::xs) as all -> if x = todrop then loop1 todrop xs else all in
+ let rec loop2 = function
+ [] -> ([],[])
+ | [x] -> ([x],[])
+ | x::y::xs ->
+ if x = y
+ then
+ let (unitary,non_unitary) = loop2(loop1 x xs) in
+ (unitary,x::non_unitary)
+ else
+ let (unitary,non_unitary) = loop2 (y::xs) in
+ (x::unitary,non_unitary) in
+ loop2 free_usage in
+
+ (* considers a list of lists *)
+ let detect_unitary_frees l =
+ let (unitary,nonunitary) =
+ List.split (List.map collect_unitary_nonunitary l) in
+ let unitary = nub (List.concat unitary) in
+ let nonunitary = nub (List.concat nonunitary) in
+ let unitary =
+ List.filter (function x -> not (List.mem x nonunitary)) unitary in
+ unitary@nonunitary@nonunitary in
+
+ let whencode afn bfn expression = function
+ Ast0.WhenNot(a) -> afn a
+ | Ast0.WhenAlways(b) -> bfn b
+ | Ast0.WhenModifier(_) -> option_default
+ | Ast0.WhenNotTrue(a) -> expression a
+ | Ast0.WhenNotFalse(a) -> expression a in
+
+ let ident r k i =
+ match Ast0.unwrap i with
+ Ast0.MetaId(name,_,_) | Ast0.MetaFunc(name,_,_)
+ | Ast0.MetaLocalFunc(name,_,_) -> checker name
+ | _ -> k i in
+
+ let expression r k e =
+ match Ast0.unwrap e with
+ Ast0.MetaErr(name,_,_) | Ast0.MetaExpr(name,_,_,_,_)
+ | Ast0.MetaExprList(name,_,_) -> checker name
+ | Ast0.DisjExpr(starter,expr_list,mids,ender) ->
+ detect_unitary_frees(List.map r.V0.combiner_expression expr_list)
+ | _ -> k e in
+
+ let typeC r k t =
+ match Ast0.unwrap t with
+ Ast0.MetaType(name,_) -> checker name
+ | Ast0.DisjType(starter,types,mids,ender) ->
+ detect_unitary_frees(List.map r.V0.combiner_typeC types)
+ | _ -> k t in
+
+ let parameter r k p =
+ match Ast0.unwrap p with
+ Ast0.MetaParam(name,_) | Ast0.MetaParamList(name,_,_) -> checker name
+ | _ -> k p in
+
+ let declaration r k d =
+ match Ast0.unwrap d with
+ Ast0.DisjDecl(starter,decls,mids,ender) ->
+ detect_unitary_frees(List.map r.V0.combiner_declaration decls)
+ | _ -> k d in
+
+ let statement r k s =
+ match Ast0.unwrap s with
+ Ast0.MetaStmt(name,_) | Ast0.MetaStmtList(name,_) -> checker name
+ | Ast0.Disj(starter,stmt_list,mids,ender) ->
+ detect_unitary_frees(List.map r.V0.combiner_statement_dots stmt_list)
+ | Ast0.Nest(starter,stmt_dots,ender,whn,multi) ->
+ bind (r.V0.combiner_statement_dots stmt_dots)
+ (detect_unitary_frees
+ (List.map
+ (whencode r.V0.combiner_statement_dots r.V0.combiner_statement
+ r.V0.combiner_expression)
+ whn))
+ | Ast0.Dots(d,whn) | Ast0.Circles(d,whn) | Ast0.Stars(d,whn) ->
+ detect_unitary_frees
+ (List.map
+ (whencode r.V0.combiner_statement_dots r.V0.combiner_statement
+ r.V0.combiner_expression)
+ whn)
+ | _ -> k s in
+
+ let res = V0.combiner bind option_default
+ mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+ mcode
+ donothing donothing donothing donothing donothing donothing
+ ident expression typeC donothing parameter declaration statement
+ donothing donothing in
+
+ collect_unitary_nonunitary
+ (List.concat (List.map res.V0.combiner_top_level t))
+
+(* ----------------------------------------------------------------------- *)
+(* update the variables that are unitary *)
+
+let update_unitary unitary =
+ let donothing r k e = k e in
+ let mcode x = x in
+
+ let is_unitary name =
+ match (List.mem (Ast0.unwrap_mcode name) unitary,
+ Ast0.get_mcode_mcodekind name) with
+ (true,Ast0.CONTEXT(mc)) -> Ast0.PureContext
+ | (true,_) -> Ast0.Pure
+ | (false,Ast0.CONTEXT(mc)) -> Ast0.Context
+ | (false,_) -> Ast0.Impure in
+
+ let ident r k i =
+ match Ast0.unwrap i with
+ Ast0.MetaId(name,constraints,_) ->
+ Ast0.rewrap i (Ast0.MetaId(name,constraints,is_unitary name))
+ | Ast0.MetaFunc(name,constraints,_) ->
+ Ast0.rewrap i (Ast0.MetaFunc(name,constraints,is_unitary name))
+ | Ast0.MetaLocalFunc(name,constraints,_) ->
+ Ast0.rewrap i (Ast0.MetaLocalFunc(name,constraints,is_unitary name))
+ | _ -> k i in
+
+ let expression r k e =
+ match Ast0.unwrap e with
+ Ast0.MetaErr(name,constraints,_) ->
+ Ast0.rewrap e (Ast0.MetaErr(name,constraints,is_unitary name))
+ | Ast0.MetaExpr(name,constraints,ty,form,_) ->
+ Ast0.rewrap e (Ast0.MetaExpr(name,constraints,ty,form,is_unitary name))
+ | Ast0.MetaExprList(name,lenname,_) ->
+ Ast0.rewrap e (Ast0.MetaExprList(name,lenname,is_unitary name))
+ | _ -> k e in
+
+ let typeC r k t =
+ match Ast0.unwrap t with
+ Ast0.MetaType(name,_) ->
+ Ast0.rewrap t (Ast0.MetaType(name,is_unitary name))
+ | _ -> k t in
+
+ let parameter r k p =
+ match Ast0.unwrap p with
+ Ast0.MetaParam(name,_) ->
+ Ast0.rewrap p (Ast0.MetaParam(name,is_unitary name))
+ | Ast0.MetaParamList(name,lenname,_) ->
+ Ast0.rewrap p (Ast0.MetaParamList(name,lenname,is_unitary name))
+ | _ -> k p in
+
+ let statement r k s =
+ match Ast0.unwrap s with
+ Ast0.MetaStmt(name,_) ->
+ Ast0.rewrap s (Ast0.MetaStmt(name,is_unitary name))
+ | Ast0.MetaStmtList(name,_) ->
+ Ast0.rewrap s (Ast0.MetaStmtList(name,is_unitary name))
+ | _ -> k s in
+
+ let res = V0.rebuilder
+ mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+ mcode
+ donothing donothing donothing donothing donothing donothing
+ ident expression typeC donothing parameter donothing statement
+ donothing donothing in
+
+ List.map res.V0.rebuilder_top_level
+
+(* ----------------------------------------------------------------------- *)
+
+let rec split3 = function
+ [] -> ([],[],[])
+ | (a,b,c)::xs -> let (l1,l2,l3) = split3 xs in (a::l1,b::l2,c::l3)
+
+let rec combine3 = function
+ ([],[],[]) -> []
+ | (a::l1,b::l2,c::l3) -> (a,b,c) :: combine3 (l1,l2,l3)
+ | _ -> failwith "not possible"
+
+(* ----------------------------------------------------------------------- *)
+(* process all rules *)
+
+let do_unitary rules =
+ let rec loop = function
+ [] -> ([],[])
+ | (r::rules) ->
+ match r with
+ Ast0.ScriptRule (a,b,c,d) ->
+ let (x,rules) = loop rules in
+ (x, r::rules)
+ | Ast0.CocciRule ((minus,metavars,chosen_isos),((plus,_) as plusz)) ->
+ let mm1 = List.map Ast.get_meta_name metavars in
+ let (used_after, rest) = loop rules in
+ let (m_unitary, m_nonunitary) = get_free minus_checker minus in
+ let (p_unitary, p_nonunitary) = get_free plus_checker plus in
+ let p_free =
+ if !Flag.sgrep_mode2 then []
+ else p_unitary @ p_nonunitary in
+ let (in_p, m_unitary) =
+ List.partition (function x -> List.mem x p_free) m_unitary in
+ let m_nonunitary = in_p @ m_nonunitary in
+ let (m_unitary, not_local) =
+ List.partition (function x -> List.mem x mm1) m_unitary in
+ let m_unitary =
+ List.filter (function x -> not (List.mem x used_after))
+ m_unitary in
+ let rebuilt = update_unitary m_unitary minus in
+ (set_minus (m_nonunitary @ used_after) mm1,
+ (Ast0.CocciRule
+ ((rebuilt, metavars, chosen_isos),plusz))::rest) in
+ let (_,rules) = loop rules in
+ rules
+
+(*
+let do_unitary minus plus =
+ let (minus,metavars,chosen_isos) = split3 minus in
+ let (plus,_) = List.split plus in
+ let rec loop = function
+ ([],[],[]) -> ([],[])
+ | (mm1::metavars,m1::minus,p1::plus) ->
+ let mm1 = List.map Ast.get_meta_name mm1 in
+ let (used_after,rest) = loop (metavars,minus,plus) in
+ let (m_unitary,m_nonunitary) = get_free minus_checker m1 in
+ let (p_unitary,p_nonunitary) = get_free plus_checker p1 in
+ let p_free =
+ if !Flag.sgrep_mode2
+ then []
+ else p_unitary @ p_nonunitary in
+ let (in_p,m_unitary) =
+ List.partition (function x -> List.mem x p_free) m_unitary in
+ let m_nonunitary = in_p@m_nonunitary in
+ let (m_unitary,not_local) =
+ List.partition (function x -> List.mem x mm1) m_unitary in
+ let m_unitary =
+ List.filter (function x -> not(List.mem x used_after)) m_unitary in
+ let rebuilt = update_unitary m_unitary m1 in
+ (set_minus (m_nonunitary @ used_after) mm1,
+ rebuilt::rest)
+ | _ -> failwith "not possible" in
+ let (_,rules) = loop (metavars,minus,plus) in
+ combine3 (rules,metavars,chosen_isos)
+*)
--- /dev/null
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+*
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+*
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
+*
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+open Format
+module Ast0 = Ast0_cocci
+module U = Pretty_print_cocci
+
+let quiet = ref true (* true = no decoration on - context, etc *)
+
+let start_block str =
+ force_newline(); print_string " "; open_box 0
+
+let end_block str =
+ close_box(); force_newline ()
+
+let print_option = Common.do_option
+let print_between = Common.print_between
+
+(* --------------------------------------------------------------------- *)
+(* Positions *)
+
+let meta_pos = function
+ Ast0.MetaPos(name,_,_) ->
+ print_string "@";
+ let (_,name) = Ast0.unwrap_mcode name in
+ print_string name
+ | Ast0.NoMetaPos -> ()
+
+(* --------------------------------------------------------------------- *)
+(* Modified code *)
+
+let mcodekind brackets fn x info = function
+ Ast0.MINUS(plus_stream) ->
+ let (lb,rb) =
+ if !quiet
+ then ("","")
+ else
+ match brackets with
+ Some x -> ("[","]^"^(string_of_int x))
+ | None -> ("","") in
+ let (plus_stream,_) = !plus_stream in
+ if !quiet
+ then fn x
+ else (print_string "-";
+ print_string lb; fn x; print_string rb);
+ U.print_anything ">>> " plus_stream
+ | Ast0.CONTEXT(plus_streams) ->
+ let (lb,rb) =
+ if !quiet
+ then ("","")
+ else
+ match brackets with
+ Some x -> ("[",("]^"^(string_of_int x))) | None -> ("","") in
+ let (plus_streams,t1,t2) = !plus_streams in
+ U.print_around
+ (function x ->
+ print_string lb; fn x; print_string rb)
+ x plus_streams
+ | Ast0.PLUS ->
+ List.iter (function s -> print_string s; force_newline())
+ info.Ast0.strings_before;
+ fn x;
+ List.iter (function s -> force_newline(); print_string s)
+ info.Ast0.strings_after
+ | Ast0.MIXED(plus_streams) ->
+ let (lb,rb) =
+ if !quiet
+ then ("","")
+ else
+ let n =
+ match brackets with Some x -> "^"^(string_of_int x) | None -> "" in
+ ("§","½"^n) in
+ let (plus_streams,_,_) = !plus_streams in
+ U.print_around (function x -> print_string lb; fn x; print_string rb)
+ x plus_streams
+
+let mcode fn (x,_,info,mc,pos) =
+ let fn x = fn x; meta_pos !pos in
+ mcodekind (Some info.Ast0.line_start)(*None*) fn x info mc
+
+let print_context x fn =
+ mcodekind (Some (Ast0.get_line x)) fn () (Ast0.get_info x)
+ (Ast0.get_mcodekind x)
+
+let print_meta (_,name) = print_string name
+
+(* --------------------------------------------------------------------- *)
+(* --------------------------------------------------------------------- *)
+(* Dots *)
+
+let dots between fn d =
+ print_context d
+ (function _ ->
+ match Ast0.unwrap d with
+ Ast0.DOTS(l) -> print_between between fn l
+ | Ast0.CIRCLES(l) -> print_between between fn l
+ | Ast0.STARS(l) -> print_between between fn l)
+
+(* --------------------------------------------------------------------- *)
+
+let print_types = function
+ None -> ()
+ | Some ty ->
+ print_string "/* ";
+ Format.print_flush();
+ print_between (function _ -> print_string ", ") Type_cocci.typeC ty;
+ Format.print_flush();
+ print_string " */"
+
+(* --------------------------------------------------------------------- *)
+(* Identifier *)
+
+let rec ident i =
+ print_context i
+ (function _ ->
+ match Ast0.unwrap i with
+ Ast0.Id(name) -> mcode print_string name
+ | Ast0.MetaId(name,_,_) -> mcode print_meta name
+ | Ast0.MetaFunc(name,_,_) -> mcode print_meta name
+ | Ast0.MetaLocalFunc(name,_,_) -> mcode print_meta name
+ | Ast0.OptIdent(id) -> print_string "?"; ident id
+ | Ast0.UniqueIdent(id) -> print_string "!"; ident id)
+
+(* --------------------------------------------------------------------- *)
+(* Expression *)
+
+let print_string_box s = print_string s; open_box 0
+
+let rec expression e =
+ print_option Type_cocci.typeC (Ast0.get_type e);
+ print_context e
+ (function _ ->
+ match Ast0.unwrap e with
+ Ast0.Ident(id) -> ident id
+ | Ast0.Constant(const) -> mcode U.constant const
+ | Ast0.FunCall(fn,lp,args,rp) ->
+ expression fn; mcode print_string_box lp;
+ let _ = dots (function _ -> ()) expression args in
+ close_box(); mcode print_string rp
+ | Ast0.Assignment(left,op,right,_) ->
+ expression left; print_string " "; mcode U.assignOp op;
+ print_string " "; expression right
+ | Ast0.CondExpr(exp1,why,exp2,colon,exp3) ->
+ expression exp1; print_string " "; mcode print_string why;
+ print_option (function e -> print_string " "; expression e) exp2;
+ print_string " "; mcode print_string colon; expression exp3
+ | Ast0.Postfix(exp,op) -> expression exp; mcode U.fixOp op
+ | Ast0.Infix(exp,op) -> mcode U.fixOp op; expression exp
+ | Ast0.Unary(exp,op) -> mcode U.unaryOp op; expression exp
+ | Ast0.Binary(left,op,right) ->
+ print_string "(";
+ expression left; print_string " "; mcode U.binaryOp op;
+ print_string " "; expression right;
+ print_string ")"
+ | Ast0.Nested(left,op,right) ->
+ print_string "(";
+ expression left; print_string " "; mcode U.binaryOp op;
+ print_string " "; expression right;
+ print_string ")"
+ | Ast0.Paren(lp,exp,rp) ->
+ mcode print_string_box lp; expression exp; close_box();
+ mcode print_string rp
+ | Ast0.ArrayAccess(exp1,lb,exp2,rb) ->
+ expression exp1; mcode print_string_box lb; expression exp2;
+ close_box(); mcode print_string rb
+ | Ast0.RecordAccess(exp,pt,field) ->
+ expression exp; mcode print_string pt; ident field
+ | Ast0.RecordPtAccess(exp,ar,field) ->
+ expression exp; mcode print_string ar; ident field
+ | Ast0.Cast(lp,ty,rp,exp) ->
+ mcode print_string_box lp; typeC ty; close_box();
+ mcode print_string rp; expression exp
+ | Ast0.SizeOfExpr(szf,exp) ->
+ mcode print_string szf; expression exp
+ | Ast0.SizeOfType(szf,lp,ty,rp) ->
+ mcode print_string szf;
+ mcode print_string_box lp; typeC ty; close_box();
+ mcode print_string rp
+ | Ast0.TypeExp(ty) -> typeC ty
+ | Ast0.MetaErr(name,_,_) -> mcode print_meta name
+ | Ast0.MetaExpr(name,_,ty,_,_) ->
+ mcode print_meta name; print_types ty
+ | Ast0.MetaExprList(name,_,_) -> mcode print_meta name
+ | Ast0.EComma(cm) -> mcode print_string cm; print_space()
+ | Ast0.DisjExpr(_,exp_list,_,_) ->
+ print_string "\n("; force_newline();
+ print_between
+ (function _ -> print_string "\n|"; force_newline())
+ expression exp_list;
+ print_string "\n)"
+ | Ast0.NestExpr(starter,expr_dots,ender,None,multi) ->
+ mcode print_string starter;
+ start_block(); dots force_newline expression expr_dots; end_block();
+ mcode print_string ender
+ | Ast0.NestExpr(starter,expr_dots,ender,Some whencode,multi) ->
+ mcode print_string starter; print_string " WHEN != ";
+ expression whencode;
+ start_block(); dots force_newline expression expr_dots; end_block();
+ mcode print_string ender
+ | Ast0.Edots(dots,Some whencode)
+ | Ast0.Ecircles(dots,Some whencode)
+ | Ast0.Estars(dots,Some whencode) ->
+ mcode print_string dots; print_string " WHEN != ";
+ expression whencode
+ | Ast0.Edots(dots,None)
+ | Ast0.Ecircles(dots,None)
+ | Ast0.Estars(dots,None) -> mcode print_string dots
+ | Ast0.OptExp(exp) -> print_string "?"; expression exp
+ | Ast0.UniqueExp(exp) -> print_string "!"; expression exp)
+
+and expression_dots x = dots (function _ -> ()) expression x
+
+(* --------------------------------------------------------------------- *)
+(* Types *)
+
+and print_function_pointer (ty,lp1,star,rp1,lp2,params,rp2) fn =
+ typeC ty; mcode print_string lp1; mcode print_string star; fn();
+ mcode print_string rp1; mcode print_string lp2;
+ parameter_list params; mcode print_string rp2
+
+and print_function_type (ty,lp1,params,rp1) fn =
+ print_option typeC ty; fn(); mcode print_string lp1;
+ parameter_list params; mcode print_string rp1
+
+and typeC t =
+ print_context t
+ (function _ ->
+ match Ast0.unwrap t with
+ Ast0.ConstVol(cv,ty) ->
+ mcode U.const_vol cv; print_string " "; typeC ty
+ | Ast0.BaseType(ty,sgn) ->
+ print_option (mcode U.sign) sgn; mcode U.baseType ty
+ | Ast0.ImplicitInt(sgn) -> mcode U.sign sgn
+ | Ast0.Pointer(ty,star) -> typeC ty; mcode print_string star
+ | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
+ print_function_pointer (ty,lp1,star,rp1,lp2,params,rp2)
+ (function _ -> ())
+ | Ast0.FunctionType(ty,lp1,params,rp1) ->
+ print_function_type (ty,lp1,params,rp1) (function _ -> ())
+ | Ast0.Array(ty,lb,size,rb) ->
+ typeC ty; mcode print_string lb; print_option expression size;
+ mcode print_string rb
+ | Ast0.StructUnionName(kind,name) ->
+ mcode U.structUnion kind;
+ print_option (function x -> ident x; print_string " ") name
+ | Ast0.StructUnionDef(ty,lb,decls,rb) ->
+ typeC ty; mcode print_string lb;
+ dots force_newline declaration decls;
+ mcode print_string rb
+ | Ast0.TypeName(name)-> mcode print_string name; print_string " "
+ | Ast0.MetaType(name,_)-> mcode print_meta name; print_string " "
+ | Ast0.DisjType(lp,types,mids,rp) ->
+ print_string "\n"; mcode print_string lp; force_newline();
+ print_between
+ (function _ -> print_string "\n|"; force_newline())
+ typeC types;
+ print_string "\n"; mcode print_string rp
+ | Ast0.OptType(ty) -> print_string "?"; typeC ty
+ | Ast0.UniqueType(ty) -> print_string "!"; typeC ty)
+
+(* --------------------------------------------------------------------- *)
+(* Variable declaration *)
+(* Even if the Cocci program specifies a list of declarations, they are
+ split out into multiple declarations of a single variable each. *)
+
+and print_named_type ty id =
+ match Ast0.unwrap ty with
+ Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
+ print_function_pointer (ty,lp1,star,rp1,lp2,params,rp2)
+ (function _ -> print_string " "; ident id)
+ | Ast0.FunctionType(ty,lp1,params,rp1) ->
+ print_function_type (ty,lp1,params,rp1)
+ (function _ -> print_string " "; ident id)
+ | Ast0.Array(ty,lb,size,rb) ->
+ let rec loop ty k =
+ match Ast0.unwrap ty with
+ Ast0.Array(ty,lb,size,rb) ->
+ loop ty
+ (function _ ->
+ k ();
+ mcode print_string lb;
+ print_option expression size;
+ mcode print_string rb)
+ | _ -> typeC ty; ident id; k () in
+ loop ty (function _ -> ())
+ | _ -> typeC ty; ident id
+
+and declaration d =
+ print_context d
+ (function _ ->
+ match Ast0.unwrap d with
+ Ast0.Init(stg,ty,id,eq,ini,sem) ->
+ print_option (mcode U.storage) stg;
+ print_named_type ty id;
+ print_string " ";
+ mcode print_string eq; print_string " "; initialiser ini;
+ mcode print_string sem
+ | Ast0.UnInit(stg,ty,id,sem) ->
+ print_option (mcode U.storage) stg; print_named_type ty id;
+ mcode print_string sem
+ | Ast0.MacroDecl(name,lp,args,rp,sem) ->
+ ident name; mcode print_string_box lp;
+ let _ = dots (function _ -> ()) expression args in
+ close_box(); mcode print_string rp; mcode print_string sem
+ | Ast0.TyDecl(ty,sem) -> typeC ty; mcode print_string sem
+ | Ast0.Typedef(stg,ty,id,sem) ->
+ mcode print_string stg; typeC ty; typeC id;
+ mcode print_string sem
+ | Ast0.DisjDecl(_,decls,_,_) ->
+ print_string "\n("; force_newline();
+ print_between
+ (function _ -> print_string "\n|"; force_newline())
+ declaration decls;
+ print_string "\n)"
+ | Ast0.Ddots(dots,Some whencode) ->
+ mcode print_string dots; print_string " when != ";
+ declaration whencode
+ | Ast0.Ddots(dots,None) -> mcode print_string dots
+ | Ast0.OptDecl(decl) -> print_string "?"; declaration decl
+ | Ast0.UniqueDecl(decl) -> print_string "!"; declaration decl)
+
+and declaration_dots l = dots (function _ -> ()) declaration l
+
+(* --------------------------------------------------------------------- *)
+(* Initialiser *)
+
+and initialiser i =
+ print_context i
+ (function _ ->
+ match Ast0.unwrap i with
+ Ast0.InitExpr(exp) -> expression exp
+ | Ast0.InitList(lb,initlist,rb) ->
+ mcode print_string lb; open_box 0;
+ let _ = dots (function _ -> ()) initialiser initlist in
+ close_box(); mcode print_string rb
+ | Ast0.InitGccDotName(dot,name,eq,ini) ->
+ mcode print_string dot; ident name; print_string " ";
+ mcode print_string eq; print_string " "; initialiser ini
+ | Ast0.InitGccName(name,eq,ini) ->
+ ident name; mcode print_string eq; initialiser ini
+ | Ast0.InitGccIndex(lb,exp,rb,eq,ini) ->
+ mcode print_string lb; expression exp; mcode print_string rb;
+ print_string " "; mcode print_string eq; print_string " ";
+ initialiser ini
+ | Ast0.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini) ->
+ mcode print_string lb; expression exp1; mcode print_string dots;
+ expression exp2; mcode print_string rb;
+ print_string " "; mcode print_string eq; print_string " ";
+ initialiser ini
+ | Ast0.IComma(cm) -> mcode print_string cm; force_newline()
+ | Ast0.Idots(d,Some whencode) ->
+ mcode print_string d; print_string " WHEN != ";
+ initialiser whencode
+ | Ast0.Idots(d,None) -> mcode print_string d
+ | Ast0.OptIni(ini) -> print_string "?"; initialiser ini
+ | Ast0.UniqueIni(ini) -> print_string "!"; initialiser ini)
+
+and initialiser_list l = dots (function _ -> ()) initialiser l
+
+(* --------------------------------------------------------------------- *)
+(* Parameter *)
+
+and parameterTypeDef p =
+ print_context p
+ (function _ ->
+ match Ast0.unwrap p with
+ Ast0.VoidParam(ty) -> typeC ty
+ | Ast0.Param(ty,Some id) -> print_named_type ty id
+ | Ast0.Param(ty,None) -> typeC ty
+ | Ast0.MetaParam(name,_) -> mcode print_meta name
+ | Ast0.MetaParamList(name,_,_) -> mcode print_meta name
+ | Ast0.PComma(cm) -> mcode print_string cm; print_space()
+ | Ast0.Pdots(dots) -> mcode print_string dots
+ | Ast0.Pcircles(dots) -> mcode print_string dots
+ | Ast0.OptParam(param) -> print_string "?"; parameterTypeDef param
+ | Ast0.UniqueParam(param) -> print_string "!"; parameterTypeDef param)
+
+and parameter_list l = dots (function _ -> ()) parameterTypeDef l
+
+(* --------------------------------------------------------------------- *)
+(* Top-level code *)
+
+and statement arity s =
+ print_context s
+ (function _ ->
+ match Ast0.unwrap s with
+ Ast0.FunDecl(_,fninfo,name,lp,params,rp,lbrace,body,rbrace) ->
+ print_string arity;
+ List.iter print_fninfo fninfo;
+ ident name; mcode print_string_box lp;
+ parameter_list params; close_box(); mcode print_string rp;
+ print_string " ";
+ print_string arity; mcode print_string lbrace; start_block();
+ dots force_newline (statement arity) body;
+ end_block(); print_string arity; mcode print_string rbrace
+ | Ast0.Decl(_,decl) -> print_string arity; declaration decl
+ | Ast0.Seq(lbrace,body,rbrace) ->
+ print_string arity; mcode print_string lbrace; start_block();
+ dots force_newline (statement arity) body;
+ end_block(); print_string arity; mcode print_string rbrace
+ | Ast0.ExprStatement(exp,sem) ->
+ print_string arity; expression exp; mcode print_string sem
+ | Ast0.IfThen(iff,lp,exp,rp,branch1,(info,aft)) ->
+ print_string arity;
+ mcode print_string iff; print_string " "; mcode print_string_box lp;
+ expression exp; close_box(); mcode print_string rp; print_string " ";
+ statement arity branch1;
+ mcode (function _ -> ()) ((),(),info,aft,ref Ast0.NoMetaPos)
+ | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,(info,aft)) ->
+ print_string arity;
+ mcode print_string iff; print_string " "; mcode print_string_box lp;
+ expression exp; close_box(); mcode print_string rp; print_string " ";
+ statement arity branch1;
+ print_string arity; mcode print_string els; print_string " ";
+ statement arity branch2;
+ mcode (function _ -> ()) ((),(),info,aft,ref Ast0.NoMetaPos)
+ | Ast0.While(whl,lp,exp,rp,body,(info,aft)) ->
+ print_string arity;
+ mcode print_string whl; print_string " "; mcode print_string_box lp;
+ expression exp; close_box(); mcode print_string rp; print_string " ";
+ statement arity body;
+ mcode (function _ -> ()) ((),(),info,aft,ref Ast0.NoMetaPos)
+ | Ast0.Do(d,body,whl,lp,exp,rp,sem) ->
+ print_string arity; mcode print_string d; print_string " ";
+ statement arity body;
+ print_string arity;
+ mcode print_string whl; print_string " "; mcode print_string_box lp;
+ expression exp; close_box(); mcode print_string rp;
+ mcode print_string sem
+ | Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,(info,aft)) ->
+ print_string arity;
+ mcode print_string fr; mcode print_string_box lp;
+ print_option expression e1; mcode print_string sem1;
+ print_option expression e2; mcode print_string sem2;
+ print_option expression e3; close_box();
+ mcode print_string rp; print_string " "; statement arity body;
+ mcode (function _ -> ()) ((),(),info,aft,ref Ast0.NoMetaPos)
+ | Ast0.Iterator(nm,lp,args,rp,body,(info,aft)) ->
+ print_string arity;
+ ident nm; print_string " "; mcode print_string_box lp;
+ let _ = dots (function _ -> ()) expression args in
+ close_box(); mcode print_string rp; print_string " ";
+ statement arity body;
+ mcode (function _ -> ()) ((),(),info,aft,ref Ast0.NoMetaPos)
+ | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) ->
+ print_string arity;
+ mcode print_string switch; print_string " ";
+ mcode print_string_box lp; expression exp; close_box();
+ mcode print_string rp; print_string " "; mcode print_string lb;
+ dots force_newline (case_line arity) cases;
+ mcode print_string rb
+ | Ast0.Break(br,sem) ->
+ print_string arity; mcode print_string br; mcode print_string sem
+ | Ast0.Continue(cont,sem) ->
+ print_string arity; mcode print_string cont; mcode print_string sem
+ | Ast0.Label(l,dd) -> ident l; print_string ":"
+ | Ast0.Goto(goto,l,sem) ->
+ mcode print_string goto; ident l; mcode print_string sem
+ | Ast0.Return(ret,sem) ->
+ print_string arity; mcode print_string ret; mcode print_string sem
+ | Ast0.ReturnExpr(ret,exp,sem) ->
+ print_string arity; mcode print_string ret; print_string " ";
+ expression exp; mcode print_string sem
+ | Ast0.MetaStmt(name,pure) ->
+ print_string arity; mcode print_meta name;(*
+ print_string "^";
+ (match pure with
+ Ast0.Pure -> print_string "pure"
+ | Ast0.Impure -> print_string "impure"
+ | Ast0.Context -> print_string "context"
+ | Ast0.PureContext -> print_string "pure_context")*)
+ | Ast0.MetaStmtList(name,_) ->
+ print_string arity; mcode print_meta name
+ | Ast0.Disj(_,statement_dots_list,_,_) ->
+ print_string arity;
+ print_string "\n("; force_newline();
+ print_between
+ (function _ -> print_string "\n|"; force_newline())
+ (dots force_newline (statement arity))
+ statement_dots_list;
+ print_string "\n)"
+ | Ast0.Nest(starter,stmt_dots,ender,whn,multi) ->
+ print_string arity;
+ mcode print_string starter;
+ open_box 0;
+ List.iter
+ (whencode (dots force_newline (statement "")) (statement ""))
+ whn;
+ close_box();
+ start_block();
+ dots force_newline (statement arity) stmt_dots;
+ end_block();
+ mcode print_string ender
+ | Ast0.Exp(exp) -> print_string arity; expression exp
+ | Ast0.TopExp(exp) -> print_string arity; expression exp
+ | Ast0.Ty(ty) -> print_string arity; typeC ty
+ | Ast0.TopInit(init) -> initialiser init
+ | Ast0.Dots(d,whn) | Ast0.Circles(d,whn) | Ast0.Stars(d,whn) ->
+ print_string arity; mcode print_string d;
+ List.iter
+ (whencode (dots force_newline (statement "")) (statement ""))
+ whn
+ | Ast0.Include(inc,s) ->
+ mcode print_string inc; print_string " "; mcode U.inc_file s
+ | Ast0.Define(def,id,params,body) ->
+ mcode print_string def; print_string " "; ident id;
+ print_define_parameters params;
+ print_string " ";
+ dots force_newline (statement arity) body
+ | Ast0.OptStm(re) -> statement "?" re
+ | Ast0.UniqueStm(re) -> statement "!" re)
+
+and print_define_parameters params =
+ match Ast0.unwrap params with
+ Ast0.NoParams -> ()
+ | Ast0.DParams(lp,params,rp) ->
+ mcode print_string lp;
+ dots (function _ -> ()) print_define_param params; mcode print_string rp
+
+and print_define_param param =
+ match Ast0.unwrap param with
+ Ast0.DParam(id) -> ident id
+ | Ast0.DPComma(comma) -> mcode print_string comma
+ | Ast0.DPdots(dots) -> mcode print_string dots
+ | Ast0.DPcircles(circles) -> mcode print_string circles
+ | Ast0.OptDParam(dp) -> print_string "?"; print_define_param dp
+ | Ast0.UniqueDParam(dp) -> print_string "!"; print_define_param dp
+
+and print_fninfo = function
+ Ast0.FStorage(stg) -> mcode U.storage stg
+ | Ast0.FType(ty) -> typeC ty
+ | Ast0.FInline(inline) -> mcode print_string inline
+ | Ast0.FAttr(attr) -> mcode print_string attr
+
+and whencode notfn alwaysfn = function
+ Ast0.WhenNot a ->
+ print_string " WHEN != "; open_box 0; notfn a; close_box()
+ | Ast0.WhenAlways a ->
+ print_string " WHEN = "; open_box 0; alwaysfn a; close_box()
+ | Ast0.WhenModifier x -> print_string " WHEN "; U.print_when_modif x
+ | Ast0.WhenNotTrue a ->
+ print_string " WHEN != TRUE "; open_box 0; expression a; close_box()
+ | Ast0.WhenNotFalse a ->
+ print_string " WHEN != FALSE "; open_box 0; expression a; close_box()
+
+and case_line arity c =
+ print_context c
+ (function _ ->
+ match Ast0.unwrap c with
+ Ast0.Default(def,colon,code) ->
+ print_string arity;
+ mcode print_string def; mcode print_string colon; print_string " ";
+ dots force_newline (statement arity) code
+ | Ast0.Case(case,exp,colon,code) ->
+ print_string arity;
+ mcode print_string case; print_string " "; expression exp;
+ mcode print_string colon; print_string " ";
+ dots force_newline (statement arity) code
+ | Ast0.OptCase(case) -> case_line "?" case)
+
+and statement_dots l = dots (function _ -> ()) (statement "") l
+and case_dots l = dots (function _ -> ()) (case_line "") l
+
+(* --------------------------------------------------------------------- *)
+(* Top level code *)
+
+let top_level t =
+ print_context t
+ (function _ ->
+ match Ast0.unwrap t with
+ Ast0.FILEINFO(old_file,new_file) ->
+ print_string "--- "; mcode print_string old_file; force_newline();
+ print_string "+++ "; mcode print_string new_file
+ | Ast0.DECL(stmt) -> statement "" stmt
+ | Ast0.CODE(stmt_dots) ->
+ dots force_newline (statement "") stmt_dots
+ | Ast0.ERRORWORDS(exps) ->
+ print_string "error words = [";
+ print_between (function _ -> print_string ", ") expression exps;
+ print_string "]"
+ | Ast0.OTHER(s) ->
+ print_string "OTHER("; statement "" s; print_string ")")
+
+let rule =
+ print_between (function _ -> force_newline(); force_newline()) top_level
+
+let unparse_anything x =
+ let q = !quiet in
+ quiet := true;
+ (match x with
+ Ast0.DotsExprTag(d) ->
+ print_string "ExpDots:"; force_newline();
+ expression_dots d
+ | Ast0.DotsParamTag(d) ->
+ parameter_list d
+ | Ast0.DotsInitTag(d) ->
+ initialiser_list d
+ | Ast0.DotsStmtTag(d) ->
+ print_string "StmDots:"; force_newline();
+ statement_dots d
+ | Ast0.DotsDeclTag(d) ->
+ declaration_dots d
+ | Ast0.DotsCaseTag(d) ->
+ case_dots d
+ | Ast0.IdentTag(d) ->
+ ident d
+ | Ast0.ExprTag(d) | Ast0.ArgExprTag(d) | Ast0.TestExprTag(d) ->
+ print_string "Exp:"; force_newline();
+ expression d
+ | Ast0.TypeCTag(d) ->
+ typeC d
+ | Ast0.ParamTag(d) ->
+ parameterTypeDef d
+ | Ast0.InitTag(d) ->
+ initialiser d
+ | Ast0.DeclTag(d) ->
+ declaration d
+ | Ast0.StmtTag(d) ->
+ print_string "Stm:"; force_newline();
+ statement "" d
+ | Ast0.CaseLineTag(d) ->
+ case_line "" d
+ | Ast0.TopTag(d) ->
+ top_level d
+ | Ast0.IsoWhenTag(x) -> U.print_when_modif x
+ | Ast0.IsoWhenTTag(e) -> expression e
+ | Ast0.IsoWhenFTag(e) -> expression e
+ | Ast0.MetaPosTag(var) -> meta_pos var);
+ quiet := q;
+ print_newline()
+
+let unparse x =
+ print_string "\n@@\n@@";
+ force_newline();
+ force_newline();
+ rule x;
+ print_newline()
+
+let unparse_to_string x = Common.format_to_string (function _ -> unparse x)
--- /dev/null
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+*
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+*
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
+*
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+module Ast = Ast_cocci
+module Ast0 = Ast0_cocci
+
+(* --------------------------------------------------------------------- *)
+(* Generic traversal: combiner *)
+(* parameters:
+ combining function
+ treatment of: mcode, identifiers, expressions, typeCs, types,
+ declarations, statements, toplevels
+ default value for options *)
+
+type 'a combiner =
+ {combiner_ident : Ast0.ident -> 'a;
+ combiner_expression : Ast0.expression -> 'a;
+ combiner_typeC : Ast0.typeC -> 'a;
+ combiner_declaration : Ast0.declaration -> 'a;
+ combiner_initialiser : Ast0.initialiser -> 'a;
+ combiner_initialiser_list : Ast0.initialiser_list -> 'a;
+ combiner_parameter : Ast0.parameterTypeDef -> 'a;
+ combiner_parameter_list : Ast0.parameter_list -> 'a;
+ combiner_statement : Ast0.statement -> 'a;
+ combiner_case_line : Ast0.case_line -> 'a;
+ combiner_top_level : Ast0.top_level -> 'a;
+ combiner_expression_dots :
+ Ast0.expression Ast0.dots -> 'a;
+ combiner_statement_dots :
+ Ast0.statement Ast0.dots -> 'a;
+ combiner_declaration_dots :
+ Ast0.declaration Ast0.dots -> 'a;
+ combiner_case_line_dots :
+ Ast0.case_line Ast0.dots -> 'a;
+ combiner_anything : Ast0.anything -> 'a}
+
+
+type ('mc,'a) cmcode = 'mc Ast0.mcode -> 'a
+type ('cd,'a) ccode = 'a combiner -> ('cd -> 'a) -> 'cd -> 'a
+
+let combiner bind option_default
+ meta_mcode string_mcode const_mcode assign_mcode fix_mcode unary_mcode
+ binary_mcode cv_mcode base_mcode sign_mcode struct_mcode storage_mcode
+ inc_mcode
+ dotsexprfn dotsinitfn dotsparamfn dotsstmtfn dotsdeclfn dotscasefn
+ identfn exprfn
+ tyfn initfn paramfn declfn stmtfn casefn topfn =
+ let multibind l =
+ let rec loop = function
+ [] -> option_default
+ | [x] -> x
+ | x::xs -> bind x (loop xs) in
+ loop l in
+ let get_option f = function
+ Some x -> f x
+ | None -> option_default in
+ let rec expression_dots d =
+ let k d =
+ match Ast0.unwrap d with
+ Ast0.DOTS(l) | Ast0.CIRCLES(l) | Ast0.STARS(l) ->
+ multibind (List.map expression l) in
+ dotsexprfn all_functions k d
+ and initialiser_dots d =
+ let k d =
+ match Ast0.unwrap d with
+ Ast0.DOTS(l) | Ast0.CIRCLES(l) | Ast0.STARS(l) ->
+ multibind (List.map initialiser l) in
+ dotsinitfn all_functions k d
+ and parameter_dots d =
+ let k d =
+ match Ast0.unwrap d with
+ Ast0.DOTS(l) | Ast0.CIRCLES(l) | Ast0.STARS(l) ->
+ multibind (List.map parameterTypeDef l) in
+ dotsparamfn all_functions k d
+ and statement_dots d =
+ let k d =
+ match Ast0.unwrap d with
+ Ast0.DOTS(l) | Ast0.CIRCLES(l) | Ast0.STARS(l) ->
+ multibind (List.map statement l) in
+ dotsstmtfn all_functions k d
+ and declaration_dots d =
+ let k d =
+ match Ast0.unwrap d with
+ Ast0.DOTS(l) | Ast0.CIRCLES(l) | Ast0.STARS(l) ->
+ multibind (List.map declaration l) in
+ dotsdeclfn all_functions k d
+ and case_line_dots d =
+ let k d =
+ match Ast0.unwrap d with
+ Ast0.DOTS(l) | Ast0.CIRCLES(l) | Ast0.STARS(l) ->
+ multibind (List.map case_line l) in
+ dotscasefn all_functions k d
+ and ident i =
+ let k i =
+ match Ast0.unwrap i with
+ Ast0.Id(name) -> string_mcode name
+ | Ast0.MetaId(name,_,_) -> meta_mcode name
+ | Ast0.MetaFunc(name,_,_) -> meta_mcode name
+ | Ast0.MetaLocalFunc(name,_,_) -> meta_mcode name
+ | Ast0.OptIdent(id) -> ident id
+ | Ast0.UniqueIdent(id) -> ident id in
+ identfn all_functions k i
+ and expression e =
+ let k e =
+ match Ast0.unwrap e with
+ Ast0.Ident(id) -> ident id
+ | Ast0.Constant(const) -> const_mcode const
+ | Ast0.FunCall(fn,lp,args,rp) ->
+ multibind
+ [expression fn; string_mcode lp; expression_dots args;
+ string_mcode rp]
+ | Ast0.Assignment(left,op,right,_) ->
+ multibind [expression left; assign_mcode op; expression right]
+ | Ast0.CondExpr(exp1,why,exp2,colon,exp3) ->
+ multibind
+ [expression exp1; string_mcode why; get_option expression exp2;
+ string_mcode colon; expression exp3]
+ | Ast0.Postfix(exp,op) -> bind (expression exp) (fix_mcode op)
+ | Ast0.Infix(exp,op) -> bind (fix_mcode op) (expression exp)
+ | Ast0.Unary(exp,op) -> bind (unary_mcode op) (expression exp)
+ | Ast0.Binary(left,op,right) ->
+ multibind [expression left; binary_mcode op; expression right]
+ | Ast0.Nested(left,op,right) ->
+ multibind [expression left; binary_mcode op; expression right]
+ | Ast0.Paren(lp,exp,rp) ->
+ multibind [string_mcode lp; expression exp; string_mcode rp]
+ | Ast0.ArrayAccess(exp1,lb,exp2,rb) ->
+ multibind
+ [expression exp1; string_mcode lb; expression exp2;
+ string_mcode rb]
+ | Ast0.RecordAccess(exp,pt,field) ->
+ multibind [expression exp; string_mcode pt; ident field]
+ | Ast0.RecordPtAccess(exp,ar,field) ->
+ multibind [expression exp; string_mcode ar; ident field]
+ | Ast0.Cast(lp,ty,rp,exp) ->
+ multibind
+ [string_mcode lp; typeC ty; string_mcode rp; expression exp]
+ | Ast0.SizeOfExpr(szf,exp) ->
+ multibind [string_mcode szf; expression exp]
+ | Ast0.SizeOfType(szf,lp,ty,rp) ->
+ multibind
+ [string_mcode szf; string_mcode lp; typeC ty; string_mcode rp]
+ | Ast0.TypeExp(ty) -> typeC ty
+ | Ast0.MetaErr(name,_,_)
+ | Ast0.MetaExpr(name,_,_,_,_)
+ | Ast0.MetaExprList(name,_,_) -> meta_mcode name
+ | Ast0.EComma(cm) -> string_mcode cm
+ | Ast0.DisjExpr(starter,expr_list,mids,ender) ->
+ (match expr_list with
+ [] -> failwith "bad disjunction"
+ | x::xs ->
+ bind (string_mcode starter)
+ (bind (expression x)
+ (bind
+ (multibind
+ (List.map2
+ (function mid ->
+ function x ->
+ bind (string_mcode mid) (expression x))
+ mids xs))
+ (string_mcode ender))))
+ | Ast0.NestExpr(starter,expr_dots,ender,whencode,multi) ->
+ bind (string_mcode starter)
+ (bind (expression_dots expr_dots)
+ (bind (string_mcode ender) (get_option expression whencode)))
+ | Ast0.Edots(dots,whencode) | Ast0.Ecircles(dots,whencode)
+ | Ast0.Estars(dots,whencode) ->
+ bind (string_mcode dots) (get_option expression whencode)
+ | Ast0.OptExp(exp) -> expression exp
+ | Ast0.UniqueExp(exp) -> expression exp in
+ exprfn all_functions k e
+ and function_pointer (ty,lp1,star,rp1,lp2,params,rp2) extra =
+ (* have to put the treatment of the identifier into the right position *)
+ multibind
+ ([typeC ty; string_mcode lp1; string_mcode star] @ extra @
+ [string_mcode rp1;
+ string_mcode lp2; parameter_dots params; string_mcode rp2])
+ and function_type (ty,lp1,params,rp1) extra =
+ (* have to put the treatment of the identifier into the right position *)
+ multibind ([get_option typeC ty] @ extra @
+ [string_mcode lp1; parameter_dots params; string_mcode rp1])
+ and array_type (ty,lb,size,rb) extra =
+ multibind
+ ([typeC ty] @ extra @
+ [string_mcode lb; get_option expression size; string_mcode rb])
+ and typeC t =
+ let k t =
+ match Ast0.unwrap t with
+ Ast0.ConstVol(cv,ty) -> bind (cv_mcode cv) (typeC ty)
+ | Ast0.BaseType(ty,sign) ->
+ bind (get_option sign_mcode sign) (base_mcode ty)
+ | Ast0.ImplicitInt(sign) -> (sign_mcode sign)
+ | Ast0.Pointer(ty,star) -> bind (typeC ty) (string_mcode star)
+ | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
+ function_pointer (ty,lp1,star,rp1,lp2,params,rp2) []
+ | Ast0.FunctionType(ty,lp1,params,rp1) ->
+ function_type (ty,lp1,params,rp1) []
+ | Ast0.Array(ty,lb,size,rb) ->
+ array_type (ty,lb,size,rb) []
+ | Ast0.StructUnionName(kind,name) ->
+ bind (struct_mcode kind) (get_option ident name)
+ | Ast0.StructUnionDef(ty,lb,decls,rb) ->
+ multibind
+ [typeC ty;string_mcode lb;declaration_dots decls;string_mcode rb]
+ | Ast0.TypeName(name) -> string_mcode name
+ | Ast0.MetaType(name,_) -> meta_mcode name
+ | Ast0.DisjType(starter,types,mids,ender) ->
+ (match types with
+ [] -> failwith "bad disjunction"
+ | x::xs ->
+ bind (string_mcode starter)
+ (bind (typeC x)
+ (bind
+ (multibind
+ (List.map2
+ (function mid ->
+ function x ->
+ bind (string_mcode mid) (typeC x))
+ mids xs))
+ (string_mcode ender))))
+ | Ast0.OptType(ty) -> typeC ty
+ | Ast0.UniqueType(ty) -> typeC ty in
+ tyfn all_functions k t
+ and named_type ty id =
+ match Ast0.unwrap ty with
+ Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
+ function_pointer (ty,lp1,star,rp1,lp2,params,rp2) [ident id]
+ | Ast0.FunctionType(ty,lp1,params,rp1) ->
+ function_type (ty,lp1,params,rp1) [ident id]
+ | Ast0.Array(ty,lb,size,rb) ->
+ array_type (ty,lb,size,rb) [ident id]
+ | _ -> bind (typeC ty) (ident id)
+ and declaration d =
+ let k d =
+ match Ast0.unwrap d with
+ Ast0.Init(stg,ty,id,eq,ini,sem) ->
+ bind (get_option storage_mcode stg)
+ (bind (named_type ty id)
+ (multibind
+ [string_mcode eq; initialiser ini; string_mcode sem]))
+ | Ast0.UnInit(stg,ty,id,sem) ->
+ bind (get_option storage_mcode stg)
+ (bind (named_type ty id) (string_mcode sem))
+ | Ast0.MacroDecl(name,lp,args,rp,sem) ->
+ multibind
+ [ident name; string_mcode lp; expression_dots args;
+ string_mcode rp; string_mcode sem]
+ | Ast0.TyDecl(ty,sem) -> bind (typeC ty) (string_mcode sem)
+ | Ast0.Typedef(stg,ty,id,sem) ->
+ bind (string_mcode stg)
+ (bind (typeC ty) (bind (typeC id) (string_mcode sem)))
+ | Ast0.DisjDecl(starter,decls,mids,ender) ->
+ (match decls with
+ [] -> failwith "bad disjunction"
+ | x::xs ->
+ bind (string_mcode starter)
+ (bind (declaration x)
+ (bind
+ (multibind
+ (List.map2
+ (function mid ->
+ function x ->
+ bind (string_mcode mid) (declaration x))
+ mids xs))
+ (string_mcode ender))))
+ | Ast0.Ddots(dots,whencode) ->
+ bind (string_mcode dots) (get_option declaration whencode)
+ | Ast0.OptDecl(decl) -> declaration decl
+ | Ast0.UniqueDecl(decl) -> declaration decl in
+ declfn all_functions k d
+ and initialiser i =
+ let k i =
+ match Ast0.unwrap i with
+ Ast0.InitExpr(exp) -> expression exp
+ | Ast0.InitList(lb,initlist,rb) ->
+ multibind
+ [string_mcode lb; initialiser_dots initlist; string_mcode rb]
+ | Ast0.InitGccDotName(dot,name,eq,ini) ->
+ multibind
+ [string_mcode dot; ident name; string_mcode eq; initialiser ini]
+ | Ast0.InitGccName(name,eq,ini) ->
+ multibind [ident name; string_mcode eq; initialiser ini]
+ | Ast0.InitGccIndex(lb,exp,rb,eq,ini) ->
+ multibind
+ [string_mcode lb; expression exp; string_mcode rb;
+ string_mcode eq; initialiser ini]
+ | Ast0.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini) ->
+ multibind
+ [string_mcode lb; expression exp1; string_mcode dots;
+ expression exp2; string_mcode rb; string_mcode eq;
+ initialiser ini]
+ | Ast0.IComma(cm) -> string_mcode cm
+ | Ast0.Idots(dots,whencode) ->
+ bind (string_mcode dots) (get_option initialiser whencode)
+ | Ast0.OptIni(i) -> initialiser i
+ | Ast0.UniqueIni(i) -> initialiser i in
+ initfn all_functions k i
+ and parameterTypeDef p =
+ let k p =
+ match Ast0.unwrap p with
+ Ast0.VoidParam(ty) -> typeC ty
+ | Ast0.Param(ty,Some id) -> named_type ty id
+ | Ast0.Param(ty,None) -> typeC ty
+ | Ast0.MetaParam(name,_) -> meta_mcode name
+ | Ast0.MetaParamList(name,_,_) -> meta_mcode name
+ | Ast0.PComma(cm) -> string_mcode cm
+ | Ast0.Pdots(dots) -> string_mcode dots
+ | Ast0.Pcircles(dots) -> string_mcode dots
+ | Ast0.OptParam(param) -> parameterTypeDef param
+ | Ast0.UniqueParam(param) -> parameterTypeDef param in
+ paramfn all_functions k p
+
+ (* discard the result, because the statement is assumed to be already
+ represented elsewhere in the code *)
+ and process_bef_aft s =
+ match Ast0.get_dots_bef_aft s with
+ Ast0.NoDots -> ()
+ | Ast0.DroppingBetweenDots(stm) -> let _ = statement stm in ()
+ | Ast0.AddingBetweenDots(stm) -> let _ = statement stm in ()
+
+ and statement s =
+ process_bef_aft s;
+ let k s =
+ match Ast0.unwrap s with
+ Ast0.FunDecl(_,fi,name,lp,params,rp,lbrace,body,rbrace) ->
+ multibind
+ ((List.map fninfo fi) @
+ [ident name; string_mcode lp;
+ parameter_dots params; string_mcode rp; string_mcode lbrace;
+ statement_dots body; string_mcode rbrace])
+ | Ast0.Decl(_,decl) -> declaration decl
+ | Ast0.Seq(lbrace,body,rbrace) ->
+ multibind
+ [string_mcode lbrace; statement_dots body; string_mcode rbrace]
+ | Ast0.ExprStatement(exp,sem) ->
+ bind (expression exp) (string_mcode sem)
+ | Ast0.IfThen(iff,lp,exp,rp,branch1,_) ->
+ multibind
+ [string_mcode iff; string_mcode lp; expression exp;
+ string_mcode rp; statement branch1]
+ | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,_) ->
+ multibind
+ [string_mcode iff; string_mcode lp; expression exp;
+ string_mcode rp; statement branch1; string_mcode els;
+ statement branch2]
+ | Ast0.While(whl,lp,exp,rp,body,_) ->
+ multibind
+ [string_mcode whl; string_mcode lp; expression exp;
+ string_mcode rp; statement body]
+ | Ast0.Do(d,body,whl,lp,exp,rp,sem) ->
+ multibind
+ [string_mcode d; statement body; string_mcode whl;
+ string_mcode lp; expression exp; string_mcode rp;
+ string_mcode sem]
+ | Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,_) ->
+ multibind
+ [string_mcode fr; string_mcode lp; get_option expression e1;
+ string_mcode sem1; get_option expression e2; string_mcode sem2;
+ get_option expression e3;
+ string_mcode rp; statement body]
+ | Ast0.Iterator(nm,lp,args,rp,body,_) ->
+ multibind
+ [ident nm; string_mcode lp; expression_dots args;
+ string_mcode rp; statement body]
+ | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) ->
+ multibind
+ [string_mcode switch; string_mcode lp; expression exp;
+ string_mcode rp; string_mcode lb; case_line_dots cases;
+ string_mcode rb]
+ | Ast0.Break(br,sem) -> bind (string_mcode br) (string_mcode sem)
+ | Ast0.Continue(cont,sem) -> bind (string_mcode cont) (string_mcode sem)
+ | Ast0.Label(l,dd) -> bind (ident l) (string_mcode dd)
+ | Ast0.Goto(goto,l,sem) ->
+ bind (string_mcode goto) (bind (ident l) (string_mcode sem))
+ | Ast0.Return(ret,sem) -> bind (string_mcode ret) (string_mcode sem)
+ | Ast0.ReturnExpr(ret,exp,sem) ->
+ multibind [string_mcode ret; expression exp; string_mcode sem]
+ | Ast0.MetaStmt(name,_) -> meta_mcode name
+ | Ast0.MetaStmtList(name,_) -> meta_mcode name
+ | Ast0.Disj(starter,statement_dots_list,mids,ender) ->
+ (match statement_dots_list with
+ [] -> failwith "bad disjunction"
+ | x::xs ->
+ bind (string_mcode starter)
+ (bind (statement_dots x)
+ (bind
+ (multibind
+ (List.map2
+ (function mid ->
+ function x ->
+ bind (string_mcode mid) (statement_dots x))
+ mids xs))
+ (string_mcode ender))))
+ | Ast0.Nest(starter,stmt_dots,ender,whn,multi) ->
+ bind (string_mcode starter)
+ (bind (statement_dots stmt_dots)
+ (bind (string_mcode ender)
+ (multibind
+ (List.map (whencode statement_dots statement) whn))))
+ | Ast0.Exp(exp) -> expression exp
+ | Ast0.TopExp(exp) -> expression exp
+ | Ast0.Ty(ty) -> typeC ty
+ | Ast0.TopInit(init) -> initialiser init
+ | Ast0.Dots(d,whn) | Ast0.Circles(d,whn) | Ast0.Stars(d,whn) ->
+ bind (string_mcode d)
+ (multibind (List.map (whencode statement_dots statement) whn))
+ | Ast0.Include(inc,name) -> bind (string_mcode inc) (inc_mcode name)
+ | Ast0.Define(def,id,params,body) ->
+ multibind [string_mcode def; ident id; define_parameters params;
+ statement_dots body]
+ | Ast0.OptStm(re) -> statement re
+ | Ast0.UniqueStm(re) -> statement re in
+ stmtfn all_functions k s
+
+ (* not parameterizable for now... *)
+ and define_parameters p =
+ let k p =
+ match Ast0.unwrap p with
+ Ast0.NoParams -> option_default
+ | Ast0.DParams(lp,params,rp) ->
+ multibind
+ [string_mcode lp; define_param_dots params; string_mcode rp] in
+ k p
+
+ and define_param_dots d =
+ let k d =
+ match Ast0.unwrap d with
+ Ast0.DOTS(l) | Ast0.CIRCLES(l) | Ast0.STARS(l) ->
+ multibind (List.map define_param l) in
+ k d
+
+ and define_param p =
+ let k p =
+ match Ast0.unwrap p with
+ Ast0.DParam(id) -> ident id
+ | Ast0.DPComma(comma) -> string_mcode comma
+ | Ast0.DPdots(d) -> string_mcode d
+ | Ast0.DPcircles(c) -> string_mcode c
+ | Ast0.OptDParam(dp) -> define_param dp
+ | Ast0.UniqueDParam(dp) -> define_param dp in
+ k p
+
+ and fninfo = function
+ Ast0.FStorage(stg) -> storage_mcode stg
+ | Ast0.FType(ty) -> typeC ty
+ | Ast0.FInline(inline) -> string_mcode inline
+ | Ast0.FAttr(init) -> string_mcode init
+
+ and whencode notfn alwaysfn = function
+ Ast0.WhenNot a -> notfn a
+ | Ast0.WhenAlways a -> alwaysfn a
+ | Ast0.WhenModifier(_) -> option_default
+ | Ast0.WhenNotTrue(e) -> expression e
+ | Ast0.WhenNotFalse(e) -> expression e
+
+ and case_line c =
+ let k c =
+ match Ast0.unwrap c with
+ Ast0.Default(def,colon,code) ->
+ multibind [string_mcode def;string_mcode colon;statement_dots code]
+ | Ast0.Case(case,exp,colon,code) ->
+ multibind [string_mcode case;expression exp;string_mcode colon;
+ statement_dots code]
+ | Ast0.OptCase(case) -> case_line case in
+ casefn all_functions k c
+
+ and anything a = (* for compile_iso, not parameterisable *)
+ let k = function
+ Ast0.DotsExprTag(exprs) -> expression_dots exprs
+ | Ast0.DotsInitTag(inits) -> initialiser_dots inits
+ | Ast0.DotsParamTag(params) -> parameter_dots params
+ | Ast0.DotsStmtTag(stmts) -> statement_dots stmts
+ | Ast0.DotsDeclTag(decls) -> declaration_dots decls
+ | Ast0.DotsCaseTag(cases) -> case_line_dots cases
+ | Ast0.IdentTag(id) -> ident id
+ | Ast0.ExprTag(exp) -> expression exp
+ | Ast0.ArgExprTag(exp) -> expression exp
+ | Ast0.TestExprTag(exp) -> expression exp
+ | Ast0.TypeCTag(ty) -> typeC ty
+ | Ast0.ParamTag(param) -> parameterTypeDef param
+ | Ast0.InitTag(init) -> initialiser init
+ | Ast0.DeclTag(decl) -> declaration decl
+ | Ast0.StmtTag(stmt) -> statement stmt
+ | Ast0.CaseLineTag(c) -> case_line c
+ | Ast0.TopTag(top) -> top_level top
+ | Ast0.IsoWhenTag(_) -> option_default
+ | Ast0.IsoWhenTTag(e) -> expression e
+ | Ast0.IsoWhenFTag(e) -> expression e
+ | Ast0.MetaPosTag(var) -> failwith "not supported" in
+ k a
+
+ and top_level t =
+ let k t =
+ match Ast0.unwrap t with
+ Ast0.FILEINFO(old_file,new_file) ->
+ bind (string_mcode old_file) (string_mcode new_file)
+ | Ast0.DECL(stmt_dots) -> statement stmt_dots
+ | Ast0.CODE(stmt_dots) -> statement_dots stmt_dots
+ | Ast0.ERRORWORDS(exps) -> multibind (List.map expression exps)
+ | Ast0.OTHER(_) -> failwith "unexpected code" in
+ topfn all_functions k t
+ and all_functions =
+ {combiner_ident = ident;
+ combiner_expression = expression;
+ combiner_typeC = typeC;
+ combiner_declaration = declaration;
+ combiner_initialiser = initialiser;
+ combiner_initialiser_list = initialiser_dots;
+ combiner_parameter = parameterTypeDef;
+ combiner_parameter_list = parameter_dots;
+ combiner_statement = statement;
+ combiner_case_line = case_line;
+ combiner_top_level = top_level;
+ combiner_expression_dots = expression_dots;
+ combiner_statement_dots = statement_dots;
+ combiner_declaration_dots = declaration_dots;
+ combiner_case_line_dots = case_line_dots;
+ combiner_anything = anything} in
+ all_functions
+
+(* --------------------------------------------------------------------- *)
+(* Generic traversal: rebuilder *)
+
+type 'a inout = 'a -> 'a (* for specifying the type of rebuilder *)
+
+type rebuilder =
+ {rebuilder_ident : Ast0.ident inout;
+ rebuilder_expression : Ast0.expression inout;
+ rebuilder_typeC : Ast0.typeC inout;
+ rebuilder_declaration : Ast0.declaration inout;
+ rebuilder_initialiser : Ast0.initialiser inout;
+ rebuilder_initialiser_list : Ast0.initialiser_list inout;
+ rebuilder_parameter : Ast0.parameterTypeDef inout;
+ rebuilder_parameter_list : Ast0.parameter_list inout;
+ rebuilder_statement : Ast0.statement inout;
+ rebuilder_case_line : Ast0.case_line inout;
+ rebuilder_top_level : Ast0.top_level inout;
+ rebuilder_expression_dots :
+ Ast0.expression Ast0.dots ->
+ Ast0.expression Ast0.dots;
+ rebuilder_statement_dots :
+ Ast0.statement Ast0.dots ->
+ Ast0.statement Ast0.dots;
+ rebuilder_declaration_dots :
+ Ast0.declaration Ast0.dots ->
+ Ast0.declaration Ast0.dots;
+ rebuilder_case_line_dots :
+ Ast0.case_line Ast0.dots ->
+ Ast0.case_line Ast0.dots;
+ rebuilder_anything :
+ Ast0.anything -> Ast0.anything}
+
+type 'mc rmcode = 'mc Ast0.mcode inout
+type 'cd rcode = rebuilder -> ('cd inout) -> 'cd inout
+
+let rebuilder = fun
+ meta_mcode string_mcode const_mcode assign_mcode fix_mcode unary_mcode
+ binary_mcode cv_mcode base_mcode sign_mcode struct_mcode storage_mcode
+ inc_mcode
+ dotsexprfn dotsinitfn dotsparamfn dotsstmtfn dotsdeclfn dotscasefn
+ identfn exprfn tyfn initfn paramfn declfn stmtfn casefn topfn ->
+ let get_option f = function
+ Some x -> Some (f x)
+ | None -> None in
+ let rec expression_dots d =
+ let k d =
+ Ast0.rewrap d
+ (match Ast0.unwrap d with
+ Ast0.DOTS(l) -> Ast0.DOTS(List.map expression l)
+ | Ast0.CIRCLES(l) -> Ast0.CIRCLES(List.map expression l)
+ | Ast0.STARS(l) -> Ast0.STARS(List.map expression l)) in
+ dotsexprfn all_functions k d
+ and initialiser_list i =
+ let k i =
+ Ast0.rewrap i
+ (match Ast0.unwrap i with
+ Ast0.DOTS(l) -> Ast0.DOTS(List.map initialiser l)
+ | Ast0.CIRCLES(l) -> Ast0.CIRCLES(List.map initialiser l)
+ | Ast0.STARS(l) -> Ast0.STARS(List.map initialiser l)) in
+ dotsinitfn all_functions k i
+ and parameter_list d =
+ let k d =
+ Ast0.rewrap d
+ (match Ast0.unwrap d with
+ Ast0.DOTS(l) -> Ast0.DOTS(List.map parameterTypeDef l)
+ | Ast0.CIRCLES(l) -> Ast0.CIRCLES(List.map parameterTypeDef l)
+ | Ast0.STARS(l) -> Ast0.STARS(List.map parameterTypeDef l)) in
+ dotsparamfn all_functions k d
+ and statement_dots d =
+ let k d =
+ Ast0.rewrap d
+ (match Ast0.unwrap d with
+ Ast0.DOTS(l) -> Ast0.DOTS(List.map statement l)
+ | Ast0.CIRCLES(l) -> Ast0.CIRCLES(List.map statement l)
+ | Ast0.STARS(l) -> Ast0.STARS(List.map statement l)) in
+ dotsstmtfn all_functions k d
+ and declaration_dots d =
+ let k d =
+ Ast0.rewrap d
+ (match Ast0.unwrap d with
+ Ast0.DOTS(l) -> Ast0.DOTS(List.map declaration l)
+ | Ast0.CIRCLES(l) -> Ast0.CIRCLES(List.map declaration l)
+ | Ast0.STARS(l) -> Ast0.STARS(List.map declaration l)) in
+ dotsdeclfn all_functions k d
+ and case_line_dots d =
+ let k d =
+ Ast0.rewrap d
+ (match Ast0.unwrap d with
+ Ast0.DOTS(l) -> Ast0.DOTS(List.map case_line l)
+ | Ast0.CIRCLES(l) -> Ast0.CIRCLES(List.map case_line l)
+ | Ast0.STARS(l) -> Ast0.STARS(List.map case_line l)) in
+ dotscasefn all_functions k d
+ and ident i =
+ let k i =
+ Ast0.rewrap i
+ (match Ast0.unwrap i with
+ Ast0.Id(name) -> Ast0.Id(string_mcode name)
+ | Ast0.MetaId(name,constraints,pure) ->
+ Ast0.MetaId(meta_mcode name,constraints,pure)
+ | Ast0.MetaFunc(name,constraints,pure) ->
+ Ast0.MetaFunc(meta_mcode name,constraints,pure)
+ | Ast0.MetaLocalFunc(name,constraints,pure) ->
+ Ast0.MetaLocalFunc(meta_mcode name,constraints,pure)
+ | Ast0.OptIdent(id) -> Ast0.OptIdent(ident id)
+ | Ast0.UniqueIdent(id) -> Ast0.UniqueIdent(ident id)) in
+ identfn all_functions k i
+ and expression e =
+ let k e =
+ Ast0.rewrap e
+ (match Ast0.unwrap e with
+ Ast0.Ident(id) -> Ast0.Ident(ident id)
+ | Ast0.Constant(const) -> Ast0.Constant(const_mcode const)
+ | Ast0.FunCall(fn,lp,args,rp) ->
+ Ast0.FunCall(expression fn,string_mcode lp,expression_dots args,
+ string_mcode rp)
+ | Ast0.Assignment(left,op,right,simple) ->
+ Ast0.Assignment(expression left,assign_mcode op,expression right,
+ simple)
+ | Ast0.CondExpr(exp1,why,exp2,colon,exp3) ->
+ Ast0.CondExpr(expression exp1, string_mcode why,
+ get_option expression exp2, string_mcode colon,
+ expression exp3)
+ | Ast0.Postfix(exp,op) -> Ast0.Postfix(expression exp, fix_mcode op)
+ | Ast0.Infix(exp,op) -> Ast0.Infix(expression exp, fix_mcode op)
+ | Ast0.Unary(exp,op) -> Ast0.Unary(expression exp, unary_mcode op)
+ | Ast0.Binary(left,op,right) ->
+ Ast0.Binary(expression left, binary_mcode op, expression right)
+ | Ast0.Nested(left,op,right) ->
+ Ast0.Nested(expression left, binary_mcode op, expression right)
+ | Ast0.Paren(lp,exp,rp) ->
+ Ast0.Paren(string_mcode lp, expression exp, string_mcode rp)
+ | Ast0.ArrayAccess(exp1,lb,exp2,rb) ->
+ Ast0.ArrayAccess(expression exp1,string_mcode lb,expression exp2,
+ string_mcode rb)
+ | Ast0.RecordAccess(exp,pt,field) ->
+ Ast0.RecordAccess(expression exp, string_mcode pt, ident field)
+ | Ast0.RecordPtAccess(exp,ar,field) ->
+ Ast0.RecordPtAccess(expression exp, string_mcode ar, ident field)
+ | Ast0.Cast(lp,ty,rp,exp) ->
+ Ast0.Cast(string_mcode lp, typeC ty, string_mcode rp,
+ expression exp)
+ | Ast0.SizeOfExpr(szf,exp) ->
+ Ast0.SizeOfExpr(string_mcode szf, expression exp)
+ | Ast0.SizeOfType(szf,lp,ty,rp) ->
+ Ast0.SizeOfType(string_mcode szf,string_mcode lp, typeC ty,
+ string_mcode rp)
+ | Ast0.TypeExp(ty) -> Ast0.TypeExp(typeC ty)
+ | Ast0.MetaErr(name,constraints,pure) ->
+ Ast0.MetaErr(meta_mcode name,constraints,pure)
+ | Ast0.MetaExpr(name,constraints,ty,form,pure) ->
+ Ast0.MetaExpr(meta_mcode name,constraints,ty,form,pure)
+ | Ast0.MetaExprList(name,lenname,pure) ->
+ Ast0.MetaExprList(meta_mcode name,lenname,pure)
+ | Ast0.EComma(cm) -> Ast0.EComma(string_mcode cm)
+ | Ast0.DisjExpr(starter,expr_list,mids,ender) ->
+ Ast0.DisjExpr(string_mcode starter,List.map expression expr_list,
+ List.map string_mcode mids,string_mcode ender)
+ | Ast0.NestExpr(starter,expr_dots,ender,whencode,multi) ->
+ Ast0.NestExpr(string_mcode starter,expression_dots expr_dots,
+ string_mcode ender, get_option expression whencode,
+ multi)
+ | Ast0.Edots(dots,whencode) ->
+ Ast0.Edots(string_mcode dots, get_option expression whencode)
+ | Ast0.Ecircles(dots,whencode) ->
+ Ast0.Ecircles(string_mcode dots, get_option expression whencode)
+ | Ast0.Estars(dots,whencode) ->
+ Ast0.Estars(string_mcode dots, get_option expression whencode)
+ | Ast0.OptExp(exp) -> Ast0.OptExp(expression exp)
+ | Ast0.UniqueExp(exp) -> Ast0.UniqueExp(expression exp)) in
+ exprfn all_functions k e
+ and typeC t =
+ let k t =
+ Ast0.rewrap t
+ (match Ast0.unwrap t with
+ Ast0.ConstVol(cv,ty) -> Ast0.ConstVol(cv_mcode cv,typeC ty)
+ | Ast0.BaseType(ty,sign) ->
+ Ast0.BaseType(base_mcode ty, get_option sign_mcode sign)
+ | Ast0.ImplicitInt(sign) -> Ast0.ImplicitInt(sign_mcode sign)
+ | Ast0.Pointer(ty,star) ->
+ Ast0.Pointer(typeC ty, string_mcode star)
+ | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
+ Ast0.FunctionPointer(typeC ty,string_mcode lp1,string_mcode star,
+ string_mcode rp1,string_mcode lp2,
+ parameter_list params,
+ string_mcode rp2)
+ | Ast0.FunctionType(ty,lp1,params,rp1) ->
+ Ast0.FunctionType(get_option typeC ty,
+ string_mcode lp1,parameter_list params,
+ string_mcode rp1)
+ | Ast0.Array(ty,lb,size,rb) ->
+ Ast0.Array(typeC ty, string_mcode lb,
+ get_option expression size, string_mcode rb)
+ | Ast0.StructUnionName(kind,name) ->
+ Ast0.StructUnionName (struct_mcode kind, get_option ident name)
+ | Ast0.StructUnionDef(ty,lb,decls,rb) ->
+ Ast0.StructUnionDef (typeC ty,
+ string_mcode lb, declaration_dots decls,
+ string_mcode rb)
+ | Ast0.TypeName(name) -> Ast0.TypeName(string_mcode name)
+ | Ast0.MetaType(name,pure) ->
+ Ast0.MetaType(meta_mcode name,pure)
+ | Ast0.DisjType(starter,types,mids,ender) ->
+ Ast0.DisjType(string_mcode starter,List.map typeC types,
+ List.map string_mcode mids,string_mcode ender)
+ | Ast0.OptType(ty) -> Ast0.OptType(typeC ty)
+ | Ast0.UniqueType(ty) -> Ast0.UniqueType(typeC ty)) in
+ tyfn all_functions k t
+ and declaration d =
+ let k d =
+ Ast0.rewrap d
+ (match Ast0.unwrap d with
+ Ast0.Init(stg,ty,id,eq,ini,sem) ->
+ Ast0.Init(get_option storage_mcode stg,
+ typeC ty, ident id, string_mcode eq, initialiser ini,
+ string_mcode sem)
+ | Ast0.UnInit(stg,ty,id,sem) ->
+ Ast0.UnInit(get_option storage_mcode stg,
+ typeC ty, ident id, string_mcode sem)
+ | Ast0.MacroDecl(name,lp,args,rp,sem) ->
+ Ast0.MacroDecl(ident name,string_mcode lp,
+ expression_dots args,
+ string_mcode rp,string_mcode sem)
+ | Ast0.TyDecl(ty,sem) -> Ast0.TyDecl(typeC ty, string_mcode sem)
+ | Ast0.Typedef(stg,ty,id,sem) ->
+ Ast0.Typedef(string_mcode stg, typeC ty, typeC id,
+ string_mcode sem)
+ | Ast0.DisjDecl(starter,decls,mids,ender) ->
+ Ast0.DisjDecl(string_mcode starter,List.map declaration decls,
+ List.map string_mcode mids,string_mcode ender)
+ | Ast0.Ddots(dots,whencode) ->
+ Ast0.Ddots(string_mcode dots, get_option declaration whencode)
+ | Ast0.OptDecl(decl) -> Ast0.OptDecl(declaration decl)
+ | Ast0.UniqueDecl(decl) -> Ast0.UniqueDecl(declaration decl)) in
+ declfn all_functions k d
+ and initialiser i =
+ let k i =
+ Ast0.rewrap i
+ (match Ast0.unwrap i with
+ Ast0.InitExpr(exp) -> Ast0.InitExpr(expression exp)
+ | Ast0.InitList(lb,initlist,rb) ->
+ Ast0.InitList(string_mcode lb, initialiser_list initlist,
+ string_mcode rb)
+ | Ast0.InitGccDotName(dot,name,eq,ini) ->
+ Ast0.InitGccDotName
+ (string_mcode dot, ident name, string_mcode eq, initialiser ini)
+ | Ast0.InitGccName(name,eq,ini) ->
+ Ast0.InitGccName(ident name, string_mcode eq, initialiser ini)
+ | Ast0.InitGccIndex(lb,exp,rb,eq,ini) ->
+ Ast0.InitGccIndex
+ (string_mcode lb, expression exp, string_mcode rb,
+ string_mcode eq, initialiser ini)
+ | Ast0.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini) ->
+ Ast0.InitGccRange
+ (string_mcode lb, expression exp1, string_mcode dots,
+ expression exp2, string_mcode rb, string_mcode eq,
+ initialiser ini)
+ | Ast0.IComma(cm) -> Ast0.IComma(string_mcode cm)
+ | Ast0.Idots(d,whencode) ->
+ Ast0.Idots(string_mcode d, get_option initialiser whencode)
+ | Ast0.OptIni(i) -> Ast0.OptIni(initialiser i)
+ | Ast0.UniqueIni(i) -> Ast0.UniqueIni(initialiser i)) in
+ initfn all_functions k i
+ and parameterTypeDef p =
+ let k p =
+ Ast0.rewrap p
+ (match Ast0.unwrap p with
+ Ast0.VoidParam(ty) -> Ast0.VoidParam(typeC ty)
+ | Ast0.Param(ty,id) -> Ast0.Param(typeC ty, get_option ident id)
+ | Ast0.MetaParam(name,pure) ->
+ Ast0.MetaParam(meta_mcode name,pure)
+ | Ast0.MetaParamList(name,lenname,pure) ->
+ Ast0.MetaParamList(meta_mcode name,lenname,pure)
+ | Ast0.PComma(cm) -> Ast0.PComma(string_mcode cm)
+ | Ast0.Pdots(dots) -> Ast0.Pdots(string_mcode dots)
+ | Ast0.Pcircles(dots) -> Ast0.Pcircles(string_mcode dots)
+ | Ast0.OptParam(param) -> Ast0.OptParam(parameterTypeDef param)
+ | Ast0.UniqueParam(param) ->
+ Ast0.UniqueParam(parameterTypeDef param)) in
+ paramfn all_functions k p
+ (* not done for combiner, because the statement is assumed to be already
+ represented elsewhere in the code *)
+ and process_bef_aft s =
+ Ast0.set_dots_bef_aft s
+ (match Ast0.get_dots_bef_aft s with
+ Ast0.NoDots -> Ast0.NoDots
+ | Ast0.DroppingBetweenDots(stm) ->
+ Ast0.DroppingBetweenDots(statement stm)
+ | Ast0.AddingBetweenDots(stm) ->
+ Ast0.AddingBetweenDots(statement stm))
+
+ and statement s =
+ let k s =
+ Ast0.rewrap s
+ (match Ast0.unwrap s with
+ Ast0.FunDecl(bef,fi,name,lp,params,rp,lbrace,body,rbrace) ->
+ Ast0.FunDecl(bef,List.map fninfo fi, ident name,
+ string_mcode lp, parameter_list params,
+ string_mcode rp, string_mcode lbrace,
+ statement_dots body, string_mcode rbrace)
+ | Ast0.Decl(bef,decl) -> Ast0.Decl(bef,declaration decl)
+ | Ast0.Seq(lbrace,body,rbrace) ->
+ Ast0.Seq(string_mcode lbrace, statement_dots body,
+ string_mcode rbrace)
+ | Ast0.ExprStatement(exp,sem) ->
+ Ast0.ExprStatement(expression exp, string_mcode sem)
+ | Ast0.IfThen(iff,lp,exp,rp,branch1,aft) ->
+ Ast0.IfThen(string_mcode iff, string_mcode lp, expression exp,
+ string_mcode rp, statement branch1,aft)
+ | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,aft) ->
+ Ast0.IfThenElse(string_mcode iff,string_mcode lp,expression exp,
+ string_mcode rp, statement branch1, string_mcode els,
+ statement branch2,aft)
+ | Ast0.While(whl,lp,exp,rp,body,aft) ->
+ Ast0.While(string_mcode whl, string_mcode lp, expression exp,
+ string_mcode rp, statement body, aft)
+ | Ast0.Do(d,body,whl,lp,exp,rp,sem) ->
+ Ast0.Do(string_mcode d, statement body, string_mcode whl,
+ string_mcode lp, expression exp, string_mcode rp,
+ string_mcode sem)
+ | Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,aft) ->
+ Ast0.For(string_mcode fr, string_mcode lp,
+ get_option expression e1, string_mcode sem1,
+ get_option expression e2, string_mcode sem2,
+ get_option expression e3,
+ string_mcode rp, statement body, aft)
+ | Ast0.Iterator(nm,lp,args,rp,body,aft) ->
+ Ast0.Iterator(ident nm, string_mcode lp,
+ expression_dots args,
+ string_mcode rp, statement body, aft)
+ | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) ->
+ Ast0.Switch(string_mcode switch,string_mcode lp,expression exp,
+ string_mcode rp,string_mcode lb,
+ case_line_dots cases, string_mcode rb)
+ | Ast0.Break(br,sem) ->
+ Ast0.Break(string_mcode br,string_mcode sem)
+ | Ast0.Continue(cont,sem) ->
+ Ast0.Continue(string_mcode cont,string_mcode sem)
+ | Ast0.Label(l,dd) -> Ast0.Label(ident l,string_mcode dd)
+ | Ast0.Goto(goto,l,sem) ->
+ Ast0.Goto(string_mcode goto,ident l,string_mcode sem)
+ | Ast0.Return(ret,sem) ->
+ Ast0.Return(string_mcode ret,string_mcode sem)
+ | Ast0.ReturnExpr(ret,exp,sem) ->
+ Ast0.ReturnExpr(string_mcode ret,expression exp,string_mcode sem)
+ | Ast0.MetaStmt(name,pure) ->
+ Ast0.MetaStmt(meta_mcode name,pure)
+ | Ast0.MetaStmtList(name,pure) ->
+ Ast0.MetaStmtList(meta_mcode name,pure)
+ | Ast0.Disj(starter,statement_dots_list,mids,ender) ->
+ Ast0.Disj(string_mcode starter,
+ List.map statement_dots statement_dots_list,
+ List.map string_mcode mids,
+ string_mcode ender)
+ | Ast0.Nest(starter,stmt_dots,ender,whn,multi) ->
+ Ast0.Nest(string_mcode starter,statement_dots stmt_dots,
+ string_mcode ender,
+ List.map (whencode statement_dots statement) whn,
+ multi)
+ | Ast0.Exp(exp) -> Ast0.Exp(expression exp)
+ | Ast0.TopExp(exp) -> Ast0.TopExp(expression exp)
+ | Ast0.Ty(ty) -> Ast0.Ty(typeC ty)
+ | Ast0.TopInit(init) -> Ast0.TopInit(initialiser init)
+ | Ast0.Dots(d,whn) ->
+ Ast0.Dots(string_mcode d,
+ List.map (whencode statement_dots statement) whn)
+ | Ast0.Circles(d,whn) ->
+ Ast0.Circles(string_mcode d,
+ List.map (whencode statement_dots statement) whn)
+ | Ast0.Stars(d,whn) ->
+ Ast0.Stars(string_mcode d,
+ List.map (whencode statement_dots statement) whn)
+ | Ast0.Include(inc,name) ->
+ Ast0.Include(string_mcode inc,inc_mcode name)
+ | Ast0.Define(def,id,params,body) ->
+ Ast0.Define(string_mcode def,ident id,
+ define_parameters params,
+ statement_dots body)
+ | Ast0.OptStm(re) -> Ast0.OptStm(statement re)
+ | Ast0.UniqueStm(re) -> Ast0.UniqueStm(statement re)) in
+ let s = stmtfn all_functions k s in
+ process_bef_aft s
+
+ (* not parameterizable for now... *)
+ and define_parameters p =
+ let k p =
+ Ast0.rewrap p
+ (match Ast0.unwrap p with
+ Ast0.NoParams -> Ast0.NoParams
+ | Ast0.DParams(lp,params,rp) ->
+ Ast0.DParams(string_mcode lp,define_param_dots params,
+ string_mcode rp))in
+ k p
+
+ and define_param_dots d =
+ let k d =
+ Ast0.rewrap d
+ (match Ast0.unwrap d with
+ Ast0.DOTS(l) -> Ast0.DOTS(List.map define_param l)
+ | Ast0.CIRCLES(l) -> Ast0.CIRCLES(List.map define_param l)
+ | Ast0.STARS(l) -> Ast0.STARS(List.map define_param l)) in
+ k d
+
+ and define_param p =
+ let k p =
+ Ast0.rewrap p
+ (match Ast0.unwrap p with
+ Ast0.DParam(id) -> Ast0.DParam(ident id)
+ | Ast0.DPComma(comma) -> Ast0.DPComma(string_mcode comma)
+ | Ast0.DPdots(d) -> Ast0.DPdots(string_mcode d)
+ | Ast0.DPcircles(c) -> Ast0.DPcircles(string_mcode c)
+ | Ast0.OptDParam(dp) -> Ast0.OptDParam(define_param dp)
+ | Ast0.UniqueDParam(dp) -> Ast0.UniqueDParam(define_param dp)) in
+ k p
+
+ and fninfo = function
+ Ast0.FStorage(stg) -> Ast0.FStorage(storage_mcode stg)
+ | Ast0.FType(ty) -> Ast0.FType(typeC ty)
+ | Ast0.FInline(inline) -> Ast0.FInline(string_mcode inline)
+ | Ast0.FAttr(init) -> Ast0.FAttr(string_mcode init)
+
+ and whencode notfn alwaysfn = function
+ Ast0.WhenNot a -> Ast0.WhenNot (notfn a)
+ | Ast0.WhenAlways a -> Ast0.WhenAlways (alwaysfn a)
+ | Ast0.WhenModifier(x) -> Ast0.WhenModifier(x)
+ | Ast0.WhenNotTrue(e) -> Ast0.WhenNotTrue(expression e)
+ | Ast0.WhenNotFalse(e) -> Ast0.WhenNotFalse(expression e)
+
+ and case_line c =
+ let k c =
+ Ast0.rewrap c
+ (match Ast0.unwrap c with
+ Ast0.Default(def,colon,code) ->
+ Ast0.Default(string_mcode def,string_mcode colon,
+ statement_dots code)
+ | Ast0.Case(case,exp,colon,code) ->
+ Ast0.Case(string_mcode case,expression exp,string_mcode colon,
+ statement_dots code)
+ | Ast0.OptCase(case) -> Ast0.OptCase(case_line case)) in
+ casefn all_functions k c
+
+ and top_level t =
+ let k t =
+ Ast0.rewrap t
+ (match Ast0.unwrap t with
+ Ast0.FILEINFO(old_file,new_file) ->
+ Ast0.FILEINFO(string_mcode old_file, string_mcode new_file)
+ | Ast0.DECL(statement_dots) ->
+ Ast0.DECL(statement statement_dots)
+ | Ast0.CODE(stmt_dots) -> Ast0.CODE(statement_dots stmt_dots)
+ | Ast0.ERRORWORDS(exps) -> Ast0.ERRORWORDS(List.map expression exps)
+ | Ast0.OTHER(_) -> failwith "unexpected code") in
+ topfn all_functions k t
+
+ and anything a = (* for compile_iso, not parameterisable *)
+ let k = function
+ Ast0.DotsExprTag(exprs) -> Ast0.DotsExprTag(expression_dots exprs)
+ | Ast0.DotsInitTag(inits) -> Ast0.DotsInitTag(initialiser_list inits)
+ | Ast0.DotsParamTag(params) -> Ast0.DotsParamTag(parameter_list params)
+ | Ast0.DotsStmtTag(stmts) -> Ast0.DotsStmtTag(statement_dots stmts)
+ | Ast0.DotsDeclTag(decls) -> Ast0.DotsDeclTag(declaration_dots decls)
+ | Ast0.DotsCaseTag(cases) -> Ast0.DotsCaseTag(case_line_dots cases)
+ | Ast0.IdentTag(id) -> Ast0.IdentTag(ident id)
+ | Ast0.ExprTag(exp) -> Ast0.ExprTag(expression exp)
+ | Ast0.ArgExprTag(exp) -> Ast0.ArgExprTag(expression exp)
+ | Ast0.TestExprTag(exp) -> Ast0.TestExprTag(expression exp)
+ | Ast0.TypeCTag(ty) -> Ast0.TypeCTag(typeC ty)
+ | Ast0.ParamTag(param) -> Ast0.ParamTag(parameterTypeDef param)
+ | Ast0.InitTag(init) -> Ast0.InitTag(initialiser init)
+ | Ast0.DeclTag(decl) -> Ast0.DeclTag(declaration decl)
+ | Ast0.StmtTag(stmt) -> Ast0.StmtTag(statement stmt)
+ | Ast0.CaseLineTag(c) -> Ast0.CaseLineTag(case_line c)
+ | Ast0.TopTag(top) -> Ast0.TopTag(top_level top)
+ | Ast0.IsoWhenTag(x) -> Ast0.IsoWhenTag(x)
+ | Ast0.IsoWhenTTag(e) -> Ast0.IsoWhenTTag(expression e)
+ | Ast0.IsoWhenFTag(e) -> Ast0.IsoWhenFTag(expression e)
+ | Ast0.MetaPosTag(var) -> failwith "not supported" in
+ k a
+
+ (* not done for combiner, because the statement is assumed to be already
+ represented elsewhere in the code *)
+
+ and all_functions =
+ {rebuilder_ident = ident;
+ rebuilder_expression = expression;
+ rebuilder_typeC = typeC;
+ rebuilder_declaration = declaration;
+ rebuilder_initialiser = initialiser;
+ rebuilder_initialiser_list = initialiser_list;
+ rebuilder_parameter = parameterTypeDef;
+ rebuilder_parameter_list = parameter_list;
+ rebuilder_statement = statement;
+ rebuilder_case_line = case_line;
+ rebuilder_top_level = top_level;
+ rebuilder_expression_dots = expression_dots;
+ rebuilder_statement_dots = statement_dots;
+ rebuilder_declaration_dots = declaration_dots;
+ rebuilder_case_line_dots = case_line_dots;
+ rebuilder_anything = anything} in
+ all_functions
let rec reverse_type ty =
match ty with
Type_cocci.ConstVol(cv,ty) ->
- ConstVol(reverse_const_vol cv,wrap(reverse_type ty))
+ ConstVol(reverse_const_vol cv,context_wrap(reverse_type ty))
| Type_cocci.BaseType(bty,None) ->
BaseType(reverse_baseType bty,None)
| Type_cocci.BaseType(bty,Some sgn) ->
BaseType(reverse_baseType bty,Some (reverse_sign sgn))
| Type_cocci.Pointer(ty) ->
- Pointer(wrap(reverse_type ty),make_mcode "*")
+ Pointer(context_wrap(reverse_type ty),make_mcode "*")
| Type_cocci.StructUnionName(su,mv,tag) ->
if mv
then
(* not right... *)
- StructUnionName(reverse_structUnion su,
- Some(wrap(MetaId(make_mcode ("",tag),[],Impure))))
+ StructUnionName
+ (reverse_structUnion su,
+ Some(context_wrap(MetaId(make_mcode ("",tag),[],Impure))))
else
- StructUnionName(reverse_structUnion su,
- Some (wrap(Id(make_mcode tag))))
+ StructUnionName
+ (reverse_structUnion su,
+ Some (context_wrap(Id(make_mcode tag))))
| Type_cocci.TypeName(name) -> TypeName(make_mcode name)
| Type_cocci.MetaType(name,_,_) ->
MetaType(make_mcode name,Impure(*not really right*))
| Ast0.Disj(_,stmts,_,_) -> isall is_ty stmts
| _ -> false
+let rec is_init s =
+ match Ast0.unwrap s with
+ Ast0.TopInit(e) -> true
+ | Ast0.Disj(_,stmts,_,_) -> isall is_init stmts
+ | _ -> false
+
let rec is_decl s =
match Ast0.unwrap s with
Ast0.Decl(_,e) -> true
let v2 = is_decl decl2 in
if v1 && not v2 then fail()
| (Ast0.CODE(code1),Ast0.CODE(code2)) ->
- let testers = [is_exp;is_ty] in
- List.iter
- (function tester ->
- let v1 = isonly tester code1 in
- let v2 = isonly tester code2 in
- if (v1 && not v2) or (!Flag.make_hrule = None && v2 && not v1)
- then fail())
- testers;
- let v1 = isonly is_fndecl code1 in
- let v2 = List.for_all is_toplevel (Ast0.undots code2) in
- if !Flag.make_hrule = None && v1 && not v2 then fail()
+ let v1 = isonly is_init code1 in
+ let v2a = isonly is_init code2 in
+ let v2b = isonly is_exp code2 in
+ if v1
+ then (if not (v2a || v2b) then fail())
+ else
+ let testers = [is_exp;is_ty] in
+ List.iter
+ (function tester ->
+ let v1 = isonly tester code1 in
+ let v2 = isonly tester code2 in
+ if (v1 && not v2) or (!Flag.make_hrule = None && v2 && not v1)
+ then fail())
+ testers;
+ let v1 = isonly is_fndecl code1 in
+ let v2 = List.for_all is_toplevel (Ast0.undots code2) in
+ if !Flag.make_hrule = None && v1 && not v2 then fail()
| (Ast0.FILEINFO(_,_),Ast0.FILEINFO(_,_)) -> ()
| (Ast0.OTHER(_),Ast0.OTHER(_)) -> ()
| _ -> fail()
| NonMatch
| Braces of Ast0.statement
| Position of string * string
+ | TypeMatch of reason list
-let interpret_reason name line reason printer =
+let rec interpret_reason name line reason printer =
Printf.printf
"warning: iso %s does not match the code below on line %d\n" name line;
printer(); Format.print_newline();
| Position(rule,name) ->
Printf.printf "position variable %s.%s conflicts with an isomorphism\n"
rule name;
+ | TypeMatch reason_list ->
+ List.iter (function r -> interpret_reason name line r printer)
+ reason_list
| _ -> failwith "not possible"
type 'a either = OK of 'a | Fail of reason
let pure_sp_code =
let bind = Ast0.lub_pure in
let option_default = Ast0.Context in
- let pure_mcodekind = function
- Ast0.CONTEXT(mc) ->
- (match !mc with
- (Ast.NOTHING,_,_) -> Ast0.PureContext
- | _ -> Ast0.Context)
- | Ast0.MINUS(mc) ->
- (match !mc with ([],_) -> Ast0.Pure | _ -> Ast0.Impure)
- | _ -> Ast0.Impure in
+ let pure_mcodekind mc =
+ if !Flag.sgrep_mode2
+ then Ast0.PureContext
+ else
+ match mc with
+ Ast0.CONTEXT(mc) ->
+ (match !mc with
+ (Ast.NOTHING,_,_) -> Ast0.PureContext
+ | _ -> Ast0.Context)
+ | Ast0.MINUS(mc) ->
+ (match !mc with ([],_) -> Ast0.Pure | _ -> Ast0.Impure)
+ | _ -> Ast0.Impure in
let donothing r k e =
bind (pure_mcodekind (Ast0.get_mcodekind e)) (k e) in
(match expty with
Some expty ->
let tyname = Ast0.rewrap_mcode name tyname in
- (function bindings ->
- let attempts =
- List.map
- (function expty ->
- (try
- conjunct_bindings
- (add_pure_binding tyname Ast0.Impure
- (function _ -> Ast0.Impure)
- (function ty -> Ast0.TypeCTag ty)
- (Ast0.rewrap expr
- (Ast0.reverse_type expty)))
- (add_pure_binding name pure
- pure_sp_code.V0.combiner_expression
- (function expr -> Ast0.ExprTag expr)
- expr)
- bindings
- with Ast0.TyConv ->
- Printf.printf "warning: unconvertible type";
- return false bindings))
- expty in
- match
- List.concat
- (List.map (function Fail _ -> [] | OK x -> x)
- attempts)
- with
- [] -> Fail NonMatch
- | x -> OK x)
- | _ ->
+ conjunct_bindings
+ (add_pure_binding name pure
+ pure_sp_code.V0.combiner_expression
+ (function expr -> Ast0.ExprTag expr)
+ expr)
+ (function bindings ->
+ let attempts =
+ List.map
+ (function expty ->
+ (try
+ add_pure_binding tyname Ast0.Impure
+ (function _ -> Ast0.Impure)
+ (function ty -> Ast0.TypeCTag ty)
+ (Ast0.rewrap expr
+ (Ast0.reverse_type expty))
+ bindings
+ with Ast0.TyConv ->
+ Printf.printf
+ "warning: unconvertible type";
+ return false bindings))
+ expty in
+ if List.exists
+ (function Fail _ -> false | OK x -> true)
+ attempts
+ then
+ (* not sure why this is ok. can there be more
+ than one OK? *)
+ OK (List.concat
+ (List.map
+ (function Fail _ -> [] | OK x -> x)
+ attempts))
+ else
+ Fail
+ (TypeMatch
+ (List.map
+ (function
+ Fail r -> r
+ | OK x -> failwith "not possible")
+ attempts)))
+ | _ ->
(*Printf.printf
"warning: type metavar can only match one type";*)
return false)
Ast0.DOTS([]) ->
(* if context is - this should be - as well. There are no tokens
here though, so the bottom-up minusifier in context_neg leaves it
- as mixed. It would be better to fix context_neg, but that would
+ as mixed (or context for sgrep2). It would be better to fix
+ context_neg, but that would
require a special case for each term with a dots subterm. *)
(match !mcodekind with
- Ast0.MIXED(mc) ->
+ Ast0.MIXED(mc) | Ast0.CONTEXT(mc) ->
(match !mc with
(Ast.NOTHING,_,_) ->
mcodekind := Ast0.MINUS(ref([],Ast0.default_token_info));
| _ ->
failwith
(Printf.sprintf
- "%d: make_minus donothingxxx: unexpected mcodekind"
- info.Ast0.line_start))
+ "%d: make_minus donothingxxx: unexpected mcodekind: %s"
+ info.Ast0.line_start (Dumper.dump e)))
| _ -> donothing r k e in
V0.rebuilder
(function b -> function mv_b ->
(instantiate b mv_b).V0.rebuilder_expression)
(function e -> Ast0.ExprTag e)
- (make_disj_expr e) make_minus.V0.rebuilder_expression
+ (make_disj_expr e)
+ make_minus.V0.rebuilder_expression
(rebuild_mcode start_line).V0.rebuilder_expression
name Unparse_ast0.expression extra_copy_other_plus update_others in
match alts with
(function s -> Ast0.DotsStmtTag s)
(function x ->
Ast0.rewrap e (Ast0.DOTS([make_disj_stmt_list x])))
- make_minus.V0.rebuilder_statement_dots
+ (function x ->
+ make_minus.V0.rebuilder_statement_dots x)
(rebuild_mcode start_line).V0.rebuilder_statement_dots
name Unparse_ast0.statement_dots extra_copy_other_plus do_nothing
| _ -> ([],stmts) in
Obj.repr _v
let default_reduction =
- (16, "\000\000\000\000\001 \001!\000\000\001#\001\"\000\001\000\000\001[\000\000\000\000\000\136\000\000\000\000\001\214\000\142\000\145\002\197\002\196\000\146\001\013\001\019\001\015\001\018\001\017\000\135\001\011\001\026\000\000\000\000\001\025\000\000\000\000\000\000\000\000\000\000\001O\000\232\002\187\002q\000\000\000\000\000\000\000\000\000\000\002\192\000\000\001\022\000\000\002\194\000\000\001\029\001\028\000\000\000\000\002\252\002;\000\000\002\250\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\253\000\000\002U\000\000\000\000\002\249\002\251\002A\001\004\002@\001\002\001\003\002?\002>\002=\0029\000\000\000\000\002:\000\205\000\000\002<\000\000\002\248\000\000\002\223\001\001\002\028\000\000\000\000\002\031\000\000\000\015\000\000\000\000\000\000\000\000\000\206\0028\002D\000[\000\021\000]\000\000\000\000\000c\000\000\000\000\000\000\000\000\000\000\000\000\000\022\000\000\000\023\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\130\001\251\000R\000\215\000^\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\\\000T\000\000\000S\000\000\000\000\000\140\000\216\000\000\002\"\000\217\000\014\000\000\001\014\001\020\001\016\001\012\000\016\000\000\000\000\000\143\000\000\000\141\000\000\000\000\000\220\000\000\000\000\002\029\002 \000\000\002\030\002!\002\224\002\222\000\000\002B\002\221\000\000\002]\000\000\000\000\001\190\000\000\001i\001\171\000\000\000\000\002\\\000\000\002\240\002[\002Z\002Y\002X\002W\002S\000\000\000\000\002T\000\000\002V\000\000\000\000\002\237\002*\000\000\000\000\002-\000\000\000\000\0020\000\000\000\000\002+\002.\000\000\002,\002/\002^\002R\002\238\002\236\002\235\002\239\000\000\000\000\000\000\000g\000h\000\000\000\000\000W\000\000\000V\000\227\000\000\001\206\000\000\000\000\000\000\000\000\000\000\000\210\001\212\000\000\000\000\001s\000U\0001\000\203\000_\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\000\000\0003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002C\000\000\000\144\000\000\000\000\001\189\000\000\001g\001\170\000\000\000\000\000d\000\000\002\255\000\000\000\000\001\207\000\000\000\000\002\226\002\225\000\000\000Q\000\147\000\000\001Q\000\000\002\190\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\226\000\151\000\000\000\000\000n\000o\001\225\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\160\001\195\000\000\000\148\000\155\000\000\001\197\000\000\000\000\000\000\000\000\000\149\000\161\000\000\001W\000\000\000\000\002\189\000\000\000\000\000\138\000\000\000\000\002\188\000\000\000\000\000\000\002\191\002\195\000\000\000\000\000\000\001\023\000\000\000\214\000\000\001\024\000\000\000\000\001:\000\000\0019\000\000\001G\000\000\001]\000\000\000\000\000\000\000\000\000\000\000\000\001\008\000\000\000\000\002\219\000\000\000\189\002\218\002\183\002\185\002\186\002\184\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002b\000\000\000\000\000\000\000\000\002i\000\000\000\000\002h\002g\002f\002e\002d\0016\002`\000\000\000\000\002a\000\000\002c\000\000\000\000\002\244\0021\000\000\000\000\0024\000\000\000\000\0027\000\000\000\000\0022\0025\000\000\0023\0026\002k\002_\002\245\002\243\002\242\000i\000j\000\000\000\000\000Z\000\000\000Y\000\000\002j\000\000\001\172\000X\000?\000\226\000`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\134\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\247\002\246\000\000\002\174\000\000\002\173\000\000\000\000\000\000\000\000\003\004\000\000\000\000\000\000\003\005\000\000\000\018\000\000\000\000\000\000\003\000\000\000\001u\000\000\000\000\000\000\000\162\002\164\001M\000\000\000\153\001L\001%\001$\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\178\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\207\000\208\000\195\000\000\001Y\000\000\000\000\000\194\000\190\000\000\000\197\000\191\000\196\000\000\002\176\000\000\002\175\002\161\000\000\000\000\000\000\000\000\000\000\002\170\000\000\000\000\000\000\000\000\000\000\002\171\002\163\000\000\002\177\000\000\002\165\000\000\000\166\000\000\002\180\000\152\000\000\001'\000\000\000\000\000\000\000\000\000\000\000\000\001\t\000\000\000w\000\000\000\000\000\000\002H\000\000\000\000\000\000\002P\000\000\000\000\002O\000\000\002\233\002N\002M\002L\002K\002J\002F\000\000\000\000\002G\000\000\002I\000\000\000\000\002\230\002#\000\000\000\000\002&\000\000\000\000\002)\000\000\000\000\002$\002'\000\000\002%\002(\002Q\002E\002\231\002\229\002\228\002\232\000\000\000\000\000\000\000e\000f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\212\001(\000\000\000\000\000\000\001.\000\000\000\000\001/\000#\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000$\000\000\000%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001-\0012\000\000\001,\000\000\000\000\0014\000\000\000\000\000\000\000\000\000\000\000\000\000t\000q\000r\0015\0011\000\000\000\000\0010\001*\000\000\001)\000\000\000\182\000\000\002\142\000\000\000\000\000\178\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\185\000\000\000\000\000\188\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\007\000\000\000\000\000\000\000\175\000\000\000\172\000\000\000\000\000\000\000\000\000\000\000\183\000\000\000\179\000\000\000\000\002\201\000\000\002\208\000\168\000\000\000\000\000\000\000\000\000\180\000\000\000\176\000\173\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\184\000\000\000\000\000\187\000\000\002\202\000\167\000\000\002\203\000\000\002\210\000\000\000\000\000\000\000\000\000\186\000\000\000\170\000\000\000\000\000\000\000\000\001\006\000\000\000\000\000\000\000\174\000\000\000\171\000\000\000\000\000\000\000\000\000\000\000\181\000\000\000\177\000\164\000\163\000\000\002\211\002\212\000\000\002\213\000\000\002\214\000\000\001&\002\168\000\000\000\000\001\194\000\000\001q\001\176\000\000\002\162\000\000\000\000\000\000\002\167\000\000\000\000\000\000\000\250\000\000\000\244\000\000\000\245\000\000\000\255\000\243\000\254\000\000\002\179\001\000\000\000\000\169\000\000\000\000\000\000\000\000\000\252\000\247\001\191\000\000\000\248\000\000\000\249\000\000\001k\001\173\000\000\000\000\000\000\001\202\000\000\001\200\000\000\000\000\001\204\001\198\000\000\001\205\001\199\000\000\002\181\001\208\000\000\000\165\000\000\000\000\001\192\000\000\001m\001\174\000\000\003\001\000\000\002\253\000\000\002\254\000\019\000\020\000\000\000\000\002\127\000\000\002~\000\000\000\000\002\129\000\000\002\128\000\000\000\000\000\000\001\235\000\000\000\000\001\239\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\242\000\000\000\000\001\245\000\000\000\000\001\229\000\000\000\000\001\232\000\000\000\000\000\000\001\236\000\000\000\000\001\240\000\000\000\000\001\193\000\000\000\000\001\233\000\000\000\000\001\237\002|\001\230\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\241\000\000\000\000\001\244\000\000\002}\000\000\000\000\000\000\000\000\001\243\000\000\001\227\000\000\001\228\000\000\000\000\001\231\000\000\000\000\000\000\001\234\000\000\000\000\001\238\000\000\001o\001\175\000\000\002\130\000\000\000\000\000\000\003\002\000\017\000u\000\000\003\003\000\000\000\000\002\138\000\000\000\000\002\182\000a\000\000\000\000\000\000\000b\000\000\002\172\000\000\001S\002\169\000\000\000\000\001@\000\000\001?\000\000\001H\000\000\001c\000\000\000\000\000\000\001>\000\000\001=\000\000\001E\000\000\001a\000\000\000\000\000\000\001B\000\000\001A\000\000\001F\000\000\001e\000\000\000\000\000\000\001C\000\000\000\000\000\000\000\000\001<\000\000\001;\000\000\001I\000\000\001_\000\000\000\000\000\000\001D\000\002\000\000\000N\000O\000M\001J\000\003\000\000\000\000\002n\000\000\001\249\000\000\002t\002v\000\000\000\000\001\140\002u\000\128\000\000\000\000\002\160\000\000\000\000\000\000\000z\000\000\000\000\002\148\000\000\001\222\001\221\001\135\002z\002r\002s\000\000\001\167\000\000\002o\000\000\000\000\000|\000\000\000\000\002\152\000\000\001\149\000\000\000\000\001\146\000\000\000\000\000\000\001\148\000\000\001\147\000\000\000\000\000\000\000\000\000\000\000\000\001\168\000\000\001\144\000\000\001\143\000\000\000v\000\000\000\000\002\140\000\000\000\000\001\139\000\000\000\000\000~\000\000\000\000\002\156\000\000\000\000\000\000\000{\000\000\000\000\002\150\000\000\001\218\001\217\001\131\002x\000\000\001\154\000\000\000\000\000\000\001\151\000\000\001\156\000\000\000\000\001\152\000\000\000\000\001\153\000\000\000\000\000\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\001\169\000\000\001\145\000}\000\000\000\000\002\154\000\000\000\000\000\000\001\031\000y\001\030\000\000\000\000\002\146\000\000\001\216\001\215\001\129\002w\000\000\000\127\000\000\000\000\002\158\000\000\000\000\000\000\000\000\001\220\001\219\001\133\002y\000\000\001\161\000\000\001\165\000\000\000\000\001\157\000\000\000\000\000\000\001\150\000\000\001\155\000\000\000\000\000\000\000\000\000\000\000\000\001\164\001\138\000\000\001\163\000\000\000\000\000\000\000\000\001\160\000\000\000\000\001\159\000\000\001\158\000\000\000\000\000\000\000\000\001\162\000\000\001\166\000\000\000\000\001K\000\004\000\000\001\141\000\005\000\000\000\000\000\230\000\006\000\000\001\180\001\181\001\179\000\000\000\000\000\000\000\000\000\000\000\000\000x\000\000\000\000\002\144\000\000\000\221\001\178\001{\002\198\001}\000\000\000\007\000\000\001\183\001\184\001\182\000\000\000\000\000\000\000\000\000\000\000\000\000\231\000\234\000\000\000\000\000\000\000\000\000\239\000\241\000\240\000\235\000\237\000\236\000\000\000\000\002\199\001\188\001\187\000\000\000\000\000\000\000\000\002\204\002\215\000\000\002\205\000\000\002\206\001\127\000\000\001\177\001\185\000\000\000\000\000\000\000\000\001\224\000\000\000\000\000l\000m\000\000\000\000\000\000\001\223\000\000\000\158\000\000\001U\000\000\000\000\000\157\000\154\000\000\000\000\000\000\000\000\001\005\000\000\000\000\002\216\000\000\002\217\000\000\000\000\001\211\001\209\000\000\001\210\000\008\000\000\000\t\000\000\002\012\002\013\002\011\000\000\000\000\002\n\000\000\000\n\000\000\002\015\002\016\002\014\000\000\002\018\000\000\000\000\000\000\002\004\000\000\000\000\002\006\000\000\002\000\000\000\002\002\000\000\002\007\000\000\002\008\002\001\001\255\002\019\001\137\000\000\002\t\000\000\002\021\000\000\002\020\000\000\002\022\000\000\002{\000\011\000\000\000\000\000\000\000\000\000\000\000\000\002\023\000\000\000\000\002\026\000\000\002\025\000\000\002\024\000\198\000\000\000\000\000\000\000\000\000\199\002\027\000\000\000\000\002\133\000\000\000\229\000\012\000\000\000\000\000\000\000\000\000\000\000\000\002\136\000k\000\000\000\000\000\204\000\000\000\000\000\224\000\223\000\222\000\000\0018\000\000\002\132\001y\001w\000\000\000\000\000\000\000\000\000\000\000\000\002\131\000\000\000\013\000\000\000\000\000\000\000\000\000\000\002\134")
+ (16, "\000\000\000\000\001 \001!\000\000\001#\001\"\000\001\000\000\001[\000\000\000\000\000\136\000\000\000\000\001\214\000\142\000\145\002\195\002\194\000\146\001\013\001\019\001\015\001\018\001\017\000\135\001\011\001\026\000\000\000\000\001\025\000\000\000\000\000\000\000\000\000\000\001O\000\232\002\185\002o\000\000\000\000\000\000\000\000\000\000\002\190\000\000\001\022\000\000\002\192\000\000\001\029\001\028\000\000\000\000\002\250\0029\000\000\002\248\000\000\002S\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\247\002\249\002?\001\004\002>\001\002\001\003\002=\002<\002;\0027\000\000\000\000\0028\000\205\000\000\002:\000\000\002\246\000\000\002\221\001\001\002\026\000\000\000\000\002\029\000\000\000\015\000\000\000\000\000\000\000\000\000\206\0026\002B\000[\000\021\000]\000\000\000\000\000c\000\000\000\000\000\000\000\000\000\000\000\000\000\022\000\000\000\023\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\130\001\251\000R\000\215\000^\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\\\000T\000\000\000S\000\000\000\000\000\140\000\216\000\000\002 \000\217\000\014\000\000\001\014\001\020\001\016\001\012\000\016\000\000\000\000\000\143\000\000\000\141\000\000\000\000\000\220\000\000\000\000\002\027\002\030\000\000\002\028\002\031\002\222\002\220\000\000\002@\002\219\000\000\002Z\000\000\000\000\002Y\002X\002W\002V\002U\002Q\000\000\000\000\002R\000\000\002T\000\000\000\000\002\235\002(\000\000\000\000\002+\000\000\000\000\002.\000\000\000\000\002)\002,\000\000\002*\002-\002\\\002P\002\236\002\234\002\233\000g\000h\000\000\000\000\000W\000\000\000V\000\227\000\000\001\206\000\000\000\000\000\000\000\000\000\000\000\210\001\212\000\000\000\000\001s\000U\0001\000\203\000_\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\000\000\0003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002A\000\000\000\144\000\000\000\000\001\190\000\000\001i\001\171\000\000\000\000\001\189\000\000\001g\001\170\000\000\000\000\000d\000\000\002[\000\000\000\000\002\238\002\237\000\000\001\207\000\000\000\000\002\224\002\223\000\000\000Q\000\147\000\000\001Q\000\000\002\188\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\226\000\151\000\000\000\000\000n\000o\001\225\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\160\001\195\000\000\000\148\000\155\000\000\001\197\000\000\000\000\000\000\000\000\000\149\000\161\000\000\001W\000\000\000\000\002\187\000\000\000\000\000\138\000\000\000\000\002\186\000\000\000\000\000\000\002\189\002\193\000\000\000\000\000\000\001\023\000\000\000\214\000\000\001\024\000\000\000\000\001:\000\000\0019\000\000\001G\000\000\001]\000\000\000\000\000\000\000\000\000\000\000\000\001\008\000\000\000\000\002\217\000\000\000\189\002\216\002\181\002\183\002\184\002\182\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002`\000\000\000\000\000\000\000\000\002g\000\000\000\000\002f\002e\002d\002c\002b\0016\002^\000\000\000\000\002_\000\000\002a\000\000\000\000\002\242\002/\000\000\000\000\0022\000\000\000\000\0025\000\000\000\000\0020\0023\000\000\0021\0024\002i\002]\002\243\002\241\002\240\000i\000j\000\000\000\000\000Z\000\000\000Y\000\000\002h\000\000\001\172\000X\000?\000\226\000`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\134\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\245\002\244\000\000\002\172\000\000\002\171\000\000\000\000\000\000\000\000\003\001\000\000\000\000\000\000\003\002\000\000\000\018\000\000\000\000\000\000\002\253\000\000\001u\000\000\000\000\000\000\000\162\002\162\001M\000\000\000\153\001L\001%\001$\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\207\000\208\000\195\000\000\001Y\000\000\000\000\000\194\000\190\000\000\000\197\000\191\000\196\000\000\002\174\000\000\002\173\002\159\000\000\000\000\000\000\000\000\000\000\002\168\000\000\000\000\000\000\000\000\000\000\002\169\002\161\000\000\002\175\000\000\002\163\000\000\000\166\000\000\002\178\000\152\000\000\001'\000\000\000\000\000\000\000\000\000\000\000\000\001\t\000\000\000w\000\000\000\000\000\000\002F\000\000\000\000\000\000\002N\000\000\000\000\002M\000\000\002\231\002L\002K\002J\002I\002H\002D\000\000\000\000\002E\000\000\002G\000\000\000\000\002\228\002!\000\000\000\000\002$\000\000\000\000\002'\000\000\000\000\002\"\002%\000\000\002#\002&\002O\002C\002\229\002\227\002\226\002\230\000\000\000\000\000\000\000e\000f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\212\001(\000\000\000\000\000\000\001.\000\000\000\000\001/\000#\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000$\000\000\000%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001-\0012\000\000\001,\000\000\000\000\0014\000\000\000\000\000\000\000\000\000\000\000\000\000t\000q\000r\0015\0011\000\000\000\000\0010\001*\000\000\001)\000\000\000\182\000\000\002\140\000\000\000\000\000\178\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\185\000\000\000\000\000\188\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\007\000\000\000\000\000\000\000\175\000\000\000\172\000\000\000\000\000\000\000\000\000\000\000\183\000\000\000\179\000\000\000\000\002\199\000\000\002\206\000\168\000\000\000\000\000\000\000\000\000\180\000\000\000\176\000\173\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\184\000\000\000\000\000\187\000\000\002\200\000\167\000\000\002\201\000\000\002\208\000\000\000\000\000\000\000\000\000\186\000\000\000\170\000\000\000\000\000\000\000\000\001\006\000\000\000\000\000\000\000\174\000\000\000\171\000\000\000\000\000\000\000\000\000\000\000\181\000\000\000\177\000\164\000\163\000\000\002\209\002\210\000\000\002\211\000\000\002\212\000\000\001&\002\166\000\000\000\000\001\194\000\000\001q\001\176\000\000\002\160\000\000\000\000\000\000\002\165\000\000\000\000\000\000\000\250\000\000\000\244\000\000\000\245\000\000\000\255\000\243\000\254\000\000\002\177\001\000\000\000\000\169\000\000\000\000\000\000\000\000\000\252\000\247\001\191\000\000\000\248\000\000\000\249\000\000\001k\001\173\000\000\000\000\000\000\001\202\000\000\001\200\000\000\000\000\001\204\001\198\000\000\001\205\001\199\000\000\002\179\001\208\000\000\000\165\000\000\000\000\001\192\000\000\001m\001\174\000\000\002\254\000\000\002\251\000\000\002\252\000\019\000\020\000\000\000\000\002}\000\000\002|\000\000\000\000\002\127\000\000\002~\000\000\000\000\000\000\001\235\000\000\000\000\001\239\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\242\000\000\000\000\001\245\000\000\000\000\001\229\000\000\000\000\001\232\000\000\000\000\000\000\001\236\000\000\000\000\001\240\000\000\000\000\001\193\000\000\000\000\001\233\000\000\000\000\001\237\002z\001\230\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\241\000\000\000\000\001\244\000\000\002{\000\000\000\000\000\000\000\000\001\243\000\000\001\227\000\000\001\228\000\000\000\000\001\231\000\000\000\000\000\000\001\234\000\000\000\000\001\238\000\000\001o\001\175\000\000\002\128\000\000\000\000\000\000\002\255\000\017\000u\000\000\003\000\000\000\000\000\002\136\000\000\000\000\002\180\000a\000\000\000\000\000\000\000b\000\000\002\170\000\000\001S\002\167\000\000\000\000\001@\000\000\001?\000\000\001H\000\000\001c\000\000\000\000\000\000\001>\000\000\001=\000\000\001E\000\000\001a\000\000\000\000\000\000\001B\000\000\001A\000\000\001F\000\000\001e\000\000\000\000\000\000\001C\000\000\000\000\000\000\000\000\001<\000\000\001;\000\000\001I\000\000\001_\000\000\000\000\000\000\001D\000\002\000\000\000N\000O\000M\001J\000\003\000\000\000\000\002l\000\000\001\249\000\000\002r\002t\000\000\000\000\001\140\002s\000\128\000\000\000\000\002\158\000\000\000\000\000\000\000z\000\000\000\000\002\146\000\000\001\222\001\221\001\135\002x\002p\002q\000\000\001\167\000\000\002m\000\000\000\000\000|\000\000\000\000\002\150\000\000\001\149\000\000\000\000\001\146\000\000\000\000\000\000\001\148\000\000\001\147\000\000\000\000\000\000\000\000\000\000\000\000\001\168\000\000\001\144\000\000\001\143\000\000\000v\000\000\000\000\002\138\000\000\000\000\001\139\000\000\000\000\000~\000\000\000\000\002\154\000\000\000\000\000\000\000{\000\000\000\000\002\148\000\000\001\218\001\217\001\131\002v\000\000\001\154\000\000\000\000\000\000\001\151\000\000\001\156\000\000\000\000\001\152\000\000\000\000\001\153\000\000\000\000\000\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\001\169\000\000\001\145\000}\000\000\000\000\002\152\000\000\000\000\000\000\001\031\000y\001\030\000\000\000\000\002\144\000\000\001\216\001\215\001\129\002u\000\000\000\127\000\000\000\000\002\156\000\000\000\000\000\000\000\000\001\220\001\219\001\133\002w\000\000\001\161\000\000\001\165\000\000\000\000\001\157\000\000\000\000\000\000\001\150\000\000\001\155\000\000\000\000\000\000\000\000\000\000\000\000\001\164\001\138\000\000\001\163\000\000\000\000\000\000\000\000\001\160\000\000\000\000\001\159\000\000\001\158\000\000\000\000\000\000\000\000\001\162\000\000\001\166\000\000\000\000\001K\000\004\000\000\001\141\000\005\000\000\000\000\000\230\000\006\000\000\001\180\001\181\001\179\000\000\000\000\000\000\000\000\000\000\000\000\000x\000\000\000\000\002\142\000\000\000\221\001\178\001{\002\196\001}\000\000\000\007\000\000\001\183\001\184\001\182\000\000\000\000\000\000\000\000\000\000\000\000\000\231\000\234\000\000\000\000\000\000\000\000\000\239\000\241\000\240\000\235\000\237\000\236\000\000\000\000\002\197\001\188\001\187\000\000\000\000\000\000\000\000\002\202\002\213\000\000\002\203\000\000\002\204\001\127\000\000\001\177\001\185\000\000\000\000\000\000\000\000\001\224\000\000\000\000\000l\000m\000\000\000\000\000\000\001\223\000\000\000\158\000\000\001U\000\000\000\000\000\157\000\154\000\000\000\000\000\000\000\000\001\005\000\000\000\000\002\214\000\000\002\215\000\000\000\000\001\211\001\209\000\000\001\210\000\008\000\000\000\t\000\000\002\n\002\011\002\t\000\000\000\000\002\008\000\000\000\n\000\000\002\013\002\014\002\012\000\000\002\016\000\000\000\000\000\000\002\002\000\000\000\000\002\004\000\000\001\254\000\000\002\000\000\000\002\005\000\000\002\006\001\255\001\253\002\017\001\137\000\000\002\007\000\000\002\019\000\000\002\018\000\000\002\020\000\000\002y\000\011\000\000\000\000\000\000\000\000\000\000\000\000\002\021\000\000\000\000\002\024\000\000\002\023\000\000\002\022\000\198\000\000\000\000\000\000\000\000\000\199\002\025\000\000\000\000\002\131\000\000\000\229\000\012\000\000\000\000\000\000\000\000\000\000\000\000\002\134\000k\000\000\000\000\000\204\000\000\000\000\000\224\000\223\000\222\000\000\0018\000\000\002\130\001y\001w\000\000\000\000\000\000\000\000\000\000\000\000\002\129\000\000\000\013\000\000\000\000\000\000\000\000\000\000\002\132")
let error =
- (167, "\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000`\000\000\000\000\016\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\192\000\000\000\000\000\000\003\214\171\128\004\000\128\000\004\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\016\006\016\000\002\t\1290\008\002\002\000\016\000\0012\024\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000z\213p\000\128\016\000\000\128\002\000\000\000\000\000\000\000\000\000\000\000\002U\024\000\1280\128\000\152L\t\128@\016\017\000\128\000\t\144\197\235U\192\002\000@\000\002\008\008\000\000\000\000 \000\016\000\000\000\000\000\000\000\000\000\000\000\002\001\000\000\000\000\000\000\000\000\000\000\000\000\018(\192\000\000\004\000\004\002@L\002\000\000\136\004\000\000L\006 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\245\170\224\t\000 \000\001\004\004\000\000\000\000\016\000\000\000\000\016\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\004\000\128\000\004\016\016\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\008\000\000\000\128\000\000\000\000\000\015Z\174\000\016\002\000\000\016@@\000\000\000\001\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\245\170\224\001\000 \000\001\004\004\000\000\000\000\016\000\008\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\002\000\000\000\000\000\000\000\004\000\001\016\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\008\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000B\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130z\213p\000\169\016\001 \208*\013\218\000\002H\008\004\000B\001\004\245\170\224\001R \002A\160T\027\180\000\004\144\016\008\000\132\002\008\000\000\000\016\164\000\004\131@\1607h\000\t \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\129@n\208\000\018@@ \002\016\008 \000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\129@n\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001 \000D`\155,\150\000\000P\004 \000;\160\"xw\000\000\000\000\000\000\000\000\000\000\000\128\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\235U\192\002\164@\004\131@\1687\232\000\t \016\001\t\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000$\000\008\004\016`\018\192\000\n\000\000\000\007d\000M\014\224\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\144\000\"\016M\132K\000\000(\002\000\000\029\144\001<;\128\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\144\000\"\016M\132K\000\000(\002\000\000\025\144\001<\027\128\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\128\001\016\130l\"X\000\001@\016\000\000\204\128\t\224\220\000\000\000\000\164\000\004\131@\1607h\000\t \016\001\008\004\016\000\000\018\000\004B\t\176\137`\000\005\000@\000\0032\000'\131p\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000H\000\017\008&\194%\128\000\020\001\000\000\012\200\000\158\013\192\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t \016\001\008\004\016\000\000\018\000\004B\t\176\137`\000\005\000@\000\0032\000'\131p\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000H\000\017\008&\194%\128\000\020\001\000\000\012\200\000\158\013\192\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\001 \000D \155\008\150\000\000P\004\000\0003 \002x7\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\004\128\001\016\130l\"X\000\001@\016\000\000\204\128\t\224\220\000\000\000\000\164\000\004\131@\1607h\000\t \016\001\008\004\016\000\000\018\000\004B\t\176\137`\000\005\000@\000\0032\000'\131p\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128`\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000H\000\017\008&\194%\128\000\020\001\000\000\012\200\000\158\013\192\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\001 \000D \155\008\150\000\000P\004\000\0003 \002x7\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\004\128\001\016\130l\"X\000\001@\016\000\000\204\128\t\224\220\000\000\000\000\164\000\004\131@\1607h\000\t \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000 \012\000\000\004\019\000\000\000\004\004\000 \000\002d\001\001*\140\000@\024@\000H&\004\192 \008\008\128@\000\004\200b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\191N\000 \012 \000$\019\002`\016\004\004@ \000\002d1\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007Z\170\000\016\002\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000@\024@\000\008&\004\192 \008\008\000@\000\004\200b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\017\000\003\214\171\128\005H\128\t\006\129Po\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\004\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\245\170\224\001R \002A\160T\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\000\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\000\000\132\002\008\000\000\000\000\164\000\004\131@\1607h\000\t \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000H\000\017\016\"\201%\000\000\016\001\008\000\006\168\008\134\017\192\000\000\000\000\000\000\000\000\000\000 \000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000z\213p\000\169\016\001 \208*\013\250\000\002H\008\004\000BA\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\129@n\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000z\213p\000\169\016\001 \208*\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\164\000\004\131@\1607h\000\t \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000H\000\017\000\"\192%\000\000\016\001\000\000\006\136\000\134\017\192\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\128\000\004\000\000\000\000\001\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\128\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018\000\004@\008\176\t@\000\004\000@\000\001\"\000!\128p\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000H\000\017\000\"\192%\000\000\016\001\000\000\004\136\000\134\001\192\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\001 \000D\000\139\000\148\000\000@\004\000\000\018 \002\024\007\000\000\000\000)\000\001 \208(\013\218\000\002H\008\000\000B\001\004\000\000\004\128\001\016\002,\002P\000\001\000\016\000\000H\128\008`\028\000\000\000\000\164\000\004\131@\1607h\000\t \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\001 \000D\000\139\000\148\000\000@\004\000\000\018 \002\024\007\000\000\000\000)\000\001 \208(\013\218\000\002H\008\000\000B\001\004\000\000\004\128\001\016\002,\002P\000\001\000\016\000\000H\128\008`\028\000\000\000\000\164\000\004\131@\1607h\000\t \000\001\008\004\016\000\000\018\000\004@\008\176\t@\000\004\000@\000\001\"\000!\128p\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000H\000\017\000\"\192%\000\000\016\001\000\000\004\136\000\134\001\192\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\001 \000D\000\139\000\148\000\000@\004\000\000\018 \002\024\007\000\000\000\000)\000\001 \208(\013\218\000\002H\008\006\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000H\000\017\000\"\192%\000\000\016\001\000\000\004\136\000\134\001\192\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\001 \000D\000\139\000\148\000\000@\004\000\000\018 \002\024\007\000\000\000\000)\000\001 \208(\013\218\000\002H\008\000\000B\001\004\000\000\004\128\001\016\002,\002P\000\001\000\016\000\000H\128\008`\028\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000 \000=j\184\000@\008\000\000@\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\000\000\132\002\008\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\n\145\000\018\013\002\160\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000@\000\000\000\000\000\000\000\128\000\"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\145F\000\000\000 \000 \018\002`\016\000\004@ \000\002`1\001\"\140\000\000\000@\000@\004\004\192 \000\008\128@\000\004\192b\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\030\181\\\000 \004\000\000 \000\140\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000 \016\000\000\000\000\000\000\000\000\002 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\017\000\003\214\171\128\004\000\128\000\004\000\017\128\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\128\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\004\000\128\000\004\000\017\128\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000D\000\015Z\174\000\016\002\000\000\016\000F\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\008\000\000\000\004@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000=j\184\000@\008\000\000@\001\024\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000z\213p\000\128\016\000\000\130\002\000\000\000\000\008\000\000\000\000\008\000\245\170\224\001\000 \000\001\004\004\000\000\000\000\016\000\008\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\014\181T\000 \004\000\000\000\000\128\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\tT`\002\000\194\000\002a0&\001\000@D\002\000\000&C\023\173W\000\008\001\000\000\008 \000\000\000\000\128\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000@\000\000\000\000\000\000\023\173W\000\008\001\000\000\008\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\030\181\\\000 \004\000\000 \000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000 \000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255_\130\011\145 \016\012b\184\253\225\000~\161\128\008\214 P@$Q\128\000\000\000\000\008\004\000\152\000\000\001\016\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000=j\184\000@\008\000\000@\001\024\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\004\000\128\000\004\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000 9\002\001\000\196(\143\218\016\007\234\024\000\140b\005\004\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@!\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000?\250\252\016\\\137\000\144j\021\199\239\008\003\245\012\002G\177\134\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002\001\128P\027\180\000\012\144\016\000\000\132\002\008\000\000\000\000\164\000\004\003\000\1607h\000\025 \000\001\008\004\019\214\171\128\005H\128\t\006\129Pn\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\020\128\000\128`\020\006\237\000\003$\004\000\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\128`\020\006\237\000\003$\004\000\000!\000\130\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\003\000\1607h\000\025 \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\016\012\002\128\221\160\000d\128\128\000\004 \016@\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002@\000\136\1936Y,\000\000\160\008@\000u@@\160\238\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\005H\128\t\006\129Po\208\000\018@@ \002\018\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000$\000\008\132\019a\018\192\000\n\000\128\000\007D\000\n\014\224\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\128\001\016\130l\"X\000\001@\016\000\000\200\128\001@\220\000\000\000\000\164\000\004\003\000\1607h\000\025 \000\001\008\004\016\000\000\018\000\004B\t\176\137`\000\005\000@\000\003\"\000\005\003p\000\000\000\002\144\000\016\012\002\128\221\160\000d\128\128\000\004 \016@\000\000H\000\017\008&\194%\128\000\020\001\000\000\012\136\000\020\013\192\000\000\000\n@\000@0\n\003v\128\001\146\002\000\000\016\128A\000\000\001 \000D \155\008\150\000\000P\004\000\0002 \000P7\000\000\000\000)\000\001\000\192(\013\218\000\006H\008\000\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\003\000\1607h\000\025 \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\016\012\002\128\221\160\000d\128\128\000\004 \016@\000\000H\000\017\008&\194%\128\000\020\001\000\000\012\136\000\020\013\192\000\000\000\n@\000@0\n\003v\128\001\146\002\000\000\016\128A\000\000\001 \000D \155\008\150\000\000P\004\000\0002 \000P7\000\000\000\000)\000\001\000\192(\013\218\000\006H\008\000\000B\001\004\000\000\004\128\001\016\130l\"X\000\001@\016\000\000\200\128\001@\220\000\000\000\000\164\000\004\003\000\1607h\000\025 \000\001\008\004\016\000\000\018\000\004B\t\176\137`\000\005\000@\000\003\"\000\005\003p\000\000\000\002\144\000\016\012\002\128\221\160\000d\128\128\000\004 \016@\000\000H\000\017\008&\194%\128\000\020\001\000\000\012\136\000\020\013\192\000\000\000\n@\000H4\n\003v\128\000\146\002\001\128\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000)\000\001\000\192(\013\218\000\006H\008\000\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\003\000\1607h\000\025 \000\001\008\004\016\000\000\018\000\004B\t\176\137`\000\005\000@\000\003\"\000\005\003p\000\000\000\002\144\000\016\012\002\128\221\160\000d\128\128\000\004 \016@\000\000H\000\017\008&\194%\128\000\020\001\000\000\012\136\000\020\013\192\000\000\000\n@\000@0\n\003v\128\001\146\002\000\000\016\128A\000\000\001 \000D \155\008\150\000\000P\004\000\0002 \000P7z\213p\000\169\016\001 \208*\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\004\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\245\248<\185\018\001\000\198+\143\222\016\007\234\024\000\141b\005\004\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\002\000\000\000\000\000\000B \000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\175\193\005\200\144\008\006!\\~\240\128?P\192\004k\016('\255_\130\011\145 \018\013B\248\253\225\000~\161\128H\214(PO\254\191\007\151\"@ \024\197q\251\194\000\253C\000\017\172@\160\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000?\251\254\030\\\137\000\128c\023\199\239\024\003\245L G\177\198\179\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\255\235\240Ar$\002\001\140W\031\188 \015\2120\001\026\196\n\t\255\215\224\130\228H\004\131P\190?x@\031\168`\0185\138\020\019\255\175\193\005\200\144\t\006\161\\~\240\128?P\192$k\016h \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001 \000D`\155,\150\000\000P\004 \000;\160\"Pw\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\016\028\129\000\128b\020G\237\008\003\245\012\000F1\002\130\000\000\000 9\002\001\000\196(\143\218\016\007\234\024\000\140b\005\004\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \008$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128 \144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\008\000\132\130\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\001\001\200\016\008\006!D~\208\128?P\192\004c\016( \000\000\002\003\144 \016\012B\136\253\161\000~\161\128\008\198 P@\000\000\000\000\000\000\000\000\000\000\016\000\000\001\000\000\128\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\016\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\004\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\136\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\002\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002@\000\128\193\006I,\000\000\128\000@\0003@D\128\140\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\001\235U\192\002\164@\004\131@\1687\232\000\t \016\001\t\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\002\003\144 \016\012B\136\253\161\000~\161\128\008\198 P@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\175\193\005\200\144\t\006\161\\~\240\128?P\192$k\016( \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\254\255\135\151\"@ \024\197\241\251\198\000\253S\008\017\236q\172\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\235U\192\002\000@\000\002\000\008\000\000\000\000 \000\000\000\000\000\000\t\020`\000\000\000\000\002\001\000&\000\000\000D\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\015Z\174\000\016\002\000\000\016\000F\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\128\000 \000\000\000\000\000\002\144\000\018\013B\128\221\160\000$\128\128@\004 \016@\000\000\000\005 \000 \025\133\001\187@\000\201\001\000\160\008A \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\128`\020\006\237\000\003$\004\000\000!\000\130\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\005H\128\t\006\129Pn\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000@0\n\003v\128\001\146\002\000\000\016\128A\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002\001\128P\027\180\000\012\144\016\000\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\008\006\001@n\208\0002@@\000\002\016\008 \000\000\000\002\144\000\016\012\002\128\221\160\000d\128\128\000\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000@@\131$\148\000\000@\000 \000\016\160\"\000\006\000\000\000\000\000\000\000\000\000\000\000\128\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\235U\192\002\164@\004\131@\1687\232\000\t \016\001\t\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\235U\192\002\164@\004\131@\1687h\000\t \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\002\144\000\016\012\002\128\221\160\000d\128\128\000\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\016\000\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\002\144\000\016\012\194\128\221\160\000d\128\128\016\004 \016@\000\000\000\005 \000 \025\133\001\187@\000\201\001\000\160\008A \128\000\000\001\n@\000@3\n\003v\128\001\146\002\001@\016\130A\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \212(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\n@\000@3\n\003v\128\001\146\002\000@\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000R\000\002\001\152P\027\180\000\012\144\016\002\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\008\000\016`\018\128\000\008\000\000\000\002\004\000@\000\192\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\128\000 \000A\128J\000\000 \000\000\000\008\016\001\000\003\000\000\000\000\020\128\000\128`\020\006\237\000\003$\004\000\000!\000\130\000\000\002\000\000\128\001\006\001(\000\000\128\000\000\000 @\004\000\012\000\000\000\000R\000\002\001\128P\027\180\000\012\144\016\000\000\132\002\008\000\000\008\000\002\000\004\024\004\160\000\002\000\000\000\000\129\000\016\0000\000\000\000\001H\000\008\006\001@n\208\0002@@\000\002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\128`\020\006\237\000\003$\004\000\000!\000\130\000\000\002\000\000\128\001\006\001(\000\000\128\000\000\000 @\004\000\012\000\000\000\000R\000\002\001\128P\027\180\000\012\144\016\000\000\132\002\008\000\000\008\000\002\000\004\024\004\160\000\002\000\000\000\000\129\000\016\0000\000\000\000\001H\000\008\006\001@n\208\0002@@\000\002\016\008 \000\000 \000\008\000\016`\018\128\000\008\000\000\000\002\004\000@\000\192\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\128\000 \000A\128J\000\000 \000\000\000\008\016\001\000\003\000\000\000\000\020\128\000\128`\020\006\237\000\003$\004\000\000!\000\130\000\000\002\000\000\128\001\006\001(\000\000\128\000\000\000 @\004\000\012\000\000\000\000R\000\002\001\128P\027\180\000\012\144\016\000\000\132\002\008\000\000\008\000\002\000\004\024\004\160\000\002\000\000\000\000\129\000\016\0000\000\000\000\001H\000\008\006\001@n\208\0002@@\000\002\016\008 \000\000 \000\008\000\016`\018\128\000\008\000\000\000\002\004\000@\000\192\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\128\000 \000A\128J\000\000 \000\000\000\008\016\001\000\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\002\144\000\016\012\194\128\221\160\000d\128\128P\004 \144@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000@3\n\003v\128\001\146\002\001@\016\130A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000)\000\001\000\204(\013\218\000\006H\008\005\000B\t\004\000\000\000\000R\000\002\001\152P\027\180\000\012\144\016\002\000\132\018\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\001H\000\008\006a@n\208\0002@@(\002\016H \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\164\000\004\0030\1607h\000\025 \004\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\004\000\128\000\004\000\017\128\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144j\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\019\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\002\000\002@\000\000\000\000\000\000\000\128\000 \000\000\000\000\000\000\000\004\000\004\128\000\000\000\000\000\000\001\000\000@\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\030\181\\\000 \004\000\000 \000\140\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000@\000\016\000\000\000\000\000\001H\000\t\006\161@n\208\000\018@@ \002\016\008 \000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000:\213P\000\128\016\000\000\000\002\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000@\000\016\000\000\000\000\000\001H\000\t\006\161@n\208\000\018@@ \002\016\008 \000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\245\248 \185\018\001\000\198+\143\2220\007\234\024\000\141b\005\004\000\000\000\000\000\000\000@ \000\000\000@\000\000\000\136\000\000\000\196\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\175\193\005\200\144\008\0061\\~\241\128?P\194\004k\016+0\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\144\000\"0M\150K\000 (\002\018\000\029\208\016(;\128\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\008\000\002\000\000\000\000\000\000)\000\001 \212(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\004\000\128\000\004\000\017\128\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144j\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\128@\000\000\000\128\000\000\001\016\000\000\001\136\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\254\191\004\023\"@$\026\133q\251\198\000\253C\008\145\172@\172\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000?\250\252\016\\\137\000\128c\021\199\239\024\003\245\012 F\177\002\179\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\001\235U\192\002\164@\004\131@\1687\232\000\t \016\001\t\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\0010\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\245\170\224\001\000 \000\001\000\004`\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\002\000\000\128\000\000\000\000\000\n@\000H5\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\214\170\128\004\000\128\000\000\000\016\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\002\000\000\128\000\000\000\000\000\n@\000H5\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\254\191\004\023\"@$\026\133q\251\198\000\253C\008\145\172@\172\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@ \016\000\000\000 \000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\255\215\224\130\228H\004\131P\174?x\192\031\168`\0185\136\020\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000L\002\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000@\000\000\000\000 9\002\001\000\196(\143\218\016\007\234\024\000\140b\005\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\002\000\000\000\000\000\000\000\000\000@\000\127\247\252 \185\026\0010\212/\143\2220\015\234\152L\143c\173f\000\000\000@r\004\002\001\136Q\031\180 \015\2120\001\024\196\n\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\175\193\005\200\144\008\0061|~\240\128?P\192\004{\028h \000\000\000\000\000\000\002\001\000\000\000\000\000\000\000\000@\000\000\000\015\254\191\004\023\"@ \024\197\241\251\194\000\253C\000\017\236q\160\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \016\008\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\255\235\240Ar$\002A\168_\031\188 \015\2120\t\030\199\026\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\175\193\005\200\144\t\006\161|~\240\128?P\192${\028h \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\008\000\015\254\191\004\023\"@ \024\197\241\251\194\000\253C\000\017\172P\160\128\000\000\000\000\000\000\008\004\001\000\000\000\000\000\000\001\000\000 \000?\250\252\016\\\137\000\128c\023\199\239\008\003\245\012\000F\177B\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\001\000\128 \000\000\000\000\000\000 \000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\254\191\004\023\"@$\026\133\241\251\194\000\253C\000\145\172P\160\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\019\000\000\000 \000\000\000\002\000\000\000\000\000\000\000@\001\128\128\000\000\000\000@\000\000 \000\001\000\023\255_\130\011\145 \016\012b\184\253\225\000~\161\128\008\214 P@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\016\012\004\000\000\000\000\002\000\000\001\000\000\008\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\245\248 \185\026\0010\212+\143\222\016\015\234\024\004\141b%\006\255\235\240Ar$\002\001\140W\031\188 \015\2120\001\026\196\n\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255_\130\011\145\160\019\013B\184\253\225\000\254\161\128H\214\"P`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\008\000\015\254\191\004\023\"@$\026\133\241\251\194\000\253C\000\145\172P\160\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\002\001\000\000\000\002\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253~\008.D\128H5\n\227\247\140\001\250\134\001#X\129A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\239\215\224\002\164H\004\003\000\1687x\000\025 \000\005\136\020\016\000\000\000\001H\002\t\006\129@n\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000=\250\252\000T\137\000\128`\021\006\239\000\003$\004\000\000\177\002\130\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\008\001\000\000\008\000 \000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \212(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000z\213p\000\128\016\000\000\128\0020\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013B\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002`\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131P\1607h\000\t \016\001\008\004\016\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007Z\170\000\016\002\000\000\000\000@\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\002\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002A\168P\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\008\000\015~\191\000\021\"@ \024\005A\187\192\000\201\001\000\000,@\160\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001 \000@`\131$\150\000@@\000$\000\024\160 @F\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131P\1607h\000\t \016\001\008\004\016\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\008\001\000\000\008\000#\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \212(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\030\181\\\000*D\000H4\n\131~\128\000\146\002\001\000\016\144A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\019\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H5\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000u\170\160\001\000 \000\000\000\004\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\133\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\128\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\016\000\000\001\0010\000\000\002\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\128\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\008@\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\245\248 \185\018\001\000\198+\143\222\016\007\234\024\000\141b\005\004\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\031\253~\008.D\128H5\n\227\247\132\001\250\134\001#\216\195A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\004 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000_\253~\008.D\128@1\138\227\247\132\001\250\134\000#X\129A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\245\248 \185\018\001\000\198+\143\222\016\007\234\024\000\141b\005\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\128\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\000\000\000\004\000\000\000\000\000\000\000\004\000\000\000\000\000\000\001\000\000\000\000)\000\001 \208(\013\218\000\002H\008\000\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 9\002\001\000\196(\143\218\016\007\234\024\000\140b\005\004\000\000\000\000\000\016\000\000\000\000\000\000\000\016\000\000\000\000\000\000\004\000\000\000\128\228\008\004\003\016\162?h@\031\168`\0021\136\020\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\003\144 \016\012B\136\253\161\000~\161\128\008\198 P@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\008\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t \000\001\008\004\016\000\000\000\000\000@\000\000\000\000\000\000\000@\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253~\000 \004\000\000 \000\128\001\000\000\002\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\004\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\008\000\000\000\000\000\000\002\255\235\240\001\000 \000\001\000\004\000\008\000\000\016\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\175\192\004\000\128\000\004\000\016\000 \000\000@\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\004\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\000\000\132\002\008\000\000\000\000\000 \000\000\000\000\000\000\000 \000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\030\181\\ p\132D\144!\000\128\000\018\000\005P\144\000&\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\028!\017\004\008@ \000\004\128\001T$\000\t\128\000\015Z\174\0008B\000\008\016\128@\000\t\000\002\168H\000\019\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000 \008\004\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\128 \000\000\000\000\000\000\000\000\016\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\008\000\000\000 \000\001\000@\000\000\000\000\000\000\000\000 \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\016\000\000\000\000\000\000@\000\000\000\000\000\000\002\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\008\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\028!\016\004\008@ \000\004\128\001T$\000\008\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\030\181\\\000p\132\000\016!\000\128\000\018\000\005P\144\000\"\000\000\000\004\000\000 \008\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\008\000\000\000 \000\001\000@\000\000\000\000\000\000\000\000 \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\016\004\000\000\000\000\000\000\000\000\002\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\128 \000\000\000\000\000\000\000\000\016\000\128\000\000\000\000\000 \000\001\000@\000\000\000\000\000\004\000\000 \001\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000 \008\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\008\000\000@\016\000\000\008\000\000\001\000\000\008\000@\000\004\000\000\000\016\000\000\128 \000\000\000\000\000\000\000\000\016\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000@\000\002\000\128\000\000\000\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\235U\192\002\000@\000\002\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\128\015Z\174\000\016\002\000\000\016\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\008\000\000@\016\000\000\008 \000\000\000\000\008\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000@\000\002\000\128\000\000\000\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\128\000\000\002\000\000\016\004\000\000\000\000\000\000\000\000\002\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\001\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\0020\000\000@\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\016\004\000\000\000\016\000\000\000\000\002\000\016\000\000\000\000\000\004\000\000 \008\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\004\001\000\000\000\000\000\000\000\000\000\128\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000 \008\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000@\000\002\000\128\000\000\000\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\016\004\000\000\000\008\000\000\000\000\002\000\016\000\000\000\000\000\004\000\000 \008\000\000\004\128\000\000\128\000\004\000 \000\002\000\000\000\008\000\000@\016\000\000\000\000\000\000\000\000\008\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000 \000\001\000@\000\000\000\000\000\000\000\000 \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\004\000\000\000\016\000\000\128 \000\000\000\000\000\000\000\000\016\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\008\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000@\000\000\000\000 \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\128 \000\000\000\000\000\000\000\000\016\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000 \000\000\000\128\000\004\001\000\000\000\000\000\000\000\000\000\128\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000@\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\001\000@\000\000\000\000\000\000\000\000 \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\008\002\000\000\000\008\000\000\000\000\001\000\008\000\000\000\000\000\002\000\000\016\004\000\000\000\000\000\000\000\000\002\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\214\235\128\006\000\128\000\004 \016\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\002\000\000\016\004\000\000\000H\000\000@\000\002\000\016\000\001\000\000\000\004\000\000 \008\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\030\183\\\0000\004\000\000!\008\128\000\000\000\002\000\016\000\000\000\000\000\004\000\000 \008\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\001\000@\000\000\000\000\000\000\000\000 \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000 \008\000\000\004\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\016\000\000\128 \000\000\000\000\000\000\000\000\016\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\235U\194\007\008DI\002\016\008\000\001 \000U\t\000\002`\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\007\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\024\128\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000A\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\000\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\254\255\132\023\"@$\030\135q\251\194\000\253S\008\145\172@\172\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\191\225\005\200\144\t\007\161\\~\240\128?T\194$k\016+3\191}\192\008\001\000\000\000\000 \000\000\000\000\008\000\000\000\000\000\000$Q\128\000\000\000\000\000\004\000\000\000\000\000\016\000\000\000\000\000\014\253\247\000 \004\000\000\000\000\128\000\000\000\000 \000\000\000\000\000\029\251\238\000@\008\000\000\000\001\000\000\000\000\000@\000\000\000\000\000\001\"\140\000\000\000\000\000\000 \000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\020`\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\018(\192\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000$Q\128\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000H\163\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000 \025\133\001\187@\000\201\001\000\160\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\239\223\240\002\000@\000\002\000\008\000\000\000\000\"\000\000\000\000\000\000\t\020`\000\000\000\000\002\000\000\000\000\000\000\004\000\000\000\000\000\007\255_\130\011\145 \016\012b\184\253\225\000~\161\128\008\214 P@\000\000\000\000\000\000\004\002\000\000\000\000\000\000\000\008\128\000\000\012@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@ \016\000\000\000\000\000\000\000D\000\000\000b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\255\215\224\130\228H\004\131P\174?x@\031\168a\0185\136\021\152\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\012@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\128\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\004\000\128\000\004\000\017\128\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\136\000\030\181\\\000 \004\000\000 \000\140\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\128\001\235U\192\002\000@\000\002\000\008\192\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000?\250\252\016\\\137\000\144j\021\199\239\008\003\245\012\002F\177\006\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\1380\000\000\000\000\001\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\002\001\000\128\000\000\000\000\000\000\002 \000\000\003\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\254\191\004\023\"@$\026\133q\251\194\000\253C\008\145\172@\172\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\002`\000\000\004\000 \000\000\0001\000\000\000\000\000@ \008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\014\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\012@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000?\251\254\016\\\137\000\144z\029\199\239\008\003\245L\"F\177\002\179\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\254\255\132\023\"@$\030\133q\251\194\000\253S\008\145\172@\172\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000?\251\254\016\\\137\000\128c\021\199\239\008\003\245L F\177\002\179\000\000\000\000\000\000\000 \016\000\000\000\000\000\000\000D\000\000\000b\255\239\248Ar$\002\001\140W\031\188 \015\2130\129\026\196\n\204\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\191\225\005\200\144\t\006\161\\~\240\128?T\194$k\016+7\255\127\194\011\145 \016\012b\184\253\225\000~\169\132\008\214 V`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\008\004\000\000\000\000\000\000\000\017\000\000\000\024\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\247\252 \185\018\001 \212+\143\222\016\007\234\152D\141b\005f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\255\223\240\130\228H\004\131P\174?x@\031\170a\0185\136\021\152\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255\127\194\011\145 \018\013B\184\253\225\000~\169\132H\214 V`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\001\136\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255\127\194\011\145 \018\013B\184\253\225\000~\169\132H\214 V`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\008\004\000\000\000\000\000\000\000\017\000\000\000\024\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\247\252 \185\018\001 \212+\143\222\016\007\234\152D\141b\005f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\019\000\000\000 \001\000\000\000\001\136\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\004\128\000\000\000\000\000\000\000\001\004\224\006\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000 \000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\001\002\000\000\000\000\000\000\002\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\004\008\000\000\000\000\000\000\008\000\000\000\016\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\004\000\128\000\000\000\000\002\000\000\008\016\000\000\000\000\000\000\016\000\000\000 \000\000\000\000\128\001\000\001\000\000\000\000\000\000\000\008\192\008\000\016\n\000\000\000\000\000\008\000\000 @\000\000\000\000\000\000@\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\016\000\016\000\000\000\000\000\000\000\140\000\128\000\000\160\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\004\000\000\000\000\000\000\000\000\000'\0000\000\000 \000\000\000\004\000\008\000\000\000\000\000\000\000\000\000F\000`\000\000@\000\000\000\008\000\016\000\000\000\000\000\000\000\000\000\140\000\128\000\000\128\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\0020\002\000@\002\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000#\000 \000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\001\024\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\001\000\000\000\000\000\000\000\000\000\008\192\012\000\000\008\000\000\000\001\000\002\000\000\000\000\000\000\000\000\000\017\128\016\000\000\016\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000#\000 \000\000 \000\000\000\000\000\008\000\000\000\000\000\000\000\000\000F\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")
+ (167, "\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000`\000\000\000\000\016\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\192\000\000\000\000\000\000\003\214\171\128\004\000\128\000\004\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\016\006\016\000\002\t\1290\008\002\002\000\016\000\0012\024\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000z\213p\000\128\016\000\000\128\002\000\000\000\000\000\000\000\000\000\000\000\002U\024\000\1280\128\000\152L\t\128@\016\017\000\128\000\t\144\197\235U\192\002\000@\000\002\008\008\000\000\000\000 \000\016\000\000\000\000\000\000\000\000\000\000\000\002\001\000\000\000\000\000\000\000\000\000\000\000\000\018(\192\000\000\004\000\004\002@L\002\000\000\136\004\000\000L\006 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\245\170\224\t\000 \000\001\004\004\000\000\000\000\016\000\000\000\000\016\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\004\000\128\000\004\016\016\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\008\000\000\000\128\000\000\000\000\000\015Z\174\000\016\002\000\000\016@@\000\000\000\001\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\245\170\224\001\000 \000\001\004\004\000\000\000\000\016\000\008\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\002\000\000\000\000\000\000\000\004\000\001\016\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\008\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\245\170\224\001R \002A\160T\027\180\000\004\144\016\008\000\132\002\t\235U\192\002\164@\004\131@\1687h\000\t \016\001\008\004\016\000\000\000\001H\000\t\006\129@n\208\000\018@@\000\002\016\008'\173W\000\n\145\000\018\013\002\160\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000$\000\008\140\019e\146\192\000\n\000\132\000\007t\004O\014\224\000\000\000\000\000\000\000\000\000\000\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000=j\184\000T\136\000\144h\021\006\253\000\001$\004\002\000! \130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\128\001\000\130\012\002X\000\001@\000\000\000\236\128\t\161\220\000\000\000\000\164\000\004\131@\1607h\000\t \016\001\008\004\016\000\000\018\000\004B\t\176\137`\000\005\000@\000\003\178\000'\135p\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018\000\004B\t\176\137`\000\005\000@\000\0032\000'\131p\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\144\000\"\016M\132K\000\000(\002\000\000\025\144\001<\027\128\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\002@\000\136A6\017,\000\000\160\008\000\000f@\004\240n\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\008\000\132\002\008\000\000\t\000\002!\004\216D\176\000\002\128 \000\001\153\000\019\193\184\000\000\000\001H\000\t\006\129@n\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\002@\000\136A6\017,\000\000\160\008\000\000f@\004\240n\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\008\000\132\002\008\000\000\t\000\002!\004\216D\176\000\002\128 \000\001\153\000\019\193\184\000\000\000\001H\000\t\006\129@n\208\000\018@@ \002\016\008 \000\000$\000\008\132\019a\018\192\000\n\000\128\000\006d\000O\006\224\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\144\000\"\016M\132K\000\000(\002\000\000\025\144\001<\027\128\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\002@\000\136A6\017,\000\000\160\008\000\000f@\004\240n\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\012\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\001H\000\t\006\129@n\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\008\000\132\002\008\000\000\t\000\002!\004\216D\176\000\002\128 \000\001\153\000\019\193\184\000\000\000\001H\000\t\006\129@n\208\000\018@@ \002\016\008 \000\000$\000\008\132\019a\018\192\000\n\000\128\000\006d\000O\006\224\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\144\000\"\016M\132K\000\000(\002\000\000\025\144\001<\027\128\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\004\001\128\000\000\130`\000\000\000\128\128\004\000\000L\128 %Q\128\008\003\008\000\t\004\192\152\004\001\001\016\008\000\000\153\012@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\023\233\192\004\001\132\000\004\130`L\002\000\128\136\004\000\000L\134 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\235U@\002\000@\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\008\003\008\000\001\004\192\152\004\001\001\000\008\000\000\153\012@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002 \000z\213p\000\169\016\001 \208*\013\250\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\000\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \208(\013\218\000\002H\008\000\000B\001\004\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\129@n\208\000\018@@\000\002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\000\008@ \128\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\128\001\017\002,\146P\000\001\000\016\128\000j\128\136a\028\000\000\000\000\000\000\000\000\000\000\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\n\145\000\018\013\002\160\223\160\000$\128\128@\004$\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000H\000\017\000\"\192%\000\000\016\001\000\000\006\136\000\134\017\192\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\128\000\004\000\000\000\000\001\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\128\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018\000\004@\008\176\t@\000\004\000@\000\001\"\000!\128p\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000H\000\017\000\"\192%\000\000\016\001\000\000\004\136\000\134\001\192\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\001 \000D\000\139\000\148\000\000@\004\000\000\018 \002\024\007\000\000\000\000)\000\001 \208(\013\218\000\002H\008\000\000B\001\004\000\000\004\128\001\016\002,\002P\000\001\000\016\000\000H\128\008`\028\000\000\000\000\164\000\004\131@\1607h\000\t \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\001 \000D\000\139\000\148\000\000@\004\000\000\018 \002\024\007\000\000\000\000)\000\001 \208(\013\218\000\002H\008\000\000B\001\004\000\000\004\128\001\016\002,\002P\000\001\000\016\000\000H\128\008`\028\000\000\000\000\164\000\004\131@\1607h\000\t \000\001\008\004\016\000\000\018\000\004@\008\176\t@\000\004\000@\000\001\"\000!\128p\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000H\000\017\000\"\192%\000\000\016\001\000\000\004\136\000\134\001\192\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\001 \000D\000\139\000\148\000\000@\004\000\000\018 \002\024\007\000\000\000\000)\000\001 \208(\013\218\000\002H\008\006\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000H\000\017\000\"\192%\000\000\016\001\000\000\004\136\000\134\001\192\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\001 \000D\000\139\000\148\000\000@\004\000\000\018 \002\024\007\000\000\000\000)\000\001 \208(\013\218\000\002H\008\000\000B\001\004\000\000\004\128\001\016\002,\002P\000\001\000\016\000\000H\128\008`\028\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\008\000\015Z\174\000\016\002\000\000\016\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\001H\000\t\006\129@n\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000=j\184\000T\136\000\144h\021\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015Z\174\000\021\"\000$\026\005A\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\128\000\000\000\000\000\000\001\000\000D\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\"\140\000\000\000@\000@$\004\192 \000\008\128@\000\004\192b\002E\024\000\000\000\128\000\128\008\t\128@\000\017\000\128\000\t\128\196\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000=j\184\000@\008\000\000@\001\024\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000@ \000\000\000\000\000\000\000\000\004@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\"\000\007\173W\000\008\001\000\000\008\000#\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000 \000\000\000\001\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\008\001\000\000\008\000#\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\136\000\030\181\\\000 \004\000\000 \000\140\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\008\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000z\213p\000\128\016\000\000\128\0020\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000D\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\245\170\224\001\000 \000\001\004\004\000\000\000\000\016\000\000\000\000\016\001\235U\192\002\000@\000\002\008\008\000\000\000\000 \000\016\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\029j\168\000@\008\000\000\000\001\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018\168\192\004\001\132\000\004\194`L\002\000\128\136\004\000\000L\134/Z\174\000\016\002\000\000\016@@\000\000\000\001\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\128\000\000\000\000\000\000/Z\174\000\016\002\000\000\016\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000=j\184\000@\008\000\000@\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000@\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\254\191\004\023\"@ \024\197q\251\194\000\253C\000\017\172@\160\128H\163\000\000\000\000\000\016\008\0010\000\000\002 \000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000z\213p\000\128\016\000\000\128\0020\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\008\001\000\000\008\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000@r\004\002\001\136Q\031\180 \015\2120\001\024\196\n\008\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\129@n\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128B\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\127\245\248 \185\018\001 \212+\143\222\016\007\234\024\004\143c\013\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\003\000\1607h\000\025 \000\001\008\004\016\000\000\000\001H\000\008\006\001@n\208\0002@@\000\002\016\008'\173W\000\n\145\000\018\013\002\160\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000)\000\001\000\192(\013\218\000\006H\008\000\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001\000\192(\013\218\000\006H\008\000\000B\001\004\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\008\006\001@n\208\0002@@\000\002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\000\n@\000@0\n\003v\128\001\146\002\000\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\128\001\017\130l\178X\000\001@\016\128\000\234\128\129A\220\000\000\000\000\000\000\000\000\000\000\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\n\145\000\018\013\002\160\223\160\000$\128\128@\004$\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000H\000\017\008&\194%\128\000\020\001\000\000\014\136\000\020\029\192\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\000\002!\004\216D\176\000\002\128 \000\001\145\000\002\129\184\000\000\000\001H\000\008\006\001@n\208\0002@@\000\002\016\008 \000\000$\000\008\132\019a\018\192\000\n\000\128\000\006D\000\n\006\224\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\144\000\"\016M\132K\000\000(\002\000\000\025\016\000(\027\128\000\000\000\020\128\000\128`\020\006\237\000\003$\004\000\000!\000\130\000\000\002@\000\136A6\017,\000\000\160\008\000\000d@\000\160n\000\000\000\000R\000\002\001\128P\027\180\000\012\144\016\000\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\008\006\001@n\208\0002@@\000\002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\144\000\"\016M\132K\000\000(\002\000\000\025\016\000(\027\128\000\000\000\020\128\000\128`\020\006\237\000\003$\004\000\000!\000\130\000\000\002@\000\136A6\017,\000\000\160\008\000\000d@\000\160n\000\000\000\000R\000\002\001\128P\027\180\000\012\144\016\000\000\132\002\008\000\000\t\000\002!\004\216D\176\000\002\128 \000\001\145\000\002\129\184\000\000\000\001H\000\008\006\001@n\208\0002@@\000\002\016\008 \000\000$\000\008\132\019a\018\192\000\n\000\128\000\006D\000\n\006\224\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\144\000\"\016M\132K\000\000(\002\000\000\025\016\000(\027\128\000\000\000\020\128\000\144h\020\006\237\000\001$\004\003\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000R\000\002\001\128P\027\180\000\012\144\016\000\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\008\006\001@n\208\0002@@\000\002\016\008 \000\000$\000\008\132\019a\018\192\000\n\000\128\000\006D\000\n\006\224\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\144\000\"\016M\132K\000\000(\002\000\000\025\016\000(\027\128\000\000\000\020\128\000\128`\020\006\237\000\003$\004\000\000!\000\130\000\000\002@\000\136A6\017,\000\000\160\008\000\000d@\000\160n\245\170\224\001R \002A\160T\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \008$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\255\235\240yr$\002\001\140W\031\188 \015\2120\001\026\196\n\008\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\129@n\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\004\000\000\000\000\000\000\132@\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255_\130\011\145 \016\012B\184\253\225\000~\161\128\008\214 PO\254\191\004\023\"@$\026\133\241\251\194\000\253C\000\145\172P\160\159\253~\015.D\128@1\138\227\247\132\001\250\134\000#X\129A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\247\252<\185\018\001\000\198/\143\2220\007\234\152@\143c\141f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\255\215\224\130\228H\004\003\024\174?x@\031\168`\0025\136\020\019\255\175\193\005\200\144\t\006\161|~\240\128?P\192$k\020('\255_\130\011\145 \018\013B\184\253\225\000~\161\128H\214 \208@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002@\000\136\1936Y,\000\000\160\008@\000w@D\160\238\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000 9\002\001\000\196(\143\218\016\007\234\024\000\140b\005\004\000\000\000@r\004\002\001\136Q\031\180 \015\2120\001\024\196\n\008\000\000\000\000\000\000\000\000\000\000\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\016H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000A \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t \016\001\t\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\002\003\144 \016\012B\136\253\161\000~\161\128\008\198 P@\000\000\004\007 @ \024\133\017\251B\000\253C\000\017\140@\160\128\000\000\000\000\000\000\000\000\000\000 \000\000\002\000\001\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002 \000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\008\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000D\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\016\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\004\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\128\001\001\130\012\146X\000\001\000\000\128\000f\128\137\001\024\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\005H\128\t\006\129Po\208\000\018@@ \002\018\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\004\007 @ \024\133\017\251B\000\253C\000\017\140@\160\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255_\130\011\145 \018\013B\184\253\225\000~\161\128H\214 P@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253\255\015.D\128@1\139\227\247\140\001\250\166\016#\216\227Y\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\004\000\128\000\004\000\016\000\000\000\000@\000\000\000\000\000\000\018(\192\000\000\000\000\004\002\000L\000\000\000\136\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\030\181\\\000 \004\000\000 \000\140\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\001\000\000@\000\000\000\000\000\005 \000$\026\133\001\187@\000I\001\000\128\008@ \128\000\000\000\n@\000@3\n\003v\128\001\146\002\001@\016\130A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001\000\192(\013\218\000\006H\008\000\000B\001\004\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\n\145\000\018\013\002\160\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\128`\020\006\237\000\003$\004\000\000!\000\130\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\003\000\1607h\000\025 \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\016\012\002\128\221\160\000d\128\128\000\004 \016@\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\128\129\006I(\000\000\128\000@\000!@D\000\012\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\005H\128\t\006\129Po\208\000\018@@ \002\018\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\005H\128\t\006\129Pn\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000 \000\000\000\000\000\164\000\004\131@\1607h\000\t \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\005 \000 \025\133\001\187@\000\201\001\000 \008@ \128\000\000\000\n@\000@3\n\003v\128\001\146\002\001@\016\130A\000\000\000\002\020\128\000\128f\020\006\237\000\003$\004\002\128!\004\130\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002A\168P\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\020\128\000\128f\020\006\237\000\003$\004\000\128!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\164\000\004\0030\1607h\000\025 \004\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\016\000 \192%\000\000\016\000\000\000\004\008\000\128\001\128\000\000\000\n@\000@0\n\003v\128\001\146\002\000\000\016\128A\000\000\001\000\000@\000\131\000\148\000\000@\000\000\000\016 \002\000\006\000\000\000\000)\000\001\000\192(\013\218\000\006H\008\000\000B\001\004\000\000\004\000\001\000\002\012\002P\000\001\000\000\000\000@\128\008\000\024\000\000\000\000\164\000\004\003\000\1607h\000\025 \000\001\008\004\016\000\000\016\000\004\000\0080\t@\000\004\000\000\000\001\002\000 \000`\000\000\000\002\144\000\016\012\002\128\221\160\000d\128\128\000\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000@0\n\003v\128\001\146\002\000\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001\000\192(\013\218\000\006H\008\000\000B\001\004\000\000\004\000\001\000\002\012\002P\000\001\000\000\000\000@\128\008\000\024\000\000\000\000\164\000\004\003\000\1607h\000\025 \000\001\008\004\016\000\000\016\000\004\000\0080\t@\000\004\000\000\000\001\002\000 \000`\000\000\000\002\144\000\016\012\002\128\221\160\000d\128\128\000\004 \016@\000\000@\000\016\000 \192%\000\000\016\000\000\000\004\008\000\128\001\128\000\000\000\n@\000@0\n\003v\128\001\146\002\000\000\016\128A\000\000\001\000\000@\000\131\000\148\000\000@\000\000\000\016 \002\000\006\000\000\000\000)\000\001\000\192(\013\218\000\006H\008\000\000B\001\004\000\000\004\000\001\000\002\012\002P\000\001\000\000\000\000@\128\008\000\024\000\000\000\000\164\000\004\003\000\1607h\000\025 \000\001\008\004\016\000\000\016\000\004\000\0080\t@\000\004\000\000\000\001\002\000 \000`\000\000\000\002\144\000\016\012\002\128\221\160\000d\128\128\000\004 \016@\000\000@\000\016\000 \192%\000\000\016\000\000\000\004\008\000\128\001\128\000\000\000\n@\000@0\n\003v\128\001\146\002\000\000\016\128A\000\000\001\000\000@\000\131\000\148\000\000@\000\000\000\016 \002\000\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\005 \000 \025\133\001\187@\000\201\001\000\160\008A \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\128f\020\006\237\000\003$\004\002\128!\004\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000R\000\002\001\152P\027\180\000\012\144\016\n\000\132\018\008\000\000\000\000\164\000\004\0030\1607h\000\025 \004\001\008$\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\002\144\000\016\012\194\128\221\160\000d\128\128P\004 \144@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\001H\000\008\006a@n\208\0002@@\008\002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\008\001\000\000\008\000#\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \212(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000&\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\004\000\004\128\000\000\000\000\000\000\001\000\000@\000\000\000\000\000\000\000\008\000\t\000\000\000\000\000\000\000\002\000\000\128\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000=j\184\000@\008\000\000@\001\024\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\128\000 \000\000\000\000\000\002\144\000\018\013B\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000u\170\160\001\000 \000\000\000\004\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\128\000 \000\000\000\000\000\002\144\000\018\013B\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\255\235\240Ar$\002\001\140W\031\188`\015\2120\001\026\196\n\008\000\000\000\000\000\000\000\128@\000\000\000\128\000\000\001\016\000\000\001\136\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255_\130\011\145 \016\012b\184\253\227\000~\161\132\008\214 V`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001 \000D`\155,\150\000@P\004$\000;\160 Pw\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\016\000\004\000\000\000\000\000\000R\000\002A\168P\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\008\001\000\000\008\000#\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \212(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\001\000\128\000\000\001\000\000\000\002 \000\000\003\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253~\008.D\128H5\n\227\247\140\001\250\134\017#X\129Y\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\245\248 \185\018\001\000\198+\143\2220\007\234\024@\141b\005f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\005H\128\t\006\129Po\208\000\018@@ \002\018\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\002`\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\001\235U\192\002\000@\000\002\000\008\192\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\004\000\001\000\000\000\000\000\000\020\128\000\144j\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\173U\000\008\001\000\000\000\000 \000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\004\000\001\000\000\000\000\000\000\020\128\000\144j\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253~\008.D\128H5\n\227\247\140\001\250\134\017#X\129Y\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128@ \000\000\000@\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\175\193\005\200\144\t\006\161\\~\241\128?P\192$k\016( \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\152\004\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\128\000\000\000\000@r\004\002\001\136Q\031\180 \015\2120\001\024\196\n\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\004\000\000\000\000\000\000\000\000\000\128\000\255\239\248Ar4\002a\168_\031\188`\031\2130\153\030\199Z\204\000\000\000\128\228\008\004\003\016\162?h@\031\168`\0021\136\020\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255_\130\011\145 \016\012b\248\253\225\000~\161\128\008\2468\208@\000\000\000\000\000\000\004\002\000\000\000\000\000\000\000\000\128\000\000\000\031\253~\008.D\128@1\139\227\247\132\001\250\134\000#\216\227A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@ \016\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\255\215\224\130\228H\004\131P\190?x@\031\168`\018=\1424\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255_\130\011\145 \018\013B\248\253\225\000~\161\128H\2468\208@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\016\000\031\253~\008.D\128@1\139\227\247\132\001\250\134\000#X\161A\000\000\000\000\000\000\000\016\008\002\000\000\000\000\000\000\002\000\000@\000\127\245\248 \185\018\001\000\198/\143\222\016\007\234\024\000\141b\133\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\002\001\000@\000\000\000\000\000\000@\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253~\008.D\128H5\011\227\247\132\001\250\134\001#X\161A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000 &\000\000\000@\000\000\000\004\000\000\000\000\000\000\000\128\003\001\000\000\000\000\000\128\000\000@\000\002\000/\254\191\004\023\"@ \024\197q\251\194\000\253C\000\017\172@\160\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004 \024\008\000\000\000\000\004\000\000\002\000\000\016\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\255\235\240Ar4\002a\168W\031\188 \031\2120\t\026\196J\013\255\215\224\130\228H\004\003\024\174?x@\031\168`\0025\136\020\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\254\191\004\023#@&\026\133q\251\194\001\253C\000\145\172D\160\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\016\000\031\253~\008.D\128H5\011\227\247\132\001\250\134\001#X\161A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\004\002\000\000\000\004\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000?\250\252\016\\\137\000\144j\021\199\239\024\003\245\012\002F\177\002\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\223\175\192\005H\144\008\006\001Pn\240\0002@@\000\011\016( \000\000\000\002\144\004\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000{\245\248\000\169\018\001\000\192*\013\222\000\006H\008\000\001b\005\004\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015Z\174\000\016\002\000\000\016\000@\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\002\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002A\168P\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\245\170\224\001\000 \000\001\000\004`\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\133\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\192\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\161@n\208\000\018@@ \002\016\008 \000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\014\181T\000 \004\000\000\000\000\128\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131P\1607h\000\t \016\001\008\004\016\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\016\000\030\253~\000*D\128@0\n\131w\128\001\146\002\000\000X\129A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002@\000\128\193\006I,\000\128\128\000H\0001@@\128\140\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\161@n\208\000\018@@ \002\016\008 \000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\015Z\174\000\016\002\000\000\016\000F\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002A\168P\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000=j\184\000T\136\000\144h\021\006\253\000\001$\004\002\000! \130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000&\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144j\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\235U@\002\000@\000\000\000\008\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H5\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\001\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000 \000\000\002\002`\000\000\004\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\001\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\016\128\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\255\235\240Ar$\002\001\140W\031\188 \015\2120\001\026\196\n\008\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000?\250\252\016\\\137\000\144j\021\199\239\008\003\245\012\002G\177\134\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\008@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\191\250\252\016\\\137\000\128c\021\199\239\008\003\245\012\000F\177\002\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\255\235\240Ar$\002\001\140W\031\188 \015\2120\001\026\196\n\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\000\000!\000\130\000\000\000\000\000\008\000\000\000\000\000\000\000\008\000\000\000\000\000\000\002\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\000\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\129@n\208\000\018@@\000\002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\004\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@r\004\002\001\136Q\031\180 \015\2120\001\024\196\n\008\000\000\000\000\000 \000\000\000\000\000\000\000 \000\000\000\000\000\000\008\000\000\001\001\200\016\008\006!D~\208\128?P\192\004c\016( \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\007 @ \024\133\017\251B\000\253C\000\017\140@\160\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\016\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\129@n\208\000\018@@\000\002\016\008 \000\000\000\000\000\128\000\000\000\000\000\000\000\128\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000?\250\252\000@\008\000\000@\001\000\002\000\000\004\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\008\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\016\000\000\000\000\000\000\005\255\215\224\002\000@\000\002\000\008\000\016\000\000 \000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255_\128\008\001\000\000\008\000 \000@\000\000\128\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\008\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t \000\001\008\004\016\000\000\000\000\000@\000\000\000\000\000\000\000@\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000=j\184@\225\008\137 B\001\000\000$\000\n\161 \000L\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015Z\174\0008B\"\008\016\128@\000\t\000\002\168H\000\019\000\000\030\181\\\000p\132\000\016!\000\128\000\018\000\005P\144\000&\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000@\016\008\000\000\000\000\000\000\000\008\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\001\000@\000\000\000\000\000\000\000\000 \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\016\000\000\000@\000\002\000\128\000\000\000\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000 \000\000\000\000\000\000\128\000\000\000\000\000\000\004\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\016\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015Z\174\0008B \008\016\128@\000\t\000\002\168H\000\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000=j\184\000\225\008\000 B\001\000\000$\000\n\161 \000D\000\000\000\008\000\000@\016\000\000\000\000\000\000\000\000\008\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\016\000\000\000@\000\002\000\128\000\000\000\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000 \008\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\001\000@\000\000\000\000\000\000\000\000 \001\000\000\000\000\000\000@\000\002\000\128\000\000\000\000\000\008\000\000@\002\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000@\016\000\000\000\000\000\000\000\000\008\000@\000\000\000\000\000\016\000\000\128 \000\000\016\000\000\002\000\000\016\000\128\000\008\000\000\000 \000\001\000@\000\000\000\000\000\000\000\000 \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\128\000\004\001\000\000\000\000\000\000\000\000\000\128\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\004\000\128\000\004\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\129\000\030\181\\\000 \004\000\000 \000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\016\000\000\128 \000\000\016@\000\000\000\000\016\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000(\000\000\000\000\000\000\000\128\000\004\001\000\000\000\000\000\000\000\000\000\128\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\001\000\000\000\004\000\000 \008\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\002\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\004`\000\000\129\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000 \008\000\000\000 \000\000\000\000\004\000 \000\000\000\000\000\008\000\000@\016\000\000\000\000\000\000\000\000\008\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\008\002\000\000\000\000\000\000\000\000\001\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000@\016\000\000\000\000\000\000\000\000\008\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\128\000\004\001\000\000\000\000\000\000\000\000\000\128\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000 \008\000\000\000\016\000\000\000\000\004\000 \000\000\000\000\000\008\000\000@\016\000\000\t\000\000\001\000\000\008\000@\000\004\000\000\000\016\000\000\128 \000\000\000\000\000\000\000\000\016\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000@\000\002\000\128\000\000\000\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\008\000\000\000 \000\001\000@\000\000\000\000\000\000\000\000 \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\016\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\001\000@\000\000\000\000\000\000\000\000 \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000@\000\000\001\000\000\008\002\000\000\000\000\000\000\000\000\001\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\128\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\002\000\128\000\000\000\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\016\004\000\000\000\016\000\000\000\000\002\000\016\000\000\000\000\000\004\000\000 \008\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\173\215\000\012\001\000\000\008@ \000\000\000\000\128\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\004\000\000 \008\000\000\000\144\000\000\128\000\004\000 \000\002\000\000\000\008\000\000@\016\000\000\000\000\000\000\000\000\008\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000=n\184\000`\008\000\000B\017\000\000\000\000\004\000 \000\000\000\000\000\008\000\000@\016\000\000\000\000\000\000\000\000\008\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\002\000\128\000\000\000\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000@\016\000\000\008\000\000\000\000\000\008\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000 \000\001\000@\000\000\000\000\000\000\000\000 \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\132\014\016\136\146\004 \016\000\002@\000\170\018\000\004\192\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\014\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\136\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\0001\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\129@n\208\000\018@@\000\002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\130\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253\255\008.D\128H=\014\227\247\132\001\250\166\017#X\129Y\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255\127\194\011\145 \018\015B\184\253\225\000~\169\132H\214 Vg~\251\128\016\002\000\000\000\000@\000\000\000\000\016\000\000\000\000\000\000H\163\000\000\000\000\000\000\008\000\000\000\000\000 \000\000\000\000\000\029\251\238\000@\008\000\000\000\001\000\000\000\000\000@\000\000\000\000\000;\247\220\000\128\016\000\000\000\002\000\000\000\000\000\128\000\000\000\000\000\002E\024\000\000\000\000\000\000@\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018(\192\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000$Q\128\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000H\163\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\145F\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000@3\n\003v\128\001\146\002\001@\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\223\191\224\004\000\128\000\004\000\016\000\000\000\000D\000\000\000\000\000\000\018(\192\000\000\000\000\004\000\000\000\000\000\000\008\000\000\000\000\000\015\254\191\004\023\"@ \024\197q\251\194\000\253C\000\017\172@\160\128\000\000\000\000\000\000\008\004\000\000\000\000\000\000\000\017\000\000\000\024\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128@ \000\000\000\000\000\000\000\136\000\000\000\196\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\175\193\005\200\144\t\006\161\\~\240\128?P\194$k\016+0\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\024\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\019\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\008\001\000\000\008\000#\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\016\000=j\184\000@\008\000\000@\001\024\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\017\000\003\214\171\128\004\000\128\000\004\000\017\128\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\127\245\248 \185\018\001 \212+\143\222\016\007\234\024\004\141b\013\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\020`\000\000\000\000\002\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\004\002\001\000\000\000\000\000\000\000\004@\000\000\006 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253~\008.D\128H5\n\227\247\132\001\250\134\017#X\129Y\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\004\192\000\000\008\000@\000\000\000b\000\000\000\000\000\128@\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\028\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\024\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\247\252 \185\018\001 \244;\143\222\016\007\234\152D\141b\005f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\136\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253\255\008.D\128H=\n\227\247\132\001\250\166\017#X\129Y\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\247\252 \185\018\001\000\198+\143\222\016\007\234\152@\141b\005f\000\000\000\000\000\000\000@ \000\000\000\000\000\000\000\136\000\000\000\197\255\223\240\130\228H\004\003\024\174?x@\031\170a\0025\136\021\152\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255\127\194\011\145 \018\013B\184\253\225\000~\169\132H\214 Vo\254\255\132\023\"@ \024\197q\251\194\000\253S\008\017\172@\172\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \016\008\000\000\000\000\000\000\000\"\000\000\0001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\255\239\248Ar$\002A\168W\031\188 \015\2130\137\026\196\n\204\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\191\225\005\200\144\t\006\161\\~\240\128?T\194$k\016+0\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\254\255\132\023\"@$\026\133q\251\194\000\253S\008\145\172@\172\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\003\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\254\255\132\023\"@$\026\133q\251\194\000\253S\008\145\172@\172\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \016\008\000\000\000\000\000\000\000\"\000\000\0001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\255\239\248Ar$\002A\168W\031\188 \015\2130\137\026\196\n\204\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000&\000\000\000@\002\000\000\000\003\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\t\000\000\000\000\000\000\000\000\002\t\192\012\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000@\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\002\004\000\000\000\000\000\000\004\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\008\016\000\000\000\000\000\000\016\000\000\000 \000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\008\001\000\000\000\000\000\004\000\000\016 \000\000\000\000\000\000 \000\000\000@\000\000\000\001\000\002\000\002\000\000\000\000\000\000\000\017\128\016\000 \020\000\000\000\000\000\016\000\000@\128\000\000\000\000\000\000\128\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000 \000 \000\000\000\000\000\000\001\024\001\000\000\001@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\008\000\000\000\000\000\000\000\000\000N\000`\000\000@\000\000\000\008\000\016\000\000\000\000\000\000\000\000\000\140\000\192\000\000\128\000\000\000\016\000 \000\000\000\000\000\000\000\000\001\024\001\000\000\001\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\004`\004\000\128\004\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000F\000@\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\0020\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\002\000\000\000\000\000\000\000\000\000\017\128\024\000\000\016\000\000\000\002\000\004\000\000\000\000\000\000\000\000\000#\000 \000\000 \000\000\000\000\000\008\000\000\000\000\000\000\000\000\000F\000@\000\000@\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\140\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")
let action =
- ((16, "\001\128\000X\000\000\000\000\001\015\000\000\000\000\000\000\001\128\000\000\002,%\"\000\000\000\127;\208\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\191\000y\000\000%\"#\"C\146\000C<2\000\000\000\000\000\000\000\000B\244\000\005C\146\001 C\146\000\000\000U\000\000C\146\000\000\000\133\000\000\000\000\000\0032\202\000\000\000\0004\156\000\0005\028\000\1822\2022\202\016j\016j5\028\000\0006L\000\0006\2042\202\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0005t2\202\000\000\000\0005t\000\0005t\000\0005t\000\000\000\000\000\000\018\208\000\133\000\000\016j\000\000*\2202\202\02302\202\000\000\000\000\000\000\000\000\000\000\000\000\025`2\202\000\000\026N2\202\026\1742\202\027\1562\202\000\0002\202\000\0002\202\027\2522\202\028\2342\202\029J2\202\03082\202\030\1522\202\000\1462\202\000\000\000\000\000\000\000\000\000\0002\202\031\1342\202\031\2302\202 \2122\202\000\000\000\0002\202\000\000\015\254%\164\000\000\000\000\000\140\000\000\000\000\000\000\023\252\000\000\000\000\000\000\000\000\000\000\014\024\000\127\000\000%\164\000\000\000\251\016j\000\0002\202\000\222\000\000\000\000\000\133\000\000\000\000\000\000\000\000\001\028\000\000\000\000\001@\000\000\00052\202\000\000\0005\000\000\000\000\016j\001B\000\000\002\"\000\000\000\000\000\000\000\000\000\000\000\000\000\0007$2\202\000\0007$\000\0007$7$\000\000\000\000'\164\000\133\000\000\016j\002N\000\0002\202\002T\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016j\002^6L\000\000\000\000;\1602\202\000\0002\202\000\000\000\000\002f\000\000\000=5\244\003N2\202\003V\000\000\000\0006L\000=\000\000\000\000\000\000\000\000\000\000<\2166L=,6L=<6L>26L\000\0006L\000\0006L>`6L>\1806L?\1506L?\1966L@\0242\202\003\0206L\000\0006L@\2506LA(6LA|\003$\000\000\003\160\000\000\000\132%\"\000\000\000\132\000\000\000\000\003\1802\202\000\000\004$\000\0006L\004\140\000\000\016j\003\214\000\000\000\000\003\232\000\000\000\000\000\003\000\000\004\198\000\000%>B:\004\196\004\198\000\133\004P\005$D0\000C\000\000\000\000\001\006D\136\000\000\000\000\000\000\005(\005\024\001\"\005>D0\001\222D0\000\000\000\000\001 \000\000\000\000\004\146\000\000\004\162\005`D0\004\186\000\000\000\000\001\006\000\000\004\202\005\156\000\000D\222C\232\000\000\000\133\005\182\000\000\014\024\000\133\005\186\000\000\000\000#\214C\146\004\234\000\000\005j\000\000\005\002\000\000\000\162%\"\000\000%\"\000\000\004\240\000\000\000\162\000\000\012\246\018\240\005\192D0\005\018\005\232\000\000%\"\000\158\000\000\005\236\000\000\000\000\000\000\000\000\000\000\000\000\005\2102\202\005$\017\"\005\2142\202\0050\005\218\001\006\005^\006z\000\0007\1648$\016j\005<\000\000\005D8$\000\000\000\000\000\000\000\000\000\000\000\000\000\0008\1642\202\000\0008\164\000\0008\1648\164\000\000\000\000\022B\000\133\000\000\016j\005`\000\0002\202\005r\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000&.2\202\000\0002\202\000\000\005z\000\000\0005\000\000\000\000\000\000\000\000\000\000+@8$,.8$,b8$-P8$\000\0008$\000\0008$-\1328$.r8$.\1668$/\1488$/\2002\202\005\1668$\000\0008$0\1828$0\2348$1\216\016j\005\130\000\000\000\0002\202\000\000\006T\000\000\001J\006.2\202\006\000\000\000\006<2\202\006\008\000\000\003>\000\000\006z\006z\001J\000\000\001J\000\000\012\246\006z\006z\000\000\000\000\000\000\020\172\000\000\000\000\000\000\000\000\006L2\202\005\162\017\"\017\240\000\133\006v\000\000\006X3\132\006|3\132\006\1302\202\005\180\017\"\017\"\000g\0026\000Y\000\000\000\000\000\000\0026\000\000\002j\000g\000\000\000\000\005\184\000\000\000\000\000\000\006\142\000\000\006\144\000\000\000\000\006\192\006v2\202\005\204\006\160\000\000\019\190\006\136\016j\005\218\017\"\000\000\000\000\006\004\000\000\0009\000\000\003\226\000\000\001J\000\000\000\000\006X\000\000.(\018\240\006\156D0\005\252\006\214\000\000\000\133\000\000\000\0272\202(J\000\0009$2\202\006\n\000\000\016j\006\n\000\000\006\016\000\000\000\000\000\000\000\000\000\000\000\000\000\0009\1642\202\000\0009\164\000\0009\1649\164\000\000\000\000D\174\000\133\000\000\016j\006\018\000\0002\202\006\016\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016j\006\024:$\000\000\000\0002\202\000w2\202\006\022\006J(J(\242'\014\006\1962\202\006\156\000\000\000\000\000\133\006^(J\000\000\006\\(J\000\000\000\000\020X:$\021F:$\025p:$!\188:$\000\000:$\000\000:$$~:$(&:$E\216:$E\238:$F8:$Ff:$F\196:$F\218\000\000\000\000\0064\000\000\006D)\154\000\000*B\006J*B1\252\006L*B\000\000\000\000\000\000\000\000\000\000\006t(J\000\000\000\000\006F\000\000\007\030\000\000\000\133\000\000\000\027\007$\000\000\000N\006\250\000\133\006^\007\024D0\006n\000@\000\0002\202\007B\000\000\001\022\001\026\003\178\007,D0\006~\007T\000\000\000\0052\202\007X\000\000\007`\000\000\014\024\000\133\002\1722\202\007|\000\000\007\128\000\000\011\170\0009\000\000\011\170\000\000\000\000\019\190\002\2442\202\007\144\000\000\007\148\000\000\000\000\001\154\007h\000\133\006\206\007\128D0\006\210\000\210\000\0002\202\007\166\000\000\0009\000\000\000\000\007\198\000\000\011\170\000\000\007\142\016j\006\228\007\182\000\000\001\022\000\000\007\158D0\006\242\007\196\000\000\00302\202\007\200\000\000\007\202\000\000\014\024\000\133\003@2\202\007\206\000\000\007\208\000\000\000\000\000\000\007\198\000\000\000\000\0009\000\000\006z\000\000\001\022\000\000\000\000\001\024\017\240\000\000\001\024\000\000\000\000\007\006\000\000\0005\000\003\017\"\000\000\003\226\0009\003\226\000\000\0009\000\000\006z\000\000\006z\000\000\000\000\000\000\007\004\000\000\000\000\007\014\000\000\001\162\005.\000\013\003\226\000\000\000\000\000\000\003\"\000\000\006z\000\000\001\162\000\000\000\000\001\022\003\214\012\246\000\000\014\242\000\000\t\018\012\246\000\000\000\000\t\018\000\000\000\000\007\012\000\000\000\000\007\018\000\000\001\248\006z\000\000\001\248\000\000\000\000\007\128\000\000\0009\000\000\006z\000\000\000\000\000\000\015\1283\226\000\000\007\232\000\000\015\128\007\236\000\000\007\244\000\000.(\000\133\002\028\000\0002\202\007\246\000\000\007\218\007\212\000\133\007H\008\002D0\007T\002d\000\0002\202\008&\000\000\001\022\002\176\000\0002\202\008,\000\000\014\024\000\133\002\196\000\0002\202\008.\000\000\002\158\015\128\000\000\019\190\003<\000\0002\202\0080\000\000\000\000\000\000\008\022\008\006\000\133\007j\008\028D0\007~\004$\000\0002\202\008V\000\000\002.\000\000\0088\016j\007\144\008b\000\000\002\188\000\000\004j\000\0002\202\008d\000\000\014\024\000\133\004\140\000\0002\202\008h\000\000\002\158\000\000\000\000\007\162\000\000\002.\003\174\008\016\000\000\000\000\000\000\008\020\000\000\002\016\002d\000\000\012\246\008f\000\000\000\0002\202\007\214\006z\000\000\007\174\000\000\001\006\000\000\000\000\003h\012\246\000\000\012\246\000\000\007\160\000\000\003h\000\0006L\003\2046L\000\0006L\000\000\007\164\000\000\003\204\000\000\017\"\004\028\017\"\000\000\017\"\000\000\007\168\000\000\004\028\000\0006L\003\204\007\174\000\000;\028\000\133\004 ;\028\000\000;\028\000\000\007\178\000\000\004 \000\0006L\003\204\007\186\000\000\000\000\021\248\000\000\000\000\000\000\000\000\000\000\025H!x\000\000\006\160\000\000\005\222\000\000\000\000\007\254\000\133\000\000\000\000\000\000\000\164\005\222\000\000\002\238\002\130\002\130\000\000\002\018\002\130\000\000\007\242\000\000\000\000\000\000\000\000\000\000\000\000\008p\000\000\"\160\000\000%\"\005\222\000\000\003^\005\222\000\000\008~\000\000\005\222\008\130\000\000\005\234\006\030\008\132\000\000\008\134\000\000\0076\007\216\005\222\008\018\005\222\008\140\000\000\008\142\000\000\008\146\000\000%\"\000\000\002\154%\"\000\000\008\028\011\188\000\000\001\002\005\222\000\000\004\166\005\222\000\000\004\208\003\136\000\133\000\000\t\004\000\133\000\000\008$\000\000\000\000\000\000\000\000\008\164\000\000\006\030\005\222\008\166\000\000\008\178\000\000\005\222\008\180\000\000\005\222\008\182\000\000\008\144\005\222\008\186\000\000\015\180\006\030\005\222\008D\005\222\008\190\000\000\008\192\000\000\000\000\004\168\005\222\000\000\004\220\001\130\001\130\000\000\000\000\000\000\003\158\001\130\000\000\008J\000\000\000\000\000\000\000\000\005\222\000\000\004\200\005\222\000\000\004\234\003\196\000\133\008L\000\000\000\000\000\000\000\000\008\204\000\000\008\206\000\000\005\222\008\208\000\000\007\216\005\222\008\210\000\000\008\216\000\000-\006\008\140\008\182\007j\005\222\008\226\000\000\000\000\008\228\000\000\008\186-\006\005\222\008\234\000\000\005\222\008\238\000\000\008\246\000\000\005\222\008\128\005\222\008\250\000\000\t\008\000\000\000\133\008\140\000\000\000\000\021\248\000\000\000\000\0028\th\000\000\000\000\003^\000\000\000\000\000\0002\202\000\135\t\166\008\208\tR6L\000\000\003\1926L\000\000\008\166\000\000\000\000\000\000\000\000\000\000\002\150\000\000\003n\000\000\000\000\000\000\003\226C2\005lC2C2\005l\000\000\000\000\000N\000N\000N\000N\000\000\000\000\000\000\000\000\000\000\000\000(J\008\166\000\000\000\000\000\000;\160\000N\014@\0009\000\000\000\000\0009\000\000\007\198\000\000\000\000\000\135\000\000\000\000\008\240\001h\t`E\146\000\000\004nE\250\000\000\000\000\tb\tR\000\133\000\000\000\133\000\000\004n\000\000\004\140E\146\000\000\000\000\008\182\tr\006z\008\204\000\000\001\154\0009\000\000\007\198\000\000\014\196\005,\000\000\000\000\tp\000\000\000\000\0028\000\000\004\172\000\000\000\000\000\0002\202\000\135\000\000\002\150\000\000\004\230\000\000\000\000\000\000\005.\000\000\n^\001\020\n^\000\000\006z\n^\000\000\001\020\000\000\006z\000\000\006z\000\000\006z\000\000\000\000\000\000\000\000\000\000\000\135\000\000\006z\000\000\001\020\000\000\006z\000\000\017H\000\000\000\000\t\018\t\008\000\133\003\144\t\152\004`\000\000\004`\t\194\000\000\t\196\000\000\t\200\000\000\000\000\001*\004`\012\244\004`\000\000\000\000\000\152\008\220\000\000\t\206\000\000\000\000\t\018\007\184\002\202\t\234\n\248\t\234\000\000\000\000\007\250\000\133\000\000\004\024\tD\000\000\000\000\000\000\004\192\000\000\008\246\000\000\000\000\000\000\007\184\002\202\007\250\004\024\004\192\008\252\000\000\000\133\000\000\t\242\t\238\t<\000\133\t\144\000\000"), (16, "\n\149\n\149\n\149\n\149\n\149\n\149\n\149\n\149\n\149\n\149\n\149\000:\n\149\n\149\n\149\n\149\n\149\n\149\n\149\n\149\n\149\tJ\000\210\tJ\002\174\n\149\000\023\000\027\003i\005\197\008\002\n\149\0055\n\149\n\149\n\149\n1\000\210\n\149\0086\000z\000\146\n\149\n\149\000\210\n\149\006F\n1\005=\006J\000\162\002\242\008\002\020\178\n\149\006N\000~\n\149\n\149\006R\020\182\0086\020>\n\149\n\149\000\162\n\149\000\222\n\149\000\174\0119\003\233\000\162\n\149\nf\n\149\n\149\n\149\n\149\n\149\000\n\011\186\008\186\n\149\n\149\n\149\n\149\n\149\n\149\008\194\n\149\n\149\n\149\n\149\005\229\005\229\011f\n\149\n\149\005\229\000\014\0119\002\253\003\218\011\158\tV\003%\n\149\n\149\n\149\n\149\n\149\n\149\n\149\000\194\n\149\002U\n\149\t\146\n\149\002U\003%\n\149\n\149\005\197\005\242\005\157\tV\n\149\011\238\005=\013f\n\149\0119\0119\n\149\011\134\022\182\0119\n\149\n\149\n\149\n\149\004\158\n\149\n\149\003\233\011\134\005=\n\149\n\149\n\149\005=\n\149\012z\n\149\n\149\0066\n\149\003\181\n\149\n\149\000\250\011\190\n\149\n\149\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\ny\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\tJ\012\190\005\250\004q\005\205\008\006\008\022\008&\000\162\008\002\005\205\003%\005\205\005\205\005\205\003%\003%\005\205\0086\004\005\002\026\005\205\004q\022\182\005\205\006F\000\182\003%\006J\004\158\013B\005\149\020\178\005\205\006N\000\006\002r\001.\006R\020\182\011\206\001:\005\205\005\205\017J\000\210\000\210\005\205\005\205\012~\0136\003%\005\205\022\190\005\205\005\205\005\205\005\205\005\205\007\217\005m\018.\005\205\005\205\005\205\005\205\005\205\005\205\000\162\005\205\005\205\005\205\005\205\000\162\000\162\018\246\005\205\005\205\001.\002\190\008\t\0016\001:\012^\tV\004q\006z\005\205\005\205\005\205\005\205\005\205\005\205\005.\005\205\016\018\005\205\005U\005\205\013\182\005E\005\205\005\205\004q\005\149\005\189\007\013\005\205\002\222\000\162\007\013\005J\008\t\008\t\005\205\022\198\018\250\008\t\005\205\005\205\005\205\005\205\000\162\005\205\005\205\002\234\022\190\003\014\005\205\005\205\005\205\005\237\014\158\005\237\005\205\005\205\005\237\005\205\003\181\005\205\005\205\015r\0146\005\205\005\205\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\008*\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005e\005e\014\206\002\242\005\237\005\237\020\026\005\237\005\165\n!\005\237\0172\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\000.\006\018\016Z\016\130\016\170\016\186\016\230\005\237\022\238\005V\005\237\017Z\n1\002y\014\230\005\237\005\237\005\237\005\237\005\237\015\142\005\237\014\162\005\213\015\002\005\173\005\237\020\026\005\237\005\237\005\237\005\237\005\237\015\022\015\250\017f\005\237\005\237\005\237\005\237\005\237\005\237\nI\005\237\005\237\005\237\005\237\003\022\n1\014b\005\237\005\237\005\157\008\190\014f\005\237\001.\005]\014\210\011\206\001:\005\237\005\237\005\237\005\237\005\237\005\237\017V\005\237\003j\005\237\tJ\005\237\008*\003v\005\237\005\237\003\170\n1\008\218\008\002\005\237\003\210\003\001\015&\005\237\n1\000\162\005\237\0086\015\230\006\021\005\237\005\237\012\014\005\237\014\234\005\237\005\237\003\233\005\213\016:\005\237\018\022\005\213\005\213\015\006\008.\005\181\005\237\n)\005\237\011\134\005\237\005\237\003\226\005\213\005\237\005\237\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\012B\000^\020\146\000b\006N\000f\000j\000n\006R\020\154\005\213\015\142\018J\004m\006V\006\021\003\234\nY\011\134\004j\000r\016b\000\226\006f\006\130\tV\007!\006\134\014b\004\001\012\218\000v\004m\014f\007\242\016B\015*\014j\012\250\004\158\008\002\007!\019B\000\238\003\233\004\142\008\002\001.\011\134\0086\011\206\001:\008J\006\142\020\214\0086\011\134\008N\013r\000\162\023\018\016\138\001\"\016\198\001&\003\197\000\134\tR\008V\015\230\015^\017\170\006\162\001.\008Z\006\166\008^\001:\000\162\006\170\006\174\008b\006\178\020+\020/\016j\022\134\008f\0203\000\162\007!\020\131\020\135\005\133\022\142\004m\020\139\006\182\006\186\008j\008n\006\190\008r\019\n\000\162\015\150\008\134\004\150\003\161\003!\nA\008\146\006\198\004m\005\149\tV\022\146\005\245\004\182\004\194\020V\tV\015\178\022\150\008\178\016\146\n9\016\206\008\182\008\242\003\197\t^\004\206\006\202\008\246\004\218\007!\023\026\006\206\003\197\003\197\003\129\023\030\005}\003\197\008\254\004\230\006\210\007!\005\245\005\245\004\250\015b\001j\005\245\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\005\n\000^\020\146\000b\006N\000f\000j\000n\006R\020\154\005\014\003\129\018F\022\158\006V\ni\na\005\141\018\242\005u\000r\015\154\000\226\006f\006\130\019>\0055\006\134\021\167\0055\005\022\000v\nq\0055\007\242\0055\006\005\021\171\015\182\0055\0055\021:\005\253\000\238\022\166\005M\008\002\021\174\005\026\006\013\005B\005F\008J\006\142\020\214\0086\021j\008N\013\186\023&\002m\005N\001\"\005r\001&\003\213\000\134\tR\008V\018:\018\230\005z\006\162\001.\008Z\006\166\008^\001:\005~\006\170\006\174\008b\006\178\005\134\021\199\021\203\0192\008f\017*\021\207\006\005\005\154\005\158\002b\017\202\004\217\005\253\006\182\006\186\008j\008n\006\190\008r\006\013\000\162\005\182\008\134\005\198\003\161\017.\005\218\008\146\006\198\021\235\021\239\017.\005\226\006\029\021\243\0172\017*\tV\005\234\006\007\008\178\0172\006\030\006&\008\182\008\242\006*\t^\006>\006\202\008\246\006Z\006b\006j\006\206\0055\003\213\017.\006r\006v\019\226\008\254\006~\006\210\006\150\006\029\006\029\0172\006\158\001j\006\029\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\006\246\000^\020\146\000b\006N\000f\000j\000n\006R\020\154\018\194\007\002\007J\t\205\006V\018~\007\194\007\234\007\254\007\221\000r\008\n\000\226\006f\006\130\008\018\000\162\006\134\008\026\008\"\008v\000v\000\162\008~\007\242\008\142\008\150\t\205\008\158\017>\007\221\008\166\008\174\000\238\008\234\017>\008\002\008\250\t\002\t\014\007\221\t\018\0082\006\142\t\026\0086\t\030\008N\000\162\017\"\t*\t2\001\"\tB\001&\003\241\000\134\008R\008V\tf\tv\017>\006\162\001.\008Z\006\166\008^\001:\t~\006\170\006\174\008b\006\178\t\130\t\170\t\182\011A\008f\t\190\n\018\n\030\t\205\nR\nn\017\226\nr\n\130\006\182\006\186\008j\008n\006\190\008r\n\138\000\162\n\154\008\134\n\166\003\161\011*\0112\008\146\006\198\011B\011N\017.\011j\008\017\011z\011\130\004a\tV\011\150\007\221\008\178\0172\011\162\011\170\008\182\008\242\003\241\t^\011\174\006\202\008\246\011\182\007\221\011\198\006\206\003\241\003\241\004a\011\218\011\226\003\241\008\254\011\230\006\210\011\246\008\017\008\017\004a\011\254\001j\008\017\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\012\022\000^\012\030\000b\006N\000f\000j\000n\006R\017*\012J\003!\012R\t\193\006V\012b\004a\012j\012n\012v\000r\012\134\000\226\006f\006\130\012\170\003!\006\134\012\178\012\182\017.\000v\000\162\012\198\007\242\012\206\012\210\t\193\012\226\012\234\0172\013\002\013\n\000\238\013Z\017>\008\002\013\162\013\174\014\"\014.\014N\0082\006\142\014z\0086\014\134\008N\004a\005\221\014\142\014\170\001\"\014\178\001&\017\230\000\134\008R\008V\014\182\019z\004a\006\162\001.\008Z\006\166\008^\001:\014\190\006\170\006\174\008b\006\178\014\194\014\202\014\218\011A\008f\014\242\015\014\0152\t\193\t\205\015B\015F\015N\015R\006\182\006\186\008j\008n\006\190\008r\003!\000\162\015Z\008\134\003!\003!\015j\015z\008\146\006\198\000\162\015\130\015\134\015\162\011A\015\190\003!\022\134\tV\015\210\015\226\008\178\015\242\017>\016\n\008\182\008\242\016\026\t^\016&\006\202\008\246\016O\005\221\016w\006\206\016\159\005\221\005\221\016\183\003!\016\219\008\254\t\205\006\210\016\243\011A\011A\0176\023\006\001j\011A\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\017r\000^\017\143\000b\006N\000f\000j\000n\006R\017\183\005\221\017\195\017\211\017\219\006V\017\238\017\247\017\255\003\141\018\007\000r\018\"\000\226\006f\006\130\018b\nQ\006\134\018w\018\135\022z\000v\007)\003\141\007\242\018\143\018\155\018\167\018\174\018\183\018\202\018\211\018\219\000\238\019\022\019J\008\002\007)\019_\019g\019s\019\131\0082\006\142\019\139\0086\019\150\008N\019\154\019\167\019\179\019\186\001\"\019\199\001&\019\211\000\134\008R\008V\019\219\019\230\019\239\006\162\001.\008Z\006\166\008^\001:\019\247\006\170\006\174\008b\006\178\020\003\020\030\020B\020F\008f\020J\020b\020\222\021&\021.\021J\021N\021z\007)\006\182\006\186\008j\008n\006\190\008r\nQ\000\162\021~\008\134\nQ\nQ\021\134\003\141\008\146\006\198\022\214\003\141\003\141\021\179\022~\022\138\022\154\022\162\tV\022\170\022\211\008\178\022\218\003\141\003\141\008\182\008\242\018V\t^\022\242\006\202\008\246\023\022\023/\nQ\006\206\023S\023b\023f\007)\nQ\023j\008\254\023s\006\210\000\000\000\000\003\141\000\000\000\000\001j\007)\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\000\000\000^\020\146\000b\006N\000f\000j\000n\006R\020\154\000\000\000\000\000\000\000\000\006V\000\000\000\000\000\000\000\000\000\000\000r\000\000\000\226\006f\006\130\000\000\000\000\006\134\000\000\000\000\000\000\000v\000\000\000\000\007\242\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008J\006\142\000\000\000\000\000\000\008N\022\002\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\134\tR\008V\000\000\000\000\000\000\006\162\001.\008Z\006\166\008^\001:\000\000\006\170\006\174\008b\006\178\000\000\000\000\000\000\000\000\008f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\182\006\186\008j\008n\006\190\008r\000\000\000\162\000\000\008\134\000\000\003\161\000\000\n\025\008\146\006\198\000\000\000\000\000\000\000\000\007\245\000\000\000\000\000\000\000\000\000\000\000\000\008\178\000\000\000\000\000\000\008\182\008\242\000\000\t^\000\000\006\202\008\246\000\000\000\000\000\000\006\206\000\000\000\000\000\000\000\000\000\000\000\000\008\254\000\000\006\210\000\000\007\245\007\245\000\000\000\000\001j\007\245\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\000\000\000^\000\000\000b\006N\000f\000j\000n\006R\0055\000\000\000\000\000\000\000\000\006V\000\000\000\000\000\000\000\000\000\000\000r\n\025\000\226\006f\006\130\n\025\n\025\006\134\000\000\000\000\0055\000v\000\000\000\000\007\242\000\000\000\000\n\025\000\000\000\000\0055\000\000\000\000\000\238\000\000\000\000\000\000\000\000\022\246\000\000\000\000\000\000\008J\006\142\000\000\000\000\000\000\008N\012&\000\000\000\000\n\025\001\"\000\000\001&\0055\000\134\tR\008V\000\000\000\000\002b\006\162\001.\008Z\006\166\008^\001:\000\000\006\170\006\174\008b\006\178\000\000\000\000\000\000\011\029\008f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\182\006\186\008j\008n\006\190\008r\000\000\000\162\000\000\008\134\000\000\000\000\000\000\000\000\008\146\006\198\0055\000\000\000\000\000\000\011\029\000\000\000\000\000\000\000\000\000\000\000\000\008\178\000\000\0055\000\000\008\182\008\242\000\000\t^\000\000\006\202\008\246\000\000\000\000\000\000\006\206\000\000\000\000\000\000\000\000\000\000\000\000\008\254\000\000\006\210\000\000\011\029\011\029\000\000\000\000\001j\011\029\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\000\000\000^\000\000\000b\006N\000f\000j\000n\006R\000\000\000\000\000\000\000\000\000\000\006V\000\000\000\000\003\029\000\000\000\000\000r\000\000\000\226\006f\006\130\000\000\000\000\006\134\000\000\000\000\000\000\000v\003\029\000\000\007\242\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\000\000\000\003\029\000\000\000\000\000\000\008J\006\142\000\000\000\000\000\000\008N\013\238\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\134\tR\008V\000\000\000\000\000\000\006\162\001.\008Z\006\166\008^\001:\000\000\006\170\006\174\008b\006\178\000\000\000\000\000\000\000\000\008f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\182\006\186\008j\008n\006\190\008r\000\000\000\162\000\000\008\134\000\000\000\000\003\029\000\000\008\146\006\198\003\029\003\029\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\178\003\029\000\000\000\000\008\182\008\242\000\000\t^\000\000\006\202\008\246\002\154\000F\000J\006\206\000N\003\029\000R\000V\000\000\000Z\008\254\000^\006\210\000b\003\029\000f\022\190\000n\001j\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\000r\000^\000\000\000b\006N\000f\000j\000n\006R\000\000\000\000\000v\000\000\000\000\006V\000\000\000\000\000\000\000\000\000\000\000r\000\000\000\226\006f\006\130\000\000\000\000\006\134\000\000\000\000\000\000\000v\000\000\000\000\007\242\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\134\000\000\000\000\000\000\000\000\000\000\008J\006\142\000\000\000\000\000\000\008N\020\246\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\134\tR\008V\000\000\000\000\000\000\006\162\001.\008Z\006\166\008^\001:\000\000\006\170\006\174\008b\006\178\000\000\000\162\000\000\000\000\008f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\182\006\186\008j\008n\006\190\008r\012\190\000\162\000\000\008\134\000\000\000\000\000\000\000\000\008\146\006\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007!\000\000\000\000\008\178\000\000\tJ\000\000\008\182\008\242\000\000\t^\000\000\006\202\008\246\008\002\007!\000\000\006\206\001.\000\000\000\000\011\206\001:\0086\008\254\000\000\006\210\000\000\0002\006\022\000F\000J\001j\000N\006F\000R\000V\006J\000Z\000\000\000^\000\000\000b\006N\000f\000j\000n\006R\000\000\000\162\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000r\000\000\000\226\006\229\006\130\007!\018\190\006\134\000\000\000\000\000\000\000v\000\000\000\000\014n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\000\017.\000\000\000\000\tV\000\000\014~\006\142\000\000\006\229\006\229\0172\000\000\000\000\006\229\000\000\001\"\0055\001&\000\000\000\134\000\000\000\000\000\000\000\000\007!\006\162\001.\000\000\006\166\0016\001:\000\000\006\170\006\174\008b\006\178\007!\0055\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\000\0055\0055\000\000\006\182\006\186\000\000\000\000\006\190\000\000\000\000\000\162\000\000\0002\0006\000F\000J\000\000\000N\006\198\000R\000V\000\000\000Z\000\000\000^\0055\000b\000\000\000f\000j\000n\002b\000\000\000\000\0055\0055\000\162\t^\000\000\006\202\014\130\000\000\000\000\000r\006\206\000\226\000\000\000\230\000\000\017>\000\234\014\138\000\000\006\210\000v\000\000\000\000\000\000\000\000\001j\000\000\000\000\000\000\000\000\000\000\0055\000\238\000\000\000\000\000\242\000\000\000\000\000\000\0055\000\000\001\006\001\002\000\000\001\n\000\000\000\000\000\000\000\000\000\000\000\000\001\"\0055\001&\000\000\000\134\000\000\000\000\000\000\000\000\000\000\001*\001.\000\000\0012\0016\001:\001\142\001>\001B\000\000\001F\0055\000\000\000\000\0055\0055\000\000\000\000\0055\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001J\000\000\0055\001N\000\000\000\000\000\162\000\000\006V\000\000\000\000\000\000\000\000\000\000\001V\000\000\000\226\006f\006\130\000\000\000\000\006\134\000\000\001Z\000\000\000\000\000\000\000\000\007\242\000\000\000\000\000\000\000\000\000\000\000\000\001^\000\000\000\238\000\000\000\000\001b\000\000\000\000\003e\000\000\000\000\008\130\006\142\000\000\001f\012\190\008N\000\000\000\000\000\000\001j\001\"\000\000\001&\000\000\000\000\000\000\008V\000\000\000\000\000\000\006\162\001.\008Z\006\166\008^\001:\000\000\006\170\006\174\000\000\006\178\000\000\000\000\000\000\000\000\008f\000\000\000\000\000\000\000\000\001.\000\000\000\000\011\206\001:\006\182\006\186\008j\008n\006\190\008r\000\000\000\162\000\000\008\134\000\000\000\000\000\000\000\000\008\146\006\198\000\000\000\000\000\000\000\000\006V\000\000\000\000\000\000\000\000\000\000\000\162\008\178\000\226\006f\006\130\008\182\008\242\006\134\000\000\000\000\006\202\008\246\000\000\008A\007\242\006\206\000\000\000\000\000\000\000\000\000\000\000\000\008\254\000\238\006\210\000\000\000\000\000\000\000\000\000\000\001j\000\000\006\138\006\142\000\000\000\000\000\000\008N\000\000\000\000\000\000\000\000\001\"\000\000\001&\008A\008A\000\000\008V\000\000\008A\000\000\006\162\001.\008Z\006\166\008^\001:\000\000\006\170\006\174\000\000\006\178\000\000\000\000\000\000\000\000\008f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\182\006\186\008j\008n\006\190\008r\000\000\000\162\000\000\008\134\000\000\000\000\000\000\000\000\008\146\006\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011m\0055\008\178\011m\0055\000\000\008\182\008\242\0055\000\000\0055\006\202\008\246\000\000\0055\0055\006\206\000\000\011m\000\000\000\000\000\000\011m\008\254\000\000\006\210\001\130\011m\000\000\000\000\000\000\001j\000\000\011m\000\000\000\000\011m\011m\000\000\011m\011m\000\000\000\000\001\138\000\000\011m\002\182\000\000\000\000\011m\000\000\000\000\011m\000\000\011m\011m\000\000\000\000\000\000\0055\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\146\000\000\000\000\000\000\000\000\000\000\011m\000\000\011m\000\000\000\000\001.\000\000\000\000\0016\001:\000\000\000\000\011m\000\000\000\000\000\000\000\000\002\194\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011m\011m\011m\000\162\011m\011m\002\198\0055\011m\000\000\000\000\000\000\004\001\000\000\000\000\004\001\002\206\000\000\000\000\000\000\011m\000\000\000\000\011m\011m\011m\011m\000\000\000\000\000\000\004\001\011m\011m\011m\004\001\011m\011m\011m\004\001\004\001\000\000\000\000\000\000\000\000\000\000\004\001\000\000\000\000\004\001\004\001\000\000\004\001\004\001\000\000\000\000\004\001\000\000\004\001\004\001\000\000\000\000\004\001\000\000\000\000\004\001\000\000\004\001\004\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\210\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\001\000\000\004\001\n\182\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\001\000\000\000\000\000\000\000\000\004\001\000\000\000\000\000\162\n\190\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\001\004\001\004\001\n\198\004\001\004m\004\001\000\000\004\001\011\006\011\014\000\000\004\005\000\000\000\000\004\005\004\001\000\000\000\000\n\230\004\001\000\000\n\206\004\001\n\222\004\001\000\000\000\000\000\000\000\000\004\005\004\001\004\001\004\001\004\005\004\001\004\001\004\001\004\005\004\005\000\000\000\000\000\000\000\000\n\238\004\005\000\000\000\000\004\005\004\005\000\000\004\005\004\005\000\000\000\000\004\005\000\000\004\005\004\005\000\000\000\000\004\005\000\000\000\000\004\005\000\000\004\005\004\005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\246\000\000\000\000\000\000\000\000\000\000\000\000\n\214\004\005\000\000\004\005\000\181\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\169\004\005\000\000\000\000\000\000\000\000\004\005\000\000\000\000\000\000\n\190\000\000\000\000\000\000\000\000\011\022\n\254\000\000\000\000\000\000\000\000\000\000\004\005\004\005\004\005\n\198\004\005\004q\004\005\000\000\004\005\000\181\000\181\000\000\000\000\000\000\000\000\000\000\004\005\000\000\000\000\n\230\004\005\000\000\n\206\004\005\n\222\004\005\000\000\000\000\000\000\000\000\000\000\004\005\004\005\004\005\000\000\004\005\004\005\004\005\001=\001=\001=\001=\000\000\001=\n\238\001=\001=\000\000\001=\000\000\001=\000\000\001=\000\000\001=\001=\001=\000\000\000\000\000\000\000\000\016\254\000\000\000\000\000\000\000\000\000\000\000\000\001=\001=\001=\000\000\000\000\000\000\000\000\001=\000\000\000\000\n\246\000\000\001=\000\000\000\000\000\000\001=\n\214\000\000\000\000\001=\000\000\000\000\017\002\000\000\000\000\001=\000\000\011\193\000\181\000\000\011\193\000\000\001=\000\000\000\000\000\000\000\000\001=\000\000\000\000\000\000\000\000\000\000\000\181\n\254\011\193\001=\000\000\000\000\011\193\000\000\000\000\000\000\006\230\011\193\000\000\000\000\000\000\000\000\000\000\011\193\000\000\000\000\011\193\011\193\001=\011\193\011\193\001=\000\000\006\238\000\000\011\193\006\250\000\000\000\000\011\193\000\000\000\000\011\193\000\000\011\193\011\193\001=\000\000\001=\000\000\001=\000\000\001=\000\000\000\000\000\000\000\000\001=\000\000\000\000\001=\000\000\000\000\000\000\011\193\000\000\011\193\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001=\011\193\000\000\001=\001=\000\000\007\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\017\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\193\011\193\011\193\000\000\011\193\000\000\007\n\000\000\011\193\000\000\000\000\000\000\001\137\000\000\000\000\001\137\007\018\000\000\000\000\000\000\000\000\000\000\000\000\011\193\000\000\011\193\000\000\000\000\000\000\000\000\001\137\011\193\011\193\011\193\001\137\011\193\011\193\011\193\000\000\001\137\000\000\000\000\000\000\000\000\000\000\001\137\000\000\000\000\001\137\001\137\000\000\001\137\001\137\000\000\000\000\000\000\000\000\001\137\000\000\000\000\000\000\001\137\000\000\000\000\001\137\000\000\001\137\001\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\137\000\000\001\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\137\004%\000\000\002\130\004%\002\134\004%\002\138\004%\000\000\004%\000\000\000\000\002\142\004%\004%\000\000\000\000\000\000\000\000\000\000\001\137\001\137\001\158\000\000\001\137\001\137\004%\000\000\001\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\004%\000\000\000\000\001\137\000\000\004%\001\137\001\137\001\137\001\137\000\000\000\000\000\000\000\000\002J\001\137\001\137\000\000\001\137\001\137\001\137\004%\000\000\000\000\004%\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\004%\004%\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\004%\004%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\000\000\004%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\004%\004%\000\000\000\000\004%\000\000\000\000\000\000\000\000\004%\004%\000\000\000\000\000\000\004%\t\189\t\189\t\189\t\189\000\000\t\189\000\000\t\189\t\189\000\000\t\189\000\000\t\189\000\000\t\189\000\000\t\189\t\189\t\189\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\189\t\189\t\189\001\190\000\000\000\000\002\018\t\189\000\000\000\000\000\000\000\157\t\189\000\000\000\000\000\000\017\022\000\000\000\000\000\000\017\030\001\202\000\000\000\000\000\000\002\001\t\189\000\000\000\000\000\157\002\001\000\000\000\000\t\189\000\000\000\000\001\210\000\000\t\189\002\001\002\001\000\000\0022\002:\n\198\000\000\000\000\t\189\002\001\000\000\000\157\000\157\001\242\000\000\000\000\001\218\000\000\001\234\002\001\000\000\000\157\000\000\000\000\n\206\000\000\n\222\t\189\000\000\000\000\t\189\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\250\000\000\002\001\000\000\000\000\000\000\000\000\t\189\000\157\t\189\000\000\t\189\002\001\t\189\000\000\000\000\000\000\000\000\t\189\000\000\000\000\t\189\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\001\002\002\000\000\t\189\002\001\002\001\017\146\t\189\001\226\000\157\000\000\000\000\000}\000\000\000\000\000}\n\214\000\000\000\000\000\000\002\001\000\000\000\000\002\001\002\001\002\001\002\001\000\000\000\157\000\000\001\202\000\000\002\001\002\001\000}\002B\002\n\002\001\000\000\000}\000\000\000\000\000\000\000\157\000\157\001\210\000\000\000\000\000}\000}\000\000\000}\000}\000\000\000\000\000\000\000\000\000}\000\000\000\000\000e\001\242\000\000\000e\001\218\000\000\001\234\000}\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000e\000\000\000\000\000\000\000e\000\000\000\000\000\000\001\250\000e\000}\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000e\000e\000}\000e\000e\000\000\000\000\000\000\000\000\000e\000\000\000\000\000\000\000e\000\000\000\000\001\218\000\000\001\234\000e\000\000\000\000\000\000\000}\002\002\000\000\000\000\000}\000}\000\000\000\000\001\226\000\000\000\000\000\000\000\000\000\000\000\000\000e\000\000\000e\000\000\000\000\000}\000\000\000\000\000}\000}\000}\000}\000e\000\000\000\000\000\000\000\000\000}\000}\000\000\000}\002\n\000}\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000e\000e\000\000\000\000\000e\000e\000\000\000\000\001\226\000\000\000\000\000\000\000]\000\000\000\000\000]\000\000\000\000\000\000\000\000\000e\000\000\000\000\000e\000e\000e\000e\000\000\000\000\000\000\000]\000\000\000e\000e\000]\000e\000e\000e\000\000\000]\000\000\000\000\000\000\000\000\000\000\000]\000\000\000\000\000]\000]\000\000\000]\000]\000\000\000\000\000\000\000\000\000]\000\000\000\000\000a\000]\000\000\000a\001\218\000\000\000]\000]\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000a\000\000\000\000\000\000\000a\000\000\000\000\000\000\000]\000a\000]\000\000\000\000\000\000\000\000\000a\000\000\000\000\000a\000a\000]\000a\000a\000\000\000\000\000\000\000\000\000a\000\000\000\000\000\000\000a\000\000\000\000\001\218\000\000\000a\000a\000\000\000\000\000\000\000]\000]\000\000\000\000\000]\000]\000\000\000\000\001\226\000\000\000\000\000\000\000\000\000\000\000\000\000a\000\000\000a\000\000\000\000\000]\000\000\000\000\000]\000]\000]\000]\000a\000\000\000\000\000\000\000\000\000]\000]\000\000\000]\000]\000]\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000a\000a\000\000\000\000\000a\000a\000\000\000\000\001\226\000\000\000\000\000\000\000q\000\000\000\000\000q\000\000\000\000\000\000\000\000\000a\000\000\000\000\000a\000a\000a\000a\000\000\000\000\000\000\001\202\000\000\000a\000a\000q\000a\000a\000a\000\000\000q\000\000\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000q\000q\000\000\000q\000q\000\000\000\000\000\000\000\000\000q\000\000\000\000\000i\000q\000\000\000i\001\218\000\000\001\234\000q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\202\000\000\000\000\000\000\000i\000\000\000\000\000\000\001\250\000i\000q\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000i\000i\000q\000i\000i\000\000\000\000\000\000\000\000\000i\000\000\000\000\000\000\000i\000\000\000\000\001\218\000\000\001\234\000i\000\000\000\000\000\000\000q\000q\000\000\000\000\000q\000q\000\000\000\000\001\226\000\000\000\000\000\000\000\000\000\000\000\000\000i\000\000\000i\000\000\000\000\000q\000\000\000\000\000q\000q\000q\000q\000i\000\000\000\000\000\000\000\000\000q\000q\000\000\000q\000q\000q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000i\000i\000\000\000\000\000i\000i\000\000\000\000\001\226\000\000\000\000\000\000\000m\000\000\000\000\000m\000\000\000\000\000\000\000\000\000i\000\000\000\000\000i\000i\000i\000i\000\000\000\000\000\000\001\202\000\000\000i\000i\000m\000i\000i\000i\000\000\000m\000\000\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000m\000m\000\000\000m\000m\000\000\000\000\000\000\000\000\000m\000\000\000\000\000u\000m\000\000\000u\001\218\000\000\001\234\000m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\202\000\000\000\000\000\000\000u\000\000\000\000\000\000\001\250\000u\000m\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000u\000u\000m\000u\000u\000\000\000\000\000\000\000\000\000u\000\000\000\000\000\000\001\242\000\000\000\000\001\218\000\000\001\234\000u\000\000\000\000\000\000\000m\000m\000\000\000\000\000m\000m\000\000\000\000\001\226\000\000\000\000\000\000\000\000\000\000\000\000\001\250\000\000\000u\000\000\000\000\000m\000\000\000\000\000m\000m\000m\000m\000u\000\000\000\000\000\000\000\000\000m\000m\000\000\000m\000m\000m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000u\002\002\000\000\000\000\000u\000u\000\000\000\000\001\226\000\000\000\000\000\000\001\190\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000u\000\000\000\000\000u\000u\000u\000u\000\000\000\000\000\000\001\202\000\000\000u\000u\000\133\000u\000u\000u\000\000\000\133\000\000\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000\133\000\133\000\000\000\133\002:\000\000\000\000\000\000\000\000\000\133\000\000\000\000\001\190\001\242\000\000\000y\001\218\000\000\001\234\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\202\000\000\000\000\000\000\000y\000\000\000\000\000\000\001\250\000y\000\133\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000y\000y\000\133\000y\000y\000\000\000\000\000\000\000\000\000y\000\000\000\000\000\000\001\242\000\000\000\000\001\218\000\000\001\234\000y\000\000\000\000\000\000\000\133\002\002\000\000\000\000\000\133\000\133\000\000\000\000\001\226\000\000\000\000\000\000\000\000\000\000\000\000\001\250\000\000\000y\000\000\000\000\000\133\000\000\000\000\000\133\000\133\000\133\000\133\000y\000\000\000\000\000\000\000\000\000\133\000\133\000\000\002B\002\n\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000y\002\002\000\000\000\000\000y\000y\000\000\000\000\001\226\000\000\000\000\000\000\001\190\000\000\000\000\000\129\000\000\000\000\000\000\000\000\000y\000\000\000\000\000y\000y\000y\000y\000\000\000\000\000\000\001\202\000\000\000y\000y\000\129\000y\002\n\000y\000\000\000\129\000\000\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000\129\000\129\000\000\000\129\002:\000\000\000\000\000\000\000\000\000\129\000\000\000\000\000\000\001\242\000\000\000\000\001\218\000\000\001\234\000\129\000\000\000\000\000\000\000\000\000\000\t\173\t\173\t\173\t\173\000\000\t\173\000\000\t\173\t\173\000\000\t\173\000\000\t\173\001\250\t\173\000\129\t\173\t\173\t\173\000\000\000\000\000\000\000\000\000\000\000\000\000\129\000\000\000\000\000\000\000\000\t\173\t\173\t\173\000\000\000\000\000\000\000\000\t\173\000\000\000\000\000\000\000\000\t\173\000\000\000\000\000\000\000\129\002\002\000\000\000\000\000\129\000\129\000\000\000\000\001\226\000\149\t\173\000\000\000\000\000\000\000\000\000\000\000\000\t\173\000\000\000\000\000\129\000\000\t\173\000\129\000\129\000\129\000\129\000\149\000\000\000\000\000\000\t\173\000\129\000\129\000\000\000\129\002\n\000\129\000\000\000\000\000\000\000\000\000\149\000\000\000\000\000\000\000\000\000\000\000\149\000\149\t\173\000\000\000\000\t\173\000\000\000\000\000\000\000\000\000\149\000\000\000\000\n\206\000\000\000\149\000\000\000\000\000\000\000\000\t\173\000\000\t\173\000\000\t\173\000\000\t\173\000\000\000\000\000\000\000\000\t\173\000\000\000\000\t\173\000\149\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\173\000\000\000\000\017\026\t\173\t\177\t\177\t\177\t\177\000\000\t\177\000\000\t\177\t\177\000\000\t\177\000\000\t\177\000\000\t\177\000\149\t\177\t\177\t\177\000\000\000\000\000\000\n\214\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\177\t\177\t\177\000\000\000\149\000\000\000\000\t\177\000\000\000\000\000\000\000\000\t\177\000\000\000\000\000\000\017\150\000\000\000\000\000\149\000\149\000\000\000\000\000\000\000\000\000\000\t\177\000\000\000\000\000\000\000\000\000\000\000\000\t\177\000\000\000\000\000\000\000\000\t\177\000\000\000\000\004i\000\000\000\000\004i\000\000\004i\t\177\004i\000\000\004i\000\000\000\000\000\000\004i\004i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\177\004i\000\000\t\177\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004i\004i\000\000\000\000\000\000\000\000\004i\t\177\000\000\t\177\000\000\t\177\000\000\t\177\000\000\000\000\000\000\000\000\t\177\000\000\000\000\t\177\004i\000\000\000\000\004i\000\138\000\000\000\000\000\000\000\000\004i\000\000\000\000\004i\004i\t\177\000\000\000\000\000\000\t\177\000\000\004i\000\000\000\000\004i\004i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004Q\004i\000\000\004Q\000\000\004Q\000\000\004Q\000\000\004Q\000\000\004i\000\000\004Q\004Q\000\000\000\000\000\000\000\000\004i\000\000\000\000\000\000\004i\000\000\000\000\004Q\000\000\000\000\000\000\000\000\000\000\004i\000\000\000\000\000\000\004Q\004Q\000\000\000\000\000\000\000\000\004Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004i\000\000\000\000\004i\004i\000\000\004Q\004i\000\000\004Q\005\210\000\000\004i\004i\000\000\004Q\000\000\004i\004Q\004Q\000\000\000\000\000\000\000\000\000\000\000\000\004Q\000\000\000\000\004Q\004Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\153\000\000\004Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004Q\000\000\000\000\000\000\004Q\000\000\000\000\000\000\000\153\000\000\000\000\000\000\000\000\004Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\153\000\000\000\000\000\000\000\000\000\000\000\153\000\153\000\000\000\000\004Q\000\000\000\000\004Q\004Q\000\000\000\153\004Q\000\000\n\206\000\000\000\153\004Q\004Q\000\000\000\000\000\000\004Q\0002\0006\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\000\000\000^\000\153\000b\000\000\000f\000j\000n\000\000\0055\000\000\000\000\0055\000\000\000\000\000\000\0055\000\000\0055\017\158\000r\017\186\0055\0055\000\000\000\000\017\198\000\000\000\000\000\000\000\000\000v\000\000\000\000\000\000\000\000\000\153\000\000\000\000\000\000\000\000\000\000\000\000\n\214\000\000\017\222\000\000\000\000\000\000\000\000\000\000\0055\000\130\000\000\000\000\000\153\000\000\018\n\000\000\000\000\0055\000\000\000\000\0055\000\000\0055\000\134\0055\000\000\0055\000\153\000\153\000\000\0055\0055\000\000\002b\000\000\000\000\0055\000\000\000\000\000\000\000\000\000\000\018*\0055\0055\018z\000\000\0055\0055\000\000\000\000\000\000\000\000\0055\0055\000\000\000\000\0055\000\000\0055\018\146\000\000\007\213\000\000\018\158\000\000\018\170\000\000\000\000\000\000\000\000\018\186\000\000\000\000\019j\0055\000\000\000\000\0055\0055\000\000\000\000\000\000\000\000\002b\000\000\000\000\0055\0055\019v\000\000\000\000\000\000\019\142\000\000\0055\000\000\000\000\0055\0055\000\000\001\161\000\000\000\000\001\161\000\000\000\000\000\000\0055\000\000\000\000\0055\0055\000\000\000\000\000\000\000\000\000\000\0055\001\161\0055\0055\000\000\001\161\000\000\0055\0055\000\000\001\161\000\000\0055\000\000\000\000\000\000\001\161\000\000\000\000\001\161\001\161\0055\001\161\001\161\000\000\000\000\000\000\000\000\001\161\000\000\000\000\000\000\001\161\000\000\000\000\001\161\000\000\001\161\001\161\000\000\000\000\0055\000\000\000\000\0055\0055\000\000\000\000\0055\000\000\000\000\000\000\000\000\0055\0055\000\000\000\000\001\161\0055\001\161\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\161\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\161\001\161\0076\000\000\001\161\000\000\000\000\000\000\001\161\000\000\000\000\000\000\n~\000\000\000\000\000\000\000\000\003I\000\000\003I\000\000\000\000\003I\001\161\000\000\001\161\000\000\000\000\000\000\000\000\000\000\007>\001\161\001\161\000\000\001\161\001\161\001\161\003I\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003I\003I\000\000\000\000\003I\003I\000\000\000\000\000\000\000\000\003I\000\000\003I\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003I\003I\000\000\003I\003I\003I\000\000\003I\003I\000\000\003I\000\000\000\000\011\165\000\000\000\000\011\165\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003I\003I\000\000\000\000\003I\000\000\011\165\003I\000\000\000\000\011\165\000\000\000\000\000\000\003Z\003I\000\000\000\000\000\000\000\000\000\000\011\165\000\000\000\000\003I\011\165\003I\011\165\011\165\000\000\000\000\003b\000\000\000\000\003n\000\000\003I\011\165\000\000\000\000\011\165\003I\011\165\000\000\000\000\000\000\000\000\003I\000\000\000\000\003I\000\000\000\000\000\169\000\000\000\000\003I\000\000\000\000\000\000\000\000\000\000\011\165\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\190\000\000\000\000\011\165\000\000\000\000\000\000\000\000\003z\000\000\000\000\000\000\000\226\000\000\t\154\n\198\000\000\t\158\000\000\000\000\000\000\000\169\000\169\000\000\000\000\011\165\011\165\000\000\011\165\000\000\003~\000\169\011\165\000\238\n\206\000\000\n\222\000\000\000\000\000\000\003\134\000\000\t\162\nJ\011\165\000\000\n^\nv\000\000\011\165\011\165\000\000\001\"\000\000\001&\011\165\n\238\000\000\000\000\011\165\011\165\011\165\t\194\001.\000\000\t\198\008^\001:\000\000\t\202\t\206\000\000\t\210\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\182\t\214\000\000\000\169\t\218\000\000\000\000\000\162\000\000\000\226\n\214\t\154\000\000\000\000\t\158\t\226\000\000\000\000\000\000\000\000\000\000\000\000\000\169\000\000\nz\000\000\n\146\000\000\000\000\000\000\000\238\000\000\000\000\000\000\000\000\000\000\t\230\000\169\000\169\t\162\nJ\t\234\000\000\n^\nv\000\000\000\000\011r\000\000\001\"\t\238\001&\000\000\000\000\000\000\000\000\001j\000\000\000\000\t\194\001.\000\000\t\198\008^\001:\000\000\t\202\t\206\000\000\t\210\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\182\t\214\000\000\000\000\t\218\000\000\000\000\000\162\000\000\000\226\000\000\t\154\000\000\000\000\t\158\t\226\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\nz\000\000\n\146\000\000\000\000\000\000\000\238\000\000\000\000\000\000\000\000\000\000\t\230\000\000\000\000\t\162\nJ\t\234\000\000\n^\nv\000\000\000\000\011\030\000\000\001\"\t\238\001&\000\000\000\000\000\000\000\000\001j\000\000\000\000\t\194\001.\000\000\t\198\008^\001:\000\000\t\202\t\206\000\000\t\210\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\182\t\214\000\000\000\000\t\218\000\000\000\000\000\162\000\000\000\226\000\000\t\154\000\000\000\000\t\158\t\226\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\nz\000\000\n\146\000\000\000\000\000\000\000\238\000\000\000\000\000\000\000\000\000\000\t\230\000\000\000\000\t\162\nJ\t\234\000\000\n^\nv\000\000\000\000\004\201\000\000\001\"\t\238\001&\000\000\000\000\000\000\000\000\001j\000\000\000\000\t\194\001.\000\000\t\198\008^\001:\000\000\t\202\t\206\000\000\t\210\000\000\000\000\000\000\000\000\001\137\000\000\000\000\001\137\000\000\000\000\000\000\000\000\000\000\000\000\006\182\t\214\000\000\000\000\t\218\000\000\000\000\000\162\001\137\000\000\000\000\000\000\000\000\000\000\000\000\t\226\000\000\001\137\000\000\000\000\000\000\000\000\000\000\001\137\nz\000\000\n\146\000\000\000\000\001\137\001\137\000\000\000\000\000\000\000\000\000\000\t\230\000\000\000\000\001\137\007j\t\234\001\137\007\186\001\137\001\137\000\000\001\189\000\000\000\000\t\238\000\000\000\000\000\000\000\000\000\000\001j\000\000\007r\000\000\000\000\000\000\002\017\000\000\001\137\000\000\001\137\002\017\000\000\000\000\000\000\000\000\000\000\007z\000\000\000\000\002\017\002\017\000\000\007\202\007\210\000\000\000\000\000\000\000\000\002\017\000\000\000\000\000\000\007\154\000\000\000\000\007\130\000\000\007\146\002\017\000\000\001\137\001\137\001\150\000\000\001\137\001\137\000\000\000\000\001\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\162\000\000\002\017\001\137\000\000\000\000\001\137\001\137\000\000\001\137\000\000\000\000\002\017\000\000\002V\001\137\001\137\000\000\001\137\001\137\001\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\017\007\170\000\000\000\000\002\017\000\000\000\000\000\000\007\138\000\000\000\000\000\000\001%\000\000\000\000\001%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\017\000\000\002\017\000\000\000\000\000\000\000\000\007r\000\000\002\017\002\017\001%\007\218\007\178\002\017\001\013\001%\000\000\001\013\000\000\000\000\000\000\007z\000\000\000\000\001%\001%\000\000\001%\001%\000\000\000\000\000\000\001\013\001%\000\000\000\000\001\013\007\154\000\000\000\000\007\130\001\013\007\146\001%\000\000\000\000\000\000\007z\000\000\000\000\001\013\001\013\000\000\001\013\001\013\000\000\000\000\000\000\000\000\001\013\000\000\000\000\007\162\001\013\001%\000\000\007\130\000\000\007\146\001\013\000\000\000\000\000\000\000\000\001%\0002\0006\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\017*\000^\001\013\000b\001\013\000f\000j\000n\000\000\001%\007\170\000\000\000\000\001%\001\013\000\000\000\000\007\138\000\000\000\000\000r\017.\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\019\146\001%\000\000\001%\001\013\001\013\000\000\000\000\001\013\000\000\001%\001%\007\138\001%\007\178\001%\001\005\000\000\000\000\001\005\000\000\000\130\000\000\000\000\000\000\000\000\018\n\001\013\000\000\001\013\000\000\000:\000\000\000\000\001\005\000\134\001\013\001\013\001\005\001\013\001\013\001\013\001\t\001\005\000\000\001\t\000\000\000\000\000\000\001\005\000\000\000\000\001\005\001\005\000\000\001\005\001\005\000\000\000\000\000\000\001\t\001\005\000\000\000\000\001\t\001\005\000\000\000\000\007\130\001\t\001\005\001\005\000\000\000\162\000\000\001\t\000\000\000\000\001\t\001\t\000\000\001\t\001\t\000\000\000\000\000\000\017>\001\t\000\000\000\000\001\005\001\t\001\005\000\000\007\130\000\000\001\t\001\t\000\000\000\000\000\000\000\000\001\005\0002\tn\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\000\000\000^\001\t\000b\001\t\000f\000j\000n\000\000\001\005\001\005\000\000\000\000\001\005\001\t\000\000\000\000\007\138\000\000\000\000\000r\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000v\001\005\000\000\001\005\001\t\001\t\000\000\000\000\001\t\000\000\001\005\001\005\007\138\001\005\001\005\001\005\001\025\000\000\000\000\001\025\000\000\000\130\000\000\000\000\000\000\000\000\000\000\001\t\000\000\001\t\000\000\000\000\000\000\000\000\007r\000\134\001\t\001\t\001\025\001\t\001\t\001\t\001\017\001\025\000\000\001\017\000\000\000\000\000\000\007z\000\000\000\000\001\025\001\025\000\000\001\025\001\025\000\000\000\000\000\000\007r\001\025\000\000\000\000\001\017\001\025\000\000\000\000\007\130\001\017\007\146\001\025\000\000\000\162\000\000\007z\000\000\000\000\001\017\001\017\000\000\001\017\001\017\000\000\000\000\000\000\000\000\001\017\000\000\000\000\007\162\001\017\001\025\000\000\007\130\000\000\007\146\001\017\000\000\000\000\000\000\000\000\001\025\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\017\000\000\001\017\000\000\000\000\000\000\000\000\001\025\001\025\000\000\000\000\001\025\001\017\000\000\000\000\007\138\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\025\000\000\001\025\001\017\001\017\000\000\000\000\001\017\000\000\001\025\001\025\007\138\001\025\001\025\001\025\001\021\000\000\000\000\001\021\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\017\000\000\001\017\000\000\000\000\000\000\000\000\007r\000\000\001\017\001\017\001\021\001\017\001\017\001\017\001\029\001\021\000\000\001\029\000\000\000\000\000\000\007z\000\000\000\000\001\021\001\021\000\000\001\021\001\021\000\000\000\000\000\000\007r\001\021\000\000\000\000\001\029\001\021\000\000\000\000\007\130\001\029\007\146\001\021\000\000\000\000\000\000\007z\000\000\000\000\001\029\001\029\000\000\001\029\001\029\000\000\000\000\000\000\000\000\001\029\000\000\000\000\007\162\007\154\001\021\000\000\007\130\000\000\007\146\001\029\000\000\000\000\000\000\000\000\001\021\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\162\000\000\001\029\000\000\000\000\000\000\000\000\001\021\001\021\000\000\000\000\001\021\001\029\000\000\000\000\007\138\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\021\000\000\001\021\001\029\007\170\000\000\000\000\001\029\000\000\001\021\001\021\007\138\001\021\001\021\001\021\007j\000\000\000\000\001-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\029\000\000\001\029\000\000\000\000\000\000\000\000\007r\000\000\001\029\001\029\001-\001\029\001\029\001\029\007j\001-\000\000\001!\000\000\000\000\000\000\007z\000\000\000\000\001-\001-\000\000\001-\007\210\000\000\000\000\000\000\007r\001-\000\000\000\000\001!\007\154\000\000\000\000\007\130\001!\007\146\001-\000\000\000\000\000\000\007z\000\000\000\000\001!\001!\000\000\001!\001!\000\000\000\000\000\000\000\000\001!\000\000\000\000\007\162\007\154\001-\000\000\007\130\000\000\007\146\001!\000\000\000\000\000\000\000\000\001-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\162\000\000\001!\000\000\000\000\000\000\000\000\001-\007\170\000\000\000\000\001-\001!\000\000\000\000\007\138\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001-\000\000\001-\001!\007\170\000\000\000\000\001!\000\000\001-\001-\007\138\007\218\007\178\001-\007j\000\000\000\000\001)\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001!\000\000\001!\000\000\000\000\000\000\000\000\007r\000\000\001!\001!\001)\001!\007\178\001!\000\000\001)\000\000\000\000\000\226\000\000\t\154\007z\000\000\t\158\001)\001)\000\000\001)\007\210\000\000\000\000\000\000\000\000\001)\000\000\000\000\000\000\007\154\000\000\000\238\007\130\000\000\007\146\001)\000\000\000\000\000\000\000\000\t\162\nJ\000\000\000\000\n^\nv\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\000\007\162\000\000\001)\000\000\000\000\000\000\t\194\001.\000\000\t\198\008^\001:\001)\t\202\t\206\000\000\t\210\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\182\t\214\001)\007\170\t\218\000\000\001)\000\162\000\000\000\000\007\138\000\000\000\000\000\000\000\000\t\226\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001)\n\146\001)\000\226\000\000\000\230\000\000\000\000\000\234\001)\001)\t\230\001)\007\178\001)\000\000\t\234\000\000\007\246\000\000\000\000\000\000\001\201\000\000\000\238\t\238\000\000\000\242\000\000\000\000\000\000\001j\000\000\000\254\001\002\000\000\001\n\000\000\t\150\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001*\001.\000\000\0012\0016\001:\000\000\001>\001B\000\000\001F\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001J\000\000\000\000\001N\000\000\000\000\000\162\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001V\000\000\000\000\000\226\000\000\000\230\000\000\000\000\000\234\001Z\007\229\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\229\000\000\000\000\001^\000\000\000\000\000\238\000\000\001b\000\242\000\000\007\229\000\000\007\229\000\000\000\254\001\002\001f\001\n\000\000\000\000\000\000\000\000\001j\000\000\001\"\000\000\001&\000\000\000\000\000\000\000\000\000\226\000\000\000\230\001*\001.\000\234\0012\0016\001:\000\000\001>\001B\000\000\001F\000\000\014r\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\242\000\000\000\000\000\000\000\000\001J\000\254\001\002\001N\001\n\000\000\000\162\000\000\000\000\000\000\000\000\001\"\000\000\001&\001V\000\000\000\000\000\000\000\000\000\000\000\000\001*\001.\001Z\0012\0016\001:\000\000\001>\001B\000\000\001F\000\000\000\000\000\000\001^\000\000\000\000\000\000\000\000\001b\000\000\000\000\000\000\000\000\000\000\000\000\001J\000\000\001f\001N\000\000\000\000\000\162\000\000\001j\000\000\000\000\000\000\000\000\000\000\001V\000\000\000\000\000\226\000\000\000\230\000\000\000\000\000\234\001Z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001^\000\000\000\000\000\238\000\000\001b\000\242\000\000\000\000\000\000\000\000\000\000\000\254\004\210\001f\001\n\000\000\000\000\000\000\000\000\001j\000\000\001\"\000\000\001&\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001*\001.\000\000\0012\0016\001:\000\000\001>\001B\000\246\001F\000\000\000\000\000\000\007\237\000\000\007\237\000\000\000\000\007\237\000\000\000\000\000\000\000\000\000\000\000\000\001J\000\000\000\000\001N\000\000\000\000\000\162\000\000\000\000\007\237\000\000\000\000\007\237\000\000\001V\000\000\000\000\000\000\007\237\007\237\000\000\007\237\000\000\001Z\000\000\000\000\000\000\000\000\007\237\000\000\007\237\000\000\000\226\000\000\000\230\001^\000\000\000\234\007\237\007\237\001b\007\237\007\237\007\237\000\000\007\237\007\237\000\000\007\237\001f\000\000\000\000\000\000\000\238\000\000\001j\000\242\000\000\000\000\000\000\000\000\000\000\000\254\001R\007\237\001\n\000\000\007\237\000\000\000\000\007\237\000\000\001\"\000\000\001&\000\000\000\000\000\000\007\237\000\000\000\000\000\000\001*\001.\000\000\0012\0016\001:\000\000\001>\001B\003\222\001F\000\000\000\000\000\000\003A\000\000\003A\007\237\000\000\003A\000\000\000\000\007\237\000\000\000\000\000\000\001J\000\000\000\000\001N\000\000\007\237\000\162\000\000\000\000\003A\000\000\007\237\003A\000\000\001V\000\000\000\000\000\000\003A\003A\000\000\003A\000\000\001Z\000\000\000\000\000\000\000\000\003A\000\000\003A\000\000\000\226\000\000\001\022\001^\000\000\001\026\003A\003A\001b\003A\003A\003A\000\000\003A\003A\000\000\003A\001f\000\000\000\000\000\000\000\238\000\000\001j\000\242\000\000\000\000\000\000\000\000\000\000\001\030\003\162\003A\001\n\000\000\003A\000\000\000\000\003A\000\000\001\"\000\000\001&\000\000\000\000\000\000\003A\000\000\000\000\000\000\003\026\001.\000\000\003\030\0016\001:\000\000\003\"\003&\000\000\003*\000\000\000\000\000\000\000\226\000\000\001\022\003A\000\000\001\026\000\000\000\000\003A\000\000\000\000\000\000\003.\000\000\000\000\0032\000\000\003A\000\162\000\000\000\000\000\238\000\000\003A\000\242\000\000\003:\000\000\000\000\000\000\001\030\003\006\000\000\001\n\000\000\000\000\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\226\000\000\001\022\003>\000\000\001\026\003\026\001.\003B\003\030\0016\001:\000\000\003\"\003&\000\000\003*\003F\000\000\000\000\000\000\000\238\000\000\001j\000\242\000\000\000\000\000\000\000\000\000\000\001\030\0036\003.\001\n\000\000\0032\000\000\000\000\000\162\000\000\001\"\000\000\001&\000\000\000\000\000\000\003:\000\000\000\000\000\000\003\026\001.\000\000\003\030\0016\001:\000\000\003\"\003&\000\000\003*\000\000\000\000\000\000\000\226\000\000\006\130\003>\000\000\006\134\000\000\000\000\003B\000\000\000\000\000\000\003.\000\000\000\000\0032\000\000\003F\000\162\000\000\000\000\000\238\000\000\001j\000\000\000\000\003:\000\000\000\000\000\000\006\138\007\226\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\000\000\000\000\000\003>\000\000\000\000\006\162\001.\003B\006\166\0016\001:\000\000\006\170\006\174\000\000\006\178\003F\000\000\000\000\000\226\000\000\006\130\001j\000\000\006\134\000\000\000\000\000\000\000\000\000\000\006\182\006\186\000\000\000\000\006\190\000\000\000\000\000\162\000\000\000\000\000\238\000\000\000\000\000\000\000\000\006\198\000\000\000\000\000\000\006\138\006\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\000\000\000\000\000\006\202\000\000\000\000\006\162\001.\006\206\006\166\0016\001:\000\000\006\170\006\174\000\000\006\178\006\210\000\000\000\000\000\226\000\000\006\130\001j\000\000\006\134\000\000\000\000\000\000\000\000\000\000\006\182\006\186\000\000\000\000\006\190\000\000\000\000\000\162\000\000\000\000\000\238\000\000\000\000\000\000\000\000\006\198\000\000\000\000\000\000\006\138\006\194\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\000\000\000\000\000\006\202\000\000\000\000\006\162\001.\006\206\006\166\0016\001:\000\000\006\170\006\174\000\000\006\178\006\210\000\000\000\000\000\226\000\000\t\154\001j\000\000\t\158\000\000\000\000\000\000\000\000\000\000\006\182\006\186\000\000\000\000\006\190\000\000\000\000\000\162\000\000\000\000\000\238\000\000\000\000\000\000\000\000\006\198\000\000\000\000\000\000\t\162\t\174\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\000\000\000\000\000\006\202\000\000\000\000\t\194\001.\006\206\t\198\0016\001:\000\000\t\202\t\206\000\000\t\210\006\210\000\000\000\000\000\226\000\000\t\154\001j\000\000\t\158\000\000\000\000\000\000\000\000\000\000\006\182\t\214\000\000\000\000\t\218\000\000\000\000\000\162\000\000\000\000\000\238\000\000\000\000\000\000\000\000\t\226\000\000\000\000\000\000\t\162\t\222\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\000\000\000\000\000\t\230\000\000\000\000\t\194\001.\t\234\t\198\0016\001:\000\000\t\202\t\206\000\000\t\210\t\238\000\000\000\000\000\226\000\000\t\154\001j\000\000\t\158\000\000\000\000\000\000\000\000\000\000\006\182\t\214\000\000\000\000\t\218\000\000\000\000\000\162\000\000\000\000\000\238\000\000\000\000\000\000\000\000\t\226\000\000\000\000\000\000\t\162\nJ\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\000\000\000\000\000\t\230\000\000\000\000\t\194\001.\t\234\t\198\0016\001:\000\000\t\202\t\206\000\000\t\210\t\238\000\000\000\000\000\000\000\000\000\000\001j\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\182\t\214\000\000\000\000\t\218\000\000\000\000\000\162\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\226\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\000\000\000^\000\000\000b\006N\000f\000j\000n\006R\t\230\000\000\000\000\000\000\000\000\t\234\000\000\000\000\000\000\000\000\000\000\000r\000\000\000\000\t\238\000\000\000\000\000\000\000\000\000\000\001j\000\000\000v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\130\000\000\000\000\0002\tn\000F\000J\000\000\000N\006F\000R\000V\006J\000Z\000\134\000^\020\146\000b\006N\000f\000j\000n\006R\020\154\001\153\000\000\000\000\001\153\000\000\008b\000\000\000\000\000\000\000\000\000r\000\000\000\000\000\000\007Q\000\000\000\000\000\000\001\153\000\000\000\000\000v\001\153\000\000\000\000\000\000\000\000\000\000\000\162\000\000\000\000\000\000\000\000\001\153\000\000\007Q\000\000\001\153\000\000\001\153\001\153\000\000\000\130\000\000\000\000\007Q\007Q\000\000\000\000\001\153\000\000\007Q\001\153\000\000\001\153\t^\000\134\000\000\0055\000\000\000\000\0055\000\000\000\000\000\000\0055\000\000\0055\000\000\000\000\007Q\0055\0055\000\000\001\153\000\000\000:\000\000\000\000\007Q\007Q\000\000\000\000\000\000\000\000\000\000\001\153\007Q\000\000\000\000\007Q\007Q\000\000\000\000\000\162\000\000\000\000\000\000\003\161\000\000\007Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\153\003\186\007Q\001\153\000\000\000\000\000\000\001\153\0055\000\000\007Q\000\000\000\000\000\000\000\000\000\000\000\000\000\146\000\000\001\153\007Q\000\000\000\000\007Q\001\153\001\153\000\000\000\000\007Q\000\000\003\194\007Q\007Q\000\000\001\153\001\153\001\153\000\000\000\000\000\000\000\000\007Q\000\000\007Q\000\000\000\000\007Q\007Q\004\018\000\000\007Q\004b\000\000\000\000\000\000\007Q\007Q\000\000\000\000\007Q\007Q\000\000\000\000\0055\000\000\000\000\004\026\000\000\000\000\000\000\002\t\000\000\007Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\"\000\000\000\000\000\000\002\t\000\000\004r\004z\000\000\000\237\000\000\007Q\000\237\000\000\007Q\007Q\004B\000\213\000\000\004*\000\213\004:\000\000\007Q\007Q\000\000\000\000\004\026\007Q\000\000\000\000\000\237\000\000\000\000\000\000\000\213\000\000\000\000\000\000\000\213\000\000\004J\004\"\000\000\000\000\000\000\000\237\000\000\000\237\000\237\004\"\000\000\000\000\002\t\000\213\000\000\000\213\000\213\004B\000\000\000\000\004*\000\000\004:\000\000\000\000\000\213\000\000\000\000\004*\000\000\004:\000\000\000\000\000\000\004R\000\000\000\000\002\t\000\000\000\000\000\000\0042\004J\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\213\000\000\000\000\002\t\000\237\000\000\000\000\000\000\002\t\002\t\000\000\000\000\000\213\000\000\000\000\000\000\000\000\000\000\004\130\004Z\002\t\000\000\000\000\000\000\000\000\000\000\004R\000\000\000\000\000\237\000\000\000\000\000\000\0042\000\213\000\000\000\000\000\213\000\000\000\000\000\000\0042\000\000\000\000\000\000\000\237\000\000\000\000\000\000\000\205\000\237\000\237\000\205\000\213\000\000\000\000\000\000\000\000\000\213\000\213\000\237\004Z\000\237\000\000\000\000\000\000\000\000\000\205\000\213\000\213\000\213\000\205\000\209\000\000\000\000\000\209\000\000\000\000\000\000\000\000\000\000\000\000\000\205\000\000\000\000\000\000\000\205\000\000\000\205\000\205\000\209\000\000\000\000\000\000\000\209\000\000\000\000\000\000\000\205\000\000\000\000\004*\000\000\000\205\000\000\000\209\000\000\000\000\000\000\000\209\000\000\000\209\000\209\000\000\000\225\000\000\000\000\000\225\000\000\000\000\000\000\000\209\000\000\000\205\004*\000\000\000\209\000\000\000\000\000\000\000\000\000\000\004\026\000\000\000\000\000\205\000\225\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\209\004\"\000\000\000\000\000\000\000\225\000\000\000\225\000\225\000\000\000\000\000\205\000\209\000\000\000\205\000\000\000\000\000\225\0042\000\000\004*\000\000\004:\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\205\000\000\000\000\000\000\000\209\000\205\000\205\000\209\000\000\000\000\000\000\0042\004J\000\000\000\000\000\205\000\205\000\205\000\000\000\000\000\000\000\000\000\000\000\209\000\225\000\000\000\000\000\000\000\209\000\209\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\209\000\209\000\209\000\000\000\000\000\000\000\000\000\000\000\225\000\000\000\000\000\225\000\000\000\217\000\000\0042\000\217\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\225\000\000\000\000\000\000\004\026\000\225\000\225\000\000\000\217\000\221\000\000\000\000\000\221\000\000\000\000\000\225\000\225\000\225\000\000\004\"\000\000\000\000\000\000\000\217\000\000\000\217\000\217\004\026\000\000\000\000\000\000\000\221\000\000\000\000\000\000\000\217\000\000\000\000\004*\000\000\004:\000\000\004\"\000\000\000\000\000\000\000\221\000\000\000\221\000\221\000\000\000\229\000\000\000\000\000\229\000\000\000\000\000\000\000\221\000\000\000\217\004*\000\000\004:\000\000\000\000\000\000\000\000\000\000\004\026\000\000\000\000\000\217\000\229\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004J\004\"\000\000\000\000\000\000\000\229\000\000\000\229\000\229\000\000\000\000\000\217\000\221\000\000\000\217\000\000\000\000\004B\0042\000\000\004*\000\000\004:\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\217\000\000\000\000\000\000\000\221\000\217\000\217\000\221\000\000\000\000\000\000\0042\004J\000\000\000\000\000\217\000\217\000\217\000\000\000\000\000\000\000\000\000\000\000\221\000\229\000\000\000\000\000\000\000\221\000\221\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\221\000\221\000\221\000\000\000\000\000\000\000\000\000\000\004R\000\000\000\000\000\229\000\000\004\018\000\000\0042\000\245\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\229\000\000\000\000\000\000\004\026\000\229\000\229\000\000\000\245\004\018\000\000\000\000\000\233\000\000\000\000\000\229\000\229\000\229\000\000\004\"\000\000\000\000\000\000\000\245\000\000\000\245\004z\004\026\000\000\000\000\000\000\000\233\000\000\000\000\000\000\004B\000\000\000\000\004*\000\000\004:\000\000\004\"\000\000\000\000\000\000\000\233\000\000\000\233\000\233\000\000\004\018\000\000\000\000\000\241\000\000\000\000\000\000\004B\000\000\004J\004*\000\000\004:\000\000\000\000\000\000\000\000\000\000\004\026\000\000\000\000\000\245\000\241\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004J\004\"\000\000\000\000\000\000\000\241\000\000\000\241\004z\000\000\000\000\004R\000\233\000\000\000\245\000\000\000\000\004B\0042\000\000\004*\000\000\004:\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\245\000\000\000\000\000\000\004R\000\245\000\245\000\233\000\000\000\000\000\000\0042\004J\000\000\000\000\004\130\004Z\000\245\003\153\000\000\000\000\003\153\000\000\000\233\000\241\003\153\000\000\003\153\000\233\000\233\000\000\003\153\003\153\000\000\000\000\000\000\000\000\000\000\000\233\004Z\000\233\000\000\000\000\000\000\000\000\000\000\004R\000\000\000\000\000\241\000\000\000\000\000\000\0042\000\000\000\000\000\000\000\000\000\000\000\000\002-\000\000\000\000\000\000\000\000\000\241\000\000\000\000\000\000\000\000\000\241\000\241\000\000\000\000\000\000\000\000\003\153\000\000\000\000\000\000\000\241\004Z\000\241\000\000\000\000\000\000\000\000\000\000\002-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002-\000\000\000\000\002-\002-\000\000\000\000\000\000\000\000\003Q\003Q\003Q\003Q\002-\003Q\000\000\003Q\003Q\000\000\003Q\000\000\003Q\000\000\003Q\000\000\003Q\003Q\003Q\000\000\000\000\000\000\002-\000\000\000\000\000\000\003\153\000\000\000\170\000\000\000\000\003Q\020\150\000F\000J\002-\000N\006F\000R\000V\006J\000Z\003Q\000^\020\146\000b\006N\000f\000\000\000n\006R\020\154\000\000\000\000\000\000\002-\000\000\000\000\002-\002-\000\000\000\000\000r\003Q\000\000\000\000\000\000\002-\002-\003Q\000\000\000\000\002-\000v\000\000\000\000\000\000\003Q\000\000\0002\000\142\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\000\000\000^\000\000\000b\000\000\000f\000j\000n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\134\000\000\000r\000\000\000\000\000\000\000\000\003Q\000\000\000\000\000\000\000\000\000\000\000v\0002\000\142\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\000\000\000^\000\000\000b\000\000\000f\000j\000n\000\000\000\130\000\000\000\000\000\000\000\000\000\000\000\158\000\000\003\161\000\000\000\000\000r\000\000\003Q\000\134\000\000\0002\005\030\000F\000J\000\000\000N\000v\000R\000V\000\000\000Z\000\000\000^\000\000\000b\000\000\000f\000j\000n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\130\000\000\000\000\000\000\000r\000\000\000\158\000\000\000\000\000\162\000\000\000\000\000\000\000\000\000\134\000v\000\000\0002\005\030\000F\000J\000\000\000N\000\000\000R\000V\000\166\000Z\000\000\000^\000\000\000b\000\000\000f\000j\000n\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000r\011\001\000\134\000\000\000\162\000\000\005\"\005&\000\000\011\137\000\000\000v\0002\000\142\000F\000J\000\000\000N\000\000\000R\000V\000\166\000Z\000\000\000^\000\000\000b\011\137\000f\000j\000n\000\000\000\130\000\000\000\000\n\002\000\000\000\000\000\000\000\000\000\000\000\000\011\137\000r\002)\000\000\000\134\000\000\011\137\011\137\005\"\005&\n\n\000\000\000v\n\022\000\000\005*\011\137\000\000\000\000\011\137\000\000\011\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\130\000\000\000\000\000\000\000\000\000\000\000\158\000\000\011\137\000\000\000\000\000\000\000\000\000\000\000\134\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\"\0052\0002\005\030\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\000\000\000^\000\000\000b\011\137\000f\000j\000n\000\000\n&\000\000\011\137\000\000\000\000\000\162\000\000\000\000\000\000\000\000\n.\000r\000\000\000\000\011\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000v\000\000\000\000\000\000\000\000\000\000\000\000\011\137\011\137\000\000\0002\005\030\000F\000J\000\161\000N\000\000\000R\000V\000\000\000Z\000\130\000^\002!\000b\000\165\000f\000j\000n\000\000\000\000\000\000\n\190\000\000\000\000\000\134\000\000\000\000\000\000\0212\005&\000r\000\000\n\190\000\000\000\000\000\000\n\198\000\000\000\000\000\000\000\000\000v\000\161\000\161\000\000\000\000\000\000\n\198\000\000\000\000\000\000\000\173\000\161\000\165\000\165\n\206\000\000\n\222\000\000\000\000\000\000\000\000\000\130\000\165\000\000\000\000\n\206\000\000\n\222\n\190\000\000\000\000\000\000\000\000\n\182\000\000\000\134\000\161\000\000\0216\0212\005&\000\000\000\000\n\198\000\000\000\000\000\000\n\238\000\000\000\173\000\173\n\190\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\230\000\000\000\000\n\206\000\000\n\222\000\000\n\198\000\000\000\000\000\000\000\161\000\000\000\189\011\014\000\000\000\000\000\000\n\214\000\000\000\000\n\182\000\165\n\230\000\000\n\238\n\206\000\000\n\222\n\214\000\161\021>\n\182\000\000\000\000\000\000\000\000\000\000\000\000\n\190\000\000\000\165\000\000\000\000\000\000\000\161\000\161\000\000\n\238\000\000\n\190\000\000\000\000\000\000\n\198\000\000\000\165\000\165\000\000\n\246\000\177\000\177\000\000\000\000\000\000\n\198\n\214\000\000\000\000\000\000\n\230\000\185\011\014\n\206\000\000\n\222\000\000\000\000\000\173\000\000\000\000\n\230\n\246\000\000\n\206\000\000\n\222\000\000\000\000\n\214\000\000\000\000\000\000\000\173\000\173\n\238\000\000\000\000\000\000\000\000\000\000\000\189\000\000\000\000\000\000\000\000\n\238\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\022\n\254\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\246\000\000\000\000\000\000\000\000\000\000\000\000\n\214\000\000\000\000\000\000\n\246\000\000\000\000\000\000\000\000\000\000\000\000\n\214\000\177\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\185\000\000\000\000\000\000\000\177\n\254\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\185\n\254"))
+ ((16, "\001\128\000X\000\000\000\000\001\015\000\000\000\000\000\000\001\128\000\000\002,%\"\000\000\000\127;\144\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\191\000y\000\000%\"#\"CR\000C;\242\000\000\000\000\000\000\000\000B\180\000\005CR\001 CR\000\000\000U\000\000CR\000\000\000\133\000\000\000\000\000\0032\202\000\000\000\0004\156\000\0006\012\000\0006\1402\2022\202\016j\016j6\012\016j\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0004\2502\202\000\000\000\0004\250\000\0004\250\000\0004\250\000\000\000\000\000\000\018\208\000\133\000\000\016j\000\000*\2202\202\02302\202\000\000\000\000\000\000\000\000\000\000\000\000\025`2\202\000\000\026N2\202\026\1742\202\027\1562\202\000\0002\202\000\0002\202\027\2522\202\028\2342\202\029J2\202\03082\202\030\1522\202\00082\202\000\000\000\000\000\000\000\000\000\0002\202\031\1342\202\031\2302\202 \2122\202\000\000\000\0002\202\000\000\015\254%\164\000\000\000\000\000l\000\000\000\000\000\000\023\252\000\000\000\000\000\000\000\000\000\000\014\024\000\127\000\000%\164\000\000\000\251\016j\000\0002\202\000\136\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000\226\000\000\000\000\001\028\000\000\001>6\012\000\000\000\000\000\000\000\000\000\000\000\0006\2282\202\000\0006\228\000\0006\2286\228\000\000\000\000'\164\000\133\000\000\016j\001B\000\0002\202\002\030\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000;`2\202\000\0002\202\000\000\000\000\002L\000\000\000=5\180\002\2522\202\002\204\000\000\000\0006\012\000=\000\000\000\000\000\000\000\000\000\000<\1526\012<\2366\012<\2526\012=\2426\012\000\0006\012\000\0006\012> 6\012>t6\012?V6\012?\1326\012?\2162\202\002\1426\012\000\0006\012@\1866\012@\2326\012A<\002\172\000\000\002\234\000\000\00052\202\000\000\0005\000\000\000\000\000\132%\"\000\000\000\132\000\000\000\000\002\2382\202\000\000\003$\000\000\016j\003\158\000\000\000\000\004p\000\000\016j\003\182\000\000\000\000\003\204\000\000\000\000\000\003\000\000\004\166\000\000%>A\250\004\156\004\148\000\133\004\020\004\216C\240\000C\000\000\000\000\001\006DH\000\000\000\000\000\000\005\000\005\018\001\"\005(C\240\001\222C\240\000\000\000\000\001 \000\000\000\000\004z\000\000\004\142\005BC\240\004\162\000\000\000\000\001\006\000\000\004\176\005\138\000\000D\158C\168\000\000\000\133\005\154\000\000\014\024\000\133\005\156\000\000\000\000#\214CR\004\224\000\000\005X\000\000\004\234\000\000\000\162%\"\000\000%\"\000\000\004\226\000\000\000\162\000\000\012\246\018\240\005\184C\240\005\n\005\224\000\000%\"\000\158\000\000\005\226\000\000\000\000\000\000\000\000\000\000\000\000\005\2002\202\005\028\017\"\005\2102\202\005$\005\206\001\006\005V\006z\000\0007d7\228\016j\0052\000\000\00587\228\000\000\000\000\000\000\000\000\000\000\000\000\000\0008d2\202\000\0008d\000\0008d8d\000\000\000\000\022B\000\133\000\000\016j\005<\000\0002\202\005@\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000&.2\202\000\0002\202\000\000\005b\000\000\0005\000\000\000\000\000\000\000\000\000\000+@7\228,.7\228,b7\228-P7\228\000\0007\228\000\0007\228-\1327\228.r7\228.\1667\228/\1487\228/\2002\202\005\1567\228\000\0007\2280\1827\2280\2347\2281\216\016j\005x\000\000\000\0002\202\000\000\006P\000\000\001J\006&2\202\005\242\000\000\006.2\202\006\000\000\000\003>\000\000\006z\006z\001J\000\000\001J\000\000\012\246\006z\006z\000\000\000\000\000\000\020\172\000\000\000\000\000\000\000\000\006H2\202\005\154\017\"\017\240\000\133\006l\000\000\006R3\132\006v3\132\006x2\202\005\172\017\"\017\"\000g\0026\000Y\000\000\000\000\000\000\0026\000\000\002j\000g\000\000\000\000\005\178\000\000\000\000\000\000\006\132\000\000\006\136\000\000\000\000\006\188\006p2\202\005\194\006\150\000\000\019\190\006|\016j\005\208\017\"\000\000\000\000\005\254\000\000\0009\000\000\003\226\000\000\001J\000\000\000\000\006H\000\000.(\018\240\006\142C\240\005\234\006\188\000\000\000\133\000\000\000\0272\202(J\000\0008\2282\202\005\254\000\000\016j\006\006\000\000\006\008\000\000\000\000\000\000\000\000\000\000\000\000\000\0009d2\202\000\0009d\000\0009d9d\000\000\000\000Dn\000\133\000\000\016j\006\n\000\0002\202\006\012\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016j\006\0189\228\000\000\000\0002\202\000w2\202\006\016\006D(J(\242'\014\006\1902\202\006\140\000\000\000\000\000\133\006L(J\000\000\006T(J\000\000\000\000\020X9\228\021F9\228\025p9\228!\1889\228\000\0009\228\000\0009\228$~9\228(&9\228E\1529\228E\1749\228E\2489\228F&9\228F\1329\228F\154\000\000\000\000\006,\000\000\006>)\154\000\000*B\006B*B1\252\006D*B\000\000\000\000\000\000\000\000\000\000\006n(J\000\000\000\000\006>\000\000\007\024\000\000\000\133\000\000\000\027\007\028\000\000\000N\006\236\000\133\006T\007\012C\240\006^\000@\000\0002\202\0078\000\000\001\022\001\026\003\178\007\030C\240\006r\007L\000\000\000\0052\202\007N\000\000\007T\000\000\014\024\000\133\002\1722\202\007X\000\000\007`\000\000\011\170\0009\000\000\011\170\000\000\000\000\019\190\002\2442\202\007|\000\000\007\128\000\000\000\000\001\154\007^\000\133\006\196\007zC\240\006\206\000\210\000\0002\202\007\160\000\000\0009\000\000\000\000\007\198\000\000\011\170\000\000\007\130\016j\006\214\007\174\000\000\001\022\000\000\007\148C\240\006\230\007\190\000\000\00302\202\007\194\000\000\007\196\000\000\014\024\000\133\003@2\202\007\200\000\000\007\202\000\000\000\000\000\000\007\198\000\000\000\000\0009\000\000\006z\000\000\001\022\000\000\000\000\001\024\017\240\000\000\001\024\000\000\000\000\007\000\000\000\0005\000\003\017\"\000\000\003\226\0009\003\226\000\000\0009\000\000\006z\000\000\006z\000\000\000\000\000\000\006\250\000\000\000\000\007\006\000\000\001\162\005.\000\013\003\226\000\000\000\000\000\000\003\"\000\000\006z\000\000\001\162\000\000\000\000\001\022\003\214\012\246\000\000\014\242\000\000\t\018\012\246\000\000\000\000\t\018\000\000\000\000\007\008\000\000\000\000\007\014\000\000\001\248\006z\000\000\001\248\000\000\000\000\007|\000\000\0009\000\000\006z\000\000\000\000\000\000\015\1283\226\000\000\007\224\000\000\015\128\007\226\000\000\007\232\000\000.(\000\133\002\028\000\0002\202\007\236\000\000\007\212\007\196\000\133\007*\007\230C\240\007H\002d\000\0002\202\008\"\000\000\001\022\002\176\000\0002\202\008$\000\000\014\024\000\133\002\196\000\0002\202\008&\000\000\002\158\015\128\000\000\019\190\003<\000\0002\202\008,\000\000\000\000\000\000\008\014\007\254\000\133\007f\008\024C\240\007j\004$\000\0002\202\008<\000\000\002.\000\000\008.\016j\007\134\008X\000\000\002\188\000\000\004j\000\0002\202\008`\000\000\014\024\000\133\004\140\000\0002\202\008b\000\000\002\158\000\000\000\000\007\150\000\000\002.\003\174\008\006\000\000\000\000\000\000\008\014\000\000\002\016\002d\000\000\012\246\008^\000\000\000\0002\202\007\204\006z\000\000\007\164\000\000\001\006\000\000\000\000\003h\012\246\000\000\012\246\000\000\007\150\000\000\003h\000\0006\012\003\2046\012\000\0006\012\000\000\007\154\000\000\003\204\000\000\017\"\004\028\017\"\000\000\017\"\000\000\007\160\000\000\004\028\000\0006\012\003\204\007\164\000\000:\220\000\133\004 :\220\000\000:\220\000\000\007\168\000\000\004 \000\0006\012\003\204\007\174\000\000\000\000\021\248\000\000\000\000\000\000\000\000\000\000\025H!x\000\000\006\160\000\000\005\222\000\000\000\000\007\240\000\133\000\000\000\000\000\000\000\164\005\222\000\000\002\238\002\130\002\130\000\000\002\018\002\130\000\000\007\206\000\000\000\000\000\000\000\000\000\000\000\000\008N\000\000\"\160\000\000%\"\005\222\000\000\003^\005\222\000\000\008l\000\000\005\222\008p\000\000\005\234\006\030\008~\000\000\008\130\000\000\0076\007\216\005\222\008\012\005\222\008\134\000\000\008\138\000\000\008\140\000\000%\"\000\000\002\154%\"\000\000\008\020\011\188\000\000\001\002\005\222\000\000\004\166\005\222\000\000\004\208\003\136\000\133\000\000\t\004\000\133\000\000\008\024\000\000\000\000\000\000\000\000\008\150\000\000\006\030\005\222\008\158\000\000\008\164\000\000\005\222\008\166\000\000\005\222\008\178\000\000\008\140\005\222\008\182\000\000\015\180\006\030\005\222\008@\005\222\008\186\000\000\008\188\000\000\000\000\004\168\005\222\000\000\004\220\001\130\001\130\000\000\000\000\000\000\003\158\001\130\000\000\008D\000\000\000\000\000\000\000\000\005\222\000\000\004\200\005\222\000\000\004\234\003\196\000\133\008F\000\000\000\000\000\000\000\000\008\196\000\000\008\198\000\000\005\222\008\204\000\000\007\216\005\222\008\206\000\000\008\208\000\000-\006\008\130\008\174\007j\005\222\008\220\000\000\000\000\008\224\000\000\008\182-\006\005\222\008\228\000\000\005\222\008\230\000\000\008\234\000\000\005\222\008v\005\222\008\246\000\000\008\248\000\000\000\133\008t\000\000\000\000\021\248\000\000\000\000\0028\t\\\000\000\000\000\003^\000\000\000\000\000\0002\202\000\135\t\162\008\204\tL6\012\000\000\003\1926\012\000\000\008\160\000\000\000\000\000\000\000\000\000\000\002\150\000\000\003n\000\000\000\000\000\000\003\226B\242\005lB\242B\242\005l\000\000\000\000\000N\000N\000N\000N\000\000\000\000\000\000\000\000\000\000\000\000(J\008\162\000\000\000\000\000\000;`\000N\014@\0009\000\000\000\000\0009\000\000\007\198\000\000\000\000\000\135\000\000\000\000\008\236\001h\t\\ER\000\000\004nE\186\000\000\000\000\t^\tN\000\133\000\000\000\133\000\000\004n\000\000\004\140ER\000\000\000\000\008\178\t\\\006z\008\176\000\000\001\154\0009\000\000\007\198\000\000\014\196\005,\000\000\000\000\tZ\000\000\000\000\0028\000\000\004\172\000\000\000\000\000\0002\202\000\135\000\000\002\150\000\000\004\230\000\000\000\000\000\000\005.\000\000\n^\001\020\n^\000\000\006z\n^\000\000\001\020\000\000\006z\000\000\006z\000\000\006z\000\000\000\000\000\000\000\000\000\000\000\135\000\000\006z\000\000\001\020\000\000\006z\000\000\017H\000\000\000\000\t\018\008\248\000\133\003\144\t\148\004`\000\000\004`\t\190\000\000\t\192\000\000\t\194\000\000\000\000\001*\004`\012\244\004`\000\000\000\000\000\152\008\214\000\000\t\200\000\000\000\000\t\018\007\184\002\202\t\216\n\248\t\216\000\000\000\000\007\250\000\133\000\000\004\024\t0\000\000\000\000\000\000\004\192\000\000\008\238\000\000\000\000\000\000\007\184\002\202\007\250\004\024\004\192\008\244\000\000\000\133\000\000\t\234\t\234\t4\000\133\t\134\000\000"), (16, "\n\141\n\141\n\141\n\141\n\141\n\141\n\141\n\141\n\141\n\141\n\141\000:\n\141\n\141\n\141\n\141\n\141\n\141\n\141\n\141\n\141\t.\000\210\t.\002\162\n\141\000\023\000\027\003i\005\197\007\230\n\141\0055\n\141\n\141\n\141\n)\000\210\n\141\008\026\000z\000\146\n\141\n\141\000\210\n\141\006*\n)\005=\006.\000\162\004^\007\230\020\150\n\141\0062\000~\n\141\n\141\0066\020\154\008\026\020\"\n\141\n\141\000\162\n\141\000\222\n\141\000\174\0111\003\233\000\162\n\141\nJ\n\141\n\141\n\141\n\141\n\141\000\n\011\158\008\158\n\141\n\141\n\141\n\141\n\141\n\141\008\166\n\141\n\141\n\141\n\141\005\229\005\229\011J\n\141\n\141\005\229\000\014\0111\002\253\003\154\011\130\t:\003%\n\141\n\141\n\141\n\141\n\141\n\141\n\141\000\194\n\141\002U\n\141\tv\n\141\002U\003%\n\141\n\141\005\197\005\214\005\157\t:\n\141\011\210\005=\013J\n\141\0111\0111\n\141\011j\022\154\0111\n\141\n\141\n\141\n\141\004v\n\141\n\141\003\233\011j\005=\n\141\n\141\n\141\005=\n\141\012^\n\141\n\141\006\026\n\141\003\181\n\141\n\141\002\014\011\162\n\141\n\141\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\nq\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\t.\012\162\005\222\004q\005\205\007\234\007\250\008\n\000\162\007\230\005\205\003%\005\205\005\205\005\205\003%\003%\005\205\008\026\004\005\002f\005\205\004q\022\154\005\205\006*\000\182\003%\006.\004v\013&\005\149\020\150\005\205\0062\000\006\002\178\001\"\0066\020\154\011\178\001.\005\205\005\205\017.\000\210\000\210\005\205\005\205\012b\013\026\003%\005\205\022\162\005\205\005\205\005\205\005\205\005\205\007\217\005m\018\018\005\205\005\205\005\205\005\205\005\205\005\205\000\162\005\205\005\205\005\205\005\205\000\162\000\162\018\218\005\205\005\205\001\"\002\210\008\001\001*\001.\012B\t:\004q\006^\005\205\005\205\005\205\005\205\005\205\005\205\005\018\005\205\015\246\005\205\005U\005\205\013\154\005E\005\205\005\205\004q\005\149\005\189\007\013\005\205\002\222\000\162\007\013\005.\008\001\008\001\005\205\022\170\018\222\008\001\005\205\005\205\005\205\005\205\000\162\005\205\005\205\002\230\022\162\003:\005\205\005\205\005\205\005\237\014\130\005\237\005\205\005\205\005\237\005\205\003\181\005\205\005\205\015V\014\026\005\205\005\205\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\008\014\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005e\005e\014\178\004^\005\237\005\237\019\254\005\237\005\165\n\025\005\237\017\022\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\000.\005\246\016>\016f\016\142\016\158\016\202\005\237\022\210\005:\005\237\017>\n)\002y\014\202\005\237\005\237\005\237\005\237\005\237\015r\005\237\014\134\005\213\014\230\005\173\005\237\019\254\005\237\005\237\005\237\005\237\005\237\014\250\015\222\017J\005\237\005\237\005\237\005\237\005\237\005\237\nA\005\237\005\237\005\237\005\237\003F\n)\014F\005\237\005\237\005\157\008\162\014J\005\237\001\"\005]\014\182\011\178\001.\005\237\005\237\005\237\005\237\005\237\005\237\017:\005\237\003\146\005\237\t.\005\237\008\014\003\162\005\237\005\237\003\170\n)\008\190\007\230\005\237\004*\003\001\015\n\005\237\n)\000\162\005\237\008\026\015\202\006\021\005\237\005\237\011\242\005\237\014\206\005\237\005\237\003\233\005\213\016\030\005\237\017\250\005\213\005\213\014\234\008\018\005\181\005\237\n!\005\237\011j\005\237\005\237\004N\005\213\005\237\005\237\0002\005\250\000F\000J\006\018\000N\006*\000R\000V\006.\000Z\012&\000^\020v\000b\0062\000f\000j\000n\0066\020~\005\213\015r\018.\004m\006:\006\021\004V\nQ\011j\004\142\000r\016F\000\226\006J\006f\t:\007!\006j\014F\004\001\012\190\000v\004m\014J\007\214\016&\015\014\014N\012\222\004v\007\230\007!\019&\000\238\003\233\004\154\007\230\001\"\011j\008\026\011\178\001.\008.\006r\020\186\008\026\011j\0082\013V\000\162\022\246\016n\001\022\016\170\001\026\003\197\000\134\t6\008:\015\202\015B\017\142\006\134\001\"\008>\006\138\008B\001.\000\162\006\142\006\146\008F\006\150\020\015\020\019\016N\022j\008J\020\023\000\162\007!\020g\020k\005\133\022r\004m\020o\006\154\006\158\008N\008R\006\162\008V\018\238\000\162\015z\008j\004\166\003\161\003!\n9\008v\006\170\004m\005\149\t:\022v\005\245\004\178\004\190\020:\t:\015\150\022z\008\150\016v\n1\016\178\008\154\008\214\003\197\tB\004\202\006\174\008\218\004\222\007!\022\254\006\178\003\197\003\197\003\129\023\002\005}\003\197\008\226\004\238\006\182\007!\005\245\005\245\004\242\015F\001^\005\245\0002\005\250\000F\000J\006\018\000N\006*\000R\000V\006.\000Z\004\250\000^\020v\000b\0062\000f\000j\000n\0066\020~\004\254\003\129\018*\022\130\006:\na\nY\005\141\018\214\005u\000r\015~\000\226\006J\006f\019\"\0055\006j\021\139\0055\005&\000v\ni\0055\007\214\0055\006\005\021\143\015\154\0055\0055\021\030\005\253\000\238\022\138\005M\007\230\021\146\005*\006\013\0052\005V\008.\006r\020\186\008\026\021N\0082\013\158\023\n\002m\005^\001\022\005b\001\026\003\213\000\134\t6\008:\018\030\018\202\005j\006\134\001\"\008>\006\138\008B\001.\005~\006\142\006\146\008F\006\150\005\130\021\171\021\175\019\022\008J\017\014\021\179\006\005\005\154\005\170\002V\017\174\004\217\005\253\006\154\006\158\008N\008R\006\162\008V\006\013\000\162\005\190\008j\005\198\003\161\017\018\005\206\008v\006\170\021\207\021\211\017\018\005\235\006\029\021\215\017\022\017\014\t:\006\002\006\n\008\150\017\022\006\014\006\"\008\154\008\214\006>\tB\006F\006\174\008\218\006N\006V\006Z\006\178\0055\003\213\017\018\006b\006z\019\198\008\226\006\130\006\182\006\218\006\029\006\029\017\022\006\230\001^\006\029\0002\005\250\000F\000J\006\018\000N\006*\000R\000V\006.\000Z\007.\000^\020v\000b\0062\000f\000j\000n\0066\020~\018\166\007\166\007\206\t\197\006:\018b\007\226\007\238\007\246\007\221\000r\007\254\000\226\006J\006f\008\006\000\162\006j\008Z\008b\008r\000v\000\162\008z\007\214\008\130\008\138\t\197\008\146\017\"\007\221\008\206\008\222\000\238\008\230\017\"\007\230\008\242\008\246\008\254\007\221\t\002\008\022\006r\t\014\008\026\t\022\0082\000\162\017\006\t&\tJ\001\022\tZ\001\026\003\241\000\134\0086\008:\tb\tf\017\"\006\134\001\"\008>\006\138\008B\001.\t\142\006\142\006\146\008F\006\150\t\154\t\162\t\246\0119\008J\n\002\n6\nR\t\197\nV\nf\017\198\nn\n~\006\154\006\158\008N\008R\006\162\008V\n\138\000\162\011\014\008j\011\022\003\161\011&\0112\008v\006\170\011N\011^\017\018\011f\008\t\011z\011\134\004a\t:\011\142\007\221\008\150\017\022\011\146\011\154\008\154\008\214\003\241\tB\011\170\006\174\008\218\011\190\007\221\011\198\006\178\003\241\003\241\004a\011\202\011\218\003\241\008\226\011\226\006\182\011\250\008\t\008\t\004a\012\002\001^\008\t\0002\005\250\000F\000J\006\018\000N\006*\000R\000V\006.\000Z\012.\000^\0126\000b\0062\000f\000j\000n\0066\017\014\012F\003!\012N\t\185\006:\012R\004a\012Z\012j\012\142\000r\012\150\000\226\006J\006f\012\154\003!\006j\012\170\012\178\017\018\000v\000\162\012\182\007\214\012\198\012\206\t\185\012\230\012\238\017\022\013>\013\134\000\238\013\146\017\"\007\230\014\006\014\018\0142\014^\014j\008\022\006r\014r\008\026\014\142\0082\004a\005\221\014\150\014\154\001\022\014\162\001\026\017\202\000\134\0086\008:\014\166\019^\004a\006\134\001\"\008>\006\138\008B\001.\014\174\006\142\006\146\008F\006\150\014\190\014\214\014\242\0119\008J\015\022\015&\015*\t\185\t\197\0152\0156\015>\015N\006\154\006\158\008N\008R\006\162\008V\003!\000\162\015^\008j\003!\003!\015f\015j\008v\006\170\000\162\015\134\015\162\015\182\0119\015\198\003!\022j\t:\015\214\015\238\008\150\015\254\017\"\016\n\008\154\008\214\0163\tB\016[\006\174\008\218\016\131\005\221\016\155\006\178\016\191\005\221\005\221\016\215\003!\017\026\008\226\t\197\006\182\017V\0119\0119\017s\022\234\001^\0119\0002\005\250\000F\000J\006\018\000N\006*\000R\000V\006.\000Z\017\155\000^\017\167\000b\0062\000f\000j\000n\0066\017\183\005\221\017\191\017\210\017\219\006:\017\227\017\235\018\006\003\141\018F\000r\018[\000\226\006J\006f\018k\nI\006j\018s\018\127\022^\000v\007)\003\141\007\214\018\139\018\146\018\155\018\174\018\183\018\191\018\250\019.\000\238\019C\019K\007\230\007)\019W\019g\019o\019z\008\022\006r\019~\008\026\019\139\0082\019\151\019\158\019\171\019\183\001\022\019\191\001\026\019\202\000\134\0086\008:\019\211\019\219\019\231\006\134\001\"\008>\006\138\008B\001.\020\002\006\142\006\146\008F\006\150\020&\020*\020.\020F\008J\020\194\021\n\021\018\021.\0212\021^\021b\021j\007)\006\154\006\158\008N\008R\006\162\008V\nI\000\162\021\151\008j\nI\nI\022b\003\141\008v\006\170\022\186\003\141\003\141\022n\022~\022\134\022\142\022\183\t:\022\190\022\214\008\150\022\250\003\141\003\141\008\154\008\214\018:\tB\023\019\006\174\008\218\0237\023F\nI\006\178\023J\023N\023W\007)\nI\000\000\008\226\000\000\006\182\000\000\000\000\003\141\000\000\000\000\001^\007)\0002\005\250\000F\000J\006\018\000N\006*\000R\000V\006.\000Z\000\000\000^\020v\000b\0062\000f\000j\000n\0066\020~\000\000\000\000\000\000\000\000\006:\000\000\000\000\000\000\000\000\000\000\000r\000\000\000\226\006J\006f\000\000\000\000\006j\000\000\000\000\000\000\000v\000\000\000\000\007\214\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008.\006r\000\000\000\000\000\000\0082\021\230\000\000\000\000\000\000\001\022\000\000\001\026\000\000\000\134\t6\008:\000\000\000\000\000\000\006\134\001\"\008>\006\138\008B\001.\000\000\006\142\006\146\008F\006\150\000\000\000\000\000\000\000\000\008J\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\154\006\158\008N\008R\006\162\008V\000\000\000\162\000\000\008j\000\000\003\161\000\000\n\017\008v\006\170\000\000\000\000\000\000\000\000\007\237\000\000\000\000\000\000\000\000\000\000\000\000\008\150\000\000\000\000\000\000\008\154\008\214\000\000\tB\000\000\006\174\008\218\000\000\000\000\000\000\006\178\000\000\000\000\000\000\000\000\000\000\000\000\008\226\000\000\006\182\000\000\007\237\007\237\000\000\000\000\001^\007\237\0002\005\250\000F\000J\006\018\000N\006*\000R\000V\006.\000Z\000\000\000^\000\000\000b\0062\000f\000j\000n\0066\0055\000\000\000\000\000\000\000\000\006:\000\000\000\000\000\000\000\000\000\000\000r\n\017\000\226\006J\006f\n\017\n\017\006j\000\000\000\000\0055\000v\000\000\000\000\007\214\000\000\000\000\n\017\000\000\000\000\0055\000\000\000\000\000\238\000\000\000\000\000\000\000\000\022\218\000\000\000\000\000\000\008.\006r\000\000\000\000\000\000\0082\012\n\000\000\000\000\n\017\001\022\000\000\001\026\0055\000\134\t6\008:\000\000\000\000\002V\006\134\001\"\008>\006\138\008B\001.\000\000\006\142\006\146\008F\006\150\000\000\000\000\000\000\011\021\008J\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\154\006\158\008N\008R\006\162\008V\000\000\000\162\000\000\008j\000\000\000\000\000\000\000\000\008v\006\170\0055\000\000\000\000\000\000\011\021\000\000\000\000\000\000\000\000\000\000\000\000\008\150\000\000\0055\000\000\008\154\008\214\000\000\tB\000\000\006\174\008\218\000\000\000\000\000\000\006\178\000\000\000\000\000\000\000\000\000\000\000\000\008\226\000\000\006\182\000\000\011\021\011\021\000\000\000\000\001^\011\021\0002\005\250\000F\000J\006\018\000N\006*\000R\000V\006.\000Z\000\000\000^\000\000\000b\0062\000f\000j\000n\0066\000\000\000\000\000\000\000\000\000\000\006:\000\000\000\000\003\029\000\000\000\000\000r\000\000\000\226\006J\006f\000\000\000\000\006j\000\000\000\000\000\000\000v\003\029\000\000\007\214\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\000\000\000\003\029\000\000\000\000\000\000\008.\006r\000\000\000\000\000\000\0082\013\210\000\000\000\000\000\000\001\022\000\000\001\026\000\000\000\134\t6\008:\000\000\000\000\000\000\006\134\001\"\008>\006\138\008B\001.\000\000\006\142\006\146\008F\006\150\000\000\000\000\000\000\000\000\008J\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\154\006\158\008N\008R\006\162\008V\000\000\000\162\000\000\008j\000\000\000\000\003\029\000\000\008v\006\170\003\029\003\029\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\150\003\029\000\000\000\000\008\154\008\214\000\000\tB\000\000\006\174\008\218\002\142\000F\000J\006\178\000N\003\029\000R\000V\000\000\000Z\008\226\000^\006\182\000b\003\029\000f\022\162\000n\001^\0002\005\250\000F\000J\006\018\000N\006*\000R\000V\006.\000Z\000r\000^\000\000\000b\0062\000f\000j\000n\0066\000\000\000\000\000v\000\000\000\000\006:\000\000\000\000\000\000\000\000\000\000\000r\000\000\000\226\006J\006f\000\000\000\000\006j\000\000\000\000\000\000\000v\000\000\000\000\007\214\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\134\000\000\000\000\000\000\000\000\000\000\008.\006r\000\000\000\000\000\000\0082\020\218\000\000\000\000\000\000\001\022\000\000\001\026\000\000\000\134\t6\008:\000\000\000\000\000\000\006\134\001\"\008>\006\138\008B\001.\000\000\006\142\006\146\008F\006\150\000\000\000\162\000\000\000\000\008J\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\154\006\158\008N\008R\006\162\008V\012\162\000\162\000\000\008j\000\000\000\000\000\000\000\000\008v\006\170\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007!\000\000\000\000\008\150\000\000\t.\000\000\008\154\008\214\000\000\tB\000\000\006\174\008\218\007\230\007!\000\000\006\178\001\"\000\000\000\000\011\178\001.\008\026\008\226\000\000\006\182\000\000\0002\005\250\000F\000J\001^\000N\006*\000R\000V\006.\000Z\000\000\000^\000\000\000b\0062\000f\000j\000n\0066\000\000\000\162\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000r\000\000\000\226\006\229\006f\007!\018\162\006j\000\000\000\000\000\000\000v\000\000\000\000\014R\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\000\017\018\000\000\000\000\t:\000\000\014b\006r\000\000\006\229\006\229\017\022\000\000\000\000\006\229\000\000\001\022\0055\001\026\000\000\000\134\000\000\000\000\000\000\000\000\007!\006\134\001\"\000\000\006\138\001*\001.\000\000\006\142\006\146\008F\006\150\007!\0055\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\000\0055\0055\000\000\006\154\006\158\000\000\000\000\006\162\000\000\000\000\000\162\000\000\0002\0006\000F\000J\000\000\000N\006\170\000R\000V\000\000\000Z\000\000\000^\0055\000b\000\000\000f\000j\000n\002V\000\000\000\000\0055\0055\000\162\tB\000\000\006\174\014f\000\000\000\000\000r\006\178\000\226\000\000\000\230\000\000\017\"\000\234\014n\000\000\006\182\000v\000\000\000\000\000\000\000\000\001^\000\000\000\000\000\000\000\000\000\000\0055\000\238\000\000\000\000\000\242\000\000\000\000\000\000\0055\000\000\001\n\001\006\000\000\001\014\000\000\000\000\000\000\000\000\000\000\000\000\001\022\0055\001\026\000\000\000\134\000\000\000\000\000\000\000\000\000\000\001\030\001\"\000\000\001&\001*\001.\001\130\0012\0016\000\000\001:\0055\000\000\000\000\0055\0055\000\000\000\000\0055\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001>\000\000\0055\001B\000\000\000\000\000\162\000\000\006:\000\000\000\000\000\000\000\000\000\000\001J\000\000\000\226\006J\006f\000\000\000\000\006j\000\000\001N\000\000\000\000\000\000\000\000\007\214\000\000\000\000\000\000\000\000\000\000\000\000\001R\000\000\000\238\000\000\000\000\001V\000\000\000\000\003e\000\000\000\000\008f\006r\000\000\001Z\012\162\0082\000\000\000\000\000\000\001^\001\022\000\000\001\026\000\000\000\000\000\000\008:\000\000\000\000\000\000\006\134\001\"\008>\006\138\008B\001.\000\000\006\142\006\146\000\000\006\150\000\000\000\000\000\000\000\000\008J\000\000\000\000\000\000\000\000\001\"\000\000\000\000\011\178\001.\006\154\006\158\008N\008R\006\162\008V\000\000\000\162\000\000\008j\000\000\000\000\000\000\000\000\008v\006\170\000\000\000\000\000\000\000\000\006:\000\000\000\000\000\000\000\000\000\000\000\162\008\150\000\226\006J\006f\008\154\008\214\006j\000\000\000\000\006\174\008\218\000\000\0089\007\214\006\178\000\000\000\000\000\000\000\000\000\000\000\000\008\226\000\238\006\182\000\000\000\000\000\000\000\000\000\000\001^\000\000\006n\006r\000\000\000\000\000\000\0082\000\000\000\000\000\000\000\000\001\022\000\000\001\026\0089\0089\000\000\008:\000\000\0089\000\000\006\134\001\"\008>\006\138\008B\001.\000\000\006\142\006\146\000\000\006\150\000\000\000\000\000\000\000\000\008J\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\154\006\158\008N\008R\006\162\008V\000\000\000\162\000\000\008j\000\000\000\000\000\000\000\000\008v\006\170\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011e\0055\008\150\011e\0055\000\000\008\154\008\214\0055\000\000\0055\006\174\008\218\000\000\0055\0055\006\178\000\000\011e\000\000\000\000\000\000\011e\008\226\000\000\006\182\001v\011e\000\000\000\000\000\000\001^\000\000\011e\000\000\000\000\011e\011e\000\000\011e\011e\000\000\000\000\001~\000\000\011e\002\170\000\000\000\000\011e\000\000\000\000\011e\000\000\011e\011e\000\000\000\000\000\000\0055\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\146\000\000\000\000\000\000\000\000\000\000\011e\000\000\011e\000\000\000\000\001\"\000\000\000\000\001*\001.\000\000\000\000\011e\000\000\000\000\000\000\000\000\002\182\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011e\011e\011e\000\162\011e\011e\002\186\0055\011e\000\000\000\000\000\000\004\001\000\000\000\000\004\001\002\194\000\000\000\000\000\000\011e\000\000\000\000\011e\011e\011e\011e\000\000\000\000\000\000\004\001\011e\011e\011e\004\001\011e\011e\011e\004\001\004\001\000\000\000\000\000\000\000\000\000\000\004\001\000\000\000\000\004\001\004\001\000\000\004\001\004\001\000\000\000\000\004\001\000\000\004\001\004\001\000\000\000\000\004\001\000\000\000\000\004\001\000\000\004\001\004\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\210\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\001\000\000\004\001\n\154\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\001\000\000\000\000\000\000\000\000\004\001\000\000\000\000\000\162\n\162\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\001\004\001\004\001\n\170\004\001\004m\004\001\000\000\004\001\n\234\n\242\000\000\004\005\000\000\000\000\004\005\004\001\000\000\000\000\n\202\004\001\000\000\n\178\004\001\n\194\004\001\000\000\000\000\000\000\000\000\004\005\004\001\004\001\004\001\004\005\004\001\004\001\004\001\004\005\004\005\000\000\000\000\000\000\000\000\n\210\004\005\000\000\000\000\004\005\004\005\000\000\004\005\004\005\000\000\000\000\004\005\000\000\004\005\004\005\000\000\000\000\004\005\000\000\000\000\004\005\000\000\004\005\004\005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\218\000\000\000\000\000\000\000\000\000\000\000\000\n\186\004\005\000\000\004\005\000\181\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\169\004\005\000\000\000\000\000\000\000\000\004\005\000\000\000\000\000\000\n\162\000\000\000\000\000\000\000\000\n\250\n\226\000\000\000\000\000\000\000\000\000\000\004\005\004\005\004\005\n\170\004\005\004q\004\005\000\000\004\005\000\181\000\181\000\000\000\000\000\000\000\000\000\000\004\005\000\000\000\000\n\202\004\005\000\000\n\178\004\005\n\194\004\005\000\000\000\000\000\000\000\000\000\000\004\005\004\005\004\005\000\000\004\005\004\005\004\005\001=\001=\001=\001=\000\000\001=\n\210\001=\001=\000\000\001=\000\000\001=\000\000\001=\000\000\001=\001=\001=\000\000\000\000\000\000\000\000\016\226\000\000\000\000\000\000\000\000\000\000\000\000\001=\001=\001=\000\000\000\000\000\000\000\000\001=\000\000\000\000\n\218\000\000\001=\000\000\000\000\000\000\001=\n\186\000\000\000\000\001=\000\000\000\000\016\230\000\000\000\000\001=\000\000\011\185\000\181\000\000\011\185\000\000\001=\000\000\000\000\000\000\000\000\001=\000\000\000\000\000\000\000\000\000\000\000\181\n\226\011\185\001=\000\000\000\000\011\185\000\000\000\000\000\000\006\202\011\185\000\000\000\000\000\000\000\000\000\000\011\185\000\000\000\000\011\185\011\185\001=\011\185\011\185\001=\000\000\006\210\000\000\011\185\006\222\000\000\000\000\011\185\000\000\000\000\011\185\000\000\011\185\011\185\001=\000\000\001=\000\000\001=\000\000\001=\000\000\000\000\000\000\000\000\001=\000\000\000\000\001=\000\000\000\000\000\000\011\185\000\000\011\185\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001=\011\185\000\000\001=\001=\000\000\006\234\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\234\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\185\011\185\011\185\000\000\011\185\000\000\006\238\000\000\011\185\000\000\000\000\000\000\001\137\000\000\000\000\001\137\006\246\000\000\000\000\000\000\000\000\000\000\000\000\011\185\000\000\011\185\000\000\000\000\000\000\000\000\001\137\011\185\011\185\011\185\001\137\011\185\011\185\011\185\000\000\001\137\000\000\000\000\000\000\000\000\000\000\001\137\000\000\000\000\001\137\001\137\000\000\001\137\001\137\000\000\000\000\000\000\000\000\001\137\000\000\000\000\000\000\001\137\000\000\000\000\001\137\000\000\001\137\001\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\137\000\000\001\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\137\004%\000\000\002v\004%\002z\004%\002~\004%\000\000\004%\000\000\000\000\002\130\004%\004%\000\000\000\000\000\000\000\000\000\000\001\137\001\137\001\146\000\000\001\137\001\137\004%\000\000\001\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\004%\000\000\000\000\001\137\000\000\004%\001\137\001\137\001\137\001\137\000\000\000\000\000\000\000\000\002>\001\137\001\137\000\000\001\137\001\137\001\137\004%\000\000\000\000\004%\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\004%\004%\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\004%\004%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\000\000\004%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\004%\004%\000\000\000\000\004%\000\000\000\000\000\000\000\000\004%\004%\000\000\000\000\000\000\004%\t\181\t\181\t\181\t\181\000\000\t\181\000\000\t\181\t\181\000\000\t\181\000\000\t\181\000\000\t\181\000\000\t\181\t\181\t\181\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\181\t\181\t\181\001\178\000\000\000\000\002\006\t\181\000\000\000\000\000\000\000\157\t\181\000\000\000\000\000\000\016\250\000\000\000\000\000\000\017\002\001\190\000\000\000\000\000\000\002\001\t\181\000\000\000\000\000\157\002\001\000\000\000\000\t\181\000\000\000\000\001\198\000\000\t\181\002\001\002\001\000\000\002&\002.\n\170\000\000\000\000\t\181\002\001\000\000\000\157\000\157\001\230\000\000\000\000\001\206\000\000\001\222\002\001\000\000\000\157\000\000\000\000\n\178\000\000\n\194\t\181\000\000\000\000\t\181\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\238\000\000\002\001\000\000\000\000\000\000\000\000\t\181\000\157\t\181\000\000\t\181\002\001\t\181\000\000\000\000\000\000\000\000\t\181\000\000\000\000\t\181\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\001\001\246\000\000\t\181\002\001\002\001\017v\t\181\001\214\000\157\000\000\000\000\000}\000\000\000\000\000}\n\186\000\000\000\000\000\000\002\001\000\000\000\000\002\001\002\001\002\001\002\001\000\000\000\157\000\000\001\190\000\000\002\001\002\001\000}\0026\001\254\002\001\000\000\000}\000\000\000\000\000\000\000\157\000\157\001\198\000\000\000\000\000}\000}\000\000\000}\000}\000\000\000\000\000\000\000\000\000}\000\000\000\000\000e\001\230\000\000\000e\001\206\000\000\001\222\000}\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000e\000\000\000\000\000\000\000e\000\000\000\000\000\000\001\238\000e\000}\000\000\000\000\000\000\000\000\001\198\000\000\000\000\000e\000e\000}\000e\000e\000\000\000\000\000\000\000\000\000e\000\000\000\000\000\000\000e\000\000\000\000\001\206\000\000\001\222\000e\000\000\000\000\000\000\000}\001\246\000\000\000\000\000}\000}\000\000\000\000\001\214\000\000\000\000\000\000\000\000\000\000\000\000\000e\000\000\000e\000\000\000\000\000}\000\000\000\000\000}\000}\000}\000}\000e\000\000\000\000\000\000\000\000\000}\000}\000\000\000}\001\254\000}\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000e\000e\000\000\000\000\000e\000e\000\000\000\000\001\214\000\000\000\000\000\000\000]\000\000\000\000\000]\000\000\000\000\000\000\000\000\000e\000\000\000\000\000e\000e\000e\000e\000\000\000\000\000\000\000]\000\000\000e\000e\000]\000e\000e\000e\000\000\000]\000\000\000\000\000\000\000\000\000\000\000]\000\000\000\000\000]\000]\000\000\000]\000]\000\000\000\000\000\000\000\000\000]\000\000\000\000\000a\000]\000\000\000a\001\206\000\000\000]\000]\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000a\000\000\000\000\000\000\000a\000\000\000\000\000\000\000]\000a\000]\000\000\000\000\000\000\000\000\000a\000\000\000\000\000a\000a\000]\000a\000a\000\000\000\000\000\000\000\000\000a\000\000\000\000\000\000\000a\000\000\000\000\001\206\000\000\000a\000a\000\000\000\000\000\000\000]\000]\000\000\000\000\000]\000]\000\000\000\000\001\214\000\000\000\000\000\000\000\000\000\000\000\000\000a\000\000\000a\000\000\000\000\000]\000\000\000\000\000]\000]\000]\000]\000a\000\000\000\000\000\000\000\000\000]\000]\000\000\000]\000]\000]\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000a\000a\000\000\000\000\000a\000a\000\000\000\000\001\214\000\000\000\000\000\000\000q\000\000\000\000\000q\000\000\000\000\000\000\000\000\000a\000\000\000\000\000a\000a\000a\000a\000\000\000\000\000\000\001\190\000\000\000a\000a\000q\000a\000a\000a\000\000\000q\000\000\000\000\000\000\000\000\000\000\001\198\000\000\000\000\000q\000q\000\000\000q\000q\000\000\000\000\000\000\000\000\000q\000\000\000\000\000i\000q\000\000\000i\001\206\000\000\001\222\000q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\190\000\000\000\000\000\000\000i\000\000\000\000\000\000\001\238\000i\000q\000\000\000\000\000\000\000\000\001\198\000\000\000\000\000i\000i\000q\000i\000i\000\000\000\000\000\000\000\000\000i\000\000\000\000\000\000\000i\000\000\000\000\001\206\000\000\001\222\000i\000\000\000\000\000\000\000q\000q\000\000\000\000\000q\000q\000\000\000\000\001\214\000\000\000\000\000\000\000\000\000\000\000\000\000i\000\000\000i\000\000\000\000\000q\000\000\000\000\000q\000q\000q\000q\000i\000\000\000\000\000\000\000\000\000q\000q\000\000\000q\000q\000q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000i\000i\000\000\000\000\000i\000i\000\000\000\000\001\214\000\000\000\000\000\000\000m\000\000\000\000\000m\000\000\000\000\000\000\000\000\000i\000\000\000\000\000i\000i\000i\000i\000\000\000\000\000\000\001\190\000\000\000i\000i\000m\000i\000i\000i\000\000\000m\000\000\000\000\000\000\000\000\000\000\001\198\000\000\000\000\000m\000m\000\000\000m\000m\000\000\000\000\000\000\000\000\000m\000\000\000\000\000u\000m\000\000\000u\001\206\000\000\001\222\000m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\190\000\000\000\000\000\000\000u\000\000\000\000\000\000\001\238\000u\000m\000\000\000\000\000\000\000\000\001\198\000\000\000\000\000u\000u\000m\000u\000u\000\000\000\000\000\000\000\000\000u\000\000\000\000\000\000\001\230\000\000\000\000\001\206\000\000\001\222\000u\000\000\000\000\000\000\000m\000m\000\000\000\000\000m\000m\000\000\000\000\001\214\000\000\000\000\000\000\000\000\000\000\000\000\001\238\000\000\000u\000\000\000\000\000m\000\000\000\000\000m\000m\000m\000m\000u\000\000\000\000\000\000\000\000\000m\000m\000\000\000m\000m\000m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000u\001\246\000\000\000\000\000u\000u\000\000\000\000\001\214\000\000\000\000\000\000\001\178\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000u\000\000\000\000\000u\000u\000u\000u\000\000\000\000\000\000\001\190\000\000\000u\000u\000\133\000u\000u\000u\000\000\000\133\000\000\000\000\000\000\000\000\000\000\001\198\000\000\000\000\000\133\000\133\000\000\000\133\002.\000\000\000\000\000\000\000\000\000\133\000\000\000\000\001\178\001\230\000\000\000y\001\206\000\000\001\222\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\190\000\000\000\000\000\000\000y\000\000\000\000\000\000\001\238\000y\000\133\000\000\000\000\000\000\000\000\001\198\000\000\000\000\000y\000y\000\133\000y\000y\000\000\000\000\000\000\000\000\000y\000\000\000\000\000\000\001\230\000\000\000\000\001\206\000\000\001\222\000y\000\000\000\000\000\000\000\133\001\246\000\000\000\000\000\133\000\133\000\000\000\000\001\214\000\000\000\000\000\000\000\000\000\000\000\000\001\238\000\000\000y\000\000\000\000\000\133\000\000\000\000\000\133\000\133\000\133\000\133\000y\000\000\000\000\000\000\000\000\000\133\000\133\000\000\0026\001\254\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000y\001\246\000\000\000\000\000y\000y\000\000\000\000\001\214\000\000\000\000\000\000\001\178\000\000\000\000\000\129\000\000\000\000\000\000\000\000\000y\000\000\000\000\000y\000y\000y\000y\000\000\000\000\000\000\001\190\000\000\000y\000y\000\129\000y\001\254\000y\000\000\000\129\000\000\000\000\000\000\000\000\000\000\001\198\000\000\000\000\000\129\000\129\000\000\000\129\002.\000\000\000\000\000\000\000\000\000\129\000\000\000\000\000\000\001\230\000\000\000\000\001\206\000\000\001\222\000\129\000\000\000\000\000\000\000\000\000\000\t\165\t\165\t\165\t\165\000\000\t\165\000\000\t\165\t\165\000\000\t\165\000\000\t\165\001\238\t\165\000\129\t\165\t\165\t\165\000\000\000\000\000\000\000\000\000\000\000\000\000\129\000\000\000\000\000\000\000\000\t\165\t\165\t\165\000\000\000\000\000\000\000\000\t\165\000\000\000\000\000\000\000\000\t\165\000\000\000\000\000\000\000\129\001\246\000\000\000\000\000\129\000\129\000\000\000\000\001\214\000\149\t\165\000\000\000\000\000\000\000\000\000\000\000\000\t\165\000\000\000\000\000\129\000\000\t\165\000\129\000\129\000\129\000\129\000\149\000\000\000\000\000\000\t\165\000\129\000\129\000\000\000\129\001\254\000\129\000\000\000\000\000\000\000\000\000\149\000\000\000\000\000\000\000\000\000\000\000\149\000\149\t\165\000\000\000\000\t\165\000\000\000\000\000\000\000\000\000\149\000\000\000\000\n\178\000\000\000\149\000\000\000\000\000\000\000\000\t\165\000\000\t\165\000\000\t\165\000\000\t\165\000\000\000\000\000\000\000\000\t\165\000\000\000\000\t\165\000\149\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\165\000\000\000\000\016\254\t\165\t\169\t\169\t\169\t\169\000\000\t\169\000\000\t\169\t\169\000\000\t\169\000\000\t\169\000\000\t\169\000\149\t\169\t\169\t\169\000\000\000\000\000\000\n\186\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\169\t\169\t\169\000\000\000\149\000\000\000\000\t\169\000\000\000\000\000\000\000\000\t\169\000\000\000\000\000\000\017z\000\000\000\000\000\149\000\149\000\000\000\000\000\000\000\000\000\000\t\169\000\000\000\000\000\000\000\000\000\000\000\000\t\169\000\000\000\000\000\000\000\000\t\169\000\000\000\000\004i\000\000\000\000\004i\000\000\004i\t\169\004i\000\000\004i\000\000\000\000\000\000\004i\004i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\169\004i\000\000\t\169\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004i\004i\000\000\000\000\000\000\000\000\004i\t\169\000\000\t\169\000\000\t\169\000\000\t\169\000\000\000\000\000\000\000\000\t\169\000\000\000\000\t\169\004i\000\000\000\000\004i\000\138\000\000\000\000\000\000\000\000\004i\000\000\000\000\004i\004i\t\169\000\000\000\000\000\000\t\169\000\000\004i\000\000\000\000\004i\004i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004Q\004i\000\000\004Q\000\000\004Q\000\000\004Q\000\000\004Q\000\000\004i\000\000\004Q\004Q\000\000\000\000\000\000\000\000\004i\000\000\000\000\000\000\004i\000\000\000\000\004Q\000\000\000\000\000\000\000\000\000\000\004i\000\000\000\000\000\000\004Q\004Q\000\000\000\000\000\000\000\000\004Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004i\000\000\000\000\004i\004i\000\000\004Q\004i\000\000\004Q\005\182\000\000\004i\004i\000\000\004Q\000\000\004i\004Q\004Q\000\000\000\000\000\000\000\000\000\000\000\000\004Q\000\000\000\000\004Q\004Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\153\000\000\004Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004Q\000\000\000\000\000\000\004Q\000\000\000\000\000\000\000\153\000\000\000\000\000\000\000\000\004Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\153\000\000\000\000\000\000\000\000\000\000\000\153\000\153\000\000\000\000\004Q\000\000\000\000\004Q\004Q\000\000\000\153\004Q\000\000\n\178\000\000\000\153\004Q\004Q\000\000\000\000\000\000\004Q\0002\0006\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\000\000\000^\000\153\000b\000\000\000f\000j\000n\000\000\0055\000\000\000\000\0055\000\000\000\000\000\000\0055\000\000\0055\017\130\000r\017\158\0055\0055\000\000\000\000\017\170\000\000\000\000\000\000\000\000\000v\000\000\000\000\000\000\000\000\000\153\000\000\000\000\000\000\000\000\000\000\000\000\n\186\000\000\017\194\000\000\000\000\000\000\000\000\000\000\0055\000\130\000\000\000\000\000\153\000\000\017\238\000\000\000\000\0055\000\000\000\000\0055\000\000\0055\000\134\0055\000\000\0055\000\153\000\153\000\000\0055\0055\000\000\002V\000\000\000\000\0055\000\000\000\000\000\000\000\000\000\000\018\014\0055\0055\018^\000\000\0055\0055\000\000\000\000\000\000\000\000\0055\0055\000\000\000\000\0055\000\000\0055\018v\000\000\007\213\000\000\018\130\000\000\018\142\000\000\000\000\000\000\000\000\018\158\000\000\000\000\019N\0055\000\000\000\000\0055\0055\000\000\000\000\000\000\000\000\002V\000\000\000\000\0055\0055\019Z\000\000\000\000\000\000\019r\000\000\0055\000\000\000\000\0055\0055\000\000\001\161\000\000\000\000\001\161\000\000\000\000\000\000\0055\000\000\000\000\0055\0055\000\000\000\000\000\000\000\000\000\000\0055\001\161\0055\0055\000\000\001\161\000\000\0055\0055\000\000\001\161\000\000\0055\000\000\000\000\000\000\001\161\000\000\000\000\001\161\001\161\0055\001\161\001\161\000\000\000\000\000\000\000\000\001\161\000\000\000\000\000\000\001\161\000\000\000\000\001\161\000\000\001\161\001\161\000\000\000\000\0055\000\000\000\000\0055\0055\000\000\000\000\0055\000\000\000\000\000\000\000\000\0055\0055\000\000\000\000\001\161\0055\001\161\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\161\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\161\001\161\007\026\000\000\001\161\000\000\000\000\000\000\001\161\000\000\000\000\000\000\nb\000\000\000\000\000\000\000\000\003I\000\000\003I\000\000\000\000\003I\001\161\000\000\001\161\000\000\000\000\000\000\000\000\000\000\007\"\001\161\001\161\000\000\001\161\001\161\001\161\003I\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003I\003I\000\000\000\000\003I\003I\000\000\000\000\000\000\000\000\003I\000\000\003I\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003I\003I\000\000\003I\003I\003I\000\000\003I\003I\000\000\003I\000\000\000\000\011\157\000\000\000\000\011\157\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003I\003I\000\000\000\000\003I\000\000\011\157\003I\000\000\000\000\011\157\000\000\000\000\000\000\003*\003I\000\000\000\000\000\000\000\000\000\000\011\157\000\000\000\000\003I\011\157\003I\011\157\011\157\000\000\000\000\0032\000\000\000\000\003>\000\000\003I\011\157\000\000\000\000\011\157\003I\011\157\000\000\000\000\000\000\000\000\003I\000\000\000\000\003I\000\000\000\000\000\169\000\000\000\000\003I\000\000\000\000\000\000\000\000\000\000\011\157\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\162\000\000\000\000\011\157\000\000\000\000\000\000\000\000\003J\000\000\000\000\000\000\000\226\000\000\t~\n\170\000\000\t\130\000\000\000\000\000\000\000\169\000\169\000\000\000\000\011\157\011\157\000\000\011\157\000\000\003N\000\169\011\157\000\238\n\178\000\000\n\194\000\000\000\000\000\000\003V\000\000\t\134\n.\011\157\000\000\nB\nZ\000\000\011\157\011\157\000\000\001\022\000\000\001\026\011\157\n\210\000\000\000\000\011\157\011\157\011\157\t\166\001\"\000\000\t\170\008B\001.\000\000\t\174\t\178\000\000\t\182\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\154\t\186\000\000\000\169\t\190\000\000\000\000\000\162\000\000\000\226\n\186\t~\000\000\000\000\t\130\t\198\000\000\000\000\000\000\000\000\000\000\000\000\000\169\000\000\n^\000\000\nv\000\000\000\000\000\000\000\238\000\000\000\000\000\000\000\000\000\000\t\202\000\169\000\169\t\134\n.\t\206\000\000\nB\nZ\000\000\000\000\011V\000\000\001\022\t\210\001\026\000\000\000\000\000\000\000\000\001^\000\000\000\000\t\166\001\"\000\000\t\170\008B\001.\000\000\t\174\t\178\000\000\t\182\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\154\t\186\000\000\000\000\t\190\000\000\000\000\000\162\000\000\000\226\000\000\t~\000\000\000\000\t\130\t\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n^\000\000\nv\000\000\000\000\000\000\000\238\000\000\000\000\000\000\000\000\000\000\t\202\000\000\000\000\t\134\n.\t\206\000\000\nB\nZ\000\000\000\000\011\002\000\000\001\022\t\210\001\026\000\000\000\000\000\000\000\000\001^\000\000\000\000\t\166\001\"\000\000\t\170\008B\001.\000\000\t\174\t\178\000\000\t\182\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\154\t\186\000\000\000\000\t\190\000\000\000\000\000\162\000\000\000\226\000\000\t~\000\000\000\000\t\130\t\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n^\000\000\nv\000\000\000\000\000\000\000\238\000\000\000\000\000\000\000\000\000\000\t\202\000\000\000\000\t\134\n.\t\206\000\000\nB\nZ\000\000\000\000\004\201\000\000\001\022\t\210\001\026\000\000\000\000\000\000\000\000\001^\000\000\000\000\t\166\001\"\000\000\t\170\008B\001.\000\000\t\174\t\178\000\000\t\182\000\000\000\000\000\000\000\000\001\137\000\000\000\000\001\137\000\000\000\000\000\000\000\000\000\000\000\000\006\154\t\186\000\000\000\000\t\190\000\000\000\000\000\162\001\137\000\000\000\000\000\000\000\000\000\000\000\000\t\198\000\000\001\137\000\000\000\000\000\000\000\000\000\000\001\137\n^\000\000\nv\000\000\000\000\001\137\001\137\000\000\000\000\000\000\000\000\000\000\t\202\000\000\000\000\001\137\007N\t\206\001\137\007\158\001\137\001\137\000\000\001\189\000\000\000\000\t\210\000\000\000\000\000\000\000\000\000\000\001^\000\000\007V\000\000\000\000\000\000\002\017\000\000\001\137\000\000\001\137\002\017\000\000\000\000\000\000\000\000\000\000\007^\000\000\000\000\002\017\002\017\000\000\007\174\007\182\000\000\000\000\000\000\000\000\002\017\000\000\000\000\000\000\007~\000\000\000\000\007f\000\000\007v\002\017\000\000\001\137\001\137\001\138\000\000\001\137\001\137\000\000\000\000\001\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\134\000\000\002\017\001\137\000\000\000\000\001\137\001\137\000\000\001\137\000\000\000\000\002\017\000\000\002J\001\137\001\137\000\000\001\137\001\137\001\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\017\007\142\000\000\000\000\002\017\000\000\000\000\000\000\007n\000\000\000\000\000\000\001%\000\000\000\000\001%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\017\000\000\002\017\000\000\000\000\000\000\000\000\007V\000\000\002\017\002\017\001%\007\190\007\150\002\017\001\013\001%\000\000\001\013\000\000\000\000\000\000\007^\000\000\000\000\001%\001%\000\000\001%\001%\000\000\000\000\000\000\001\013\001%\000\000\000\000\001\013\007~\000\000\000\000\007f\001\013\007v\001%\000\000\000\000\000\000\007^\000\000\000\000\001\013\001\013\000\000\001\013\001\013\000\000\000\000\000\000\000\000\001\013\000\000\000\000\007\134\001\013\001%\000\000\007f\000\000\007v\001\013\000\000\000\000\000\000\000\000\001%\0002\0006\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\017\014\000^\001\013\000b\001\013\000f\000j\000n\000\000\001%\007\142\000\000\000\000\001%\001\013\000\000\000\000\007n\000\000\000\000\000r\017\018\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\019v\001%\000\000\001%\001\013\001\013\000\000\000\000\001\013\000\000\001%\001%\007n\001%\007\150\001%\001\005\000\000\000\000\001\005\000\000\000\130\000\000\000\000\000\000\000\000\017\238\001\013\000\000\001\013\000\000\000:\000\000\000\000\001\005\000\134\001\013\001\013\001\005\001\013\001\013\001\013\001\t\001\005\000\000\001\t\000\000\000\000\000\000\001\005\000\000\000\000\001\005\001\005\000\000\001\005\001\005\000\000\000\000\000\000\001\t\001\005\000\000\000\000\001\t\001\005\000\000\000\000\007f\001\t\001\005\001\005\000\000\000\162\000\000\001\t\000\000\000\000\001\t\001\t\000\000\001\t\001\t\000\000\000\000\000\000\017\"\001\t\000\000\000\000\001\005\001\t\001\005\000\000\007f\000\000\001\t\001\t\000\000\000\000\000\000\000\000\001\005\0002\tR\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\000\000\000^\001\t\000b\001\t\000f\000j\000n\000\000\001\005\001\005\000\000\000\000\001\005\001\t\000\000\000\000\007n\000\000\000\000\000r\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000v\001\005\000\000\001\005\001\t\001\t\000\000\000\000\001\t\000\000\001\005\001\005\007n\001\005\001\005\001\005\001\025\000\000\000\000\001\025\000\000\000\130\000\000\000\000\000\000\000\000\000\000\001\t\000\000\001\t\000\000\000\000\000\000\000\000\007V\000\134\001\t\001\t\001\025\001\t\001\t\001\t\001\017\001\025\000\000\001\017\000\000\000\000\000\000\007^\000\000\000\000\001\025\001\025\000\000\001\025\001\025\000\000\000\000\000\000\007V\001\025\000\000\000\000\001\017\001\025\000\000\000\000\007f\001\017\007v\001\025\000\000\000\162\000\000\007^\000\000\000\000\001\017\001\017\000\000\001\017\001\017\000\000\000\000\000\000\000\000\001\017\000\000\000\000\007\134\001\017\001\025\000\000\007f\000\000\007v\001\017\000\000\000\000\000\000\000\000\001\025\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\017\000\000\001\017\000\000\000\000\000\000\000\000\001\025\001\025\000\000\000\000\001\025\001\017\000\000\000\000\007n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\025\000\000\001\025\001\017\001\017\000\000\000\000\001\017\000\000\001\025\001\025\007n\001\025\001\025\001\025\001\021\000\000\000\000\001\021\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\017\000\000\001\017\000\000\000\000\000\000\000\000\007V\000\000\001\017\001\017\001\021\001\017\001\017\001\017\001\029\001\021\000\000\001\029\000\000\000\000\000\000\007^\000\000\000\000\001\021\001\021\000\000\001\021\001\021\000\000\000\000\000\000\007V\001\021\000\000\000\000\001\029\001\021\000\000\000\000\007f\001\029\007v\001\021\000\000\000\000\000\000\007^\000\000\000\000\001\029\001\029\000\000\001\029\001\029\000\000\000\000\000\000\000\000\001\029\000\000\000\000\007\134\007~\001\021\000\000\007f\000\000\007v\001\029\000\000\000\000\000\000\000\000\001\021\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\134\000\000\001\029\000\000\000\000\000\000\000\000\001\021\001\021\000\000\000\000\001\021\001\029\000\000\000\000\007n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\021\000\000\001\021\001\029\007\142\000\000\000\000\001\029\000\000\001\021\001\021\007n\001\021\001\021\001\021\007N\000\000\000\000\001-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\029\000\000\001\029\000\000\000\000\000\000\000\000\007V\000\000\001\029\001\029\001-\001\029\001\029\001\029\007N\001-\000\000\001!\000\000\000\000\000\000\007^\000\000\000\000\001-\001-\000\000\001-\007\182\000\000\000\000\000\000\007V\001-\000\000\000\000\001!\007~\000\000\000\000\007f\001!\007v\001-\000\000\000\000\000\000\007^\000\000\000\000\001!\001!\000\000\001!\001!\000\000\000\000\000\000\000\000\001!\000\000\000\000\007\134\007~\001-\000\000\007f\000\000\007v\001!\000\000\000\000\000\000\000\000\001-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\134\000\000\001!\000\000\000\000\000\000\000\000\001-\007\142\000\000\000\000\001-\001!\000\000\000\000\007n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001-\000\000\001-\001!\007\142\000\000\000\000\001!\000\000\001-\001-\007n\007\190\007\150\001-\007N\000\000\000\000\001)\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001!\000\000\001!\000\000\000\000\000\000\000\000\007V\000\000\001!\001!\001)\001!\007\150\001!\000\000\001)\000\000\000\000\000\226\000\000\t~\007^\000\000\t\130\001)\001)\000\000\001)\007\182\000\000\000\000\000\000\000\000\001)\000\000\000\000\000\000\007~\000\000\000\238\007f\000\000\007v\001)\000\000\000\000\000\000\000\000\t\134\n.\000\000\000\000\nB\nZ\000\000\000\000\000\000\000\000\001\022\000\000\001\026\000\000\007\134\000\000\001)\000\000\000\000\000\000\t\166\001\"\000\000\t\170\008B\001.\001)\t\174\t\178\000\000\t\182\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\154\t\186\001)\007\142\t\190\000\000\001)\000\162\000\000\000\000\007n\000\000\000\000\000\000\000\000\t\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001)\nv\001)\000\226\000\000\000\230\000\000\000\000\000\234\001)\001)\t\202\001)\007\150\001)\000\000\t\206\000\000\007\218\000\000\000\000\000\000\001\201\000\000\000\238\t\210\000\000\000\242\000\000\000\000\000\000\001^\000\000\001\002\001\006\000\000\001\014\000\000\tz\000\000\000\000\000\000\000\000\001\022\000\000\001\026\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\030\001\"\000\000\001&\001*\001.\000\000\0012\0016\000\000\001:\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001>\000\000\000\000\001B\000\000\000\000\000\162\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001J\000\000\000\000\000\226\000\000\000\230\000\000\000\000\000\234\001N\007\229\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\229\000\000\000\000\001R\000\000\000\000\000\238\000\000\001V\000\242\000\000\007\229\000\000\007\229\000\000\001\002\001\006\001Z\001\014\000\000\000\000\000\000\000\000\001^\000\000\001\022\000\000\001\026\000\000\000\000\000\000\000\000\000\226\000\000\000\230\001\030\001\"\000\234\001&\001*\001.\000\000\0012\0016\000\000\001:\000\000\014V\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\242\000\000\000\000\000\000\000\000\001>\001\002\001\006\001B\001\014\000\000\000\162\000\000\000\000\000\000\000\000\001\022\000\000\001\026\001J\000\000\000\000\000\000\000\000\000\000\000\000\001\030\001\"\001N\001&\001*\001.\000\000\0012\0016\000\000\001:\000\000\000\000\000\000\001R\000\000\000\000\000\000\000\000\001V\000\000\000\000\000\000\000\000\000\000\000\000\001>\000\000\001Z\001B\000\000\000\000\000\162\000\000\001^\000\000\000\000\000\000\000\000\000\000\001J\000\000\000\000\000\226\000\000\000\230\000\000\000\000\000\234\001N\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001R\000\000\000\000\000\238\000\000\001V\000\242\000\000\000\000\000\000\000\000\000\000\001\002\004\182\001Z\001\014\000\000\000\000\000\000\000\000\001^\000\000\001\022\000\000\001\026\000\000\000\000\000\000\000\000\000\226\000\000\000\230\001\030\001\"\000\234\001&\001*\001.\000\000\0012\0016\000\000\001:\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\242\000\000\000\000\000\000\000\000\001>\001\002\001F\001B\001\014\000\000\000\162\000\000\000\000\000\000\000\000\001\022\000\000\001\026\001J\000\000\000\000\000\000\000\000\000\000\000\000\001\030\001\"\001N\001&\001*\001.\000\000\0012\0016\000\000\001:\000\000\000\000\000\000\001R\000\000\000\000\000\000\000\000\001V\000\000\000\000\000\000\000\000\000\000\000\000\001>\000\000\001Z\001B\000\000\000\000\000\162\000\000\001^\000\000\000\000\000\000\003\158\000\000\001J\000\000\000\000\003A\000\000\003A\000\000\000\000\003A\001N\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001R\000\000\000\000\003A\000\000\001V\003A\000\000\000\000\000\000\000\000\000\000\003A\003A\001Z\003A\000\000\000\000\000\000\000\000\001^\000\000\003A\000\000\003A\000\000\000\226\000\000\000\246\000\000\000\000\000\250\003A\003A\000\000\003A\003A\003A\000\000\003A\003A\000\000\003A\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\242\000\000\000\000\000\000\000\000\000\000\000\254\001\018\003A\001\014\000\000\003A\000\000\000\000\003A\000\000\001\022\000\000\001\026\000\000\000\000\000\000\003A\000\000\000\000\000\000\002\234\001\"\000\000\002\238\001*\001.\000\000\002\242\002\246\000\000\002\250\000\000\000\000\000\000\000\226\000\000\000\246\003A\000\000\000\250\000\000\000\000\003A\000\000\000\000\000\000\002\254\000\000\000\000\003\002\000\000\003A\000\162\000\000\000\000\000\238\000\000\003A\000\242\000\000\003\n\000\000\000\000\000\000\000\254\004\158\000\000\001\014\000\000\000\000\000\000\000\000\000\000\000\000\001\022\000\000\001\026\000\000\000\226\000\000\000\246\003\014\000\000\000\250\002\234\001\"\003\018\002\238\001*\001.\000\000\002\242\002\246\000\000\002\250\003\022\000\000\000\000\000\000\000\238\000\000\001^\000\242\000\000\000\000\000\000\000\000\000\000\000\254\003\006\002\254\001\014\000\000\003\002\000\000\000\000\000\162\000\000\001\022\000\000\001\026\000\000\000\000\000\000\003\n\000\000\000\000\000\000\002\234\001\"\000\000\002\238\001*\001.\000\000\002\242\002\246\000\000\002\250\000\000\000\000\000\000\000\226\000\000\006f\003\014\000\000\006j\000\000\000\000\003\018\000\000\000\000\000\000\002\254\000\000\000\000\003\002\000\000\003\022\000\162\000\000\000\000\000\238\000\000\001^\000\000\000\000\003\n\000\000\000\000\000\000\006n\007\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\022\000\000\001\026\000\000\000\000\000\000\000\000\003\014\000\000\000\000\006\134\001\"\003\018\006\138\001*\001.\000\000\006\142\006\146\000\000\006\150\003\022\000\000\000\000\000\226\000\000\006f\001^\000\000\006j\000\000\000\000\000\000\000\000\000\000\006\154\006\158\000\000\000\000\006\162\000\000\000\000\000\162\000\000\000\000\000\238\000\000\000\000\000\000\000\000\006\170\000\000\000\000\000\000\006n\006r\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\022\000\000\001\026\000\000\000\000\000\000\000\000\006\174\000\000\000\000\006\134\001\"\006\178\006\138\001*\001.\000\000\006\142\006\146\000\000\006\150\006\182\000\000\000\000\000\226\000\000\006f\001^\000\000\006j\000\000\000\000\000\000\000\000\000\000\006\154\006\158\000\000\000\000\006\162\000\000\000\000\000\162\000\000\000\000\000\238\000\000\000\000\000\000\000\000\006\170\000\000\000\000\000\000\006n\006\166\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\022\000\000\001\026\000\000\000\000\000\000\000\000\006\174\000\000\000\000\006\134\001\"\006\178\006\138\001*\001.\000\000\006\142\006\146\000\000\006\150\006\182\000\000\000\000\000\226\000\000\t~\001^\000\000\t\130\000\000\000\000\000\000\000\000\000\000\006\154\006\158\000\000\000\000\006\162\000\000\000\000\000\162\000\000\000\000\000\238\000\000\000\000\000\000\000\000\006\170\000\000\000\000\000\000\t\134\t\146\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\022\000\000\001\026\000\000\000\000\000\000\000\000\006\174\000\000\000\000\t\166\001\"\006\178\t\170\001*\001.\000\000\t\174\t\178\000\000\t\182\006\182\000\000\000\000\000\226\000\000\t~\001^\000\000\t\130\000\000\000\000\000\000\000\000\000\000\006\154\t\186\000\000\000\000\t\190\000\000\000\000\000\162\000\000\000\000\000\238\000\000\000\000\000\000\000\000\t\198\000\000\000\000\000\000\t\134\t\194\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\022\000\000\001\026\000\000\000\000\000\000\000\000\t\202\000\000\000\000\t\166\001\"\t\206\t\170\001*\001.\000\000\t\174\t\178\000\000\t\182\t\210\000\000\000\000\000\226\000\000\t~\001^\000\000\t\130\000\000\000\000\000\000\000\000\000\000\006\154\t\186\000\000\000\000\t\190\000\000\000\000\000\162\000\000\000\000\000\238\000\000\000\000\000\000\000\000\t\198\000\000\000\000\000\000\t\134\n.\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\022\000\000\001\026\000\000\000\000\000\000\000\000\t\202\000\000\000\000\t\166\001\"\t\206\t\170\001*\001.\000\000\t\174\t\178\000\000\t\182\t\210\000\000\000\000\000\000\000\000\000\000\001^\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\154\t\186\000\000\000\000\t\190\000\000\000\000\000\162\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\198\0002\005\250\000F\000J\006\018\000N\006*\000R\000V\006.\000Z\000\000\000^\000\000\000b\0062\000f\000j\000n\0066\t\202\000\000\000\000\000\000\000\000\t\206\000\000\000\000\000\000\000\000\000\000\000r\000\000\000\000\t\210\000\000\000\000\000\000\000\000\000\000\001^\000\000\000v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\130\000\000\000\000\0002\tR\000F\000J\000\000\000N\006*\000R\000V\006.\000Z\000\134\000^\020v\000b\0062\000f\000j\000n\0066\020~\001\153\000\000\000\000\001\153\000\000\008F\000\000\000\000\000\000\000\000\000r\000\000\000\000\000\000\007Q\000\000\000\000\000\000\001\153\000\000\000\000\000v\001\153\000\000\000\000\000\000\000\000\000\000\000\162\000\000\000\000\000\000\000\000\001\153\000\000\007Q\000\000\001\153\000\000\001\153\001\153\000\000\000\130\000\000\000\000\007Q\007Q\000\000\000\000\001\153\000\000\007Q\001\153\000\000\001\153\tB\000\134\000\000\0055\000\000\000\000\0055\000\000\000\000\000\000\0055\000\000\0055\000\000\000\000\007Q\0055\0055\000\000\001\153\000\000\000:\000\000\000\000\007Q\007Q\000\000\000\000\000\000\000\000\000\000\001\153\007Q\000\000\000\000\007Q\007Q\000\000\000\000\000\162\000\000\000\000\000\000\003\161\000\000\007Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\153\003z\007Q\001\153\000\000\000\000\000\000\001\153\0055\000\000\007Q\000\000\000\000\000\000\000\000\000\000\000\000\000\146\000\000\001\153\007Q\000\000\000\000\007Q\001\153\001\153\000\000\000\000\007Q\000\000\003\130\007Q\007Q\000\000\001\153\001\153\001\153\000\000\000\000\000\000\000\000\007Q\000\000\007Q\000\000\000\000\007Q\007Q\003\210\000\000\007Q\004\"\000\000\000\000\000\000\007Q\007Q\000\000\000\000\007Q\007Q\000\000\000\000\0055\000\000\000\000\003\218\000\000\000\000\000\000\002\t\000\000\007Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\226\000\000\000\000\000\000\002\t\000\000\0042\004:\000\000\000\237\000\000\007Q\000\237\000\000\007Q\007Q\004\002\000\213\000\000\003\234\000\213\003\250\000\000\007Q\007Q\000\000\000\000\003\218\007Q\000\000\000\000\000\237\000\000\000\000\000\000\000\213\000\000\000\000\000\000\000\213\000\000\004\n\003\226\000\000\000\000\000\000\000\237\000\000\000\237\000\237\003\226\000\000\000\000\002\t\000\213\000\000\000\213\000\213\004\002\000\000\000\000\003\234\000\000\003\250\000\000\000\000\000\213\000\000\000\000\003\234\000\000\003\250\000\000\000\000\000\000\004\018\000\000\000\000\002\t\000\000\000\000\000\000\003\242\004\n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\213\000\000\000\000\002\t\000\237\000\000\000\000\000\000\002\t\002\t\000\000\000\000\000\213\000\000\000\000\000\000\000\000\000\000\004B\004\026\002\t\000\000\000\000\000\000\000\000\000\000\004\018\000\000\000\000\000\237\000\000\000\000\000\000\003\242\000\213\000\000\000\000\000\213\000\000\000\000\000\000\003\242\000\000\000\000\000\000\000\237\000\000\000\000\000\000\000\205\000\237\000\237\000\205\000\213\000\000\000\000\000\000\000\000\000\213\000\213\000\237\004\026\000\237\000\000\000\000\000\000\000\000\000\205\000\213\000\213\000\213\000\205\000\209\000\000\000\000\000\209\000\000\000\000\000\000\000\000\000\000\000\000\000\205\000\000\000\000\000\000\000\205\000\000\000\205\000\205\000\209\000\000\000\000\000\000\000\209\000\000\000\000\000\000\000\205\000\000\000\000\003\234\000\000\000\205\000\000\000\209\000\000\000\000\000\000\000\209\000\000\000\209\000\209\000\000\000\225\000\000\000\000\000\225\000\000\000\000\000\000\000\209\000\000\000\205\003\234\000\000\000\209\000\000\000\000\000\000\000\000\000\000\003\218\000\000\000\000\000\205\000\225\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\209\003\226\000\000\000\000\000\000\000\225\000\000\000\225\000\225\000\000\000\000\000\205\000\209\000\000\000\205\000\000\000\000\000\225\003\242\000\000\003\234\000\000\003\250\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\205\000\000\000\000\000\000\000\209\000\205\000\205\000\209\000\000\000\000\000\000\003\242\004\n\000\000\000\000\000\205\000\205\000\205\000\000\000\000\000\000\000\000\000\000\000\209\000\225\000\000\000\000\000\000\000\209\000\209\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\209\000\209\000\209\000\000\000\000\000\000\000\000\000\000\000\225\000\000\000\000\000\225\000\000\000\217\000\000\003\242\000\217\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\225\000\000\000\000\000\000\003\218\000\225\000\225\000\000\000\217\000\221\000\000\000\000\000\221\000\000\000\000\000\225\000\225\000\225\000\000\003\226\000\000\000\000\000\000\000\217\000\000\000\217\000\217\003\218\000\000\000\000\000\000\000\221\000\000\000\000\000\000\000\217\000\000\000\000\003\234\000\000\003\250\000\000\003\226\000\000\000\000\000\000\000\221\000\000\000\221\000\221\000\000\000\229\000\000\000\000\000\229\000\000\000\000\000\000\000\221\000\000\000\217\003\234\000\000\003\250\000\000\000\000\000\000\000\000\000\000\003\218\000\000\000\000\000\217\000\229\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\n\003\226\000\000\000\000\000\000\000\229\000\000\000\229\000\229\000\000\000\000\000\217\000\221\000\000\000\217\000\000\000\000\004\002\003\242\000\000\003\234\000\000\003\250\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\217\000\000\000\000\000\000\000\221\000\217\000\217\000\221\000\000\000\000\000\000\003\242\004\n\000\000\000\000\000\217\000\217\000\217\000\000\000\000\000\000\000\000\000\000\000\221\000\229\000\000\000\000\000\000\000\221\000\221\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\221\000\221\000\221\000\000\000\000\000\000\000\000\000\000\004\018\000\000\000\000\000\229\000\000\003\210\000\000\003\242\000\245\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\229\000\000\000\000\000\000\003\218\000\229\000\229\000\000\000\245\003\210\000\000\000\000\000\233\000\000\000\000\000\229\000\229\000\229\000\000\003\226\000\000\000\000\000\000\000\245\000\000\000\245\004:\003\218\000\000\000\000\000\000\000\233\000\000\000\000\000\000\004\002\000\000\000\000\003\234\000\000\003\250\000\000\003\226\000\000\000\000\000\000\000\233\000\000\000\233\000\233\000\000\003\210\000\000\000\000\000\241\000\000\000\000\000\000\004\002\000\000\004\n\003\234\000\000\003\250\000\000\000\000\000\000\000\000\000\000\003\218\000\000\000\000\000\245\000\241\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\n\003\226\000\000\000\000\000\000\000\241\000\000\000\241\004:\000\000\000\000\004\018\000\233\000\000\000\245\000\000\000\000\004\002\003\242\000\000\003\234\000\000\003\250\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\245\000\000\000\000\000\000\004\018\000\245\000\245\000\233\000\000\000\000\000\000\003\242\004\n\000\000\000\000\004B\004\026\000\245\003\153\000\000\000\000\003\153\000\000\000\233\000\241\003\153\000\000\003\153\000\233\000\233\000\000\003\153\003\153\000\000\000\000\000\000\000\000\000\000\000\233\004\026\000\233\000\000\000\000\000\000\000\000\000\000\004\018\000\000\000\000\000\241\000\000\000\000\000\000\003\242\000\000\000\000\000\000\000\000\000\000\000\000\002-\000\000\000\000\000\000\000\000\000\241\000\000\000\000\000\000\000\000\000\241\000\241\000\000\000\000\000\000\000\000\003\153\000\000\000\000\000\000\000\241\004\026\000\241\000\000\000\000\000\000\000\000\000\000\002-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002-\000\000\000\000\002-\002-\000\000\000\000\000\000\000\000\003Q\003Q\003Q\003Q\002-\003Q\000\000\003Q\003Q\000\000\003Q\000\000\003Q\000\000\003Q\000\000\003Q\003Q\003Q\000\000\000\000\000\000\002-\000\000\000\000\000\000\003\153\000\000\000\170\000\000\000\000\003Q\020z\000F\000J\002-\000N\006*\000R\000V\006.\000Z\003Q\000^\020v\000b\0062\000f\000\000\000n\0066\020~\000\000\000\000\000\000\002-\000\000\000\000\002-\002-\000\000\000\000\000r\003Q\000\000\000\000\000\000\002-\002-\003Q\000\000\000\000\002-\000v\000\000\000\000\000\000\003Q\000\000\0002\000\142\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\000\000\000^\000\000\000b\000\000\000f\000j\000n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\134\000\000\000r\000\000\000\000\000\000\000\000\003Q\000\000\000\000\000\000\000\000\000\000\000v\0002\000\142\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\000\000\000^\000\000\000b\000\000\000f\000j\000n\000\000\000\130\000\000\000\000\000\000\000\000\000\000\000\158\000\000\003\161\000\000\000\000\000r\000\000\003Q\000\134\000\000\0002\005\002\000F\000J\000\000\000N\000v\000R\000V\000\000\000Z\000\000\000^\000\000\000b\000\000\000f\000j\000n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\130\000\000\000\000\000\000\000r\000\000\000\158\000\000\000\000\000\162\000\000\000\000\000\000\000\000\000\134\000v\000\000\0002\005\002\000F\000J\000\000\000N\000\000\000R\000V\000\166\000Z\000\000\000^\000\000\000b\000\000\000f\000j\000n\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000r\n\249\000\134\000\000\000\162\000\000\005\006\005\n\000\000\011\129\000\000\000v\0002\000\142\000F\000J\000\000\000N\000\000\000R\000V\000\166\000Z\000\000\000^\000\000\000b\011\129\000f\000j\000n\000\000\000\130\000\000\000\000\t\230\000\000\000\000\000\000\000\000\000\000\000\000\011\129\000r\002)\000\000\000\134\000\000\011\129\011\129\005\006\005\n\t\238\000\000\000v\t\250\000\000\005\014\011\129\000\000\000\000\011\129\000\000\011\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\130\000\000\000\000\000\000\000\000\000\000\000\158\000\000\011\129\000\000\000\000\000\000\000\000\000\000\000\134\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\006\005\022\0002\005\002\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\000\000\000^\000\000\000b\011\129\000f\000j\000n\000\000\n\n\000\000\011\129\000\000\000\000\000\162\000\000\000\000\000\000\000\000\n\018\000r\000\000\000\000\011\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000v\000\000\000\000\000\000\000\000\000\000\000\000\011\129\011\129\000\000\0002\005\002\000F\000J\000\161\000N\000\000\000R\000V\000\000\000Z\000\130\000^\002!\000b\000\165\000f\000j\000n\000\000\000\000\000\000\n\162\000\000\000\000\000\134\000\000\000\000\000\000\021\022\005\n\000r\000\000\n\162\000\000\000\000\000\000\n\170\000\000\000\000\000\000\000\000\000v\000\161\000\161\000\000\000\000\000\000\n\170\000\000\000\000\000\000\000\173\000\161\000\165\000\165\n\178\000\000\n\194\000\000\000\000\000\000\000\000\000\130\000\165\000\000\000\000\n\178\000\000\n\194\n\162\000\000\000\000\000\000\000\000\n\154\000\000\000\134\000\161\000\000\021\026\021\022\005\n\000\000\000\000\n\170\000\000\000\000\000\000\n\210\000\000\000\173\000\173\n\162\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\202\000\000\000\000\n\178\000\000\n\194\000\000\n\170\000\000\000\000\000\000\000\161\000\000\000\189\n\242\000\000\000\000\000\000\n\186\000\000\000\000\n\154\000\165\n\202\000\000\n\210\n\178\000\000\n\194\n\186\000\161\021\"\n\154\000\000\000\000\000\000\000\000\000\000\000\000\n\162\000\000\000\165\000\000\000\000\000\000\000\161\000\161\000\000\n\210\000\000\n\162\000\000\000\000\000\000\n\170\000\000\000\165\000\165\000\000\n\218\000\177\000\177\000\000\000\000\000\000\n\170\n\186\000\000\000\000\000\000\n\202\000\185\n\242\n\178\000\000\n\194\000\000\000\000\000\173\000\000\000\000\n\202\n\218\000\000\n\178\000\000\n\194\000\000\000\000\n\186\000\000\000\000\000\000\000\173\000\173\n\210\000\000\000\000\000\000\000\000\000\000\000\189\000\000\000\000\000\000\000\000\n\210\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\250\n\226\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\218\000\000\000\000\000\000\000\000\000\000\000\000\n\186\000\000\000\000\000\000\n\218\000\000\000\000\000\000\000\000\000\000\000\000\n\186\000\177\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\185\000\000\000\000\000\000\000\177\n\226\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\185\n\226"))
let lhs =
- (16, "\000\012\000\011\000\n\000\t\000\008\000\007\000\006\000\005\000\004\000\003\000\002\000\001\000\000\001\005\001\005\001\005\001\004\001\004\001\004\001\004\001\003\001\003\001\003\001\003\001\003\001\003\001\003\001\003\001\003\001\003\001\003\001\003\001\003\001\003\001\002\001\002\001\002\001\002\001\002\001\002\001\002\001\002\001\002\001\002\001\002\001\002\001\002\001\002\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\000\255\000\255\000\255\000\255\000\254\000\253\000\253\000\253\000\252\000\252\000\252\000\251\000\251\000\251\000\250\000\250\000\250\000\249\000\248\000\247\000\246\000\246\000\245\000\245\000\244\000\244\000\243\000\243\000\242\000\242\000\241\000\240\000\240\000\239\000\239\000\238\000\238\000\238\000\237\000\237\000\236\000\235\000\234\000\233\000\232\000\231\000\230\000\229\000\228\000\227\000\226\000\225\000\224\000\224\000\223\000\223\000\222\000\222\000\221\000\221\000\220\000\220\000\220\000\219\000\219\000\219\000\219\000\219\000\218\000\218\000\217\000\216\000\216\000\216\000\216\000\215\000\215\000\214\000\213\000\212\000\212\000\212\000\211\000\211\000\211\000\210\000\210\000\210\000\210\000\209\000\209\000\209\000\209\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\207\000\206\000\206\000\205\000\205\000\205\000\204\000\204\000\203\000\203\000\203\000\202\000\202\000\201\000\200\000\199\000\199\000\198\000\198\000\197\000\197\000\196\000\196\000\195\000\195\000\194\000\193\000\192\000\192\000\191\000\191\000\190\000\189\000\189\000\189\000\189\000\188\000\187\000\186\000\186\000\185\000\184\000\184\000\183\000\183\000\183\000\183\000\183\000\182\000\182\000\182\000\182\000\181\000\181\000\181\000\181\000\180\000\180\000\180\000\180\000\179\000\178\000\178\000\177\000\177\000\177\000\176\000\175\000\175\000\175\000\175\000\174\000\173\000\173\000\173\000\173\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\171\000\171\000\170\000\170\000\169\000\169\000\168\000\168\000\167\000\167\000\167\000\167\000\166\000\166\000\166\000\165\000\165\000\165\000\165\000\165\000\165\000\165\000\164\000\163\000\163\000\163\000\162\000\161\000\161\000\160\000\160\000\159\000\159\000\158\000\158\000\157\000\157\000\156\000\156\000\155\000\155\000\155\000\155\000\155\000\155\000\155\000\154\000\153\000\152\000\152\000\151\000\151\000\150\000\150\000\149\000\149\000\148\000\148\000\147\000\147\000\146\000\146\000\145\000\145\000\144\000\144\000\143\000\143\000\142\000\142\000\141\000\141\000\140\000\140\000\139\000\139\000\138\000\138\000\137\000\137\000\136\000\136\000\135\000\135\000\134\000\134\000\133\000\133\000\132\000\132\000\131\000\131\000\130\000\130\000\129\000\129\000\128\000\128\000\127\000\127\000~\000~\000}\000}\000|\000|\000{\000{\000z\000z\000y\000y\000x\000w\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000u\000t\000s\000r\000q\000p\000o\000n\000m\000l\000l\000l\000k\000k\000k\000j\000j\000j\000j\000i\000h\000g\000f\000e\000d\000c\000c\000c\000b\000b\000b\000a\000a\000`\000`\000`\000_\000_\000^\000]\000]\000]\000\\\000[\000[\000Z\000Z\000Y\000Y\000X\000X\000W\000W\000V\000V\000U\000U\000T\000T\000T\000T\000T\000T\000T\000T\000T\000T\000T\000T\000T\000T\000T\000T\000T\000T\000T\000S\000S\000R\000R\000Q\000Q\000P\000P\000O\000O\000O\000O\000O\000N\000N\000M\000M\000M\000M\000L\000K\000J\000J\000J\000I\000I\000I\000H\000H\000H\000H\000H\000H\000G\000G\000G\000G\000G\000F\000F\000F\000F\000F\000F\000F\000E\000E\000E\000E\000E\000E\000E\000D\000D\000D\000D\000D\000D\000D\000C\000C\000C\000C\000C\000C\000C\000B\000B\000B\000B\000B\000B\000B\000B\000B\000B\000B\000B\000B\000A\000A\000A\000A\000A\000A\000A\000A\000A\000A\000A\000A\000A\000@\000@\000@\000@\000@\000@\000@\000@\000@\000@\000@\000@\000@\000?\000?\000?\000?\000?\000?\000?\000?\000?\000?\000?\000?\000?\000>\000>\000>\000>\000>\000=\000<\000<\000<\000<\000<\000;\000:\0009\0008\0007\0006\0006\0006\0006\0006\0006\0006\0005\0005\0005\0004\0003\0003\0002\0002\0001\0001\0000\0000\000/\000/\000.\000.\000-\000-\000,\000,\000+\000+\000*\000*\000)\000)\000(\000(\000'\000'\000&\000&\000%\000%\000%\000%\000%\000%\000%\000%\000%\000%\000%\000%\000%\000%\000%\000%\000%\000$\000$\000$\000#\000#\000#\000#\000\"\000\"\000\"\000\"\000\"\000!\000 \000 \000 \000\031\000\031\000\030\000\029\000\028\000\028\000\028\000\028\000\027\000\027\000\027\000\026\000\026\000\025\000\025\000\025\000\024\000\024\000\024\000\023\000\023\000\023\000\022\000\022\000\021\000\021\000\021\000\021\000\021\000\021\000\021\000\020\000\020\000\020\000\020\000\020\000\020\000\020\000\019\000\019\000\019\000\019\000\019\000\019\000\019\000\018\000\018\000\018\000\018\000\018\000\018\000\018\000\017\000\017\000\017\000\017\000\017\000\016\000\016\000\015\000\014\000\013\000\013\000\013\000\013\000\013")
+ (16, "\000\012\000\011\000\n\000\t\000\008\000\007\000\006\000\005\000\004\000\003\000\002\000\001\000\000\001\003\001\003\001\003\001\002\001\002\001\002\001\002\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\000\255\000\255\000\255\000\255\000\255\000\255\000\255\000\255\000\255\000\255\000\255\000\255\000\255\000\255\000\254\000\254\000\254\000\254\000\254\000\254\000\254\000\254\000\254\000\254\000\254\000\254\000\254\000\254\000\253\000\253\000\253\000\253\000\252\000\251\000\251\000\251\000\250\000\250\000\250\000\249\000\249\000\249\000\248\000\248\000\248\000\247\000\246\000\245\000\244\000\244\000\243\000\243\000\242\000\242\000\241\000\241\000\240\000\240\000\239\000\238\000\238\000\237\000\237\000\236\000\236\000\236\000\235\000\235\000\234\000\233\000\232\000\231\000\230\000\229\000\228\000\227\000\226\000\225\000\224\000\223\000\222\000\222\000\221\000\221\000\220\000\220\000\219\000\219\000\218\000\218\000\218\000\217\000\217\000\217\000\217\000\217\000\216\000\216\000\215\000\214\000\214\000\214\000\214\000\213\000\213\000\212\000\211\000\210\000\210\000\210\000\209\000\209\000\209\000\208\000\208\000\208\000\208\000\207\000\207\000\207\000\207\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\205\000\204\000\204\000\203\000\203\000\203\000\202\000\202\000\201\000\201\000\201\000\200\000\200\000\199\000\198\000\197\000\197\000\196\000\196\000\195\000\195\000\194\000\194\000\193\000\193\000\192\000\191\000\190\000\190\000\189\000\189\000\188\000\187\000\187\000\187\000\187\000\186\000\185\000\184\000\184\000\183\000\182\000\182\000\181\000\181\000\181\000\181\000\181\000\180\000\180\000\180\000\180\000\179\000\179\000\179\000\179\000\178\000\178\000\178\000\178\000\177\000\176\000\176\000\175\000\175\000\175\000\174\000\173\000\173\000\173\000\173\000\172\000\171\000\171\000\171\000\171\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\169\000\169\000\168\000\168\000\167\000\167\000\166\000\166\000\165\000\165\000\165\000\165\000\164\000\164\000\164\000\163\000\163\000\163\000\163\000\163\000\163\000\163\000\162\000\161\000\161\000\161\000\160\000\159\000\159\000\158\000\158\000\157\000\157\000\156\000\156\000\155\000\155\000\154\000\154\000\153\000\153\000\153\000\153\000\153\000\153\000\153\000\152\000\151\000\150\000\150\000\149\000\149\000\148\000\148\000\147\000\147\000\146\000\146\000\145\000\145\000\144\000\144\000\143\000\143\000\142\000\142\000\141\000\141\000\140\000\140\000\139\000\139\000\138\000\138\000\137\000\137\000\136\000\136\000\135\000\135\000\134\000\134\000\133\000\133\000\132\000\132\000\131\000\131\000\130\000\130\000\129\000\129\000\128\000\128\000\127\000\127\000~\000~\000}\000}\000|\000|\000{\000{\000z\000z\000y\000y\000x\000x\000w\000w\000v\000u\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000s\000r\000q\000p\000o\000n\000m\000l\000k\000j\000j\000j\000i\000i\000i\000h\000h\000h\000h\000g\000f\000e\000d\000c\000b\000a\000a\000a\000`\000`\000`\000_\000_\000^\000^\000^\000]\000]\000\\\000[\000[\000[\000Z\000Y\000Y\000X\000X\000W\000W\000V\000V\000U\000U\000T\000T\000S\000S\000R\000R\000R\000R\000R\000R\000R\000R\000R\000R\000R\000R\000R\000R\000R\000R\000R\000R\000R\000Q\000Q\000P\000P\000O\000O\000N\000N\000N\000N\000N\000M\000M\000L\000L\000L\000L\000K\000J\000I\000I\000I\000H\000H\000H\000G\000G\000G\000G\000G\000G\000F\000F\000F\000F\000F\000E\000E\000E\000E\000E\000E\000E\000D\000D\000D\000D\000D\000D\000D\000C\000C\000C\000C\000C\000C\000C\000B\000B\000B\000B\000B\000B\000B\000A\000A\000A\000A\000A\000A\000A\000A\000A\000A\000A\000A\000A\000@\000@\000@\000@\000@\000@\000@\000@\000@\000@\000@\000@\000@\000?\000?\000?\000?\000?\000?\000?\000?\000?\000?\000?\000?\000?\000>\000>\000>\000>\000>\000>\000>\000>\000>\000>\000>\000>\000>\000=\000=\000=\000=\000=\000<\000;\000;\000;\000;\000;\000:\0009\0008\0007\0006\0005\0005\0005\0005\0005\0005\0005\0004\0004\0004\0003\0002\0002\0001\0001\0000\0000\000/\000/\000.\000.\000-\000-\000,\000,\000+\000+\000*\000*\000)\000)\000(\000(\000'\000'\000&\000&\000%\000%\000$\000$\000$\000$\000$\000$\000$\000$\000$\000$\000$\000$\000$\000$\000$\000$\000$\000#\000#\000#\000\"\000\"\000\"\000\"\000!\000!\000!\000!\000!\000 \000\031\000\031\000\031\000\030\000\030\000\029\000\028\000\027\000\027\000\027\000\027\000\026\000\026\000\026\000\025\000\025\000\024\000\024\000\024\000\023\000\023\000\023\000\022\000\022\000\022\000\021\000\021\000\020\000\020\000\020\000\020\000\020\000\020\000\020\000\019\000\019\000\019\000\019\000\019\000\019\000\019\000\018\000\018\000\018\000\018\000\018\000\018\000\018\000\017\000\017\000\017\000\017\000\017\000\017\000\017\000\016\000\016\000\016\000\016\000\016\000\015\000\015\000\014\000\013\000\013\000\013\000\013\000\013")
let goto =
- ((16, "\000\209\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\249\000\000\001/\008\000\000\000\000g\000a\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\188\000\000\002J\000g\000a\000\000\000\000\000\000\000\000\000\000\000\000\001t\000$\006B\000\000\000\000\000\000\t\216\000\000\000\017\000\000\000\000\001\027\002\208\000\000\000\000\000\029\000\000\000\184\000\0001\020\004p\018\252$`\000\188\000\000\000\012\000\000\000\150\t\212\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003`\018\252\000\000\000\000\017t\000\000\019n\000\000\0210\000\000\000\000\000\000\000\000\000\202\000\000\031\238\000\000\000\000\020\222\000\000\027\232\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018$\000\000\000\000\022\232\000\0006v\000\0007\008\000\0007>\000\0007V\000\0007|\000\0007\158\000\0007\252\000\0008\026\000\000)\178\000\000)\180\000\000\000\000\000\000\000\000\000\0008\030\000\00088\000\0008\\\000\000$\228\000\000\000\0005\176\000\000\000I\000a\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\184\000\194\000\000\001\162\000\000\000\000$v\000\0001f\000\000\000\000\000\000\0010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000k2\008\000\000\001N\000\000\000\000%8\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003,%8\000\000\004\172\000\000\n\196\021\178\000\000\000\000\000\000\001\152\000\000 |\000\000\000\0002 \000\000\000\000\000\000\001\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000%R\000\000\000\130\000\000\000\000\000\0005\208\000\00060\000\000\000\000\000\000\000\000\000;\000\000\000\0002\136\000\000\000\000\000\000\nx\0018\000\000\000\000\000\000\000\000\000\000\000\000\000&\000\000\012\018\000\000\",\000\000%.\000\000'r\000\000*\000\000\000,v\000\0003,\000\0003\174\000\0007\234\000\000+^\000\000\0166\000\0007\250\000\0008\n\000\0008~\000\000\000\000\000\000\000\000\000\000\000K\t*\000\000\003\028\000\000\000\000\000\000\014\244\000\000\000\000\000\000\013\138\000\000\000\000%\232\000\000\000\000\000\000\000\000\000\000\000\000\000\191\000\000\000\000\000\000\001\206\000\000\000\000\000\000\001\014\000\000\000\000\005|\000g\000\000\000\000\000\240\002\206\000\000\000\000\000\000\000\000\000\000\002\238\000\000\005\226\000\000\001\134\000\000\000\000\003\136\000\000\000\000\000\000\000\000\000\000\000\000\007\238\000\000\000\000\000\000\002\238\000\000\000\000\000\000\000\000\019\184(H\000\000\001F\000\000\000\000\004\192\004\136\000\000\000\000\000\000\000\000\012t\000\000\000\000\000\000\000\000\000\000\000\000\001\007\012\138\000\000\014\240\000\000\000\000\000\000\000\169\000\000\012\152\000g\000\000\023\190\000\000\000\000\000\000\017x\001\214\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\158\000\000&\220\000\0002\182\000\000\000\000\000\194\000\000\006\246\000\000\006\028\018\234&\170\000\000\000\000\000\000\018\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\nR&\170\000\000\023\180\000\000%\000*\160\000\000\000\000\000\000\003\242\000\000!\020\000\000\000\0003\030\000\000\000\000\000\000\005<\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0006J\000\0006N\000\000\000\000\000\000\003f\000\000\000\000\000\000\000\000\000\000\000\000\012\030\000\000\020\024\000\000 \128\000\000!\206\000\000$4\000\000'\194\000\0008L\000\0008\138\000\0008\204\000\0008\240\000\000+\180\000\000\002\220\000\0009\000\000\0009\020\000\0009>\000\000'H\000\000\000\000\000\0003@\000\000\000\000\000\000\003\216\000\0003`\000\000\000\000\000\0003\222\000\000\000\000\000\031\000\000\023p\000x\003\254\000\000\004\248\000\000\013\026\001\192\007\194\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0004>\000\000'\148% \005\186\000\000\000\000\000\000+\252\000\000,\028\000\000,>\000\000(\004(n\000w\002,\006*\000\000\000\000\000\000\003$\000\000\000\000\002(\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0004\\\000\000\000\000\000\000\000\000\000\000!\240\000\000)\000\000\000\000\000\000\000\000\000\000\000\000\000\013\220\000\000\005r\000\000\000\000\000\000\000\000\004N\001l\000\000\029\188\000\000\000\000\000\000\007d\000\000\000\000\030j\007\140\000\000\002& ~\000\000\000\000)2\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012b)2\000\000\016\202\000\000\020\178\026\148\000\000\000\000\000\000\006d\000\000\"~\000\000\000\0004\144\000\000\000\000\000\000\006\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\174\000\000\028\224\000\000\000\0004\178\000\00052\000\000\000\000\013V\tB\000\000\000\000!\204\000\000\000\000\000\000\006\204\000\000\014\204\000\000\000\000\028\178\000\000\000\000\000\000\008<\000\000\nt\000\000\014\136\000\000\018\216\000\000\021\002\000\000\021$\000\000\026 \000\000\0306\000\000 Z\000\000#\244\000\000$\130\000\000-j\000\000-\144\000\000\000\000\000\000\000\000\000\000\000\000\003^\000\000\011\130\000\000\022\162\003\238\000\000\"8\000\000\000\000\000\000\000\000\000\000\000\000\030V\000\000\000\000\000\000\000\000\000\000\000\000\003\230\000\000\000\000\000\000\000\000\000\000\000\000\005(\000\000\000\000 \006\000\000\000\000\000\000,\208\000\000\000\000\000?\000\000\000\000\000\000#\134\000\000\000\000\000\000\000\000,\242\000\000\000\000\000\000\000\000\004\224\008\024\000\000-\166\000\000\000\000\000\000\000\000\024<\000F\000\000\024\184\000\000\000\000\013\214\000\000-\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\146\000\000\000\000%\240\000\000\000\000\000\000-\230\000\000\000\000\002\158\000\000\000\000\014^\000\000\025\132\000\000\000\000\"\198\000\000\000\000\000\000\000K\000\000\000\000&\178\000\000\000\000\000\000\000\000.$\000\000\000\000\000\000\000\000\005p\015D\000\000.p\000\000\000\000\000\000\000\000\000\000\000\000\015 \000\000\000\000\003\154\000\000\015\162\000\000\000K\000\000\000\000\003\238\0254\000\000\004\012\000\000\000\000\000\000\000\000\003f\000\000)\210\000\000\026\000\0022\026|\000\000\002\252\000\000\016\"\000\000\016\230\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\022\027J\004\232\027\198\000\000\000\000\000\000\006*\000\000\017f\000\000\004\130\000\000\000\000\000K\004\014\028\146\000\000\005\130\000\000\017\230\029J\000\000\000\000\018\170\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\030\008z\000\000\006\166\000\000\000\000\000\000\000\000\003\194\000\000\019\154\000\000\000\000\000\000\031j5P\000\000\000\000\000\000\030\216\000\000\000\000\000\000\000\000\015.\005\170\000\000\000\000.\164\000\000\000\000\000\000\000\000\006\210\000\000\000\0000T\000\000\000\000\000\000.\188\000\000\000\000\000-\000\000\000\000/:\000\000\000\000\n\022\006\244\000\000\000\000/x\000\000\000\000\006\174\031\208\000\000\006\252\000\000\000\000/\152\000\000\000\000\000\000\000\000\000\000\000\000\007\022\000\000\000\0006>\000\000\000\000\000\000/\192\000\000\000\000\000\000\000\000\000\000#\014\000\000\000\000\000\000\000\162\000\000\000\000\000\000/\196\000\000\000\000\n\174\007*\000\000\000\0000V\000\000\000\000\006\180\000\000\000\000\000\000\000\000\003f\005\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\134\000\000\020J\000\000\000\000\000\0005h\000\000\t\012\000\000\000\000\000\000\004t\000\000\000\000\000g\020\250\000\000\021\170\000\000\000\000\000\000\004\194\000\000\014>\005<\016\n\000\000\023Z\000\000\000\000\000\000\005\224\000\000*~\006\018+,\000\000+r\000\000\000\000\000\000\007J\000\000\026\200\007X\000\000\000\000\022l\013\214\007j\029T\000\000\030,\000\000\000\000\000\000\007\234\000\0003\176\008 \000\000\000\000\000\000\000c\000\000\000\000\000\000\000\000\000\000\002\208\000\000\000\000\002\186\000\000\003\024\000\000\000\000\000\000\003\018\000\000\000\000\000\000\000\000\000E\000\000\006\242\002\166\002\184\000\000\000\000\006\184\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\246\002B\000\000\000\000\000\025\000\000\000\000\000\000\004&\000\000\000\000\006j\006x\000\000\000\000\000\000\000\000\008\146\011&\000\024\000\000\012\172\000\000\000\000\000\000\000\000\000\000\000\000\007H\000\000\000\000\005\022\000\000\000\000\002\164\000\000\000\000\000\140\000\000\000\000\005\154\000\000\007\030\004J\005\140\000\000\000\000\0060\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\206\017\254\000\000\000\000\000\000\000\000\006^\000\000\000\000\007\138\000\000\000\000\000\000\019\252\000\000\000\000\t\130\021\144\0044\000\000\021\188\000\000\000\000\000\000\000\000\000\000\000\000\0007\000\000\007\166\007h\001\224\000\000\000\000\000\000\000\000\006\002\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000v\000\000\008\026\004r\006\020\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\142\000\000\000\000\014r\022@\000\000\000\000\000\000\000\000\001\230\000\000\003\018\000\000\n0\000\000\000\000\000\000\000\000\000\000\000\000\000\007\0114\000\000\000\000\011\222\000\000\000\000\000\000\000\000\007x\000\000\013B\000\000\000\000\000\000\000\000\003\198\000\000\000\000\000\000\000B\000\000\000\000\003\128\000\000\000\000\000\000\000\000\000\000\000\000\000\0000~\005\188\000\000\000\000\000\0000\142\000\000\000\000\016\140\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003f\000\000\000\000\000\000\000\000\000\000\000#\007\128\000g\007\212\013\136\003\214\000\000\000\000\000\204\001\150\003*\004\170\000\000\000\000\000\000\000\000\000\000\000\000\028\\\000\000\000\000\000\000\000\000\016\248\000\204\029\220\005\234\000\000\000\000\008(\000\000\022Z\000\000\000\000\007\204\000\000\000\000\000\000\007\128\000\000\004\012\000\000\004h!l\000\000\000\000\000\000\000\000\002\238\000\000\003\136\000\000\007\164\000\000\000\000\006\214\000\000\000\000\000\000\000\000\t\196\000\000\000\000\000\204\008\178\000\000\022\244\000\000\000K\004\164\000\000\000\000\000\000\000\000\000\000\000\250\000\000\000\000\000\000\000\000\000\0000\182\008$\000\000\001\178\000\000\000\000\000\000\000\000\000\000\001&\000\000\n\144\t$\011R\000\000\002n\011\212\000\000\t*\000\000\003\178\000\000\004,\000\000\004\248\000\000\000\000\000\000\000\000\000\000\008x\000\000\005\176\000\000\tD\000\000\006|\000\000\000K\005\006\000\000\000[\000\000\006<\005p\000\000\008\156\000\000\008\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\192\000\000\t \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\238\005\246\008\150\007<\000\000\007R\000\000\000\000\006\128\tT\000\000\006T\000\000\000\000\000\000\000\000\0074\000\000\000\000\000\000\000\000\000\000\007L\008\172\008\146\007\138\007\204\000\000\000\000\000\028\000\000\000\000\000\000\000\000\008\188\000\000\000\000"), (16, "\001\182\001\205\0006\000\\\004>\004T\0059\0018\005\184\001;\000^\002c\005:\001\129\000-\004\187\005\185\002c\005;\005=\003\014\000\n\004R\000\211\002\245\000\238\004U\004a\000-\001\131\002\245\004l\004\185\004\188\004a\003\251\000\211\004\203\000\236\002\245\000\017\000\005\004\203\000\016\003\015\000\t\001\184\000^\004j\004a\001\185\000\191\000_\0006\004\204\001=\000`\004\207\004a\004\204\001\132\003\011\004\207\004a\000\008\000\t\005\215\000^\001*\004C\000\213\003\012\004{\004a\000\214\005\216\001\131\001\182\001\205\0006\000^\000i\000\211\000\213\000\236\000\193\004b\000\214\004\240\005E\004\019\000-\000\211\004b\000\232\002[\003\\\003D\000\243\004\206\000'\000\227\001,\000&\000\252\004D\004\021\000D\004b\000D\005F\004\141\0026\001<\000\227\000\154\004\204\004b\004\243\004\207\004a\003\015\004b\001\184\001\135\000-\000^\001\185\004\142\000\213\004\145\004a\004b\000\214\0007\002J\000^\005/\0031\000\213\0007\005\207\002\245\000\214\002\246\001\198\0029\002:\002<\0007\002O\005\004\005\005\002\246\002P\001@\003\022\005H\001\199\001<\000\227\000j\0006\0007\001\182\001\205\005I\005c\000\253\000\152\000\227\005d\0012\003\139\000E\001\210\005\127\001%\000-\004b\0036\000\228\005;\005\128\003\014\000k\002\251\002T\000\168\001t\004b\003%\005f\000\244\000\228\003\185\0006\003:\003*\005p\005q\000\160\005h\002\255\003<\001\214\004E\000\246\003\015\001>\001\184\001%\002J\0006\001\185\000\160\004\235\000-\000\166\005\146\001x\003\252\001\198\004\246\0006\001\215\000-\002O\004\215\001\000\001\216\002P\001@\003\022\001\217\001\199\003\141\003j\005/\001\218\000\228\001\182\001\205\000^\003\023\003\254\004\t\0004\003X\001\001\000\228\000-\0007\005u\001\002\000-\0031\001\143\001\003\002[\003\\\003D\001\001\001\004\002T\0006\000\152\001c\003E\005\147\003d\000\191\000b\000\017\000-\003*\001\006\0006\000\160\003{\001U\003<\001\214\004\203\0053\003\015\004\192\001\184\004E\000\255\005y\001\185\002}\005z\001O\002\146\001\145\004\157\003\229\002J\004\204\004\193\001\215\004\207\004a\000\192\0007\001\216\000\237\001\198\005\029\001\217\000\160\001'\002O\000\166\001\218\003^\002P\001@\003\022\005\149\001\199\000\179\000-\000/\001z\0002\001\182\001\205\005I\005c\004i\000'\0007\005\151\000^\0006\003k\001\210\002\127\001%\000-\004\011\002\128\005~\005;\005\133\003D\004j\004a\002T\001E\000\253\0004\003%\005\153\002]\001@\001d\000\170\003$\003*\004b\004\232\000\160\005\155\001@\003<\001\214\001B\003\012\003\015\004\000\001\184\000\216\002J\000\\\001\185\001P\001m\000e\001A\001\182\001\203\0052\001\198\000\225\005\143\001\215\000-\002O\000\169\004X\001\216\002P\001@\003\022\001\217\001\199\004\141\003m\005\029\001\218\000\160\001l\001W\001o\003\023\004b\004\194\001X\003X\000\160\001Y\000\152\000\166\004\142\003^\004\145\004a\000^\004g\000\211\0023\000\231\000_\000^\002T\001\184\000`\004J\003E\001\185\003d\004Q\0006\002\141\000\160\003*\005/\0019\000\160\003{\001N\003<\001\214\0026\002}\000\\\002\142\002\150\004R\000\185\004O\000i\004U\004a\001O\004^\003f\000\160\004\235\002J\000\166\001@\001\215\000^\004Y\004\236\000\213\001\216\004\197\001\198\000\214\001\217\0024\001B\002O\004b\001\218\0028\002P\001@\003\022\005\139\001\199\003J\001i\004\138\001\182\001\205\002I\000^\005I\005c\002\127\003\012\000_\002R\002\128\000\227\000`\001*\000-\002\015\002\016\003\150\005;\005\133\003D\000\160\001l\0006\001o\002T\004b\003\012\004m\003E\002}\005\141\001e\002\150\002\015\002\016\003*\000i\001\198\000\160\003/\001@\003<\001\214\003\015\000j\001\184\001+\000-\000\191\001\185\001\199\005\031\001P\005\000\005 \001^\002\227\0025\000-\005\138\001\182\001\205\001\215\000\137\003}\005\t\005\n\001\216\000k\0006\003a\001\217\005$\002I\000-\0006\001\218\002\127\005;\005\133\003D\002\128\001\213\004i\001X\005\014\000\160\001Y\004\\\000\166\000\228\000-\003\254\000\138\000\\\004\163\0051\001\242\000e\004\238\004j\004a\002\141\002\206\003\015\002\204\001\184\004\178\004a\0024\001\185\002\169\003S\005Z\000m\002\142\000j\001\215\000\139\004\154\005\140\002b\000\140\001d\000\211\003\135\000\230\003S\000o\005\029\004c\001\218\001Z\004\001\002J\003x\002\207\004\248\000^\004\212\000k\005/\005\029\000_\001\198\005\002\003U\000`\000-\002O\0006\005*\002\018\002P\001@\003\022\005\139\001\199\002\015\002\016\004b\003T\001\182\001\205\000-\005I\005c\004b\000^\003z\002R\000\213\000i\003p\002\141\000\214\000-\002\211\001p\0007\005;\005\133\003D\002\169\002\172\001\187\002T\002\142\000\152\003x\003E\000-\005\141\001#\003\002\002J\005n\003*\002\173\001@\000\160\003/\000\227\003<\001\214\001\198\003\015\005\157\001\184\004\135\002O\005R\001\185\002\245\002P\001@\003\022\005\139\001\199\002\015\002\016\005W\005\142\003y\001\215\002\228\005I\005c\004\012\001\216\0006\002R\001@\001\217\000\160\004\235\000-\000\166\001\218\005]\0006\005^\000-\005U\002\231\000\160\005V\002T\000\166\002\214\003}\003E\000j\005\141\001\182\001\205\002\172\001*\003*\004\022\0007\000\160\003/\004\148\003<\001\214\003=\004\144\000-\004p\002\173\000\188\005;\005\133\003D\004\021\000k\002\017\000\160\002\243\004\149\003\001\000\228\0006\004\142\001\215\004\145\004a\0050\000\169\001\216\001,\005?\000-\001\217\0006\001U\002J\003\015\001\218\001\184\000\138\003\012\0006\001\185\000\169\001q\001\198\001\182\001\252\001O\003\128\002O\005X\005\150\003r\002P\001@\003\022\005\139\001\199\004\029\000m\0007\004\196\004\011\000\139\0031\005I\005c\000\140\004\148\000\152\002R\003p\000\160\000o\004\031\002W\004\193\0007\000-\000/\0000\0002\004\151\004b\001U\004\149\002T\001\196\000\160\000^\003E\001\184\005\141\001\182\001\205\001\185\0006\003*\001O\004\149\000\160\003/\004\141\003<\001\214\005\161\003\229\000-\0004\005\026\004i\005;\005\133\003D\000\169\000\160\004\133\004i\000\166\004\142\001@\004\145\004a\002\234\001\215\0006\002J\004j\004a\001\216\0007\003\144\001P\001\217\004j\004a\001\198\003\015\001\218\001\184\004 \002O\0007\001\185\005\180\002P\001@\003\022\005\139\001\199\002#\004[\000-\005\154\001\182\001\205\004\031\005I\005c\001[\000\160\001f\002R\004'\001X\003\146\000\160\001Y\000-\000\166\005\027\001@\002[\003\\\003D\0006\003\026\0006\002T\004)\0006\004b\003E\001P\005\141\004\194\004\152\004b\003\167\003*\001\198\005\186\000\160\003/\004b\003<\001\214\0006\003\015\003\144\001\184\0006\003\241\001\199\001\185\003\241\0022\005Z\005\196\000-\001[\005\187\001\\\003u\0006\001X\001\215\000\160\001Y\001@\000\166\001\216\004_\005\192\0006\001\217\004Y\004\132\002J\002}\001\218\001B\002\150\003\145\005\191\002\130\003\243\000-\001\198\003\242\002c\005(\001i\002O\004\184\005\201\004\155\002P\001@\003\022\005\139\001\199\004\141\0006\004\210\004\193\001\182\001\205\004`\005I\005c\004\185\004\188\004a\002R\000\160\001l\000^\001o\004\142\000-\004\145\004a\002I\002[\003\\\003D\002\127\005\205\000-\002T\002\128\004\156\005(\003E\002\139\005\141\002\166\004\166\002J\0007\003*\000-\001@\000\160\003/\004v\003<\001\214\001\198\003\015\000-\001\184\004t\002O\005R\001\185\0007\002P\001@\003\022\0007\001\199\004\004\003j\004\200\005B\002}\001\215\004*\002\150\003\023\004b\001\216\0007\002R\003\012\001\217\004-\005\203\002c\004b\001\218\005\\\0007\004)\003\175\005U\0046\000\160\005V\002T\000\166\0006\004\031\003E\001U\003d\001\182\001\205\000\152\004\201\003*\003\192\0048\000\160\003/\003\201\003<\001\214\001O\000^\000-\0007\004\199\002\127\002[\003\\\003D\002\128\003\211\004\213\005Y\005G\002\141\002\201\002\222\002\204\005)\001\215\003\236\005K\005\208\002\169\001\216\005e\004i\002\142\001\217\0055\005,\002J\003\015\001\218\001\184\003\012\000\160\004\133\001\185\000\166\005\211\001\198\0049\004j\004a\005\212\002O\004\214\002\207\002d\002P\001@\003\022\004\136\001\199\003h\003j\005w\0048\005\172\005)\001\182\001\205\003\023\000\160\005\220\002\229\002R\004<\005\172\004\253\0054\005,\001@\005\027\000-\000\000\005\172\004\169\002[\003\\\003D\000\152\002T\004\031\001P\000\000\003E\002}\003d\000-\002\150\005\130\0007\003*\005\130\002\172\000\160\003/\005\148\003<\001\214\002\141\004b\005X\003\015\000\160\001\184\005\130\000\000\002\173\001\185\001[\005\210\001a\002\142\005\193\001X\005\027\000\160\001Y\001\215\000\166\002J\005\195\005\172\001\216\005\209\000\160\001|\001\217\000\166\002I\001\198\005\144\001\218\002\127\005\136\002O\003\003\002\128\004\149\002P\001@\003\022\004\184\001\199\003\143\003j\004\203\005\152\000\000\000\000\001\182\001\205\003\023\003\007\000\000\000\000\002R\005\027\000\\\004\185\004\188\004a\000e\004\204\000-\000\000\004\207\004a\002[\003\\\003D\000\000\002T\000\000\000-\0003\003E\0002\003d\000\000\005\205\002\172\000\000\003*\000\000\000\000\000\160\003/\005\179\003<\001\214\004\202\000\000\002J\003\015\002\175\001\184\000\000\005\173\000\000\001\185\000\000\000^\001\198\0004\000-\005\175\000_\002O\004\129\001\215\000`\002P\001@\003\022\001\216\001\199\004\008\003j\001\217\004b\001\182\001\202\005\206\001\218\003\023\004b\004\203\000\152\002R\002\141\002\201\002\202\002\204\005\206\003\191\000i\000\000\002}\002\169\000\211\002\150\000\238\002\142\004\204\002T\000\000\004\207\004a\003E\000\000\003d\001\182\001\205\005\177\000\000\003*\000\186\000\000\000\160\003/\000\000\003<\001\214\002\207\000^\000-\001\184\000\000\000\000\005;\001\185\003\014\000\000\000\160\001)\000\000\000\166\000\211\000\000\000\229\000-\000^\001\215\000^\002J\002\127\000\213\001\216\000\000\002\128\000\214\001\217\000\000\000\000\001\198\003\015\001\218\001\184\000\000\002O\000\000\001\185\000\000\002P\001@\003\022\004b\001\199\005a\003j\003\235\002\172\000\000\005\145\001@\000j\003\023\000\227\000\000\000\000\002R\000^\000\000\000\000\000\213\002\173\001B\004\217\000\214\000\000\000\000\004\220\000\000\000\000\000\188\000\000\002T\001i\000\000\000k\003E\000\000\003d\000\000\000\000\000\169\000\000\003*\001\182\001\205\000\160\003/\004i\003<\001\214\000\227\004\203\000\000\000\000\000\000\000\160\001l\000-\001o\000\138\001\198\005;\000\000\003\014\004j\004a\000\000\002}\004\204\001\215\002\150\004\207\004a\001\199\001\216\000\000\000\000\002\141\001\217\000\000\000m\002J\000\000\001\218\000\139\000\000\000\160\003\015\000\140\001\184\002\142\001\198\000\228\001\185\000o\000\000\002O\000\000\000\000\000\000\002P\001@\003\022\005\132\001\199\005\131\000\000\004\233\001\182\001\205\000\000\002I\005I\005c\000\000\002\127\000\169\005\135\000\254\002\128\000\000\000\000\000-\000\000\004b\000\000\005;\000\000\003\014\000\000\000\228\004b\000\000\002T\000\000\000\000\004\203\003%\005\137\000\211\001\000\000\236\000\000\000\000\003*\001\182\001\203\000\160\003/\000\000\003<\001\214\003\015\004\204\001\184\000\000\004\207\004a\001\185\002\172\001\001\000\000\000\160\000\000\000\000\001\002\000\000\000\000\000\000\001\003\005\134\001\215\000\000\002\177\001\004\000\000\001\216\000\000\002J\002}\001\217\000\000\002\145\000^\000\000\001\218\000\213\000\000\001\198\000^\000\214\001\184\000\000\002O\000\000\001\185\000\000\002P\001@\003\022\005\132\001\199\000-\000/\001v\0002\001\182\001\205\000\000\005I\005c\000\000\002\141\000-\005\135\002\208\004b\000\227\000\000\000\000\000-\002\169\000\000\000^\002[\002\142\003\014\002\127\000\000\000\000\002T\002\128\0004\004\127\003%\005\137\000\000\004\241\000\000\000\000\000\000\003*\004i\002J\000\160\003/\002\210\003<\001\214\000\000\003\015\000\000\001\184\001\198\000\000\000\000\001\185\000\000\002O\004j\004a\000\000\002P\001@\003\022\005\132\001\199\000\000\001\215\000\000\000\000\001\182\001\205\001\216\005I\005c\000\000\001\217\000\000\005\135\000\000\000\000\001\218\004\014\000\000\000-\000\000\003\138\002\216\002[\001\198\003\014\000\000\000\000\002\172\002T\000\000\000\228\000\000\003%\005\137\002}\000\000\001\199\002\150\000\000\003*\000\000\002\173\000\160\003/\000\000\003<\001\214\004\203\003\015\000\000\001\184\000\000\004b\000\000\001\185\004\244\000\000\002\141\000\000\000\000\000\211\000\000\000\238\000\000\004\204\000\000\001\215\004\207\004a\000\000\002\142\001\216\000\000\000-\002J\001\217\001@\005(\002I\000\000\001\218\003\136\002\127\000\000\001\198\003\138\002\128\000\152\001B\002O\000\000\000\000\000\000\002P\001@\003\022\000\000\001\199\001\001\001i\000\000\001\182\001\205\001\215\000^\000\000\003\023\000\213\002Y\000\000\003\127\000\214\001\008\000\000\000\000\000-\000\000\001\220\000\000\002[\003\t\003\014\000\160\001l\000\000\001o\002T\004b\000\000\002c\003%\003\129\000\000\000\160\001~\000\243\000\166\003*\000\227\002J\000\160\003/\0006\003<\001\214\003\015\000\000\001\184\000\000\001\198\000\211\001\185\000\238\000\000\002O\000\000\000\000\000\000\002P\001@\003\022\004}\001\199\000\000\001\215\000\000\001\182\001\205\000\000\001\216\000\000\003\023\000\000\001\217\003'\003\127\000\000\000\000\001\218\002\141\000-\000\000\002\217\000\000\002[\003(\003D\002}\002\169\000\000\002\150\002T\002\142\000\000\000^\003%\003\129\000\213\000\000\000\000\004\141\000\214\003*\000\000\000\000\000\160\003/\000\000\003<\001\214\003\015\000\000\001\184\000\000\005)\000\000\001\185\004\142\000\228\004\145\004a\002}\000\000\000\000\002\150\005+\005,\000\000\000\227\001\215\0013\000^\000\000\004\251\001\216\002\127\002J\000\000\001\217\002\128\000\000\000\\\000\000\001\218\000\246\000q\001\198\000\000\000\000\000\000\000\000\002O\0007\000-\000\000\002P\001@\003\022\000\000\001\199\000\160\002\172\000\000\001\182\001\205\002I\001\000\000\000\003\023\002\127\000\000\003G\003I\002\128\000\000\002\173\000\000\000-\000\000\004b\000\000\002[\003(\003D\000-\000^\001\001\000\000\002T\000\000\000_\001\002\003%\003K\000`\001\003\000\000\000\000\003\016\003*\001\004\002J\000\160\003M\000\000\003<\001\214\003\015\000\228\001\184\000\000\001\198\002c\001\185\003\166\003\020\002O\000\000\000\000\000i\002P\001@\003\022\000\000\001\199\0006\001\215\000\000\001\182\001\205\000\000\001\216\002\141\003\023\004\024\001\217\003L\002R\000\000\000\000\001\218\000\000\000-\000\000\000\000\002\142\002[\003(\003D\000\000\000\000\000\000\000\000\002T\000\000\000\000\001\000\003E\000\000\003F\000\000\000\000\000\000\000\000\003*\000\000\002\141\000\160\003/\002\168\003<\001\214\003\015\000\000\001\184\002\169\001\001\000\000\001\185\002\142\000\211\001\002\000\238\000\000\000\000\001\003\004\226\000\000\000\000\000\000\001\004\001\215\001\182\001\205\000\152\000\000\001\216\000\000\002J\000j\001\217\000\000\000\211\000\000\000\236\001\218\000-\000\000\001\198\000\000\002[\003\\\003D\002O\002\172\000\000\000\000\002P\001@\003\022\000\000\001\199\000\000\000k\000^\001@\000\000\000\213\002\179\000\000\003\023\000\214\000\000\000\000\002R\0007\003\015\003\172\001\184\000\000\000\160\001\128\001\185\000\166\000\000\000\211\000^\000\238\002\172\000\213\002T\000\000\000\000\000\214\003E\000\000\003F\000\000\000\227\000\000\000\000\003*\002\173\002J\000\160\003/\000\000\003<\001\214\001/\000\000\000\160\003\184\001\198\003\190\005\023\002}\000\000\002O\002\144\000\227\003>\002P\001@\003\022\000\000\001\199\000\000\001\215\000^\001\182\001\205\000\213\001\216\000\000\003\023\000\214\001\217\003B\002R\000\000\000\000\001\218\000\000\000-\000\000\000\000\000\000\002[\003\\\003D\000\000\000\000\000-\000\000\002T\000\000\005(\000\000\003E\000^\003F\000\000\000\227\002\127\000\000\003*\002J\002\128\000\160\003/\000\000\003<\001\214\003\015\000\000\001\184\001\198\000\228\000\000\001\185\000\000\002O\002b\000\000\000\000\002P\001@\003\022\000\000\001\199\000\000\003c\001\215\001\182\001\205\000\000\000\000\001\216\003\023\000\228\000\\\001\217\002R\004\026\000\182\000\000\001\218\000-\000\000\000\000\000\000\002[\003\\\003D\000\000\000\000\000-\000\000\002T\000\000\000\000\000\000\003E\000\000\003d\001\000\000\000\000\000\000\000\003*\000\000\000\000\000\160\003/\000\000\003<\001\214\003\015\000\000\001\184\000\000\000\000\000\228\001\185\000^\001\001\000\000\001\028\000\000\000_\001\002\000\000\000\000\000`\001\003\000\000\001\215\001\182\001\205\001\004\002\141\001\216\000\000\000\000\002J\001\217\000\000\001\001\005\021\000\000\001\218\000-\000\000\002\142\001\198\002[\003\130\003D\000i\002O\000\000\001\004\000\000\002P\001@\003\022\000\000\001\199\000\\\003e\001\000\000\000\000q\001@\000\000\004i\003\023\000\000\000\000\000\000\002R\003\015\000\000\001\184\005+\005<\000\000\001\185\000\000\000\000\001\001\000\000\004j\004a\000\000\001\002\002T\000\000\000\000\001\003\003E\000\000\003d\000\000\001\004\000\000\000\000\003*\002J\000\000\000\160\003/\000^\003<\001\214\000\000\003\132\000_\001\198\000\160\002\243\000`\003\001\002O\000\000\000\000\000\000\002P\001@\003\022\000\000\001\199\000\000\003w\001\215\001\182\001\205\000\152\000j\001\216\003\023\000\000\000\000\001\217\002R\000\000\000i\000\000\001\218\000-\001\182\001\203\004b\002[\003\130\003D\000\000\000\000\002}\000\000\002T\002\150\000k\000\000\003E\000\000\003d\001\182\001\205\000\000\000\000\003*\002J\000\000\000\160\003/\000\\\003<\001\214\003\015\000e\001\184\001\198\000\160\001\141\001\185\000\166\002O\000\000\000\000\000-\002P\001@\003\022\000^\001\199\001\184\000\000\001\215\000\000\001\185\000\000\000^\001\216\003\023\000\000\002\127\001\217\002R\000\000\002\128\000^\001\218\001\184\003\134\000\000\000\000\001\185\000\000\000\000\000^\000\000\000\000\000\000\002T\000_\000j\000\000\003E\000`\003\133\000\000\000\000\000\\\000\000\003*\000\000\000\181\000\160\003/\000\000\003<\001\214\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000k\000\000\000\000\000\000\000i\001\182\001\205\000\000\000\000\000\000\000\000\004\161\001\215\003\152\000\000\001\210\000\000\001\216\000\000\000-\002J\001\217\000\000\002[\003(\003D\001\218\000^\000\000\000\000\001\198\000\000\000_\000\000\000-\002O\000`\001j\000\000\002P\001@\003\022\000\000\001\199\000\000\001\198\000m\000\000\000\000\003\015\000\000\001\184\003\023\002\141\000\000\001\185\002R\000\000\001\199\000\000\000r\000i\001\198\000\000\0004\000\000\002\142\000\000\001\182\001\203\000\000\000\000\002T\000\000\000\000\001\199\003E\000\000\003\133\000\000\004i\000\152\000\000\003*\000j\000\000\000\160\003/\001\212\003<\001\214\000\000\000\000\001\182\001\205\000\000\000\000\004j\004a\000\000\000\000\000\000\000\000\000\183\000\000\000\000\000\000\000-\000k\000\000\001\215\002[\000^\003\014\001\184\001\216\000\000\000\000\001\185\001\217\000\000\000\000\001\214\000\000\001\218\001\204\000\000\000\160\001-\000\000\000\166\000\000\000\000\000\138\000\000\002\172\000\000\003\015\000\000\001\184\002J\000j\001\215\001\185\000\000\002}\000\000\001\216\002\143\002\181\001\198\001\217\000\000\000\000\000m\002O\001\218\004b\000\139\002P\001@\003\022\000\140\001\199\000\000\000k\000\000\000\\\000o\000\000\004\002\000g\003\023\000\000\003\138\001@\002R\000\000\000\000\000\000\000\000\001\182\001\205\000\000\000\000\002}\000\000\001B\002\150\000^\000\000\000\000\002T\002\127\000\000\000-\003E\002\128\003F\002[\000\000\003\014\002}\003*\000\000\002\150\000\160\003/\000\\\003<\001\214\000^\000]\001\198\000\000\000\000\000_\000\000\000\000\000\000\000`\000\160\001l\001s\001o\003\015\001\199\001\184\002J\000^\001\215\001\185\000\000\002\127\000\000\001\216\000\000\002\128\001\198\001\217\000\000\000\000\000\000\002O\001\218\000i\000^\002P\001@\003\022\002\127\001\199\000^\000\000\002\128\000\000\000\000\000_\004\016\000\000\003\023\000`\003\138\000\000\003\127\000\000\004\173\000\000\000\000\001\182\001\205\000\000\000\000\000\211\000\000\000\212\000\000\000\000\000\000\000\000\002T\000\000\004i\000-\003%\003\129\000i\002[\000\000\003\014\002\141\003*\000\000\001\215\000\160\003/\000\000\003<\001\214\004j\004a\000\000\000\000\002\142\004i\000\000\000\000\001\222\000\000\000\000\000\000\000\000\000\000\003\015\000\000\001\184\002J\000^\001\215\001\185\000\213\004j\004a\001\216\000\214\000j\001\198\001\217\000\000\000\000\002\141\002O\001\218\000\000\000\000\002P\001@\003\022\000\000\001\199\000\000\000\000\000\000\002\142\000\000\000\000\004\018\002\141\003\023\000k\003\138\000\227\003\127\000\000\000\000\000\000\000\000\001\182\001\205\004b\002\142\000\000\000\000\000\000\000\000\005D\000j\000\000\002T\000\000\004i\000-\003%\003\129\000l\002[\003(\003D\000\000\003*\000-\004b\000\160\003/\002[\003<\001\214\004j\004a\000\000\000k\000\000\000\000\002}\000\000\000m\002\150\000\000\000\000\000\000\000\149\003\015\000\000\001\184\002J\000\000\001\215\001\185\000\000\000o\0040\001\216\002\172\000\000\001\198\001\217\000\000\000\000\000\000\002O\001\218\000\000\000\000\002P\001@\003\022\002\183\001\199\000\\\002\172\000\000\000\228\000q\000\000\001\182\001\205\003\023\002I\000\000\000\000\003\127\002\127\005g\002\185\000\000\002\128\000\000\004b\000-\000\000\000\000\000\000\002[\003(\003D\000\000\002T\000\000\000\000\000\000\003%\003\129\000\000\000\000\000\000\000\000\000\000\003*\004\182\000\000\000\160\003/\000^\003<\001\214\000\000\000\000\000_\003\015\000\000\001\184\000`\000\000\000\000\001\185\000\211\000\000\000\238\000\000\000\000\004\180\000\000\002J\000\000\001\215\003\147\001\182\001\205\000\000\001\216\000\000\000\000\001\198\001\217\000\000\000\000\000i\002O\001\218\000\000\000-\002P\001@\003\022\002[\001\199\003D\000\000\000\000\000\000\000\000\001@\003\022\000\000\003\023\000\000\000\000\000\000\002R\000^\001\182\001\201\000\213\003\023\000\000\000\000\000\214\000\000\002\141\000\000\003\015\002\208\001\184\000\000\002T\000\000\001\185\002\169\003E\000-\003F\002\142\000\000\000\000\000\000\003*\004\224\0041\000\160\003/\000\000\003<\001\214\000\227\003*\000\000\000\000\000\160\003/\002J\003<\000\000\002\210\000\000\000^\000\000\001\184\000\000\000\000\001\198\001\185\000\000\001\215\000\000\002O\000\000\000j\001\216\002P\001@\003\022\001\217\001\199\000\000\000\000\000\000\001\218\000\000\001\182\001\205\000\000\003\023\000\000\001U\000\000\002R\000\000\000\000\000\000\003H\000k\000\000\000-\000\000\002\215\000\000\002[\001O\003\014\000\000\002\172\002T\000\000\000\000\000\000\003E\000\000\003F\000\000\000\000\000\000\002J\003*\000\000\002\173\000\160\003/\000\000\003<\001\214\000\000\001\198\003\015\000\228\001\184\000\000\002O\000\000\001\185\000\000\002P\001@\003\022\000\000\001\199\000\000\000m\000\000\000\000\001\215\001\182\001\205\000\000\003\023\001\216\000\000\000\000\003\149\001\217\004\028\000t\003\013\000\000\001\218\000-\001\198\000\000\000\000\002[\000\000\003\014\000\000\000\000\002T\000\000\000\000\000\000\003E\001\199\003\151\001@\001\000\000\000\000\000\003*\000\000\000\000\000\160\003/\000\000\003<\001\214\001P\000\000\003\015\000\000\001\184\000\000\000\000\000\000\001\185\001\001\000\000\000\000\000\000\000\000\001\002\000\000\000\000\000\000\001\003\001\215\001\182\001\205\000\000\001\004\001\216\000\000\000\000\001[\001\217\001\137\000\000\002J\001X\001\218\000\160\001Y\000\000\000\166\000\000\000\000\003R\001\198\000\000\000\000\000\000\000\000\002O\000\000\000\000\000\000\002P\001@\003\022\000\000\001\199\000\000\000\000\000\000\000\000\000\000\001\182\001\205\000\000\003\023\002I\000\000\001\184\003#\000\000\000\000\001\185\003)\000\000\000\000\000-\000\000\000\000\000\000\002[\000\000\003\014\000\000\000\000\002T\000\000\000\000\000\000\003%\003&\000\000\000\000\000\000\000\000\002J\003*\000\000\000\000\000\160\003/\000\000\003<\001\214\000\000\001\198\003\015\000\000\001\184\000\000\002O\000\000\001\185\000\000\002P\001@\003\022\000\000\001\199\000\000\000\000\000\000\000\000\001\215\001\182\001\205\000\000\003\023\001\216\000\000\000\000\003#\001\217\000\000\000\000\000\000\000\000\001\218\000-\000\000\002}\000\000\002[\002\150\003\014\000\000\000\000\002T\000\000\000\000\000\000\003%\003&\000\000\000\000\000\000\000\000\002J\003*\000\000\000\000\000\160\003/\000\000\003<\001\214\000\000\001\198\003\015\000\000\001\184\000\000\002O\000\000\001\185\000\000\002P\000\000\000\000\000\000\001\199\000\000\000\000\000\000\000^\001\215\001\182\001\205\002\127\000\000\001\216\000\000\002\128\002R\001\217\000\000\000\000\002J\002}\001\218\000-\002~\000\000\000\000\002[\000\000\003\014\001\198\000\000\002T\000\000\000\000\002O\000\000\000\000\000\000\002P\001@\003\022\000\000\001\199\000\000\000\000\000\000\000\211\000\000\000\238\001\214\000\000\003\023\003\015\000\000\001\184\003#\000\000\000\000\001\185\000\000\000\000\000\000\000\000\000\000\000^\000\000\000\000\000\000\002\127\001\215\000\000\002T\002\128\000\000\001\216\003%\003&\000\000\001\217\000\000\000\000\002J\003*\001\218\000\000\000\160\003/\000\000\003<\001\214\000^\001\198\000\000\000\213\000\000\000\000\002O\000\214\000\000\000\000\002P\001@\003\022\000\000\001\199\000\000\000\000\002\141\000\000\001\215\003g\001\182\001\205\003\023\001\216\000\000\000\000\003`\001\217\000\000\002\142\000\000\000\000\001\218\000\227\000-\000\000\000\000\000\000\002[\000\000\003\014\000\000\002T\000\000\000\000\000\000\003%\003b\000\000\000\000\000\000\000\000\002J\003*\000\000\000\000\000\160\003/\000\000\003<\001\214\000\000\001\198\000\000\003\015\000\000\001\184\002O\000\000\000\000\001\185\002P\001@\003\022\002\141\001\199\000\000\000\000\000\000\000\000\001\215\003_\001\182\001\205\003\023\001\216\000\000\002\142\003`\001\217\000\000\000\000\000\000\000\000\001\218\000\000\000-\000\000\002\172\000\\\002[\000\000\003\014\000g\002T\000\000\000\000\000\000\003%\003b\000\000\000\000\002\187\000\228\000\000\003*\000\000\000\000\000\160\003/\000\000\003<\001\214\000\000\000\000\000\000\003\015\000\000\001\184\000\000\000\000\000\000\001\185\000\000\000\000\000\000\000\000\000\000\000\000\004,\000\000\000\000\001\215\000^\000\000\000\000\000\000\001\216\000_\000\000\000\000\001\217\000`\000\000\000\000\002J\001\218\002}\000\000\000\000\002\150\001\000\000\000\000\000\000\000\001\198\000\000\000\000\000\000\000\000\002O\000\000\000\000\000\000\002P\001@\003\022\000i\001\199\000\000\000\000\001\001\000\000\003s\001\182\001\205\001\002\003\023\000\000\000\000\001\003\003t\000\000\000\000\000\000\001\004\000\000\000\000\000-\000\000\002}\002I\002[\002\150\003\014\002\127\000\000\002T\000\000\002\128\000\000\003%\003v\000\000\000\000\000\000\000\000\002J\003*\000\000\000\000\000\160\003/\002}\003<\001\214\002\150\001\198\003\015\000\000\001\184\000\000\002O\000\000\001\185\000\000\002P\001@\003\022\000\000\001\199\000\000\000\000\000\000\002I\001\215\003q\000\000\002\127\003\023\001\216\000\000\002\128\003`\001\217\000\000\000\000\000j\000\000\001\218\000\000\000\000\000\000\000\000\000\000\003~\000\000\000^\000\000\002T\000\000\002\127\000\000\003%\003b\002\128\001\182\001\205\000\000\000\000\003*\000k\000\000\000\160\003/\000\000\003<\001\214\000\000\000\000\000-\000\000\000\000\000\000\002[\000-\003\014\000\000\000\000\002[\000\000\000\000\002\141\002\201\0057\002\204\000l\001\215\000\000\000\000\000\000\002\169\001\216\000\000\000\000\002\142\001\217\000\000\000\000\002J\003\015\001\218\001\184\000\000\000\000\0040\001\185\000m\000\000\001\198\000\000\000\000\000n\000\000\002O\000\000\002\207\000\000\002P\001@\003\022\000o\001\199\000\000\000\000\002\141\000\000\000-\002\171\001\182\001\205\003\023\000\000\000\000\002\169\003\127\000\000\003\131\002\142\005@\000\000\000\000\000\000\000-\000\000\000\000\000\000\002[\002\141\003\014\000\000\002T\000\000\000\000\000\000\003%\003\129\000\000\000\000\000\000\000\000\002\142\003*\000\000\002\172\000\160\003/\000\000\003<\001\214\000\000\000\000\000\000\003\015\002}\001\184\000\000\002\150\002\173\001\185\000\000\001U\000\000\000-\000\000\000\000\000\000\002[\000\000\001\215\002}\002J\000\000\002\150\001\216\001O\000\000\000\000\001\217\000\000\000\\\001\198\000\000\001\218\000e\000\000\002O\002\172\000\000\000\000\002P\001@\003\022\0040\001\199\000\000\001@\003\022\000^\000\000\000\000\002\173\002\127\003\023\000\000\000\000\002\128\003\127\003\023\000\000\002\151\000\000\000\000\000\000\002I\000\000\000\000\000\000\002\127\000\000\000\000\000\000\002\128\002T\000^\000\000\000\000\003%\003\129\000_\000\000\000\000\0043\000`\003*\001\182\001\205\000\160\003/\003*\003<\001\214\000\160\003/\002J\003<\000\000\000\000\001@\000-\000\000\000\000\000\000\003\165\001\198\000\000\000\000\000\000\000i\002O\001P\001\215\000\000\002P\001@\003\022\001\216\001\199\000\000\000\000\001\217\000\000\003\197\000\000\000\000\001\218\003\023\000\000\000\000\003\200\005A\001\184\000\000\000\000\000\000\001\185\000\000\001[\000\000\002_\000\000\000\000\001X\000\000\000\160\001Y\002T\000\166\000\000\002\141\003%\005C\003\206\000\000\001@\003\022\000\000\003*\001\182\001\205\000\160\003/\002\142\003<\001\214\002\141\003\023\000\000\002\220\000\000\000\000\000\000\000-\000\000\002\169\000\000\003\165\000\000\002\142\002\224\003\244\000\000\000\000\001\210\001\215\001%\000\000\000\000\000j\001\216\0045\000\000\000\000\001\217\000\000\003\248\000\000\003*\001\218\000\000\000\160\003/\003\200\003<\001\184\000\000\000\000\002\164\001\185\001\182\001\205\000\000\000k\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000-\000\\\003\206\000\000\003\165\000e\000\000\001\198\002\172\000\000\000\000\000\000\000\000\000\000\000\138\000-\000\000\001@\003\207\000\000\001\199\000\000\002\189\003\199\002\172\000\000\000\000\000-\000\000\003\208\003\200\000\000\001\184\003\246\000\000\000m\001\185\000\000\002\173\000\139\000\000\000\000\000\000\000\140\000\000\000^\000\000\000\000\000\000\000o\000_\000\000\000\000\003\206\000`\002}\000\000\000\000\002\150\000\000\003\222\000\000\000\000\000\160\003\247\000\000\003\234\001\214\000\000\000\000\000\000\000\000\000\\\000\\\001\182\001\203\000e\000e\000\000\000i\001\198\001U\000\000\000\000\000\000\000\000\000-\001\215\000\000\000\000\001@\003\207\001\216\001\199\000\000\001O\001\217\000\000\000\000\000^\000\000\001\218\003\208\002\127\000\000\000\000\003\220\002\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000^\000^\000^\000\000\001\184\000_\000_\000\000\001\185\000`\000`\000\000\000\000\000\000\000\000\001\198\000\000\003\222\000\000\000\000\000\160\003\227\000\000\003\234\001\214\001@\003\207\000\000\001\199\000\000\000\000\000\000\000\\\000\000\000i\000i\000e\003\208\000\000\000\000\000\152\003\220\000\000\000j\001\215\000\000\000-\000\000\000\000\001\216\000\000\000\000\001@\001\217\000\000\000\000\002j\000\000\001\218\000\155\000\156\000\158\000\159\000\000\001P\000\000\000\000\000k\003\222\000\000\000\000\000\160\003\227\000\000\003\234\001\214\000^\000\000\000\000\000\000\000\000\000_\000\000\000\000\002\141\000`\000\160\000\165\000\000\000\166\000-\001[\000\138\002\237\000\000\001\215\001X\002\142\000\160\001Y\001\216\000\166\000\000\001\198\001\217\000\000\000\000\000\000\000\000\001\218\000i\000\152\000\000\000m\000j\000j\001\199\000\139\000\000\000\000\000\000\000\140\000\000\000\000\000\\\001\182\001\203\000o\000e\000\171\000\155\000\218\000\158\000\159\000\188\000\000\000\000\000\000\000k\000k\000\000\000\000\000\\\000\000\000\000\005Q\000e\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000-\000\160\000\165\000\000\000\166\000\000\000\000\000\138\000\138\000\000\002\172\000\000\000^\000^\000\000\001\184\000\211\000_\000\236\001\185\000\000\000`\002}\000\000\002\191\002\150\000\000\001\215\000m\000m\000^\000\152\000\139\000\139\000j\000_\000\140\000\140\000\000\000`\000\000\001\224\000o\000o\000\171\000\000\000i\000\000\000\000\000\000\000\155\001\189\000\158\000\159\000\000\000\000\000\000\000\\\000k\000\000\000^\000e\000\000\000\213\000i\000\000\002I\000\214\000\000\000\000\002\127\000-\000\000\000\000\002\128\001@\000\000\000\160\000\165\000\000\000\166\000\000\000\000\000\138\000\000\000\000\000\000\005R\000\000\000\000\000\000\000\000\000\000\000\\\000\227\000\000\000\000\000e\000\000\000\000\000\000\000^\000\000\000\000\000m\000\000\000_\000-\000\139\000\000\000`\000\000\000\140\000\000\001\198\000\000\000\000\002\162\000o\005U\000\171\000\160\005V\000\000\000\166\000\000\000j\001\199\000\000\000\\\000\000\000\000\000\000\000e\000\000\000i\000\000\000^\000\000\000\000\000\000\000\152\000_\000-\000j\002\164\000`\000\000\000\000\000\000\000k\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\155\002L\000\158\000\159\000\000\000\000\000\000\002\141\000k\000\000\002\208\000i\000\000\000^\000\228\000\138\002\169\000\000\000_\000\000\002\142\000\000\000`\000\000\000\000\000\000\000\000\000\160\000\165\000\000\000\166\000\000\000\000\000\138\001\215\000\000\000m\000\000\000\000\000\000\000\139\002\210\000\000\000-\000\140\000\000\000\000\000i\001\226\000\000\000o\000\000\000\152\000\000\000m\000j\000\000\000\000\000\139\000\000\000\000\000\000\000\140\000\000\000\000\000\000\000\000\000\000\000o\000\000\000\171\000\155\002\132\000\158\000\159\000\000\000\000\000\000\000\000\000k\000\000\000\000\001\001\002\213\002}\000\000\000\000\002\150\000\152\002\172\000\000\000j\000\000\000\000\000\000\000\000\001\n\001U\000\160\000\165\000\000\000\166\000\000\002\173\000\138\000\000\000\000\000\155\003,\000\158\000\159\001O\000\000\000\000\000\000\000k\001\182\001\203\000\000\000\000\000\000\000\000\000\000\000\000\000\152\000m\000\000\000j\000^\000\139\000\000\000\000\002\127\000\140\000\160\000\165\002\128\000\166\000\\\000o\000\138\000\171\000e\000\155\003\224\000\158\000\159\000\000\000\000\000\\\000\000\000k\000-\000e\000\000\002}\000\000\000\000\002\150\000\000\000^\000m\001\184\000-\000\000\000\139\001\185\000\000\000\000\000\140\000\160\000\165\000\000\000\166\000\000\000o\000\138\000\171\000\000\000\000\000\000\000\000\000^\000\000\001@\000\000\000\000\000_\000\000\000\000\000\000\000`\000\000\000^\000\000\000\000\001P\000m\000_\000^\000\000\000\139\000`\002\127\000\\\000\140\000\000\002\128\000g\000\000\000\000\000o\000\000\000\171\000\000\000\000\000i\000\000\001\182\001\200\000\000\000\000\000\000\001[\000\000\002\248\000\000\000i\001X\002\141\000\160\001Y\000\000\000\166\001\182\001\205\000\000\001#\001%\000\000\000\000\000\211\002\142\000\236\000\000\000\000\000\\\000\000\000^\000\000\000e\000\000\000\000\000_\003P\000\000\000\000\000`\000\000\000\\\000-\001\198\000^\000e\001\184\000\000\000\000\000\000\001\185\000\000\000\000\000\000\000\000\000-\001\199\000\000\000\000\000\000\002I\000\000\001\184\000\000\000i\000\000\001\185\000^\000\000\000\000\000\213\000\000\000^\000\000\000\214\000\152\000\000\000_\000j\000\000\000\000\000`\002\141\000\000\000\000\000^\000\152\000\000\000\000\000j\000_\000\000\000\000\002\172\000`\002\142\000\000\000\188\000\000\000\000\000\000\000\227\000k\000\000\000\000\000\173\000i\002\193\000\159\000\000\003V\000\000\000\000\000k\001\210\000\000\000\\\000\000\000\000\000i\000e\000\160\001'\001\215\000\166\000\000\000\000\000\138\000\000\000\000\000-\000\000\000\160\000\165\000-\000\166\000\000\001\228\000\138\000\000\000\000\000\000\000\000\000\000\000j\001\198\000\000\000\000\000m\000\000\000\000\002J\000\139\000\000\000\000\000\000\000\140\000\000\001\199\000m\000^\001\198\000o\000\139\002\172\000_\002O\000\140\000k\000`\002P\000\000\000\000\000o\001\199\000\171\000\000\000\000\002\195\000\000\000\000\000\228\000\000\000\152\000\000\000\000\000j\003X\001U\000\000\000\000\000\000\000\000\000l\000i\000\000\000\152\000\000\000\000\000j\000\000\000\000\001O\002T\000\000\000\195\000\000\000\000\000\000\000\000\000k\000\000\000\000\000\\\000m\000\000\000\000\000e\000\195\000\148\000\000\001\214\000\000\000k\000\000\000\000\000\000\000-\000o\000\160\000\197\000-\000\166\000\000\000\000\000\138\000\000\000\000\001\182\001\205\000\000\001\215\000\160\000\234\000\000\000\166\001\216\000\000\000\138\001\001\001\217\000\000\000\000\000\000\000\000\001\218\000m\000^\002B\004\013\000\139\000\000\000_\001\012\000\140\000\000\000`\000\000\000\000\000m\000o\000\152\000\000\000\139\000j\001@\000\000\000\140\000\000\000\000\000\000\000\000\002I\000o\001\184\001U\000\000\001P\001\185\000\000\000\000\000i\000\\\000\183\000\000\000\000\000e\000\000\000k\001O\000\000\000\000\000\000\000\000\000\000\000\000\000-\000\000\000\000\000\000\000\000\000\000\000\000\000\211\001[\000\236\003\029\000\160\0016\001X\000\166\000\160\001Y\000\138\000\166\000\000\000\000\000\000\000\000\000\000\001\182\001\205\000\000\000\000\000\000\000\000\000^\000\000\000\000\000\000\000\000\000_\000\000\000\000\000m\000`\000\000\000\000\000\139\000\000\002B\003Y\000\140\001\182\001\203\000\000\000\000\000^\000o\000\000\000\213\000\000\000\000\000\000\000\214\000\000\000\000\000\000\000\152\000\000\000i\000j\001@\002J\002I\000\000\001\184\000\000\000\000\000\000\001\185\000\000\000\000\001\198\001P\000\000\001\182\001\205\002O\000\000\001\165\000\227\002P\000\000\000\000\000k\001\199\000^\000\000\001\184\000\000\000\000\000\000\001\185\000\000\000\000\002B\003O\000\000\002R\000\000\001[\000\000\0033\000\160\001\167\001X\000\166\000\160\001Y\000\138\000\166\000\000\000\000\000\000\002T\000\000\000\000\000\000\000\000\002I\000\000\001\184\000\000\000-\001k\001\185\0002\000\000\001\182\001\205\000m\000\000\001\214\000\000\000\139\000\000\000\152\000\000\000\140\000j\000\000\000\000\000\000\000\000\000o\000\000\000\000\000\000\002B\002C\000\000\000\000\001\215\0004\002J\000\000\000\000\001\216\001\165\000\000\000\228\001\217\000\000\000k\001\198\000\000\001\218\000\000\000\000\002O\000\000\000\000\002I\002P\001\184\000\000\000\000\001\199\001\185\000\000\000\000\000\000\000\160\001\250\000\000\000\166\000\000\001\198\000\138\000\000\002R\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\199\001\182\001\205\000\000\000\000\000\000\002T\000\000\000\000\000m\002J\000\000\000\000\000\139\000\000\000\000\000\000\000\140\000\000\000\000\001\198\002B\002N\000o\001\214\002O\000\\\000\000\001\001\002P\000e\000\000\000\000\001\199\000\000\000\000\000\000\000\000\000\000\000\000\000-\000\000\001\014\000\000\001\215\002I\002R\001\184\000\000\001\216\000\000\001\185\000\000\001\217\000\000\000\000\000\000\000\000\001\218\000\000\000\000\000\000\002T\002J\001@\000\000\000\000\001\215\000\000\000\000\000^\000\000\000\000\001\198\000\000\000_\001B\000\000\002O\000`\001\214\001\230\002P\000\000\000\000\000\000\001\199\001i\000\\\000\000\000\\\000\\\000e\000\000\000e\000q\000\000\000\000\000\000\002R\001\215\000\000\000-\000\000\000i\001\216\001\182\001\205\000\000\001\217\000\160\001l\000\000\001o\001\218\002T\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002B\003[\000\000\000\211\000\000\000\236\000^\001\214\000^\000^\002J\000_\000\000\000_\000_\000`\000\000\000`\000`\000\000\001\198\000\000\000\000\000\000\002I\002O\001\184\001\215\000\134\002P\001\185\000\000\001\216\001\199\000\000\000\000\001\217\000\000\000\000\000\000\000i\001\218\000i\000i\000\000\000\000\002R\000^\000\000\000\000\000\213\000\000\000\000\000\000\000\214\000\152\000\000\000\000\000j\000\000\000\000\000\000\002T\000\000\000\000\000\000\001\182\001\205\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002m\000\000\000\000\001\214\000\227\000k\001\182\001\183\000\000\002B\004\"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\215\000\160\002o\000\000\000\166\001\216\000\000\000\138\000\000\001\217\002I\000\000\001\184\000\000\001\218\002J\001\185\000\152\000\000\000\000\000j\000\000\000j\000j\000\000\001\198\000\000\000^\000m\001\184\002O\000\000\000\139\001\185\002P\000\000\000\140\000\000\001\199\002m\000\000\000\137\000o\000\000\000k\000\000\000k\000k\000\000\000\000\000\000\002R\000\000\001\182\001\205\000\000\000\000\000\000\000\000\000\000\000\000\000\228\000\000\000\160\002\148\000\000\000\166\002T\000\000\000\138\000\000\000\138\000\136\002B\004$\000\000\000\000\000\000\000\\\000\000\000\000\000\000\000e\000\000\000\000\001\214\000\000\000\000\001\182\001\205\000m\000\000\000m\000m\000\139\000\000\000\139\002I\000\140\001\184\000\140\002J\000\000\001\185\000o\001\215\000o\000o\002B\004&\001\216\001\198\000\000\000\000\001\217\000\000\002O\000\000\000\000\001\218\002P\000\\\000^\000\000\001\199\000e\000\000\000_\001\198\001\001\000\000\000`\002I\000\000\001\184\000\000\000\000\002R\001\185\000\000\000\000\001\199\001\026\001\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002T\000\000\000\000\000i\000\\\000\000\000\000\000\000\000e\000\000\000\000\000\000\000^\000\000\000\000\000\000\000\000\000_\001\214\000\000\000\\\000`\000\000\000\000\000e\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\240\000\000\000\000\002J\000\000\000\\\001\215\000\000\000\000\000e\000\000\001\216\000\000\001\198\000i\001\217\000^\000\000\002O\000\000\001\218\000_\002P\000\000\000\000\000`\001\199\000\000\000\000\000\000\000\000\000\000\000^\000\211\000\000\000\236\002'\000_\002J\002R\000\000\000`\000\000\000\000\000\000\000\000\000\000\000\000\001\198\000^\000i\000j\002)\002O\000_\002T\000\000\002P\000`\000\000\000\000\001\199\000\000\000\000\000\000\000\000\000i\000\000\000\000\002+\000\137\000\000\000\000\001\214\002R\000k\000\000\000^\000\\\000\000\000\213\000\000\000e\000i\000\214\000\000\000\000\000\000\000\000\000\000\002T\000\000\000\000\001\215\000j\000\\\000\000\000\000\001\216\000e\000\138\000\000\001\217\000\000\000\000\000\000\000\000\001\218\001\214\000\000\000\000\000\227\000\000\000\137\000\000\000\000\000\000\000\000\000k\000\000\000\000\000m\000^\000\000\000\000\000\139\000\000\000_\001\215\000\140\000j\000`\000\000\001\216\000\000\000o\000\000\001\217\000\000\000^\000\000\000\000\001\218\000\138\000_\000\000\000j\000\000\000`\000\137\000\000\000\000\000\000\000\000\000k\002}\000i\000\000\002\150\000\000\000\000\000\000\000\000\000j\000m\000\137\000\000\000\000\000\139\000\000\000k\000\000\000\140\000i\002}\000\000\000\000\002\150\000o\000\138\000\000\000\000\000\137\000\000\000\000\000\\\000\000\000k\000\000\000e\000\000\000\228\000\000\000\000\000\000\000\138\000\000\000\000\000\000\000^\000m\000\\\000\000\002\127\000\139\000e\000\000\002\128\000\140\000\000\000\000\000\000\000\138\000\000\000o\000\000\000m\000\\\000^\000\000\000\139\000e\002\127\000\000\000\140\000\000\002\128\002\241\000\000\000^\000o\000\000\000\000\000m\000_\000\000\000j\000\139\000`\000\000\000\000\000\140\000\000\000\000\002\253\000^\000\000\000o\000\\\000\000\000_\000\000\000e\000j\000`\002\164\000\000\000\000\000\000\001\001\000k\000^\000\000\000i\000\000\000\000\000_\000\000\000\000\000\000\000`\000\000\002\164\001\018\000\000\000\000\000\000\000k\000\000\000i\000\000\000\000\000\000\000\000\000\000\000\138\000\\\000\000\000\000\000\000\000e\000\000\000^\000\000\000\000\000i\000\000\000_\000\000\000\000\002\141\000`\000\138\000\000\000\000\000\000\000m\000\000\000\000\000\000\000\139\000\000\000\\\002\142\000\140\000\000\000e\000\000\000\000\002\141\000o\000\000\000\000\000m\000\\\000\000\000i\000\139\000e\000\000\000^\000\140\002\142\000\000\003\005\000_\000\000\000o\000\000\000`\000\000\000\000\000\000\000j\000\000\000\000\000\000\000\000\000\000\000\000\003\018\000\000\000\000\000\000\000\000\000\000\000^\000\000\000\000\000j\000\000\000_\002\164\000\000\000i\000`\003!\000k\000^\000\000\000\000\000\000\000\000\000_\000\000\000j\000\000\000`\002\164\000\000\000\000\000\000\002\172\000k\000\000\000\000\000\000\000\\\000\000\000\000\000i\000e\000\138\000\000\002\164\000\000\002\197\0038\000\000\000k\000\000\002\172\000i\000\000\000\000\000\000\000j\000\000\000\138\000\000\000\000\000\000\000\000\000m\000\000\002\199\000\000\000\139\000\\\000\000\000\000\000\140\000e\000\000\000\138\002\164\000\000\000o\000\000\000m\000k\000^\000\000\000\139\000\\\003@\000_\000\140\000e\000\000\000`\000\000\000\000\000o\000j\000m\000\000\000\000\000\000\000\139\000\000\000\000\000\000\000\140\000\\\000\138\000\\\000\000\000e\000o\000e\003\170\000^\002\164\000\000\000i\000\000\000_\000k\000\000\000j\000`\000\000\003\182\000\000\000\000\000m\000\000\000^\000\000\000\139\000\000\000j\000_\000\140\000\000\000\000\000`\000\000\002\164\000o\000\000\000\000\000\138\000k\000\000\000i\000\000\000^\000\000\000^\002\164\000\000\000_\000\000\000_\000k\000`\000\000\000`\000\000\000\000\000i\000\000\000m\000\000\000\000\000\000\000\139\000\138\000\000\000\000\000\140\000\000\000\000\000\000\000\000\000\000\000o\000\\\000\000\000\138\000i\000e\000i\000\000\003\188\000\000\000\000\000\000\000m\000\000\000-\000\000\000\139\000j\000\000\000\000\000\140\000\\\000\000\000\000\000m\000e\000o\000\000\000\139\000\211\000\000\000\238\000\140\000\000\005\015\000\000\002\164\000\000\000o\003\195\000\000\000k\000\000\000\000\000\000\000^\000\000\000\000\000j\000\\\000_\000\000\000\000\000e\000`\003\204\000\000\000\000\000\000\005\020\000\000\000\000\005v\000\000\000j\000^\000\138\002\164\001U\000\000\000_\000\000\000k\000^\000`\003\218\000\213\003\232\000\000\000i\000\214\000\000\001O\002\164\000j\000\000\000j\000m\000k\000\000\000\000\000\139\000\000\000^\000\000\000\140\000\\\000\138\000_\000i\000e\000o\000`\002\164\000\000\002\164\000\000\000\227\000k\000\000\000k\000\000\000\000\000\138\000\000\000\000\000\000\000\000\000m\000\000\000\000\000\000\000\139\000\000\000\000\000\000\000\140\000i\000\000\000\000\000\000\000\000\000o\000\138\000m\000\138\000\000\000\\\000\139\000\000\000^\000e\000\140\000\000\000\000\000_\000\000\000\000\000o\000`\003\239\000\000\000\000\000\000\000m\001@\000m\000\000\000\139\000j\000\139\000\000\000\140\000\000\000\140\000\000\000\000\001P\000o\000\000\000o\000\000\000\000\000\000\000i\000\000\000\000\000\000\002\164\000j\000\000\000^\000\000\000k\000\000\000\000\000_\000\228\000\000\000\000\000`\000\000\000\000\000\000\001[\000\000\003\178\000\000\005\028\001X\000\000\000\160\001Y\000k\000\166\000\000\000\000\000j\000\138\000\000\000\000\000\000\000\000\005\021\000\000\000i\000\000\000\000\000\\\000\000\000\000\000\000\000e\000\000\000\000\000\000\005\028\000\000\000\138\000m\000\\\000k\000\000\000\139\000e\001\000\000\000\000\140\000\000\000\000\000\000\000\000\000\000\000o\000\000\005\024\000\000\000\000\000\000\000m\000\000\000\000\000\000\000\139\000j\001\001\000\138\000\140\000\000\000\000\001\002\000\000\000^\000o\001\003\000\000\000\000\000_\000\000\001\004\000\000\000`\000\000\0010\000^\000\000\000\000\000m\000k\000_\000\000\000\139\000\\\000`\000\000\000\140\000e\000\000\000\000\000\000\000\000\000o\000\000\000\\\000\000\000j\000i\000e\000\000\000\000\000\000\000\000\000\000\000\138\000\000\000\\\000\000\000\000\000i\000e\000\000\000\000\000\000\000\000\000\175\000\000\000\000\000\000\000\000\000k\000\000\000\000\000\000\000\000\000m\000\000\000^\000\000\000\139\000\000\000\000\000_\000\140\000\000\000\000\000`\000\000\000^\000o\000\000\000\000\000\000\000_\000\000\000\138\000\000\000`\000\000\000\000\000^\000\000\000\000\000\000\000\000\000_\000\000\000\000\000\\\000`\000\000\000i\000e\000\000\000\000\000\211\000m\000\236\000\000\000\000\000\139\000\000\000i\000\000\000\140\000\\\000\000\000j\000\000\000e\000o\000\000\000\000\000\000\000i\000\000\000\000\000\000\000\000\000j\000\000\000\\\000\000\000\000\000\000\000e\000\190\000\000\000\000\000\000\000\000\000k\000^\000\000\000\000\000\000\000\000\000_\000\221\000^\000\000\000`\000\213\000k\000\000\000\000\000\214\000\000\000\000\000^\000\000\000\000\000\000\000\000\000_\000\000\000\138\000\000\000`\000\000\000\211\000\211\000\236\000\238\000\000\000^\000i\000\000\000\138\000\000\000_\000j\000\000\000\227\000`\000\000\000\000\000m\000\000\000\000\000\000\000\139\000j\000i\000\\\000\140\000\000\000\000\000e\000m\000\250\000o\000\000\000\139\000j\000k\000\000\000\140\000\000\000i\000\000\001\152\000\000\000o\000^\000^\000k\000\213\000\213\000\000\000\000\000\214\000\214\001\156\000\000\000\000\000\000\000\000\000k\000\000\000\138\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000^\000\000\000\000\000\138\000\\\000_\000\000\000\000\000e\000`\000\227\000\227\000\000\000m\000\000\000\138\000\000\000\139\000j\000\\\000\000\000\140\000\000\000e\000m\000\228\000\000\000o\000\139\000\000\000\000\000\000\000\140\000\000\000i\000j\000m\001\192\000o\000\000\000\139\000\000\000k\000\000\000\140\000\\\000\000\000\000\000^\000e\000o\000j\000\000\000_\001\255\000\000\000\000\000`\000\000\000k\000\000\000\000\000\\\000^\000\000\000\000\000e\000\138\000_\000\000\002\004\000\000\000`\000\000\000\000\000k\000\000\000\000\000\000\000\000\000\000\000\000\000i\000\000\000\138\000\000\000\000\000\000\000m\000^\000\228\000\228\000\139\001\001\000_\000\000\000\140\000i\000`\000\000\000\138\000\000\000o\000\000\000\000\000m\000^\001\020\000\000\000\139\000\000\000_\000\000\000\140\000j\000`\000\000\004;\000\000\000o\000\000\000m\000\000\000i\000\000\000\139\000\\\000\000\000\000\000\140\000e\000\000\000\000\002\008\000\000\000o\000\000\000\000\000k\001\000\000i\000\\\000\000\000\000\000\000\000e\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\\\000\000\000\000\000\000\000e\001\001\001\001\000\000\000\000\000j\000\138\001\002\000\000\000\000\000\000\001\003\000\000\000^\000\000\001\022\001\004\000\000\000_\000\000\000j\000\000\000`\000\000\002\031\000\000\000\000\000m\000^\000k\000\000\000\139\000\\\000_\000\000\000\140\000g\000`\000\000\002F\000^\000o\000\000\000\000\000k\000_\000j\000i\000\\\000`\000\000\000\000\000g\000\000\000\138\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000i\000j\000\000\002\135\000\000\000\000\000\000\000\138\000k\000\000\000\000\000\000\000i\000m\000^\000\000\000\000\000\139\000\000\000_\002\153\000\140\000\000\000`\000\000\000k\000\000\000o\000m\000\000\000^\000\000\000\139\000\138\000\\\000_\000\140\000\000\000g\000`\000\000\000\000\000o\000\000\000\000\000\000\000\000\000\\\000i\000\\\000\138\000g\000\000\000g\000m\000-\000\000\000\000\000\139\000\000\000\000\000\000\000\140\000\000\000i\000j\000\000\000\000\000o\000\\\000\000\000m\000\000\000q\000\000\000\139\000\000\000\000\000^\000\140\000j\000\000\000\000\000_\002\155\000o\000\000\000`\000\000\000k\000\000\000^\000j\000^\000\000\000\000\000_\000\000\000_\003\158\000`\000\000\000`\000\000\000k\000\000\000\000\000\000\000\000\001U\000\000\004\006\000i\000^\000\138\000\000\000k\000\000\000_\000\000\000\000\000\000\000`\001O\000\000\000i\000\000\000i\000j\000\138\000\000\000\000\000\000\000\000\000\000\000m\000\000\000\000\000\000\000\139\000\000\000\138\000\\\000\140\000j\000\000\000q\000i\000\000\000o\000m\000\000\000k\000\000\000\139\000\000\000\000\000\000\000\140\000\000\000\000\000\000\000m\000\000\000o\000\000\000\139\000\000\000k\000\\\000\140\000\000\000\000\000q\000\000\000\000\000o\000l\000\000\000\000\000\000\000\\\000\000\000\000\000\000\000q\000^\000\000\000\000\000\000\000\000\000_\000j\000l\000\000\000`\001@\000\000\000m\000\000\000\\\000\000\000\000\000\151\000q\000j\000\000\000j\001P\000\000\000\000\000\000\000o\000^\000m\000\000\000k\000\\\000_\000\240\000i\000q\000`\000\000\000\000\000^\000\000\000j\000o\000k\000_\000k\000\000\000\000\000`\001[\000\000\003\214\000\000\000\000\001X\000l\000\160\001Y\000^\000\166\000\000\000i\000\000\000_\000\000\000k\000\000\000`\000l\000\211\000l\000\236\000\000\000i\000\000\000^\000m\000\211\000\\\000\236\000_\000\242\000q\000\000\000`\000\211\000\000\000\236\000\000\000m\000o\000m\000i\000\\\001\207\000\\\001\209\000q\000\000\000q\000\000\000\000\000\000\000o\000\000\000o\000\000\000\000\000\\\000i\000\000\000m\000q\000^\000j\000\000\000\213\000\000\001\182\001\203\000\214\000^\000^\000\000\000\213\000v\000\\\000_\000\214\000^\000q\000`\000\213\000\000\000\000\000\000\000\214\000^\000k\000^\000\000\000j\000_\000\211\000_\000\236\000`\000\227\000`\001\182\001\203\000\000\000^\000j\000\000\000\227\000i\000_\000\000\000\000\000\000\000`\000^\000\227\001\184\000k\000\000\000\000\001\185\000\000\000^\000i\000j\000i\000\000\000_\000\000\000k\000\000\000`\000\000\000\000\001\182\001\203\000m\000\000\000i\000^\000\000\000j\000\213\000\000\000\000\000^\000\214\001\184\000k\000\000\000x\001\185\001\182\001\203\000\000\000\000\000i\000\000\000\000\000\000\001\182\001\203\000\000\000m\000\000\000k\000\000\000\000\000\000\000\000\001\182\001\203\000\000\000\227\000\000\000m\000\000\000z\000^\000\228\001\184\000\000\000\000\000\000\001\185\000\000\000\000\000\228\000j\000|\000\000\001\182\001\203\000\000\000m\000\228\000^\000\000\001\184\000\000\000\000\000\000\001\185\000j\000^\000j\001\184\000\000\000~\000\000\001\185\000m\000k\000\000\000^\001\198\001\184\000\000\000j\000\000\001\185\000\000\000\000\000\000\000\000\000\128\000\000\000k\001\199\000k\000\000\000\000\000\000\000\000\000\000\000^\000j\001\184\000\000\000\000\000\000\001\185\000k\000\000\000\000\000\000\001\198\001\001\000\000\000\000\000\000\000\000\000\000\000\228\000\000\001\001\000\000\000\000\000m\001\199\000k\001\024\000\000\001\001\000\000\000\000\000\000\000\000\000\000\001\030\000\000\000\000\000\130\000m\000\000\000m\000\000\001 \000\000\001\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\000m\000\142\000\000\000\000\001\199\000\000\000\000\001\215\000\000\001\198\000\000\000\000\000\000\000\000\000\144\000\000\000\000\001\198\000m\000\000\000\000\001\232\001\199\000\000\000\000\000\000\000\000\001\198\000\000\000\000\001\199\000\000\000\146\001\001\000\000\000\000\000\000\000\000\001\215\000\000\001\199\000\000\000\000\000\000\000\000\000\000\000\000\001\"\001\198\000\000\000\000\000\000\001\234\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\199\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\215\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\236\000\000\000\000\000\000\001\215\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\215\000\000\000\000\000\000\000\000\000\000\001\238\000\000\000\000\000\000\001\215\000\000\000\000\000\000\001\244\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\246\000\000\000\000\000\000\000\000\000\000\000\000\001\215\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\248"))
+ ((16, "\000\183\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\021\000\000\000\135\001\148\000\000\000\137\000Y\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004v\000\000\005z\000\137\000Y\000\000\000\000\000\000\000\000\000\000\000\000\t*\000\023\006B\000\000\000\000\000\000\0014\000\000\000_\000\000\000\000\000K\016\164\000\000\000\000\000L\000\000\000\014\000\000\011\168\021\006$\250%\222$\250\006\160&\152\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011Z%\222\000\000\000\000\013P\000\000\016\216\000\000\017\226\000\000\000\000\000\000\000\000\000\166\000\000\000\218\000\000\000\000\002\136\000\000\015\202\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\132\000\000\000\000\027t\000\000&\158\000\000/J\000\0001\192\000\0007\130\000\0007\142\000\0007\154\000\0008\030\000\0008>\000\000+\206\000\000(8\000\000\000\000\000\000\000\000\000\0008J\000\0008t\000\0008\132\000\000\019\144\000\000\000\000\0312\000\000\000[\000Y\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000N\0004\000\000\000\003\000\000\000\000%~\000\0002j\000\000\000\000\000\000\000\246\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\192\000\000\000\000\000\000\000\000\000\000\000\000\014\248&\152\000\000\020\004\000\000\0234\024\020\000\000\000\000\000\000\001,\000\000!\138\000\000\000\0002\136\000\000\000\000\000\000\001\194\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0006\222\000\0007T\000\000\000\000\000\000\000\000\000\209\000\000\000\0003\024\000\000\000\000\000\000\008\190\000\015\000\000\000\000\000\000\000\000\000\000\000\000\012\224\000\000\013f\000\000\023\230\000\000\028\210\000\000 \192\000\000!P\000\000!\196\000\000#|\000\000&X\000\000-d\000\000+\210\000\000\002\182\000\0002\206\000\0004(\000\0008\130\000\000\000\000\000\000\000\000\000\000\000#3d\000\000\001\194\000\000\000\000\000W\003\178\000\000\0038\000\000\000\000\000\000\000\016\000\000\000\000\000\000'\030\000\000\000\000\000\000\000\000\000\000'~\000\000\000\000\000\000\000\000\000\000\000\000\003\178\000\000\000\000\000\000\000,\000\000\000\000\000\000\000\234\000\000\000\000\007\212\000\137\000\000\000\000\002\004\004\220\000\000\000\000\000\000\000\000\000\000\003<\000\000\013`\000\000\014,\000\000\000\000\004.\000\000\000\000\000\000\000\000\000\000\000\000\015\190\000\000\000\000\000\000\003.\000\000\000\000\000\000\000\000\006l\024\180\000\000\002\228\000\000\000\000\000T\004\252\000\000\000\000\000\000\000\000\014\252\000\000\000\000\000\000\000\000\000\000\000\000\002\138\005N\000\000\008\210\000\000\000\000\000\000\003J\000\000\012z\0005\000\000\020\210\000\000\000\000\000\000\014\148\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0003\238\000\000\030\170\000\0004\016\000\000\000\000\0004\000\000\007b\000\000\003\208$6'\162\000\000\000\000\000\000\000\019\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\000'\162\000\000\011\198\000\000\012.\017\150\000\000\000\000\000\000\004\132\000\000\".\000\000\000\00042\000\000\000\000\000\000\005\190\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0007`\000\0007d\000\000\000\000\000\000\004\022\000\000\000\000\000\000\000\000\000\000\000\000\008\\\000\000\020\188\000\000%L\000\000*\004\000\000*\154\000\000,d\000\000,\238\000\000-N\000\000.\128\000\0000d\000\000,\154\000\000\000\152\000\0002\176\000\0008\176\000\0009\022\000\000(2\000\000\000\000\000\0004\154\000\000\000\000\000\000\000\007\000\0004\178\000\000\000\000\000\0005$\000\000\000\000\003\200\000\000\024\160\000`\000\132\000\000\002Z\000\000\013:\002\"\007\244\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0005H\000\000 \230%\194\005\202\000\000\000\000\000\000,\198\000\000,\222\000\000-^\000\000( )\006\002`\000\213\006`\000\000\000\000\000\000\000\157\000\000\000\000\004\012\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0005\140\000\000\000\000\000\000\000\000\000\000\"\250\000\000)\030\000\000\000\000\000\000\000\000\000\000\000\000\014\006\000\000\004\142\000\000\000\000\000\000\000\000\006v\003\024\000\000\029T\000\000\000\000\000\000\001\014\000\000\000\000-\130\003\168\000\000\0082-\128\000\000\000\000)\152\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016j)\152\000\000\018\022\000\000\018Z\023\240\000\000\000\000\000\000\006\138\000\000#B\000\000\000\0005\194\000\000\000\000\000\000\006\240\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000* \000\000\007\222\000\000\000\0005\216\000\0006@\000\000\000\000\003\018\t\178\000\000\000\000.,\000\000\000\000\000\000\006\242\000\000\020\020\000\000\000\000\025\178\000\000\000\000\000\000\008\128\000\000\011\132\000\000\019>\000\000\0252\000\000\031\018\000\000!n\000\0008\002\000\0008\138\000\00092\000\0009>\000\0009b\000\0009\128\000\0009\178\000\000\000\000\000\000\000\000\000\000\000\000\024\002\000\000\004\020\000\000\025x\"\004\000\000\025\142\000\000\000\000\000\000\000\000\000\000\000\000\"\236\000\000\000\000\000\000\000\000\000\000\000\000\002\\\000\000\000\000\000\000\000\000\000\000\000\000\004\254\000\000\000\000#,\000\000\000\000\000\000.N\000\000\000\000\000\180\000\000\000\000\000\000$l\000\000\000\000\000\000\000\000.l\000\000\000\000\000\000\000\000\000\204\002\178\000\000/\016\000\000\000\000\000\000\000\000\025X\002\234\000\000\026,\000\000\000\000\003^\000\000/(\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\150\000\000\000\000&\202\000\000\000\000\000\000/\210\000\000\000\000\005&\000\000\000\000\014\128\000\000\026\166\000\000\000\000#\208\000\000\000\000\000\000\000W\000\000\000\000)\138\000\000\000\000\000\000\000\000/\212\000\000\000\000\000\000\000\000\003t\008r\000\000/\244\000\000\000\000\000\000\000\000\000\000\000\000\015L\000\000\000\000\006X\000\000\015\222\000\000\000W\000\000\000\000\005,+P\000\000\006v\000\000\000\000\000\000\000\000\004\022\000\000*L\000\000\027&\004\128\027\232\000\000\004\252\000\000\016\148\000\000\017`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\150\028h\001j\028\232\000\000\000\000\000\000\006\240\000\000\017\218\000\000\006\194\000\000\000\000\000W\000\196\030*\000\000\001\240\000\000\018\164\030\164\000\000\000\000\019f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\216\008\170\000\000\007\140\000\000\000\000\000\000\000\000\006j\000\000\0200\000\000\000\000\000\000 \2246v\000\000\000\000\000\000 f\000\000\000\000\000\000\000\000\013\008\005\206\000\000\000\0000 \000\000\000\000\000\000\000\000\005\244\000\000\000\000)\176\000\000\000\000\000\0000\176\000\000\000\000\001\246\000\000\000\0000\216\000\000\000\000\005\228\006\236\000\000\000\0001z\000\000\000\000\007\154!F\000\000\007\022\000\000\000\0001\156\000\000\000\000\000\000\000\000\000\000\000\000\007>\000\000\000\0003|\000\000\000\000\000\0001\190\000\000\000\000\000\000\000\000\000\000#\230\000\000\000\000\000\000\004\200\000\000\000\000\000\0001\196\000\000\000\000\006\024\008\146\000\000\000\0002>\000\000\000\000\007\190\000\000\000\000\000\000\000\000\004\022\004\216\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\198\000\000\020\172\000\000\000\000\000\0006\150\000\000\tv\000\000\000\000\000\000\004\174\000\000\000\000\005\172\021v\000\000\022.\000\000\000\000\000\000\006\132\000\000\018J\0072\023>\000\000\025\166\000\000\000\000\000\000\007\194\000\000*d\007\200+8\000\000+\162\000\000\000\000\000\000\007\208\000\000\028|\007\248\000\000\000\000\021f\003^\008 \021\224\000\000'\198\000\000\000\000\000\000\008B\000\000\030\184\008V\000\000\000\000\000\000\001\132\000\000\000\000\000\000\000\000\000\000\001\178\000\000\000\000\002\154\000\000\000;\000\000\000\000\000\000\002\246\000\000\000\000\000\000\000\000\000/\000\000\006l\002\216\001\176\000\000\000\000\002\204\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002|\001\214\000\000\000\000\004\008\000\000\000\000\000\000\006F\000\000\000\000\012B\012\164\000\000\000\000\000\000\000\000\014\170\014\214\000\025\000\000\015\196\000\000\000\000\000\000\000\000\000\000\000\000\004L\000\000\000\000\002f\000\000\000\000\003\198\000\000\000\000\tX\000\000\000\000\000\004\000\000\007\220\004\194\000\170\000\000\000\000\0007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\226\018\240\000\000\000\000\000\000\000\000\013\222\000\000\000\000\018\150\000\000\000\000\000\000\018\252\000\000\000\000\002z\019(\000\162\000\000\020\180\000\000\000\000\000\000\000\000\000\000\000\000\006R\000\000\008l\002\236\000\022\000\000\000\000\000\000\000\000\006\202\000\000\000\000\000\000\000\000\000\000\000\000\0088\000\000\000\000\005\144\000\000\008\128\004\196\000\184\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\250\000\000\000\000\018\226\020\204\000\000\000\000\000\000\000\000\0024\000\000\002\246\000\000\011\128\000\000\000\000\000\000\000\000\000\000\000\000\000r\012P\000\000\000\000\012Z\000\000\000\000\000\000\000\000\000'\000\000\013\198\000\000\000\000\000\000\000\000\004\198\000\000\000\000\000\000\003\216\000\000\000\000\001\024\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\222\005\214\000\000\000\000\000\000\012\184\000\000\000\000\021\178\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003n\000\000\000\000\000\000\000\000\000\000\000!\005\156\000\137\006\014\t&\004\028\000\000\000\000\003|\005\008\007\240\008*\000\000\000\000\000\000\000\000\000\000\000\000\023\132\000\000\000\000\000\000\000\000\018\178\003|\031$\007f\000\000\000\000\008\228\000\000\023\002\000\000\000\000\008\156\000\000\000\000\000\000\007\172\000\000\004\194\000\000\007\162\014`\000\000\000\000\000\000\000\000\003<\000\000\004.\000\000\007\196\000\000\000\000\012L\000\000\000\000\000\000\000\000\t\240\000\000\000\000\003|\t\130\000\000\023\186\000\000\000W\004\186\000\000\000\000\000\000\000\000\000\000\000\143\000\000\000\000\000\000\000\000\000\0002T\008\176\000\000\003x\000\000\000\000\000\000\000\000\000\000\001\162\000\000\nl\007n\0118\000\000\003d\011\248\000\000\tr\000\000\003\222\000\000\004Z\000\000\005\160\000\000\000\000\000\000\000\000\000\000\008\222\000\000\006\028\000\000\t\128\000\000\006\150\000\000\000W\005\252\000\000\000#\000\000\006\002\005\022\000\000\001,\000\000\008\228\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\\\000\000\t~\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005`\005F\002p\006\136\000\000\006\190\000\000\000\000\008V\t\138\000\000\005\178\000\000\000\000\000\000\000\000\006\184\000\000\000\000\000\000\000\000\000\000\006\204\0080\t\"\006\236\007&\000\000\000\000\002L\000\000\000\000\000\000\000\000\007\250\000\000\000\000"), (16, "\001\175\001\198\005i\005j\002\\\000\n\0052\001\175\001\196\004J\002\008\002\t\0053\0006\000-\004M\004\144\002\238\0054\0056\003\007\000\017\004\177\000\199\000Y\000\222\004K\000\236\000n\000\t\004N\004Z\004K\004\142\000[\005\177\004N\004Z\002,\004\178\004\181\004Z\004\137\005\178\003\008\000\016\001\177\004t\004Z\0006\001\178\000[\000\005\001\177\000Y\005n\004\185\001\178\0011\004\135\001 \004\138\004Z\000\017\001\175\001\198\002.\000[\000[\000-\000\201\004\186\000-\000\\\000\202\000\008\000\t\000]\000-\002\008\002\t\000'\002T\003U\003=\001\026\0047\000-\005>\004[\002-\000\237\001\175\001\196\001\"\004[\004\196\000\227\000[\004[\000\215\000f\001i\000\\\000\151\000&\004[\000]\003\008\005?\001\177\0014\005\022\004\197\001\178\000\165\004\200\004Z\002-\001\028\004[\001\136\0007\000'\000\239\000Y\0007\003\250\004\141\000b\003*\000f\000-\003v\002C\004\141\000[\002\\\001\177\000-\004\171\004Z\001\178\0006\001\191\004\142\004\233\001\128\000\167\002H\002\238\001\191\004\142\002I\0019\003\015\005A\001\192\001m\003\132\001\138\001\203\002\251\001\021\001\192\005B\005\\\005\200\0017\000[\005]\001:\003/\004\002\000\\\004[\004\236\0006\000]\004\187\000\216\000g\002\\\0006\000-\0003\002M\0002\000\237\0033\003\030\005_\001,\003\128\004\\\0006\002\011\003#\002C\004[\000\157\005a\000f\0035\001\207\000h\000\230\004\246\001\191\000\166\0006\000g\000\166\002H\0004\0015\003i\002I\0019\003\015\005\165\001\192\003\134\003c\001\208\001\175\001\198\000\149\000\240\001\209\003\016\001\197\000-\001\210\003Q\000h\001\191\005x\001\211\000-\000\199\004\190\000\220\0054\005y\003\007\005\002\005\003\000\241\001\192\002M\001%\000_\000\242\003>\000\157\003]\000\243\000\157\0007\004Q\003#\000\244\002\239\000\157\003t\005\007\0035\001\207\003\008\004\004\001\177\000\166\000\157\004\228\001\178\000\163\004b\004`\000\149\005\139\004\239\000g\003v\000[\0006\0007\000\201\001\208\001\175\001\198\000\202\000\176\001\209\004c\004Z\001\235\001\210\000\152\000\153\000\155\000\156\001\211\000-\0007\002\244\000h\002T\003U\003=\004<\002\238\000-\004\145\002\008\002\t\001\208\000\215\000\157\000\204\004\203\004\196\002\248\005\022\0019\000\157\000\162\001\026\000\163\005\140\001\211\000\135\001>\003\008\004R\001\177\001;\000-\004\197\001\178\000Y\004\200\004Z\003y\000d\005\208\004=\001b\000-\002\220\002]\005\172\000j\004[\005\209\004\128\000\136\003k\004\177\002C\000\137\001\027\0006\000\199\0006\000\220\000l\002\222\000\168\001\191\000\157\001e\000\149\001h\002H\004\178\004\181\004Z\002I\0019\003\015\005\142\001\192\000Y\000[\003d\001\203\000b\001\021\000\\\005B\005\\\002\\\000]\000\213\005\144\005\008\000\216\003\004\004\231\004[\004\225\004T\001\\\003\249\0006\004\195\000[\003\005\002v\000\201\002M\002\143\004C\000\202\003\030\005\146\000f\000\157\001u\0007\000\163\003#\002C\002\239\000\157\005\148\000[\0035\001\207\0006\002\n\000\\\001\191\004\186\004[\000]\004\241\002H\004H\000\215\005\186\002I\0019\003\015\004U\001\192\004>\003f\001\208\001\175\001\198\000\149\002B\001\209\003\016\000[\002x\001\210\003Q\000f\002y\004f\001\211\000-\000\221\003\178\001z\0054\005~\003=\0007\000-\002/\0006\002M\004R\000\149\002\\\003>\005(\003]\004W\001|\002v\000\017\003#\002\143\000\149\000\157\003t\0006\0035\001\207\003\008\001]\001\177\000g\000\157\004\228\001\178\000\163\0036\000-\001\175\001\245\004\229\0022\0023\0025\005\136\001\175\001\198\001\208\0007\001 \005r\002\221\001\209\005s\000\216\000h\001\210\000\157\004~\000-\000\163\001\211\002B\0054\005~\003=\002x\003\244\000\157\004\228\002y\000\163\002v\0007\000g\002\143\004\192\004\210\005\024\000'\000i\005\025\000[\001!\001\177\005\199\001^\002\134\001\178\003\008\002\210\001\177\004e\005\021\002\252\001\178\002\162\001}\000h\005\029\002\135\000j\001\012\002V\005w\005\131\000\146\001\175\001\198\004c\004Z\003\000\0006\001|\000-\000l\002B\001W\002C\001f\002x\000-\000\241\000\135\002y\0054\005~\003=\001\191\0006\002\008\002\t\004}\002H\0007\000-\000\244\002I\0019\003\015\005\132\001\192\004\253\004\254\000j\003W\000\166\003\247\000\136\005B\005\\\003\008\000\137\001\177\002K\0016\005\022\001\178\000l\001\026\005,\005\022\002\134\002\194\002\215\002\197\004\131\005\133\004[\002\165\002M\002\162\0006\000-\003>\002\135\005\134\000\149\001]\002C\003\t\003#\001\191\002\166\000\157\003(\000-\0035\001\207\001\191\001\175\001\195\000\157\001\206\002H\001\192\002\200\003\013\002I\0019\003\015\005\132\001\192\004\147\004\205\004\249\002\238\003W\001\208\005#\005B\005\\\005(\001\209\002\238\002K\002\134\001\210\003\029\002\201\001\021\002/\001\211\000\157\001\031\002\162\000\163\005S\003\005\002\135\005g\002M\0006\0006\000[\003>\001\177\005\134\001S\001G\001\178\002C\003#\000-\002\165\000\157\003(\002P\0035\001\207\002\203\001\191\003\245\001H\000\149\0021\002H\001 \002\166\0015\002I\0019\003\015\005\132\001\192\000-\000/\001s\0002\001\208\001\175\001\198\005B\005\\\001\209\000\149\003\247\002K\001\210\004>\004\005\001\180\000-\001\211\000-\004\199\005!\003_\0054\005~\003=\001\"\002\209\002M\003L\0004\004\251\003>\002\165\005\134\000\157\004~\004\197\000\163\003#\004\200\004Z\000\157\003(\0006\0035\001\207\002\166\0019\003\008\0007\001\177\004\129\000-\003*\001\178\000\157\001\029\0007\000\163\005K\0019\003*\003N\0006\005\135\001\208\001\175\001\198\001\191\0006\001\209\0006\001I\000-\001\210\0007\0007\005!\000-\001\211\000-\001\192\003\184\003Z\0054\005~\003=\005V\005\150\005W\0006\005N\005+\000\157\005O\003\222\000\163\005\154\004[\000-\000/\0000\0002\003\222\001Q\003C\000\157\001R\003\228\000\163\003\008\004\004\001\177\004b\003\143\003\005\001\178\000\149\004\180\005\173\000-\001j\002\227\001c\003\005\000-\005\143\001\175\001\198\0004\004c\004Z\000\199\004\012\000\222\004\178\004\181\004Z\002C\0019\005\179\000-\005\019\005\180\0006\0054\005~\003=\001\191\004\014\0004\001;\0007\002H\005\185\002[\005\"\002I\0019\003\015\005\132\001\192\001b\000\157\001w\0006\000\163\005.\005%\005B\005\\\003\008\001\189\001\177\002K\004X\000[\001\178\002\028\000\201\0007\005\184\004\189\000\202\005\194\000\157\001e\005\147\001h\004[\002M\003i\000\166\003L\003>\004[\005\134\004\186\003\019\0007\002C\003#\000\157\005\020\000\157\003(\000\227\0035\001\207\000\215\001\191\004Y\003q\005\"\0006\002H\0006\0006\000\166\002I\0019\003\015\005\132\001\192\005-\005%\003\160\003M\001\208\001\175\001\198\005B\005\\\001\209\003q\0006\002K\001\210\000\157\0019\0058\004\015\001\211\000-\003\137\003\168\003s\002T\003U\003=\003\005\001;\002M\002+\005{\0006\003>\004\014\005\134\000\157\0019\002C\001b\003#\000\157\0019\000\157\003(\003r\0035\001\207\001\191\001;\003\008\002{\001\177\002H\002\224\003\139\001\178\002I\0019\003\015\005\132\001\192\000\157\001e\005\196\001h\000\216\001\208\002v\005B\005\\\002\143\001\209\005\137\002K\004i\001\210\000-\000\228\001\175\001\198\001\211\004\187\000\157\001e\001l\001h\000[\000\157\002\236\002M\002\250\000\230\000-\003>\005(\005\134\002T\003U\003=\0007\003#\002\132\002\159\000\157\003(\004\022\0035\001\207\003n\002v\003\137\000[\002\139\000\240\005\201\002x\003\234\005\204\005\205\002y\0007\004\024\003\008\005(\001\177\005\213\000\000\001\208\001\178\001N\001\175\001\196\001\209\000\241\003\234\004\196\001\210\004\148\000\242\002C\0007\001\211\000\243\001H\003\138\003\185\000\000\000\244\002v\001\191\003\236\002\143\004\197\000[\002H\004\200\004Z\002x\002I\0019\003\015\002y\001\192\003\253\003c\000\000\003\194\005P\003\235\001\175\001\198\003\016\002\\\004\149\000[\002K\001\177\004\025\004 \000\199\001\178\000\222\004#\000-\005R\0006\003\204\002T\003U\003=\000\000\002M\000[\004\024\004\"\003>\002x\003]\004\"\005D\002y\0006\003#\000-\004&\000\157\003(\005;\0035\001\207\004\193\002\134\002C\003\008\004[\001\177\0019\003\005\004\206\001\178\004\024\005\202\001\191\000[\002\135\004/\000\201\002H\001I\001\208\000\202\002I\0019\003\015\001\209\001\192\003a\003c\001\210\005\189\005*\0041\0042\001\211\003\016\000-\004\194\000-\002K\005!\001q\0045\005\165\002\134\004\207\001T\000\215\001_\0041\005Q\001Q\000\000\000\157\001R\002M\000\163\002\135\004\024\003>\005)\003]\001\175\001\198\005@\001\191\003#\005Q\0004\000\157\003(\004\134\0035\001\207\005p\000\000\000-\005^\001\192\005{\002T\003U\003=\002\134\002\144\0007\005{\003\005\004\135\000\000\004\138\004Z\002v\001\208\002C\002\143\002\135\005\141\001\209\005\188\005\198\0007\001\210\005\165\001\191\000\000\003\008\001\211\001\177\002H\000\000\004\208\001\178\002I\0019\003\015\004\142\001\192\003\136\003c\005\165\005\129\005\199\001\175\001\198\005\020\003\016\000\216\005\145\000\000\002K\0037\005\203\000\000\000\149\005\020\002B\000-\000\000\000\000\002x\002T\003U\003=\002y\001\208\002M\003\229\003;\004[\003>\004\196\003]\000\238\000\000\000\000\000\000\003#\005\020\001\213\000\157\003(\000\000\0035\001\207\002\165\000\000\003\008\004\197\001\177\000\000\004\200\004Z\001\178\005\166\000\240\005\"\000\000\0019\002\168\000\157\001y\000\000\000\163\001\208\001\175\001\198\005$\005%\001\209\001;\000\000\000\000\001\210\000\000\000\241\002C\000Y\001\211\000-\000\242\000n\005\198\0054\000\243\003\007\001\191\000\000\000\000\000\244\000\000\002H\000\000\000\000\000\000\002I\0019\003\015\000\000\001\192\004\001\003c\000\157\000\000\000\157\001e\000\000\001h\003\016\003\008\004[\001\177\002K\000\000\005\168\001\178\002\134\002\194\002\195\002\197\000\000\000[\000\000\000\000\000\000\002\162\000\\\005\138\002M\002\135\000]\005\170\003>\000\000\003]\000\000\004\150\002C\000\000\003#\000\000\000\000\000\157\003(\000\000\0035\001\207\001\191\000\000\000\000\002\200\000\000\002H\000\000\000f\000\000\002I\0019\003\015\000\000\001\192\005Z\003c\000\000\000\000\000\000\001\208\001\175\001\198\003\016\000\000\001\209\000\000\002K\000\000\001\210\000\000\000\000\000\000\000\000\001\211\000-\000\000\000\000\000Y\0054\000\000\003\007\000\182\002M\000\000\000\000\000\000\003>\000\000\003]\000\000\000\000\002\165\002C\003#\000\000\000\000\000\157\003(\002v\0035\001\207\002\143\001\191\000\000\003\008\002\166\001\177\002H\000\000\004\213\001\178\002I\0019\003\015\005}\001\192\000\199\000\000\001+\004\196\001\208\000[\005|\005B\005\\\001\209\000\\\000g\005\128\001\210\000]\001\175\001\194\000\000\001\211\000\000\004\197\000\000\000\000\004\200\004Z\000\000\000[\000\000\002M\000\000\002x\000\000\003\030\005\130\002y\000h\000\000\000\000\000f\003#\001\175\001\198\000\157\003(\000[\0035\001\207\000\201\000\000\000\000\000\000\000\202\000\000\004\134\000-\000\000\000\000\000\000\0054\000[\003\007\001\177\000\000\000\000\000\000\001\178\001\208\001\175\001\193\000\000\004\135\001\209\004\138\004Z\000\000\001\210\000\000\000\215\002C\000\000\001\211\000j\004[\000\000\003\008\000\000\001\177\000\000\001\191\000\000\001\178\000\000\000\000\002H\000\000\000o\000-\002I\0019\003\015\005}\001\192\005\127\004b\000\000\001\175\001\198\004\196\000\000\005B\005\\\000[\004\196\001\177\005\128\000\000\000\000\001\178\000g\000-\004c\004Z\000\000\002T\004\197\003\007\002\134\004\200\004Z\004\197\002M\004[\004\200\004Z\003\030\005\130\000\199\000\000\000\222\002\135\000\000\003#\000h\000\000\000\157\003(\000\000\0035\001\207\003\008\005S\001\177\004b\000\000\000\000\001\178\000\199\000\216\000\220\001\191\000\000\000\000\000\000\000\000\000\000\000\000\005\013\000\000\001\208\004c\004Z\000\000\001\192\001\209\002C\000\000\000\000\001\210\000\000\004[\000[\004\007\001\211\000\201\001\191\003\131\004[\000\202\004\226\002H\000-\004[\000\000\002I\0019\003\015\005}\001\192\000\000\000\000\000[\001\175\001\198\000\201\000\000\005B\005\\\000\202\002\165\000\000\005\128\001\191\000Y\000\215\000\000\000-\000\179\000\000\000\000\002T\003\159\003\007\002\170\000\199\001\192\000\220\002M\000\000\004[\000\000\003\030\005\130\000\000\000\215\000-\000\000\0019\003#\004\156\002C\000\157\003(\000\000\0035\001\207\003\008\000\000\001\177\005K\001\191\000\000\001\178\000\000\000\000\002H\000\000\000[\000\000\002I\0019\003\015\000\\\001\192\000\000\001\208\000]\000\000\000[\000\000\001\209\000\201\003\016\000\000\001\210\000\202\003x\005U\003\129\001\211\000\000\005N\003\131\000\157\005O\000\000\000\163\000\000\001N\004o\000f\000\000\002M\004\234\000\216\004\196\003\030\003z\004\237\000\000\000\000\000\215\001H\003#\001\175\001\198\000\157\003(\004\134\0035\001\207\002R\004\197\000\000\000\216\004\200\004Z\000\000\000-\000\000\005\014\000\000\002T\003\002\003\007\004\135\000\000\004\138\004Z\000\000\001\208\0019\000\000\000\000\000\000\001\209\002C\000-\004m\001\210\000\000\000\000\000\240\003\165\001\211\000\000\001\191\000\000\003\008\000\000\001\177\002H\005\017\000\000\001\178\002I\0019\003\015\000\000\001\192\000\000\000\000\000\241\000-\000\000\001\175\001\198\000\242\003\016\000\000\000g\000\243\003x\003 \004[\0019\000\244\000\157\003\177\000-\003\183\000\216\000\241\002T\003!\003=\004[\001I\002M\000-\001N\000\000\003\030\003z\000h\000\000\000\246\000\000\000\000\003#\000\000\000\000\000\157\003(\001H\0035\001\207\000\000\000\000\003\008\000\000\001\177\004b\000\000\001T\001\178\001U\005J\000\000\001Q\000\000\000\157\001R\000\000\000\163\000\199\001\208\000\219\000\000\004c\004Z\001\209\000\000\000\000\004b\001\210\000\000\000\000\002C\000\000\001\211\000-\000/\001o\0002\000\000\000\000\000\000\001\191\000\241\000\000\004c\004Z\002H\000\000\000\000\000\000\002I\0019\003\015\000\000\001\192\000\000\000\248\000\000\000\000\000\000\001\175\001\198\000[\003\016\0004\000\201\000\000\003B\003@\000\202\0019\000\000\000\000\004\244\000-\000\000\000\000\000\000\002T\003!\003=\004[\001I\002M\000\000\000\000\004\159\003\030\003D\000\000\000\000\000\000\002C\000\000\003#\000\215\0019\000\157\003F\000\000\0035\001\207\001\191\004[\003\008\000\000\001\177\002H\005K\001P\001\178\002I\0019\003\015\001Q\001\192\000\157\001R\000\000\000\163\000\000\001\208\000\149\000Y\003\016\000\000\001\209\000d\002K\000\000\001\210\000-\000\000\001\175\001\198\001\211\000\000\000\000\000\000\000\000\005N\003E\000\157\005O\002M\000\163\004b\000-\003>\000\000\003?\002T\003!\003=\000\000\003#\000\000\000\000\000\157\003(\000\000\0035\001\207\004c\004Z\000\000\000\000\000[\000\157\001\134\000\000\000\163\000\\\000\000\0019\000\216\000]\003\008\000\000\001\177\000\000\000\000\001\208\001\178\001N\000\000\001;\001\209\000\000\000\000\004z\001\210\000\000\000\000\002C\000\000\001\211\001b\001H\000\000\000f\000\000\000\000\002v\001\191\000\000\002\138\000\000\000\000\002H\000\000\000\000\004x\002I\0019\003\015\000\000\001\192\000\000\000\000\000\157\001e\004[\001h\001\175\001\198\003\016\000\000\000\000\000\000\002K\000\000\000Y\000\000\000\000\000\000\000b\000\000\000-\000\000\000\000\000\000\002T\003U\003=\000\000\002M\000[\000\000\000\000\003>\002x\003?\000\000\000\000\002y\000\000\003#\000Y\000\000\000\157\003(\000\178\0035\001\207\000\000\000\000\002C\003\008\000\000\001\177\0019\000\000\000\000\001\178\000\000\000[\001\191\000\000\000\000\000g\000\\\002H\001I\001\208\000]\002I\0019\003\015\001\209\001\192\000\000\000\000\001\210\000\000\0012\000\000\000\000\001\211\003\016\000\000\000\000\000[\002K\000h\000\000\000\000\000\\\000\000\000f\001T\000]\001Z\000\000\000\000\001Q\000\000\000\157\001R\002M\000\163\000\000\000\000\003>\000\000\003?\001\175\001\198\000\000\000i\003#\004v\000\000\000\157\003(\000f\0035\001\207\000\000\000\000\000-\000\000\000\000\000\000\002T\003U\003=\002\134\000\000\000\000\000j\000\000\000\000\001\175\001\176\000k\000\000\001\208\002C\000\000\002\135\000\000\001\209\000\000\000l\000\000\001\210\000\000\001\191\000\000\003\008\001\211\001\177\002H\000\000\000\000\001\178\002I\0019\003\015\000\000\001\192\000\000\003\\\000\000\000\000\000\000\001\175\001\198\000g\003\016\000Y\000\000\000\000\002K\000Z\000\000\000[\000\000\001\177\000\000\000-\000\000\001\178\000\000\002T\003U\003=\000\134\000\000\002M\000\000\000\000\000h\003>\000g\003]\002v\000\000\000\000\002\137\003#\000\000\000\000\000\157\003(\000\000\0035\001\207\000\000\000\000\003\008\000\000\001\177\000\000\000[\000\000\001\178\000\135\000h\000\\\000\000\000\000\000\199\000]\000\222\000\000\000\000\001\208\000\000\000\000\002v\000\000\001\209\002\136\000\000\000\000\001\210\000\000\000j\002C\000[\001\211\000\136\000\000\002x\000\000\000\137\000f\002y\001\191\000\000\000\000\000l\000\000\002H\000\000\000\000\000\000\002I\0019\003\015\000\000\001\192\000\000\003^\000\000\000[\001\175\001\198\000\201\000\000\003\016\000\000\000\202\000[\002K\001\191\000\000\002x\000\000\000\000\000-\002y\000\000\004\134\002T\003{\003=\000-\001\192\000\000\002M\005!\000\000\000\000\003>\000\000\003]\000\000\000\215\002C\004\135\003#\004\138\004Z\000\157\003(\000\000\0035\001\207\001\191\003\008\000\000\001\177\000\000\002H\000\000\001\178\002[\002I\0019\003\015\004\134\001\192\000\000\003p\000\000\000g\000\000\001\208\000\000\004b\003\016\000\000\001\209\000\000\002K\004b\001\210\004\135\002\134\004\138\004Z\001\211\002v\003}\000\000\002\143\004c\004Z\000\000\000h\002M\002\135\004c\004Z\003>\000\000\003]\004b\000\000\000\000\004[\003#\001\175\001\198\000\157\003(\000\000\0035\001\207\000\000\000\000\000\000\002\134\000\000\004c\004Z\000-\000\216\000\000\000\000\002T\003{\003=\000Y\000\000\002\135\000[\000d\001\208\000\000\002x\000\000\000\000\001\209\002y\000\000\000\000\001\210\004[\002C\000\000\000\000\001\211\004\017\000\000\004[\003\008\000\000\001\177\001\191\000\000\004[\001\178\000\000\002H\000\000\000\000\000\000\002I\0019\003\015\000\000\001\192\000\000\000\000\000\240\0019\000[\000\000\000\000\000\000\003\016\000\\\004[\000\000\002K\000]\005$\0055\000\000\003\127\000\199\000\000\000\218\000\000\000\241\000\000\000\000\000\000\002v\000\242\002M\002\143\000\000\000\243\003>\000\000\003~\000\000\000\244\000f\000\000\003#\001\175\001\198\000\157\003(\004\162\0035\001\207\000\000\003\145\000\157\002\236\000\000\002\250\000\000\000-\000\000\000\000\000\000\002T\003!\003=\000\000\000[\002\134\000\000\000\201\001\208\000\000\000\000\000\202\002B\001\209\000\000\002C\002x\001\210\002\135\000\000\002y\000\000\001\211\000\000\004\219\001\191\003\008\000\000\001\177\000\000\002H\000\000\001\178\004\154\002I\0019\003\015\000\215\001\192\004\166\000\000\000\000\000\000\000\000\001\175\001\198\000\000\003\016\000\000\000\000\000\000\002K\001\175\001\196\000\000\000\000\000\000\000\000\000-\000g\000\000\004\175\002T\000\000\003\007\000\000\000\000\002M\000\000\000\000\000\000\003>\000\000\003~\004b\000\000\000\000\000-\003#\000\000\000\000\000\157\003(\000h\0035\001\207\004b\002\165\003\008\000Y\001\177\004c\004Z\000b\001\178\000\000\000[\000\000\001\177\000\000\000\000\002\172\001\178\004c\004Z\001\208\000\000\000\000\000i\000\000\001\209\000\000\002\134\000\000\001\210\002\161\002C\000\216\000\000\001\211\003\251\002\162\000\000\000\000\003\131\002\135\001\191\000\000\000\000\000j\001N\002H\000\000\000[\000\145\002I\0019\003\015\000\\\001\192\000\000\000\000\000]\000l\001H\001\175\001\198\000\000\003\016\000\000\004[\000-\002K\000\000\000\000\002T\000\000\000\000\000\000\000-\000\000\000\000\004[\002T\000\000\003\007\000f\000\000\002M\000\000\000\000\000\000\003>\000\000\003?\000\199\000\000\000\222\002C\003#\000\000\004)\000\157\003(\000\000\0035\001\207\001&\001\191\003\008\000\000\001\177\000\000\002H\002\165\001\178\001\191\002I\0019\003\015\000\000\001\192\000\000\000\000\000\000\005\016\001\208\000\000\002\166\001\192\003\016\001\209\000-\000\000\003x\001\210\002T\0019\000\000\000[\001\211\004\t\000\201\000\000\000\000\003\131\000\202\000\000\000\000\001I\002M\000\000\000\000\000\000\003\030\003z\000\000\001\175\001\198\000\000\000\000\003#\004)\000\000\000\157\003(\000g\0035\001\207\000\000\000\000\000-\000\215\000\000\000\000\002T\001T\003\007\001\130\004\173\000\000\001Q\000\000\000\157\001R\001\023\000\163\000\000\001\208\000\000\000h\004\217\000\000\001\209\000\000\000\000\001\208\001\210\000\000\002C\000\000\003\008\001\211\001\177\000\000\000\000\000\000\001\178\000\000\001\191\001\215\0019\003\015\000\000\002H\000\135\000\000\000\000\002I\0019\003\015\000\000\001\192\003\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\016\000\000\004\011\000\000\003x\000j\003\131\000\000\000\000\000\136\000\000\000\000\000\000\000\137\000\000\000\000\004*\000\000\000\000\000l\002M\000\216\000\000\003#\003\030\003z\000\157\003(\000\000\0035\000\000\003#\001\175\001\198\000\157\003(\000\000\0035\001\207\000\000\005=\0019\003\015\000\000\000\000\000\000\000-\005\014\000\000\000\000\002T\003!\003=\003\016\000\000\000\000\000\000\000\199\001\208\000\217\002C\000\000\000\199\001\209\000\222\000\000\000\000\001\210\000\000\000\240\001\191\000\000\001\211\000\000\000\000\002H\003\008\004,\001\177\002I\0019\003\015\001\178\001\192\003#\000\000\000\000\000\157\003(\000\241\0035\000\000\003\016\000\000\000\242\000\000\003x\002v\000\243\000\000\002\143\000[\000\000\000\244\000\201\000\000\000[\000\000\000\202\000\201\000\000\000\000\002M\000\202\000\000\000\000\003\030\003z\000\000\000\000\000\000\000\000\000\000\003#\001\175\001\198\000\157\003(\000\000\0035\001\207\000\000\005`\000\000\000\215\000\000\000\000\000\000\000-\000\215\000\000\002B\002T\003!\003=\002x\000\199\000\000\000\220\002y\001\208\002v\000\000\000\000\002w\001\209\000\000\000\000\000\000\001\210\002v\000\000\000\000\002\143\001\211\000\000\002C\000\000\003\008\000\199\001\177\000\200\000\000\000\000\001\178\000\000\001\191\000\000\000\000\000\000\000\000\002H\000\000\000\000\000\000\002I\0019\003\015\000\000\001\192\000[\000\000\000\000\000\201\000\000\000[\000\000\000\202\003\016\002x\000\000\000\000\002K\002y\002B\000\000\000\000\000\000\002x\000\000\000\000\000\000\002y\000[\000\216\000\000\000\201\000\000\002M\000\216\000\202\000\000\003>\000\215\003?\000\000\000\000\000\000\000\000\003#\000\000\000\000\000\157\003(\000\000\0035\001\207\000\000\003\140\001\175\001\198\002\134\002\194\0050\002\197\004\019\000\215\000\000\000\000\000\000\002\162\000\000\000\000\000-\002\135\000\000\001\208\002T\002C\003=\000\000\001\209\000\000\000-\001d\001\210\0002\000\240\001\191\000\000\001\211\000\000\000\000\002H\000\000\002\200\000\000\002I\0019\003\015\000\000\001\192\000\000\003\008\000\000\001\177\000\000\000\241\000\000\001\178\003\016\000\000\000\242\0004\002K\002\134\000\243\000\000\000\000\000\000\000\000\000\244\000\000\000\216\002\134\002\199\000\000\002\197\002\135\000\000\002M\000\000\002v\002\162\003>\002\143\003?\002\135\000\000\000\000\000\000\003#\000\000\002\165\000\157\003(\000\216\0035\001\207\000\000\000\000\001\175\001\198\000\000\000\000\000\000\000\000\002\166\002\200\000\000\000\000\000\000\003A\000\000\000\000\000-\000\000\002v\001\208\002T\002\143\003\007\000\000\001\209\000\000\000\000\000[\001\210\002v\000\000\002x\002\143\001\211\000\000\002y\000\000\000\000\000\000\000\000\000\000\000\199\000\241\000\222\002C\000\000\003\008\002v\001\177\000\000\002\143\000\000\001\178\000\000\001\191\000\000\000\250\002\165\000\000\002H\000\000\000\000\002B\002I\0019\003\015\002x\001\192\000\000\000\000\002y\002\166\000\000\002B\0019\000\000\003\016\002x\000\000\000\000\003\142\002y\000\000\000\000\000\000\000[\001;\000\000\000\201\000\000\000\000\002B\000\202\000\000\000\000\002x\002M\001b\000\000\002y\003>\000\000\003\144\000\000\000\000\000\000\000\000\003#\001\175\001\198\000\157\003(\000\000\0035\001\207\000\000\000\000\000\000\000\215\003\006\000\157\001e\000-\001h\000\000\000\000\002T\002\134\003\007\000\000\000\000\000\000\000\000\000\000\001\208\000\000\002C\000\000\000\000\001\209\002\135\000\000\000\000\001\210\000\000\000\000\001\191\000\000\001\211\000\000\000\000\002H\003\008\000\000\001\177\002I\0019\003\015\001\178\001\192\000\000\000\000\002\134\000\000\000\000\002\201\000\000\000\000\003\016\001\175\001\198\002\162\003\028\002\134\000\000\002\135\002\201\000\000\000\000\000\000\003\"\000\000\002\162\000-\000\000\000\000\002\135\002T\002M\003\007\000\000\002\134\003\030\003\031\002\164\000\000\002\203\000\000\000\216\003#\002\162\000\000\000\157\003(\002\135\0035\001\207\002\203\000\000\002\165\000\000\000\000\000\000\003\008\000\000\001\177\000\000\000\000\000\000\001\178\000\000\000\000\000\000\002\174\004\021\000\000\001\208\000\000\000\000\000\000\000\000\001\209\000\000\001\175\001\198\001\210\000\000\000\000\002\208\000\000\001\211\000\000\002C\000\000\002\165\000\000\000\240\000-\000\000\002\206\000\000\002T\001\191\003\007\000\000\002\165\000\000\002H\002\166\000\000\000\000\002I\0019\003\015\000\000\001\192\000\241\000\000\000\000\002\166\000\000\000\242\000Y\002\165\003\016\000\243\000n\003\008\003\028\001\177\000\244\000\000\000\000\001\178\000\000\000\000\000\000\002\166\000\000\000\000\000\000\000\000\000\000\000\000\002M\000\000\000\000\000\000\003\030\003\031\000\000\000\000\000\000\002C\000\000\003#\000\000\000\000\000\157\003(\000\000\0035\001\207\001\191\000\000\000\000\000[\000\000\002H\000\000\000\000\000\\\002I\0019\003\015\000]\001\192\000\000\000\000\000\000\001\175\001\198\001\208\000\000\000\000\003\016\000\000\001\209\000\000\003\028\000\000\001\210\000\000\000\000\000-\000\000\001\211\000\000\002T\000f\003\007\000\000\000\000\000\000\000\000\002M\000\000\000\000\000\000\003\030\003\031\000\000\000\000\000\000\000\000\000\000\003#\002C\000\000\000\157\003(\000\000\0035\001\207\003\008\000\000\001\177\001\191\000\000\000\000\001\178\000\000\002H\000\000\000\000\000\000\002I\0019\003\015\000\000\001\192\000\000\000\000\001\208\001\175\001\198\003`\000\000\001\209\003\016\000\000\000\000\001\210\003Y\000\199\000\000\000\222\001\211\000-\000\000\000\000\000\000\002T\000\000\003\007\000\000\000\000\000\000\000\000\002M\000\000\000\000\000\000\003\030\003[\000\000\000\000\000\000\000\000\000g\003#\000\000\000\000\000\157\003(\000\000\0035\001\207\003\008\000\000\001\177\000\000\000\000\000\000\001\178\000\000\000\000\000\199\000[\000\220\000\000\000\201\000\000\000h\000\000\000\202\000\000\001\208\001\175\001\198\000\000\000\000\001\209\000\000\002C\000\000\001\210\000\000\000\000\000\000\000\000\001\211\000-\000\000\001\191\000\000\002T\000\000\003\007\002H\000\000\000\215\000\000\002I\0019\003\015\000\000\001\192\000\000\000\000\000\000\000[\000\000\003X\000\201\000\000\003\016\000\000\000\202\000j\003Y\000\000\003\008\000\000\001\177\000\000\000\000\000\000\001\178\000\000\000\000\000\000\000\000\000q\000\000\000\000\002M\000\000\000\000\000\000\003\030\003[\000\000\000\000\000\215\000\000\000-\003#\002C\000\000\000\157\003(\000\000\0035\001\207\000\000\000\000\000\000\001\191\000\000\000\000\000\000\000\000\002H\000\000\000\000\000\000\002I\0019\003\015\000\000\001\192\000\000\000\000\001\208\000\000\003l\000\000\000\000\001\209\003\016\000\216\000\000\001\210\003m\000\000\000\000\000\000\001\211\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001N\002M\000\000\000\000\000\000\003\030\003o\000\000\004%\000\000\000\000\000\000\003#\002C\001H\000\157\003(\000\000\0035\001\207\000\000\000\000\000\000\001\191\000\000\000\216\000\000\000\000\002H\000\000\000\240\000\000\002I\0019\003\015\000\000\001\192\000\000\000\000\001\208\001\175\001\198\003j\000\000\001\209\003\016\000\000\000\000\001\210\003Y\000\241\000\000\000\000\001\211\000-\000\242\000\000\000\000\002T\000\243\003\007\000\000\000\000\000\000\000\244\002M\000\000\000\000\000\000\003\030\003[\000\000\000\000\000\000\000\000\000\000\003#\000\000\000\000\000\157\003(\000\000\0035\001\207\003\008\000\000\001\177\0019\000\000\000\000\001\178\000\000\000\000\000\241\000\000\000\000\000\000\000\000\000\000\001I\000\000\001\175\001\198\001\208\001\175\001\198\000\000\000\252\001\209\000\000\000\000\000\199\001\210\000\222\000\000\000-\000\000\001\211\000\000\002T\003w\003\007\000\000\000\000\002;\004\006\001T\000\000\002X\000\000\000\000\001Q\000\000\000\157\001R\000\000\000\163\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\008\000\000\001\177\002B\000\000\001\177\001\178\000\000\000\000\001\178\000[\002v\000\000\000\201\002\143\000\000\000\000\000\202\000\000\000\000\001\175\001\198\000\000\000\000\000\000\000\000\000\000\000Y\000\000\002C\0059\000d\000\000\000\000\000-\000\000\003|\000\000\002T\001\191\003\007\000\000\000\000\000\215\002H\000\000\000\000\000\000\002I\0019\003\015\000\000\001\192\000\000\000\000\000[\000\000\000\000\000\000\002x\000\000\003\016\000\000\002y\003\008\003x\001\177\000\000\000\000\000\000\001\178\000[\000\000\000\000\000\000\000\000\000\\\000\000\000\000\000\000\000]\002M\000\000\000\000\000\000\003\030\003z\000\000\000\000\000\000\002C\000\000\003#\002C\000\000\000\157\003(\000\000\0035\001\207\001\191\000\000\000\000\001\191\000f\002H\000\000\000\000\002H\002I\0019\003\015\002I\001\192\000\000\000\000\001\192\000\000\000\000\001\208\000\000\000\000\003\016\000\216\001\209\000\000\003x\000\000\001\210\002K\000\000\000\000\000\000\001\211\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002M\000\000\000\000\002M\003\030\003z\000\000\0044\000\000\000\000\000\000\003#\002C\002\134\000\157\003(\000\000\0035\001\207\000\000\000\000\001\207\001\191\000\000\000\000\000\000\002\135\002H\000\000\000\240\000\000\002I\0019\003\015\000\000\001\192\000\000\000\000\001\208\001\175\001\198\001\208\000g\001\209\003\016\000\000\001\209\001\210\005:\000\241\001\210\000\000\001\211\000-\000\242\001\211\000\000\003\158\000\243\000\000\000\000\000\000\000\000\000\244\002M\000\000\000h\000\000\003\030\005<\000\000\000\000\000\000\000\000\000\000\003#\003\190\000\000\000\157\003(\000\000\0035\001\207\003\193\000\199\001\177\000\220\000\000\000\000\001\178\000\000\000i\000\000\000\000\000\000\002\165\000\000\000\000\000\000\000\000\001\175\001\198\001\208\001\175\001\198\003\199\000\000\001\209\000\000\002\176\000\000\001\210\000j\000\000\000-\000\000\001\211\000\148\003\158\000\000\000\000\000\000\000\000\002;\003R\000\000\000l\000\000\000[\000\000\000\000\000\201\000\000\003\237\000\000\000\202\001\203\003\241\001\021\000\000\000\000\000\000\000\000\000\000\003\193\000\000\001\177\002B\000\000\001\177\001\178\001\175\001\198\001\178\000\000\000\000\000\199\000\000\000\220\000\000\000\000\000\215\000\000\000\000\000\000\000-\003\199\000\000\000\000\003\158\000\000\002v\000\000\000\000\002\143\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\191\000\000\000Y\000\000\000\000\003\192\000b\000\000\000\000\000\000\0019\003\200\003\193\001\192\001\177\000\000\000-\000[\001\178\000\000\000\201\000\000\003\201\000\000\000\202\000\000\003\239\000\000\000\000\000\000\000\000\000\199\000[\000\220\003\199\000\000\002x\000\000\000\000\000\000\002y\000\000\000\000\000\000\000\000\000\000\000[\000\000\000\000\000\000\000\215\000\\\000\000\003\215\002C\000]\000\157\003\240\000\216\003\227\001\207\001\191\000\000\002v\001\191\000\000\002\143\000\000\000\000\002H\000\000\0019\003\200\002I\001\192\000[\000\000\001\192\000\201\000f\001\208\000\000\000\202\003\201\000Y\001\209\000\000\003\213\000b\001\210\002K\000\000\000\000\000\000\001\211\000\000\000\000\000\000\000-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002M\002B\000\215\000\000\000\000\002x\001\191\000\000\003\215\002y\000\000\000\157\003\220\000\000\003\227\001\207\0019\003\200\001\207\001\192\000\241\000\000\000[\000\000\000\216\000\000\002\134\000\\\003\201\000\000\000\000\000]\003\213\000\000\000\254\001\208\000\000\000\000\001\208\002\135\001\209\000\000\000\000\001\209\001\210\000\000\000\000\001\210\000\000\001\211\000\149\000\000\001\211\000g\000\000\000f\000\000\000\000\000\000\003\215\000\000\000\000\000\157\003\220\000\000\003\227\001\207\000\000\000\000\000\152\000\206\000\155\000\156\002v\000\000\000\000\002\143\000h\000\000\000\000\000Y\000\000\000\216\000\000\000b\000\000\001\208\000\000\000\000\000\000\000\000\001\209\000\241\000\000\000-\001\210\000\157\000\162\000\000\000\163\001\211\002\134\000\135\000\000\002\204\000\000\001\000\000\000\002\165\000\000\002\162\000\000\000\000\000\000\002\135\000\000\000Y\002B\000\000\000-\000b\002x\002\178\000j\000[\002y\000\000\000\136\000\000\000\\\000-\000\137\000\149\000]\000\000\000g\000\000\000l\000\000\000\168\000\000\000\000\000\000\000\000\000\000\000\199\000\000\000\220\000\000\000\000\000\241\000\152\001\182\000\155\000\156\000\000\000\000\000f\000\000\000h\000[\000\000\000\000\000\000\001\002\000\\\000\000\000\000\000\000\000]\000\000\000\000\001N\000\000\000\000\000\000\002\207\000\000\000\157\000\162\000\000\000\163\000\000\002\165\000\135\000\000\001H\000Y\000\000\000[\000\000\000b\000\201\000f\000\000\000\000\000\202\002\166\000Y\000\000\000\000\000-\000b\000\000\000\000\000j\000\000\000\000\000\000\000\136\000\000\000\000\000-\000\137\000\000\000\000\000\000\002\134\000\000\000l\002\213\000\168\000\215\000\000\000\000\000\000\002\162\000\000\000\000\000\000\002\135\000[\000\000\000\000\000\149\000\000\000\\\000g\001\175\001\198\000]\000\000\000[\000\000\000\000\000\000\000\000\000\\\000\000\000\000\000\000\000]\000\000\000\152\002E\000\155\000\156\000\000\000\000\0019\000\000\000h\000\000\000\000\000f\000\000\000\000\000\000\000\000\000\000\000\149\001I\000\000\000g\000\000\000f\000\000\000\000\000\000\000-\000\157\000\162\000[\000\163\001\177\000\000\000\135\000\000\001\178\000\152\002}\000\155\000\156\000\000\000\000\000\000\000\000\000h\001T\002\165\002\230\000\000\000\216\001Q\000\000\000\157\001R\000j\000\163\000\000\000\000\000\136\000\000\002\166\000\000\000\137\000\157\000\162\000\000\000\163\000\000\000l\000\135\000\168\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001N\000\000\000\000\001\203\000Y\000\000\000\000\000\000\000b\000\149\000\000\000j\000g\000\000\001H\000\136\000\000\000\000\000-\000\137\000\149\000\000\000\000\000g\000\000\000l\000\000\000\168\000\152\003%\000\155\000\156\000\000\000\000\000\000\000\000\000h\000\000\000\241\000\152\003\217\000\155\000\156\000\000\000\000\001\175\001\196\000h\000[\000\000\001\191\000\000\001\004\000\\\000\000\000\157\000\162\000]\000\163\000\000\000\000\000\135\000\000\001\192\000\000\000\000\000\157\000\162\000\000\000\163\000Y\000\000\000\135\000\000\000b\000\000\001\205\000\000\000\000\000\000\000\000\000f\000j\000\000\000-\000\000\000\136\0019\000\000\000[\000\137\001\177\000\000\000j\000\000\001\178\000l\000\136\000\168\001I\000\000\000\137\001\019\001\021\001\175\001\198\000\000\000l\000\000\000\168\001\207\000\000\000\000\000\000\000[\000\000\000\000\000\000\000Y\000\\\000\000\000\000\000b\000]\003I\000\000\001T\000\000\002\241\000\000\001\208\001Q\000-\000\157\001R\001\209\000\163\000\000\000\000\001\210\000\000\000\000\000\000\000\000\001\211\000\000\000\000\000f\002B\000\000\001\177\000\000\000\000\000\000\001\178\000\000\000\000\000\000\000\149\000\000\000\000\000g\000[\000\000\000\000\000\000\000\000\000\\\000\000\000\000\000\000\000]\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\199\001\023\000\220\000\000\000\000\000\000\000h\000\000\000\000\000\000\001\191\000\000\000\000\000\000\000\000\000\000\000f\000\000\003O\000\000\000\000\000\000\001\203\001\192\000\000\000\157\001\029\000\000\000\163\000\000\000\000\000\135\000Y\000\000\000\000\000Y\000b\000\000\000\000\000n\000\000\000\000\000\000\000\000\000[\000\149\000-\000\201\000g\000\000\000\000\000\202\000j\000\000\000\000\000\000\000\136\000\000\000\000\002C\000\137\000\000\000\000\000\000\000\170\000\000\000l\000\156\000\000\001\191\000\000\000-\000h\000\000\002H\000\000\000[\000\215\002I\000[\000\000\000\\\001\192\000\000\000\\\000]\000\000\000\000\000]\000\000\001\208\000\157\000\162\000\149\000\163\003Q\000g\000\135\000\000\000Y\000\000\000\000\000\000\000b\001\217\000\000\000\000\000\000\000\000\000f\000\000\002M\000f\000-\000\000\000\180\000\000\000\000\000j\000\000\000h\000\000\000\136\000\000\001N\000\000\000\137\000\000\000\000\001\207\000\000\000\000\000l\000\000\000\168\000\000\000\000\000\000\001H\000\157\001#\000\000\000\163\000[\000\000\000\135\000\000\000Y\000\\\001\208\000\000\000b\000]\000\000\001\209\000\000\000\000\000\216\001\210\000\000\000\000\000-\000\000\001\211\000\000\000Y\000j\000\000\000\000\000b\000\136\000\000\000\000\000\000\000\137\000\000\000f\000\000\000\000\000-\000l\000\000\000\000\000\000\000\000\000\000\000\149\000\000\000\000\000g\000\000\000[\000g\000\000\000\000\000\000\000\\\000-\000\000\000\000\000]\002T\000\000\000\000\000\000\000\000\000\000\000\000\000\183\000[\000\000\0019\000\000\000h\000\\\000\000\000h\000\000\000]\000\000\000\000\000\000\000\000\001I\000f\000\241\000\000\004)\001\175\001\198\000\000\000\000\000\157\000\185\000\000\000\163\000\000\000Y\000\135\001\006\000Y\000b\000f\000\000\000n\000\000\000\000\000\000\002;\003H\001T\000-\003\022\000\149\000\000\001Q\000g\000\157\001R\000j\000\163\000\000\000j\000\136\000\000\000\000\000\000\000\137\000\000\000\000\000\000\000\000\002B\000l\001\177\000\183\000s\000\000\001\178\000\000\000h\000[\000\000\000\000\000[\000\000\000\\\000\000\000\000\000\\\000]\000\000\000\000\000]\000\000\000\000\000\000\000\000\000\000\000\157\001)\000\149\000\163\000\000\000g\000\135\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000f\000\000\000\000\000f\000\000\000\149\000\000\000\000\000g\000\180\000\000\000\000\000j\000\000\000h\000\000\000\136\000\000\000\000\000\000\000\137\000\000\000\000\0019\003\015\000\000\000l\001\158\000\000\001\175\001\198\000\000\000h\000\157\001/\003\016\000\163\000\000\000\000\000\135\000\000\001\175\001\198\000\000\000\000\000\000\000\000\000\000\002C\002;\002<\000\157\001\160\000\000\000\163\000\000\000\000\000\135\001\191\004.\000j\002;\002G\002H\000\136\000\000\003#\002I\000\137\000\157\003(\001\192\0035\002B\000l\001\177\000\000\000\149\000j\001\178\000g\000\000\000\136\000g\002K\002B\000\137\001\177\000\000\000\000\000\000\001\178\000l\000\000\000\000\000\000\000\000\000\000\000\000\001\158\002M\000\000\000Y\000\000\000h\000\000\000b\000h\000\000\000-\000\000\000\000\000\000\000\000\000\000\000\000\000-\000\000\001\207\000\000\000\000\000\000\000\000\000\157\001\243\000\000\000\163\000\000\000-\000\135\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000\000\001\208\000\000\000\000\000\000\000\000\001\209\000\000\000\000\000[\001\210\000\000\000\000\000j\000\\\001\211\000j\000\136\000]\001\175\001\196\000\137\000\000\000\000\000\000\001N\002C\000l\000\000\000\000\000l\000\000\000\000\000Y\000\000\000\000\001\191\000b\002C\001H\000\000\002H\000f\000\000\001N\002I\000\000\000-\001\191\001\192\000\000\000\000\000\000\002H\000\000\001\175\001\198\002I\001H\000\000\000\000\001\192\002K\000[\000\000\001\177\000\000\001\175\001\198\001\178\000\000\000\000\000\000\000\000\002K\002;\003T\000[\002M\000\000\000\000\000\000\000\\\000\000\000\000\000\000\000]\002;\004\027\000\000\002M\000\000\000\000\000\000\001\175\001\196\001\207\000\000\000\000\002B\000\000\001\177\000\000\000\000\000\000\001\178\000\000\000\000\001\207\000\000\000f\002B\0019\001\177\000\000\000\000\001\208\001\178\000\000\000\149\000\000\001\209\000g\000\000\001I\001\210\000\000\000\000\001\208\000\000\001\211\0019\000\000\001\209\000\000\000\000\000\000\001\210\000[\000\000\001\177\002f\001\211\001I\001\178\000\000\000h\000\000\000\000\000\000\000\000\001T\000\000\003,\000\000\000\000\001Q\000\000\000\157\001R\000\000\000\163\000\000\001\191\000\000\000\157\002h\000\000\000\163\000\000\001T\000\135\003\171\001\175\001\198\001Q\001\192\000\157\001R\000\000\000\163\000\000\000\000\000\000\000\000\001\175\001\198\000\149\000\000\002C\000g\000\000\000j\002;\004\029\000\000\000\136\000\000\000\000\001\191\000\137\002C\000\000\000\000\002H\003K\000l\000\000\002I\002f\000\000\001\191\001\192\000\000\000h\000\000\002H\002B\000\000\001\177\002I\000\000\000\000\001\178\001\192\002K\001\175\001\198\000\000\002B\000\000\001\177\000\000\000\157\002\141\001\178\000\163\002K\001\191\000\135\000\000\002M\000\000\001\208\000\000\000\000\002;\004\031\000Y\000\000\000Y\001\192\000b\002M\000b\000\000\000\000\001\219\000\000\001\207\000j\000\000\000\000\000\000\000\136\000\000\000\000\000\000\000\137\000\000\002B\001\207\001\177\000\000\000l\000\000\001\178\000\000\000\000\001\208\000\000\000\000\000\000\000\000\001\209\000\000\000\000\000\000\001\210\000\000\000\000\001\208\000[\001\211\000[\000\000\001\209\000\\\000\000\000\\\001\210\000]\000\000\000]\000\000\001\211\000\000\002C\000\000\000\000\000\000\000\131\000\000\001\n\000\000\000\000\000\000\001\191\001\208\002C\000\000\000\000\002H\001\175\001\196\000f\002I\000f\000\000\001\191\001\192\000\000\001\221\000\000\002H\000\000\000\000\000\000\002I\000\000\000\000\000\000\001\192\002K\000\000\000\000\000\000\000\000\000\000\000\000\000Y\000\000\000\000\000\000\000b\002K\000\000\000\000\000\000\002M\002C\000\000\000\000\000\000\000\000\000\000\000\000\000[\000\000\001\177\001\191\002M\000Y\001\178\000\000\002H\000b\001\207\000\000\002I\000\000\000\000\000\000\001\192\000Y\000\000\000\000\000\000\000b\001\207\000\000\000\000\001\175\001\196\000[\000\000\002K\001\208\000\000\000\\\000\000\000\000\001\209\000]\000\000\000g\001\210\000g\000\000\001\208\000\000\001\211\002M\001\233\001\209\000\000\000[\000\000\001\210\000\000\000\000\000\\\000\000\001\211\000\134\000]\000\134\000f\000[\000h\001\207\000h\000\000\000\\\000\000\002 \000[\000]\001\177\000\000\001\175\001\196\001\178\000\000\000\000\000\000\000\000\002\"\000Y\000f\001\208\000\199\000b\000\220\000\135\001\209\000\135\000\000\000\000\001\210\000\000\000f\000\000\000\000\001\211\000Y\000Y\001\191\000\000\000b\000b\000\000\000\000\000\000\000\000\000j\000\000\000j\000\000\000\136\001\192\000\136\000\000\000\137\000[\000\137\001\177\000\000\000\000\000l\001\178\000l\000[\000\000\000\000\000[\000\000\000\\\000\201\000\000\000\000\000]\000\202\000\000\000\000\000\000\000\000\000g\000\000\000[\000[\002$\000\000\000\000\000\\\000\\\000\000\000\000\000]\000]\000\000\000\000\000\000\000\000\000\000\000f\000\134\000\000\000\215\000g\000\000\000h\000\000\000\000\000\000\000\000\001\191\000\000\000\000\000\000\000\000\000g\000f\000f\000\000\000\000\000\000\001\208\000\134\001\192\000\000\000Y\000\000\000h\000\000\000b\000\135\000\000\000\000\000\000\000\134\001\223\000\000\002c\000\000\000h\000\000\000\000\000Y\000\000\000\000\000\000\000b\000\000\000\000\000\000\000\000\000j\000\135\000\000\000\000\000\136\000\000\000Y\001\191\000\137\000\000\000b\000\000\000\000\000\135\000l\000\000\001\175\001\196\000[\000\000\001\192\000\000\000j\000\\\000\000\000\000\000\136\000]\000g\000\000\000\137\000\216\000\000\000\000\000j\000[\000l\002\217\000\136\001\208\000\\\000\000\000\137\000\000\000]\000g\000g\000\134\000l\000\000\000[\000f\000h\001\225\000\000\000\\\000\000\000\000\000\000\000]\000[\000\000\001\177\000\000\001\023\002\157\001\178\000\000\000f\000h\000h\000\000\000\000\000\000\000\000\000\000\000\000\000\135\000\000\000\000\000\000\000\000\000\000\000f\000\000\000\000\000\000\001\208\000Y\000\000\000\000\000\000\000b\000\000\000\135\000\135\000\000\000\000\000j\000\241\000Y\001\227\000\136\000\000\000b\000\000\000\137\000\000\000\000\000\000\000\000\000\000\000l\001\008\000\000\000j\000j\000Y\000\000\000\136\000\136\000n\002\155\000\137\000\137\000\000\000\000\000\000\000\000\000l\000l\000g\000[\000\000\000\000\000\000\000\000\000\\\000\000\002\234\000\000\000]\000\000\000\000\000[\000\000\000\000\000\000\000g\000\\\002\157\000\000\000\000\000]\002\246\000h\000\000\000\000\000\000\000\000\001\191\000[\000\000\000g\000\000\000f\000\\\002\157\000\000\000\000\000]\000\000\000h\001\192\000\000\000\000\000\000\000f\000\000\000\000\000\135\000\000\002\157\000\000\000\000\000Y\000Y\000h\000\000\000b\000b\000\000\000\000\000\000\000f\000\000\000\000\000\135\000\000\000\000\000\000\000j\000Y\000\000\000\000\000\136\000b\000\000\000\000\000\137\000\000\000\000\000\135\000\000\000\000\000l\000\000\000\000\000j\000\000\000\000\000\000\000\136\000\000\000Y\000\000\000\137\000\000\000b\000[\000[\000\000\000l\000j\000\\\000\\\002\254\000\136\000]\000]\001\208\000\137\000\000\000\000\000\000\000g\000[\000l\003\011\000\000\000\000\000\\\000\000\000\000\001\229\000]\000\000\000g\001\175\001\196\000\000\000\000\000f\000f\002\157\000\000\000\000\000\000\000[\000h\000\000\000\000\000\000\000\\\000g\000\000\002\157\000]\000\000\000f\000\000\000h\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\135\000\000\000Y\000\000\000h\000\000\000b\000f\000[\000\000\001\177\000\000\000\135\000\000\001\178\000\000\000\000\000\000\000\000\000\000\000\000\000j\000Y\000\000\000\000\000\136\000b\000\000\000\000\000\137\000\000\000\000\000\000\000j\000\000\000l\000\000\000\136\000\000\003\026\0031\000\137\000\000\000\000\000\000\000\000\000[\000l\000g\000g\000j\000\\\000\000\000\000\000\000\000]\0039\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000u\000g\000[\002\157\002\157\000\000\000\000\000\\\000h\000h\000\000\000]\000\000\000\000\003\163\000f\000\000\000\000\000\000\000\000\002\157\000\000\000\000\000g\000\000\000h\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\135\000\135\000f\000\000\000\000\000\000\000Y\000\000\000\000\002\157\000b\001\191\000\000\000\000\000h\000\000\000\000\000\135\000\000\000\000\000\000\000j\000j\000Y\001\192\000\136\000\136\000b\000\000\000\137\000\137\000\000\000\000\000\000\000\000\000l\000l\000\000\000j\000\135\000Y\000Y\000\136\000Y\000b\000n\000\137\000b\000\000\000\000\000[\000\000\000l\003\175\000\000\000\\\000\000\000\000\000\000\000]\000j\000\000\000g\000\000\000\136\000\000\000\000\000[\000\137\000\000\000\000\000\000\000\\\003\181\000l\000\000\000]\000\000\000\000\000\000\000\000\002\157\000g\000f\000[\000[\000h\000[\000\000\000\\\000\\\001\208\000\\\000]\000]\000\000\000]\000\000\000\000\000\000\000f\002\157\000\000\000\000\000Y\001\231\000h\000\000\000b\000\000\000\000\000\135\000\000\000\000\000\000\000Y\000\000\000f\000f\000b\000f\000\000\000\000\000\000\000\000\000\000\000Y\000\000\005o\000\000\000b\000\135\000j\000\000\000\000\000\000\000\136\000\000\000\000\000\000\000\137\000Y\000\000\000\000\000\000\000b\000l\000\000\000[\000\000\000\000\000\000\000j\000\\\003\188\000\000\000\136\000]\000\000\000[\000\137\001\175\001\196\000g\000\\\000\000\000l\000\000\000]\000\000\000[\003\197\000\000\000\000\000\000\000\\\000\199\000\000\000\220\000]\000g\000f\002\157\000\000\000\000\000[\000\000\000h\003\211\000\000\000\\\003\225\000f\000\000\000]\000\000\000\000\000g\000g\002\157\000g\000\000\000\000\000f\000h\000[\000\000\001\177\000\000\000\000\000\000\001\178\000\135\000Y\000\000\000\000\002\157\000b\000f\002\157\000[\000h\000h\000\201\000h\000\000\000\000\000\202\000\000\000\135\000\000\000\000\000\000\000j\000\000\000\000\000\000\000\136\000\000\000\000\000\000\000\137\000\000\000\000\000\000\000\000\000\135\000l\000\000\000\135\000j\000Y\003\232\000\215\000\136\000b\000\000\000[\000\137\000\000\000\000\000g\000\\\000\000\000l\000\000\000]\000j\000j\000\000\000j\000\136\000g\000\000\000\136\000\137\000\000\000-\000\137\000\000\002\157\000l\000w\000g\000l\000h\000\000\000\000\000\000\000\000\000f\005\021\000\000\000\000\000\000\000[\000h\000\000\000g\000\000\000\\\000\000\000\172\000\000\000]\001\191\000\000\000h\000\000\000\000\000\135\000\000\000\000\000\000\000\000\000\000\000\000\000\209\001\192\000\000\000Y\000\135\000h\000\000\000b\000\000\000\000\000\000\000f\000\000\001N\000j\000\135\000\216\000\000\000\136\000\000\000Y\000\000\000\137\000\000\000b\000j\000\000\001H\000l\000\136\000\135\000\000\000\199\000\137\000\220\000\000\000j\000Y\000\000\000l\000\136\000b\000\000\000\000\000\137\000\000\000\000\000[\000\000\000\000\000l\000j\000\\\000g\000\000\000\136\000]\000\000\000\000\000\137\000\000\000\000\000\000\000\000\000[\000l\000\000\000\000\001\208\000\\\000\000\000\000\000\234\000]\000\000\000\000\000[\000h\000\000\000\201\000f\000[\001\237\000\202\000\241\000\000\000\\\000\000\000\000\000Y\000]\000g\000\000\000b\000\000\000\000\000\000\000f\001\014\000\000\0019\000Y\000\135\000\000\000\000\000b\000\000\000\000\000\000\000\215\001\025\000\000\001I\000\000\000f\000h\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000j\000\000\000\000\000\000\000\136\000\000\000\000\000\000\000\137\000\000\000[\000\000\000\000\000\000\000l\000\\\001T\000\135\003\207\000]\000\000\001Q\000[\000\157\001R\000\000\000\163\000\\\000\000\000\000\000\000\000]\000\000\000\000\000\000\000Y\000\000\000g\000j\000b\000\000\000\000\000\136\000f\000\000\000\000\000\137\000\000\000\000\000\000\000\000\000\000\000l\000Y\000g\000f\001\145\000b\000\000\000\000\000\000\000h\000\000\000\000\000\000\000\000\000\216\000\000\000\000\000\000\000\000\000g\000\000\001\149\000\000\000\000\000\000\000\000\000h\000[\000\000\000\000\000\000\000\000\000\\\000\000\000\135\000Y\000]\000\000\001\185\000b\000\000\000\000\000\000\000h\000\000\000[\000\000\000\000\000\000\000\000\000\\\000\135\000\000\000\000\000]\000j\000\000\000\000\000\000\000\136\000f\000\000\000Y\000\137\000\000\000\000\000b\000\000\000\135\000l\000\000\000g\000j\000Y\000\000\000\000\000\136\000b\000f\000[\000\137\000\000\000\241\000g\000\\\000\000\000l\000\000\000]\000j\001\248\000\000\000\000\000\136\000\000\000h\001\016\000\137\000\000\000\000\000\000\000\000\001\253\000l\000\000\000\000\000[\000h\000\000\000\000\000\000\000\\\000f\000\000\000\000\000]\000\000\000[\000\000\000\000\000\135\000\000\000\\\000\000\000\000\000Y\000]\000\000\000\000\000b\000\000\000\000\000\135\000\000\000\000\000\000\000\000\000\000\000\000\000f\000g\000j\000\000\000\000\000\000\000\136\000\000\000\000\000\000\000\137\000f\000\000\000Y\000j\000\000\000l\000b\000\136\000g\002\001\000\000\000\137\000\000\000\000\000h\000\000\000\000\000l\000Y\000[\000\000\000\000\000b\000\000\000\\\000\000\000\000\002\024\000]\000\000\000\000\000\000\000h\000\000\000\000\000\000\000\000\000\000\000\000\000\135\000\000\000\000\000g\000\000\000\000\000\000\000[\000\000\000\000\000\000\000\000\000\\\000f\000\000\000Y\000]\000\000\000\135\000d\000\000\000j\002?\000[\000\000\000\136\000\000\000h\000\\\000\137\000g\000\000\000]\000\000\000\000\000l\000\000\000\000\000\000\000j\000f\000g\000\000\000\136\000\000\000\000\000\000\000\137\000\000\002\128\000\000\000\000\000\135\000l\000h\000\000\000f\000\000\000\000\000[\002\146\000\000\000\000\000\000\000\\\000h\000\000\000\000\000]\000\000\000\000\000\000\000\000\000j\000Y\000\000\000\000\000\136\000d\000\135\000Y\000\137\000Y\000\000\000d\000\000\000d\000l\000\000\000\000\000\135\000\000\000f\000g\000\000\000\000\000\000\000Y\000\000\000\000\000j\000n\000\000\000Y\000\136\000\000\000\000\000n\000\137\000Y\000\000\000j\002\148\000n\000l\000\136\000\000\000h\000[\000\137\000g\000\000\000\000\000\\\000[\000l\000[\000]\000\000\000\\\000\000\000\\\000\000\000]\000\000\000]\000g\000\000\000\000\003\151\000\000\000[\000\135\000\000\000h\000\000\000\\\000[\000\000\000\000\000]\000f\000\\\000[\000\000\003\255\000]\000f\000\\\000f\000h\002v\000]\000j\002\143\000\000\000\000\000\136\000\000\000\135\000\000\000\137\000g\000\000\000f\000Y\000\000\000l\000\000\000n\000f\000\000\000\000\000\000\000\000\000\135\000f\000\000\000\000\000\000\000j\000Y\000\000\000\000\000\136\000n\000h\000Y\000\137\000\000\000\000\000n\000\000\000\000\000l\000[\000j\000\000\000\000\002x\000\136\000\000\000\000\002y\000\137\000\000\000\000\000\000\000Y\000[\000l\000i\000n\000\000\000\\\000\199\000Y\000\220\000]\002v\000n\000g\002\143\000\000\000\000\000[\000\000\000g\000\000\000g\000\\\000[\000j\000\000\000]\000\000\000\\\000\224\001\175\001\196\000]\000\000\000f\000\000\000g\000h\000l\000\000\000\000\000\000\000g\000h\000[\000h\000\000\000\000\000g\000\\\000f\000[\000[\000]\000\201\000[\000f\000\\\000\202\002x\000h\000]\000i\002y\000\000\000\000\000h\000\000\000i\000\000\000i\000\000\000h\000\000\000[\000\000\001\177\000f\000\000\000\000\001\178\001\175\001\196\000j\000\215\000f\000\000\002\134\000\226\000j\000\000\000j\000\000\000\000\001\200\002v\001\202\000l\002\143\000\000\002\135\002v\000\000\000l\002\143\000l\000j\000\000\000\000\000\000\000\000\000\000\000j\000\000\000g\000\000\000\000\000\000\000j\002v\000y\000\000\002\143\000\000\000\000\000[\000{\001\177\000\000\000\000\000g\001\178\000}\000\000\002v\000\000\000g\002\143\000h\000[\000\000\000\000\000\000\002x\000\000\000[\000\000\002y\000\000\002x\000\000\000\000\000\000\002y\000h\002\134\000\000\000g\000\000\002v\000h\000\000\002\143\000[\000\216\000g\000\000\002x\002\135\002\165\000\000\002y\000\000\000\000\001\191\000\000\000\000\000\000\000[\000\000\000\000\000h\002x\002\180\000j\000\000\002y\001\192\000\000\000h\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\000\000\000j\000\000\000\000\000[\000\000\000\000\000j\002x\000\000\000\000\000\000\002y\000\000\000\000\000\129\000\000\000\000\000\000\000\000\000\000\000\139\000\000\000\000\000\000\000\000\001\191\000\000\000j\000\000\000\000\000\000\000\000\000\241\000\000\000\000\000j\000\000\002\165\001\192\002\134\000\000\000\141\000\000\000\000\000\000\002\134\001\018\000\000\000\000\000\143\000\000\002\182\002\135\000\000\001\208\000\000\000\000\000\000\002\135\000\000\000\000\000\000\000\000\002\134\000\000\000\000\000\000\000\000\001\239\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\135\000\000\002\134\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\135\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\134\000\000\001\208\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\135\000\000\000\000\001\241\000\000\002\165\000\000\000\000\000\000\000\000\000\000\002\165\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\184\000\000\000\000\000\000\000\000\000\000\002\186\000\000\000\000\000\000\002\165\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\188\002\165\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\190\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\165\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\192"))
let semantic_action =
[|
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_aexpr =
-# 1662 "parser_cocci_menhir.mly"
+# 1663 "parser_cocci_menhir.mly"
( Ast0.set_arg_exp _1 )
# 1497 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_aexpr =
-# 1664 "parser_cocci_menhir.mly"
+# 1665 "parser_cocci_menhir.mly"
( let (nm,lenname,pure,clt) = _1 in
let nm = P.clt2mcode nm clt in
let lenname =
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_aexpr =
-# 1672 "parser_cocci_menhir.mly"
+# 1673 "parser_cocci_menhir.mly"
( Ast0.set_arg_exp(Ast0.wrap(Ast0.TypeExp(_1))) )
# 1555 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_any_strict =
-# 1716 "parser_cocci_menhir.mly"
+# 1717 "parser_cocci_menhir.mly"
( Ast.WhenAny )
# 1577 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_any_strict =
-# 1717 "parser_cocci_menhir.mly"
+# 1718 "parser_cocci_menhir.mly"
( Ast.WhenStrict )
# 1599 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_any_strict =
-# 1718 "parser_cocci_menhir.mly"
+# 1719 "parser_cocci_menhir.mly"
( Ast.WhenForall )
# 1621 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_any_strict =
-# 1719 "parser_cocci_menhir.mly"
+# 1720 "parser_cocci_menhir.mly"
( Ast.WhenExists )
# 1643 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_arith_expr_eexpr_dot_expressions_ =
-# 1190 "parser_cocci_menhir.mly"
+# 1191 "parser_cocci_menhir.mly"
( _1 )
# 1667 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_dot_expressions_ =
-# 1192 "parser_cocci_menhir.mly"
+# 1193 "parser_cocci_menhir.mly"
( P.arith_op Ast.Mul _1 _2 _3 )
# 1707 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_dot_expressions_ =
-# 1194 "parser_cocci_menhir.mly"
+# 1195 "parser_cocci_menhir.mly"
( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
# 1747 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_dot_expressions_ =
-# 1196 "parser_cocci_menhir.mly"
+# 1197 "parser_cocci_menhir.mly"
( P.arith_op Ast.Plus _1 _2 _3 )
# 1787 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_dot_expressions_ =
-# 1198 "parser_cocci_menhir.mly"
+# 1199 "parser_cocci_menhir.mly"
( P.arith_op Ast.Minus _1 _2 _3 )
# 1827 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_dot_expressions_ =
-# 1200 "parser_cocci_menhir.mly"
+# 1201 "parser_cocci_menhir.mly"
( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
# 1867 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_dot_expressions_ =
-# 1202 "parser_cocci_menhir.mly"
+# 1203 "parser_cocci_menhir.mly"
( let (op,clt) = _2 in P.logic_op op _1 clt _3 )
# 1907 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_dot_expressions_ =
-# 1204 "parser_cocci_menhir.mly"
+# 1205 "parser_cocci_menhir.mly"
( P.logic_op Ast.Eq _1 _2 _3 )
# 1947 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_dot_expressions_ =
-# 1206 "parser_cocci_menhir.mly"
+# 1207 "parser_cocci_menhir.mly"
( P.logic_op Ast.NotEq _1 _2 _3 )
# 1987 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_dot_expressions_ =
-# 1208 "parser_cocci_menhir.mly"
+# 1209 "parser_cocci_menhir.mly"
( P.arith_op Ast.And _1 _2 _3 )
# 2027 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_dot_expressions_ =
-# 1210 "parser_cocci_menhir.mly"
+# 1211 "parser_cocci_menhir.mly"
( P.arith_op Ast.Or _1 _2 _3 )
# 2067 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_dot_expressions_ =
-# 1212 "parser_cocci_menhir.mly"
+# 1213 "parser_cocci_menhir.mly"
( P.arith_op Ast.Xor _1 _2 _3 )
# 2107 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_dot_expressions_ =
-# 1214 "parser_cocci_menhir.mly"
+# 1215 "parser_cocci_menhir.mly"
( P.logic_op Ast.AndLog _1 _2 _3 )
# 2147 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_dot_expressions_ =
-# 1216 "parser_cocci_menhir.mly"
+# 1217 "parser_cocci_menhir.mly"
( P.logic_op Ast.OrLog _1 _2 _3 )
# 2187 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_arith_expr_eexpr_invalid_ =
-# 1190 "parser_cocci_menhir.mly"
+# 1191 "parser_cocci_menhir.mly"
( _1 )
# 2211 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_invalid_ =
-# 1192 "parser_cocci_menhir.mly"
+# 1193 "parser_cocci_menhir.mly"
( P.arith_op Ast.Mul _1 _2 _3 )
# 2251 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_invalid_ =
-# 1194 "parser_cocci_menhir.mly"
+# 1195 "parser_cocci_menhir.mly"
( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
# 2291 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_invalid_ =
-# 1196 "parser_cocci_menhir.mly"
+# 1197 "parser_cocci_menhir.mly"
( P.arith_op Ast.Plus _1 _2 _3 )
# 2331 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_invalid_ =
-# 1198 "parser_cocci_menhir.mly"
+# 1199 "parser_cocci_menhir.mly"
( P.arith_op Ast.Minus _1 _2 _3 )
# 2371 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_invalid_ =
-# 1200 "parser_cocci_menhir.mly"
+# 1201 "parser_cocci_menhir.mly"
( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
# 2411 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_invalid_ =
-# 1202 "parser_cocci_menhir.mly"
+# 1203 "parser_cocci_menhir.mly"
( let (op,clt) = _2 in P.logic_op op _1 clt _3 )
# 2451 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_invalid_ =
-# 1204 "parser_cocci_menhir.mly"
+# 1205 "parser_cocci_menhir.mly"
( P.logic_op Ast.Eq _1 _2 _3 )
# 2491 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_invalid_ =
-# 1206 "parser_cocci_menhir.mly"
+# 1207 "parser_cocci_menhir.mly"
( P.logic_op Ast.NotEq _1 _2 _3 )
# 2531 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_invalid_ =
-# 1208 "parser_cocci_menhir.mly"
+# 1209 "parser_cocci_menhir.mly"
( P.arith_op Ast.And _1 _2 _3 )
# 2571 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_invalid_ =
-# 1210 "parser_cocci_menhir.mly"
+# 1211 "parser_cocci_menhir.mly"
( P.arith_op Ast.Or _1 _2 _3 )
# 2611 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_invalid_ =
-# 1212 "parser_cocci_menhir.mly"
+# 1213 "parser_cocci_menhir.mly"
( P.arith_op Ast.Xor _1 _2 _3 )
# 2651 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_invalid_ =
-# 1214 "parser_cocci_menhir.mly"
+# 1215 "parser_cocci_menhir.mly"
( P.logic_op Ast.AndLog _1 _2 _3 )
# 2691 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_invalid_ =
-# 1216 "parser_cocci_menhir.mly"
+# 1217 "parser_cocci_menhir.mly"
( P.logic_op Ast.OrLog _1 _2 _3 )
# 2731 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_arith_expr_eexpr_nest_expressions_ =
-# 1190 "parser_cocci_menhir.mly"
+# 1191 "parser_cocci_menhir.mly"
( _1 )
# 2755 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_nest_expressions_ =
-# 1192 "parser_cocci_menhir.mly"
+# 1193 "parser_cocci_menhir.mly"
( P.arith_op Ast.Mul _1 _2 _3 )
# 2795 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_nest_expressions_ =
-# 1194 "parser_cocci_menhir.mly"
+# 1195 "parser_cocci_menhir.mly"
( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
# 2835 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_nest_expressions_ =
-# 1196 "parser_cocci_menhir.mly"
+# 1197 "parser_cocci_menhir.mly"
( P.arith_op Ast.Plus _1 _2 _3 )
# 2875 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_nest_expressions_ =
-# 1198 "parser_cocci_menhir.mly"
+# 1199 "parser_cocci_menhir.mly"
( P.arith_op Ast.Minus _1 _2 _3 )
# 2915 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_nest_expressions_ =
-# 1200 "parser_cocci_menhir.mly"
+# 1201 "parser_cocci_menhir.mly"
( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
# 2955 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_nest_expressions_ =
-# 1202 "parser_cocci_menhir.mly"
+# 1203 "parser_cocci_menhir.mly"
( let (op,clt) = _2 in P.logic_op op _1 clt _3 )
# 2995 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_nest_expressions_ =
-# 1204 "parser_cocci_menhir.mly"
+# 1205 "parser_cocci_menhir.mly"
( P.logic_op Ast.Eq _1 _2 _3 )
# 3035 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_nest_expressions_ =
-# 1206 "parser_cocci_menhir.mly"
+# 1207 "parser_cocci_menhir.mly"
( P.logic_op Ast.NotEq _1 _2 _3 )
# 3075 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_nest_expressions_ =
-# 1208 "parser_cocci_menhir.mly"
+# 1209 "parser_cocci_menhir.mly"
( P.arith_op Ast.And _1 _2 _3 )
# 3115 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_nest_expressions_ =
-# 1210 "parser_cocci_menhir.mly"
+# 1211 "parser_cocci_menhir.mly"
( P.arith_op Ast.Or _1 _2 _3 )
# 3155 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_nest_expressions_ =
-# 1212 "parser_cocci_menhir.mly"
+# 1213 "parser_cocci_menhir.mly"
( P.arith_op Ast.Xor _1 _2 _3 )
# 3195 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_nest_expressions_ =
-# 1214 "parser_cocci_menhir.mly"
+# 1215 "parser_cocci_menhir.mly"
( P.logic_op Ast.AndLog _1 _2 _3 )
# 3235 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_eexpr_nest_expressions_ =
-# 1216 "parser_cocci_menhir.mly"
+# 1217 "parser_cocci_menhir.mly"
( P.logic_op Ast.OrLog _1 _2 _3 )
# 3275 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_arith_expr_expr_invalid_ =
-# 1190 "parser_cocci_menhir.mly"
+# 1191 "parser_cocci_menhir.mly"
( _1 )
# 3299 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_expr_invalid_ =
-# 1192 "parser_cocci_menhir.mly"
+# 1193 "parser_cocci_menhir.mly"
( P.arith_op Ast.Mul _1 _2 _3 )
# 3339 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_expr_invalid_ =
-# 1194 "parser_cocci_menhir.mly"
+# 1195 "parser_cocci_menhir.mly"
( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
# 3379 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_expr_invalid_ =
-# 1196 "parser_cocci_menhir.mly"
+# 1197 "parser_cocci_menhir.mly"
( P.arith_op Ast.Plus _1 _2 _3 )
# 3419 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_expr_invalid_ =
-# 1198 "parser_cocci_menhir.mly"
+# 1199 "parser_cocci_menhir.mly"
( P.arith_op Ast.Minus _1 _2 _3 )
# 3459 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_expr_invalid_ =
-# 1200 "parser_cocci_menhir.mly"
+# 1201 "parser_cocci_menhir.mly"
( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
# 3499 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_expr_invalid_ =
-# 1202 "parser_cocci_menhir.mly"
+# 1203 "parser_cocci_menhir.mly"
( let (op,clt) = _2 in P.logic_op op _1 clt _3 )
# 3539 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_expr_invalid_ =
-# 1204 "parser_cocci_menhir.mly"
+# 1205 "parser_cocci_menhir.mly"
( P.logic_op Ast.Eq _1 _2 _3 )
# 3579 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_expr_invalid_ =
-# 1206 "parser_cocci_menhir.mly"
+# 1207 "parser_cocci_menhir.mly"
( P.logic_op Ast.NotEq _1 _2 _3 )
# 3619 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_expr_invalid_ =
-# 1208 "parser_cocci_menhir.mly"
+# 1209 "parser_cocci_menhir.mly"
( P.arith_op Ast.And _1 _2 _3 )
# 3659 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_expr_invalid_ =
-# 1210 "parser_cocci_menhir.mly"
+# 1211 "parser_cocci_menhir.mly"
( P.arith_op Ast.Or _1 _2 _3 )
# 3699 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_expr_invalid_ =
-# 1212 "parser_cocci_menhir.mly"
+# 1213 "parser_cocci_menhir.mly"
( P.arith_op Ast.Xor _1 _2 _3 )
# 3739 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_expr_invalid_ =
-# 1214 "parser_cocci_menhir.mly"
+# 1215 "parser_cocci_menhir.mly"
( P.logic_op Ast.AndLog _1 _2 _3 )
# 3779 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_arith_expr_expr_invalid_ =
-# 1216 "parser_cocci_menhir.mly"
+# 1217 "parser_cocci_menhir.mly"
( P.logic_op Ast.OrLog _1 _2 _3 )
# 3819 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_assign_expr_eexpr_dot_expressions_ =
-# 1162 "parser_cocci_menhir.mly"
+# 1163 "parser_cocci_menhir.mly"
( _1 )
# 3970 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_assign_expr_eexpr_dot_expressions_ =
-# 1164 "parser_cocci_menhir.mly"
+# 1165 "parser_cocci_menhir.mly"
( let (op,clt) = _2 in
Ast0.wrap(Ast0.Assignment(_1,P.clt2mcode op clt,
Ast0.set_arg_exp _3,false)) )
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_assign_expr_eexpr_dot_expressions_ =
-# 1168 "parser_cocci_menhir.mly"
+# 1169 "parser_cocci_menhir.mly"
( Ast0.wrap
(Ast0.Assignment
(_1,P.clt2mcode Ast.SimpleAssign _2,Ast0.set_arg_exp _3,false)) )
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_assign_expr_eexpr_nest_expressions_ =
-# 1162 "parser_cocci_menhir.mly"
+# 1163 "parser_cocci_menhir.mly"
( _1 )
# 4078 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_assign_expr_eexpr_nest_expressions_ =
-# 1164 "parser_cocci_menhir.mly"
+# 1165 "parser_cocci_menhir.mly"
( let (op,clt) = _2 in
Ast0.wrap(Ast0.Assignment(_1,P.clt2mcode op clt,
Ast0.set_arg_exp _3,false)) )
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_assign_expr_eexpr_nest_expressions_ =
-# 1168 "parser_cocci_menhir.mly"
+# 1169 "parser_cocci_menhir.mly"
( Ast0.wrap
(Ast0.Assignment
(_1,P.clt2mcode Ast.SimpleAssign _2,Ast0.set_arg_exp _3,false)) )
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_assign_expr_expr_invalid_ =
-# 1162 "parser_cocci_menhir.mly"
+# 1163 "parser_cocci_menhir.mly"
( _1 )
# 4186 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_assign_expr_expr_invalid_ =
-# 1164 "parser_cocci_menhir.mly"
+# 1165 "parser_cocci_menhir.mly"
( let (op,clt) = _2 in
Ast0.wrap(Ast0.Assignment(_1,P.clt2mcode op clt,
Ast0.set_arg_exp _3,false)) )
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_assign_expr_expr_invalid_ =
-# 1168 "parser_cocci_menhir.mly"
+# 1169 "parser_cocci_menhir.mly"
( Ast0.wrap
(Ast0.Assignment
(_1,P.clt2mcode Ast.SimpleAssign _2,Ast0.set_arg_exp _3,false)) )
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_assign_expr_bis =
-# 1173 "parser_cocci_menhir.mly"
+# 1174 "parser_cocci_menhir.mly"
( _1 )
# 4294 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_assign_expr_bis =
-# 1175 "parser_cocci_menhir.mly"
+# 1176 "parser_cocci_menhir.mly"
( let (op,clt) = _2 in
Ast0.wrap(Ast0.Assignment(_1,P.clt2mcode op clt,
Ast0.set_arg_exp _3,false)) )
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_assign_expr_bis =
-# 1179 "parser_cocci_menhir.mly"
+# 1180 "parser_cocci_menhir.mly"
( Ast0.wrap
(Ast0.Assignment
(_1,P.clt2mcode Ast.SimpleAssign _2,Ast0.set_arg_exp _3,false)) )
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_basic_expr_eexpr_dot_expressions_ =
-# 1159 "parser_cocci_menhir.mly"
+# 1160 "parser_cocci_menhir.mly"
( _1 )
# 4402 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_basic_expr_eexpr_nest_expressions_ =
-# 1159 "parser_cocci_menhir.mly"
+# 1160 "parser_cocci_menhir.mly"
( _1 )
# 4426 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_basic_expr_expr_invalid_ =
-# 1159 "parser_cocci_menhir.mly"
+# 1160 "parser_cocci_menhir.mly"
( _1 )
# 4450 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_cast_expr_eexpr_dot_expressions_ =
-# 1219 "parser_cocci_menhir.mly"
+# 1220 "parser_cocci_menhir.mly"
( _1 )
# 4568 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_lp_ in
let _endpos = _endpos_e_ in
let _v : 'tv_cast_expr_eexpr_dot_expressions_ =
-# 1221 "parser_cocci_menhir.mly"
+# 1222 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Cast (P.clt2mcode "(" lp, t,
P.clt2mcode ")" rp, e)) )
# 4619 "parser_cocci_menhir.ml"
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_cast_expr_eexpr_invalid_ =
-# 1219 "parser_cocci_menhir.mly"
+# 1220 "parser_cocci_menhir.mly"
( _1 )
# 4643 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_lp_ in
let _endpos = _endpos_e_ in
let _v : 'tv_cast_expr_eexpr_invalid_ =
-# 1221 "parser_cocci_menhir.mly"
+# 1222 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Cast (P.clt2mcode "(" lp, t,
P.clt2mcode ")" rp, e)) )
# 4694 "parser_cocci_menhir.ml"
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_cast_expr_eexpr_nest_expressions_ =
-# 1219 "parser_cocci_menhir.mly"
+# 1220 "parser_cocci_menhir.mly"
( _1 )
# 4718 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_lp_ in
let _endpos = _endpos_e_ in
let _v : 'tv_cast_expr_eexpr_nest_expressions_ =
-# 1221 "parser_cocci_menhir.mly"
+# 1222 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Cast (P.clt2mcode "(" lp, t,
P.clt2mcode ")" rp, e)) )
# 4769 "parser_cocci_menhir.ml"
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_cast_expr_expr_invalid_ =
-# 1219 "parser_cocci_menhir.mly"
+# 1220 "parser_cocci_menhir.mly"
( _1 )
# 4793 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_lp_ in
let _endpos = _endpos_e_ in
let _v : 'tv_cast_expr_expr_invalid_ =
-# 1221 "parser_cocci_menhir.mly"
+# 1222 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Cast (P.clt2mcode "(" lp, t,
P.clt2mcode ")" rp, e)) )
# 4844 "parser_cocci_menhir.ml"
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_comma_decls_TEllipsis_decl_ =
-# 1470 "parser_cocci_menhir.mly"
+# 1471 "parser_cocci_menhir.mly"
( function dot_builder ->
[Ast0.wrap(Ast0.PComma(P.clt2mcode "," _1));
dot_builder _2] )
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_comma_decls_TEllipsis_decl_ =
-# 1474 "parser_cocci_menhir.mly"
+# 1475 "parser_cocci_menhir.mly"
( function dot_builder ->
[Ast0.wrap(Ast0.PComma(P.clt2mcode "," _1)); _2] )
# 4947 "parser_cocci_menhir.ml"
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_comma_decls_TEllipsis_name_opt_decl_ =
-# 1470 "parser_cocci_menhir.mly"
+# 1471 "parser_cocci_menhir.mly"
( function dot_builder ->
[Ast0.wrap(Ast0.PComma(P.clt2mcode "," _1));
dot_builder _2] )
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_comma_decls_TEllipsis_name_opt_decl_ =
-# 1474 "parser_cocci_menhir.mly"
+# 1475 "parser_cocci_menhir.mly"
( function dot_builder ->
[Ast0.wrap(Ast0.PComma(P.clt2mcode "," _1)); _2] )
# 5022 "parser_cocci_menhir.ml"
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_comma_list_any_strict_ =
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
( _1 )
# 5192 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_comma_list_ctype_ =
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
( _1 )
# 5216 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_comma_list_d_ident_ =
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
( _1 )
# 5240 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_comma_list_dexpr_ =
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
( _1 )
# 5264 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_comma_list_ident_or_const_ =
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
( _1 )
# 5288 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_comma_list_meta_ident_ =
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
( _1 )
# 5312 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_comma_list_pure_ident_ =
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
( _1 )
# 5336 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_comma_list_pure_ident_or_meta_ident_ =
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
( _1 )
# 5360 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_comma_list_pure_ident_or_meta_ident_with_not_eq_not_ceq__ =
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
( _1 )
# 5384 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_comma_list_pure_ident_or_meta_ident_with_not_eq_not_eq__ =
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
( _1 )
# 5408 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_comma_list_pure_ident_or_meta_ident_with_not_eq_not_eqe__ =
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
( _1 )
# 5432 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_comma_list_pure_ident_or_meta_ident_with_not_eq_not_pos__ =
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
( _1 )
# 5456 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_cond_expr_eexpr_dot_expressions_ =
-# 1184 "parser_cocci_menhir.mly"
+# 1185 "parser_cocci_menhir.mly"
( _1 )
# 5480 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_l_ in
let _endpos = _endpos_r_ in
let _v : 'tv_cond_expr_eexpr_dot_expressions_ =
-# 1186 "parser_cocci_menhir.mly"
+# 1187 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.CondExpr (l, P.clt2mcode "?" w, t,
P.clt2mcode ":" dd, r)) )
# 5537 "parser_cocci_menhir.ml"
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_cond_expr_eexpr_nest_expressions_ =
-# 1184 "parser_cocci_menhir.mly"
+# 1185 "parser_cocci_menhir.mly"
( _1 )
# 5561 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_l_ in
let _endpos = _endpos_r_ in
let _v : 'tv_cond_expr_eexpr_nest_expressions_ =
-# 1186 "parser_cocci_menhir.mly"
+# 1187 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.CondExpr (l, P.clt2mcode "?" w, t,
P.clt2mcode ":" dd, r)) )
# 5618 "parser_cocci_menhir.ml"
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_cond_expr_expr_invalid_ =
-# 1184 "parser_cocci_menhir.mly"
+# 1185 "parser_cocci_menhir.mly"
( _1 )
# 5642 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_l_ in
let _endpos = _endpos_r_ in
let _v : 'tv_cond_expr_expr_invalid_ =
-# 1186 "parser_cocci_menhir.mly"
+# 1187 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.CondExpr (l, P.clt2mcode "?" w, t,
P.clt2mcode ":" dd, r)) )
# 5699 "parser_cocci_menhir.ml"
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_decl_ident =
-# 1420 "parser_cocci_menhir.mly"
+# 1421 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Id(P.id2mcode _1)) )
# 6346 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_decl_ident =
-# 1422 "parser_cocci_menhir.mly"
+# 1423 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,clt) = _1 in
Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) )
# 6375 "parser_cocci_menhir.ml"
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_decl_list_decl_ =
-# 1443 "parser_cocci_menhir.mly"
+# 1444 "parser_cocci_menhir.mly"
(let circle x =
match Ast0.unwrap x with Ast0.Pcircles(_) -> true | _ -> false in
if List.exists circle _1
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_decl_list_name_opt_decl_ =
-# 1443 "parser_cocci_menhir.mly"
+# 1444 "parser_cocci_menhir.mly"
(let circle x =
match Ast0.unwrap x with Ast0.Pcircles(_) -> true | _ -> false in
if List.exists circle _1
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_decl_list_start_decl_ =
-# 1450 "parser_cocci_menhir.mly"
+# 1451 "parser_cocci_menhir.mly"
( [_1] )
# 6455 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_decl_list_start_decl_ =
-# 1452 "parser_cocci_menhir.mly"
+# 1453 "parser_cocci_menhir.mly"
( _1::Ast0.wrap(Ast0.PComma(P.clt2mcode "," _2))::_3 )
# 6495 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_decl_list_start_decl_ =
-# 1454 "parser_cocci_menhir.mly"
+# 1455 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Pdots(P.clt2mcode "..." _1))::
(List.concat(List.map (function x -> x (P.mkpdots "...")) _2)) )
# 6530 "parser_cocci_menhir.ml"
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_decl_list_start_name_opt_decl_ =
-# 1450 "parser_cocci_menhir.mly"
+# 1451 "parser_cocci_menhir.mly"
( [_1] )
# 6554 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_decl_list_start_name_opt_decl_ =
-# 1452 "parser_cocci_menhir.mly"
+# 1453 "parser_cocci_menhir.mly"
( _1::Ast0.wrap(Ast0.PComma(P.clt2mcode "," _2))::_3 )
# 6594 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_decl_list_start_name_opt_decl_ =
-# 1454 "parser_cocci_menhir.mly"
+# 1455 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Pdots(P.clt2mcode "..." _1))::
(List.concat(List.map (function x -> x (P.mkpdots "...")) _2)) )
# 6629 "parser_cocci_menhir.ml"
let _startpos = _startpos_d_ in
let _endpos = _endpos_d_ in
let _v : 'tv_edots_when_TEllipsis_eexpr_ =
-# 1704 "parser_cocci_menhir.mly"
+# 1705 "parser_cocci_menhir.mly"
( (d,None) )
# 8997 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_d_ in
let _endpos = _endpos__5_ in
let _v : 'tv_edots_when_TEllipsis_eexpr_ =
-# 1705 "parser_cocci_menhir.mly"
+# 1706 "parser_cocci_menhir.mly"
( (d,Some w) )
# 9043 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_d_ in
let _endpos = _endpos_d_ in
let _v : 'tv_edots_when_TEllipsis_initialize_ =
-# 1704 "parser_cocci_menhir.mly"
+# 1705 "parser_cocci_menhir.mly"
( (d,None) )
# 9071 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_d_ in
let _endpos = _endpos__5_ in
let _v : 'tv_edots_when_TEllipsis_initialize_ =
-# 1705 "parser_cocci_menhir.mly"
+# 1706 "parser_cocci_menhir.mly"
( (d,Some w) )
# 9117 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_d_ in
let _endpos = _endpos_d_ in
let _v : 'tv_edots_when_TEllipsis_struct_decl_ =
-# 1704 "parser_cocci_menhir.mly"
+# 1705 "parser_cocci_menhir.mly"
( (d,None) )
# 9145 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_d_ in
let _endpos = _endpos__5_ in
let _v : 'tv_edots_when_TEllipsis_struct_decl_ =
-# 1705 "parser_cocci_menhir.mly"
+# 1706 "parser_cocci_menhir.mly"
( (d,Some w) )
# 9191 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_eexpr_list =
-# 1648 "parser_cocci_menhir.mly"
+# 1649 "parser_cocci_menhir.mly"
(let circle x =
match Ast0.unwrap x with Ast0.Ecircles(_) -> true | _ -> false in
let star x =
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_eexpr_list_option =
-# 1687 "parser_cocci_menhir.mly"
+# 1688 "parser_cocci_menhir.mly"
( _1 )
# 9272 "parser_cocci_menhir.ml"
in
let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
let _endpos = _startpos in
let _v : 'tv_eexpr_list_option =
-# 1688 "parser_cocci_menhir.mly"
+# 1689 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.DOTS([])) )
# 9289 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_eexpr_list_start =
-# 1675 "parser_cocci_menhir.mly"
+# 1676 "parser_cocci_menhir.mly"
( [_1] )
# 9313 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_eexpr_list_start =
-# 1677 "parser_cocci_menhir.mly"
+# 1678 "parser_cocci_menhir.mly"
( _1::Ast0.wrap(Ast0.EComma(P.clt2mcode "," _2))::_3 )
# 9353 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__6_ in
let _v : 'tv_error_words =
-# 1481 "parser_cocci_menhir.mly"
+# 1482 "parser_cocci_menhir.mly"
( [Ast0.wrap(Ast0.ERRORWORDS(cl))] )
# 9397 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_r_ in
let _endpos = _endpos_r_ in
let _v : 'tv_expr_dots_TEllipsis_ =
-# 1311 "parser_cocci_menhir.mly"
+# 1312 "parser_cocci_menhir.mly"
( r )
# 9532 "parser_cocci_menhir.ml"
in
let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
let _endpos = _startpos in
let _v : 'tv_fun_after_dots =
-# 1596 "parser_cocci_menhir.mly"
+# 1597 "parser_cocci_menhir.mly"
([])
# 9984 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_fun_after_dots =
-# 1597 "parser_cocci_menhir.mly"
+# 1598 "parser_cocci_menhir.mly"
(_2)
# 10012 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_fun_after_dots =
-# 1598 "parser_cocci_menhir.mly"
+# 1599 "parser_cocci_menhir.mly"
(Ast0.wrap(Ast0.Exp(_1))::_2)
# 10042 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_fun_after_dots =
-# 1599 "parser_cocci_menhir.mly"
+# 1600 "parser_cocci_menhir.mly"
(_1@_2)
# 10072 "parser_cocci_menhir.ml"
in
let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
let _endpos = _startpos in
let _v : 'tv_fun_after_dots_or =
-# 1606 "parser_cocci_menhir.mly"
+# 1607 "parser_cocci_menhir.mly"
([])
# 10089 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_fun_after_dots_or =
-# 1607 "parser_cocci_menhir.mly"
+# 1608 "parser_cocci_menhir.mly"
(_2)
# 10117 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_fun_after_dots_or =
-# 1608 "parser_cocci_menhir.mly"
+# 1609 "parser_cocci_menhir.mly"
(Ast0.wrap(Ast0.Exp(_1))::_2)
# 10147 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_fun_after_dots_or =
-# 1609 "parser_cocci_menhir.mly"
+# 1610 "parser_cocci_menhir.mly"
(_1@_2)
# 10177 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_fun_after_exp =
-# 1602 "parser_cocci_menhir.mly"
+# 1603 "parser_cocci_menhir.mly"
(_1::_2)
# 10207 "parser_cocci_menhir.ml"
in
let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
let _endpos = _startpos in
let _v : 'tv_fun_after_exp_or =
-# 1612 "parser_cocci_menhir.mly"
+# 1613 "parser_cocci_menhir.mly"
([])
# 10224 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_fun_after_exp_or =
-# 1613 "parser_cocci_menhir.mly"
+# 1614 "parser_cocci_menhir.mly"
(_1::_2)
# 10254 "parser_cocci_menhir.ml"
in
let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
let _endpos = _startpos in
let _v : 'tv_fun_after_stm =
-# 1591 "parser_cocci_menhir.mly"
+# 1592 "parser_cocci_menhir.mly"
([])
# 10271 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_fun_after_stm =
-# 1592 "parser_cocci_menhir.mly"
+# 1593 "parser_cocci_menhir.mly"
(_1::_2)
# 10301 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_fun_after_stm =
-# 1593 "parser_cocci_menhir.mly"
+# 1594 "parser_cocci_menhir.mly"
(_1@_2)
# 10331 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_fun_start =
-# 1588 "parser_cocci_menhir.mly"
+# 1589 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.DOTS(_1)) )
# 10355 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_func_ident =
-# 1400 "parser_cocci_menhir.mly"
+# 1401 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Id(P.id2mcode _1)) )
# 10379 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_func_ident =
-# 1402 "parser_cocci_menhir.mly"
+# 1403 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,clt) = _1 in
Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) )
# 10408 "parser_cocci_menhir.ml"
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_func_ident =
-# 1405 "parser_cocci_menhir.mly"
+# 1406 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,clt) = _1 in
Ast0.wrap(Ast0.MetaFunc(P.clt2mcode nm clt,constraints,pure)) )
# 10437 "parser_cocci_menhir.ml"
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_func_ident =
-# 1408 "parser_cocci_menhir.mly"
+# 1409 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,clt) = _1 in
Ast0.wrap
(Ast0.MetaLocalFunc(P.clt2mcode nm clt,constraints,pure)) )
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_ident =
-# 1413 "parser_cocci_menhir.mly"
+# 1414 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Id(P.id2mcode _1)) )
# 11631 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_ident =
-# 1415 "parser_cocci_menhir.mly"
+# 1416 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,clt) = _1 in
Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) )
# 11660 "parser_cocci_menhir.ml"
let _startpos = _startpos_i_ in
let _endpos = _endpos_i_ in
let _v : 'tv_ident_or_const =
-# 1371 "parser_cocci_menhir.mly"
+# 1372 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Ident(Ast0.wrap(Ast0.Id(P.id2mcode i)))) )
# 11684 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_ident_or_const =
-# 1373 "parser_cocci_menhir.mly"
+# 1374 "parser_cocci_menhir.mly"
( let (x,clt) = _1 in
Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) )
# 11713 "parser_cocci_menhir.ml"
let _startpos = _startpos__1_ in
let _endpos = _endpos_t_ in
let _v : 'tv_iso_ctype_ =
-# 1756 "parser_cocci_menhir.mly"
+# 1757 "parser_cocci_menhir.mly"
( Common.Left t )
# 12652 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos_t_ in
let _v : 'tv_iso_ctype_ =
-# 1757 "parser_cocci_menhir.mly"
+# 1758 "parser_cocci_menhir.mly"
( Common.Right t )
# 12680 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos_t_ in
let _v : 'tv_iso_decl_var_ =
-# 1756 "parser_cocci_menhir.mly"
+# 1757 "parser_cocci_menhir.mly"
( Common.Left t )
# 12708 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos_t_ in
let _v : 'tv_iso_decl_var_ =
-# 1757 "parser_cocci_menhir.mly"
+# 1758 "parser_cocci_menhir.mly"
( Common.Right t )
# 12736 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos_t_ in
let _v : 'tv_iso_dexpr_ =
-# 1756 "parser_cocci_menhir.mly"
+# 1757 "parser_cocci_menhir.mly"
( Common.Left t )
# 12764 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos_t_ in
let _v : 'tv_iso_dexpr_ =
-# 1757 "parser_cocci_menhir.mly"
+# 1758 "parser_cocci_menhir.mly"
( Common.Right t )
# 12792 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos_t_ in
let _v : 'tv_iso_nest_start_ =
-# 1756 "parser_cocci_menhir.mly"
+# 1757 "parser_cocci_menhir.mly"
( Common.Left t )
# 12820 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos_t_ in
let _v : 'tv_iso_nest_start_ =
-# 1757 "parser_cocci_menhir.mly"
+# 1758 "parser_cocci_menhir.mly"
( Common.Right t )
# 12848 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos_t_ in
let _v : 'tv_iso_single_statement_ =
-# 1756 "parser_cocci_menhir.mly"
+# 1757 "parser_cocci_menhir.mly"
( Common.Left t )
# 12876 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos_t_ in
let _v : 'tv_iso_single_statement_ =
-# 1757 "parser_cocci_menhir.mly"
+# 1758 "parser_cocci_menhir.mly"
( Common.Right t )
# 12904 "parser_cocci_menhir.ml"
in
(Ast0_cocci.anything list list)
# 12942 "parser_cocci_menhir.ml"
) =
-# 1728 "parser_cocci_menhir.mly"
+# 1729 "parser_cocci_menhir.mly"
( P.iso_adjust (function x -> Ast0.ExprTag x) e1 el )
# 12946 "parser_cocci_menhir.ml"
in
(Ast0_cocci.anything list list)
# 12984 "parser_cocci_menhir.ml"
) =
-# 1730 "parser_cocci_menhir.mly"
+# 1731 "parser_cocci_menhir.mly"
( P.iso_adjust (function x -> Ast0.ArgExprTag x) e1 el )
# 12988 "parser_cocci_menhir.ml"
in
(Ast0_cocci.anything list list)
# 13026 "parser_cocci_menhir.ml"
) =
-# 1732 "parser_cocci_menhir.mly"
+# 1733 "parser_cocci_menhir.mly"
( P.iso_adjust (function x -> Ast0.TestExprTag x) e1 el )
# 13030 "parser_cocci_menhir.ml"
in
(Ast0_cocci.anything list list)
# 13068 "parser_cocci_menhir.ml"
) =
-# 1734 "parser_cocci_menhir.mly"
+# 1735 "parser_cocci_menhir.mly"
( P.iso_adjust (function x -> Ast0.StmtTag x) s1 sl )
# 13072 "parser_cocci_menhir.ml"
in
(Ast0_cocci.anything list list)
# 13110 "parser_cocci_menhir.ml"
) =
-# 1736 "parser_cocci_menhir.mly"
+# 1737 "parser_cocci_menhir.mly"
( P.iso_adjust (function x -> Ast0.TypeCTag x) t1 tl )
# 13114 "parser_cocci_menhir.ml"
in
(Ast0_cocci.anything list list)
# 13152 "parser_cocci_menhir.ml"
) =
-# 1738 "parser_cocci_menhir.mly"
+# 1739 "parser_cocci_menhir.mly"
( P.iso_adjust (function x -> Ast0.DotsStmtTag x) e1 el )
# 13156 "parser_cocci_menhir.ml"
in
(Ast0_cocci.anything list list)
# 13194 "parser_cocci_menhir.ml"
) =
-# 1740 "parser_cocci_menhir.mly"
+# 1741 "parser_cocci_menhir.mly"
( let check_one = function
[x] -> x
| _ ->
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_iter_ident =
-# 1427 "parser_cocci_menhir.mly"
+# 1428 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Id(P.id2mcode _1)) )
# 13299 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_iter_ident =
-# 1429 "parser_cocci_menhir.mly"
+# 1430 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,clt) = _1 in
Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) )
# 13328 "parser_cocci_menhir.ml"
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_meta_ident =
-# 1325 "parser_cocci_menhir.mly"
+# 1326 "parser_cocci_menhir.mly"
( (Some _1,P.id2name _3) )
# 14799 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_a_ in
let _endpos = _endpos_b_ in
let _v : 'tv_midzero_list_ctype_ctype_ =
-# 1698 "parser_cocci_menhir.mly"
+# 1699 "parser_cocci_menhir.mly"
( let (mids,code) = List.split b in (mids,(a::code)) )
# 16523 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_a_ in
let _endpos = _endpos_b_ in
let _v : 'tv_midzero_list_eexpr_eexpr_ =
-# 1698 "parser_cocci_menhir.mly"
+# 1699 "parser_cocci_menhir.mly"
( let (mids,code) = List.split b in (mids,(a::code)) )
# 16553 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_a_ in
let _endpos = _endpos_b_ in
let _v : 'tv_midzero_list_expr_eexpr_ =
-# 1698 "parser_cocci_menhir.mly"
+# 1699 "parser_cocci_menhir.mly"
( let (mids,code) = List.split b in (mids,(a::code)) )
# 16583 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_a_ in
let _endpos = _endpos_b_ in
let _v : 'tv_midzero_list_fun_after_stm_fun_after_dots_or_ =
-# 1698 "parser_cocci_menhir.mly"
+# 1699 "parser_cocci_menhir.mly"
( let (mids,code) = List.split b in (mids,(a::code)) )
# 16613 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_a_ in
let _endpos = _endpos_b_ in
let _v : 'tv_midzero_list_fun_start_fun_start_ =
-# 1698 "parser_cocci_menhir.mly"
+# 1699 "parser_cocci_menhir.mly"
( let (mids,code) = List.split b in (mids,(a::code)) )
# 16643 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_a_ in
let _endpos = _endpos_b_ in
let _v : 'tv_midzero_list_rule_elem_statement_rule_elem_statement_ =
-# 1698 "parser_cocci_menhir.mly"
+# 1699 "parser_cocci_menhir.mly"
( let (mids,code) = List.split b in (mids,(a::code)) )
# 16673 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_a_ in
let _endpos = _endpos_b_ in
let _v : 'tv_midzero_list_statement_statement_ =
-# 1698 "parser_cocci_menhir.mly"
+# 1699 "parser_cocci_menhir.mly"
( let (mids,code) = List.split b in (mids,(a::code)) )
# 16703 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_minus_start =
-# 1514 "parser_cocci_menhir.mly"
+# 1515 "parser_cocci_menhir.mly"
( [Ast0.wrap(Ast0.DECL(_1))] )
# 16995 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_minus_start =
-# 1515 "parser_cocci_menhir.mly"
+# 1516 "parser_cocci_menhir.mly"
( [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Ty(_1))))] )
# 17019 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_minus_start =
-# 1516 "parser_cocci_menhir.mly"
+# 1517 "parser_cocci_menhir.mly"
( [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.TopInit(_1))))] )
# 17043 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_minus_start =
-# 1518 "parser_cocci_menhir.mly"
+# 1519 "parser_cocci_menhir.mly"
( List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) _1 )
# 17067 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_a_ in
let _endpos = _endpos_b_ in
let _v : 'tv_mzl_ctype_ =
-# 1701 "parser_cocci_menhir.mly"
+# 1702 "parser_cocci_menhir.mly"
( (P.clt2mcode "|" a, b) )
# 17101 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_a_ in
let _endpos = _endpos_b_ in
let _v : 'tv_mzl_eexpr_ =
-# 1701 "parser_cocci_menhir.mly"
+# 1702 "parser_cocci_menhir.mly"
( (P.clt2mcode "|" a, b) )
# 17135 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_a_ in
let _endpos = _endpos_b_ in
let _v : 'tv_mzl_fun_after_dots_or_ =
-# 1701 "parser_cocci_menhir.mly"
+# 1702 "parser_cocci_menhir.mly"
( (P.clt2mcode "|" a, b) )
# 17169 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_a_ in
let _endpos = _endpos_b_ in
let _v : 'tv_mzl_fun_start_ =
-# 1701 "parser_cocci_menhir.mly"
+# 1702 "parser_cocci_menhir.mly"
( (P.clt2mcode "|" a, b) )
# 17203 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_a_ in
let _endpos = _endpos_b_ in
let _v : 'tv_mzl_rule_elem_statement_ =
-# 1701 "parser_cocci_menhir.mly"
+# 1702 "parser_cocci_menhir.mly"
( (P.clt2mcode "|" a, b) )
# 17237 "parser_cocci_menhir.ml"
in
let _startpos = _startpos_a_ in
let _endpos = _endpos_b_ in
let _v : 'tv_mzl_statement_ =
-# 1701 "parser_cocci_menhir.mly"
+# 1702 "parser_cocci_menhir.mly"
( (P.clt2mcode "|" a, b) )
# 17271 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_nest_after_dots =
-# 1622 "parser_cocci_menhir.mly"
+# 1623 "parser_cocci_menhir.mly"
(_1@_2)
# 17434 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_nest_after_dots =
-# 1623 "parser_cocci_menhir.mly"
+# 1624 "parser_cocci_menhir.mly"
(_2)
# 17462 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_nest_after_dots =
-# 1624 "parser_cocci_menhir.mly"
+# 1625 "parser_cocci_menhir.mly"
((Ast0.wrap(Ast0.Exp(_1)))::_2)
# 17492 "parser_cocci_menhir.ml"
in
let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
let _endpos = _startpos in
let _v : 'tv_nest_after_exp =
-# 1632 "parser_cocci_menhir.mly"
+# 1633 "parser_cocci_menhir.mly"
([])
# 17509 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_nest_after_exp =
-# 1633 "parser_cocci_menhir.mly"
+# 1634 "parser_cocci_menhir.mly"
(_1::_2)
# 17539 "parser_cocci_menhir.ml"
in
let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
let _endpos = _startpos in
let _v : 'tv_nest_after_stm =
-# 1627 "parser_cocci_menhir.mly"
+# 1628 "parser_cocci_menhir.mly"
([])
# 17556 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_nest_after_stm =
-# 1628 "parser_cocci_menhir.mly"
+# 1629 "parser_cocci_menhir.mly"
(_1::_2)
# 17586 "parser_cocci_menhir.ml"
in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_nest_after_stm =
-# 1629 "parser_cocci_menhir.mly"
+# 1630 "parser_cocci_menhir.mly"
(_1@_2)
# 17616 "parser_cocci_menhir.ml"
in
MenhirLib.EngineTypes.startp = _startpos_e_;
MenhirLib.EngineTypes.endp = _endpos_e_;
MenhirLib.EngineTypes.next = {
- MenhirLib.EngineTypes.semv = w;
- MenhirLib.EngineTypes.startp = _startpos_w_;
- MenhirLib.EngineTypes.endp = _endpos_w_;
- MenhirLib.EngineTypes.next = {
- MenhirLib.EngineTypes.state = _menhir_s;
- MenhirLib.EngineTypes.semv = _1;
- MenhirLib.EngineTypes.startp = _startpos__1_;
- MenhirLib.EngineTypes.endp = _endpos__1_;
- MenhirLib.EngineTypes.next = _menhir_stack;
- };
+ MenhirLib.EngineTypes.state = _menhir_s;
+ MenhirLib.EngineTypes.semv = _1;
+ MenhirLib.EngineTypes.startp = _startpos__1_;
+ MenhirLib.EngineTypes.endp = _endpos__1_;
+ MenhirLib.EngineTypes.next = _menhir_stack;
};
};
} = _menhir_stack in
let c : (
# 72 "parser_cocci_menhir.mly"
(Data.clt)
-# 17652 "parser_cocci_menhir.ml"
+# 17647 "parser_cocci_menhir.ml"
) = Obj.magic c in
let e : 'tv_expr_dots_TEllipsis_ = Obj.magic e in
- let w : 'tv_option_whenexp_ = Obj.magic w in
let _1 : (
# 72 "parser_cocci_menhir.mly"
(Data.clt)
-# 17659 "parser_cocci_menhir.ml"
+# 17653 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos_c_ in
let _v : 'tv_nest_expressions =
-# 1148 "parser_cocci_menhir.mly"
+# 1149 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.NestExpr(P.clt2mcode "<..." _1,
Ast0.wrap(Ast0.DOTS(e (P.mkedots "..."))),
- P.clt2mcode "...>" c, w, false)) )
-# 17668 "parser_cocci_menhir.ml"
+ P.clt2mcode "...>" c, None, false)) )
+# 17662 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
MenhirLib.EngineTypes.startp = _startpos_e_;
MenhirLib.EngineTypes.endp = _endpos_e_;
MenhirLib.EngineTypes.next = {
- MenhirLib.EngineTypes.semv = w;
- MenhirLib.EngineTypes.startp = _startpos_w_;
- MenhirLib.EngineTypes.endp = _endpos_w_;
- MenhirLib.EngineTypes.next = {
- MenhirLib.EngineTypes.state = _menhir_s;
- MenhirLib.EngineTypes.semv = _1;
- MenhirLib.EngineTypes.startp = _startpos__1_;
- MenhirLib.EngineTypes.endp = _endpos__1_;
- MenhirLib.EngineTypes.next = _menhir_stack;
- };
+ MenhirLib.EngineTypes.state = _menhir_s;
+ MenhirLib.EngineTypes.semv = _1;
+ MenhirLib.EngineTypes.startp = _startpos__1_;
+ MenhirLib.EngineTypes.endp = _endpos__1_;
+ MenhirLib.EngineTypes.next = _menhir_stack;
};
};
} = _menhir_stack in
let c : (
# 72 "parser_cocci_menhir.mly"
(Data.clt)
-# 17704 "parser_cocci_menhir.ml"
+# 17693 "parser_cocci_menhir.ml"
) = Obj.magic c in
let e : 'tv_expr_dots_TEllipsis_ = Obj.magic e in
- let w : 'tv_option_whenexp_ = Obj.magic w in
let _1 : (
# 72 "parser_cocci_menhir.mly"
(Data.clt)
-# 17711 "parser_cocci_menhir.ml"
+# 17699 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos_c_ in
let _v : 'tv_nest_expressions =
-# 1152 "parser_cocci_menhir.mly"
+# 1153 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.NestExpr(P.clt2mcode "<+..." _1,
Ast0.wrap(Ast0.DOTS(e (P.mkedots "..."))),
- P.clt2mcode "...+>" c, w, true)) )
-# 17720 "parser_cocci_menhir.ml"
+ P.clt2mcode "...+>" c, None, true)) )
+# 17708 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_nest_start =
-# 1619 "parser_cocci_menhir.mly"
+# 1620 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.DOTS(_1)) )
-# 17744 "parser_cocci_menhir.ml"
+# 17732 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : (
# 167 "parser_cocci_menhir.mly"
(unit)
-# 17766 "parser_cocci_menhir.ml"
+# 17754 "parser_cocci_menhir.ml"
) =
-# 1764 "parser_cocci_menhir.mly"
+# 1765 "parser_cocci_menhir.mly"
( () )
-# 17770 "parser_cocci_menhir.ml"
+# 17758 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : (
# 167 "parser_cocci_menhir.mly"
(unit)
-# 17796 "parser_cocci_menhir.ml"
+# 17784 "parser_cocci_menhir.ml"
) =
-# 1765 "parser_cocci_menhir.mly"
+# 1766 "parser_cocci_menhir.mly"
( () )
-# 17800 "parser_cocci_menhir.ml"
+# 17788 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : (
# 167 "parser_cocci_menhir.mly"
(unit)
-# 17822 "parser_cocci_menhir.ml"
+# 17810 "parser_cocci_menhir.ml"
) =
-# 1766 "parser_cocci_menhir.mly"
+# 1767 "parser_cocci_menhir.mly"
( () )
-# 17826 "parser_cocci_menhir.ml"
+# 17814 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos_g_ in
let _endpos = _endpos_dg_ in
let _v : 'tv_no_dot_start_end_dexpr_edots_when_TEllipsis_eexpr__ =
-# 1316 "parser_cocci_menhir.mly"
+# 1317 "parser_cocci_menhir.mly"
( function dot_builder ->
g :: (List.concat(List.map (function (d,g) -> [dot_builder d;g]) dg)) )
-# 17857 "parser_cocci_menhir.ml"
+# 17845 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let x : (
# 98 "parser_cocci_menhir.mly"
(Data.clt)
-# 17878 "parser_cocci_menhir.ml"
+# 17866 "parser_cocci_menhir.ml"
) = Obj.magic x in
let _startpos = _startpos_x_ in
let _endpos = _endpos_x_ in
let _v : 'tv_nonempty_list_TMul_ =
# 124 "standard.mly"
( [ x ] )
-# 17885 "parser_cocci_menhir.ml"
+# 17873 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let x : (
# 98 "parser_cocci_menhir.mly"
(Data.clt)
-# 17912 "parser_cocci_menhir.ml"
+# 17900 "parser_cocci_menhir.ml"
) = Obj.magic x in
let _startpos = _startpos_x_ in
let _endpos = _endpos_xs_ in
let _v : 'tv_nonempty_list_TMul_ =
# 126 "standard.mly"
( x :: xs )
-# 17919 "parser_cocci_menhir.ml"
+# 17907 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos_i_ in
let _v : 'tv_not_ceq =
-# 1362 "parser_cocci_menhir.mly"
+# 1363 "parser_cocci_menhir.mly"
( (if !Data.in_iso
then failwith "constraints not allowed in iso file");
[i] )
-# 17949 "parser_cocci_menhir.ml"
+# 17937 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__4_ in
let _v : 'tv_not_ceq =
-# 1366 "parser_cocci_menhir.mly"
+# 1367 "parser_cocci_menhir.mly"
( (if !Data.in_iso
then failwith "constraints not allowed in iso file");
l )
-# 17987 "parser_cocci_menhir.ml"
+# 17975 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos_i_ in
let _v : 'tv_not_eq =
-# 1339 "parser_cocci_menhir.mly"
+# 1340 "parser_cocci_menhir.mly"
( (if !Data.in_iso
then failwith "constraints not allowed in iso file");
[Ast0.wrap(Ast0.Id(P.id2mcode i))] )
-# 18017 "parser_cocci_menhir.ml"
+# 18005 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__4_ in
let _v : 'tv_not_eq =
-# 1343 "parser_cocci_menhir.mly"
+# 1344 "parser_cocci_menhir.mly"
( (if !Data.in_iso
then failwith "constraints not allowed in iso file");
List.map (function i -> Ast0.wrap(Ast0.Id(P.id2mcode i))) l )
-# 18055 "parser_cocci_menhir.ml"
+# 18043 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos_i_ in
let _v : 'tv_not_eqe =
-# 1349 "parser_cocci_menhir.mly"
+# 1350 "parser_cocci_menhir.mly"
( (if !Data.in_iso
then failwith "constraints not allowed in iso file");
[Ast0.wrap(Ast0.Ident(Ast0.wrap(Ast0.Id(P.id2mcode i))))] )
-# 18085 "parser_cocci_menhir.ml"
+# 18073 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__4_ in
let _v : 'tv_not_eqe =
-# 1353 "parser_cocci_menhir.mly"
+# 1354 "parser_cocci_menhir.mly"
( (if !Data.in_iso
then failwith "constraints not allowed in iso file");
List.map
(function i ->
Ast0.wrap(Ast0.Ident(Ast0.wrap(Ast0.Id(P.id2mcode i)))))
l )
-# 18126 "parser_cocci_menhir.ml"
+# 18114 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos_i_ in
let _v : 'tv_not_pos =
-# 1378 "parser_cocci_menhir.mly"
+# 1379 "parser_cocci_menhir.mly"
( (if !Data.in_iso
then failwith "constraints not allowed in iso file");
match i with
let i = (rule,name) in
P.check_meta(Ast.MetaPosDecl(Ast.NONE,i));
[i] )
-# 18161 "parser_cocci_menhir.ml"
+# 18149 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__4_ in
let _v : 'tv_not_pos =
-# 1387 "parser_cocci_menhir.mly"
+# 1388 "parser_cocci_menhir.mly"
( (if !Data.in_iso
then failwith "constraints not allowed in iso file");
List.map
P.check_meta(Ast.MetaPosDecl(Ast.NONE,i));
i)
l )
-# 18207 "parser_cocci_menhir.ml"
+# 18195 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_one_dec_decl_ =
-# 1458 "parser_cocci_menhir.mly"
+# 1459 "parser_cocci_menhir.mly"
( _1 )
-# 18231 "parser_cocci_menhir.ml"
+# 18219 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 65 "parser_cocci_menhir.mly"
(Parse_aux.list_info)
-# 18252 "parser_cocci_menhir.ml"
+# 18240 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_one_dec_decl_ =
-# 1460 "parser_cocci_menhir.mly"
+# 1461 "parser_cocci_menhir.mly"
( let (nm,lenname,pure,clt) = _1 in
let nm = P.clt2mcode nm clt in
let lenname =
Some nm -> Some(P.clt2mcode nm clt)
| None -> None in
Ast0.wrap(Ast0.MetaParamList(nm,lenname,pure)) )
-# 18265 "parser_cocci_menhir.ml"
+# 18253 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_one_dec_name_opt_decl_ =
-# 1458 "parser_cocci_menhir.mly"
+# 1459 "parser_cocci_menhir.mly"
( _1 )
-# 18289 "parser_cocci_menhir.ml"
+# 18277 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 65 "parser_cocci_menhir.mly"
(Parse_aux.list_info)
-# 18310 "parser_cocci_menhir.ml"
+# 18298 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_one_dec_name_opt_decl_ =
-# 1460 "parser_cocci_menhir.mly"
+# 1461 "parser_cocci_menhir.mly"
( let (nm,lenname,pure,clt) = _1 in
let nm = P.clt2mcode nm clt in
let lenname =
Some nm -> Some(P.clt2mcode nm clt)
| None -> None in
Ast0.wrap(Ast0.MetaParamList(nm,lenname,pure)) )
-# 18323 "parser_cocci_menhir.ml"
+# 18311 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let pv : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 18349 "parser_cocci_menhir.ml"
+# 18337 "parser_cocci_menhir.ml"
) = Obj.magic pv in
let t : 'tv_ctype = Obj.magic t in
let _startpos = _startpos_t_ in
let _v : 'tv_one_decl_var =
# 944 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.TyDecl(t,P.clt2mcode ";" pv)) )
-# 18357 "parser_cocci_menhir.ml"
+# 18345 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let pv : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 18388 "parser_cocci_menhir.ml"
+# 18376 "parser_cocci_menhir.ml"
) = Obj.magic pv in
let d : 'tv_d_ident = Obj.magic d in
let t : 'tv_ctype = Obj.magic t in
# 39 "standard.mly"
( None )
-# 18398 "parser_cocci_menhir.ml"
+# 18386 "parser_cocci_menhir.ml"
in
# 946 "parser_cocci_menhir.mly"
( let (id,fn) = d in
Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv)) )
-# 18405 "parser_cocci_menhir.ml"
+# 18393 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let pv : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 18441 "parser_cocci_menhir.ml"
+# 18429 "parser_cocci_menhir.ml"
) = Obj.magic pv in
let d : 'tv_d_ident = Obj.magic d in
let t : 'tv_ctype = Obj.magic t in
# 41 "standard.mly"
( Some x )
-# 18453 "parser_cocci_menhir.ml"
+# 18441 "parser_cocci_menhir.ml"
in
# 946 "parser_cocci_menhir.mly"
( let (id,fn) = d in
Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv)) )
-# 18460 "parser_cocci_menhir.ml"
+# 18448 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_one_decl_var =
# 948 "parser_cocci_menhir.mly"
( f )
-# 18484 "parser_cocci_menhir.ml"
+# 18472 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let pv : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 18525 "parser_cocci_menhir.ml"
+# 18513 "parser_cocci_menhir.ml"
) = Obj.magic pv in
let e : 'tv_initialize = Obj.magic e in
let q : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 18531 "parser_cocci_menhir.ml"
+# 18519 "parser_cocci_menhir.ml"
) = Obj.magic q in
let d : 'tv_d_ident = Obj.magic d in
let t : 'tv_ctype = Obj.magic t in
# 39 "standard.mly"
( None )
-# 18541 "parser_cocci_menhir.ml"
+# 18529 "parser_cocci_menhir.ml"
in
# 950 "parser_cocci_menhir.mly"
( let (id,fn) = d in
Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv)) )
-# 18548 "parser_cocci_menhir.ml"
+# 18536 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let pv : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 18594 "parser_cocci_menhir.ml"
+# 18582 "parser_cocci_menhir.ml"
) = Obj.magic pv in
let e : 'tv_initialize = Obj.magic e in
let q : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 18600 "parser_cocci_menhir.ml"
+# 18588 "parser_cocci_menhir.ml"
) = Obj.magic q in
let d : 'tv_d_ident = Obj.magic d in
let t : 'tv_ctype = Obj.magic t in
# 41 "standard.mly"
( Some x )
-# 18612 "parser_cocci_menhir.ml"
+# 18600 "parser_cocci_menhir.ml"
in
# 950 "parser_cocci_menhir.mly"
( let (id,fn) = d in
Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv)) )
-# 18619 "parser_cocci_menhir.ml"
+# 18607 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let pv : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 18650 "parser_cocci_menhir.ml"
+# 18638 "parser_cocci_menhir.ml"
) = Obj.magic pv in
let d : 'tv_d_ident = Obj.magic d in
let i : 'tv_pure_ident = Obj.magic i in
# 39 "standard.mly"
( None )
-# 18660 "parser_cocci_menhir.ml"
+# 18648 "parser_cocci_menhir.ml"
in
let s =
# 39 "standard.mly"
( None )
-# 18667 "parser_cocci_menhir.ml"
+# 18655 "parser_cocci_menhir.ml"
in
( let (id,fn) = d in
let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
Ast0.wrap(Ast0.UnInit(s,fn idtype,id,P.clt2mcode ";" pv)) )
-# 18675 "parser_cocci_menhir.ml"
+# 18663 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let pv : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 18711 "parser_cocci_menhir.ml"
+# 18699 "parser_cocci_menhir.ml"
) = Obj.magic pv in
let d : 'tv_d_ident = Obj.magic d in
let i : 'tv_pure_ident = Obj.magic i in
# 41 "standard.mly"
( Some x )
-# 18723 "parser_cocci_menhir.ml"
+# 18711 "parser_cocci_menhir.ml"
in
let s =
# 39 "standard.mly"
( None )
-# 18730 "parser_cocci_menhir.ml"
+# 18718 "parser_cocci_menhir.ml"
in
( let (id,fn) = d in
let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
Ast0.wrap(Ast0.UnInit(s,fn idtype,id,P.clt2mcode ";" pv)) )
-# 18738 "parser_cocci_menhir.ml"
+# 18726 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let pv : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 18774 "parser_cocci_menhir.ml"
+# 18762 "parser_cocci_menhir.ml"
) = Obj.magic pv in
let d : 'tv_d_ident = Obj.magic d in
let i : 'tv_pure_ident = Obj.magic i in
# 39 "standard.mly"
( None )
-# 18785 "parser_cocci_menhir.ml"
+# 18773 "parser_cocci_menhir.ml"
in
let s =
# 41 "standard.mly"
( Some x )
-# 18793 "parser_cocci_menhir.ml"
+# 18781 "parser_cocci_menhir.ml"
in
( let (id,fn) = d in
let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
Ast0.wrap(Ast0.UnInit(s,fn idtype,id,P.clt2mcode ";" pv)) )
-# 18801 "parser_cocci_menhir.ml"
+# 18789 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let pv : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 18842 "parser_cocci_menhir.ml"
+# 18830 "parser_cocci_menhir.ml"
) = Obj.magic pv in
let d : 'tv_d_ident = Obj.magic d in
let i : 'tv_pure_ident = Obj.magic i in
# 41 "standard.mly"
( Some x )
-# 18855 "parser_cocci_menhir.ml"
+# 18843 "parser_cocci_menhir.ml"
in
let s =
# 41 "standard.mly"
( Some x )
-# 18863 "parser_cocci_menhir.ml"
+# 18851 "parser_cocci_menhir.ml"
in
( let (id,fn) = d in
let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
Ast0.wrap(Ast0.UnInit(s,fn idtype,id,P.clt2mcode ";" pv)) )
-# 18871 "parser_cocci_menhir.ml"
+# 18859 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let pv : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 18912 "parser_cocci_menhir.ml"
+# 18900 "parser_cocci_menhir.ml"
) = Obj.magic pv in
let e : 'tv_initialize = Obj.magic e in
let q : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 18918 "parser_cocci_menhir.ml"
+# 18906 "parser_cocci_menhir.ml"
) = Obj.magic q in
let d : 'tv_d_ident = Obj.magic d in
let i : 'tv_pure_ident = Obj.magic i in
# 39 "standard.mly"
( None )
-# 18928 "parser_cocci_menhir.ml"
+# 18916 "parser_cocci_menhir.ml"
in
let s =
# 39 "standard.mly"
( None )
-# 18935 "parser_cocci_menhir.ml"
+# 18923 "parser_cocci_menhir.ml"
in
let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
Ast0.wrap(Ast0.Init(s,fn idtype,id,P.clt2mcode "=" q,e,
P.clt2mcode ";" pv)) )
-# 18945 "parser_cocci_menhir.ml"
+# 18933 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let pv : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 18991 "parser_cocci_menhir.ml"
+# 18979 "parser_cocci_menhir.ml"
) = Obj.magic pv in
let e : 'tv_initialize = Obj.magic e in
let q : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 18997 "parser_cocci_menhir.ml"
+# 18985 "parser_cocci_menhir.ml"
) = Obj.magic q in
let d : 'tv_d_ident = Obj.magic d in
let i : 'tv_pure_ident = Obj.magic i in
# 41 "standard.mly"
( Some x )
-# 19009 "parser_cocci_menhir.ml"
+# 18997 "parser_cocci_menhir.ml"
in
let s =
# 39 "standard.mly"
( None )
-# 19016 "parser_cocci_menhir.ml"
+# 19004 "parser_cocci_menhir.ml"
in
let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
Ast0.wrap(Ast0.Init(s,fn idtype,id,P.clt2mcode "=" q,e,
P.clt2mcode ";" pv)) )
-# 19026 "parser_cocci_menhir.ml"
+# 19014 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let pv : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 19072 "parser_cocci_menhir.ml"
+# 19060 "parser_cocci_menhir.ml"
) = Obj.magic pv in
let e : 'tv_initialize = Obj.magic e in
let q : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 19078 "parser_cocci_menhir.ml"
+# 19066 "parser_cocci_menhir.ml"
) = Obj.magic q in
let d : 'tv_d_ident = Obj.magic d in
let i : 'tv_pure_ident = Obj.magic i in
# 39 "standard.mly"
( None )
-# 19089 "parser_cocci_menhir.ml"
+# 19077 "parser_cocci_menhir.ml"
in
let s =
# 41 "standard.mly"
( Some x )
-# 19097 "parser_cocci_menhir.ml"
+# 19085 "parser_cocci_menhir.ml"
in
let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
Ast0.wrap(Ast0.Init(s,fn idtype,id,P.clt2mcode "=" q,e,
P.clt2mcode ";" pv)) )
-# 19107 "parser_cocci_menhir.ml"
+# 19095 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let pv : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 19158 "parser_cocci_menhir.ml"
+# 19146 "parser_cocci_menhir.ml"
) = Obj.magic pv in
let e : 'tv_initialize = Obj.magic e in
let q : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 19164 "parser_cocci_menhir.ml"
+# 19152 "parser_cocci_menhir.ml"
) = Obj.magic q in
let d : 'tv_d_ident = Obj.magic d in
let i : 'tv_pure_ident = Obj.magic i in
# 41 "standard.mly"
( Some x )
-# 19177 "parser_cocci_menhir.ml"
+# 19165 "parser_cocci_menhir.ml"
in
let s =
# 41 "standard.mly"
( Some x )
-# 19185 "parser_cocci_menhir.ml"
+# 19173 "parser_cocci_menhir.ml"
in
let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
Ast0.wrap(Ast0.Init(s,fn idtype,id,P.clt2mcode "=" q,e,
P.clt2mcode ";" pv)) )
-# 19195 "parser_cocci_menhir.ml"
+# 19183 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let pv : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 19256 "parser_cocci_menhir.ml"
+# 19244 "parser_cocci_menhir.ml"
) = Obj.magic pv in
let rp2 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 19261 "parser_cocci_menhir.ml"
+# 19249 "parser_cocci_menhir.ml"
) = Obj.magic rp2 in
let p : 'tv_decl_list_name_opt_decl_ = Obj.magic p in
let lp2 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 19267 "parser_cocci_menhir.ml"
+# 19255 "parser_cocci_menhir.ml"
) = Obj.magic lp2 in
let rp1 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 19272 "parser_cocci_menhir.ml"
+# 19260 "parser_cocci_menhir.ml"
) = Obj.magic rp1 in
let d : 'tv_d_ident = Obj.magic d in
let st : (
# 98 "parser_cocci_menhir.mly"
(Data.clt)
-# 19278 "parser_cocci_menhir.ml"
+# 19266 "parser_cocci_menhir.ml"
) = Obj.magic st in
let lp1 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 19283 "parser_cocci_menhir.ml"
+# 19271 "parser_cocci_menhir.ml"
) = Obj.magic lp1 in
let t : 'tv_fn_ctype = Obj.magic t in
let _startpos = _startpos_t_ in
# 39 "standard.mly"
( None )
-# 19292 "parser_cocci_menhir.ml"
+# 19280 "parser_cocci_menhir.ml"
in
(t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv)) )
-# 19304 "parser_cocci_menhir.ml"
+# 19292 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let pv : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 19370 "parser_cocci_menhir.ml"
+# 19358 "parser_cocci_menhir.ml"
) = Obj.magic pv in
let rp2 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 19375 "parser_cocci_menhir.ml"
+# 19363 "parser_cocci_menhir.ml"
) = Obj.magic rp2 in
let p : 'tv_decl_list_name_opt_decl_ = Obj.magic p in
let lp2 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 19381 "parser_cocci_menhir.ml"
+# 19369 "parser_cocci_menhir.ml"
) = Obj.magic lp2 in
let rp1 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 19386 "parser_cocci_menhir.ml"
+# 19374 "parser_cocci_menhir.ml"
) = Obj.magic rp1 in
let d : 'tv_d_ident = Obj.magic d in
let st : (
# 98 "parser_cocci_menhir.mly"
(Data.clt)
-# 19392 "parser_cocci_menhir.ml"
+# 19380 "parser_cocci_menhir.ml"
) = Obj.magic st in
let lp1 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 19397 "parser_cocci_menhir.ml"
+# 19385 "parser_cocci_menhir.ml"
) = Obj.magic lp1 in
let t : 'tv_fn_ctype = Obj.magic t in
let x0 : 'tv_storage = Obj.magic x0 in
# 41 "standard.mly"
( Some x )
-# 19408 "parser_cocci_menhir.ml"
+# 19396 "parser_cocci_menhir.ml"
in
(t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv)) )
-# 19420 "parser_cocci_menhir.ml"
+# 19408 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _5 : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 19461 "parser_cocci_menhir.ml"
+# 19449 "parser_cocci_menhir.ml"
) = Obj.magic _5 in
let _4 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 19466 "parser_cocci_menhir.ml"
+# 19454 "parser_cocci_menhir.ml"
) = Obj.magic _4 in
let _3 : 'tv_eexpr_list_option = Obj.magic _3 in
let _2 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 19472 "parser_cocci_menhir.ml"
+# 19460 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_decl_ident = Obj.magic _1 in
let _startpos = _startpos__1_ in
# 978 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.MacroDecl(_1,P.clt2mcode "(" _2,_3,
P.clt2mcode ")" _4,P.clt2mcode ";" _5)) )
-# 19481 "parser_cocci_menhir.ml"
+# 19469 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let pv : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 19552 "parser_cocci_menhir.ml"
+# 19540 "parser_cocci_menhir.ml"
) = Obj.magic pv in
let e : 'tv_initialize = Obj.magic e in
let q : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 19558 "parser_cocci_menhir.ml"
+# 19546 "parser_cocci_menhir.ml"
) = Obj.magic q in
let rp2 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 19563 "parser_cocci_menhir.ml"
+# 19551 "parser_cocci_menhir.ml"
) = Obj.magic rp2 in
let p : 'tv_decl_list_name_opt_decl_ = Obj.magic p in
let lp2 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 19569 "parser_cocci_menhir.ml"
+# 19557 "parser_cocci_menhir.ml"
) = Obj.magic lp2 in
let rp1 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 19574 "parser_cocci_menhir.ml"
+# 19562 "parser_cocci_menhir.ml"
) = Obj.magic rp1 in
let d : 'tv_d_ident = Obj.magic d in
let st : (
# 98 "parser_cocci_menhir.mly"
(Data.clt)
-# 19580 "parser_cocci_menhir.ml"
+# 19568 "parser_cocci_menhir.ml"
) = Obj.magic st in
let lp1 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 19585 "parser_cocci_menhir.ml"
+# 19573 "parser_cocci_menhir.ml"
) = Obj.magic lp1 in
let t : 'tv_fn_ctype = Obj.magic t in
let _startpos = _startpos_t_ in
# 39 "standard.mly"
( None )
-# 19594 "parser_cocci_menhir.ml"
+# 19582 "parser_cocci_menhir.ml"
in
(t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv)))
-# 19606 "parser_cocci_menhir.ml"
+# 19594 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let pv : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 19682 "parser_cocci_menhir.ml"
+# 19670 "parser_cocci_menhir.ml"
) = Obj.magic pv in
let e : 'tv_initialize = Obj.magic e in
let q : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 19688 "parser_cocci_menhir.ml"
+# 19676 "parser_cocci_menhir.ml"
) = Obj.magic q in
let rp2 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 19693 "parser_cocci_menhir.ml"
+# 19681 "parser_cocci_menhir.ml"
) = Obj.magic rp2 in
let p : 'tv_decl_list_name_opt_decl_ = Obj.magic p in
let lp2 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 19699 "parser_cocci_menhir.ml"
+# 19687 "parser_cocci_menhir.ml"
) = Obj.magic lp2 in
let rp1 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 19704 "parser_cocci_menhir.ml"
+# 19692 "parser_cocci_menhir.ml"
) = Obj.magic rp1 in
let d : 'tv_d_ident = Obj.magic d in
let st : (
# 98 "parser_cocci_menhir.mly"
(Data.clt)
-# 19710 "parser_cocci_menhir.ml"
+# 19698 "parser_cocci_menhir.ml"
) = Obj.magic st in
let lp1 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 19715 "parser_cocci_menhir.ml"
+# 19703 "parser_cocci_menhir.ml"
) = Obj.magic lp1 in
let t : 'tv_fn_ctype = Obj.magic t in
let x0 : 'tv_storage = Obj.magic x0 in
# 41 "standard.mly"
( Some x )
-# 19726 "parser_cocci_menhir.ml"
+# 19714 "parser_cocci_menhir.ml"
in
(t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv)))
-# 19738 "parser_cocci_menhir.ml"
+# 19726 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_option_TLocal_ =
# 29 "standard.mly"
( None )
-# 19755 "parser_cocci_menhir.ml"
+# 19743 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_option_TLocal_ =
# 31 "standard.mly"
( Some x )
-# 19779 "parser_cocci_menhir.ml"
+# 19767 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_option_TPosAny_ =
# 29 "standard.mly"
( None )
-# 19796 "parser_cocci_menhir.ml"
+# 19784 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_option_TPosAny_ =
# 31 "standard.mly"
( Some x )
-# 19820 "parser_cocci_menhir.ml"
+# 19808 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_option_eexpr_ =
# 29 "standard.mly"
( None )
-# 19837 "parser_cocci_menhir.ml"
+# 19825 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_option_eexpr_ =
# 31 "standard.mly"
( Some x )
-# 19861 "parser_cocci_menhir.ml"
- in
- _menhir_env.MenhirLib.EngineTypes.stack <- {
- MenhirLib.EngineTypes.state = _menhir_s;
- MenhirLib.EngineTypes.semv = Obj.repr _v;
- MenhirLib.EngineTypes.startp = _startpos;
- MenhirLib.EngineTypes.endp = _endpos;
- MenhirLib.EngineTypes.next = _menhir_stack;
- });
- (fun _menhir_env ->
- let _menhir_stack = _menhir_env.MenhirLib.EngineTypes.stack in
- let _menhir_s = _menhir_env.MenhirLib.EngineTypes.current in
- let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
- let _endpos = _startpos in
- let _v : 'tv_option_whenexp_ =
-# 29 "standard.mly"
- ( None )
-# 19878 "parser_cocci_menhir.ml"
- in
- _menhir_env.MenhirLib.EngineTypes.stack <- {
- MenhirLib.EngineTypes.state = _menhir_s;
- MenhirLib.EngineTypes.semv = Obj.repr _v;
- MenhirLib.EngineTypes.startp = _startpos;
- MenhirLib.EngineTypes.endp = _endpos;
- MenhirLib.EngineTypes.next = _menhir_stack;
- });
- (fun _menhir_env ->
- let _menhir_stack = _menhir_env.MenhirLib.EngineTypes.stack in
- let {
- MenhirLib.EngineTypes.state = _menhir_s;
- MenhirLib.EngineTypes.semv = x;
- MenhirLib.EngineTypes.startp = _startpos_x_;
- MenhirLib.EngineTypes.endp = _endpos_x_;
- MenhirLib.EngineTypes.next = _menhir_stack;
- } = _menhir_stack in
- let x : 'tv_whenexp = Obj.magic x in
- let _startpos = _startpos_x_ in
- let _endpos = _endpos_x_ in
- let _v : 'tv_option_whenexp_ =
-# 31 "standard.mly"
- ( Some x )
-# 19902 "parser_cocci_menhir.ml"
+# 19849 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
let _endpos = _startpos in
let _v : 'tv_plus_after_dots =
-# 1569 "parser_cocci_menhir.mly"
+# 1570 "parser_cocci_menhir.mly"
([])
-# 19919 "parser_cocci_menhir.ml"
+# 19866 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_plus_after_dots =
-# 1570 "parser_cocci_menhir.mly"
+# 1571 "parser_cocci_menhir.mly"
(_2)
-# 19947 "parser_cocci_menhir.ml"
+# 19894 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_plus_after_dots =
-# 1572 "parser_cocci_menhir.mly"
+# 1573 "parser_cocci_menhir.mly"
( (Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Exp(_1)))))::_2 )
-# 19977 "parser_cocci_menhir.ml"
+# 19924 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_plus_after_dots =
-# 1573 "parser_cocci_menhir.mly"
+# 1574 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.DECL(_1))::_2 )
-# 20007 "parser_cocci_menhir.ml"
+# 19954 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_plus_after_dots =
-# 1575 "parser_cocci_menhir.mly"
+# 1576 "parser_cocci_menhir.mly"
( (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) _1)@_2 )
-# 20037 "parser_cocci_menhir.ml"
+# 19984 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
let _endpos = _startpos in
let _v : 'tv_plus_after_exp =
-# 1565 "parser_cocci_menhir.mly"
+# 1566 "parser_cocci_menhir.mly"
([])
-# 20054 "parser_cocci_menhir.ml"
+# 20001 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_plus_after_exp =
-# 1566 "parser_cocci_menhir.mly"
+# 1567 "parser_cocci_menhir.mly"
( (Ast0.wrap(Ast0.OTHER(_1)))::_2 )
-# 20084 "parser_cocci_menhir.ml"
+# 20031 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
let _endpos = _startpos in
let _v : 'tv_plus_after_stm =
-# 1578 "parser_cocci_menhir.mly"
+# 1579 "parser_cocci_menhir.mly"
([])
-# 20101 "parser_cocci_menhir.ml"
+# 20048 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_plus_after_stm =
-# 1579 "parser_cocci_menhir.mly"
+# 1580 "parser_cocci_menhir.mly"
( (Ast0.wrap(Ast0.OTHER(_1)))::_2 )
-# 20131 "parser_cocci_menhir.ml"
+# 20078 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_plus_after_stm =
-# 1580 "parser_cocci_menhir.mly"
+# 1581 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.DECL(_1))::_2 )
-# 20161 "parser_cocci_menhir.ml"
+# 20108 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_plus_after_stm =
-# 1582 "parser_cocci_menhir.mly"
+# 1583 "parser_cocci_menhir.mly"
( (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) _1)@_2 )
-# 20191 "parser_cocci_menhir.ml"
+# 20138 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_plus_body =
# 562 "parser_cocci_menhir.mly"
( Top_level.top_level (f@b@ew) )
-# 20227 "parser_cocci_menhir.ml"
+# 20174 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_plus_exp_body =
# 576 "parser_cocci_menhir.mly"
( Top_level.top_level (f@[b]@ew) )
-# 20263 "parser_cocci_menhir.ml"
+# 20210 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : (
# 142 "parser_cocci_menhir.mly"
(Ast0_cocci.rule)
-# 20291 "parser_cocci_menhir.ml"
+# 20238 "parser_cocci_menhir.ml"
) =
# 178 "parser_cocci_menhir.mly"
( _1 )
-# 20295 "parser_cocci_menhir.ml"
+# 20242 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : (
# 142 "parser_cocci_menhir.mly"
(Ast0_cocci.rule)
-# 20323 "parser_cocci_menhir.ml"
+# 20270 "parser_cocci_menhir.ml"
) =
# 178 "parser_cocci_menhir.mly"
( p )
-# 20327 "parser_cocci_menhir.ml"
+# 20274 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : (
# 142 "parser_cocci_menhir.mly"
(Ast0_cocci.rule)
-# 20355 "parser_cocci_menhir.ml"
+# 20302 "parser_cocci_menhir.ml"
) =
# 179 "parser_cocci_menhir.mly"
( p )
-# 20359 "parser_cocci_menhir.ml"
+# 20306 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : (
# 139 "parser_cocci_menhir.mly"
(Ast0_cocci.rule)
-# 20387 "parser_cocci_menhir.ml"
+# 20334 "parser_cocci_menhir.ml"
) =
# 174 "parser_cocci_menhir.mly"
( _1 )
-# 20391 "parser_cocci_menhir.ml"
+# 20338 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : (
# 139 "parser_cocci_menhir.mly"
(Ast0_cocci.rule)
-# 20419 "parser_cocci_menhir.ml"
+# 20366 "parser_cocci_menhir.ml"
) =
# 174 "parser_cocci_menhir.mly"
( p )
-# 20423 "parser_cocci_menhir.ml"
+# 20370 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : (
# 139 "parser_cocci_menhir.mly"
(Ast0_cocci.rule)
-# 20451 "parser_cocci_menhir.ml"
+# 20398 "parser_cocci_menhir.ml"
) =
# 175 "parser_cocci_menhir.mly"
( p )
-# 20455 "parser_cocci_menhir.ml"
+# 20402 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_plus_start =
-# 1554 "parser_cocci_menhir.mly"
+# 1555 "parser_cocci_menhir.mly"
( [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Ty(_1))))] )
-# 20479 "parser_cocci_menhir.ml"
+# 20426 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_plus_start =
-# 1555 "parser_cocci_menhir.mly"
+# 1556 "parser_cocci_menhir.mly"
( [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.TopInit(_1))))] )
-# 20503 "parser_cocci_menhir.ml"
+# 20450 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_plus_start =
-# 1557 "parser_cocci_menhir.mly"
+# 1558 "parser_cocci_menhir.mly"
( (Ast0.wrap(Ast0.OTHER(_1)))::_2 )
-# 20533 "parser_cocci_menhir.ml"
+# 20480 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_plus_start =
-# 1559 "parser_cocci_menhir.mly"
+# 1560 "parser_cocci_menhir.mly"
( (Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Exp(_1)))))::_2 )
-# 20563 "parser_cocci_menhir.ml"
+# 20510 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_plus_start =
-# 1560 "parser_cocci_menhir.mly"
+# 1561 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.DECL(_1))::_2 )
-# 20593 "parser_cocci_menhir.ml"
+# 20540 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_plus_start =
-# 1562 "parser_cocci_menhir.mly"
+# 1563 "parser_cocci_menhir.mly"
( (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) _1)@_2 )
-# 20623 "parser_cocci_menhir.ml"
+# 20570 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 47 "parser_cocci_menhir.mly"
(string)
-# 20644 "parser_cocci_menhir.ml"
+# 20591 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_pnrule =
# 220 "parser_cocci_menhir.mly"
( Ast.Dep _1 )
-# 20651 "parser_cocci_menhir.ml"
+# 20598 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 47 "parser_cocci_menhir.mly"
(string)
-# 20676 "parser_cocci_menhir.ml"
+# 20623 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_pnrule =
# 221 "parser_cocci_menhir.mly"
( Ast.AntiDep _2 )
-# 20683 "parser_cocci_menhir.ml"
+# 20630 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 47 "parser_cocci_menhir.mly"
(string)
-# 20708 "parser_cocci_menhir.ml"
+# 20655 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_pnrule =
# 222 "parser_cocci_menhir.mly"
( Ast.EverDep _2 )
-# 20715 "parser_cocci_menhir.ml"
+# 20662 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 47 "parser_cocci_menhir.mly"
(string)
-# 20740 "parser_cocci_menhir.ml"
+# 20687 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_pnrule =
# 223 "parser_cocci_menhir.mly"
( Ast.NeverDep _2 )
-# 20747 "parser_cocci_menhir.ml"
+# 20694 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_pnrule =
# 224 "parser_cocci_menhir.mly"
( _2 )
-# 20779 "parser_cocci_menhir.ml"
+# 20726 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_postfix_expr_eexpr_dot_expressions_ =
-# 1249 "parser_cocci_menhir.mly"
+# 1250 "parser_cocci_menhir.mly"
( _1 )
-# 20803 "parser_cocci_menhir.ml"
+# 20750 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _4 : (
# 101 "parser_cocci_menhir.mly"
(Data.clt)
-# 20839 "parser_cocci_menhir.ml"
+# 20786 "parser_cocci_menhir.ml"
) = Obj.magic _4 in
let _3 : 'tv_eexpr = Obj.magic _3 in
let _2 : (
# 101 "parser_cocci_menhir.mly"
(Data.clt)
-# 20845 "parser_cocci_menhir.ml"
+# 20792 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_eexpr_dot_expressions_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__4_ in
let _v : 'tv_postfix_expr_eexpr_dot_expressions_ =
-# 1251 "parser_cocci_menhir.mly"
+# 1252 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.ArrayAccess (_1,P.clt2mcode "[" _2,_3,
P.clt2mcode "]" _4)) )
-# 20854 "parser_cocci_menhir.ml"
+# 20801 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 20886 "parser_cocci_menhir.ml"
+# 20833 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_eexpr_dot_expressions_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_postfix_expr_eexpr_dot_expressions_ =
-# 1254 "parser_cocci_menhir.mly"
+# 1255 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.RecordAccess(_1, P.clt2mcode "." _2, _3)) )
-# 20894 "parser_cocci_menhir.ml"
+# 20841 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 103 "parser_cocci_menhir.mly"
(Data.clt)
-# 20926 "parser_cocci_menhir.ml"
+# 20873 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_eexpr_dot_expressions_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_postfix_expr_eexpr_dot_expressions_ =
-# 1256 "parser_cocci_menhir.mly"
+# 1257 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.RecordPtAccess(_1, P.clt2mcode "->" _2,
_3)) )
-# 20935 "parser_cocci_menhir.ml"
+# 20882 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 84 "parser_cocci_menhir.mly"
(Data.clt)
-# 20961 "parser_cocci_menhir.ml"
+# 20908 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_eexpr_dot_expressions_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_postfix_expr_eexpr_dot_expressions_ =
-# 1259 "parser_cocci_menhir.mly"
+# 1260 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Inc _2)) )
-# 20969 "parser_cocci_menhir.ml"
+# 20916 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 84 "parser_cocci_menhir.mly"
(Data.clt)
-# 20995 "parser_cocci_menhir.ml"
+# 20942 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_eexpr_dot_expressions_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_postfix_expr_eexpr_dot_expressions_ =
-# 1261 "parser_cocci_menhir.mly"
+# 1262 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Dec _2)) )
-# 21003 "parser_cocci_menhir.ml"
+# 20950 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _4 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 21039 "parser_cocci_menhir.ml"
+# 20986 "parser_cocci_menhir.ml"
) = Obj.magic _4 in
let _3 : 'tv_eexpr_list_option = Obj.magic _3 in
let _2 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 21045 "parser_cocci_menhir.ml"
+# 20992 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_eexpr_dot_expressions_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__4_ in
let _v : 'tv_postfix_expr_eexpr_dot_expressions_ =
-# 1263 "parser_cocci_menhir.mly"
+# 1264 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.FunCall(_1,P.clt2mcode "(" _2,
_3,
P.clt2mcode ")" _4)) )
-# 21055 "parser_cocci_menhir.ml"
+# 21002 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_postfix_expr_eexpr_invalid_ =
-# 1249 "parser_cocci_menhir.mly"
+# 1250 "parser_cocci_menhir.mly"
( _1 )
-# 21079 "parser_cocci_menhir.ml"
+# 21026 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _4 : (
# 101 "parser_cocci_menhir.mly"
(Data.clt)
-# 21115 "parser_cocci_menhir.ml"
+# 21062 "parser_cocci_menhir.ml"
) = Obj.magic _4 in
let _3 : 'tv_eexpr = Obj.magic _3 in
let _2 : (
# 101 "parser_cocci_menhir.mly"
(Data.clt)
-# 21121 "parser_cocci_menhir.ml"
+# 21068 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_eexpr_invalid_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__4_ in
let _v : 'tv_postfix_expr_eexpr_invalid_ =
-# 1251 "parser_cocci_menhir.mly"
+# 1252 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.ArrayAccess (_1,P.clt2mcode "[" _2,_3,
P.clt2mcode "]" _4)) )
-# 21130 "parser_cocci_menhir.ml"
+# 21077 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 21162 "parser_cocci_menhir.ml"
+# 21109 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_eexpr_invalid_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_postfix_expr_eexpr_invalid_ =
-# 1254 "parser_cocci_menhir.mly"
+# 1255 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.RecordAccess(_1, P.clt2mcode "." _2, _3)) )
-# 21170 "parser_cocci_menhir.ml"
+# 21117 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 103 "parser_cocci_menhir.mly"
(Data.clt)
-# 21202 "parser_cocci_menhir.ml"
+# 21149 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_eexpr_invalid_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_postfix_expr_eexpr_invalid_ =
-# 1256 "parser_cocci_menhir.mly"
+# 1257 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.RecordPtAccess(_1, P.clt2mcode "->" _2,
_3)) )
-# 21211 "parser_cocci_menhir.ml"
+# 21158 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 84 "parser_cocci_menhir.mly"
(Data.clt)
-# 21237 "parser_cocci_menhir.ml"
+# 21184 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_eexpr_invalid_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_postfix_expr_eexpr_invalid_ =
-# 1259 "parser_cocci_menhir.mly"
+# 1260 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Inc _2)) )
-# 21245 "parser_cocci_menhir.ml"
+# 21192 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 84 "parser_cocci_menhir.mly"
(Data.clt)
-# 21271 "parser_cocci_menhir.ml"
+# 21218 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_eexpr_invalid_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_postfix_expr_eexpr_invalid_ =
-# 1261 "parser_cocci_menhir.mly"
+# 1262 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Dec _2)) )
-# 21279 "parser_cocci_menhir.ml"
+# 21226 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _4 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 21315 "parser_cocci_menhir.ml"
+# 21262 "parser_cocci_menhir.ml"
) = Obj.magic _4 in
let _3 : 'tv_eexpr_list_option = Obj.magic _3 in
let _2 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 21321 "parser_cocci_menhir.ml"
+# 21268 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_eexpr_invalid_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__4_ in
let _v : 'tv_postfix_expr_eexpr_invalid_ =
-# 1263 "parser_cocci_menhir.mly"
+# 1264 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.FunCall(_1,P.clt2mcode "(" _2,
_3,
P.clt2mcode ")" _4)) )
-# 21331 "parser_cocci_menhir.ml"
+# 21278 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_postfix_expr_eexpr_nest_expressions_ =
-# 1249 "parser_cocci_menhir.mly"
+# 1250 "parser_cocci_menhir.mly"
( _1 )
-# 21355 "parser_cocci_menhir.ml"
+# 21302 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _4 : (
# 101 "parser_cocci_menhir.mly"
(Data.clt)
-# 21391 "parser_cocci_menhir.ml"
+# 21338 "parser_cocci_menhir.ml"
) = Obj.magic _4 in
let _3 : 'tv_eexpr = Obj.magic _3 in
let _2 : (
# 101 "parser_cocci_menhir.mly"
(Data.clt)
-# 21397 "parser_cocci_menhir.ml"
+# 21344 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_eexpr_nest_expressions_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__4_ in
let _v : 'tv_postfix_expr_eexpr_nest_expressions_ =
-# 1251 "parser_cocci_menhir.mly"
+# 1252 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.ArrayAccess (_1,P.clt2mcode "[" _2,_3,
P.clt2mcode "]" _4)) )
-# 21406 "parser_cocci_menhir.ml"
+# 21353 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 21438 "parser_cocci_menhir.ml"
+# 21385 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_eexpr_nest_expressions_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_postfix_expr_eexpr_nest_expressions_ =
-# 1254 "parser_cocci_menhir.mly"
+# 1255 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.RecordAccess(_1, P.clt2mcode "." _2, _3)) )
-# 21446 "parser_cocci_menhir.ml"
+# 21393 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 103 "parser_cocci_menhir.mly"
(Data.clt)
-# 21478 "parser_cocci_menhir.ml"
+# 21425 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_eexpr_nest_expressions_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_postfix_expr_eexpr_nest_expressions_ =
-# 1256 "parser_cocci_menhir.mly"
+# 1257 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.RecordPtAccess(_1, P.clt2mcode "->" _2,
_3)) )
-# 21487 "parser_cocci_menhir.ml"
+# 21434 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 84 "parser_cocci_menhir.mly"
(Data.clt)
-# 21513 "parser_cocci_menhir.ml"
+# 21460 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_eexpr_nest_expressions_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_postfix_expr_eexpr_nest_expressions_ =
-# 1259 "parser_cocci_menhir.mly"
+# 1260 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Inc _2)) )
-# 21521 "parser_cocci_menhir.ml"
+# 21468 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 84 "parser_cocci_menhir.mly"
(Data.clt)
-# 21547 "parser_cocci_menhir.ml"
+# 21494 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_eexpr_nest_expressions_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_postfix_expr_eexpr_nest_expressions_ =
-# 1261 "parser_cocci_menhir.mly"
+# 1262 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Dec _2)) )
-# 21555 "parser_cocci_menhir.ml"
+# 21502 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _4 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 21591 "parser_cocci_menhir.ml"
+# 21538 "parser_cocci_menhir.ml"
) = Obj.magic _4 in
let _3 : 'tv_eexpr_list_option = Obj.magic _3 in
let _2 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 21597 "parser_cocci_menhir.ml"
+# 21544 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_eexpr_nest_expressions_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__4_ in
let _v : 'tv_postfix_expr_eexpr_nest_expressions_ =
-# 1263 "parser_cocci_menhir.mly"
+# 1264 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.FunCall(_1,P.clt2mcode "(" _2,
_3,
P.clt2mcode ")" _4)) )
-# 21607 "parser_cocci_menhir.ml"
+# 21554 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_postfix_expr_expr_invalid_ =
-# 1249 "parser_cocci_menhir.mly"
+# 1250 "parser_cocci_menhir.mly"
( _1 )
-# 21631 "parser_cocci_menhir.ml"
+# 21578 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _4 : (
# 101 "parser_cocci_menhir.mly"
(Data.clt)
-# 21667 "parser_cocci_menhir.ml"
+# 21614 "parser_cocci_menhir.ml"
) = Obj.magic _4 in
let _3 : 'tv_eexpr = Obj.magic _3 in
let _2 : (
# 101 "parser_cocci_menhir.mly"
(Data.clt)
-# 21673 "parser_cocci_menhir.ml"
+# 21620 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_expr_invalid_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__4_ in
let _v : 'tv_postfix_expr_expr_invalid_ =
-# 1251 "parser_cocci_menhir.mly"
+# 1252 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.ArrayAccess (_1,P.clt2mcode "[" _2,_3,
P.clt2mcode "]" _4)) )
-# 21682 "parser_cocci_menhir.ml"
+# 21629 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 21714 "parser_cocci_menhir.ml"
+# 21661 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_expr_invalid_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_postfix_expr_expr_invalid_ =
-# 1254 "parser_cocci_menhir.mly"
+# 1255 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.RecordAccess(_1, P.clt2mcode "." _2, _3)) )
-# 21722 "parser_cocci_menhir.ml"
+# 21669 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 103 "parser_cocci_menhir.mly"
(Data.clt)
-# 21754 "parser_cocci_menhir.ml"
+# 21701 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_expr_invalid_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_postfix_expr_expr_invalid_ =
-# 1256 "parser_cocci_menhir.mly"
+# 1257 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.RecordPtAccess(_1, P.clt2mcode "->" _2,
_3)) )
-# 21763 "parser_cocci_menhir.ml"
+# 21710 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 84 "parser_cocci_menhir.mly"
(Data.clt)
-# 21789 "parser_cocci_menhir.ml"
+# 21736 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_expr_invalid_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_postfix_expr_expr_invalid_ =
-# 1259 "parser_cocci_menhir.mly"
+# 1260 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Inc _2)) )
-# 21797 "parser_cocci_menhir.ml"
+# 21744 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 84 "parser_cocci_menhir.mly"
(Data.clt)
-# 21823 "parser_cocci_menhir.ml"
+# 21770 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_expr_invalid_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_postfix_expr_expr_invalid_ =
-# 1261 "parser_cocci_menhir.mly"
+# 1262 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Dec _2)) )
-# 21831 "parser_cocci_menhir.ml"
+# 21778 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _4 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 21867 "parser_cocci_menhir.ml"
+# 21814 "parser_cocci_menhir.ml"
) = Obj.magic _4 in
let _3 : 'tv_eexpr_list_option = Obj.magic _3 in
let _2 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 21873 "parser_cocci_menhir.ml"
+# 21820 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_postfix_expr_expr_invalid_ = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__4_ in
let _v : 'tv_postfix_expr_expr_invalid_ =
-# 1263 "parser_cocci_menhir.mly"
+# 1264 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.FunCall(_1,P.clt2mcode "(" _2,
_3,
P.clt2mcode ")" _4)) )
-# 21883 "parser_cocci_menhir.ml"
+# 21830 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_dot_expressions_ =
-# 1268 "parser_cocci_menhir.mly"
+# 1269 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Ident(_1)) )
-# 21907 "parser_cocci_menhir.ml"
+# 21854 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 86 "parser_cocci_menhir.mly"
(string * Data.clt)
-# 21928 "parser_cocci_menhir.ml"
+# 21875 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_dot_expressions_ =
-# 1270 "parser_cocci_menhir.mly"
+# 1271 "parser_cocci_menhir.mly"
( let (x,clt) = _1 in
Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) )
-# 21936 "parser_cocci_menhir.ml"
+# 21883 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 86 "parser_cocci_menhir.mly"
(string * Data.clt)
-# 21957 "parser_cocci_menhir.ml"
+# 21904 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_dot_expressions_ =
-# 1273 "parser_cocci_menhir.mly"
+# 1274 "parser_cocci_menhir.mly"
( let (x,clt) = _1 in
Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Float x) clt)) )
-# 21965 "parser_cocci_menhir.ml"
+# 21912 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 86 "parser_cocci_menhir.mly"
(string * Data.clt)
-# 21986 "parser_cocci_menhir.ml"
+# 21933 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_dot_expressions_ =
-# 1276 "parser_cocci_menhir.mly"
+# 1277 "parser_cocci_menhir.mly"
( let (x,clt) = _1 in
Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.String x) clt)) )
-# 21994 "parser_cocci_menhir.ml"
+# 21941 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 86 "parser_cocci_menhir.mly"
(string * Data.clt)
-# 22015 "parser_cocci_menhir.ml"
+# 21962 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_dot_expressions_ =
-# 1279 "parser_cocci_menhir.mly"
+# 1280 "parser_cocci_menhir.mly"
( let (x,clt) = _1 in
Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Char x) clt)) )
-# 22023 "parser_cocci_menhir.ml"
+# 21970 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 66 "parser_cocci_menhir.mly"
(Parse_aux.typed_info)
-# 22044 "parser_cocci_menhir.ml"
+# 21991 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_dot_expressions_ =
-# 1282 "parser_cocci_menhir.mly"
+# 1283 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,ty,clt) = _1 in
Ast0.wrap
(Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.CONST,pure)) )
-# 22053 "parser_cocci_menhir.ml"
+# 22000 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 63 "parser_cocci_menhir.mly"
(Parse_aux.expinfo)
-# 22074 "parser_cocci_menhir.ml"
+# 22021 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_dot_expressions_ =
-# 1286 "parser_cocci_menhir.mly"
+# 1287 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,clt) = _1 in
Ast0.wrap(Ast0.MetaErr(P.clt2mcode nm clt,constraints,pure)) )
-# 22082 "parser_cocci_menhir.ml"
+# 22029 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 66 "parser_cocci_menhir.mly"
(Parse_aux.typed_info)
-# 22103 "parser_cocci_menhir.ml"
+# 22050 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_dot_expressions_ =
-# 1289 "parser_cocci_menhir.mly"
+# 1290 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,ty,clt) = _1 in
Ast0.wrap
(Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ANY,pure)) )
-# 22112 "parser_cocci_menhir.ml"
+# 22059 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 66 "parser_cocci_menhir.mly"
(Parse_aux.typed_info)
-# 22133 "parser_cocci_menhir.ml"
+# 22080 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_dot_expressions_ =
-# 1293 "parser_cocci_menhir.mly"
+# 1294 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,ty,clt) = _1 in
Ast0.wrap
(Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ID,pure)) )
-# 22142 "parser_cocci_menhir.ml"
+# 22089 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 66 "parser_cocci_menhir.mly"
(Parse_aux.typed_info)
-# 22163 "parser_cocci_menhir.ml"
+# 22110 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_dot_expressions_ =
-# 1297 "parser_cocci_menhir.mly"
+# 1298 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,ty,clt) = _1 in
Ast0.wrap
(Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.LocalID,pure)) )
-# 22172 "parser_cocci_menhir.ml"
+# 22119 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _3 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 22203 "parser_cocci_menhir.ml"
+# 22150 "parser_cocci_menhir.ml"
) = Obj.magic _3 in
let _2 : 'tv_eexpr = Obj.magic _2 in
let _1 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 22209 "parser_cocci_menhir.ml"
+# 22156 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_primary_expr_eexpr_dot_expressions_ =
-# 1301 "parser_cocci_menhir.mly"
+# 1302 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Paren(P.clt2mcode "(" _1,_2,
P.clt2mcode ")" _3)) )
-# 22217 "parser_cocci_menhir.ml"
+# 22164 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _3 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 22248 "parser_cocci_menhir.ml"
+# 22195 "parser_cocci_menhir.ml"
) = Obj.magic _3 in
let _2 : 'tv_midzero_list_eexpr_eexpr_ = Obj.magic _2 in
let _1 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 22254 "parser_cocci_menhir.ml"
+# 22201 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_primary_expr_eexpr_dot_expressions_ =
-# 1304 "parser_cocci_menhir.mly"
+# 1305 "parser_cocci_menhir.mly"
( let (mids,code) = _2 in
Ast0.wrap(Ast0.DisjExpr(P.clt2mcode "(" _1,
code, mids,
P.clt2mcode ")" _3)) )
-# 22264 "parser_cocci_menhir.ml"
+# 22211 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_dot_expressions_ =
-# 1308 "parser_cocci_menhir.mly"
+# 1309 "parser_cocci_menhir.mly"
( _1 )
-# 22288 "parser_cocci_menhir.ml"
+# 22235 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_invalid_ =
-# 1268 "parser_cocci_menhir.mly"
+# 1269 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Ident(_1)) )
-# 22312 "parser_cocci_menhir.ml"
+# 22259 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 86 "parser_cocci_menhir.mly"
(string * Data.clt)
-# 22333 "parser_cocci_menhir.ml"
+# 22280 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_invalid_ =
-# 1270 "parser_cocci_menhir.mly"
+# 1271 "parser_cocci_menhir.mly"
( let (x,clt) = _1 in
Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) )
-# 22341 "parser_cocci_menhir.ml"
+# 22288 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 86 "parser_cocci_menhir.mly"
(string * Data.clt)
-# 22362 "parser_cocci_menhir.ml"
+# 22309 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_invalid_ =
-# 1273 "parser_cocci_menhir.mly"
+# 1274 "parser_cocci_menhir.mly"
( let (x,clt) = _1 in
Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Float x) clt)) )
-# 22370 "parser_cocci_menhir.ml"
+# 22317 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 86 "parser_cocci_menhir.mly"
(string * Data.clt)
-# 22391 "parser_cocci_menhir.ml"
+# 22338 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_invalid_ =
-# 1276 "parser_cocci_menhir.mly"
+# 1277 "parser_cocci_menhir.mly"
( let (x,clt) = _1 in
Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.String x) clt)) )
-# 22399 "parser_cocci_menhir.ml"
+# 22346 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 86 "parser_cocci_menhir.mly"
(string * Data.clt)
-# 22420 "parser_cocci_menhir.ml"
+# 22367 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_invalid_ =
-# 1279 "parser_cocci_menhir.mly"
+# 1280 "parser_cocci_menhir.mly"
( let (x,clt) = _1 in
Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Char x) clt)) )
-# 22428 "parser_cocci_menhir.ml"
+# 22375 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 66 "parser_cocci_menhir.mly"
(Parse_aux.typed_info)
-# 22449 "parser_cocci_menhir.ml"
+# 22396 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_invalid_ =
-# 1282 "parser_cocci_menhir.mly"
+# 1283 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,ty,clt) = _1 in
Ast0.wrap
(Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.CONST,pure)) )
-# 22458 "parser_cocci_menhir.ml"
+# 22405 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 63 "parser_cocci_menhir.mly"
(Parse_aux.expinfo)
-# 22479 "parser_cocci_menhir.ml"
+# 22426 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_invalid_ =
-# 1286 "parser_cocci_menhir.mly"
+# 1287 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,clt) = _1 in
Ast0.wrap(Ast0.MetaErr(P.clt2mcode nm clt,constraints,pure)) )
-# 22487 "parser_cocci_menhir.ml"
+# 22434 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 66 "parser_cocci_menhir.mly"
(Parse_aux.typed_info)
-# 22508 "parser_cocci_menhir.ml"
+# 22455 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_invalid_ =
-# 1289 "parser_cocci_menhir.mly"
+# 1290 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,ty,clt) = _1 in
Ast0.wrap
(Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ANY,pure)) )
-# 22517 "parser_cocci_menhir.ml"
+# 22464 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 66 "parser_cocci_menhir.mly"
(Parse_aux.typed_info)
-# 22538 "parser_cocci_menhir.ml"
+# 22485 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_invalid_ =
-# 1293 "parser_cocci_menhir.mly"
+# 1294 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,ty,clt) = _1 in
Ast0.wrap
(Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ID,pure)) )
-# 22547 "parser_cocci_menhir.ml"
+# 22494 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 66 "parser_cocci_menhir.mly"
(Parse_aux.typed_info)
-# 22568 "parser_cocci_menhir.ml"
+# 22515 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_invalid_ =
-# 1297 "parser_cocci_menhir.mly"
+# 1298 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,ty,clt) = _1 in
Ast0.wrap
(Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.LocalID,pure)) )
-# 22577 "parser_cocci_menhir.ml"
+# 22524 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _3 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 22608 "parser_cocci_menhir.ml"
+# 22555 "parser_cocci_menhir.ml"
) = Obj.magic _3 in
let _2 : 'tv_eexpr = Obj.magic _2 in
let _1 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 22614 "parser_cocci_menhir.ml"
+# 22561 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_primary_expr_eexpr_invalid_ =
-# 1301 "parser_cocci_menhir.mly"
+# 1302 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Paren(P.clt2mcode "(" _1,_2,
P.clt2mcode ")" _3)) )
-# 22622 "parser_cocci_menhir.ml"
+# 22569 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _3 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 22653 "parser_cocci_menhir.ml"
+# 22600 "parser_cocci_menhir.ml"
) = Obj.magic _3 in
let _2 : 'tv_midzero_list_eexpr_eexpr_ = Obj.magic _2 in
let _1 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 22659 "parser_cocci_menhir.ml"
+# 22606 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_primary_expr_eexpr_invalid_ =
-# 1304 "parser_cocci_menhir.mly"
+# 1305 "parser_cocci_menhir.mly"
( let (mids,code) = _2 in
Ast0.wrap(Ast0.DisjExpr(P.clt2mcode "(" _1,
code, mids,
P.clt2mcode ")" _3)) )
-# 22669 "parser_cocci_menhir.ml"
+# 22616 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_invalid_ =
-# 1308 "parser_cocci_menhir.mly"
+# 1309 "parser_cocci_menhir.mly"
( _1 )
-# 22693 "parser_cocci_menhir.ml"
+# 22640 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_nest_expressions_ =
-# 1268 "parser_cocci_menhir.mly"
+# 1269 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Ident(_1)) )
-# 22717 "parser_cocci_menhir.ml"
+# 22664 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 86 "parser_cocci_menhir.mly"
(string * Data.clt)
-# 22738 "parser_cocci_menhir.ml"
+# 22685 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_nest_expressions_ =
-# 1270 "parser_cocci_menhir.mly"
+# 1271 "parser_cocci_menhir.mly"
( let (x,clt) = _1 in
Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) )
-# 22746 "parser_cocci_menhir.ml"
+# 22693 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 86 "parser_cocci_menhir.mly"
(string * Data.clt)
-# 22767 "parser_cocci_menhir.ml"
+# 22714 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_nest_expressions_ =
-# 1273 "parser_cocci_menhir.mly"
+# 1274 "parser_cocci_menhir.mly"
( let (x,clt) = _1 in
Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Float x) clt)) )
-# 22775 "parser_cocci_menhir.ml"
+# 22722 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 86 "parser_cocci_menhir.mly"
(string * Data.clt)
-# 22796 "parser_cocci_menhir.ml"
+# 22743 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_nest_expressions_ =
-# 1276 "parser_cocci_menhir.mly"
+# 1277 "parser_cocci_menhir.mly"
( let (x,clt) = _1 in
Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.String x) clt)) )
-# 22804 "parser_cocci_menhir.ml"
+# 22751 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 86 "parser_cocci_menhir.mly"
(string * Data.clt)
-# 22825 "parser_cocci_menhir.ml"
+# 22772 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_nest_expressions_ =
-# 1279 "parser_cocci_menhir.mly"
+# 1280 "parser_cocci_menhir.mly"
( let (x,clt) = _1 in
Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Char x) clt)) )
-# 22833 "parser_cocci_menhir.ml"
+# 22780 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 66 "parser_cocci_menhir.mly"
(Parse_aux.typed_info)
-# 22854 "parser_cocci_menhir.ml"
+# 22801 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_nest_expressions_ =
-# 1282 "parser_cocci_menhir.mly"
+# 1283 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,ty,clt) = _1 in
Ast0.wrap
(Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.CONST,pure)) )
-# 22863 "parser_cocci_menhir.ml"
+# 22810 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 63 "parser_cocci_menhir.mly"
(Parse_aux.expinfo)
-# 22884 "parser_cocci_menhir.ml"
+# 22831 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_nest_expressions_ =
-# 1286 "parser_cocci_menhir.mly"
+# 1287 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,clt) = _1 in
Ast0.wrap(Ast0.MetaErr(P.clt2mcode nm clt,constraints,pure)) )
-# 22892 "parser_cocci_menhir.ml"
+# 22839 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 66 "parser_cocci_menhir.mly"
(Parse_aux.typed_info)
-# 22913 "parser_cocci_menhir.ml"
+# 22860 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_nest_expressions_ =
-# 1289 "parser_cocci_menhir.mly"
+# 1290 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,ty,clt) = _1 in
Ast0.wrap
(Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ANY,pure)) )
-# 22922 "parser_cocci_menhir.ml"
+# 22869 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 66 "parser_cocci_menhir.mly"
(Parse_aux.typed_info)
-# 22943 "parser_cocci_menhir.ml"
+# 22890 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_nest_expressions_ =
-# 1293 "parser_cocci_menhir.mly"
+# 1294 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,ty,clt) = _1 in
Ast0.wrap
(Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ID,pure)) )
-# 22952 "parser_cocci_menhir.ml"
+# 22899 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 66 "parser_cocci_menhir.mly"
(Parse_aux.typed_info)
-# 22973 "parser_cocci_menhir.ml"
+# 22920 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_nest_expressions_ =
-# 1297 "parser_cocci_menhir.mly"
+# 1298 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,ty,clt) = _1 in
Ast0.wrap
(Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.LocalID,pure)) )
-# 22982 "parser_cocci_menhir.ml"
+# 22929 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _3 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 23013 "parser_cocci_menhir.ml"
+# 22960 "parser_cocci_menhir.ml"
) = Obj.magic _3 in
let _2 : 'tv_eexpr = Obj.magic _2 in
let _1 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 23019 "parser_cocci_menhir.ml"
+# 22966 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_primary_expr_eexpr_nest_expressions_ =
-# 1301 "parser_cocci_menhir.mly"
+# 1302 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Paren(P.clt2mcode "(" _1,_2,
P.clt2mcode ")" _3)) )
-# 23027 "parser_cocci_menhir.ml"
+# 22974 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _3 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 23058 "parser_cocci_menhir.ml"
+# 23005 "parser_cocci_menhir.ml"
) = Obj.magic _3 in
let _2 : 'tv_midzero_list_eexpr_eexpr_ = Obj.magic _2 in
let _1 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 23064 "parser_cocci_menhir.ml"
+# 23011 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_primary_expr_eexpr_nest_expressions_ =
-# 1304 "parser_cocci_menhir.mly"
+# 1305 "parser_cocci_menhir.mly"
( let (mids,code) = _2 in
Ast0.wrap(Ast0.DisjExpr(P.clt2mcode "(" _1,
code, mids,
P.clt2mcode ")" _3)) )
-# 23074 "parser_cocci_menhir.ml"
+# 23021 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_eexpr_nest_expressions_ =
-# 1308 "parser_cocci_menhir.mly"
+# 1309 "parser_cocci_menhir.mly"
( _1 )
-# 23098 "parser_cocci_menhir.ml"
+# 23045 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_expr_invalid_ =
-# 1268 "parser_cocci_menhir.mly"
+# 1269 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Ident(_1)) )
-# 23122 "parser_cocci_menhir.ml"
+# 23069 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 86 "parser_cocci_menhir.mly"
(string * Data.clt)
-# 23143 "parser_cocci_menhir.ml"
+# 23090 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_expr_invalid_ =
-# 1270 "parser_cocci_menhir.mly"
+# 1271 "parser_cocci_menhir.mly"
( let (x,clt) = _1 in
Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) )
-# 23151 "parser_cocci_menhir.ml"
+# 23098 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 86 "parser_cocci_menhir.mly"
(string * Data.clt)
-# 23172 "parser_cocci_menhir.ml"
+# 23119 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_expr_invalid_ =
-# 1273 "parser_cocci_menhir.mly"
+# 1274 "parser_cocci_menhir.mly"
( let (x,clt) = _1 in
Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Float x) clt)) )
-# 23180 "parser_cocci_menhir.ml"
+# 23127 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 86 "parser_cocci_menhir.mly"
(string * Data.clt)
-# 23201 "parser_cocci_menhir.ml"
+# 23148 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_expr_invalid_ =
-# 1276 "parser_cocci_menhir.mly"
+# 1277 "parser_cocci_menhir.mly"
( let (x,clt) = _1 in
Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.String x) clt)) )
-# 23209 "parser_cocci_menhir.ml"
+# 23156 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 86 "parser_cocci_menhir.mly"
(string * Data.clt)
-# 23230 "parser_cocci_menhir.ml"
+# 23177 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_expr_invalid_ =
-# 1279 "parser_cocci_menhir.mly"
+# 1280 "parser_cocci_menhir.mly"
( let (x,clt) = _1 in
Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Char x) clt)) )
-# 23238 "parser_cocci_menhir.ml"
+# 23185 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 66 "parser_cocci_menhir.mly"
(Parse_aux.typed_info)
-# 23259 "parser_cocci_menhir.ml"
+# 23206 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_expr_invalid_ =
-# 1282 "parser_cocci_menhir.mly"
+# 1283 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,ty,clt) = _1 in
Ast0.wrap
(Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.CONST,pure)) )
-# 23268 "parser_cocci_menhir.ml"
+# 23215 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 63 "parser_cocci_menhir.mly"
(Parse_aux.expinfo)
-# 23289 "parser_cocci_menhir.ml"
+# 23236 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_expr_invalid_ =
-# 1286 "parser_cocci_menhir.mly"
+# 1287 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,clt) = _1 in
Ast0.wrap(Ast0.MetaErr(P.clt2mcode nm clt,constraints,pure)) )
-# 23297 "parser_cocci_menhir.ml"
+# 23244 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 66 "parser_cocci_menhir.mly"
(Parse_aux.typed_info)
-# 23318 "parser_cocci_menhir.ml"
+# 23265 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_expr_invalid_ =
-# 1289 "parser_cocci_menhir.mly"
+# 1290 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,ty,clt) = _1 in
Ast0.wrap
(Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ANY,pure)) )
-# 23327 "parser_cocci_menhir.ml"
+# 23274 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 66 "parser_cocci_menhir.mly"
(Parse_aux.typed_info)
-# 23348 "parser_cocci_menhir.ml"
+# 23295 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_expr_invalid_ =
-# 1293 "parser_cocci_menhir.mly"
+# 1294 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,ty,clt) = _1 in
Ast0.wrap
(Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ID,pure)) )
-# 23357 "parser_cocci_menhir.ml"
+# 23304 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 66 "parser_cocci_menhir.mly"
(Parse_aux.typed_info)
-# 23378 "parser_cocci_menhir.ml"
+# 23325 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_expr_invalid_ =
-# 1297 "parser_cocci_menhir.mly"
+# 1298 "parser_cocci_menhir.mly"
( let (nm,constraints,pure,ty,clt) = _1 in
Ast0.wrap
(Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.LocalID,pure)) )
-# 23387 "parser_cocci_menhir.ml"
+# 23334 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _3 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 23418 "parser_cocci_menhir.ml"
+# 23365 "parser_cocci_menhir.ml"
) = Obj.magic _3 in
let _2 : 'tv_eexpr = Obj.magic _2 in
let _1 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 23424 "parser_cocci_menhir.ml"
+# 23371 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_primary_expr_expr_invalid_ =
-# 1301 "parser_cocci_menhir.mly"
+# 1302 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Paren(P.clt2mcode "(" _1,_2,
P.clt2mcode ")" _3)) )
-# 23432 "parser_cocci_menhir.ml"
+# 23379 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _3 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 23463 "parser_cocci_menhir.ml"
+# 23410 "parser_cocci_menhir.ml"
) = Obj.magic _3 in
let _2 : 'tv_midzero_list_expr_eexpr_ = Obj.magic _2 in
let _1 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 23469 "parser_cocci_menhir.ml"
+# 23416 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_primary_expr_expr_invalid_ =
-# 1304 "parser_cocci_menhir.mly"
+# 1305 "parser_cocci_menhir.mly"
( let (mids,code) = _2 in
Ast0.wrap(Ast0.DisjExpr(P.clt2mcode "(" _1,
code, mids,
P.clt2mcode ")" _3)) )
-# 23479 "parser_cocci_menhir.ml"
+# 23426 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_primary_expr_expr_invalid_ =
-# 1308 "parser_cocci_menhir.mly"
+# 1309 "parser_cocci_menhir.mly"
( _1 )
-# 23503 "parser_cocci_menhir.ml"
+# 23450 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_pure =
# 189 "parser_cocci_menhir.mly"
( Ast0.Pure )
-# 23525 "parser_cocci_menhir.ml"
+# 23472 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_pure =
# 190 "parser_cocci_menhir.mly"
( Ast0.Context )
-# 23547 "parser_cocci_menhir.ml"
+# 23494 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_pure =
# 191 "parser_cocci_menhir.mly"
( Ast0.PureContext )
-# 23573 "parser_cocci_menhir.ml"
+# 23520 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_pure =
# 192 "parser_cocci_menhir.mly"
( Ast0.PureContext )
-# 23599 "parser_cocci_menhir.ml"
+# 23546 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_pure =
# 193 "parser_cocci_menhir.mly"
( Ast0.Impure )
-# 23616 "parser_cocci_menhir.ml"
+# 23563 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 59 "parser_cocci_menhir.mly"
(string * Data.clt)
-# 23637 "parser_cocci_menhir.ml"
+# 23584 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_pure_ident =
-# 1322 "parser_cocci_menhir.mly"
+# 1323 "parser_cocci_menhir.mly"
( _1 )
-# 23644 "parser_cocci_menhir.ml"
+# 23591 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_pure_ident_or_meta_ident =
-# 1328 "parser_cocci_menhir.mly"
+# 1329 "parser_cocci_menhir.mly"
( (None,P.id2name _1) )
-# 23668 "parser_cocci_menhir.ml"
+# 23615 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_pure_ident_or_meta_ident =
-# 1329 "parser_cocci_menhir.mly"
+# 1330 "parser_cocci_menhir.mly"
( _1 )
-# 23692 "parser_cocci_menhir.ml"
+# 23639 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_pure_ident_or_meta_ident =
-# 1330 "parser_cocci_menhir.mly"
+# 1331 "parser_cocci_menhir.mly"
( (None,"list") )
-# 23714 "parser_cocci_menhir.ml"
+# 23661 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_pure_ident_or_meta_ident =
-# 1331 "parser_cocci_menhir.mly"
+# 1332 "parser_cocci_menhir.mly"
( (None,"error") )
-# 23736 "parser_cocci_menhir.ml"
+# 23683 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_pure_ident_or_meta_ident =
-# 1332 "parser_cocci_menhir.mly"
+# 1333 "parser_cocci_menhir.mly"
( (None,"type") )
-# 23758 "parser_cocci_menhir.ml"
+# 23705 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos_i_ in
let _endpos = _endpos_l_ in
let _v : 'tv_pure_ident_or_meta_ident_with_not_eq_not_ceq_ =
-# 1335 "parser_cocci_menhir.mly"
+# 1336 "parser_cocci_menhir.mly"
( (i,l) )
-# 23788 "parser_cocci_menhir.ml"
+# 23735 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos_i_ in
let _endpos = _endpos_l_ in
let _v : 'tv_pure_ident_or_meta_ident_with_not_eq_not_eq_ =
-# 1335 "parser_cocci_menhir.mly"
+# 1336 "parser_cocci_menhir.mly"
( (i,l) )
-# 23818 "parser_cocci_menhir.ml"
+# 23765 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos_i_ in
let _endpos = _endpos_l_ in
let _v : 'tv_pure_ident_or_meta_ident_with_not_eq_not_eqe_ =
-# 1335 "parser_cocci_menhir.mly"
+# 1336 "parser_cocci_menhir.mly"
( (i,l) )
-# 23848 "parser_cocci_menhir.ml"
+# 23795 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos_i_ in
let _endpos = _endpos_l_ in
let _v : 'tv_pure_ident_or_meta_ident_with_not_eq_not_pos_ =
-# 1335 "parser_cocci_menhir.mly"
+# 1336 "parser_cocci_menhir.mly"
( (i,l) )
-# 23878 "parser_cocci_menhir.ml"
+# 23825 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : (
# 130 "parser_cocci_menhir.mly"
(unit)
-# 23895 "parser_cocci_menhir.ml"
+# 23842 "parser_cocci_menhir.ml"
) =
# 171 "parser_cocci_menhir.mly"
( )
-# 23899 "parser_cocci_menhir.ml"
+# 23846 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_rule_elem_statement =
# 849 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Decl((Ast0.default_info(),Ast0.context_befaft()),_1)) )
-# 23923 "parser_cocci_menhir.ml"
+# 23870 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 23949 "parser_cocci_menhir.ml"
+# 23896 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_expr = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _v : 'tv_rule_elem_statement =
# 850 "parser_cocci_menhir.mly"
( P.exp_stm _1 _2 )
-# 23957 "parser_cocci_menhir.ml"
+# 23904 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _3 : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 23988 "parser_cocci_menhir.ml"
+# 23935 "parser_cocci_menhir.ml"
) = Obj.magic _3 in
let _2 : 'tv_eexpr = Obj.magic _2 in
let _1 : (
# 57 "parser_cocci_menhir.mly"
(Data.clt)
-# 23994 "parser_cocci_menhir.ml"
+# 23941 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_rule_elem_statement =
# 851 "parser_cocci_menhir.mly"
( P.ret_exp _1 _2 _3 )
-# 24001 "parser_cocci_menhir.ml"
+# 23948 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 24027 "parser_cocci_menhir.ml"
+# 23974 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : (
# 57 "parser_cocci_menhir.mly"
(Data.clt)
-# 24032 "parser_cocci_menhir.ml"
+# 23979 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_rule_elem_statement =
# 852 "parser_cocci_menhir.mly"
( P.ret _1 _2 )
-# 24039 "parser_cocci_menhir.ml"
+# 23986 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 24065 "parser_cocci_menhir.ml"
+# 24012 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : (
# 58 "parser_cocci_menhir.mly"
(Data.clt)
-# 24070 "parser_cocci_menhir.ml"
+# 24017 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_rule_elem_statement =
# 853 "parser_cocci_menhir.mly"
( P.break _1 _2 )
-# 24077 "parser_cocci_menhir.ml"
+# 24024 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 24103 "parser_cocci_menhir.ml"
+# 24050 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : (
# 58 "parser_cocci_menhir.mly"
(Data.clt)
-# 24108 "parser_cocci_menhir.ml"
+# 24055 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_rule_elem_statement =
# 854 "parser_cocci_menhir.mly"
( P.cont _1 _2 )
-# 24115 "parser_cocci_menhir.ml"
+# 24062 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _3 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 24146 "parser_cocci_menhir.ml"
+# 24093 "parser_cocci_menhir.ml"
) = Obj.magic _3 in
let _2 : 'tv_midzero_list_rule_elem_statement_rule_elem_statement_ = Obj.magic _2 in
let _1 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 24152 "parser_cocci_menhir.ml"
+# 24099 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
(Ast0.Disj(P.clt2mcode "(" _1,
List.map (function x -> Ast0.wrap(Ast0.DOTS([x]))) code,
mids, P.clt2mcode ")" _3)) )
-# 24163 "parser_cocci_menhir.ml"
+# 24110 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : (
# 152 "parser_cocci_menhir.mly"
(Ast_cocci.rulename)
-# 24219 "parser_cocci_menhir.ml"
+# 24166 "parser_cocci_menhir.ml"
) = let nm =
# 39 "standard.mly"
( None )
-# 24224 "parser_cocci_menhir.ml"
+# 24171 "parser_cocci_menhir.ml"
in
# 201 "parser_cocci_menhir.mly"
( P.make_cocci_rule_name_result nm d i a e ee )
-# 24230 "parser_cocci_menhir.ml"
+# 24177 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : (
# 152 "parser_cocci_menhir.mly"
(Ast_cocci.rulename)
-# 24292 "parser_cocci_menhir.ml"
+# 24239 "parser_cocci_menhir.ml"
) = let nm =
let x = x0 in
# 41 "standard.mly"
( Some x )
-# 24298 "parser_cocci_menhir.ml"
+# 24245 "parser_cocci_menhir.ml"
in
# 201 "parser_cocci_menhir.mly"
( P.make_cocci_rule_name_result nm d i a e ee )
-# 24304 "parser_cocci_menhir.ml"
+# 24251 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : (
# 152 "parser_cocci_menhir.mly"
(Ast_cocci.rulename)
-# 24346 "parser_cocci_menhir.ml"
+# 24293 "parser_cocci_menhir.ml"
) =
# 203 "parser_cocci_menhir.mly"
( P.make_script_rule_name_result lang d )
-# 24350 "parser_cocci_menhir.ml"
+# 24297 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _3 : (
# 47 "parser_cocci_menhir.mly"
(string)
-# 24394 "parser_cocci_menhir.ml"
+# 24341 "parser_cocci_menhir.ml"
) = Obj.magic _3 in
let py : 'tv_pure_ident = Obj.magic py in
let _startpos = _startpos_py_ in
let _v : (
# 158 "parser_cocci_menhir.mly"
(string * (string * string))
-# 24402 "parser_cocci_menhir.ml"
+# 24349 "parser_cocci_menhir.ml"
) =
-# 1769 "parser_cocci_menhir.mly"
+# 1770 "parser_cocci_menhir.mly"
( (P.id2name py, (_3, P.id2name cocci)) )
-# 24406 "parser_cocci_menhir.ml"
+# 24353 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let x : (
# 86 "parser_cocci_menhir.mly"
(string * Data.clt)
-# 24427 "parser_cocci_menhir.ml"
+# 24374 "parser_cocci_menhir.ml"
) = Obj.magic x in
let _startpos = _startpos_x_ in
let _endpos = _endpos_x_ in
let _v : 'tv_separated_nonempty_list_TComma_TString_ =
# 144 "standard.mly"
( [ x ] )
-# 24434 "parser_cocci_menhir.ml"
+# 24381 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let x : (
# 86 "parser_cocci_menhir.mly"
(string * Data.clt)
-# 24465 "parser_cocci_menhir.ml"
+# 24412 "parser_cocci_menhir.ml"
) = Obj.magic x in
let _startpos = _startpos_x_ in
let _endpos = _endpos_xs_ in
let _v : 'tv_separated_nonempty_list_TComma_TString_ =
# 146 "standard.mly"
( x :: xs )
-# 24472 "parser_cocci_menhir.ml"
+# 24419 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_any_strict_ =
# 144 "standard.mly"
( [ x ] )
-# 24496 "parser_cocci_menhir.ml"
+# 24443 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_any_strict_ =
# 146 "standard.mly"
( x :: xs )
-# 24530 "parser_cocci_menhir.ml"
+# 24477 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_ctype_ =
# 144 "standard.mly"
( [ x ] )
-# 24554 "parser_cocci_menhir.ml"
+# 24501 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_ctype_ =
# 146 "standard.mly"
( x :: xs )
-# 24588 "parser_cocci_menhir.ml"
+# 24535 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_d_ident_ =
# 144 "standard.mly"
( [ x ] )
-# 24612 "parser_cocci_menhir.ml"
+# 24559 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_d_ident_ =
# 146 "standard.mly"
( x :: xs )
-# 24646 "parser_cocci_menhir.ml"
+# 24593 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_dexpr_ =
# 144 "standard.mly"
( [ x ] )
-# 24670 "parser_cocci_menhir.ml"
+# 24617 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_dexpr_ =
# 146 "standard.mly"
( x :: xs )
-# 24704 "parser_cocci_menhir.ml"
+# 24651 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_ident_or_const_ =
# 144 "standard.mly"
( [ x ] )
-# 24728 "parser_cocci_menhir.ml"
+# 24675 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_ident_or_const_ =
# 146 "standard.mly"
( x :: xs )
-# 24762 "parser_cocci_menhir.ml"
+# 24709 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_meta_ident_ =
# 144 "standard.mly"
( [ x ] )
-# 24786 "parser_cocci_menhir.ml"
+# 24733 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_meta_ident_ =
# 146 "standard.mly"
( x :: xs )
-# 24820 "parser_cocci_menhir.ml"
+# 24767 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_pure_ident_ =
# 144 "standard.mly"
( [ x ] )
-# 24844 "parser_cocci_menhir.ml"
+# 24791 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_pure_ident_ =
# 146 "standard.mly"
( x :: xs )
-# 24878 "parser_cocci_menhir.ml"
+# 24825 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_ =
# 144 "standard.mly"
( [ x ] )
-# 24902 "parser_cocci_menhir.ml"
+# 24849 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_ =
# 146 "standard.mly"
( x :: xs )
-# 24936 "parser_cocci_menhir.ml"
+# 24883 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_with_not_eq_not_ceq__ =
# 144 "standard.mly"
( [ x ] )
-# 24960 "parser_cocci_menhir.ml"
+# 24907 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_with_not_eq_not_ceq__ =
# 146 "standard.mly"
( x :: xs )
-# 24994 "parser_cocci_menhir.ml"
+# 24941 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_with_not_eq_not_eq__ =
# 144 "standard.mly"
( [ x ] )
-# 25018 "parser_cocci_menhir.ml"
+# 24965 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_with_not_eq_not_eq__ =
# 146 "standard.mly"
( x :: xs )
-# 25052 "parser_cocci_menhir.ml"
+# 24999 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_with_not_eq_not_eqe__ =
# 144 "standard.mly"
( [ x ] )
-# 25076 "parser_cocci_menhir.ml"
+# 25023 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_with_not_eq_not_eqe__ =
# 146 "standard.mly"
( x :: xs )
-# 25110 "parser_cocci_menhir.ml"
+# 25057 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_with_not_eq_not_pos__ =
# 144 "standard.mly"
( [ x ] )
-# 25134 "parser_cocci_menhir.ml"
+# 25081 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_with_not_eq_not_pos__ =
# 146 "standard.mly"
( x :: xs )
-# 25168 "parser_cocci_menhir.ml"
+# 25115 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_single_statement =
# 864 "parser_cocci_menhir.mly"
( _1 )
-# 25192 "parser_cocci_menhir.ml"
+# 25139 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _3 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 25223 "parser_cocci_menhir.ml"
+# 25170 "parser_cocci_menhir.ml"
) = Obj.magic _3 in
let _2 : 'tv_midzero_list_statement_statement_ = Obj.magic _2 in
let _1 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 25229 "parser_cocci_menhir.ml"
+# 25176 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
(Ast0.Disj(P.clt2mcode "(" _1,
List.map (function x -> Ast0.wrap(Ast0.DOTS([x]))) code,
mids, P.clt2mcode ")" _3)) )
-# 25240 "parser_cocci_menhir.ml"
+# 25187 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_statement =
# 803 "parser_cocci_menhir.mly"
( _1 )
-# 25264 "parser_cocci_menhir.ml"
+# 25211 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 64 "parser_cocci_menhir.mly"
(Parse_aux.info)
-# 25285 "parser_cocci_menhir.ml"
+# 25232 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_statement =
# 805 "parser_cocci_menhir.mly"
( P.meta_stm _1 )
-# 25292 "parser_cocci_menhir.ml"
+# 25239 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 25318 "parser_cocci_menhir.ml"
+# 25265 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_expr = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _v : 'tv_statement =
# 807 "parser_cocci_menhir.mly"
( P.exp_stm _1 _2 )
-# 25326 "parser_cocci_menhir.ml"
+# 25273 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _4 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 25368 "parser_cocci_menhir.ml"
+# 25315 "parser_cocci_menhir.ml"
) = Obj.magic _4 in
let _3 : 'tv_eexpr = Obj.magic _3 in
let _2 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 25374 "parser_cocci_menhir.ml"
+# 25321 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : (
# 57 "parser_cocci_menhir.mly"
(Data.clt)
-# 25379 "parser_cocci_menhir.ml"
+# 25326 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__5_ in
let _v : 'tv_statement =
# 809 "parser_cocci_menhir.mly"
( P.ifthen _1 _2 _3 _4 _5 )
-# 25386 "parser_cocci_menhir.ml"
+# 25333 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _6 : (
# 57 "parser_cocci_menhir.mly"
(Data.clt)
-# 25438 "parser_cocci_menhir.ml"
+# 25385 "parser_cocci_menhir.ml"
) = Obj.magic _6 in
let _5 : 'tv_single_statement = Obj.magic _5 in
let _4 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 25444 "parser_cocci_menhir.ml"
+# 25391 "parser_cocci_menhir.ml"
) = Obj.magic _4 in
let _3 : 'tv_eexpr = Obj.magic _3 in
let _2 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 25450 "parser_cocci_menhir.ml"
+# 25397 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : (
# 57 "parser_cocci_menhir.mly"
(Data.clt)
-# 25455 "parser_cocci_menhir.ml"
+# 25402 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__7_ in
let _v : 'tv_statement =
# 811 "parser_cocci_menhir.mly"
( P.ifthenelse _1 _2 _3 _4 _5 _6 _7 )
-# 25462 "parser_cocci_menhir.ml"
+# 25409 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _8 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 25524 "parser_cocci_menhir.ml"
+# 25471 "parser_cocci_menhir.ml"
) = Obj.magic _8 in
let _7 : 'tv_option_eexpr_ = Obj.magic _7 in
let _6 : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 25530 "parser_cocci_menhir.ml"
+# 25477 "parser_cocci_menhir.ml"
) = Obj.magic _6 in
let _5 : 'tv_option_eexpr_ = Obj.magic _5 in
let _4 : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 25536 "parser_cocci_menhir.ml"
+# 25483 "parser_cocci_menhir.ml"
) = Obj.magic _4 in
let _3 : 'tv_option_eexpr_ = Obj.magic _3 in
let _2 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 25542 "parser_cocci_menhir.ml"
+# 25489 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : (
# 57 "parser_cocci_menhir.mly"
(Data.clt)
-# 25547 "parser_cocci_menhir.ml"
+# 25494 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__9_ in
let _v : 'tv_statement =
# 814 "parser_cocci_menhir.mly"
( P.forloop _1 _2 _3 _4 _5 _6 _7 _8 _9 )
-# 25554 "parser_cocci_menhir.ml"
+# 25501 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _4 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 25596 "parser_cocci_menhir.ml"
+# 25543 "parser_cocci_menhir.ml"
) = Obj.magic _4 in
let _3 : 'tv_eexpr = Obj.magic _3 in
let _2 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 25602 "parser_cocci_menhir.ml"
+# 25549 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : (
# 57 "parser_cocci_menhir.mly"
(Data.clt)
-# 25607 "parser_cocci_menhir.ml"
+# 25554 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__5_ in
let _v : 'tv_statement =
# 816 "parser_cocci_menhir.mly"
( P.whileloop _1 _2 _3 _4 _5 )
-# 25614 "parser_cocci_menhir.ml"
+# 25561 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _7 : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 25665 "parser_cocci_menhir.ml"
+# 25612 "parser_cocci_menhir.ml"
) = Obj.magic _7 in
let _6 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 25670 "parser_cocci_menhir.ml"
+# 25617 "parser_cocci_menhir.ml"
) = Obj.magic _6 in
let _5 : 'tv_eexpr = Obj.magic _5 in
let _4 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 25676 "parser_cocci_menhir.ml"
+# 25623 "parser_cocci_menhir.ml"
) = Obj.magic _4 in
let _3 : (
# 57 "parser_cocci_menhir.mly"
(Data.clt)
-# 25681 "parser_cocci_menhir.ml"
+# 25628 "parser_cocci_menhir.ml"
) = Obj.magic _3 in
let _2 : 'tv_single_statement = Obj.magic _2 in
let _1 : (
# 57 "parser_cocci_menhir.mly"
(Data.clt)
-# 25687 "parser_cocci_menhir.ml"
+# 25634 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__7_ in
let _v : 'tv_statement =
# 818 "parser_cocci_menhir.mly"
( P.doloop _1 _2 _3 _4 _5 _6 _7 )
-# 25694 "parser_cocci_menhir.ml"
+# 25641 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _4 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 25736 "parser_cocci_menhir.ml"
+# 25683 "parser_cocci_menhir.ml"
) = Obj.magic _4 in
let _3 : 'tv_eexpr_list_option = Obj.magic _3 in
let _2 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 25742 "parser_cocci_menhir.ml"
+# 25689 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_iter_ident = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _v : 'tv_statement =
# 820 "parser_cocci_menhir.mly"
( P.iterator _1 _2 _3 _4 _5 )
-# 25750 "parser_cocci_menhir.ml"
+# 25697 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _7 : (
# 100 "parser_cocci_menhir.mly"
(Data.clt)
-# 25801 "parser_cocci_menhir.ml"
+# 25748 "parser_cocci_menhir.ml"
) = Obj.magic _7 in
let _6 : 'tv_list_case_line_ = Obj.magic _6 in
let _5 : (
# 100 "parser_cocci_menhir.mly"
(Data.clt)
-# 25807 "parser_cocci_menhir.ml"
+# 25754 "parser_cocci_menhir.ml"
) = Obj.magic _5 in
let _4 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 25812 "parser_cocci_menhir.ml"
+# 25759 "parser_cocci_menhir.ml"
) = Obj.magic _4 in
let _3 : 'tv_eexpr = Obj.magic _3 in
let _2 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 25818 "parser_cocci_menhir.ml"
+# 25765 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : (
# 57 "parser_cocci_menhir.mly"
(Data.clt)
-# 25823 "parser_cocci_menhir.ml"
+# 25770 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__7_ in
let _v : 'tv_statement =
# 822 "parser_cocci_menhir.mly"
( P.switch _1 _2 _3 _4 _5 _6 _7 )
-# 25830 "parser_cocci_menhir.ml"
+# 25777 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _3 : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 25861 "parser_cocci_menhir.ml"
+# 25808 "parser_cocci_menhir.ml"
) = Obj.magic _3 in
let _2 : 'tv_eexpr = Obj.magic _2 in
let _1 : (
# 57 "parser_cocci_menhir.mly"
(Data.clt)
-# 25867 "parser_cocci_menhir.ml"
+# 25814 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_statement =
# 823 "parser_cocci_menhir.mly"
( P.ret_exp _1 _2 _3 )
-# 25874 "parser_cocci_menhir.ml"
+# 25821 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 25900 "parser_cocci_menhir.ml"
+# 25847 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : (
# 57 "parser_cocci_menhir.mly"
(Data.clt)
-# 25905 "parser_cocci_menhir.ml"
+# 25852 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_statement =
# 824 "parser_cocci_menhir.mly"
( P.ret _1 _2 )
-# 25912 "parser_cocci_menhir.ml"
+# 25859 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 25938 "parser_cocci_menhir.ml"
+# 25885 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : (
# 58 "parser_cocci_menhir.mly"
(Data.clt)
-# 25943 "parser_cocci_menhir.ml"
+# 25890 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_statement =
# 825 "parser_cocci_menhir.mly"
( P.break _1 _2 )
-# 25950 "parser_cocci_menhir.ml"
+# 25897 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 25976 "parser_cocci_menhir.ml"
+# 25923 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : (
# 58 "parser_cocci_menhir.mly"
(Data.clt)
-# 25981 "parser_cocci_menhir.ml"
+# 25928 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_statement =
# 826 "parser_cocci_menhir.mly"
( P.cont _1 _2 )
-# 25988 "parser_cocci_menhir.ml"
+# 25935 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _2 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 26014 "parser_cocci_menhir.ml"
+# 25961 "parser_cocci_menhir.ml"
) = Obj.magic _2 in
let _1 : 'tv_ident = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _v : 'tv_statement =
# 827 "parser_cocci_menhir.mly"
( P.label _1 _2 )
-# 26022 "parser_cocci_menhir.ml"
+# 25969 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _3 : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 26053 "parser_cocci_menhir.ml"
+# 26000 "parser_cocci_menhir.ml"
) = Obj.magic _3 in
let _2 : 'tv_ident = Obj.magic _2 in
let _1 : (
# 58 "parser_cocci_menhir.mly"
(Data.clt)
-# 26059 "parser_cocci_menhir.ml"
+# 26006 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_statement =
# 828 "parser_cocci_menhir.mly"
( P.goto _1 _2 _3 )
-# 26066 "parser_cocci_menhir.ml"
+# 26013 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _3 : (
# 100 "parser_cocci_menhir.mly"
(Data.clt)
-# 26097 "parser_cocci_menhir.ml"
+# 26044 "parser_cocci_menhir.ml"
) = Obj.magic _3 in
let _2 : 'tv_fun_start = Obj.magic _2 in
let _1 : (
# 100 "parser_cocci_menhir.mly"
(Data.clt)
-# 26103 "parser_cocci_menhir.ml"
+# 26050 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_statement =
# 830 "parser_cocci_menhir.mly"
( P.seq _1 _2 _3 )
-# 26110 "parser_cocci_menhir.ml"
+# 26057 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 72 "parser_cocci_menhir.mly"
(Data.clt)
-# 26137 "parser_cocci_menhir.ml"
+# 26084 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos_w_ in
let _v : 'tv_stm_dots =
# 834 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Dots(P.clt2mcode "..." _1, List.concat w)) )
-# 26144 "parser_cocci_menhir.ml"
+# 26091 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let c : (
# 72 "parser_cocci_menhir.mly"
(Data.clt)
-# 26180 "parser_cocci_menhir.ml"
+# 26127 "parser_cocci_menhir.ml"
) = Obj.magic c in
let b : 'tv_nest_start = Obj.magic b in
let w : 'tv_list_whenppdecs_ = Obj.magic w in
let _1 : (
# 72 "parser_cocci_menhir.mly"
(Data.clt)
-# 26187 "parser_cocci_menhir.ml"
+# 26134 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos_c_ in
# 836 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Nest(P.clt2mcode "<..." _1, b,
P.clt2mcode "...>" c, List.concat w, false)) )
-# 26195 "parser_cocci_menhir.ml"
+# 26142 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let c : (
# 72 "parser_cocci_menhir.mly"
(Data.clt)
-# 26231 "parser_cocci_menhir.ml"
+# 26178 "parser_cocci_menhir.ml"
) = Obj.magic c in
let b : 'tv_nest_start = Obj.magic b in
let w : 'tv_list_whenppdecs_ = Obj.magic w in
let _1 : (
# 72 "parser_cocci_menhir.mly"
(Data.clt)
-# 26238 "parser_cocci_menhir.ml"
+# 26185 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos_c_ in
# 839 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Nest(P.clt2mcode "<+..." _1, b,
P.clt2mcode "...+>" c, List.concat w, true)) )
-# 26246 "parser_cocci_menhir.ml"
+# 26193 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let s : (
# 53 "parser_cocci_menhir.mly"
(Data.clt)
-# 26267 "parser_cocci_menhir.ml"
+# 26214 "parser_cocci_menhir.ml"
) = Obj.magic s in
let _startpos = _startpos_s_ in
let _endpos = _endpos_s_ in
let _v : 'tv_storage =
# 762 "parser_cocci_menhir.mly"
( P.clt2mcode Ast.Static s )
-# 26274 "parser_cocci_menhir.ml"
+# 26221 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let s : (
# 53 "parser_cocci_menhir.mly"
(Data.clt)
-# 26295 "parser_cocci_menhir.ml"
+# 26242 "parser_cocci_menhir.ml"
) = Obj.magic s in
let _startpos = _startpos_s_ in
let _endpos = _endpos_s_ in
let _v : 'tv_storage =
# 763 "parser_cocci_menhir.mly"
( P.clt2mcode Ast.Auto s )
-# 26302 "parser_cocci_menhir.ml"
+# 26249 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let s : (
# 53 "parser_cocci_menhir.mly"
(Data.clt)
-# 26323 "parser_cocci_menhir.ml"
+# 26270 "parser_cocci_menhir.ml"
) = Obj.magic s in
let _startpos = _startpos_s_ in
let _endpos = _endpos_s_ in
let _v : 'tv_storage =
# 764 "parser_cocci_menhir.mly"
( P.clt2mcode Ast.Register s )
-# 26330 "parser_cocci_menhir.ml"
+# 26277 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let s : (
# 53 "parser_cocci_menhir.mly"
(Data.clt)
-# 26351 "parser_cocci_menhir.ml"
+# 26298 "parser_cocci_menhir.ml"
) = Obj.magic s in
let _startpos = _startpos_s_ in
let _endpos = _endpos_s_ in
let _v : 'tv_storage =
# 765 "parser_cocci_menhir.mly"
( P.clt2mcode Ast.Extern s )
-# 26358 "parser_cocci_menhir.ml"
+# 26305 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_struct_decl =
# 488 "parser_cocci_menhir.mly"
( [] )
-# 26380 "parser_cocci_menhir.ml"
+# 26327 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let pv : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 26411 "parser_cocci_menhir.ml"
+# 26358 "parser_cocci_menhir.ml"
) = Obj.magic pv in
let d : 'tv_d_ident = Obj.magic d in
let t : 'tv_ctype = Obj.magic t in
# 490 "parser_cocci_menhir.mly"
( let (id,fn) = d in
[Ast0.wrap(Ast0.UnInit(None,fn t,id,P.clt2mcode ";" pv))] )
-# 26421 "parser_cocci_menhir.ml"
+# 26368 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let pv : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 26482 "parser_cocci_menhir.ml"
+# 26429 "parser_cocci_menhir.ml"
) = Obj.magic pv in
let rp2 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 26487 "parser_cocci_menhir.ml"
+# 26434 "parser_cocci_menhir.ml"
) = Obj.magic rp2 in
let p : 'tv_decl_list_name_opt_decl_ = Obj.magic p in
let lp2 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 26493 "parser_cocci_menhir.ml"
+# 26440 "parser_cocci_menhir.ml"
) = Obj.magic lp2 in
let rp1 : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 26498 "parser_cocci_menhir.ml"
+# 26445 "parser_cocci_menhir.ml"
) = Obj.magic rp1 in
let d : 'tv_d_ident = Obj.magic d in
let st : (
# 98 "parser_cocci_menhir.mly"
(Data.clt)
-# 26504 "parser_cocci_menhir.ml"
+# 26451 "parser_cocci_menhir.ml"
) = Obj.magic st in
let lp1 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 26509 "parser_cocci_menhir.ml"
+# 26456 "parser_cocci_menhir.ml"
) = Obj.magic lp1 in
let t : 'tv_fn_ctype = Obj.magic t in
let _startpos = _startpos_t_ in
(t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
[Ast0.wrap(Ast0.UnInit(None,fn t,id,P.clt2mcode ";" pv))] )
-# 26523 "parser_cocci_menhir.ml"
+# 26470 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let pv : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 26554 "parser_cocci_menhir.ml"
+# 26501 "parser_cocci_menhir.ml"
) = Obj.magic pv in
let d : 'tv_d_ident = Obj.magic d in
let i : 'tv_pure_ident = Obj.magic i in
# 39 "standard.mly"
( None )
-# 26564 "parser_cocci_menhir.ml"
+# 26511 "parser_cocci_menhir.ml"
in
( let (id,fn) = d in
let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
[Ast0.wrap(Ast0.UnInit(None,fn idtype,id,P.clt2mcode ";" pv))] )
-# 26572 "parser_cocci_menhir.ml"
+# 26519 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let pv : (
# 106 "parser_cocci_menhir.mly"
(Data.clt)
-# 26608 "parser_cocci_menhir.ml"
+# 26555 "parser_cocci_menhir.ml"
) = Obj.magic pv in
let d : 'tv_d_ident = Obj.magic d in
let i : 'tv_pure_ident = Obj.magic i in
# 41 "standard.mly"
( Some x )
-# 26620 "parser_cocci_menhir.ml"
+# 26567 "parser_cocci_menhir.ml"
in
( let (id,fn) = d in
let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
[Ast0.wrap(Ast0.UnInit(None,fn idtype,id,P.clt2mcode ";" pv))] )
-# 26628 "parser_cocci_menhir.ml"
+# 26575 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_struct_decl_list =
# 507 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.DOTS(_1)) )
-# 26652 "parser_cocci_menhir.ml"
+# 26599 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_struct_decl_list_start =
# 510 "parser_cocci_menhir.mly"
( _1 )
-# 26676 "parser_cocci_menhir.ml"
+# 26623 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_struct_decl_list_start =
# 511 "parser_cocci_menhir.mly"
( _1@_2 )
-# 26706 "parser_cocci_menhir.ml"
+# 26653 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_struct_decl_list_start =
# 513 "parser_cocci_menhir.mly"
( (P.mkddots "..." d)::r )
-# 26736 "parser_cocci_menhir.ml"
+# 26683 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let s : (
# 50 "parser_cocci_menhir.mly"
(Data.clt)
-# 26757 "parser_cocci_menhir.ml"
+# 26704 "parser_cocci_menhir.ml"
) = Obj.magic s in
let _startpos = _startpos_s_ in
let _endpos = _endpos_s_ in
let _v : 'tv_struct_or_union =
# 484 "parser_cocci_menhir.mly"
( P.clt2mcode Ast.Struct s )
-# 26764 "parser_cocci_menhir.ml"
+# 26711 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let u : (
# 50 "parser_cocci_menhir.mly"
(Data.clt)
-# 26785 "parser_cocci_menhir.ml"
+# 26732 "parser_cocci_menhir.ml"
) = Obj.magic u in
let _startpos = _startpos_u_ in
let _endpos = _endpos_u_ in
let _v : 'tv_struct_or_union =
# 485 "parser_cocci_menhir.mly"
( P.clt2mcode Ast.Union u )
-# 26792 "parser_cocci_menhir.ml"
+# 26739 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_top_eexpr =
# 1137 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Exp(_1)))) )
-# 26816 "parser_cocci_menhir.ml"
+# 26763 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _3 : (
# 100 "parser_cocci_menhir.mly"
(Data.clt)
-# 26847 "parser_cocci_menhir.ml"
+# 26794 "parser_cocci_menhir.ml"
) = Obj.magic _3 in
let _2 : 'tv_initialize_list = Obj.magic _2 in
let _1 : (
# 100 "parser_cocci_menhir.mly"
(Data.clt)
-# 26853 "parser_cocci_menhir.ml"
+# 26800 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_top_init =
-# 1547 "parser_cocci_menhir.mly"
+# 1548 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.InitList(P.clt2mcode "{" _1,_2,P.clt2mcode "}" _3)) )
-# 26860 "parser_cocci_menhir.ml"
+# 26807 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
let _endpos = _startpos in
let _v : 'tv_toplevel_after_dots =
-# 1535 "parser_cocci_menhir.mly"
+# 1536 "parser_cocci_menhir.mly"
([])
-# 26877 "parser_cocci_menhir.ml"
+# 26824 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_toplevel_after_dots =
-# 1536 "parser_cocci_menhir.mly"
+# 1537 "parser_cocci_menhir.mly"
(_2)
-# 26905 "parser_cocci_menhir.ml"
+# 26852 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_toplevel_after_dots =
-# 1537 "parser_cocci_menhir.mly"
+# 1538 "parser_cocci_menhir.mly"
((Ast0.wrap(Ast0.Exp(_1)))::_2)
-# 26935 "parser_cocci_menhir.ml"
+# 26882 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_toplevel_after_dots =
-# 1538 "parser_cocci_menhir.mly"
+# 1539 "parser_cocci_menhir.mly"
(_1@_2)
-# 26965 "parser_cocci_menhir.ml"
+# 26912 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_toplevel_after_dots_init =
-# 1526 "parser_cocci_menhir.mly"
+# 1527 "parser_cocci_menhir.mly"
(_2)
-# 26993 "parser_cocci_menhir.ml"
+# 26940 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_toplevel_after_dots_init =
-# 1527 "parser_cocci_menhir.mly"
+# 1528 "parser_cocci_menhir.mly"
((Ast0.wrap(Ast0.Exp(_1)))::_2)
-# 27023 "parser_cocci_menhir.ml"
+# 26970 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_toplevel_after_dots_init =
-# 1528 "parser_cocci_menhir.mly"
+# 1529 "parser_cocci_menhir.mly"
(_1@_2)
-# 27053 "parser_cocci_menhir.ml"
+# 27000 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
let _endpos = _startpos in
let _v : 'tv_toplevel_after_exp =
-# 1531 "parser_cocci_menhir.mly"
+# 1532 "parser_cocci_menhir.mly"
([])
-# 27070 "parser_cocci_menhir.ml"
+# 27017 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_toplevel_after_exp =
-# 1532 "parser_cocci_menhir.mly"
+# 1533 "parser_cocci_menhir.mly"
(_1::_2)
-# 27100 "parser_cocci_menhir.ml"
+# 27047 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
let _endpos = _startpos in
let _v : 'tv_toplevel_after_stm =
-# 1541 "parser_cocci_menhir.mly"
+# 1542 "parser_cocci_menhir.mly"
([])
-# 27117 "parser_cocci_menhir.ml"
+# 27064 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_toplevel_after_stm =
-# 1542 "parser_cocci_menhir.mly"
+# 1543 "parser_cocci_menhir.mly"
(_1::_2)
-# 27147 "parser_cocci_menhir.ml"
+# 27094 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_toplevel_after_stm =
-# 1543 "parser_cocci_menhir.mly"
+# 1544 "parser_cocci_menhir.mly"
(_1@_2)
-# 27177 "parser_cocci_menhir.ml"
+# 27124 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_toplevel_seq_start_toplevel_after_dots_ =
-# 1521 "parser_cocci_menhir.mly"
+# 1522 "parser_cocci_menhir.mly"
( _1::_2 )
-# 27207 "parser_cocci_menhir.ml"
+# 27154 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_toplevel_seq_start_toplevel_after_dots_ =
-# 1522 "parser_cocci_menhir.mly"
+# 1523 "parser_cocci_menhir.mly"
( (Ast0.wrap(Ast0.Exp(_1)))::_2 )
-# 27237 "parser_cocci_menhir.ml"
+# 27184 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_toplevel_seq_start_toplevel_after_dots_ =
-# 1523 "parser_cocci_menhir.mly"
+# 1524 "parser_cocci_menhir.mly"
( _1@_2 )
-# 27267 "parser_cocci_menhir.ml"
+# 27214 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_toplevel_seq_start_toplevel_after_dots_init_ =
-# 1521 "parser_cocci_menhir.mly"
+# 1522 "parser_cocci_menhir.mly"
( _1::_2 )
-# 27297 "parser_cocci_menhir.ml"
+# 27244 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_toplevel_seq_start_toplevel_after_dots_init_ =
-# 1522 "parser_cocci_menhir.mly"
+# 1523 "parser_cocci_menhir.mly"
( (Ast0.wrap(Ast0.Exp(_1)))::_2 )
-# 27327 "parser_cocci_menhir.ml"
+# 27274 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_toplevel_seq_start_toplevel_after_dots_init_ =
-# 1523 "parser_cocci_menhir.mly"
+# 1524 "parser_cocci_menhir.mly"
( _1@_2 )
-# 27357 "parser_cocci_menhir.ml"
+# 27304 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_typedef_ident =
-# 1434 "parser_cocci_menhir.mly"
+# 1435 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.TypeName(P.id2mcode _1)) )
-# 27381 "parser_cocci_menhir.ml"
+# 27328 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 64 "parser_cocci_menhir.mly"
(Parse_aux.info)
-# 27402 "parser_cocci_menhir.ml"
+# 27349 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_typedef_ident =
-# 1436 "parser_cocci_menhir.mly"
+# 1437 "parser_cocci_menhir.mly"
( let (nm,pure,clt) = _1 in
Ast0.wrap(Ast0.MetaType(P.clt2mcode nm clt,pure)) )
-# 27410 "parser_cocci_menhir.ml"
+# 27357 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_unary_expr_eexpr_dot_expressions_ =
-# 1225 "parser_cocci_menhir.mly"
+# 1226 "parser_cocci_menhir.mly"
( _1 )
-# 27434 "parser_cocci_menhir.ml"
+# 27381 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 84 "parser_cocci_menhir.mly"
(Data.clt)
-# 27461 "parser_cocci_menhir.ml"
+# 27408 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_unary_expr_eexpr_dot_expressions_ =
-# 1227 "parser_cocci_menhir.mly"
+# 1228 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Inc _1)) )
-# 27468 "parser_cocci_menhir.ml"
+# 27415 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 84 "parser_cocci_menhir.mly"
(Data.clt)
-# 27495 "parser_cocci_menhir.ml"
+# 27442 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_unary_expr_eexpr_dot_expressions_ =
-# 1229 "parser_cocci_menhir.mly"
+# 1230 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Dec _1)) )
-# 27502 "parser_cocci_menhir.ml"
+# 27449 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_unary_expr_eexpr_dot_expressions_ =
-# 1231 "parser_cocci_menhir.mly"
+# 1232 "parser_cocci_menhir.mly"
( let mcode = _1 in Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 27532 "parser_cocci_menhir.ml"
+# 27479 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 27559 "parser_cocci_menhir.ml"
+# 27506 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_unary_expr_eexpr_dot_expressions_ =
-# 1233 "parser_cocci_menhir.mly"
+# 1234 "parser_cocci_menhir.mly"
( let mcode = P.clt2mcode Ast.Not _1 in
Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 27567 "parser_cocci_menhir.ml"
+# 27514 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 58 "parser_cocci_menhir.mly"
(Data.clt)
-# 27594 "parser_cocci_menhir.ml"
+# 27541 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_unary_expr_eexpr_dot_expressions_ =
-# 1236 "parser_cocci_menhir.mly"
+# 1237 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.SizeOfExpr (P.clt2mcode "sizeof" _1, _2)) )
-# 27601 "parser_cocci_menhir.ml"
+# 27548 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let rp : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 27637 "parser_cocci_menhir.ml"
+# 27584 "parser_cocci_menhir.ml"
) = Obj.magic rp in
let t : 'tv_ctype = Obj.magic t in
let lp : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 27643 "parser_cocci_menhir.ml"
+# 27590 "parser_cocci_menhir.ml"
) = Obj.magic lp in
let s : (
# 58 "parser_cocci_menhir.mly"
(Data.clt)
-# 27648 "parser_cocci_menhir.ml"
+# 27595 "parser_cocci_menhir.ml"
) = Obj.magic s in
let _startpos = _startpos_s_ in
let _endpos = _endpos_rp_ in
let _v : 'tv_unary_expr_eexpr_dot_expressions_ =
-# 1238 "parser_cocci_menhir.mly"
+# 1239 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.SizeOfType (P.clt2mcode "sizeof" s,
P.clt2mcode "(" lp,t,
P.clt2mcode ")" rp)) )
-# 27657 "parser_cocci_menhir.ml"
+# 27604 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_unary_expr_eexpr_invalid_ =
-# 1225 "parser_cocci_menhir.mly"
+# 1226 "parser_cocci_menhir.mly"
( _1 )
-# 27681 "parser_cocci_menhir.ml"
+# 27628 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 84 "parser_cocci_menhir.mly"
(Data.clt)
-# 27708 "parser_cocci_menhir.ml"
+# 27655 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_unary_expr_eexpr_invalid_ =
-# 1227 "parser_cocci_menhir.mly"
+# 1228 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Inc _1)) )
-# 27715 "parser_cocci_menhir.ml"
+# 27662 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 84 "parser_cocci_menhir.mly"
(Data.clt)
-# 27742 "parser_cocci_menhir.ml"
+# 27689 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_unary_expr_eexpr_invalid_ =
-# 1229 "parser_cocci_menhir.mly"
+# 1230 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Dec _1)) )
-# 27749 "parser_cocci_menhir.ml"
+# 27696 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_unary_expr_eexpr_invalid_ =
-# 1231 "parser_cocci_menhir.mly"
+# 1232 "parser_cocci_menhir.mly"
( let mcode = _1 in Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 27779 "parser_cocci_menhir.ml"
+# 27726 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 27806 "parser_cocci_menhir.ml"
+# 27753 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_unary_expr_eexpr_invalid_ =
-# 1233 "parser_cocci_menhir.mly"
+# 1234 "parser_cocci_menhir.mly"
( let mcode = P.clt2mcode Ast.Not _1 in
Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 27814 "parser_cocci_menhir.ml"
+# 27761 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 58 "parser_cocci_menhir.mly"
(Data.clt)
-# 27841 "parser_cocci_menhir.ml"
+# 27788 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_unary_expr_eexpr_invalid_ =
-# 1236 "parser_cocci_menhir.mly"
+# 1237 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.SizeOfExpr (P.clt2mcode "sizeof" _1, _2)) )
-# 27848 "parser_cocci_menhir.ml"
+# 27795 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let rp : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 27884 "parser_cocci_menhir.ml"
+# 27831 "parser_cocci_menhir.ml"
) = Obj.magic rp in
let t : 'tv_ctype = Obj.magic t in
let lp : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 27890 "parser_cocci_menhir.ml"
+# 27837 "parser_cocci_menhir.ml"
) = Obj.magic lp in
let s : (
# 58 "parser_cocci_menhir.mly"
(Data.clt)
-# 27895 "parser_cocci_menhir.ml"
+# 27842 "parser_cocci_menhir.ml"
) = Obj.magic s in
let _startpos = _startpos_s_ in
let _endpos = _endpos_rp_ in
let _v : 'tv_unary_expr_eexpr_invalid_ =
-# 1238 "parser_cocci_menhir.mly"
+# 1239 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.SizeOfType (P.clt2mcode "sizeof" s,
P.clt2mcode "(" lp,t,
P.clt2mcode ")" rp)) )
-# 27904 "parser_cocci_menhir.ml"
+# 27851 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_unary_expr_eexpr_nest_expressions_ =
-# 1225 "parser_cocci_menhir.mly"
+# 1226 "parser_cocci_menhir.mly"
( _1 )
-# 27928 "parser_cocci_menhir.ml"
+# 27875 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 84 "parser_cocci_menhir.mly"
(Data.clt)
-# 27955 "parser_cocci_menhir.ml"
+# 27902 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_unary_expr_eexpr_nest_expressions_ =
-# 1227 "parser_cocci_menhir.mly"
+# 1228 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Inc _1)) )
-# 27962 "parser_cocci_menhir.ml"
+# 27909 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 84 "parser_cocci_menhir.mly"
(Data.clt)
-# 27989 "parser_cocci_menhir.ml"
+# 27936 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_unary_expr_eexpr_nest_expressions_ =
-# 1229 "parser_cocci_menhir.mly"
+# 1230 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Dec _1)) )
-# 27996 "parser_cocci_menhir.ml"
+# 27943 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_unary_expr_eexpr_nest_expressions_ =
-# 1231 "parser_cocci_menhir.mly"
+# 1232 "parser_cocci_menhir.mly"
( let mcode = _1 in Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 28026 "parser_cocci_menhir.ml"
+# 27973 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 28053 "parser_cocci_menhir.ml"
+# 28000 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_unary_expr_eexpr_nest_expressions_ =
-# 1233 "parser_cocci_menhir.mly"
+# 1234 "parser_cocci_menhir.mly"
( let mcode = P.clt2mcode Ast.Not _1 in
Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 28061 "parser_cocci_menhir.ml"
+# 28008 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 58 "parser_cocci_menhir.mly"
(Data.clt)
-# 28088 "parser_cocci_menhir.ml"
+# 28035 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_unary_expr_eexpr_nest_expressions_ =
-# 1236 "parser_cocci_menhir.mly"
+# 1237 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.SizeOfExpr (P.clt2mcode "sizeof" _1, _2)) )
-# 28095 "parser_cocci_menhir.ml"
+# 28042 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let rp : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 28131 "parser_cocci_menhir.ml"
+# 28078 "parser_cocci_menhir.ml"
) = Obj.magic rp in
let t : 'tv_ctype = Obj.magic t in
let lp : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 28137 "parser_cocci_menhir.ml"
+# 28084 "parser_cocci_menhir.ml"
) = Obj.magic lp in
let s : (
# 58 "parser_cocci_menhir.mly"
(Data.clt)
-# 28142 "parser_cocci_menhir.ml"
+# 28089 "parser_cocci_menhir.ml"
) = Obj.magic s in
let _startpos = _startpos_s_ in
let _endpos = _endpos_rp_ in
let _v : 'tv_unary_expr_eexpr_nest_expressions_ =
-# 1238 "parser_cocci_menhir.mly"
+# 1239 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.SizeOfType (P.clt2mcode "sizeof" s,
P.clt2mcode "(" lp,t,
P.clt2mcode ")" rp)) )
-# 28151 "parser_cocci_menhir.ml"
+# 28098 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_unary_expr_expr_invalid_ =
-# 1225 "parser_cocci_menhir.mly"
+# 1226 "parser_cocci_menhir.mly"
( _1 )
-# 28175 "parser_cocci_menhir.ml"
+# 28122 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 84 "parser_cocci_menhir.mly"
(Data.clt)
-# 28202 "parser_cocci_menhir.ml"
+# 28149 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_unary_expr_expr_invalid_ =
-# 1227 "parser_cocci_menhir.mly"
+# 1228 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Inc _1)) )
-# 28209 "parser_cocci_menhir.ml"
+# 28156 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 84 "parser_cocci_menhir.mly"
(Data.clt)
-# 28236 "parser_cocci_menhir.ml"
+# 28183 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_unary_expr_expr_invalid_ =
-# 1229 "parser_cocci_menhir.mly"
+# 1230 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Dec _1)) )
-# 28243 "parser_cocci_menhir.ml"
+# 28190 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_unary_expr_expr_invalid_ =
-# 1231 "parser_cocci_menhir.mly"
+# 1232 "parser_cocci_menhir.mly"
( let mcode = _1 in Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 28273 "parser_cocci_menhir.ml"
+# 28220 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 28300 "parser_cocci_menhir.ml"
+# 28247 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_unary_expr_expr_invalid_ =
-# 1233 "parser_cocci_menhir.mly"
+# 1234 "parser_cocci_menhir.mly"
( let mcode = P.clt2mcode Ast.Not _1 in
Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 28308 "parser_cocci_menhir.ml"
+# 28255 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 58 "parser_cocci_menhir.mly"
(Data.clt)
-# 28335 "parser_cocci_menhir.ml"
+# 28282 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_unary_expr_expr_invalid_ =
-# 1236 "parser_cocci_menhir.mly"
+# 1237 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.SizeOfExpr (P.clt2mcode "sizeof" _1, _2)) )
-# 28342 "parser_cocci_menhir.ml"
+# 28289 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let rp : (
# 76 "parser_cocci_menhir.mly"
(Data.clt)
-# 28378 "parser_cocci_menhir.ml"
+# 28325 "parser_cocci_menhir.ml"
) = Obj.magic rp in
let t : 'tv_ctype = Obj.magic t in
let lp : (
# 75 "parser_cocci_menhir.mly"
(Data.clt)
-# 28384 "parser_cocci_menhir.ml"
+# 28331 "parser_cocci_menhir.ml"
) = Obj.magic lp in
let s : (
# 58 "parser_cocci_menhir.mly"
(Data.clt)
-# 28389 "parser_cocci_menhir.ml"
+# 28336 "parser_cocci_menhir.ml"
) = Obj.magic s in
let _startpos = _startpos_s_ in
let _endpos = _endpos_rp_ in
let _v : 'tv_unary_expr_expr_invalid_ =
-# 1238 "parser_cocci_menhir.mly"
+# 1239 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.SizeOfType (P.clt2mcode "sizeof" s,
P.clt2mcode "(" lp,t,
P.clt2mcode ")" rp)) )
-# 28398 "parser_cocci_menhir.ml"
+# 28345 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 92 "parser_cocci_menhir.mly"
(Data.clt)
-# 28419 "parser_cocci_menhir.ml"
+# 28366 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_unary_op =
-# 1242 "parser_cocci_menhir.mly"
+# 1243 "parser_cocci_menhir.mly"
( P.clt2mcode Ast.GetRef _1 )
-# 28426 "parser_cocci_menhir.ml"
+# 28373 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 98 "parser_cocci_menhir.mly"
(Data.clt)
-# 28447 "parser_cocci_menhir.ml"
+# 28394 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_unary_op =
-# 1243 "parser_cocci_menhir.mly"
+# 1244 "parser_cocci_menhir.mly"
( P.clt2mcode Ast.DeRef _1 )
-# 28454 "parser_cocci_menhir.ml"
+# 28401 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 97 "parser_cocci_menhir.mly"
(Data.clt)
-# 28475 "parser_cocci_menhir.ml"
+# 28422 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_unary_op =
-# 1244 "parser_cocci_menhir.mly"
+# 1245 "parser_cocci_menhir.mly"
( P.clt2mcode Ast.UnPlus _1 )
-# 28482 "parser_cocci_menhir.ml"
+# 28429 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 97 "parser_cocci_menhir.mly"
(Data.clt)
-# 28503 "parser_cocci_menhir.ml"
+# 28450 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_unary_op =
-# 1245 "parser_cocci_menhir.mly"
+# 1246 "parser_cocci_menhir.mly"
( P.clt2mcode Ast.UnMinus _1 )
-# 28510 "parser_cocci_menhir.ml"
+# 28457 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _1 : (
# 98 "parser_cocci_menhir.mly"
(Data.clt)
-# 28531 "parser_cocci_menhir.ml"
+# 28478 "parser_cocci_menhir.ml"
) = Obj.magic _1 in
let _startpos = _startpos__1_ in
let _endpos = _endpos__1_ in
let _v : 'tv_unary_op =
-# 1246 "parser_cocci_menhir.mly"
+# 1247 "parser_cocci_menhir.mly"
( P.clt2mcode Ast.Tilde _1 )
-# 28538 "parser_cocci_menhir.ml"
+# 28485 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_when_start =
-# 1640 "parser_cocci_menhir.mly"
+# 1641 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.DOTS((Ast0.wrap(Ast0.Exp(_1)))::_2)) )
-# 28568 "parser_cocci_menhir.ml"
+# 28515 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__2_ in
let _v : 'tv_when_start =
-# 1642 "parser_cocci_menhir.mly"
+# 1643 "parser_cocci_menhir.mly"
( Ast0.wrap(Ast0.DOTS(_1@_2)) )
-# 28598 "parser_cocci_menhir.ml"
- in
- _menhir_env.MenhirLib.EngineTypes.stack <- {
- MenhirLib.EngineTypes.state = _menhir_s;
- MenhirLib.EngineTypes.semv = Obj.repr _v;
- MenhirLib.EngineTypes.startp = _startpos;
- MenhirLib.EngineTypes.endp = _endpos;
- MenhirLib.EngineTypes.next = _menhir_stack;
- });
- (fun _menhir_env ->
- let _menhir_stack = _menhir_env.MenhirLib.EngineTypes.stack in
- let {
- MenhirLib.EngineTypes.startp = _startpos__4_;
- MenhirLib.EngineTypes.endp = _endpos__4_;
- MenhirLib.EngineTypes.next = {
- MenhirLib.EngineTypes.semv = w;
- MenhirLib.EngineTypes.startp = _startpos_w_;
- MenhirLib.EngineTypes.endp = _endpos_w_;
- MenhirLib.EngineTypes.next = {
- MenhirLib.EngineTypes.startp = _startpos__2_;
- MenhirLib.EngineTypes.endp = _endpos__2_;
- MenhirLib.EngineTypes.next = {
- MenhirLib.EngineTypes.state = _menhir_s;
- MenhirLib.EngineTypes.startp = _startpos__1_;
- MenhirLib.EngineTypes.endp = _endpos__1_;
- MenhirLib.EngineTypes.next = _menhir_stack;
- };
- };
- };
- } = _menhir_stack in
- let w : 'tv_eexpr = Obj.magic w in
- let _startpos = _startpos__1_ in
- let _endpos = _endpos__4_ in
- let _v : 'tv_whenexp =
-# 1156 "parser_cocci_menhir.mly"
- ( w )
-# 28634 "parser_cocci_menhir.ml"
+# 28545 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _v : 'tv_whenppdecs =
# 843 "parser_cocci_menhir.mly"
( w )
-# 28658 "parser_cocci_menhir.ml"
+# 28569 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__4_ in
let _v : 'tv_whens_when_start_rule_elem_statement_ =
-# 1708 "parser_cocci_menhir.mly"
+# 1709 "parser_cocci_menhir.mly"
( [Ast0.WhenNot w] )
-# 28694 "parser_cocci_menhir.ml"
+# 28605 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__4_ in
let _v : 'tv_whens_when_start_rule_elem_statement_ =
-# 1709 "parser_cocci_menhir.mly"
+# 1710 "parser_cocci_menhir.mly"
( [Ast0.WhenAlways w] )
-# 28730 "parser_cocci_menhir.ml"
+# 28641 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__3_ in
let _v : 'tv_whens_when_start_rule_elem_statement_ =
-# 1711 "parser_cocci_menhir.mly"
+# 1712 "parser_cocci_menhir.mly"
( List.map (function x -> Ast0.WhenModifier(x)) _2 )
-# 28762 "parser_cocci_menhir.ml"
+# 28673 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__4_ in
let _v : 'tv_whens_when_start_rule_elem_statement_ =
-# 1712 "parser_cocci_menhir.mly"
+# 1713 "parser_cocci_menhir.mly"
( [Ast0.WhenNotTrue e] )
-# 28798 "parser_cocci_menhir.ml"
+# 28709 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let _startpos = _startpos__1_ in
let _endpos = _endpos__4_ in
let _v : 'tv_whens_when_start_rule_elem_statement_ =
-# 1713 "parser_cocci_menhir.mly"
+# 1714 "parser_cocci_menhir.mly"
( [Ast0.WhenNotFalse e] )
-# 28834 "parser_cocci_menhir.ml"
+# 28745 "parser_cocci_menhir.ml"
in
_menhir_env.MenhirLib.EngineTypes.stack <- {
MenhirLib.EngineTypes.state = _menhir_s;
let rec script_meta_main =
fun lexer lexbuf ->
- (Obj.magic (MenhirInterpreter.entry 1493 lexer lexbuf) : (
+ (Obj.magic (MenhirInterpreter.entry 1486 lexer lexbuf) : (
# 158 "parser_cocci_menhir.mly"
(string * (string * string))
-# 28858 "parser_cocci_menhir.ml"
+# 28769 "parser_cocci_menhir.ml"
))
and rule_name =
fun lexer lexbuf ->
- (Obj.magic (MenhirInterpreter.entry 1437 lexer lexbuf) : (
+ (Obj.magic (MenhirInterpreter.entry 1430 lexer lexbuf) : (
# 152 "parser_cocci_menhir.mly"
(Ast_cocci.rulename)
-# 28866 "parser_cocci_menhir.ml"
+# 28777 "parser_cocci_menhir.ml"
))
and reinit =
fun lexer lexbuf ->
- (Obj.magic (MenhirInterpreter.entry 1435 lexer lexbuf) : (
+ (Obj.magic (MenhirInterpreter.entry 1428 lexer lexbuf) : (
# 130 "parser_cocci_menhir.mly"
(unit)
-# 28874 "parser_cocci_menhir.ml"
+# 28785 "parser_cocci_menhir.ml"
))
and plus_main =
fun lexer lexbuf ->
- (Obj.magic (MenhirInterpreter.entry 1399 lexer lexbuf) : (
+ (Obj.magic (MenhirInterpreter.entry 1392 lexer lexbuf) : (
# 139 "parser_cocci_menhir.mly"
(Ast0_cocci.rule)
-# 28882 "parser_cocci_menhir.ml"
+# 28793 "parser_cocci_menhir.ml"
))
and plus_exp_main =
fun lexer lexbuf ->
- (Obj.magic (MenhirInterpreter.entry 1390 lexer lexbuf) : (
+ (Obj.magic (MenhirInterpreter.entry 1383 lexer lexbuf) : (
# 142 "parser_cocci_menhir.mly"
(Ast0_cocci.rule)
-# 28890 "parser_cocci_menhir.ml"
+# 28801 "parser_cocci_menhir.ml"
))
and never_used =
fun lexer lexbuf ->
- (Obj.magic (MenhirInterpreter.entry 1384 lexer lexbuf) : (
+ (Obj.magic (MenhirInterpreter.entry 1377 lexer lexbuf) : (
# 167 "parser_cocci_menhir.mly"
(unit)
-# 28898 "parser_cocci_menhir.ml"
+# 28809 "parser_cocci_menhir.ml"
))
and minus_main =
fun lexer lexbuf ->
- (Obj.magic (MenhirInterpreter.entry 1309 lexer lexbuf) : (
+ (Obj.magic (MenhirInterpreter.entry 1302 lexer lexbuf) : (
# 133 "parser_cocci_menhir.mly"
(Ast0_cocci.rule)
-# 28906 "parser_cocci_menhir.ml"
+# 28817 "parser_cocci_menhir.ml"
))
and minus_exp_main =
fun lexer lexbuf ->
- (Obj.magic (MenhirInterpreter.entry 1285 lexer lexbuf) : (
+ (Obj.magic (MenhirInterpreter.entry 1278 lexer lexbuf) : (
# 136 "parser_cocci_menhir.mly"
(Ast0_cocci.rule)
-# 28914 "parser_cocci_menhir.ml"
+# 28825 "parser_cocci_menhir.ml"
))
and meta_main =
fun lexer lexbuf ->
- (Obj.magic (MenhirInterpreter.entry 1282 lexer lexbuf) : (
+ (Obj.magic (MenhirInterpreter.entry 1275 lexer lexbuf) : (
# 156 "parser_cocci_menhir.mly"
((Ast_cocci.metavar,Ast_cocci.metavar) Common.either list)
-# 28922 "parser_cocci_menhir.ml"
+# 28833 "parser_cocci_menhir.ml"
))
and iso_rule_name =
fun lexer lexbuf ->
- (Obj.magic (MenhirInterpreter.entry 1278 lexer lexbuf) : (
+ (Obj.magic (MenhirInterpreter.entry 1271 lexer lexbuf) : (
# 148 "parser_cocci_menhir.mly"
(Ast_cocci.rulename)
-# 28930 "parser_cocci_menhir.ml"
+# 28841 "parser_cocci_menhir.ml"
))
and iso_meta_main =
fun lexer lexbuf ->
- (Obj.magic (MenhirInterpreter.entry 1086 lexer lexbuf) : (
+ (Obj.magic (MenhirInterpreter.entry 1079 lexer lexbuf) : (
# 164 "parser_cocci_menhir.mly"
((Ast_cocci.metavar,Ast_cocci.metavar) Common.either list)
-# 28938 "parser_cocci_menhir.ml"
+# 28849 "parser_cocci_menhir.ml"
))
and iso_main =
(Obj.magic (MenhirInterpreter.entry 10 lexer lexbuf) : (
# 161 "parser_cocci_menhir.mly"
(Ast0_cocci.anything list list)
-# 28946 "parser_cocci_menhir.ml"
+# 28857 "parser_cocci_menhir.ml"
))
and include_main =
(Obj.magic (MenhirInterpreter.entry 0 lexer lexbuf) : (
# 145 "parser_cocci_menhir.mly"
((string,string) Common.either list)
-# 28954 "parser_cocci_menhir.ml"
+# 28865 "parser_cocci_menhir.ml"
))
TEllipsis { Ast0.wrap(Ast0.Edots(P.clt2mcode "..." $1,None)) }
| nest_expressions { $1 }
+/* not clear what whencode would mean, so just drop it */
nest_expressions:
- TOEllipsis w=option(whenexp) e=expr_dots(TEllipsis) c=TCEllipsis
+ TOEllipsis e=expr_dots(TEllipsis) c=TCEllipsis
{ Ast0.wrap(Ast0.NestExpr(P.clt2mcode "<..." $1,
Ast0.wrap(Ast0.DOTS(e (P.mkedots "..."))),
- P.clt2mcode "...>" c, w, false)) }
-| TPOEllipsis w=option(whenexp) e=expr_dots(TEllipsis) c=TPCEllipsis
+ P.clt2mcode "...>" c, None, false)) }
+| TPOEllipsis e=expr_dots(TEllipsis) c=TPCEllipsis
{ Ast0.wrap(Ast0.NestExpr(P.clt2mcode "<+..." $1,
Ast0.wrap(Ast0.DOTS(e (P.mkedots "..."))),
- P.clt2mcode "...+>" c, w, true)) }
+ P.clt2mcode "...+>" c, None, true)) }
-whenexp: TWhen TNotEq w=eexpr TLineEnd { w }
+//whenexp: TWhen TNotEq w=eexpr TLineEnd { w }
basic_expr(recurser,primary_extra):
assign_expr(recurser,primary_extra) { $1 }
let is_unitary name =
match (List.mem (Ast0.unwrap_mcode name) unitary,
- Ast0.get_mcode_mcodekind name) with
- (true,Ast0.CONTEXT(mc)) -> Ast0.PureContext
- | (true,_) -> Ast0.Pure
- | (false,Ast0.CONTEXT(mc)) -> Ast0.Context
- | (false,_) -> Ast0.Impure in
+ !Flag.sgrep_mode2, Ast0.get_mcode_mcodekind name) with
+ (true,true,_) | (true,_,Ast0.CONTEXT(_)) -> Ast0.PureContext
+ | (true,_,_) -> Ast0.Pure
+ | (false,true,_) | (false,_,Ast0.CONTEXT(_)) -> Ast0.Context
+ | (false,_,_) -> Ast0.Impure in
let ident r k i =
match Ast0.unwrap i with
mcode print_string rp
| Ast0.TypeExp(ty) -> typeC ty
| Ast0.MetaErr(name,_,_) -> mcode print_meta name
- | Ast0.MetaExpr(name,_,ty,_,_) ->
- mcode print_meta name; print_types ty
+ | Ast0.MetaExpr(name,_,ty,_,pure) ->
+ mcode print_meta name; print_types ty(*;
+ print_string "^";
+ (match pure with
+ Ast0.Pure -> print_string "pure"
+ | Ast0.Impure -> print_string "impure"
+ | Ast0.Context -> print_string "context"
+ | Ast0.PureContext -> print_string "pure_context")*)
| Ast0.MetaExprList(name,_,_) -> mcode print_meta name
| Ast0.EComma(cm) -> mcode print_string cm; print_space()
| Ast0.DisjExpr(_,exp_list,_,_) ->
--- /dev/null
+# Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+# Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+# This file is part of Coccinelle.
+#
+# Coccinelle is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, according to version 2 of the License.
+#
+# Coccinelle is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
+#
+# The authors reserve the right to distribute this or future versions of
+# Coccinelle under other licenses.
+
+
+#note: if you add a file (a .mli or .ml), dont forget to do a make depend
+
+TARGET = popl
+
+SRC = ast_popl.ml asttopopl.ml insert_quantifiers.ml \
+pretty_print_popl.ml flag_popl.ml popltoctl.ml popl.ml
+
+SYSLIBS=str.cma unix.cma
+LIBS=../commons/commons.cma ../globals/globals.cma
+
+INCLUDES = -I ../commons -I ../globals \
+ -I ../ctl -I ../parsing_c -I ../parsing_cocci -I ../engine
+
+#The Caml compilers.
+#for warning: -w A
+#for profiling: -p -inline 0 with OCAMLOPT
+OCAMLCFLAGS ?= -g -dtypes
+OCAMLC =ocamlc$(OPTBIN) $(OCAMLCFLAGS) $(INCLUDES)
+OCAMLOPT = ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
+OCAMLDEP = ocamldep$(OPTBIN) $(INCLUDES)
+OCAMLMKTOP=ocamlmktop -g -custom
+
+
+
+LIB=$(TARGET).cma
+OPTLIB=$(LIB:.cma=.cmxa)
+
+OBJS = $(SRC:.ml=.cmo)
+OPTOBJS = $(SRC:.ml=.cmx)
+
+all: $(LIB)
+all.opt: $(OPTLIB)
+
+$(TARGET).top: $(LIB)
+ $(OCAMLMKTOP) -o $(TARGET).top $(SYSLIBS) $(LIBS) $(OBJS)
+
+$(LIB): $(OBJS)
+ $(OCAMLC) -a -o $(LIB) $(OBJS)
+
+clean::
+ rm -f $(LIB) $(TARGET).top
+
+
+$(OPTLIB): $(OPTOBJS)
+ $(OCAMLOPT) -a -o $(OPTLIB) $(OPTOBJS)
+
+# clean rule for LIB.opt
+clean::
+ rm -f $(OPTLIB) $(LIB:.cma=.a)
+
+
+.SUFFIXES:
+.SUFFIXES: .ml .mli .cmo .cmi .cmx
+
+.ml.cmo:
+ $(OCAMLC) -c $<
+
+.mli.cmi:
+ $(OCAMLC) -c $<
+
+.ml.cmx:
+ $(OCAMLOPT) -c $<
+
+
+
+
+# clean rule for others files
+clean::
+ rm -f *.cm[iox] *.o *.annot
+ rm -f *~ .*~ #*#
+
+depend:
+ $(OCAMLDEP) *.mli *.ml > .depend
+
+#clean::
+# rm -f .depend
+
+.depend:
+ $(OCAMLDEP) $(INCLUDE_PATH) *.mli *.ml > .depend
+
+-include .depend
LIBS=../commons/commons.cma ../globals/globals.cma
INCLUDES = -I ../commons -I ../globals \
- -I ../ctl -I ../parsing_c -I ../parsing_cocci -I ../engine
+ -I ../ctl -I ../parsing_cocci -I ../parsing_c -I ../engine
#The Caml compilers.
#for warning: -w A
pyobject = "pytuple_fromarray"
external pytuple5 : (pyobject * pyobject * pyobject * pyobject * pyobject) ->
pyobject = "pytuple_fromarray"
+external pytuple6 : (pyobject * pyobject * pyobject * pyobject * pyobject * pyobject) ->
+ pyobject = "pytuple_fromarray"
let pyint_fromint i = pyint_fromlong (Int64.of_int i)
let pyint_asint obj = Int64.to_int (pyint_aslong obj)
--- /dev/null
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+*
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+*
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
+*
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+open Ast_c
+open Common
+open Pycaml
+open Pycocci_aux
+module StringMap = Map.Make (String)
+
+exception Pycocciexception
+
+let check_return_value v =
+ if v = (pynull ()) then
+ (pyerr_print ();
+ raise Pycocciexception)
+ else ()
+let check_int_return_value v =
+ if v = -1 then
+ (pyerr_print ();
+ raise Pycocciexception)
+ else ()
+
+let initialised = ref false
+
+let coccinelle_module = ref (pynone ())
+let cocci_file_name = ref ""
+
+(* dealing with python modules loaded *)
+let module_map = ref (StringMap.add "__main__" (pynone ()) StringMap.empty)
+
+let get_module module_name =
+ StringMap.find module_name (!module_map)
+
+let is_module_loaded module_name =
+ try
+ let _ = get_module module_name in
+ true
+ with Not_found -> false
+
+let load_module module_name =
+ if not (is_module_loaded module_name) then
+ let m = pyimport_importmodule module_name in
+ check_return_value m;
+ (module_map := (StringMap.add module_name m (!module_map));
+ m)
+ else get_module module_name
+(* end python module handling part *)
+
+(* initialisation routines *)
+let pycocci_init () =
+ (* initialize *)
+ if not !initialised then (
+ initialised := true;
+ Unix.putenv "PYTHONPATH"
+ (Printf.sprintf "%s/coccinelle" (Unix.getenv "HOME"));
+ let _ = if not (py_isinitialized () != 0) then
+ (if !Flag.show_misc then Common.pr2 "Initializing python\n%!";
+ py_initialize()) in
+
+ (* set argv *)
+ let argv0 = Printf.sprintf "%s%sspatch" (Sys.getcwd ()) (match Sys.os_type with "Win32" -> "\\" | _ -> "/") in
+ let _ = pycaml_setargs argv0 in
+
+ coccinelle_module := (pymodule_new "coccinelle");
+ module_map := StringMap.add "coccinelle" !coccinelle_module !module_map;
+ let _ = load_module "coccilib.elems" in
+ let _ = load_module "coccilib.output" in
+ ()) else
+
+ ()
+
+(*let _ = pycocci_init ()*)
+(* end initialisation routines *)
+
+(* python interaction *)
+let split_fqn fqn =
+ let last_period = String.rindex fqn '.' in
+ let module_name = String.sub fqn 0 last_period in
+ let class_name = String.sub fqn (last_period + 1) (String.length fqn - last_period - 1) in
+ (module_name, class_name)
+
+let pycocci_get_class_type fqn =
+ let (module_name, class_name) = split_fqn fqn in
+ let m = get_module module_name in
+ let attr = pyobject_getattrstring(m, class_name) in
+ check_return_value attr;
+ attr
+
+let pycocci_instantiate_class fqn args =
+ let class_type = pycocci_get_class_type fqn in
+ let obj = pyobject_callobject(class_type, args) in
+ check_return_value obj;
+ obj
+
+(* end python interaction *)
+
+let inc_match = ref true
+
+let include_match v =
+ let truth = pyobject_istrue (pytuple_getitem (v, 1)) in
+ check_int_return_value truth;
+ inc_match := truth != 0;
+ pynone ()
+
+let build_method (mname, camlfunc, args) pymodule classx classdict =
+ let cmx = pymethod_new(pywrap_closure camlfunc, args, classx) in
+ let v = pydict_setitemstring(classdict, mname, cmx) in
+ check_int_return_value v;
+ ()
+
+let build_class cname parent methods pymodule =
+ let cd = pydict_new() in
+ check_return_value cd;
+ let cx = pyclass_new(pytuple_fromsingle (pycocci_get_class_type parent), cd, pystring_fromstring cname) in
+ check_return_value cx;
+ List.iter (function meth -> build_method meth pymodule cx cd) methods;
+ let v = pydict_setitemstring(pymodule_getdict pymodule, cname, cx) in
+ check_int_return_value v;
+ (cd, cx)
+
+let has_environment_binding env name =
+ let a = pytuple_toarray name in
+ let (rule, name) = (Array.get a 1, Array.get a 2) in
+ let orule = pystring_asstring rule in
+ let oname = pystring_asstring name in
+ let e = List.exists (function (x,y) -> orule = x && oname = y) env in
+ if e then pytrue () else pyfalse ()
+
+let pyoutputinstance = ref (pynone ())
+let pyoutputdict = ref (pynone ())
+
+let get_cocci_file args =
+ pystring_fromstring (!cocci_file_name)
+
+let build_classes env =
+ let _ = pycocci_init () in
+ let module_dictionary = pyimport_getmoduledict() in
+ coccinelle_module := pymodule_new "coccinelle";
+ let mx = !coccinelle_module in
+ inc_match := true;
+ let (cd, cx) = build_class "Cocci" (!Flag.pyoutput)
+ [("include_match", include_match, (pynull()));
+ ("has_env_binding", has_environment_binding env, (pynull()))] mx in
+ pyoutputinstance := cx;
+ pyoutputdict := cd;
+ let v1 = pydict_setitemstring(module_dictionary, "coccinelle", mx) in
+ check_int_return_value v1;
+ let mypystring = pystring_fromstring !cocci_file_name in
+ let v2 = pydict_setitemstring(cd, "cocci_file", mypystring) in
+ check_int_return_value v2;
+ ()
+
+let build_variable name value =
+ let mx = !coccinelle_module in
+ check_int_return_value (pydict_setitemstring(pymodule_getdict mx, name, value))
+
+let contains_binding e (_,(r,m)) =
+ try
+ let _ = List.find (function ((re, rm), _) -> r = re && m = rm) e in true
+ with Not_found -> false
+
+let construct_variables mv e =
+ let find_binding (r,m) =
+ try
+ let elem = List.find (function ((re,rm),_) -> r = re && m = rm) e in
+ Some elem
+ with Not_found -> None
+ in
+
+ let instantiate_Expression(x) =
+ let str = pystring_fromstring (Pycocci_aux.exprrep x) in
+ pycocci_instantiate_class "coccilib.elems.Expression" (pytuple_fromsingle (str))
+ in
+
+ let instantiate_Identifier(x) =
+ let str = pystring_fromstring x in
+ pycocci_instantiate_class "coccilib.elems.Identifier" (pytuple_fromsingle (str))
+ in
+
+ List.iter (function (py,(r,m)) ->
+ match find_binding (r,m) with
+ None -> ()
+ | Some (_, Ast_c.MetaExprVal ((expr, _), info_list)) ->
+ let expr_repr = instantiate_Expression(expr) in
+ let _ = build_variable py expr_repr in
+ ()
+ | Some (_, Ast_c.MetaIdVal id) ->
+ let id_repr = instantiate_Identifier(id) in
+ let _ = build_variable py id_repr in
+ ()
+ | Some (_, Ast_c.MetaPosValList l) ->
+ let locs = List.map (function (fname,(line,col),(line_end,col_end)) ->
+ pycocci_instantiate_class "coccilib.elems.Location" (pytuple5
+ (pystring_fromstring fname,
+ pystring_fromstring (Printf.sprintf "%d" line),
+ pystring_fromstring (Printf.sprintf "%d" col),
+ pystring_fromstring (Printf.sprintf "%d" line_end),
+ pystring_fromstring (Printf.sprintf "%d" col_end)))) l in
+ let pylocs = pytuple_fromarray (Array.of_list locs) in
+ let _ = build_variable py pylocs in
+ ()
+ | Some (_,binding) ->
+ let _ = build_variable py (pystring_fromstring (Pycocci_aux.stringrep binding))
+ in ()
+ ) mv;
+
+ ()
+
+let set_coccifile cocci_file =
+ cocci_file_name := cocci_file;
+ ()
+
+
+let pyrun_simplestring s =
+ Pycaml.pyrun_simplestring s
+
+let py_isinitialized () =
+ Pycaml.py_isinitialized ()
+
+
+let py_finalize () =
+ Pycaml.py_finalize ()
class Location:
- def __init__(self, file, line, column, line_end, column_end):
+ def __init__(self, file, current_element, line, column, line_end, column_end):
self.file = file
+ self.current_element = current_element
self.line = line
self.column = column
self.line_end = line_end
let _ = build_variable py id_repr in
()
| Some (_, Ast_c.MetaPosValList l) ->
- let locs = List.map (function (fname,(line,col),(line_end,col_end)) ->
- pycocci_instantiate_class "coccilib.elems.Location" (pytuple5
- (pystring_fromstring fname,
+ let locs =
+ List.map
+ (function (fname,current_element,(line,col),(line_end,col_end)) ->
+ pycocci_instantiate_class "coccilib.elems.Location" (pytuple6
+ (pystring_fromstring fname,pystring_fromstring current_element,
pystring_fromstring (Printf.sprintf "%d" line),
pystring_fromstring (Printf.sprintf "%d" col),
pystring_fromstring (Printf.sprintf "%d" line_end),
sizeof(T) => sizeof(E)
+// Expression
+// @ fld_func_call @
+// expression list ES;
+// identifier fld;
+// expression E;
+// @@
+// E.fld(ES) <=> (*E.fld)(ES)
+
// ****************************************************************************
// Linux specific isomorphisms
let sp_of_file file iso = Parse_cocci.process file iso false
(* TODO: Remove
-let (rule_elem_of_string: string -> filename option -> Ast_cocci.rule_elem) =
- fun s iso ->
- begin
- Common.write_file ("/tmp/__cocci.cocci") (s);
- let (astcocci, _,_,_,_,_) = sp_of_file ("/tmp/__cocci.cocci") iso in
- let stmt =
- astcocci +>
- List.hd +> (function (_,_,x) -> List.hd x) +> (function x ->
- match Ast_cocci.unwrap x with
- | Ast_cocci.CODE stmt_dots -> Ast_cocci.undots stmt_dots +> List.hd
- | _ -> raise Not_found)
- in
- match Ast_cocci.unwrap stmt with
- | Ast_cocci.Atomic(re) -> re
- | _ -> failwith "only atomic patterns allowed"
- end
*)
(*
--- /dev/null
+// for seeing when errorexit nodes are created
+
+int main () {
+ int bad = -1;
+ if (x < 100) return -ENOMEM;
+ if (x < 100) return bad;
+ if (x < 100) goto out;
+ return 0;
+out:
+ return bad;
+}
--- /dev/null
+@r@
+struct sys_timer E;
+expression E2;
+@@
+
+* E.suspend = E2;
+
+@s@
+struct sys_timer E;
+expression E2;
+@@
+
+E.suspend = E2;
+
--- /dev/null
+TopLevel
+@ mkinit @
+type T;
+pure context T E;
+identifier I;
+identifier fld;
+expression E1;
+@@
+
+E.fld = E1; => T I = { .fld = E1, };
--- /dev/null
+void main(int foo) {
+
+ f(1);
+ x();
+ g(2);
+ x();
+ if(1) {
+ // h(3);
+ h(3);
+ } else {
+ h(4);
+ }
+
+
+}
+
--- /dev/null
+@ rule1 @
+expression X,Y,Z;
+@@
+ f(X);
+ ... when any, strict
+ g(Z);
+ ... when any, strict
+- h(Y);
++ h(X,Y,Z);
--- /dev/null
+@@
+//identifier f;
+expression E;
+@@
+
+* WARN_ON(E && !irqs_disabled())
-PROGS=gitgrep split_patch extract_c_and_res meta_files generate_dependencies
+PROGS=gitgrep split_patch extract_c_and_res #generate_dependencies
all: $(PROGS)
INCLUDE=-I ../commons -I ../extra -I ../parsing_c
LIBS=../commons/commons.cma ../globals/globals.cma \
- ../parsing_c/c_parser.cma ../extra/extra.cma
+ ../parsing_c/parsing_c.cma ../extra/extra.cma
OCAMLC=ocamlc$(OPTBIN) -g -dtypes $(INCLUDE)
OCAMLOPT=ocamlopt$(OPTBIN) $(INCLUDE) $(OPTFLAGS)
extract_c_and_res: extract_c_and_res.cmo
$(OCAMLC) -o $@ $(SYSLIBS) $(INCLUDE) $(LIBS) $+
-meta_files: meta_files.cmo
- $(OCAMLC) -o $@ $(SYSLIBS) $(INCLUDE) $(LIBS) $+
-
generate_dependencies: generate_dependencies.cmo
$(OCAMLC) -o $@ $(SYSLIBS) $(INCLUDE) $(LIBS) $+
# -allow_inconsistent_paths
-(~/coccinelle/spatch.opt -quiet -timeout 120 \
+(spatch.opt -quiet -timeout 120 \
-dir /home/julia/linux-2.6 -use_glimpse -cocci_file $* > ${1:r}.${3}.out) \
>& tmp.${1:r}.${3}.out
-open Common open Commonop
+open Common
(*****************************************************************************)
(* *)
-open Common open Commonop
+open Common
(*****************************************************************************)
(* Flags *)
-open Common open Commonop
+open Common
module CP = Classic_patch