From 485bce717a659e363d3bb74bf2ff76f1cd3b0ff7 Mon Sep 17 00:00:00 2001 From: Coccinelle Date: Sun, 3 Oct 2010 13:56:16 +0200 Subject: [PATCH] Release coccinelle-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 --- .depend | 22 +- Makefile | 23 +- changes.txt | 12 +- cocci.ml | 99 +- commitmsg | 10 +- commons/.depend | 6 +- commons/Makefile | 9 +- commons/backtrace.ml | 2 + commons/common.ml | 164 +- commons/common.mli | 31 +- commons/ocollection.ml | 5 + commons/ocollection.mli | 2 + commons/ograph_extended.ml | 52 +- commons/ograph_extended.mli | 10 +- .../{ocamlextra => }/parser_combinators.ml | 0 .../{ocamlextra => }/parser_combinators.mli | 0 ctl/.#ctl_engine.ml.1.185 | 2418 ++++++++++++ ctl/.#ctl_engine.ml.1.187 | 2418 ++++++++++++ .../flag_engine.ml => ctl/.#flag_ctl.ml.1.12 | 20 +- ctl/.#flag_ctl.ml.1.13 | 39 + ctl/ctl_engine.ml | 97 +- ctl/ctl_engine.mli | 6 + ctl/flag_ctl.ml | 4 + engine/.#Makefile.1.49 | 126 + engine/.#asttoctl2.ml.1.138 | 2222 ----------- ...sttoctl2.ml.1.141 => .#asttoctl2.ml.1.144} | 16 +- engine/.#c_vs_c.ml.1.9 | 294 ++ engine/.#check_exhaustive_pattern.ml.1.39 | 183 - engine/.#check_reachability.ml.1.18 | 208 + engine/.#cocci_vs_c_3.ml.1.154 | 3419 ----------------- ....1.111 => .#ctlcocci_integration.ml.1.116} | 13 +- engine/.#pattern3.ml.1.56 | 467 --- engine/.#pattern3.ml.1.57 | 476 --- engine/.#postprocess_transinfo.ml.1.12 | 105 + engine/.#pretty_print_engine.ml.1.42 | 161 + engine/.#transformation3.ml.1.47 | 526 --- engine/.#transformation3.ml.1.48 | 528 --- engine/.depend | 66 +- engine/Makefile | 129 +- engine/asttoctl2.ml | 54 +- engine/c_vs_c.ml | 8 +- engine/check_reachability.ml | 6 + engine/{cocci_vs_c_3.ml => cocci_vs_c.ml} | 372 +- engine/{cocci_vs_c_3.mli => cocci_vs_c.mli} | 4 +- engine/ctlcocci_integration.ml | 28 +- engine/flag_engine.ml | 46 +- engine/flag_matcher.ml | 14 + engine/lib_engine.ml | 2 + engine/{pattern3.ml => pattern_c.ml} | 50 +- engine/{pattern3.mli => pattern_c.mli} | 0 engine/postprocess_transinfo.ml | 2 +- engine/pretty_print_engine.ml | 6 +- ...transformation3.ml => transformation_c.ml} | 53 +- ...ansformation3.mli => transformation_c.mli} | 0 extra/.depend | 8 - flag_cocci.ml | 2 + globals/.#config.ml.1.2 | 8 + globals/config.ml | 2 +- globals/flag.ml | 5 + install.txt | 3 +- main.ml | 38 +- parsing_c/.depend | 81 +- parsing_c/Makefile | 58 +- parsing_c/ast_c.ml | 322 +- parsing_c/ast_to_flow.ml | 151 +- parsing_c/compare_c.ml | 15 +- parsing_c/control_flow_c.ml | 22 +- parsing_c/control_flow_c.mli | 13 +- parsing_c/copyright.txt | 8 +- parsing_c/cpp_ast_c.ml | 277 ++ parsing_c/cpp_ast_c.mli | 14 + parsing_c/credits.txt | 5 +- parsing_c/flag_parsing_c.ml | 72 +- parsing_c/lexer_c.mll | 270 +- parsing_c/lexer_parser.ml | 33 +- parsing_c/lexer_parser.mli | 20 +- parsing_c/lib_parsing_c.ml | 9 +- parsing_c/parse_c.ml | 606 +-- parsing_c/parse_c.mli | 68 +- parsing_c/parser_c.mly | 1189 ++++-- parsing_c/parsing_hacks.ml | 829 ++-- parsing_c/parsing_hacks.mli | 34 +- parsing_c/parsing_stat.ml | 274 ++ parsing_c/pretty_print_c.ml | 453 ++- parsing_c/pretty_print_c.mli | 5 +- parsing_c/test_parsing_c.ml | 30 +- parsing_c/test_parsing_c.mli | 1 + parsing_c/token_helpers.ml | 115 +- parsing_c/token_helpers.mli | 5 + parsing_c/type_annoter_c.ml | 16 +- parsing_c/{unparse_c2.ml => unparse_c.ml} | 37 +- parsing_c/{unparse_c2.mli => unparse_c.mli} | 2 + .../{unparse_cocci2.ml => unparse_cocci.ml} | 0 .../{unparse_cocci2.mli => unparse_cocci.mli} | 0 parsing_c/unparse_hrule.ml | 10 +- parsing_c/visitor_c.ml | 527 ++- parsing_c/visitor_c.mli | 27 +- parsing_cocci/.#ast0_cocci.ml.1.107 | 646 ++++ parsing_cocci/.#context_neg.ml.1.97 | 1003 +++++ parsing_cocci/.#iso_pattern.ml.1.138 | 2311 +++++++++++ parsing_cocci/.#parser_cocci_menhir.mly.1.156 | 1769 +++++++++ parsing_cocci/.#unitary_ast0.ml.1.29 | 288 ++ parsing_cocci/.#unparse_ast0.ml.1.109 | 658 ++++ parsing_cocci/.#visitor_ast0.ml.1.81 | 1038 +++++ parsing_cocci/ast0_cocci.ml | 14 +- parsing_cocci/context_neg.ml | 34 +- parsing_cocci/iso_pattern.ml | 109 +- parsing_cocci/parser_cocci_menhir.ml | 2165 +++++------ parsing_cocci/parser_cocci_menhir.mly | 11 +- parsing_cocci/unitary_ast0.ml | 10 +- parsing_cocci/unparse_ast0.ml | 10 +- popl09/.#Makefile.1.3 | 101 + popl09/Makefile | 2 +- pycaml/pycaml.ml | 2 + python/.#yes_pycocci.ml.1.1 | 241 ++ python/coccilib/elems.py | 3 +- python/yes_pycocci.ml | 8 +- standard.iso | 8 + testing.ml | 16 - tests/error.c | 11 + tests/sys.cocci | 14 + tests/sys.iso | 10 + tests/testprint.c | 16 + tests/testprint.cocci | 9 + tests/warnon.cocci | 6 + tools/Makefile | 7 +- tools/distributed/spatch_linux_script | 2 +- tools/extract_c_and_res.ml | 2 +- tools/generate_dependencies.ml | 2 +- tools/split_patch.ml | 2 +- 130 files changed, 20189 insertions(+), 11036 deletions(-) rename commons/{ocamlextra => }/parser_combinators.ml (100%) rename commons/{ocamlextra => }/parser_combinators.mli (100%) create mode 100644 ctl/.#ctl_engine.ml.1.185 create mode 100644 ctl/.#ctl_engine.ml.1.187 copy engine/flag_engine.ml => ctl/.#flag_ctl.ml.1.12 (71%) create mode 100644 ctl/.#flag_ctl.ml.1.13 create mode 100644 engine/.#Makefile.1.49 delete mode 100644 engine/.#asttoctl2.ml.1.138 rename engine/{.#asttoctl2.ml.1.141 => .#asttoctl2.ml.1.144} (99%) create mode 100644 engine/.#c_vs_c.ml.1.9 delete mode 100644 engine/.#check_exhaustive_pattern.ml.1.39 create mode 100644 engine/.#check_reachability.ml.1.18 delete mode 100644 engine/.#cocci_vs_c_3.ml.1.154 rename engine/{.#ctlcocci_integration.ml.1.111 => .#ctlcocci_integration.ml.1.116} (97%) delete mode 100644 engine/.#pattern3.ml.1.56 delete mode 100644 engine/.#pattern3.ml.1.57 create mode 100644 engine/.#postprocess_transinfo.ml.1.12 create mode 100644 engine/.#pretty_print_engine.ml.1.42 delete mode 100644 engine/.#transformation3.ml.1.47 delete mode 100644 engine/.#transformation3.ml.1.48 rename engine/{cocci_vs_c_3.ml => cocci_vs_c.ml} (92%) rename engine/{cocci_vs_c_3.mli => cocci_vs_c.mli} (98%) rewrite engine/flag_engine.ml (71%) create mode 100644 engine/flag_matcher.ml rename engine/{pattern3.ml => pattern_c.ml} (92%) rename engine/{pattern3.mli => pattern_c.mli} (100%) rename engine/{transformation3.ml => transformation_c.ml} (94%) rename engine/{transformation3.mli => transformation_c.mli} (100%) create mode 100644 globals/.#config.ml.1.2 create mode 100644 parsing_c/cpp_ast_c.ml create mode 100644 parsing_c/cpp_ast_c.mli create mode 100644 parsing_c/parsing_stat.ml rename parsing_c/{unparse_c2.ml => unparse_c.ml} (95%) rename parsing_c/{unparse_c2.mli => unparse_c.mli} (75%) rename parsing_c/{unparse_cocci2.ml => unparse_cocci.ml} (100%) rename parsing_c/{unparse_cocci2.mli => unparse_cocci.mli} (100%) create mode 100644 parsing_cocci/.#ast0_cocci.ml.1.107 create mode 100644 parsing_cocci/.#context_neg.ml.1.97 create mode 100644 parsing_cocci/.#iso_pattern.ml.1.138 create mode 100644 parsing_cocci/.#parser_cocci_menhir.mly.1.156 create mode 100644 parsing_cocci/.#unitary_ast0.ml.1.29 create mode 100644 parsing_cocci/.#unparse_ast0.ml.1.109 create mode 100644 parsing_cocci/.#visitor_ast0.ml.1.81 create mode 100644 popl09/.#Makefile.1.3 create mode 100644 python/.#yes_pycocci.ml.1.1 create mode 100644 tests/error.c create mode 100644 tests/sys.cocci create mode 100644 tests/sys.iso create mode 100644 tests/testprint.c create mode 100644 tests/testprint.cocci create mode 100644 tests/warnon.cocci diff --git a/.depend b/.depend index 0df0e6f..30da4d6 100644 --- a/.depend +++ b/.depend @@ -1,37 +1,39 @@ 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 \ diff --git a/Makefile b/Makefile index 06b01a5..36cac02 100644 --- a/Makefile +++ b/Makefile @@ -107,13 +107,10 @@ BYTECODE_STATIC=-custom ############################################################################## # 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); \ @@ -123,6 +120,9 @@ rec.opt: 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) $^ @@ -214,6 +214,7 @@ OCAMLVERSION=$(shell ocaml -version |perl -p -e 's/.*version (.*)/$$1/;') # cvs update -d -P # touch **/* # make licensify +# remember to comment the -g -dtypes in this Makefile # Procedure to do each time: # cvs update @@ -319,6 +320,17 @@ syncwiki: 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 @@ -346,8 +358,9 @@ tags: 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 diff --git a/changes.txt b/changes.txt index 0a0013d..c1493ab 100644 --- a/changes.txt +++ b/changes.txt @@ -1,8 +1,18 @@ -*- 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 diff --git a/cocci.ml b/cocci.ml index b55eb06..6ab9293 100644 --- a/cocci.ml +++ b/cocci.ml @@ -46,11 +46,15 @@ let cprogram_of_file file = 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 @@ -272,18 +276,29 @@ let show_or_not_ctl_text a b c = (* 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) @@ -437,7 +452,7 @@ let sp_contain_typed_metavar rules = * serio.c is related we think to #include *) -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 @@ -446,7 +461,8 @@ let includes_to_parse xs = 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 @@ -567,7 +583,9 @@ let compute_new_prefixes xs = 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 | _ -> @@ -676,14 +694,37 @@ let g_contain_typedmetavar = ref false 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 = @@ -789,7 +830,7 @@ let rebuild_info_program cs file isexp = | 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); *) @@ -822,7 +863,7 @@ let rebuild_info_c_and_headers ccs isexp = -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 @@ -976,7 +1017,7 @@ let rec apply_python_rule r cache newes e rules_that_have_matched 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; @@ -1020,13 +1061,13 @@ and apply_cocci_rule r rules_that_have_ever_matched es ccs = (* 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 -> @@ -1098,7 +1139,7 @@ and merge_env new_e old_e = | _ -> 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 @@ -1131,7 +1172,7 @@ and bigloop2 rs ccs = 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); @@ -1248,9 +1289,10 @@ and bigloop a b = (* 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; @@ -1281,7 +1323,7 @@ and process_a_ctl_a_env_a_toplevel2 r e c = * 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; @@ -1290,9 +1332,9 @@ and process_a_ctl_a_env_a_toplevel2 r e c = 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) @@ -1355,6 +1397,7 @@ let full_engine2 (coccifile, isofile) cfiles = 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 -> diff --git a/commitmsg b/commitmsg index 2df494c..62edc40 100644 --- a/commitmsg +++ b/commitmsg @@ -1,4 +1,8 @@ -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 diff --git a/commons/.depend b/commons/.depend index 39a569b..eae66ad 100644 --- a/commons/.depend +++ b/commons/.depend @@ -71,6 +71,8 @@ oseti.cmo: seti.cmo oset.cmi ocollection.cmi 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 @@ -81,10 +83,6 @@ ocamlextra/dynArray.cmo: ocamlextra/enum.cmi ocamlextra/dynArray.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 diff --git a/commons/Makefile b/commons/Makefile index c36c18f..c5878f5 100644 --- a/commons/Makefile +++ b/commons/Makefile @@ -14,7 +14,7 @@ MYSRC=common.ml common_extra.ml \ 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 @@ -23,7 +23,6 @@ SRC+=ocamlextra/setb.ml ocamlextra/mapb.ml # defunctorized version of standard s 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 @@ -60,12 +59,6 @@ MPIINCLUDES=-I ../ocamlmpi -I ../../ocamlmpi -I +ocamlmpi MYMPISRC=distribution.ml MPISYSLIBS=mpi.cma -#ocamlmpi -MPIINCLUDES=-I ../ocamlmpi -I ../../ocamlmpi -I +ocamlmpi -MYMPISRC=distribution.ml -MPISYSLIBS=mpi.cma - - #----------------------------------------------------------------------------- # Other stuff #----------------------------------------------------------------------------- diff --git a/commons/backtrace.ml b/commons/backtrace.ml index 85a61b3..9a0ee50 100644 --- a/commons/backtrace.ml +++ b/commons/backtrace.ml @@ -5,6 +5,8 @@ open Common * 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" diff --git a/commons/common.ml b/commons/common.ml index ee2b75e..d891cc5 100644 --- a/commons/common.ml +++ b/commons/common.ml @@ -190,6 +190,8 @@ let (with_open_stringbuf: (((string -> unit) * Buffer.t) -> unit) -> string) = Buffer.contents buf +let foldl1 p = function x::xs -> List.fold_left p x xs | _ -> failwith "foldl1" + (*****************************************************************************) (* Debugging/logging *) (*****************************************************************************) @@ -545,6 +547,7 @@ let time_func f = 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 @@ -553,9 +556,24 @@ let check_profile category = | 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. *) @@ -563,6 +581,7 @@ let profile_code category f = 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 ()), "" @@ -570,22 +589,41 @@ let profile_code category 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 @@ -892,6 +930,8 @@ let write_back func filename = write_value (func (get_value filename)) filename +let read_value f = get_value f + (*****************************************************************************) (* Counter *) @@ -2017,7 +2057,28 @@ let all_match re s = 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 + (*****************************************************************************) @@ -2104,6 +2165,9 @@ let size_ko i = + + + (* 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] @@ -2170,6 +2234,7 @@ let dirname = Filename.dirname 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 @@ -2577,15 +2642,34 @@ let rough_days_since_jesus (DMY (Day nday, month, Year year)) = +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 @@ -3327,6 +3411,25 @@ let (exclude_but_keep_attached: ('a -> bool) -> 'a list -> ('a * 'a list) list)= 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) = @@ -3396,6 +3499,10 @@ let index_list_1 xs = 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 @@ -3428,7 +3535,8 @@ let remove 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 @@ -4111,6 +4219,12 @@ let _ = example (lookup_list2 "c" [["a",1;"b",2];["a",1;"b",3];["a",1;"c",7]] = 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 *) (*****************************************************************************) @@ -4706,6 +4820,8 @@ let fake_parse_info = { 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)) = @@ -5155,6 +5271,8 @@ let cmdline_flags_verbose () = " 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 () = @@ -5259,6 +5377,18 @@ let main_boilerplate f = (* 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 *) (*****************************************************************************) diff --git a/commons/common.mli b/commons/common.mli index a0cdac7..04fdd01 100644 --- a/commons/common.mli +++ b/commons/common.mli @@ -31,6 +31,8 @@ val debugger : bool ref type prof = PALL | PNONE | PSOME of string list val profile : prof ref +val show_trace_profile : bool ref + val verbose_level : int ref @@ -63,6 +65,7 @@ val save_tmp_files : bool 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 @@ -214,6 +217,9 @@ val _profile_table : (string, (float ref * int ref)) Hashtbl.t ref 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 *) @@ -276,6 +282,7 @@ val laws2 : (* 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 @@ -591,9 +598,6 @@ val ( /! ) : int -> int -> int 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 @@ -786,11 +790,14 @@ val size_ko : int -> string 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 @@ -819,6 +826,11 @@ val join : string (* sep *) -> string list -> string 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 *) @@ -948,6 +960,11 @@ val rough_days_between_dates : date_dmy -> date_dmy -> days 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 *) @@ -1087,6 +1104,7 @@ val exn_to_real_unixexit : (unit -> 'a) -> 'a (* 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 *) @@ -1116,6 +1134,7 @@ val fpartition : ('a -> 'b option) -> 'a list -> 'b list * 'a list 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 @@ -1214,6 +1233,10 @@ val prepare_want_all_assoc : ('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 @@ -1379,6 +1402,7 @@ val lookup_list : 'a -> ('a, 'b) assoc 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. *) @@ -1696,6 +1720,7 @@ type parse_info = { } 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 diff --git a/commons/ocollection.ml b/commons/ocollection.ml index 6869f4b..38e4b96 100644 --- a/commons/ocollection.ml +++ b/commons/ocollection.ml @@ -71,6 +71,11 @@ object(o: 'o) 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 diff --git a/commons/ocollection.mli b/commons/ocollection.mli index 03d2d83..c23dced 100644 --- a/commons/ocollection.mli +++ b/commons/ocollection.mli @@ -17,6 +17,8 @@ object ('o) method virtual mem : 'a -> bool method virtual null : bool + (* effect version *) + method add2: 'a -> unit method fold : ('c -> 'a -> 'c) -> 'c -> 'c diff --git a/commons/ograph_extended.ml b/commons/ograph_extended.ml index a11d494..a481249 100644 --- a/commons/ograph_extended.ml +++ b/commons/ograph_extended.ml @@ -227,6 +227,41 @@ let dfs_iter_with_path xi f g = +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,_) -> @@ -236,7 +271,7 @@ let generate_ograph_xxx g filename = 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) -> @@ -247,11 +282,12 @@ let generate_ograph_xxx g filename = ); 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 @@ -261,8 +297,12 @@ let launch_gv filename = 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 diff --git a/commons/ograph_extended.mli b/commons/ograph_extended.mli index 5b9908a..c9f3936 100644 --- a/commons/ograph_extended.mli +++ b/commons/ograph_extended.mli @@ -58,6 +58,15 @@ val dfs_iter_with_path : 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 -> @@ -70,4 +79,3 @@ val print_ograph_mutable : filename (* output file *) -> bool (* launch gv ? *) -> unit - diff --git a/commons/ocamlextra/parser_combinators.ml b/commons/parser_combinators.ml similarity index 100% rename from commons/ocamlextra/parser_combinators.ml rename to commons/parser_combinators.ml diff --git a/commons/ocamlextra/parser_combinators.mli b/commons/parser_combinators.mli similarity index 100% rename from commons/ocamlextra/parser_combinators.mli rename to commons/parser_combinators.mli diff --git a/ctl/.#ctl_engine.ml.1.185 b/ctl/.#ctl_engine.ml.1.185 new file mode 100644 index 0000000..cee310c --- /dev/null +++ b/ctl/.#ctl_engine.ml.1.185 @@ -0,0 +1,2418 @@ +(* +* 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 . +* +* 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 +;; + diff --git a/ctl/.#ctl_engine.ml.1.187 b/ctl/.#ctl_engine.ml.1.187 new file mode 100644 index 0000000..cee310c --- /dev/null +++ b/ctl/.#ctl_engine.ml.1.187 @@ -0,0 +1,2418 @@ +(* +* 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 . +* +* 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 +;; + diff --git a/engine/flag_engine.ml b/ctl/.#flag_ctl.ml.1.12 similarity index 71% copy from engine/flag_engine.ml copy to ctl/.#flag_ctl.ml.1.12 index 3140109..97a487d 100644 --- a/engine/flag_engine.ml +++ b/ctl/.#flag_ctl.ml.1.12 @@ -20,15 +20,19 @@ *) -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 diff --git a/ctl/.#flag_ctl.ml.1.13 b/ctl/.#flag_ctl.ml.1.13 new file mode 100644 index 0000000..6bbb66a --- /dev/null +++ b/ctl/.#flag_ctl.ml.1.13 @@ -0,0 +1,39 @@ +(* +* 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 . +* +* 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 diff --git a/ctl/ctl_engine.ml b/ctl/ctl_engine.ml index cee310c..c19260f 100644 --- a/ctl/ctl_engine.ml +++ b/ctl/ctl_engine.ml @@ -46,6 +46,10 @@ let pUNCHECK_OPT = ref true 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 @@ -125,6 +129,8 @@ module type GRAPH = 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 ;; @@ -154,6 +160,9 @@ 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 = @@ -363,7 +372,44 @@ let print_required_states = function 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 + (* ---------------------------------------------------------------------- *) (* *) (* ---------------------------------------------------------------------- *) @@ -1050,7 +1096,8 @@ 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 = +let satEU dir ((_,_,states) as m) s1 s2 reqst print_graph = + let ctr = ref 0 in inc satEU_calls; if s1 = [] then s2 @@ -1064,6 +1111,7 @@ let satEU dir ((_,_,states) as m) s1 s2 reqst = [] -> 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 @@ -1075,6 +1123,8 @@ let satEU dir ((_,_,states) as m) s1 s2 reqst = 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 @@ -1115,7 +1165,8 @@ 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 = +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 @@ -1132,9 +1183,10 @@ let satAU dir ((cfg,_,states) as m) s1 s2 reqst = 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 @@ -1169,6 +1221,8 @@ let satAU dir ((cfg,_,states) as m) s1 s2 reqst = 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) @@ -1349,8 +1403,8 @@ let strict_A2 strict op failop dir ((_,_,states) as m) trips trips' 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 @@ -1710,7 +1764,8 @@ let rec satloop unchecked required required_states | 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 @@ -1728,7 +1783,9 @@ let rec satloop unchecked required required_states 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 -> @@ -1739,7 +1796,10 @@ let rec satloop unchecked required required_states (* 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) -> @@ -1758,6 +1818,7 @@ let rec satloop unchecked required required_states (* 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) @@ -1768,7 +1829,9 @@ let rec satloop unchecked required required_states 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 ;; @@ -1974,7 +2037,8 @@ let rec sat_verbose_loop unchecked required required_states annot maxlvl lvl 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 @@ -2001,7 +2065,8 @@ let rec sat_verbose_loop unchecked required required_states annot maxlvl lvl 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] @@ -2013,7 +2078,11 @@ let rec sat_verbose_loop unchecked required required_states annot maxlvl lvl (* 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])) diff --git a/ctl/ctl_engine.mli b/ctl/ctl_engine.mli index 05e2f5e..ba21a17 100644 --- a/ctl/ctl_engine.mli +++ b/ctl/ctl_engine.mli @@ -20,6 +20,8 @@ module type GRAPH = 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 : @@ -62,3 +64,7 @@ module CTL_ENGINE : val print_bench : unit -> unit end + +val get_graph_files : unit -> string list +val get_graph_comp_files : string -> string list + diff --git a/ctl/flag_ctl.ml b/ctl/flag_ctl.ml index 97a487d..e78fb19 100644 --- a/ctl/flag_ctl.ml +++ b/ctl/flag_ctl.ml @@ -36,3 +36,7 @@ let bench = ref 0 let steps = ref (None : int option) +let graphical_trace = ref false +let gt_without_label = ref false + +let checking_reachability = ref false diff --git a/engine/.#Makefile.1.49 b/engine/.#Makefile.1.49 new file mode 100644 index 0000000..4103bca --- /dev/null +++ b/engine/.#Makefile.1.49 @@ -0,0 +1,126 @@ +# 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 . +# +# 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 diff --git a/engine/.#asttoctl2.ml.1.138 b/engine/.#asttoctl2.ml.1.138 deleted file mode 100644 index bf9268b..0000000 --- a/engine/.#asttoctl2.ml.1.138 +++ /dev/null @@ -1,2222 +0,0 @@ -(* -* 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 . -* -* 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 diff --git a/engine/.#asttoctl2.ml.1.141 b/engine/.#asttoctl2.ml.1.144 similarity index 99% rename from engine/.#asttoctl2.ml.1.141 rename to engine/.#asttoctl2.ml.1.144 index 6f1f8f6..0691c57 100644 --- a/engine/.#asttoctl2.ml.1.141 +++ b/engine/.#asttoctl2.ml.1.144 @@ -1230,7 +1230,7 @@ let dots_au is_strict toend label s wrapcode x seq_after y quantifier = (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) @@ -1248,7 +1248,7 @@ let dots_au is_strict toend label s wrapcode x seq_after y quantifier = (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 @@ -2027,7 +2027,13 @@ and statement stmt after quantified minus_quantified 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 = @@ -2065,6 +2071,8 @@ and statement stmt after quantified minus_quantified 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)) @@ -2078,6 +2086,8 @@ and statement stmt after quantified minus_quantified 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 diff --git a/engine/.#c_vs_c.ml.1.9 b/engine/.#c_vs_c.ml.1.9 new file mode 100644 index 0000000..4391933 --- /dev/null +++ b/engine/.#c_vs_c.ml.1.9 @@ -0,0 +1,294 @@ +(* +* 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 . +* +* 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) diff --git a/engine/.#check_exhaustive_pattern.ml.1.39 b/engine/.#check_exhaustive_pattern.ml.1.39 deleted file mode 100644 index a716d1b..0000000 --- a/engine/.#check_exhaustive_pattern.ml.1.39 +++ /dev/null @@ -1,183 +0,0 @@ -(* -* 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 . -* -* 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 - -*) diff --git a/engine/.#check_reachability.ml.1.18 b/engine/.#check_reachability.ml.1.18 new file mode 100644 index 0000000..297a7d4 --- /dev/null +++ b/engine/.#check_reachability.ml.1.18 @@ -0,0 +1,208 @@ +(* +* 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 . +* +* 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 diff --git a/engine/.#cocci_vs_c_3.ml.1.154 b/engine/.#cocci_vs_c_3.ml.1.154 deleted file mode 100644 index fc1f4c0..0000000 --- a/engine/.#cocci_vs_c_3.ml.1.154 +++ /dev/null @@ -1,3419 +0,0 @@ -(* -* 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 . -* -* 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 in the .cocci, need to find where is - * the '+' attached to this element, to later find the first concrete - * #include 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 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 - diff --git a/engine/.#ctlcocci_integration.ml.1.111 b/engine/.#ctlcocci_integration.ml.1.116 similarity index 97% rename from engine/.#ctlcocci_integration.ml.1.111 rename to engine/.#ctlcocci_integration.ml.1.116 index 5f736aa..134089c 100644 --- a/engine/.#ctlcocci_integration.ml.1.111 +++ b/engine/.#ctlcocci_integration.ml.1.116 @@ -30,7 +30,7 @@ module F = Control_flow_c (* 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; @@ -39,7 +39,7 @@ let show_or_not_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 () -> @@ -116,7 +116,7 @@ let (labels_for_ctl: string list (* dropped isos *) -> | 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 ) @@ -400,14 +400,15 @@ let (mysat2: 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 @@ -416,7 +417,7 @@ let (mysat2: 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) diff --git a/engine/.#pattern3.ml.1.56 b/engine/.#pattern3.ml.1.56 deleted file mode 100644 index 5b04d31..0000000 --- a/engine/.#pattern3.ml.1.56 +++ /dev/null @@ -1,467 +0,0 @@ -(* -* 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 . -* -* 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) diff --git a/engine/.#pattern3.ml.1.57 b/engine/.#pattern3.ml.1.57 deleted file mode 100644 index 9a7c6ce..0000000 --- a/engine/.#pattern3.ml.1.57 +++ /dev/null @@ -1,476 +0,0 @@ -(* -* 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 . -* -* 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) diff --git a/engine/.#postprocess_transinfo.ml.1.12 b/engine/.#postprocess_transinfo.ml.1.12 new file mode 100644 index 0000000..89b30b7 --- /dev/null +++ b/engine/.#postprocess_transinfo.ml.1.12 @@ -0,0 +1,105 @@ +(* +* 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 . +* +* 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) diff --git a/engine/.#pretty_print_engine.ml.1.42 b/engine/.#pretty_print_engine.ml.1.42 new file mode 100644 index 0000000..0dd3bb3 --- /dev/null +++ b/engine/.#pretty_print_engine.ml.1.42 @@ -0,0 +1,161 @@ +(* +* 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 . +* +* 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 "<>" + | 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 "<>" + | Ast_c.MetaParamListVal params -> pp "<>" + | 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 " + | 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 + + diff --git a/engine/.#transformation3.ml.1.47 b/engine/.#transformation3.ml.1.47 deleted file mode 100644 index 5691a73..0000000 --- a/engine/.#transformation3.ml.1.47 +++ /dev/null @@ -1,526 +0,0 @@ -(* -* 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 . -* -* 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) diff --git a/engine/.#transformation3.ml.1.48 b/engine/.#transformation3.ml.1.48 deleted file mode 100644 index 5ade85b..0000000 --- a/engine/.#transformation3.ml.1.48 +++ /dev/null @@ -1,528 +0,0 @@ -(* -* 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 . -* -* 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) diff --git a/engine/.depend b/engine/.depend index 301f8e4..cd7367f 100644 --- a/engine/.depend +++ b/engine/.depend @@ -7,20 +7,20 @@ asttomember.cmi: lib_engine.cmo ../ctl/ast_ctl.cmo \ 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 \ @@ -32,13 +32,13 @@ asttoctl.cmx: ../ctl/wrapper_ctl.cmx ../parsing_cocci/visitor_ast.cmx \ 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 \ @@ -63,26 +63,26 @@ check_reachability.cmo: ../ctl/wrapper_ctl.cmi ../commons/ograph_extended.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 \ @@ -101,12 +101,12 @@ lib_engine.cmx: ../ctl/wrapper_ctl.cmx ../commons/ograph_extended.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 @@ -125,17 +125,13 @@ pretty_print_engine.cmx: ../ctl/pretty_print_ctl.cmx \ 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 diff --git a/engine/Makefile b/engine/Makefile index 044cc14..105528d 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -18,106 +18,109 @@ # 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 diff --git a/engine/asttoctl2.ml b/engine/asttoctl2.ml index fca5fcf..6b2a340 100644 --- a/engine/asttoctl2.ml +++ b/engine/asttoctl2.ml @@ -1229,35 +1229,41 @@ let dots_au is_strict toend label s wrapcode x seq_after y quantifier = 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 = diff --git a/engine/c_vs_c.ml b/engine/c_vs_c.ml index 440f7ba..303be64 100644 --- a/engine/c_vs_c.ml +++ b/engine/c_vs_c.ml @@ -143,6 +143,7 @@ and typeC tya tyb = 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 @@ -198,7 +199,9 @@ and typeC tya tyb = 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 @@ -224,7 +227,8 @@ and typeC tya tyb = ) ) (return []) >>= (fun fx -> - return ((FieldDeclList (List.rev fx), iix)::xs) + return (((DeclarationField + (FieldDeclList (List.rev fx,iipt))), iix)::xs) ) | _ -> fail ) diff --git a/engine/check_reachability.ml b/engine/check_reachability.ml index 297a7d4..53e041f 100644 --- a/engine/check_reachability.ml +++ b/engine/check_reachability.ml @@ -144,6 +144,7 @@ module CFG = 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) @@ -161,14 +162,19 @@ let test_formula state formula cfg = 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 (* ---------------------------------------------------------------- *) diff --git a/engine/cocci_vs_c_3.ml b/engine/cocci_vs_c.ml similarity index 92% rename from engine/cocci_vs_c_3.ml rename to engine/cocci_vs_c.ml index f2348f3..ed20853 100644 --- a/engine/cocci_vs_c_3.ml +++ b/engine/cocci_vs_c.ml @@ -1,24 +1,16 @@ -(* -* 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 . -* -* 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 @@ -27,6 +19,8 @@ module B = Ast_c module F = Control_flow_c +module Flag = Flag_matcher + (*****************************************************************************) (* Wrappers *) (*****************************************************************************) @@ -123,7 +117,12 @@ let generalize_mcode ia = 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) @@ -156,7 +155,10 @@ let equal_unaryOp a b = | 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 @@ -170,7 +172,8 @@ let equal_arithOp a b = | 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 @@ -182,37 +185,38 @@ let equal_logicalOp a b = | 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 @@ -221,7 +225,9 @@ let equal_storage a b = | 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 + (*---------------------------------------------------------------------------*) @@ -262,15 +268,20 @@ let equal_metavarval valu valu' = | 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 (*---------------------------------------------------------------------------*) @@ -422,7 +433,11 @@ let initialisation_to_affectation decl = (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) -> @@ -528,7 +543,7 @@ module type PARAM = 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 @@ -549,7 +564,7 @@ module type PARAM = 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 : @@ -726,7 +741,7 @@ let rec (expression: (A.expression, Ast_c.expression) matcher) = - | 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. @@ -772,7 +787,9 @@ let rec (expression: (A.expression, Ast_c.expression) matcher) = )) | _ -> fail (* multi string, not handled *) ) - | _, _ -> fail + + | _, B.MultiString -> (* todo cocci? *) fail + | _, (B.String _ | B.Float _ | B.Char _ | B.Int _) -> fail ) @@ -1019,17 +1036,17 @@ let rec (expression: (A.expression, Ast_c.expression) matcher) = 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 @@ -1047,7 +1064,20 @@ let rec (expression: (A.expression, Ast_c.expression) matcher) = | _, ((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 + + + @@ -1591,8 +1621,8 @@ and (declaration: (A.mcodekind * bool * A.declaration,B.declaration) matcher) = (B.MacroDecl ((sb,ebs), [iisb;lpb;rpb;iiendb;iifakestart] ++ iistob)) )))))))) - - | _ -> fail + + | _, (B.MacroDecl _ |B.DeclList _) -> fail @@ -1604,7 +1634,12 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) -> * 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) -> @@ -1662,8 +1697,12 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) -> 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 @@ -1686,8 +1725,12 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) -> 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 @@ -1702,18 +1745,28 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) -> ) | 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) -> @@ -1721,12 +1774,22 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) -> (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 -> @@ -1737,25 +1800,46 @@ and onedecl = fun allminus decla (declb, iiptvirgb, 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), + (({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 -> @@ -1793,14 +1877,19 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) -> ) >>= (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 @@ -1819,11 +1908,12 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) -> | 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 @@ -1949,8 +2039,13 @@ and (initialiser: (A.initialiser, Ast_c.initialiser) matcher) = fun ia ib -> | 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 + @@ -2026,7 +2121,7 @@ and initialisers_unordered2 = fun ias ibs -> (* ------------------------------------------------------------------------- *) -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 ([], []) @@ -2069,12 +2164,13 @@ and (struct_fields: (A.declaration list, B.field B.wrap list) matcher) = | _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 @@ -2095,19 +2191,29 @@ and (struct_field: (A.declaration, B.field B.wrap) matcher) = fun fa fb -> 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 ) @@ -2117,7 +2223,13 @@ and (struct_field: (A.declaration, B.field B.wrap) matcher) = fun fa fb -> 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 @@ -2313,10 +2425,9 @@ and (typeC: (A.typeC, Ast_c.typeC) matcher) = pr2_once "warning: long long or long double not handled by ast_cocci"; fail - - - | _, _ -> fail - + + | _, (B.Void|B.FloatType _|B.IntType _) -> fail + ) @@ -2534,8 +2645,19 @@ and (typeC: (A.typeC, Ast_c.typeC) matcher) = | _, (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 @@ -2656,9 +2778,13 @@ and compatible_type a (b,_local) = 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, _ -> @@ -2714,7 +2840,26 @@ and compatible_type a (b,_local) = (* 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 = @@ -2731,7 +2876,7 @@ and equal_structUnion_type_cocci a b = match a, b with | Type_cocci.Struct, B.Struct -> true | Type_cocci.Union, B.Union -> true - | _, _ -> false + | _, (B.Struct | B.Union) -> false @@ -3062,7 +3207,13 @@ let rec (rule_elem_node: (A.rule_elem, Control_flow_c.node) matcher) = | 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. @@ -3120,8 +3271,12 @@ let rec (rule_elem_node: (A.rule_elem, Control_flow_c.node) matcher) = 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) ) )))))))) @@ -3301,8 +3456,14 @@ let rec (rule_elem_node: (A.rule_elem, Control_flow_c.node) matcher) = - | 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 _), _ -> @@ -3320,7 +3481,11 @@ let rec (rule_elem_node: (A.rule_elem, Control_flow_c.node) matcher) = 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 @@ -3417,12 +3582,27 @@ let rec (rule_elem_node: (A.rule_elem, Control_flow_c.node) matcher) = (* 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 diff --git a/engine/cocci_vs_c_3.mli b/engine/cocci_vs_c.mli similarity index 98% rename from engine/cocci_vs_c_3.mli rename to engine/cocci_vs_c.mli index 514ef64..3e28251 100644 --- a/engine/cocci_vs_c_3.mli +++ b/engine/cocci_vs_c.mli @@ -109,7 +109,7 @@ module type PARAM = 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 : @@ -145,7 +145,7 @@ module type PARAM = 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 : diff --git a/engine/ctlcocci_integration.ml b/engine/ctlcocci_integration.ml index 2b6c75f..1c04b18 100644 --- a/engine/ctlcocci_integration.ml +++ b/engine/ctlcocci_integration.ml @@ -30,7 +30,7 @@ module F = Control_flow_c (* 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; @@ -39,7 +39,7 @@ let show_or_not_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 () -> @@ -116,7 +116,7 @@ let (labels_for_ctl: string list (* dropped isos *) -> | 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 ) @@ -327,7 +327,7 @@ module ENV = 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) @@ -335,6 +335,24 @@ module CFG = 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 @@ -408,7 +426,7 @@ let (mysat2: 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 diff --git a/engine/flag_engine.ml b/engine/flag_engine.ml dissimilarity index 71% index 3140109..950835c 100644 --- a/engine/flag_engine.ml +++ b/engine/flag_engine.ml @@ -1,34 +1,12 @@ -(* -* 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 . -* -* 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 diff --git a/engine/flag_matcher.ml b/engine/flag_matcher.ml new file mode 100644 index 0000000..885eb3d --- /dev/null +++ b/engine/flag_matcher.ml @@ -0,0 +1,14 @@ +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 diff --git a/engine/lib_engine.ml b/engine/lib_engine.ml index ba36fc4..8b9bf26 100644 --- a/engine/lib_engine.ml +++ b/engine/lib_engine.ml @@ -42,6 +42,7 @@ type predicate = | BindBad of Ast_cocci.meta_name | FakeBrace +(* coccionly: *) type ctlcocci = (predicate, Ast_cocci.meta_name) Wrapper_ctl.wrapped_ctl @@ -64,6 +65,7 @@ and metavars_binding2 = (mvar, metavar_binding_kind2) Common.assoc (*****************************************************************************) (* the CTL model related types *) (*****************************************************************************) +(* coccionly: *) type label_ctlcocci = predicate -> (nodei * diff --git a/engine/pattern3.ml b/engine/pattern_c.ml similarity index 92% rename from engine/pattern3.ml rename to engine/pattern_c.ml index 88560ee..68cde1e 100644 --- a/engine/pattern3.ml +++ b/engine/pattern_c.ml @@ -1,27 +1,19 @@ -(* -* 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 . -* -* 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 *) (*****************************************************************************) @@ -146,7 +138,7 @@ module XMATCH = struct else fail tin - let mode = Cocci_vs_c_3.PatternMode + let mode = Cocci_vs_c.PatternMode (* ------------------------------------------------------------------------*) (* Exp *) @@ -301,7 +293,7 @@ module XMATCH = struct 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 *) @@ -324,14 +316,14 @@ module XMATCH = struct 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 @@ -384,8 +376,8 @@ module XMATCH = struct (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. *) @@ -468,7 +460,7 @@ end (*****************************************************************************) (* 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 = diff --git a/engine/pattern3.mli b/engine/pattern_c.mli similarity index 100% rename from engine/pattern3.mli rename to engine/pattern_c.mli diff --git a/engine/postprocess_transinfo.ml b/engine/postprocess_transinfo.ml index 89b30b7..f442ef3 100644 --- a/engine/postprocess_transinfo.ml +++ b/engine/postprocess_transinfo.ml @@ -40,7 +40,7 @@ let get_extra _ = 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() diff --git a/engine/pretty_print_engine.ml b/engine/pretty_print_engine.ml index 0dd3bb3..0b913a4 100644 --- a/engine/pretty_print_engine.ml +++ b/engine/pretty_print_engine.ml @@ -52,9 +52,9 @@ let rec pp_binding_kind = function 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 = diff --git a/engine/transformation3.ml b/engine/transformation_c.ml similarity index 94% rename from engine/transformation3.ml rename to engine/transformation_c.ml index 84a3d33..ec3a2b0 100644 --- a/engine/transformation3.ml +++ b/engine/transformation_c.ml @@ -1,29 +1,21 @@ -(* -* 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 . -* -* 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 *) (*****************************************************************************) @@ -100,7 +92,7 @@ module XTRANS = struct 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 *) @@ -187,9 +179,12 @@ module XTRANS = struct 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 @@ -213,10 +208,13 @@ module XTRANS = struct 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; @@ -225,6 +223,7 @@ module XTRANS = struct 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 @@ -460,7 +459,7 @@ module XTRANS = struct *) (*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 @@ -478,7 +477,7 @@ end (*****************************************************************************) (* 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 = diff --git a/engine/transformation3.mli b/engine/transformation_c.mli similarity index 100% rename from engine/transformation3.mli rename to engine/transformation_c.mli diff --git a/extra/.depend b/extra/.depend index a321b42..8c6112e 100644 --- a/extra/.depend +++ b/extra/.depend @@ -1,14 +1,6 @@ -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 diff --git a/flag_cocci.ml b/flag_cocci.ml index af2b9b5..fae3229 100644 --- a/flag_cocci.ml +++ b/flag_cocci.ml @@ -46,6 +46,8 @@ let windows = ref false 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 diff --git a/globals/.#config.ml.1.2 b/globals/.#config.ml.1.2 new file mode 100644 index 0000000..c5516d9 --- /dev/null +++ b/globals/.#config.ml.1.2 @@ -0,0 +1,8 @@ +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") diff --git a/globals/config.ml b/globals/config.ml index c5516d9..f2d0bbd 100644 --- a/globals/config.ml +++ b/globals/config.ml @@ -1,4 +1,4 @@ -let version = "0.1.1" +let version = "0.1.2" let path = try (Sys.getenv "COCCINELLE_HOME") diff --git a/globals/flag.ml b/globals/flag.ml index 222e4bb..ebee85e 100644 --- a/globals/flag.ml +++ b/globals/flag.ml @@ -14,3 +14,8 @@ let pyoutput = ref "coccilib.output.Console" let patch = ref (None : string option) let make_hrule = ref (None : string (*dir*) option) + +let currentfile = ref (None : string option) + +let current_element = ref "" + diff --git a/install.txt b/install.txt index b9ee270..6568c4f 100644 --- a/install.txt +++ b/install.txt @@ -7,7 +7,8 @@ You must first install a recent version of 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 diff --git a/main.ml b/main.ml index 75ca33d..1b00f0d 100644 --- a/main.ml +++ b/main.ml @@ -89,7 +89,7 @@ let quiet_profile = ( 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; @@ -116,7 +116,7 @@ let pad_profile = ( 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; @@ -197,7 +197,7 @@ let short_options = [ " 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"; @@ -264,8 +264,10 @@ let other_options = [ "", [ "-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, " "; @@ -294,7 +296,7 @@ let other_options = [ "-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, " "; @@ -365,26 +367,27 @@ let other_options = [ "-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"; ]; @@ -504,11 +507,14 @@ let adjust_stdin cfile k = 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 = diff --git a/parsing_c/.depend b/parsing_c/.depend index 70d620d..33810a6 100644 --- a/parsing_c/.depend +++ b/parsing_c/.depend @@ -1,15 +1,20 @@ 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 @@ -32,6 +37,10 @@ control_flow_c.cmo: ../commons/ograph_extended.cmi flag_parsing_c.cmo \ ../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 @@ -42,32 +51,38 @@ lib_parsing_c.cmo: visitor_c.cmi ../commons/common.cmi \ ../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 \ @@ -76,20 +91,30 @@ type_annoter_c.cmo: visitor_c.cmi parse_c.cmi lib_parsing_c.cmo \ 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 \ diff --git a/parsing_c/Makefile b/parsing_c/Makefile index c0d1df0..ea1b150 100644 --- a/parsing_c/Makefile +++ b/parsing_c/Makefile @@ -3,28 +3,37 @@ ############################################################################## 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 @@ -80,6 +89,33 @@ clean:: 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 ############################################################################## diff --git a/parsing_c/ast_c.ml b/parsing_c/ast_c.ml index 877cb51..5d74a7d 100644 --- a/parsing_c/ast_c.ml +++ b/parsing_c/ast_c.ml @@ -1,4 +1,4 @@ -(* 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) @@ -15,7 +15,44 @@ open Common (* 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). @@ -28,23 +65,19 @@ open Common * 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 @@ -61,8 +94,12 @@ type 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 @@ -95,7 +132,8 @@ and 'a wrap2 = 'a * il * Constructor. * * Some stuff are tagged semantic: which means that they are computed - * after parsing. *) + * after parsing. +*) and fullType = typeQualifier * typeC @@ -118,15 +156,21 @@ and typeCbis = | 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 @@ -149,11 +193,22 @@ and typeCbis = (* -------------------------------------- *) 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 @@ -182,16 +237,21 @@ and typeCbis = 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 @@ -228,12 +288,15 @@ and expressionbis = (* 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 @@ -247,15 +310,16 @@ and expressionbis = 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 @@ -274,6 +338,7 @@ and expressionbis = and constExpression = expression (* => int *) + (* ------------------------------------------------------------------------- *) (* C statement *) (* ------------------------------------------------------------------------- *) @@ -313,8 +378,20 @@ and statementbis = * 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 @@ -324,13 +401,14 @@ and statementbis = 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 @@ -354,7 +432,7 @@ and statementbis = * * 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. @@ -371,9 +449,13 @@ and declaration = | 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 @@ -403,52 +485,96 @@ and declaration = * 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 and last of #include - * - * The first_of and last_of store the list of prefixes that was - * introduced by the include. On #include , if the include was - * the first in the file, it would give in first_of the following - * prefixes a/b/c; a/b/; a/ ; - * - * This is set after parsing, in cocci.ml, in update_rel_pos. - *) + (* cocci: to tag the first of #include and last of #include + * + * The first_of and last_of store the list of prefixes that was + * introduced by the include. On #include , if the include was + * the first in the file, it would give in first_of the following + * prefixes a/b/c; a/b/; a/ ; + * + * 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 *) (* ------------------------------------------------------------------------- *) @@ -457,15 +583,15 @@ and toplevel = | 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 *) (* ------------------------------------------------------------------------- *) @@ -499,7 +625,8 @@ and metavars_binding = (Ast_cocci.meta_name, metavar_binding_kind) assoc * 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 @@ -507,8 +634,8 @@ and metavars_binding = (Ast_cocci.meta_name, metavar_binding_kind) assoc (* 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 *) @@ -537,7 +664,7 @@ and com = comment list ref (*****************************************************************************) -(* 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. @@ -545,7 +672,11 @@ and com = comment list ref * it also in lexer_parser. *) type cppcommentkind = - CppDirective | CppAttr | CppMacro | CppOther + | CppDirective + | CppAttr + | CppMacro + | CppPassingNormal (* ifdef 0, cplusplus, etc *) + | CppPassingCosWouldGetError (* expr passsing *) @@ -595,6 +726,9 @@ let fakeInfo pi = comments_tag = ref emptyComments; } +let noii = [] +let noattr = [] +let noi_content = (None: ((Common.filename * program) option)) (*****************************************************************************) (* Wrappers *) @@ -640,11 +774,6 @@ let get_opi = function | 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 @@ -678,7 +807,18 @@ let mcode_of_info ii = fst (!(ii.cocci_tag)) 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 @@ -713,6 +853,7 @@ let info_to_fixpos ii = 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 @@ -788,3 +929,46 @@ let split_register_param = fun (hasreg, idb, ii_b_s) -> | _, 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 + diff --git a/parsing_c/ast_to_flow.ml b/parsing_c/ast_to_flow.ml index 608d3f3..3a12704 100644 --- a/parsing_c/ast_to_flow.ml +++ b/parsing_c/ast_to_flow.ml @@ -26,6 +26,10 @@ open Oassocb * todo?: steal code from CIL ? (but seems complicated ... again) *) (*****************************************************************************) +(*****************************************************************************) +(* Types *) +(*****************************************************************************) + type error = | DeadCode of Common.parse_info option | CaseNoSwitch of Common.parse_info @@ -304,17 +308,7 @@ let rec (aux_statement: (nodei option * xinfo) -> statement -> nodei option) = !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 -> @@ -477,46 +471,6 @@ let rec (aux_statement: (nodei option * xinfo) -> statement -> nodei option) = 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 @@ -538,6 +492,7 @@ let rec (aux_statement: (nodei option * xinfo) -> statement -> nodei option) = 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, ...) @@ -945,7 +900,8 @@ let rec (aux_statement: (nodei option * xinfo) -> statement -> nodei option) = | 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 @@ -973,6 +929,61 @@ let rec (aux_statement: (nodei option * xinfo) -> statement -> nodei option) = + + + +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 *) (*****************************************************************************) @@ -981,7 +992,12 @@ let (aux_definition: nodei -> definition -> unit) = fun topi funcdef -> 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 -> @@ -993,8 +1009,15 @@ let (aux_definition: nodei -> definition -> unit) = fun topi funcdef -> 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 @@ -1048,21 +1071,23 @@ let ast_to_control_flow e = 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" @@ -1076,7 +1101,7 @@ let ast_to_control_flow e = !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); @@ -1116,7 +1141,7 @@ let ast_to_control_flow e = ) - | 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); @@ -1135,6 +1160,10 @@ let ast_to_control_flow e = | 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 diff --git a/parsing_c/compare_c.ml b/parsing_c/compare_c.ml index efea7d1..4070927 100644 --- a/parsing_c/compare_c.ml +++ b/parsing_c/compare_c.ml @@ -67,7 +67,7 @@ let normal_form_program xs = ); 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 @@ -175,8 +175,9 @@ let compare_ast filename1 filename2 = | 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 -> @@ -188,7 +189,13 @@ let compare_ast filename1 filename2 = | _, 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 -> diff --git a/parsing_c/control_flow_c.ml b/parsing_c/control_flow_c.ml index 7c6d07f..2b23662 100644 --- a/parsing_c/control_flow_c.ml +++ b/parsing_c/control_flow_c.ml @@ -70,6 +70,7 @@ open Ast_c (*****************************************************************************) +(* ---------------------------------------------------------------------- *) (* 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 @@ -85,6 +86,7 @@ type node = node1 * string } 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 @@ -101,10 +103,12 @@ type node = node1 * string | 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 { }. * @@ -183,6 +187,11 @@ type node = node1 * string | 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 @@ -190,8 +199,9 @@ type node = node1 * string | 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 @@ -212,8 +222,6 @@ type node = node1 * string | Asm of statement * asmbody wrap | MacroStmt of statement * unit wrap - | Ifdef of statement * unit wrap - (* ------------------------ *) (* some control nodes *) | Enter @@ -316,13 +324,15 @@ let extract_fullstatement node = | 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, _) diff --git a/parsing_c/control_flow_c.mli b/parsing_c/control_flow_c.mli index 0bd1ecf..3938bb4 100644 --- a/parsing_c/control_flow_c.mli +++ b/parsing_c/control_flow_c.mli @@ -12,7 +12,7 @@ type node = node1 * string (* For debugging. Used by print_graph *) | TopNode | EndNode - | FunHeader of (string * functionType * storage) wrap + | FunHeader of definition (* but empty body *) | Decl of declaration | SeqStart of statement * int * info @@ -37,6 +37,11 @@ type node = node1 * string (* For debugging. Used by print_graph *) | ReturnExpr of statement * expression wrap + (* ------------------------ *) + | IfdefHeader of ifdef_directive + | IfdefElse of ifdef_directive + | IfdefEndif of ifdef_directive + (* ------------------------ *) | DefineHeader of string wrap * define_kind @@ -44,7 +49,9 @@ type node = node1 * string (* For debugging. Used by print_graph *) | 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 @@ -64,8 +71,6 @@ type node = node1 * string (* For debugging. Used by print_graph *) | Asm of statement * asmbody wrap | MacroStmt of statement * unit wrap - | Ifdef of statement * unit wrap - (* ------------------------ *) | Enter diff --git a/parsing_c/copyright.txt b/parsing_c/copyright.txt index 6a6a6be..1931509 100644 --- a/parsing_c/copyright.txt +++ b/parsing_c/copyright.txt @@ -1,6 +1,6 @@ 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) @@ -10,9 +10,3 @@ Copyright (C) 2002-2008 Yoann Padioleau 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. - diff --git a/parsing_c/cpp_ast_c.ml b/parsing_c/cpp_ast_c.ml new file mode 100644 index 0000000..df0718b --- /dev/null +++ b/parsing_c/cpp_ast_c.ml @@ -0,0 +1,277 @@ +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 diff --git a/parsing_c/cpp_ast_c.mli b/parsing_c/cpp_ast_c.mli new file mode 100644 index 0000000..401fe1b --- /dev/null +++ b/parsing_c/cpp_ast_c.mli @@ -0,0 +1,14 @@ +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 + diff --git a/parsing_c/credits.txt b/parsing_c/credits.txt index 29a9218..6ee963d 100644 --- a/parsing_c/credits.txt +++ b/parsing_c/credits.txt @@ -3,7 +3,10 @@ indentation information for heuristic-based parsing. Thanks to Julia 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 ? diff --git a/parsing_c/flag_parsing_c.ml b/parsing_c/flag_parsing_c.ml index c1b1b54..049e3ff 100644 --- a/parsing_c/flag_parsing_c.ml +++ b/parsing_c/flag_parsing_c.ml @@ -1,15 +1,32 @@ (*****************************************************************************) (* 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, " (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), + " "; + "-I", Arg.String (fun s -> Common.push2 s cpp_i_opts), + " " ] (*****************************************************************************) @@ -21,8 +38,11 @@ let verbose_parsing = ref true 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 @@ -40,8 +60,12 @@ let cmdline_flags_verbose () = "-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," "; ] @@ -74,23 +98,41 @@ let cmdline_flags_debugging () = (* 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 *) diff --git a/parsing_c/lexer_c.mll b/parsing_c/lexer_c.mll index 12727e5..5dd00d7 100644 --- a/parsing_c/lexer_c.mll +++ b/parsing_c/lexer_c.mll @@ -1,5 +1,5 @@ { -(* 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) @@ -67,12 +67,16 @@ let tokinfo lexbuf = 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); @@ -121,16 +125,16 @@ let keyword_table = Common.hash_of_list [ "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); @@ -138,6 +142,14 @@ let keyword_table = Common.hash_of_list [ "__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); ] @@ -207,6 +219,7 @@ rule token = parse (* 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) } @@ -240,39 +253,27 @@ rule token = parse (* 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 *) @@ -283,90 +284,84 @@ rule token = parse *) | "#" [' ' '\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) @@ -391,49 +386,105 @@ rule token = parse *) - (* 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) + } @@ -511,19 +562,32 @@ rule token = parse 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 *) @@ -574,11 +638,11 @@ rule token = parse | ['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) } @@ -662,6 +726,8 @@ and string = parse 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. *) @@ -694,7 +760,7 @@ and comment = parse (* 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. *) diff --git a/parsing_c/lexer_parser.ml b/parsing_c/lexer_parser.ml index 1c6eee4..cf18a58 100644 --- a/parsing_c/lexer_parser.ml +++ b/parsing_c/lexer_parser.ml @@ -87,25 +87,42 @@ let restore_typedef_state () = +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 diff --git a/parsing_c/lexer_parser.mli b/parsing_c/lexer_parser.mli index 2f6287f..30d161f 100644 --- a/parsing_c/lexer_parser.mli +++ b/parsing_c/lexer_parser.mli @@ -27,13 +27,23 @@ val save_typedef_state : unit -> unit 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 diff --git a/parsing_c/lib_parsing_c.ml b/parsing_c/lib_parsing_c.ml index 6e3c26e..fd87d49 100644 --- a/parsing_c/lib_parsing_c.ml +++ b/parsing_c/lib_parsing_c.ml @@ -1,4 +1,4 @@ -(* 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) @@ -102,11 +102,14 @@ let ii_of_ini = extract_info_visitor Visitor_c.vk_ini 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" @@ -137,7 +140,7 @@ let lin_col_by_pos xs = 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)) diff --git a/parsing_c/parse_c.ml b/parsing_c/parse_c.ml index 6450692..00c62f7 100644 --- a/parsing_c/parse_c.ml +++ b/parsing_c/parse_c.ml @@ -1,4 +1,4 @@ -(* 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) @@ -15,12 +15,18 @@ open Common 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 *) @@ -41,14 +47,15 @@ let error_msg_tok tok = 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 @@ -76,106 +83,6 @@ let mk_info_item a b = -(*****************************************************************************) -(* 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 *) @@ -183,21 +90,50 @@ let print_parsing_stat_list = fun statxs -> 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 @@ -295,11 +231,15 @@ let tokens2 file = | 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 () = @@ -369,7 +309,7 @@ let parse_print_error file = *) 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 @@ -509,7 +449,11 @@ let consistency_checking2 xs = 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 @@ -613,7 +557,7 @@ and find_next_synchro_define next already_passed = 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) @@ -678,6 +622,20 @@ and find_next_synchro_orig next 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 as 2 or more tokens ? just + * lex #include ? so then need recognize 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 *) (* ------------------------------------------------------------------------- *) @@ -705,8 +663,13 @@ let rec comment_until_defeol xs = 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 = @@ -726,14 +689,28 @@ let tokens_include (info, includes, filename, inifdef) = ] (*****************************************************************************) -(* 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 *) @@ -744,6 +721,18 @@ type info_item = string * Parser_c.token list 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 @@ -756,7 +745,7 @@ type program2 = toplevel2 list * 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 @@ -779,6 +768,9 @@ type program2 = toplevel2 list * 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 = { @@ -789,9 +781,46 @@ 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 -> @@ -803,7 +832,7 @@ let rec lexer_function tr = fun lexbuf -> 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 @@ -811,16 +840,22 @@ let rec lexer_function tr = fun lexbuf -> 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; @@ -829,12 +864,14 @@ let rec lexer_function tr = fun lexbuf -> 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) = @@ -854,21 +891,26 @@ let rec lexer_function tr = fun lexbuf -> (* 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 @@ -877,29 +919,97 @@ let rec lexer_function tr = fun lexbuf -> +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); @@ -907,114 +1017,126 @@ let parse_print_error_heuristic2 file = 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 @@ -1025,14 +1147,19 @@ 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 = @@ -1047,14 +1174,27 @@ let parse_cache file = (*****************************************************************************) +(* 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 + ) diff --git a/parsing_c/parse_c.mli b/parsing_c/parse_c.mli index ef896b5..2287d7a 100644 --- a/parsing_c/parse_c.mli +++ b/parsing_c/parse_c.mli @@ -1,14 +1,3 @@ -(* 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 @@ -16,28 +5,29 @@ open Common * 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 @@ -45,26 +35,36 @@ 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 diff --git a/parsing_c/parser_c.mly b/parsing_c/parser_c.mly index 6153e26..a14d178 100644 --- a/parsing_c/parser_c.mly +++ b/parsing_c/parser_c.mly @@ -1,5 +1,5 @@ %{ -(* 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) @@ -19,6 +19,7 @@ open Lexer_parser (* for the fields *) open Semantic_c (* Semantic exn *) +module Stat = Parsing_stat (*****************************************************************************) (* Wrappers *) @@ -93,6 +94,7 @@ let addTypeD = function | ((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)) -> @@ -227,9 +229,12 @@ let fixFunc = function | (( (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 @@ -241,7 +246,12 @@ let fixFunc = function (* 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 @@ -264,7 +274,7 @@ let et s () = 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,_)))),_), _] -> () @@ -287,6 +297,8 @@ let mk_e e ii = ((e, Ast_c.noType()), ii) %} /*(*****************************************************************************)*/ +/*(* Tokens *)*/ +/*(*************************************************************************)*/ /* (* @@ -300,63 +312,26 @@ let mk_e e ii = ((e, Ast_c.noType()), ii) %token TUnknown /*(* unrecognized token *)*/ /*(* coupling: Token_helpers.is_real_comment *)*/ -%token TComment TCommentSpace TCommentNewline - -/*(* cppext: extra tokens *)*/ - -%token TDefine -%token <(string * Ast_c.info)> TDefParamVariadic -/*(* disappear after fix_tokens_define *)*/ -%token TCppEscapedNewline -/*(* appear after fix_tokens_define *)*/ -%token TOParDefine -%token <(string * Ast_c.info)> TIdentDefine /*(* same *)*/ -%token 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 TIfdef TIfdefelse TIfdefelif TEndif -%token <(bool * Ast_c.info)> TIfdefBool TIfdefMisc TIfdefVersion - - -%token TCommentMisc -%token <(Ast_c.cppcommentkind * Ast_c.info)> TCommentCpp - -/*(* appear after fix_tokens_cpp *)*/ - -%token TMacroStmt -/*(* no need value for the moment *)*/ -%token TMacroString -%token <(string * Ast_c.info)> TMacroDecl -%token TMacroDeclConst -%token <(string * Ast_c.info)> TMacroIterator -/*(* %token <(string * Ast_c.info)> TMacroTop *)*/ -/*(* appear after parsing_hack *)*/ -%token TCParEOL - -%token TAction - +%token TCommentSpace TCommentNewline TComment +/*(*-----------------------------------------*)*/ /*(* the normal tokens *)*/ +/*(*-----------------------------------------*)*/ %token 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 TIdent TypedefIdent +%token TIdent +/*(* appears mostly after some fix_xxx in parsing_hack *)*/ +%token 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. *) */ @@ -385,18 +360,115 @@ let mk_e e ii = ((e, Ast_c.noType()), ii) Tgoto Tdefault Tsizeof +/*(* C99 *)*/ +%token + Trestrict + +/*(*-----------------------------------------*)*/ /*(* gccext: extra tokens *)*/ +/*(*-----------------------------------------*)*/ %token Tasm %token Tattribute %token Tinline %token Ttypeof +/*(*-----------------------------------------*)*/ +/*(* cppext: extra tokens *)*/ +/*(*-----------------------------------------*)*/ +/*(* coupling with Token_helpers.is_cpp_token *)*/ + + +/*(*---------------*)*/ +/*(* define *)*/ +/*(*---------------*)*/ + +%token TDefine +%token <(string * Ast_c.info)> TDefParamVariadic + +/*(* disappear after fix_tokens_define *)*/ +%token TCppEscapedNewline + +/*(* appear after fix_tokens_define *)*/ +%token TOParDefine +%token TOBraceDefineInit + +%token <(string * Ast_c.info)> TIdentDefine /*(* same *)*/ +%token 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 TUndef + +%token 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 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 TCParEOL + +%token TAction + + +%token TCommentMisc +%token <(Ast_c.cppcommentkind * Ast_c.info)> TCommentCpp + +/*(*-----------------------------------------*)*/ %token EOF +/*(*-----------------------------------------*)*/ + +/*(* must be at the top so that it has the lowest priority *)*/ +%nonassoc SHIFTHERE -/* operator precedence */ -%nonassoc Tif %nonassoc Telse %left TOrLog @@ -410,6 +482,10 @@ let mk_e e ii = ((e, Ast_c.noType()), ii) %left TPlus TMinus %left TMul TDiv TMod +/*(*************************************************************************)*/ +/*(* Rules type declaration *)*/ +/*(*************************************************************************)*/ + %start main celem statement expr type_name %type main %type celem @@ -422,27 +498,57 @@ let mk_e e ii = ((e, Ast_c.noType()), ii) /*(*************************************************************************)*/ /* (* 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 *)*/ @@ -537,14 +643,15 @@ postfix_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 }) *)*/ @@ -552,16 +659,22 @@ primary_expr: +/*(*----------------------------*)*/ +/*(* 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: @@ -571,6 +684,7 @@ action_higherordermacro_ne: else ActMisc $1 } + action_higherordermacro: | taction_list { if null $1 @@ -583,17 +697,6 @@ action_higherordermacro: /*(* 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 } @@ -620,8 +723,7 @@ statement: | 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] } @@ -638,8 +740,10 @@ labeled: 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] } @@ -652,19 +756,6 @@ end_labeled: 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 @@ -678,19 +769,26 @@ compound2: | { ([]) } | 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 } @@ -701,7 +799,7 @@ expr_statement: | 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] } @@ -717,12 +815,12 @@ iteration: { 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] } @@ -746,7 +844,7 @@ jump: string_elem: | TString { [snd $1] } /*(* cppext: ex= printk (KERN_INFO "xxx" UTS_RELEASE) *)*/ - | TMacroString { [$1] } + | TMacroString { [snd $1] } asmbody: @@ -767,74 +865,14 @@ colon_option: 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]} @@ -866,73 +904,43 @@ type_spec2: | 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: @@ -953,12 +961,9 @@ pointer: | 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]))) } @@ -975,6 +980,43 @@ direct_d: { (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])) } @@ -987,7 +1029,7 @@ parameter_decl2: (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 ++ []) } @@ -1001,65 +1043,193 @@ parameter_decl2: /*(* 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: *)*/ @@ -1079,9 +1249,9 @@ initialize_list: 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 *)*/ @@ -1091,8 +1261,12 @@ initialize2: /*(* 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: @@ -1113,14 +1287,16 @@ gcc_comma_opt_struct: | /*(* 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] } @@ -1132,10 +1308,25 @@ s_or_u_spec2: 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 @@ -1144,13 +1335,12 @@ struct_decl2: 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 *) @@ -1158,9 +1348,10 @@ struct_decl2: 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] } + + @@ -1180,19 +1371,12 @@ struct_declarator: /*(*----------------------------*)*/ /*(* 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 } @@ -1208,11 +1392,13 @@ struct_decl_list_gcc: | /*(* 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] } @@ -1229,29 +1415,287 @@ enumerator: 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 } @@ -1269,7 +1713,6 @@ colon_option_list: | colon_option_list TComma colon_option { $1 ++ [$3, [$2]] } - argument_list_ne: | argument_ne { [$1, []] } | argument_list_ne TComma argument { $1 ++ [$3, [$2]] } @@ -1314,6 +1757,11 @@ taction_list_ne: | 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 } @@ -1326,12 +1774,29 @@ designator_list: | 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 { } @@ -1349,127 +1814,7 @@ opt_ptvirg: *)*/ -/*(*************************************************************************)*/ -/*(* 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 } diff --git a/parsing_c/parsing_hacks.ml b/parsing_c/parsing_hacks.ml index af59c37..fcca15a 100644 --- a/parsing_c/parsing_hacks.ml +++ b/parsing_c/parsing_hacks.ml @@ -1,4 +1,4 @@ -(* 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) @@ -15,13 +15,9 @@ open Common 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 *) @@ -36,15 +32,6 @@ let pr2_cpp s = 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 @@ -55,15 +42,16 @@ let msg_gen cond is_known printer s = 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" @@ -84,15 +72,29 @@ let msg_typedef s = | _ -> 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 @@ -121,25 +123,33 @@ let msg_declare_macro s = 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 @@ -155,6 +165,7 @@ let msg_macro_higher_order s = let msg_stringification s = + incr Stat.nMacroString; msg_gen (!Flag_parsing_c.debug_cpp) (fun s -> (match s with @@ -170,10 +181,51 @@ let msg_stringification s = (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 *) @@ -196,14 +248,72 @@ let regexp_foreach = Str.regexp_case_fold 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) @@ -389,7 +499,7 @@ let rec mk_ifdef xs = | 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 *) @@ -397,7 +507,7 @@ let rec mk_ifdef xs = 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 @@ -427,7 +537,7 @@ and mk_ifdef_parameters extras acc_before_sep 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 @@ -439,7 +549,7 @@ and mk_ifdef_parameters extras acc_before_sep xs = 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 @@ -669,6 +779,128 @@ let set_context_tag 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 *) (* ------------------------------------------------------------------------- *) @@ -678,10 +910,8 @@ let rec find_ifdef_bool xs = 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 @@ -690,14 +920,14 @@ let rec find_ifdef_bool xs = 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 @@ -708,26 +938,6 @@ let rec find_ifdef_bool xs = -(* 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 *) @@ -759,11 +969,12 @@ let rec find_ifdef_mid xs = ) *) 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 ); @@ -796,10 +1007,12 @@ let rec find_ifdef_funheaders = function 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 @@ -816,10 +1029,12 @@ let rec find_ifdef_funheaders = function ::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 @@ -832,11 +1047,13 @@ let rec find_ifdef_funheaders = function ::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; @@ -844,7 +1061,7 @@ let rec find_ifdef_funheaders = function - +(* ?? *) let rec adjust_inifdef_include xs = xs +> List.iter (function | NotIfdefLine _ -> () @@ -860,23 +1077,15 @@ let rec adjust_inifdef_include xs = (* ------------------------------------------------------------------------- *) -(* 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. *) @@ -885,62 +1094,109 @@ let rec apply_macro_defs xs = 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 @@ -968,16 +1224,16 @@ let rec find_string_macro_paren 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 @@ -1008,6 +1264,37 @@ let rec find_macro_paren xs = 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 @@ -1015,11 +1302,12 @@ let rec find_macro_paren xs = *) (* 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 @@ -1027,10 +1315,11 @@ let rec 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 @@ -1041,27 +1330,24 @@ let rec 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 *) @@ -1090,6 +1376,7 @@ let rec find_macro_lineparen xs = )) ::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); @@ -1110,6 +1397,7 @@ let rec find_macro_lineparen xs = )) ::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); @@ -1163,6 +1451,7 @@ let rec find_macro_lineparen xs = ) ::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); @@ -1233,6 +1522,7 @@ let rec find_macro_lineparen xs = 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 @@ -1293,7 +1583,7 @@ let rec find_macro_lineparen xs = 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; @@ -1339,7 +1629,7 @@ let rec find_macro_lineparen xs = 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) @@ -1347,6 +1637,76 @@ let rec find_macro_lineparen 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 *) (* ------------------------------------------------------------------------- *) @@ -1451,6 +1811,7 @@ let insert_virtual_positions l = | _ -> x::skip_fake xs in skip_fake l +(* ------------------------------------------------------------------------- *) let fix_tokens_cpp2 tokens = let tokens2 = ref (tokens +> acc_map mk_token_extended) in @@ -1472,6 +1833,8 @@ let fix_tokens_cpp2 tokens = 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; @@ -1503,6 +1866,7 @@ let fix_tokens_cpp2 tokens = 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; @@ -1517,8 +1881,11 @@ let fix_tokens_cpp2 tokens = 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) @@ -1618,7 +1985,7 @@ let rec define_ident acc xs = 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 -> @@ -1635,9 +2002,20 @@ let fix_tokens_define a = (*****************************************************************************) -(* 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 | [] -> [] @@ -1654,7 +2032,7 @@ let rec define_parse xs = ) 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 -> @@ -1662,10 +2040,11 @@ let rec define_parse 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 @@ -1693,54 +2072,8 @@ let extract_cpp_define 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 @@ -1752,8 +2085,14 @@ let ok_typedef s = not (List.mem s false_typedef) * *) +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 @@ -1800,7 +2139,7 @@ let lookahead2 next before = (* [,(] 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; @@ -1830,7 +2169,7 @@ let lookahead2 next before = (* 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 @@ -1840,7 +2179,7 @@ let lookahead2 next before = 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 *) @@ -1851,7 +2190,7 @@ let lookahead2 next before = (* xx * const *) - | (TIdent (s, i1)::TMul _::(Tconst _ | Tvolatile _)::_ , _ ) + | (TIdent (s, i1)::TMul _::(Tconst _ | Tvolatile _|Trestrict _)::_ , _ ) when not_struct_enum before && ok_typedef s -> @@ -1862,7 +2201,7 @@ let lookahead2 next before = (* ( 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) @@ -1870,7 +2209,7 @@ let lookahead2 next before = (* ( xx ) [sizeof, ~] *) - | (TIdent (s, i1)::TCPar _::(Tsizeof _|TTilde _)::_ , TOPar _::_ ) + | (TIdent (s, i1)::TCPar _::(Tsizeof _|TTilde _)::_ , TOPar _::_ ) when not_struct_enum before && ok_typedef s -> @@ -1879,7 +2218,7 @@ let lookahead2 next before = (* [(,] 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; @@ -1892,7 +2231,7 @@ let lookahead2 next before = (* 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; @@ -1903,7 +2242,7 @@ let lookahead2 next before = (* 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 -> @@ -1915,13 +2254,14 @@ let lookahead2 next before = | (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 -> @@ -1930,7 +2270,8 @@ let lookahead2 next before = (* 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; @@ -1940,7 +2281,7 @@ let lookahead2 next before = (* 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; @@ -1948,7 +2289,7 @@ let lookahead2 next before = (* 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; @@ -1980,7 +2321,7 @@ let lookahead2 next before = (* 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; @@ -1993,7 +2334,7 @@ let lookahead2 next before = && 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) @@ -2045,33 +2386,42 @@ let lookahead2 next before = (* ----------------------------------- *) + (* 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::_) @@ -2100,28 +2450,49 @@ let lookahead2 next before = (*-------------------------------------------------------------*) (* 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 *) @@ -2143,7 +2514,7 @@ let lookahead2 next before = | 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) diff --git a/parsing_c/parsing_hacks.mli b/parsing_c/parsing_hacks.mli index 3897a47..dbf050f 100644 --- a/parsing_c/parsing_hacks.mli +++ b/parsing_c/parsing_hacks.mli @@ -1,8 +1,8 @@ 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 @@ -32,18 +32,38 @@ open Common * 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 diff --git a/parsing_c/parsing_stat.ml b/parsing_c/parsing_stat.ml new file mode 100644 index 0000000..a5cb607 --- /dev/null +++ b/parsing_c/parsing_stat.ml @@ -0,0 +1,274 @@ +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); + ) diff --git a/parsing_c/pretty_print_c.ml b/parsing_c/pretty_print_c.ml index be1931b..0c8bef0 100644 --- a/parsing_c/pretty_print_c.ml +++ b/parsing_c/pretty_print_c.ml @@ -1,4 +1,4 @@ -(* 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) @@ -16,6 +16,8 @@ open Ast_c 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 @@ -30,7 +32,8 @@ type pr_space_func = unit -> unit 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 @@ -79,7 +82,7 @@ let rec pp_expression_gen pr_elem pr_space = | 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 -> @@ -109,6 +112,7 @@ let rec pp_expression_gen pr_elem pr_space = | ParenExpr (_) ),_ -> raise Impossible ); + if !Flag_parsing_c.pretty_print_type_info then begin pr_elem (Ast_c.fakeInfo() +> Ast_c.rewrap_str "/*"); @@ -156,7 +160,9 @@ and pp_statement_gen pr_elem pr_space = 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), [] -> () @@ -239,19 +245,6 @@ and pp_statement_gen pr_elem pr_space = | 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 _ @@ -261,13 +254,41 @@ and pp_statement_gen pr_elem pr_space = | 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) -> @@ -282,20 +303,33 @@ and pp_asmbody_gen pr_elem pr_space (string_list, colon_list) = 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: @@ -352,10 +386,10 @@ 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 @@ -372,7 +406,7 @@ and (pp_base_type_gen: | 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 ',' *) @@ -384,13 +418,13 @@ and (pp_base_type_gen: 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 @@ -403,26 +437,36 @@ and (pp_base_type_gen: | 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 @@ -503,8 +547,14 @@ and (pp_base_type_gen: | _ -> raise Impossible ) + | (Pointer _ | (*ParenType _ |*) Array _ | FunctionType _ + (* | StructUnion _ | Enum _ | BaseType _ *) + (* | StructUnionName _ | EnumName _ | TypeName _ *) + (* | TypeOfExpr _ | TypeOfType _ *) + ), _ -> raise Impossible + + - | x -> raise Impossible in pp_base_type @@ -513,10 +563,16 @@ and (pp_base_type_gen: 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 @@ -539,7 +595,7 @@ and (pp_type_with_ident_rest_gen: (* 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)) , @@ -572,7 +628,7 @@ and (pp_type_with_ident_rest_gen: | (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]) -> @@ -591,8 +647,10 @@ and (pp_type_with_ident_rest_gen: 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) = @@ -616,7 +674,12 @@ 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 @@ -630,10 +693,12 @@ and pp_param_gen pr_elem pr_space = fun ((b, sopt, t), ii_b_s) -> 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 @@ -673,16 +738,25 @@ and (pp_type_right_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_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; @@ -695,7 +769,7 @@ and pp_decl_gen pr_elem pr_space = function | 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 @@ -704,11 +778,16 @@ and pp_decl_gen pr_elem pr_space = function (* 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); @@ -732,7 +811,7 @@ and pp_decl_gen pr_elem pr_space = function pr_elem rp; pr_elem iiend; - | x -> raise Impossible + | (DeclList (_, _) | (MacroDecl _)) -> raise Impossible (* ---------------------- *) @@ -762,7 +841,10 @@ and pp_init_gen = fun pr_elem pr_space -> | 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 @@ -779,22 +861,40 @@ and pp_designator pr_elem pr_space design = | 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 @@ -849,33 +949,41 @@ and pp_def_gen pr_elem pr_space def = 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 @@ -883,6 +991,10 @@ let pp_program_gen pr_elem pr_space progelem = | 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 -> () @@ -899,6 +1011,21 @@ let pp_program_gen pr_elem pr_space progelem = 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; @@ -917,9 +1044,188 @@ let pp_program_gen pr_elem pr_space progelem = 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" + + + + + @@ -935,3 +1241,6 @@ let pr_space _ = Format.print_space() 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 + diff --git a/parsing_c/pretty_print_c.mli b/parsing_c/pretty_print_c.mli index 70091fa..c78de1a 100644 --- a/parsing_c/pretty_print_c.mli +++ b/parsing_c/pretty_print_c.mli @@ -13,7 +13,8 @@ val pp_type_gen : pr_elem_func -> pr_space_func -> Ast_c.fullType -> unit 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 @@ -21,3 +22,5 @@ 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 diff --git a/parsing_c/test_parsing_c.ml b/parsing_c/test_parsing_c.ml index d49f7b0..868c537 100644 --- a/parsing_c/test_parsing_c.ml +++ b/parsing_c/test_parsing_c.ml @@ -39,12 +39,12 @@ let test_parse_gen xs ext = 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)) @@ -62,15 +62,15 @@ let test_parse_gen xs 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 "--------------------------------"; @@ -106,7 +106,6 @@ let test_parse_ch xs = (* ---------------------------------------------------------------------- *) (* file can be "foo.c" or "foo.c:main" *) let test_cfg file = - let (file, specific_func) = if file =~ "\\(.*\\.c\\):\\(.*\\)" then @@ -125,8 +124,8 @@ let test_cfg file = 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 @@ -147,7 +146,8 @@ let test_cfg file = *) 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 ) @@ -155,23 +155,20 @@ let test_cfg file = - (* ---------------------------------------------------------------------- *) 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;*) -*) () @@ -194,11 +191,10 @@ let test_type_c infile = ) +> 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); ();; diff --git a/parsing_c/test_parsing_c.mli b/parsing_c/test_parsing_c.mli index 082c9cc..80f45f7 100644 --- a/parsing_c/test_parsing_c.mli +++ b/parsing_c/test_parsing_c.mli @@ -1,6 +1,7 @@ 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 diff --git a/parsing_c/token_helpers.ml b/parsing_c/token_helpers.ml index 14aed16..4fdf39c 100644 --- a/parsing_c/token_helpers.ml +++ b/parsing_c/token_helpers.ml @@ -8,33 +8,30 @@ open Parser_c 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 _ @@ -45,11 +42,25 @@ let is_not_comment x = 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 @@ -64,10 +75,24 @@ let is_cpar = function | 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 _ @@ -145,6 +170,9 @@ let info_of_tok = function | TDefine (ii) -> ii | TInclude (includes, filename, inifdef, i1) -> i1 + | TUndef (s, ii) -> ii + | TCppDirectiveOther (ii) -> ii + | TIncludeStart (i1, inifdef) -> i1 | TIncludeFilename (s, i1) -> i1 @@ -154,11 +182,16 @@ let info_of_tok = function | 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 *) @@ -172,13 +205,13 @@ let info_of_tok = function | 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 @@ -232,6 +265,9 @@ let info_of_tok = function | Tstatic (i) -> i | Tconst (i) -> i | Tvolatile (i) -> i + + | Trestrict (i) -> i + | Tstruct (i) -> i | Tenum (i) -> i | Ttypedef (i) -> i @@ -258,6 +294,7 @@ let info_of_tok = function + (* 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) @@ -271,6 +308,9 @@ let visitor_info_of_tok f = function | 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) @@ -284,14 +324,19 @@ let visitor_info_of_tok f = function | 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) @@ -303,13 +348,14 @@ let visitor_info_of_tok f = function | 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) @@ -362,6 +408,9 @@ let visitor_info_of_tok f = function | 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) diff --git a/parsing_c/token_helpers.mli b/parsing_c/token_helpers.mli index 8c48683..0d7cfd8 100644 --- a/parsing_c/token_helpers.mli +++ b/parsing_c/token_helpers.mli @@ -8,6 +8,8 @@ val is_fake_comment : Parser_c.token -> bool 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 @@ -16,6 +18,9 @@ val is_stuff_taking_parenthized : 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 diff --git a/parsing_c/type_annoter_c.ml b/parsing_c/type_annoter_c.ml index d35aeba..21547ff 100644 --- a/parsing_c/type_annoter_c.ml +++ b/parsing_c/type_annoter_c.ml @@ -1,4 +1,4 @@ -(* 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) @@ -246,7 +246,7 @@ let (type_field: 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 -> @@ -257,6 +257,9 @@ let (type_field: ) ) | EmptyField -> None + | MacroStructDeclTodo -> pr2 "DeclTodo"; None + | CppDirectiveStruct _ + | IfdefStruct _ -> pr2 "StructCpp"; None ) @@ -522,7 +525,9 @@ let rec (annotate_program2 : 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 @@ -566,7 +571,10 @@ let rec (annotate_program2 : _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 diff --git a/parsing_c/unparse_c2.ml b/parsing_c/unparse_c.ml similarity index 95% rename from parsing_c/unparse_c2.ml rename to parsing_c/unparse_c.ml index 7fb532e..806ad4f 100644 --- a/parsing_c/unparse_c2.ml +++ b/parsing_c/unparse_c.ml @@ -1,4 +1,4 @@ -(* 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) @@ -8,6 +8,9 @@ * 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 @@ -122,6 +125,7 @@ let rebuild_tokens_extented toks_ext = 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 @@ -214,6 +218,7 @@ let displace_fake_nodes toks = 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 = @@ -238,7 +243,8 @@ let displace_fake_nodes 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 @@ -304,28 +310,32 @@ let expand_mcode 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 @@ -343,6 +353,7 @@ let is_minusable_comment = function | 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, _) @@ -351,7 +362,7 @@ let is_minusable_comment = function | Parser_c.TCommentMisc _ | Parser_c.TCommentCpp (Ast_c.CppDirective, _) - | Parser_c.TCommentCpp (Ast_c.CppOther, _) + | Parser_c.TCommentCpp (Ast_c.CppPassingCosWouldGetError, _) -> false | _ -> false @@ -363,6 +374,7 @@ let all_coccis = function | _ -> 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 @@ -371,6 +383,7 @@ let set_minus_comment = function let str = TH.str_of_tok t in (match t with | Parser_c.TCommentSpace _ +(* patch: coccinelle *) | Parser_c.TCommentNewline _ -> () | Parser_c.TComment _ @@ -381,6 +394,7 @@ let set_minus_comment = function | _ -> raise Impossible ); T2 (t, true, idx) +(* patch: coccinelle *) | T2 (Parser_c.TCommentNewline _,true,idx) as x -> x | _ -> raise Impossible @@ -403,6 +417,7 @@ let remove_minus_and_between_and_expanded_and_fake xs = (*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 @@ -523,6 +538,7 @@ let rec adjust_indentation xs = [] -> () | ((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 @@ -533,6 +549,7 @@ let rec adjust_indentation xs = 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 *) @@ -758,3 +775,7 @@ let pp_program2 xs outfile = 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 diff --git a/parsing_c/unparse_c2.mli b/parsing_c/unparse_c.mli similarity index 75% rename from parsing_c/unparse_c2.mli rename to parsing_c/unparse_c.mli index b0bcd36..a51534f 100644 --- a/parsing_c/unparse_c2.mli +++ b/parsing_c/unparse_c.mli @@ -5,3 +5,5 @@ type ppmethod = PPnormal | PPviastr (* 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 diff --git a/parsing_c/unparse_cocci2.ml b/parsing_c/unparse_cocci.ml similarity index 100% rename from parsing_c/unparse_cocci2.ml rename to parsing_c/unparse_cocci.ml diff --git a/parsing_c/unparse_cocci2.mli b/parsing_c/unparse_cocci.mli similarity index 100% rename from parsing_c/unparse_cocci2.mli rename to parsing_c/unparse_cocci.mli diff --git a/parsing_c/unparse_hrule.ml b/parsing_c/unparse_hrule.ml index a2fcfb6..c7b29f8 100644 --- a/parsing_c/unparse_hrule.ml +++ b/parsing_c/unparse_hrule.ml @@ -82,7 +82,8 @@ let print_metavar pr typedefs = function 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"); @@ -114,7 +115,8 @@ let print_param_name pr = function ((_,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 @@ -129,12 +131,12 @@ let pp_def_gen pr (s, (_, (paramst, (b, iib))), _, _) isexp = 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 = diff --git a/parsing_c/visitor_c.ml b/parsing_c/visitor_c.ml index 32f85bc..27840f0 100644 --- a/parsing_c/visitor_c.ml +++ b/parsing_c/visitor_c.ml @@ -1,4 +1,4 @@ -(* 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) @@ -21,7 +21,8 @@ module F = Control_flow_c (* 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. * * * @@ -113,6 +114,8 @@ let test = * * 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 = { @@ -124,12 +127,16 @@ 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 = @@ -142,8 +149,15 @@ 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 @@ -156,10 +170,7 @@ let rec vk_expr = fun bigf expr -> | 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; @@ -184,7 +195,7 @@ let rec vk_expr = fun bigf expr -> *) | 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 @@ -201,19 +212,11 @@ let rec vk_expr = fun bigf expr -> 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 @@ -227,14 +230,12 @@ and vk_statement = fun bigf st -> 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)) -> @@ -247,10 +248,7 @@ and vk_statement = fun bigf 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) -> () @@ -265,21 +263,25 @@ and vk_statement = fun bigf st -> 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 @@ -302,11 +304,7 @@ and vk_type = fun bigf t -> (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) -> @@ -330,6 +328,16 @@ and vk_type = fun bigf t -> 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 @@ -339,15 +347,14 @@ and vk_decl = fun bigf d -> | 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) @@ -375,6 +382,7 @@ and vk_ini = fun bigf ini -> | InitIndexOld (e1, e) -> vk_expr bigf e1; inif e + in inif ini @@ -387,18 +395,32 @@ and vk_designator = fun bigf design -> | 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; @@ -410,6 +432,7 @@ and vk_struct_field = fun bigf onefield_multivars -> vk_type bigf t ) +(* ------------------------------------------------------------------------ *) and vk_def = fun bigf d -> @@ -418,15 +441,22 @@ 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 @@ -441,20 +471,49 @@ and vk_toplevel = fun bigf p -> | 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 @@ -467,17 +526,28 @@ and vk_define_kind bigf defkind = ) 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 + @@ -490,7 +560,7 @@ and vk_define_val 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. *) @@ -503,7 +573,16 @@ and vk_node = fun bigf node -> 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; @@ -531,10 +610,7 @@ and vk_node = fun bigf node -> 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 @@ -552,14 +628,20 @@ and vk_node = fun bigf node -> 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 @@ -567,9 +649,12 @@ and vk_node = fun bigf node -> | 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 @@ -601,12 +686,58 @@ and vk_ii = fun bigf ii -> 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 @@ -631,7 +762,7 @@ let vk_params_splitted = fun bigf args_splitted -> | Right ii -> iif ii ) - +(* ------------------------------------------------------------------------ *) let vk_cst = fun bigf (cst, ii) -> let iif ii = vk_ii bigf ii in iif ii; @@ -646,6 +777,9 @@ let vk_cst = fun bigf (cst, ii) -> (*****************************************************************************) (* "syntetisized attributes" style *) (*****************************************************************************) + +(* TODO port the xxs_s to new cpp construct too *) + type 'a inout = 'a -> 'a (* _s for synthetizized attributes @@ -657,16 +791,21 @@ type visitor_c_s = { 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; } @@ -681,6 +820,9 @@ let default_visitor_c_s = 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 -> @@ -721,7 +863,7 @@ 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 @@ -768,15 +910,11 @@ and vk_statement_s = fun bigf st -> 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)) -> @@ -817,6 +955,36 @@ and vk_statement_s = fun bigf 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 @@ -883,6 +1051,14 @@ and vk_type_s = fun bigf t -> 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 @@ -898,15 +1074,20 @@ and vk_decl_s = fun bigf d -> 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 @@ -932,6 +1113,7 @@ and vk_ini_s = fun bigf ini -> | 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 @@ -949,6 +1131,18 @@ and vk_designator_s = fun bigf design -> +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 @@ -956,18 +1150,20 @@ and vk_struct_fields_s = fun bigf fields -> 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 ) @@ -977,16 +1173,25 @@ and vk_def_s = fun bigf d -> 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 @@ -1007,15 +1212,50 @@ and vk_toplevel_s = fun bigf p -> ), 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 @@ -1035,12 +1275,19 @@ and vk_define_val_s = fun bigf x -> 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 @@ -1063,13 +1310,27 @@ and vk_node_s = fun bigf node -> 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) @@ -1115,9 +1376,21 @@ and vk_node_s = fun bigf node -> | 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, @@ -1140,6 +1413,10 @@ and vk_node_s = fun bigf node -> | 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| diff --git a/parsing_c/visitor_c.mli b/parsing_c/visitor_c.mli index 58f0523..197c1d1 100644 --- a/parsing_c/visitor_c.mli +++ b/parsing_c/visitor_c.mli @@ -7,10 +7,13 @@ type visitor_c = { 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 @@ -23,7 +26,8 @@ val vk_ini : visitor_c -> initialiser -> unit 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 @@ -32,8 +36,8 @@ val vk_param : visitor_c -> parameterType -> 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 @@ -48,13 +52,17 @@ type visitor_c_s = { 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; } @@ -63,6 +71,7 @@ val default_visitor_c_s : visitor_c_s 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 @@ -70,6 +79,7 @@ val vk_def_s : visitor_c_s -> definition -> definition 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 -> @@ -98,7 +108,6 @@ val vk_define_params_splitted_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 diff --git a/parsing_cocci/.#ast0_cocci.ml.1.107 b/parsing_cocci/.#ast0_cocci.ml.1.107 new file mode 100644 index 0000000..5d9f214 --- /dev/null +++ b/parsing_cocci/.#ast0_cocci.ml.1.107 @@ -0,0 +1,646 @@ +(* +* 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 . +* +* 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 *) diff --git a/parsing_cocci/.#context_neg.ml.1.97 b/parsing_cocci/.#context_neg.ml.1.97 new file mode 100644 index 0000000..abc2054 --- /dev/null +++ b/parsing_cocci/.#context_neg.ml.1.97 @@ -0,0 +1,1003 @@ +(* +* 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 . +* +* 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) diff --git a/parsing_cocci/.#iso_pattern.ml.1.138 b/parsing_cocci/.#iso_pattern.ml.1.138 new file mode 100644 index 0000000..f7975b8 --- /dev/null +++ b/parsing_cocci/.#iso_pattern.ml.1.138 @@ -0,0 +1,2311 @@ +(* +* 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 . +* +* 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 diff --git a/parsing_cocci/.#parser_cocci_menhir.mly.1.156 b/parsing_cocci/.#parser_cocci_menhir.mly.1.156 new file mode 100644 index 0000000..1e71638 --- /dev/null +++ b/parsing_cocci/.#parser_cocci_menhir.mly.1.156 @@ -0,0 +1,1769 @@ +/* +* 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 . +* +* 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 TRuleName + +%token Tchar Tshort Tint Tdouble Tfloat Tlong +%token Tvoid Tstruct Tunion +%token Tunsigned Tsigned + +%token Tstatic Tauto Tregister Textern Tinline Ttypedef +%token Tconst Tvolatile +%token Tattr + +%token TIf TElse TWhile TFor TDo TSwitch TCase TDefault TReturn +%token TBreak TContinue TGoto TSizeof TFunDecl +%token TIdent TTypeId TDeclarerId TIteratorId + +%token TMetaId TMetaFunc TMetaLocalFunc +%token TMetaIterator TMetaDeclarer +%token TMetaErr +%token TMetaParam TMetaStm TMetaStmList TMetaType +%token TMetaParamList TMetaExpList +%token TMetaExp TMetaIdExp TMetaLocalIdExp TMetaConst +%token TMetaPos + +%token TArob TArobArob TPArob +%token TScriptData + +%token TEllipsis TOEllipsis TCEllipsis TPOEllipsis TPCEllipsis +%token TWhen TWhenTrue TWhenFalse TAny TStrict TLineEnd + +%token TWhy TDotDot TBang TOPar TOPar0 +%token TMid0 TCPar TCPar0 + +%token TPragma TPathIsoFile +%token TIncludeL TIncludeNL +%token TDefine +%token TDefineParam +%token TMinusFile TPlusFile + +%token TInc TDec + +%token TString TChar TFloat TInt + +%token TOrLog +%token TAndLog +%token TOr +%token TXor +%token TAnd +%token TEqEq TNotEq +%token TLogOp /* TInf TSup TInfEq TSupEq */ +%token TShOp /* TShl TShr */ +%token TDmOp /* TDiv TMod */ +%token TPlus TMinus +%token TMul TTilde + +%token TOBrace TCBrace TOInit +%token TOCro TCCro + +%token TPtrOp + +%token TMPtVirg +%token TEq TDot TComma TPtVirg +%token 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 reinit + +%start minus_main +%type minus_main + +%start minus_exp_main +%type minus_exp_main + +%start plus_main +%type plus_main + +%start plus_exp_main +%type plus_exp_main + +%start include_main +%type <(string,string) Common.either list> include_main + +%start iso_rule_name +%type +iso_rule_name + +%start rule_name +%type +rule_name + +%start meta_main +%type <(Ast_cocci.metavar,Ast_cocci.metavar) Common.either list> meta_main + +%start script_meta_main + +%start iso_main +%type iso_main + +%start iso_meta_main +%type <(Ast_cocci.metavar,Ast_cocci.metavar) Common.either list> iso_meta_main + +%start never_used +%type 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)) } diff --git a/parsing_cocci/.#unitary_ast0.ml.1.29 b/parsing_cocci/.#unitary_ast0.ml.1.29 new file mode 100644 index 0000000..31ad2c0 --- /dev/null +++ b/parsing_cocci/.#unitary_ast0.ml.1.29 @@ -0,0 +1,288 @@ +(* +* 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 . +* +* 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) +*) diff --git a/parsing_cocci/.#unparse_ast0.ml.1.109 b/parsing_cocci/.#unparse_ast0.ml.1.109 new file mode 100644 index 0000000..7fb2c75 --- /dev/null +++ b/parsing_cocci/.#unparse_ast0.ml.1.109 @@ -0,0 +1,658 @@ +(* +* 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 . +* +* 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) diff --git a/parsing_cocci/.#visitor_ast0.ml.1.81 b/parsing_cocci/.#visitor_ast0.ml.1.81 new file mode 100644 index 0000000..2e258a9 --- /dev/null +++ b/parsing_cocci/.#visitor_ast0.ml.1.81 @@ -0,0 +1,1038 @@ +(* +* 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 . +* +* 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 diff --git a/parsing_cocci/ast0_cocci.ml b/parsing_cocci/ast0_cocci.ml index 5d9f214..02cb0f9 100644 --- a/parsing_cocci/ast0_cocci.ml +++ b/parsing_cocci/ast0_cocci.ml @@ -580,22 +580,24 @@ exception TyConv 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*)) diff --git a/parsing_cocci/context_neg.ml b/parsing_cocci/context_neg.ml index abc2054..86d6a8f 100644 --- a/parsing_cocci/context_neg.ml +++ b/parsing_cocci/context_neg.ml @@ -875,6 +875,12 @@ let rec is_ty s = | 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 @@ -920,17 +926,23 @@ let check_compatible m p = 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() diff --git a/parsing_cocci/iso_pattern.ml b/parsing_cocci/iso_pattern.ml index f7975b8..6b6875d 100644 --- a/parsing_cocci/iso_pattern.ml +++ b/parsing_cocci/iso_pattern.ml @@ -119,8 +119,9 @@ type reason = | 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(); @@ -155,6 +156,9 @@ let interpret_reason name line reason printer = | 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 @@ -342,14 +346,18 @@ let match_maker checks_needed context_required whencode_allowed = 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 @@ -522,34 +530,46 @@ let match_maker checks_needed context_required whencode_allowed = (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) @@ -1239,10 +1259,11 @@ let make_minus = 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)); @@ -1253,8 +1274,8 @@ let make_minus = | _ -> 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 @@ -2095,7 +2116,8 @@ let transform_expr (metavars,alts,name) 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 + (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 @@ -2194,7 +2216,8 @@ let transform_top (metavars,alts,name) e = (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 diff --git a/parsing_cocci/parser_cocci_menhir.ml b/parsing_cocci/parser_cocci_menhir.ml index e798752..2abc53a 100644 --- a/parsing_cocci/parser_cocci_menhir.ml +++ b/parsing_cocci/parser_cocci_menhir.ml @@ -1332,19 +1332,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 = [| @@ -1491,7 +1491,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -1519,7 +1519,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 = @@ -1549,7 +1549,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -1571,7 +1571,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -1593,7 +1593,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -1615,7 +1615,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -1637,7 +1637,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -1661,7 +1661,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -1701,7 +1701,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -1741,7 +1741,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -1781,7 +1781,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -1821,7 +1821,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -1861,7 +1861,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -1901,7 +1901,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -1941,7 +1941,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -1981,7 +1981,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2021,7 +2021,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2061,7 +2061,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2101,7 +2101,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2141,7 +2141,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2181,7 +2181,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2205,7 +2205,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2245,7 +2245,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2285,7 +2285,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2325,7 +2325,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2365,7 +2365,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2405,7 +2405,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2445,7 +2445,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2485,7 +2485,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2525,7 +2525,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2565,7 +2565,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2605,7 +2605,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2645,7 +2645,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2685,7 +2685,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2725,7 +2725,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2749,7 +2749,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2789,7 +2789,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2829,7 +2829,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2869,7 +2869,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2909,7 +2909,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2949,7 +2949,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -2989,7 +2989,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -3029,7 +3029,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -3069,7 +3069,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -3109,7 +3109,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -3149,7 +3149,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -3189,7 +3189,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -3229,7 +3229,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -3269,7 +3269,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -3293,7 +3293,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -3333,7 +3333,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -3373,7 +3373,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -3413,7 +3413,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -3453,7 +3453,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -3493,7 +3493,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -3533,7 +3533,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -3573,7 +3573,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -3613,7 +3613,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -3653,7 +3653,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -3693,7 +3693,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -3733,7 +3733,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -3773,7 +3773,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -3813,7 +3813,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -3964,7 +3964,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -4004,7 +4004,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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)) ) @@ -4046,7 +4046,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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)) ) @@ -4072,7 +4072,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -4112,7 +4112,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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)) ) @@ -4154,7 +4154,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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)) ) @@ -4180,7 +4180,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -4220,7 +4220,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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)) ) @@ -4262,7 +4262,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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)) ) @@ -4288,7 +4288,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -4328,7 +4328,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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)) ) @@ -4370,7 +4370,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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)) ) @@ -4396,7 +4396,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -4420,7 +4420,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -4444,7 +4444,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -4562,7 +4562,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -4612,7 +4612,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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" @@ -4637,7 +4637,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -4687,7 +4687,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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" @@ -4712,7 +4712,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -4762,7 +4762,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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" @@ -4787,7 +4787,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -4837,7 +4837,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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" @@ -4904,7 +4904,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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] ) @@ -4940,7 +4940,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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" @@ -4979,7 +4979,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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] ) @@ -5015,7 +5015,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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" @@ -5186,7 +5186,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -5210,7 +5210,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -5234,7 +5234,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -5258,7 +5258,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -5282,7 +5282,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -5306,7 +5306,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -5330,7 +5330,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -5354,7 +5354,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -5378,7 +5378,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -5402,7 +5402,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -5426,7 +5426,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -5450,7 +5450,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -5474,7 +5474,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -5530,7 +5530,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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" @@ -5555,7 +5555,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -5611,7 +5611,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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" @@ -5636,7 +5636,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -5692,7 +5692,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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" @@ -6340,7 +6340,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -6368,7 +6368,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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" @@ -6393,7 +6393,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -6421,7 +6421,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -6449,7 +6449,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -6489,7 +6489,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -6523,7 +6523,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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" @@ -6548,7 +6548,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -6588,7 +6588,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -6622,7 +6622,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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" @@ -8991,7 +8991,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -9037,7 +9037,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -9065,7 +9065,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -9111,7 +9111,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -9139,7 +9139,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -9185,7 +9185,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -9233,7 +9233,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 = @@ -9266,7 +9266,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -9283,7 +9283,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -9307,7 +9307,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -9347,7 +9347,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -9391,7 +9391,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -9526,7 +9526,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -9978,7 +9978,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -10006,7 +10006,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -10036,7 +10036,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -10066,7 +10066,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -10083,7 +10083,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -10111,7 +10111,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -10141,7 +10141,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -10171,7 +10171,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -10201,7 +10201,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -10218,7 +10218,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -10248,7 +10248,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -10265,7 +10265,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -10295,7 +10295,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -10325,7 +10325,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -10349,7 +10349,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -10373,7 +10373,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -10401,7 +10401,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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" @@ -10430,7 +10430,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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" @@ -10459,7 +10459,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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)) ) @@ -11625,7 +11625,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -11653,7 +11653,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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" @@ -11678,7 +11678,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -11706,7 +11706,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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" @@ -12646,7 +12646,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -12674,7 +12674,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -12702,7 +12702,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -12730,7 +12730,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -12758,7 +12758,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -12786,7 +12786,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -12814,7 +12814,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -12842,7 +12842,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -12870,7 +12870,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -12898,7 +12898,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -12940,7 +12940,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (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 @@ -12982,7 +12982,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (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 @@ -13024,7 +13024,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (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 @@ -13066,7 +13066,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (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 @@ -13108,7 +13108,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (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 @@ -13150,7 +13150,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (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 @@ -13192,7 +13192,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (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 | _ -> @@ -13293,7 +13293,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -13321,7 +13321,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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" @@ -14793,7 +14793,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -16517,7 +16517,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -16547,7 +16547,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -16577,7 +16577,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -16607,7 +16607,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -16637,7 +16637,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -16667,7 +16667,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -16697,7 +16697,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -16989,7 +16989,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -17013,7 +17013,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -17037,7 +17037,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -17061,7 +17061,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -17095,7 +17095,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -17129,7 +17129,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -17163,7 +17163,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -17197,7 +17197,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -17231,7 +17231,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -17265,7 +17265,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -17428,7 +17428,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -17456,7 +17456,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -17486,7 +17486,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -17503,7 +17503,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -17533,7 +17533,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -17550,7 +17550,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -17580,7 +17580,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -17610,7 +17610,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -17632,39 +17632,33 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -17684,39 +17678,33 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -17738,9 +17726,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -17762,11 +17750,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -17792,11 +17780,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -17818,11 +17806,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -17850,10 +17838,10 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -17874,14 +17862,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -17908,14 +17896,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -17941,11 +17929,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -17979,11 +17967,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -18009,11 +17997,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -18047,11 +18035,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -18077,11 +18065,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -18115,14 +18103,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -18148,7 +18136,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -18157,7 +18145,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -18191,7 +18179,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -18203,7 +18191,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -18225,9 +18213,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -18248,12 +18236,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 = @@ -18261,7 +18249,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -18283,9 +18271,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -18306,12 +18294,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 = @@ -18319,7 +18307,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -18345,7 +18333,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -18353,7 +18341,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -18384,7 +18372,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -18394,14 +18382,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 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; @@ -18437,7 +18425,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -18449,14 +18437,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 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; @@ -18480,7 +18468,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -18521,13 +18509,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -18537,14 +18525,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 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; @@ -18590,13 +18578,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -18608,14 +18596,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 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; @@ -18646,7 +18634,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -18656,14 +18644,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 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 @@ -18671,7 +18659,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( 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; @@ -18707,7 +18695,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -18719,14 +18707,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 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 @@ -18734,7 +18722,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( 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; @@ -18770,7 +18758,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -18781,7 +18769,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 18785 "parser_cocci_menhir.ml" +# 18773 "parser_cocci_menhir.ml" in let s = @@ -18789,7 +18777,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 18793 "parser_cocci_menhir.ml" +# 18781 "parser_cocci_menhir.ml" in @@ -18797,7 +18785,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( 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; @@ -18838,7 +18826,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -18851,7 +18839,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 18855 "parser_cocci_menhir.ml" +# 18843 "parser_cocci_menhir.ml" in let s = @@ -18859,7 +18847,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 18863 "parser_cocci_menhir.ml" +# 18851 "parser_cocci_menhir.ml" in @@ -18867,7 +18855,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( 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; @@ -18908,13 +18896,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -18924,14 +18912,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 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 @@ -18941,7 +18929,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -18987,13 +18975,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -19005,14 +18993,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 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 @@ -19022,7 +19010,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -19068,13 +19056,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -19085,7 +19073,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 19089 "parser_cocci_menhir.ml" +# 19077 "parser_cocci_menhir.ml" in let s = @@ -19093,7 +19081,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 19097 "parser_cocci_menhir.ml" +# 19085 "parser_cocci_menhir.ml" in @@ -19103,7 +19091,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -19154,13 +19142,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -19173,7 +19161,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 19177 "parser_cocci_menhir.ml" +# 19165 "parser_cocci_menhir.ml" in let s = @@ -19181,7 +19169,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 19185 "parser_cocci_menhir.ml" +# 19173 "parser_cocci_menhir.ml" in @@ -19191,7 +19179,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -19252,34 +19240,34 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -19288,7 +19276,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 19292 "parser_cocci_menhir.ml" +# 19280 "parser_cocci_menhir.ml" in @@ -19300,7 +19288,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (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; @@ -19366,34 +19354,34 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -19404,7 +19392,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 19408 "parser_cocci_menhir.ml" +# 19396 "parser_cocci_menhir.ml" in @@ -19416,7 +19404,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (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; @@ -19457,18 +19445,18 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -19477,7 +19465,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 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; @@ -19548,40 +19536,40 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -19590,7 +19578,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 19594 "parser_cocci_menhir.ml" +# 19582 "parser_cocci_menhir.ml" in @@ -19602,7 +19590,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (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; @@ -19678,40 +19666,40 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -19722,7 +19710,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 19726 "parser_cocci_menhir.ml" +# 19714 "parser_cocci_menhir.ml" in @@ -19734,7 +19722,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (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; @@ -19751,7 +19739,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -19775,7 +19763,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -19792,7 +19780,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -19816,7 +19804,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -19833,7 +19821,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -19857,48 +19845,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -19913,9 +19860,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -19941,9 +19888,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -19971,9 +19918,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20001,9 +19948,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20031,9 +19978,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20048,9 +19995,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20078,9 +20025,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20095,9 +20042,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20125,9 +20072,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20155,9 +20102,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20185,9 +20132,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20223,7 +20170,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20259,7 +20206,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20287,11 +20234,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20319,11 +20266,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20351,11 +20298,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20383,11 +20330,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20415,11 +20362,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20447,11 +20394,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20473,9 +20420,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20497,9 +20444,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20527,9 +20474,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20557,9 +20504,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20587,9 +20534,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20617,9 +20564,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20640,14 +20587,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20672,14 +20619,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20704,14 +20651,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20736,14 +20683,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20775,7 +20722,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20797,9 +20744,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20835,22 +20782,22 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20882,15 +20829,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20922,16 +20869,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20957,15 +20904,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -20991,15 +20938,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21035,23 +20982,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21073,9 +21020,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21111,22 +21058,22 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21158,15 +21105,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21198,16 +21145,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21233,15 +21180,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21267,15 +21214,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21311,23 +21258,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21349,9 +21296,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21387,22 +21334,22 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21434,15 +21381,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21474,16 +21421,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21509,15 +21456,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21543,15 +21490,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21587,23 +21534,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21625,9 +21572,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21663,22 +21610,22 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21710,15 +21657,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21750,16 +21697,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21785,15 +21732,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21819,15 +21766,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21863,23 +21810,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21901,9 +21848,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21924,15 +21871,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21953,15 +21900,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -21982,15 +21929,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22011,15 +21958,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22040,16 +21987,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22070,15 +22017,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22099,16 +22046,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22129,16 +22076,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22159,16 +22106,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22199,21 +22146,21 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22244,23 +22191,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22282,9 +22229,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22306,9 +22253,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22329,15 +22276,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22358,15 +22305,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22387,15 +22334,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22416,15 +22363,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22445,16 +22392,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22475,15 +22422,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22504,16 +22451,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22534,16 +22481,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22564,16 +22511,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22604,21 +22551,21 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22649,23 +22596,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22687,9 +22634,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22711,9 +22658,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22734,15 +22681,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22763,15 +22710,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22792,15 +22739,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22821,15 +22768,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22850,16 +22797,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22880,15 +22827,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22909,16 +22856,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22939,16 +22886,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -22969,16 +22916,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23009,21 +22956,21 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23054,23 +23001,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23092,9 +23039,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23116,9 +23063,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23139,15 +23086,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23168,15 +23115,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23197,15 +23144,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23226,15 +23173,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23255,16 +23202,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23285,15 +23232,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23314,16 +23261,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23344,16 +23291,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23374,16 +23321,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23414,21 +23361,21 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23459,23 +23406,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23497,9 +23444,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23521,7 +23468,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23543,7 +23490,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23569,7 +23516,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23595,7 +23542,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23612,7 +23559,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23633,14 +23580,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23662,9 +23609,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23686,9 +23633,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23708,9 +23655,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23730,9 +23677,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23752,9 +23699,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23782,9 +23729,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23812,9 +23759,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23842,9 +23789,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23872,9 +23819,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23891,11 +23838,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23919,7 +23866,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23945,7 +23892,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -23953,7 +23900,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -23984,20 +23931,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24023,19 +23970,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24061,19 +24008,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24099,19 +24046,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24142,13 +24089,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -24159,7 +24106,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (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; @@ -24215,18 +24162,18 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24288,19 +24235,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24342,11 +24289,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24390,7 +24337,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -24398,11 +24345,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24423,14 +24370,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24461,14 +24408,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24492,7 +24439,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24526,7 +24473,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24550,7 +24497,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24584,7 +24531,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24608,7 +24555,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24642,7 +24589,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24666,7 +24613,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24700,7 +24647,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24724,7 +24671,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24758,7 +24705,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24782,7 +24729,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24816,7 +24763,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24840,7 +24787,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24874,7 +24821,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24898,7 +24845,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24932,7 +24879,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24956,7 +24903,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -24990,7 +24937,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -25014,7 +24961,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -25048,7 +24995,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -25072,7 +25019,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -25106,7 +25053,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -25130,7 +25077,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -25164,7 +25111,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -25188,7 +25135,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -25219,13 +25166,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -25236,7 +25183,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (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; @@ -25260,7 +25207,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -25281,14 +25228,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -25314,7 +25261,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -25322,7 +25269,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -25364,25 +25311,25 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -25434,31 +25381,31 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -25520,37 +25467,37 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -25592,25 +25539,25 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -25661,36 +25608,36 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -25732,13 +25679,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -25746,7 +25693,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -25797,36 +25744,36 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -25857,20 +25804,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -25896,19 +25843,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -25934,19 +25881,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -25972,19 +25919,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -26010,7 +25957,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -26018,7 +25965,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -26049,20 +25996,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -26093,20 +26040,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -26133,14 +26080,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -26176,14 +26123,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -26191,7 +26138,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 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; @@ -26227,14 +26174,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -26242,7 +26189,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 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; @@ -26263,14 +26210,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -26291,14 +26238,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -26319,14 +26266,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -26347,14 +26294,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -26376,7 +26323,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -26407,7 +26354,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -26417,7 +26364,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 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; @@ -26478,34 +26425,34 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -26519,7 +26466,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (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; @@ -26550,7 +26497,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -26560,7 +26507,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 26564 "parser_cocci_menhir.ml" +# 26511 "parser_cocci_menhir.ml" in @@ -26568,7 +26515,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( 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; @@ -26604,7 +26551,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 @@ -26616,7 +26563,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 26620 "parser_cocci_menhir.ml" +# 26567 "parser_cocci_menhir.ml" in @@ -26624,7 +26571,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( 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; @@ -26648,7 +26595,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -26672,7 +26619,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -26702,7 +26649,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -26732,7 +26679,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -26753,14 +26700,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -26781,14 +26728,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -26812,7 +26759,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -26843,20 +26790,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -26871,9 +26818,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -26899,9 +26846,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -26929,9 +26876,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -26959,9 +26906,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -26987,9 +26934,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27017,9 +26964,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27047,9 +26994,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27064,9 +27011,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27094,9 +27041,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27111,9 +27058,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27141,9 +27088,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27171,9 +27118,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27201,9 +27148,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27231,9 +27178,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27261,9 +27208,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27291,9 +27238,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27321,9 +27268,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27351,9 +27298,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27375,9 +27322,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27398,15 +27345,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27428,9 +27375,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27457,14 +27404,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27491,14 +27438,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27526,9 +27473,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27555,15 +27502,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27590,14 +27537,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27633,27 +27580,27 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27675,9 +27622,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27704,14 +27651,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27738,14 +27685,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27773,9 +27720,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27802,15 +27749,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27837,14 +27784,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27880,27 +27827,27 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27922,9 +27869,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27951,14 +27898,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -27985,14 +27932,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28020,9 +27967,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28049,15 +27996,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28084,14 +28031,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28127,27 +28074,27 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28169,9 +28116,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28198,14 +28145,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28232,14 +28179,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28267,9 +28214,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28296,15 +28243,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28331,14 +28278,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28374,27 +28321,27 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28415,14 +28362,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28443,14 +28390,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28471,14 +28418,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28499,14 +28446,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28527,14 +28474,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28562,9 +28509,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28592,45 +28539,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28654,7 +28565,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28688,9 +28599,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28724,9 +28635,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28756,9 +28667,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28792,9 +28703,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28828,9 +28739,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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; @@ -28851,90 +28762,90 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 = @@ -28942,7 +28853,7 @@ 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 = @@ -28950,7 +28861,7 @@ 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" )) diff --git a/parsing_cocci/parser_cocci_menhir.mly b/parsing_cocci/parser_cocci_menhir.mly index 1e71638..76942f4 100644 --- a/parsing_cocci/parser_cocci_menhir.mly +++ b/parsing_cocci/parser_cocci_menhir.mly @@ -1143,17 +1143,18 @@ dot_expressions: 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 } diff --git a/parsing_cocci/unitary_ast0.ml b/parsing_cocci/unitary_ast0.ml index 31ad2c0..a557b0e 100644 --- a/parsing_cocci/unitary_ast0.ml +++ b/parsing_cocci/unitary_ast0.ml @@ -155,11 +155,11 @@ let update_unitary unitary = 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 diff --git a/parsing_cocci/unparse_ast0.ml b/parsing_cocci/unparse_ast0.ml index 7fb2c75..c77a39b 100644 --- a/parsing_cocci/unparse_ast0.ml +++ b/parsing_cocci/unparse_ast0.ml @@ -197,8 +197,14 @@ let rec expression e = 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,_,_) -> diff --git a/popl09/.#Makefile.1.3 b/popl09/.#Makefile.1.3 new file mode 100644 index 0000000..96ec617 --- /dev/null +++ b/popl09/.#Makefile.1.3 @@ -0,0 +1,101 @@ +# 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 . +# +# 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 diff --git a/popl09/Makefile b/popl09/Makefile index 96ec617..36a6c27 100644 --- a/popl09/Makefile +++ b/popl09/Makefile @@ -29,7 +29,7 @@ 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 + -I ../ctl -I ../parsing_cocci -I ../parsing_c -I ../engine #The Caml compilers. #for warning: -w A diff --git a/pycaml/pycaml.ml b/pycaml/pycaml.ml index 5d5ff99..1db1ae1 100644 --- a/pycaml/pycaml.ml +++ b/pycaml/pycaml.ml @@ -523,6 +523,8 @@ external pytuple4 : (pyobject * pyobject * pyobject * pyobject) -> 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) diff --git a/python/.#yes_pycocci.ml.1.1 b/python/.#yes_pycocci.ml.1.1 new file mode 100644 index 0000000..c252439 --- /dev/null +++ b/python/.#yes_pycocci.ml.1.1 @@ -0,0 +1,241 @@ +(* +* 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 . +* +* 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 () diff --git a/python/coccilib/elems.py b/python/coccilib/elems.py index 325c8b0..0e794c9 100644 --- a/python/coccilib/elems.py +++ b/python/coccilib/elems.py @@ -1,6 +1,7 @@ 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 diff --git a/python/yes_pycocci.ml b/python/yes_pycocci.ml index c252439..a0a6a22 100644 --- a/python/yes_pycocci.ml +++ b/python/yes_pycocci.ml @@ -208,9 +208,11 @@ let construct_variables mv e = 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), diff --git a/standard.iso b/standard.iso index a2e4503..d029e9b 100644 --- a/standard.iso +++ b/standard.iso @@ -631,6 +631,14 @@ T E; sizeof(T) => sizeof(E) +// Expression +// @ fld_func_call @ +// expression list ES; +// identifier fld; +// expression E; +// @@ +// E.fld(ES) <=> (*E.fld)(ES) + // **************************************************************************** // Linux specific isomorphisms diff --git a/testing.ml b/testing.ml index 57518d9..a2a3d29 100644 --- a/testing.ml +++ b/testing.ml @@ -400,22 +400,6 @@ let test_parse_cocci file = 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 *) (* diff --git a/tests/error.c b/tests/error.c new file mode 100644 index 0000000..1e46dbb --- /dev/null +++ b/tests/error.c @@ -0,0 +1,11 @@ +// 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; +} diff --git a/tests/sys.cocci b/tests/sys.cocci new file mode 100644 index 0000000..c01ef25 --- /dev/null +++ b/tests/sys.cocci @@ -0,0 +1,14 @@ +@r@ +struct sys_timer E; +expression E2; +@@ + +* E.suspend = E2; + +@s@ +struct sys_timer E; +expression E2; +@@ + +E.suspend = E2; + diff --git a/tests/sys.iso b/tests/sys.iso new file mode 100644 index 0000000..7b33eb4 --- /dev/null +++ b/tests/sys.iso @@ -0,0 +1,10 @@ +TopLevel +@ mkinit @ +type T; +pure context T E; +identifier I; +identifier fld; +expression E1; +@@ + +E.fld = E1; => T I = { .fld = E1, }; diff --git a/tests/testprint.c b/tests/testprint.c new file mode 100644 index 0000000..bb15614 --- /dev/null +++ b/tests/testprint.c @@ -0,0 +1,16 @@ +void main(int foo) { + + f(1); + x(); + g(2); + x(); + if(1) { + // h(3); + h(3); + } else { + h(4); + } + + +} + diff --git a/tests/testprint.cocci b/tests/testprint.cocci new file mode 100644 index 0000000..ed1846f --- /dev/null +++ b/tests/testprint.cocci @@ -0,0 +1,9 @@ +@ rule1 @ +expression X,Y,Z; +@@ + f(X); + ... when any, strict + g(Z); + ... when any, strict +- h(Y); ++ h(X,Y,Z); diff --git a/tests/warnon.cocci b/tests/warnon.cocci new file mode 100644 index 0000000..c0fca69 --- /dev/null +++ b/tests/warnon.cocci @@ -0,0 +1,6 @@ +@@ +//identifier f; +expression E; +@@ + +* WARN_ON(E && !irqs_disabled()) diff --git a/tools/Makefile b/tools/Makefile index 227e415..615238d 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,4 +1,4 @@ -PROGS=gitgrep split_patch extract_c_and_res meta_files generate_dependencies +PROGS=gitgrep split_patch extract_c_and_res #generate_dependencies all: $(PROGS) @@ -29,7 +29,7 @@ SYSLIBS = str.cma unix.cma 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) @@ -45,9 +45,6 @@ split_patch: split_patch.cmo 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) $+ diff --git a/tools/distributed/spatch_linux_script b/tools/distributed/spatch_linux_script index aea394c..7124cd4 100755 --- a/tools/distributed/spatch_linux_script +++ b/tools/distributed/spatch_linux_script @@ -6,6 +6,6 @@ setenv COCCINELLE_HOME ${HOME}/coccinelle # -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 diff --git a/tools/extract_c_and_res.ml b/tools/extract_c_and_res.ml index 41f7712..1eb3804 100644 --- a/tools/extract_c_and_res.ml +++ b/tools/extract_c_and_res.ml @@ -1,4 +1,4 @@ -open Common open Commonop +open Common (*****************************************************************************) (* *) diff --git a/tools/generate_dependencies.ml b/tools/generate_dependencies.ml index 7dd22de..4cf056c 100644 --- a/tools/generate_dependencies.ml +++ b/tools/generate_dependencies.ml @@ -1,4 +1,4 @@ -open Common open Commonop +open Common (*****************************************************************************) (* Flags *) diff --git a/tools/split_patch.ml b/tools/split_patch.ml index f77e026..059ba55 100644 --- a/tools/split_patch.ml +++ b/tools/split_patch.ml @@ -1,4 +1,4 @@ -open Common open Commonop +open Common module CP = Classic_patch -- 2.20.1