From 1be43e1299fc61538d62349ca012514b28f8734f Mon Sep 17 00:00:00 2001 From: Coccinelle Date: Sun, 3 Oct 2010 13:56:01 +0200 Subject: [PATCH] Release coccinelle-0.1.1 ** Language: - support for initializer at toplevel, cf -test substruct --- .cvsignore | 3 + .project | 17 + Makefile | 15 +- changes.txt | 4 + cocci.ml | 170 +- commitmsg | 8 +- commons/.cvsignore | 2 + ctl/.cvsignore | 2 + emacs/cocci.el | 3 + engine/.#asttoctl2.ml.1.138 | 2222 ++++++++++ engine/.#asttoctl2.ml.1.141 | 2295 ++++++++++ engine/.#check_exhaustive_pattern.ml.1.39 | 183 + engine/.#cocci_vs_c_3.ml.1.154 | 3419 +++++++++++++++ engine/.#ctlcocci_integration.ml.1.111 | 422 ++ engine/.#pattern3.ml.1.56 | 467 ++ engine/.#pattern3.ml.1.57 | 476 +++ engine/.#transformation3.ml.1.47 | 526 +++ engine/.#transformation3.ml.1.48 | 528 +++ engine/.cvsignore | 2 + engine/asttoctl2.ml | 127 +- engine/check_exhaustive_pattern.ml | 1 + engine/cocci_vs_c_3.ml | 13 +- engine/cocci_vs_c_3.mli | 4 + engine/ctlcocci_integration.ml | 5 +- engine/ctlcocci_integration.mli | 3 +- engine/pattern3.ml | 80 +- engine/transformation3.ml | 24 +- engine/transformation3.mli | 1 + extra/.cvsignore | 2 + extra/Makefile | 2 +- extra/c_info.ml | 525 --- extra/c_info.mli | 53 - flag_cocci.ml | 1 + globals/.cvsignore | 2 + globals/config.ml | 2 +- main.ml | 6 +- menhirlib/.cvsignore | 2 + parsing_c/.cvsignore | 6 + parsing_c/unparse_cocci2.ml | 1 + parsing_cocci/.#arity.ml.1.81 | 1054 +++++ parsing_cocci/.#arity.ml.1.82 | 1060 +++++ parsing_cocci/.#ast0_cocci.ml.1.105 | 641 +++ parsing_cocci/.#ast0_cocci.ml.1.106 | 645 +++ parsing_cocci/.#ast0toast.ml.1.132 | 916 ++++ parsing_cocci/.#ast0toast.ml.1.133 | 927 ++++ parsing_cocci/.#ast_cocci.ml.1.142 | 668 +++ parsing_cocci/.#ast_cocci.ml.1.143 | 672 +++ parsing_cocci/.#check_meta.ml.1.79 | 528 +++ parsing_cocci/.#check_meta.ml.1.80 | 532 +++ parsing_cocci/.#compute_lines.ml.1.85 | 760 ++++ parsing_cocci/.#context_neg.ml.1.95 | 992 +++++ parsing_cocci/.#context_neg.ml.1.96 | 1002 +++++ parsing_cocci/.#disjdistr.ml.1.20 | 393 ++ parsing_cocci/.#index.ml.1.54 | 220 + parsing_cocci/.#insert_plus.ml.1.68 | 941 ++++ parsing_cocci/.#insert_plus.ml.1.69 | 946 ++++ parsing_cocci/.#iso_pattern.ml.1.136 | 2306 ++++++++++ parsing_cocci/.#iso_pattern.ml.1.137 | 2310 ++++++++++ parsing_cocci/.#lexer_cocci.mll.1.80 | 700 +++ parsing_cocci/.#parse_aux.ml.1.23 | 467 ++ parsing_cocci/.#parse_cocci.ml.1.162 | 1512 +++++++ parsing_cocci/.#parse_cocci.ml.1.163 | 1530 +++++++ parsing_cocci/.#parser_cocci_menhir.mly.1.153 | 1765 ++++++++ parsing_cocci/.#parser_cocci_menhir.mly.1.155 | 1763 ++++++++ parsing_cocci/.#pretty_print_cocci.ml.1.127 | 855 ++++ parsing_cocci/.#pretty_print_cocci.ml.1.128 | 859 ++++ parsing_cocci/.#single_statement.ml.1.51 | 596 +++ parsing_cocci/.#test_exps.ml.1.3 | 89 + parsing_cocci/.#type_infer.ml.1.54 | 356 ++ parsing_cocci/.#unify_ast.ml.1.70 | 565 +++ parsing_cocci/.#unitary_ast0.ml.1.28 | 284 ++ parsing_cocci/.#unparse_ast0.ml.1.107 | 651 +++ parsing_cocci/.#unparse_ast0.ml.1.108 | 657 +++ parsing_cocci/.#visitor_ast.ml.1.89 | 1048 +++++ parsing_cocci/.#visitor_ast.ml.1.90 | 1052 +++++ parsing_cocci/.#visitor_ast0.ml.1.79 | 1028 +++++ parsing_cocci/.#visitor_ast0.ml.1.80 | 1036 +++++ parsing_cocci/.cvsignore | 6 + parsing_cocci/arity.ml | 25 +- parsing_cocci/ast0_cocci.ml | 5 + parsing_cocci/ast0_cocci.mli | 5 + parsing_cocci/ast0toast.ml | 13 + parsing_cocci/ast_cocci.ml | 7 +- parsing_cocci/ast_cocci.mli | 3 + parsing_cocci/check_meta.ml | 11 +- parsing_cocci/compute_lines.ml | 3 + parsing_cocci/context_neg.ml | 15 +- parsing_cocci/disjdistr.ml | 4 + parsing_cocci/index.ml | 3 +- parsing_cocci/insert_plus.ml | 10 +- parsing_cocci/iso_pattern.ml | 49 +- parsing_cocci/lexer_cocci.mll | 1 + parsing_cocci/parse_aux.ml | 7 +- parsing_cocci/parse_cocci.ml | 72 +- parsing_cocci/parser_cocci_menhir.ml | 3802 +++++++++-------- parsing_cocci/parser_cocci_menhir.mli | 4 + parsing_cocci/parser_cocci_menhir.mly | 22 +- parsing_cocci/pretty_print_cocci.ml | 5 + parsing_cocci/single_statement.ml | 3 + parsing_cocci/test_exps.ml | 9 + parsing_cocci/type_infer.ml | 9 +- parsing_cocci/unify_ast.ml | 1 + parsing_cocci/unitary_ast0.ml | 12 +- parsing_cocci/unparse_ast0.ml | 7 + parsing_cocci/visitor_ast.ml | 6 + parsing_cocci/visitor_ast0.ml | 12 +- popl09/.cvsignore | 2 + pycaml/.cvsignore | 3 + python/.cvsignore | 2 + tests/.cvsignore | 1 + tests/double_assign.cocci | 2 +- tests/if.c | 28 + tests/if.cocci | 21 + tests/if.res | 38 + tests/substruct.c | 5 + tests/substruct.cocci | 9 + tests/substruct.res | 5 + tests/testifdef.c | 2601 +++++++++++ tests/testifdef.cocci | 12 + 119 files changed, 50209 insertions(+), 2601 deletions(-) create mode 100644 .cvsignore create mode 100644 .project create mode 100644 commons/.cvsignore create mode 100644 ctl/.cvsignore create mode 100644 engine/.#asttoctl2.ml.1.138 create mode 100644 engine/.#asttoctl2.ml.1.141 create mode 100644 engine/.#check_exhaustive_pattern.ml.1.39 create mode 100644 engine/.#cocci_vs_c_3.ml.1.154 create mode 100644 engine/.#ctlcocci_integration.ml.1.111 create mode 100644 engine/.#pattern3.ml.1.56 create mode 100644 engine/.#pattern3.ml.1.57 create mode 100644 engine/.#transformation3.ml.1.47 create mode 100644 engine/.#transformation3.ml.1.48 create mode 100644 engine/.cvsignore create mode 100644 extra/.cvsignore delete mode 100644 extra/c_info.ml delete mode 100644 extra/c_info.mli create mode 100644 globals/.cvsignore create mode 100644 menhirlib/.cvsignore create mode 100644 parsing_c/.cvsignore create mode 100644 parsing_cocci/.#arity.ml.1.81 create mode 100644 parsing_cocci/.#arity.ml.1.82 create mode 100644 parsing_cocci/.#ast0_cocci.ml.1.105 create mode 100644 parsing_cocci/.#ast0_cocci.ml.1.106 create mode 100644 parsing_cocci/.#ast0toast.ml.1.132 create mode 100644 parsing_cocci/.#ast0toast.ml.1.133 create mode 100644 parsing_cocci/.#ast_cocci.ml.1.142 create mode 100644 parsing_cocci/.#ast_cocci.ml.1.143 create mode 100644 parsing_cocci/.#check_meta.ml.1.79 create mode 100644 parsing_cocci/.#check_meta.ml.1.80 create mode 100644 parsing_cocci/.#compute_lines.ml.1.85 create mode 100644 parsing_cocci/.#context_neg.ml.1.95 create mode 100644 parsing_cocci/.#context_neg.ml.1.96 create mode 100644 parsing_cocci/.#disjdistr.ml.1.20 create mode 100644 parsing_cocci/.#index.ml.1.54 create mode 100644 parsing_cocci/.#insert_plus.ml.1.68 create mode 100644 parsing_cocci/.#insert_plus.ml.1.69 create mode 100644 parsing_cocci/.#iso_pattern.ml.1.136 create mode 100644 parsing_cocci/.#iso_pattern.ml.1.137 create mode 100644 parsing_cocci/.#lexer_cocci.mll.1.80 create mode 100644 parsing_cocci/.#parse_aux.ml.1.23 create mode 100644 parsing_cocci/.#parse_cocci.ml.1.162 create mode 100644 parsing_cocci/.#parse_cocci.ml.1.163 create mode 100644 parsing_cocci/.#parser_cocci_menhir.mly.1.153 create mode 100644 parsing_cocci/.#parser_cocci_menhir.mly.1.155 create mode 100644 parsing_cocci/.#pretty_print_cocci.ml.1.127 create mode 100644 parsing_cocci/.#pretty_print_cocci.ml.1.128 create mode 100644 parsing_cocci/.#single_statement.ml.1.51 create mode 100644 parsing_cocci/.#test_exps.ml.1.3 create mode 100644 parsing_cocci/.#type_infer.ml.1.54 create mode 100644 parsing_cocci/.#unify_ast.ml.1.70 create mode 100644 parsing_cocci/.#unitary_ast0.ml.1.28 create mode 100644 parsing_cocci/.#unparse_ast0.ml.1.107 create mode 100644 parsing_cocci/.#unparse_ast0.ml.1.108 create mode 100644 parsing_cocci/.#visitor_ast.ml.1.89 create mode 100644 parsing_cocci/.#visitor_ast.ml.1.90 create mode 100644 parsing_cocci/.#visitor_ast0.ml.1.79 create mode 100644 parsing_cocci/.#visitor_ast0.ml.1.80 create mode 100644 parsing_cocci/.cvsignore create mode 100644 popl09/.cvsignore create mode 100644 pycaml/.cvsignore create mode 100644 python/.cvsignore create mode 100644 tests/.cvsignore create mode 100644 tests/if.c create mode 100644 tests/if.cocci create mode 100644 tests/if.res create mode 100644 tests/substruct.c create mode 100644 tests/substruct.cocci create mode 100644 tests/substruct.res create mode 100644 tests/testifdef.c create mode 100644 tests/testifdef.cocci diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 0000000..da56228 --- /dev/null +++ b/.cvsignore @@ -0,0 +1,3 @@ +.depend +Makefile.config +spatch diff --git a/.project b/.project new file mode 100644 index 0000000..321c5c3 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + Coccinelle + + + + + + Ocaml.ocamlMakefileBuilder + + + + + + ocaml.ocamlnatureMakefile + + diff --git a/Makefile b/Makefile index a6c7122..06b01a5 100644 --- a/Makefile +++ b/Makefile @@ -57,8 +57,8 @@ LIBS=commons/commons.cma globals/globals.cma\ MAKESUBDIRS=commons globals menhirlib $(PYDIR) ctl parsing_cocci parsing_c \ engine popl09 extra python -INCLUDEDIRS=commons globals menhirlib $(PYDIR) ctl parsing_cocci parsing_c \ - engine popl09 extra python +INCLUDEDIRS=commons commons/ocamlextra globals menhirlib $(PYDIR) ctl \ + parsing_cocci parsing_c engine popl09 extra python ############################################################################## # Generic variables @@ -107,6 +107,9 @@ BYTECODE_STATIC=-custom ############################################################################## # Top rules ############################################################################## +eclipse: depend all +configure: + ./configure all: rec $(EXEC) opt: rec.opt $(EXEC).opt @@ -138,7 +141,7 @@ clean:: rm -f dllpycaml_stubs.so -.PHONY: tools +.PHONY: tools all configure tools: $(MAKE) -C tools @@ -250,14 +253,14 @@ srctar: bintar: all rm -f $(TMP)/$(PACKAGE) ln -s `pwd` $(TMP)/$(PACKAGE) - cd $(TMP); tar cvfz $(PACKAGE)-bin-x86.tgz $(BINSRC2) + cd $(TMP); tar cvfz $(PACKAGE)-bin-x86.tgz --exclude=CVS $(BINSRC2) rm -f $(TMP)/$(PACKAGE) staticbintar: all.opt rm -f $(TMP)/$(PACKAGE) ln -s `pwd` $(TMP)/$(PACKAGE) make static - cd $(TMP); tar cvfz $(PACKAGE)-bin-x86-static.tgz $(BINSRC2) + cd $(TMP); tar cvfz $(PACKAGE)-bin-x86-static.tgz --exclude=CVS $(BINSRC2) rm -f $(TMP)/$(PACKAGE) # add ocaml version in name ? @@ -265,7 +268,7 @@ bytecodetar: all rm -f $(TMP)/$(PACKAGE) ln -s `pwd` $(TMP)/$(PACKAGE) make purebytecode - cd $(TMP); tar cvfz $(PACKAGE)-bin-bytecode-$(OCAMLVERSION).tgz $(BINSRC2) + cd $(TMP); tar cvfz $(PACKAGE)-bin-bytecode-$(OCAMLVERSION).tgz --exclude=CVS $(BINSRC2) rm -f $(TMP)/$(PACKAGE) clean:: diff --git a/changes.txt b/changes.txt index bbc8c07..0a0013d 100644 --- a/changes.txt +++ b/changes.txt @@ -1,5 +1,9 @@ -*- org -*- +* 0.1.1 + +** better support for initializer, cf -test substruct + * 0.1 ** first public release of the source code: diff --git a/cocci.ml b/cocci.ml index 9953d1e..b55eb06 100644 --- a/cocci.ml +++ b/cocci.ml @@ -494,36 +494,40 @@ let rec interpret_dependencies local global = function (interpret_dependencies local global s2) | Ast_cocci.NoDep -> true -let rec print_dependencies local global = - let seen = ref [] in - let rec loop = function - Ast_cocci.Dep s | Ast_cocci.AntiDep s -> - if not (List.mem s !seen) - then - begin - if List.mem s local - then pr2 (s^" satisfied") - else pr2 (s^" not satisfied"); - seen := s :: !seen - end - | Ast_cocci.EverDep s | Ast_cocci.NeverDep s -> - if not (List.mem s !seen) - then - begin - if List.mem s global - then pr2 (s^" satisfied") - else pr2 (s^" not satisfied"); - seen := s :: !seen - end - | Ast_cocci.AndDep(s1,s2) -> - print_dependencies local global s1; - print_dependencies local global s2 - | Ast_cocci.OrDep(s1,s2) -> - print_dependencies local global s1; - print_dependencies local global s2 - | Ast_cocci.NoDep -> () in - loop - +let rec print_dependencies str local global dep = + if !Flag_cocci.show_dependencies + then + begin + pr2 str; + let seen = ref [] in + let rec loop = function + Ast_cocci.Dep s | Ast_cocci.AntiDep s -> + if not (List.mem s !seen) + then + begin + if List.mem s local + then pr2 (s^" satisfied") + else pr2 (s^" not satisfied"); + seen := s :: !seen + end + | Ast_cocci.EverDep s | Ast_cocci.NeverDep s -> + if not (List.mem s !seen) + then + begin + if List.mem s global + then pr2 (s^" satisfied") + else pr2 (s^" not satisfied"); + seen := s :: !seen + end + | Ast_cocci.AndDep(s1,s2) -> + loop s1; + loop s2 + | Ast_cocci.OrDep(s1,s2) -> + loop s1; + loop s2 + | Ast_cocci.NoDep -> () in + loop dep + end @@ -931,20 +935,15 @@ let rec apply_python_rule r cache newes e rules_that_have_matched !rules_that_have_ever_matched r.scr_dependencies) then begin - if !Flag.show_misc - then - begin - pr2 ("dependencies for script not satisfied:"); - print_dependencies rules_that_have_matched - !rules_that_have_ever_matched r.scr_dependencies; - show_or_not_binding "in environment" e - end; + print_dependencies "dependencies for script not satisfied:" + rules_that_have_matched + !rules_that_have_ever_matched r.scr_dependencies; + show_or_not_binding "in environment" e; (cache, (e, rules_that_have_matched)::newes) end else begin let (_, mv, _) = r.scr_ast_rule in - show_or_not_binding "in" e; if List.for_all (Pycocci.contains_binding e) mv then begin @@ -958,6 +957,10 @@ let rec apply_python_rule r cache newes e rules_that_have_matched then cache else begin + print_dependencies "dependencies for script satisfied:" + rules_that_have_matched + !rules_that_have_ever_matched r.scr_dependencies; + show_or_not_binding "in" e; Pycocci.build_classes (List.map (function (x,y) -> x) e); Pycocci.construct_variables mv e; let _ = Pycocci.pyrun_simplestring @@ -967,10 +970,10 @@ let rec apply_python_rule r cache newes e rules_that_have_matched relevant_bindings :: cache end in if !Pycocci.inc_match - then (new_cache, (e, rules_that_have_matched)::newes) + then (new_cache, merge_env [(e, rules_that_have_matched)] newes) else (new_cache, newes) end - else (cache, (e, rules_that_have_matched)::newes) + else (cache, merge_env [(e, rules_that_have_matched)] newes) end and apply_cocci_rule r rules_that_have_ever_matched es ccs = @@ -990,50 +993,49 @@ and apply_cocci_rule r rules_that_have_ever_matched es ccs = !rules_that_have_ever_matched r.dependencies) then begin - if !Flag.show_misc - then - begin - pr2 - ("dependencies for rule "^r.rulename^" not satisfied:"); - print_dependencies rules_that_have_matched - !rules_that_have_ever_matched r.dependencies; - show_or_not_binding "in environment" e - end; + print_dependencies + ("dependencies for rule "^r.rulename^" not satisfied:") + rules_that_have_matched + !rules_that_have_ever_matched r.dependencies; + show_or_not_binding "in environment" e; (cache, - Common.union_set newes + merge_env [(e +> List.filter (fun (s,v) -> List.mem s r.used_after), - rules_that_have_matched)]) + rules_that_have_matched)] + newes) end else let new_bindings = try List.assoc relevant_bindings cache with Not_found -> - begin - show_or_not_binding "in" e; - show_or_not_binding "relevant in" relevant_bindings; + print_dependencies + ("dependencies for rule "^r.rulename^" satisfied:") + rules_that_have_matched + !rules_that_have_ever_matched r.dependencies; + show_or_not_binding "in" e; + show_or_not_binding "relevant in" relevant_bindings; - let children_e = ref [] in + let children_e = ref [] in (* looping over the functions and toplevel elements in .c and .h *) - concat_headers_and_c !ccs +> List.iter (fun c -> - if c.flow <> None - then + concat_headers_and_c !ccs +> List.iter (fun c -> + 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 - match processed with - | None -> () - | Some newbindings -> - newbindings +> List.iter (fun newbinding -> - children_e := - Common.insert_set newbinding !children_e) - ); (* end iter cs *) - - !children_e - end in + let processed = + process_a_ctl_a_env_a_toplevel r relevant_bindings + c in + match processed with + | None -> () + | Some newbindings -> + newbindings +> List.iter (fun newbinding -> + children_e := + Common.insert_set newbinding !children_e) + ); (* end iter cs *) + + !children_e in let old_bindings_to_keep = Common.nub (e +> List.filter (fun (s,v) -> List.mem s r.used_after)) in @@ -1067,12 +1069,13 @@ and apply_cocci_rule r rules_that_have_ever_matched es ccs = not (List.mem s old_variables)))) in List.map (function new_binding_to_add -> - (Common.union_set - old_bindings_to_keep new_binding_to_add, + (List.sort compare + (Common.union_set + old_bindings_to_keep new_binding_to_add), r.rulename::rules_that_have_matched)) new_bindings_to_add in ((relevant_bindings,new_bindings)::cache, - Common.union_set new_e newes)) + merge_env new_e newes)) ([],[]) reorganized_env in (* end iter es *) if !(r.was_matched) then Common.push2 r.rulename rules_that_have_ever_matched; @@ -1084,6 +1087,17 @@ and apply_cocci_rule r rules_that_have_ever_matched es ccs = then ccs := rebuild_info_c_and_headers !ccs r.isexp ) +and merge_env new_e old_e = + List.fold_left + (function old_e -> + function (e,rules) as elem -> + let (same,diff) = List.partition (function (e1,_) -> e = e1) old_e in + match same with + [] -> elem :: old_e + | [(_,old_rules)] -> (e,Common.union_set rules old_rules) :: diff + | _ -> failwith "duplicate environment entries") + old_e new_e + and bigloop2 rs ccs = let es = ref [(Ast_c.emptyMetavarsBinding,[])] in let ccs = ref ccs in @@ -1237,7 +1251,7 @@ and bigloop a b = and process_a_ctl_a_env_a_toplevel2 r e c = indent_do (fun () -> show_or_not_celem "trying" c.ast_c; - let (trans_info, returned_any_states, newbindings) = + 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; @@ -1268,11 +1282,11 @@ and process_a_ctl_a_env_a_toplevel2 r e c = (* modify ast via side effect *) ignore(Transformation3.transform r.rulename r.dropped_isos - trans_info (Common.some c.flow)); + inherited_bindings trans_info (Common.some c.flow)); with Timeout -> raise Timeout | UnixExit i -> raise (UnixExit i) end; - Some newbindings + Some (List.map (function x -> x@inherited_bindings) newbindings) end ) diff --git a/commitmsg b/commitmsg index f4b65dd..2df494c 100644 --- a/commitmsg +++ b/commitmsg @@ -1,6 +1,4 @@ -Release coccinelle-0.1 +Release coccinelle-0.1.1 - * First public release of the source code: - * Features - - embeded python scripting - - position +** Language: + - support for initializer at toplevel, cf -test substruct diff --git a/commons/.cvsignore b/commons/.cvsignore new file mode 100644 index 0000000..0a2d2b3 --- /dev/null +++ b/commons/.cvsignore @@ -0,0 +1,2 @@ +.depend +*.cma diff --git a/ctl/.cvsignore b/ctl/.cvsignore new file mode 100644 index 0000000..0a2d2b3 --- /dev/null +++ b/ctl/.cvsignore @@ -0,0 +1,2 @@ +.depend +*.cma diff --git a/emacs/cocci.el b/emacs/cocci.el index 58fc80a..f3f6d3d 100644 --- a/emacs/cocci.el +++ b/emacs/cocci.el @@ -15,7 +15,10 @@ ;;; Usage +;; Copy this file in your ~/.emacs.d directory +;; ;; Add the following lines to your ~/.emacs or equivalent: +;; (load "~/.emacs.d/cocci.el") ;; (setq auto-mode-alist ;; (cons '("\\.cocci$" . cocci-mode) auto-mode-alist)) ;; (autoload 'cocci-mode "cocci" diff --git a/engine/.#asttoctl2.ml.1.138 b/engine/.#asttoctl2.ml.1.138 new file mode 100644 index 0000000..bf9268b --- /dev/null +++ b/engine/.#asttoctl2.ml.1.138 @@ -0,0 +1,2222 @@ +(* +* 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.141 new file mode 100644 index 0000000..6f1f8f6 --- /dev/null +++ b/engine/.#asttoctl2.ml.1.141 @@ -0,0 +1,2295 @@ +(* +* 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) + | Ast.WhenNotTrue w -> Ast.WhenNotTrue w + | Ast.WhenNotFalse w -> Ast.WhenNotFalse w) + 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) + | Ast.WhenNotTrue w -> Ast.WhenNotTrue w + | Ast.WhenNotFalse w -> Ast.WhenNotFalse w) + 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) -> + let rec loop x = + match Ast.unwrap x with + Ast.Return(_,_) | Ast.ReturnExpr(_,_,_) -> true + | Ast.DisjRuleElem((_::_) as l) -> List.for_all loop l + | _ -> false in + loop x + | 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 quantified 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.WhenForall Ast.WhenExists + 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) + | Ast.WhenNotTrue(e) -> + (poswhen, + ctl_or (whencond_true e label guard quantified) negwhen) + | Ast.WhenNotFalse(e) -> + (poswhen, + ctl_or (whencond_false e label guard quantified) 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) + +and get_whencond_exps e = + match Ast.unwrap e with + Ast.Exp e -> [e] + | Ast.DisjRuleElem(res) -> + List.fold_left Common.union_set [] (List.map get_whencond_exps res) + | _ -> failwith "not possible" + +and make_whencond_headers e e1 label guard quantified = + let fvs = Ast.get_fvs e in + let header_pred h = + quantify guard (get_unquantified quantified fvs) + (make_match label guard h) in + let if_header e1 = + header_pred + (Ast.rewrap e + (Ast.IfHeader + (Ast.make_mcode "if", + Ast.make_mcode "(",e1,Ast.make_mcode ")"))) in + let while_header e1 = + header_pred + (Ast.rewrap e + (Ast.WhileHeader + (Ast.make_mcode "while", + Ast.make_mcode "(",e1,Ast.make_mcode ")"))) in + let for_header e1 = + header_pred + (Ast.rewrap e + (Ast.ForHeader + (Ast.make_mcode "for",Ast.make_mcode "(",None,Ast.make_mcode ";", + Some e1,Ast.make_mcode ";",None,Ast.make_mcode ")"))) in + let if_headers = + List.fold_left ctl_or CTL.False (List.map if_header e1) in + let while_headers = + List.fold_left ctl_or CTL.False (List.map while_header e1) in + let for_headers = + List.fold_left ctl_or CTL.False (List.map for_header e1) in + (if_headers, while_headers, for_headers) + +and whencond_true e label guard quantified = + let e1 = get_whencond_exps e in + let (if_headers, while_headers, for_headers) = + make_whencond_headers e e1 label guard quantified in + ctl_or + (ctl_and CTL.NONSTRICT (truepred label) (ctl_back_ex if_headers)) + (ctl_and CTL.NONSTRICT + (inlooppred label) (ctl_back_ex (ctl_or while_headers for_headers))) + +and whencond_false e label guard quantified = + let e1 = get_whencond_exps e in + let (if_headers, while_headers, for_headers) = + make_whencond_headers e e1 label guard quantified in + ctl_or (ctl_and CTL.NONSTRICT (falsepred label) (ctl_back_ex if_headers)) + (ctl_and CTL.NONSTRICT (fallpred label) + (ctl_or (ctl_back_ex if_headers) + (ctl_or (ctl_back_ex while_headers) (ctl_back_ex for_headers)))) + +(* --------------------------------------------------------------------- *) +(* 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 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 end_brace = + (* label is not needed; paren_pred is enough *) + quantify guard rbfvs + (ctl_au (make_match empty_rbrace) + (ctl_and + (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 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 quantified + (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 quantified + (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,cleanup phi) + | CTL.EX(dir,CTL.XX((CTL.AU(_,s,_,_)) as phi)) -> + CTL.AX(dir,s,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/.#check_exhaustive_pattern.ml.1.39 b/engine/.#check_exhaustive_pattern.ml.1.39 new file mode 100644 index 0000000..a716d1b --- /dev/null +++ b/engine/.#check_exhaustive_pattern.ml.1.39 @@ -0,0 +1,183 @@ +(* +* 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/.#cocci_vs_c_3.ml.1.154 b/engine/.#cocci_vs_c_3.ml.1.154 new file mode 100644 index 0000000..fc1f4c0 --- /dev/null +++ b/engine/.#cocci_vs_c_3.ml.1.154 @@ -0,0 +1,3419 @@ +(* +* 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.111 new file mode 100644 index 0000000..5f736aa --- /dev/null +++ b/engine/.#ctlcocci_integration.ml.1.111 @@ -0,0 +1,422 @@ +(* +* 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 Ograph_extended + +module F = Control_flow_c + +(*****************************************************************************) +(* Debugging functions *) +(*****************************************************************************) +let show_or_not_predicate pred = + if !Flag_engine.debug_engine then begin + indent_do (fun () -> + adjust_pp_with_indent_and_header "labeling: pred = " (fun () -> + Pretty_print_engine.pp_predicate pred; + ); + ) + end + +let show_or_not_nodes nodes = + if !Flag_engine.debug_engine then begin + indent_do (fun () -> + adjust_pp_with_indent_and_header "labeling: result = " (fun () -> + Common.pp_do_in_box (fun () -> + pp "{"; + Common.print_between + (fun () -> pp ";"; Format.print_cut()) + (fun (nodei, (_predTODO, subst)) -> + Format.print_int nodei; + Common.pp_do_in_box (fun () -> + Pretty_print_engine.pp_binding2_ctlsubst subst + ) + ) nodes; + pp "}"; + ); + ) + ) + end + +let show_isos rule_elem = + match Ast_cocci.get_isos rule_elem with + [] -> () + | isos -> + let line = Ast_cocci.get_line rule_elem in + Printf.printf "rule elem: "; + Pretty_print_cocci.rule_elem "" rule_elem; + Format.print_newline(); + List.iter + (function (nm,x) -> + Printf.printf " iso: %s(%d): " nm line; + Pretty_print_cocci.pp_print_anything x; + Format.print_newline()) + isos + +(*****************************************************************************) +(* Labeling function *) +(*****************************************************************************) +let (-->) x v = Ast_ctl.Subst (x,v);; + +(* Take list of predicate and for each predicate returns where in the + * control flow it matches, and the set of subsitutions for this match. + *) +let (labels_for_ctl: string list (* dropped isos *) -> + (nodei * F.node) list -> Lib_engine.metavars_binding -> + Lib_engine.label_ctlcocci) = + fun dropped_isos nodes binding -> + + (fun p -> + show_or_not_predicate p; + + let nodes' = nodes +> List.map (fun (nodei, node) -> + (* todo? put part of this code in pattern ? *) + (match p, F.unwrap node with + | Lib_engine.Paren s, (F.SeqStart (_, bracelevel, _)) -> + let make_var x = ("",i_to_s x) in + [(nodei, (p,[(s --> (Lib_engine.ParenVal (make_var bracelevel)))]))] + | Lib_engine.Paren s, (F.SeqEnd (bracelevel, _)) -> + let make_var x = ("",i_to_s x) in + [(nodei, (p,[(s --> (Lib_engine.ParenVal (make_var bracelevel)))]))] + | Lib_engine.Paren _, _ -> [] + | Lib_engine.Label s, _ -> + let labels = F.extract_labels node in + [(nodei, (p,[(s --> (Lib_engine.LabelVal labels))]))] + | Lib_engine.BCLabel s, _ -> + (match F.extract_bclabels node with + [] -> [] (* null for all nodes that are not break or continue *) + | labels -> + [(nodei, (p,[(s --> (Lib_engine.LabelVal labels))]))]) + | Lib_engine.PrefixLabel s, _ -> + let labels = F.extract_labels node in + let prefixes = Common.inits labels +> Common.tail in + prefixes +> List.map (fun prefixlabels -> + (nodei, (p,[(s --> (Lib_engine.LabelVal prefixlabels))])) + ) + + | Lib_engine.Match (re), _unwrapnode -> + let substs = + Pattern3.match_re_node dropped_isos re node binding + +> List.map (fun (re', subst) -> + Lib_engine.Match (re'), subst + ) + in + substs +> List.map (fun (p', subst) -> + (nodei, + (p', + subst +> List.map (fun (s, meta) -> + s --> Lib_engine.NormalMetaVal meta + )))) + + | Lib_engine.InLoop, F.InLoopNode -> [nodei, (p,[])] + | Lib_engine.TrueBranch , F.TrueNode -> [nodei, (p,[])] + | Lib_engine.FalseBranch, F.FalseNode -> [nodei, (p,[])] + | Lib_engine.After, F.AfterNode -> [nodei, (p,[])] + | Lib_engine.FallThrough, F.FallThroughNode -> [nodei,(p,[])] + | Lib_engine.FunHeader, F.FunHeader _ -> [nodei, (p,[])] + | Lib_engine.Top, F.TopNode -> [nodei, (p,[])] + | Lib_engine.Exit, F.Exit -> [nodei, (p,[])] + | Lib_engine.ErrorExit, F.ErrorExit -> [nodei, (p,[])] + | Lib_engine.Goto, F.Goto(_,_) -> [nodei, (p,[])] + + | Lib_engine.InLoop , _ -> [] + | Lib_engine.TrueBranch , _ -> [] + | Lib_engine.FalseBranch, _ -> [] + | Lib_engine.After, _ -> [] + | Lib_engine.FallThrough, _ -> [] + | Lib_engine.FunHeader, _ -> [] + | Lib_engine.Top, _ -> [] + | Lib_engine.Exit, _ -> [] + | Lib_engine.ErrorExit, _ -> [] + | Lib_engine.Goto, _ -> [] + + | Lib_engine.BindGood s, _ -> [(nodei, (p,[(s --> Lib_engine.GoodVal)]))] + | Lib_engine.BindBad s, _ -> [(nodei, (p,[(s --> Lib_engine.BadVal)]))] + | Lib_engine.FakeBrace, _ -> + if F.extract_is_fake node then [nodei, (p,[])] else [] + + | Lib_engine.Return, node -> + (match node with + (* todo? should match the Exit code ? + * todo: one day try also to match the special function + * such as panic(); + *) + | F.Return _ -> [nodei, (p,[])] + | F.ReturnExpr _ -> [nodei, (p,[])] + | _ -> [] + ) + ) + ) +> List.concat + in + + show_or_not_nodes nodes'; + nodes' + ) + +(*****************************************************************************) +(* Some fix flow, for CTL, for unparse *) +(*****************************************************************************) +(* could erase info on nodes, and edge, because they are not used by rene *) +let (control_flow_for_ctl: F.cflow -> ('a, 'b) ograph_mutable) = + fun cflow -> cflow + + + +(* Just make the final node of the control flow loop over itself. + * It seems that one hypothesis of the SAT algorithm is that each node as at + * least a successor. + * + * update: do same for errorexit node. + * + * update: also erase the fake nodes (and adjust the edges accordingly), + * so that AX in CTL can now work. + * Indeed, à la fin de la branche then (et else), on devrait aller directement + * au suivant du endif, sinon si ecrit if(1) { foo(); }; bar(); + * sans '...' entre le if et bar(), alors ca matchera pas car le CTL + * generera un AX bar() qui il tombera d'abord sur le [endif] :( + * Mais chiant de changer l'algo de generation, marche pas tres bien avec + * ma facon de faire recursive et compositionnel. + * => faire une fonction qui applique des fixes autour de ce control flow, + * comme ca passe un bon flow a rene, mais garde un flow a moi pour pouvoir + * facilement generate back the ast. + * alt: faire un wrapper autourde mon graphe pour lui passer dans le module CFG + * une fonction qui passe a travers les Fake, mais bof. + * + * update: also make loop the deadcode nodes, the one that have + * no predecessor. + *) +let (fix_flow_ctl2: F.cflow -> F.cflow) = fun flow -> + let g = ref flow in + + let topi = F.first_node !g in + !g#add_arc ((topi, topi), F.Direct); + + (* for the #define CFG who have no Exit but have at least a EndNode *) + (try + let endi = F.find_node (fun x -> x = F.EndNode) !g in + !g#add_arc ((endi, endi), F.Direct); + with Not_found -> () + ); + + (* for the regular functions *) + (try + let exitnodei = F.find_node (fun x -> x = F.Exit) !g in + let errornodei = F.find_node (fun x -> x = F.ErrorExit) !g in + + !g#add_arc ((exitnodei, exitnodei), F.Direct); + + if null ((!g#successors errornodei)#tolist) && + null ((!g#predecessors errornodei)#tolist) + then !g#del_node errornodei + else !g#add_arc ((errornodei, errornodei), F.Direct); + with Not_found -> () + ); + + let fake_nodes = !g#nodes#tolist +> List.filter (fun (nodei, node) -> + match F.unwrap node with + | F.CaseNode _ + | F.Enter + (*| F.Fake*) (* [endif], [endswitch], ... *) + -> true + | _ -> false + ) in + + fake_nodes +> List.iter (fun (nodei, node) -> F.remove_one_node nodei !g); + + (* even when have deadcode, julia want loop over those nodes *) + !g#nodes#tolist +> List.iter (fun (nodei, node) -> + if (!g#predecessors nodei)#null + then begin + let fakei = !g#add_node (F.mk_node F.Fake [] [] "DEADCODELOOP") in + !g#add_arc ((fakei, nodei), F.Direct); + !g#add_arc ((fakei, fakei), F.Direct); + end + ); + + !g#nodes#tolist +> List.iter (fun (nodei, node) -> + assert (List.length ((!g#successors nodei)#tolist) >= 1); + (* no: && List.length ((!g#predecessors nodei)#tolist) >= 1 + because the enter node at least have no predecessors *) + ); + + !g +let fix_flow_ctl a = + Common.profile_code "fix_flow" (fun () -> fix_flow_ctl2 a) + + + + + +(*****************************************************************************) +(* subtil: the label must operate on newflow, not (old) cflow + * update: now I supposed that we give me a fixed_flow + *) +let model_for_ctl dropped_isos cflow binding = + let newflow = cflow (* old: fix_flow_ctl (control_flow_for_ctl cflow) *) in + let labels = labels_for_ctl dropped_isos (newflow#nodes#tolist) binding in + let states = List.map fst newflow#nodes#tolist in + newflow, labels, states + + +(*****************************************************************************) + +module PRED = + struct + type t = Lib_engine.predicate + let print_predicate x = + Pretty_print_cocci.print_plus_flag := false; + Pretty_print_cocci.print_minus_flag := false; + Pretty_print_engine.pp_predicate x + end + +module ENV = + struct + type value = Lib_engine.metavar_binding_kind2 + type mvar = Ast_cocci.meta_name + let eq_mvar x x' = x = x' + let eq_val v v' = + (* v = v' *) + match (v,v') with + (Lib_engine.NormalMetaVal(Ast_c.MetaPosVal(min1,max1)), + Lib_engine.NormalMetaVal(Ast_c.MetaPosVal(min2,max2))) -> + ((min1 <= min2) && (max1 >= max2)) or + ((min2 <= min1) && (max2 >= max1)) + | (Lib_engine.NormalMetaVal(Ast_c.MetaTypeVal a), + Lib_engine.NormalMetaVal(Ast_c.MetaTypeVal b)) -> + C_vs_c.eq_type a b + | _ -> v = v' + let merge_val v v' = (* values guaranteed to be compatible *) + (* v *) + match (v,v') with + (Lib_engine.NormalMetaVal(Ast_c.MetaPosVal(min1,max1)), + Lib_engine.NormalMetaVal(Ast_c.MetaPosVal(min2,max2))) -> + if (min1 <= min2) && (max1 >= max2) + then Lib_engine.NormalMetaVal(Ast_c.MetaPosVal(min1,max1)) + else + if (min2 <= min1) && (max2 >= max1) + then Lib_engine.NormalMetaVal(Ast_c.MetaPosVal(min2,max2)) + else failwith "incompatible positions give to merge" + | (Lib_engine.NormalMetaVal(Ast_c.MetaTypeVal a), + Lib_engine.NormalMetaVal(Ast_c.MetaTypeVal b)) -> + Lib_engine.NormalMetaVal (Ast_c.MetaTypeVal (C_vs_c.merge_type a b)) + + | _ -> v + let print_mvar (_,s) = Format.print_string s + let print_value x = Pretty_print_engine.pp_binding_kind2 x + end + +module CFG = + struct + type node = int + 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) + let extract_is_loop cfg n = + 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 + end + + +module WRAPPED_ENGINE = Wrapper_ctl.CTL_ENGINE_BIS (ENV) (CFG) (PRED) + +let print_bench _ = WRAPPED_ENGINE.print_bench() + +type pred = Lib_engine.predicate * Ast_cocci.meta_name Ast_ctl.modif + +(*****************************************************************************) +let metavars_binding2_to_binding binding2 = + binding2 +> Common.map_filter (fun (s, kind2) -> + match kind2 with + | Lib_engine.NormalMetaVal kind -> Some (s, kind) + (* I thought it was Impossible to have this when called from + satbis_to_trans_info but it does not seems so *) + | Lib_engine.ParenVal _ -> None + | Lib_engine.LabelVal _ -> None + | Lib_engine.BadVal -> None (* should not occur *) + | Lib_engine.GoodVal -> None (* should not occur *) + ) + +let metavars_binding_to_binding2 binding = + binding +> List.map (fun (s, kind) -> s, Lib_engine.NormalMetaVal kind) + + +let (satbis_to_trans_info: + (nodei * Lib_engine.metavars_binding2 * Lib_engine.predicate) list -> + (nodei * Lib_engine.metavars_binding * Ast_cocci.rule_elem) list) = + fun xs -> + xs +> List.fold_left (fun prev (nodei, binding2, pred) -> + match pred with + | Lib_engine.Match (rule_elem) -> + if !Flag.track_iso_usage then show_isos rule_elem; + (nodei, metavars_binding2_to_binding binding2, rule_elem) + ::prev + (* see BindGood in asttotctl2 *) + | Lib_engine.BindGood (_) -> prev + | _ -> raise Impossible + ) [] + +(*****************************************************************************) + +let rec coalesce_positions = function + [] -> [] + | (x,Ast_c.MetaPosValList l)::rest -> + let (same,others) = List.partition (function (x1,_) -> x = x1) rest in + let ls = + List.concat + (List.map + (function + (_,Ast_c.MetaPosValList l) -> l + | _ -> failwith "unexpected non-position") + same) in + let new_ls = List.sort compare (l@ls) in + (x,Ast_c.MetaPosValList new_ls) :: coalesce_positions others + | x::rest -> x :: coalesce_positions rest + +(*****************************************************************************) +(* Call ctl engine *) +(*****************************************************************************) +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)) = + 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) + then Check_reachability.check_reachability triples flow; + let (trans_info2,used_after_fresh_envs) = + Postprocess_transinfo.process used_after binding2 trans_info2 in + let used_after_envs = + Common.uniq(List.map2 (@) used_after_fresh_envs used_after_envs) in + let trans_info = satbis_to_trans_info trans_info2 in + let newbindings = List.map metavars_binding2_to_binding used_after_envs in + let newbindings = List.map coalesce_positions newbindings in + (trans_info, returned_any_states, newbindings) + +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 new file mode 100644 index 0000000..5b04d31 --- /dev/null +++ b/engine/.#pattern3.ml.1.56 @@ -0,0 +1,467 @@ +(* +* 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 new file mode 100644 index 0000000..9a7c6ce --- /dev/null +++ b/engine/.#pattern3.ml.1.57 @@ -0,0 +1,476 @@ +(* +* 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/.#transformation3.ml.1.47 b/engine/.#transformation3.ml.1.47 new file mode 100644 index 0000000..5691a73 --- /dev/null +++ b/engine/.#transformation3.ml.1.47 @@ -0,0 +1,526 @@ +(* +* 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 new file mode 100644 index 0000000..5ade85b --- /dev/null +++ b/engine/.#transformation3.ml.1.48 @@ -0,0 +1,528 @@ +(* +* 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/.cvsignore b/engine/.cvsignore new file mode 100644 index 0000000..0a2d2b3 --- /dev/null +++ b/engine/.cvsignore @@ -0,0 +1,2 @@ +.depend +*.cma diff --git a/engine/asttoctl2.ml b/engine/asttoctl2.ml index bf9268b..fca5fcf 100644 --- a/engine/asttoctl2.ml +++ b/engine/asttoctl2.ml @@ -577,7 +577,9 @@ and get_before_whencode wc = (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)) + | Ast.WhenModifier(x) -> Ast.WhenModifier(x) + | Ast.WhenNotTrue w -> Ast.WhenNotTrue w + | Ast.WhenNotFalse w -> Ast.WhenNotFalse w) wc and get_before_e s a = @@ -678,7 +680,9 @@ and get_after_whencode a wc = (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)) + | Ast.WhenModifier(x) -> Ast.WhenModifier(x) + | Ast.WhenNotTrue w -> Ast.WhenNotTrue w + | Ast.WhenNotFalse w -> Ast.WhenNotFalse w) wc and get_after_e s a = @@ -807,9 +811,12 @@ let rec ends_in_return stmt_list = x::_ -> (match Ast.unwrap x with Ast.Atomic(x) -> - (match Ast.unwrap x with - Ast.Return(_,_) | Ast.ReturnExpr(_,_,_) -> true - | _ -> false) + let rec loop x = + match Ast.unwrap x with + Ast.Return(_,_) | Ast.ReturnExpr(_,_,_) -> true + | Ast.DisjRuleElem((_::_) as l) -> List.for_all loop l + | _ -> false in + loop x | Ast.Disj(disjs) -> List.for_all ends_in_return disjs | _ -> false) | _ -> false) @@ -1223,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) @@ -1253,7 +1260,7 @@ let dots_au is_strict toend label s wrapcode x seq_after y quantifier = 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 = + process_bef_aft statement_list statement guard quantified wrapcode = let ctl_and_ns = ctl_and CTL.NONSTRICT in (* proces bef_aft *) let shortest l = @@ -1285,7 +1292,7 @@ let rec dots_and_nests plus nest whencodes bef aft dotcode after label if check_quantifier Ast.WhenExists Ast.WhenForall then Exists else - if check_quantifier Ast.WhenExists Ast.WhenForall + if check_quantifier Ast.WhenForall Ast.WhenExists then Forall else !exists in (* the following is used when we find a goto, etc and consider accepting @@ -1302,7 +1309,13 @@ let rec dots_and_nests plus nest whencodes bef aft dotcode after label (poswhen,ctl_or (statement_list whencodes) negwhen) | Ast.WhenAlways stm -> (ctl_and CTL.NONSTRICT (statement stm) poswhen,negwhen) - | Ast.WhenModifier(_) -> (poswhen,negwhen)) + | Ast.WhenModifier(_) -> (poswhen,negwhen) + | Ast.WhenNotTrue(e) -> + (poswhen, + ctl_or (whencond_true e label guard quantified) negwhen) + | Ast.WhenNotFalse(e) -> + (poswhen, + ctl_or (whencond_false e label guard quantified) negwhen)) (CTL.True,bef_aft) (List.rev whencodes) in let poswhen = ctl_and_ns arg poswhen in let negwhen = @@ -1383,6 +1396,62 @@ let rec dots_and_nests plus nest whencodes bef aft dotcode after label (ctl_and_ns dotcode (ctl_and_ns ornest labelled)) aft ender quantifier) +and get_whencond_exps e = + match Ast.unwrap e with + Ast.Exp e -> [e] + | Ast.DisjRuleElem(res) -> + List.fold_left Common.union_set [] (List.map get_whencond_exps res) + | _ -> failwith "not possible" + +and make_whencond_headers e e1 label guard quantified = + let fvs = Ast.get_fvs e in + let header_pred h = + quantify guard (get_unquantified quantified fvs) + (make_match label guard h) in + let if_header e1 = + header_pred + (Ast.rewrap e + (Ast.IfHeader + (Ast.make_mcode "if", + Ast.make_mcode "(",e1,Ast.make_mcode ")"))) in + let while_header e1 = + header_pred + (Ast.rewrap e + (Ast.WhileHeader + (Ast.make_mcode "while", + Ast.make_mcode "(",e1,Ast.make_mcode ")"))) in + let for_header e1 = + header_pred + (Ast.rewrap e + (Ast.ForHeader + (Ast.make_mcode "for",Ast.make_mcode "(",None,Ast.make_mcode ";", + Some e1,Ast.make_mcode ";",None,Ast.make_mcode ")"))) in + let if_headers = + List.fold_left ctl_or CTL.False (List.map if_header e1) in + let while_headers = + List.fold_left ctl_or CTL.False (List.map while_header e1) in + let for_headers = + List.fold_left ctl_or CTL.False (List.map for_header e1) in + (if_headers, while_headers, for_headers) + +and whencond_true e label guard quantified = + let e1 = get_whencond_exps e in + let (if_headers, while_headers, for_headers) = + make_whencond_headers e e1 label guard quantified in + ctl_or + (ctl_and CTL.NONSTRICT (truepred label) (ctl_back_ex if_headers)) + (ctl_and CTL.NONSTRICT + (inlooppred label) (ctl_back_ex (ctl_or while_headers for_headers))) + +and whencond_false e label guard quantified = + let e1 = get_whencond_exps e in + let (if_headers, while_headers, for_headers) = + make_whencond_headers e e1 label guard quantified in + ctl_or (ctl_and CTL.NONSTRICT (falsepred label) (ctl_back_ex if_headers)) + (ctl_and CTL.NONSTRICT (fallpred label) + (ctl_or (ctl_back_ex if_headers) + (ctl_or (ctl_back_ex while_headers) (ctl_back_ex for_headers)))) + (* --------------------------------------------------------------------- *) (* the main translation loop *) @@ -1585,11 +1654,18 @@ and statement stmt after quantified minus_quantified ctl_and (quantify guard lbfvs (make_match lbrace)) (ctl_and paren_pred label_pred) in + 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 end_brace = (* label is not needed; paren_pred is enough *) - ctl_and - (quantify guard rbfvs (real_make_match None guard rbrace)) - paren_pred in + quantify guard rbfvs + (ctl_au (make_match empty_rbrace) + (ctl_and + (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 @@ -1627,11 +1703,6 @@ and statement stmt after quantified minus_quantified 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; @@ -1726,7 +1797,8 @@ and statement stmt after quantified minus_quantified (function x -> statement x Tail new_quantified minus_quantified None llabel slabel true) - guard (function x -> Ast.set_fvs [] (Ast.rewrap stmt x))) + guard quantified + (function x -> Ast.set_fvs [] (Ast.rewrap stmt x))) | Ast.Dots((_,i,d,_),whencodes,bef,aft) -> let dot_code = @@ -1743,7 +1815,8 @@ and statement stmt after 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)) + guard quantified + (function x -> Ast.set_fvs [] (Ast.rewrap stmt x)) | Ast.Switch(header,lb,cases,rb) -> let rec intersect_all = function @@ -1954,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 = @@ -1992,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)) @@ -2005,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 @@ -2121,9 +2204,9 @@ let rec cleanup c = 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.AX(dir,s,CTL.XX(phi)) -> CTL.EX(dir,cleanup phi) | CTL.EX(dir,CTL.XX((CTL.AU(_,s,_,_)) as phi)) -> - CTL.AX(dir,s,CTL.XX(cleanup phi)) + CTL.AX(dir,s,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) diff --git a/engine/check_exhaustive_pattern.ml b/engine/check_exhaustive_pattern.ml index a716d1b..2914b42 100644 --- a/engine/check_exhaustive_pattern.ml +++ b/engine/check_exhaustive_pattern.ml @@ -42,6 +42,7 @@ let dumb_astcocci_rule_elem = function | A.Exp expr -> () | A.TopExp expr -> () | A.Ty ty -> () + | A.TopInit init -> () | A.FunHeader (bef,allminus, fninfo, ida, _, paramsa, _) -> () | A.Decl (bef,allminus,decla) -> () | A.SeqStart _ -> () diff --git a/engine/cocci_vs_c_3.ml b/engine/cocci_vs_c_3.ml index fc1f4c0..f2348f3 100644 --- a/engine/cocci_vs_c_3.ml +++ b/engine/cocci_vs_c_3.ml @@ -543,6 +543,9 @@ module type PARAM = val cocciTy : (A.fullType, B.fullType) matcher -> (A.fullType, F.node) matcher + val cocciInit : + (A.initialiser, B.initialiser) matcher -> (A.initialiser, F.node) matcher + val envf : A.keep_binding -> A.inherited -> A.meta_name A.mcode * Ast_c.metavar_binding_kind * @@ -3041,8 +3044,6 @@ let rec (rule_elem_node: (A.rule_elem, Control_flow_c.node) matcher) = ) ) - - | A.Ty ty, nodeb -> X.cocciTy fullType ty node >>= (fun ty node -> return ( @@ -3051,6 +3052,14 @@ let rec (rule_elem_node: (A.rule_elem, Control_flow_c.node) matcher) = ) ) + | A.TopInit init, nodeb -> + X.cocciInit initialiser init node >>= (fun init node -> + return ( + A.TopInit init, + F.unwrap node + ) + ) + | A.FunHeader (mckstart, allminus, fninfoa, ida, oparen, paramsa, cparen), F.FunHeader ((idb, (retb, (paramsb, (isvaargs, iidotsb))), stob), ii) -> diff --git a/engine/cocci_vs_c_3.mli b/engine/cocci_vs_c_3.mli index 57cbe35..514ef64 100644 --- a/engine/cocci_vs_c_3.mli +++ b/engine/cocci_vs_c_3.mli @@ -133,6 +133,10 @@ module type PARAM = (Ast_cocci.fullType, Ast_c.fullType) matcher -> (Ast_cocci.fullType, Control_flow_c.node) matcher + val cocciInit : + (Ast_cocci.initialiser, Ast_c.initialiser) matcher -> + (Ast_cocci.initialiser, Control_flow_c.node) matcher + (* -------------------------------------------------------------------- *) (* Environment manipulation. Extract info from tin, the "something" *) (* -------------------------------------------------------------------- *) diff --git a/engine/ctlcocci_integration.ml b/engine/ctlcocci_integration.ml index 5f736aa..2b6c75f 100644 --- a/engine/ctlcocci_integration.ml +++ b/engine/ctlcocci_integration.ml @@ -400,7 +400,8 @@ 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)) = @@ -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/ctlcocci_integration.mli b/engine/ctlcocci_integration.mli index 8dbeb76..593bca6 100644 --- a/engine/ctlcocci_integration.mli +++ b/engine/ctlcocci_integration.mli @@ -19,7 +19,8 @@ val mysat : 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) val print_bench : unit -> unit diff --git a/engine/pattern3.ml b/engine/pattern3.ml index 5b04d31..88560ee 100644 --- a/engine/pattern3.ml +++ b/engine/pattern3.ml @@ -80,6 +80,7 @@ module XMATCH = struct 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 *) @@ -91,7 +92,7 @@ module XMATCH = struct 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} + m2 a b {tin with binding = binding} ) in List.flatten xxs @@ -223,6 +224,23 @@ module XMATCH = struct (a, node), binding ) + let cocciInit = fun expf expa node -> fun tin -> + + let globals = ref [] in + let bigf = { + Visitor_c.default_visitor_c with + Visitor_c.kini = (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 *) @@ -279,7 +297,9 @@ module XMATCH = struct (fun c exp tin -> let success = [[]] in let failure = [] in - (match Common.optionise (fun () -> tin.binding +> List.assoc c) with + (* 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 @@ -300,62 +320,67 @@ module XMATCH = struct * 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 = @@ -374,7 +399,7 @@ module XMATCH = struct check_add_metavars_binding false keep inherited (x, pvalu) new_tin with | Some binding -> - f () {extra = new_tin.extra; binding = binding} + f () {new_tin with binding = binding} | None -> fail tin)) new_tin | Ast_cocci.NoMetaPos -> f () new_tin) @@ -393,7 +418,7 @@ module XMATCH = struct 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 + match Common.optionise (fun () -> tin.binding0 +> List.assoc inhvar) with | Some _ -> true | None -> false ) @@ -428,7 +453,7 @@ module XMATCH = struct (match check_add_metavars_binding false keep inherited (x, pvalu) tin with - Some binding -> finish {extra = tin.extra; binding = binding} + Some binding -> finish {tin with binding = binding} | None -> fail tin)) tin | _ -> finish tin @@ -446,7 +471,7 @@ end module MATCH = Cocci_vs_c_3.COCCI_VS_C (XMATCH) -let match_re_node2 dropped_isos a b binding = +let match_re_node2 dropped_isos a b binding0 = let tin = { XMATCH.extra = { @@ -454,7 +479,8 @@ let match_re_node2 dropped_isos a b binding = optional_qualifier_iso = not(List.mem "optional_qualifier" dropped_isos); value_format_iso = not(List.mem "value_format" dropped_isos); }; - XMATCH.binding = binding; + XMATCH.binding = []; + XMATCH.binding0 = binding0; } in MATCH.rule_elem_node a b tin diff --git a/engine/transformation3.ml b/engine/transformation3.ml index 5691a73..84a3d33 100644 --- a/engine/transformation3.ml +++ b/engine/transformation3.ml @@ -63,6 +63,7 @@ module XTRANS = struct type tin = { extra: xinfo; binding: Lib_engine.metavars_binding; + binding0: Lib_engine.metavars_binding; (* inherited variable *) } type 'x tout = 'x option @@ -144,6 +145,18 @@ module XTRANS = struct in Some (expa, Visitor_c.vk_node_s bigf node) + let cocciInit = fun expf expa node -> fun tin -> + + let bigf = { + Visitor_c.default_visitor_c_s with + Visitor_c.kini_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 *) @@ -473,10 +486,10 @@ let transform_re_node a b tin = | 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 xs cflow -> + fun rule_name dropped_isos binding0 xs cflow -> let extra = { optional_storage_iso = not(List.mem "optional_storage" dropped_isos); @@ -496,7 +509,8 @@ let (transform2: string (* rule name *) -> string list (* dropped_isos *) -> let tin = { XTRANS.extra = extra; - XTRANS.binding = binding; + XTRANS.binding = binding0@binding; + XTRANS.binding0 = []; (* not used - everything constant for trans *) } in let node' = transform_re_node rule_elem node tin in @@ -521,6 +535,6 @@ let (transform2: string (* rule name *) -> string list (* dropped_isos *) -> -let transform a b c d = +let transform a b c d e = Common.profile_code "Transformation3.transform" - (fun () -> transform2 a b c d) + (fun () -> transform2 a b c d e) diff --git a/engine/transformation3.mli b/engine/transformation3.mli index 2126bde..c380456 100644 --- a/engine/transformation3.mli +++ b/engine/transformation3.mli @@ -1,5 +1,6 @@ (* note that now we do the transformation via side effect on ast *) val transform : string (* rule name *) -> string list (* dropped isos *) -> + Lib_engine.metavars_binding -> (* inherited bindings *) Lib_engine.transformation_info -> Control_flow_c.cflow -> Control_flow_c.cflow (* could be unit *) diff --git a/extra/.cvsignore b/extra/.cvsignore new file mode 100644 index 0000000..0a2d2b3 --- /dev/null +++ b/extra/.cvsignore @@ -0,0 +1,2 @@ +.depend +*.cma diff --git a/extra/Makefile b/extra/Makefile index 1442bdb..c70c5a3 100644 --- a/extra/Makefile +++ b/extra/Makefile @@ -1,6 +1,6 @@ TARGET=extra -SOURCES = classic_patch.ml kbuild.ml maintainers.ml c_info.ml +SOURCES = classic_patch.ml kbuild.ml maintainers.ml SYSLIBS = str.cma unix.cma diff --git a/extra/c_info.ml b/extra/c_info.ml deleted file mode 100644 index 9169bb5..0000000 --- a/extra/c_info.ml +++ /dev/null @@ -1,525 +0,0 @@ -open Common - -open Ast_c - - -(* used both for storing the entities 'defined' and 'used' in a file, but - * depending on the use, some fields may not be used - *) -type entities = { - macros: string hashset; (* object-like or function-like *) - variables: string hashset; - static_variables: string hashset; (* for defined only *) - functions: string hashset; - static_functions: string hashset; (* for defined only *) - structs: string hashset; (* union defs, enum defs, enum values *) - typedefs: string hashset; - include_c: filename hashset; (* for used only *) -} - -(* inverted index *) -type idx_entities = { - idx_macros: (string, (filename hashset)) Hashtbl.t; - idx_variables: (string, (filename hashset)) Hashtbl.t; - idx_functions: (string, (filename hashset)) Hashtbl.t; - idx_structs: (string, (filename hashset)) Hashtbl.t; - idx_typedefs: (string, (filename hashset)) Hashtbl.t; -} - -let empty_entities () = { - macros = Hashtbl.create 101; - variables = Hashtbl.create 101; - static_variables = Hashtbl.create 101; - functions = Hashtbl.create 101; - static_functions = Hashtbl.create 101; - structs = Hashtbl.create 101; - typedefs = Hashtbl.create 101; - include_c = Hashtbl.create 101; -} - -let empty_idx_entities () = { - idx_macros = Hashtbl.create 101; - idx_variables = Hashtbl.create 101; - idx_functions = Hashtbl.create 101; - idx_structs = Hashtbl.create 101; - idx_typedefs = Hashtbl.create 101; -} - - -let h_to_l h = Common.hashset_to_list h - -let print_entities e = - begin -(* e.macros +> h_to_l +> List.iter (fun s -> pr("MACRO: " ^ s)); *) - e.variables +> h_to_l +> List.iter (fun s -> pr("VAR: " ^ s)); - e.static_variables +> h_to_l +> List.iter (fun s -> pr("STATICVAR: " ^ s)); - e.functions +> h_to_l +> List.iter (fun s -> pr("FUNC: " ^ s)); - e.static_functions +> h_to_l +> List.iter (fun s -> pr("STATICFUNC: " ^ s)); - e.structs +> h_to_l +> List.iter (fun s -> pr("STRUCT: "^s)); - e.typedefs +> h_to_l +> List.iter (fun s -> pr("TYPEDEF: "^s)); - e.include_c +> h_to_l +> List.iter (fun s -> pr("INCLUDEC: "^s)); - end - - -(* the defined_stuff and used_stuff may not be 100% correct. They don't handle - * I think every dark corner of the C. It's possible to shadow in so many - * ways. - *) - -(* look only for toplevel definition *) -let defined_stuff xs = - let e = empty_entities() in - let add h s = Hashtbl.add h s true in - - (* look only for toplevel definition: don't recurse, don't call k *) - let bigf = { Visitor_c.default_visitor_c with - Visitor_c.ktoplevel = (fun (k,bigf) t -> - match t with - | Declaration decl -> - (match decl with - | DeclList (xs, ii) -> - xs +> List.iter (fun ((var, t, sto, _local), iicomma) -> - Visitor_c.vk_type bigf t; - match var, sto with - | None, _ -> () - | Some ((s, ini), ii_s_ini), (StoTypedef,inline) -> - add e.typedefs s; - | Some ((s, ini), ii_s_ini), (Sto Static,inline) -> - (* need add them to do the adjust_need *) - add e.static_variables s; - - | Some ((s, ini), ii_s_ini), (Sto Extern,inline) -> - () - | Some ((s, ini), ii_s_ini), (_,inline) -> - add e.variables s; - ); - | MacroDecl ((s, args),ii) -> () - ) - - | Definition def -> - let ((s, typ, sto, cp), ii) = def in - (match sto with - | Sto Static, inline -> - (* need add them to do the adjust_need *) - add e.static_functions s - | _ -> - add e.functions s - ) - - | Include includ -> () - | Define ((s,ii), body) -> add e.macros s - | MacroTop (s, args, ii) -> () - - | EmptyDef _ | NotParsedCorrectly _ | FinalDef _ -> () - ); - - Visitor_c.ktype = (fun (k, bigf) t -> - match Ast_c.unwrap_typeC t with - | StructUnion (su, sopt, fields) -> - sopt +> do_option (fun s -> - add e.structs s; - ); - - | _ -> () - ); - - } in - xs +> List.iter (fun (p, info_item) -> Visitor_c.vk_toplevel bigf p); - e - - - - - - - - -(* look only for use of external stuff. Don't consider local vars, - * typedefs, structures *) -let used_stuff xs = - - let e = empty_entities() in - let add h s = Hashtbl.replace h s true in - - let initial_env = [ - ["NULL"; - "do_gettimeofday"; - "le32_to_cpu"; - "udelay"; - "printk"; - (* !!! sometimes considered as VAR :( *) - "u8"; "u16"; "u32"; - "s32"; - ] +> List.map (fun s -> s, true); - ] - in - let regexp_macro = Str.regexp - "^[A-Z_][A-Z_0-9]*$" - in - - let (_env: (string, bool) Common.scoped_env ref) = ref initial_env in - - - let bigf = { Visitor_c.default_visitor_c with - - (* --------- handling scope of variables (and also some use) --------- *) - Visitor_c.kstatement = (fun (k, bigf) st -> - match st with - | Compound statxs, ii -> Common.do_in_new_scope _env (fun () -> k st); - | _ -> k st - ); - Visitor_c.kdecl = (fun (k, bigf) d -> - k d; (* to add possible definition in type found in Decl *) - (match d with - | (DeclList (xs, ii)) -> - xs +> List.iter (fun ((var, t, sto, _local), iicomma) -> - var +> do_option (fun ((s, ini), ii_s_ini) -> - match sto with - | StoTypedef, _inline -> - (* add_binding (TypeDef (s)) true; *) - () - | _ -> - Common.add_in_scope _env (s, true); - ); - ); - | _ -> () - ); - ); - Visitor_c.ktoplevel = (fun (k, bigf) elem -> - match elem with - | Definition def -> - let (funcs, ((returnt, (paramst, b))), sto, statxs),ii = def in - Common.do_in_new_scope _env (fun () -> - paramst +> List.iter (fun (((b, s, t), _),_) -> - match s with - | Some s -> Common.add_in_scope _env (s, true) - | None -> pr2 "no type, certainly because Void type ?" - ); - k elem - ); - | Define (s, (defkind, defval)) -> - Common.do_in_new_scope _env (fun () -> - (match defkind with - | DefineFunc (params, ii) -> - params +> List.iter (fun ((s,iis), iicomma) -> - Common.add_in_scope _env (s, true) - ); - | _ -> () - ); - k elem - ); - | Include ((inc_file,ii), posref) -> - (match inc_file with - | Local [x] when x =~ ".*\\.c$" -> - add e.include_c x - | _ -> () - ) - | _ -> k elem - ); - - - (* --------- and now looking for use --------- *) - Visitor_c.kexpr = (fun (k,bigf) x -> - match Ast_c.unwrap_expr x with - - | FunCall (((Ident f, typ), ii), args) -> - if not (Common.member_env_key f !_env) - then - if f ==~ regexp_macro - then add e.macros f - else add e.functions f - ; - args +> List.iter (fun (x,ii) -> - Visitor_c.vk_argument bigf x - ); - | Ident s -> - if not (Common.member_env_key s !_env) - then - if s ==~ regexp_macro - then add e.macros s - else add e.variables s - - | _ -> k x - ); - - Visitor_c.ktype = (fun (k,bigf) t -> - match Ast_c.unwrap_typeC t with - | StructUnionName (su, s) -> - if not (Common.member_env_key s !_env) - then - add e.structs s; - | TypeName (s,_typ) -> - if not (Common.member_env_key s !_env) - then - add e.typedefs s; - | _ -> k t - ); - - } in - xs +> List.iter (fun (p, info_item) -> Visitor_c.vk_toplevel bigf p); - e - - - - -(* for the moment, just look if it looks like a linux module file *) -let extra_stuff xs = - let is_module = ref false in - - (* look only for toplevel definition: don't recurse, don't call k *) - let bigf = { Visitor_c.default_visitor_c with - Visitor_c.ktoplevel = (fun (k,bigf) t -> - match t with - | MacroTop (s, args, ii) -> - if s = "module_init" - then is_module := true; - | Definition def -> - let ((s, typ, sto, cp), ii) = def in - if s = "init_module" - then is_module := true; - - | _ -> () - ); - } in - xs +> List.iter (fun (p, info_item) -> Visitor_c.vk_toplevel bigf p); - !is_module - - - -let adjust_used_only_external used defined = - begin - used.variables +> h_to_l +> List.iter (fun s -> - if Hashtbl.mem defined.variables s || - Hashtbl.mem defined.static_variables s || - (* sometimes functions are used as variable, when for example - * stored in a pointer variable, so look also for function here. - *) - Hashtbl.mem defined.functions s || - Hashtbl.mem defined.static_functions s - then Hashtbl.remove used.variables s - ); - used.functions +> h_to_l +> List.iter (fun s -> - if Hashtbl.mem defined.functions s || - Hashtbl.mem defined.static_functions s - then Hashtbl.remove used.functions s - ); - used.structs +> h_to_l +> List.iter (fun s -> - if Hashtbl.mem defined.structs s - then Hashtbl.remove used.structs s - ); - used.typedefs +> h_to_l +> List.iter (fun s -> - if Hashtbl.mem defined.typedefs s - then Hashtbl.remove used.typedefs s - ); - end - - - - -type file_info = { - used: entities; - defined: entities; - is_module: bool; -} -type global_definitions = idx_entities - -let mk_global_definitions_index xs = - let idx = empty_idx_entities () in - xs +> List.iter (fun (file, {defined = defined}) -> - defined.variables +> h_to_l +> List.iter (fun s -> - Common.hash_hashset_add s file idx.idx_variables; - ); - defined.functions +> h_to_l +> List.iter (fun s -> - Common.hash_hashset_add s file idx.idx_functions; - ); - defined.structs +> h_to_l +> List.iter (fun s -> - Common.hash_hashset_add s file idx.idx_structs; - ); - defined.typedefs +> h_to_l +> List.iter (fun s -> - Common.hash_hashset_add s file idx.idx_typedefs; - ); - ); - idx - -let known_duplicate = - ["init_module"; "cleanup_module"; - "main";"usage"; - ] - -let check_no_duplicate_global_definitions idx = - begin - pr2 "DUPLICATE processing:"; - idx.idx_functions +> hash_to_list +> List.iter (fun (f, set) -> - let xs = hash_to_list set in - if List.length xs <> 1 && not (List.mem f known_duplicate) - then - pr2 ("multiple def for : " ^ f ^ " in " ^ - (join " " (List.map (fun x -> basename (fst x)) xs))); - ); - end - -type dependencies_graph = - ((filename * file_info) * string, bool) Ograph_extended.ograph_mutable - - -let build_graph xs dep graphfile = - let g = ref (new Ograph_extended.ograph_mutable) in - let h = Hashtbl.create 101 in - let s_to_nodei s = Hashtbl.find h s in - - pr2 "BUILDING graph:"; - - let arrow a b c d = - (sprintf "%-20s -- %s:%25s --> %s" a b c d) - in - with_open_outfile (graphfile ^ ".graph") (fun (pr_no_nl,chan) -> - let pr_arrow a b c d = - pr2 (arrow a b c d); - pr_no_nl (arrow a b c d ^ "\n"); - in - - (* build nodes *) - xs +> List.iter (fun (file, cinfo) -> - let s = (if cinfo.is_module then "[M]" else "") ^ Filename.basename file in - let xi = !g#add_node ((file, cinfo), s) in - Hashtbl.add h file xi; - ); - - xs +> List.iter (fun (file, {used = used}) -> - - used.functions +> h_to_l +> List.iter (fun s -> - match Common.optionise (fun () -> Hashtbl.find dep.idx_functions s) with - | None -> () - | Some hset -> - hset +> h_to_l +> List.iter (fun file_defined -> - !g#add_arc ((s_to_nodei file, s_to_nodei file_defined), true); - let (file, file_defined) = basename file, basename file_defined in - pr_arrow file "f" s file_defined; - ); - ); - (* sometime use functions as variable *) - used.variables +> h_to_l +> List.iter (fun s -> - match Common.optionise (fun () -> Hashtbl.find dep.idx_functions s) with - | None -> () - | Some hset -> - hset +> h_to_l +> List.iter (fun file_defined -> - !g#add_arc ((s_to_nodei file, s_to_nodei file_defined), true); - let (file, file_defined) = basename file, basename file_defined in - pr_arrow file "f" s file_defined; - ); - ); - - used.variables +> h_to_l +> List.iter (fun s -> - match Common.optionise (fun () -> Hashtbl.find dep.idx_variables s) with - | None -> () - | Some hset -> - hset +> h_to_l +> List.iter (fun file_defined -> - !g#add_arc ((s_to_nodei file, s_to_nodei file_defined), true); - let (file, file_defined) = basename file, basename file_defined in - pr_arrow file "v" s file_defined; - ); - ); - - used.include_c +> h_to_l +> List.iter (fun local_file -> - let file_defined = Filename.concat (dirname file) local_file in - try ( - !g#add_arc ((s_to_nodei file, s_to_nodei file_defined), true); - let (file, file_defined) = basename file, basename file_defined in - pr_arrow file "I" "include" file_defined; - ) - with Not_found -> - pr2 ("can't find included C file: " ^ file_defined) - ) - -(* - used.structs +> h_to_l +> List.iter (fun s -> - match Common.optionise (fun () -> Hashtbl.find dep.idx_structs s) with - | None -> () - | Some hset -> - hset +> h_to_l +> List.iter (fun file_defined -> - !g#add_arc ((s_to_nodei file, s_to_nodei file_defined), true); - ); - ); - - used.typedefs +> h_to_l +> List.iter (fun s -> - match Common.optionise (fun () -> Hashtbl.find dep.idx_typedefs s) with - | None -> () - | Some hset -> - hset +> h_to_l +> List.iter (fun file_defined -> - !g#add_arc ((s_to_nodei file, s_to_nodei file_defined), true); - ); - ); -*) - ); - ); - Ograph_extended.print_ograph_mutable !g graphfile (!Flag.show_misc); - !g - - - - - -let generate_makefile (g: dependencies_graph) file = - pr2 "GENERATING makefile"; - with_open_outfile file (fun (pr_no_nl, chan) -> - - let nodei_to_file xi = - let ((file, cinfo ), s) = (g#nodes#assoc xi) in - file - in - let all_nodes = g#nodes#tolist +> List.map fst in - let visited_nodes_h = Hashtbl.create 101 in - - let modules = all_nodes +> List.filter (fun xi -> - let ((file, cinfo), s) = g#nodes#assoc xi in - cinfo.is_module - ) in - - pr_no_nl " # ---- modules files ---- \n"; - modules +> List.iter (fun xi -> - pr2 (nodei_to_file xi); - pr_no_nl " "; - g +> Ograph_extended.dfs_iter xi (fun yi -> - pr2 (" " ^ (Filename.basename (nodei_to_file yi))); - pr_no_nl (" " ^ (Filename.basename (nodei_to_file yi))); - Hashtbl.add visited_nodes_h yi true; - ); - pr_no_nl "\n"; - ); - let visited_nodes = Common.hashset_to_list visited_nodes_h in - let rest = all_nodes $-$ visited_nodes in - - let startfiles = rest +> List.filter (fun xi -> - (g#predecessors xi)#null - ) in - pr_no_nl " # ---- not module starting files ---- \n"; - - startfiles +> List.iter (fun xi -> - pr2 (nodei_to_file xi); - pr_no_nl " "; - g +> Ograph_extended.dfs_iter xi (fun yi -> - pr2 (" " ^ (Filename.basename (nodei_to_file yi))); - pr_no_nl (" " ^ (Filename.basename (nodei_to_file yi))); - Hashtbl.add visited_nodes_h yi true; - ); - pr_no_nl "\n"; - ); - let visited_nodes = Common.hashset_to_list visited_nodes_h in - let rest = rest $-$ visited_nodes in - - if not (null rest) then pr_no_nl " # ---- files in cycle ---- \n"; - rest +> List.iter (fun xi -> - if Hashtbl.mem visited_nodes_h xi then () (* already handled *) - else begin - pr2 (nodei_to_file xi); - pr_no_nl " "; - g +> Ograph_extended.dfs_iter xi (fun yi -> - pr2 (" " ^ (Filename.basename (nodei_to_file yi))); - pr_no_nl (" " ^ (Filename.basename (nodei_to_file yi))); - Hashtbl.add visited_nodes_h yi true; - ); - pr_no_nl "\n"; - end - ) - ) - diff --git a/extra/c_info.mli b/extra/c_info.mli deleted file mode 100644 index c8e07a4..0000000 --- a/extra/c_info.mli +++ /dev/null @@ -1,53 +0,0 @@ -open Common - -type entities = { - macros : string hashset; - variables : string hashset; - static_variables : string hashset; - functions : string hashset; - static_functions : string hashset; - structs : string hashset; - typedefs : string hashset; - include_c : filename hashset; -} -val print_entities : entities -> unit - -type idx_entities = { - idx_macros : (string, filename hashset) Hashtbl.t; - idx_variables : (string, filename hashset) Hashtbl.t; - idx_functions : (string, filename hashset) Hashtbl.t; - idx_structs : (string, filename hashset) Hashtbl.t; - idx_typedefs : (string, filename hashset) Hashtbl.t; -} - -type file_info = { - used : entities; - defined : entities; - is_module : bool; -} - -type global_definitions = idx_entities - -type dependencies_graph = - ((filename * file_info) * string, bool) Ograph_extended.ograph_mutable - - -val defined_stuff : (Ast_c.toplevel * 'a) list -> entities -val used_stuff : (Ast_c.toplevel * 'a) list -> entities -(* is_module *) -val extra_stuff : (Ast_c.toplevel * 'a) list -> bool - -val adjust_used_only_external : entities -> entities -> unit - -val mk_global_definitions_index : - (filename * file_info) list -> idx_entities -val check_no_duplicate_global_definitions : - idx_entities -> unit - - -val build_graph : - (filename * file_info) list -> idx_entities -> filename (*outfile*) -> - ((filename * file_info) * string, bool) Ograph_extended.ograph_mutable - - -val generate_makefile : dependencies_graph -> filename -> unit diff --git a/flag_cocci.ml b/flag_cocci.ml index 7c3b42c..af2b9b5 100644 --- a/flag_cocci.ml +++ b/flag_cocci.ml @@ -40,6 +40,7 @@ let show_mcodekind_in_ctl = ref false (* the "underived" outputs *) let show_transinfo = ref true let show_binding_in_out = ref false +let show_dependencies = ref false let windows = ref false diff --git a/globals/.cvsignore b/globals/.cvsignore new file mode 100644 index 0000000..0a2d2b3 --- /dev/null +++ b/globals/.cvsignore @@ -0,0 +1,2 @@ +.depend +*.cma diff --git a/globals/config.ml b/globals/config.ml index 5169aa2..c5516d9 100644 --- a/globals/config.ml +++ b/globals/config.ml @@ -1,4 +1,4 @@ -let version = "0.1" +let version = "0.1.1" let path = try (Sys.getenv "COCCINELLE_HOME") diff --git a/main.ml b/main.ml index aaa0678..75ca33d 100644 --- a/main.ml +++ b/main.ml @@ -197,7 +197,7 @@ let short_options = [ " guess what"; "-date", Arg.Unit (fun () -> - pr2 "version: $Date: 2008/09/26 00:44:57 $"; + pr2 "version: $Date: 2008/10/11 16:22:38 $"; raise (Common.UnixExit 0) ), " guess what"; @@ -254,6 +254,10 @@ let other_options = [ "-no_show_misc", Arg.Clear Flag.show_misc, " "; "-show_trying", Arg.Set Flag.show_trying, " show the name of each function being processed"; + "-show_dependencies", + Arg.Unit (function _ -> Flag_cocci.show_dependencies := true; + Flag_cocci.show_binding_in_out := true), + " show the dependencies related to each rule"; ]; "verbose subsystems options", diff --git a/menhirlib/.cvsignore b/menhirlib/.cvsignore new file mode 100644 index 0000000..0a2d2b3 --- /dev/null +++ b/menhirlib/.cvsignore @@ -0,0 +1,2 @@ +.depend +*.cma diff --git a/parsing_c/.cvsignore b/parsing_c/.cvsignore new file mode 100644 index 0000000..3f95352 --- /dev/null +++ b/parsing_c/.cvsignore @@ -0,0 +1,6 @@ +.depend +*.cma +lexer_c.ml +parser_c.ml +parser_c.mli +parser_c.output diff --git a/parsing_c/unparse_cocci2.ml b/parsing_c/unparse_cocci2.ml index 77e6a7f..7c5dd58 100644 --- a/parsing_c/unparse_cocci2.ml +++ b/parsing_c/unparse_cocci2.ml @@ -524,6 +524,7 @@ and rule_elem arity re = | Ast.Exp(exp) -> print_string arity; expression exp | Ast.TopExp(exp) -> print_string arity; expression exp | Ast.Ty(ty) -> print_string arity; fullType ty + | Ast.TopInit(init) -> initialiser false init | Ast.Include(inc,s) -> mcode print_string inc; print_string " "; mcode inc_file s | Ast.DefineHeader(def,id,params) -> diff --git a/parsing_cocci/.#arity.ml.1.81 b/parsing_cocci/.#arity.ml.1.81 new file mode 100644 index 0000000..2248a97 --- /dev/null +++ b/parsing_cocci/.#arity.ml.1.81 @@ -0,0 +1,1054 @@ +(* +* 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. +*) + + +(* Arities matter for the minus slice, but not for the plus slice. *) + +(* ? only allowed on rule_elems, and on subterms if the context is ? also. *) + +module Ast0 = Ast0_cocci +module Ast = Ast_cocci + +(* --------------------------------------------------------------------- *) + +let warning s = Printf.printf "warning: %s\n" s + +let fail w str = + failwith + (Printf.sprintf "cocci line %d: %s" ((Ast0.get_info w).Ast0.line_start) + str) + +let make_opt_unique optfn uniquefn info tgt arity term = + let term = Ast0.rewrap info term in + if tgt = arity + then term + else (* tgt must be NONE *) + match arity with + Ast0.OPT -> Ast0.copywrap info (optfn term) + | Ast0.UNIQUE -> Ast0.copywrap info (uniquefn term) + | Ast0.NONE -> failwith "tgt must be NONE" + +let all_same opt_allowed tgt line arities = + let tgt = + match tgt with + Ast0.NONE -> + (match List.hd arities with + Ast0.OPT when not opt_allowed -> + failwith "opt only allowed for the elements of a statement list" + | x -> x) + | _ -> tgt in + if not(List.for_all (function x -> x = tgt) arities) + then warning (Printf.sprintf "incompatible arity found on line %d" line); + tgt + +let get_option fn = function + None -> None + | Some x -> Some (fn x) + +let anyopt l fn = List.exists (function w -> fn(Ast0.unwrap w)) l + +let allopt l fn = + let rec loop = function + [] -> [] + | x::xs -> + match fn (Ast0.unwrap x) with + Some x -> x :: (loop xs) + | None -> [] in + let res = loop l in + if List.length res = List.length l then Some res else None + +(* --------------------------------------------------------------------- *) +(* --------------------------------------------------------------------- *) +(* Mcode *) + +let mcode2line (_,_,info,_,_) = info.Ast0.line_start +let mcode2arity (_,arity,_,_,_) = arity + +let mcode x = x (* nothing to do ... *) + +(* --------------------------------------------------------------------- *) +(* Dots *) + +let dots fn d = + Ast0.rewrap d + (match Ast0.unwrap d with + Ast0.DOTS(x) -> Ast0.DOTS(List.map fn x) + | Ast0.CIRCLES(x) -> Ast0.CIRCLES(List.map fn x) + | Ast0.STARS(x) -> Ast0.STARS(List.map fn x)) + +let only_dots l = + not + (List.exists + (function x -> + match Ast0.unwrap x with + Ast0.Circles(_,_) | Ast0.Stars(_,_) -> true + | _ -> false) + l) + +let only_circles l = + not (List.exists + (function x -> + match Ast0.unwrap x with + Ast0.Dots(_,_) | Ast0.Stars(_,_) -> true + | _ -> false) + l) + +let only_stars l = + not (List.exists + (function x -> + match Ast0.unwrap x with + Ast0.Dots(_,_) | Ast0.Circles(_,_) -> true + | _ -> false) + l) + +let concat_dots fn d = + Ast0.rewrap d + (match Ast0.unwrap d with + Ast0.DOTS(x) -> + let l = List.map fn x in + if only_dots l + then Ast0.DOTS(l) + else fail d "inconsistent dots usage" + | Ast0.CIRCLES(x) -> + let l = List.map fn x in + if only_circles l + then Ast0.CIRCLES(l) + else fail d "inconsistent dots usage" + | Ast0.STARS(x) -> + let l = List.map fn x in + if only_stars l + then Ast0.STARS(l) + else fail d "inconsistent dots usage") + +let flat_concat_dots fn d = + match Ast0.unwrap d with + Ast0.DOTS(x) -> List.map fn x + | Ast0.CIRCLES(x) -> List.map fn x + | Ast0.STARS(x) -> List.map fn x + +(* --------------------------------------------------------------------- *) +(* Identifier *) + +let make_id = + make_opt_unique + (function x -> Ast0.OptIdent x) + (function x -> Ast0.UniqueIdent x) + +let ident opt_allowed tgt i = + match Ast0.unwrap i with + Ast0.Id(name) -> + let arity = + all_same opt_allowed tgt (mcode2line name) + [mcode2arity name] in + let name = mcode name in + make_id i tgt arity (Ast0.Id(name)) + | Ast0.MetaId(name,constraints,pure) -> + let arity = + all_same opt_allowed tgt (mcode2line name) + [mcode2arity name] in + let name = mcode name in + make_id i tgt arity (Ast0.MetaId(name,constraints,pure)) + | Ast0.MetaFunc(name,constraints,pure) -> + let arity = + all_same opt_allowed tgt (mcode2line name) + [mcode2arity name] in + let name = mcode name in + make_id i tgt arity (Ast0.MetaFunc(name,constraints,pure)) + | Ast0.MetaLocalFunc(name,constraints,pure) -> + let arity = + all_same opt_allowed tgt (mcode2line name) + [mcode2arity name] in + let name = mcode name in + make_id i tgt arity (Ast0.MetaLocalFunc(name,constraints,pure)) + | Ast0.OptIdent(_) | Ast0.UniqueIdent(_) -> + failwith "unexpected code" + +(* --------------------------------------------------------------------- *) +(* Expression *) + +let make_exp = + make_opt_unique + (function x -> Ast0.OptExp x) + (function x -> Ast0.UniqueExp x) + +let rec top_expression opt_allowed tgt expr = + let exp_same = all_same opt_allowed tgt in + match Ast0.unwrap expr with + Ast0.Ident(id) -> + let new_id = ident opt_allowed tgt id in + Ast0.rewrap expr + (match Ast0.unwrap new_id with + Ast0.OptIdent(id) -> + Ast0.OptExp(Ast0.rewrap expr (Ast0.Ident(id))) + | Ast0.UniqueIdent(id) -> + Ast0.UniqueExp(Ast0.rewrap expr (Ast0.Ident(id))) + | _ -> Ast0.Ident(new_id)) + | Ast0.Constant(const) -> + let arity = exp_same (mcode2line const) [mcode2arity const] in + let const = mcode const in + make_exp expr tgt arity (Ast0.Constant(const)) + | Ast0.FunCall(fn,lp,args,rp) -> + let arity = exp_same (mcode2line lp) [mcode2arity lp;mcode2arity rp] in + let fn = expression arity fn in + let lp = mcode lp in + let args = dots (expression arity) args in + let rp = mcode rp in + make_exp expr tgt arity (Ast0.FunCall(fn,lp,args,rp)) + | Ast0.Assignment(left,op,right,simple) -> + let arity = exp_same (mcode2line op) [mcode2arity op] in + let left = expression arity left in + let op = mcode op in + let right = expression arity right in + make_exp expr tgt arity (Ast0.Assignment(left,op,right,simple)) + | Ast0.CondExpr(exp1,why,exp2,colon,exp3) -> + let arity = + exp_same (mcode2line why) [mcode2arity why; mcode2arity colon] in + let exp1 = expression arity exp1 in + let why = mcode why in + let exp2 = get_option (expression arity) exp2 in + let colon = mcode colon in + let exp3 = expression arity exp3 in + make_exp expr tgt arity (Ast0.CondExpr(exp1,why,exp2,colon,exp3)) + | Ast0.Postfix(exp,op) -> + let arity = exp_same (mcode2line op) [mcode2arity op] in + let exp = expression arity exp in + let op = mcode op in + make_exp expr tgt arity (Ast0.Postfix(exp,op)) + | Ast0.Infix(exp,op) -> + let arity = exp_same (mcode2line op) [mcode2arity op] in + let exp = expression arity exp in + let op = mcode op in + make_exp expr tgt arity (Ast0.Infix(exp,op)) + | Ast0.Unary(exp,op) -> + let arity = exp_same (mcode2line op) [mcode2arity op] in + let exp = expression arity exp in + let op = mcode op in + make_exp expr tgt arity (Ast0.Unary(exp,op)) + | Ast0.Binary(left,op,right) -> + let arity = exp_same (mcode2line op) [mcode2arity op] in + let left = expression arity left in + let op = mcode op in + let right = expression arity right in + make_exp expr tgt arity (Ast0.Binary(left,op,right)) + | Ast0.Nested(left,op,right) -> failwith "nested in arity not possible" + | Ast0.Paren(lp,exp,rp) -> + let arity = exp_same (mcode2line lp) [mcode2arity lp;mcode2arity rp] in + let lp = mcode lp in + let exp = expression arity exp in + let rp = mcode rp in + make_exp expr tgt arity (Ast0.Paren(lp,exp,rp)) + | Ast0.ArrayAccess(exp1,lb,exp2,rb) -> + let arity = exp_same (mcode2line lb) [mcode2arity lb; mcode2arity rb] in + let exp1 = expression arity exp1 in + let lb = mcode lb in + let exp2 = expression arity exp2 in + let rb = mcode rb in + make_exp expr tgt arity (Ast0.ArrayAccess(exp1,lb,exp2,rb)) + | Ast0.RecordAccess(exp,pt,field) -> + let arity = exp_same (mcode2line pt) [mcode2arity pt] in + let exp = expression arity exp in + let pt = mcode pt in + let field = ident false arity field in + make_exp expr tgt arity (Ast0.RecordAccess(exp,pt,field)) + | Ast0.RecordPtAccess(exp,ar,field) -> + let arity = exp_same (mcode2line ar) [mcode2arity ar] in + let exp = expression arity exp in + let ar = mcode ar in + let field = ident false arity field in + make_exp expr tgt arity (Ast0.RecordPtAccess(exp,ar,field)) + | Ast0.Cast(lp,ty,rp,exp) -> + let arity = exp_same (mcode2line lp) [mcode2arity lp;mcode2arity rp] in + let lp = mcode lp in + let ty = typeC arity ty in + let rp = mcode rp in + let exp = expression arity exp in + make_exp expr tgt arity (Ast0.Cast(lp,ty,rp,exp)) + | Ast0.SizeOfExpr(szf,exp) -> + let arity = exp_same (mcode2line szf) [mcode2arity szf] in + let szf = mcode szf in + let exp = expression arity exp in + make_exp expr tgt arity (Ast0.SizeOfExpr(szf,exp)) + | Ast0.SizeOfType(szf,lp,ty,rp) -> + let arity = + exp_same (mcode2line szf) (List.map mcode2arity [szf;lp;rp]) in + let szf = mcode szf in + let lp = mcode lp in + let ty = typeC arity ty in + let rp = mcode rp in + make_exp expr tgt arity (Ast0.SizeOfType(szf,lp,ty,rp)) + | Ast0.TypeExp(ty) -> Ast0.rewrap expr (Ast0.TypeExp(typeC tgt ty)) + | Ast0.MetaErr(name,constraints,pure) -> + let arity = exp_same (mcode2line name) [mcode2arity name] in + let name = mcode name in + make_exp expr tgt arity (Ast0.MetaErr(name,constraints,pure)) + | Ast0.MetaExpr(name,constraints,ty,form,pure) -> + let arity = exp_same (mcode2line name) [mcode2arity name] in + let name = mcode name in + make_exp expr tgt arity (Ast0.MetaExpr(name,constraints,ty,form,pure)) + | Ast0.MetaExprList(name,lenname,pure) -> + let arity = exp_same (mcode2line name) [mcode2arity name] in + let name = mcode name in + make_exp expr tgt arity (Ast0.MetaExprList(name,lenname,pure)) + | Ast0.EComma(cm) -> + let arity = exp_same (mcode2line cm) [mcode2arity cm] in + let cm = mcode cm in + make_exp expr tgt arity (Ast0.EComma(cm)) + | Ast0.DisjExpr(starter,exps,mids,ender) -> + let exps = List.map (top_expression opt_allowed tgt) exps in + (match List.rev exps with + _::xs -> + if anyopt xs (function Ast0.OptExp(_) -> true | _ -> false) + then fail expr "opt only allowed in the last disjunct" + | _ -> ()); + Ast0.rewrap expr (Ast0.DisjExpr(starter,exps,mids,ender)) + | Ast0.NestExpr(starter,exp_dots,ender,whencode,multi) -> + let res = + Ast0.NestExpr(starter, + dots (top_expression true Ast0.NONE) exp_dots, + ender,whencode,multi) in + Ast0.rewrap expr res + | Ast0.Edots(dots,whencode) -> + let arity = exp_same (mcode2line dots) [mcode2arity dots] in + let dots = mcode dots in + let whencode = get_option (expression Ast0.NONE) whencode in + make_exp expr tgt arity (Ast0.Edots(dots,whencode)) + | Ast0.Ecircles(dots,whencode) -> + let arity = exp_same (mcode2line dots) [mcode2arity dots] in + let dots = mcode dots in + let whencode = get_option (expression Ast0.NONE) whencode in + make_exp expr tgt arity (Ast0.Ecircles(dots,whencode)) + | Ast0.Estars(dots,whencode) -> + let arity = exp_same (mcode2line dots) [mcode2arity dots] in + let dots = mcode dots in + let whencode = get_option (expression Ast0.NONE) whencode in + make_exp expr tgt arity (Ast0.Estars(dots,whencode)) + | Ast0.OptExp(_) | Ast0.UniqueExp(_) -> + failwith "unexpected code" + +and expression tgt exp = top_expression false tgt exp + +(* --------------------------------------------------------------------- *) +(* Types *) + +and make_typeC = + make_opt_unique + (function x -> Ast0.OptType x) + (function x -> Ast0.UniqueType x) + +and top_typeC tgt opt_allowed typ = + match Ast0.unwrap typ with + Ast0.ConstVol(cv,ty) -> + let arity = all_same opt_allowed tgt (mcode2line cv) + [mcode2arity cv] in + let cv = mcode cv in + let ty = typeC arity ty in + make_typeC typ tgt arity (Ast0.ConstVol(cv,ty)) + | Ast0.BaseType(ty,Some sign) -> + let arity = + all_same opt_allowed tgt (mcode2line ty) + [mcode2arity ty; mcode2arity sign] in + let ty = mcode ty in + let sign = mcode sign in + make_typeC typ tgt arity (Ast0.BaseType(ty,Some sign)) + | Ast0.BaseType(ty,None) -> + let arity = + all_same opt_allowed tgt (mcode2line ty) [mcode2arity ty] in + let ty = mcode ty in + make_typeC typ tgt arity (Ast0.BaseType(ty,None)) + | Ast0.ImplicitInt(sign) -> + let arity = + all_same opt_allowed tgt (mcode2line sign) [mcode2arity sign] in + let sign = mcode sign in + make_typeC typ tgt arity (Ast0.ImplicitInt(sign)) + | Ast0.Pointer(ty,star) -> + let arity = + all_same opt_allowed tgt (mcode2line star) [mcode2arity star] in + let ty = typeC arity ty in + let star = mcode star in + make_typeC typ tgt arity (Ast0.Pointer(ty,star)) + | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> + let arity = + all_same opt_allowed tgt (mcode2line lp1) + (List.map mcode2arity [lp1;star;rp1;lp2;rp2]) in + let ty = typeC arity ty in + let params = parameter_list tgt params in + make_typeC typ tgt arity + (Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2)) + | Ast0.FunctionType(ty,lp1,params,rp1) -> + let arity = + all_same opt_allowed tgt (mcode2line lp1) + (List.map mcode2arity [lp1;rp1]) in + let ty = get_option (typeC arity) ty in + let params = parameter_list tgt params in + make_typeC typ tgt arity (Ast0.FunctionType(ty,lp1,params,rp1)) + | Ast0.Array(ty,lb,size,rb) -> + let arity = + all_same opt_allowed tgt (mcode2line lb) + [mcode2arity lb;mcode2arity rb] in + let ty = typeC arity ty in + let lb = mcode lb in + let size = get_option (expression arity) size in + let rb = mcode rb in + make_typeC typ tgt arity (Ast0.Array(ty,lb,size,rb)) + | Ast0.StructUnionName(kind,name) -> + let arity = + all_same opt_allowed tgt (mcode2line kind) + [mcode2arity kind] in + let kind = mcode kind in + let name = get_option (ident false arity) name in + make_typeC typ tgt arity (Ast0.StructUnionName(kind,name)) + | Ast0.StructUnionDef(ty,lb,decls,rb) -> + let arity = + all_same opt_allowed tgt (mcode2line lb) + (List.map mcode2arity [lb;rb]) in + let ty = typeC arity ty in + let lb = mcode lb in + let decls = dots (declaration tgt) decls in + let rb = mcode rb in + make_typeC typ tgt arity (Ast0.StructUnionDef(ty,lb,decls,rb)) + | Ast0.TypeName(name) -> + let arity = + all_same opt_allowed tgt (mcode2line name) [mcode2arity name] in + let name = mcode name in + make_typeC typ tgt arity (Ast0.TypeName(name)) + | Ast0.MetaType(name,pure) -> + let arity = + all_same opt_allowed tgt (mcode2line name) [mcode2arity name] in + let name = mcode name in + make_typeC typ tgt arity (Ast0.MetaType(name,pure)) + | Ast0.DisjType(starter,types,mids,ender) -> + let types = List.map (typeC tgt) types in + (match List.rev types with + _::xs -> + if anyopt xs (function Ast0.OptType(_) -> true | _ -> false) + then fail typ "opt only allowed in the last disjunct" + | _ -> ()); + let res = Ast0.DisjType(starter,types,mids,ender) in + Ast0.rewrap typ res + | Ast0.OptType(_) | Ast0.UniqueType(_) -> + failwith "unexpected code" + +and typeC tgt ty = top_typeC tgt false 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 make_decl = + make_opt_unique + (function x -> Ast0.OptDecl x) + (function x -> Ast0.UniqueDecl x) + +and declaration tgt decl = + match Ast0.unwrap decl with + Ast0.Init(stg,ty,id,eq,exp,sem) -> + let arity = + all_same true tgt (mcode2line eq) + ((match stg with None -> [] | Some x -> [mcode2arity x]) @ + (List.map mcode2arity [eq;sem])) in + let stg = get_option mcode stg in + let ty = typeC arity ty in + let id = ident false arity id in + let eq = mcode eq in + let exp = initialiser arity exp in + let sem = mcode sem in + make_decl decl tgt arity (Ast0.Init(stg,ty,id,eq,exp,sem)) + | Ast0.UnInit(stg,ty,id,sem) -> + let arity = + all_same true tgt (mcode2line sem) + ((match stg with None -> [] | Some x -> [mcode2arity x]) @ + [mcode2arity sem]) in + let stg = get_option mcode stg in + let ty = typeC arity ty in + let id = ident false arity id in + let sem = mcode sem in + make_decl decl tgt arity (Ast0.UnInit(stg,ty,id,sem)) + | Ast0.MacroDecl(name,lp,args,rp,sem) -> + let arity = + all_same true tgt (mcode2line lp) (List.map mcode2arity [lp;rp;sem]) in + let name = ident false arity name in + let lp = mcode lp in + let args = dots (expression arity) args in + let rp = mcode rp in + let sem = mcode sem in + make_decl decl tgt arity (Ast0.MacroDecl(name,lp,args,rp,sem)) + | Ast0.TyDecl(ty,sem) -> + let arity = + all_same true tgt (mcode2line sem) [mcode2arity sem] in + let ty = typeC arity ty in + let sem = mcode sem in + make_decl decl tgt arity (Ast0.TyDecl(ty,sem)) + | Ast0.Typedef(stg,ty,id,sem) -> + let arity = + all_same true tgt (mcode2line sem) + [mcode2arity stg;mcode2arity sem] in + let stg = mcode stg in + let ty = typeC arity ty in + let id = typeC arity id in + let sem = mcode sem in + make_decl decl tgt arity (Ast0.Typedef(stg,ty,id,sem)) + | Ast0.DisjDecl(starter,decls,mids,ender) -> + let decls = List.map (declaration tgt) decls in + (match List.rev decls with + _::xs -> + if anyopt xs (function Ast0.OptDecl(_) -> true | _ -> false) + then fail decl "opt only allowed in the last disjunct" + | _ -> ()); + let res = Ast0.DisjDecl(starter,decls,mids,ender) in + Ast0.rewrap decl res + | Ast0.Ddots(dots,whencode) -> + let arity = all_same true tgt (mcode2line dots) [mcode2arity dots] in + let dots = mcode dots in + let whencode = get_option (declaration Ast0.NONE) whencode in + make_decl decl tgt arity (Ast0.Ddots(dots,whencode)) + | Ast0.OptDecl(_) | Ast0.UniqueDecl(_) -> + failwith "unexpected code" + +(* --------------------------------------------------------------------- *) +(* Initializer *) + +and make_init = + make_opt_unique + (function x -> Ast0.OptIni x) + (function x -> Ast0.UniqueIni x) + +and initialiser tgt i = + let init_same = all_same true tgt in + match Ast0.unwrap i with + Ast0.InitExpr(exp) -> + Ast0.rewrap i (Ast0.InitExpr(expression tgt exp)) + | Ast0.InitList(lb,initlist,rb) -> + let arity = init_same (mcode2line lb) [mcode2arity lb; mcode2arity rb] in + let lb = mcode lb in + let initlist = dots (initialiser arity) initlist in + let rb = mcode rb in + make_init i tgt arity (Ast0.InitList(lb,initlist,rb)) + | Ast0.InitGccDotName(dot,name,eq,ini) -> + let arity = + init_same (mcode2line dot) [mcode2arity dot; mcode2arity eq] in + let dot = mcode dot in + let name = ident true arity name in + let eq = mcode eq in + let ini = initialiser arity ini in + make_init i tgt arity (Ast0.InitGccDotName(dot,name,eq,ini)) + | Ast0.InitGccName(name,eq,ini) -> + let arity = init_same (mcode2line eq) [mcode2arity eq] in + let name = ident true arity name in + let eq = mcode eq in + let ini = initialiser arity ini in + make_init i tgt arity (Ast0.InitGccName(name,eq,ini)) + | Ast0.InitGccIndex(lb,exp,rb,eq,ini) -> + let arity = + init_same (mcode2line lb) + [mcode2arity lb; mcode2arity rb; mcode2arity eq] in + let lb = mcode lb in + let exp = expression arity exp in + let rb = mcode rb in + let eq = mcode eq in + let ini = initialiser arity ini in + make_init i tgt arity (Ast0.InitGccIndex(lb,exp,rb,eq,ini)) + | Ast0.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini) -> + let arity = + init_same (mcode2line lb) + [mcode2arity lb; mcode2arity dots; mcode2arity rb; mcode2arity eq] in + let lb = mcode lb in + let exp1 = expression arity exp1 in + let dots = mcode dots in + let exp2 = expression arity exp2 in + let rb = mcode rb in + let eq = mcode eq in + let ini = initialiser arity ini in + make_init i tgt arity + (Ast0.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini)) + | Ast0.IComma(cm) -> + let arity = init_same (mcode2line cm) [mcode2arity cm] in + let cm = mcode cm in + make_init i tgt arity (Ast0.IComma(cm)) + | Ast0.Idots(dots,whencode) -> + let arity = init_same (mcode2line dots) [mcode2arity dots] in + let dots = mcode dots in + let whencode = get_option (initialiser Ast0.NONE) whencode in + make_init i tgt arity (Ast0.Idots(dots,whencode)) + | Ast0.OptIni(_) | Ast0.UniqueIni(_) -> + failwith "unexpected code" + +(* --------------------------------------------------------------------- *) +(* Parameter *) + +and make_param = + make_opt_unique + (function x -> Ast0.OptParam x) + (function x -> Ast0.UniqueParam x) + +and parameterTypeDef tgt param = + let param_same = all_same true tgt in + match Ast0.unwrap param with + Ast0.VoidParam(ty) -> Ast0.rewrap param (Ast0.VoidParam(typeC tgt ty)) + | Ast0.Param(ty,Some id) -> + let ty = top_typeC tgt true ty in + let id = ident true tgt id in + Ast0.rewrap param + (match (Ast0.unwrap ty,Ast0.unwrap id) with + (Ast0.OptType(ty),Ast0.OptIdent(id)) -> + Ast0.OptParam(Ast0.rewrap param (Ast0.Param(ty,Some id))) + | (Ast0.UniqueType(ty),Ast0.UniqueIdent(id)) -> + Ast0.UniqueParam(Ast0.rewrap param (Ast0.Param(ty,Some id))) + | (Ast0.OptType(ty),_) -> + fail param "arity mismatch in param declaration" + | (_,Ast0.OptIdent(id)) -> + fail param "arity mismatch in param declaration" + | _ -> Ast0.Param(ty,Some id)) + | Ast0.Param(ty,None) -> + let ty = top_typeC tgt true ty in + Ast0.rewrap param + (match Ast0.unwrap ty with + Ast0.OptType(ty) -> + Ast0.OptParam(Ast0.rewrap param (Ast0.Param(ty,None))) + | Ast0.UniqueType(ty) -> + Ast0.UniqueParam(Ast0.rewrap param (Ast0.Param(ty,None))) + | _ -> Ast0.Param(ty,None)) + | Ast0.MetaParam(name,pure) -> + let arity = param_same (mcode2line name) [mcode2arity name] in + let name = mcode name in + make_param param tgt arity (Ast0.MetaParam(name,pure)) + | Ast0.MetaParamList(name,lenname,pure) -> + let arity = param_same (mcode2line name) [mcode2arity name] in + let name = mcode name in + make_param param tgt arity (Ast0.MetaParamList(name,lenname,pure)) + | Ast0.PComma(cm) -> + let arity = param_same (mcode2line cm) [mcode2arity cm] in + let cm = mcode cm in + make_param param tgt arity (Ast0.PComma(cm)) + | Ast0.Pdots(dots) -> + let arity = param_same (mcode2line dots) [mcode2arity dots] in + let dots = mcode dots in + make_param param tgt arity (Ast0.Pdots(dots)) + | Ast0.Pcircles(dots) -> + let arity = param_same (mcode2line dots) [mcode2arity dots] in + let dots = mcode dots in + make_param param tgt arity (Ast0.Pcircles(dots)) + | Ast0.OptParam(_) | Ast0.UniqueParam(_) -> + failwith "unexpected code" + +and parameter_list tgt = dots (parameterTypeDef tgt) + +(* --------------------------------------------------------------------- *) +(* Top-level code *) + +and make_rule_elem x = + make_opt_unique + (function x -> Ast0.OptStm x) + (function x -> Ast0.UniqueStm x) + x + +and statement tgt stm = + let stm_same = all_same true tgt in + match Ast0.unwrap stm with + Ast0.Decl(bef,decl) -> + let new_decl = declaration tgt decl in + Ast0.rewrap stm + (match Ast0.unwrap new_decl with + Ast0.OptDecl(decl) -> + Ast0.OptStm(Ast0.rewrap stm (Ast0.Decl(bef,decl))) + | Ast0.UniqueDecl(decl) -> + Ast0.UniqueStm(Ast0.rewrap stm (Ast0.Decl(bef,decl))) + | _ -> Ast0.Decl(bef,new_decl)) + | Ast0.Seq(lbrace,body,rbrace) -> + let arity = + stm_same (mcode2line lbrace) + [mcode2arity lbrace; mcode2arity rbrace] in + let lbrace = mcode lbrace in + let body = dots (statement arity) body in + let rbrace = mcode rbrace in + make_rule_elem stm tgt arity (Ast0.Seq(lbrace,body,rbrace)) + | Ast0.ExprStatement(exp,sem) -> + let arity = stm_same (mcode2line sem) [mcode2arity sem] in + let exp = expression arity exp in + let sem = mcode sem in + make_rule_elem stm tgt arity (Ast0.ExprStatement(exp,sem)) + | Ast0.IfThen(iff,lp,exp,rp,branch,aft) -> + let arity = + stm_same (mcode2line iff) (List.map mcode2arity [iff;lp;rp]) in + let iff = mcode iff in + let lp = mcode lp in + let exp = expression arity exp in + let rp = mcode rp in + let branch = statement arity branch in + make_rule_elem stm tgt arity (Ast0.IfThen(iff,lp,exp,rp,branch,aft)) + | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,aft) -> + let arity = + stm_same (mcode2line iff) (List.map mcode2arity [iff;lp;rp;els]) in + let iff = mcode iff in + let lp = mcode lp in + let exp = expression arity exp in + let rp = mcode rp in + let branch1 = statement arity branch1 in + let els = mcode els in + let branch2 = statement arity branch2 in + make_rule_elem stm tgt arity + (Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,aft)) + | Ast0.While(wh,lp,exp,rp,body,aft) -> + let arity = + stm_same (mcode2line wh) + (List.map mcode2arity [wh;lp;rp]) in + let wh = mcode wh in + let lp = mcode lp in + let exp = expression arity exp in + let rp = mcode rp in + let body = statement arity body in + make_rule_elem stm tgt arity (Ast0.While(wh,lp,exp,rp,body,aft)) + | Ast0.Do(d,body,wh,lp,exp,rp,sem) -> + let arity = + stm_same (mcode2line wh) (List.map mcode2arity [d;wh;lp;rp;sem]) in + let d = mcode d in + let body = statement arity body in + let wh = mcode wh in + let lp = mcode lp in + let exp = expression arity exp in + let rp = mcode rp in + let sem = mcode sem in + make_rule_elem stm tgt arity (Ast0.Do(d,body,wh,lp,exp,rp,sem)) + | Ast0.For(fr,lp,exp1,sem1,exp2,sem2,exp3,rp,body,aft) -> + let arity = + stm_same (mcode2line fr) (List.map mcode2arity [fr;lp;sem1;sem2;rp]) in + let fr = mcode fr in + let lp = mcode lp in + let exp1 = get_option (expression arity) exp1 in + let sem1 = mcode sem1 in + let exp2 = get_option (expression arity) exp2 in + let sem2= mcode sem2 in + let exp3 = get_option (expression arity) exp3 in + let rp = mcode rp in + let body = statement arity body in + make_rule_elem stm tgt arity + (Ast0.For(fr,lp,exp1,sem1,exp2,sem2,exp3,rp,body,aft)) + | Ast0.Iterator(nm,lp,args,rp,body,aft) -> + let arity = stm_same (mcode2line lp) (List.map mcode2arity [lp;rp]) in + let nm = ident false arity nm in + let lp = mcode lp in + let args = dots (expression arity) args in + let rp = mcode rp in + let body = statement arity body in + make_rule_elem stm tgt arity (Ast0.Iterator(nm,lp,args,rp,body,aft)) + | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) -> + let arity = + stm_same (mcode2line switch) + (List.map mcode2arity [switch;lp;rp;lb;rb]) in + let switch = mcode switch in + let lp = mcode lp in + let exp = expression arity exp in + let rp = mcode rp in + let lb = mcode lb in + let cases = dots (case_line arity) cases in + let rb = mcode rb in + make_rule_elem stm tgt arity + (Ast0.Switch(switch,lp,exp,rp,lb,cases,rb)) + | Ast0.Break(br,sem) -> + let arity = stm_same (mcode2line br) (List.map mcode2arity [br;sem]) in + let br = mcode br in + let sem = mcode sem in + make_rule_elem stm tgt arity (Ast0.Break(br,sem)) + | Ast0.Continue(cont,sem) -> + let arity = + stm_same (mcode2line cont) (List.map mcode2arity [cont;sem]) in + let cont = mcode cont in + let sem = mcode sem in + make_rule_elem stm tgt arity (Ast0.Continue(cont,sem)) + | Ast0.Label(l,dd) -> + let arity = mcode2arity dd in + let l = ident false tgt l in + let dd = mcode dd in + make_rule_elem stm tgt arity (Ast0.Label(l,dd)) + | Ast0.Goto(goto,l,sem) -> + let arity = + stm_same (mcode2line goto) (List.map mcode2arity [goto;sem]) in + let goto = mcode goto in + let l = ident false tgt l in + let sem = mcode sem in + make_rule_elem stm tgt arity (Ast0.Goto(goto,l,sem)) + | Ast0.Return(ret,sem) -> + let arity = stm_same (mcode2line ret) (List.map mcode2arity [ret;sem]) in + let ret = mcode ret in + let sem = mcode sem in + make_rule_elem stm tgt arity (Ast0.Return(ret,sem)) + | Ast0.ReturnExpr(ret,exp,sem) -> + let arity = stm_same (mcode2line ret) (List.map mcode2arity [ret;sem]) in + let ret = mcode ret in + let exp = expression arity exp in + let sem = mcode sem in + make_rule_elem stm tgt arity (Ast0.ReturnExpr(ret,exp,sem)) + | Ast0.MetaStmt(name,pure) -> + let arity = stm_same (mcode2line name) [mcode2arity name] in + let name = mcode name in + make_rule_elem stm tgt arity (Ast0.MetaStmt(name,pure)) + | Ast0.MetaStmtList(name,pure) -> + let arity = stm_same (mcode2line name) [mcode2arity name] in + let name = mcode name in + make_rule_elem stm tgt arity (Ast0.MetaStmtList(name,pure)) + | Ast0.Exp(exp) -> + let new_exp = top_expression true tgt exp in + Ast0.rewrap stm + (match Ast0.unwrap new_exp with + Ast0.OptExp(exp) -> + Ast0.OptStm(Ast0.rewrap stm (Ast0.Exp(exp))) + | Ast0.UniqueExp(exp) -> + Ast0.UniqueStm(Ast0.rewrap stm (Ast0.Exp(exp))) + | _ -> Ast0.Exp(new_exp)) + | Ast0.TopExp(exp) -> + let new_exp = top_expression true tgt exp in + Ast0.rewrap stm + (match Ast0.unwrap new_exp with + Ast0.OptExp(exp) -> + Ast0.OptStm(Ast0.rewrap stm (Ast0.TopExp(exp))) + | Ast0.UniqueExp(exp) -> + Ast0.UniqueStm(Ast0.rewrap stm (Ast0.TopExp(exp))) + | _ -> Ast0.TopExp(new_exp)) + | Ast0.Ty(ty) -> + let new_ty = typeC tgt ty in (* opt makes no sense alone at top level *) + Ast0.rewrap stm + (match Ast0.unwrap new_ty with + Ast0.OptType(ty) -> + Ast0.OptStm(Ast0.rewrap stm (Ast0.Ty(ty))) + | Ast0.UniqueType(ty) -> + Ast0.UniqueStm(Ast0.rewrap stm (Ast0.Ty(ty))) + | _ -> Ast0.Ty(new_ty)) + | Ast0.Disj(starter,rule_elem_dots_list,mids,ender) -> + let stms = + List.map (function x -> concat_dots (statement tgt) x) + rule_elem_dots_list in + let (found_opt,unopt) = + List.fold_left + (function (found_opt,lines) -> + function x -> + let rebuild l = + (* previously just checked the last thing in the list, + but everything should be optional for the whole thing to + be optional *) + let is_opt x = + match Ast0.unwrap x with + Ast0.OptStm(x) -> true + | _ -> false in + let unopt x = + match Ast0.unwrap x with + Ast0.OptStm(x) -> x + | _ -> x in + if List.for_all is_opt l + then (true,List.map unopt l) + else (false, l) in + let (l,k) = + match Ast0.unwrap x with + Ast0.DOTS(l) -> + (l,function l -> Ast0.rewrap x (Ast0.DOTS l)) + | Ast0.CIRCLES(l) -> + (l,function l -> Ast0.rewrap x (Ast0.CIRCLES l)) + | Ast0.STARS(l) -> + (l,function l -> Ast0.rewrap x (Ast0.STARS l)) in + let (found_opt,l) = rebuild l in + (found_opt,(k l)::lines)) + (false,[]) stms in + let unopt = List.rev unopt in + if found_opt + then + make_rule_elem stm tgt Ast0.OPT (Ast0.Disj(starter,unopt,mids,ender)) + else Ast0.rewrap stm (Ast0.Disj(starter,stms,mids,ender)) + | Ast0.Nest(starter,rule_elem_dots,ender,whn,multi) -> + let new_rule_elem_dots = + concat_dots (statement Ast0.NONE) rule_elem_dots in + let whn = + List.map + (whencode (concat_dots (statement Ast0.NONE)) (statement Ast0.NONE)) + whn in + Ast0.rewrap stm + (Ast0.Nest(starter,new_rule_elem_dots,ender,whn,multi)) + | Ast0.Dots(dots,whn) -> + let arity = stm_same (mcode2line dots) [mcode2arity dots] in + let dots = mcode dots in + let whn = + List.map + (whencode (concat_dots (statement Ast0.NONE)) (statement Ast0.NONE)) + whn in + make_rule_elem stm tgt arity (Ast0.Dots(dots,whn)) + | Ast0.Circles(dots,whn) -> + let arity = stm_same (mcode2line dots) [mcode2arity dots] in + let dots = mcode dots in + let whn = + List.map + (whencode (concat_dots (statement Ast0.NONE)) (statement Ast0.NONE)) + whn in + make_rule_elem stm tgt arity (Ast0.Circles(dots,whn)) + | Ast0.Stars(dots,whn) -> + let arity = stm_same (mcode2line dots) [mcode2arity dots] in + let dots = mcode dots in + let whn = + List.map + (whencode (concat_dots (statement Ast0.NONE)) (statement Ast0.NONE)) + whn in + make_rule_elem stm tgt arity (Ast0.Stars(dots,whn)) + | Ast0.FunDecl(bef,fi,name,lp,params,rp,lbrace,body,rbrace) -> + let arity = + all_same true tgt (mcode2line lp) + ((List.map mcode2arity [lp;rp;lbrace;rbrace]) @ (fninfo2arity fi)) in + let fi = List.map (fninfo arity) fi in + let name = ident false arity name in + let lp = mcode lp in + let params = parameter_list arity params in + let rp = mcode rp in + let lbrace = mcode lbrace in + let body = dots (statement arity) body in + let rbrace = mcode rbrace in + make_rule_elem stm tgt arity + (Ast0.FunDecl(bef,fi,name,lp,params,rp,lbrace,body,rbrace)) + | Ast0.Include(inc,s) -> + let arity = + all_same true tgt (mcode2line inc) [mcode2arity inc; mcode2arity s] in + let inc = mcode inc in + let s = mcode s in + make_rule_elem stm tgt arity (Ast0.Include(inc,s)) + | Ast0.Define(def,id,params,body) -> + let arity = all_same true tgt (mcode2line def) [mcode2arity def] in + let def = mcode def in + let id = ident false arity id in + let params = define_parameters arity params in + let body = dots (statement arity) body in + make_rule_elem stm tgt arity (Ast0.Define(def,id,params,body)) + | Ast0.OptStm(_) | Ast0.UniqueStm(_) -> + failwith "unexpected code" + +and define_parameters tgt params = + match Ast0.unwrap params with + Ast0.NoParams -> params + | Ast0.DParams(lp,params,rp) -> + let arity = + all_same true tgt (mcode2line lp) [mcode2arity lp;mcode2arity rp] in + let lp = mcode lp in + let params = dots (define_param arity) params in + let rp = mcode rp in + Ast0.rewrap params (Ast0.DParams(lp,params,rp)) + +and make_define_param x = + make_opt_unique + (function x -> Ast0.OptDParam x) + (function x -> Ast0.UniqueDParam x) + x + +and define_param tgt param = + match Ast0.unwrap param with + Ast0.DParam(id) -> + let new_id = ident true tgt id in + Ast0.rewrap param + (match Ast0.unwrap new_id with + Ast0.OptIdent(id) -> + Ast0.OptDParam(Ast0.rewrap param (Ast0.DParam(id))) + | Ast0.UniqueIdent(decl) -> + Ast0.UniqueDParam(Ast0.rewrap param (Ast0.DParam(id))) + | _ -> Ast0.DParam(new_id)) + | Ast0.DPComma(cm) -> + let arity = + all_same true tgt (mcode2line cm) [mcode2arity cm] in + let cm = mcode cm in + make_define_param param tgt arity (Ast0.DPComma(cm)) + | Ast0.DPdots(dots) -> + let arity = + all_same true tgt (mcode2line dots) [mcode2arity dots] in + let dots = mcode dots in + make_define_param param tgt arity (Ast0.DPdots(dots)) + | Ast0.DPcircles(circles) -> + let arity = + all_same true tgt (mcode2line circles) [mcode2arity circles] in + let circles = mcode circles in + make_define_param param tgt arity (Ast0.DPcircles(circles)) + | Ast0.OptDParam(dp) | Ast0.UniqueDParam(dp) -> + failwith "unexpected code" + +and fninfo arity = function + Ast0.FStorage(stg) -> Ast0.FStorage(mcode stg) + | Ast0.FType(ty) -> Ast0.FType(typeC arity ty) + | Ast0.FInline(inline) -> Ast0.FInline(mcode inline) + | Ast0.FAttr(attr) -> Ast0.FAttr(mcode attr) + +and fninfo2arity fninfo = + List.concat + (List.map + (function + Ast0.FStorage(stg) -> [mcode2arity stg] + | Ast0.FType(ty) -> [] + | Ast0.FInline(inline) -> [mcode2arity inline] + | Ast0.FAttr(attr) -> [mcode2arity attr]) + fninfo) + +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) + +and make_case_line = + make_opt_unique + (function x -> Ast0.OptCase x) + (function x -> failwith "unique not allowed for case_line") + +and case_line tgt c = + match Ast0.unwrap c with + Ast0.Default(def,colon,code) -> + let arity = + all_same true tgt (mcode2line def) + [mcode2arity def; mcode2arity colon] in + let def = mcode def in + let colon = mcode colon in + let code = dots (statement arity) code in + make_case_line c tgt arity (Ast0.Default(def,colon,code)) + | Ast0.Case(case,exp,colon,code) -> + let arity = + all_same true tgt (mcode2line case) + [mcode2arity case; mcode2arity colon] in + let case = mcode case in + let exp = expression arity exp in + let colon = mcode colon in + let code = dots (statement arity) code in + make_case_line c tgt arity (Ast0.Case(case,exp,colon,code)) + | Ast0.OptCase(_) -> failwith "unexpected OptCase" + +(* --------------------------------------------------------------------- *) +(* Function declaration *) +(* Haven't thought much about arity here... *) + +let top_level tgt t = + Ast0.rewrap t + (match Ast0.unwrap t with + Ast0.FILEINFO(old_file,new_file) -> + if mcode2arity old_file = Ast0.NONE && mcode2arity new_file = Ast0.NONE + then Ast0.FILEINFO(mcode old_file,mcode new_file) + else fail t "unexpected arity for file info" + | Ast0.DECL(stmt) -> + Ast0.DECL(statement tgt stmt) + | Ast0.CODE(rule_elem_dots) -> + Ast0.CODE(concat_dots (statement tgt) rule_elem_dots) + | Ast0.ERRORWORDS(exps) -> + Ast0.ERRORWORDS(List.map (top_expression false Ast0.NONE) exps) + | Ast0.OTHER(_) -> fail t "eliminated by top_level") + +let rule tgt = List.map (top_level tgt) + +(* --------------------------------------------------------------------- *) +(* Entry points *) + +let minus_arity code = + rule Ast0.NONE code diff --git a/parsing_cocci/.#arity.ml.1.82 b/parsing_cocci/.#arity.ml.1.82 new file mode 100644 index 0000000..cb31690 --- /dev/null +++ b/parsing_cocci/.#arity.ml.1.82 @@ -0,0 +1,1060 @@ +(* +* 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. +*) + + +(* Arities matter for the minus slice, but not for the plus slice. *) + +(* ? only allowed on rule_elems, and on subterms if the context is ? also. *) + +module Ast0 = Ast0_cocci +module Ast = Ast_cocci + +(* --------------------------------------------------------------------- *) + +let warning s = Printf.printf "warning: %s\n" s + +let fail w str = + failwith + (Printf.sprintf "cocci line %d: %s" ((Ast0.get_info w).Ast0.line_start) + str) + +let make_opt_unique optfn uniquefn info tgt arity term = + let term = Ast0.rewrap info term in + if tgt = arity + then term + else (* tgt must be NONE *) + match arity with + Ast0.OPT -> Ast0.copywrap info (optfn term) + | Ast0.UNIQUE -> Ast0.copywrap info (uniquefn term) + | Ast0.NONE -> failwith "tgt must be NONE" + +let all_same opt_allowed tgt line arities = + let tgt = + match tgt with + Ast0.NONE -> + (match List.hd arities with + Ast0.OPT when not opt_allowed -> + failwith "opt only allowed for the elements of a statement list" + | x -> x) + | _ -> tgt in + if not(List.for_all (function x -> x = tgt) arities) + then warning (Printf.sprintf "incompatible arity found on line %d" line); + tgt + +let get_option fn = function + None -> None + | Some x -> Some (fn x) + +let anyopt l fn = List.exists (function w -> fn(Ast0.unwrap w)) l + +let allopt l fn = + let rec loop = function + [] -> [] + | x::xs -> + match fn (Ast0.unwrap x) with + Some x -> x :: (loop xs) + | None -> [] in + let res = loop l in + if List.length res = List.length l then Some res else None + +(* --------------------------------------------------------------------- *) +(* --------------------------------------------------------------------- *) +(* Mcode *) + +let mcode2line (_,_,info,_,_) = info.Ast0.line_start +let mcode2arity (_,arity,_,_,_) = arity + +let mcode x = x (* nothing to do ... *) + +(* --------------------------------------------------------------------- *) +(* Dots *) + +let dots fn d = + Ast0.rewrap d + (match Ast0.unwrap d with + Ast0.DOTS(x) -> Ast0.DOTS(List.map fn x) + | Ast0.CIRCLES(x) -> Ast0.CIRCLES(List.map fn x) + | Ast0.STARS(x) -> Ast0.STARS(List.map fn x)) + +let only_dots l = + not + (List.exists + (function x -> + match Ast0.unwrap x with + Ast0.Circles(_,_) | Ast0.Stars(_,_) -> true + | _ -> false) + l) + +let only_circles l = + not (List.exists + (function x -> + match Ast0.unwrap x with + Ast0.Dots(_,_) | Ast0.Stars(_,_) -> true + | _ -> false) + l) + +let only_stars l = + not (List.exists + (function x -> + match Ast0.unwrap x with + Ast0.Dots(_,_) | Ast0.Circles(_,_) -> true + | _ -> false) + l) + +let concat_dots fn d = + Ast0.rewrap d + (match Ast0.unwrap d with + Ast0.DOTS(x) -> + let l = List.map fn x in + if only_dots l + then Ast0.DOTS(l) + else fail d "inconsistent dots usage" + | Ast0.CIRCLES(x) -> + let l = List.map fn x in + if only_circles l + then Ast0.CIRCLES(l) + else fail d "inconsistent dots usage" + | Ast0.STARS(x) -> + let l = List.map fn x in + if only_stars l + then Ast0.STARS(l) + else fail d "inconsistent dots usage") + +let flat_concat_dots fn d = + match Ast0.unwrap d with + Ast0.DOTS(x) -> List.map fn x + | Ast0.CIRCLES(x) -> List.map fn x + | Ast0.STARS(x) -> List.map fn x + +(* --------------------------------------------------------------------- *) +(* Identifier *) + +let make_id = + make_opt_unique + (function x -> Ast0.OptIdent x) + (function x -> Ast0.UniqueIdent x) + +let ident opt_allowed tgt i = + match Ast0.unwrap i with + Ast0.Id(name) -> + let arity = + all_same opt_allowed tgt (mcode2line name) + [mcode2arity name] in + let name = mcode name in + make_id i tgt arity (Ast0.Id(name)) + | Ast0.MetaId(name,constraints,pure) -> + let arity = + all_same opt_allowed tgt (mcode2line name) + [mcode2arity name] in + let name = mcode name in + make_id i tgt arity (Ast0.MetaId(name,constraints,pure)) + | Ast0.MetaFunc(name,constraints,pure) -> + let arity = + all_same opt_allowed tgt (mcode2line name) + [mcode2arity name] in + let name = mcode name in + make_id i tgt arity (Ast0.MetaFunc(name,constraints,pure)) + | Ast0.MetaLocalFunc(name,constraints,pure) -> + let arity = + all_same opt_allowed tgt (mcode2line name) + [mcode2arity name] in + let name = mcode name in + make_id i tgt arity (Ast0.MetaLocalFunc(name,constraints,pure)) + | Ast0.OptIdent(_) | Ast0.UniqueIdent(_) -> + failwith "unexpected code" + +(* --------------------------------------------------------------------- *) +(* Expression *) + +let make_exp = + make_opt_unique + (function x -> Ast0.OptExp x) + (function x -> Ast0.UniqueExp x) + +let rec top_expression opt_allowed tgt expr = + let exp_same = all_same opt_allowed tgt in + match Ast0.unwrap expr with + Ast0.Ident(id) -> + let new_id = ident opt_allowed tgt id in + Ast0.rewrap expr + (match Ast0.unwrap new_id with + Ast0.OptIdent(id) -> + Ast0.OptExp(Ast0.rewrap expr (Ast0.Ident(id))) + | Ast0.UniqueIdent(id) -> + Ast0.UniqueExp(Ast0.rewrap expr (Ast0.Ident(id))) + | _ -> Ast0.Ident(new_id)) + | Ast0.Constant(const) -> + let arity = exp_same (mcode2line const) [mcode2arity const] in + let const = mcode const in + make_exp expr tgt arity (Ast0.Constant(const)) + | Ast0.FunCall(fn,lp,args,rp) -> + let arity = exp_same (mcode2line lp) [mcode2arity lp;mcode2arity rp] in + let fn = expression arity fn in + let lp = mcode lp in + let args = dots (expression arity) args in + let rp = mcode rp in + make_exp expr tgt arity (Ast0.FunCall(fn,lp,args,rp)) + | Ast0.Assignment(left,op,right,simple) -> + let arity = exp_same (mcode2line op) [mcode2arity op] in + let left = expression arity left in + let op = mcode op in + let right = expression arity right in + make_exp expr tgt arity (Ast0.Assignment(left,op,right,simple)) + | Ast0.CondExpr(exp1,why,exp2,colon,exp3) -> + let arity = + exp_same (mcode2line why) [mcode2arity why; mcode2arity colon] in + let exp1 = expression arity exp1 in + let why = mcode why in + let exp2 = get_option (expression arity) exp2 in + let colon = mcode colon in + let exp3 = expression arity exp3 in + make_exp expr tgt arity (Ast0.CondExpr(exp1,why,exp2,colon,exp3)) + | Ast0.Postfix(exp,op) -> + let arity = exp_same (mcode2line op) [mcode2arity op] in + let exp = expression arity exp in + let op = mcode op in + make_exp expr tgt arity (Ast0.Postfix(exp,op)) + | Ast0.Infix(exp,op) -> + let arity = exp_same (mcode2line op) [mcode2arity op] in + let exp = expression arity exp in + let op = mcode op in + make_exp expr tgt arity (Ast0.Infix(exp,op)) + | Ast0.Unary(exp,op) -> + let arity = exp_same (mcode2line op) [mcode2arity op] in + let exp = expression arity exp in + let op = mcode op in + make_exp expr tgt arity (Ast0.Unary(exp,op)) + | Ast0.Binary(left,op,right) -> + let arity = exp_same (mcode2line op) [mcode2arity op] in + let left = expression arity left in + let op = mcode op in + let right = expression arity right in + make_exp expr tgt arity (Ast0.Binary(left,op,right)) + | Ast0.Nested(left,op,right) -> failwith "nested in arity not possible" + | Ast0.Paren(lp,exp,rp) -> + let arity = exp_same (mcode2line lp) [mcode2arity lp;mcode2arity rp] in + let lp = mcode lp in + let exp = expression arity exp in + let rp = mcode rp in + make_exp expr tgt arity (Ast0.Paren(lp,exp,rp)) + | Ast0.ArrayAccess(exp1,lb,exp2,rb) -> + let arity = exp_same (mcode2line lb) [mcode2arity lb; mcode2arity rb] in + let exp1 = expression arity exp1 in + let lb = mcode lb in + let exp2 = expression arity exp2 in + let rb = mcode rb in + make_exp expr tgt arity (Ast0.ArrayAccess(exp1,lb,exp2,rb)) + | Ast0.RecordAccess(exp,pt,field) -> + let arity = exp_same (mcode2line pt) [mcode2arity pt] in + let exp = expression arity exp in + let pt = mcode pt in + let field = ident false arity field in + make_exp expr tgt arity (Ast0.RecordAccess(exp,pt,field)) + | Ast0.RecordPtAccess(exp,ar,field) -> + let arity = exp_same (mcode2line ar) [mcode2arity ar] in + let exp = expression arity exp in + let ar = mcode ar in + let field = ident false arity field in + make_exp expr tgt arity (Ast0.RecordPtAccess(exp,ar,field)) + | Ast0.Cast(lp,ty,rp,exp) -> + let arity = exp_same (mcode2line lp) [mcode2arity lp;mcode2arity rp] in + let lp = mcode lp in + let ty = typeC arity ty in + let rp = mcode rp in + let exp = expression arity exp in + make_exp expr tgt arity (Ast0.Cast(lp,ty,rp,exp)) + | Ast0.SizeOfExpr(szf,exp) -> + let arity = exp_same (mcode2line szf) [mcode2arity szf] in + let szf = mcode szf in + let exp = expression arity exp in + make_exp expr tgt arity (Ast0.SizeOfExpr(szf,exp)) + | Ast0.SizeOfType(szf,lp,ty,rp) -> + let arity = + exp_same (mcode2line szf) (List.map mcode2arity [szf;lp;rp]) in + let szf = mcode szf in + let lp = mcode lp in + let ty = typeC arity ty in + let rp = mcode rp in + make_exp expr tgt arity (Ast0.SizeOfType(szf,lp,ty,rp)) + | Ast0.TypeExp(ty) -> Ast0.rewrap expr (Ast0.TypeExp(typeC tgt ty)) + | Ast0.MetaErr(name,constraints,pure) -> + let arity = exp_same (mcode2line name) [mcode2arity name] in + let name = mcode name in + make_exp expr tgt arity (Ast0.MetaErr(name,constraints,pure)) + | Ast0.MetaExpr(name,constraints,ty,form,pure) -> + let arity = exp_same (mcode2line name) [mcode2arity name] in + let name = mcode name in + make_exp expr tgt arity (Ast0.MetaExpr(name,constraints,ty,form,pure)) + | Ast0.MetaExprList(name,lenname,pure) -> + let arity = exp_same (mcode2line name) [mcode2arity name] in + let name = mcode name in + make_exp expr tgt arity (Ast0.MetaExprList(name,lenname,pure)) + | Ast0.EComma(cm) -> + let arity = exp_same (mcode2line cm) [mcode2arity cm] in + let cm = mcode cm in + make_exp expr tgt arity (Ast0.EComma(cm)) + | Ast0.DisjExpr(starter,exps,mids,ender) -> + let exps = List.map (top_expression opt_allowed tgt) exps in + (match List.rev exps with + _::xs -> + if anyopt xs (function Ast0.OptExp(_) -> true | _ -> false) + then fail expr "opt only allowed in the last disjunct" + | _ -> ()); + Ast0.rewrap expr (Ast0.DisjExpr(starter,exps,mids,ender)) + | Ast0.NestExpr(starter,exp_dots,ender,whencode,multi) -> + let res = + Ast0.NestExpr(starter, + dots (top_expression true Ast0.NONE) exp_dots, + ender,whencode,multi) in + Ast0.rewrap expr res + | Ast0.Edots(dots,whencode) -> + let arity = exp_same (mcode2line dots) [mcode2arity dots] in + let dots = mcode dots in + let whencode = get_option (expression Ast0.NONE) whencode in + make_exp expr tgt arity (Ast0.Edots(dots,whencode)) + | Ast0.Ecircles(dots,whencode) -> + let arity = exp_same (mcode2line dots) [mcode2arity dots] in + let dots = mcode dots in + let whencode = get_option (expression Ast0.NONE) whencode in + make_exp expr tgt arity (Ast0.Ecircles(dots,whencode)) + | Ast0.Estars(dots,whencode) -> + let arity = exp_same (mcode2line dots) [mcode2arity dots] in + let dots = mcode dots in + let whencode = get_option (expression Ast0.NONE) whencode in + make_exp expr tgt arity (Ast0.Estars(dots,whencode)) + | Ast0.OptExp(_) | Ast0.UniqueExp(_) -> + failwith "unexpected code" + +and expression tgt exp = top_expression false tgt exp + +(* --------------------------------------------------------------------- *) +(* Types *) + +and make_typeC = + make_opt_unique + (function x -> Ast0.OptType x) + (function x -> Ast0.UniqueType x) + +and top_typeC tgt opt_allowed typ = + match Ast0.unwrap typ with + Ast0.ConstVol(cv,ty) -> + let arity = all_same opt_allowed tgt (mcode2line cv) + [mcode2arity cv] in + let cv = mcode cv in + let ty = typeC arity ty in + make_typeC typ tgt arity (Ast0.ConstVol(cv,ty)) + | Ast0.BaseType(ty,Some sign) -> + let arity = + all_same opt_allowed tgt (mcode2line ty) + [mcode2arity ty; mcode2arity sign] in + let ty = mcode ty in + let sign = mcode sign in + make_typeC typ tgt arity (Ast0.BaseType(ty,Some sign)) + | Ast0.BaseType(ty,None) -> + let arity = + all_same opt_allowed tgt (mcode2line ty) [mcode2arity ty] in + let ty = mcode ty in + make_typeC typ tgt arity (Ast0.BaseType(ty,None)) + | Ast0.ImplicitInt(sign) -> + let arity = + all_same opt_allowed tgt (mcode2line sign) [mcode2arity sign] in + let sign = mcode sign in + make_typeC typ tgt arity (Ast0.ImplicitInt(sign)) + | Ast0.Pointer(ty,star) -> + let arity = + all_same opt_allowed tgt (mcode2line star) [mcode2arity star] in + let ty = typeC arity ty in + let star = mcode star in + make_typeC typ tgt arity (Ast0.Pointer(ty,star)) + | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> + let arity = + all_same opt_allowed tgt (mcode2line lp1) + (List.map mcode2arity [lp1;star;rp1;lp2;rp2]) in + let ty = typeC arity ty in + let params = parameter_list tgt params in + make_typeC typ tgt arity + (Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2)) + | Ast0.FunctionType(ty,lp1,params,rp1) -> + let arity = + all_same opt_allowed tgt (mcode2line lp1) + (List.map mcode2arity [lp1;rp1]) in + let ty = get_option (typeC arity) ty in + let params = parameter_list tgt params in + make_typeC typ tgt arity (Ast0.FunctionType(ty,lp1,params,rp1)) + | Ast0.Array(ty,lb,size,rb) -> + let arity = + all_same opt_allowed tgt (mcode2line lb) + [mcode2arity lb;mcode2arity rb] in + let ty = typeC arity ty in + let lb = mcode lb in + let size = get_option (expression arity) size in + let rb = mcode rb in + make_typeC typ tgt arity (Ast0.Array(ty,lb,size,rb)) + | Ast0.StructUnionName(kind,name) -> + let arity = + all_same opt_allowed tgt (mcode2line kind) + [mcode2arity kind] in + let kind = mcode kind in + let name = get_option (ident false arity) name in + make_typeC typ tgt arity (Ast0.StructUnionName(kind,name)) + | Ast0.StructUnionDef(ty,lb,decls,rb) -> + let arity = + all_same opt_allowed tgt (mcode2line lb) + (List.map mcode2arity [lb;rb]) in + let ty = typeC arity ty in + let lb = mcode lb in + let decls = dots (declaration tgt) decls in + let rb = mcode rb in + make_typeC typ tgt arity (Ast0.StructUnionDef(ty,lb,decls,rb)) + | Ast0.TypeName(name) -> + let arity = + all_same opt_allowed tgt (mcode2line name) [mcode2arity name] in + let name = mcode name in + make_typeC typ tgt arity (Ast0.TypeName(name)) + | Ast0.MetaType(name,pure) -> + let arity = + all_same opt_allowed tgt (mcode2line name) [mcode2arity name] in + let name = mcode name in + make_typeC typ tgt arity (Ast0.MetaType(name,pure)) + | Ast0.DisjType(starter,types,mids,ender) -> + let types = List.map (typeC tgt) types in + (match List.rev types with + _::xs -> + if anyopt xs (function Ast0.OptType(_) -> true | _ -> false) + then fail typ "opt only allowed in the last disjunct" + | _ -> ()); + let res = Ast0.DisjType(starter,types,mids,ender) in + Ast0.rewrap typ res + | Ast0.OptType(_) | Ast0.UniqueType(_) -> + failwith "unexpected code" + +and typeC tgt ty = top_typeC tgt false 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 make_decl = + make_opt_unique + (function x -> Ast0.OptDecl x) + (function x -> Ast0.UniqueDecl x) + +and declaration tgt decl = + match Ast0.unwrap decl with + Ast0.Init(stg,ty,id,eq,exp,sem) -> + let arity = + all_same true tgt (mcode2line eq) + ((match stg with None -> [] | Some x -> [mcode2arity x]) @ + (List.map mcode2arity [eq;sem])) in + let stg = get_option mcode stg in + let ty = typeC arity ty in + let id = ident false arity id in + let eq = mcode eq in + let exp = initialiser arity exp in + let sem = mcode sem in + make_decl decl tgt arity (Ast0.Init(stg,ty,id,eq,exp,sem)) + | Ast0.UnInit(stg,ty,id,sem) -> + let arity = + all_same true tgt (mcode2line sem) + ((match stg with None -> [] | Some x -> [mcode2arity x]) @ + [mcode2arity sem]) in + let stg = get_option mcode stg in + let ty = typeC arity ty in + let id = ident false arity id in + let sem = mcode sem in + make_decl decl tgt arity (Ast0.UnInit(stg,ty,id,sem)) + | Ast0.MacroDecl(name,lp,args,rp,sem) -> + let arity = + all_same true tgt (mcode2line lp) (List.map mcode2arity [lp;rp;sem]) in + let name = ident false arity name in + let lp = mcode lp in + let args = dots (expression arity) args in + let rp = mcode rp in + let sem = mcode sem in + make_decl decl tgt arity (Ast0.MacroDecl(name,lp,args,rp,sem)) + | Ast0.TyDecl(ty,sem) -> + let arity = + all_same true tgt (mcode2line sem) [mcode2arity sem] in + let ty = typeC arity ty in + let sem = mcode sem in + make_decl decl tgt arity (Ast0.TyDecl(ty,sem)) + | Ast0.Typedef(stg,ty,id,sem) -> + let arity = + all_same true tgt (mcode2line sem) + [mcode2arity stg;mcode2arity sem] in + let stg = mcode stg in + let ty = typeC arity ty in + let id = typeC arity id in + let sem = mcode sem in + make_decl decl tgt arity (Ast0.Typedef(stg,ty,id,sem)) + | Ast0.DisjDecl(starter,decls,mids,ender) -> + let decls = List.map (declaration tgt) decls in + (match List.rev decls with + _::xs -> + if anyopt xs (function Ast0.OptDecl(_) -> true | _ -> false) + then fail decl "opt only allowed in the last disjunct" + | _ -> ()); + let res = Ast0.DisjDecl(starter,decls,mids,ender) in + Ast0.rewrap decl res + | Ast0.Ddots(dots,whencode) -> + let arity = all_same true tgt (mcode2line dots) [mcode2arity dots] in + let dots = mcode dots in + let whencode = get_option (declaration Ast0.NONE) whencode in + make_decl decl tgt arity (Ast0.Ddots(dots,whencode)) + | Ast0.OptDecl(_) | Ast0.UniqueDecl(_) -> + failwith "unexpected code" + +(* --------------------------------------------------------------------- *) +(* Initializer *) + +and make_init = + make_opt_unique + (function x -> Ast0.OptIni x) + (function x -> Ast0.UniqueIni x) + +and initialiser tgt i = + let init_same = all_same true tgt in + match Ast0.unwrap i with + Ast0.InitExpr(exp) -> + Ast0.rewrap i (Ast0.InitExpr(expression tgt exp)) + | Ast0.InitList(lb,initlist,rb) -> + let arity = init_same (mcode2line lb) [mcode2arity lb; mcode2arity rb] in + let lb = mcode lb in + let initlist = dots (initialiser arity) initlist in + let rb = mcode rb in + make_init i tgt arity (Ast0.InitList(lb,initlist,rb)) + | Ast0.InitGccDotName(dot,name,eq,ini) -> + let arity = + init_same (mcode2line dot) [mcode2arity dot; mcode2arity eq] in + let dot = mcode dot in + let name = ident true arity name in + let eq = mcode eq in + let ini = initialiser arity ini in + make_init i tgt arity (Ast0.InitGccDotName(dot,name,eq,ini)) + | Ast0.InitGccName(name,eq,ini) -> + let arity = init_same (mcode2line eq) [mcode2arity eq] in + let name = ident true arity name in + let eq = mcode eq in + let ini = initialiser arity ini in + make_init i tgt arity (Ast0.InitGccName(name,eq,ini)) + | Ast0.InitGccIndex(lb,exp,rb,eq,ini) -> + let arity = + init_same (mcode2line lb) + [mcode2arity lb; mcode2arity rb; mcode2arity eq] in + let lb = mcode lb in + let exp = expression arity exp in + let rb = mcode rb in + let eq = mcode eq in + let ini = initialiser arity ini in + make_init i tgt arity (Ast0.InitGccIndex(lb,exp,rb,eq,ini)) + | Ast0.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini) -> + let arity = + init_same (mcode2line lb) + [mcode2arity lb; mcode2arity dots; mcode2arity rb; mcode2arity eq] in + let lb = mcode lb in + let exp1 = expression arity exp1 in + let dots = mcode dots in + let exp2 = expression arity exp2 in + let rb = mcode rb in + let eq = mcode eq in + let ini = initialiser arity ini in + make_init i tgt arity + (Ast0.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini)) + | Ast0.IComma(cm) -> + let arity = init_same (mcode2line cm) [mcode2arity cm] in + let cm = mcode cm in + make_init i tgt arity (Ast0.IComma(cm)) + | Ast0.Idots(dots,whencode) -> + let arity = init_same (mcode2line dots) [mcode2arity dots] in + let dots = mcode dots in + let whencode = get_option (initialiser Ast0.NONE) whencode in + make_init i tgt arity (Ast0.Idots(dots,whencode)) + | Ast0.OptIni(_) | Ast0.UniqueIni(_) -> + failwith "unexpected code" + +(* --------------------------------------------------------------------- *) +(* Parameter *) + +and make_param = + make_opt_unique + (function x -> Ast0.OptParam x) + (function x -> Ast0.UniqueParam x) + +and parameterTypeDef tgt param = + let param_same = all_same true tgt in + match Ast0.unwrap param with + Ast0.VoidParam(ty) -> Ast0.rewrap param (Ast0.VoidParam(typeC tgt ty)) + | Ast0.Param(ty,Some id) -> + let ty = top_typeC tgt true ty in + let id = ident true tgt id in + Ast0.rewrap param + (match (Ast0.unwrap ty,Ast0.unwrap id) with + (Ast0.OptType(ty),Ast0.OptIdent(id)) -> + Ast0.OptParam(Ast0.rewrap param (Ast0.Param(ty,Some id))) + | (Ast0.UniqueType(ty),Ast0.UniqueIdent(id)) -> + Ast0.UniqueParam(Ast0.rewrap param (Ast0.Param(ty,Some id))) + | (Ast0.OptType(ty),_) -> + fail param "arity mismatch in param declaration" + | (_,Ast0.OptIdent(id)) -> + fail param "arity mismatch in param declaration" + | _ -> Ast0.Param(ty,Some id)) + | Ast0.Param(ty,None) -> + let ty = top_typeC tgt true ty in + Ast0.rewrap param + (match Ast0.unwrap ty with + Ast0.OptType(ty) -> + Ast0.OptParam(Ast0.rewrap param (Ast0.Param(ty,None))) + | Ast0.UniqueType(ty) -> + Ast0.UniqueParam(Ast0.rewrap param (Ast0.Param(ty,None))) + | _ -> Ast0.Param(ty,None)) + | Ast0.MetaParam(name,pure) -> + let arity = param_same (mcode2line name) [mcode2arity name] in + let name = mcode name in + make_param param tgt arity (Ast0.MetaParam(name,pure)) + | Ast0.MetaParamList(name,lenname,pure) -> + let arity = param_same (mcode2line name) [mcode2arity name] in + let name = mcode name in + make_param param tgt arity (Ast0.MetaParamList(name,lenname,pure)) + | Ast0.PComma(cm) -> + let arity = param_same (mcode2line cm) [mcode2arity cm] in + let cm = mcode cm in + make_param param tgt arity (Ast0.PComma(cm)) + | Ast0.Pdots(dots) -> + let arity = param_same (mcode2line dots) [mcode2arity dots] in + let dots = mcode dots in + make_param param tgt arity (Ast0.Pdots(dots)) + | Ast0.Pcircles(dots) -> + let arity = param_same (mcode2line dots) [mcode2arity dots] in + let dots = mcode dots in + make_param param tgt arity (Ast0.Pcircles(dots)) + | Ast0.OptParam(_) | Ast0.UniqueParam(_) -> + failwith "unexpected code" + +and parameter_list tgt = dots (parameterTypeDef tgt) + +(* --------------------------------------------------------------------- *) +(* Top-level code *) + +and make_rule_elem x = + make_opt_unique + (function x -> Ast0.OptStm x) + (function x -> Ast0.UniqueStm x) + x + +and statement tgt stm = + let stm_same = all_same true tgt in + match Ast0.unwrap stm with + Ast0.Decl(bef,decl) -> + let new_decl = declaration tgt decl in + Ast0.rewrap stm + (match Ast0.unwrap new_decl with + Ast0.OptDecl(decl) -> + Ast0.OptStm(Ast0.rewrap stm (Ast0.Decl(bef,decl))) + | Ast0.UniqueDecl(decl) -> + Ast0.UniqueStm(Ast0.rewrap stm (Ast0.Decl(bef,decl))) + | _ -> Ast0.Decl(bef,new_decl)) + | Ast0.Seq(lbrace,body,rbrace) -> + let arity = + stm_same (mcode2line lbrace) + [mcode2arity lbrace; mcode2arity rbrace] in + let lbrace = mcode lbrace in + let body = dots (statement arity) body in + let rbrace = mcode rbrace in + make_rule_elem stm tgt arity (Ast0.Seq(lbrace,body,rbrace)) + | Ast0.ExprStatement(exp,sem) -> + let arity = stm_same (mcode2line sem) [mcode2arity sem] in + let exp = expression arity exp in + let sem = mcode sem in + make_rule_elem stm tgt arity (Ast0.ExprStatement(exp,sem)) + | Ast0.IfThen(iff,lp,exp,rp,branch,aft) -> + let arity = + stm_same (mcode2line iff) (List.map mcode2arity [iff;lp;rp]) in + let iff = mcode iff in + let lp = mcode lp in + let exp = expression arity exp in + let rp = mcode rp in + let branch = statement arity branch in + make_rule_elem stm tgt arity (Ast0.IfThen(iff,lp,exp,rp,branch,aft)) + | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,aft) -> + let arity = + stm_same (mcode2line iff) (List.map mcode2arity [iff;lp;rp;els]) in + let iff = mcode iff in + let lp = mcode lp in + let exp = expression arity exp in + let rp = mcode rp in + let branch1 = statement arity branch1 in + let els = mcode els in + let branch2 = statement arity branch2 in + make_rule_elem stm tgt arity + (Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,aft)) + | Ast0.While(wh,lp,exp,rp,body,aft) -> + let arity = + stm_same (mcode2line wh) + (List.map mcode2arity [wh;lp;rp]) in + let wh = mcode wh in + let lp = mcode lp in + let exp = expression arity exp in + let rp = mcode rp in + let body = statement arity body in + make_rule_elem stm tgt arity (Ast0.While(wh,lp,exp,rp,body,aft)) + | Ast0.Do(d,body,wh,lp,exp,rp,sem) -> + let arity = + stm_same (mcode2line wh) (List.map mcode2arity [d;wh;lp;rp;sem]) in + let d = mcode d in + let body = statement arity body in + let wh = mcode wh in + let lp = mcode lp in + let exp = expression arity exp in + let rp = mcode rp in + let sem = mcode sem in + make_rule_elem stm tgt arity (Ast0.Do(d,body,wh,lp,exp,rp,sem)) + | Ast0.For(fr,lp,exp1,sem1,exp2,sem2,exp3,rp,body,aft) -> + let arity = + stm_same (mcode2line fr) (List.map mcode2arity [fr;lp;sem1;sem2;rp]) in + let fr = mcode fr in + let lp = mcode lp in + let exp1 = get_option (expression arity) exp1 in + let sem1 = mcode sem1 in + let exp2 = get_option (expression arity) exp2 in + let sem2= mcode sem2 in + let exp3 = get_option (expression arity) exp3 in + let rp = mcode rp in + let body = statement arity body in + make_rule_elem stm tgt arity + (Ast0.For(fr,lp,exp1,sem1,exp2,sem2,exp3,rp,body,aft)) + | Ast0.Iterator(nm,lp,args,rp,body,aft) -> + let arity = stm_same (mcode2line lp) (List.map mcode2arity [lp;rp]) in + let nm = ident false arity nm in + let lp = mcode lp in + let args = dots (expression arity) args in + let rp = mcode rp in + let body = statement arity body in + make_rule_elem stm tgt arity (Ast0.Iterator(nm,lp,args,rp,body,aft)) + | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) -> + let arity = + stm_same (mcode2line switch) + (List.map mcode2arity [switch;lp;rp;lb;rb]) in + let switch = mcode switch in + let lp = mcode lp in + let exp = expression arity exp in + let rp = mcode rp in + let lb = mcode lb in + let cases = dots (case_line arity) cases in + let rb = mcode rb in + make_rule_elem stm tgt arity + (Ast0.Switch(switch,lp,exp,rp,lb,cases,rb)) + | Ast0.Break(br,sem) -> + let arity = stm_same (mcode2line br) (List.map mcode2arity [br;sem]) in + let br = mcode br in + let sem = mcode sem in + make_rule_elem stm tgt arity (Ast0.Break(br,sem)) + | Ast0.Continue(cont,sem) -> + let arity = + stm_same (mcode2line cont) (List.map mcode2arity [cont;sem]) in + let cont = mcode cont in + let sem = mcode sem in + make_rule_elem stm tgt arity (Ast0.Continue(cont,sem)) + | Ast0.Label(l,dd) -> + let arity = mcode2arity dd in + let l = ident false tgt l in + let dd = mcode dd in + make_rule_elem stm tgt arity (Ast0.Label(l,dd)) + | Ast0.Goto(goto,l,sem) -> + let arity = + stm_same (mcode2line goto) (List.map mcode2arity [goto;sem]) in + let goto = mcode goto in + let l = ident false tgt l in + let sem = mcode sem in + make_rule_elem stm tgt arity (Ast0.Goto(goto,l,sem)) + | Ast0.Return(ret,sem) -> + let arity = stm_same (mcode2line ret) (List.map mcode2arity [ret;sem]) in + let ret = mcode ret in + let sem = mcode sem in + make_rule_elem stm tgt arity (Ast0.Return(ret,sem)) + | Ast0.ReturnExpr(ret,exp,sem) -> + let arity = stm_same (mcode2line ret) (List.map mcode2arity [ret;sem]) in + let ret = mcode ret in + let exp = expression arity exp in + let sem = mcode sem in + make_rule_elem stm tgt arity (Ast0.ReturnExpr(ret,exp,sem)) + | Ast0.MetaStmt(name,pure) -> + let arity = stm_same (mcode2line name) [mcode2arity name] in + let name = mcode name in + make_rule_elem stm tgt arity (Ast0.MetaStmt(name,pure)) + | Ast0.MetaStmtList(name,pure) -> + let arity = stm_same (mcode2line name) [mcode2arity name] in + let name = mcode name in + make_rule_elem stm tgt arity (Ast0.MetaStmtList(name,pure)) + | Ast0.Exp(exp) -> + let new_exp = top_expression true tgt exp in + Ast0.rewrap stm + (match Ast0.unwrap new_exp with + Ast0.OptExp(exp) -> + Ast0.OptStm(Ast0.rewrap stm (Ast0.Exp(exp))) + | Ast0.UniqueExp(exp) -> + Ast0.UniqueStm(Ast0.rewrap stm (Ast0.Exp(exp))) + | _ -> Ast0.Exp(new_exp)) + | Ast0.TopExp(exp) -> + let new_exp = top_expression true tgt exp in + Ast0.rewrap stm + (match Ast0.unwrap new_exp with + Ast0.OptExp(exp) -> + Ast0.OptStm(Ast0.rewrap stm (Ast0.TopExp(exp))) + | Ast0.UniqueExp(exp) -> + Ast0.UniqueStm(Ast0.rewrap stm (Ast0.TopExp(exp))) + | _ -> Ast0.TopExp(new_exp)) + | Ast0.Ty(ty) -> + let new_ty = typeC tgt ty in (* opt makes no sense alone at top level *) + Ast0.rewrap stm + (match Ast0.unwrap new_ty with + Ast0.OptType(ty) -> + Ast0.OptStm(Ast0.rewrap stm (Ast0.Ty(ty))) + | Ast0.UniqueType(ty) -> + Ast0.UniqueStm(Ast0.rewrap stm (Ast0.Ty(ty))) + | _ -> Ast0.Ty(new_ty)) + | Ast0.Disj(starter,rule_elem_dots_list,mids,ender) -> + let stms = + List.map (function x -> concat_dots (statement tgt) x) + rule_elem_dots_list in + let (found_opt,unopt) = + List.fold_left + (function (found_opt,lines) -> + function x -> + let rebuild l = + (* previously just checked the last thing in the list, + but everything should be optional for the whole thing to + be optional *) + let is_opt x = + match Ast0.unwrap x with + Ast0.OptStm(x) -> true + | _ -> false in + let unopt x = + match Ast0.unwrap x with + Ast0.OptStm(x) -> x + | _ -> x in + if List.for_all is_opt l + then (true,List.map unopt l) + else (false, l) in + let (l,k) = + match Ast0.unwrap x with + Ast0.DOTS(l) -> + (l,function l -> Ast0.rewrap x (Ast0.DOTS l)) + | Ast0.CIRCLES(l) -> + (l,function l -> Ast0.rewrap x (Ast0.CIRCLES l)) + | Ast0.STARS(l) -> + (l,function l -> Ast0.rewrap x (Ast0.STARS l)) in + let (found_opt,l) = rebuild l in + (found_opt,(k l)::lines)) + (false,[]) stms in + let unopt = List.rev unopt in + if found_opt + then + make_rule_elem stm tgt Ast0.OPT (Ast0.Disj(starter,unopt,mids,ender)) + else Ast0.rewrap stm (Ast0.Disj(starter,stms,mids,ender)) + | Ast0.Nest(starter,rule_elem_dots,ender,whn,multi) -> + let new_rule_elem_dots = + concat_dots (statement Ast0.NONE) rule_elem_dots in + let whn = + List.map + (whencode (concat_dots (statement Ast0.NONE)) (statement Ast0.NONE) + (expression Ast0.NONE)) + whn in + Ast0.rewrap stm + (Ast0.Nest(starter,new_rule_elem_dots,ender,whn,multi)) + | Ast0.Dots(dots,whn) -> + let arity = stm_same (mcode2line dots) [mcode2arity dots] in + let dots = mcode dots in + let whn = + List.map + (whencode (concat_dots (statement Ast0.NONE)) (statement Ast0.NONE) + (expression Ast0.NONE)) + whn in + make_rule_elem stm tgt arity (Ast0.Dots(dots,whn)) + | Ast0.Circles(dots,whn) -> + let arity = stm_same (mcode2line dots) [mcode2arity dots] in + let dots = mcode dots in + let whn = + List.map + (whencode (concat_dots (statement Ast0.NONE)) (statement Ast0.NONE) + (expression Ast0.NONE)) + whn in + make_rule_elem stm tgt arity (Ast0.Circles(dots,whn)) + | Ast0.Stars(dots,whn) -> + let arity = stm_same (mcode2line dots) [mcode2arity dots] in + let dots = mcode dots in + let whn = + List.map + (whencode (concat_dots (statement Ast0.NONE)) (statement Ast0.NONE) + (expression Ast0.NONE)) + whn in + make_rule_elem stm tgt arity (Ast0.Stars(dots,whn)) + | Ast0.FunDecl(bef,fi,name,lp,params,rp,lbrace,body,rbrace) -> + let arity = + all_same true tgt (mcode2line lp) + ((List.map mcode2arity [lp;rp;lbrace;rbrace]) @ (fninfo2arity fi)) in + let fi = List.map (fninfo arity) fi in + let name = ident false arity name in + let lp = mcode lp in + let params = parameter_list arity params in + let rp = mcode rp in + let lbrace = mcode lbrace in + let body = dots (statement arity) body in + let rbrace = mcode rbrace in + make_rule_elem stm tgt arity + (Ast0.FunDecl(bef,fi,name,lp,params,rp,lbrace,body,rbrace)) + | Ast0.Include(inc,s) -> + let arity = + all_same true tgt (mcode2line inc) [mcode2arity inc; mcode2arity s] in + let inc = mcode inc in + let s = mcode s in + make_rule_elem stm tgt arity (Ast0.Include(inc,s)) + | Ast0.Define(def,id,params,body) -> + let arity = all_same true tgt (mcode2line def) [mcode2arity def] in + let def = mcode def in + let id = ident false arity id in + let params = define_parameters arity params in + let body = dots (statement arity) body in + make_rule_elem stm tgt arity (Ast0.Define(def,id,params,body)) + | Ast0.OptStm(_) | Ast0.UniqueStm(_) -> + failwith "unexpected code" + +and define_parameters tgt params = + match Ast0.unwrap params with + Ast0.NoParams -> params + | Ast0.DParams(lp,params,rp) -> + let arity = + all_same true tgt (mcode2line lp) [mcode2arity lp;mcode2arity rp] in + let lp = mcode lp in + let params = dots (define_param arity) params in + let rp = mcode rp in + Ast0.rewrap params (Ast0.DParams(lp,params,rp)) + +and make_define_param x = + make_opt_unique + (function x -> Ast0.OptDParam x) + (function x -> Ast0.UniqueDParam x) + x + +and define_param tgt param = + match Ast0.unwrap param with + Ast0.DParam(id) -> + let new_id = ident true tgt id in + Ast0.rewrap param + (match Ast0.unwrap new_id with + Ast0.OptIdent(id) -> + Ast0.OptDParam(Ast0.rewrap param (Ast0.DParam(id))) + | Ast0.UniqueIdent(decl) -> + Ast0.UniqueDParam(Ast0.rewrap param (Ast0.DParam(id))) + | _ -> Ast0.DParam(new_id)) + | Ast0.DPComma(cm) -> + let arity = + all_same true tgt (mcode2line cm) [mcode2arity cm] in + let cm = mcode cm in + make_define_param param tgt arity (Ast0.DPComma(cm)) + | Ast0.DPdots(dots) -> + let arity = + all_same true tgt (mcode2line dots) [mcode2arity dots] in + let dots = mcode dots in + make_define_param param tgt arity (Ast0.DPdots(dots)) + | Ast0.DPcircles(circles) -> + let arity = + all_same true tgt (mcode2line circles) [mcode2arity circles] in + let circles = mcode circles in + make_define_param param tgt arity (Ast0.DPcircles(circles)) + | Ast0.OptDParam(dp) | Ast0.UniqueDParam(dp) -> + failwith "unexpected code" + +and fninfo arity = function + Ast0.FStorage(stg) -> Ast0.FStorage(mcode stg) + | Ast0.FType(ty) -> Ast0.FType(typeC arity ty) + | Ast0.FInline(inline) -> Ast0.FInline(mcode inline) + | Ast0.FAttr(attr) -> Ast0.FAttr(mcode attr) + +and fninfo2arity fninfo = + List.concat + (List.map + (function + Ast0.FStorage(stg) -> [mcode2arity stg] + | Ast0.FType(ty) -> [] + | Ast0.FInline(inline) -> [mcode2arity inline] + | Ast0.FAttr(attr) -> [mcode2arity attr]) + fninfo) + +and whencode notfn alwaysfn expression = function + Ast0.WhenNot a -> Ast0.WhenNot (notfn a) + | Ast0.WhenAlways a -> Ast0.WhenAlways (alwaysfn a) + | Ast0.WhenModifier(x) -> Ast0.WhenModifier(x) + | Ast0.WhenNotTrue a -> Ast0.WhenNotTrue (expression a) + | Ast0.WhenNotFalse a -> Ast0.WhenNotFalse (expression a) + +and make_case_line = + make_opt_unique + (function x -> Ast0.OptCase x) + (function x -> failwith "unique not allowed for case_line") + +and case_line tgt c = + match Ast0.unwrap c with + Ast0.Default(def,colon,code) -> + let arity = + all_same true tgt (mcode2line def) + [mcode2arity def; mcode2arity colon] in + let def = mcode def in + let colon = mcode colon in + let code = dots (statement arity) code in + make_case_line c tgt arity (Ast0.Default(def,colon,code)) + | Ast0.Case(case,exp,colon,code) -> + let arity = + all_same true tgt (mcode2line case) + [mcode2arity case; mcode2arity colon] in + let case = mcode case in + let exp = expression arity exp in + let colon = mcode colon in + let code = dots (statement arity) code in + make_case_line c tgt arity (Ast0.Case(case,exp,colon,code)) + | Ast0.OptCase(_) -> failwith "unexpected OptCase" + +(* --------------------------------------------------------------------- *) +(* Function declaration *) +(* Haven't thought much about arity here... *) + +let top_level tgt t = + Ast0.rewrap t + (match Ast0.unwrap t with + Ast0.FILEINFO(old_file,new_file) -> + if mcode2arity old_file = Ast0.NONE && mcode2arity new_file = Ast0.NONE + then Ast0.FILEINFO(mcode old_file,mcode new_file) + else fail t "unexpected arity for file info" + | Ast0.DECL(stmt) -> + Ast0.DECL(statement tgt stmt) + | Ast0.CODE(rule_elem_dots) -> + Ast0.CODE(concat_dots (statement tgt) rule_elem_dots) + | Ast0.ERRORWORDS(exps) -> + Ast0.ERRORWORDS(List.map (top_expression false Ast0.NONE) exps) + | Ast0.OTHER(_) -> fail t "eliminated by top_level") + +let rule tgt = List.map (top_level tgt) + +(* --------------------------------------------------------------------- *) +(* Entry points *) + +let minus_arity code = + rule Ast0.NONE code diff --git a/parsing_cocci/.#ast0_cocci.ml.1.105 b/parsing_cocci/.#ast0_cocci.ml.1.105 new file mode 100644 index 0000000..5175cf7 --- /dev/null +++ b/parsing_cocci/.#ast0_cocci.ml.1.105 @@ -0,0 +1,641 @@ +(* +* 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 *) + | 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 + +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 + | 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/.#ast0_cocci.ml.1.106 b/parsing_cocci/.#ast0_cocci.ml.1.106 new file mode 100644 index 0000000..306fb6a --- /dev/null +++ b/parsing_cocci/.#ast0_cocci.ml.1.106 @@ -0,0 +1,645 @@ +(* +* 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 *) + | 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/.#ast0toast.ml.1.132 b/parsing_cocci/.#ast0toast.ml.1.132 new file mode 100644 index 0000000..ccc23cc --- /dev/null +++ b/parsing_cocci/.#ast0toast.ml.1.132 @@ -0,0 +1,916 @@ +(* +* 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. +*) + + +(* Arities matter for the minus slice, but not for the plus slice. *) + +(* + only allowed on code in a nest (in_nest = true). ? only allowed on +rule_elems, and on subterms if the context is ? also. *) + +module Ast0 = Ast0_cocci +module Ast = Ast_cocci +module V0 = Visitor_ast0 +module V = Visitor_ast + +let unitary = Type_cocci.Unitary + +let ctr = ref 0 +let get_ctr _ = + let c = !ctr in + ctr := !ctr + 1; + c + +(* --------------------------------------------------------------------- *) +(* Move plus tokens from the MINUS and CONTEXT structured nodes to the +corresponding leftmost and rightmost mcodes *) + +let inline_mcodes = + let bind x y = () in + let option_default = () in + let mcode _ = () in + let do_nothing r k e = + k e; + let einfo = Ast0.get_info e in + match (Ast0.get_mcodekind e) with + Ast0.MINUS(replacements) -> + (match !replacements with + ([],_) -> () + | replacements -> + let minus_try = function + (true,mc) -> + if List.for_all + (function + Ast0.MINUS(mreplacements) -> true | _ -> false) + mc + then + (List.iter + (function + Ast0.MINUS(mreplacements) -> + mreplacements := replacements + | _ -> ()) + mc; + true) + else false + | _ -> false in + if not (minus_try(einfo.Ast0.attachable_start, + einfo.Ast0.mcode_start) + or + minus_try(einfo.Ast0.attachable_end, + einfo.Ast0.mcode_end)) + then + failwith "minus tree should not have bad code on both sides") + | Ast0.CONTEXT(befaft) + | Ast0.MIXED(befaft) -> + let concat starter startinfo ender endinfo = + let lst = + match (starter,ender) with + ([],_) -> ender + | (_,[]) -> starter + | _ -> + if startinfo.Ast0.tline_end = endinfo.Ast0.tline_start + then (* put them in the same inner list *) + let last = List.hd (List.rev starter) in + let butlast = List.rev(List.tl(List.rev starter)) in + butlast @ (last@(List.hd ender)) :: (List.tl ender) + else starter @ ender in + (lst, + {endinfo with Ast0.tline_start = startinfo.Ast0.tline_start}) in + let attach_bef bef beforeinfo = function + (true,mcl) -> + List.iter + (function + Ast0.MINUS(mreplacements) -> + let (mrepl,tokeninfo) = !mreplacements in + mreplacements := concat bef beforeinfo mrepl tokeninfo + | Ast0.CONTEXT(mbefaft) -> + (match !mbefaft with + (Ast.BEFORE(mbef),mbeforeinfo,a) -> + let (newbef,newinfo) = + concat bef beforeinfo mbef mbeforeinfo in + mbefaft := (Ast.BEFORE(newbef),newinfo,a) + | (Ast.AFTER(maft),_,a) -> + mbefaft := + (Ast.BEFOREAFTER(bef,maft),beforeinfo,a) + | (Ast.BEFOREAFTER(mbef,maft),mbeforeinfo,a) -> + let (newbef,newinfo) = + concat bef beforeinfo mbef mbeforeinfo in + mbefaft := + (Ast.BEFOREAFTER(newbef,maft),newinfo,a) + | (Ast.NOTHING,_,a) -> + mbefaft := (Ast.BEFORE(bef),beforeinfo,a)) + | _ -> failwith "unexpected annotation") + mcl + | _ -> + failwith + "context tree should not have bad code on both sides" in + let attach_aft aft afterinfo = function + (true,mcl) -> + List.iter + (function + Ast0.MINUS(mreplacements) -> + let (mrepl,tokeninfo) = !mreplacements in + mreplacements := concat mrepl tokeninfo aft afterinfo + | Ast0.CONTEXT(mbefaft) -> + (match !mbefaft with + (Ast.BEFORE(mbef),b,_) -> + mbefaft := + (Ast.BEFOREAFTER(mbef,aft),b,afterinfo) + | (Ast.AFTER(maft),b,mafterinfo) -> + let (newaft,newinfo) = + concat maft mafterinfo aft afterinfo in + mbefaft := (Ast.AFTER(newaft),b,newinfo) + | (Ast.BEFOREAFTER(mbef,maft),b,mafterinfo) -> + let (newaft,newinfo) = + concat maft mafterinfo aft afterinfo in + mbefaft := + (Ast.BEFOREAFTER(mbef,newaft),b,newinfo) + | (Ast.NOTHING,b,_) -> + mbefaft := (Ast.AFTER(aft),b,afterinfo)) + | _ -> failwith "unexpected annotation") + mcl + | _ -> + failwith + "context tree should not have bad code on both sides" in + (match !befaft with + (Ast.BEFORE(bef),beforeinfo,_) -> + attach_bef bef beforeinfo + (einfo.Ast0.attachable_start,einfo.Ast0.mcode_start) + | (Ast.AFTER(aft),_,afterinfo) -> + attach_aft aft afterinfo + (einfo.Ast0.attachable_end,einfo.Ast0.mcode_end) + | (Ast.BEFOREAFTER(bef,aft),beforeinfo,afterinfo) -> + attach_bef bef beforeinfo + (einfo.Ast0.attachable_start,einfo.Ast0.mcode_start); + attach_aft aft afterinfo + (einfo.Ast0.attachable_end,einfo.Ast0.mcode_end) + | (Ast.NOTHING,_,_) -> ()) + | Ast0.PLUS -> () 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 + +(* --------------------------------------------------------------------- *) +(* For function declarations. Can't use the mcode at the root, because that +might be mixed when the function contains ()s, where agglomeration of -s is +not possible. *) + +let check_allminus = + let donothing r k e = k e in + let bind x y = x && y in + let option_default = true in + let mcode (_,_,_,mc,_) = + match mc with + Ast0.MINUS(r) -> let (plusses,_) = !r in plusses = [] + | _ -> false in + + (* special case for disj *) + let expression r k e = + match Ast0.unwrap e with + Ast0.DisjExpr(starter,expr_list,mids,ender) -> + List.for_all r.V0.combiner_expression expr_list + | _ -> k e in + + let declaration r k e = + match Ast0.unwrap e with + Ast0.DisjDecl(starter,decls,mids,ender) -> + List.for_all r.V0.combiner_declaration decls + | _ -> k e in + + let typeC r k e = + match Ast0.unwrap e with + Ast0.DisjType(starter,decls,mids,ender) -> + List.for_all r.V0.combiner_typeC decls + | _ -> k e in + + let statement r k e = + match Ast0.unwrap e with + Ast0.Disj(starter,statement_dots_list,mids,ender) -> + List.for_all r.V0.combiner_statement_dots statement_dots_list + | _ -> k e 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 expression typeC donothing donothing declaration + statement donothing donothing + +(* --------------------------------------------------------------------- *) +(* --------------------------------------------------------------------- *) + +let get_option fn = function + None -> None + | Some x -> Some (fn x) + +(* --------------------------------------------------------------------- *) +(* --------------------------------------------------------------------- *) +(* Mcode *) + +let convert_info info = + { Ast.line = info.Ast0.line_start; Ast.column = info.Ast0.column; + Ast.strbef = info.Ast0.strings_before; + Ast.straft = info.Ast0.strings_after; } + +let convert_mcodekind = function + Ast0.MINUS(replacements) -> + let (replacements,_) = !replacements in + Ast.MINUS(Ast.NoPos,replacements) + | Ast0.PLUS -> Ast.PLUS + | Ast0.CONTEXT(befaft) -> + let (befaft,_,_) = !befaft in Ast.CONTEXT(Ast.NoPos,befaft) + | Ast0.MIXED(_) -> failwith "not possible for mcode" + +let pos_mcode(term,_,info,mcodekind,pos) = + (* avoids a recursion problem *) + (term,convert_info info,convert_mcodekind mcodekind,Ast.NoMetaPos) + +let mcode(term,_,info,mcodekind,pos) = + let pos = + match !pos with + Ast0.MetaPos(pos,constraints,per) -> + Ast.MetaPos(pos_mcode pos,constraints,per,unitary,false) + | _ -> Ast.NoMetaPos in + (term,convert_info info,convert_mcodekind mcodekind,pos) + +(* --------------------------------------------------------------------- *) +(* Dots *) +let wrap ast line isos = + {(Ast.make_term ast) with Ast.node_line = line; + Ast.iso_info = isos} + +let rewrap ast0 isos ast = + wrap ast ((Ast0.get_info ast0).Ast0.line_start) isos + +let no_isos = [] + +(* no isos on tokens *) +let tokenwrap (_,info,_,_) s ast = wrap ast info.Ast.line no_isos +let iso_tokenwrap (_,info,_,_) s ast iso = wrap ast info.Ast.line iso + +let dots fn d = + rewrap d no_isos + (match Ast0.unwrap d with + Ast0.DOTS(x) -> Ast.DOTS(List.map fn x) + | Ast0.CIRCLES(x) -> Ast.CIRCLES(List.map fn x) + | Ast0.STARS(x) -> Ast.STARS(List.map fn x)) + +(* --------------------------------------------------------------------- *) +(* Identifier *) + +let rec do_isos l = List.map (function (nm,x) -> (nm,anything x)) l + +and ident i = + rewrap i (do_isos (Ast0.get_iso i)) + (match Ast0.unwrap i with + Ast0.Id(name) -> Ast.Id(mcode name) + | Ast0.MetaId(name,constraints,_) -> + let constraints = List.map ident constraints in + Ast.MetaId(mcode name,constraints,unitary,false) + | Ast0.MetaFunc(name,constraints,_) -> + let constraints = List.map ident constraints in + Ast.MetaFunc(mcode name,constraints,unitary,false) + | Ast0.MetaLocalFunc(name,constraints,_) -> + let constraints = List.map ident constraints in + Ast.MetaLocalFunc(mcode name,constraints,unitary,false) + | Ast0.OptIdent(id) -> Ast.OptIdent(ident id) + | Ast0.UniqueIdent(id) -> Ast.UniqueIdent(ident id)) + +(* --------------------------------------------------------------------- *) +(* Expression *) + +and expression e = + let e1 = + rewrap e (do_isos (Ast0.get_iso e)) + (match Ast0.unwrap e with + Ast0.Ident(id) -> Ast.Ident(ident id) + | Ast0.Constant(const) -> + Ast.Constant(mcode const) + | Ast0.FunCall(fn,lp,args,rp) -> + let fn = expression fn in + let lp = mcode lp in + let args = dots expression args in + let rp = mcode rp in + Ast.FunCall(fn,lp,args,rp) + | Ast0.Assignment(left,op,right,simple) -> + Ast.Assignment(expression left,mcode op,expression right,simple) + | Ast0.CondExpr(exp1,why,exp2,colon,exp3) -> + let exp1 = expression exp1 in + let why = mcode why in + let exp2 = get_option expression exp2 in + let colon = mcode colon in + let exp3 = expression exp3 in + Ast.CondExpr(exp1,why,exp2,colon,exp3) + | Ast0.Postfix(exp,op) -> + Ast.Postfix(expression exp,mcode op) + | Ast0.Infix(exp,op) -> + Ast.Infix(expression exp,mcode op) + | Ast0.Unary(exp,op) -> + Ast.Unary(expression exp,mcode op) + | Ast0.Binary(left,op,right) -> + Ast.Binary(expression left,mcode op,expression right) + | Ast0.Nested(left,op,right) -> + Ast.Nested(expression left,mcode op,expression right) + | Ast0.Paren(lp,exp,rp) -> + Ast.Paren(mcode lp,expression exp,mcode rp) + | Ast0.ArrayAccess(exp1,lb,exp2,rb) -> + Ast.ArrayAccess(expression exp1,mcode lb,expression exp2,mcode rb) + | Ast0.RecordAccess(exp,pt,field) -> + Ast.RecordAccess(expression exp,mcode pt,ident field) + | Ast0.RecordPtAccess(exp,ar,field) -> + Ast.RecordPtAccess(expression exp,mcode ar,ident field) + | Ast0.Cast(lp,ty,rp,exp) -> + Ast.Cast(mcode lp,typeC ty,mcode rp,expression exp) + | Ast0.SizeOfExpr(szf,exp) -> + Ast.SizeOfExpr(mcode szf,expression exp) + | Ast0.SizeOfType(szf,lp,ty,rp) -> + Ast.SizeOfType(mcode szf, mcode lp,typeC ty,mcode rp) + | Ast0.TypeExp(ty) -> Ast.TypeExp(typeC ty) + | Ast0.MetaErr(name,constraints,_) -> + let constraints = List.map expression constraints in + Ast.MetaErr(mcode name,constraints,unitary,false) + | Ast0.MetaExpr(name,constraints,ty,form,_) -> + let constraints = List.map expression constraints in + Ast.MetaExpr(mcode name,constraints,unitary,ty,form,false) + | Ast0.MetaExprList(name,Some lenname,_) -> + Ast.MetaExprList(mcode name,Some (mcode lenname,unitary,false), + unitary,false) + | Ast0.MetaExprList(name,None,_) -> + Ast.MetaExprList(mcode name,None,unitary,false) + | Ast0.EComma(cm) -> Ast.EComma(mcode cm) + | Ast0.DisjExpr(_,exps,_,_) -> Ast.DisjExpr(List.map expression exps) + | Ast0.NestExpr(_,exp_dots,_,whencode,multi) -> + let whencode = get_option expression whencode in + Ast.NestExpr(dots expression exp_dots,whencode,multi) + | Ast0.Edots(dots,whencode) -> + let dots = mcode dots in + let whencode = get_option expression whencode in + Ast.Edots(dots,whencode) + | Ast0.Ecircles(dots,whencode) -> + let dots = mcode dots in + let whencode = get_option expression whencode in + Ast.Ecircles(dots,whencode) + | Ast0.Estars(dots,whencode) -> + let dots = mcode dots in + let whencode = get_option expression whencode in + Ast.Estars(dots,whencode) + | Ast0.OptExp(exp) -> Ast.OptExp(expression exp) + | Ast0.UniqueExp(exp) -> Ast.UniqueExp(expression exp)) in + if Ast0.get_test_exp e then Ast.set_test_exp e1 else e1 + +and expression_dots ed = dots expression ed + +(* --------------------------------------------------------------------- *) +(* Types *) + +and typeC t = + rewrap t (do_isos (Ast0.get_iso t)) + (match Ast0.unwrap t with + Ast0.ConstVol(cv,ty) -> + let rec collect_disjs t = + match Ast0.unwrap t with + Ast0.DisjType(_,types,_,_) -> + if Ast0.get_iso t = [] + then List.concat (List.map collect_disjs types) + else failwith "unexpected iso on a disjtype" + | _ -> [t] in + let res = + List.map + (function ty -> + Ast.Type + (Some (mcode cv), + rewrap ty (do_isos (Ast0.get_iso ty)) (base_typeC ty))) + (collect_disjs ty) in + (* one could worry that isos are lost because we flatten the + disjunctions. but there should not be isos on the disjunctions + themselves. *) + (match res with + [ty] -> ty + | types -> Ast.DisjType(List.map (rewrap t no_isos) types)) + | Ast0.BaseType(_,_) | Ast0.ImplicitInt(_) | Ast0.Pointer(_,_) + | Ast0.FunctionPointer(_,_,_,_,_,_,_) | Ast0.FunctionType(_,_,_,_) + | Ast0.Array(_,_,_,_) | Ast0.StructUnionName(_,_) + | Ast0.StructUnionDef(_,_,_,_) | Ast0.TypeName(_) | Ast0.MetaType(_,_) -> + Ast.Type(None,rewrap t no_isos (base_typeC t)) + | Ast0.DisjType(_,types,_,_) -> Ast.DisjType(List.map typeC types) + | Ast0.OptType(ty) -> Ast.OptType(typeC ty) + | Ast0.UniqueType(ty) -> Ast.UniqueType(typeC ty)) + +and base_typeC t = + match Ast0.unwrap t with + Ast0.BaseType(ty,sign) -> + Ast.BaseType(mcode ty,get_option mcode sign) + | Ast0.ImplicitInt(sgn) -> Ast.ImplicitInt(mcode sgn) + | Ast0.Pointer(ty,star) -> Ast.Pointer(typeC ty,mcode star) + | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> + Ast.FunctionPointer + (typeC ty,mcode lp1,mcode star,mcode rp1, + mcode lp2,parameter_list params,mcode rp2) + | Ast0.FunctionType(ret,lp,params,rp) -> + let allminus = check_allminus.V0.combiner_typeC t in + Ast.FunctionType + (allminus,get_option typeC ret,mcode lp, + parameter_list params,mcode rp) + | Ast0.Array(ty,lb,size,rb) -> + Ast.Array(typeC ty,mcode lb,get_option expression size,mcode rb) + | Ast0.StructUnionName(kind,name) -> + Ast.StructUnionName(mcode kind,get_option ident name) + | Ast0.StructUnionDef(ty,lb,decls,rb) -> + Ast.StructUnionDef(typeC ty,mcode lb, + dots declaration decls, + mcode rb) + | Ast0.TypeName(name) -> Ast.TypeName(mcode name) + | Ast0.MetaType(name,_) -> + Ast.MetaType(mcode name,unitary,false) + | _ -> failwith "ast0toast: unexpected type" + +(* --------------------------------------------------------------------- *) +(* 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 declaration d = + rewrap d (do_isos (Ast0.get_iso d)) + (match Ast0.unwrap d with + Ast0.Init(stg,ty,id,eq,ini,sem) -> + let stg = get_option mcode stg in + let ty = typeC ty in + let id = ident id in + let eq = mcode eq in + let ini = initialiser ini in + let sem = mcode sem in + Ast.Init(stg,ty,id,eq,ini,sem) + | Ast0.UnInit(stg,ty,id,sem) -> + (match Ast0.unwrap ty with + Ast0.FunctionType(tyx,lp1,params,rp1) -> + let allminus = check_allminus.V0.combiner_declaration d in + Ast.UnInit(get_option mcode stg, + rewrap ty (do_isos (Ast0.get_iso ty)) + (Ast.Type + (None, + rewrap ty no_isos + (Ast.FunctionType + (allminus,get_option typeC tyx,mcode lp1, + parameter_list params,mcode rp1)))), + ident id,mcode sem) + | _ -> Ast.UnInit(get_option mcode stg,typeC ty,ident id,mcode sem)) + | Ast0.MacroDecl(name,lp,args,rp,sem) -> + let name = ident name in + let lp = mcode lp in + let args = dots expression args in + let rp = mcode rp in + let sem = mcode sem in + Ast.MacroDecl(name,lp,args,rp,sem) + | Ast0.TyDecl(ty,sem) -> Ast.TyDecl(typeC ty,mcode sem) + | Ast0.Typedef(stg,ty,id,sem) -> + let id = typeC id in + (match Ast.unwrap id with + Ast.Type(None,id) -> (* only MetaType or Id *) + Ast.Typedef(mcode stg,typeC ty,id,mcode sem) + | _ -> failwith "bad typedef") + | Ast0.DisjDecl(_,decls,_,_) -> Ast.DisjDecl(List.map declaration decls) + | Ast0.Ddots(dots,whencode) -> + let dots = mcode dots in + let whencode = get_option declaration whencode in + Ast.Ddots(dots,whencode) + | Ast0.OptDecl(decl) -> Ast.OptDecl(declaration decl) + | Ast0.UniqueDecl(decl) -> Ast.UniqueDecl(declaration decl)) + +and declaration_dots l = dots declaration l + +(* --------------------------------------------------------------------- *) +(* Initialiser *) + +and strip_idots initlist = + match Ast0.unwrap initlist with + Ast0.DOTS(x) -> + let (whencode,init) = + List.fold_left + (function (prevwhen,previnit) -> + function cur -> + match Ast0.unwrap cur with + Ast0.Idots(dots,Some whencode) -> + (whencode :: prevwhen, previnit) + | Ast0.Idots(dots,None) -> (prevwhen,previnit) + | _ -> (prevwhen, cur :: previnit)) + ([],[]) x in + (List.rev whencode, List.rev init) + | Ast0.CIRCLES(x) | Ast0.STARS(x) -> failwith "not possible for an initlist" + +and initialiser i = + rewrap i no_isos + (match Ast0.unwrap i with + Ast0.InitExpr(exp) -> Ast.InitExpr(expression exp) + | Ast0.InitList(lb,initlist,rb) -> + let (whencode,initlist) = strip_idots initlist in + Ast.InitList(mcode lb,List.map initialiser initlist,mcode rb, + List.map initialiser whencode) + | Ast0.InitGccDotName(dot,name,eq,ini) -> + Ast.InitGccDotName(mcode dot,ident name,mcode eq,initialiser ini) + | Ast0.InitGccName(name,eq,ini) -> + Ast.InitGccName(ident name,mcode eq,initialiser ini) + | Ast0.InitGccIndex(lb,exp,rb,eq,ini) -> + Ast.InitGccIndex(mcode lb,expression exp,mcode rb,mcode eq, + initialiser ini) + | Ast0.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini) -> + Ast.InitGccRange(mcode lb,expression exp1,mcode dots, + expression exp2,mcode rb,mcode eq,initialiser ini) + | Ast0.IComma(comma) -> Ast.IComma(mcode comma) + | Ast0.Idots(_,_) -> failwith "Idots should have been removed" + | Ast0.OptIni(ini) -> Ast.OptIni(initialiser ini) + | Ast0.UniqueIni(ini) -> Ast.UniqueIni(initialiser ini)) + +(* --------------------------------------------------------------------- *) +(* Parameter *) + +and parameterTypeDef p = + rewrap p no_isos + (match Ast0.unwrap p with + Ast0.VoidParam(ty) -> Ast.VoidParam(typeC ty) + | Ast0.Param(ty,id) -> Ast.Param(typeC ty,get_option ident id) + | Ast0.MetaParam(name,_) -> + Ast.MetaParam(mcode name,unitary,false) + | Ast0.MetaParamList(name,Some lenname,_) -> + Ast.MetaParamList(mcode name,Some(mcode lenname,unitary,false), + unitary,false) + | Ast0.MetaParamList(name,None,_) -> + Ast.MetaParamList(mcode name,None,unitary,false) + | Ast0.PComma(cm) -> Ast.PComma(mcode cm) + | Ast0.Pdots(dots) -> Ast.Pdots(mcode dots) + | Ast0.Pcircles(dots) -> Ast.Pcircles(mcode dots) + | Ast0.OptParam(param) -> Ast.OptParam(parameterTypeDef param) + | Ast0.UniqueParam(param) -> Ast.UniqueParam(parameterTypeDef param)) + +and parameter_list l = dots parameterTypeDef l + +(* --------------------------------------------------------------------- *) +(* Top-level code *) + +and statement s = + let rec statement seqible s = + let rewrap_stmt ast0 ast = + let befaft = + match Ast0.get_dots_bef_aft s with + Ast0.NoDots -> Ast.NoDots + | Ast0.DroppingBetweenDots s -> + Ast.DroppingBetweenDots (statement seqible s,get_ctr()) + | Ast0.AddingBetweenDots s -> + Ast.AddingBetweenDots (statement seqible s,get_ctr()) in + Ast.set_dots_bef_aft befaft (rewrap ast0 no_isos ast) in + let rewrap_rule_elem ast0 ast = + rewrap ast0 (do_isos (Ast0.get_iso ast0)) ast in + rewrap_stmt s + (match Ast0.unwrap s with + Ast0.Decl((_,bef),decl) -> + Ast.Atomic(rewrap_rule_elem s + (Ast.Decl(convert_mcodekind bef, + check_allminus.V0.combiner_statement s, + declaration decl))) + | Ast0.Seq(lbrace,body,rbrace) -> + let lbrace = mcode lbrace in + let (decls,body) = separate_decls seqible body in + let rbrace = mcode rbrace in + Ast.Seq(iso_tokenwrap lbrace s (Ast.SeqStart(lbrace)) + (do_isos (Ast0.get_iso s)), + decls,body, + tokenwrap rbrace s (Ast.SeqEnd(rbrace))) + | Ast0.ExprStatement(exp,sem) -> + Ast.Atomic(rewrap_rule_elem s + (Ast.ExprStatement(expression exp,mcode sem))) + | Ast0.IfThen(iff,lp,exp,rp,branch,(_,aft)) -> + Ast.IfThen + (rewrap_rule_elem s + (Ast.IfHeader(mcode iff,mcode lp,expression exp,mcode rp)), + statement Ast.NotSequencible branch, + ([],[],[],convert_mcodekind aft)) + | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,(_,aft)) -> + let els = mcode els in + Ast.IfThenElse + (rewrap_rule_elem s + (Ast.IfHeader(mcode iff,mcode lp,expression exp,mcode rp)), + statement Ast.NotSequencible branch1, + tokenwrap els s (Ast.Else(els)), + statement Ast.NotSequencible branch2, + ([],[],[],convert_mcodekind aft)) + | Ast0.While(wh,lp,exp,rp,body,(_,aft)) -> + Ast.While(rewrap_rule_elem s + (Ast.WhileHeader + (mcode wh,mcode lp,expression exp,mcode rp)), + statement Ast.NotSequencible body, + ([],[],[],convert_mcodekind aft)) + | Ast0.Do(d,body,wh,lp,exp,rp,sem) -> + let wh = mcode wh in + Ast.Do(rewrap_rule_elem s (Ast.DoHeader(mcode d)), + statement Ast.NotSequencible body, + tokenwrap wh s + (Ast.WhileTail(wh,mcode lp,expression exp,mcode rp, + mcode sem))) + | Ast0.For(fr,lp,exp1,sem1,exp2,sem2,exp3,rp,body,(_,aft)) -> + let fr = mcode fr in + let lp = mcode lp in + let exp1 = get_option expression exp1 in + let sem1 = mcode sem1 in + let exp2 = get_option expression exp2 in + let sem2= mcode sem2 in + let exp3 = get_option expression exp3 in + let rp = mcode rp in + let body = statement Ast.NotSequencible body in + Ast.For(rewrap_rule_elem s + (Ast.ForHeader(fr,lp,exp1,sem1,exp2,sem2,exp3,rp)), + body,([],[],[],convert_mcodekind aft)) + | Ast0.Iterator(nm,lp,args,rp,body,(_,aft)) -> + Ast.Iterator(rewrap_rule_elem s + (Ast.IteratorHeader + (ident nm,mcode lp, + dots expression args, + mcode rp)), + statement Ast.NotSequencible body, + ([],[],[],convert_mcodekind aft)) + | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) -> + let switch = mcode switch in + let lp = mcode lp in + let exp = expression exp in + let rp = mcode rp in + let lb = mcode lb in + let cases = List.map case_line (Ast0.undots cases) in + let rb = mcode rb in + Ast.Switch(rewrap_rule_elem s (Ast.SwitchHeader(switch,lp,exp,rp)), + tokenwrap lb s (Ast.SeqStart(lb)), + cases, + tokenwrap rb s (Ast.SeqEnd(rb))) + | Ast0.Break(br,sem) -> + Ast.Atomic(rewrap_rule_elem s (Ast.Break(mcode br,mcode sem))) + | Ast0.Continue(cont,sem) -> + Ast.Atomic(rewrap_rule_elem s (Ast.Continue(mcode cont,mcode sem))) + | Ast0.Label(l,dd) -> + Ast.Atomic(rewrap_rule_elem s (Ast.Label(ident l,mcode dd))) + | Ast0.Goto(goto,l,sem) -> + Ast.Atomic + (rewrap_rule_elem s (Ast.Goto(mcode goto,ident l,mcode sem))) + | Ast0.Return(ret,sem) -> + Ast.Atomic(rewrap_rule_elem s (Ast.Return(mcode ret,mcode sem))) + | Ast0.ReturnExpr(ret,exp,sem) -> + Ast.Atomic + (rewrap_rule_elem s + (Ast.ReturnExpr(mcode ret,expression exp,mcode sem))) + | Ast0.MetaStmt(name,_) -> + Ast.Atomic(rewrap_rule_elem s + (Ast.MetaStmt(mcode name,unitary,seqible,false))) + | Ast0.MetaStmtList(name,_) -> + Ast.Atomic(rewrap_rule_elem s + (Ast.MetaStmtList(mcode name,unitary,false))) + | Ast0.TopExp(exp) -> + Ast.Atomic(rewrap_rule_elem s (Ast.TopExp(expression exp))) + | Ast0.Exp(exp) -> + Ast.Atomic(rewrap_rule_elem s (Ast.Exp(expression exp))) + | Ast0.Ty(ty) -> + Ast.Atomic(rewrap_rule_elem s (Ast.Ty(typeC ty))) + | Ast0.Disj(_,rule_elem_dots_list,_,_) -> + Ast.Disj(List.map (function x -> statement_dots seqible x) + rule_elem_dots_list) + | Ast0.Nest(_,rule_elem_dots,_,whn,multi) -> + Ast.Nest + (statement_dots Ast.Sequencible rule_elem_dots, + List.map + (whencode (statement_dots Ast.Sequencible) + (statement Ast.NotSequencible)) + whn, + multi,[],[]) + | Ast0.Dots(d,whn) -> + let d = mcode d in + let whn = + List.map + (whencode (statement_dots Ast.Sequencible) + (statement Ast.NotSequencible)) + whn in + Ast.Dots(d,whn,[],[]) + | Ast0.Circles(d,whn) -> + let d = mcode d in + let whn = + List.map + (whencode (statement_dots Ast.Sequencible) + (statement Ast.NotSequencible)) + whn in + Ast.Circles(d,whn,[],[]) + | Ast0.Stars(d,whn) -> + let d = mcode d in + let whn = + List.map + (whencode (statement_dots Ast.Sequencible) + (statement Ast.NotSequencible)) + whn in + Ast.Stars(d,whn,[],[]) + | Ast0.FunDecl((_,bef),fi,name,lp,params,rp,lbrace,body,rbrace) -> + let fi = List.map fninfo fi in + let name = ident name in + let lp = mcode lp in + let params = parameter_list params in + let rp = mcode rp in + let lbrace = mcode lbrace in + let (decls,body) = separate_decls seqible body in + let rbrace = mcode rbrace in + let allminus = check_allminus.V0.combiner_statement s in + Ast.FunDecl(rewrap_rule_elem s + (Ast.FunHeader(convert_mcodekind bef, + allminus,fi,name,lp,params,rp)), + tokenwrap lbrace s (Ast.SeqStart(lbrace)), + decls,body, + tokenwrap rbrace s (Ast.SeqEnd(rbrace))) + | Ast0.Include(inc,str) -> + Ast.Atomic(rewrap_rule_elem s (Ast.Include(mcode inc,mcode str))) + | Ast0.Define(def,id,params,body) -> + Ast.Define + (rewrap_rule_elem s + (Ast.DefineHeader + (mcode def,ident id, define_parameters params)), + statement_dots Ast.NotSequencible (*not sure*) body) + | Ast0.OptStm(stm) -> Ast.OptStm(statement seqible stm) + | Ast0.UniqueStm(stm) -> Ast.UniqueStm(statement seqible stm)) + + and define_parameters p = + rewrap p no_isos + (match Ast0.unwrap p with + Ast0.NoParams -> Ast.NoParams + | Ast0.DParams(lp,params,rp) -> + Ast.DParams(mcode lp, + dots define_param params, + mcode rp)) + + and define_param p = + rewrap p no_isos + (match Ast0.unwrap p with + Ast0.DParam(id) -> Ast.DParam(ident id) + | Ast0.DPComma(comma) -> Ast.DPComma(mcode comma) + | Ast0.DPdots(d) -> Ast.DPdots(mcode d) + | Ast0.DPcircles(c) -> Ast.DPcircles(mcode c) + | Ast0.OptDParam(dp) -> Ast.OptDParam(define_param dp) + | Ast0.UniqueDParam(dp) -> Ast.UniqueDParam(define_param dp)) + + and whencode notfn alwaysfn = function + Ast0.WhenNot a -> Ast.WhenNot (notfn a) + | Ast0.WhenAlways a -> Ast.WhenAlways (alwaysfn a) + | Ast0.WhenModifier(x) -> Ast.WhenModifier(x) + + and process_list seqible isos = function + [] -> [] + | x::rest -> + let first = statement seqible x in + let first = + if !Flag.track_iso_usage + then Ast.set_isos first (isos@(Ast.get_isos first)) + else first in + (match Ast0.unwrap x with + Ast0.Dots(_,_) | Ast0.Nest(_) -> + first::(process_list (Ast.SequencibleAfterDots []) no_isos rest) + | _ -> + first::(process_list Ast.Sequencible no_isos rest)) + + and statement_dots seqible d = + let isos = do_isos (Ast0.get_iso d) in + rewrap d no_isos + (match Ast0.unwrap d with + Ast0.DOTS(x) -> Ast.DOTS(process_list seqible isos x) + | Ast0.CIRCLES(x) -> Ast.CIRCLES(process_list seqible isos x) + | Ast0.STARS(x) -> Ast.STARS(process_list seqible isos x)) + + and separate_decls seqible d = + let rec collect_decls = function + [] -> ([],[]) + | (x::xs) as l -> + (match Ast0.unwrap x with + Ast0.Decl(_) -> + let (decls,other) = collect_decls xs in + (x :: decls,other) + | Ast0.Dots(_,_) | Ast0.Nest(_,_,_,_,_) -> + let (decls,other) = collect_decls xs in + (match decls with + [] -> ([],x::other) + | _ -> (x :: decls,other)) + | Ast0.Disj(starter,stmt_dots_list,mids,ender) -> + let disjs = List.map collect_dot_decls stmt_dots_list in + let all_decls = List.for_all (function (_,s) -> s=[]) disjs in + if all_decls + then + let (decls,other) = collect_decls xs in + (x :: decls,other) + else ([],l) + | _ -> ([],l)) + + and collect_dot_decls d = + match Ast0.unwrap d with + Ast0.DOTS(x) -> collect_decls x + | Ast0.CIRCLES(x) -> collect_decls x + | Ast0.STARS(x) -> collect_decls x in + + let process l d fn = + let (decls,other) = collect_decls l in + (rewrap d no_isos (fn (List.map (statement seqible) decls)), + rewrap d no_isos + (fn (process_list seqible (do_isos (Ast0.get_iso d)) other))) in + match Ast0.unwrap d with + Ast0.DOTS(x) -> process x d (function x -> Ast.DOTS x) + | Ast0.CIRCLES(x) -> process x d (function x -> Ast.CIRCLES x) + | Ast0.STARS(x) -> process x d (function x -> Ast.STARS x) in + + statement Ast.Sequencible s + +and fninfo = function + Ast0.FStorage(stg) -> Ast.FStorage(mcode stg) + | Ast0.FType(ty) -> Ast.FType(typeC ty) + | Ast0.FInline(inline) -> Ast.FInline(mcode inline) + | Ast0.FAttr(attr) -> Ast.FAttr(mcode attr) + +and option_to_list = function + Some x -> [x] + | None -> [] + +and case_line c = + rewrap c no_isos + (match Ast0.unwrap c with + Ast0.Default(def,colon,code) -> + let def = mcode def in + let colon = mcode colon in + let code = dots statement code in + Ast.CaseLine(rewrap c no_isos (Ast.Default(def,colon)),code) + | Ast0.Case(case,exp,colon,code) -> + let case = mcode case in + let exp = expression exp in + let colon = mcode colon in + let code = dots statement code in + Ast.CaseLine(rewrap c no_isos (Ast.Case(case,exp,colon)),code) + | Ast0.OptCase(case) -> Ast.OptCase(case_line case)) + +and statement_dots l = dots statement l + +(* --------------------------------------------------------------------- *) + +(* what is possible is only what is at the top level in an iso *) +and anything = function + Ast0.DotsExprTag(d) -> Ast.ExprDotsTag(expression_dots d) + | Ast0.DotsParamTag(d) -> Ast.ParamDotsTag(parameter_list d) + | Ast0.DotsInitTag(d) -> failwith "not possible" + | Ast0.DotsStmtTag(d) -> Ast.StmtDotsTag(statement_dots d) + | Ast0.DotsDeclTag(d) -> Ast.DeclDotsTag(declaration_dots d) + | Ast0.DotsCaseTag(d) -> failwith "not possible" + | Ast0.IdentTag(d) -> Ast.IdentTag(ident d) + | Ast0.ExprTag(d) -> Ast.ExpressionTag(expression d) + | Ast0.ArgExprTag(d) | Ast0.TestExprTag(d) -> + failwith "only in isos, not converted to ast" + | Ast0.TypeCTag(d) -> Ast.FullTypeTag(typeC d) + | Ast0.ParamTag(d) -> Ast.ParamTag(parameterTypeDef d) + | Ast0.InitTag(d) -> Ast.InitTag(initialiser d) + | Ast0.DeclTag(d) -> Ast.DeclarationTag(declaration d) + | Ast0.StmtTag(d) -> Ast.StatementTag(statement d) + | Ast0.CaseLineTag(d) -> Ast.CaseLineTag(case_line d) + | Ast0.TopTag(d) -> Ast.Code(top_level d) + | Ast0.IsoWhenTag(_) -> failwith "not possible" + | Ast0.MetaPosTag _ -> failwith "not possible" + +(* --------------------------------------------------------------------- *) +(* Function declaration *) +(* top level isos are probably lost to tracking *) + +and top_level t = + rewrap t no_isos + (match Ast0.unwrap t with + Ast0.FILEINFO(old_file,new_file) -> + Ast.FILEINFO(mcode old_file,mcode new_file) + | Ast0.DECL(stmt) -> Ast.DECL(statement stmt) + | Ast0.CODE(rule_elem_dots) -> + Ast.CODE(statement_dots rule_elem_dots) + | Ast0.ERRORWORDS(exps) -> Ast.ERRORWORDS(List.map expression exps) + | Ast0.OTHER(_) -> failwith "eliminated by top_level") + +(* --------------------------------------------------------------------- *) +(* Entry point for minus code *) + +(* Inline_mcodes is very important - sends + code attached to the - code +down to the mcodes. The functions above can only be used when there is no +attached + code, eg in + code itself. *) +let ast0toast_toplevel x = + inline_mcodes.V0.combiner_top_level x; + top_level x + +let ast0toast name deps dropped exists x is_exp = + List.iter inline_mcodes.V0.combiner_top_level x; + Ast.CocciRule (name,(deps,dropped,exists),List.map top_level x,is_exp) diff --git a/parsing_cocci/.#ast0toast.ml.1.133 b/parsing_cocci/.#ast0toast.ml.1.133 new file mode 100644 index 0000000..1948804 --- /dev/null +++ b/parsing_cocci/.#ast0toast.ml.1.133 @@ -0,0 +1,927 @@ +(* +* 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. +*) + + +(* Arities matter for the minus slice, but not for the plus slice. *) + +(* + only allowed on code in a nest (in_nest = true). ? only allowed on +rule_elems, and on subterms if the context is ? also. *) + +module Ast0 = Ast0_cocci +module Ast = Ast_cocci +module V0 = Visitor_ast0 +module V = Visitor_ast + +let unitary = Type_cocci.Unitary + +let ctr = ref 0 +let get_ctr _ = + let c = !ctr in + ctr := !ctr + 1; + c + +(* --------------------------------------------------------------------- *) +(* Move plus tokens from the MINUS and CONTEXT structured nodes to the +corresponding leftmost and rightmost mcodes *) + +let inline_mcodes = + let bind x y = () in + let option_default = () in + let mcode _ = () in + let do_nothing r k e = + k e; + let einfo = Ast0.get_info e in + match (Ast0.get_mcodekind e) with + Ast0.MINUS(replacements) -> + (match !replacements with + ([],_) -> () + | replacements -> + let minus_try = function + (true,mc) -> + if List.for_all + (function + Ast0.MINUS(mreplacements) -> true | _ -> false) + mc + then + (List.iter + (function + Ast0.MINUS(mreplacements) -> + mreplacements := replacements + | _ -> ()) + mc; + true) + else false + | _ -> false in + if not (minus_try(einfo.Ast0.attachable_start, + einfo.Ast0.mcode_start) + or + minus_try(einfo.Ast0.attachable_end, + einfo.Ast0.mcode_end)) + then + failwith "minus tree should not have bad code on both sides") + | Ast0.CONTEXT(befaft) + | Ast0.MIXED(befaft) -> + let concat starter startinfo ender endinfo = + let lst = + match (starter,ender) with + ([],_) -> ender + | (_,[]) -> starter + | _ -> + if startinfo.Ast0.tline_end = endinfo.Ast0.tline_start + then (* put them in the same inner list *) + let last = List.hd (List.rev starter) in + let butlast = List.rev(List.tl(List.rev starter)) in + butlast @ (last@(List.hd ender)) :: (List.tl ender) + else starter @ ender in + (lst, + {endinfo with Ast0.tline_start = startinfo.Ast0.tline_start}) in + let attach_bef bef beforeinfo = function + (true,mcl) -> + List.iter + (function + Ast0.MINUS(mreplacements) -> + let (mrepl,tokeninfo) = !mreplacements in + mreplacements := concat bef beforeinfo mrepl tokeninfo + | Ast0.CONTEXT(mbefaft) -> + (match !mbefaft with + (Ast.BEFORE(mbef),mbeforeinfo,a) -> + let (newbef,newinfo) = + concat bef beforeinfo mbef mbeforeinfo in + mbefaft := (Ast.BEFORE(newbef),newinfo,a) + | (Ast.AFTER(maft),_,a) -> + mbefaft := + (Ast.BEFOREAFTER(bef,maft),beforeinfo,a) + | (Ast.BEFOREAFTER(mbef,maft),mbeforeinfo,a) -> + let (newbef,newinfo) = + concat bef beforeinfo mbef mbeforeinfo in + mbefaft := + (Ast.BEFOREAFTER(newbef,maft),newinfo,a) + | (Ast.NOTHING,_,a) -> + mbefaft := (Ast.BEFORE(bef),beforeinfo,a)) + | _ -> failwith "unexpected annotation") + mcl + | _ -> + failwith + "context tree should not have bad code on both sides" in + let attach_aft aft afterinfo = function + (true,mcl) -> + List.iter + (function + Ast0.MINUS(mreplacements) -> + let (mrepl,tokeninfo) = !mreplacements in + mreplacements := concat mrepl tokeninfo aft afterinfo + | Ast0.CONTEXT(mbefaft) -> + (match !mbefaft with + (Ast.BEFORE(mbef),b,_) -> + mbefaft := + (Ast.BEFOREAFTER(mbef,aft),b,afterinfo) + | (Ast.AFTER(maft),b,mafterinfo) -> + let (newaft,newinfo) = + concat maft mafterinfo aft afterinfo in + mbefaft := (Ast.AFTER(newaft),b,newinfo) + | (Ast.BEFOREAFTER(mbef,maft),b,mafterinfo) -> + let (newaft,newinfo) = + concat maft mafterinfo aft afterinfo in + mbefaft := + (Ast.BEFOREAFTER(mbef,newaft),b,newinfo) + | (Ast.NOTHING,b,_) -> + mbefaft := (Ast.AFTER(aft),b,afterinfo)) + | _ -> failwith "unexpected annotation") + mcl + | _ -> + failwith + "context tree should not have bad code on both sides" in + (match !befaft with + (Ast.BEFORE(bef),beforeinfo,_) -> + attach_bef bef beforeinfo + (einfo.Ast0.attachable_start,einfo.Ast0.mcode_start) + | (Ast.AFTER(aft),_,afterinfo) -> + attach_aft aft afterinfo + (einfo.Ast0.attachable_end,einfo.Ast0.mcode_end) + | (Ast.BEFOREAFTER(bef,aft),beforeinfo,afterinfo) -> + attach_bef bef beforeinfo + (einfo.Ast0.attachable_start,einfo.Ast0.mcode_start); + attach_aft aft afterinfo + (einfo.Ast0.attachable_end,einfo.Ast0.mcode_end) + | (Ast.NOTHING,_,_) -> ()) + | Ast0.PLUS -> () 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 + +(* --------------------------------------------------------------------- *) +(* For function declarations. Can't use the mcode at the root, because that +might be mixed when the function contains ()s, where agglomeration of -s is +not possible. *) + +let check_allminus = + let donothing r k e = k e in + let bind x y = x && y in + let option_default = true in + let mcode (_,_,_,mc,_) = + match mc with + Ast0.MINUS(r) -> let (plusses,_) = !r in plusses = [] + | _ -> false in + + (* special case for disj *) + let expression r k e = + match Ast0.unwrap e with + Ast0.DisjExpr(starter,expr_list,mids,ender) -> + List.for_all r.V0.combiner_expression expr_list + | _ -> k e in + + let declaration r k e = + match Ast0.unwrap e with + Ast0.DisjDecl(starter,decls,mids,ender) -> + List.for_all r.V0.combiner_declaration decls + | _ -> k e in + + let typeC r k e = + match Ast0.unwrap e with + Ast0.DisjType(starter,decls,mids,ender) -> + List.for_all r.V0.combiner_typeC decls + | _ -> k e in + + let statement r k e = + match Ast0.unwrap e with + Ast0.Disj(starter,statement_dots_list,mids,ender) -> + List.for_all r.V0.combiner_statement_dots statement_dots_list + | _ -> k e 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 expression typeC donothing donothing declaration + statement donothing donothing + +(* --------------------------------------------------------------------- *) +(* --------------------------------------------------------------------- *) + +let get_option fn = function + None -> None + | Some x -> Some (fn x) + +(* --------------------------------------------------------------------- *) +(* --------------------------------------------------------------------- *) +(* Mcode *) + +let convert_info info = + { Ast.line = info.Ast0.line_start; Ast.column = info.Ast0.column; + Ast.strbef = info.Ast0.strings_before; + Ast.straft = info.Ast0.strings_after; } + +let convert_mcodekind = function + Ast0.MINUS(replacements) -> + let (replacements,_) = !replacements in + Ast.MINUS(Ast.NoPos,replacements) + | Ast0.PLUS -> Ast.PLUS + | Ast0.CONTEXT(befaft) -> + let (befaft,_,_) = !befaft in Ast.CONTEXT(Ast.NoPos,befaft) + | Ast0.MIXED(_) -> failwith "not possible for mcode" + +let pos_mcode(term,_,info,mcodekind,pos) = + (* avoids a recursion problem *) + (term,convert_info info,convert_mcodekind mcodekind,Ast.NoMetaPos) + +let mcode(term,_,info,mcodekind,pos) = + let pos = + match !pos with + Ast0.MetaPos(pos,constraints,per) -> + Ast.MetaPos(pos_mcode pos,constraints,per,unitary,false) + | _ -> Ast.NoMetaPos in + (term,convert_info info,convert_mcodekind mcodekind,pos) + +(* --------------------------------------------------------------------- *) +(* Dots *) +let wrap ast line isos = + {(Ast.make_term ast) with Ast.node_line = line; + Ast.iso_info = isos} + +let rewrap ast0 isos ast = + wrap ast ((Ast0.get_info ast0).Ast0.line_start) isos + +let no_isos = [] + +(* no isos on tokens *) +let tokenwrap (_,info,_,_) s ast = wrap ast info.Ast.line no_isos +let iso_tokenwrap (_,info,_,_) s ast iso = wrap ast info.Ast.line iso + +let dots fn d = + rewrap d no_isos + (match Ast0.unwrap d with + Ast0.DOTS(x) -> Ast.DOTS(List.map fn x) + | Ast0.CIRCLES(x) -> Ast.CIRCLES(List.map fn x) + | Ast0.STARS(x) -> Ast.STARS(List.map fn x)) + +(* --------------------------------------------------------------------- *) +(* Identifier *) + +let rec do_isos l = List.map (function (nm,x) -> (nm,anything x)) l + +and ident i = + rewrap i (do_isos (Ast0.get_iso i)) + (match Ast0.unwrap i with + Ast0.Id(name) -> Ast.Id(mcode name) + | Ast0.MetaId(name,constraints,_) -> + let constraints = List.map ident constraints in + Ast.MetaId(mcode name,constraints,unitary,false) + | Ast0.MetaFunc(name,constraints,_) -> + let constraints = List.map ident constraints in + Ast.MetaFunc(mcode name,constraints,unitary,false) + | Ast0.MetaLocalFunc(name,constraints,_) -> + let constraints = List.map ident constraints in + Ast.MetaLocalFunc(mcode name,constraints,unitary,false) + | Ast0.OptIdent(id) -> Ast.OptIdent(ident id) + | Ast0.UniqueIdent(id) -> Ast.UniqueIdent(ident id)) + +(* --------------------------------------------------------------------- *) +(* Expression *) + +and expression e = + let e1 = + rewrap e (do_isos (Ast0.get_iso e)) + (match Ast0.unwrap e with + Ast0.Ident(id) -> Ast.Ident(ident id) + | Ast0.Constant(const) -> + Ast.Constant(mcode const) + | Ast0.FunCall(fn,lp,args,rp) -> + let fn = expression fn in + let lp = mcode lp in + let args = dots expression args in + let rp = mcode rp in + Ast.FunCall(fn,lp,args,rp) + | Ast0.Assignment(left,op,right,simple) -> + Ast.Assignment(expression left,mcode op,expression right,simple) + | Ast0.CondExpr(exp1,why,exp2,colon,exp3) -> + let exp1 = expression exp1 in + let why = mcode why in + let exp2 = get_option expression exp2 in + let colon = mcode colon in + let exp3 = expression exp3 in + Ast.CondExpr(exp1,why,exp2,colon,exp3) + | Ast0.Postfix(exp,op) -> + Ast.Postfix(expression exp,mcode op) + | Ast0.Infix(exp,op) -> + Ast.Infix(expression exp,mcode op) + | Ast0.Unary(exp,op) -> + Ast.Unary(expression exp,mcode op) + | Ast0.Binary(left,op,right) -> + Ast.Binary(expression left,mcode op,expression right) + | Ast0.Nested(left,op,right) -> + Ast.Nested(expression left,mcode op,expression right) + | Ast0.Paren(lp,exp,rp) -> + Ast.Paren(mcode lp,expression exp,mcode rp) + | Ast0.ArrayAccess(exp1,lb,exp2,rb) -> + Ast.ArrayAccess(expression exp1,mcode lb,expression exp2,mcode rb) + | Ast0.RecordAccess(exp,pt,field) -> + Ast.RecordAccess(expression exp,mcode pt,ident field) + | Ast0.RecordPtAccess(exp,ar,field) -> + Ast.RecordPtAccess(expression exp,mcode ar,ident field) + | Ast0.Cast(lp,ty,rp,exp) -> + Ast.Cast(mcode lp,typeC ty,mcode rp,expression exp) + | Ast0.SizeOfExpr(szf,exp) -> + Ast.SizeOfExpr(mcode szf,expression exp) + | Ast0.SizeOfType(szf,lp,ty,rp) -> + Ast.SizeOfType(mcode szf, mcode lp,typeC ty,mcode rp) + | Ast0.TypeExp(ty) -> Ast.TypeExp(typeC ty) + | Ast0.MetaErr(name,constraints,_) -> + let constraints = List.map expression constraints in + Ast.MetaErr(mcode name,constraints,unitary,false) + | Ast0.MetaExpr(name,constraints,ty,form,_) -> + let constraints = List.map expression constraints in + Ast.MetaExpr(mcode name,constraints,unitary,ty,form,false) + | Ast0.MetaExprList(name,Some lenname,_) -> + Ast.MetaExprList(mcode name,Some (mcode lenname,unitary,false), + unitary,false) + | Ast0.MetaExprList(name,None,_) -> + Ast.MetaExprList(mcode name,None,unitary,false) + | Ast0.EComma(cm) -> Ast.EComma(mcode cm) + | Ast0.DisjExpr(_,exps,_,_) -> Ast.DisjExpr(List.map expression exps) + | Ast0.NestExpr(_,exp_dots,_,whencode,multi) -> + let whencode = get_option expression whencode in + Ast.NestExpr(dots expression exp_dots,whencode,multi) + | Ast0.Edots(dots,whencode) -> + let dots = mcode dots in + let whencode = get_option expression whencode in + Ast.Edots(dots,whencode) + | Ast0.Ecircles(dots,whencode) -> + let dots = mcode dots in + let whencode = get_option expression whencode in + Ast.Ecircles(dots,whencode) + | Ast0.Estars(dots,whencode) -> + let dots = mcode dots in + let whencode = get_option expression whencode in + Ast.Estars(dots,whencode) + | Ast0.OptExp(exp) -> Ast.OptExp(expression exp) + | Ast0.UniqueExp(exp) -> Ast.UniqueExp(expression exp)) in + if Ast0.get_test_exp e then Ast.set_test_exp e1 else e1 + +and expression_dots ed = dots expression ed + +(* --------------------------------------------------------------------- *) +(* Types *) + +and typeC t = + rewrap t (do_isos (Ast0.get_iso t)) + (match Ast0.unwrap t with + Ast0.ConstVol(cv,ty) -> + let rec collect_disjs t = + match Ast0.unwrap t with + Ast0.DisjType(_,types,_,_) -> + if Ast0.get_iso t = [] + then List.concat (List.map collect_disjs types) + else failwith "unexpected iso on a disjtype" + | _ -> [t] in + let res = + List.map + (function ty -> + Ast.Type + (Some (mcode cv), + rewrap ty (do_isos (Ast0.get_iso ty)) (base_typeC ty))) + (collect_disjs ty) in + (* one could worry that isos are lost because we flatten the + disjunctions. but there should not be isos on the disjunctions + themselves. *) + (match res with + [ty] -> ty + | types -> Ast.DisjType(List.map (rewrap t no_isos) types)) + | Ast0.BaseType(_,_) | Ast0.ImplicitInt(_) | Ast0.Pointer(_,_) + | Ast0.FunctionPointer(_,_,_,_,_,_,_) | Ast0.FunctionType(_,_,_,_) + | Ast0.Array(_,_,_,_) | Ast0.StructUnionName(_,_) + | Ast0.StructUnionDef(_,_,_,_) | Ast0.TypeName(_) | Ast0.MetaType(_,_) -> + Ast.Type(None,rewrap t no_isos (base_typeC t)) + | Ast0.DisjType(_,types,_,_) -> Ast.DisjType(List.map typeC types) + | Ast0.OptType(ty) -> Ast.OptType(typeC ty) + | Ast0.UniqueType(ty) -> Ast.UniqueType(typeC ty)) + +and base_typeC t = + match Ast0.unwrap t with + Ast0.BaseType(ty,sign) -> + Ast.BaseType(mcode ty,get_option mcode sign) + | Ast0.ImplicitInt(sgn) -> Ast.ImplicitInt(mcode sgn) + | Ast0.Pointer(ty,star) -> Ast.Pointer(typeC ty,mcode star) + | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> + Ast.FunctionPointer + (typeC ty,mcode lp1,mcode star,mcode rp1, + mcode lp2,parameter_list params,mcode rp2) + | Ast0.FunctionType(ret,lp,params,rp) -> + let allminus = check_allminus.V0.combiner_typeC t in + Ast.FunctionType + (allminus,get_option typeC ret,mcode lp, + parameter_list params,mcode rp) + | Ast0.Array(ty,lb,size,rb) -> + Ast.Array(typeC ty,mcode lb,get_option expression size,mcode rb) + | Ast0.StructUnionName(kind,name) -> + Ast.StructUnionName(mcode kind,get_option ident name) + | Ast0.StructUnionDef(ty,lb,decls,rb) -> + Ast.StructUnionDef(typeC ty,mcode lb, + dots declaration decls, + mcode rb) + | Ast0.TypeName(name) -> Ast.TypeName(mcode name) + | Ast0.MetaType(name,_) -> + Ast.MetaType(mcode name,unitary,false) + | _ -> failwith "ast0toast: unexpected type" + +(* --------------------------------------------------------------------- *) +(* 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 declaration d = + rewrap d (do_isos (Ast0.get_iso d)) + (match Ast0.unwrap d with + Ast0.Init(stg,ty,id,eq,ini,sem) -> + let stg = get_option mcode stg in + let ty = typeC ty in + let id = ident id in + let eq = mcode eq in + let ini = initialiser ini in + let sem = mcode sem in + Ast.Init(stg,ty,id,eq,ini,sem) + | Ast0.UnInit(stg,ty,id,sem) -> + (match Ast0.unwrap ty with + Ast0.FunctionType(tyx,lp1,params,rp1) -> + let allminus = check_allminus.V0.combiner_declaration d in + Ast.UnInit(get_option mcode stg, + rewrap ty (do_isos (Ast0.get_iso ty)) + (Ast.Type + (None, + rewrap ty no_isos + (Ast.FunctionType + (allminus,get_option typeC tyx,mcode lp1, + parameter_list params,mcode rp1)))), + ident id,mcode sem) + | _ -> Ast.UnInit(get_option mcode stg,typeC ty,ident id,mcode sem)) + | Ast0.MacroDecl(name,lp,args,rp,sem) -> + let name = ident name in + let lp = mcode lp in + let args = dots expression args in + let rp = mcode rp in + let sem = mcode sem in + Ast.MacroDecl(name,lp,args,rp,sem) + | Ast0.TyDecl(ty,sem) -> Ast.TyDecl(typeC ty,mcode sem) + | Ast0.Typedef(stg,ty,id,sem) -> + let id = typeC id in + (match Ast.unwrap id with + Ast.Type(None,id) -> (* only MetaType or Id *) + Ast.Typedef(mcode stg,typeC ty,id,mcode sem) + | _ -> failwith "bad typedef") + | Ast0.DisjDecl(_,decls,_,_) -> Ast.DisjDecl(List.map declaration decls) + | Ast0.Ddots(dots,whencode) -> + let dots = mcode dots in + let whencode = get_option declaration whencode in + Ast.Ddots(dots,whencode) + | Ast0.OptDecl(decl) -> Ast.OptDecl(declaration decl) + | Ast0.UniqueDecl(decl) -> Ast.UniqueDecl(declaration decl)) + +and declaration_dots l = dots declaration l + +(* --------------------------------------------------------------------- *) +(* Initialiser *) + +and strip_idots initlist = + match Ast0.unwrap initlist with + Ast0.DOTS(x) -> + let (whencode,init) = + List.fold_left + (function (prevwhen,previnit) -> + function cur -> + match Ast0.unwrap cur with + Ast0.Idots(dots,Some whencode) -> + (whencode :: prevwhen, previnit) + | Ast0.Idots(dots,None) -> (prevwhen,previnit) + | _ -> (prevwhen, cur :: previnit)) + ([],[]) x in + (List.rev whencode, List.rev init) + | Ast0.CIRCLES(x) | Ast0.STARS(x) -> failwith "not possible for an initlist" + +and initialiser i = + rewrap i no_isos + (match Ast0.unwrap i with + Ast0.InitExpr(exp) -> Ast.InitExpr(expression exp) + | Ast0.InitList(lb,initlist,rb) -> + let (whencode,initlist) = strip_idots initlist in + Ast.InitList(mcode lb,List.map initialiser initlist,mcode rb, + List.map initialiser whencode) + | Ast0.InitGccDotName(dot,name,eq,ini) -> + Ast.InitGccDotName(mcode dot,ident name,mcode eq,initialiser ini) + | Ast0.InitGccName(name,eq,ini) -> + Ast.InitGccName(ident name,mcode eq,initialiser ini) + | Ast0.InitGccIndex(lb,exp,rb,eq,ini) -> + Ast.InitGccIndex(mcode lb,expression exp,mcode rb,mcode eq, + initialiser ini) + | Ast0.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini) -> + Ast.InitGccRange(mcode lb,expression exp1,mcode dots, + expression exp2,mcode rb,mcode eq,initialiser ini) + | Ast0.IComma(comma) -> Ast.IComma(mcode comma) + | Ast0.Idots(_,_) -> failwith "Idots should have been removed" + | Ast0.OptIni(ini) -> Ast.OptIni(initialiser ini) + | Ast0.UniqueIni(ini) -> Ast.UniqueIni(initialiser ini)) + +(* --------------------------------------------------------------------- *) +(* Parameter *) + +and parameterTypeDef p = + rewrap p no_isos + (match Ast0.unwrap p with + Ast0.VoidParam(ty) -> Ast.VoidParam(typeC ty) + | Ast0.Param(ty,id) -> Ast.Param(typeC ty,get_option ident id) + | Ast0.MetaParam(name,_) -> + Ast.MetaParam(mcode name,unitary,false) + | Ast0.MetaParamList(name,Some lenname,_) -> + Ast.MetaParamList(mcode name,Some(mcode lenname,unitary,false), + unitary,false) + | Ast0.MetaParamList(name,None,_) -> + Ast.MetaParamList(mcode name,None,unitary,false) + | Ast0.PComma(cm) -> Ast.PComma(mcode cm) + | Ast0.Pdots(dots) -> Ast.Pdots(mcode dots) + | Ast0.Pcircles(dots) -> Ast.Pcircles(mcode dots) + | Ast0.OptParam(param) -> Ast.OptParam(parameterTypeDef param) + | Ast0.UniqueParam(param) -> Ast.UniqueParam(parameterTypeDef param)) + +and parameter_list l = dots parameterTypeDef l + +(* --------------------------------------------------------------------- *) +(* Top-level code *) + +and statement s = + let rec statement seqible s = + let rewrap_stmt ast0 ast = + let befaft = + match Ast0.get_dots_bef_aft s with + Ast0.NoDots -> Ast.NoDots + | Ast0.DroppingBetweenDots s -> + Ast.DroppingBetweenDots (statement seqible s,get_ctr()) + | Ast0.AddingBetweenDots s -> + Ast.AddingBetweenDots (statement seqible s,get_ctr()) in + Ast.set_dots_bef_aft befaft (rewrap ast0 no_isos ast) in + let rewrap_rule_elem ast0 ast = + rewrap ast0 (do_isos (Ast0.get_iso ast0)) ast in + rewrap_stmt s + (match Ast0.unwrap s with + Ast0.Decl((_,bef),decl) -> + Ast.Atomic(rewrap_rule_elem s + (Ast.Decl(convert_mcodekind bef, + check_allminus.V0.combiner_statement s, + declaration decl))) + | Ast0.Seq(lbrace,body,rbrace) -> + let lbrace = mcode lbrace in + let (decls,body) = separate_decls seqible body in + let rbrace = mcode rbrace in + Ast.Seq(iso_tokenwrap lbrace s (Ast.SeqStart(lbrace)) + (do_isos (Ast0.get_iso s)), + decls,body, + tokenwrap rbrace s (Ast.SeqEnd(rbrace))) + | Ast0.ExprStatement(exp,sem) -> + Ast.Atomic(rewrap_rule_elem s + (Ast.ExprStatement(expression exp,mcode sem))) + | Ast0.IfThen(iff,lp,exp,rp,branch,(_,aft)) -> + Ast.IfThen + (rewrap_rule_elem s + (Ast.IfHeader(mcode iff,mcode lp,expression exp,mcode rp)), + statement Ast.NotSequencible branch, + ([],[],[],convert_mcodekind aft)) + | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,(_,aft)) -> + let els = mcode els in + Ast.IfThenElse + (rewrap_rule_elem s + (Ast.IfHeader(mcode iff,mcode lp,expression exp,mcode rp)), + statement Ast.NotSequencible branch1, + tokenwrap els s (Ast.Else(els)), + statement Ast.NotSequencible branch2, + ([],[],[],convert_mcodekind aft)) + | Ast0.While(wh,lp,exp,rp,body,(_,aft)) -> + Ast.While(rewrap_rule_elem s + (Ast.WhileHeader + (mcode wh,mcode lp,expression exp,mcode rp)), + statement Ast.NotSequencible body, + ([],[],[],convert_mcodekind aft)) + | Ast0.Do(d,body,wh,lp,exp,rp,sem) -> + let wh = mcode wh in + Ast.Do(rewrap_rule_elem s (Ast.DoHeader(mcode d)), + statement Ast.NotSequencible body, + tokenwrap wh s + (Ast.WhileTail(wh,mcode lp,expression exp,mcode rp, + mcode sem))) + | Ast0.For(fr,lp,exp1,sem1,exp2,sem2,exp3,rp,body,(_,aft)) -> + let fr = mcode fr in + let lp = mcode lp in + let exp1 = get_option expression exp1 in + let sem1 = mcode sem1 in + let exp2 = get_option expression exp2 in + let sem2= mcode sem2 in + let exp3 = get_option expression exp3 in + let rp = mcode rp in + let body = statement Ast.NotSequencible body in + Ast.For(rewrap_rule_elem s + (Ast.ForHeader(fr,lp,exp1,sem1,exp2,sem2,exp3,rp)), + body,([],[],[],convert_mcodekind aft)) + | Ast0.Iterator(nm,lp,args,rp,body,(_,aft)) -> + Ast.Iterator(rewrap_rule_elem s + (Ast.IteratorHeader + (ident nm,mcode lp, + dots expression args, + mcode rp)), + statement Ast.NotSequencible body, + ([],[],[],convert_mcodekind aft)) + | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) -> + let switch = mcode switch in + let lp = mcode lp in + let exp = expression exp in + let rp = mcode rp in + let lb = mcode lb in + let cases = List.map case_line (Ast0.undots cases) in + let rb = mcode rb in + Ast.Switch(rewrap_rule_elem s (Ast.SwitchHeader(switch,lp,exp,rp)), + tokenwrap lb s (Ast.SeqStart(lb)), + cases, + tokenwrap rb s (Ast.SeqEnd(rb))) + | Ast0.Break(br,sem) -> + Ast.Atomic(rewrap_rule_elem s (Ast.Break(mcode br,mcode sem))) + | Ast0.Continue(cont,sem) -> + Ast.Atomic(rewrap_rule_elem s (Ast.Continue(mcode cont,mcode sem))) + | Ast0.Label(l,dd) -> + Ast.Atomic(rewrap_rule_elem s (Ast.Label(ident l,mcode dd))) + | Ast0.Goto(goto,l,sem) -> + Ast.Atomic + (rewrap_rule_elem s (Ast.Goto(mcode goto,ident l,mcode sem))) + | Ast0.Return(ret,sem) -> + Ast.Atomic(rewrap_rule_elem s (Ast.Return(mcode ret,mcode sem))) + | Ast0.ReturnExpr(ret,exp,sem) -> + Ast.Atomic + (rewrap_rule_elem s + (Ast.ReturnExpr(mcode ret,expression exp,mcode sem))) + | Ast0.MetaStmt(name,_) -> + Ast.Atomic(rewrap_rule_elem s + (Ast.MetaStmt(mcode name,unitary,seqible,false))) + | Ast0.MetaStmtList(name,_) -> + Ast.Atomic(rewrap_rule_elem s + (Ast.MetaStmtList(mcode name,unitary,false))) + | Ast0.TopExp(exp) -> + Ast.Atomic(rewrap_rule_elem s (Ast.TopExp(expression exp))) + | Ast0.Exp(exp) -> + Ast.Atomic(rewrap_rule_elem s (Ast.Exp(expression exp))) + | Ast0.Ty(ty) -> + Ast.Atomic(rewrap_rule_elem s (Ast.Ty(typeC ty))) + | Ast0.Disj(_,rule_elem_dots_list,_,_) -> + Ast.Disj(List.map (function x -> statement_dots seqible x) + rule_elem_dots_list) + | Ast0.Nest(_,rule_elem_dots,_,whn,multi) -> + Ast.Nest + (statement_dots Ast.Sequencible rule_elem_dots, + List.map + (whencode (statement_dots Ast.Sequencible) + (statement Ast.NotSequencible)) + whn, + multi,[],[]) + | Ast0.Dots(d,whn) -> + let d = mcode d in + let whn = + List.map + (whencode (statement_dots Ast.Sequencible) + (statement Ast.NotSequencible)) + whn in + Ast.Dots(d,whn,[],[]) + | Ast0.Circles(d,whn) -> + let d = mcode d in + let whn = + List.map + (whencode (statement_dots Ast.Sequencible) + (statement Ast.NotSequencible)) + whn in + Ast.Circles(d,whn,[],[]) + | Ast0.Stars(d,whn) -> + let d = mcode d in + let whn = + List.map + (whencode (statement_dots Ast.Sequencible) + (statement Ast.NotSequencible)) + whn in + Ast.Stars(d,whn,[],[]) + | Ast0.FunDecl((_,bef),fi,name,lp,params,rp,lbrace,body,rbrace) -> + let fi = List.map fninfo fi in + let name = ident name in + let lp = mcode lp in + let params = parameter_list params in + let rp = mcode rp in + let lbrace = mcode lbrace in + let (decls,body) = separate_decls seqible body in + let rbrace = mcode rbrace in + let allminus = check_allminus.V0.combiner_statement s in + Ast.FunDecl(rewrap_rule_elem s + (Ast.FunHeader(convert_mcodekind bef, + allminus,fi,name,lp,params,rp)), + tokenwrap lbrace s (Ast.SeqStart(lbrace)), + decls,body, + tokenwrap rbrace s (Ast.SeqEnd(rbrace))) + | Ast0.Include(inc,str) -> + Ast.Atomic(rewrap_rule_elem s (Ast.Include(mcode inc,mcode str))) + | Ast0.Define(def,id,params,body) -> + Ast.Define + (rewrap_rule_elem s + (Ast.DefineHeader + (mcode def,ident id, define_parameters params)), + statement_dots Ast.NotSequencible (*not sure*) body) + | Ast0.OptStm(stm) -> Ast.OptStm(statement seqible stm) + | Ast0.UniqueStm(stm) -> Ast.UniqueStm(statement seqible stm)) + + and define_parameters p = + rewrap p no_isos + (match Ast0.unwrap p with + Ast0.NoParams -> Ast.NoParams + | Ast0.DParams(lp,params,rp) -> + Ast.DParams(mcode lp, + dots define_param params, + mcode rp)) + + and define_param p = + rewrap p no_isos + (match Ast0.unwrap p with + Ast0.DParam(id) -> Ast.DParam(ident id) + | Ast0.DPComma(comma) -> Ast.DPComma(mcode comma) + | Ast0.DPdots(d) -> Ast.DPdots(mcode d) + | Ast0.DPcircles(c) -> Ast.DPcircles(mcode c) + | Ast0.OptDParam(dp) -> Ast.OptDParam(define_param dp) + | Ast0.UniqueDParam(dp) -> Ast.UniqueDParam(define_param dp)) + + and whencode notfn alwaysfn = function + Ast0.WhenNot a -> Ast.WhenNot (notfn a) + | Ast0.WhenAlways a -> Ast.WhenAlways (alwaysfn a) + | Ast0.WhenModifier(x) -> Ast.WhenModifier(x) + | x -> + let rewrap_rule_elem ast0 ast = + rewrap ast0 (do_isos (Ast0.get_iso ast0)) ast in + match x with + Ast0.WhenNotTrue(e) -> + Ast.WhenNotTrue(rewrap_rule_elem e (Ast.Exp(expression e))) + | Ast0.WhenNotFalse(e) -> + Ast.WhenNotFalse(rewrap_rule_elem e (Ast.Exp(expression e))) + | _ -> failwith "not possible" + + and process_list seqible isos = function + [] -> [] + | x::rest -> + let first = statement seqible x in + let first = + if !Flag.track_iso_usage + then Ast.set_isos first (isos@(Ast.get_isos first)) + else first in + (match Ast0.unwrap x with + Ast0.Dots(_,_) | Ast0.Nest(_) -> + first::(process_list (Ast.SequencibleAfterDots []) no_isos rest) + | _ -> + first::(process_list Ast.Sequencible no_isos rest)) + + and statement_dots seqible d = + let isos = do_isos (Ast0.get_iso d) in + rewrap d no_isos + (match Ast0.unwrap d with + Ast0.DOTS(x) -> Ast.DOTS(process_list seqible isos x) + | Ast0.CIRCLES(x) -> Ast.CIRCLES(process_list seqible isos x) + | Ast0.STARS(x) -> Ast.STARS(process_list seqible isos x)) + + and separate_decls seqible d = + let rec collect_decls = function + [] -> ([],[]) + | (x::xs) as l -> + (match Ast0.unwrap x with + Ast0.Decl(_) -> + let (decls,other) = collect_decls xs in + (x :: decls,other) + | Ast0.Dots(_,_) | Ast0.Nest(_,_,_,_,_) -> + let (decls,other) = collect_decls xs in + (match decls with + [] -> ([],x::other) + | _ -> (x :: decls,other)) + | Ast0.Disj(starter,stmt_dots_list,mids,ender) -> + let disjs = List.map collect_dot_decls stmt_dots_list in + let all_decls = List.for_all (function (_,s) -> s=[]) disjs in + if all_decls + then + let (decls,other) = collect_decls xs in + (x :: decls,other) + else ([],l) + | _ -> ([],l)) + + and collect_dot_decls d = + match Ast0.unwrap d with + Ast0.DOTS(x) -> collect_decls x + | Ast0.CIRCLES(x) -> collect_decls x + | Ast0.STARS(x) -> collect_decls x in + + let process l d fn = + let (decls,other) = collect_decls l in + (rewrap d no_isos (fn (List.map (statement seqible) decls)), + rewrap d no_isos + (fn (process_list seqible (do_isos (Ast0.get_iso d)) other))) in + match Ast0.unwrap d with + Ast0.DOTS(x) -> process x d (function x -> Ast.DOTS x) + | Ast0.CIRCLES(x) -> process x d (function x -> Ast.CIRCLES x) + | Ast0.STARS(x) -> process x d (function x -> Ast.STARS x) in + + statement Ast.Sequencible s + +and fninfo = function + Ast0.FStorage(stg) -> Ast.FStorage(mcode stg) + | Ast0.FType(ty) -> Ast.FType(typeC ty) + | Ast0.FInline(inline) -> Ast.FInline(mcode inline) + | Ast0.FAttr(attr) -> Ast.FAttr(mcode attr) + +and option_to_list = function + Some x -> [x] + | None -> [] + +and case_line c = + rewrap c no_isos + (match Ast0.unwrap c with + Ast0.Default(def,colon,code) -> + let def = mcode def in + let colon = mcode colon in + let code = dots statement code in + Ast.CaseLine(rewrap c no_isos (Ast.Default(def,colon)),code) + | Ast0.Case(case,exp,colon,code) -> + let case = mcode case in + let exp = expression exp in + let colon = mcode colon in + let code = dots statement code in + Ast.CaseLine(rewrap c no_isos (Ast.Case(case,exp,colon)),code) + | Ast0.OptCase(case) -> Ast.OptCase(case_line case)) + +and statement_dots l = dots statement l + +(* --------------------------------------------------------------------- *) + +(* what is possible is only what is at the top level in an iso *) +and anything = function + Ast0.DotsExprTag(d) -> Ast.ExprDotsTag(expression_dots d) + | Ast0.DotsParamTag(d) -> Ast.ParamDotsTag(parameter_list d) + | Ast0.DotsInitTag(d) -> failwith "not possible" + | Ast0.DotsStmtTag(d) -> Ast.StmtDotsTag(statement_dots d) + | Ast0.DotsDeclTag(d) -> Ast.DeclDotsTag(declaration_dots d) + | Ast0.DotsCaseTag(d) -> failwith "not possible" + | Ast0.IdentTag(d) -> Ast.IdentTag(ident d) + | Ast0.ExprTag(d) -> Ast.ExpressionTag(expression d) + | Ast0.ArgExprTag(d) | Ast0.TestExprTag(d) -> + failwith "only in isos, not converted to ast" + | Ast0.TypeCTag(d) -> Ast.FullTypeTag(typeC d) + | Ast0.ParamTag(d) -> Ast.ParamTag(parameterTypeDef d) + | Ast0.InitTag(d) -> Ast.InitTag(initialiser d) + | Ast0.DeclTag(d) -> Ast.DeclarationTag(declaration d) + | Ast0.StmtTag(d) -> Ast.StatementTag(statement d) + | Ast0.CaseLineTag(d) -> Ast.CaseLineTag(case_line d) + | Ast0.TopTag(d) -> Ast.Code(top_level d) + | Ast0.IsoWhenTag(_) -> failwith "not possible" + | Ast0.IsoWhenTTag(_) -> failwith "not possible" + | Ast0.IsoWhenFTag(_) -> failwith "not possible" + | Ast0.MetaPosTag _ -> failwith "not possible" + +(* --------------------------------------------------------------------- *) +(* Function declaration *) +(* top level isos are probably lost to tracking *) + +and top_level t = + rewrap t no_isos + (match Ast0.unwrap t with + Ast0.FILEINFO(old_file,new_file) -> + Ast.FILEINFO(mcode old_file,mcode new_file) + | Ast0.DECL(stmt) -> Ast.DECL(statement stmt) + | Ast0.CODE(rule_elem_dots) -> + Ast.CODE(statement_dots rule_elem_dots) + | Ast0.ERRORWORDS(exps) -> Ast.ERRORWORDS(List.map expression exps) + | Ast0.OTHER(_) -> failwith "eliminated by top_level") + +(* --------------------------------------------------------------------- *) +(* Entry point for minus code *) + +(* Inline_mcodes is very important - sends + code attached to the - code +down to the mcodes. The functions above can only be used when there is no +attached + code, eg in + code itself. *) +let ast0toast_toplevel x = + inline_mcodes.V0.combiner_top_level x; + top_level x + +let ast0toast name deps dropped exists x is_exp = + List.iter inline_mcodes.V0.combiner_top_level x; + Ast.CocciRule (name,(deps,dropped,exists),List.map top_level x,is_exp) diff --git a/parsing_cocci/.#ast_cocci.ml.1.142 b/parsing_cocci/.#ast_cocci.ml.1.142 new file mode 100644 index 0000000..a98a8dc --- /dev/null +++ b/parsing_cocci/.#ast_cocci.ml.1.142 @@ -0,0 +1,668 @@ +(* +* 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. +*) + + +(* --------------------------------------------------------------------- *) +(* Modified code *) + +type info = { line : int; column : int; + strbef : string list; straft : string list } +type line = int +type meta_name = string * string +(* need to be careful about rewrapping, to avoid duplicating pos info +currently, the pos info is always None until asttoctl2. *) +type 'a wrap = + {node : 'a; + node_line : line; + free_vars : meta_name list; (*free vars*) + minus_free_vars : meta_name list; (*minus free vars*) + fresh_vars : meta_name list; (*fresh vars*) + inherited : meta_name list; (*inherited vars*) + saved_witness : meta_name list; (*witness vars*) + bef_aft : dots_bef_aft; + (* the following is for or expressions *) + pos_info : meta_name mcode option; (* pos info, try not to duplicate *) + true_if_test_exp : bool;(* true if "test_exp from iso", only for exprs *) + (* isos relevant to the term; ultimately only used for rule_elems *) + iso_info : (string*anything) list } + +and 'a befaft = + BEFORE of 'a list list + | AFTER of 'a list list + | BEFOREAFTER of 'a list list * 'a list list + | NOTHING + +and 'a mcode = 'a * info * mcodekind * meta_pos (* pos variable *) + (* pos is an offset indicating where in the C code the mcodekind has an + effect *) + and mcodekind = + MINUS of pos * anything list list + | CONTEXT of pos * anything befaft + | PLUS + and fixpos = + Real of int (* charpos *) | Virt of int * int (* charpos + offset *) + and pos = NoPos | DontCarePos | FixPos of (fixpos * fixpos) + +and dots_bef_aft = + NoDots + | AddingBetweenDots of statement * int (*index of let var*) + | DroppingBetweenDots of statement * int (*index of let var*) + +and inherited = Type_cocci.inherited +and keep_binding = Type_cocci.keep_binding +and multi = bool (*true if a nest is one or more, false if it is zero or more*) + +and end_info = + meta_name list (*free vars*) * meta_name list (*inherited vars*) * + meta_name list (*witness vars*) * mcodekind + +(* --------------------------------------------------------------------- *) +(* Metavariables *) + +and arity = UNIQUE | OPT | MULTI | NONE + +and metavar = + MetaIdDecl of arity * meta_name (* name *) + | MetaFreshIdDecl of arity * meta_name (* name *) + | MetaTypeDecl of arity * meta_name (* name *) + | MetaListlenDecl of meta_name (* name *) + | MetaParamDecl of arity * meta_name (* name *) + | MetaParamListDecl of arity * meta_name (*name*) * meta_name option (*len*) + | MetaConstDecl of + arity * meta_name (* name *) * Type_cocci.typeC list option + | MetaErrDecl of arity * meta_name (* name *) + | MetaExpDecl of + arity * meta_name (* name *) * Type_cocci.typeC list option + | MetaIdExpDecl of + arity * meta_name (* name *) * Type_cocci.typeC list option + | MetaLocalIdExpDecl of + arity * meta_name (* name *) * Type_cocci.typeC list option + | MetaExpListDecl of arity * meta_name (*name*) * meta_name option (*len*) + | MetaStmDecl of arity * meta_name (* name *) + | MetaStmListDecl of arity * meta_name (* name *) + | MetaFuncDecl of arity * meta_name (* name *) + | MetaLocalFuncDecl of arity * meta_name (* name *) + | MetaPosDecl of arity * meta_name (* name *) + | MetaDeclarerDecl of arity * meta_name (* name *) + | MetaIteratorDecl of arity * meta_name (* name *) + +(* --------------------------------------------------------------------- *) +(* --------------------------------------------------------------------- *) +(* 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 meta_name mcode * ident list * keep_binding * inherited + | MetaFunc of meta_name mcode * ident list * keep_binding * inherited + | MetaLocalFunc of meta_name mcode * ident list * keep_binding * inherited + + | OptIdent of ident + | UniqueIdent of ident + +and ident = base_ident wrap + +(* --------------------------------------------------------------------- *) +(* Expression *) + +and base_expression = + Ident of ident + | Constant of constant mcode + | FunCall of expression * string mcode (* ( *) * + expression dots * string mcode (* ) *) + | Assignment of expression * assignOp mcode * expression * + bool (* true if it can match an initialization *) + | CondExpr of expression * string mcode (* ? *) * expression option * + string mcode (* : *) * expression + | Postfix of expression * fixOp mcode + | Infix of expression * fixOp mcode + | Unary of expression * unaryOp mcode + | Binary of expression * binaryOp mcode * expression + | Nested of expression * binaryOp mcode * expression + | ArrayAccess of expression * string mcode (* [ *) * expression * + string mcode (* ] *) + | RecordAccess of expression * string mcode (* . *) * ident + | RecordPtAccess of expression * string mcode (* -> *) * ident + | Cast of string mcode (* ( *) * fullType * string mcode (* ) *) * + expression + | SizeOfExpr of string mcode (* sizeof *) * expression + | SizeOfType of string mcode (* sizeof *) * string mcode (* ( *) * + fullType * string mcode (* ) *) + | TypeExp of fullType (*type name used as an expression, only in + arg or #define*) + + | Paren of string mcode (* ( *) * expression * + string mcode (* ) *) + + | MetaErr of meta_name mcode * expression list * keep_binding * + inherited + | MetaExpr of meta_name mcode * expression list * keep_binding * + Type_cocci.typeC list option * form * inherited + | MetaExprList of meta_name mcode * listlen option * keep_binding * + inherited (* only in arg lists *) + + | EComma of string mcode (* only in arg lists *) + + | DisjExpr of expression list + | NestExpr of expression dots * expression option * multi + + (* can appear in arg lists, and also inside Nest, as in: + if(< ... X ... Y ...>) + In the following, the expression option is the WHEN *) + | 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 + +(* ANY = int E; ID = idexpression int X; CONST = constant int X; *) +and form = ANY | ID | LocalID | CONST (* form for MetaExp *) + +and expression = base_expression wrap + +and listlen = meta_name mcode * keep_binding * inherited + +and unaryOp = GetRef | DeRef | UnPlus | UnMinus | Tilde | Not +and assignOp = SimpleAssign | OpAssign of arithOp +and fixOp = Dec | Inc + +and binaryOp = Arith of arithOp | Logical of logicalOp +and arithOp = + Plus | Minus | Mul | Div | Mod | DecLeft | DecRight | And | Or | Xor +and logicalOp = Inf | Sup | InfEq | SupEq | Eq | NotEq | AndLog | OrLog + +and constant = + String of string + | Char of string + | Int of string + | Float of string + +(* --------------------------------------------------------------------- *) +(* Types *) + +and base_fullType = + Type of const_vol mcode option * typeC + | DisjType of fullType list (* only after iso *) + | OptType of fullType + | UniqueType of fullType + +and base_typeC = + BaseType of baseType mcode * sign mcode option + | ImplicitInt of sign mcode + | Pointer of fullType * string mcode (* * *) + | FunctionPointer of fullType * + string mcode(* ( *)*string mcode(* * *)*string mcode(* ) *)* + string mcode (* ( *)*parameter_list*string mcode(* ) *) + + (* used for the automatic managment of prototypes *) + | FunctionType of bool (* true if all minus for dropping return type *) * + fullType option * + string mcode (* ( *) * parameter_list * + string mcode (* ) *) + + | Array of fullType * string mcode (* [ *) * + expression option * string mcode (* ] *) + | StructUnionName of structUnion mcode * ident option (* name *) + | StructUnionDef of fullType (* either StructUnionName or metavar *) * + string mcode (* { *) * declaration dots * string mcode (* } *) + | TypeName of string mcode + + | MetaType of meta_name mcode * keep_binding * inherited + +and fullType = base_fullType wrap +and typeC = base_typeC wrap + +and baseType = VoidType | CharType | ShortType | IntType | DoubleType +| FloatType | LongType + +and structUnion = Struct | Union + +and sign = Signed | Unsigned + +and const_vol = Const | Volatile + +(* --------------------------------------------------------------------- *) +(* 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 storage mcode option * fullType * ident * string mcode (*=*) * + initialiser * string mcode (*;*) + | UnInit of storage mcode option * fullType * ident * string mcode (* ; *) + | TyDecl of fullType * string mcode (* ; *) + | MacroDecl of ident (* name *) * string mcode (* ( *) * + expression dots * string mcode (* ) *) * string mcode (* ; *) + | Typedef of string mcode (*typedef*) * fullType * + typeC (* either TypeName or metavar *) * string mcode (*;*) + | DisjDecl of declaration list + (* Ddots is for a structure declaration *) + | Ddots of string mcode (* ... *) * declaration option (* whencode *) + + | MetaDecl of meta_name mcode * keep_binding * inherited + + | 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 (*}*) * + initialiser list (* whencode: elements that shouldn't appear in init *) + | 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 (* , *) + + | OptIni of initialiser + | UniqueIni of initialiser + +and initialiser = base_initialiser wrap + +(* --------------------------------------------------------------------- *) +(* Parameter *) + +and base_parameterTypeDef = + VoidParam of fullType + | Param of fullType * ident option + + | MetaParam of meta_name mcode * keep_binding * inherited + | MetaParamList of meta_name mcode * listlen option * keep_binding * + inherited + + | 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 (* not parameter list, not an empty one *) + | DParams of string mcode(*( *) * define_param dots * string mcode(* )*) + +and define_parameters = base_define_parameters wrap + +(* --------------------------------------------------------------------- *) +(* positions *) + +(* PER = keep bindings separate, ALL = collect them *) +and meta_collect = PER | ALL + +and meta_pos = + MetaPos of meta_name mcode * meta_name list * + meta_collect * keep_binding * inherited + | NoMetaPos + +(* --------------------------------------------------------------------- *) +(* Function declaration *) + +and storage = Static | Auto | Register | Extern + +(* --------------------------------------------------------------------- *) +(* Top-level code *) + +and base_rule_elem = + FunHeader of mcodekind (* before the function header *) * + bool (* true if all minus, for dropping static, etc *) * + fninfo list * ident (* name *) * + string mcode (* ( *) * parameter_list * + string mcode (* ) *) + | Decl of mcodekind (* before the decl *) * + bool (* true if all minus *) * declaration + + | SeqStart of string mcode (* { *) + | SeqEnd of string mcode (* } *) + + | ExprStatement of expression * string mcode (*;*) + | IfHeader of string mcode (* if *) * string mcode (* ( *) * + expression * string mcode (* ) *) + | Else of string mcode (* else *) + | WhileHeader of string mcode (* while *) * string mcode (* ( *) * + expression * string mcode (* ) *) + | DoHeader of string mcode (* do *) + | WhileTail of string mcode (* while *) * string mcode (* ( *) * + expression * string mcode (* ) *) * + string mcode (* ; *) + | ForHeader of string mcode (* for *) * string mcode (* ( *) * + expression option * string mcode (*;*) * + expression option * string mcode (*;*) * + expression option * string mcode (* ) *) + | IteratorHeader of ident (* name *) * string mcode (* ( *) * + expression dots * string mcode (* ) *) + | SwitchHeader of string mcode (* switch *) * string mcode (* ( *) * + expression * 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 (* ; *) + + | MetaRuleElem of meta_name mcode * keep_binding * inherited + | MetaStmt of meta_name mcode * keep_binding * metaStmtInfo * + inherited + | MetaStmtList of meta_name mcode * keep_binding * inherited + + | Exp of expression (* matches a subterm *) + | TopExp of expression (* for macros body, exp at top level, + not subexp *) + | Ty of fullType (* only at SP top level, matches a subterm *) + | Include of string mcode (*#include*) * inc_file mcode (*file *) + | DefineHeader of string mcode (* #define *) * ident (* name *) * + define_parameters (*params*) + | Case of string mcode (* case *) * expression * string mcode (*:*) + | Default of string mcode (* default *) * string mcode (*:*) + | DisjRuleElem of rule_elem list + +and fninfo = + FStorage of storage mcode + | FType of fullType + | FInline of string mcode + | FAttr of string mcode + +and metaStmtInfo = + NotSequencible | SequencibleAfterDots of dots_whencode list | Sequencible + +and rule_elem = base_rule_elem wrap + +and base_statement = + Seq of rule_elem (* { *) * statement dots * + statement dots * rule_elem (* } *) + | IfThen of rule_elem (* header *) * statement * end_info (* endif *) + | IfThenElse of rule_elem (* header *) * statement * + rule_elem (* else *) * statement * end_info (* endif *) + | While of rule_elem (* header *) * statement * end_info (*endwhile*) + | Do of rule_elem (* do *) * statement * rule_elem (* tail *) + | For of rule_elem (* header *) * statement * end_info (*endfor*) + | Iterator of rule_elem (* header *) * statement * end_info (*enditer*) + | Switch of rule_elem (* header *) * rule_elem (* { *) * + case_line list * rule_elem (* } *) + | Atomic of rule_elem + | Disj of statement dots list + | Nest of statement dots * + (statement dots,statement) whencode list * multi * + dots_whencode list * dots_whencode list + | FunDecl of rule_elem (* header *) * rule_elem (* { *) * + statement dots * statement dots * rule_elem (* } *) + | Define of rule_elem (* header *) * statement dots + | Dots of string mcode (* ... *) * + (statement dots,statement) whencode list * + dots_whencode list * dots_whencode list + | Circles of string mcode (* ooo *) * + (statement dots,statement) whencode list * + dots_whencode list * dots_whencode list + | Stars of string mcode (* *** *) * + (statement dots,statement) whencode list * + dots_whencode list * dots_whencode list + | OptStm of statement + | UniqueStm of statement + +and ('a,'b) whencode = + WhenNot of 'a + | WhenAlways of 'b + | WhenModifier of when_modifier + +and when_modifier = + (* The following removes the shortest path constraint. It can be used + with other when modifiers *) + WhenAny + (* The following removes the special consideration of error paths. It + can be used with other when modifiers *) + | WhenStrict + | WhenForall + | WhenExists + +(* only used with asttoctl *) +and dots_whencode = + WParen of rule_elem * meta_name (*pren_var*) + | Other of statement + | Other_dots of statement dots + +and statement = base_statement wrap + +and base_case_line = + CaseLine of rule_elem (* case/default header *) * statement dots + | OptCase of case_line + +and case_line = base_case_line wrap + +and inc_file = + Local of inc_elem list + | NonLocal of inc_elem list + +and inc_elem = + IncPath of string + | IncDots + +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 + +and top_level = base_top_level wrap + +and rulename = + CocciRulename of string option * dependency * + string list * string list * exists * bool + | ScriptRulename of string * dependency + +and rule = + CocciRule of string (* name *) * + (dependency * string list (* dropped isos *) * exists) * top_level list + * bool list + | ScriptRule of string * dependency * (string * meta_name) list * string + +and dependency = + Dep of string (* rule applies for the current binding *) + | AntiDep of string (* rule doesn't apply for the current binding *) + | EverDep of string (* rule applies for some binding *) + | NeverDep of string (* rule never applies for any binding *) + | AndDep of dependency * dependency + | OrDep of dependency * dependency + | NoDep + +and rule_with_metavars = metavar list * rule + +and anything = + FullTypeTag of fullType + | BaseTypeTag of baseType + | StructUnionTag of structUnion + | SignTag of sign + | IdentTag of ident + | ExpressionTag of expression + | ConstantTag of constant + | UnaryOpTag of unaryOp + | AssignOpTag of assignOp + | FixOpTag of fixOp + | BinaryOpTag of binaryOp + | ArithOpTag of arithOp + | LogicalOpTag of logicalOp + | DeclarationTag of declaration + | InitTag of initialiser + | StorageTag of storage + | IncFileTag of inc_file + | Rule_elemTag of rule_elem + | StatementTag of statement + | CaseLineTag of case_line + | ConstVolTag of const_vol + | Token of string * info option + | Code of top_level + | ExprDotsTag of expression dots + | ParamDotsTag of parameterTypeDef dots + | StmtDotsTag of statement dots + | DeclDotsTag of declaration dots + | TypeCTag of typeC + | ParamTag of parameterTypeDef + | SgrepStartTag of string + | SgrepEndTag of string + +(* --------------------------------------------------------------------- *) + +and exists = Exists | Forall | ReverseForall | Undetermined + +(* --------------------------------------------------------------------- *) + +let mkToken x = Token (x,None) + +(* --------------------------------------------------------------------- *) + +let rewrap model x = {model with node = x} +let rewrap_mcode (_,a,b,c) x = (x,a,b,c) +let unwrap x = x.node +let unwrap_mcode (x,_,_,_) = x +let get_mcodekind (_,_,x,_) = x +let get_line x = x.node_line +let get_mcode_line (_,l,_,_) = l.line +let get_fvs x = x.free_vars +let set_fvs fvs x = {x with free_vars = fvs} +let get_mfvs x = x.minus_free_vars +let set_mfvs mfvs x = {x with minus_free_vars = mfvs} +let get_fresh x = x.fresh_vars +let get_inherited x = x.inherited +let get_saved x = x.saved_witness +let get_dots_bef_aft x = x.bef_aft +let set_dots_bef_aft d x = {x with bef_aft = d} +let get_pos x = x.pos_info +let set_pos x pos = {x with pos_info = pos} +let get_test_exp x = x.true_if_test_exp +let set_test_exp x = {x with true_if_test_exp = true} +let get_isos x = x.iso_info +let set_isos x isos = {x with iso_info = isos} +let get_pos_var (_,_,_,p) = p +let set_pos_var vr (a,b,c,_) = (a,b,c,vr) +let drop_pos (a,b,c,_) = (a,b,c,NoMetaPos) + +let get_wcfvs (whencode : ('a wrap, 'b wrap) whencode list) = + Common.union_all + (List.map + (function + WhenNot(a) -> get_fvs a + | WhenAlways(a) -> get_fvs a + | WhenModifier(_) -> []) + whencode) + +(* --------------------------------------------------------------------- *) + +let get_meta_name = function + MetaIdDecl(ar,nm) -> nm + | MetaFreshIdDecl(ar,nm) -> nm + | MetaTypeDecl(ar,nm) -> nm + | MetaListlenDecl(nm) -> nm + | MetaParamDecl(ar,nm) -> nm + | MetaParamListDecl(ar,nm,nm1) -> nm + | MetaConstDecl(ar,nm,ty) -> nm + | MetaErrDecl(ar,nm) -> nm + | MetaExpDecl(ar,nm,ty) -> nm + | MetaIdExpDecl(ar,nm,ty) -> nm + | MetaLocalIdExpDecl(ar,nm,ty) -> nm + | MetaExpListDecl(ar,nm,nm1) -> nm + | MetaStmDecl(ar,nm) -> nm + | MetaStmListDecl(ar,nm) -> nm + | MetaFuncDecl(ar,nm) -> nm + | MetaLocalFuncDecl(ar,nm) -> nm + | MetaPosDecl(ar,nm) -> nm + | MetaDeclarerDecl(ar,nm) -> nm + | MetaIteratorDecl(ar,nm) -> nm + +(* --------------------------------------------------------------------- *) + +let no_info = { line = 0; column = 0; strbef = []; straft = [] } + +let make_term x = + {node = x; + node_line = 0; + free_vars = []; + minus_free_vars = []; + fresh_vars = []; + inherited = []; + saved_witness = []; + bef_aft = NoDots; + pos_info = None; + true_if_test_exp = false; + iso_info = [] } + +let make_meta_rule_elem s d (fvs,fresh,inh) = + {(make_term + (MetaRuleElem((("",s),no_info,d,NoMetaPos),Type_cocci.Unitary,false))) + with free_vars = fvs; fresh_vars = fresh; inherited = inh} + +let make_meta_decl s d (fvs,fresh,inh) = + {(make_term + (MetaDecl((("",s),no_info,d,NoMetaPos),Type_cocci.Unitary,false))) with + free_vars = fvs; fresh_vars = fresh; inherited = inh} + +let make_mcode x = (x,no_info,CONTEXT(NoPos,NOTHING),NoMetaPos) + +(* --------------------------------------------------------------------- *) + +let equal_pos x y = x = y + +(* --------------------------------------------------------------------- *) + +let undots x = + match unwrap x with + DOTS e -> e + | CIRCLES e -> e + | STARS e -> e diff --git a/parsing_cocci/.#ast_cocci.ml.1.143 b/parsing_cocci/.#ast_cocci.ml.1.143 new file mode 100644 index 0000000..bbbdd58 --- /dev/null +++ b/parsing_cocci/.#ast_cocci.ml.1.143 @@ -0,0 +1,672 @@ +(* +* 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. +*) + + +(* --------------------------------------------------------------------- *) +(* Modified code *) + +type info = { line : int; column : int; + strbef : string list; straft : string list } +type line = int +type meta_name = string * string +(* need to be careful about rewrapping, to avoid duplicating pos info +currently, the pos info is always None until asttoctl2. *) +type 'a wrap = + {node : 'a; + node_line : line; + free_vars : meta_name list; (*free vars*) + minus_free_vars : meta_name list; (*minus free vars*) + fresh_vars : meta_name list; (*fresh vars*) + inherited : meta_name list; (*inherited vars*) + saved_witness : meta_name list; (*witness vars*) + bef_aft : dots_bef_aft; + (* the following is for or expressions *) + pos_info : meta_name mcode option; (* pos info, try not to duplicate *) + true_if_test_exp : bool;(* true if "test_exp from iso", only for exprs *) + (* isos relevant to the term; ultimately only used for rule_elems *) + iso_info : (string*anything) list } + +and 'a befaft = + BEFORE of 'a list list + | AFTER of 'a list list + | BEFOREAFTER of 'a list list * 'a list list + | NOTHING + +and 'a mcode = 'a * info * mcodekind * meta_pos (* pos variable *) + (* pos is an offset indicating where in the C code the mcodekind has an + effect *) + and mcodekind = + MINUS of pos * anything list list + | CONTEXT of pos * anything befaft + | PLUS + and fixpos = + Real of int (* charpos *) | Virt of int * int (* charpos + offset *) + and pos = NoPos | DontCarePos | FixPos of (fixpos * fixpos) + +and dots_bef_aft = + NoDots + | AddingBetweenDots of statement * int (*index of let var*) + | DroppingBetweenDots of statement * int (*index of let var*) + +and inherited = Type_cocci.inherited +and keep_binding = Type_cocci.keep_binding +and multi = bool (*true if a nest is one or more, false if it is zero or more*) + +and end_info = + meta_name list (*free vars*) * meta_name list (*inherited vars*) * + meta_name list (*witness vars*) * mcodekind + +(* --------------------------------------------------------------------- *) +(* Metavariables *) + +and arity = UNIQUE | OPT | MULTI | NONE + +and metavar = + MetaIdDecl of arity * meta_name (* name *) + | MetaFreshIdDecl of arity * meta_name (* name *) + | MetaTypeDecl of arity * meta_name (* name *) + | MetaListlenDecl of meta_name (* name *) + | MetaParamDecl of arity * meta_name (* name *) + | MetaParamListDecl of arity * meta_name (*name*) * meta_name option (*len*) + | MetaConstDecl of + arity * meta_name (* name *) * Type_cocci.typeC list option + | MetaErrDecl of arity * meta_name (* name *) + | MetaExpDecl of + arity * meta_name (* name *) * Type_cocci.typeC list option + | MetaIdExpDecl of + arity * meta_name (* name *) * Type_cocci.typeC list option + | MetaLocalIdExpDecl of + arity * meta_name (* name *) * Type_cocci.typeC list option + | MetaExpListDecl of arity * meta_name (*name*) * meta_name option (*len*) + | MetaStmDecl of arity * meta_name (* name *) + | MetaStmListDecl of arity * meta_name (* name *) + | MetaFuncDecl of arity * meta_name (* name *) + | MetaLocalFuncDecl of arity * meta_name (* name *) + | MetaPosDecl of arity * meta_name (* name *) + | MetaDeclarerDecl of arity * meta_name (* name *) + | MetaIteratorDecl of arity * meta_name (* name *) + +(* --------------------------------------------------------------------- *) +(* --------------------------------------------------------------------- *) +(* 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 meta_name mcode * ident list * keep_binding * inherited + | MetaFunc of meta_name mcode * ident list * keep_binding * inherited + | MetaLocalFunc of meta_name mcode * ident list * keep_binding * inherited + + | OptIdent of ident + | UniqueIdent of ident + +and ident = base_ident wrap + +(* --------------------------------------------------------------------- *) +(* Expression *) + +and base_expression = + Ident of ident + | Constant of constant mcode + | FunCall of expression * string mcode (* ( *) * + expression dots * string mcode (* ) *) + | Assignment of expression * assignOp mcode * expression * + bool (* true if it can match an initialization *) + | CondExpr of expression * string mcode (* ? *) * expression option * + string mcode (* : *) * expression + | Postfix of expression * fixOp mcode + | Infix of expression * fixOp mcode + | Unary of expression * unaryOp mcode + | Binary of expression * binaryOp mcode * expression + | Nested of expression * binaryOp mcode * expression + | ArrayAccess of expression * string mcode (* [ *) * expression * + string mcode (* ] *) + | RecordAccess of expression * string mcode (* . *) * ident + | RecordPtAccess of expression * string mcode (* -> *) * ident + | Cast of string mcode (* ( *) * fullType * string mcode (* ) *) * + expression + | SizeOfExpr of string mcode (* sizeof *) * expression + | SizeOfType of string mcode (* sizeof *) * string mcode (* ( *) * + fullType * string mcode (* ) *) + | TypeExp of fullType (*type name used as an expression, only in + arg or #define*) + + | Paren of string mcode (* ( *) * expression * + string mcode (* ) *) + + | MetaErr of meta_name mcode * expression list * keep_binding * + inherited + | MetaExpr of meta_name mcode * expression list * keep_binding * + Type_cocci.typeC list option * form * inherited + | MetaExprList of meta_name mcode * listlen option * keep_binding * + inherited (* only in arg lists *) + + | EComma of string mcode (* only in arg lists *) + + | DisjExpr of expression list + | NestExpr of expression dots * expression option * multi + + (* can appear in arg lists, and also inside Nest, as in: + if(< ... X ... Y ...>) + In the following, the expression option is the WHEN *) + | 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 + +(* ANY = int E; ID = idexpression int X; CONST = constant int X; *) +and form = ANY | ID | LocalID | CONST (* form for MetaExp *) + +and expression = base_expression wrap + +and listlen = meta_name mcode * keep_binding * inherited + +and unaryOp = GetRef | DeRef | UnPlus | UnMinus | Tilde | Not +and assignOp = SimpleAssign | OpAssign of arithOp +and fixOp = Dec | Inc + +and binaryOp = Arith of arithOp | Logical of logicalOp +and arithOp = + Plus | Minus | Mul | Div | Mod | DecLeft | DecRight | And | Or | Xor +and logicalOp = Inf | Sup | InfEq | SupEq | Eq | NotEq | AndLog | OrLog + +and constant = + String of string + | Char of string + | Int of string + | Float of string + +(* --------------------------------------------------------------------- *) +(* Types *) + +and base_fullType = + Type of const_vol mcode option * typeC + | DisjType of fullType list (* only after iso *) + | OptType of fullType + | UniqueType of fullType + +and base_typeC = + BaseType of baseType mcode * sign mcode option + | ImplicitInt of sign mcode + | Pointer of fullType * string mcode (* * *) + | FunctionPointer of fullType * + string mcode(* ( *)*string mcode(* * *)*string mcode(* ) *)* + string mcode (* ( *)*parameter_list*string mcode(* ) *) + + (* used for the automatic managment of prototypes *) + | FunctionType of bool (* true if all minus for dropping return type *) * + fullType option * + string mcode (* ( *) * parameter_list * + string mcode (* ) *) + + | Array of fullType * string mcode (* [ *) * + expression option * string mcode (* ] *) + | StructUnionName of structUnion mcode * ident option (* name *) + | StructUnionDef of fullType (* either StructUnionName or metavar *) * + string mcode (* { *) * declaration dots * string mcode (* } *) + | TypeName of string mcode + + | MetaType of meta_name mcode * keep_binding * inherited + +and fullType = base_fullType wrap +and typeC = base_typeC wrap + +and baseType = VoidType | CharType | ShortType | IntType | DoubleType +| FloatType | LongType + +and structUnion = Struct | Union + +and sign = Signed | Unsigned + +and const_vol = Const | Volatile + +(* --------------------------------------------------------------------- *) +(* 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 storage mcode option * fullType * ident * string mcode (*=*) * + initialiser * string mcode (*;*) + | UnInit of storage mcode option * fullType * ident * string mcode (* ; *) + | TyDecl of fullType * string mcode (* ; *) + | MacroDecl of ident (* name *) * string mcode (* ( *) * + expression dots * string mcode (* ) *) * string mcode (* ; *) + | Typedef of string mcode (*typedef*) * fullType * + typeC (* either TypeName or metavar *) * string mcode (*;*) + | DisjDecl of declaration list + (* Ddots is for a structure declaration *) + | Ddots of string mcode (* ... *) * declaration option (* whencode *) + + | MetaDecl of meta_name mcode * keep_binding * inherited + + | 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 (*}*) * + initialiser list (* whencode: elements that shouldn't appear in init *) + | 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 (* , *) + + | OptIni of initialiser + | UniqueIni of initialiser + +and initialiser = base_initialiser wrap + +(* --------------------------------------------------------------------- *) +(* Parameter *) + +and base_parameterTypeDef = + VoidParam of fullType + | Param of fullType * ident option + + | MetaParam of meta_name mcode * keep_binding * inherited + | MetaParamList of meta_name mcode * listlen option * keep_binding * + inherited + + | 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 (* not parameter list, not an empty one *) + | DParams of string mcode(*( *) * define_param dots * string mcode(* )*) + +and define_parameters = base_define_parameters wrap + +(* --------------------------------------------------------------------- *) +(* positions *) + +(* PER = keep bindings separate, ALL = collect them *) +and meta_collect = PER | ALL + +and meta_pos = + MetaPos of meta_name mcode * meta_name list * + meta_collect * keep_binding * inherited + | NoMetaPos + +(* --------------------------------------------------------------------- *) +(* Function declaration *) + +and storage = Static | Auto | Register | Extern + +(* --------------------------------------------------------------------- *) +(* Top-level code *) + +and base_rule_elem = + FunHeader of mcodekind (* before the function header *) * + bool (* true if all minus, for dropping static, etc *) * + fninfo list * ident (* name *) * + string mcode (* ( *) * parameter_list * + string mcode (* ) *) + | Decl of mcodekind (* before the decl *) * + bool (* true if all minus *) * declaration + + | SeqStart of string mcode (* { *) + | SeqEnd of string mcode (* } *) + + | ExprStatement of expression * string mcode (*;*) + | IfHeader of string mcode (* if *) * string mcode (* ( *) * + expression * string mcode (* ) *) + | Else of string mcode (* else *) + | WhileHeader of string mcode (* while *) * string mcode (* ( *) * + expression * string mcode (* ) *) + | DoHeader of string mcode (* do *) + | WhileTail of string mcode (* while *) * string mcode (* ( *) * + expression * string mcode (* ) *) * + string mcode (* ; *) + | ForHeader of string mcode (* for *) * string mcode (* ( *) * + expression option * string mcode (*;*) * + expression option * string mcode (*;*) * + expression option * string mcode (* ) *) + | IteratorHeader of ident (* name *) * string mcode (* ( *) * + expression dots * string mcode (* ) *) + | SwitchHeader of string mcode (* switch *) * string mcode (* ( *) * + expression * 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 (* ; *) + + | MetaRuleElem of meta_name mcode * keep_binding * inherited + | MetaStmt of meta_name mcode * keep_binding * metaStmtInfo * + inherited + | MetaStmtList of meta_name mcode * keep_binding * inherited + + | Exp of expression (* matches a subterm *) + | TopExp of expression (* for macros body, exp at top level, + not subexp *) + | Ty of fullType (* only at SP top level, matches a subterm *) + | Include of string mcode (*#include*) * inc_file mcode (*file *) + | DefineHeader of string mcode (* #define *) * ident (* name *) * + define_parameters (*params*) + | Case of string mcode (* case *) * expression * string mcode (*:*) + | Default of string mcode (* default *) * string mcode (*:*) + | DisjRuleElem of rule_elem list + +and fninfo = + FStorage of storage mcode + | FType of fullType + | FInline of string mcode + | FAttr of string mcode + +and metaStmtInfo = + NotSequencible | SequencibleAfterDots of dots_whencode list | Sequencible + +and rule_elem = base_rule_elem wrap + +and base_statement = + Seq of rule_elem (* { *) * statement dots * + statement dots * rule_elem (* } *) + | IfThen of rule_elem (* header *) * statement * end_info (* endif *) + | IfThenElse of rule_elem (* header *) * statement * + rule_elem (* else *) * statement * end_info (* endif *) + | While of rule_elem (* header *) * statement * end_info (*endwhile*) + | Do of rule_elem (* do *) * statement * rule_elem (* tail *) + | For of rule_elem (* header *) * statement * end_info (*endfor*) + | Iterator of rule_elem (* header *) * statement * end_info (*enditer*) + | Switch of rule_elem (* header *) * rule_elem (* { *) * + case_line list * rule_elem (* } *) + | Atomic of rule_elem + | Disj of statement dots list + | Nest of statement dots * + (statement dots,statement) whencode list * multi * + dots_whencode list * dots_whencode list + | FunDecl of rule_elem (* header *) * rule_elem (* { *) * + statement dots * statement dots * rule_elem (* } *) + | Define of rule_elem (* header *) * statement dots + | Dots of string mcode (* ... *) * + (statement dots,statement) whencode list * + dots_whencode list * dots_whencode list + | Circles of string mcode (* ooo *) * + (statement dots,statement) whencode list * + dots_whencode list * dots_whencode list + | Stars of string mcode (* *** *) * + (statement dots,statement) whencode list * + dots_whencode list * dots_whencode list + | OptStm of statement + | UniqueStm of statement + +and ('a,'b) whencode = + WhenNot of 'a + | WhenAlways of 'b + | WhenModifier of when_modifier + | WhenNotTrue of rule_elem (* useful for fvs *) + | WhenNotFalse of rule_elem + +and when_modifier = + (* The following removes the shortest path constraint. It can be used + with other when modifiers *) + WhenAny + (* The following removes the special consideration of error paths. It + can be used with other when modifiers *) + | WhenStrict + | WhenForall + | WhenExists + +(* only used with asttoctl *) +and dots_whencode = + WParen of rule_elem * meta_name (*pren_var*) + | Other of statement + | Other_dots of statement dots + +and statement = base_statement wrap + +and base_case_line = + CaseLine of rule_elem (* case/default header *) * statement dots + | OptCase of case_line + +and case_line = base_case_line wrap + +and inc_file = + Local of inc_elem list + | NonLocal of inc_elem list + +and inc_elem = + IncPath of string + | IncDots + +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 + +and top_level = base_top_level wrap + +and rulename = + CocciRulename of string option * dependency * + string list * string list * exists * bool + | ScriptRulename of string * dependency + +and rule = + CocciRule of string (* name *) * + (dependency * string list (* dropped isos *) * exists) * top_level list + * bool list + | ScriptRule of string * dependency * (string * meta_name) list * string + +and dependency = + Dep of string (* rule applies for the current binding *) + | AntiDep of string (* rule doesn't apply for the current binding *) + | EverDep of string (* rule applies for some binding *) + | NeverDep of string (* rule never applies for any binding *) + | AndDep of dependency * dependency + | OrDep of dependency * dependency + | NoDep + +and rule_with_metavars = metavar list * rule + +and anything = + FullTypeTag of fullType + | BaseTypeTag of baseType + | StructUnionTag of structUnion + | SignTag of sign + | IdentTag of ident + | ExpressionTag of expression + | ConstantTag of constant + | UnaryOpTag of unaryOp + | AssignOpTag of assignOp + | FixOpTag of fixOp + | BinaryOpTag of binaryOp + | ArithOpTag of arithOp + | LogicalOpTag of logicalOp + | DeclarationTag of declaration + | InitTag of initialiser + | StorageTag of storage + | IncFileTag of inc_file + | Rule_elemTag of rule_elem + | StatementTag of statement + | CaseLineTag of case_line + | ConstVolTag of const_vol + | Token of string * info option + | Code of top_level + | ExprDotsTag of expression dots + | ParamDotsTag of parameterTypeDef dots + | StmtDotsTag of statement dots + | DeclDotsTag of declaration dots + | TypeCTag of typeC + | ParamTag of parameterTypeDef + | SgrepStartTag of string + | SgrepEndTag of string + +(* --------------------------------------------------------------------- *) + +and exists = Exists | Forall | ReverseForall | Undetermined + +(* --------------------------------------------------------------------- *) + +let mkToken x = Token (x,None) + +(* --------------------------------------------------------------------- *) + +let rewrap model x = {model with node = x} +let rewrap_mcode (_,a,b,c) x = (x,a,b,c) +let unwrap x = x.node +let unwrap_mcode (x,_,_,_) = x +let get_mcodekind (_,_,x,_) = x +let get_line x = x.node_line +let get_mcode_line (_,l,_,_) = l.line +let get_fvs x = x.free_vars +let set_fvs fvs x = {x with free_vars = fvs} +let get_mfvs x = x.minus_free_vars +let set_mfvs mfvs x = {x with minus_free_vars = mfvs} +let get_fresh x = x.fresh_vars +let get_inherited x = x.inherited +let get_saved x = x.saved_witness +let get_dots_bef_aft x = x.bef_aft +let set_dots_bef_aft d x = {x with bef_aft = d} +let get_pos x = x.pos_info +let set_pos x pos = {x with pos_info = pos} +let get_test_exp x = x.true_if_test_exp +let set_test_exp x = {x with true_if_test_exp = true} +let get_isos x = x.iso_info +let set_isos x isos = {x with iso_info = isos} +let get_pos_var (_,_,_,p) = p +let set_pos_var vr (a,b,c,_) = (a,b,c,vr) +let drop_pos (a,b,c,_) = (a,b,c,NoMetaPos) + +let get_wcfvs (whencode : ('a wrap, 'b wrap) whencode list) = + Common.union_all + (List.map + (function + WhenNot(a) -> get_fvs a + | WhenAlways(a) -> get_fvs a + | WhenModifier(_) -> [] + | WhenNotTrue(e) -> get_fvs e + | WhenNotFalse(e) -> get_fvs e) + whencode) + +(* --------------------------------------------------------------------- *) + +let get_meta_name = function + MetaIdDecl(ar,nm) -> nm + | MetaFreshIdDecl(ar,nm) -> nm + | MetaTypeDecl(ar,nm) -> nm + | MetaListlenDecl(nm) -> nm + | MetaParamDecl(ar,nm) -> nm + | MetaParamListDecl(ar,nm,nm1) -> nm + | MetaConstDecl(ar,nm,ty) -> nm + | MetaErrDecl(ar,nm) -> nm + | MetaExpDecl(ar,nm,ty) -> nm + | MetaIdExpDecl(ar,nm,ty) -> nm + | MetaLocalIdExpDecl(ar,nm,ty) -> nm + | MetaExpListDecl(ar,nm,nm1) -> nm + | MetaStmDecl(ar,nm) -> nm + | MetaStmListDecl(ar,nm) -> nm + | MetaFuncDecl(ar,nm) -> nm + | MetaLocalFuncDecl(ar,nm) -> nm + | MetaPosDecl(ar,nm) -> nm + | MetaDeclarerDecl(ar,nm) -> nm + | MetaIteratorDecl(ar,nm) -> nm + +(* --------------------------------------------------------------------- *) + +let no_info = { line = 0; column = 0; strbef = []; straft = [] } + +let make_term x = + {node = x; + node_line = 0; + free_vars = []; + minus_free_vars = []; + fresh_vars = []; + inherited = []; + saved_witness = []; + bef_aft = NoDots; + pos_info = None; + true_if_test_exp = false; + iso_info = [] } + +let make_meta_rule_elem s d (fvs,fresh,inh) = + {(make_term + (MetaRuleElem((("",s),no_info,d,NoMetaPos),Type_cocci.Unitary,false))) + with free_vars = fvs; fresh_vars = fresh; inherited = inh} + +let make_meta_decl s d (fvs,fresh,inh) = + {(make_term + (MetaDecl((("",s),no_info,d,NoMetaPos),Type_cocci.Unitary,false))) with + free_vars = fvs; fresh_vars = fresh; inherited = inh} + +let make_mcode x = (x,no_info,CONTEXT(NoPos,NOTHING),NoMetaPos) + +(* --------------------------------------------------------------------- *) + +let equal_pos x y = x = y + +(* --------------------------------------------------------------------- *) + +let undots x = + match unwrap x with + DOTS e -> e + | CIRCLES e -> e + | STARS e -> e diff --git a/parsing_cocci/.#check_meta.ml.1.79 b/parsing_cocci/.#check_meta.ml.1.79 new file mode 100644 index 0000000..28da910 --- /dev/null +++ b/parsing_cocci/.#check_meta.ml.1.79 @@ -0,0 +1,528 @@ +(* +* 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 fragment, checks that all of the identifier metavariables that +are used are not declared as fresh, and check that all declared variables +are used. For plus fragment, just check that the variables declared as +fresh are used. What is the issue about error variables? (don't remember) *) + +module Ast0 = Ast0_cocci +module Ast = Ast_cocci +module V0 = Visitor_ast0 + +(* all fresh identifiers *) +let fresh_table = (Hashtbl.create(50) : ((string * string), unit) Hashtbl.t) + +let warning s = Printf.fprintf stderr "warning: %s\n" s + +let promote name = (name,(),Ast0.default_info(),(),None) + +(* --------------------------------------------------------------------- *) + +let find_loop table name = + let rec loop = function + [] -> raise Not_found + | x::xs -> (try Hashtbl.find x name with Not_found -> loop xs) in + loop table + +let check_table table minus (name,_,info,_,_) = + let rl = info.Ast0.line_start in + if minus + then + (try (find_loop table name) := true + with + Not_found -> + (try + Hashtbl.find fresh_table name; + let (_,name) = name in + failwith + (Printf.sprintf + "%d: unexpected use of a fresh identifier %s" rl name) + with Not_found -> ())) + else (try (find_loop table name) := true with Not_found -> ()) + +let get_opt fn = Common.do_option fn + +(* --------------------------------------------------------------------- *) +(* Dots *) + +let dots fn d = + match Ast0.unwrap d with + Ast0.DOTS(x) -> List.iter fn x + | Ast0.CIRCLES(x) -> List.iter fn x + | Ast0.STARS(x) -> List.iter fn x + +(* --------------------------------------------------------------------- *) +(* Identifier *) + +type context = ID | FIELD | FN | GLOBAL + +(* heuristic for distinguishing ifdef variables from undeclared metavariables*) +let is_ifdef name = + String.length name > 2 && String.uppercase name = name + +let ident context old_metas table minus i = + match Ast0.unwrap i with + Ast0.Id((name,_,info,_,_) : string Ast0.mcode) -> + let rl = info.Ast0.line_start in + let err = + if List.exists (function x -> x = name) old_metas + && (minus || Ast0.get_mcodekind i = Ast0.PLUS) + then + begin + warning + (Printf.sprintf + "line %d: %s, previously declared as a metavariable, is used as an identifier" rl name); + true + end + else false in + (match context with + ID -> + if not (is_ifdef name) && minus && not err(* warn only once per id *) + then + warning + (Printf.sprintf "line %d: should %s be a metavariable?" rl name) + | _ -> ()) + | Ast0.MetaId(name,_,_) -> check_table table minus name + | Ast0.MetaFunc(name,_,_) -> check_table table minus name + | Ast0.MetaLocalFunc(name,_,_) -> check_table table minus name + | Ast0.OptIdent(_) | Ast0.UniqueIdent(_) -> + failwith "unexpected code" + +(* --------------------------------------------------------------------- *) +(* Expression *) + +let rec expression context old_metas table minus e = + match Ast0.unwrap e with + Ast0.Ident(id) -> + ident context old_metas table minus id + | Ast0.FunCall(fn,lp,args,rp) -> + expression FN old_metas table minus fn; + dots (expression ID old_metas table minus) args + | Ast0.Assignment(left,op,right,_) -> + expression context old_metas table minus left; + expression ID old_metas table minus right + | Ast0.CondExpr(exp1,why,exp2,colon,exp3) -> + expression ID old_metas table minus exp1; + get_opt (expression ID old_metas table minus) exp2; + expression ID old_metas table minus exp3 + | Ast0.Postfix(exp,op) -> + expression ID old_metas table minus exp + | Ast0.Infix(exp,op) -> + expression ID old_metas table minus exp + | Ast0.Unary(exp,op) -> + expression ID old_metas table minus exp + | Ast0.Binary(left,op,right) -> + expression ID old_metas table minus left; + expression ID old_metas table minus right + | Ast0.Paren(lp,exp,rp) -> + expression ID old_metas table minus exp + | Ast0.ArrayAccess(exp1,lb,exp2,rb) -> + expression ID old_metas table minus exp1; + expression ID old_metas table minus exp2 + | Ast0.RecordAccess(exp,pt,field) -> + expression ID old_metas table minus exp; + ident FIELD old_metas table minus field + | Ast0.RecordPtAccess(exp,ar,field) -> + expression ID old_metas table minus exp; + ident FIELD old_metas table minus field + | Ast0.Cast(lp,ty,rp,exp) -> + typeC old_metas table minus ty; expression ID old_metas table minus exp + | Ast0.SizeOfExpr(szf,exp) -> expression ID old_metas table minus exp + | Ast0.SizeOfType(szf,lp,ty,rp) -> typeC old_metas table minus ty + | Ast0.TypeExp(ty) -> typeC old_metas table minus ty + | Ast0.MetaExpr(name,_,Some tys,_,_) -> + List.iter + (function x -> + match get_type_name x with + Some(ty) -> check_table table minus (promote ty) + | None -> ()) + tys; + check_table table minus name + | Ast0.MetaExpr(name,_,_,_,_) | Ast0.MetaErr(name,_,_) -> + check_table table minus name + | Ast0.MetaExprList(name,None,_) -> + check_table table minus name + | Ast0.MetaExprList(name,Some lenname,_) -> + check_table table minus name; + check_table table minus lenname + | Ast0.DisjExpr(_,exps,_,_) -> + List.iter (expression ID old_metas table minus) exps + | Ast0.NestExpr(_,exp_dots,_,w,_) -> + dots (expression ID old_metas table minus) exp_dots; + get_opt (expression ID old_metas table minus) w + | Ast0.Edots(_,Some x) | Ast0.Ecircles(_,Some x) | Ast0.Estars(_,Some x) -> + expression ID old_metas table minus x + | _ -> () (* no metavariable subterms *) + +and get_type_name = function + Type_cocci.ConstVol(_,ty) | Type_cocci.Pointer(ty) + | Type_cocci.FunctionPointer(ty) | Type_cocci.Array(ty) -> get_type_name ty + | Type_cocci.MetaType(nm,_,_) -> Some nm + | _ -> None + +(* --------------------------------------------------------------------- *) +(* Types *) + +and typeC old_metas table minus t = + match Ast0.unwrap t with + Ast0.ConstVol(cv,ty) -> typeC old_metas table minus ty + | Ast0.Pointer(ty,star) -> typeC old_metas table minus ty + | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> + typeC old_metas table minus ty; + parameter_list old_metas table minus params + | Ast0.FunctionType(ty,lp1,params,rp1) -> + get_opt (typeC old_metas table minus) ty; + parameter_list old_metas table minus params + | Ast0.Array(ty,lb,size,rb) -> + typeC old_metas table minus ty; + get_opt (expression ID old_metas table minus) size + | Ast0.MetaType(name,_) -> + check_table table minus name + | Ast0.DisjType(_,types,_,_) -> + List.iter (typeC old_metas table minus) types + | Ast0.StructUnionName(su,Some id) -> ident GLOBAL old_metas table minus id + | Ast0.StructUnionDef(ty,lb,decls,rb) -> + typeC old_metas table minus ty; + dots (declaration GLOBAL old_metas table minus) decls + | Ast0.OptType(ty) | Ast0.UniqueType(ty) -> + failwith "unexpected code" + | _ -> () (* no metavariable subterms *) + +(* --------------------------------------------------------------------- *) +(* 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 declaration context old_metas table minus d = + match Ast0.unwrap d with + Ast0.Init(stg,ty,id,eq,ini,sem) -> + (match Ast0.unwrap ini with + Ast0.InitExpr exp -> + typeC old_metas table minus ty; + ident context old_metas table minus id; + expression ID old_metas table minus exp + | _ -> + (* + if minus + then + failwith "complex initializer specification not allowed in - code" + else*) + (typeC old_metas table minus ty; + ident context old_metas table minus id; + initialiser old_metas table minus ini)) + | Ast0.UnInit(stg,ty,id,sem) -> + typeC old_metas table minus ty; ident context old_metas table minus id + | Ast0.MacroDecl(name,lp,args,rp,sem) -> + ident ID old_metas table minus name; + dots (expression ID old_metas table minus) args + | Ast0.TyDecl(ty,sem) -> typeC old_metas table minus ty + | Ast0.Typedef(stg,ty,id,sem) -> + typeC old_metas table minus ty; + typeC old_metas table minus id + | Ast0.DisjDecl(_,decls,_,_) -> + List.iter (declaration ID old_metas table minus) decls + | Ast0.Ddots(_,Some x) -> declaration ID old_metas table minus x + | Ast0.Ddots(_,None) -> () + | Ast0.OptDecl(_) | Ast0.UniqueDecl(_) -> + failwith "unexpected code" + +(* --------------------------------------------------------------------- *) +(* Initialiser *) + +and initialiser old_metas table minus ini = + match Ast0.unwrap ini with + Ast0.InitExpr(exp) -> expression ID old_metas table minus exp + | Ast0.InitList(lb,initlist,rb) -> + dots (initialiser old_metas table minus) initlist + | Ast0.InitGccDotName(dot,name,eq,ini) -> + ident FIELD old_metas table minus name; + initialiser old_metas table minus ini + | Ast0.InitGccName(name,eq,ini) -> + ident FIELD old_metas table minus name; + initialiser old_metas table minus ini + | Ast0.InitGccIndex(lb,exp,rb,eq,ini) -> + expression ID old_metas table minus exp; + initialiser old_metas table minus ini + | Ast0.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini) -> + expression ID old_metas table minus exp1; + expression ID old_metas table minus exp2; + initialiser old_metas table minus ini + | Ast0.Idots(_,Some x) -> initialiser old_metas table minus x + | Ast0.OptIni(_) | Ast0.UniqueIni(_) -> + failwith "unexpected code" + | _ -> () (* no metavariable subterms *) + +and initialiser_list old_metas table minus = + dots (initialiser old_metas table minus) + +(* --------------------------------------------------------------------- *) +(* Parameter *) + +and parameterTypeDef old_metas table minus param = + match Ast0.unwrap param with + Ast0.Param(ty,id) -> + get_opt (ident ID old_metas table minus) id; + typeC old_metas table minus ty + | Ast0.MetaParam(name,_) -> + check_table table minus name + | Ast0.MetaParamList(name,None,_) -> + check_table table minus name + | Ast0.MetaParamList(name,Some lenname,_) -> + check_table table minus name; + check_table table minus lenname + | _ -> () (* no metavariable subterms *) + +and parameter_list old_metas table minus = + dots (parameterTypeDef old_metas table minus) + +(* --------------------------------------------------------------------- *) +(* Top-level code *) + +and statement old_metas table minus s = + match Ast0.unwrap s with + Ast0.Decl(_,decl) -> declaration ID old_metas table minus decl + | Ast0.Seq(lbrace,body,rbrace) -> dots (statement old_metas table minus) body + | Ast0.ExprStatement(exp,sem) -> expression ID old_metas table minus exp + | Ast0.IfThen(iff,lp,exp,rp,branch,_) -> + expression ID old_metas table minus exp; + statement old_metas table minus branch + | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,_) -> + expression ID old_metas table minus exp; + statement old_metas table minus branch1; + statement old_metas table minus branch2 + | Ast0.While(wh,lp,exp,rp,body,_) -> + expression ID old_metas table minus exp; + statement old_metas table minus body + | Ast0.Do(d,body,wh,lp,exp,rp,sem) -> + statement old_metas table minus body; + expression ID old_metas table minus exp + | Ast0.For(fr,lp,exp1,sem1,exp2,sem2,exp3,rp,body,_) -> + get_opt (expression ID old_metas table minus) exp1; + get_opt (expression ID old_metas table minus) exp2; + get_opt (expression ID old_metas table minus) exp3; + statement old_metas table minus body + | Ast0.Iterator(nm,lp,args,rp,body,_) -> + ident ID old_metas table minus nm; + dots (expression ID old_metas table minus) args; + statement old_metas table minus body + | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) -> + expression ID old_metas table minus exp; + dots (case_line old_metas table minus) cases + | Ast0.ReturnExpr(ret,exp,sem) -> expression ID old_metas table minus exp + | Ast0.MetaStmt(name,_) -> check_table table minus name + | Ast0.MetaStmtList(name,_) -> check_table table minus name + | Ast0.Exp(exp) -> expression ID old_metas table minus exp + | Ast0.TopExp(exp) -> expression ID old_metas table minus exp + | Ast0.Ty(ty) -> typeC old_metas table minus ty + | Ast0.Disj(_,rule_elem_dots_list,_,_) -> + List.iter (dots (statement old_metas table minus)) rule_elem_dots_list + | Ast0.Nest(_,rule_elem_dots,_,w,_) -> + dots (statement old_metas table minus) rule_elem_dots; + List.iter (whencode (dots (statement old_metas table minus)) + (statement old_metas table minus)) + w + | Ast0.Dots(_,x) | Ast0.Circles(_,x) | Ast0.Stars(_,x) -> + List.iter + (whencode (dots (statement old_metas table minus)) + (statement old_metas table minus)) x + | Ast0.FunDecl(_,fi,name,lp,params,rp,lbrace,body,rbrace) -> + ident FN old_metas table minus name; + List.iter (fninfo old_metas table minus) fi; + parameter_list old_metas table minus params; + dots (statement old_metas table minus) body + | Ast0.Include(inc,s) -> () (* no metavariables possible *) + | Ast0.Define(def,id,_,body) -> + ident GLOBAL old_metas table minus id; + dots (statement old_metas table minus) body + | Ast0.Goto(_,i,_) -> ident ID old_metas table minus i + | _ -> () (* no metavariable subterms *) + +and fninfo old_metas table minus = function + Ast0.FStorage(stg) -> () + | Ast0.FType(ty) -> typeC old_metas table minus ty + | Ast0.FInline(inline) -> () + | Ast0.FAttr(attr) -> () + +and whencode notfn alwaysfn = function + Ast0.WhenNot a -> notfn a + | Ast0.WhenAlways a -> alwaysfn a + | Ast0.WhenModifier(_) -> () + +and case_line old_metas table minus c = + match Ast0.unwrap c with + Ast0.Default(def,colon,code) -> + dots (statement old_metas table minus) code + | Ast0.Case(case,exp,colon,code) -> + dots (statement old_metas table minus) code + | Ast0.OptCase(case) -> failwith "unexpected code" + +(* --------------------------------------------------------------------- *) +(* Rules *) + +let top_level old_metas table minus t = + match Ast0.unwrap t with + Ast0.DECL(stmt) -> statement old_metas table minus stmt + | Ast0.CODE(stmt_dots) -> dots (statement old_metas table minus) stmt_dots + | Ast0.ERRORWORDS(exps) -> + List.iter (expression FN old_metas table minus) exps + | _ -> () (* no metavariables possible *) + +let rule old_metas table minus rules = + List.iter (top_level old_metas table minus) rules + +(* --------------------------------------------------------------------- *) + +let positions table rules = + let mcode x = + match Ast0.get_pos x with + Ast0.MetaPos(name,constraints,_) -> + let pos = Ast0.unwrap_mcode name in + (find_loop table pos) := true + | _ -> () in + let option_default = () in + let bind x y = () in + let donothing r k e = k e 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 + + List.iter fn.V0.combiner_top_level rules + +let dup_positions rules = + let mcode x = + match Ast0.get_pos x with + Ast0.MetaPos(name,constraints,_) -> + let pos = Ast0.unwrap_mcode name in [pos] + | _ -> [] in + let option_default = [] in + let bind x y = x@y in + + (* Case for everything that has a disj. + Note, no positions on ( | ) of a disjunction, so no need to recurse on + these. *) + + let expression r k e = + match Ast0.unwrap e with + Ast0.DisjExpr(_,explist,_,_) -> + List.fold_left Common.union_set option_default + (List.map r.V0.combiner_expression explist) + | _ -> k e in + + let typeC r k e = (* not sure relevent because "only after iso" *) + match Ast0.unwrap e with + Ast0.DisjType(_,types,_,_) -> + List.fold_left Common.union_set option_default + (List.map r.V0.combiner_typeC types) + | _ -> k e in + + let declaration r k e = + match Ast0.unwrap e with + Ast0.DisjDecl(_,decls,_,_) -> + List.fold_left Common.union_set option_default + (List.map r.V0.combiner_declaration decls) + | _ -> k e in + + let statement r k e = + match Ast0.unwrap e with + Ast0.Disj(_,stmts,_,_) -> + List.fold_left Common.union_set option_default + (List.map r.V0.combiner_statement_dots stmts) + | _ -> k e in + + let donothing r k e = k e 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 expression typeC donothing donothing declaration statement + donothing donothing in + + let res = + List.sort compare + (List.fold_left Common.union_set option_default + (List.map fn.V0.combiner_top_level rules)) in + let rec loop = function + [] | [_] -> () + | ((rule,name) as x)::y::_ when x = y -> + failwith (Printf.sprintf "duplicate use of %s.%s" rule name) + | _::xs -> loop xs in + loop res + +(* --------------------------------------------------------------------- *) + +let make_table l = + let table = + (Hashtbl.create(List.length l) : + ((string * string), bool ref) Hashtbl.t) in + List.iter + (function x -> Hashtbl.add table (Ast.get_meta_name x) (ref false)) l; + table + +let add_to_fresh_table l = + List.iter + (function x -> + let name = Ast.get_meta_name x in Hashtbl.replace fresh_table name ()) + l + +let check_all_marked rname err table after_err = + Hashtbl.iter + (function name -> + function (cell) -> + if not (!cell) + then + let (_,name) = name in + warning + (Printf.sprintf "%s: %s %s not used %s" rname err name after_err)) + table + +let check_meta rname old_metas inherited_metavars metavars minus plus = + let old_metas = + List.map (function (_,x) -> x) (List.map Ast.get_meta_name old_metas) in + let (fresh,other) = + List.partition (function Ast.MetaFreshIdDecl(_,_) -> true | _ -> false) + metavars in + let (err,other) = + List.partition (function Ast.MetaErrDecl(_,_) -> true | _ -> false) + other in + let (ierr,iother) = + List.partition (function Ast.MetaErrDecl(_,_) -> true | _ -> false) + inherited_metavars in + let fresh_table = make_table fresh in + let err_table = make_table (err@ierr) in + let other_table = make_table other in + let iother_table = make_table iother in + add_to_fresh_table fresh; + rule old_metas [iother_table;other_table;err_table] true minus; + positions [iother_table;other_table] minus; + dup_positions minus; + check_all_marked rname "metavariable" other_table "in the - or context code"; + rule old_metas [iother_table;fresh_table;err_table] false plus; + check_all_marked rname "fresh identifier metavariable" iother_table + "in the -, +, or context code"; + check_all_marked rname "metavariable" fresh_table "in the + code"; + check_all_marked rname "error metavariable" err_table "" diff --git a/parsing_cocci/.#check_meta.ml.1.80 b/parsing_cocci/.#check_meta.ml.1.80 new file mode 100644 index 0000000..b195e42 --- /dev/null +++ b/parsing_cocci/.#check_meta.ml.1.80 @@ -0,0 +1,532 @@ +(* +* 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 fragment, checks that all of the identifier metavariables that +are used are not declared as fresh, and check that all declared variables +are used. For plus fragment, just check that the variables declared as +fresh are used. What is the issue about error variables? (don't remember) *) + +module Ast0 = Ast0_cocci +module Ast = Ast_cocci +module V0 = Visitor_ast0 + +(* all fresh identifiers *) +let fresh_table = (Hashtbl.create(50) : ((string * string), unit) Hashtbl.t) + +let warning s = Printf.fprintf stderr "warning: %s\n" s + +let promote name = (name,(),Ast0.default_info(),(),None) + +(* --------------------------------------------------------------------- *) + +let find_loop table name = + let rec loop = function + [] -> raise Not_found + | x::xs -> (try Hashtbl.find x name with Not_found -> loop xs) in + loop table + +let check_table table minus (name,_,info,_,_) = + let rl = info.Ast0.line_start in + if minus + then + (try (find_loop table name) := true + with + Not_found -> + (try + Hashtbl.find fresh_table name; + let (_,name) = name in + failwith + (Printf.sprintf + "%d: unexpected use of a fresh identifier %s" rl name) + with Not_found -> ())) + else (try (find_loop table name) := true with Not_found -> ()) + +let get_opt fn = Common.do_option fn + +(* --------------------------------------------------------------------- *) +(* Dots *) + +let dots fn d = + match Ast0.unwrap d with + Ast0.DOTS(x) -> List.iter fn x + | Ast0.CIRCLES(x) -> List.iter fn x + | Ast0.STARS(x) -> List.iter fn x + +(* --------------------------------------------------------------------- *) +(* Identifier *) + +type context = ID | FIELD | FN | GLOBAL + +(* heuristic for distinguishing ifdef variables from undeclared metavariables*) +let is_ifdef name = + String.length name > 2 && String.uppercase name = name + +let ident context old_metas table minus i = + match Ast0.unwrap i with + Ast0.Id((name,_,info,_,_) : string Ast0.mcode) -> + let rl = info.Ast0.line_start in + let err = + if List.exists (function x -> x = name) old_metas + && (minus || Ast0.get_mcodekind i = Ast0.PLUS) + then + begin + warning + (Printf.sprintf + "line %d: %s, previously declared as a metavariable, is used as an identifier" rl name); + true + end + else false in + (match context with + ID -> + if not (is_ifdef name) && minus && not err(* warn only once per id *) + then + warning + (Printf.sprintf "line %d: should %s be a metavariable?" rl name) + | _ -> ()) + | Ast0.MetaId(name,_,_) -> check_table table minus name + | Ast0.MetaFunc(name,_,_) -> check_table table minus name + | Ast0.MetaLocalFunc(name,_,_) -> check_table table minus name + | Ast0.OptIdent(_) | Ast0.UniqueIdent(_) -> + failwith "unexpected code" + +(* --------------------------------------------------------------------- *) +(* Expression *) + +let rec expression context old_metas table minus e = + match Ast0.unwrap e with + Ast0.Ident(id) -> + ident context old_metas table minus id + | Ast0.FunCall(fn,lp,args,rp) -> + expression FN old_metas table minus fn; + dots (expression ID old_metas table minus) args + | Ast0.Assignment(left,op,right,_) -> + expression context old_metas table minus left; + expression ID old_metas table minus right + | Ast0.CondExpr(exp1,why,exp2,colon,exp3) -> + expression ID old_metas table minus exp1; + get_opt (expression ID old_metas table minus) exp2; + expression ID old_metas table minus exp3 + | Ast0.Postfix(exp,op) -> + expression ID old_metas table minus exp + | Ast0.Infix(exp,op) -> + expression ID old_metas table minus exp + | Ast0.Unary(exp,op) -> + expression ID old_metas table minus exp + | Ast0.Binary(left,op,right) -> + expression ID old_metas table minus left; + expression ID old_metas table minus right + | Ast0.Paren(lp,exp,rp) -> + expression ID old_metas table minus exp + | Ast0.ArrayAccess(exp1,lb,exp2,rb) -> + expression ID old_metas table minus exp1; + expression ID old_metas table minus exp2 + | Ast0.RecordAccess(exp,pt,field) -> + expression ID old_metas table minus exp; + ident FIELD old_metas table minus field + | Ast0.RecordPtAccess(exp,ar,field) -> + expression ID old_metas table minus exp; + ident FIELD old_metas table minus field + | Ast0.Cast(lp,ty,rp,exp) -> + typeC old_metas table minus ty; expression ID old_metas table minus exp + | Ast0.SizeOfExpr(szf,exp) -> expression ID old_metas table minus exp + | Ast0.SizeOfType(szf,lp,ty,rp) -> typeC old_metas table minus ty + | Ast0.TypeExp(ty) -> typeC old_metas table minus ty + | Ast0.MetaExpr(name,_,Some tys,_,_) -> + List.iter + (function x -> + match get_type_name x with + Some(ty) -> check_table table minus (promote ty) + | None -> ()) + tys; + check_table table minus name + | Ast0.MetaExpr(name,_,_,_,_) | Ast0.MetaErr(name,_,_) -> + check_table table minus name + | Ast0.MetaExprList(name,None,_) -> + check_table table minus name + | Ast0.MetaExprList(name,Some lenname,_) -> + check_table table minus name; + check_table table minus lenname + | Ast0.DisjExpr(_,exps,_,_) -> + List.iter (expression ID old_metas table minus) exps + | Ast0.NestExpr(_,exp_dots,_,w,_) -> + dots (expression ID old_metas table minus) exp_dots; + get_opt (expression ID old_metas table minus) w + | Ast0.Edots(_,Some x) | Ast0.Ecircles(_,Some x) | Ast0.Estars(_,Some x) -> + expression ID old_metas table minus x + | _ -> () (* no metavariable subterms *) + +and get_type_name = function + Type_cocci.ConstVol(_,ty) | Type_cocci.Pointer(ty) + | Type_cocci.FunctionPointer(ty) | Type_cocci.Array(ty) -> get_type_name ty + | Type_cocci.MetaType(nm,_,_) -> Some nm + | _ -> None + +(* --------------------------------------------------------------------- *) +(* Types *) + +and typeC old_metas table minus t = + match Ast0.unwrap t with + Ast0.ConstVol(cv,ty) -> typeC old_metas table minus ty + | Ast0.Pointer(ty,star) -> typeC old_metas table minus ty + | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> + typeC old_metas table minus ty; + parameter_list old_metas table minus params + | Ast0.FunctionType(ty,lp1,params,rp1) -> + get_opt (typeC old_metas table minus) ty; + parameter_list old_metas table minus params + | Ast0.Array(ty,lb,size,rb) -> + typeC old_metas table minus ty; + get_opt (expression ID old_metas table minus) size + | Ast0.MetaType(name,_) -> + check_table table minus name + | Ast0.DisjType(_,types,_,_) -> + List.iter (typeC old_metas table minus) types + | Ast0.StructUnionName(su,Some id) -> ident GLOBAL old_metas table minus id + | Ast0.StructUnionDef(ty,lb,decls,rb) -> + typeC old_metas table minus ty; + dots (declaration GLOBAL old_metas table minus) decls + | Ast0.OptType(ty) | Ast0.UniqueType(ty) -> + failwith "unexpected code" + | _ -> () (* no metavariable subterms *) + +(* --------------------------------------------------------------------- *) +(* 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 declaration context old_metas table minus d = + match Ast0.unwrap d with + Ast0.Init(stg,ty,id,eq,ini,sem) -> + (match Ast0.unwrap ini with + Ast0.InitExpr exp -> + typeC old_metas table minus ty; + ident context old_metas table minus id; + expression ID old_metas table minus exp + | _ -> + (* + if minus + then + failwith "complex initializer specification not allowed in - code" + else*) + (typeC old_metas table minus ty; + ident context old_metas table minus id; + initialiser old_metas table minus ini)) + | Ast0.UnInit(stg,ty,id,sem) -> + typeC old_metas table minus ty; ident context old_metas table minus id + | Ast0.MacroDecl(name,lp,args,rp,sem) -> + ident ID old_metas table minus name; + dots (expression ID old_metas table minus) args + | Ast0.TyDecl(ty,sem) -> typeC old_metas table minus ty + | Ast0.Typedef(stg,ty,id,sem) -> + typeC old_metas table minus ty; + typeC old_metas table minus id + | Ast0.DisjDecl(_,decls,_,_) -> + List.iter (declaration ID old_metas table minus) decls + | Ast0.Ddots(_,Some x) -> declaration ID old_metas table minus x + | Ast0.Ddots(_,None) -> () + | Ast0.OptDecl(_) | Ast0.UniqueDecl(_) -> + failwith "unexpected code" + +(* --------------------------------------------------------------------- *) +(* Initialiser *) + +and initialiser old_metas table minus ini = + match Ast0.unwrap ini with + Ast0.InitExpr(exp) -> expression ID old_metas table minus exp + | Ast0.InitList(lb,initlist,rb) -> + dots (initialiser old_metas table minus) initlist + | Ast0.InitGccDotName(dot,name,eq,ini) -> + ident FIELD old_metas table minus name; + initialiser old_metas table minus ini + | Ast0.InitGccName(name,eq,ini) -> + ident FIELD old_metas table minus name; + initialiser old_metas table minus ini + | Ast0.InitGccIndex(lb,exp,rb,eq,ini) -> + expression ID old_metas table minus exp; + initialiser old_metas table minus ini + | Ast0.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini) -> + expression ID old_metas table minus exp1; + expression ID old_metas table minus exp2; + initialiser old_metas table minus ini + | Ast0.Idots(_,Some x) -> initialiser old_metas table minus x + | Ast0.OptIni(_) | Ast0.UniqueIni(_) -> + failwith "unexpected code" + | _ -> () (* no metavariable subterms *) + +and initialiser_list old_metas table minus = + dots (initialiser old_metas table minus) + +(* --------------------------------------------------------------------- *) +(* Parameter *) + +and parameterTypeDef old_metas table minus param = + match Ast0.unwrap param with + Ast0.Param(ty,id) -> + get_opt (ident ID old_metas table minus) id; + typeC old_metas table minus ty + | Ast0.MetaParam(name,_) -> + check_table table minus name + | Ast0.MetaParamList(name,None,_) -> + check_table table minus name + | Ast0.MetaParamList(name,Some lenname,_) -> + check_table table minus name; + check_table table minus lenname + | _ -> () (* no metavariable subterms *) + +and parameter_list old_metas table minus = + dots (parameterTypeDef old_metas table minus) + +(* --------------------------------------------------------------------- *) +(* Top-level code *) + +and statement old_metas table minus s = + match Ast0.unwrap s with + Ast0.Decl(_,decl) -> declaration ID old_metas table minus decl + | Ast0.Seq(lbrace,body,rbrace) -> dots (statement old_metas table minus) body + | Ast0.ExprStatement(exp,sem) -> expression ID old_metas table minus exp + | Ast0.IfThen(iff,lp,exp,rp,branch,_) -> + expression ID old_metas table minus exp; + statement old_metas table minus branch + | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,_) -> + expression ID old_metas table minus exp; + statement old_metas table minus branch1; + statement old_metas table minus branch2 + | Ast0.While(wh,lp,exp,rp,body,_) -> + expression ID old_metas table minus exp; + statement old_metas table minus body + | Ast0.Do(d,body,wh,lp,exp,rp,sem) -> + statement old_metas table minus body; + expression ID old_metas table minus exp + | Ast0.For(fr,lp,exp1,sem1,exp2,sem2,exp3,rp,body,_) -> + get_opt (expression ID old_metas table minus) exp1; + get_opt (expression ID old_metas table minus) exp2; + get_opt (expression ID old_metas table minus) exp3; + statement old_metas table minus body + | Ast0.Iterator(nm,lp,args,rp,body,_) -> + ident ID old_metas table minus nm; + dots (expression ID old_metas table minus) args; + statement old_metas table minus body + | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) -> + expression ID old_metas table minus exp; + dots (case_line old_metas table minus) cases + | Ast0.ReturnExpr(ret,exp,sem) -> expression ID old_metas table minus exp + | Ast0.MetaStmt(name,_) -> check_table table minus name + | Ast0.MetaStmtList(name,_) -> check_table table minus name + | Ast0.Exp(exp) -> expression ID old_metas table minus exp + | Ast0.TopExp(exp) -> expression ID old_metas table minus exp + | Ast0.Ty(ty) -> typeC old_metas table minus ty + | Ast0.Disj(_,rule_elem_dots_list,_,_) -> + List.iter (dots (statement old_metas table minus)) rule_elem_dots_list + | Ast0.Nest(_,rule_elem_dots,_,w,_) -> + dots (statement old_metas table minus) rule_elem_dots; + List.iter (whencode (dots (statement old_metas table minus)) + (statement old_metas table minus) + (expression ID old_metas table minus)) + w + | Ast0.Dots(_,x) | Ast0.Circles(_,x) | Ast0.Stars(_,x) -> + List.iter + (whencode (dots (statement old_metas table minus)) + (statement old_metas table minus) + (expression ID old_metas table minus)) x + | Ast0.FunDecl(_,fi,name,lp,params,rp,lbrace,body,rbrace) -> + ident FN old_metas table minus name; + List.iter (fninfo old_metas table minus) fi; + parameter_list old_metas table minus params; + dots (statement old_metas table minus) body + | Ast0.Include(inc,s) -> () (* no metavariables possible *) + | Ast0.Define(def,id,_,body) -> + ident GLOBAL old_metas table minus id; + dots (statement old_metas table minus) body + | Ast0.Goto(_,i,_) -> ident ID old_metas table minus i + | _ -> () (* no metavariable subterms *) + +and fninfo old_metas table minus = function + Ast0.FStorage(stg) -> () + | Ast0.FType(ty) -> typeC old_metas table minus ty + | Ast0.FInline(inline) -> () + | Ast0.FAttr(attr) -> () + +and whencode notfn alwaysfn expression = function + Ast0.WhenNot a -> notfn a + | Ast0.WhenAlways a -> alwaysfn a + | Ast0.WhenModifier(_) -> () + | Ast0.WhenNotTrue a -> expression a + | Ast0.WhenNotFalse a -> expression a + +and case_line old_metas table minus c = + match Ast0.unwrap c with + Ast0.Default(def,colon,code) -> + dots (statement old_metas table minus) code + | Ast0.Case(case,exp,colon,code) -> + dots (statement old_metas table minus) code + | Ast0.OptCase(case) -> failwith "unexpected code" + +(* --------------------------------------------------------------------- *) +(* Rules *) + +let top_level old_metas table minus t = + match Ast0.unwrap t with + Ast0.DECL(stmt) -> statement old_metas table minus stmt + | Ast0.CODE(stmt_dots) -> dots (statement old_metas table minus) stmt_dots + | Ast0.ERRORWORDS(exps) -> + List.iter (expression FN old_metas table minus) exps + | _ -> () (* no metavariables possible *) + +let rule old_metas table minus rules = + List.iter (top_level old_metas table minus) rules + +(* --------------------------------------------------------------------- *) + +let positions table rules = + let mcode x = + match Ast0.get_pos x with + Ast0.MetaPos(name,constraints,_) -> + let pos = Ast0.unwrap_mcode name in + (find_loop table pos) := true + | _ -> () in + let option_default = () in + let bind x y = () in + let donothing r k e = k e 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 + + List.iter fn.V0.combiner_top_level rules + +let dup_positions rules = + let mcode x = + match Ast0.get_pos x with + Ast0.MetaPos(name,constraints,_) -> + let pos = Ast0.unwrap_mcode name in [pos] + | _ -> [] in + let option_default = [] in + let bind x y = x@y in + + (* Case for everything that has a disj. + Note, no positions on ( | ) of a disjunction, so no need to recurse on + these. *) + + let expression r k e = + match Ast0.unwrap e with + Ast0.DisjExpr(_,explist,_,_) -> + List.fold_left Common.union_set option_default + (List.map r.V0.combiner_expression explist) + | _ -> k e in + + let typeC r k e = (* not sure relevent because "only after iso" *) + match Ast0.unwrap e with + Ast0.DisjType(_,types,_,_) -> + List.fold_left Common.union_set option_default + (List.map r.V0.combiner_typeC types) + | _ -> k e in + + let declaration r k e = + match Ast0.unwrap e with + Ast0.DisjDecl(_,decls,_,_) -> + List.fold_left Common.union_set option_default + (List.map r.V0.combiner_declaration decls) + | _ -> k e in + + let statement r k e = + match Ast0.unwrap e with + Ast0.Disj(_,stmts,_,_) -> + List.fold_left Common.union_set option_default + (List.map r.V0.combiner_statement_dots stmts) + | _ -> k e in + + let donothing r k e = k e 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 expression typeC donothing donothing declaration statement + donothing donothing in + + let res = + List.sort compare + (List.fold_left Common.union_set option_default + (List.map fn.V0.combiner_top_level rules)) in + let rec loop = function + [] | [_] -> () + | ((rule,name) as x)::y::_ when x = y -> + failwith (Printf.sprintf "duplicate use of %s.%s" rule name) + | _::xs -> loop xs in + loop res + +(* --------------------------------------------------------------------- *) + +let make_table l = + let table = + (Hashtbl.create(List.length l) : + ((string * string), bool ref) Hashtbl.t) in + List.iter + (function x -> Hashtbl.add table (Ast.get_meta_name x) (ref false)) l; + table + +let add_to_fresh_table l = + List.iter + (function x -> + let name = Ast.get_meta_name x in Hashtbl.replace fresh_table name ()) + l + +let check_all_marked rname err table after_err = + Hashtbl.iter + (function name -> + function (cell) -> + if not (!cell) + then + let (_,name) = name in + warning + (Printf.sprintf "%s: %s %s not used %s" rname err name after_err)) + table + +let check_meta rname old_metas inherited_metavars metavars minus plus = + let old_metas = + List.map (function (_,x) -> x) (List.map Ast.get_meta_name old_metas) in + let (fresh,other) = + List.partition (function Ast.MetaFreshIdDecl(_,_) -> true | _ -> false) + metavars in + let (err,other) = + List.partition (function Ast.MetaErrDecl(_,_) -> true | _ -> false) + other in + let (ierr,iother) = + List.partition (function Ast.MetaErrDecl(_,_) -> true | _ -> false) + inherited_metavars in + let fresh_table = make_table fresh in + let err_table = make_table (err@ierr) in + let other_table = make_table other in + let iother_table = make_table iother in + add_to_fresh_table fresh; + rule old_metas [iother_table;other_table;err_table] true minus; + positions [iother_table;other_table] minus; + dup_positions minus; + check_all_marked rname "metavariable" other_table "in the - or context code"; + rule old_metas [iother_table;fresh_table;err_table] false plus; + check_all_marked rname "fresh identifier metavariable" iother_table + "in the -, +, or context code"; + check_all_marked rname "metavariable" fresh_table "in the + code"; + check_all_marked rname "error metavariable" err_table "" diff --git a/parsing_cocci/.#compute_lines.ml.1.85 b/parsing_cocci/.#compute_lines.ml.1.85 new file mode 100644 index 0000000..5a08d1f --- /dev/null +++ b/parsing_cocci/.#compute_lines.ml.1.85 @@ -0,0 +1,760 @@ +(* +* 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. +*) + + +(* Computes starting and ending logical lines for statements and +expressions. every node gets an index as well. *) + +module Ast0 = Ast0_cocci +module Ast = Ast_cocci + +(* --------------------------------------------------------------------- *) +(* Result *) + +let mkres x e left right = + let lstart = Ast0.get_info left in + let lend = Ast0.get_info right in + let info = + { Ast0.line_start = lstart.Ast0.line_start; + Ast0.line_end = lend.Ast0.line_end; + Ast0.logical_start = lstart.Ast0.logical_start; + Ast0.logical_end = lend.Ast0.logical_end; + Ast0.attachable_start = lstart.Ast0.attachable_start; + Ast0.attachable_end = lend.Ast0.attachable_end; + Ast0.mcode_start = lstart.Ast0.mcode_start; + Ast0.mcode_end = lend.Ast0.mcode_end; + Ast0.column = lstart.Ast0.column; + Ast0.offset = lstart.Ast0.offset; + (* only for tokens, not inherited upwards *) + Ast0.strings_before = []; Ast0.strings_after = []} in + {x with Ast0.node = e; Ast0.info = info} + +let mkmultires x e left right (astart,start_mcodes) (aend,end_mcodes) = + let lstart = Ast0.get_info left in + let lend = Ast0.get_info right in + let info = + { Ast0.line_start = lstart.Ast0.line_start; + Ast0.line_end = lend.Ast0.line_end; + Ast0.logical_start = lstart.Ast0.logical_start; + Ast0.logical_end = lend.Ast0.logical_end; + Ast0.attachable_start = astart; + Ast0.attachable_end = aend; + Ast0.mcode_start = start_mcodes; + Ast0.mcode_end = end_mcodes; + Ast0.column = lstart.Ast0.column; + Ast0.offset = lstart.Ast0.offset; + (* only for tokens, not inherited upwards *) + Ast0.strings_before = []; Ast0.strings_after = [] } in + {x with Ast0.node = e; Ast0.info = info} + +(* --------------------------------------------------------------------- *) + +let get_option fn = function + None -> None + | Some x -> Some (fn x) + +(* --------------------------------------------------------------------- *) +(* --------------------------------------------------------------------- *) +(* Mcode *) + +let promote_mcode (_,_,info,mcodekind,_) = + let new_info = + {info with + Ast0.mcode_start = [mcodekind]; Ast0.mcode_end = [mcodekind]} in + {(Ast0.wrap ()) with Ast0.info = new_info; Ast0.mcodekind = ref mcodekind} + +let promote_mcode_plus_one (_,_,info,mcodekind,_) = + let new_info = + {info with + Ast0.line_start = info.Ast0.line_start + 1; + Ast0.logical_start = info.Ast0.logical_start + 1; + Ast0.line_end = info.Ast0.line_end + 1; + Ast0.logical_end = info.Ast0.logical_end + 1; + Ast0.mcode_start = [mcodekind]; Ast0.mcode_end = [mcodekind]} in + {(Ast0.wrap ()) with Ast0.info = new_info; Ast0.mcodekind = ref mcodekind} + +let promote_to_statement stm mcodekind = + let info = Ast0.get_info stm in + let new_info = + {info with + Ast0.logical_start = info.Ast0.logical_end; + Ast0.line_start = info.Ast0.line_end; + Ast0.mcode_start = [mcodekind]; Ast0.mcode_end = [mcodekind]; + Ast0.attachable_start = true; Ast0.attachable_end = true} in + {(Ast0.wrap ()) with Ast0.info = new_info; Ast0.mcodekind = ref mcodekind} + +let promote_to_statement_start stm mcodekind = + let info = Ast0.get_info stm in + let new_info = + {info with + Ast0.logical_end = info.Ast0.logical_start; + Ast0.line_end = info.Ast0.line_start; + Ast0.mcode_start = [mcodekind]; Ast0.mcode_end = [mcodekind]; + Ast0.attachable_start = true; Ast0.attachable_end = true} in + {(Ast0.wrap ()) with Ast0.info = new_info; Ast0.mcodekind = ref mcodekind} + +(* mcode is good by default *) +let bad_mcode (t,a,info,mcodekind,pos) = + let new_info = + {info with Ast0.attachable_start = false; Ast0.attachable_end = false} in + (t,a,new_info,mcodekind,pos) + +let get_all_start_info l = + (List.for_all (function x -> (Ast0.get_info x).Ast0.attachable_start) l, + List.concat (List.map (function x -> (Ast0.get_info x).Ast0.mcode_start) l)) + +let get_all_end_info l = + (List.for_all (function x -> (Ast0.get_info x).Ast0.attachable_end) l, + List.concat (List.map (function x -> (Ast0.get_info x).Ast0.mcode_end) l)) + +(* --------------------------------------------------------------------- *) +(* Dots *) + +(* for the logline classification and the mcode field, on both sides, skip +over initial minus dots, as they don't contribute anything *) +let dot_list is_dots fn = function + [] -> failwith "dots should not be empty" + | l -> + let get_node l fn = + let first = List.hd l in + let chosen = + match (is_dots first, l) with (true,_::x::_) -> x | _ -> first in + (* get the logline decorator and the mcodekind of the chosen node *) + fn (Ast0.get_info chosen) in + let forward = List.map fn l in + let backward = List.rev forward in + let (first_attachable,first_mcode) = + get_node forward + (function x -> (x.Ast0.attachable_start,x.Ast0.mcode_start)) in + let (last_attachable,last_mcode) = + get_node backward + (function x -> (x.Ast0.attachable_end,x.Ast0.mcode_end)) in + let first = List.hd forward in + let last = List.hd backward in + let first_info = + { (Ast0.get_info first) with + Ast0.attachable_start = first_attachable; + Ast0.mcode_start = first_mcode } in + let last_info = + { (Ast0.get_info last) with + Ast0.attachable_end = last_attachable; + Ast0.mcode_end = last_mcode } in + let first = Ast0.set_info first first_info in + let last = Ast0.set_info last last_info in + (forward,first,last) + +let dots is_dots prev fn d = + match (prev,Ast0.unwrap d) with + (Some prev,Ast0.DOTS([])) -> + mkres d (Ast0.DOTS []) prev prev + | (None,Ast0.DOTS([])) -> + Ast0.set_info d + {(Ast0.get_info d) + with Ast0.attachable_start = false; Ast0.attachable_end = false} + | (_,Ast0.DOTS(x)) -> + let (l,lstart,lend) = dot_list is_dots fn x in + mkres d (Ast0.DOTS l) lstart lend + | (_,Ast0.CIRCLES(x)) -> + let (l,lstart,lend) = dot_list is_dots fn x in + mkres d (Ast0.CIRCLES l) lstart lend + | (_,Ast0.STARS(x)) -> + let (l,lstart,lend) = dot_list is_dots fn x in + mkres d (Ast0.STARS l) lstart lend + +(* --------------------------------------------------------------------- *) +(* Identifier *) + +let rec ident i = + match Ast0.unwrap i with + Ast0.Id(name) as ui -> + let name = promote_mcode name in mkres i ui name name + | Ast0.MetaId(name,_,_) + | Ast0.MetaFunc(name,_,_) | Ast0.MetaLocalFunc(name,_,_) as ui -> + let name = promote_mcode name in mkres i ui name name + | Ast0.OptIdent(id) -> + let id = ident id in mkres i (Ast0.OptIdent(id)) id id + | Ast0.UniqueIdent(id) -> + let id = ident id in mkres i (Ast0.UniqueIdent(id)) id id + +(* --------------------------------------------------------------------- *) +(* Expression *) + +let is_exp_dots e = + match Ast0.unwrap e with + Ast0.Edots(_,_) | Ast0.Ecircles(_,_) | Ast0.Estars(_,_) -> true + | _ -> false + +let rec expression e = + match Ast0.unwrap e with + Ast0.Ident(id) -> + let id = ident id in + mkres e (Ast0.Ident(id)) id id + | Ast0.Constant(const) as ue -> + let ln = promote_mcode const in + mkres e ue ln ln + | Ast0.FunCall(fn,lp,args,rp) -> + let fn = expression fn in + let args = dots is_exp_dots (Some(promote_mcode lp)) expression args in + mkres e (Ast0.FunCall(fn,lp,args,rp)) fn (promote_mcode rp) + | Ast0.Assignment(left,op,right,simple) -> + let left = expression left in + let right = expression right in + mkres e (Ast0.Assignment(left,op,right,simple)) left right + | Ast0.CondExpr(exp1,why,exp2,colon,exp3) -> + let exp1 = expression exp1 in + let exp2 = get_option expression exp2 in + let exp3 = expression exp3 in + mkres e (Ast0.CondExpr(exp1,why,exp2,colon,exp3)) exp1 exp3 + | Ast0.Postfix(exp,op) -> + let exp = expression exp in + mkres e (Ast0.Postfix(exp,op)) exp (promote_mcode op) + | Ast0.Infix(exp,op) -> + let exp = expression exp in + mkres e (Ast0.Infix(exp,op)) (promote_mcode op) exp + | Ast0.Unary(exp,op) -> + let exp = expression exp in + mkres e (Ast0.Unary(exp,op)) (promote_mcode op) exp + | Ast0.Binary(left,op,right) -> + let left = expression left in + let right = expression right in + mkres e (Ast0.Binary(left,op,right)) left right + | Ast0.Nested(left,op,right) -> + let left = expression left in + let right = expression right in + mkres e (Ast0.Nested(left,op,right)) left right + | Ast0.Paren(lp,exp,rp) -> + mkres e (Ast0.Paren(lp,expression exp,rp)) + (promote_mcode lp) (promote_mcode rp) + | Ast0.ArrayAccess(exp1,lb,exp2,rb) -> + let exp1 = expression exp1 in + let exp2 = expression exp2 in + mkres e (Ast0.ArrayAccess(exp1,lb,exp2,rb)) exp1 (promote_mcode rb) + | Ast0.RecordAccess(exp,pt,field) -> + let exp = expression exp in + let field = ident field in + mkres e (Ast0.RecordAccess(exp,pt,field)) exp field + | Ast0.RecordPtAccess(exp,ar,field) -> + let exp = expression exp in + let field = ident field in + mkres e (Ast0.RecordPtAccess(exp,ar,field)) exp field + | Ast0.Cast(lp,ty,rp,exp) -> + let exp = expression exp in + mkres e (Ast0.Cast(lp,typeC ty,rp,exp)) (promote_mcode lp) exp + | Ast0.SizeOfExpr(szf,exp) -> + let exp = expression exp in + mkres e (Ast0.SizeOfExpr(szf,exp)) (promote_mcode szf) exp + | Ast0.SizeOfType(szf,lp,ty,rp) -> + mkres e (Ast0.SizeOfType(szf,lp,typeC ty,rp)) + (promote_mcode szf) (promote_mcode rp) + | Ast0.TypeExp(ty) -> + let ty = typeC ty in mkres e (Ast0.TypeExp(ty)) ty ty + | Ast0.MetaErr(name,_,_) | Ast0.MetaExpr(name,_,_,_,_) + | Ast0.MetaExprList(name,_,_) as ue -> + let ln = promote_mcode name in mkres e ue ln ln + | Ast0.EComma(cm) -> + let cm = bad_mcode cm in + let ln = promote_mcode cm in + mkres e (Ast0.EComma(cm)) ln ln + | Ast0.DisjExpr(starter,exps,mids,ender) -> + let starter = bad_mcode starter in + let exps = List.map expression exps in + let mids = List.map bad_mcode mids in + let ender = bad_mcode ender in + mkmultires e (Ast0.DisjExpr(starter,exps,mids,ender)) + (promote_mcode starter) (promote_mcode ender) + (get_all_start_info exps) (get_all_end_info exps) + | Ast0.NestExpr(starter,exp_dots,ender,whencode,multi) -> + let exp_dots = dots is_exp_dots None expression exp_dots in + let starter = bad_mcode starter in + let ender = bad_mcode ender in + mkres e (Ast0.NestExpr(starter,exp_dots,ender,whencode,multi)) + (promote_mcode starter) (promote_mcode ender) + | Ast0.Edots(dots,whencode) -> + let dots = bad_mcode dots in + let ln = promote_mcode dots in + mkres e (Ast0.Edots(dots,whencode)) ln ln + | Ast0.Ecircles(dots,whencode) -> + let dots = bad_mcode dots in + let ln = promote_mcode dots in + mkres e (Ast0.Ecircles(dots,whencode)) ln ln + | Ast0.Estars(dots,whencode) -> + let dots = bad_mcode dots in + let ln = promote_mcode dots in + mkres e (Ast0.Estars(dots,whencode)) ln ln + | Ast0.OptExp(exp) -> + let exp = expression exp in + mkres e (Ast0.OptExp(exp)) exp exp + | Ast0.UniqueExp(exp) -> + let exp = expression exp in + mkres e (Ast0.UniqueExp(exp)) exp exp + +and expression_dots x = dots is_exp_dots None expression x + +(* --------------------------------------------------------------------- *) +(* Types *) + +and typeC t = + match Ast0.unwrap t with + Ast0.ConstVol(cv,ty) -> + let ty = typeC ty in + mkres t (Ast0.ConstVol(cv,ty)) (promote_mcode cv) ty + | Ast0.BaseType(ty,None) as ut -> + mkres t ut (promote_mcode ty) (promote_mcode ty) + | Ast0.BaseType(ty,Some sgn) as ut -> + mkres t ut (promote_mcode sgn) (promote_mcode ty) + | Ast0.ImplicitInt(sgn) as ut -> + mkres t ut (promote_mcode sgn) (promote_mcode sgn) + | Ast0.Pointer(ty,star) -> + let ty = typeC ty in + mkres t (Ast0.Pointer(ty,star)) ty (promote_mcode star) + | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> + let ty = typeC ty in + let params = parameter_list (Some(promote_mcode lp2)) params in + mkres t (Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2)) + ty (promote_mcode rp2) + | Ast0.FunctionType(Some ty,lp1,params,rp1) -> + let ty = typeC ty in + let params = parameter_list (Some(promote_mcode lp1)) params in + let res = Ast0.FunctionType(Some ty,lp1,params,rp1) in + mkres t res ty (promote_mcode rp1) + | Ast0.FunctionType(None,lp1,params,rp1) -> + let params = parameter_list (Some(promote_mcode lp1)) params in + let res = Ast0.FunctionType(None,lp1,params,rp1) in + mkres t res (promote_mcode lp1) (promote_mcode rp1) + | Ast0.Array(ty,lb,size,rb) -> + let ty = typeC ty in + mkres t (Ast0.Array(ty,lb,get_option expression size,rb)) + ty (promote_mcode rb) + | Ast0.StructUnionName(kind,Some name) -> + let name = ident name in + mkres t (Ast0.StructUnionName(kind,Some name)) (promote_mcode kind) name + | Ast0.StructUnionName(kind,None) -> + let mc = promote_mcode kind in + mkres t (Ast0.StructUnionName(kind,None)) mc mc + | Ast0.StructUnionDef(ty,lb,decls,rb) -> + let ty = typeC ty in + let decls = + dots is_decl_dots (Some(promote_mcode lb)) declaration decls in + mkres t (Ast0.StructUnionDef(ty,lb,decls,rb)) ty (promote_mcode rb) + | Ast0.TypeName(name) as ut -> + let ln = promote_mcode name in mkres t ut ln ln + | Ast0.MetaType(name,_) as ut -> + let ln = promote_mcode name in mkres t ut ln ln + | Ast0.DisjType(starter,types,mids,ender) -> + let starter = bad_mcode starter in + let types = List.map typeC types in + let mids = List.map bad_mcode mids in + let ender = bad_mcode ender in + mkmultires t (Ast0.DisjType(starter,types,mids,ender)) + (promote_mcode starter) (promote_mcode ender) + (get_all_start_info types) (get_all_end_info types) + | Ast0.OptType(ty) -> + let ty = typeC ty in mkres t (Ast0.OptType(ty)) ty ty + | Ast0.UniqueType(ty) -> + let ty = typeC ty in mkres t (Ast0.UniqueType(ty)) ty 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 is_decl_dots s = + match Ast0.unwrap s with + Ast0.Ddots(_,_) -> true + | _ -> false + +and declaration d = + match Ast0.unwrap d with + Ast0.Init(stg,ty,id,eq,exp,sem) -> + let ty = typeC ty in + let id = ident id in + let exp = initialiser exp in + (match stg with + None -> + mkres d (Ast0.Init(stg,ty,id,eq,exp,sem)) ty (promote_mcode sem) + | Some x -> + mkres d (Ast0.Init(stg,ty,id,eq,exp,sem)) + (promote_mcode x) (promote_mcode sem)) + | Ast0.UnInit(stg,ty,id,sem) -> + let ty = typeC ty in + let id = ident id in + (match stg with + None -> + mkres d (Ast0.UnInit(stg,ty,id,sem)) ty (promote_mcode sem) + | Some x -> + mkres d (Ast0.UnInit(stg,ty,id,sem)) + (promote_mcode x) (promote_mcode sem)) + | Ast0.MacroDecl(name,lp,args,rp,sem) -> + let name = ident name in + let args = dots is_exp_dots (Some(promote_mcode lp)) expression args in + mkres d (Ast0.MacroDecl(name,lp,args,rp,sem)) name (promote_mcode sem) + | Ast0.TyDecl(ty,sem) -> + let ty = typeC ty in + mkres d (Ast0.TyDecl(ty,sem)) ty (promote_mcode sem) + | Ast0.Typedef(stg,ty,id,sem) -> + let ty = typeC ty in + let id = typeC id in + mkres d (Ast0.Typedef(stg,ty,id,sem)) + (promote_mcode stg) (promote_mcode sem) + | Ast0.DisjDecl(starter,decls,mids,ender) -> + let starter = bad_mcode starter in + let decls = List.map declaration decls in + let mids = List.map bad_mcode mids in + let ender = bad_mcode ender in + mkmultires d (Ast0.DisjDecl(starter,decls,mids,ender)) + (promote_mcode starter) (promote_mcode ender) + (get_all_start_info decls) (get_all_end_info decls) + | Ast0.Ddots(dots,whencode) -> + let dots = bad_mcode dots in + let ln = promote_mcode dots in + mkres d (Ast0.Ddots(dots,whencode)) ln ln + | Ast0.OptDecl(decl) -> + let decl = declaration decl in + mkres d (Ast0.OptDecl(declaration decl)) decl decl + | Ast0.UniqueDecl(decl) -> + let decl = declaration decl in + mkres d (Ast0.UniqueDecl(declaration decl)) decl decl + +(* --------------------------------------------------------------------- *) +(* Initializer *) + +and is_init_dots i = + match Ast0.unwrap i with + Ast0.Idots(_,_) -> true + | _ -> false + +and initialiser i = + match Ast0.unwrap i with + Ast0.InitExpr(exp) -> + let exp = expression exp in + mkres i (Ast0.InitExpr(exp)) exp exp + | Ast0.InitList(lb,initlist,rb) -> + let initlist = + dots is_init_dots (Some(promote_mcode lb)) initialiser initlist in + mkres i (Ast0.InitList(lb,initlist,rb)) + (promote_mcode lb) (promote_mcode rb) + | Ast0.InitGccDotName(dot,name,eq,ini) -> + let name = ident name in + let ini = initialiser ini in + mkres i (Ast0.InitGccDotName(dot,name,eq,ini)) (promote_mcode dot) ini + | Ast0.InitGccName(name,eq,ini) -> + let name = ident name in + let ini = initialiser ini in + mkres i (Ast0.InitGccName(name,eq,ini)) name ini + | Ast0.InitGccIndex(lb,exp,rb,eq,ini) -> + let exp = expression exp in + let ini = initialiser ini in + mkres i (Ast0.InitGccIndex(lb,exp,rb,eq,ini)) (promote_mcode lb) ini + | Ast0.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini) -> + let exp1 = expression exp1 in + let exp2 = expression exp2 in + let ini = initialiser ini in + mkres i (Ast0.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini)) + (promote_mcode lb) ini + | Ast0.IComma(cm) as up -> + let ln = promote_mcode cm in mkres i up ln ln + | Ast0.Idots(dots,whencode) -> + let dots = bad_mcode dots in + let ln = promote_mcode dots in + mkres i (Ast0.Idots(dots,whencode)) ln ln + | Ast0.OptIni(ini) -> + let ini = initialiser ini in + mkres i (Ast0.OptIni(ini)) ini ini + | Ast0.UniqueIni(ini) -> + let ini = initialiser ini in + mkres i (Ast0.UniqueIni(ini)) ini ini + +and initialiser_list prev = dots is_init_dots prev initialiser + +(* for export *) +and initialiser_dots x = dots is_init_dots None initialiser x + +(* --------------------------------------------------------------------- *) +(* Parameter *) + +and is_param_dots p = + match Ast0.unwrap p with + Ast0.Pdots(_) | Ast0.Pcircles(_) -> true + | _ -> false + +and parameterTypeDef p = + match Ast0.unwrap p with + Ast0.VoidParam(ty) -> + let ty = typeC ty in mkres p (Ast0.VoidParam(ty)) ty ty + | Ast0.Param(ty,Some id) -> + let id = ident id in + let ty = typeC ty in mkres p (Ast0.Param(ty,Some id)) ty id + | Ast0.Param(ty,None) -> + let ty = typeC ty in mkres p (Ast0.Param(ty,None)) ty ty + | Ast0.MetaParam(name,_) as up -> + let ln = promote_mcode name in mkres p up ln ln + | Ast0.MetaParamList(name,_,_) as up -> + let ln = promote_mcode name in mkres p up ln ln + | Ast0.PComma(cm) -> + let cm = bad_mcode cm in + let ln = promote_mcode cm in + mkres p (Ast0.PComma(cm)) ln ln + | Ast0.Pdots(dots) -> + let dots = bad_mcode dots in + let ln = promote_mcode dots in + mkres p (Ast0.Pdots(dots)) ln ln + | Ast0.Pcircles(dots) -> + let dots = bad_mcode dots in + let ln = promote_mcode dots in + mkres p (Ast0.Pcircles(dots)) ln ln + | Ast0.OptParam(param) -> + let res = parameterTypeDef param in + mkres p (Ast0.OptParam(res)) res res + | Ast0.UniqueParam(param) -> + let res = parameterTypeDef param in + mkres p (Ast0.UniqueParam(res)) res res + +and parameter_list prev = dots is_param_dots prev parameterTypeDef + +(* for export *) +let parameter_dots x = dots is_param_dots None parameterTypeDef x + +(* --------------------------------------------------------------------- *) +(* Top-level code *) + +let is_stm_dots s = + match Ast0.unwrap s with + Ast0.Dots(_,_) | Ast0.Circles(_,_) | Ast0.Stars(_,_) -> true + | _ -> false + +let rec statement s = + let res = + match Ast0.unwrap s with + Ast0.Decl((_,bef),decl) -> + let decl = declaration decl in + let left = promote_to_statement_start decl bef in + mkres s (Ast0.Decl((Ast0.get_info left,bef),decl)) decl decl + | Ast0.Seq(lbrace,body,rbrace) -> + let body = + dots is_stm_dots (Some(promote_mcode lbrace)) statement body in + mkres s (Ast0.Seq(lbrace,body,rbrace)) + (promote_mcode lbrace) (promote_mcode rbrace) + | Ast0.ExprStatement(exp,sem) -> + let exp = expression exp in + mkres s (Ast0.ExprStatement(exp,sem)) exp (promote_mcode sem) + | Ast0.IfThen(iff,lp,exp,rp,branch,(_,aft)) -> + let exp = expression exp in + let branch = statement branch in + let right = promote_to_statement branch aft in + mkres s (Ast0.IfThen(iff,lp,exp,rp,branch,(Ast0.get_info right,aft))) + (promote_mcode iff) right + | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,(_,aft)) -> + let exp = expression exp in + let branch1 = statement branch1 in + let branch2 = statement branch2 in + let right = promote_to_statement branch2 aft in + mkres s + (Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2, + (Ast0.get_info right,aft))) + (promote_mcode iff) right + | Ast0.While(wh,lp,exp,rp,body,(_,aft)) -> + let exp = expression exp in + let body = statement body in + let right = promote_to_statement body aft in + mkres s (Ast0.While(wh,lp,exp,rp,body,(Ast0.get_info right,aft))) + (promote_mcode wh) right + | Ast0.Do(d,body,wh,lp,exp,rp,sem) -> + let body = statement body in + let exp = expression exp in + mkres s (Ast0.Do(d,body,wh,lp,exp,rp,sem)) + (promote_mcode d) (promote_mcode sem) + | Ast0.For(fr,lp,exp1,sem1,exp2,sem2,exp3,rp,body,(_,aft)) -> + let exp1 = get_option expression exp1 in + let exp2 = get_option expression exp2 in + let exp3 = get_option expression exp3 in + let body = statement body in + let right = promote_to_statement body aft in + mkres s (Ast0.For(fr,lp,exp1,sem1,exp2,sem2,exp3,rp,body, + (Ast0.get_info right,aft))) + (promote_mcode fr) right + | Ast0.Iterator(nm,lp,args,rp,body,(_,aft)) -> + let nm = ident nm in + let args = dots is_exp_dots (Some(promote_mcode lp)) expression args in + let body = statement body in + let right = promote_to_statement body aft in + mkres s (Ast0.Iterator(nm,lp,args,rp,body,(Ast0.get_info right,aft))) + nm right + | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) -> + let exp = expression exp in + let cases = + dots (function _ -> false) (Some(promote_mcode lb)) case_line cases in + mkres s + (Ast0.Switch(switch,lp,exp,rp,lb,cases,rb)) + (promote_mcode switch) (promote_mcode rb) + | Ast0.Break(br,sem) as us -> + mkres s us (promote_mcode br) (promote_mcode sem) + | Ast0.Continue(cont,sem) as us -> + mkres s us (promote_mcode cont) (promote_mcode sem) + | Ast0.Label(l,dd) -> + let l = ident l in + mkres s (Ast0.Label(l,dd)) l (promote_mcode dd) + | Ast0.Goto(goto,id,sem) -> + let id = ident id in + mkres s (Ast0.Goto(goto,id,sem)) + (promote_mcode goto) (promote_mcode sem) + | Ast0.Return(ret,sem) as us -> + mkres s us (promote_mcode ret) (promote_mcode sem) + | Ast0.ReturnExpr(ret,exp,sem) -> + let exp = expression exp in + mkres s (Ast0.ReturnExpr(ret,exp,sem)) + (promote_mcode ret) (promote_mcode sem) + | Ast0.MetaStmt(name,_) + | Ast0.MetaStmtList(name,_) as us -> + let ln = promote_mcode name in mkres s us ln ln + | Ast0.Exp(exp) -> + let exp = expression exp in + mkres s (Ast0.Exp(exp)) exp exp + | Ast0.TopExp(exp) -> + let exp = expression exp in + mkres s (Ast0.TopExp(exp)) exp exp + | Ast0.Ty(ty) -> + let ty = typeC ty in + mkres s (Ast0.Ty(ty)) ty ty + | Ast0.Disj(starter,rule_elem_dots_list,mids,ender) -> + let starter = bad_mcode starter in + let mids = List.map bad_mcode mids in + let ender = bad_mcode ender in + let rec loop prevs = function + [] -> [] + | stm::stms -> + (dots is_stm_dots (Some(promote_mcode_plus_one(List.hd prevs))) + statement stm):: + (loop (List.tl prevs) stms) in + let elems = loop (starter::mids) rule_elem_dots_list in + mkmultires s (Ast0.Disj(starter,elems,mids,ender)) + (promote_mcode starter) (promote_mcode ender) + (get_all_start_info elems) (get_all_end_info elems) + | Ast0.Nest(starter,rule_elem_dots,ender,whencode,multi) -> + let starter = bad_mcode starter in + let ender = bad_mcode ender in + let rule_elem_dots = dots is_stm_dots None statement rule_elem_dots in + mkres s (Ast0.Nest(starter,rule_elem_dots,ender,whencode,multi)) + (promote_mcode starter) (promote_mcode ender) + | Ast0.Dots(dots,whencode) -> + let dots = bad_mcode dots in + let ln = promote_mcode dots in + mkres s (Ast0.Dots(dots,whencode)) ln ln + | Ast0.Circles(dots,whencode) -> + let dots = bad_mcode dots in + let ln = promote_mcode dots in + mkres s (Ast0.Circles(dots,whencode)) ln ln + | Ast0.Stars(dots,whencode) -> + let dots = bad_mcode dots in + let ln = promote_mcode dots in + mkres s (Ast0.Stars(dots,whencode)) ln ln + | Ast0.FunDecl((_,bef),fninfo,name,lp,params,rp,lbrace,body,rbrace) -> + let fninfo = + List.map + (function Ast0.FType(ty) -> Ast0.FType(typeC ty) | x -> x) + fninfo in + let name = ident name in + let params = parameter_list (Some(promote_mcode lp)) params in + let body = + dots is_stm_dots (Some(promote_mcode lbrace)) statement body in + let left = + (* cases on what is leftmost *) + match fninfo with + [] -> promote_to_statement_start name bef + | Ast0.FStorage(stg)::_ -> + promote_to_statement_start (promote_mcode stg) bef + | Ast0.FType(ty)::_ -> + promote_to_statement_start ty bef + | Ast0.FInline(inline)::_ -> + promote_to_statement_start (promote_mcode inline) bef + | Ast0.FAttr(attr)::_ -> + promote_to_statement_start (promote_mcode attr) bef in + (* pretend it is one line before the start of the function, so that it + will catch things defined at top level. We assume that these will not + be defined on the same line as the function. This is a HACK. + A better approach would be to attach top_level things to this node, + and other things to the node after, but that would complicate + insert_plus, which doesn't distinguish between different mcodekinds *) + let res = + Ast0.FunDecl((Ast0.get_info left,bef),fninfo,name,lp,params,rp,lbrace, + body,rbrace) in + (* have to do this test again, because of typing problems - can't save + the result, only use it *) + (match fninfo with + [] -> mkres s res name (promote_mcode rbrace) + | Ast0.FStorage(stg)::_ -> + mkres s res (promote_mcode stg) (promote_mcode rbrace) + | Ast0.FType(ty)::_ -> mkres s res ty (promote_mcode rbrace) + | Ast0.FInline(inline)::_ -> + mkres s res (promote_mcode inline) (promote_mcode rbrace) + | Ast0.FAttr(attr)::_ -> + mkres s res (promote_mcode attr) (promote_mcode rbrace)) + + | Ast0.Include(inc,stm) -> + mkres s (Ast0.Include(inc,stm)) (promote_mcode inc) (promote_mcode stm) + | Ast0.Define(def,id,params,body) -> + let id = ident id in + let body = dots is_stm_dots None statement body in + mkres s (Ast0.Define(def,id,params,body)) (promote_mcode def) body + | Ast0.OptStm(stm) -> + let stm = statement stm in mkres s (Ast0.OptStm(stm)) stm stm + | Ast0.UniqueStm(stm) -> + let stm = statement stm in mkres s (Ast0.UniqueStm(stm)) stm stm in + Ast0.set_dots_bef_aft res + (match Ast0.get_dots_bef_aft res with + Ast0.NoDots -> Ast0.NoDots + | Ast0.AddingBetweenDots s -> + Ast0.AddingBetweenDots(statement s) + | Ast0.DroppingBetweenDots s -> + Ast0.DroppingBetweenDots(statement s)) + +and case_line c = + match Ast0.unwrap c with + Ast0.Default(def,colon,code) -> + let code = dots is_stm_dots (Some(promote_mcode colon)) statement code in + mkres c (Ast0.Default(def,colon,code)) (promote_mcode def) code + | Ast0.Case(case,exp,colon,code) -> + let exp = expression exp in + let code = dots is_stm_dots (Some(promote_mcode colon)) statement code in + mkres c (Ast0.Case(case,exp,colon,code)) (promote_mcode case) code + | Ast0.OptCase(case) -> + let case = case_line case in mkres c (Ast0.OptCase(case)) case case + +and statement_dots x = dots is_stm_dots None statement x + +(* --------------------------------------------------------------------- *) +(* Function declaration *) + +let top_level t = + match Ast0.unwrap t with + Ast0.FILEINFO(old_file,new_file) -> t + | Ast0.DECL(stmt) -> + let stmt = statement stmt in mkres t (Ast0.DECL(stmt)) stmt stmt + | Ast0.CODE(rule_elem_dots) -> + let rule_elem_dots = dots is_stm_dots None statement rule_elem_dots in + mkres t (Ast0.CODE(rule_elem_dots)) rule_elem_dots rule_elem_dots + | Ast0.ERRORWORDS(exps) -> t + | Ast0.OTHER(_) -> failwith "eliminated by top_level" + +(* --------------------------------------------------------------------- *) +(* Entry points *) + +let compute_lines = List.map top_level + diff --git a/parsing_cocci/.#context_neg.ml.1.95 b/parsing_cocci/.#context_neg.ml.1.95 new file mode 100644 index 0000000..e20fe00 --- /dev/null +++ b/parsing_cocci/.#context_neg.ml.1.95 @@ -0,0 +1,992 @@ +(* +* 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.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.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.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.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(_)) -> + 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(_) -> () 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/.#context_neg.ml.1.96 b/parsing_cocci/.#context_neg.ml.1.96 new file mode 100644 index 0000000..93e3293 --- /dev/null +++ b/parsing_cocci/.#context_neg.ml.1.96 @@ -0,0 +1,1002 @@ +(* +* 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.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/.#disjdistr.ml.1.20 b/parsing_cocci/.#disjdistr.ml.1.20 new file mode 100644 index 0000000..c624418 --- /dev/null +++ b/parsing_cocci/.#disjdistr.ml.1.20 @@ -0,0 +1,393 @@ +(* +* 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 V = Visitor_ast + +let disjmult2 e1 e2 k = + List.concat + (List.map (function e1 -> List.map (function e2 -> k e1 e2) e2) e1) + +let disjmult3 e1 e2 e3 k = + List.concat + (List.map + (function e1 -> + List.concat + (List.map + (function e2 -> List.map (function e3 -> k e1 e2 e3) e3) + e2)) + e1) + +let rec disjmult f = function + [] -> [[]] + | x::xs -> + let cur = f x in + let rest = disjmult f xs in + disjmult2 cur rest (function cur -> function rest -> cur :: rest) + +let disjoption f = function + None -> [None] + | Some x -> List.map (function x -> Some x) (f x) + +let disjdots f d = + match Ast.unwrap d with + Ast.DOTS(l) -> + List.map (function l -> Ast.rewrap d (Ast.DOTS(l))) (disjmult f l) + | Ast.CIRCLES(l) -> + List.map (function l -> Ast.rewrap d (Ast.CIRCLES(l))) (disjmult f l) + | Ast.STARS(l) -> + List.map (function l -> Ast.rewrap d (Ast.STARS(l))) (disjmult f l) + +let rec disjty ft = + match Ast.unwrap ft with + Ast.Type(cv,ty) -> + let ty = disjtypeC ty in + List.map (function ty -> Ast.rewrap ft (Ast.Type(cv,ty))) ty + | Ast.DisjType(types) -> List.concat (List.map disjty types) + | Ast.OptType(ty) -> + let ty = disjty ty in + List.map (function ty -> Ast.rewrap ft (Ast.OptType(ty))) ty + | Ast.UniqueType(ty) -> + let ty = disjty ty in + List.map (function ty -> Ast.rewrap ft (Ast.UniqueType(ty))) ty + +and disjtypeC bty = + match Ast.unwrap bty with + Ast.BaseType(_,_) | Ast.ImplicitInt(_) -> [bty] + | Ast.Pointer(ty,star) -> + let ty = disjty ty in + List.map (function ty -> Ast.rewrap bty (Ast.Pointer(ty,star))) ty + | Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> + let ty = disjty ty in + List.map + (function ty -> + Ast.rewrap bty (Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2))) + ty + | Ast.FunctionType (s,ty,lp1,params,rp1) -> + let ty = disjoption disjty ty in + List.map + (function ty -> + Ast.rewrap bty (Ast.FunctionType (s,ty,lp1,params,rp1))) + ty + | Ast.Array(ty,lb,size,rb) -> + disjmult2 (disjty ty) (disjoption disjexp size) + (function ty -> function size -> + Ast.rewrap bty (Ast.Array(ty,lb,size,rb))) + | Ast.StructUnionName(kind,name) -> [bty] + | Ast.StructUnionDef(ty,lb,decls,rb) -> + disjmult2 (disjty ty) (disjdots disjdecl decls) + (function ty -> function decls -> + Ast.rewrap bty (Ast.StructUnionDef(ty,lb,decls,rb))) + | Ast.TypeName(_) | Ast.MetaType(_,_,_) -> [bty] + +and disjexp e = + match Ast.unwrap e with + Ast.Ident(_) | Ast.Constant(_) -> [e] + | Ast.FunCall(fn,lp,args,rp) -> + disjmult2 (disjexp fn) (disjdots disjexp args) + (function fn -> function args -> + Ast.rewrap e (Ast.FunCall(fn,lp,args,rp))) + | Ast.Assignment(left,op,right,simple) -> + disjmult2 (disjexp left) (disjexp right) + (function left -> function right -> + Ast.rewrap e (Ast.Assignment(left,op,right,simple))) + | Ast.CondExpr(exp1,why,Some exp2,colon,exp3) -> + let res = disjmult disjexp [exp1;exp2;exp3] in + List.map + (function + [exp1;exp2;exp3] -> + Ast.rewrap e (Ast.CondExpr(exp1,why,Some exp2,colon,exp3)) + | _ -> failwith "not possible") + res + | Ast.CondExpr(exp1,why,None,colon,exp3) -> + disjmult2 (disjexp exp1) (disjexp exp3) + (function exp1 -> function exp3 -> + Ast.rewrap e (Ast.CondExpr(exp1,why,None,colon,exp3))) + | Ast.Postfix(exp,op) -> + let exp = disjexp exp in + List.map (function exp -> Ast.rewrap e (Ast.Postfix(exp,op))) exp + | Ast.Infix(exp,op) -> + let exp = disjexp exp in + List.map (function exp -> Ast.rewrap e (Ast.Infix(exp,op))) exp + | Ast.Unary(exp,op) -> + let exp = disjexp exp in + List.map (function exp -> Ast.rewrap e (Ast.Unary(exp,op))) exp + | Ast.Binary(left,op,right) -> + disjmult2 (disjexp left) (disjexp right) + (function left -> function right -> + Ast.rewrap e (Ast.Binary(left,op,right))) + | Ast.Nested(exp,op,right) -> + (* disj not possible in right *) + let exp = disjexp exp in + List.map (function exp -> Ast.rewrap e (Ast.Nested(exp,op,right))) exp + | Ast.Paren(lp,exp,rp) -> + let exp = disjexp exp in + List.map (function exp -> Ast.rewrap e (Ast.Paren(lp,exp,rp))) exp + | Ast.ArrayAccess(exp1,lb,exp2,rb) -> + disjmult2 (disjexp exp1) (disjexp exp2) + (function exp1 -> function exp2 -> + Ast.rewrap e (Ast.ArrayAccess(exp1,lb,exp2,rb))) + | Ast.RecordAccess(exp,pt,field) -> + let exp = disjexp exp in + List.map + (function exp -> Ast.rewrap e (Ast.RecordAccess(exp,pt,field))) exp + | Ast.RecordPtAccess(exp,ar,field) -> + let exp = disjexp exp in + List.map + (function exp -> Ast.rewrap e (Ast.RecordPtAccess(exp,ar,field))) exp + | Ast.Cast(lp,ty,rp,exp) -> + disjmult2 (disjty ty) (disjexp exp) + (function ty -> function exp -> Ast.rewrap e (Ast.Cast(lp,ty,rp,exp))) + | Ast.SizeOfExpr(szf,exp) -> + let exp = disjexp exp in + List.map (function exp -> Ast.rewrap e (Ast.SizeOfExpr(szf,exp))) exp + | Ast.SizeOfType(szf,lp,ty,rp) -> + let ty = disjty ty in + List.map + (function ty -> Ast.rewrap e (Ast.SizeOfType(szf,lp,ty,rp))) ty + | Ast.TypeExp(ty) -> + let ty = disjty ty in + List.map (function ty -> Ast.rewrap e (Ast.TypeExp(ty))) ty + | Ast.MetaErr(_,_,_,_) | Ast.MetaExpr(_,_,_,_,_,_) + | Ast.MetaExprList(_,_,_,_) | Ast.EComma(_) -> [e] + | Ast.DisjExpr(exp_list) -> List.concat (List.map disjexp exp_list) + | Ast.NestExpr(expr_dots,whencode,multi) -> + (* not sure what to do here, so ambiguities still possible *) + [e] + | Ast.Edots(dots,_) | Ast.Ecircles(dots,_) | Ast.Estars(dots,_) -> [e] + | Ast.OptExp(exp) -> + let exp = disjexp exp in + List.map (function exp -> Ast.rewrap e (Ast.OptExp(exp))) exp + | Ast.UniqueExp(exp) -> + let exp = disjexp exp in + List.map (function exp -> Ast.rewrap e (Ast.UniqueExp(exp))) exp + +and disjparam p = + match Ast.unwrap p with + Ast.VoidParam(ty) -> [p] (* void is the only possible value *) + | Ast.Param(ty,id) -> + let ty = disjty ty in + List.map (function ty -> Ast.rewrap p (Ast.Param(ty,id))) ty + | Ast.MetaParam(_,_,_) | Ast.MetaParamList(_,_,_,_) | Ast.PComma(_) -> [p] + | Ast.Pdots(dots) | Ast.Pcircles(dots) -> [p] + | Ast.OptParam(param) -> + let param = disjparam param in + List.map (function param -> Ast.rewrap p (Ast.OptParam(param))) param + | Ast.UniqueParam(param) -> + let param = disjparam param in + List.map (function param -> Ast.rewrap p (Ast.UniqueParam(param))) param + +and disjini i = + match Ast.unwrap i with + Ast.InitExpr(exp) -> + let exp = disjexp exp in + List.map (function exp -> Ast.rewrap i (Ast.InitExpr(exp))) exp + | Ast.InitList(lb,initlist,rb,whencode) -> + List.map + (function initlist -> + Ast.rewrap i (Ast.InitList(lb,initlist,rb,whencode))) + (disjmult disjini initlist) + | Ast.InitGccDotName(dot,name,eq,ini) -> + let ini = disjini ini in + List.map + (function ini -> Ast.rewrap i (Ast.InitGccDotName(dot,name,eq,ini))) + ini + | Ast.InitGccName(name,eq,ini) -> + let ini = disjini ini in + List.map + (function ini -> Ast.rewrap i (Ast.InitGccName(name,eq,ini))) + ini + | Ast.InitGccIndex(lb,exp,rb,eq,ini) -> + disjmult2 (disjexp exp) (disjini ini) + (function exp -> function ini -> + Ast.rewrap i (Ast.InitGccIndex(lb,exp,rb,eq,ini))) + | Ast.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini) -> + disjmult3 (disjexp exp1) (disjexp exp2) (disjini ini) + (function exp1 -> function exp2 -> function ini -> + Ast.rewrap i (Ast.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini))) + | Ast.IComma(comma) -> [i] + | Ast.OptIni(ini) -> + let ini = disjini ini in + List.map (function ini -> Ast.rewrap i (Ast.OptIni(ini))) ini + | Ast.UniqueIni(ini) -> + let ini = disjini ini in + List.map (function ini -> Ast.rewrap i (Ast.UniqueIni(ini))) ini + +and disjdecl d = + match Ast.unwrap d with + Ast.Init(stg,ty,id,eq,ini,sem) -> + disjmult2 (disjty ty) (disjini ini) + (function ty -> function ini -> + Ast.rewrap d (Ast.Init(stg,ty,id,eq,ini,sem))) + | Ast.UnInit(stg,ty,id,sem) -> + let ty = disjty ty in + List.map (function ty -> Ast.rewrap d (Ast.UnInit(stg,ty,id,sem))) ty + | Ast.MacroDecl(name,lp,args,rp,sem) -> + List.map + (function args -> Ast.rewrap d (Ast.MacroDecl(name,lp,args,rp,sem))) + (disjdots disjexp args) + | Ast.TyDecl(ty,sem) -> + let ty = disjty ty in + List.map (function ty -> Ast.rewrap d (Ast.TyDecl(ty,sem))) ty + | Ast.Typedef(stg,ty,id,sem) -> + let ty = disjty ty in (* disj not allowed in id *) + List.map (function ty -> Ast.rewrap d (Ast.Typedef(stg,ty,id,sem))) ty + | Ast.DisjDecl(decls) -> List.concat (List.map disjdecl decls) + | Ast.Ddots(_,_) | Ast.MetaDecl(_,_,_) -> [d] + | Ast.OptDecl(decl) -> + let decl = disjdecl decl in + List.map (function decl -> Ast.rewrap d (Ast.OptDecl(decl))) decl + | Ast.UniqueDecl(decl) -> + let decl = disjdecl decl in + List.map (function decl -> Ast.rewrap d (Ast.UniqueDecl(decl))) decl + +let generic_orify_rule_elem f re exp rebuild = + match f exp with + [exp] -> re + | orexps -> Ast.rewrap re (Ast.DisjRuleElem (List.map rebuild orexps)) + +let orify_rule_elem re exp rebuild = + generic_orify_rule_elem disjexp re exp rebuild + +let orify_rule_elem_ty = generic_orify_rule_elem disjty +let orify_rule_elem_param = generic_orify_rule_elem disjparam +let orify_rule_elem_decl = generic_orify_rule_elem disjdecl + +let disj_rule_elem r k re = + match Ast.unwrap re with + Ast.FunHeader(bef,allminus,fninfo,name,lp,params,rp) -> + generic_orify_rule_elem (disjdots disjparam) re params + (function params -> + Ast.rewrap re + (Ast.FunHeader(bef,allminus,fninfo,name,lp,params,rp))) + | Ast.Decl(bef,allminus,decl) -> + orify_rule_elem_decl re decl + (function decl -> Ast.rewrap re (Ast.Decl(bef,allminus,decl))) + | Ast.SeqStart(brace) -> re + | Ast.SeqEnd(brace) -> re + | Ast.ExprStatement(exp,sem) -> + orify_rule_elem re exp + (function exp -> Ast.rewrap re (Ast.ExprStatement(exp,sem))) + | Ast.IfHeader(iff,lp,exp,rp) -> + orify_rule_elem re exp + (function exp -> Ast.rewrap re (Ast.IfHeader(iff,lp,exp,rp))) + | Ast.Else(els) -> re + | Ast.WhileHeader(whl,lp,exp,rp) -> + orify_rule_elem re exp + (function exp -> Ast.rewrap re (Ast.WhileHeader(whl,lp,exp,rp))) + | Ast.DoHeader(d) -> re + | Ast.WhileTail(whl,lp,exp,rp,sem) -> + orify_rule_elem re exp + (function exp -> Ast.rewrap re (Ast.WhileTail(whl,lp,exp,rp,sem))) + | Ast.ForHeader(fr,lp,e1,sem1,e2,sem2,e3,rp) -> + generic_orify_rule_elem (disjmult (disjoption disjexp)) re [e1;e2;e3] + (function + [exp1;exp2;exp3] -> + Ast.rewrap re (Ast.ForHeader(fr,lp,exp1,sem1,exp2,sem2,exp3,rp)) + | _ -> failwith "not possible") + | Ast.IteratorHeader(whl,lp,args,rp) -> + generic_orify_rule_elem (disjdots disjexp) re args + (function args -> Ast.rewrap re (Ast.IteratorHeader(whl,lp,args,rp))) + | Ast.SwitchHeader(switch,lp,exp,rp) -> + orify_rule_elem re exp + (function exp -> Ast.rewrap re (Ast.SwitchHeader(switch,lp,exp,rp))) + | Ast.Break(_,_) | Ast.Continue(_,_) | Ast.Label(_,_) | Ast.Goto(_,_,_) + | Ast.Return(_,_) -> re + | Ast.ReturnExpr(ret,exp,sem) -> + orify_rule_elem re exp + (function exp -> Ast.rewrap re (Ast.ReturnExpr(ret,exp,sem))) + | Ast.MetaRuleElem(_,_,_) | Ast.MetaStmt(_,_,_,_) + | Ast.MetaStmtList(_,_,_) -> re + | Ast.Exp(exp) -> + orify_rule_elem re exp (function exp -> Ast.rewrap exp (Ast.Exp(exp))) + | Ast.TopExp(exp) -> + orify_rule_elem re exp (function exp -> Ast.rewrap exp (Ast.TopExp(exp))) + | Ast.Ty(ty) -> + orify_rule_elem_ty re ty (function ty -> Ast.rewrap ty (Ast.Ty(ty))) + | Ast.Include(inc,s) -> re + | Ast.DefineHeader(def,id,params) -> re + | Ast.Default(def,colon) -> re + | Ast.Case(case,exp,colon) -> + orify_rule_elem re exp + (function exp -> Ast.rewrap re (Ast.Case(case,exp,colon))) + | Ast.DisjRuleElem(_) -> failwith "not possible" + +let disj_all = + let mcode x = x in + let donothing r k e = k e in + V.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 + disj_rule_elem donothing donothing donothing donothing + +(* ----------------------------------------------------------------------- *) +(* collect iso information at the rule_elem level *) + +let collect_all_isos = + let bind = (@) in + let option_default = [] in + let mcode r x = [] in + let donothing r k e = Common.union_set (Ast.get_isos e) (k e) in + let doanything r k e = k e in + 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 donothing donothing + donothing doanything + +let collect_iso_info = + let mcode x = x in + let donothing r k e = k e in + let rule_elem r k e = + match Ast.unwrap e with + Ast.DisjRuleElem(l) -> k e + | _ -> + let isos = collect_all_isos.V.combiner_rule_elem e in + Ast.set_isos e isos in + V.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 rule_elem donothing donothing + donothing donothing + +(* ----------------------------------------------------------------------- *) + +let disj rules = + List.map + (function (mv,r) -> + match r with + Ast.ScriptRule _ -> (mv, r) + | Ast.CocciRule (nm, rule_info, r, isexp) -> + let res = + List.map + (function x -> + let res = disj_all.V.rebuilder_top_level x in + if !Flag.track_iso_usage + then collect_iso_info.V.rebuilder_top_level res + else res) + r in + (mv, Ast.CocciRule (nm,rule_info,res,isexp))) + rules diff --git a/parsing_cocci/.#index.ml.1.54 b/parsing_cocci/.#index.ml.1.54 new file mode 100644 index 0000000..e4b98a2 --- /dev/null +++ b/parsing_cocci/.#index.ml.1.54 @@ -0,0 +1,220 @@ +(* +* 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. +*) + + +(* create an index for each constructor *) +(* current max is 145 *) + +(* doesn't really work - requires that identical terms with no token +subterms (eg dots) not appear on the same line *) + +module Ast = Ast_cocci +module Ast0 = Ast0_cocci + +(* if a dot list is empty, add the starting line of the dot list to the +address. Otherwise add 0. An empty dot list should only match with another +empty one. *) +let expression_dots d = + let ln = (Ast0.get_info d).Ast0.line_start in + match Ast0.unwrap d with + Ast0.DOTS(l) -> 1::(if l = [] then [ln] else [0]) + | Ast0.CIRCLES(l) -> 2::(if l = [] then [ln] else [0]) + | Ast0.STARS(l) -> 3::(if l = [] then [ln] else [0]) + +let initialiser_dots d = + let ln = (Ast0.get_info d).Ast0.line_start in + match Ast0.unwrap d with + Ast0.DOTS(l) -> 113::(if l = [] then [ln] else [0]) + | Ast0.CIRCLES(l) -> 114::(if l = [] then [ln] else [0]) + | Ast0.STARS(l) -> 115::(if l = [] then [ln] else [0]) + +let parameter_dots d = + let ln = (Ast0.get_info d).Ast0.line_start in + match Ast0.unwrap d with + Ast0.DOTS(l) -> 4::(if l = [] then [ln] else [0]) + | Ast0.CIRCLES(l) -> 5::(if l = [] then [ln] else [0]) + | Ast0.STARS(l) -> 6::(if l = [] then [ln] else [0]) + +let statement_dots d = + let ln = (Ast0.get_info d).Ast0.line_start in + match Ast0.unwrap d with + Ast0.DOTS(l) -> 7::(if l = [] then [ln] else [0]) + | Ast0.CIRCLES(l) -> 8::(if l = [] then [ln] else [0]) + | Ast0.STARS(l) -> 9::(if l = [] then [ln] else [0]) + +let declaration_dots d = + let ln = (Ast0.get_info d).Ast0.line_start in + match Ast0.unwrap d with + Ast0.DOTS(l) -> 134::(if l = [] then [ln] else [0]) + | Ast0.CIRCLES(l) -> 135::(if l = [] then [ln] else [0]) + | Ast0.STARS(l) -> 136::(if l = [] then [ln] else [0]) + +let case_line_dots d = + let ln = (Ast0.get_info d).Ast0.line_start in + match Ast0.unwrap d with + Ast0.DOTS(l) -> 138::(if l = [] then [ln] else [0]) + | Ast0.CIRCLES(l) -> 139::(if l = [] then [ln] else [0]) + | Ast0.STARS(l) -> 140::(if l = [] then [ln] else [0]) + +let ident i = + match Ast0.unwrap i with + Ast0.Id(name) -> [10] + | Ast0.MetaId(name,_,_) -> [11] + | Ast0.MetaFunc(name,_,_) -> [12] + | Ast0.MetaLocalFunc(name,_,_) -> [13] + | Ast0.OptIdent(id) -> [14] + | Ast0.UniqueIdent(id) -> [15] + +let expression e = + match Ast0.unwrap e with + Ast0.Ident(id) -> [17] + | Ast0.Constant(const) -> [18] + | Ast0.FunCall(fn,lp,args,rp) -> [19] + | Ast0.Assignment(left,op,right,simple) -> [20] + | Ast0.CondExpr(exp1,why,exp2,colon,exp3) -> [21] + | Ast0.Postfix(exp,op) -> [22] + | Ast0.Infix(exp,op) -> [23] + | Ast0.Unary(exp,op) -> [24] + | Ast0.Binary(left,op,right) -> [25] + | Ast0.Nested(left,op,right) -> failwith "nested in index not possible" + | Ast0.Paren(lp,exp,rp) -> [26] + | Ast0.ArrayAccess(exp1,lb,exp2,rb) -> [27] + | Ast0.RecordAccess(exp,pt,field) -> [28] + | Ast0.RecordPtAccess(exp,ar,field) -> [29] + | Ast0.Cast(lp,ty,rp,exp) -> [30] + | Ast0.SizeOfExpr(szf,exp) -> [98] (* added after *) + | Ast0.SizeOfType(szf,lp,ty,rp) -> [99] (* added after *) + | Ast0.TypeExp(ty) -> [123] (* added after *) + | Ast0.MetaErr(name,_,_) -> [32] + | Ast0.MetaExpr(name,_,ty,_,_) -> [33] + | Ast0.MetaExprList(name,_,_) -> [34] + | Ast0.EComma(cm) -> [35] + | Ast0.DisjExpr(_,expr_list,_,_) -> [36] + | Ast0.NestExpr(_,expr_dots,_,_,_) -> [37] + | Ast0.Edots(dots,whencode) -> [38] + | Ast0.Ecircles(dots,whencode) -> [39] + | Ast0.Estars(dots,whencode) -> [40] + | Ast0.OptExp(exp) -> [41] + | Ast0.UniqueExp(exp) -> [42] + +let typeC t = + match Ast0.unwrap t with + Ast0.ConstVol(cv,ty) -> [44] + | Ast0.BaseType(ty,sign) -> [48] + | Ast0.ImplicitInt(sign) -> [129] + | Ast0.Pointer(ty,star) -> [49] + | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> [131] + | Ast0.FunctionType(ty,lp1,params,rp1) -> [132] + | Ast0.Array(ty,lb,size,rb) -> [50] + | Ast0.StructUnionName(kind,name) -> [51] + | Ast0.StructUnionDef(ty,lb,decls,rb) -> [117] + | Ast0.TypeName(name) -> [52] + | Ast0.MetaType(name,_) -> [53] + | Ast0.DisjType(_,type_list,_,_) -> [130] + | Ast0.OptType(ty) -> [45] + | Ast0.UniqueType(ty) -> [46] + +let declaration d = + match Ast0.unwrap d with + Ast0.Init(stg,ty,id,eq,exp,sem) -> [54] + | Ast0.UnInit(stg,ty,id,sem) -> [55] + | Ast0.MacroDecl(name,lp,args,rp,sem) -> [137] + | Ast0.TyDecl(ty,sem) -> [116] + | Ast0.Typedef(stg,ty,id,sem) -> [143] + | Ast0.DisjDecl(_,decls,_,_) -> [97] (* added after *) + | Ast0.Ddots(dots,whencode) -> [133] + | Ast0.OptDecl(decl) -> [56] + | Ast0.UniqueDecl(decl) -> [57] + +let initialiser i = + match Ast0.unwrap i with + Ast0.InitExpr(exp) -> [102] (* added after *) + | Ast0.InitList(lb,initlist,rb) -> [103] + | Ast0.InitGccDotName(dot,name,eq,ini) -> [104] + | Ast0.InitGccName(name,eq,ini) -> [105] + | Ast0.InitGccIndex(lb,exp,rb,eq,ini) -> [106] + | Ast0.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini) -> [107] + | Ast0.IComma(cm) -> [108] + | Ast0.Idots(d,whencode) -> [109] + | Ast0.OptIni(id) -> [110] + | Ast0.UniqueIni(id) -> [111] + +let parameterTypeDef p = + match Ast0.unwrap p with + Ast0.VoidParam(ty) -> [59] + | Ast0.Param(ty,id) -> [60] + | Ast0.MetaParam(name,_) -> [61] + | Ast0.MetaParamList(name,_,_) -> [62] + | Ast0.PComma(cm) -> [63] + | Ast0.Pdots(dots) -> [64] + | Ast0.Pcircles(dots) -> [65] + | Ast0.OptParam(param) -> [66] + | Ast0.UniqueParam(param) -> [67] + +let statement s = + match Ast0.unwrap s with + Ast0.FunDecl(bef,fninfo,name,lp,params,rp,lbrace,body,rbrace) -> [68] + | Ast0.Decl(bef,decl) -> [69] + | Ast0.Seq(lbrace,body,rbrace) -> [70] + | Ast0.ExprStatement(exp,sem) -> [71] + | Ast0.IfThen(iff,lp,exp,rp,branch1,aft) -> [72] + | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,aft) -> [73] + | Ast0.While(whl,lp,exp,rp,body,_) -> [74] + | Ast0.Do(d,body,whl,lp,exp,rp,sem) -> [75] + | Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,_) -> [76] + | Ast0.Iterator(nm,lp,args,rp,body,_) -> [142] + | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) -> [125] + | Ast0.Break(br,sem) -> [100] + | Ast0.Continue(cont,sem) -> [101] + | Ast0.Label(l,dd) -> [144] + | Ast0.Goto(goto,l,sem) -> [145] + | Ast0.Return(ret,sem) -> [77] + | Ast0.ReturnExpr(ret,exp,sem) -> [78] + | Ast0.MetaStmt(name,_) -> [79] + | Ast0.MetaStmtList(name,_) -> [80] + | Ast0.Disj(_,statement_dots_list,_,_) -> [81] + | Ast0.Nest(_,stmt_dots,_,_,_) -> [82] + | Ast0.Exp(exp) -> [83] + | Ast0.TopExp(exp) -> [141] + | Ast0.Ty(ty) -> [124] + | Ast0.Dots(d,whencode) -> [84] + | Ast0.Circles(d,whencode) -> [85] + | Ast0.Stars(d,whencode) -> [86] + | Ast0.Include(inc,name) -> [118] + | Ast0.Define(def,id,params,body) -> [119] + | Ast0.OptStm(re) -> [87] + | Ast0.UniqueStm(re) -> [88] + +let case_line c = + match Ast0.unwrap c with + Ast0.Default(def,colon,code) -> [126] + | Ast0.Case(case,exp,colon,code) -> [127] + | Ast0.OptCase(case) -> [128] + +let top_level t = + match Ast0.unwrap t with + Ast0.DECL(stmt) -> [90] + | Ast0.FILEINFO(old_file,new_file) -> [92] + | Ast0.CODE(stmt_dots) -> [94] + | Ast0.ERRORWORDS(exps) -> [95] + | Ast0.OTHER(_) -> [96] + +(* 99-101 already used *) diff --git a/parsing_cocci/.#insert_plus.ml.1.68 b/parsing_cocci/.#insert_plus.ml.1.68 new file mode 100644 index 0000000..12009c7 --- /dev/null +++ b/parsing_cocci/.#insert_plus.ml.1.68 @@ -0,0 +1,941 @@ +(* +* 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. +*) + + +(* The error message "no available token to attach to" often comes in an +argument list of unbounded length. In this case, one should move a comma so +that there is a comma after the + code. *) + +(* Start at all of the corresponding BindContext nodes in the minus and +plus trees, and traverse their children. We take the same strategy as +before: collect the list of minus/context nodes/tokens and the list of plus +tokens, and then merge them. *) + +module Ast = Ast_cocci +module Ast0 = Ast0_cocci +module V0 = Visitor_ast0 +module CN = Context_neg + +let get_option f = function + None -> [] + | Some x -> f x + +(* --------------------------------------------------------------------- *) +(* Collect root and all context nodes in a tree *) + +let collect_context e = + let bind x y = x @ y in + let option_default = [] in + + let mcode _ = [] in + + let donothing builder r k e = + match Ast0.get_mcodekind e with + Ast0.CONTEXT(_) -> (builder e) :: (k e) + | _ -> k e in + +(* special case for everything that contains whencode, so that we skip over +it *) + let expression r k e = + donothing Ast0.expr r k + (Ast0.rewrap e + (match Ast0.unwrap e with + Ast0.NestExpr(starter,exp,ender,whencode,multi) -> + Ast0.NestExpr(starter,exp,ender,None,multi) + | Ast0.Edots(dots,whencode) -> Ast0.Edots(dots,None) + | Ast0.Ecircles(dots,whencode) -> Ast0.Ecircles(dots,None) + | Ast0.Estars(dots,whencode) -> Ast0.Estars(dots,None) + | e -> e)) in + + let initialiser r k i = + donothing Ast0.ini r k + (Ast0.rewrap i + (match Ast0.unwrap i with + Ast0.Idots(dots,whencode) -> Ast0.Idots(dots,None) + | i -> i)) in + + let statement r k s = + donothing Ast0.stmt r k + (Ast0.rewrap s + (match Ast0.unwrap s with + Ast0.Nest(started,stm_dots,ender,whencode,multi) -> + Ast0.Nest(started,stm_dots,ender,[],multi) + | Ast0.Dots(dots,whencode) -> Ast0.Dots(dots,[]) + | Ast0.Circles(dots,whencode) -> Ast0.Circles(dots,[]) + | Ast0.Stars(dots,whencode) -> Ast0.Stars(dots,[]) + | s -> s)) in + + let topfn r k e = Ast0.TopTag(e) :: (k e) in + + let res = + V0.combiner bind option_default + mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode + mcode + (donothing Ast0.dotsExpr) (donothing Ast0.dotsInit) + (donothing Ast0.dotsParam) (donothing Ast0.dotsStmt) + (donothing Ast0.dotsDecl) (donothing Ast0.dotsCase) + (donothing Ast0.ident) expression (donothing Ast0.typeC) initialiser + (donothing Ast0.param) (donothing Ast0.decl) statement + (donothing Ast0.case_line) topfn in + res.V0.combiner_top_level e + +(* --------------------------------------------------------------------- *) +(* --------------------------------------------------------------------- *) +(* collect the possible join points, in order, among the children of a +BindContext. Dots are not allowed. Nests and disjunctions are no problem, +because their delimiters take up a line by themselves *) + +(* An Unfavored token is one that is in a BindContext node; using this causes + the node to become Neither, meaning that isomorphisms can't be applied *) +(* Toplevel is for the bef token of a function declaration and is for +attaching top-level definitions that should come before the complete +declaration *) +type minus_join_point = Favored | Unfavored | Toplevel | Decl + +(* Maps the index of a node to the indices of the mcodes it contains *) +let root_token_table = (Hashtbl.create(50) : (int, int list) Hashtbl.t) + +let create_root_token_table minus = + Hashtbl.iter + (function tokens -> + function (node,_) -> + let key = + match node with + Ast0.DotsExprTag(d) -> Ast0.get_index d + | Ast0.DotsInitTag(d) -> Ast0.get_index d + | Ast0.DotsParamTag(d) -> Ast0.get_index d + | Ast0.DotsStmtTag(d) -> Ast0.get_index d + | Ast0.DotsDeclTag(d) -> Ast0.get_index d + | Ast0.DotsCaseTag(d) -> Ast0.get_index d + | Ast0.IdentTag(d) -> Ast0.get_index d + | Ast0.ExprTag(d) -> Ast0.get_index d + | Ast0.ArgExprTag(d) | Ast0.TestExprTag(d) -> + failwith "not possible - iso only" + | Ast0.TypeCTag(d) -> Ast0.get_index d + | Ast0.ParamTag(d) -> Ast0.get_index d + | Ast0.InitTag(d) -> Ast0.get_index d + | Ast0.DeclTag(d) -> Ast0.get_index d + | Ast0.StmtTag(d) -> Ast0.get_index d + | Ast0.CaseLineTag(d) -> Ast0.get_index d + | Ast0.TopTag(d) -> Ast0.get_index d + | Ast0.IsoWhenTag(_) -> failwith "only within iso phase" + | Ast0.MetaPosTag(p) -> failwith "metapostag only within iso phase" + in + Hashtbl.add root_token_table key tokens) + CN.minus_table; + List.iter + (function r -> + let index = Ast0.get_index r in + try let _ = Hashtbl.find root_token_table index in () + with Not_found -> Hashtbl.add root_token_table index []) + minus + +let collect_minus_join_points root = + let root_index = Ast0.get_index root in + let unfavored_tokens = Hashtbl.find root_token_table root_index in + let bind x y = x @ y in + let option_default = [] in + + let mcode (_,_,info,mcodekind,_) = + if List.mem (info.Ast0.offset) unfavored_tokens + then [(Unfavored,info,mcodekind)] + else [(Favored,info,mcodekind)] in + + let do_nothing r k e = + let info = Ast0.get_info e in + let index = Ast0.get_index e in + match Ast0.get_mcodekind e with + (Ast0.MINUS(_)) as mc -> [(Favored,info,mc)] + | (Ast0.CONTEXT(_)) as mc when not(index = root_index) -> + (* This was unfavored at one point, but I don't remember why *) + [(Favored,info,mc)] + | _ -> k e in + +(* don't want to attach to the outside of DOTS, because metavariables can't +bind to that; not good for isomorphisms *) + + let dots f k d = + let multibind l = + let rec loop = function + [] -> option_default + | [x] -> x + | x::xs -> bind x (loop xs) in + loop l in + + match Ast0.unwrap d with + Ast0.DOTS(l) -> multibind (List.map f l) + | Ast0.CIRCLES(l) -> multibind (List.map f l) + | Ast0.STARS(l) -> multibind (List.map f l) in + + let edots r k d = dots r.V0.combiner_expression k d in + let idots r k d = dots r.V0.combiner_initialiser k d in + let pdots r k d = dots r.V0.combiner_parameter k d in + let sdots r k d = dots r.V0.combiner_statement k d in + let ddots r k d = dots r.V0.combiner_declaration k d in + let cdots r k d = dots r.V0.combiner_case_line k d in + + (* a case for everything that has a Opt *) + + let statement r k s = + (* + let redo_branched res (ifinfo,aftmc) = + let redo fv info mc rest = + let new_info = {info with Ast0.attachable_end = false} in + List.rev ((Favored,ifinfo,aftmc)::(fv,new_info,mc)::rest) in + match List.rev res with + [(fv,info,mc)] -> + (match mc with + Ast0.MINUS(_) | Ast0.CONTEXT(_) -> + (* even for -, better for isos not to integrate code after an + if into the if body. + but the problem is that this can extend the region in + which a variable is bound, because a variable bound in the + aft node would seem to have to be live in the whole if, + whereas we might like it to be live in only one branch. + ie ideally, if we can keep the minus code in the right + order, we would like to drop it as close to the bindings + of its free variables. This could be anywhere in the minus + code. Perhaps we would like to do this after the + application of isomorphisms, though. + *) + redo fv info mc [] + | _ -> res) + | (fv,info,mc)::rest -> + (match mc with + Ast0.CONTEXT(_) -> redo fv info mc rest + | _ -> res) + | _ -> failwith "unexpected empty code" in *) + match Ast0.unwrap s with + (* Ast0.IfThen(_,_,_,_,_,aft) + | Ast0.IfThenElse(_,_,_,_,_,_,_,aft) + | Ast0.While(_,_,_,_,_,aft) + | Ast0.For(_,_,_,_,_,_,_,_,_,aft) + | Ast0.Iterator(_,_,_,_,_,aft) -> + redo_branched (do_nothing r k s) aft*) + | Ast0.FunDecl((info,bef),fninfo,name,lp,params,rp,lbrace,body,rbrace) -> + (Toplevel,info,bef)::(k s) + | Ast0.Decl((info,bef),decl) -> (Decl,info,bef)::(k s) + | Ast0.Nest(starter,stmt_dots,ender,whencode,multi) -> + mcode starter @ r.V0.combiner_statement_dots stmt_dots @ mcode ender + | Ast0.Dots(d,whencode) | Ast0.Circles(d,whencode) + | Ast0.Stars(d,whencode) -> mcode d (* ignore whencode *) + | Ast0.OptStm s | Ast0.UniqueStm s -> + (* put the + code on the thing, not on the opt *) + r.V0.combiner_statement s + | _ -> do_nothing r k s in + + let expression r k e = + match Ast0.unwrap e with + Ast0.NestExpr(starter,expr_dots,ender,whencode,multi) -> + mcode starter @ + r.V0.combiner_expression_dots expr_dots @ mcode ender + | Ast0.Edots(d,whencode) | Ast0.Ecircles(d,whencode) + | Ast0.Estars(d,whencode) -> mcode d (* ignore whencode *) + | Ast0.OptExp e | Ast0.UniqueExp e -> + (* put the + code on the thing, not on the opt *) + r.V0.combiner_expression e + | _ -> do_nothing r k e in + + let ident r k e = + match Ast0.unwrap e with + Ast0.OptIdent i | Ast0.UniqueIdent i -> + (* put the + code on the thing, not on the opt *) + r.V0.combiner_ident i + | _ -> do_nothing r k e in + + let typeC r k e = + match Ast0.unwrap e with + Ast0.OptType t | Ast0.UniqueType t -> + (* put the + code on the thing, not on the opt *) + r.V0.combiner_typeC t + | _ -> do_nothing r k e in + + let decl r k e = + match Ast0.unwrap e with + Ast0.OptDecl d | Ast0.UniqueDecl d -> + (* put the + code on the thing, not on the opt *) + r.V0.combiner_declaration d + | _ -> do_nothing r k e in + + let initialiser r k e = + match Ast0.unwrap e with + Ast0.Idots(d,whencode) -> mcode d (* ignore whencode *) + | Ast0.OptIni i | Ast0.UniqueIni i -> + (* put the + code on the thing, not on the opt *) + r.V0.combiner_initialiser i + | _ -> do_nothing r k e in + + let param r k e = + match Ast0.unwrap e with + Ast0.OptParam p | Ast0.UniqueParam p -> + (* put the + code on the thing, not on the opt *) + r.V0.combiner_parameter p + | _ -> do_nothing r k e in + + let case_line r k e = + match Ast0.unwrap e with + Ast0.OptCase c -> + (* put the + code on the thing, not on the opt *) + r.V0.combiner_case_line c + | _ -> do_nothing r k e in + + let do_top r k (e: Ast0.top_level) = k e in + + V0.combiner bind option_default + mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode + mcode + edots idots pdots sdots ddots cdots + ident expression typeC initialiser param decl statement case_line do_top + + +let call_collect_minus context_nodes : + (int * (minus_join_point * Ast0.info * Ast0.mcodekind) list) list = + List.map + (function e -> + match e with + Ast0.DotsExprTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_expression_dots e) + | Ast0.DotsInitTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_initialiser_list e) + | Ast0.DotsParamTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_parameter_list e) + | Ast0.DotsStmtTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_statement_dots e) + | Ast0.DotsDeclTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_declaration_dots e) + | Ast0.DotsCaseTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_case_line_dots e) + | Ast0.IdentTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_ident e) + | Ast0.ExprTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_expression e) + | Ast0.ArgExprTag(e) | Ast0.TestExprTag(e) -> + failwith "not possible - iso only" + | Ast0.TypeCTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_typeC e) + | Ast0.ParamTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_parameter e) + | Ast0.InitTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_initialiser e) + | Ast0.DeclTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_declaration e) + | Ast0.StmtTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_statement e) + | Ast0.CaseLineTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_case_line e) + | Ast0.TopTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_top_level e) + | Ast0.IsoWhenTag(_) -> failwith "only within iso phase" + | Ast0.MetaPosTag(p) -> failwith "metapostag only within iso phase") + context_nodes + +(* result of collecting the join points should be sorted in nondecreasing + order by line *) +let verify l = + let get_info = function + (Favored,info,_) | (Unfavored,info,_) | (Toplevel,info,_) + | (Decl,info,_) -> info in + let token_start_line x = (get_info x).Ast0.logical_start in + let token_end_line x = (get_info x).Ast0.logical_end in + let token_real_start_line x = (get_info x).Ast0.line_start in + let token_real_end_line x = (get_info x).Ast0.line_end in + List.iter + (function + (index,((_::_) as l1)) -> + let _ = + List.fold_left + (function (prev,real_prev) -> + function cur -> + let ln = token_start_line cur in + if ln < prev + then + failwith + (Printf.sprintf + "error in collection of - tokens %d less than %d" + (token_real_start_line cur) real_prev); + (token_end_line cur,token_real_end_line cur)) + (token_end_line (List.hd l1), token_real_end_line (List.hd l1)) + (List.tl l1) in + () + | _ -> ()) (* dots, in eg f() has no join points *) + l + +let process_minus minus = + create_root_token_table minus; + List.concat + (List.map + (function x -> + let res = call_collect_minus (collect_context x) in + verify res; + res) + minus) + +(* --------------------------------------------------------------------- *) +(* --------------------------------------------------------------------- *) +(* collect the plus tokens *) + +let mk_baseType x = Ast.BaseTypeTag x +let mk_structUnion x = Ast.StructUnionTag x +let mk_sign x = Ast.SignTag x +let mk_ident x = Ast.IdentTag (Ast0toast.ident x) +let mk_expression x = Ast.ExpressionTag (Ast0toast.expression x) +let mk_constant x = Ast.ConstantTag x +let mk_unaryOp x = Ast.UnaryOpTag x +let mk_assignOp x = Ast.AssignOpTag x +let mk_fixOp x = Ast.FixOpTag x +let mk_binaryOp x = Ast.BinaryOpTag x +let mk_arithOp x = Ast.ArithOpTag x +let mk_logicalOp x = Ast.LogicalOpTag x +let mk_declaration x = Ast.DeclarationTag (Ast0toast.declaration x) +let mk_topdeclaration x = Ast.DeclarationTag (Ast0toast.declaration x) +let mk_storage x = Ast.StorageTag x +let mk_inc_file x = Ast.IncFileTag x +let mk_statement x = Ast.StatementTag (Ast0toast.statement x) +let mk_case_line x = Ast.CaseLineTag (Ast0toast.case_line x) +let mk_const_vol x = Ast.ConstVolTag x +let mk_token x info = Ast.Token (x,Some info) +let mk_meta (_,x) info = Ast.Token (x,Some info) +let mk_code x = Ast.Code (Ast0toast.top_level x) + +let mk_exprdots x = Ast.ExprDotsTag (Ast0toast.expression_dots x) +let mk_paramdots x = Ast.ParamDotsTag (Ast0toast.parameter_list x) +let mk_stmtdots x = Ast.StmtDotsTag (Ast0toast.statement_dots x) +let mk_decldots x = Ast.DeclDotsTag (Ast0toast.declaration_dots x) +let mk_casedots x = failwith "+ case lines not supported" +let mk_typeC x = Ast.FullTypeTag (Ast0toast.typeC x) +let mk_init x = Ast.InitTag (Ast0toast.initialiser x) +let mk_param x = Ast.ParamTag (Ast0toast.parameterTypeDef x) + +let collect_plus_nodes root = + let root_index = Ast0.get_index root in + + let bind x y = x @ y in + let option_default = [] in + + let mcode fn (term,_,info,mcodekind,_) = + match mcodekind with Ast0.PLUS -> [(info,fn term)] | _ -> [] in + + let imcode fn (term,_,info,mcodekind,_) = + match mcodekind with + Ast0.PLUS -> [(info,fn term (Ast0toast.convert_info info))] + | _ -> [] in + + let do_nothing fn r k e = + match Ast0.get_mcodekind e with + (Ast0.CONTEXT(_)) when not(Ast0.get_index e = root_index) -> [] + | Ast0.PLUS -> [(Ast0.get_info e,fn e)] + | _ -> k e in + + (* case for everything that is just a wrapper for a simpler thing *) + let stmt r k e = + match Ast0.unwrap e with + Ast0.Exp(exp) -> r.V0.combiner_expression exp + | Ast0.TopExp(exp) -> r.V0.combiner_expression exp + | Ast0.Ty(ty) -> r.V0.combiner_typeC ty + | Ast0.Decl(_,decl) -> r.V0.combiner_declaration decl + | _ -> do_nothing mk_statement r k e in + + (* statementTag is preferred, because it indicates that one statement is + replaced by one statement, in single_statement *) + let stmt_dots r k e = + match Ast0.unwrap e with + Ast0.DOTS([s]) | Ast0.CIRCLES([s]) | Ast0.STARS([s]) -> + r.V0.combiner_statement s + | _ -> do_nothing mk_stmtdots r k e in + + let toplevel r k e = + match Ast0.unwrap e with + Ast0.DECL(s) -> r.V0.combiner_statement s + | Ast0.CODE(sdots) -> r.V0.combiner_statement_dots sdots + | _ -> do_nothing mk_code r k e in + + let initdots r k e = k e in + + V0.combiner bind option_default + (imcode mk_meta) (imcode mk_token) (mcode mk_constant) (mcode mk_assignOp) + (mcode mk_fixOp) + (mcode mk_unaryOp) (mcode mk_binaryOp) (mcode mk_const_vol) + (mcode mk_baseType) (mcode mk_sign) (mcode mk_structUnion) + (mcode mk_storage) (mcode mk_inc_file) + (do_nothing mk_exprdots) initdots + (do_nothing mk_paramdots) stmt_dots (do_nothing mk_decldots) + (do_nothing mk_casedots) + (do_nothing mk_ident) (do_nothing mk_expression) + (do_nothing mk_typeC) (do_nothing mk_init) (do_nothing mk_param) + (do_nothing mk_declaration) + stmt (do_nothing mk_case_line) toplevel + +let call_collect_plus context_nodes : + (int * (Ast0.info * Ast.anything) list) list = + List.map + (function e -> + match e with + Ast0.DotsExprTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_expression_dots e) + | Ast0.DotsInitTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_initialiser_list e) + | Ast0.DotsParamTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_parameter_list e) + | Ast0.DotsStmtTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_statement_dots e) + | Ast0.DotsDeclTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_declaration_dots e) + | Ast0.DotsCaseTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_case_line_dots e) + | Ast0.IdentTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_ident e) + | Ast0.ExprTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_expression e) + | Ast0.ArgExprTag(_) | Ast0.TestExprTag(_) -> + failwith "not possible - iso only" + | Ast0.TypeCTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_typeC e) + | Ast0.InitTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_initialiser e) + | Ast0.ParamTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_parameter e) + | Ast0.DeclTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_declaration e) + | Ast0.StmtTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_statement e) + | Ast0.CaseLineTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_case_line e) + | Ast0.TopTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_top_level e) + | Ast0.IsoWhenTag(_) -> failwith "only within iso phase" + | Ast0.MetaPosTag(p) -> failwith "metapostag only within iso phase") + context_nodes + +(* The plus fragments are converted to a list of lists of lists. +Innermost list: Elements have type anything. For any pair of successive +elements, n and n+1, the ending line of n is the same as the starting line +of n+1. +Middle lists: For any pair of successive elements, n and n+1, the ending +line of n is one less than the starting line of n+1. +Outer list: For any pair of successive elements, n and n+1, the ending +line of n is more than one less than the starting line of n+1. *) + +let logstart info = info.Ast0.logical_start +let logend info = info.Ast0.logical_end + +let redo info start finish = + {{info with Ast0.logical_start = start} with Ast0.logical_end = finish} + +let rec find_neighbors (index,l) : + int * (Ast0.info * (Ast.anything list list)) list = + let rec loop = function + [] -> [] + | (i,x)::rest -> + (match loop rest with + ((i1,(x1::rest_inner))::rest_middle)::rest_outer -> + let finish1 = logend i in + let start2 = logstart i1 in + if finish1 = start2 + then + ((redo i (logstart i) (logend i1),(x::x1::rest_inner)) + ::rest_middle) + ::rest_outer + else if finish1 + 1 = start2 + then ((i,[x])::(i1,(x1::rest_inner))::rest_middle)::rest_outer + else [(i,[x])]::((i1,(x1::rest_inner))::rest_middle)::rest_outer + | _ -> [[(i,[x])]]) (* rest must be [] *) in + let res = + List.map + (function l -> + let (start_info,_) = List.hd l in + let (end_info,_) = List.hd (List.rev l) in + (redo start_info (logstart start_info) (logend end_info), + List.map (function (_,x) -> x) l)) + (loop l) in + (index,res) + +let process_plus plus : + (int * (Ast0.info * Ast.anything list list) list) list = + List.concat + (List.map + (function x -> + List.map find_neighbors (call_collect_plus (collect_context x))) + plus) + +(* --------------------------------------------------------------------- *) +(* --------------------------------------------------------------------- *) +(* merge *) +(* +let merge_one = function + (m1::m2::minus_info,p::plus_info) -> + if p < m1, then + attach p to the beginning of m1.bef if m1 is Good, fail if it is bad + if p > m1 && p < m2, then consider the following possibilities, in order + m1 is Good and favored: attach to the beginning of m1.aft + m2 is Good and favored: attach to the beginning of m2.bef; drop m1 + m1 is Good and unfavored: attach to the beginning of m1.aft + m2 is Good and unfavored: attach to the beginning of m2.bef; drop m1 + also flip m1.bef if the first where > m1 + if we drop m1, then flip m1.aft first + if p > m2 + m2 is Good and favored: attach to the beginning of m2.aft; drop m1 +*) + +(* end of first argument < start/end of second argument *) +let less_than_start info1 info2 = + info1.Ast0.logical_end < info2.Ast0.logical_start +let less_than_end info1 info2 = + info1.Ast0.logical_end < info2.Ast0.logical_end +let greater_than_end info1 info2 = + info1.Ast0.logical_start > info2.Ast0.logical_end +let good_start info = info.Ast0.attachable_start +let good_end info = info.Ast0.attachable_end + +let toplevel = function Toplevel -> true | Favored | Unfavored | Decl -> false +let decl = function Decl -> true | Favored | Unfavored | Toplevel -> false +let favored = function Favored -> true | Unfavored | Toplevel | Decl -> false + +let top_code = + List.for_all (List.for_all (function Ast.Code _ -> true | _ -> false)) + +(* The following is probably not correct. The idea is to detect what +should be placed completely before the declaration. So type/storage +related things do not fall into this category, and complete statements do +fall into this category. But perhaps other things should be in this +category as well, such as { or ;? *) +let predecl_code = + let tester = function + (* the following should definitely be true *) + Ast.DeclarationTag _ + | Ast.StatementTag _ + | Ast.Rule_elemTag _ + | Ast.StmtDotsTag _ + | Ast.Code _ -> true + (* the following should definitely be false *) + | Ast.FullTypeTag _ | Ast.BaseTypeTag _ | Ast.StructUnionTag _ + | Ast.SignTag _ + | Ast.StorageTag _ | Ast.ConstVolTag _ | Ast.TypeCTag _ -> false + (* not sure about the rest *) + | _ -> false in + List.for_all (List.for_all tester) + +let pr = Printf.sprintf + +let insert thing thinginfo into intoinfo = + let get_last l = let l = List.rev l in (List.rev(List.tl l),List.hd l) in + let get_first l = (List.hd l,List.tl l) in + let thing_start = thinginfo.Ast0.logical_start in + let thing_end = thinginfo.Ast0.logical_end in + let thing_offset = thinginfo.Ast0.offset in + let into_start = intoinfo.Ast0.tline_start in + let into_end = intoinfo.Ast0.tline_end in + let into_left_offset = intoinfo.Ast0.left_offset in + let into_right_offset = intoinfo.Ast0.right_offset in + Printf.printf "thing start %d thing end %d into start %d into end %d\n" + thing_start thing_end into_start into_end; + if thing_end < into_start && thing_start < into_start + then (thing@into, + {{intoinfo with Ast0.tline_start = thing_start} + with Ast0.left_offset = thing_offset}) + else if thing_end = into_start && thing_offset < into_left_offset + then + let (prev,last) = get_last thing in + let (first,rest) = get_first into in + (prev@[last@first]@rest, + {{intoinfo with Ast0.tline_start = thing_start} + with Ast0.left_offset = thing_offset}) + else if thing_start > into_end && thing_end > into_end + then (into@thing, + {{intoinfo with Ast0.tline_end = thing_end} + with Ast0.right_offset = thing_offset}) + else if thing_start = into_end && thing_offset > into_right_offset + then + let (first,rest) = get_first thing in + let (prev,last) = get_last into in + (prev@[last@first]@rest, + {{intoinfo with Ast0.tline_end = thing_end} + with Ast0.right_offset = thing_offset}) + else + begin + Printf.printf "thing start %d thing end %d into start %d into end %d\n" + thing_start thing_end into_start into_end; + Printf.printf "thing offset %d left offset %d right offset %d\n" + thing_offset into_left_offset into_right_offset; + Pretty_print_cocci.print_anything "" thing; + failwith "can't figure out where to put the + code" + end + +let init thing info = + (thing, + {Ast0.tline_start = info.Ast0.logical_start; + Ast0.tline_end = info.Ast0.logical_end; + Ast0.left_offset = info.Ast0.offset; + Ast0.right_offset = info.Ast0.offset}) + +let attachbefore (infop,p) = function + Ast0.MINUS(replacements) -> + (match !replacements with + ([],ti) -> replacements := init p infop + | (repl,ti) -> replacements := insert p infop repl ti) + | Ast0.CONTEXT(neighbors) -> + let (repl,ti1,ti2) = !neighbors in + (match repl with + Ast.BEFORE(bef) -> + let (bef,ti1) = insert p infop bef ti1 in + neighbors := (Ast.BEFORE(bef),ti1,ti2) + | Ast.AFTER(aft) -> + let (bef,ti1) = init p infop in + neighbors := (Ast.BEFOREAFTER(bef,aft),ti1,ti2) + | Ast.BEFOREAFTER(bef,aft) -> + let (bef,ti1) = insert p infop bef ti1 in + neighbors := (Ast.BEFOREAFTER(bef,aft),ti1,ti2) + | Ast.NOTHING -> + let (bef,ti1) = init p infop in + neighbors := (Ast.BEFORE(bef),ti1,ti2)) + | _ -> failwith "not possible for attachbefore" + +let attachafter (infop,p) = function + Ast0.MINUS(replacements) -> + (match !replacements with + ([],ti) -> replacements := init p infop + | (repl,ti) -> replacements := insert p infop repl ti) + | Ast0.CONTEXT(neighbors) -> + let (repl,ti1,ti2) = !neighbors in + (match repl with + Ast.BEFORE(bef) -> + let (aft,ti2) = init p infop in + neighbors := (Ast.BEFOREAFTER(bef,aft),ti1,ti2) + | Ast.AFTER(aft) -> + let (aft,ti2) = insert p infop aft ti2 in + neighbors := (Ast.AFTER(aft),ti1,ti2) + | Ast.BEFOREAFTER(bef,aft) -> + let (aft,ti2) = insert p infop aft ti2 in + neighbors := (Ast.BEFOREAFTER(bef,aft),ti1,ti2) + | Ast.NOTHING -> + let (aft,ti2) = init p infop in + neighbors := (Ast.AFTER(aft),ti1,ti2)) + | _ -> failwith "not possible for attachbefore" + +let attach_all_before ps m = + List.iter (function x -> attachbefore x m) ps + +let attach_all_after ps m = + List.iter (function x -> attachafter x m) ps + +let split_at_end info ps = + let split_point = info.Ast0.logical_end in + List.partition + (function (info,_) -> info.Ast0.logical_end < split_point) + ps + +let allminus = function + Ast0.MINUS(_) -> true + | _ -> false + +let rec before_m1 ((f1,infom1,m1) as x1) ((f2,infom2,m2) as x2) rest = function + [] -> () + | (((infop,_) as p) :: ps) as all -> + if less_than_start infop infom1 or + (allminus m1 && less_than_end infop infom1) (* account for trees *) + then + if good_start infom1 + then (attachbefore p m1; before_m1 x1 x2 rest ps) + else + failwith + (pr "%d: no available token to attach to" infop.Ast0.line_start) + else after_m1 x1 x2 rest all + +and after_m1 ((f1,infom1,m1) as x1) ((f2,infom2,m2) as x2) rest = function + [] -> () + | (((infop,pcode) as p) :: ps) as all -> + (* if the following is false, then some + code is stuck in the middle + of some context code (m1). could drop down to the token level. + this might require adjustments in ast0toast as well, when + code on + expressions is dropped down to + code on expressions. it might + also break some invariants on which iso depends, particularly on + what it can infer from something being CONTEXT with no top-level + modifications. for the moment, we thus give an error, asking the + user to rewrite the semantic patch. *) + if greater_than_end infop infom1 + then + if less_than_start infop infom2 + then + if predecl_code pcode && good_end infom1 && decl f1 + then (attachafter p m1; after_m1 x1 x2 rest ps) + else if predecl_code pcode && good_start infom2 && decl f2 + then before_m2 x2 rest all + else if top_code pcode && good_end infom1 && toplevel f1 + then (attachafter p m1; after_m1 x1 x2 rest ps) + else if top_code pcode && good_start infom2 && toplevel f2 + then before_m2 x2 rest all + else if good_end infom1 && favored f1 + then (attachafter p m1; after_m1 x1 x2 rest ps) + else if good_start infom2 && favored f2 + then before_m2 x2 rest all + else if good_end infom1 + then (attachafter p m1; after_m1 x1 x2 rest ps) + else if good_start infom2 + then before_m2 x2 rest all + else + failwith + (pr "%d: no available token to attach to" infop.Ast0.line_start) + else after_m2 x2 rest all + else + begin + Printf.printf "between: p start %d p end %d m1 start %d m1 end %d m2 start %d m2 end %d\n" + infop.Ast0.line_start infop.Ast0.line_end + infom1.Ast0.line_start infom1.Ast0.line_end + infom2.Ast0.line_start infom2.Ast0.line_end; + Pretty_print_cocci.print_anything "" pcode; + failwith + "The semantic patch is structured in a way that may give bad results with isomorphisms. Please try to rewrite it by moving + code out from -/context terms." + end + +and before_m2 ((f2,infom2,m2) as x2) rest + (p : (Ast0.info * Ast.anything list list) list) = + match (rest,p) with + (_,[]) -> () + | ([],((infop,_)::_)) -> + let (bef_m2,aft_m2) = split_at_end infom2 p in (* bef_m2 isn't empty *) + if good_start infom2 + then (attach_all_before bef_m2 m2; after_m2 x2 rest aft_m2) + else + failwith + (pr "%d: no available token to attach to" infop.Ast0.line_start) + | (m::ms,_) -> before_m1 x2 m ms p + +and after_m2 ((f2,infom2,m2) as x2) rest + (p : (Ast0.info * Ast.anything list list) list) = + match (rest,p) with + (_,[]) -> () + | ([],((infop,_)::_)) -> + if good_end infom2 + then attach_all_after p m2 + else + failwith + (pr "%d: no available token to attach to" infop.Ast0.line_start) + | (m::ms,_) -> after_m1 x2 m ms p + +let merge_one : (minus_join_point * Ast0.info * 'a) list * + (Ast0.info * Ast.anything list list) list -> unit = function (m,p) -> + (* + Printf.printf "minus code\n"; + List.iter + (function (_,info,_) -> + Printf.printf "start %d end %d real_start %d real_end %d\n" + info.Ast0.logical_start info.Ast0.logical_end + info.Ast0.line_start info.Ast0.line_end) + m; + Printf.printf "plus code\n"; + List.iter + (function (info,p) -> + Printf.printf "start %d end %d real_start %d real_end %d\n" + info.Ast0.logical_start info.Ast0.logical_end + info.Ast0.line_end info.Ast0.line_end; + Pretty_print_cocci.print_anything "" p; + Format.print_newline()) + p; + *) + match (m,p) with + (_,[]) -> () + | (m1::m2::restm,p) -> before_m1 m1 m2 restm p + | ([m],p) -> before_m2 m [] p + | ([],_) -> failwith "minus tree ran out before the plus tree" + +let merge minus_list plus_list = + (* + Printf.printf "minus list %s\n" + (String.concat " " + (List.map (function (x,_) -> string_of_int x) minus_list)); + Printf.printf "plus list %s\n" + (String.concat " " + (List.map (function (x,_) -> string_of_int x) plus_list)); + *) + List.iter + (function (index,minus_info) -> + let plus_info = List.assoc index plus_list in + merge_one (minus_info,plus_info)) + minus_list + +(* --------------------------------------------------------------------- *) +(* --------------------------------------------------------------------- *) +(* Need to check that CONTEXT nodes have nothing attached to their tokens. +If they do, they become MIXED *) + +let reevaluate_contextness = + let bind = (@) in + let option_default = [] in + + let mcode (_,_,_,mc,_) = + match mc with + Ast0.CONTEXT(mc) -> let (ba,_,_) = !mc in [ba] + | _ -> [] in + + let donothing r k e = + match Ast0.get_mcodekind e with + Ast0.CONTEXT(mc) -> + if List.exists (function Ast.NOTHING -> false | _ -> true) (k e) + then Ast0.set_mcodekind e (Ast0.MIXED(mc)); + [] + | _ -> let _ = k e in [] 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 donothing + donothing + donothing donothing donothing donothing donothing donothing donothing in + res.V0.combiner_top_level + +(* --------------------------------------------------------------------- *) +(* --------------------------------------------------------------------- *) + +let insert_plus minus plus = + let minus_stream = process_minus minus in + let plus_stream = process_plus plus in + merge minus_stream plus_stream; + List.iter (function x -> let _ = reevaluate_contextness x in ()) minus diff --git a/parsing_cocci/.#insert_plus.ml.1.69 b/parsing_cocci/.#insert_plus.ml.1.69 new file mode 100644 index 0000000..7609cf8 --- /dev/null +++ b/parsing_cocci/.#insert_plus.ml.1.69 @@ -0,0 +1,946 @@ +(* +* 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. +*) + + +(* The error message "no available token to attach to" often comes in an +argument list of unbounded length. In this case, one should move a comma so +that there is a comma after the + code. *) + +(* Start at all of the corresponding BindContext nodes in the minus and +plus trees, and traverse their children. We take the same strategy as +before: collect the list of minus/context nodes/tokens and the list of plus +tokens, and then merge them. *) + +module Ast = Ast_cocci +module Ast0 = Ast0_cocci +module V0 = Visitor_ast0 +module CN = Context_neg + +let get_option f = function + None -> [] + | Some x -> f x + +(* --------------------------------------------------------------------- *) +(* Collect root and all context nodes in a tree *) + +let collect_context e = + let bind x y = x @ y in + let option_default = [] in + + let mcode _ = [] in + + let donothing builder r k e = + match Ast0.get_mcodekind e with + Ast0.CONTEXT(_) -> (builder e) :: (k e) + | _ -> k e in + +(* special case for everything that contains whencode, so that we skip over +it *) + let expression r k e = + donothing Ast0.expr r k + (Ast0.rewrap e + (match Ast0.unwrap e with + Ast0.NestExpr(starter,exp,ender,whencode,multi) -> + Ast0.NestExpr(starter,exp,ender,None,multi) + | Ast0.Edots(dots,whencode) -> Ast0.Edots(dots,None) + | Ast0.Ecircles(dots,whencode) -> Ast0.Ecircles(dots,None) + | Ast0.Estars(dots,whencode) -> Ast0.Estars(dots,None) + | e -> e)) in + + let initialiser r k i = + donothing Ast0.ini r k + (Ast0.rewrap i + (match Ast0.unwrap i with + Ast0.Idots(dots,whencode) -> Ast0.Idots(dots,None) + | i -> i)) in + + let statement r k s = + donothing Ast0.stmt r k + (Ast0.rewrap s + (match Ast0.unwrap s with + Ast0.Nest(started,stm_dots,ender,whencode,multi) -> + Ast0.Nest(started,stm_dots,ender,[],multi) + | Ast0.Dots(dots,whencode) -> Ast0.Dots(dots,[]) + | Ast0.Circles(dots,whencode) -> Ast0.Circles(dots,[]) + | Ast0.Stars(dots,whencode) -> Ast0.Stars(dots,[]) + | s -> s)) in + + let topfn r k e = Ast0.TopTag(e) :: (k e) in + + let res = + V0.combiner bind option_default + mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode + mcode + (donothing Ast0.dotsExpr) (donothing Ast0.dotsInit) + (donothing Ast0.dotsParam) (donothing Ast0.dotsStmt) + (donothing Ast0.dotsDecl) (donothing Ast0.dotsCase) + (donothing Ast0.ident) expression (donothing Ast0.typeC) initialiser + (donothing Ast0.param) (donothing Ast0.decl) statement + (donothing Ast0.case_line) topfn in + res.V0.combiner_top_level e + +(* --------------------------------------------------------------------- *) +(* --------------------------------------------------------------------- *) +(* collect the possible join points, in order, among the children of a +BindContext. Dots are not allowed. Nests and disjunctions are no problem, +because their delimiters take up a line by themselves *) + +(* An Unfavored token is one that is in a BindContext node; using this causes + the node to become Neither, meaning that isomorphisms can't be applied *) +(* Toplevel is for the bef token of a function declaration and is for +attaching top-level definitions that should come before the complete +declaration *) +type minus_join_point = Favored | Unfavored | Toplevel | Decl + +(* Maps the index of a node to the indices of the mcodes it contains *) +let root_token_table = (Hashtbl.create(50) : (int, int list) Hashtbl.t) + +let create_root_token_table minus = + Hashtbl.iter + (function tokens -> + function (node,_) -> + let key = + match node with + Ast0.DotsExprTag(d) -> Ast0.get_index d + | Ast0.DotsInitTag(d) -> Ast0.get_index d + | Ast0.DotsParamTag(d) -> Ast0.get_index d + | Ast0.DotsStmtTag(d) -> Ast0.get_index d + | Ast0.DotsDeclTag(d) -> Ast0.get_index d + | Ast0.DotsCaseTag(d) -> Ast0.get_index d + | Ast0.IdentTag(d) -> Ast0.get_index d + | Ast0.ExprTag(d) -> Ast0.get_index d + | Ast0.ArgExprTag(d) | Ast0.TestExprTag(d) -> + failwith "not possible - iso only" + | Ast0.TypeCTag(d) -> Ast0.get_index d + | Ast0.ParamTag(d) -> Ast0.get_index d + | Ast0.InitTag(d) -> Ast0.get_index d + | Ast0.DeclTag(d) -> Ast0.get_index d + | Ast0.StmtTag(d) -> Ast0.get_index d + | Ast0.CaseLineTag(d) -> Ast0.get_index d + | Ast0.TopTag(d) -> Ast0.get_index 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" + in + Hashtbl.add root_token_table key tokens) + CN.minus_table; + List.iter + (function r -> + let index = Ast0.get_index r in + try let _ = Hashtbl.find root_token_table index in () + with Not_found -> Hashtbl.add root_token_table index []) + minus + +let collect_minus_join_points root = + let root_index = Ast0.get_index root in + let unfavored_tokens = Hashtbl.find root_token_table root_index in + let bind x y = x @ y in + let option_default = [] in + + let mcode (_,_,info,mcodekind,_) = + if List.mem (info.Ast0.offset) unfavored_tokens + then [(Unfavored,info,mcodekind)] + else [(Favored,info,mcodekind)] in + + let do_nothing r k e = + let info = Ast0.get_info e in + let index = Ast0.get_index e in + match Ast0.get_mcodekind e with + (Ast0.MINUS(_)) as mc -> [(Favored,info,mc)] + | (Ast0.CONTEXT(_)) as mc when not(index = root_index) -> + (* This was unfavored at one point, but I don't remember why *) + [(Favored,info,mc)] + | _ -> k e in + +(* don't want to attach to the outside of DOTS, because metavariables can't +bind to that; not good for isomorphisms *) + + let dots f k d = + let multibind l = + let rec loop = function + [] -> option_default + | [x] -> x + | x::xs -> bind x (loop xs) in + loop l in + + match Ast0.unwrap d with + Ast0.DOTS(l) -> multibind (List.map f l) + | Ast0.CIRCLES(l) -> multibind (List.map f l) + | Ast0.STARS(l) -> multibind (List.map f l) in + + let edots r k d = dots r.V0.combiner_expression k d in + let idots r k d = dots r.V0.combiner_initialiser k d in + let pdots r k d = dots r.V0.combiner_parameter k d in + let sdots r k d = dots r.V0.combiner_statement k d in + let ddots r k d = dots r.V0.combiner_declaration k d in + let cdots r k d = dots r.V0.combiner_case_line k d in + + (* a case for everything that has a Opt *) + + let statement r k s = + (* + let redo_branched res (ifinfo,aftmc) = + let redo fv info mc rest = + let new_info = {info with Ast0.attachable_end = false} in + List.rev ((Favored,ifinfo,aftmc)::(fv,new_info,mc)::rest) in + match List.rev res with + [(fv,info,mc)] -> + (match mc with + Ast0.MINUS(_) | Ast0.CONTEXT(_) -> + (* even for -, better for isos not to integrate code after an + if into the if body. + but the problem is that this can extend the region in + which a variable is bound, because a variable bound in the + aft node would seem to have to be live in the whole if, + whereas we might like it to be live in only one branch. + ie ideally, if we can keep the minus code in the right + order, we would like to drop it as close to the bindings + of its free variables. This could be anywhere in the minus + code. Perhaps we would like to do this after the + application of isomorphisms, though. + *) + redo fv info mc [] + | _ -> res) + | (fv,info,mc)::rest -> + (match mc with + Ast0.CONTEXT(_) -> redo fv info mc rest + | _ -> res) + | _ -> failwith "unexpected empty code" in *) + match Ast0.unwrap s with + (* Ast0.IfThen(_,_,_,_,_,aft) + | Ast0.IfThenElse(_,_,_,_,_,_,_,aft) + | Ast0.While(_,_,_,_,_,aft) + | Ast0.For(_,_,_,_,_,_,_,_,_,aft) + | Ast0.Iterator(_,_,_,_,_,aft) -> + redo_branched (do_nothing r k s) aft*) + | Ast0.FunDecl((info,bef),fninfo,name,lp,params,rp,lbrace,body,rbrace) -> + (Toplevel,info,bef)::(k s) + | Ast0.Decl((info,bef),decl) -> (Decl,info,bef)::(k s) + | Ast0.Nest(starter,stmt_dots,ender,whencode,multi) -> + mcode starter @ r.V0.combiner_statement_dots stmt_dots @ mcode ender + | Ast0.Dots(d,whencode) | Ast0.Circles(d,whencode) + | Ast0.Stars(d,whencode) -> mcode d (* ignore whencode *) + | Ast0.OptStm s | Ast0.UniqueStm s -> + (* put the + code on the thing, not on the opt *) + r.V0.combiner_statement s + | _ -> do_nothing r k s in + + let expression r k e = + match Ast0.unwrap e with + Ast0.NestExpr(starter,expr_dots,ender,whencode,multi) -> + mcode starter @ + r.V0.combiner_expression_dots expr_dots @ mcode ender + | Ast0.Edots(d,whencode) | Ast0.Ecircles(d,whencode) + | Ast0.Estars(d,whencode) -> mcode d (* ignore whencode *) + | Ast0.OptExp e | Ast0.UniqueExp e -> + (* put the + code on the thing, not on the opt *) + r.V0.combiner_expression e + | _ -> do_nothing r k e in + + let ident r k e = + match Ast0.unwrap e with + Ast0.OptIdent i | Ast0.UniqueIdent i -> + (* put the + code on the thing, not on the opt *) + r.V0.combiner_ident i + | _ -> do_nothing r k e in + + let typeC r k e = + match Ast0.unwrap e with + Ast0.OptType t | Ast0.UniqueType t -> + (* put the + code on the thing, not on the opt *) + r.V0.combiner_typeC t + | _ -> do_nothing r k e in + + let decl r k e = + match Ast0.unwrap e with + Ast0.OptDecl d | Ast0.UniqueDecl d -> + (* put the + code on the thing, not on the opt *) + r.V0.combiner_declaration d + | _ -> do_nothing r k e in + + let initialiser r k e = + match Ast0.unwrap e with + Ast0.Idots(d,whencode) -> mcode d (* ignore whencode *) + | Ast0.OptIni i | Ast0.UniqueIni i -> + (* put the + code on the thing, not on the opt *) + r.V0.combiner_initialiser i + | _ -> do_nothing r k e in + + let param r k e = + match Ast0.unwrap e with + Ast0.OptParam p | Ast0.UniqueParam p -> + (* put the + code on the thing, not on the opt *) + r.V0.combiner_parameter p + | _ -> do_nothing r k e in + + let case_line r k e = + match Ast0.unwrap e with + Ast0.OptCase c -> + (* put the + code on the thing, not on the opt *) + r.V0.combiner_case_line c + | _ -> do_nothing r k e in + + let do_top r k (e: Ast0.top_level) = k e in + + V0.combiner bind option_default + mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode + mcode + edots idots pdots sdots ddots cdots + ident expression typeC initialiser param decl statement case_line do_top + + +let call_collect_minus context_nodes : + (int * (minus_join_point * Ast0.info * Ast0.mcodekind) list) list = + List.map + (function e -> + match e with + Ast0.DotsExprTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_expression_dots e) + | Ast0.DotsInitTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_initialiser_list e) + | Ast0.DotsParamTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_parameter_list e) + | Ast0.DotsStmtTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_statement_dots e) + | Ast0.DotsDeclTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_declaration_dots e) + | Ast0.DotsCaseTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_case_line_dots e) + | Ast0.IdentTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_ident e) + | Ast0.ExprTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_expression e) + | Ast0.ArgExprTag(e) | Ast0.TestExprTag(e) -> + failwith "not possible - iso only" + | Ast0.TypeCTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_typeC e) + | Ast0.ParamTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_parameter e) + | Ast0.InitTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_initialiser e) + | Ast0.DeclTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_declaration e) + | Ast0.StmtTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_statement e) + | Ast0.CaseLineTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_case_line e) + | Ast0.TopTag(e) -> + (Ast0.get_index e, + (collect_minus_join_points e).V0.combiner_top_level e) + | 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") + context_nodes + +(* result of collecting the join points should be sorted in nondecreasing + order by line *) +let verify l = + let get_info = function + (Favored,info,_) | (Unfavored,info,_) | (Toplevel,info,_) + | (Decl,info,_) -> info in + let token_start_line x = (get_info x).Ast0.logical_start in + let token_end_line x = (get_info x).Ast0.logical_end in + let token_real_start_line x = (get_info x).Ast0.line_start in + let token_real_end_line x = (get_info x).Ast0.line_end in + List.iter + (function + (index,((_::_) as l1)) -> + let _ = + List.fold_left + (function (prev,real_prev) -> + function cur -> + let ln = token_start_line cur in + if ln < prev + then + failwith + (Printf.sprintf + "error in collection of - tokens %d less than %d" + (token_real_start_line cur) real_prev); + (token_end_line cur,token_real_end_line cur)) + (token_end_line (List.hd l1), token_real_end_line (List.hd l1)) + (List.tl l1) in + () + | _ -> ()) (* dots, in eg f() has no join points *) + l + +let process_minus minus = + create_root_token_table minus; + List.concat + (List.map + (function x -> + let res = call_collect_minus (collect_context x) in + verify res; + res) + minus) + +(* --------------------------------------------------------------------- *) +(* --------------------------------------------------------------------- *) +(* collect the plus tokens *) + +let mk_baseType x = Ast.BaseTypeTag x +let mk_structUnion x = Ast.StructUnionTag x +let mk_sign x = Ast.SignTag x +let mk_ident x = Ast.IdentTag (Ast0toast.ident x) +let mk_expression x = Ast.ExpressionTag (Ast0toast.expression x) +let mk_constant x = Ast.ConstantTag x +let mk_unaryOp x = Ast.UnaryOpTag x +let mk_assignOp x = Ast.AssignOpTag x +let mk_fixOp x = Ast.FixOpTag x +let mk_binaryOp x = Ast.BinaryOpTag x +let mk_arithOp x = Ast.ArithOpTag x +let mk_logicalOp x = Ast.LogicalOpTag x +let mk_declaration x = Ast.DeclarationTag (Ast0toast.declaration x) +let mk_topdeclaration x = Ast.DeclarationTag (Ast0toast.declaration x) +let mk_storage x = Ast.StorageTag x +let mk_inc_file x = Ast.IncFileTag x +let mk_statement x = Ast.StatementTag (Ast0toast.statement x) +let mk_case_line x = Ast.CaseLineTag (Ast0toast.case_line x) +let mk_const_vol x = Ast.ConstVolTag x +let mk_token x info = Ast.Token (x,Some info) +let mk_meta (_,x) info = Ast.Token (x,Some info) +let mk_code x = Ast.Code (Ast0toast.top_level x) + +let mk_exprdots x = Ast.ExprDotsTag (Ast0toast.expression_dots x) +let mk_paramdots x = Ast.ParamDotsTag (Ast0toast.parameter_list x) +let mk_stmtdots x = Ast.StmtDotsTag (Ast0toast.statement_dots x) +let mk_decldots x = Ast.DeclDotsTag (Ast0toast.declaration_dots x) +let mk_casedots x = failwith "+ case lines not supported" +let mk_typeC x = Ast.FullTypeTag (Ast0toast.typeC x) +let mk_init x = Ast.InitTag (Ast0toast.initialiser x) +let mk_param x = Ast.ParamTag (Ast0toast.parameterTypeDef x) + +let collect_plus_nodes root = + let root_index = Ast0.get_index root in + + let bind x y = x @ y in + let option_default = [] in + + let mcode fn (term,_,info,mcodekind,_) = + match mcodekind with Ast0.PLUS -> [(info,fn term)] | _ -> [] in + + let imcode fn (term,_,info,mcodekind,_) = + match mcodekind with + Ast0.PLUS -> [(info,fn term (Ast0toast.convert_info info))] + | _ -> [] in + + let do_nothing fn r k e = + match Ast0.get_mcodekind e with + (Ast0.CONTEXT(_)) when not(Ast0.get_index e = root_index) -> [] + | Ast0.PLUS -> [(Ast0.get_info e,fn e)] + | _ -> k e in + + (* case for everything that is just a wrapper for a simpler thing *) + let stmt r k e = + match Ast0.unwrap e with + Ast0.Exp(exp) -> r.V0.combiner_expression exp + | Ast0.TopExp(exp) -> r.V0.combiner_expression exp + | Ast0.Ty(ty) -> r.V0.combiner_typeC ty + | Ast0.Decl(_,decl) -> r.V0.combiner_declaration decl + | _ -> do_nothing mk_statement r k e in + + (* statementTag is preferred, because it indicates that one statement is + replaced by one statement, in single_statement *) + let stmt_dots r k e = + match Ast0.unwrap e with + Ast0.DOTS([s]) | Ast0.CIRCLES([s]) | Ast0.STARS([s]) -> + r.V0.combiner_statement s + | _ -> do_nothing mk_stmtdots r k e in + + let toplevel r k e = + match Ast0.unwrap e with + Ast0.DECL(s) -> r.V0.combiner_statement s + | Ast0.CODE(sdots) -> r.V0.combiner_statement_dots sdots + | _ -> do_nothing mk_code r k e in + + let initdots r k e = k e in + + V0.combiner bind option_default + (imcode mk_meta) (imcode mk_token) (mcode mk_constant) (mcode mk_assignOp) + (mcode mk_fixOp) + (mcode mk_unaryOp) (mcode mk_binaryOp) (mcode mk_const_vol) + (mcode mk_baseType) (mcode mk_sign) (mcode mk_structUnion) + (mcode mk_storage) (mcode mk_inc_file) + (do_nothing mk_exprdots) initdots + (do_nothing mk_paramdots) stmt_dots (do_nothing mk_decldots) + (do_nothing mk_casedots) + (do_nothing mk_ident) (do_nothing mk_expression) + (do_nothing mk_typeC) (do_nothing mk_init) (do_nothing mk_param) + (do_nothing mk_declaration) + stmt (do_nothing mk_case_line) toplevel + +let call_collect_plus context_nodes : + (int * (Ast0.info * Ast.anything) list) list = + List.map + (function e -> + match e with + Ast0.DotsExprTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_expression_dots e) + | Ast0.DotsInitTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_initialiser_list e) + | Ast0.DotsParamTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_parameter_list e) + | Ast0.DotsStmtTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_statement_dots e) + | Ast0.DotsDeclTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_declaration_dots e) + | Ast0.DotsCaseTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_case_line_dots e) + | Ast0.IdentTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_ident e) + | Ast0.ExprTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_expression e) + | Ast0.ArgExprTag(_) | Ast0.TestExprTag(_) -> + failwith "not possible - iso only" + | Ast0.TypeCTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_typeC e) + | Ast0.InitTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_initialiser e) + | Ast0.ParamTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_parameter e) + | Ast0.DeclTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_declaration e) + | Ast0.StmtTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_statement e) + | Ast0.CaseLineTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_case_line e) + | Ast0.TopTag(e) -> + (Ast0.get_index e, + (collect_plus_nodes e).V0.combiner_top_level e) + | 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") + context_nodes + +(* The plus fragments are converted to a list of lists of lists. +Innermost list: Elements have type anything. For any pair of successive +elements, n and n+1, the ending line of n is the same as the starting line +of n+1. +Middle lists: For any pair of successive elements, n and n+1, the ending +line of n is one less than the starting line of n+1. +Outer list: For any pair of successive elements, n and n+1, the ending +line of n is more than one less than the starting line of n+1. *) + +let logstart info = info.Ast0.logical_start +let logend info = info.Ast0.logical_end + +let redo info start finish = + {{info with Ast0.logical_start = start} with Ast0.logical_end = finish} + +let rec find_neighbors (index,l) : + int * (Ast0.info * (Ast.anything list list)) list = + let rec loop = function + [] -> [] + | (i,x)::rest -> + (match loop rest with + ((i1,(x1::rest_inner))::rest_middle)::rest_outer -> + let finish1 = logend i in + let start2 = logstart i1 in + if finish1 = start2 + then + ((redo i (logstart i) (logend i1),(x::x1::rest_inner)) + ::rest_middle) + ::rest_outer + else if finish1 + 1 = start2 + then ((i,[x])::(i1,(x1::rest_inner))::rest_middle)::rest_outer + else [(i,[x])]::((i1,(x1::rest_inner))::rest_middle)::rest_outer + | _ -> [[(i,[x])]]) (* rest must be [] *) in + let res = + List.map + (function l -> + let (start_info,_) = List.hd l in + let (end_info,_) = List.hd (List.rev l) in + (redo start_info (logstart start_info) (logend end_info), + List.map (function (_,x) -> x) l)) + (loop l) in + (index,res) + +let process_plus plus : + (int * (Ast0.info * Ast.anything list list) list) list = + List.concat + (List.map + (function x -> + List.map find_neighbors (call_collect_plus (collect_context x))) + plus) + +(* --------------------------------------------------------------------- *) +(* --------------------------------------------------------------------- *) +(* merge *) +(* +let merge_one = function + (m1::m2::minus_info,p::plus_info) -> + if p < m1, then + attach p to the beginning of m1.bef if m1 is Good, fail if it is bad + if p > m1 && p < m2, then consider the following possibilities, in order + m1 is Good and favored: attach to the beginning of m1.aft + m2 is Good and favored: attach to the beginning of m2.bef; drop m1 + m1 is Good and unfavored: attach to the beginning of m1.aft + m2 is Good and unfavored: attach to the beginning of m2.bef; drop m1 + also flip m1.bef if the first where > m1 + if we drop m1, then flip m1.aft first + if p > m2 + m2 is Good and favored: attach to the beginning of m2.aft; drop m1 +*) + +(* end of first argument < start/end of second argument *) +let less_than_start info1 info2 = + info1.Ast0.logical_end < info2.Ast0.logical_start +let less_than_end info1 info2 = + info1.Ast0.logical_end < info2.Ast0.logical_end +let greater_than_end info1 info2 = + info1.Ast0.logical_start > info2.Ast0.logical_end +let good_start info = info.Ast0.attachable_start +let good_end info = info.Ast0.attachable_end + +let toplevel = function Toplevel -> true | Favored | Unfavored | Decl -> false +let decl = function Decl -> true | Favored | Unfavored | Toplevel -> false +let favored = function Favored -> true | Unfavored | Toplevel | Decl -> false + +let top_code = + List.for_all (List.for_all (function Ast.Code _ -> true | _ -> false)) + +(* The following is probably not correct. The idea is to detect what +should be placed completely before the declaration. So type/storage +related things do not fall into this category, and complete statements do +fall into this category. But perhaps other things should be in this +category as well, such as { or ;? *) +let predecl_code = + let tester = function + (* the following should definitely be true *) + Ast.DeclarationTag _ + | Ast.StatementTag _ + | Ast.Rule_elemTag _ + | Ast.StmtDotsTag _ + | Ast.Code _ -> true + (* the following should definitely be false *) + | Ast.FullTypeTag _ | Ast.BaseTypeTag _ | Ast.StructUnionTag _ + | Ast.SignTag _ + | Ast.StorageTag _ | Ast.ConstVolTag _ | Ast.TypeCTag _ -> false + (* not sure about the rest *) + | _ -> false in + List.for_all (List.for_all tester) + +let pr = Printf.sprintf + +let insert thing thinginfo into intoinfo = + let get_last l = let l = List.rev l in (List.rev(List.tl l),List.hd l) in + let get_first l = (List.hd l,List.tl l) in + let thing_start = thinginfo.Ast0.logical_start in + let thing_end = thinginfo.Ast0.logical_end in + let thing_offset = thinginfo.Ast0.offset in + let into_start = intoinfo.Ast0.tline_start in + let into_end = intoinfo.Ast0.tline_end in + let into_left_offset = intoinfo.Ast0.left_offset in + let into_right_offset = intoinfo.Ast0.right_offset in + if thing_end < into_start && thing_start < into_start + then (thing@into, + {{intoinfo with Ast0.tline_start = thing_start} + with Ast0.left_offset = thing_offset}) + else if thing_end = into_start && thing_offset < into_left_offset + then + let (prev,last) = get_last thing in + let (first,rest) = get_first into in + (prev@[last@first]@rest, + {{intoinfo with Ast0.tline_start = thing_start} + with Ast0.left_offset = thing_offset}) + else if thing_start > into_end && thing_end > into_end + then (into@thing, + {{intoinfo with Ast0.tline_end = thing_end} + with Ast0.right_offset = thing_offset}) + else if thing_start = into_end && thing_offset > into_right_offset + then + let (first,rest) = get_first thing in + let (prev,last) = get_last into in + (prev@[last@first]@rest, + {{intoinfo with Ast0.tline_end = thing_end} + with Ast0.right_offset = thing_offset}) + else + begin + Printf.printf "thing start %d thing end %d into start %d into end %d\n" + thing_start thing_end into_start into_end; + Printf.printf "thing offset %d left offset %d right offset %d\n" + thing_offset into_left_offset into_right_offset; + Pretty_print_cocci.print_anything "" thing; + Pretty_print_cocci.print_anything "" into; + failwith "can't figure out where to put the + code" + end + +let init thing info = + (thing, + {Ast0.tline_start = info.Ast0.logical_start; + Ast0.tline_end = info.Ast0.logical_end; + Ast0.left_offset = info.Ast0.offset; + Ast0.right_offset = info.Ast0.offset}) + +let attachbefore (infop,p) = function + Ast0.MINUS(replacements) -> + (match !replacements with + ([],ti) -> replacements := init p infop + | (repl,ti) -> replacements := insert p infop repl ti) + | Ast0.CONTEXT(neighbors) -> + let (repl,ti1,ti2) = !neighbors in + (match repl with + Ast.BEFORE(bef) -> + let (bef,ti1) = insert p infop bef ti1 in + neighbors := (Ast.BEFORE(bef),ti1,ti2) + | Ast.AFTER(aft) -> + let (bef,ti1) = init p infop in + neighbors := (Ast.BEFOREAFTER(bef,aft),ti1,ti2) + | Ast.BEFOREAFTER(bef,aft) -> + let (bef,ti1) = insert p infop bef ti1 in + neighbors := (Ast.BEFOREAFTER(bef,aft),ti1,ti2) + | Ast.NOTHING -> + let (bef,ti1) = init p infop in + neighbors := (Ast.BEFORE(bef),ti1,ti2)) + | _ -> failwith "not possible for attachbefore" + +let attachafter (infop,p) = function + Ast0.MINUS(replacements) -> + (match !replacements with + ([],ti) -> replacements := init p infop + | (repl,ti) -> replacements := insert p infop repl ti) + | Ast0.CONTEXT(neighbors) -> + let (repl,ti1,ti2) = !neighbors in + (match repl with + Ast.BEFORE(bef) -> + let (aft,ti2) = init p infop in + neighbors := (Ast.BEFOREAFTER(bef,aft),ti1,ti2) + | Ast.AFTER(aft) -> + let (aft,ti2) = insert p infop aft ti2 in + neighbors := (Ast.AFTER(aft),ti1,ti2) + | Ast.BEFOREAFTER(bef,aft) -> + let (aft,ti2) = insert p infop aft ti2 in + neighbors := (Ast.BEFOREAFTER(bef,aft),ti1,ti2) + | Ast.NOTHING -> + let (aft,ti2) = init p infop in + neighbors := (Ast.AFTER(aft),ti1,ti2)) + | _ -> failwith "not possible for attachbefore" + +let attach_all_before ps m = + List.iter (function x -> attachbefore x m) ps + +let attach_all_after ps m = + List.iter (function x -> attachafter x m) ps + +let split_at_end info ps = + let split_point = info.Ast0.logical_end in + List.partition + (function (info,_) -> info.Ast0.logical_end < split_point) + ps + +let allminus = function + Ast0.MINUS(_) -> true + | _ -> false + +let rec before_m1 ((f1,infom1,m1) as x1) ((f2,infom2,m2) as x2) rest = function + [] -> () + | (((infop,_) as p) :: ps) as all -> + if less_than_start infop infom1 or + (allminus m1 && less_than_end infop infom1) (* account for trees *) + then + if good_start infom1 + then (attachbefore p m1; before_m1 x1 x2 rest ps) + else + failwith + (pr "%d: no available token to attach to" infop.Ast0.line_start) + else after_m1 x1 x2 rest all + +and after_m1 ((f1,infom1,m1) as x1) ((f2,infom2,m2) as x2) rest = function + [] -> () + | (((infop,pcode) as p) :: ps) as all -> + (* if the following is false, then some + code is stuck in the middle + of some context code (m1). could drop down to the token level. + this might require adjustments in ast0toast as well, when + code on + expressions is dropped down to + code on expressions. it might + also break some invariants on which iso depends, particularly on + what it can infer from something being CONTEXT with no top-level + modifications. for the moment, we thus give an error, asking the + user to rewrite the semantic patch. *) + if greater_than_end infop infom1 + then + if less_than_start infop infom2 + then + if predecl_code pcode && good_end infom1 && decl f1 + then (attachafter p m1; after_m1 x1 x2 rest ps) + else if predecl_code pcode && good_start infom2 && decl f2 + then before_m2 x2 rest all + else if top_code pcode && good_end infom1 && toplevel f1 + then (attachafter p m1; after_m1 x1 x2 rest ps) + else if top_code pcode && good_start infom2 && toplevel f2 + then before_m2 x2 rest all + else if good_end infom1 && favored f1 + then (attachafter p m1; after_m1 x1 x2 rest ps) + else if good_start infom2 && favored f2 + then before_m2 x2 rest all + else if good_end infom1 + then (attachafter p m1; after_m1 x1 x2 rest ps) + else if good_start infom2 + then before_m2 x2 rest all + else + failwith + (pr "%d: no available token to attach to" infop.Ast0.line_start) + else after_m2 x2 rest all + else + begin + Printf.printf "between: p start %d p end %d m1 start %d m1 end %d m2 start %d m2 end %d\n" + infop.Ast0.line_start infop.Ast0.line_end + infom1.Ast0.line_start infom1.Ast0.line_end + infom2.Ast0.line_start infom2.Ast0.line_end; + Pretty_print_cocci.print_anything "" pcode; + failwith + "The semantic patch is structured in a way that may give bad results with isomorphisms. Please try to rewrite it by moving + code out from -/context terms." + end + +and before_m2 ((f2,infom2,m2) as x2) rest + (p : (Ast0.info * Ast.anything list list) list) = + match (rest,p) with + (_,[]) -> () + | ([],((infop,_)::_)) -> + let (bef_m2,aft_m2) = split_at_end infom2 p in (* bef_m2 isn't empty *) + if good_start infom2 + then (attach_all_before bef_m2 m2; after_m2 x2 rest aft_m2) + else + failwith + (pr "%d: no available token to attach to" infop.Ast0.line_start) + | (m::ms,_) -> before_m1 x2 m ms p + +and after_m2 ((f2,infom2,m2) as x2) rest + (p : (Ast0.info * Ast.anything list list) list) = + match (rest,p) with + (_,[]) -> () + | ([],((infop,_)::_)) -> + if good_end infom2 + then attach_all_after p m2 + else + failwith + (pr "%d: no available token to attach to" infop.Ast0.line_start) + | (m::ms,_) -> after_m1 x2 m ms p + +let merge_one : (minus_join_point * Ast0.info * 'a) list * + (Ast0.info * Ast.anything list list) list -> unit = function (m,p) -> + (* + Printf.printf "minus code\n"; + List.iter + (function (_,info,_) -> + Printf.printf "start %d end %d real_start %d real_end %d\n" + info.Ast0.logical_start info.Ast0.logical_end + info.Ast0.line_start info.Ast0.line_end) + m; + Printf.printf "plus code\n"; + List.iter + (function (info,p) -> + Printf.printf "start %d end %d real_start %d real_end %d\n" + info.Ast0.logical_start info.Ast0.logical_end + info.Ast0.line_end info.Ast0.line_end; + Pretty_print_cocci.print_anything "" p; + Format.print_newline()) + p; + *) + match (m,p) with + (_,[]) -> () + | (m1::m2::restm,p) -> before_m1 m1 m2 restm p + | ([m],p) -> before_m2 m [] p + | ([],_) -> failwith "minus tree ran out before the plus tree" + +let merge minus_list plus_list = + (* + Printf.printf "minus list %s\n" + (String.concat " " + (List.map (function (x,_) -> string_of_int x) minus_list)); + Printf.printf "plus list %s\n" + (String.concat " " + (List.map (function (x,_) -> string_of_int x) plus_list)); + *) + List.iter + (function (index,minus_info) -> + let plus_info = List.assoc index plus_list in + merge_one (minus_info,plus_info)) + minus_list + +(* --------------------------------------------------------------------- *) +(* --------------------------------------------------------------------- *) +(* Need to check that CONTEXT nodes have nothing attached to their tokens. +If they do, they become MIXED *) + +let reevaluate_contextness = + let bind = (@) in + let option_default = [] in + + let mcode (_,_,_,mc,_) = + match mc with + Ast0.CONTEXT(mc) -> let (ba,_,_) = !mc in [ba] + | _ -> [] in + + let donothing r k e = + match Ast0.get_mcodekind e with + Ast0.CONTEXT(mc) -> + if List.exists (function Ast.NOTHING -> false | _ -> true) (k e) + then Ast0.set_mcodekind e (Ast0.MIXED(mc)); + [] + | _ -> let _ = k e in [] 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 donothing + donothing + donothing donothing donothing donothing donothing donothing donothing in + res.V0.combiner_top_level + +(* --------------------------------------------------------------------- *) +(* --------------------------------------------------------------------- *) + +let insert_plus minus plus = + let minus_stream = process_minus minus in + let plus_stream = process_plus plus in + merge minus_stream plus_stream; + List.iter (function x -> let _ = reevaluate_contextness x in ()) minus diff --git a/parsing_cocci/.#iso_pattern.ml.1.136 b/parsing_cocci/.#iso_pattern.ml.1.136 new file mode 100644 index 0000000..6bbf1a7 --- /dev/null +++ b/parsing_cocci/.#iso_pattern.ml.1.136 @@ -0,0 +1,2306 @@ +(* +* 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.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.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.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 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 + (function (_,v) -> + match v with + Ast0.DotsStmtTag(stms) -> Ast0.WhenNot stms + | Ast0.StmtTag(stm) -> Ast0.WhenAlways stm + | Ast0.IsoWhenTag(x) -> Ast0.WhenModifier(x) + | _ -> failwith "unexpected binding") + (List.filter (function (x,v) -> x = (dot_term d)) bindings))) + | Ast0.Circles(d,_) -> + Ast0.rewrap e + (Ast0.Circles + (d, + List.map + (function (_,v) -> + match v with + Ast0.DotsStmtTag(stms) -> Ast0.WhenNot stms + | Ast0.StmtTag(stm) -> Ast0.WhenAlways stm + | Ast0.IsoWhenTag(x) -> Ast0.WhenModifier(x) + | _ -> failwith "unexpected binding") + (List.filter (function (x,v) -> x = (dot_term d)) bindings))) + | Ast0.Stars(d,_) -> + Ast0.rewrap e + (Ast0.Stars + (d, + List.map + (function (_,v) -> + match v with + Ast0.DotsStmtTag(stms) -> Ast0.WhenNot stms + | Ast0.StmtTag(stm) -> Ast0.WhenAlways stm + | Ast0.IsoWhenTag(x) -> Ast0.WhenModifier(x) + | _ -> failwith "unexpected binding") + (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(_) -> 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/.#iso_pattern.ml.1.137 b/parsing_cocci/.#iso_pattern.ml.1.137 new file mode 100644 index 0000000..e8abab4 --- /dev/null +++ b/parsing_cocci/.#iso_pattern.ml.1.137 @@ -0,0 +1,2310 @@ +(* +* 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.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/.#lexer_cocci.mll.1.80 b/parsing_cocci/.#lexer_cocci.mll.1.80 new file mode 100644 index 0000000..c066d1d --- /dev/null +++ b/parsing_cocci/.#lexer_cocci.mll.1.80 @@ -0,0 +1,700 @@ +(* +* 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 Parser_cocci_menhir +module D = Data +module Ast = Ast_cocci +module Ast0 = Ast0_cocci +module P = Parse_aux +exception Lexical of string +let tok = Lexing.lexeme + +let line = ref 1 +let logical_line = ref 0 + +(* ---------------------------------------------------------------------- *) +(* control codes *) + +(* Defined in data.ml +type line_type = MINUS | OPTMINUS | UNIQUEMINUS | PLUS | CONTEXT | UNIQUE | OPT +*) + +let current_line_type = ref (D.CONTEXT,!line,!logical_line) + +let prev_plus = ref false +let line_start = ref 0 (* offset of the beginning of the line *) +let get_current_line_type lexbuf = + let (c,l,ll) = !current_line_type in + let lex_start = Lexing.lexeme_start lexbuf in + let preceeding_spaces = + if !line_start < 0 then 0 else lex_start - !line_start in + line_start := -1; + prev_plus := (c = D.PLUS); + (c,l,ll,lex_start,preceeding_spaces,[],[],Ast0.NoMetaPos) +let current_line_started = ref false +let col_zero = ref true + +let reset_line lexbuf = + line := !line + 1; + current_line_type := (D.CONTEXT,!line,!logical_line); + current_line_started := false; + col_zero := true; + line_start := Lexing.lexeme_start lexbuf + 1 + +let started_line = ref (-1) + +let start_line seen_char = + current_line_started := true; + col_zero := false; + (if seen_char && not(!line = !started_line) + then + begin + started_line := !line; + logical_line := !logical_line + 1 + end) + +let pass_zero _ = col_zero := false + +let lexerr s1 s2 = raise (Lexical (Printf.sprintf "%s%s" s1 s2)) + +let add_current_line_type x = + match (x,!current_line_type) with + (D.MINUS,(D.CONTEXT,ln,lln)) -> + current_line_type := (D.MINUS,ln,lln) + | (D.MINUS,(D.UNIQUE,ln,lln)) -> + current_line_type := (D.UNIQUEMINUS,ln,lln) + | (D.MINUS,(D.OPT,ln,lln)) -> + current_line_type := (D.OPTMINUS,ln,lln) + | (D.PLUS,(D.CONTEXT,ln,lln)) -> + current_line_type := (D.PLUS,ln,lln) + | (D.UNIQUE,(D.CONTEXT,ln,lln)) -> + current_line_type := (D.UNIQUE,ln,lln) + | (D.OPT,(D.CONTEXT,ln,lln)) -> + current_line_type := (D.OPT,ln,lln) + | _ -> lexerr "invalid control character combination" "" + +let check_minus_context_linetype s = + match !current_line_type with + (D.PLUS,_,_) -> lexerr "invalid in a + context: " s + | _ -> () + +let check_context_linetype s = + match !current_line_type with + (D.CONTEXT,_,_) -> () + | _ -> lexerr "invalid in a nonempty context: " s + +let check_plus_linetype s = + match !current_line_type with + (D.PLUS,_,_) -> () + | _ -> lexerr "invalid in a non + context: " s + +let check_arity_context_linetype s = + match !current_line_type with + (D.CONTEXT,_,_) | (D.PLUS,_,_) | (D.UNIQUE,_,_) | (D.OPT,_,_) -> () + | _ -> lexerr "invalid in a nonempty context: " s + +let process_include start finish str = + (match !current_line_type with + (D.PLUS,_,_) -> + (try + let _ = Str.search_forward (Str.regexp "\\.\\.\\.") str start in + lexerr "... not allowed in + include" "" + with Not_found -> ()) + | _ -> ()); + String.sub str (start + 1) (finish - start - 1) + +(* ---------------------------------------------------------------------- *) +type pm = PATCH | MATCH | UNKNOWN + +let pm = ref UNKNOWN + +let patch_or_match = function + PATCH -> + (match !pm with + MATCH -> lexerr "- or + not allowed in the first column for a match" "" + | PATCH -> () + | UNKNOWN -> Flag.sgrep_mode2 := false; pm := PATCH) + | MATCH -> + (match !pm with + PATCH -> lexerr "* not allowed in the first column for a patch" "" + | MATCH -> () + | UNKNOWN -> Flag.sgrep_mode2 := true; pm := MATCH) + | _ -> failwith "unexpected argument" + +(* ---------------------------------------------------------------------- *) +(* identifiers, including metavariables *) + +let metavariables = (Hashtbl.create(100) : (string, D.clt -> token) Hashtbl.t) + +let all_metavariables = + (Hashtbl.create(100) : (string,(string * (D.clt -> token)) list) Hashtbl.t) + +let type_names = (Hashtbl.create(100) : (string, D.clt -> token) Hashtbl.t) + +let declarer_names = (Hashtbl.create(100) : (string, D.clt -> token) Hashtbl.t) + +let iterator_names = (Hashtbl.create(100) : (string, D.clt -> token) Hashtbl.t) + +let rule_names = (Hashtbl.create(100) : (string, unit) Hashtbl.t) + +let check_var s linetype = + let fail _ = + if (!Data.in_prolog || !Data.in_rule_name) && + Str.string_match (Str.regexp "<.*>") s 0 + then TPathIsoFile s + else + try (Hashtbl.find metavariables s) linetype + with Not_found -> + (try (Hashtbl.find type_names s) linetype + with Not_found -> + (try (Hashtbl.find declarer_names s) linetype + with Not_found -> + (try (Hashtbl.find iterator_names s) linetype + with Not_found -> TIdent (s,linetype)))) in + if !Data.in_meta or !Data.in_rule_name + then (try Hashtbl.find rule_names s; TRuleName s with Not_found -> fail()) + else fail() + +let id_tokens lexbuf = + let s = tok lexbuf in + let linetype = get_current_line_type lexbuf in + let in_rule_name = !Data.in_rule_name in + let in_meta = !Data.in_meta in + let in_iso = !Data.in_iso in + let in_prolog = !Data.in_prolog in + match s with + "identifier" when in_meta -> check_arity_context_linetype s; TIdentifier + | "type" when in_meta -> check_arity_context_linetype s; TType + | "parameter" when in_meta -> check_arity_context_linetype s; TParameter + | "constant" when in_meta -> check_arity_context_linetype s; TConstant + | "expression" when in_meta || in_rule_name -> + check_arity_context_linetype s; TExpression + | "idexpression" when in_meta -> + check_arity_context_linetype s; TIdExpression + | "statement" when in_meta -> check_arity_context_linetype s; TStatement + | "function" when in_meta -> check_arity_context_linetype s; TFunction + | "local" when in_meta -> check_arity_context_linetype s; TLocal + | "list" when in_meta -> check_arity_context_linetype s; Tlist + | "fresh" when in_meta -> check_arity_context_linetype s; TFresh + | "typedef" when in_meta -> check_arity_context_linetype s; TTypedef + | "declarer" when in_meta -> check_arity_context_linetype s; TDeclarer + | "iterator" when in_meta -> check_arity_context_linetype s; TIterator + | "name" when in_meta -> check_arity_context_linetype s; TName + | "position" when in_meta -> check_arity_context_linetype s; TPosition + | "any" when in_meta -> check_arity_context_linetype s; TPosAny + | "pure" when in_meta && in_iso -> + check_arity_context_linetype s; TPure + | "context" when in_meta && in_iso -> + check_arity_context_linetype s; TContext + | "error" when in_meta -> check_arity_context_linetype s; TError + | "words" when in_meta -> check_context_linetype s; TWords + + | "using" when in_rule_name || in_prolog -> check_context_linetype s; TUsing + | "disable" when in_rule_name -> check_context_linetype s; TDisable + | "extends" when in_rule_name -> check_context_linetype s; TExtends + | "depends" when in_rule_name -> check_context_linetype s; TDepends + | "on" when in_rule_name -> check_context_linetype s; TOn + | "ever" when in_rule_name -> check_context_linetype s; TEver + | "never" when in_rule_name -> check_context_linetype s; TNever + | "exists" when in_rule_name -> check_context_linetype s; TExists + | "forall" when in_rule_name -> check_context_linetype s; TForall + | "reverse" when in_rule_name -> check_context_linetype s; TReverse + + | "char" -> Tchar linetype + | "short" -> Tshort linetype + | "int" -> Tint linetype + | "double" -> Tdouble linetype + | "float" -> Tfloat linetype + | "long" -> Tlong linetype + | "void" -> Tvoid linetype + | "struct" -> Tstruct linetype + | "union" -> Tunion linetype + | "unsigned" -> Tunsigned linetype + | "signed" -> Tsigned linetype + + | "auto" -> Tauto linetype + | "register" -> Tregister linetype + | "extern" -> Textern linetype + | "static" -> Tstatic linetype + | "inline" -> Tinline linetype + | "typedef" -> Ttypedef linetype + + | "const" -> Tconst linetype + | "volatile" -> Tvolatile linetype + + | "if" -> TIf linetype + | "else" -> TElse linetype + | "while" -> TWhile linetype + | "do" -> TDo linetype + | "for" -> TFor linetype + | "switch" -> TSwitch linetype + | "case" -> TCase linetype + | "default" -> TDefault linetype + | "return" -> TReturn linetype + | "break" -> TBreak linetype + | "continue" -> TContinue linetype + | "goto" -> TGoto linetype + + | "sizeof" -> TSizeof linetype + + | "Expression" -> TIsoExpression + | "ArgExpression" -> TIsoArgExpression + | "TestExpression" -> TIsoTestExpression + | "Statement" -> TIsoStatement + | "Declaration" -> TIsoDeclaration + | "Type" -> TIsoType + | "TopLevel" -> TIsoTopLevel + + | s -> check_var s linetype + +let mkassign op lexbuf = + TAssign (Ast.OpAssign op, (get_current_line_type lexbuf)) + +let init _ = + line := 1; + logical_line := 0; + prev_plus := false; + line_start := 0; + current_line_started := false; + col_zero := true; + pm := UNKNOWN; + Data.in_rule_name := false; + Data.in_meta := false; + Data.in_prolog := false; + Data.inheritable_positions := []; + Hashtbl.clear all_metavariables; + Hashtbl.clear Data.all_metadecls; + Hashtbl.clear metavariables; + Hashtbl.clear type_names; + Hashtbl.clear rule_names; + let get_name (_,x) = x in + Data.add_id_meta := + (fun name constraints pure -> + let fn clt = TMetaId(name,constraints,pure,clt) in + Hashtbl.replace metavariables (get_name name) fn); + Data.add_type_meta := + (fun name pure -> + let fn clt = TMetaType(name,pure,clt) in + Hashtbl.replace metavariables (get_name name) fn); + Data.add_param_meta := + (function name -> function pure -> + let fn clt = TMetaParam(name,pure,clt) in + Hashtbl.replace metavariables (get_name name) fn); + Data.add_paramlist_meta := + (function name -> function lenname -> function pure -> + let fn clt = TMetaParamList(name,lenname,pure,clt) in + Hashtbl.replace metavariables (get_name name) fn); + Data.add_const_meta := + (fun tyopt name constraints pure -> + let fn clt = TMetaConst(name,constraints,pure,tyopt,clt) in + Hashtbl.replace metavariables (get_name name) fn); + Data.add_err_meta := + (fun name constraints pure -> + let fn clt = TMetaErr(name,constraints,pure,clt) in + Hashtbl.replace metavariables (get_name name) fn); + Data.add_exp_meta := + (fun tyopt name constraints pure -> + let fn clt = TMetaExp(name,constraints,pure,tyopt,clt) in + Hashtbl.replace metavariables (get_name name) fn); + Data.add_idexp_meta := + (fun tyopt name constraints pure -> + let fn clt = TMetaIdExp(name,constraints,pure,tyopt,clt) in + Hashtbl.replace metavariables (get_name name) fn); + Data.add_local_idexp_meta := + (fun tyopt name constraints pure -> + let fn clt = TMetaLocalIdExp(name,constraints,pure,tyopt,clt) in + Hashtbl.replace metavariables (get_name name) fn); + Data.add_explist_meta := + (function name -> function lenname -> function pure -> + let fn clt = TMetaExpList(name,lenname,pure,clt) in + Hashtbl.replace metavariables (get_name name) fn); + Data.add_stm_meta := + (function name -> function pure -> + let fn clt = TMetaStm(name,pure,clt) in + Hashtbl.replace metavariables (get_name name) fn); + Data.add_stmlist_meta := + (function name -> function pure -> + let fn clt = TMetaStmList(name,pure,clt) in + Hashtbl.replace metavariables (get_name name) fn); + Data.add_func_meta := + (fun name constraints pure -> + let fn clt = TMetaFunc(name,constraints,pure,clt) in + Hashtbl.replace metavariables (get_name name) fn); + Data.add_local_func_meta := + (fun name constraints pure -> + let fn clt = TMetaLocalFunc(name,constraints,pure,clt) in + Hashtbl.replace metavariables (get_name name) fn); + Data.add_iterator_meta := + (fun name constraints pure -> + let fn clt = TMetaIterator(name,constraints,pure,clt) in + Hashtbl.replace metavariables (get_name name) fn); + Data.add_declarer_meta := + (fun name constraints pure -> + let fn clt = TMetaDeclarer(name,constraints,pure,clt) in + Hashtbl.replace metavariables (get_name name) fn); + Data.add_pos_meta := + (fun name constraints any -> + let fn ((d,ln,_,_,_,_,_,_) as clt) = + (if d = Data.PLUS + then + failwith + (Printf.sprintf "%d: positions only allowed in minus code" ln)); + TMetaPos(name,constraints,any,clt) in + Hashtbl.replace metavariables (get_name name) fn); + Data.add_type_name := + (function name -> + let fn clt = TTypeId(name,clt) in + Hashtbl.replace type_names name fn); + Data.add_declarer_name := + (function name -> + let fn clt = TDeclarerId(name,clt) in + Hashtbl.replace declarer_names name fn); + Data.add_iterator_name := + (function name -> + let fn clt = TIteratorId(name,clt) in + Hashtbl.replace iterator_names name fn); + Data.init_rule := (function _ -> Hashtbl.clear metavariables); + Data.install_bindings := + (function parent -> + List.iter (function (name,fn) -> Hashtbl.add metavariables name fn) + (Hashtbl.find all_metavariables parent)) + +let drop_spaces s = + let len = String.length s in + let rec loop n = + if n = len + then n + else + if List.mem (String.get s n) [' ';'\t'] + then loop (n+1) + else n in + let start = loop 0 in + String.sub s start (len - start) +} + +(* ---------------------------------------------------------------------- *) +(* tokens *) + +let letter = ['A'-'Z' 'a'-'z' '_'] +let digit = ['0'-'9'] + +let dec = ['0'-'9'] +let oct = ['0'-'7'] +let hex = ['0'-'9' 'a'-'f' 'A'-'F'] + +let decimal = ('0' | (['1'-'9'] dec*)) +let octal = ['0'] oct+ +let hexa = ("0x" |"0X") hex+ + +let pent = dec+ +let pfract = dec+ +let sign = ['-' '+'] +let exp = ['e''E'] sign? dec+ +let real = pent exp | ((pent? '.' pfract | pent '.' pfract? ) exp?) + + +rule token = parse + | [' ' '\t' ]+ { start_line false; token lexbuf } + | ['\n' '\r' '\011' '\012'] { reset_line lexbuf; token lexbuf } + + | "//" [^ '\n']* { start_line false; token lexbuf } + + | "@@" { start_line true; TArobArob } + | "@" { pass_zero(); + if !Data.in_rule_name or not !current_line_started + then (start_line true; TArob) + else (check_minus_context_linetype "@"; TPArob) } + + | "WHEN" | "when" + { start_line true; check_minus_context_linetype (tok lexbuf); + TWhen (get_current_line_type lexbuf) } + + | "..." + { start_line true; check_minus_context_linetype (tok lexbuf); + TEllipsis (get_current_line_type lexbuf) } +(* + | "ooo" + { start_line true; check_minus_context_linetype (tok lexbuf); + TCircles (get_current_line_type lexbuf) } + + | "***" + { start_line true; check_minus_context_linetype (tok lexbuf); + TStars (get_current_line_type lexbuf) } +*) + | "<..." { start_line true; check_context_linetype (tok lexbuf); + TOEllipsis (get_current_line_type lexbuf) } + | "...>" { start_line true; check_context_linetype (tok lexbuf); + TCEllipsis (get_current_line_type lexbuf) } + | "<+..." { start_line true; check_context_linetype (tok lexbuf); + TPOEllipsis (get_current_line_type lexbuf) } + | "...+>" { start_line true; check_context_linetype (tok lexbuf); + TPCEllipsis (get_current_line_type lexbuf) } +(* + | "" { start_line true; check_context_linetype (tok lexbuf); + TCCircles (get_current_line_type lexbuf) } + + | "<***" { start_line true; check_context_linetype (tok lexbuf); + TOStars (get_current_line_type lexbuf) } + | "***>" { start_line true; check_context_linetype (tok lexbuf); + TCStars (get_current_line_type lexbuf) } +*) + | "-" { pass_zero(); + if !current_line_started + then (start_line true; TMinus (get_current_line_type lexbuf)) + else (patch_or_match PATCH; + add_current_line_type D.MINUS; token lexbuf) } + | "+" { pass_zero(); + if !current_line_started + then (start_line true; TPlus (get_current_line_type lexbuf)) + else if !Data.in_meta + then TPlus0 + else (patch_or_match PATCH; + add_current_line_type D.PLUS; token lexbuf) } + | "?" { pass_zero(); + if !current_line_started + then (start_line true; TWhy (get_current_line_type lexbuf)) + else if !Data.in_meta + then TWhy0 + else (add_current_line_type D.OPT; token lexbuf) } + | "!" { pass_zero(); + if !current_line_started + then (start_line true; TBang (get_current_line_type lexbuf)) + else if !Data.in_meta + then TBang0 + else (add_current_line_type D.UNIQUE; token lexbuf) } + | "(" { if not !col_zero + then (start_line true; TOPar (get_current_line_type lexbuf)) + else + (start_line true; check_context_linetype (tok lexbuf); + TOPar0 (get_current_line_type lexbuf))} + | "\\(" { start_line true; TOPar0 (get_current_line_type lexbuf) } + | "|" { if not (!col_zero) + then (start_line true; TOr(get_current_line_type lexbuf)) + else (start_line true; + check_context_linetype (tok lexbuf); + TMid0 (get_current_line_type lexbuf))} + | "\\|" { start_line true; TMid0 (get_current_line_type lexbuf) } + | ")" { if not !col_zero + then (start_line true; TCPar (get_current_line_type lexbuf)) + else + (start_line true; check_context_linetype (tok lexbuf); + TCPar0 (get_current_line_type lexbuf))} + | "\\)" { start_line true; TCPar0 (get_current_line_type lexbuf) } + + | '[' { start_line true; TOCro (get_current_line_type lexbuf) } + | ']' { start_line true; TCCro (get_current_line_type lexbuf) } + | '{' { start_line true; TOBrace (get_current_line_type lexbuf) } + | '}' { start_line true; TCBrace (get_current_line_type lexbuf) } + + | "->" { start_line true; TPtrOp (get_current_line_type lexbuf) } + | '.' { start_line true; TDot (get_current_line_type lexbuf) } + | ',' { start_line true; TComma (get_current_line_type lexbuf) } + | ";" { start_line true; + if !Data.in_meta + then TMPtVirg (* works better with tokens_all *) + else TPtVirg (get_current_line_type lexbuf) } + + + | '*' { pass_zero(); + if !current_line_started + then + (start_line true; TMul (get_current_line_type lexbuf)) + else + (patch_or_match MATCH; + add_current_line_type D.MINUS; token lexbuf) } + | '/' { start_line true; + TDmOp (Ast.Div,get_current_line_type lexbuf) } + | '%' { start_line true; + TDmOp (Ast.Mod,get_current_line_type lexbuf) } + | '~' { start_line true; TTilde (get_current_line_type lexbuf) } + + | "++" { start_line true; TInc (get_current_line_type lexbuf) } + | "--" { start_line true; TDec (get_current_line_type lexbuf) } + + | "=" { start_line true; TEq (get_current_line_type lexbuf) } + + | "-=" { start_line true; mkassign Ast.Minus lexbuf } + | "+=" { start_line true; mkassign Ast.Plus lexbuf } + + | "*=" { start_line true; mkassign Ast.Mul lexbuf } + | "/=" { start_line true; mkassign Ast.Div lexbuf } + | "%=" { start_line true; mkassign Ast.Mod lexbuf } + + | "&=" { start_line true; mkassign Ast.And lexbuf } + | "|=" { start_line true; mkassign Ast.Or lexbuf } + | "^=" { start_line true; mkassign Ast.Xor lexbuf } + + | "<<=" { start_line true; mkassign Ast.DecLeft lexbuf } + | ">>=" { start_line true; mkassign Ast.DecRight lexbuf } + + | ":" { start_line true; TDotDot (get_current_line_type lexbuf) } + + | "==" { start_line true; TEqEq (get_current_line_type lexbuf) } + | "!=" { start_line true; TNotEq (get_current_line_type lexbuf) } + | ">=" { start_line true; + TLogOp(Ast.SupEq,get_current_line_type lexbuf) } + | "<=" { start_line true; + TLogOp(Ast.InfEq,get_current_line_type lexbuf) } + | "<" { start_line true; + TLogOp(Ast.Inf,get_current_line_type lexbuf) } + | ">" { start_line true; + TLogOp(Ast.Sup,get_current_line_type lexbuf) } + + | "&&" { start_line true; TAndLog (get_current_line_type lexbuf) } + | "||" { start_line true; TOrLog (get_current_line_type lexbuf) } + + | ">>" { start_line true; + TShOp(Ast.DecRight,get_current_line_type lexbuf) } + | "<<" { start_line true; + TShOp(Ast.DecLeft,get_current_line_type lexbuf) } + + | "&" { start_line true; TAnd (get_current_line_type lexbuf) } + | "^" { start_line true; TXor(get_current_line_type lexbuf) } + + | ( ("#" [' ' '\t']* "define" [' ' '\t']+)) + ( (letter (letter |digit)*) as ident) + { start_line true; + let (arity,line,lline,offset,col,strbef,straft,pos) as lt = + get_current_line_type lexbuf in + let off = String.length "#define " in + (* -1 in the code below because the ident is not at the line start *) + TDefine + (lt, + check_var ident + (arity,line,lline,offset+off,(-1),[],[],Ast0.NoMetaPos)) } + | ( ("#" [' ' '\t']* "define" [' ' '\t']+)) + ( (letter (letter | digit)*) as ident) + '(' + { start_line true; + let (arity,line,lline,offset,col,strbef,straft,pos) as lt = + get_current_line_type lexbuf in + let off = String.length "#define " in + TDefineParam + (lt, + check_var ident + (* why pos here but not above? *) + (arity,line,lline,offset+off,(-1),strbef,straft,pos), + offset + off + (String.length ident)) } + | "#" [' ' '\t']* "include" [' ' '\t']* '"' [^ '"']+ '"' + { TIncludeL + (let str = tok lexbuf in + let start = String.index str '"' in + let finish = String.rindex str '"' in + start_line true; + (process_include start finish str,get_current_line_type lexbuf)) } + | "#" [' ' '\t']* "include" [' ' '\t']* '<' [^ '>']+ '>' + { TIncludeNL + (let str = tok lexbuf in + let start = String.index str '<' in + let finish = String.rindex str '>' in + start_line true; + (process_include start finish str,get_current_line_type lexbuf)) } + | "#" [' ' '\t']* "if" [^'\n']* + | "#" [' ' '\t']* "ifdef" [^'\n']* + | "#" [' ' '\t']* "ifndef" [^'\n']* + | "#" [' ' '\t']* "else" [^'\n']* + | "#" [' ' '\t']* "elif" [^'\n']* + | "#" [' ' '\t']* "endif" [^'\n']* + | "#" [' ' '\t']* "error" [^'\n']* + { start_line true; check_plus_linetype (tok lexbuf); + TPragma (tok lexbuf) } + | "---" [^'\n']* + { (if !current_line_started + then lexerr "--- must be at the beginning of the line" ""); + start_line true; + TMinusFile + (let str = tok lexbuf in + (drop_spaces(String.sub str 3 (String.length str - 3)), + (get_current_line_type lexbuf))) } + | "+++" [^'\n']* + { (if !current_line_started + then lexerr "+++ must be at the beginning of the line" ""); + start_line true; + TPlusFile + (let str = tok lexbuf in + (drop_spaces(String.sub str 3 (String.length str - 3)), + (get_current_line_type lexbuf))) } + + | letter (letter | digit)* + { start_line true; id_tokens lexbuf } + + | "'" { start_line true; + TChar(char lexbuf,get_current_line_type lexbuf) } + | '"' { start_line true; + TString(string lexbuf,(get_current_line_type lexbuf)) } + | (real as x) { start_line true; + TFloat(x,(get_current_line_type lexbuf)) } + | ((( decimal | hexa | octal) + ( ['u' 'U'] + | ['l' 'L'] + | (['l' 'L'] ['u' 'U']) + | (['u' 'U'] ['l' 'L']) + | (['u' 'U'] ['l' 'L'] ['l' 'L']) + | (['l' 'L'] ['l' 'L']) + )? + ) as x) { start_line true; TInt(x,(get_current_line_type lexbuf)) } + + | "<=>" { TIso } + | "=>" { TRightIso } + + | eof { EOF } + + | _ { lexerr "unrecognised symbol, in token rule: " (tok lexbuf) } + + +and char = parse + | (_ as x) "'" { String.make 1 x } + | (("\\" (oct | oct oct | oct oct oct)) as x "'") { x } + | (("\\x" (hex | hex hex)) as x "'") { x } + | (("\\" (_ as v)) as x "'") + { (match v with + | 'n' -> () | 't' -> () | 'v' -> () | 'b' -> () + | 'r' -> () | 'f' -> () | 'a' -> () + | '\\' -> () | '?' -> () | '\'' -> () | '"' -> () + | 'e' -> () + | _ -> lexerr "unrecognised symbol: " (tok lexbuf) + ); + x + } + | _ { lexerr "unrecognised symbol: " (tok lexbuf) } + +and string = parse + | '"' { "" } + | (_ as x) { Common.string_of_char x ^ string lexbuf } + | ("\\" (oct | oct oct | oct oct oct)) as x { x ^ string lexbuf } + | ("\\x" (hex | hex hex)) as x { x ^ string lexbuf } + | ("\\" (_ as v)) as x + { + (match v with + | 'n' -> () | 't' -> () | 'v' -> () | 'b' -> () | 'r' -> () + | 'f' -> () | 'a' -> () + | '\\' -> () | '?' -> () | '\'' -> () | '"' -> () + | 'e' -> () + | '\n' -> () + | _ -> lexerr "unrecognised symbol:" (tok lexbuf) + ); + x ^ string lexbuf + } + | _ { lexerr "unrecognised symbol: " (tok lexbuf) } diff --git a/parsing_cocci/.#parse_aux.ml.1.23 b/parsing_cocci/.#parse_aux.ml.1.23 new file mode 100644 index 0000000..fb1ff7d --- /dev/null +++ b/parsing_cocci/.#parse_aux.ml.1.23 @@ -0,0 +1,467 @@ +(* +* 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. +*) + + +(* exports everything, used only by parser_cocci_menhir.mly *) +module Ast0 = Ast0_cocci +module Ast = Ast_cocci + +(* types for metavariable tokens *) +type info = Ast.meta_name * Ast0.pure * Data.clt +type idinfo = Ast.meta_name * Data.iconstraints * Ast0.pure * Data.clt +type expinfo = Ast.meta_name * Data.econstraints * Ast0.pure * Data.clt +type tyinfo = Ast.meta_name * Ast0.typeC list * Ast0.pure * Data.clt +type list_info = Ast.meta_name * Ast.meta_name option * Ast0.pure * Data.clt +type typed_info = + Ast.meta_name * Data.econstraints * Ast0.pure * + Type_cocci.typeC list option * Data.clt +type pos_info = Ast.meta_name * Data.pconstraints * Ast.meta_collect * Data.clt + + +let get_option fn = function + None -> None + | Some x -> Some (fn x) + +let make_info line logical_line offset col strbef straft = + { Ast0.line_start = line; Ast0.line_end = line; + Ast0.logical_start = logical_line; Ast0.logical_end = logical_line; + Ast0.attachable_start = true; Ast0.attachable_end = true; + Ast0.mcode_start = []; Ast0.mcode_end = []; + Ast0.column = col; Ast0.offset = offset; + Ast0.strings_before = strbef; Ast0.strings_after = straft; } + +let clt2info (_,line,logical_line,offset,col,strbef,straft,pos) = + make_info line logical_line offset col strbef straft + +let drop_bef (arity,line,lline,offset,col,strbef,straft,pos) = + (arity,line,lline,offset,col,[],straft,pos) + +let drop_aft (arity,line,lline,offset,col,strbef,straft,pos) = + (arity,line,lline,offset,col,strbef,[],pos) + +let clt2mcode str = function + (Data.MINUS,line,lline,offset,col,strbef,straft,pos) -> + (str,Ast0.NONE,make_info line lline offset col strbef straft, + Ast0.MINUS(ref([],Ast0.default_token_info)),ref pos) + | (Data.OPTMINUS,line,lline,offset,col,strbef,straft,pos) -> + (str,Ast0.OPT,make_info line lline offset col strbef straft, + Ast0.MINUS(ref([],Ast0.default_token_info)),ref pos) + | (Data.UNIQUEMINUS,line,lline,offset,col,strbef,straft,pos) -> + (str,Ast0.UNIQUE,make_info line lline offset col strbef straft, + Ast0.MINUS(ref([],Ast0.default_token_info)),ref pos) + | (Data.PLUS,line,lline,offset,col,strbef,straft,pos) -> + (str,Ast0.NONE,make_info line lline offset col strbef straft,Ast0.PLUS, + ref pos) + | (Data.CONTEXT,line,lline,offset,col,strbef,straft,pos) -> + (str,Ast0.NONE,make_info line lline offset col strbef straft, + Ast0.CONTEXT(ref(Ast.NOTHING, + Ast0.default_token_info,Ast0.default_token_info)), + ref pos) + | (Data.OPT,line,lline,offset,col,strbef,straft,pos) -> + (str,Ast0.OPT,make_info line lline offset col strbef straft, + Ast0.CONTEXT(ref(Ast.NOTHING, + Ast0.default_token_info,Ast0.default_token_info)), + ref pos) + | (Data.UNIQUE,line,lline,offset,col,strbef,straft,pos) -> + (str,Ast0.UNIQUE,make_info line lline offset col strbef straft, + Ast0.CONTEXT(ref(Ast.NOTHING, + Ast0.default_token_info,Ast0.default_token_info)), + ref pos) + +let id2name (name, clt) = name +let id2clt (name, clt) = clt +let id2mcode (name, clt) = clt2mcode name clt + +let mkdots str (dot,whencode) = + match str with + "..." -> Ast0.wrap(Ast0.Dots(clt2mcode str dot, whencode)) + | "ooo" -> Ast0.wrap(Ast0.Circles(clt2mcode str dot, whencode)) + | "***" -> Ast0.wrap(Ast0.Stars(clt2mcode str dot, whencode)) + | _ -> failwith "cannot happen" + +let mkedots str (dot,whencode) = + match str with + "..." -> Ast0.wrap(Ast0.Edots(clt2mcode str dot, whencode)) + | "ooo" -> Ast0.wrap(Ast0.Ecircles(clt2mcode str dot, whencode)) + | "***" -> Ast0.wrap(Ast0.Estars(clt2mcode str dot, whencode)) + | _ -> failwith "cannot happen" + +let mkdpdots str dot = + match str with + "..." -> Ast0.wrap(Ast0.DPdots(clt2mcode str dot)) + | "ooo" -> Ast0.wrap(Ast0.DPcircles(clt2mcode str dot)) + | _ -> failwith "cannot happen" + +let mkidots str (dot,whencode) = + match str with + "..." -> Ast0.wrap(Ast0.Idots(clt2mcode str dot, whencode)) + | _ -> failwith "cannot happen" + +let mkddots str (dot,whencode) = + match (str,whencode) with + ("...",None) -> Ast0.wrap(Ast0.Ddots(clt2mcode str dot, None)) + | ("...",Some [w]) -> Ast0.wrap(Ast0.Ddots(clt2mcode str dot, Some w)) + | _ -> failwith "cannot happen" + +let mkpdots str dot = + match str with + "..." -> Ast0.wrap(Ast0.Pdots(clt2mcode str dot)) + | "ooo" -> Ast0.wrap(Ast0.Pcircles(clt2mcode str dot)) + | _ -> failwith "cannot happen" + +let arith_op ast_op left op right = + Ast0.wrap + (Ast0.Binary(left, clt2mcode (Ast.Arith ast_op) op, right)) + +let logic_op ast_op left op right = + Ast0.wrap + (Ast0.Binary(left, clt2mcode (Ast.Logical ast_op) op, right)) + +let make_cv cv ty = + match cv with None -> ty | Some x -> Ast0.wrap (Ast0.ConstVol(x,ty)) + +let top_dots l = + let circle x = + match Ast0.unwrap x with Ast0.Circles(_) -> true | _ -> false in + let star x = + match Ast0.unwrap x with Ast0.Stars(_) -> true | _ -> false in + if List.exists circle l + then Ast0.wrap(Ast0.CIRCLES(l)) + else + if List.exists star l + then Ast0.wrap(Ast0.STARS(l)) + else Ast0.wrap(Ast0.DOTS(l)) + +(* here the offset is that of the first in the sequence of *s, not that of +each * individually *) +let pointerify ty m = + List.fold_left + (function inner -> + function cur -> + Ast0.wrap(Ast0.Pointer(inner,clt2mcode "*" cur))) + ty m + +let ty_pointerify ty m = + List.fold_left + (function inner -> function cur -> Type_cocci.Pointer(inner)) + ty m + +(* Left is <=>, Right is =>. Collect <=>s. *) +(* The parser should have done this, with precedences. But whatever... *) +let iso_adjust fn first rest = + let rec loop = function + [] -> [[]] + | (Common.Left x)::rest -> + (match loop rest with + front::after -> (fn x::front)::after + | _ -> failwith "not possible") + | (Common.Right x)::rest -> + (match loop rest with + front::after -> []::(fn x::front)::after + | _ -> failwith "not possible") in + match loop rest with + front::after -> (fn first::front)::after + | _ -> failwith "not possible" + +let check_meta tok = + let lookup rule name = + try + let info = Hashtbl.find Data.all_metadecls rule in + List.find (function mv -> Ast.get_meta_name mv = (rule,name)) info + with + Not_found -> + raise + (Semantic_cocci.Semantic + ("bad rule "^rule^" or bad variable "^name)) in + match tok with + Ast.MetaIdDecl(Ast.NONE,(rule,name)) -> + (match lookup rule name with + Ast.MetaIdDecl(_,_) | Ast.MetaFreshIdDecl(_,_) -> () + | _ -> + raise + (Semantic_cocci.Semantic + ("incompatible inheritance declaration "^name))) + | Ast.MetaFreshIdDecl(Ast.NONE,(rule,name)) -> + raise + (Semantic_cocci.Semantic + "can't inherit the freshness of an identifier") + | Ast.MetaListlenDecl((rule,name)) -> + (match lookup rule name with + Ast.MetaListlenDecl(_) -> () + | _ -> + raise + (Semantic_cocci.Semantic + ("incompatible inheritance declaration "^name))) + | Ast.MetaTypeDecl(Ast.NONE,(rule,name)) -> + (match lookup rule name with + Ast.MetaTypeDecl(_,_) -> () + | _ -> + raise + (Semantic_cocci.Semantic + ("incompatible inheritance declaration "^name))) + | Ast.MetaParamDecl(Ast.NONE,(rule,name)) -> + (match lookup rule name with + Ast.MetaParamDecl(_,_) -> () + | _ -> + raise + (Semantic_cocci.Semantic + ("incompatible inheritance declaration "^name))) + | Ast.MetaParamListDecl(Ast.NONE,(rule,name),len_name) -> + (match lookup rule name with + Ast.MetaParamListDecl(_,_,_) -> () + | _ -> + raise + (Semantic_cocci.Semantic + ("incompatible inheritance declaration "^name))) + | Ast.MetaErrDecl(Ast.NONE,(rule,name)) -> + (match lookup rule name with + Ast.MetaErrDecl(_,_) -> () + | _ -> + raise + (Semantic_cocci.Semantic + ("incompatible inheritance declaration "^name))) + | Ast.MetaExpDecl(Ast.NONE,(rule,name),ty) -> + (match lookup rule name with + Ast.MetaExpDecl(_,_,ty1) when ty = ty1 -> () + | _ -> + raise + (Semantic_cocci.Semantic + ("incompatible inheritance declaration "^name))) + | Ast.MetaIdExpDecl(Ast.NONE,(rule,name),ty) -> + (match lookup rule name with + Ast.MetaIdExpDecl(_,_,ty1) when ty = ty1 -> () + | _ -> + raise + (Semantic_cocci.Semantic + ("incompatible inheritance declaration "^name))) + | Ast.MetaLocalIdExpDecl(Ast.NONE,(rule,name),ty) -> + (match lookup rule name with + Ast.MetaLocalIdExpDecl(_,_,ty1) when ty = ty1 -> () + | _ -> + raise + (Semantic_cocci.Semantic + ("incompatible inheritance declaration "^name))) + | Ast.MetaExpListDecl(Ast.NONE,(rule,name),len_name) -> + (match lookup rule name with + Ast.MetaExpListDecl(_,_,_) -> () + | _ -> + raise + (Semantic_cocci.Semantic + ("incompatible inheritance declaration "^name))) + | Ast.MetaStmDecl(Ast.NONE,(rule,name)) -> + (match lookup rule name with + Ast.MetaStmDecl(_,_) -> () + | _ -> + raise + (Semantic_cocci.Semantic + ("incompatible inheritance declaration "^name))) + | Ast.MetaStmListDecl(Ast.NONE,(rule,name)) -> + (match lookup rule name with + Ast.MetaStmListDecl(_,_) -> () + | _ -> + raise + (Semantic_cocci.Semantic + ("incompatible inheritance declaration "^name))) + | Ast.MetaFuncDecl(Ast.NONE,(rule,name)) -> + (match lookup rule name with + Ast.MetaFuncDecl(_,_) -> () + | _ -> + raise + (Semantic_cocci.Semantic + ("incompatible inheritance declaration "^name))) + | Ast.MetaLocalFuncDecl(Ast.NONE,(rule,name)) -> + (match lookup rule name with + Ast.MetaLocalFuncDecl(_,_) -> () + | _ -> + raise + (Semantic_cocci.Semantic + ("incompatible inheritance declaration "^name))) + | Ast.MetaConstDecl(Ast.NONE,(rule,name),ty) -> + (match lookup rule name with + Ast.MetaConstDecl(_,_,ty1) when ty = ty1 -> () + | _ -> + raise + (Semantic_cocci.Semantic + ("incompatible inheritance declaration "^name))) + | Ast.MetaPosDecl(Ast.NONE,(rule,name)) -> + (match lookup rule name with + Ast.MetaPosDecl(_,_) -> + if not (List.mem rule !Data.inheritable_positions) + then + raise + (Semantic_cocci.Semantic + ("position cannot be inherited over modifications: "^name)) + | _ -> + raise + (Semantic_cocci.Semantic + ("incompatible inheritance declaration "^name))) + | _ -> + raise + (Semantic_cocci.Semantic ("arity not allowed on imported declaration")) + +let create_metadec ar ispure kindfn ids current_rule = + List.concat + (List.map + (function (rule,nm) -> + let (rule,checker) = + match rule with + None -> ((current_rule,nm),function x -> [Common.Left x]) + | Some rule -> + ((rule,nm), + function x -> check_meta x; [Common.Right x]) in + kindfn ar rule ispure checker) + ids) + +let create_metadec_ne ar ispure kindfn ids current_rule = + List.concat + (List.map + (function ((rule,nm),constraints) -> + let (rule,checker) = + match rule with + None -> ((current_rule,nm),function x -> [Common.Left x]) + | Some rule -> + ((rule,nm), + function x -> check_meta x; [Common.Right x]) in + kindfn ar rule ispure checker constraints) + ids) + +let create_metadec_ty ar ispure kindfn ids current_rule = + List.concat + (List.map + (function ((rule,nm),constraints) -> + let (rule,checker) = + match rule with + None -> ((current_rule,nm),function x -> [Common.Left x]) + | Some rule -> + ((rule,nm), + function x -> check_meta x; [Common.Right x]) in + kindfn ar rule ispure checker constraints) + ids) + +let create_len_metadec ar ispure kindfn lenid ids current_rule = + let lendec = + create_metadec Ast.NONE Ast0.Impure + (fun _ name _ check_meta -> check_meta(Ast.MetaListlenDecl(name))) + [lenid] current_rule in + let lenname = + match lendec with + [Common.Left (Ast.MetaListlenDecl(x))] -> x + | [Common.Right (Ast.MetaListlenDecl(x))] -> x + | _ -> failwith "unexpected length declaration" in + lendec@(create_metadec ar ispure (kindfn lenname) ids current_rule) + +(* ---------------------------------------------------------------------- *) + +let str2inc s = + let elements = Str.split (Str.regexp "/") s in + List.map (function "..." -> Ast.IncDots | s -> Ast.IncPath s) elements + +(* ---------------------------------------------------------------------- *) +(* statements *) + +let meta_stm name = + let (nm,pure,clt) = name in + Ast0.wrap(Ast0.MetaStmt(clt2mcode nm clt,pure)) + +let exp_stm exp pv = + Ast0.wrap(Ast0.ExprStatement (exp, clt2mcode ";" pv)) + +let ifthen iff lp tst rp thn = + Ast0.wrap(Ast0.IfThen(clt2mcode "if" iff, + clt2mcode "(" lp,tst,clt2mcode ")" rp,thn, + (Ast0.default_info(),Ast0.context_befaft()))) + +let ifthenelse iff lp tst rp thn e els = + Ast0.wrap(Ast0.IfThenElse(clt2mcode "if" iff, + clt2mcode "(" lp,tst,clt2mcode ")" rp,thn, + clt2mcode "else" e,els, + (Ast0.default_info(),Ast0.context_befaft()))) + +let forloop fr lp e1 sc1 e2 sc2 e3 rp s = + Ast0.wrap(Ast0.For(clt2mcode "for" fr,clt2mcode "(" lp,e1, + clt2mcode ";" sc1,e2, + clt2mcode ";" sc2,e3,clt2mcode ")" rp,s, + (Ast0.default_info(),Ast0.context_befaft()))) + +let whileloop w lp e rp s = + Ast0.wrap(Ast0.While(clt2mcode "while" w,clt2mcode "(" lp, + e,clt2mcode ")" rp,s, + (Ast0.default_info(),Ast0.context_befaft()))) + +let doloop d s w lp e rp pv = + Ast0.wrap(Ast0.Do(clt2mcode "do" d,s,clt2mcode "while" w, + clt2mcode "(" lp,e,clt2mcode ")" rp, + clt2mcode ";" pv)) + +let iterator i lp e rp s = + Ast0.wrap(Ast0.Iterator(i,clt2mcode "(" lp,e,clt2mcode ")" rp,s, + (Ast0.default_info(),Ast0.context_befaft()))) + +let switch s lp e rp lb c rb = + Ast0.wrap(Ast0.Switch(clt2mcode "switch" s,clt2mcode "(" lp,e, + clt2mcode ")" rp,clt2mcode "{" lb, + Ast0.wrap(Ast0.DOTS(c)),clt2mcode "}" rb)) + +let ret_exp r e pv = + Ast0.wrap(Ast0.ReturnExpr(clt2mcode "return" r,e,clt2mcode ";" pv)) + +let ret r pv = + Ast0.wrap(Ast0.Return(clt2mcode "return" r,clt2mcode ";" pv)) + +let break b pv = + Ast0.wrap(Ast0.Break(clt2mcode "break" b,clt2mcode ";" pv)) + +let cont c pv = + Ast0.wrap(Ast0.Continue(clt2mcode "continue" c,clt2mcode ";" pv)) + +let label i dd = + Ast0.wrap(Ast0.Label(i,clt2mcode ":" dd)) + +let goto g i pv = + Ast0.wrap(Ast0.Goto(clt2mcode "goto" g,i,clt2mcode ";" pv)) + +let seq lb s rb = + Ast0.wrap(Ast0.Seq(clt2mcode "{" lb,s,clt2mcode "}" rb)) + +(* ---------------------------------------------------------------------- *) + +let make_iso_rule_name_result n = + (try let _ = Hashtbl.find Data.all_metadecls n in + raise (Semantic_cocci.Semantic ("repeated rule name")) + with Not_found -> ()); + Ast.CocciRulename (Some n,Ast.NoDep,[],[],Ast.Undetermined,false (*discarded*)) + +let make_cocci_rule_name_result nm d i a e ee = + match nm with + Some nm -> + let n = id2name nm in + (try let _ = Hashtbl.find Data.all_metadecls n in + raise (Semantic_cocci.Semantic ("repeated rule name")) + with Not_found -> ()); + Ast.CocciRulename (Some n,d,i,a,e,ee) + | None -> Ast.CocciRulename (None,d,i,a,e,ee) + +let make_script_rule_name_result scr lang deps = + let s = id2name scr in + let l = id2name lang in + if s <> "script" then + raise (Semantic_cocci.Semantic ("malformed script rule")); + Ast.ScriptRulename (l,deps) diff --git a/parsing_cocci/.#parse_cocci.ml.1.162 b/parsing_cocci/.#parse_cocci.ml.1.162 new file mode 100644 index 0000000..45938ff --- /dev/null +++ b/parsing_cocci/.#parse_cocci.ml.1.162 @@ -0,0 +1,1512 @@ +(* +* 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. +*) + + +(* splits the entire file into minus and plus fragments, and parses each +separately (thus duplicating work for the parsing of the context elements) *) + +module D = Data +module PC = Parser_cocci_menhir +module V0 = Visitor_ast0 +module Ast = Ast_cocci +module Ast0 = Ast0_cocci +let pr = Printf.sprintf +(*let pr2 s = prerr_string s; prerr_string "\n"; flush stderr*) +let pr2 s = Printf.printf "%s\n" s + +(* for isomorphisms. all should be at the front!!! *) +let reserved_names = + ["all";"optional_storage";"optional_qualifier";"value_format";"comm_assoc"] + +(* ----------------------------------------------------------------------- *) +(* Debugging... *) + +let line_type (d,_,_,_,_,_,_,_) = d + +let line_type2c tok = + match line_type tok with + D.MINUS | D.OPTMINUS | D.UNIQUEMINUS -> ":-" + | D.PLUS -> ":+" + | D.CONTEXT | D.UNIQUE | D.OPT -> "" + +let token2c (tok,_) = + match tok with + PC.TIdentifier -> "identifier" + | PC.TType -> "type" + | PC.TParameter -> "parameter" + | PC.TConstant -> "constant" + | PC.TExpression -> "expression" + | PC.TIdExpression -> "idexpression" + | PC.TStatement -> "statement" + | PC.TPosition -> "position" + | PC.TPosAny -> "any" + | PC.TFunction -> "function" + | PC.TLocal -> "local" + | PC.Tlist -> "list" + | PC.TFresh -> "fresh" + | PC.TPure -> "pure" + | PC.TContext -> "context" + | PC.TTypedef -> "typedef" + | PC.TDeclarer -> "declarer" + | PC.TIterator -> "iterator" + | PC.TName -> "name" + | PC.TRuleName str -> "rule_name-"^str + | PC.TUsing -> "using" + | PC.TPathIsoFile str -> "path_iso_file-"^str + | PC.TDisable -> "disable" + | PC.TExtends -> "extends" + | PC.TDepends -> "depends" + | PC.TOn -> "on" + | PC.TEver -> "ever" + | PC.TNever -> "never" + | PC.TExists -> "exists" + | PC.TForall -> "forall" + | PC.TReverse -> "reverse" + | PC.TError -> "error" + | PC.TWords -> "words" + + | PC.TNothing -> "nothing" + + | PC.Tchar(clt) -> "char"^(line_type2c clt) + | PC.Tshort(clt) -> "short"^(line_type2c clt) + | PC.Tint(clt) -> "int"^(line_type2c clt) + | PC.Tdouble(clt) -> "double"^(line_type2c clt) + | PC.Tfloat(clt) -> "float"^(line_type2c clt) + | PC.Tlong(clt) -> "long"^(line_type2c clt) + | PC.Tvoid(clt) -> "void"^(line_type2c clt) + | PC.Tstruct(clt) -> "struct"^(line_type2c clt) + | PC.Tunion(clt) -> "union"^(line_type2c clt) + | PC.Tunsigned(clt) -> "unsigned"^(line_type2c clt) + | PC.Tsigned(clt) -> "signed"^(line_type2c clt) + | PC.Tstatic(clt) -> "static"^(line_type2c clt) + | PC.Tinline(clt) -> "inline"^(line_type2c clt) + | PC.Ttypedef(clt) -> "typedef"^(line_type2c clt) + | PC.Tattr(s,clt) -> s^(line_type2c clt) + | PC.Tauto(clt) -> "auto"^(line_type2c clt) + | PC.Tregister(clt) -> "register"^(line_type2c clt) + | PC.Textern(clt) -> "extern"^(line_type2c clt) + | PC.Tconst(clt) -> "const"^(line_type2c clt) + | PC.Tvolatile(clt) -> "volatile"^(line_type2c clt) + + | PC.TPragma(s) -> s + | PC.TIncludeL(s,clt) -> (pr "#include \"%s\"" s)^(line_type2c clt) + | PC.TIncludeNL(s,clt) -> (pr "#include <%s>" s)^(line_type2c clt) + | PC.TDefine(clt,_) -> "#define"^(line_type2c clt) + | PC.TDefineParam(clt,_,_) -> "#define_param"^(line_type2c clt) + | PC.TMinusFile(s,clt) -> (pr "--- %s" s)^(line_type2c clt) + | PC.TPlusFile(s,clt) -> (pr "+++ %s" s)^(line_type2c clt) + + | PC.TInc(clt) -> "++"^(line_type2c clt) + | PC.TDec(clt) -> "--"^(line_type2c clt) + + | PC.TIf(clt) -> "if"^(line_type2c clt) + | PC.TElse(clt) -> "else"^(line_type2c clt) + | PC.TWhile(clt) -> "while"^(line_type2c clt) + | PC.TFor(clt) -> "for"^(line_type2c clt) + | PC.TDo(clt) -> "do"^(line_type2c clt) + | PC.TSwitch(clt) -> "switch"^(line_type2c clt) + | PC.TCase(clt) -> "case"^(line_type2c clt) + | PC.TDefault(clt) -> "default"^(line_type2c clt) + | PC.TReturn(clt) -> "return"^(line_type2c clt) + | PC.TBreak(clt) -> "break"^(line_type2c clt) + | PC.TContinue(clt) -> "continue"^(line_type2c clt) + | PC.TGoto(clt) -> "goto"^(line_type2c clt) + | PC.TIdent(s,clt) -> (pr "ident-%s" s)^(line_type2c clt) + | PC.TTypeId(s,clt) -> (pr "typename-%s" s)^(line_type2c clt) + | PC.TDeclarerId(s,clt) -> (pr "declarername-%s" s)^(line_type2c clt) + | PC.TIteratorId(s,clt) -> (pr "iteratorname-%s" s)^(line_type2c clt) + | PC.TMetaDeclarer(_,_,_,clt) -> "declmeta"^(line_type2c clt) + | PC.TMetaIterator(_,_,_,clt) -> "itermeta"^(line_type2c clt) + + | PC.TSizeof(clt) -> "sizeof"^(line_type2c clt) + + | PC.TString(x,clt) -> x^(line_type2c clt) + | PC.TChar(x,clt) -> x^(line_type2c clt) + | PC.TFloat(x,clt) -> x^(line_type2c clt) + | PC.TInt(x,clt) -> x^(line_type2c clt) + + | PC.TOrLog(clt) -> "||"^(line_type2c clt) + | PC.TAndLog(clt) -> "&&"^(line_type2c clt) + | PC.TOr(clt) -> "|"^(line_type2c clt) + | PC.TXor(clt) -> "^"^(line_type2c clt) + | PC.TAnd (clt) -> "&"^(line_type2c clt) + | PC.TEqEq(clt) -> "=="^(line_type2c clt) + | PC.TNotEq(clt) -> "!="^(line_type2c clt) + | PC.TLogOp(op,clt) -> + (match op with + Ast.Inf -> "<" + | Ast.InfEq -> "<=" + | Ast.Sup -> ">" + | Ast.SupEq -> ">=" + | _ -> failwith "not possible") + ^(line_type2c clt) + | PC.TShOp(op,clt) -> + (match op with + Ast.DecLeft -> "<<" + | Ast.DecRight -> ">>" + | _ -> failwith "not possible") + ^(line_type2c clt) + | PC.TPlus(clt) -> "+"^(line_type2c clt) + | PC.TMinus(clt) -> "-"^(line_type2c clt) + | PC.TMul(clt) -> "*"^(line_type2c clt) + | PC.TDmOp(op,clt) -> + (match op with + Ast.Div -> "/" + | Ast.Mod -> "%" + | _ -> failwith "not possible") + ^(line_type2c clt) + | PC.TTilde (clt) -> "~"^(line_type2c clt) + + | PC.TMetaParam(_,_,clt) -> "parammeta"^(line_type2c clt) + | PC.TMetaParamList(_,_,_,clt) -> "paramlistmeta"^(line_type2c clt) + | PC.TMetaConst(_,_,_,_,clt) -> "constmeta"^(line_type2c clt) + | PC.TMetaErr(_,_,_,clt) -> "errmeta"^(line_type2c clt) + | PC.TMetaExp(_,_,_,_,clt) -> "expmeta"^(line_type2c clt) + | PC.TMetaIdExp(_,_,_,_,clt) -> "idexpmeta"^(line_type2c clt) + | PC.TMetaLocalIdExp(_,_,_,_,clt) -> "localidexpmeta"^(line_type2c clt) + | PC.TMetaExpList(_,_,_,clt) -> "explistmeta"^(line_type2c clt) + | PC.TMetaId(_,_,_,clt) -> "idmeta"^(line_type2c clt) + | PC.TMetaType(_,_,clt) -> "typemeta"^(line_type2c clt) + | PC.TMetaStm(_,_,clt) -> "stmmeta"^(line_type2c clt) + | PC.TMetaStmList(_,_,clt) -> "stmlistmeta"^(line_type2c clt) + | PC.TMetaFunc(_,_,_,clt) -> "funcmeta"^(line_type2c clt) + | PC.TMetaLocalFunc(_,_,_,clt) -> "funcmeta"^(line_type2c clt) + | PC.TMetaPos(_,_,_,clt) -> "posmeta" + | PC.TMPtVirg -> ";" + | PC.TArobArob -> "@@" + | PC.TArob -> "@" + | PC.TPArob -> "P@" + + | PC.TWhen(clt) -> "WHEN"^(line_type2c clt) + | PC.TAny(clt) -> "ANY"^(line_type2c clt) + | PC.TStrict(clt) -> "STRICT"^(line_type2c clt) + | PC.TEllipsis(clt) -> "..."^(line_type2c clt) +(* + | PC.TCircles(clt) -> "ooo"^(line_type2c clt) + | PC.TStars(clt) -> "***"^(line_type2c clt) +*) + + | PC.TOEllipsis(clt) -> "<..."^(line_type2c clt) + | PC.TCEllipsis(clt) -> "...>"^(line_type2c clt) + | PC.TPOEllipsis(clt) -> "<+..."^(line_type2c clt) + | PC.TPCEllipsis(clt) -> "...+>"^(line_type2c clt) +(* + | PC.TOCircles(clt) -> " "ooo>"^(line_type2c clt) + | PC.TOStars(clt) -> "<***"^(line_type2c clt) + | PC.TCStars(clt) -> "***>"^(line_type2c clt) +*) + | PC.TBang0 -> "!" + | PC.TPlus0 -> "+" + | PC.TWhy0 -> "?" + + | PC.TWhy(clt) -> "?"^(line_type2c clt) + | PC.TDotDot(clt) -> ":"^(line_type2c clt) + | PC.TBang(clt) -> "!"^(line_type2c clt) + | PC.TOPar(clt) -> "("^(line_type2c clt) + | PC.TOPar0(clt) -> "("^(line_type2c clt) + | PC.TMid0(clt) -> "|"^(line_type2c clt) + | PC.TCPar(clt) -> ")"^(line_type2c clt) + | PC.TCPar0(clt) -> ")"^(line_type2c clt) + + | PC.TOBrace(clt) -> "{"^(line_type2c clt) + | PC.TCBrace(clt) -> "}"^(line_type2c clt) + | PC.TOCro(clt) -> "["^(line_type2c clt) + | PC.TCCro(clt) -> "]"^(line_type2c clt) + + | PC.TPtrOp(clt) -> "->"^(line_type2c clt) + + | PC.TEq(clt) -> "="^(line_type2c clt) + | PC.TAssign(_,clt) -> "=op"^(line_type2c clt) + | PC.TDot(clt) -> "."^(line_type2c clt) + | PC.TComma(clt) -> ","^(line_type2c clt) + | PC.TPtVirg(clt) -> ";"^(line_type2c clt) + + | PC.EOF -> "eof" + | PC.TLineEnd(clt) -> "line end" + | PC.TInvalid -> "invalid" + | PC.TFunDecl(clt) -> "fundecl" + + | PC.TIso -> "<=>" + | PC.TRightIso -> "=>" + | PC.TIsoTopLevel -> "TopLevel" + | PC.TIsoExpression -> "Expression" + | PC.TIsoArgExpression -> "ArgExpression" + | PC.TIsoTestExpression -> "TestExpression" + | PC.TIsoStatement -> "Statement" + | PC.TIsoDeclaration -> "Declaration" + | PC.TIsoType -> "Type" + | PC.TScriptData s -> s + +let print_tokens s tokens = + Printf.printf "%s\n" s; + List.iter (function x -> Printf.printf "%s " (token2c x)) tokens; + Printf.printf "\n\n"; + flush stdout + +type plus = PLUS | NOTPLUS | SKIP + +let plus_attachable (tok,_) = + match tok with + PC.Tchar(clt) | PC.Tshort(clt) | PC.Tint(clt) | PC.Tdouble(clt) + | PC.Tfloat(clt) | PC.Tlong(clt) | PC.Tvoid(clt) | PC.Tstruct(clt) + | PC.Tunion(clt) | PC.Tunsigned(clt) | PC.Tsigned(clt) | PC.Tstatic(clt) + | PC.Tinline(clt) | PC.Ttypedef(clt) | PC.Tattr(_,clt) + | PC.Tauto(clt) | PC.Tregister(clt) + | PC.Textern(clt) | PC.Tconst(clt) | PC.Tvolatile(clt) + + | PC.TIncludeL(_,clt) | PC.TIncludeNL(_,clt) | PC.TDefine(clt,_) + | PC.TDefineParam(clt,_,_) | PC.TMinusFile(_,clt) | PC.TPlusFile(_,clt) + + | PC.TInc(clt) | PC.TDec(clt) + + | PC.TIf(clt) | PC.TElse(clt) | PC.TWhile(clt) | PC.TFor(clt) | PC.TDo(clt) + | PC.TSwitch(clt) | PC.TCase(clt) | PC.TDefault(clt) | PC.TReturn(clt) + | PC.TBreak(clt) | PC.TContinue(clt) | PC.TGoto(clt) | PC.TIdent(_,clt) + | PC.TTypeId(_,clt) | PC.TDeclarerId(_,clt) | PC.TIteratorId(_,clt) + + | PC.TSizeof(clt) + + | PC.TString(_,clt) | PC.TChar(_,clt) | PC.TFloat(_,clt) | PC.TInt(_,clt) + + | PC.TOrLog(clt) | PC.TAndLog(clt) | PC.TOr(clt) | PC.TXor(clt) + | PC.TAnd (clt) | PC.TEqEq(clt) | PC.TNotEq(clt) | PC.TLogOp(_,clt) + | PC.TShOp(_,clt) | PC.TPlus(clt) | PC.TMinus(clt) | PC.TMul(clt) + | PC.TDmOp(_,clt) | PC.TTilde (clt) + + | PC.TMetaParam(_,_,clt) | PC.TMetaParamList(_,_,_,clt) + | PC.TMetaConst(_,_,_,_,clt) | PC.TMetaErr(_,_,_,clt) + | PC.TMetaExp(_,_,_,_,clt) | PC.TMetaIdExp(_,_,_,_,clt) + | PC.TMetaLocalIdExp(_,_,_,_,clt) + | PC.TMetaExpList(_,_,_,clt) + | PC.TMetaId(_,_,_,clt) + | PC.TMetaType(_,_,clt) | PC.TMetaStm(_,_,clt) + | PC.TMetaStmList(_,_,clt) | PC.TMetaFunc(_,_,_,clt) + | PC.TMetaLocalFunc(_,_,_,clt) + + | PC.TWhen(clt) | PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt) + (* | PC.TCircles(clt) | PC.TStars(clt) *) + + | PC.TWhy(clt) | PC.TDotDot(clt) | PC.TBang(clt) | PC.TOPar(clt) + | PC.TCPar(clt) + + | PC.TOBrace(clt) | PC.TCBrace(clt) | PC.TOCro(clt) | PC.TCCro(clt) + + | PC.TPtrOp(clt) + + | PC.TEq(clt) | PC.TAssign(_,clt) | PC.TDot(clt) | PC.TComma(clt) + | PC.TPtVirg(clt) -> + if line_type clt = D.PLUS then PLUS else NOTPLUS + + | PC.TOPar0(clt) | PC.TMid0(clt) | PC.TCPar0(clt) + | PC.TOEllipsis(clt) | PC.TCEllipsis(clt) + | PC.TPOEllipsis(clt) | PC.TPCEllipsis(clt) (* | PC.TOCircles(clt) + | PC.TCCircles(clt) | PC.TOStars(clt) | PC.TCStars(clt) *) -> NOTPLUS + | PC.TMetaPos(nm,_,_,_) -> NOTPLUS + + | _ -> SKIP + +let get_clt (tok,_) = + match tok with + PC.Tchar(clt) | PC.Tshort(clt) | PC.Tint(clt) | PC.Tdouble(clt) + | PC.Tfloat(clt) | PC.Tlong(clt) | PC.Tvoid(clt) | PC.Tstruct(clt) + | PC.Tunion(clt) | PC.Tunsigned(clt) | PC.Tsigned(clt) | PC.Tstatic(clt) + | PC.Tinline(clt) | PC.Tattr(_,clt) | PC.Tauto(clt) | PC.Tregister(clt) + | PC.Textern(clt) | PC.Tconst(clt) | PC.Tvolatile(clt) + + | PC.TIncludeL(_,clt) | PC.TIncludeNL(_,clt) | PC.TDefine(clt,_) + | PC.TDefineParam(clt,_,_) | PC.TMinusFile(_,clt) | PC.TPlusFile(_,clt) + + | PC.TInc(clt) | PC.TDec(clt) + + | PC.TIf(clt) | PC.TElse(clt) | PC.TWhile(clt) | PC.TFor(clt) | PC.TDo(clt) + | PC.TSwitch(clt) | PC.TCase(clt) | PC.TDefault(clt) | PC.TReturn(clt) + | PC.TBreak(clt) | PC.TContinue(clt) | PC.TGoto(clt) | PC.TIdent(_,clt) + | PC.TTypeId(_,clt) | PC.TDeclarerId(_,clt) | PC.TIteratorId(_,clt) + + | PC.TSizeof(clt) + + | PC.TString(_,clt) | PC.TChar(_,clt) | PC.TFloat(_,clt) | PC.TInt(_,clt) + + | PC.TOrLog(clt) | PC.TAndLog(clt) | PC.TOr(clt) | PC.TXor(clt) + | PC.TAnd (clt) | PC.TEqEq(clt) | PC.TNotEq(clt) | PC.TLogOp(_,clt) + | PC.TShOp(_,clt) | PC.TPlus(clt) | PC.TMinus(clt) | PC.TMul(clt) + | PC.TDmOp(_,clt) | PC.TTilde (clt) + + | PC.TMetaParam(_,_,clt) | PC.TMetaParamList(_,_,_,clt) + | PC.TMetaConst(_,_,_,_,clt) | PC.TMetaErr(_,_,_,clt) + | PC.TMetaExp(_,_,_,_,clt) | PC.TMetaIdExp(_,_,_,_,clt) + | PC.TMetaLocalIdExp(_,_,_,_,clt) + | PC.TMetaExpList(_,_,_,clt) + | PC.TMetaId(_,_,_,clt) + | PC.TMetaType(_,_,clt) | PC.TMetaStm(_,_,clt) + | PC.TMetaStmList(_,_,clt) | PC.TMetaFunc(_,_,_,clt) + | PC.TMetaLocalFunc(_,_,_,clt) | PC.TMetaPos(_,_,_,clt) + + | PC.TWhen(clt) | PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt) + (* | PC.TCircles(clt) | PC.TStars(clt) *) + + | PC.TWhy(clt) | PC.TDotDot(clt) | PC.TBang(clt) | PC.TOPar(clt) + | PC.TCPar(clt) + + | PC.TOBrace(clt) | PC.TCBrace(clt) | PC.TOCro(clt) | PC.TCCro(clt) + + | PC.TPtrOp(clt) + + | PC.TEq(clt) | PC.TAssign(_,clt) | PC.TDot(clt) | PC.TComma(clt) + | PC.TPtVirg(clt) + + | PC.TOPar0(clt) | PC.TMid0(clt) | PC.TCPar0(clt) + | PC.TOEllipsis(clt) | PC.TCEllipsis(clt) + | PC.TPOEllipsis(clt) | PC.TPCEllipsis(clt) (* | PC.TOCircles(clt) + | PC.TCCircles(clt) | PC.TOStars(clt) | PC.TCStars(clt) *) -> clt + + | _ -> failwith "no clt" + +let update_clt (tok,x) clt = + match tok with + PC.Tchar(_) -> (PC.Tchar(clt),x) + | PC.Tshort(_) -> (PC.Tshort(clt),x) + | PC.Tint(_) -> (PC.Tint(clt),x) + | PC.Tdouble(_) -> (PC.Tdouble(clt),x) + | PC.Tfloat(_) -> (PC.Tfloat(clt),x) + | PC.Tlong(_) -> (PC.Tlong(clt),x) + | PC.Tvoid(_) -> (PC.Tvoid(clt),x) + | PC.Tstruct(_) -> (PC.Tstruct(clt),x) + | PC.Tunion(_) -> (PC.Tunion(clt),x) + | PC.Tunsigned(_) -> (PC.Tunsigned(clt),x) + | PC.Tsigned(_) -> (PC.Tsigned(clt),x) + | PC.Tstatic(_) -> (PC.Tstatic(clt),x) + | PC.Tinline(_) -> (PC.Tinline(clt),x) + | PC.Ttypedef(_) -> (PC.Ttypedef(clt),x) + | PC.Tattr(s,_) -> (PC.Tattr(s,clt),x) + | PC.Tauto(_) -> (PC.Tauto(clt),x) + | PC.Tregister(_) -> (PC.Tregister(clt),x) + | PC.Textern(_) -> (PC.Textern(clt),x) + | PC.Tconst(_) -> (PC.Tconst(clt),x) + | PC.Tvolatile(_) -> (PC.Tvolatile(clt),x) + + | PC.TIncludeL(s,_) -> (PC.TIncludeL(s,clt),x) + | PC.TIncludeNL(s,_) -> (PC.TIncludeNL(s,clt),x) + | PC.TDefine(_,a) -> (PC.TDefine(clt,a),x) + | PC.TDefineParam(_,a,b) -> (PC.TDefineParam(clt,a,b),x) + | PC.TMinusFile(s,_) -> (PC.TMinusFile(s,clt),x) + | PC.TPlusFile(s,_) -> (PC.TPlusFile(s,clt),x) + + | PC.TInc(_) -> (PC.TInc(clt),x) + | PC.TDec(_) -> (PC.TDec(clt),x) + + | PC.TIf(_) -> (PC.TIf(clt),x) + | PC.TElse(_) -> (PC.TElse(clt),x) + | PC.TWhile(_) -> (PC.TWhile(clt),x) + | PC.TFor(_) -> (PC.TFor(clt),x) + | PC.TDo(_) -> (PC.TDo(clt),x) + | PC.TSwitch(_) -> (PC.TSwitch(clt),x) + | PC.TCase(_) -> (PC.TCase(clt),x) + | PC.TDefault(_) -> (PC.TDefault(clt),x) + | PC.TReturn(_) -> (PC.TReturn(clt),x) + | PC.TBreak(_) -> (PC.TBreak(clt),x) + | PC.TContinue(_) -> (PC.TContinue(clt),x) + | PC.TGoto(_) -> (PC.TGoto(clt),x) + | PC.TIdent(s,_) -> (PC.TIdent(s,clt),x) + | PC.TTypeId(s,_) -> (PC.TTypeId(s,clt),x) + | PC.TDeclarerId(s,_) -> (PC.TDeclarerId(s,clt),x) + | PC.TIteratorId(s,_) -> (PC.TIteratorId(s,clt),x) + + | PC.TSizeof(_) -> (PC.TSizeof(clt),x) + + | PC.TString(s,_) -> (PC.TString(s,clt),x) + | PC.TChar(s,_) -> (PC.TChar(s,clt),x) + | PC.TFloat(s,_) -> (PC.TFloat(s,clt),x) + | PC.TInt(s,_) -> (PC.TInt(s,clt),x) + + | PC.TOrLog(_) -> (PC.TOrLog(clt),x) + | PC.TAndLog(_) -> (PC.TAndLog(clt),x) + | PC.TOr(_) -> (PC.TOr(clt),x) + | PC.TXor(_) -> (PC.TXor(clt),x) + | PC.TAnd (_) -> (PC.TAnd (clt),x) + | PC.TEqEq(_) -> (PC.TEqEq(clt),x) + | PC.TNotEq(_) -> (PC.TNotEq(clt),x) + | PC.TLogOp(op,_) -> (PC.TLogOp(op,clt),x) + | PC.TShOp(op,_) -> (PC.TShOp(op,clt),x) + | PC.TPlus(_) -> (PC.TPlus(clt),x) + | PC.TMinus(_) -> (PC.TMinus(clt),x) + | PC.TMul(_) -> (PC.TMul(clt),x) + | PC.TDmOp(op,_) -> (PC.TDmOp(op,clt),x) + | PC.TTilde (_) -> (PC.TTilde (clt),x) + + | PC.TMetaParam(a,b,_) -> (PC.TMetaParam(a,b,clt),x) + | PC.TMetaParamList(a,b,c,_) -> (PC.TMetaParamList(a,b,c,clt),x) + | PC.TMetaConst(a,b,c,d,_) -> (PC.TMetaConst(a,b,c,d,clt),x) + | PC.TMetaErr(a,b,c,_) -> (PC.TMetaErr(a,b,c,clt),x) + | PC.TMetaExp(a,b,c,d,_) -> (PC.TMetaExp(a,b,c,d,clt),x) + | PC.TMetaIdExp(a,b,c,d,_) -> (PC.TMetaIdExp(a,b,c,d,clt),x) + | PC.TMetaLocalIdExp(a,b,c,d,_) -> (PC.TMetaLocalIdExp(a,b,c,d,clt),x) + | PC.TMetaExpList(a,b,c,_) -> (PC.TMetaExpList(a,b,c,clt),x) + | PC.TMetaId(a,b,c,_) -> (PC.TMetaId(a,b,c,clt),x) + | PC.TMetaType(a,b,_) -> (PC.TMetaType(a,b,clt),x) + | PC.TMetaStm(a,b,_) -> (PC.TMetaStm(a,b,clt),x) + | PC.TMetaStmList(a,b,_) -> (PC.TMetaStmList(a,b,clt),x) + | PC.TMetaFunc(a,b,c,_) -> (PC.TMetaFunc(a,b,c,clt),x) + | PC.TMetaLocalFunc(a,b,c,_) -> (PC.TMetaLocalFunc(a,b,c,clt),x) + + | PC.TWhen(_) -> (PC.TWhen(clt),x) + | PC.TAny(_) -> (PC.TAny(clt),x) + | PC.TStrict(_) -> (PC.TStrict(clt),x) + | PC.TEllipsis(_) -> (PC.TEllipsis(clt),x) +(* + | PC.TCircles(_) -> (PC.TCircles(clt),x) + | PC.TStars(_) -> (PC.TStars(clt),x) +*) + + | PC.TOEllipsis(_) -> (PC.TOEllipsis(clt),x) + | PC.TCEllipsis(_) -> (PC.TCEllipsis(clt),x) + | PC.TPOEllipsis(_) -> (PC.TPOEllipsis(clt),x) + | PC.TPCEllipsis(_) -> (PC.TPCEllipsis(clt),x) +(* + | PC.TOCircles(_) -> (PC.TOCircles(clt),x) + | PC.TCCircles(_) -> (PC.TCCircles(clt),x) + | PC.TOStars(_) -> (PC.TOStars(clt),x) + | PC.TCStars(_) -> (PC.TCStars(clt),x) +*) + + | PC.TWhy(_) -> (PC.TWhy(clt),x) + | PC.TDotDot(_) -> (PC.TDotDot(clt),x) + | PC.TBang(_) -> (PC.TBang(clt),x) + | PC.TOPar(_) -> (PC.TOPar(clt),x) + | PC.TOPar0(_) -> (PC.TOPar0(clt),x) + | PC.TMid0(_) -> (PC.TMid0(clt),x) + | PC.TCPar(_) -> (PC.TCPar(clt),x) + | PC.TCPar0(_) -> (PC.TCPar0(clt),x) + + | PC.TOBrace(_) -> (PC.TOBrace(clt),x) + | PC.TCBrace(_) -> (PC.TCBrace(clt),x) + | PC.TOCro(_) -> (PC.TOCro(clt),x) + | PC.TCCro(_) -> (PC.TCCro(clt),x) + + | PC.TPtrOp(_) -> (PC.TPtrOp(clt),x) + + | PC.TEq(_) -> (PC.TEq(clt),x) + | PC.TAssign(s,_) -> (PC.TAssign(s,clt),x) + | PC.TDot(_) -> (PC.TDot(clt),x) + | PC.TComma(_) -> (PC.TComma(clt),x) + | PC.TPtVirg(_) -> (PC.TPtVirg(clt),x) + + | PC.TLineEnd(_) -> (PC.TLineEnd(clt),x) + | PC.TFunDecl(_) -> (PC.TFunDecl(clt),x) + + | _ -> failwith "no clt" + + +(* ----------------------------------------------------------------------- *) + +let make_name prefix ln = Printf.sprintf "%s starting on line %d" prefix ln + +(* ----------------------------------------------------------------------- *) +(* Read tokens *) + +let wrap_lexbuf_info lexbuf = + (Lexing.lexeme lexbuf, Lexing.lexeme_start lexbuf) + +let tokens_all_full token table file get_ats lexbuf end_markers : + (bool * ((PC.token * (string * (int * int) * (int * int))) list)) = + try + let rec aux () = + let result = token lexbuf in + let info = (Lexing.lexeme lexbuf, + (table.(Lexing.lexeme_start lexbuf)), + (Lexing.lexeme_start lexbuf, Lexing.lexeme_end lexbuf)) in + if result = PC.EOF + then + if get_ats + then failwith "unexpected end of file in a metavariable declaration" + else (false,[(result,info)]) + else if List.mem result end_markers + then (true,[(result,info)]) + else + let (more,rest) = aux() in + (more,(result, info)::rest) + in aux () + with + e -> pr2 (Common.error_message file (wrap_lexbuf_info lexbuf) ); raise e + +let tokens_all table file get_ats lexbuf end_markers : + (bool * ((PC.token * (string * (int * int) * (int * int))) list)) = + tokens_all_full Lexer_cocci.token table file get_ats lexbuf end_markers + +let tokens_script_all table file get_ats lexbuf end_markers : + (bool * ((PC.token * (string * (int * int) * (int * int))) list)) = + tokens_all_full Lexer_script.token table file get_ats lexbuf end_markers + +(* ----------------------------------------------------------------------- *) +(* Split tokens into minus and plus fragments *) + +let split t clt = + let (d,_,_,_,_,_,_,_) = clt in + match d with + D.MINUS | D.OPTMINUS | D.UNIQUEMINUS -> ([t],[]) + | D.PLUS -> ([],[t]) + | D.CONTEXT | D.UNIQUE | D.OPT -> ([t],[t]) + +let split_token ((tok,_) as t) = + match tok with + PC.TIdentifier | PC.TConstant | PC.TExpression | PC.TIdExpression + | PC.TStatement | PC.TPosition | PC.TPosAny + | PC.TFunction | PC.TTypedef | PC.TDeclarer | PC.TIterator | PC.TName + | PC.TType | PC.TParameter | PC.TLocal | PC.Tlist | PC.TFresh | PC.TPure + | PC.TContext | PC.TRuleName(_) | PC.TUsing | PC.TDisable | PC.TExtends + | PC.TPathIsoFile(_) + | PC.TDepends | PC.TOn | PC.TEver | PC.TNever | PC.TExists | PC.TForall + | PC.TReverse + | PC.TError | PC.TWords | PC.TNothing -> ([t],[t]) + + | PC.Tchar(clt) | PC.Tshort(clt) | PC.Tint(clt) | PC.Tdouble(clt) + | PC.Tfloat(clt) | PC.Tlong(clt) | PC.Tvoid(clt) | PC.Tstruct(clt) + | PC.Tunion(clt) | PC.Tunsigned(clt) | PC.Tsigned(clt) + | PC.Tstatic(clt) | PC.Tauto(clt) | PC.Tregister(clt) | PC.Textern(clt) + | PC.Tinline(clt) | PC.Ttypedef(clt) | PC.Tattr(_,clt) + | PC.Tconst(clt) | PC.Tvolatile(clt) -> split t clt + + | PC.TPragma(s) -> ([],[t]) (* only allowed in + *) + | PC.TPlusFile(s,clt) | PC.TMinusFile(s,clt) + | PC.TIncludeL(s,clt) | PC.TIncludeNL(s,clt) -> + split t clt + | PC.TDefine(clt,_) | PC.TDefineParam(clt,_,_) -> split t clt + + | PC.TIf(clt) | PC.TElse(clt) | PC.TWhile(clt) | PC.TFor(clt) | PC.TDo(clt) + | PC.TSwitch(clt) | PC.TCase(clt) | PC.TDefault(clt) + | PC.TSizeof(clt) + | PC.TReturn(clt) | PC.TBreak(clt) | PC.TContinue(clt) | PC.TGoto(clt) + | PC.TIdent(_,clt) + | PC.TTypeId(_,clt) | PC.TDeclarerId(_,clt) | PC.TIteratorId(_,clt) + | PC.TMetaConst(_,_,_,_,clt) | PC.TMetaExp(_,_,_,_,clt) + | PC.TMetaIdExp(_,_,_,_,clt) | PC.TMetaLocalIdExp(_,_,_,_,clt) + | PC.TMetaExpList(_,_,_,clt) + | PC.TMetaParam(_,_,clt) | PC.TMetaParamList(_,_,_,clt) + | PC.TMetaId(_,_,_,clt) | PC.TMetaType(_,_,clt) + | PC.TMetaStm(_,_,clt) | PC.TMetaStmList(_,_,clt) | PC.TMetaErr(_,_,_,clt) + | PC.TMetaFunc(_,_,_,clt) | PC.TMetaLocalFunc(_,_,_,clt) + | PC.TMetaDeclarer(_,_,_,clt) | PC.TMetaIterator(_,_,_,clt) -> split t clt + | PC.TMPtVirg | PC.TArob | PC.TArobArob -> ([t],[t]) + | PC.TPArob | PC.TMetaPos(_,_,_,_) -> ([t],[]) + + | PC.TFunDecl(clt) + | PC.TWhen(clt) | PC.TAny(clt) | PC.TStrict(clt) | PC.TLineEnd(clt) + | PC.TEllipsis(clt) (* | PC.TCircles(clt) | PC.TStars(clt) *) -> split t clt + + | PC.TOEllipsis(_) | PC.TCEllipsis(_) (* clt must be context *) + | PC.TPOEllipsis(_) | PC.TPCEllipsis(_) (* clt must be context *) +(* + | PC.TOCircles(_) | PC.TCCircles(_) (* clt must be context *) + | PC.TOStars(_) | PC.TCStars(_) (* clt must be context *) +*) + | PC.TBang0 | PC.TPlus0 | PC.TWhy0 -> + ([t],[t]) + + | PC.TWhy(clt) | PC.TDotDot(clt) + | PC.TBang(clt) | PC.TOPar(clt) | PC.TOPar0(clt) + | PC.TMid0(clt) | PC.TCPar(clt) | PC.TCPar0(clt) -> split t clt + + | PC.TInc(clt) | PC.TDec(clt) -> split t clt + + | PC.TString(_,clt) | PC.TChar(_,clt) | PC.TFloat(_,clt) | PC.TInt(_,clt) -> + split t clt + + | PC.TOrLog(clt) | PC.TAndLog(clt) | PC.TOr(clt) | PC.TXor(clt) + | PC.TAnd (clt) | PC.TEqEq(clt) | PC.TNotEq(clt) | PC.TLogOp(_,clt) + | PC.TShOp(_,clt) | PC.TPlus(clt) | PC.TMinus(clt) | PC.TMul(clt) + | PC.TDmOp(_,clt) | PC.TTilde (clt) -> split t clt + + | PC.TOBrace(clt) | PC.TCBrace(clt) -> split t clt + | PC.TOCro(clt) | PC.TCCro(clt) -> split t clt + + | PC.TPtrOp(clt) -> split t clt + + | PC.TEq(clt) | PC.TAssign(_,clt) | PC.TDot(clt) | PC.TComma(clt) + | PC.TPtVirg(clt) -> split t clt + + | PC.EOF | PC.TInvalid -> ([t],[t]) + + | PC.TIso | PC.TRightIso + | PC.TIsoExpression | PC.TIsoStatement | PC.TIsoDeclaration | PC.TIsoType + | PC.TIsoTopLevel | PC.TIsoArgExpression | PC.TIsoTestExpression -> + failwith "unexpected tokens" + | PC.TScriptData s -> ([t],[t]) + +let split_token_stream tokens = + let rec loop = function + [] -> ([],[]) + | token::tokens -> + let (minus,plus) = split_token token in + let (minus_stream,plus_stream) = loop tokens in + (minus@minus_stream,plus@plus_stream) in + loop tokens + +(* ----------------------------------------------------------------------- *) +(* Find function names *) +(* This addresses a shift-reduce problem in the parser, allowing us to +distinguish a function declaration from a function call even if the latter +has no return type. Undoubtedly, this is not very nice, but it doesn't +seem very convenient to refactor the grammar to get around the problem. *) + +let rec find_function_names = function + [] -> [] + | ((PC.TIdent(_,clt),info) as t1) :: ((PC.TOPar(_),_) as t2) :: rest + | ((PC.TMetaId(_,_,_,clt),info) as t1) :: ((PC.TOPar(_),_) as t2) :: rest + | ((PC.TMetaFunc(_,_,_,clt),info) as t1) :: ((PC.TOPar(_),_) as t2) :: rest + | ((PC.TMetaLocalFunc(_,_,_,clt),info) as t1)::((PC.TOPar(_),_) as t2)::rest + -> + let rec skip level = function + [] -> ([],false,[]) + | ((PC.TCPar(_),_) as t)::rest -> + let level = level - 1 in + if level = 0 + then ([t],true,rest) + else let (pre,found,post) = skip level rest in (t::pre,found,post) + | ((PC.TOPar(_),_) as t)::rest -> + let level = level + 1 in + let (pre,found,post) = skip level rest in (t::pre,found,post) + | ((PC.TArobArob,_) as t)::rest + | ((PC.TArob,_) as t)::rest + | ((PC.EOF,_) as t)::rest -> ([t],false,rest) + | t::rest -> + let (pre,found,post) = skip level rest in (t::pre,found,post) in + let (pre,found,post) = skip 1 rest in + (match (found,post) with + (true,((PC.TOBrace(_),_) as t3)::rest) -> + (PC.TFunDecl(clt),info) :: t1 :: t2 :: pre @ + t3 :: (find_function_names rest) + | _ -> t1 :: t2 :: pre @ find_function_names post) + | t :: rest -> t :: find_function_names rest + +(* ----------------------------------------------------------------------- *) +(* an attribute is an identifier that preceeds another identifier and + begins with __ *) + +let rec detect_attr l = + let is_id = function + (PC.TIdent(_,_),_) | (PC.TMetaId(_,_,_,_),_) | (PC.TMetaFunc(_,_,_,_),_) + | (PC.TMetaLocalFunc(_,_,_,_),_) -> true + | _ -> false in + let rec loop = function + [] -> [] + | [x] -> [x] + | ((PC.TIdent(nm,clt),info) as t1)::id::rest when is_id id -> + if String.length nm > 2 && String.sub nm 0 2 = "__" + then (PC.Tattr(nm,clt),info)::(loop (id::rest)) + else t1::(loop (id::rest)) + | x::xs -> x::(loop xs) in + loop l + +(* ----------------------------------------------------------------------- *) +(* Look for variable declarations where the name is a typedef name. +We assume that C code does not contain a multiplication as a top-level +statement. *) + +(* bug: once a type, always a type, even if the same name is later intended + to be used as a real identifier *) +let detect_types in_meta_decls l = + let is_delim infn = function + (PC.TOEllipsis(_),_) (* | (PC.TOCircles(_),_) | (PC.TOStars(_),_) *) + | (PC.TPOEllipsis(_),_) (* | (PC.TOCircles(_),_) | (PC.TOStars(_),_) *) + | (PC.TEllipsis(_),_) (* | (PC.TCircles(_),_) | (PC.TStars(_),_) *) + | (PC.TPtVirg(_),_) | (PC.TOBrace(_),_) | (PC.TCBrace(_),_) + | (PC.TPure,_) | (PC.TContext,_) + | (PC.Tstatic(_),_) | (PC.Textern(_),_) + | (PC.Tinline(_),_) | (PC.Ttypedef(_),_) | (PC.Tattr(_),_) -> true + | (PC.TComma(_),_) when infn > 0 or in_meta_decls -> true + | (PC.TDotDot(_),_) when in_meta_decls -> true + | _ -> false in + let is_choices_delim = function + (PC.TOBrace(_),_) | (PC.TComma(_),_) -> true | _ -> false in + let is_id = function + (PC.TIdent(_,_),_) | (PC.TMetaId(_,_,_,_),_) | (PC.TMetaFunc(_,_,_,_),_) + | (PC.TMetaLocalFunc(_,_,_,_),_) -> true + | (PC.TMetaParam(_,_,_),_) + | (PC.TMetaParamList(_,_,_,_),_) + | (PC.TMetaConst(_,_,_,_,_),_) + | (PC.TMetaErr(_,_,_,_),_) + | (PC.TMetaExp(_,_,_,_,_),_) + | (PC.TMetaIdExp(_,_,_,_,_),_) + | (PC.TMetaLocalIdExp(_,_,_,_,_),_) + | (PC.TMetaExpList(_,_,_,_),_) + | (PC.TMetaType(_,_,_),_) + | (PC.TMetaStm(_,_,_),_) + | (PC.TMetaStmList(_,_,_),_) + | (PC.TMetaPos(_,_,_,_),_) -> in_meta_decls + | _ -> false in + let redo_id ident clt v = + !Data.add_type_name ident; + (PC.TTypeId(ident,clt),v) in + let rec loop start infn type_names = function + (* infn: 0 means not in a function header + > 0 means in a function header, after infn - 1 unmatched open parens*) + [] -> [] + | ((PC.TOBrace(clt),v)::_) as all when in_meta_decls -> + collect_choices type_names all (* never a function header *) + | delim::(PC.TIdent(ident,clt),v)::((PC.TMul(_),_) as x)::rest + when is_delim infn delim -> + let newid = redo_id ident clt v in + delim::newid::x::(loop false infn (ident::type_names) rest) + | delim::(PC.TIdent(ident,clt),v)::id::rest + when is_delim infn delim && is_id id -> + let newid = redo_id ident clt v in + delim::newid::id::(loop false infn (ident::type_names) rest) + | ((PC.TFunDecl(_),_) as fn)::rest -> + fn::(loop false 1 type_names rest) + | ((PC.TOPar(_),_) as lp)::rest when infn > 0 -> + lp::(loop false (infn + 1) type_names rest) + | ((PC.TCPar(_),_) as rp)::rest when infn > 0 -> + if infn - 1 = 1 + then rp::(loop false 0 type_names rest) (* 0 means not in fn header *) + else rp::(loop false (infn - 1) type_names rest) + | (PC.TIdent(ident,clt),v)::((PC.TMul(_),_) as x)::rest when start -> + let newid = redo_id ident clt v in + newid::x::(loop false infn (ident::type_names) rest) + | (PC.TIdent(ident,clt),v)::id::rest when start && is_id id -> + let newid = redo_id ident clt v in + newid::id::(loop false infn (ident::type_names) rest) + | (PC.TIdent(ident,clt),v)::rest when List.mem ident type_names -> + (PC.TTypeId(ident,clt),v)::(loop false infn type_names rest) + | ((PC.TIdent(ident,clt),v) as x)::rest -> + x::(loop false infn type_names rest) + | x::rest -> x::(loop false infn type_names rest) + and collect_choices type_names = function + [] -> [] (* should happen, but let the parser detect that *) + | (PC.TCBrace(clt),v)::rest -> + (PC.TCBrace(clt),v)::(loop false 0 type_names rest) + | delim::(PC.TIdent(ident,clt),v)::rest + when is_choices_delim delim -> + let newid = redo_id ident clt v in + delim::newid::(collect_choices (ident::type_names) rest) + | x::rest -> x::(collect_choices type_names rest) in + loop true 0 [] l + + +(* ----------------------------------------------------------------------- *) +(* Insert TLineEnd tokens at the end of a line that contains a WHEN. + WHEN is restricted to a single line, to avoid ambiguity in eg: + ... WHEN != x + +3 *) + +let token2line (tok,_) = + match tok with + PC.Tchar(clt) | PC.Tshort(clt) | PC.Tint(clt) | PC.Tdouble(clt) + | PC.Tfloat(clt) | PC.Tlong(clt) | PC.Tvoid(clt) | PC.Tstruct(clt) + | PC.Tunion(clt) | PC.Tunsigned(clt) | PC.Tsigned(clt) + | PC.Tstatic(clt) | PC.Tauto(clt) | PC.Tregister(clt) | PC.Textern(clt) + | PC.Tinline(clt) | PC.Ttypedef(clt) | PC.Tattr(_,clt) | PC.Tconst(clt) + | PC.Tvolatile(clt) + + | PC.TInc(clt) | PC.TDec(clt) + + | PC.TIf(clt) | PC.TElse(clt) | PC.TWhile(clt) | PC.TFor(clt) | PC.TDo(clt) + | PC.TSwitch (clt) | PC.TCase (clt) | PC.TDefault (clt) | PC.TSizeof (clt) + | PC.TReturn(clt) | PC.TBreak(clt) | PC.TContinue(clt) | PC.TGoto(clt) + | PC.TIdent(_,clt) + | PC.TTypeId(_,clt) | PC.TDeclarerId(_,clt) | PC.TIteratorId(_,clt) + | PC.TMetaDeclarer(_,_,_,clt) | PC.TMetaIterator(_,_,_,clt) + + | PC.TString(_,clt) | PC.TChar(_,clt) | PC.TFloat(_,clt) | PC.TInt(_,clt) + + | PC.TOrLog(clt) | PC.TAndLog(clt) | PC.TOr(clt) | PC.TXor(clt) + | PC.TAnd (clt) | PC.TEqEq(clt) | PC.TNotEq(clt) | PC.TLogOp(_,clt) + | PC.TShOp(_,clt) | PC.TPlus(clt) | PC.TMinus(clt) | PC.TMul(clt) + | PC.TDmOp(_,clt) | PC.TTilde (clt) + + | PC.TMetaParam(_,_,clt) | PC.TMetaParamList(_,_,_,clt) + | PC.TMetaConst(_,_,_,_,clt) | PC.TMetaExp(_,_,_,_,clt) + | PC.TMetaIdExp(_,_,_,_,clt) | PC.TMetaLocalIdExp(_,_,_,_,clt) + | PC.TMetaExpList(_,_,_,clt) + | PC.TMetaId(_,_,_,clt) | PC.TMetaType(_,_,clt) + | PC.TMetaStm(_,_,clt) | PC.TMetaStmList(_,_,clt) | PC.TMetaFunc(_,_,_,clt) + | PC.TMetaLocalFunc(_,_,_,clt) | PC.TMetaPos(_,_,_,clt) + + | PC.TFunDecl(clt) + | PC.TWhen(clt) | PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt) + (* | PC.TCircles(clt) | PC.TStars(clt) *) + + | PC.TOEllipsis(clt) | PC.TCEllipsis(clt) + | PC.TPOEllipsis(clt) | PC.TPCEllipsis(clt) (*| PC.TOCircles(clt) + | PC.TCCircles(clt) | PC.TOStars(clt) | PC.TCStars(clt) *) + + | PC.TWhy(clt) | PC.TDotDot(clt) | PC.TBang(clt) | PC.TOPar(clt) + | PC.TOPar0(clt) | PC.TMid0(clt) | PC.TCPar(clt) + | PC.TCPar0(clt) + + | PC.TOBrace(clt) | PC.TCBrace(clt) | PC.TOCro(clt) | PC.TCCro(clt) + + | PC.TPtrOp(clt) + + | PC.TDefine(clt,_) | PC.TDefineParam(clt,_,_) + | PC.TIncludeL(_,clt) | PC.TIncludeNL(_,clt) + + | PC.TEq(clt) | PC.TAssign(_,clt) | PC.TDot(clt) | PC.TComma(clt) + | PC.TPtVirg(clt) -> + let (_,line,_,_,_,_,_,_) = clt in Some line + + | _ -> None + +let rec insert_line_end = function + [] -> [] + | (((PC.TWhen(clt),q) as x)::xs) -> + x::(find_line_end true (token2line x) clt q xs) + | (((PC.TDefine(clt,_),q) as x)::xs) + | (((PC.TDefineParam(clt,_,_),q) as x)::xs) -> + x::(find_line_end false (token2line x) clt q xs) + | x::xs -> x::(insert_line_end xs) + +and find_line_end inwhen line clt q = function + (* don't know what 2nd component should be so just use the info of + the When. Also inherit - of when, if any *) + [] -> [(PC.TLineEnd(clt),q)] + | ((PC.TIdent("strict",clt),a) as x)::xs when token2line x = line -> + (PC.TStrict(clt),a) :: (find_line_end inwhen line clt q xs) + | ((PC.TIdent("STRICT",clt),a) as x)::xs when token2line x = line -> + (PC.TStrict(clt),a) :: (find_line_end inwhen line clt q xs) + | ((PC.TIdent("any",clt),a) as x)::xs when token2line x = line -> + (PC.TAny(clt),a) :: (find_line_end inwhen line clt q xs) + | ((PC.TIdent("ANY",clt),a) as x)::xs when token2line x = line -> + (PC.TAny(clt),a) :: (find_line_end inwhen line clt q xs) + | ((PC.TIdent("forall",clt),a) as x)::xs when token2line x = line -> + (PC.TForall,a) :: (find_line_end inwhen line clt q xs) + | ((PC.TIdent("exists",clt),a) as x)::xs when token2line x = line -> + (PC.TExists,a) :: (find_line_end inwhen line clt q xs) + | ((PC.TComma(clt),a) as x)::xs when token2line x = line -> + (PC.TComma(clt),a) :: (find_line_end inwhen line clt q xs) + | ((PC.TPArob,a) as x)::xs -> (* no line #, just assume on the same line *) + x :: (find_line_end inwhen line clt q xs) + | x::xs when token2line x = line -> x :: (find_line_end inwhen line clt q xs) + | xs -> (PC.TLineEnd(clt),q)::(insert_line_end xs) + +(* ----------------------------------------------------------------------- *) +(* process pragmas: they can only be used in + code, and adjacent to +another + token. They are concatenated to the string representation of +that other token. *) + +let rec collect_all_pragmas collected = function + (PC.TPragma(s),_)::rest -> collect_all_pragmas (s::collected) rest + | l -> (List.rev collected,l) + +let rec collect_up_to_pragmas skipped = function + [] -> None (* didn't reach a pragma, so nothing to do *) + | ((PC.TPragma(s),_) as t)::rest -> + let (pragmas,rest) = collect_all_pragmas [] (t::rest) in + Some (List.rev skipped,pragmas,rest) + | x::xs -> + match plus_attachable x with + PLUS -> None + | NOTPLUS -> None + | SKIP -> collect_up_to_pragmas (x::skipped) xs + +let rec collect_up_to_plus skipped = function + [] -> failwith "nothing to attach a pragma to" + | x::xs -> + match plus_attachable x with + PLUS -> (List.rev skipped,x,xs) + | NOTPLUS -> failwith "nothing to attach a pragma to" + | SKIP -> collect_up_to_plus (x::skipped) xs + +let rec process_pragmas = function + [] -> [] + | ((PC.TPragma(s),_)::_) as l -> + let (pragmas,rest) = collect_all_pragmas [] l in + let (skipped,aft,rest) = collect_up_to_plus [] rest in + let (a,b,c,d,e,strbef,straft,pos) = get_clt aft in + skipped@ + (process_pragmas ((update_clt aft (a,b,c,d,e,pragmas,straft,pos))::rest)) + | bef::xs -> + (match plus_attachable bef with + PLUS -> + (match collect_up_to_pragmas [] xs with + Some(skipped,pragmas,rest) -> + let (a,b,c,d,e,strbef,straft,pos) = get_clt bef in + (update_clt bef (a,b,c,d,e,strbef,pragmas,pos)):: + skipped@(process_pragmas rest) + | None -> bef::(process_pragmas xs)) + | _ -> bef::(process_pragmas xs)) + +(* ----------------------------------------------------------------------- *) +(* Drop ... ... . This is only allowed in + code, and arises when there is +some - code between the ... *) +(* drop whens as well - they serve no purpose in + code and they cause +problems for drop_double_dots *) + +let rec drop_when = function + [] -> [] + | (PC.TWhen(clt),info)::xs -> + let rec loop = function + [] -> [] + | (PC.TLineEnd(_),info)::xs -> drop_when xs + | x::xs -> loop xs in + loop xs + | x::xs -> x::drop_when xs + +(* instead of dropping the double dots, we put TNothing in between them. +these vanish after the parser, but keeping all the ...s in the + code makes +it easier to align the + and - code in context_neg and in preparation for the +isomorphisms. This shouldn't matter because the context code of the + +slice is mostly ignored anyway *) +let rec drop_double_dots l = + let start = function + (PC.TOEllipsis(_),_) | (PC.TPOEllipsis(_),_) + (* | (PC.TOCircles(_),_) | (PC.TOStars(_),_) *) -> + true + | _ -> false in + let middle = function + (PC.TEllipsis(_),_) (* | (PC.TCircles(_),_) | (PC.TStars(_),_) *) -> true + | _ -> false in + let final = function + (PC.TCEllipsis(_),_) | (PC.TPCEllipsis(_),_) + (* | (PC.TCCircles(_),_) | (PC.TCStars(_),_) *) -> + true + | _ -> false in + let rec loop ((_,i) as prev) = function + [] -> [] + | x::rest when middle prev && middle x -> (PC.TNothing,i)::x::(loop x rest) + | x::rest when start prev && middle x -> (PC.TNothing,i)::x::(loop x rest) + | x::rest when start prev && final x -> (PC.TNothing,i)::x::(loop x rest) + | x::rest when middle prev && final x -> (PC.TNothing,i)::x::(loop x rest) + | x::rest -> x :: (loop x rest) in + match l with + [] -> [] + | (x::xs) -> x :: loop x xs + +let rec fix f l = + let cur = f l in + if l = cur then l else fix f cur + +(* ( | ... | ) also causes parsing problems *) + +exception Not_empty + +let rec drop_empty_thing starter middle ender = function + [] -> [] + | hd::rest when starter hd -> + let rec loop = function + x::rest when middle x -> loop rest + | x::rest when ender x -> rest + | _ -> raise Not_empty in + (match try Some(loop rest) with Not_empty -> None with + Some x -> drop_empty_thing starter middle ender x + | None -> hd :: drop_empty_thing starter middle ender rest) + | x::rest -> x :: drop_empty_thing starter middle ender rest + +let drop_empty_or = + drop_empty_thing + (function (PC.TOPar0(_),_) -> true | _ -> false) + (function (PC.TMid0(_),_) -> true | _ -> false) + (function (PC.TCPar0(_),_) -> true | _ -> false) + +let drop_empty_nest = drop_empty_thing + +(* ----------------------------------------------------------------------- *) +(* Read tokens *) + +let get_s_starts (_, (s,_,(starts, ends))) = + Printf.printf "%d %d\n" starts ends; (s, starts) + +let pop2 l = + let v = List.hd !l in + l := List.tl !l; + v + +let reinit _ = + PC.reinit (function _ -> PC.TArobArob (* a handy token *)) + (Lexing.from_function + (function buf -> function n -> raise Common.Impossible)) + +let parse_one str parsefn file toks = + let all_tokens = ref toks in + let cur_tok = ref (List.hd !all_tokens) in + + let lexer_function _ = + let (v, info) = pop2 all_tokens in + cur_tok := (v, info); + v in + + let lexbuf_fake = + Lexing.from_function + (function buf -> function n -> raise Common.Impossible) + in + + reinit(); + + try parsefn lexer_function lexbuf_fake + with + Lexer_cocci.Lexical s -> + failwith + (Printf.sprintf "%s: lexical error: %s\n =%s\n" str s + (Common.error_message file (get_s_starts !cur_tok) )) + | Parser_cocci_menhir.Error -> + failwith + (Printf.sprintf "%s: parse error: \n = %s\n" str + (Common.error_message file (get_s_starts !cur_tok) )) + | Semantic_cocci.Semantic s -> + failwith + (Printf.sprintf "%s: semantic error: %s\n =%s\n" str s + (Common.error_message file (get_s_starts !cur_tok) )) + + | e -> raise e + +let prepare_tokens tokens = + insert_line_end + (detect_types false (find_function_names (detect_attr tokens))) + +let rec consume_minus_positions = function + [] -> [] + | x::(PC.TPArob,_)::(PC.TMetaPos(name,constraints,per,clt),_)::xs -> + let (arity,ln,lln,offset,col,strbef,straft,_) = get_clt x in + let name = Parse_aux.clt2mcode name clt in + let x = + update_clt x + (arity,ln,lln,offset,col,strbef,straft, + Ast0.MetaPos(name,constraints,per)) in + x::(consume_minus_positions xs) + | x::xs -> x::consume_minus_positions xs + +let any_modif rule = + let mcode x = + match Ast0.get_mcode_mcodekind x with + Ast0.MINUS _ | Ast0.PLUS -> true + | _ -> false in + let donothing r k e = k e in + let bind x y = x or y in + let option_default = false 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 + List.exists fn.V0.combiner_top_level rule + +let drop_last extra l = List.rev(extra@(List.tl(List.rev l))) + +let partition_either l = + let rec part_either left right = function + | [] -> (List.rev left, List.rev right) + | x :: l -> + (match x with + | Common.Left e -> part_either (e :: left) right l + | Common.Right e -> part_either left (e :: right) l) in + part_either [] [] l + +let get_metavars parse_fn table file lexbuf = + let rec meta_loop acc (* read one decl at a time *) = + let (_,tokens) = + tokens_all table file true lexbuf [PC.TArobArob;PC.TMPtVirg] in + let tokens = prepare_tokens tokens in + match tokens with + [(PC.TArobArob,_)] -> List.rev acc + | _ -> + let metavars = parse_one "meta" parse_fn file tokens in + meta_loop (metavars@acc) in + partition_either (meta_loop []) + +let get_script_metavars parse_fn table file lexbuf = + let rec meta_loop acc = + let (_, tokens) = + tokens_all table file true lexbuf [PC.TArobArob; PC.TMPtVirg] in + let tokens = prepare_tokens tokens in + match tokens with + [(PC.TArobArob, _)] -> List.rev acc + | _ -> + let metavar = parse_one "scriptmeta" parse_fn file tokens in + meta_loop (metavar :: acc) + in + meta_loop [] + +let get_rule_name parse_fn starts_with_name get_tokens file prefix = + Data.in_rule_name := true; + let mknm _ = make_name prefix (!Lexer_cocci.line) in + let name_res = + if starts_with_name + then + let (_,tokens) = get_tokens [PC.TArob] in + match parse_one "rule name" parse_fn file tokens with + Ast.CocciRulename (None,a,b,c,d,e) -> + Ast.CocciRulename (Some (mknm()),a,b,c,d,e) + | Ast.CocciRulename (Some nm,a,b,c,d,e) -> + (if List.mem nm reserved_names + then failwith (Printf.sprintf "invalid name %s\n" nm)); + Ast.CocciRulename (Some nm,a,b,c,d,e) + | Ast.ScriptRulename(s,deps) -> Ast.ScriptRulename(s,deps) + else + Ast.CocciRulename(Some(mknm()),Ast.NoDep,[],[],Ast.Undetermined,false) in + Data.in_rule_name := false; + name_res + +let parse_iso file = + let table = Common.full_charpos_to_pos file in + Common.with_open_infile file (fun channel -> + let lexbuf = Lexing.from_channel channel in + let get_tokens = tokens_all table file false lexbuf in + let res = + match get_tokens [PC.TArobArob;PC.TArob] with + (true,start) -> + let parse_start start = + let rev = List.rev start in + let (arob,_) = List.hd rev in + (arob = PC.TArob,List.rev(List.tl rev)) in + let (starts_with_name,start) = parse_start start in + let rec loop starts_with_name start = + (!Data.init_rule)(); + (* get metavariable declarations - have to be read before the + rest *) + let (rule_name,_,_,_,_,_) = + match get_rule_name PC.iso_rule_name starts_with_name get_tokens + file ("iso file "^file) with + Ast.CocciRulename (Some n,a,b,c,d,e) -> (n,a,b,c,d,e) + | _ -> failwith "Script rules cannot appear in isomorphism rules" + in + Ast0.rule_name := rule_name; + Data.in_meta := true; + let iso_metavars = + match get_metavars PC.iso_meta_main table file lexbuf with + (iso_metavars,[]) -> iso_metavars + | _ -> failwith "unexpected inheritance in iso" in + Data.in_meta := false; + (* get the rule *) + let (more,tokens) = + get_tokens + [PC.TIsoStatement;PC.TIsoExpression;PC.TIsoArgExpression; + PC.TIsoTestExpression; + PC.TIsoDeclaration;PC.TIsoType;PC.TIsoTopLevel] in + let next_start = List.hd(List.rev tokens) in + let dummy_info = ("",(-1,-1),(-1,-1)) in + let tokens = drop_last [(PC.EOF,dummy_info)] tokens in + let tokens = prepare_tokens (start@tokens) in + (* + print_tokens "iso tokens" tokens; + *) + let entry = parse_one "iso main" PC.iso_main file tokens in + let entry = List.map (List.map Test_exps.process_anything) entry in + if more + then (* The code below allows a header like Statement list, + which is more than one word. We don't have that any more, + but the code is left here in case it is put back. *) + match get_tokens [PC.TArobArob;PC.TArob] with + (true,start) -> + let (starts_with_name,start) = parse_start start in + (iso_metavars,entry,rule_name) :: + (loop starts_with_name (next_start::start)) + | _ -> failwith "isomorphism ends early" + else [(iso_metavars,entry,rule_name)] in + loop starts_with_name start + | (false,_) -> [] in + res) + +let parse_iso_files existing_isos iso_files extra_path = + let get_names = List.map (function (_,_,nm) -> nm) in + let old_names = get_names existing_isos in + Data.in_iso := true; + let (res,_) = + List.fold_left + (function (prev,names) -> + function file -> + Lexer_cocci.init (); + let file = + match file with + Common.Left(fl) -> Filename.concat extra_path fl + | Common.Right(fl) -> Filename.concat Config.path fl in + let current = parse_iso file in + let new_names = get_names current in + if List.exists (function x -> List.mem x names) new_names + then failwith (Printf.sprintf "repeated iso name found in %s" file); + (current::prev,new_names @ names)) + ([],old_names) iso_files in + Data.in_iso := false; + existing_isos@(List.concat (List.rev res)) + +let parse file = + let table = Common.full_charpos_to_pos file in + Common.with_open_infile file (fun channel -> + let lexbuf = Lexing.from_channel channel in + let get_tokens = tokens_all table file false lexbuf in + Data.in_prolog := true; + let initial_tokens = get_tokens [PC.TArobArob;PC.TArob] in + Data.in_prolog := false; + let res = + match initial_tokens with + (true,data) -> + (match List.rev data with + ((PC.TArobArob as x),_)::_ | ((PC.TArob as x),_)::_ -> + let iso_files = + parse_one "iso file names" PC.include_main file data in + + let parse_cocci_rule old_metas + (rule_name, dependencies, iso, dropiso, exists, is_expression) = + Ast0.rule_name := rule_name; + Data.inheritable_positions := + rule_name :: !Data.inheritable_positions; + + (* get metavariable declarations *) + Data.in_meta := true; + let (metavars, inherited_metavars) = + get_metavars PC.meta_main table file lexbuf in + Data.in_meta := false; + Hashtbl.add Data.all_metadecls rule_name metavars; + Hashtbl.add Lexer_cocci.rule_names rule_name (); + Hashtbl.add Lexer_cocci.all_metavariables rule_name + (Hashtbl.fold + (fun key v rest -> (key,v)::rest) + Lexer_cocci.metavariables []); + + (* get transformation rules *) + let (more, tokens) = get_tokens [PC.TArobArob; PC.TArob] in + let (minus_tokens, plus_tokens) = split_token_stream tokens in + + let minus_tokens = consume_minus_positions minus_tokens in + let minus_tokens = prepare_tokens minus_tokens in + let plus_tokens = prepare_tokens plus_tokens in + + (* + print_tokens "minus tokens" minus_tokens; + print_tokens "plus tokens" plus_tokens; + *) + + let plus_tokens = + process_pragmas + (fix (function x -> drop_double_dots (drop_empty_or x)) + (drop_when plus_tokens)) in + (* + print_tokens "plus tokens" plus_tokens; + Printf.printf "before minus parse\n"; + *) + let minus_res = + if is_expression + then parse_one "minus" PC.minus_exp_main file minus_tokens + else parse_one "minus" PC.minus_main file minus_tokens in + (* + Unparse_ast0.unparse minus_res; + Printf.printf "before plus parse\n"; + *) + let plus_res = + if !Flag.sgrep_mode2 + then (* not actually used for anything, except context_neg *) + List.map + (Iso_pattern.rebuild_mcode None).V0.rebuilder_top_level + minus_res + else + if is_expression + then parse_one "plus" PC.plus_exp_main file plus_tokens + else parse_one "plus" PC.plus_main file plus_tokens in + (* + Printf.printf "after plus parse\n"; + *) + + (if not !Flag.sgrep_mode2 && + (any_modif minus_res or any_modif plus_res) + then Data.inheritable_positions := []); + + Check_meta.check_meta rule_name old_metas inherited_metavars + metavars minus_res plus_res; + + (more, Ast0.CocciRule ((minus_res, metavars, + (iso, dropiso, dependencies, rule_name, exists)), + (plus_res, metavars)), metavars, tokens) in + + let parse_script_rule language old_metas deps = + let get_tokens = tokens_script_all table file false lexbuf in + + (* meta-variables *) + Data.in_meta := true; + let metavars = + get_script_metavars PC.script_meta_main table file lexbuf in + Data.in_meta := false; + + let exists_in old_metas (py,(r,m)) = + let test (rr,mr) x = + let (ro,vo) = Ast.get_meta_name x in + ro = rr && vo = mr in + List.exists (test (r,m)) old_metas in + + List.iter + (function x -> + let meta2c (r,n) = Printf.sprintf "%s.%s" r n in + if not (exists_in old_metas x) then + failwith + (Printf.sprintf + "Script references unknown meta-variable: %s" + (meta2c(snd x)))) + metavars; + + (* script code *) + let (more, tokens) = get_tokens [PC.TArobArob; PC.TArob] in + let data = + match List.hd tokens with + (PC.TScriptData(s),_) -> s + | (PC.TArobArob,_) | (PC.TArob,_) -> "" + | _ -> failwith "Malformed script rule" in + (more,Ast0.ScriptRule(language, deps, metavars, data),[],tokens) in + + let parse_rule old_metas starts_with_name = + let rulename = + get_rule_name PC.rule_name starts_with_name get_tokens file + "rule" in + match rulename with + Ast.CocciRulename (Some s, a, b, c, d, e) -> + parse_cocci_rule old_metas (s, a, b, c, d, e) + | Ast.ScriptRulename (l,deps) -> parse_script_rule l old_metas deps + | _ -> failwith "Malformed rule name" + in + + let rec loop old_metas starts_with_name = + (!Data.init_rule)(); + + let gen_starts_with_name more tokens = + more && + (match List.hd (List.rev tokens) with + (PC.TArobArob,_) -> false + | (PC.TArob,_) -> true + | _ -> failwith "unexpected token") + in + + let (more, rule, metavars, tokens) = + parse_rule old_metas starts_with_name in + if more then + rule:: + (loop (metavars @ old_metas) (gen_starts_with_name more tokens)) + else [rule]; + + in + + (iso_files, loop [] (x = PC.TArob)) + | _ -> failwith "unexpected code before the first rule\n") + | (false,[(PC.TArobArob,_)]) | (false,[(PC.TArob,_)]) -> + ([],([] : Ast0.parsed_rule list)) + | _ -> failwith "unexpected code before the first rule\n" in + res) + +(* parse to ast0 and then convert to ast *) +let process file isofile verbose = + let extra_path = Filename.dirname file in + Lexer_cocci.init(); + let (iso_files, rules) = parse file in + let std_isos = + match isofile with + None -> [] + | Some iso_file -> parse_iso_files [] [Common.Left iso_file] "" in + let global_isos = parse_iso_files std_isos iso_files extra_path in + let rules = Unitary_ast0.do_unitary rules in + let parsed = + List.map + (function + Ast0.ScriptRule (a,b,c,d) -> [([],Ast.ScriptRule (a,b,c,d))] + | Ast0.CocciRule + ((minus, metavarsm, + (iso, dropiso, dependencies, rule_name, exists)), + (plus, metavars)) -> + let chosen_isos = + parse_iso_files global_isos + (List.map (function x -> Common.Left x) iso) + extra_path in + let chosen_isos = + (* check that dropped isos are actually available *) + (try + let iso_names = + List.map (function (_,_,nm) -> nm) chosen_isos in + let local_iso_names = reserved_names @ iso_names in + let bad_dropped = + List.find + (function dropped -> + not (List.mem dropped local_iso_names)) + dropiso in + failwith + ("invalid iso name " ^ bad_dropped ^ " in " ^ rule_name) + with Not_found -> ()); + if List.mem "all" dropiso + then + if List.length dropiso = 1 + then [] + else failwith "disable all should only be by itself" + else (* drop those isos *) + List.filter + (function (_,_,nm) -> not (List.mem nm dropiso)) + chosen_isos in + List.iter Iso_compile.process chosen_isos; + let dropped_isos = + match reserved_names with + "all"::others -> + (match dropiso with + ["all"] -> others + | _ -> + List.filter (function x -> List.mem x dropiso) others) + | _ -> + failwith + "bad list of reserved names - all must be at start" in + let minus = Test_exps.process minus in + let minus = Compute_lines.compute_lines minus in + let plus = Compute_lines.compute_lines plus in + let is_exp = + (* only relevant to Flag.make_hrule *) + (* doesn't handle multiple minirules properly, but since + we don't really handle them in lots of other ways, it + doesn't seem very important *) + match plus with + [] -> [false] + | p::_ -> + [match Ast0.unwrap p with + Ast0.CODE c -> + (match List.map Ast0.unwrap (Ast0.undots c) with + [Ast0.Exp e] -> true | _ -> false) + | _ -> false] in + let minus = Arity.minus_arity minus in + let ((metavars,minus),function_prototypes) = + Function_prototypes.process + rule_name metavars dropped_isos minus plus in + (* warning! context_neg side-effects its arguments *) + let (m,p) = List.split (Context_neg.context_neg minus plus) in + Type_infer.type_infer p; + (if not !Flag.sgrep_mode2 then Insert_plus.insert_plus m p); + Type_infer.type_infer minus; + let (extra_meta, minus) = + Iso_pattern.apply_isos chosen_isos minus rule_name in + let minus = Comm_assoc.comm_assoc minus rule_name dropiso in + let minus = + if !Flag.sgrep_mode2 then minus + else Single_statement.single_statement minus in + let minus = Simple_assignments.simple_assignments minus in + let minus_ast = + Ast0toast.ast0toast rule_name dependencies dropped_isos + exists minus is_exp in + match function_prototypes with + None -> [(extra_meta @ metavars, minus_ast)] + | Some mv_fp -> + [(extra_meta @ metavars, minus_ast); mv_fp]) +(* Ast0.CocciRule ((minus, metavarsm, (iso, dropiso, dependencies, rule_name, exists)), (plus, metavars))*) + rules in + let parsed = List.concat parsed in + let disjd = Disjdistr.disj parsed in + + let (code,fvs,neg_pos,ua,pos) = Free_vars.free_vars disjd in + if !Flag_parsing_cocci.show_SP + then List.iter Pretty_print_cocci.unparse code; + + let grep_tokens = + Common.profile_code "get_constants" + (fun () -> Get_constants.get_constants code) in (* for grep *) + let glimpse_tokens2 = + Common.profile_code "get_glimpse_constants" + (fun () -> Get_constants2.get_constants code neg_pos) in(* for glimpse *) + (code,fvs,neg_pos,ua,pos,grep_tokens,glimpse_tokens2) diff --git a/parsing_cocci/.#parse_cocci.ml.1.163 b/parsing_cocci/.#parse_cocci.ml.1.163 new file mode 100644 index 0000000..a38afe9 --- /dev/null +++ b/parsing_cocci/.#parse_cocci.ml.1.163 @@ -0,0 +1,1530 @@ +(* +* 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. +*) + + +(* splits the entire file into minus and plus fragments, and parses each +separately (thus duplicating work for the parsing of the context elements) *) + +module D = Data +module PC = Parser_cocci_menhir +module V0 = Visitor_ast0 +module Ast = Ast_cocci +module Ast0 = Ast0_cocci +let pr = Printf.sprintf +(*let pr2 s = prerr_string s; prerr_string "\n"; flush stderr*) +let pr2 s = Printf.printf "%s\n" s + +(* for isomorphisms. all should be at the front!!! *) +let reserved_names = + ["all";"optional_storage";"optional_qualifier";"value_format";"comm_assoc"] + +(* ----------------------------------------------------------------------- *) +(* Debugging... *) + +let line_type (d,_,_,_,_,_,_,_) = d + +let line_type2c tok = + match line_type tok with + D.MINUS | D.OPTMINUS | D.UNIQUEMINUS -> ":-" + | D.PLUS -> ":+" + | D.CONTEXT | D.UNIQUE | D.OPT -> "" + +let token2c (tok,_) = + match tok with + PC.TIdentifier -> "identifier" + | PC.TType -> "type" + | PC.TParameter -> "parameter" + | PC.TConstant -> "constant" + | PC.TExpression -> "expression" + | PC.TIdExpression -> "idexpression" + | PC.TStatement -> "statement" + | PC.TPosition -> "position" + | PC.TPosAny -> "any" + | PC.TFunction -> "function" + | PC.TLocal -> "local" + | PC.Tlist -> "list" + | PC.TFresh -> "fresh" + | PC.TPure -> "pure" + | PC.TContext -> "context" + | PC.TTypedef -> "typedef" + | PC.TDeclarer -> "declarer" + | PC.TIterator -> "iterator" + | PC.TName -> "name" + | PC.TRuleName str -> "rule_name-"^str + | PC.TUsing -> "using" + | PC.TPathIsoFile str -> "path_iso_file-"^str + | PC.TDisable -> "disable" + | PC.TExtends -> "extends" + | PC.TDepends -> "depends" + | PC.TOn -> "on" + | PC.TEver -> "ever" + | PC.TNever -> "never" + | PC.TExists -> "exists" + | PC.TForall -> "forall" + | PC.TReverse -> "reverse" + | PC.TError -> "error" + | PC.TWords -> "words" + + | PC.TNothing -> "nothing" + + | PC.Tchar(clt) -> "char"^(line_type2c clt) + | PC.Tshort(clt) -> "short"^(line_type2c clt) + | PC.Tint(clt) -> "int"^(line_type2c clt) + | PC.Tdouble(clt) -> "double"^(line_type2c clt) + | PC.Tfloat(clt) -> "float"^(line_type2c clt) + | PC.Tlong(clt) -> "long"^(line_type2c clt) + | PC.Tvoid(clt) -> "void"^(line_type2c clt) + | PC.Tstruct(clt) -> "struct"^(line_type2c clt) + | PC.Tunion(clt) -> "union"^(line_type2c clt) + | PC.Tunsigned(clt) -> "unsigned"^(line_type2c clt) + | PC.Tsigned(clt) -> "signed"^(line_type2c clt) + | PC.Tstatic(clt) -> "static"^(line_type2c clt) + | PC.Tinline(clt) -> "inline"^(line_type2c clt) + | PC.Ttypedef(clt) -> "typedef"^(line_type2c clt) + | PC.Tattr(s,clt) -> s^(line_type2c clt) + | PC.Tauto(clt) -> "auto"^(line_type2c clt) + | PC.Tregister(clt) -> "register"^(line_type2c clt) + | PC.Textern(clt) -> "extern"^(line_type2c clt) + | PC.Tconst(clt) -> "const"^(line_type2c clt) + | PC.Tvolatile(clt) -> "volatile"^(line_type2c clt) + + | PC.TPragma(s) -> s + | PC.TIncludeL(s,clt) -> (pr "#include \"%s\"" s)^(line_type2c clt) + | PC.TIncludeNL(s,clt) -> (pr "#include <%s>" s)^(line_type2c clt) + | PC.TDefine(clt,_) -> "#define"^(line_type2c clt) + | PC.TDefineParam(clt,_,_) -> "#define_param"^(line_type2c clt) + | PC.TMinusFile(s,clt) -> (pr "--- %s" s)^(line_type2c clt) + | PC.TPlusFile(s,clt) -> (pr "+++ %s" s)^(line_type2c clt) + + | PC.TInc(clt) -> "++"^(line_type2c clt) + | PC.TDec(clt) -> "--"^(line_type2c clt) + + | PC.TIf(clt) -> "if"^(line_type2c clt) + | PC.TElse(clt) -> "else"^(line_type2c clt) + | PC.TWhile(clt) -> "while"^(line_type2c clt) + | PC.TFor(clt) -> "for"^(line_type2c clt) + | PC.TDo(clt) -> "do"^(line_type2c clt) + | PC.TSwitch(clt) -> "switch"^(line_type2c clt) + | PC.TCase(clt) -> "case"^(line_type2c clt) + | PC.TDefault(clt) -> "default"^(line_type2c clt) + | PC.TReturn(clt) -> "return"^(line_type2c clt) + | PC.TBreak(clt) -> "break"^(line_type2c clt) + | PC.TContinue(clt) -> "continue"^(line_type2c clt) + | PC.TGoto(clt) -> "goto"^(line_type2c clt) + | PC.TIdent(s,clt) -> (pr "ident-%s" s)^(line_type2c clt) + | PC.TTypeId(s,clt) -> (pr "typename-%s" s)^(line_type2c clt) + | PC.TDeclarerId(s,clt) -> (pr "declarername-%s" s)^(line_type2c clt) + | PC.TIteratorId(s,clt) -> (pr "iteratorname-%s" s)^(line_type2c clt) + | PC.TMetaDeclarer(_,_,_,clt) -> "declmeta"^(line_type2c clt) + | PC.TMetaIterator(_,_,_,clt) -> "itermeta"^(line_type2c clt) + + | PC.TSizeof(clt) -> "sizeof"^(line_type2c clt) + + | PC.TString(x,clt) -> x^(line_type2c clt) + | PC.TChar(x,clt) -> x^(line_type2c clt) + | PC.TFloat(x,clt) -> x^(line_type2c clt) + | PC.TInt(x,clt) -> x^(line_type2c clt) + + | PC.TOrLog(clt) -> "||"^(line_type2c clt) + | PC.TAndLog(clt) -> "&&"^(line_type2c clt) + | PC.TOr(clt) -> "|"^(line_type2c clt) + | PC.TXor(clt) -> "^"^(line_type2c clt) + | PC.TAnd (clt) -> "&"^(line_type2c clt) + | PC.TEqEq(clt) -> "=="^(line_type2c clt) + | PC.TNotEq(clt) -> "!="^(line_type2c clt) + | PC.TLogOp(op,clt) -> + (match op with + Ast.Inf -> "<" + | Ast.InfEq -> "<=" + | Ast.Sup -> ">" + | Ast.SupEq -> ">=" + | _ -> failwith "not possible") + ^(line_type2c clt) + | PC.TShOp(op,clt) -> + (match op with + Ast.DecLeft -> "<<" + | Ast.DecRight -> ">>" + | _ -> failwith "not possible") + ^(line_type2c clt) + | PC.TPlus(clt) -> "+"^(line_type2c clt) + | PC.TMinus(clt) -> "-"^(line_type2c clt) + | PC.TMul(clt) -> "*"^(line_type2c clt) + | PC.TDmOp(op,clt) -> + (match op with + Ast.Div -> "/" + | Ast.Mod -> "%" + | _ -> failwith "not possible") + ^(line_type2c clt) + | PC.TTilde (clt) -> "~"^(line_type2c clt) + + | PC.TMetaParam(_,_,clt) -> "parammeta"^(line_type2c clt) + | PC.TMetaParamList(_,_,_,clt) -> "paramlistmeta"^(line_type2c clt) + | PC.TMetaConst(_,_,_,_,clt) -> "constmeta"^(line_type2c clt) + | PC.TMetaErr(_,_,_,clt) -> "errmeta"^(line_type2c clt) + | PC.TMetaExp(_,_,_,_,clt) -> "expmeta"^(line_type2c clt) + | PC.TMetaIdExp(_,_,_,_,clt) -> "idexpmeta"^(line_type2c clt) + | PC.TMetaLocalIdExp(_,_,_,_,clt) -> "localidexpmeta"^(line_type2c clt) + | PC.TMetaExpList(_,_,_,clt) -> "explistmeta"^(line_type2c clt) + | PC.TMetaId(_,_,_,clt) -> "idmeta"^(line_type2c clt) + | PC.TMetaType(_,_,clt) -> "typemeta"^(line_type2c clt) + | PC.TMetaStm(_,_,clt) -> "stmmeta"^(line_type2c clt) + | PC.TMetaStmList(_,_,clt) -> "stmlistmeta"^(line_type2c clt) + | PC.TMetaFunc(_,_,_,clt) -> "funcmeta"^(line_type2c clt) + | PC.TMetaLocalFunc(_,_,_,clt) -> "funcmeta"^(line_type2c clt) + | PC.TMetaPos(_,_,_,clt) -> "posmeta" + | PC.TMPtVirg -> ";" + | PC.TArobArob -> "@@" + | PC.TArob -> "@" + | PC.TPArob -> "P@" + | PC.TScript -> "script" + + | PC.TWhen(clt) -> "WHEN"^(line_type2c clt) + | PC.TWhenTrue(clt) -> "WHEN TRUE"^(line_type2c clt) + | PC.TWhenFalse(clt) -> "WHEN FALSE"^(line_type2c clt) + | PC.TAny(clt) -> "ANY"^(line_type2c clt) + | PC.TStrict(clt) -> "STRICT"^(line_type2c clt) + | PC.TEllipsis(clt) -> "..."^(line_type2c clt) +(* + | PC.TCircles(clt) -> "ooo"^(line_type2c clt) + | PC.TStars(clt) -> "***"^(line_type2c clt) +*) + + | PC.TOEllipsis(clt) -> "<..."^(line_type2c clt) + | PC.TCEllipsis(clt) -> "...>"^(line_type2c clt) + | PC.TPOEllipsis(clt) -> "<+..."^(line_type2c clt) + | PC.TPCEllipsis(clt) -> "...+>"^(line_type2c clt) +(* + | PC.TOCircles(clt) -> " "ooo>"^(line_type2c clt) + | PC.TOStars(clt) -> "<***"^(line_type2c clt) + | PC.TCStars(clt) -> "***>"^(line_type2c clt) +*) + | PC.TBang0 -> "!" + | PC.TPlus0 -> "+" + | PC.TWhy0 -> "?" + + | PC.TWhy(clt) -> "?"^(line_type2c clt) + | PC.TDotDot(clt) -> ":"^(line_type2c clt) + | PC.TBang(clt) -> "!"^(line_type2c clt) + | PC.TOPar(clt) -> "("^(line_type2c clt) + | PC.TOPar0(clt) -> "("^(line_type2c clt) + | PC.TMid0(clt) -> "|"^(line_type2c clt) + | PC.TCPar(clt) -> ")"^(line_type2c clt) + | PC.TCPar0(clt) -> ")"^(line_type2c clt) + + | PC.TOBrace(clt) -> "{"^(line_type2c clt) + | PC.TCBrace(clt) -> "}"^(line_type2c clt) + | PC.TOCro(clt) -> "["^(line_type2c clt) + | PC.TCCro(clt) -> "]"^(line_type2c clt) + + | PC.TPtrOp(clt) -> "->"^(line_type2c clt) + + | PC.TEq(clt) -> "="^(line_type2c clt) + | PC.TAssign(_,clt) -> "=op"^(line_type2c clt) + | PC.TDot(clt) -> "."^(line_type2c clt) + | PC.TComma(clt) -> ","^(line_type2c clt) + | PC.TPtVirg(clt) -> ";"^(line_type2c clt) + + | PC.EOF -> "eof" + | PC.TLineEnd(clt) -> "line end" + | PC.TInvalid -> "invalid" + | PC.TFunDecl(clt) -> "fundecl" + + | PC.TIso -> "<=>" + | PC.TRightIso -> "=>" + | PC.TIsoTopLevel -> "TopLevel" + | PC.TIsoExpression -> "Expression" + | PC.TIsoArgExpression -> "ArgExpression" + | PC.TIsoTestExpression -> "TestExpression" + | PC.TIsoStatement -> "Statement" + | PC.TIsoDeclaration -> "Declaration" + | PC.TIsoType -> "Type" + | PC.TScriptData s -> s + +let print_tokens s tokens = + Printf.printf "%s\n" s; + List.iter (function x -> Printf.printf "%s " (token2c x)) tokens; + Printf.printf "\n\n"; + flush stdout + +type plus = PLUS | NOTPLUS | SKIP + +let plus_attachable (tok,_) = + match tok with + PC.Tchar(clt) | PC.Tshort(clt) | PC.Tint(clt) | PC.Tdouble(clt) + | PC.Tfloat(clt) | PC.Tlong(clt) | PC.Tvoid(clt) | PC.Tstruct(clt) + | PC.Tunion(clt) | PC.Tunsigned(clt) | PC.Tsigned(clt) | PC.Tstatic(clt) + | PC.Tinline(clt) | PC.Ttypedef(clt) | PC.Tattr(_,clt) + | PC.Tauto(clt) | PC.Tregister(clt) + | PC.Textern(clt) | PC.Tconst(clt) | PC.Tvolatile(clt) + + | PC.TIncludeL(_,clt) | PC.TIncludeNL(_,clt) | PC.TDefine(clt,_) + | PC.TDefineParam(clt,_,_) | PC.TMinusFile(_,clt) | PC.TPlusFile(_,clt) + + | PC.TInc(clt) | PC.TDec(clt) + + | PC.TIf(clt) | PC.TElse(clt) | PC.TWhile(clt) | PC.TFor(clt) | PC.TDo(clt) + | PC.TSwitch(clt) | PC.TCase(clt) | PC.TDefault(clt) | PC.TReturn(clt) + | PC.TBreak(clt) | PC.TContinue(clt) | PC.TGoto(clt) | PC.TIdent(_,clt) + | PC.TTypeId(_,clt) | PC.TDeclarerId(_,clt) | PC.TIteratorId(_,clt) + + | PC.TSizeof(clt) + + | PC.TString(_,clt) | PC.TChar(_,clt) | PC.TFloat(_,clt) | PC.TInt(_,clt) + + | PC.TOrLog(clt) | PC.TAndLog(clt) | PC.TOr(clt) | PC.TXor(clt) + | PC.TAnd (clt) | PC.TEqEq(clt) | PC.TNotEq(clt) | PC.TLogOp(_,clt) + | PC.TShOp(_,clt) | PC.TPlus(clt) | PC.TMinus(clt) | PC.TMul(clt) + | PC.TDmOp(_,clt) | PC.TTilde (clt) + + | PC.TMetaParam(_,_,clt) | PC.TMetaParamList(_,_,_,clt) + | PC.TMetaConst(_,_,_,_,clt) | PC.TMetaErr(_,_,_,clt) + | PC.TMetaExp(_,_,_,_,clt) | PC.TMetaIdExp(_,_,_,_,clt) + | PC.TMetaLocalIdExp(_,_,_,_,clt) + | PC.TMetaExpList(_,_,_,clt) + | PC.TMetaId(_,_,_,clt) + | PC.TMetaType(_,_,clt) | PC.TMetaStm(_,_,clt) + | PC.TMetaStmList(_,_,clt) | PC.TMetaFunc(_,_,_,clt) + | PC.TMetaLocalFunc(_,_,_,clt) + + | PC.TWhen(clt) | PC.TWhenTrue(clt) | PC.TWhenFalse(clt) + | PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt) + (* | PC.TCircles(clt) | PC.TStars(clt) *) + + | PC.TWhy(clt) | PC.TDotDot(clt) | PC.TBang(clt) | PC.TOPar(clt) + | PC.TCPar(clt) + + | PC.TOBrace(clt) | PC.TCBrace(clt) | PC.TOCro(clt) | PC.TCCro(clt) + + | PC.TPtrOp(clt) + + | PC.TEq(clt) | PC.TAssign(_,clt) | PC.TDot(clt) | PC.TComma(clt) + | PC.TPtVirg(clt) -> + if line_type clt = D.PLUS then PLUS else NOTPLUS + + | PC.TOPar0(clt) | PC.TMid0(clt) | PC.TCPar0(clt) + | PC.TOEllipsis(clt) | PC.TCEllipsis(clt) + | PC.TPOEllipsis(clt) | PC.TPCEllipsis(clt) (* | PC.TOCircles(clt) + | PC.TCCircles(clt) | PC.TOStars(clt) | PC.TCStars(clt) *) -> NOTPLUS + | PC.TMetaPos(nm,_,_,_) -> NOTPLUS + + | _ -> SKIP + +let get_clt (tok,_) = + match tok with + PC.Tchar(clt) | PC.Tshort(clt) | PC.Tint(clt) | PC.Tdouble(clt) + | PC.Tfloat(clt) | PC.Tlong(clt) | PC.Tvoid(clt) | PC.Tstruct(clt) + | PC.Tunion(clt) | PC.Tunsigned(clt) | PC.Tsigned(clt) | PC.Tstatic(clt) + | PC.Tinline(clt) | PC.Tattr(_,clt) | PC.Tauto(clt) | PC.Tregister(clt) + | PC.Textern(clt) | PC.Tconst(clt) | PC.Tvolatile(clt) + + | PC.TIncludeL(_,clt) | PC.TIncludeNL(_,clt) | PC.TDefine(clt,_) + | PC.TDefineParam(clt,_,_) | PC.TMinusFile(_,clt) | PC.TPlusFile(_,clt) + + | PC.TInc(clt) | PC.TDec(clt) + + | PC.TIf(clt) | PC.TElse(clt) | PC.TWhile(clt) | PC.TFor(clt) | PC.TDo(clt) + | PC.TSwitch(clt) | PC.TCase(clt) | PC.TDefault(clt) | PC.TReturn(clt) + | PC.TBreak(clt) | PC.TContinue(clt) | PC.TGoto(clt) | PC.TIdent(_,clt) + | PC.TTypeId(_,clt) | PC.TDeclarerId(_,clt) | PC.TIteratorId(_,clt) + + | PC.TSizeof(clt) + + | PC.TString(_,clt) | PC.TChar(_,clt) | PC.TFloat(_,clt) | PC.TInt(_,clt) + + | PC.TOrLog(clt) | PC.TAndLog(clt) | PC.TOr(clt) | PC.TXor(clt) + | PC.TAnd (clt) | PC.TEqEq(clt) | PC.TNotEq(clt) | PC.TLogOp(_,clt) + | PC.TShOp(_,clt) | PC.TPlus(clt) | PC.TMinus(clt) | PC.TMul(clt) + | PC.TDmOp(_,clt) | PC.TTilde (clt) + + | PC.TMetaParam(_,_,clt) | PC.TMetaParamList(_,_,_,clt) + | PC.TMetaConst(_,_,_,_,clt) | PC.TMetaErr(_,_,_,clt) + | PC.TMetaExp(_,_,_,_,clt) | PC.TMetaIdExp(_,_,_,_,clt) + | PC.TMetaLocalIdExp(_,_,_,_,clt) + | PC.TMetaExpList(_,_,_,clt) + | PC.TMetaId(_,_,_,clt) + | PC.TMetaType(_,_,clt) | PC.TMetaStm(_,_,clt) + | PC.TMetaStmList(_,_,clt) | PC.TMetaFunc(_,_,_,clt) + | PC.TMetaLocalFunc(_,_,_,clt) | PC.TMetaPos(_,_,_,clt) + + | PC.TWhen(clt) | PC.TWhenTrue(clt) | PC.TWhenFalse(clt) | + PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt) + (* | PC.TCircles(clt) | PC.TStars(clt) *) + + | PC.TWhy(clt) | PC.TDotDot(clt) | PC.TBang(clt) | PC.TOPar(clt) + | PC.TCPar(clt) + + | PC.TOBrace(clt) | PC.TCBrace(clt) | PC.TOCro(clt) | PC.TCCro(clt) + + | PC.TPtrOp(clt) + + | PC.TEq(clt) | PC.TAssign(_,clt) | PC.TDot(clt) | PC.TComma(clt) + | PC.TPtVirg(clt) + + | PC.TOPar0(clt) | PC.TMid0(clt) | PC.TCPar0(clt) + | PC.TOEllipsis(clt) | PC.TCEllipsis(clt) + | PC.TPOEllipsis(clt) | PC.TPCEllipsis(clt) (* | PC.TOCircles(clt) + | PC.TCCircles(clt) | PC.TOStars(clt) | PC.TCStars(clt) *) -> clt + + | _ -> failwith "no clt" + +let update_clt (tok,x) clt = + match tok with + PC.Tchar(_) -> (PC.Tchar(clt),x) + | PC.Tshort(_) -> (PC.Tshort(clt),x) + | PC.Tint(_) -> (PC.Tint(clt),x) + | PC.Tdouble(_) -> (PC.Tdouble(clt),x) + | PC.Tfloat(_) -> (PC.Tfloat(clt),x) + | PC.Tlong(_) -> (PC.Tlong(clt),x) + | PC.Tvoid(_) -> (PC.Tvoid(clt),x) + | PC.Tstruct(_) -> (PC.Tstruct(clt),x) + | PC.Tunion(_) -> (PC.Tunion(clt),x) + | PC.Tunsigned(_) -> (PC.Tunsigned(clt),x) + | PC.Tsigned(_) -> (PC.Tsigned(clt),x) + | PC.Tstatic(_) -> (PC.Tstatic(clt),x) + | PC.Tinline(_) -> (PC.Tinline(clt),x) + | PC.Ttypedef(_) -> (PC.Ttypedef(clt),x) + | PC.Tattr(s,_) -> (PC.Tattr(s,clt),x) + | PC.Tauto(_) -> (PC.Tauto(clt),x) + | PC.Tregister(_) -> (PC.Tregister(clt),x) + | PC.Textern(_) -> (PC.Textern(clt),x) + | PC.Tconst(_) -> (PC.Tconst(clt),x) + | PC.Tvolatile(_) -> (PC.Tvolatile(clt),x) + + | PC.TIncludeL(s,_) -> (PC.TIncludeL(s,clt),x) + | PC.TIncludeNL(s,_) -> (PC.TIncludeNL(s,clt),x) + | PC.TDefine(_,a) -> (PC.TDefine(clt,a),x) + | PC.TDefineParam(_,a,b) -> (PC.TDefineParam(clt,a,b),x) + | PC.TMinusFile(s,_) -> (PC.TMinusFile(s,clt),x) + | PC.TPlusFile(s,_) -> (PC.TPlusFile(s,clt),x) + + | PC.TInc(_) -> (PC.TInc(clt),x) + | PC.TDec(_) -> (PC.TDec(clt),x) + + | PC.TIf(_) -> (PC.TIf(clt),x) + | PC.TElse(_) -> (PC.TElse(clt),x) + | PC.TWhile(_) -> (PC.TWhile(clt),x) + | PC.TFor(_) -> (PC.TFor(clt),x) + | PC.TDo(_) -> (PC.TDo(clt),x) + | PC.TSwitch(_) -> (PC.TSwitch(clt),x) + | PC.TCase(_) -> (PC.TCase(clt),x) + | PC.TDefault(_) -> (PC.TDefault(clt),x) + | PC.TReturn(_) -> (PC.TReturn(clt),x) + | PC.TBreak(_) -> (PC.TBreak(clt),x) + | PC.TContinue(_) -> (PC.TContinue(clt),x) + | PC.TGoto(_) -> (PC.TGoto(clt),x) + | PC.TIdent(s,_) -> (PC.TIdent(s,clt),x) + | PC.TTypeId(s,_) -> (PC.TTypeId(s,clt),x) + | PC.TDeclarerId(s,_) -> (PC.TDeclarerId(s,clt),x) + | PC.TIteratorId(s,_) -> (PC.TIteratorId(s,clt),x) + + | PC.TSizeof(_) -> (PC.TSizeof(clt),x) + + | PC.TString(s,_) -> (PC.TString(s,clt),x) + | PC.TChar(s,_) -> (PC.TChar(s,clt),x) + | PC.TFloat(s,_) -> (PC.TFloat(s,clt),x) + | PC.TInt(s,_) -> (PC.TInt(s,clt),x) + + | PC.TOrLog(_) -> (PC.TOrLog(clt),x) + | PC.TAndLog(_) -> (PC.TAndLog(clt),x) + | PC.TOr(_) -> (PC.TOr(clt),x) + | PC.TXor(_) -> (PC.TXor(clt),x) + | PC.TAnd (_) -> (PC.TAnd (clt),x) + | PC.TEqEq(_) -> (PC.TEqEq(clt),x) + | PC.TNotEq(_) -> (PC.TNotEq(clt),x) + | PC.TLogOp(op,_) -> (PC.TLogOp(op,clt),x) + | PC.TShOp(op,_) -> (PC.TShOp(op,clt),x) + | PC.TPlus(_) -> (PC.TPlus(clt),x) + | PC.TMinus(_) -> (PC.TMinus(clt),x) + | PC.TMul(_) -> (PC.TMul(clt),x) + | PC.TDmOp(op,_) -> (PC.TDmOp(op,clt),x) + | PC.TTilde (_) -> (PC.TTilde (clt),x) + + | PC.TMetaParam(a,b,_) -> (PC.TMetaParam(a,b,clt),x) + | PC.TMetaParamList(a,b,c,_) -> (PC.TMetaParamList(a,b,c,clt),x) + | PC.TMetaConst(a,b,c,d,_) -> (PC.TMetaConst(a,b,c,d,clt),x) + | PC.TMetaErr(a,b,c,_) -> (PC.TMetaErr(a,b,c,clt),x) + | PC.TMetaExp(a,b,c,d,_) -> (PC.TMetaExp(a,b,c,d,clt),x) + | PC.TMetaIdExp(a,b,c,d,_) -> (PC.TMetaIdExp(a,b,c,d,clt),x) + | PC.TMetaLocalIdExp(a,b,c,d,_) -> (PC.TMetaLocalIdExp(a,b,c,d,clt),x) + | PC.TMetaExpList(a,b,c,_) -> (PC.TMetaExpList(a,b,c,clt),x) + | PC.TMetaId(a,b,c,_) -> (PC.TMetaId(a,b,c,clt),x) + | PC.TMetaType(a,b,_) -> (PC.TMetaType(a,b,clt),x) + | PC.TMetaStm(a,b,_) -> (PC.TMetaStm(a,b,clt),x) + | PC.TMetaStmList(a,b,_) -> (PC.TMetaStmList(a,b,clt),x) + | PC.TMetaFunc(a,b,c,_) -> (PC.TMetaFunc(a,b,c,clt),x) + | PC.TMetaLocalFunc(a,b,c,_) -> (PC.TMetaLocalFunc(a,b,c,clt),x) + + | PC.TWhen(_) -> (PC.TWhen(clt),x) + | PC.TWhenTrue(_) -> (PC.TWhenTrue(clt),x) + | PC.TWhenFalse(_) -> (PC.TWhenFalse(clt),x) + | PC.TAny(_) -> (PC.TAny(clt),x) + | PC.TStrict(_) -> (PC.TStrict(clt),x) + | PC.TEllipsis(_) -> (PC.TEllipsis(clt),x) +(* + | PC.TCircles(_) -> (PC.TCircles(clt),x) + | PC.TStars(_) -> (PC.TStars(clt),x) +*) + + | PC.TOEllipsis(_) -> (PC.TOEllipsis(clt),x) + | PC.TCEllipsis(_) -> (PC.TCEllipsis(clt),x) + | PC.TPOEllipsis(_) -> (PC.TPOEllipsis(clt),x) + | PC.TPCEllipsis(_) -> (PC.TPCEllipsis(clt),x) +(* + | PC.TOCircles(_) -> (PC.TOCircles(clt),x) + | PC.TCCircles(_) -> (PC.TCCircles(clt),x) + | PC.TOStars(_) -> (PC.TOStars(clt),x) + | PC.TCStars(_) -> (PC.TCStars(clt),x) +*) + + | PC.TWhy(_) -> (PC.TWhy(clt),x) + | PC.TDotDot(_) -> (PC.TDotDot(clt),x) + | PC.TBang(_) -> (PC.TBang(clt),x) + | PC.TOPar(_) -> (PC.TOPar(clt),x) + | PC.TOPar0(_) -> (PC.TOPar0(clt),x) + | PC.TMid0(_) -> (PC.TMid0(clt),x) + | PC.TCPar(_) -> (PC.TCPar(clt),x) + | PC.TCPar0(_) -> (PC.TCPar0(clt),x) + + | PC.TOBrace(_) -> (PC.TOBrace(clt),x) + | PC.TCBrace(_) -> (PC.TCBrace(clt),x) + | PC.TOCro(_) -> (PC.TOCro(clt),x) + | PC.TCCro(_) -> (PC.TCCro(clt),x) + + | PC.TPtrOp(_) -> (PC.TPtrOp(clt),x) + + | PC.TEq(_) -> (PC.TEq(clt),x) + | PC.TAssign(s,_) -> (PC.TAssign(s,clt),x) + | PC.TDot(_) -> (PC.TDot(clt),x) + | PC.TComma(_) -> (PC.TComma(clt),x) + | PC.TPtVirg(_) -> (PC.TPtVirg(clt),x) + + | PC.TLineEnd(_) -> (PC.TLineEnd(clt),x) + | PC.TFunDecl(_) -> (PC.TFunDecl(clt),x) + + | _ -> failwith "no clt" + + +(* ----------------------------------------------------------------------- *) + +let make_name prefix ln = Printf.sprintf "%s starting on line %d" prefix ln + +(* ----------------------------------------------------------------------- *) +(* Read tokens *) + +let wrap_lexbuf_info lexbuf = + (Lexing.lexeme lexbuf, Lexing.lexeme_start lexbuf) + +let tokens_all_full token table file get_ats lexbuf end_markers : + (bool * ((PC.token * (string * (int * int) * (int * int))) list)) = + try + let rec aux () = + let result = token lexbuf in + let info = (Lexing.lexeme lexbuf, + (table.(Lexing.lexeme_start lexbuf)), + (Lexing.lexeme_start lexbuf, Lexing.lexeme_end lexbuf)) in + if result = PC.EOF + then + if get_ats + then failwith "unexpected end of file in a metavariable declaration" + else (false,[(result,info)]) + else if List.mem result end_markers + then (true,[(result,info)]) + else + let (more,rest) = aux() in + (more,(result, info)::rest) + in aux () + with + e -> pr2 (Common.error_message file (wrap_lexbuf_info lexbuf) ); raise e + +let tokens_all table file get_ats lexbuf end_markers : + (bool * ((PC.token * (string * (int * int) * (int * int))) list)) = + tokens_all_full Lexer_cocci.token table file get_ats lexbuf end_markers + +let tokens_script_all table file get_ats lexbuf end_markers : + (bool * ((PC.token * (string * (int * int) * (int * int))) list)) = + tokens_all_full Lexer_script.token table file get_ats lexbuf end_markers + +(* ----------------------------------------------------------------------- *) +(* Split tokens into minus and plus fragments *) + +let split t clt = + let (d,_,_,_,_,_,_,_) = clt in + match d with + D.MINUS | D.OPTMINUS | D.UNIQUEMINUS -> ([t],[]) + | D.PLUS -> ([],[t]) + | D.CONTEXT | D.UNIQUE | D.OPT -> ([t],[t]) + +let split_token ((tok,_) as t) = + match tok with + PC.TIdentifier | PC.TConstant | PC.TExpression | PC.TIdExpression + | PC.TStatement | PC.TPosition | PC.TPosAny + | PC.TFunction | PC.TTypedef | PC.TDeclarer | PC.TIterator | PC.TName + | PC.TType | PC.TParameter | PC.TLocal | PC.Tlist | PC.TFresh | PC.TPure + | PC.TContext | PC.TRuleName(_) | PC.TUsing | PC.TDisable | PC.TExtends + | PC.TPathIsoFile(_) + | PC.TDepends | PC.TOn | PC.TEver | PC.TNever | PC.TExists | PC.TForall + | PC.TReverse + | PC.TError | PC.TWords | PC.TNothing -> ([t],[t]) + + | PC.Tchar(clt) | PC.Tshort(clt) | PC.Tint(clt) | PC.Tdouble(clt) + | PC.Tfloat(clt) | PC.Tlong(clt) | PC.Tvoid(clt) | PC.Tstruct(clt) + | PC.Tunion(clt) | PC.Tunsigned(clt) | PC.Tsigned(clt) + | PC.Tstatic(clt) | PC.Tauto(clt) | PC.Tregister(clt) | PC.Textern(clt) + | PC.Tinline(clt) | PC.Ttypedef(clt) | PC.Tattr(_,clt) + | PC.Tconst(clt) | PC.Tvolatile(clt) -> split t clt + + | PC.TPragma(s) -> ([],[t]) (* only allowed in + *) + | PC.TPlusFile(s,clt) | PC.TMinusFile(s,clt) + | PC.TIncludeL(s,clt) | PC.TIncludeNL(s,clt) -> + split t clt + | PC.TDefine(clt,_) | PC.TDefineParam(clt,_,_) -> split t clt + + | PC.TIf(clt) | PC.TElse(clt) | PC.TWhile(clt) | PC.TFor(clt) | PC.TDo(clt) + | PC.TSwitch(clt) | PC.TCase(clt) | PC.TDefault(clt) + | PC.TSizeof(clt) + | PC.TReturn(clt) | PC.TBreak(clt) | PC.TContinue(clt) | PC.TGoto(clt) + | PC.TIdent(_,clt) + | PC.TTypeId(_,clt) | PC.TDeclarerId(_,clt) | PC.TIteratorId(_,clt) + | PC.TMetaConst(_,_,_,_,clt) | PC.TMetaExp(_,_,_,_,clt) + | PC.TMetaIdExp(_,_,_,_,clt) | PC.TMetaLocalIdExp(_,_,_,_,clt) + | PC.TMetaExpList(_,_,_,clt) + | PC.TMetaParam(_,_,clt) | PC.TMetaParamList(_,_,_,clt) + | PC.TMetaId(_,_,_,clt) | PC.TMetaType(_,_,clt) + | PC.TMetaStm(_,_,clt) | PC.TMetaStmList(_,_,clt) | PC.TMetaErr(_,_,_,clt) + | PC.TMetaFunc(_,_,_,clt) | PC.TMetaLocalFunc(_,_,_,clt) + | PC.TMetaDeclarer(_,_,_,clt) | PC.TMetaIterator(_,_,_,clt) -> split t clt + | PC.TMPtVirg | PC.TArob | PC.TArobArob | PC.TScript -> ([t],[t]) + | PC.TPArob | PC.TMetaPos(_,_,_,_) -> ([t],[]) + + | PC.TFunDecl(clt) + | PC.TWhen(clt) | PC.TWhenTrue(clt) | PC.TWhenFalse(clt) + | PC.TAny(clt) | PC.TStrict(clt) | PC.TLineEnd(clt) + | PC.TEllipsis(clt) (* | PC.TCircles(clt) | PC.TStars(clt) *) -> split t clt + + | PC.TOEllipsis(_) | PC.TCEllipsis(_) (* clt must be context *) + | PC.TPOEllipsis(_) | PC.TPCEllipsis(_) (* clt must be context *) +(* + | PC.TOCircles(_) | PC.TCCircles(_) (* clt must be context *) + | PC.TOStars(_) | PC.TCStars(_) (* clt must be context *) +*) + | PC.TBang0 | PC.TPlus0 | PC.TWhy0 -> + ([t],[t]) + + | PC.TWhy(clt) | PC.TDotDot(clt) + | PC.TBang(clt) | PC.TOPar(clt) | PC.TOPar0(clt) + | PC.TMid0(clt) | PC.TCPar(clt) | PC.TCPar0(clt) -> split t clt + + | PC.TInc(clt) | PC.TDec(clt) -> split t clt + + | PC.TString(_,clt) | PC.TChar(_,clt) | PC.TFloat(_,clt) | PC.TInt(_,clt) -> + split t clt + + | PC.TOrLog(clt) | PC.TAndLog(clt) | PC.TOr(clt) | PC.TXor(clt) + | PC.TAnd (clt) | PC.TEqEq(clt) | PC.TNotEq(clt) | PC.TLogOp(_,clt) + | PC.TShOp(_,clt) | PC.TPlus(clt) | PC.TMinus(clt) | PC.TMul(clt) + | PC.TDmOp(_,clt) | PC.TTilde (clt) -> split t clt + + | PC.TOBrace(clt) | PC.TCBrace(clt) -> split t clt + | PC.TOCro(clt) | PC.TCCro(clt) -> split t clt + + | PC.TPtrOp(clt) -> split t clt + + | PC.TEq(clt) | PC.TAssign(_,clt) | PC.TDot(clt) | PC.TComma(clt) + | PC.TPtVirg(clt) -> split t clt + + | PC.EOF | PC.TInvalid -> ([t],[t]) + + | PC.TIso | PC.TRightIso + | PC.TIsoExpression | PC.TIsoStatement | PC.TIsoDeclaration | PC.TIsoType + | PC.TIsoTopLevel | PC.TIsoArgExpression | PC.TIsoTestExpression -> + failwith "unexpected tokens" + | PC.TScriptData s -> ([t],[t]) + +let split_token_stream tokens = + let rec loop = function + [] -> ([],[]) + | token::tokens -> + let (minus,plus) = split_token token in + let (minus_stream,plus_stream) = loop tokens in + (minus@minus_stream,plus@plus_stream) in + loop tokens + +(* ----------------------------------------------------------------------- *) +(* Find function names *) +(* This addresses a shift-reduce problem in the parser, allowing us to +distinguish a function declaration from a function call even if the latter +has no return type. Undoubtedly, this is not very nice, but it doesn't +seem very convenient to refactor the grammar to get around the problem. *) + +let rec find_function_names = function + [] -> [] + | ((PC.TIdent(_,clt),info) as t1) :: ((PC.TOPar(_),_) as t2) :: rest + | ((PC.TMetaId(_,_,_,clt),info) as t1) :: ((PC.TOPar(_),_) as t2) :: rest + | ((PC.TMetaFunc(_,_,_,clt),info) as t1) :: ((PC.TOPar(_),_) as t2) :: rest + | ((PC.TMetaLocalFunc(_,_,_,clt),info) as t1)::((PC.TOPar(_),_) as t2)::rest + -> + let rec skip level = function + [] -> ([],false,[]) + | ((PC.TCPar(_),_) as t)::rest -> + let level = level - 1 in + if level = 0 + then ([t],true,rest) + else let (pre,found,post) = skip level rest in (t::pre,found,post) + | ((PC.TOPar(_),_) as t)::rest -> + let level = level + 1 in + let (pre,found,post) = skip level rest in (t::pre,found,post) + | ((PC.TArobArob,_) as t)::rest + | ((PC.TArob,_) as t)::rest + | ((PC.EOF,_) as t)::rest -> ([t],false,rest) + | t::rest -> + let (pre,found,post) = skip level rest in (t::pre,found,post) in + let (pre,found,post) = skip 1 rest in + (match (found,post) with + (true,((PC.TOBrace(_),_) as t3)::rest) -> + (PC.TFunDecl(clt),info) :: t1 :: t2 :: pre @ + t3 :: (find_function_names rest) + | _ -> t1 :: t2 :: pre @ find_function_names post) + | t :: rest -> t :: find_function_names rest + +(* ----------------------------------------------------------------------- *) +(* an attribute is an identifier that preceeds another identifier and + begins with __ *) + +let rec detect_attr l = + let is_id = function + (PC.TIdent(_,_),_) | (PC.TMetaId(_,_,_,_),_) | (PC.TMetaFunc(_,_,_,_),_) + | (PC.TMetaLocalFunc(_,_,_,_),_) -> true + | _ -> false in + let rec loop = function + [] -> [] + | [x] -> [x] + | ((PC.TIdent(nm,clt),info) as t1)::id::rest when is_id id -> + if String.length nm > 2 && String.sub nm 0 2 = "__" + then (PC.Tattr(nm,clt),info)::(loop (id::rest)) + else t1::(loop (id::rest)) + | x::xs -> x::(loop xs) in + loop l + +(* ----------------------------------------------------------------------- *) +(* Look for variable declarations where the name is a typedef name. +We assume that C code does not contain a multiplication as a top-level +statement. *) + +(* bug: once a type, always a type, even if the same name is later intended + to be used as a real identifier *) +let detect_types in_meta_decls l = + let is_delim infn = function + (PC.TOEllipsis(_),_) (* | (PC.TOCircles(_),_) | (PC.TOStars(_),_) *) + | (PC.TPOEllipsis(_),_) (* | (PC.TOCircles(_),_) | (PC.TOStars(_),_) *) + | (PC.TEllipsis(_),_) (* | (PC.TCircles(_),_) | (PC.TStars(_),_) *) + | (PC.TPtVirg(_),_) | (PC.TOBrace(_),_) | (PC.TCBrace(_),_) + | (PC.TPure,_) | (PC.TContext,_) + | (PC.Tstatic(_),_) | (PC.Textern(_),_) + | (PC.Tinline(_),_) | (PC.Ttypedef(_),_) | (PC.Tattr(_),_) -> true + | (PC.TComma(_),_) when infn > 0 or in_meta_decls -> true + | (PC.TDotDot(_),_) when in_meta_decls -> true + | _ -> false in + let is_choices_delim = function + (PC.TOBrace(_),_) | (PC.TComma(_),_) -> true | _ -> false in + let is_id = function + (PC.TIdent(_,_),_) | (PC.TMetaId(_,_,_,_),_) | (PC.TMetaFunc(_,_,_,_),_) + | (PC.TMetaLocalFunc(_,_,_,_),_) -> true + | (PC.TMetaParam(_,_,_),_) + | (PC.TMetaParamList(_,_,_,_),_) + | (PC.TMetaConst(_,_,_,_,_),_) + | (PC.TMetaErr(_,_,_,_),_) + | (PC.TMetaExp(_,_,_,_,_),_) + | (PC.TMetaIdExp(_,_,_,_,_),_) + | (PC.TMetaLocalIdExp(_,_,_,_,_),_) + | (PC.TMetaExpList(_,_,_,_),_) + | (PC.TMetaType(_,_,_),_) + | (PC.TMetaStm(_,_,_),_) + | (PC.TMetaStmList(_,_,_),_) + | (PC.TMetaPos(_,_,_,_),_) -> in_meta_decls + | _ -> false in + let redo_id ident clt v = + !Data.add_type_name ident; + (PC.TTypeId(ident,clt),v) in + let rec loop start infn type_names = function + (* infn: 0 means not in a function header + > 0 means in a function header, after infn - 1 unmatched open parens*) + [] -> [] + | ((PC.TOBrace(clt),v)::_) as all when in_meta_decls -> + collect_choices type_names all (* never a function header *) + | delim::(PC.TIdent(ident,clt),v)::((PC.TMul(_),_) as x)::rest + when is_delim infn delim -> + let newid = redo_id ident clt v in + delim::newid::x::(loop false infn (ident::type_names) rest) + | delim::(PC.TIdent(ident,clt),v)::id::rest + when is_delim infn delim && is_id id -> + let newid = redo_id ident clt v in + delim::newid::id::(loop false infn (ident::type_names) rest) + | ((PC.TFunDecl(_),_) as fn)::rest -> + fn::(loop false 1 type_names rest) + | ((PC.TOPar(_),_) as lp)::rest when infn > 0 -> + lp::(loop false (infn + 1) type_names rest) + | ((PC.TCPar(_),_) as rp)::rest when infn > 0 -> + if infn - 1 = 1 + then rp::(loop false 0 type_names rest) (* 0 means not in fn header *) + else rp::(loop false (infn - 1) type_names rest) + | (PC.TIdent(ident,clt),v)::((PC.TMul(_),_) as x)::rest when start -> + let newid = redo_id ident clt v in + newid::x::(loop false infn (ident::type_names) rest) + | (PC.TIdent(ident,clt),v)::id::rest when start && is_id id -> + let newid = redo_id ident clt v in + newid::id::(loop false infn (ident::type_names) rest) + | (PC.TIdent(ident,clt),v)::rest when List.mem ident type_names -> + (PC.TTypeId(ident,clt),v)::(loop false infn type_names rest) + | ((PC.TIdent(ident,clt),v) as x)::rest -> + x::(loop false infn type_names rest) + | x::rest -> x::(loop false infn type_names rest) + and collect_choices type_names = function + [] -> [] (* should happen, but let the parser detect that *) + | (PC.TCBrace(clt),v)::rest -> + (PC.TCBrace(clt),v)::(loop false 0 type_names rest) + | delim::(PC.TIdent(ident,clt),v)::rest + when is_choices_delim delim -> + let newid = redo_id ident clt v in + delim::newid::(collect_choices (ident::type_names) rest) + | x::rest -> x::(collect_choices type_names rest) in + loop true 0 [] l + + +(* ----------------------------------------------------------------------- *) +(* Insert TLineEnd tokens at the end of a line that contains a WHEN. + WHEN is restricted to a single line, to avoid ambiguity in eg: + ... WHEN != x + +3 *) + +let token2line (tok,_) = + match tok with + PC.Tchar(clt) | PC.Tshort(clt) | PC.Tint(clt) | PC.Tdouble(clt) + | PC.Tfloat(clt) | PC.Tlong(clt) | PC.Tvoid(clt) | PC.Tstruct(clt) + | PC.Tunion(clt) | PC.Tunsigned(clt) | PC.Tsigned(clt) + | PC.Tstatic(clt) | PC.Tauto(clt) | PC.Tregister(clt) | PC.Textern(clt) + | PC.Tinline(clt) | PC.Ttypedef(clt) | PC.Tattr(_,clt) | PC.Tconst(clt) + | PC.Tvolatile(clt) + + | PC.TInc(clt) | PC.TDec(clt) + + | PC.TIf(clt) | PC.TElse(clt) | PC.TWhile(clt) | PC.TFor(clt) | PC.TDo(clt) + | PC.TSwitch (clt) | PC.TCase (clt) | PC.TDefault (clt) | PC.TSizeof (clt) + | PC.TReturn(clt) | PC.TBreak(clt) | PC.TContinue(clt) | PC.TGoto(clt) + | PC.TIdent(_,clt) + | PC.TTypeId(_,clt) | PC.TDeclarerId(_,clt) | PC.TIteratorId(_,clt) + | PC.TMetaDeclarer(_,_,_,clt) | PC.TMetaIterator(_,_,_,clt) + + | PC.TString(_,clt) | PC.TChar(_,clt) | PC.TFloat(_,clt) | PC.TInt(_,clt) + + | PC.TOrLog(clt) | PC.TAndLog(clt) | PC.TOr(clt) | PC.TXor(clt) + | PC.TAnd (clt) | PC.TEqEq(clt) | PC.TNotEq(clt) | PC.TLogOp(_,clt) + | PC.TShOp(_,clt) | PC.TPlus(clt) | PC.TMinus(clt) | PC.TMul(clt) + | PC.TDmOp(_,clt) | PC.TTilde (clt) + + | PC.TMetaParam(_,_,clt) | PC.TMetaParamList(_,_,_,clt) + | PC.TMetaConst(_,_,_,_,clt) | PC.TMetaExp(_,_,_,_,clt) + | PC.TMetaIdExp(_,_,_,_,clt) | PC.TMetaLocalIdExp(_,_,_,_,clt) + | PC.TMetaExpList(_,_,_,clt) + | PC.TMetaId(_,_,_,clt) | PC.TMetaType(_,_,clt) + | PC.TMetaStm(_,_,clt) | PC.TMetaStmList(_,_,clt) | PC.TMetaFunc(_,_,_,clt) + | PC.TMetaLocalFunc(_,_,_,clt) | PC.TMetaPos(_,_,_,clt) + + | PC.TFunDecl(clt) + | PC.TWhen(clt) | PC.TWhenTrue(clt) | PC.TWhenFalse(clt) + | PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt) + (* | PC.TCircles(clt) | PC.TStars(clt) *) + + | PC.TOEllipsis(clt) | PC.TCEllipsis(clt) + | PC.TPOEllipsis(clt) | PC.TPCEllipsis(clt) (*| PC.TOCircles(clt) + | PC.TCCircles(clt) | PC.TOStars(clt) | PC.TCStars(clt) *) + + | PC.TWhy(clt) | PC.TDotDot(clt) | PC.TBang(clt) | PC.TOPar(clt) + | PC.TOPar0(clt) | PC.TMid0(clt) | PC.TCPar(clt) + | PC.TCPar0(clt) + + | PC.TOBrace(clt) | PC.TCBrace(clt) | PC.TOCro(clt) | PC.TCCro(clt) + + | PC.TPtrOp(clt) + + | PC.TDefine(clt,_) | PC.TDefineParam(clt,_,_) + | PC.TIncludeL(_,clt) | PC.TIncludeNL(_,clt) + + | PC.TEq(clt) | PC.TAssign(_,clt) | PC.TDot(clt) | PC.TComma(clt) + | PC.TPtVirg(clt) -> + let (_,line,_,_,_,_,_,_) = clt in Some line + + | _ -> None + +let rec insert_line_end = function + [] -> [] + | (((PC.TWhen(clt),q) as x)::xs) -> + x::(find_line_end true (token2line x) clt q xs) + | (((PC.TDefine(clt,_),q) as x)::xs) + | (((PC.TDefineParam(clt,_,_),q) as x)::xs) -> + x::(find_line_end false (token2line x) clt q xs) + | x::xs -> x::(insert_line_end xs) + +and find_line_end inwhen line clt q = function + (* don't know what 2nd component should be so just use the info of + the When. Also inherit - of when, if any *) + [] -> [(PC.TLineEnd(clt),q)] + | ((PC.TIdent("strict",clt),a) as x)::xs when token2line x = line -> + (PC.TStrict(clt),a) :: (find_line_end inwhen line clt q xs) + | ((PC.TIdent("STRICT",clt),a) as x)::xs when token2line x = line -> + (PC.TStrict(clt),a) :: (find_line_end inwhen line clt q xs) + | ((PC.TIdent("any",clt),a) as x)::xs when token2line x = line -> + (PC.TAny(clt),a) :: (find_line_end inwhen line clt q xs) + | ((PC.TIdent("ANY",clt),a) as x)::xs when token2line x = line -> + (PC.TAny(clt),a) :: (find_line_end inwhen line clt q xs) + | ((PC.TIdent("forall",clt),a) as x)::xs when token2line x = line -> + (PC.TForall,a) :: (find_line_end inwhen line clt q xs) + | ((PC.TIdent("exists",clt),a) as x)::xs when token2line x = line -> + (PC.TExists,a) :: (find_line_end inwhen line clt q xs) + | ((PC.TComma(clt),a) as x)::xs when token2line x = line -> + (PC.TComma(clt),a) :: (find_line_end inwhen line clt q xs) + | ((PC.TPArob,a) as x)::xs -> (* no line #, just assume on the same line *) + x :: (find_line_end inwhen line clt q xs) + | x::xs when token2line x = line -> x :: (find_line_end inwhen line clt q xs) + | xs -> (PC.TLineEnd(clt),q)::(insert_line_end xs) + +let rec translate_when_true_false = function + [] -> [] + | (PC.TWhen(clt),q)::((PC.TNotEq(_),_) as x)::(PC.TIdent("true",_),_)::xs -> + (PC.TWhenTrue(clt),q)::x::xs + | (PC.TWhen(clt),q)::((PC.TNotEq(_),_) as x)::(PC.TIdent("false",_),_)::xs -> + (PC.TWhenFalse(clt),q)::x::xs + | x::xs -> x :: (translate_when_true_false xs) + +(* ----------------------------------------------------------------------- *) +(* process pragmas: they can only be used in + code, and adjacent to +another + token. They are concatenated to the string representation of +that other token. *) + +let rec collect_all_pragmas collected = function + (PC.TPragma(s),_)::rest -> collect_all_pragmas (s::collected) rest + | l -> (List.rev collected,l) + +let rec collect_up_to_pragmas skipped = function + [] -> None (* didn't reach a pragma, so nothing to do *) + | ((PC.TPragma(s),_) as t)::rest -> + let (pragmas,rest) = collect_all_pragmas [] (t::rest) in + Some (List.rev skipped,pragmas,rest) + | x::xs -> + match plus_attachable x with + PLUS -> None + | NOTPLUS -> None + | SKIP -> collect_up_to_pragmas (x::skipped) xs + +let rec collect_up_to_plus skipped = function + [] -> failwith "nothing to attach a pragma to" + | x::xs -> + match plus_attachable x with + PLUS -> (List.rev skipped,x,xs) + | NOTPLUS -> failwith "nothing to attach a pragma to" + | SKIP -> collect_up_to_plus (x::skipped) xs + +let rec process_pragmas = function + [] -> [] + | ((PC.TPragma(s),_)::_) as l -> + let (pragmas,rest) = collect_all_pragmas [] l in + let (skipped,aft,rest) = collect_up_to_plus [] rest in + let (a,b,c,d,e,strbef,straft,pos) = get_clt aft in + skipped@ + (process_pragmas ((update_clt aft (a,b,c,d,e,pragmas,straft,pos))::rest)) + | bef::xs -> + (match plus_attachable bef with + PLUS -> + (match collect_up_to_pragmas [] xs with + Some(skipped,pragmas,rest) -> + let (a,b,c,d,e,strbef,straft,pos) = get_clt bef in + (update_clt bef (a,b,c,d,e,strbef,pragmas,pos)):: + skipped@(process_pragmas rest) + | None -> bef::(process_pragmas xs)) + | _ -> bef::(process_pragmas xs)) + +(* ----------------------------------------------------------------------- *) +(* Drop ... ... . This is only allowed in + code, and arises when there is +some - code between the ... *) +(* drop whens as well - they serve no purpose in + code and they cause +problems for drop_double_dots *) + +let rec drop_when = function + [] -> [] + | (PC.TWhen(clt),info)::xs -> + let rec loop = function + [] -> [] + | (PC.TLineEnd(_),info)::xs -> drop_when xs + | x::xs -> loop xs in + loop xs + | x::xs -> x::drop_when xs + +(* instead of dropping the double dots, we put TNothing in between them. +these vanish after the parser, but keeping all the ...s in the + code makes +it easier to align the + and - code in context_neg and in preparation for the +isomorphisms. This shouldn't matter because the context code of the + +slice is mostly ignored anyway *) +let rec drop_double_dots l = + let start = function + (PC.TOEllipsis(_),_) | (PC.TPOEllipsis(_),_) + (* | (PC.TOCircles(_),_) | (PC.TOStars(_),_) *) -> + true + | _ -> false in + let middle = function + (PC.TEllipsis(_),_) (* | (PC.TCircles(_),_) | (PC.TStars(_),_) *) -> true + | _ -> false in + let final = function + (PC.TCEllipsis(_),_) | (PC.TPCEllipsis(_),_) + (* | (PC.TCCircles(_),_) | (PC.TCStars(_),_) *) -> + true + | _ -> false in + let rec loop ((_,i) as prev) = function + [] -> [] + | x::rest when middle prev && middle x -> (PC.TNothing,i)::x::(loop x rest) + | x::rest when start prev && middle x -> (PC.TNothing,i)::x::(loop x rest) + | x::rest when start prev && final x -> (PC.TNothing,i)::x::(loop x rest) + | x::rest when middle prev && final x -> (PC.TNothing,i)::x::(loop x rest) + | x::rest -> x :: (loop x rest) in + match l with + [] -> [] + | (x::xs) -> x :: loop x xs + +let rec fix f l = + let cur = f l in + if l = cur then l else fix f cur + +(* ( | ... | ) also causes parsing problems *) + +exception Not_empty + +let rec drop_empty_thing starter middle ender = function + [] -> [] + | hd::rest when starter hd -> + let rec loop = function + x::rest when middle x -> loop rest + | x::rest when ender x -> rest + | _ -> raise Not_empty in + (match try Some(loop rest) with Not_empty -> None with + Some x -> drop_empty_thing starter middle ender x + | None -> hd :: drop_empty_thing starter middle ender rest) + | x::rest -> x :: drop_empty_thing starter middle ender rest + +let drop_empty_or = + drop_empty_thing + (function (PC.TOPar0(_),_) -> true | _ -> false) + (function (PC.TMid0(_),_) -> true | _ -> false) + (function (PC.TCPar0(_),_) -> true | _ -> false) + +let drop_empty_nest = drop_empty_thing + +(* ----------------------------------------------------------------------- *) +(* Read tokens *) + +let get_s_starts (_, (s,_,(starts, ends))) = + Printf.printf "%d %d\n" starts ends; (s, starts) + +let pop2 l = + let v = List.hd !l in + l := List.tl !l; + v + +let reinit _ = + PC.reinit (function _ -> PC.TArobArob (* a handy token *)) + (Lexing.from_function + (function buf -> function n -> raise Common.Impossible)) + +let parse_one str parsefn file toks = + let all_tokens = ref toks in + let cur_tok = ref (List.hd !all_tokens) in + + let lexer_function _ = + let (v, info) = pop2 all_tokens in + cur_tok := (v, info); + v in + + let lexbuf_fake = + Lexing.from_function + (function buf -> function n -> raise Common.Impossible) + in + + reinit(); + + try parsefn lexer_function lexbuf_fake + with + Lexer_cocci.Lexical s -> + failwith + (Printf.sprintf "%s: lexical error: %s\n =%s\n" str s + (Common.error_message file (get_s_starts !cur_tok) )) + | Parser_cocci_menhir.Error -> + failwith + (Printf.sprintf "%s: parse error: \n = %s\n" str + (Common.error_message file (get_s_starts !cur_tok) )) + | Semantic_cocci.Semantic s -> + failwith + (Printf.sprintf "%s: semantic error: %s\n =%s\n" str s + (Common.error_message file (get_s_starts !cur_tok) )) + + | e -> raise e + +let prepare_tokens tokens = + translate_when_true_false (* after insert_line_end *) + (insert_line_end + (detect_types false (find_function_names (detect_attr tokens)))) + +let rec consume_minus_positions = function + [] -> [] + | x::(PC.TPArob,_)::(PC.TMetaPos(name,constraints,per,clt),_)::xs -> + let (arity,ln,lln,offset,col,strbef,straft,_) = get_clt x in + let name = Parse_aux.clt2mcode name clt in + let x = + update_clt x + (arity,ln,lln,offset,col,strbef,straft, + Ast0.MetaPos(name,constraints,per)) in + x::(consume_minus_positions xs) + | x::xs -> x::consume_minus_positions xs + +let any_modif rule = + let mcode x = + match Ast0.get_mcode_mcodekind x with + Ast0.MINUS _ | Ast0.PLUS -> true + | _ -> false in + let donothing r k e = k e in + let bind x y = x or y in + let option_default = false 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 + List.exists fn.V0.combiner_top_level rule + +let drop_last extra l = List.rev(extra@(List.tl(List.rev l))) + +let partition_either l = + let rec part_either left right = function + | [] -> (List.rev left, List.rev right) + | x :: l -> + (match x with + | Common.Left e -> part_either (e :: left) right l + | Common.Right e -> part_either left (e :: right) l) in + part_either [] [] l + +let get_metavars parse_fn table file lexbuf = + let rec meta_loop acc (* read one decl at a time *) = + let (_,tokens) = + tokens_all table file true lexbuf [PC.TArobArob;PC.TMPtVirg] in + let tokens = prepare_tokens tokens in + match tokens with + [(PC.TArobArob,_)] -> List.rev acc + | _ -> + let metavars = parse_one "meta" parse_fn file tokens in + meta_loop (metavars@acc) in + partition_either (meta_loop []) + +let get_script_metavars parse_fn table file lexbuf = + let rec meta_loop acc = + let (_, tokens) = + tokens_all table file true lexbuf [PC.TArobArob; PC.TMPtVirg] in + let tokens = prepare_tokens tokens in + match tokens with + [(PC.TArobArob, _)] -> List.rev acc + | _ -> + let metavar = parse_one "scriptmeta" parse_fn file tokens in + meta_loop (metavar :: acc) + in + meta_loop [] + +let get_rule_name parse_fn starts_with_name get_tokens file prefix = + Data.in_rule_name := true; + let mknm _ = make_name prefix (!Lexer_cocci.line) in + let name_res = + if starts_with_name + then + let (_,tokens) = get_tokens [PC.TArob] in + match parse_one "rule name" parse_fn file tokens with + Ast.CocciRulename (None,a,b,c,d,e) -> + Ast.CocciRulename (Some (mknm()),a,b,c,d,e) + | Ast.CocciRulename (Some nm,a,b,c,d,e) -> + (if List.mem nm reserved_names + then failwith (Printf.sprintf "invalid name %s\n" nm)); + Ast.CocciRulename (Some nm,a,b,c,d,e) + | Ast.ScriptRulename(s,deps) -> Ast.ScriptRulename(s,deps) + else + Ast.CocciRulename(Some(mknm()),Ast.NoDep,[],[],Ast.Undetermined,false) in + Data.in_rule_name := false; + name_res + +let parse_iso file = + let table = Common.full_charpos_to_pos file in + Common.with_open_infile file (fun channel -> + let lexbuf = Lexing.from_channel channel in + let get_tokens = tokens_all table file false lexbuf in + let res = + match get_tokens [PC.TArobArob;PC.TArob] with + (true,start) -> + let parse_start start = + let rev = List.rev start in + let (arob,_) = List.hd rev in + (arob = PC.TArob,List.rev(List.tl rev)) in + let (starts_with_name,start) = parse_start start in + let rec loop starts_with_name start = + (!Data.init_rule)(); + (* get metavariable declarations - have to be read before the + rest *) + let (rule_name,_,_,_,_,_) = + match get_rule_name PC.iso_rule_name starts_with_name get_tokens + file ("iso file "^file) with + Ast.CocciRulename (Some n,a,b,c,d,e) -> (n,a,b,c,d,e) + | _ -> failwith "Script rules cannot appear in isomorphism rules" + in + Ast0.rule_name := rule_name; + Data.in_meta := true; + let iso_metavars = + match get_metavars PC.iso_meta_main table file lexbuf with + (iso_metavars,[]) -> iso_metavars + | _ -> failwith "unexpected inheritance in iso" in + Data.in_meta := false; + (* get the rule *) + let (more,tokens) = + get_tokens + [PC.TIsoStatement;PC.TIsoExpression;PC.TIsoArgExpression; + PC.TIsoTestExpression; + PC.TIsoDeclaration;PC.TIsoType;PC.TIsoTopLevel] in + let next_start = List.hd(List.rev tokens) in + let dummy_info = ("",(-1,-1),(-1,-1)) in + let tokens = drop_last [(PC.EOF,dummy_info)] tokens in + let tokens = prepare_tokens (start@tokens) in + (* + print_tokens "iso tokens" tokens; + *) + let entry = parse_one "iso main" PC.iso_main file tokens in + let entry = List.map (List.map Test_exps.process_anything) entry in + if more + then (* The code below allows a header like Statement list, + which is more than one word. We don't have that any more, + but the code is left here in case it is put back. *) + match get_tokens [PC.TArobArob;PC.TArob] with + (true,start) -> + let (starts_with_name,start) = parse_start start in + (iso_metavars,entry,rule_name) :: + (loop starts_with_name (next_start::start)) + | _ -> failwith "isomorphism ends early" + else [(iso_metavars,entry,rule_name)] in + loop starts_with_name start + | (false,_) -> [] in + res) + +let parse_iso_files existing_isos iso_files extra_path = + let get_names = List.map (function (_,_,nm) -> nm) in + let old_names = get_names existing_isos in + Data.in_iso := true; + let (res,_) = + List.fold_left + (function (prev,names) -> + function file -> + Lexer_cocci.init (); + let file = + match file with + Common.Left(fl) -> Filename.concat extra_path fl + | Common.Right(fl) -> Filename.concat Config.path fl in + let current = parse_iso file in + let new_names = get_names current in + if List.exists (function x -> List.mem x names) new_names + then failwith (Printf.sprintf "repeated iso name found in %s" file); + (current::prev,new_names @ names)) + ([],old_names) iso_files in + Data.in_iso := false; + existing_isos@(List.concat (List.rev res)) + +let parse file = + let table = Common.full_charpos_to_pos file in + Common.with_open_infile file (fun channel -> + let lexbuf = Lexing.from_channel channel in + let get_tokens = tokens_all table file false lexbuf in + Data.in_prolog := true; + let initial_tokens = get_tokens [PC.TArobArob;PC.TArob] in + Data.in_prolog := false; + let res = + match initial_tokens with + (true,data) -> + (match List.rev data with + ((PC.TArobArob as x),_)::_ | ((PC.TArob as x),_)::_ -> + let iso_files = + parse_one "iso file names" PC.include_main file data in + + let parse_cocci_rule old_metas + (rule_name, dependencies, iso, dropiso, exists, is_expression) = + Ast0.rule_name := rule_name; + Data.inheritable_positions := + rule_name :: !Data.inheritable_positions; + + (* get metavariable declarations *) + Data.in_meta := true; + let (metavars, inherited_metavars) = + get_metavars PC.meta_main table file lexbuf in + Data.in_meta := false; + Hashtbl.add Data.all_metadecls rule_name metavars; + Hashtbl.add Lexer_cocci.rule_names rule_name (); + Hashtbl.add Lexer_cocci.all_metavariables rule_name + (Hashtbl.fold + (fun key v rest -> (key,v)::rest) + Lexer_cocci.metavariables []); + + (* get transformation rules *) + let (more, tokens) = get_tokens [PC.TArobArob; PC.TArob] in + let (minus_tokens, plus_tokens) = split_token_stream tokens in + + let minus_tokens = consume_minus_positions minus_tokens in + let minus_tokens = prepare_tokens minus_tokens in + let plus_tokens = prepare_tokens plus_tokens in + + (* + print_tokens "minus tokens" minus_tokens; + print_tokens "plus tokens" plus_tokens; + *) + + let plus_tokens = + process_pragmas + (fix (function x -> drop_double_dots (drop_empty_or x)) + (drop_when plus_tokens)) in + (* + print_tokens "plus tokens" plus_tokens; + Printf.printf "before minus parse\n"; + *) + let minus_res = + if is_expression + then parse_one "minus" PC.minus_exp_main file minus_tokens + else parse_one "minus" PC.minus_main file minus_tokens in + (* + Unparse_ast0.unparse minus_res; + Printf.printf "before plus parse\n"; + *) + let plus_res = + if !Flag.sgrep_mode2 + then (* not actually used for anything, except context_neg *) + List.map + (Iso_pattern.rebuild_mcode None).V0.rebuilder_top_level + minus_res + else + if is_expression + then parse_one "plus" PC.plus_exp_main file plus_tokens + else parse_one "plus" PC.plus_main file plus_tokens in + (* + Printf.printf "after plus parse\n"; + *) + + (if not !Flag.sgrep_mode2 && + (any_modif minus_res or any_modif plus_res) + then Data.inheritable_positions := []); + + Check_meta.check_meta rule_name old_metas inherited_metavars + metavars minus_res plus_res; + + (more, Ast0.CocciRule ((minus_res, metavars, + (iso, dropiso, dependencies, rule_name, exists)), + (plus_res, metavars)), metavars, tokens) in + + let parse_script_rule language old_metas deps = + let get_tokens = tokens_script_all table file false lexbuf in + + (* meta-variables *) + Data.in_meta := true; + let metavars = + get_script_metavars PC.script_meta_main table file lexbuf in + Data.in_meta := false; + + let exists_in old_metas (py,(r,m)) = + let test (rr,mr) x = + let (ro,vo) = Ast.get_meta_name x in + ro = rr && vo = mr in + List.exists (test (r,m)) old_metas in + + List.iter + (function x -> + let meta2c (r,n) = Printf.sprintf "%s.%s" r n in + if not (exists_in old_metas x) then + failwith + (Printf.sprintf + "Script references unknown meta-variable: %s" + (meta2c(snd x)))) + metavars; + + (* script code *) + let (more, tokens) = get_tokens [PC.TArobArob; PC.TArob] in + let data = + match List.hd tokens with + (PC.TScriptData(s),_) -> s + | (PC.TArobArob,_) | (PC.TArob,_) -> "" + | _ -> failwith "Malformed script rule" in + (more,Ast0.ScriptRule(language, deps, metavars, data),[],tokens) in + + let parse_rule old_metas starts_with_name = + let rulename = + get_rule_name PC.rule_name starts_with_name get_tokens file + "rule" in + match rulename with + Ast.CocciRulename (Some s, a, b, c, d, e) -> + parse_cocci_rule old_metas (s, a, b, c, d, e) + | Ast.ScriptRulename (l,deps) -> parse_script_rule l old_metas deps + | _ -> failwith "Malformed rule name" + in + + let rec loop old_metas starts_with_name = + (!Data.init_rule)(); + + let gen_starts_with_name more tokens = + more && + (match List.hd (List.rev tokens) with + (PC.TArobArob,_) -> false + | (PC.TArob,_) -> true + | _ -> failwith "unexpected token") + in + + let (more, rule, metavars, tokens) = + parse_rule old_metas starts_with_name in + if more then + rule:: + (loop (metavars @ old_metas) (gen_starts_with_name more tokens)) + else [rule]; + + in + + (iso_files, loop [] (x = PC.TArob)) + | _ -> failwith "unexpected code before the first rule\n") + | (false,[(PC.TArobArob,_)]) | (false,[(PC.TArob,_)]) -> + ([],([] : Ast0.parsed_rule list)) + | _ -> failwith "unexpected code before the first rule\n" in + res) + +(* parse to ast0 and then convert to ast *) +let process file isofile verbose = + let extra_path = Filename.dirname file in + Lexer_cocci.init(); + let (iso_files, rules) = parse file in + let std_isos = + match isofile with + None -> [] + | Some iso_file -> parse_iso_files [] [Common.Left iso_file] "" in + let global_isos = parse_iso_files std_isos iso_files extra_path in + let rules = Unitary_ast0.do_unitary rules in + let parsed = + List.map + (function + Ast0.ScriptRule (a,b,c,d) -> [([],Ast.ScriptRule (a,b,c,d))] + | Ast0.CocciRule + ((minus, metavarsm, + (iso, dropiso, dependencies, rule_name, exists)), + (plus, metavars)) -> + let chosen_isos = + parse_iso_files global_isos + (List.map (function x -> Common.Left x) iso) + extra_path in + let chosen_isos = + (* check that dropped isos are actually available *) + (try + let iso_names = + List.map (function (_,_,nm) -> nm) chosen_isos in + let local_iso_names = reserved_names @ iso_names in + let bad_dropped = + List.find + (function dropped -> + not (List.mem dropped local_iso_names)) + dropiso in + failwith + ("invalid iso name " ^ bad_dropped ^ " in " ^ rule_name) + with Not_found -> ()); + if List.mem "all" dropiso + then + if List.length dropiso = 1 + then [] + else failwith "disable all should only be by itself" + else (* drop those isos *) + List.filter + (function (_,_,nm) -> not (List.mem nm dropiso)) + chosen_isos in + List.iter Iso_compile.process chosen_isos; + let dropped_isos = + match reserved_names with + "all"::others -> + (match dropiso with + ["all"] -> others + | _ -> + List.filter (function x -> List.mem x dropiso) others) + | _ -> + failwith + "bad list of reserved names - all must be at start" in + let minus = Test_exps.process minus in + let minus = Compute_lines.compute_lines minus in + let plus = Compute_lines.compute_lines plus in + let is_exp = + (* only relevant to Flag.make_hrule *) + (* doesn't handle multiple minirules properly, but since + we don't really handle them in lots of other ways, it + doesn't seem very important *) + match plus with + [] -> [false] + | p::_ -> + [match Ast0.unwrap p with + Ast0.CODE c -> + (match List.map Ast0.unwrap (Ast0.undots c) with + [Ast0.Exp e] -> true | _ -> false) + | _ -> false] in + let minus = Arity.minus_arity minus in + let ((metavars,minus),function_prototypes) = + Function_prototypes.process + rule_name metavars dropped_isos minus plus in + (* warning! context_neg side-effects its arguments *) + let (m,p) = List.split (Context_neg.context_neg minus plus) in + Type_infer.type_infer p; + (if not !Flag.sgrep_mode2 then Insert_plus.insert_plus m p); + Type_infer.type_infer minus; + let (extra_meta, minus) = + Iso_pattern.apply_isos chosen_isos minus rule_name in + let minus = Comm_assoc.comm_assoc minus rule_name dropiso in + let minus = + if !Flag.sgrep_mode2 then minus + else Single_statement.single_statement minus in + let minus = Simple_assignments.simple_assignments minus in + let minus_ast = + Ast0toast.ast0toast rule_name dependencies dropped_isos + exists minus is_exp in + match function_prototypes with + None -> [(extra_meta @ metavars, minus_ast)] + | Some mv_fp -> + [(extra_meta @ metavars, minus_ast); mv_fp]) +(* Ast0.CocciRule ((minus, metavarsm, (iso, dropiso, dependencies, rule_name, exists)), (plus, metavars))*) + rules in + let parsed = List.concat parsed in + let disjd = Disjdistr.disj parsed in + + let (code,fvs,neg_pos,ua,pos) = Free_vars.free_vars disjd in + if !Flag_parsing_cocci.show_SP + then List.iter Pretty_print_cocci.unparse code; + + let grep_tokens = + Common.profile_code "get_constants" + (fun () -> Get_constants.get_constants code) in (* for grep *) + let glimpse_tokens2 = + Common.profile_code "get_glimpse_constants" + (fun () -> Get_constants2.get_constants code neg_pos) in(* for glimpse *) + (code,fvs,neg_pos,ua,pos,grep_tokens,glimpse_tokens2) diff --git a/parsing_cocci/.#parser_cocci_menhir.mly.1.153 b/parsing_cocci/.#parser_cocci_menhir.mly.1.153 new file mode 100644 index 0000000..a3be6b6 --- /dev/null +++ b/parsing_cocci/.#parser_cocci_menhir.mly.1.153 @@ -0,0 +1,1765 @@ +/* +* 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 +%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 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 +%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 } + | scr=pure_ident TDotDot lang=pure_ident d=depends TArob + { P.make_script_rule_name_result scr 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))))] } +| 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} + +/* ------------------------------------------------------------------------ */ +/* Plus top level */ + +/* does allow only ... also allows multiple top-level functions */ +plus_start: + ctype { [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Ty($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) } + +dots_when(dotter,when_grammar,simple_when_grammar): + d=dotter w=list(whens(when_grammar,simple_when_grammar)) + { (d,List.concat 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 } + +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/.#parser_cocci_menhir.mly.1.155 b/parsing_cocci/.#parser_cocci_menhir.mly.1.155 new file mode 100644 index 0000000..3e30d2d --- /dev/null +++ b/parsing_cocci/.#parser_cocci_menhir.mly.1.155 @@ -0,0 +1,1763 @@ +/* +* 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 +%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))))] } +| 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} + +/* ------------------------------------------------------------------------ */ +/* Plus top level */ + +/* does allow only ... also allows multiple top-level functions */ +plus_start: + ctype { [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Ty($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/.#pretty_print_cocci.ml.1.127 b/parsing_cocci/.#pretty_print_cocci.ml.1.127 new file mode 100644 index 0000000..308a25e --- /dev/null +++ b/parsing_cocci/.#pretty_print_cocci.ml.1.127 @@ -0,0 +1,855 @@ +(* +* 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 Ast = Ast_cocci + +let print_plus_flag = ref true +let print_minus_flag = ref true +let print_newlines_disj = ref true + +let start_block str = + force_newline(); print_string " "; open_box 0 + +let end_block str = + close_box(); force_newline () + +let print_string_box s = print_string s; open_box 0 + + +let print_option = Common.do_option +let print_between = Common.print_between + +(* --------------------------------------------------------------------- *) +(* Modified code *) + +(* avoid polyvariance problems *) +let anything : (Ast.anything -> unit) ref = ref (function _ -> ()) + +let rec print_anything str = function + [] -> () + | stream -> + start_block(); + print_between force_newline + (function x -> + print_string str; open_box 0; print_anything_list x; close_box()) + stream; + end_block() + +and print_anything_list = function + [] -> () + | [x] -> !anything x + | bef::((aft::_) as rest) -> + !anything bef; + let space = + (match bef with + Ast.Rule_elemTag(_) | Ast.AssignOpTag(_) | Ast.BinaryOpTag(_) + | Ast.ArithOpTag(_) | Ast.LogicalOpTag(_) + | Ast.Token("if",_) | Ast.Token("while",_) -> true | _ -> false) or + (match aft with + Ast.Rule_elemTag(_) | Ast.AssignOpTag(_) | Ast.BinaryOpTag(_) + | Ast.ArithOpTag(_) | Ast.LogicalOpTag(_) | Ast.Token("{",_) -> true + | _ -> false) in + if space then print_string " "; + print_anything_list rest + +let print_around printer term = function + Ast.NOTHING -> printer term + | Ast.BEFORE(bef) -> print_anything "<<< " bef; printer term + | Ast.AFTER(aft) -> printer term; print_anything ">>> " aft + | Ast.BEFOREAFTER(bef,aft) -> + print_anything "<<< " bef; printer term; print_anything ">>> " aft + +let print_string_befaft fn x info = + List.iter (function s -> print_string s; force_newline()) + info.Ast.strbef; + fn x; + List.iter (function s -> force_newline(); print_string s) + info.Ast.straft + +let print_meta (r,x) = print_string r; print_string ":"; print_string x + +let print_pos = function + Ast.MetaPos(name,_,_,_,_) -> + let name = Ast.unwrap_mcode name in + print_string "@"; print_meta name + | _ -> () + +let mcode fn = function + (x, _, Ast.MINUS(_,plus_stream), pos) -> + if !print_minus_flag + then print_string (if !Flag.sgrep_mode2 then "*" else "-"); + fn x; print_pos pos; + if !print_plus_flag + then print_anything ">>> " plus_stream + | (x, _, Ast.CONTEXT(_,plus_streams), pos) -> + if !print_plus_flag + then + let fn x = fn x; print_pos pos in + print_around fn x plus_streams + else (fn x; print_pos pos) + | (x, info, Ast.PLUS, pos) -> + let fn x = fn x; print_pos pos in + print_string_befaft fn x info + +let print_mcodekind = function + Ast.MINUS(_,plus_stream) -> + print_string "MINUS"; + print_anything ">>> " plus_stream + | Ast.CONTEXT(_,plus_streams) -> + print_around (function _ -> print_string "CONTEXT") () plus_streams + | Ast.PLUS -> print_string "PLUS" + +(* --------------------------------------------------------------------- *) +(* --------------------------------------------------------------------- *) +(* Dots *) + +let dots between fn d = + match Ast.unwrap d with + Ast.DOTS(l) -> print_between between fn l + | Ast.CIRCLES(l) -> print_between between fn l + | Ast.STARS(l) -> print_between between fn l + +let nest_dots multi fn f d = + let mo s = if multi then "<+"^s else "<"^s in + let mc s = if multi then s^"+>" else s^">" in + match Ast.unwrap d with + Ast.DOTS(l) -> + print_string (mo "..."); f(); start_block(); + print_between force_newline fn l; + end_block(); print_string (mc "...") + | Ast.CIRCLES(l) -> + print_string (mo "ooo"); f(); start_block(); + print_between force_newline fn l; + end_block(); print_string (mc "ooo") + | Ast.STARS(l) -> + print_string (mo "***"); f(); start_block(); + print_between force_newline fn l; + end_block(); print_string (mc "***") + +(* --------------------------------------------------------------------- *) + +let print_type keep info = function + None -> () + (* print_string "/* "; + print_string "keep:"; print_unitary keep; + print_string " inherited:"; print_bool inherited; + print_string " */"*) + | Some ty -> () + (*; + print_string "/* "; + print_between (function _ -> print_string ", ") Type_cocci.typeC ty;(* + print_string "keep:"; print_unitary keep; + print_string " inherited:"; print_bool inherited;*) + print_string " */"*) + +(* --------------------------------------------------------------------- *) +(* Identifier *) + +let rec ident i = + match Ast.unwrap i with + Ast.Id(name) -> mcode print_string name + | Ast.MetaId(name,_,keep,inherited) -> mcode print_meta name + | Ast.MetaFunc(name,_,_,_) -> mcode print_meta name + | Ast.MetaLocalFunc(name,_,_,_) -> mcode print_meta name + | Ast.OptIdent(id) -> print_string "?"; ident id + | Ast.UniqueIdent(id) -> print_string "!"; ident id + +and print_unitary = function + Type_cocci.Unitary -> print_string "unitary" + | Type_cocci.Nonunitary -> print_string "nonunitary" + | Type_cocci.Saved -> print_string "saved" + +(* --------------------------------------------------------------------- *) +(* Expression *) + +let print_disj_list fn l = + if !print_newlines_disj + then (force_newline(); print_string "("; force_newline()) + else print_string "("; + print_between + (function _ -> + if !print_newlines_disj + then (force_newline(); print_string "|"; force_newline()) + else print_string " | ") + fn l; + if !print_newlines_disj + then (force_newline(); print_string ")"; force_newline()) + else print_string ")" + +let rec expression e = + match Ast.unwrap e with + Ast.Ident(id) -> ident id + | Ast.Constant(const) -> mcode constant const + | Ast.FunCall(fn,lp,args,rp) -> + expression fn; mcode print_string_box lp; + dots (function _ -> ()) expression args; + close_box(); mcode print_string rp + | Ast.Assignment(left,op,right,simple) -> + expression left; print_string " "; mcode assignOp op; + print_string " "; expression right + | Ast.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 + | Ast.Postfix(exp,op) -> expression exp; mcode fixOp op + | Ast.Infix(exp,op) -> mcode fixOp op; expression exp + | Ast.Unary(exp,op) -> mcode unaryOp op; expression exp + | Ast.Binary(left,op,right) -> + expression left; print_string " "; mcode binaryOp op; print_string " "; + expression right + | Ast.Nested(left,op,right) -> + expression left; print_string " "; mcode binaryOp op; print_string " "; + expression right + | Ast.Paren(lp,exp,rp) -> + mcode print_string_box lp; expression exp; close_box(); + mcode print_string rp + | Ast.ArrayAccess(exp1,lb,exp2,rb) -> + expression exp1; mcode print_string_box lb; expression exp2; close_box(); + mcode print_string rb + | Ast.RecordAccess(exp,pt,field) -> + expression exp; mcode print_string pt; ident field + | Ast.RecordPtAccess(exp,ar,field) -> + expression exp; mcode print_string ar; ident field + | Ast.Cast(lp,ty,rp,exp) -> + mcode print_string_box lp; fullType ty; close_box(); + mcode print_string rp; expression exp + | Ast.SizeOfExpr(sizeof,exp) -> + mcode print_string sizeof; expression exp + | Ast.SizeOfType(sizeof,lp,ty,rp) -> + mcode print_string sizeof; + mcode print_string_box lp; fullType ty; close_box(); + mcode print_string rp + | Ast.TypeExp(ty) -> fullType ty + + | Ast.MetaErr(name,_,_,_) -> mcode print_meta name + | Ast.MetaExpr(name,_,keep,ty,form,inherited) -> + mcode print_meta name; print_type keep inherited ty + | Ast.MetaExprList(name,_,_,_) -> mcode print_meta name + | Ast.EComma(cm) -> mcode print_string cm; print_space() + | Ast.DisjExpr(exp_list) -> print_disj_list expression exp_list + | Ast.NestExpr(expr_dots,Some whencode,multi) -> + nest_dots multi expression + (function _ -> print_string " when != "; expression whencode) + expr_dots + | Ast.NestExpr(expr_dots,None,multi) -> + nest_dots multi expression (function _ -> ()) expr_dots + | Ast.Edots(dots,Some whencode) + | Ast.Ecircles(dots,Some whencode) + | Ast.Estars(dots,Some whencode) -> + mcode print_string dots; print_string " when != "; expression whencode + | Ast.Edots(dots,None) + | Ast.Ecircles(dots,None) + | Ast.Estars(dots,None) -> mcode print_string dots + | Ast.OptExp(exp) -> print_string "?"; expression exp + | Ast.UniqueExp(exp) -> print_string "!"; expression exp + +and unaryOp = function + Ast.GetRef -> print_string "&" + | Ast.DeRef -> print_string "*" + | Ast.UnPlus -> print_string "+" + | Ast.UnMinus -> print_string "-" + | Ast.Tilde -> print_string "~" + | Ast.Not -> print_string "!" + +and assignOp = function + Ast.SimpleAssign -> print_string "=" + | Ast.OpAssign(aop) -> arithOp aop; print_string "=" + +and fixOp = function + Ast.Dec -> print_string "--" + | Ast.Inc -> print_string "++" + +and binaryOp = function + Ast.Arith(aop) -> arithOp aop + | Ast.Logical(lop) -> logicalOp lop + +and arithOp = function + Ast.Plus -> print_string "+" + | Ast.Minus -> print_string "-" + | Ast.Mul -> print_string "*" + | Ast.Div -> print_string "/" + | Ast.Mod -> print_string "%" + | Ast.DecLeft -> print_string "<<" + | Ast.DecRight -> print_string ">>" + | Ast.And -> print_string "&" + | Ast.Or -> print_string "|" + | Ast.Xor -> print_string "^" + +and logicalOp = function + Ast.Inf -> print_string "<" + | Ast.Sup -> print_string ">" + | Ast.InfEq -> print_string "<=" + | Ast.SupEq -> print_string ">=" + | Ast.Eq -> print_string "==" + | Ast.NotEq -> print_string "!=" + | Ast.AndLog -> print_string "&&" + | Ast.OrLog -> print_string "||" + +and constant = function + Ast.String(s) -> print_string "\""; print_string s; print_string "\"" + | Ast.Char(s) -> print_string "'"; print_string s; print_string "'" + | Ast.Int(s) -> print_string s + | Ast.Float(s) -> print_string s + +(* --------------------------------------------------------------------- *) +(* Declarations *) + +and storage = function + Ast.Static -> print_string "static " + | Ast.Auto -> print_string "auto " + | Ast.Register -> print_string "register " + | Ast.Extern -> print_string "extern " + +(* --------------------------------------------------------------------- *) +(* Types *) + +and fullType ft = + match Ast.unwrap ft with + Ast.Type(cv,ty) -> + print_option (function x -> mcode const_vol x; print_string " ") cv; + typeC ty + | Ast.DisjType(decls) -> print_disj_list fullType decls + | Ast.OptType(ty) -> print_string "?"; fullType ty + | Ast.UniqueType(ty) -> print_string "!"; fullType ty + +and print_function_pointer (ty,lp1,star,rp1,lp2,params,rp2) fn = + fullType ty; mcode print_string lp1; mcode print_string star; fn(); + mcode print_string rp1; mcode print_string lp1; + parameter_list params; mcode print_string rp2 + +and print_function_type (ty,lp1,params,rp1) fn = + print_option fullType ty; fn(); mcode print_string lp1; + parameter_list params; mcode print_string rp1 + +and print_fninfo = function + Ast.FStorage(stg) -> mcode storage stg + | Ast.FType(ty) -> fullType ty + | Ast.FInline(inline) -> mcode print_string inline; print_string " " + | Ast.FAttr(attr) -> mcode print_string attr; print_string " " + +and typeC ty = + match Ast.unwrap ty with + Ast.BaseType(ty,sgn) -> print_option (mcode sign) sgn; mcode baseType ty + | Ast.ImplicitInt(sgn) -> mcode sign sgn + | Ast.Pointer(ty,star) -> fullType ty; mcode print_string star + | Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> + print_function_pointer (ty,lp1,star,rp1,lp2,params,rp2) + (function _ -> ()) + | Ast.FunctionType (_,ty,lp1,params,rp1) -> + print_function_type (ty,lp1,params,rp1) (function _ -> ()) + | Ast.Array(ty,lb,size,rb) -> + fullType ty; mcode print_string lb; print_option expression size; + mcode print_string rb + | Ast.StructUnionName(kind,name) -> + mcode structUnion kind; + print_option (function x -> ident x; print_string " ") name + | Ast.StructUnionDef(ty,lb,decls,rb) -> + fullType ty; mcode print_string lb; + dots force_newline declaration decls; + mcode print_string rb + | Ast.TypeName(name) -> mcode print_string name; print_string " " + | Ast.MetaType(name,_,_) -> + mcode print_meta name; print_string " " + +and baseType = function + Ast.VoidType -> print_string "void " + | Ast.CharType -> print_string "char " + | Ast.ShortType -> print_string "short " + | Ast.IntType -> print_string "int " + | Ast.DoubleType -> print_string "double " + | Ast.FloatType -> print_string "float " + | Ast.LongType -> print_string "long " + +and structUnion = function + Ast.Struct -> print_string "struct " + | Ast.Union -> print_string "union " + +and sign = function + Ast.Signed -> print_string "signed " + | Ast.Unsigned -> print_string "unsigned " + +and const_vol = function + Ast.Const -> print_string "const" + | Ast.Volatile -> print_string "volatile" + +(* --------------------------------------------------------------------- *) +(* 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 Ast.unwrap ty with + Ast.Type(None,ty1) -> + (match Ast.unwrap ty1 with + Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> + print_function_pointer (ty,lp1,star,rp1,lp2,params,rp2) + (function _ -> print_string " "; ident id) + | Ast.FunctionType(_,ty,lp1,params,rp1) -> + print_function_type (ty,lp1,params,rp1) + (function _ -> print_string " "; ident id) + | Ast.Array(ty,lb,size,rb) -> + let rec loop ty k = + match Ast.unwrap ty with + Ast.Array(ty,lb,size,rb) -> + (match Ast.unwrap ty with + Ast.Type(None,ty) -> + loop ty + (function _ -> + k (); + mcode print_string lb; + print_option expression size; + mcode print_string rb) + | _ -> failwith "complex array types not supported") + | _ -> typeC ty; ident id; k () in + loop ty1 (function _ -> ()) + | _ -> fullType ty; ident id) + | _ -> fullType ty; ident id + +and declaration d = + match Ast.unwrap d with + Ast.Init(stg,ty,id,eq,ini,sem) -> + print_option (mcode storage) stg; print_named_type ty id; + print_string " "; mcode print_string eq; + print_string " "; initialiser ini; mcode print_string sem + | Ast.UnInit(stg,ty,id,sem) -> + print_option (mcode storage) stg; print_named_type ty id; + mcode print_string sem + | Ast.MacroDecl(name,lp,args,rp,sem) -> + ident name; mcode print_string_box lp; + dots (function _ -> ()) expression args; + close_box(); mcode print_string rp; mcode print_string sem + | Ast.TyDecl(ty,sem) -> fullType ty; mcode print_string sem + | Ast.Typedef(stg,ty,id,sem) -> + mcode print_string stg; print_string " "; fullType ty; typeC id; + mcode print_string sem + | Ast.DisjDecl(decls) -> print_disj_list declaration decls + | Ast.Ddots(dots,Some whencode) -> + mcode print_string dots; print_string " when != "; declaration whencode + | Ast.Ddots(dots,None) -> mcode print_string dots + | Ast.MetaDecl(name,_,_) -> mcode print_meta name + | Ast.OptDecl(decl) -> print_string "?"; declaration decl + | Ast.UniqueDecl(decl) -> print_string "!"; declaration decl + +(* --------------------------------------------------------------------- *) +(* Initialiser *) + +and initialiser i = + match Ast.unwrap i with + Ast.InitExpr(exp) -> expression exp + | Ast.InitList(lb,initlist,rb,whencode) -> + mcode print_string lb; open_box 0; + if not (whencode = []) + then + (print_string " WHEN != "; + print_between (function _ -> print_string " v ") + initialiser whencode; + force_newline()); + List.iter initialiser initlist; close_box(); + mcode print_string rb + | Ast.InitGccDotName(dot,name,eq,ini) -> + mcode print_string dot; ident name; print_string " "; + mcode print_string eq; print_string " "; initialiser ini + | Ast.InitGccName(name,eq,ini) -> + ident name; mcode print_string eq; initialiser ini + | Ast.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 + | Ast.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 + | Ast.IComma(comma) -> mcode print_string comma; force_newline() + | Ast.OptIni(ini) -> print_string "?"; initialiser ini + | Ast.UniqueIni(ini) -> print_string "!"; initialiser ini + +(* --------------------------------------------------------------------- *) +(* Parameter *) + +and parameterTypeDef p = + match Ast.unwrap p with + Ast.VoidParam(ty) -> fullType ty + | Ast.Param(ty,Some id) -> print_named_type ty id + | Ast.Param(ty,None) -> fullType ty + | Ast.MetaParam(name,_,_) -> mcode print_meta name + | Ast.MetaParamList(name,_,_,_) -> mcode print_meta name + | Ast.PComma(cm) -> mcode print_string cm; print_space() + | Ast.Pdots(dots) -> mcode print_string dots + | Ast.Pcircles(dots) -> mcode print_string dots + | Ast.OptParam(param) -> print_string "?"; parameterTypeDef param + | Ast.UniqueParam(param) -> print_string "!"; parameterTypeDef param + +and parameter_list l = dots (function _ -> ()) parameterTypeDef l + +(* --------------------------------------------------------------------- *) +(* Top-level code *) + +let rec rule_elem arity re = + match Ast.unwrap re with + Ast.FunHeader(bef,allminus,fninfo,name,lp,params,rp) -> + mcode (function _ -> ()) ((),Ast.no_info,bef,Ast.NoMetaPos); + 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 " " + | Ast.Decl(bef,allminus,decl) -> + mcode (function _ -> ()) ((),Ast.no_info,bef,Ast.NoMetaPos); + print_string arity; + declaration decl + | Ast.SeqStart(brace) -> + print_string arity; mcode print_string brace; + if !print_newlines_disj then start_block() + | Ast.SeqEnd(brace) -> + if !print_newlines_disj then end_block(); + print_string arity; mcode print_string brace + | Ast.ExprStatement(exp,sem) -> + print_string arity; expression exp; mcode print_string sem + | Ast.IfHeader(iff,lp,exp,rp) -> + print_string arity; + mcode print_string iff; print_string " "; mcode print_string_box lp; + expression exp; close_box(); mcode print_string rp; print_string " " + | Ast.Else(els) -> + print_string arity; mcode print_string els; print_string " " + | Ast.WhileHeader(whl,lp,exp,rp) -> + print_string arity; + mcode print_string whl; print_string " "; mcode print_string_box lp; + expression exp; close_box(); mcode print_string rp; print_string " " + | Ast.DoHeader(d) -> + print_string arity; mcode print_string d; print_string " " + | Ast.WhileTail(whl,lp,exp,rp,sem) -> + 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 + | Ast.ForHeader(fr,lp,e1,sem1,e2,sem2,e3,rp) -> + 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 " " + | Ast.IteratorHeader(nm,lp,args,rp) -> + print_string arity; + ident nm; print_string " "; mcode print_string_box lp; + dots (function _ -> ()) expression args; close_box(); + mcode print_string rp; print_string " " + | Ast.SwitchHeader(switch,lp,exp,rp) -> + print_string arity; + mcode print_string switch; print_string " "; mcode print_string_box lp; + expression exp; close_box(); mcode print_string rp; print_string " " + | Ast.Break(br,sem) -> + print_string arity; mcode print_string br; mcode print_string sem + | Ast.Continue(cont,sem) -> + print_string arity; mcode print_string cont; mcode print_string sem + | Ast.Label(l,dd) -> ident l; mcode print_string dd + | Ast.Goto(goto,l,sem) -> + mcode print_string goto; ident l; mcode print_string sem + | Ast.Return(ret,sem) -> + print_string arity; mcode print_string ret; mcode print_string sem + | Ast.ReturnExpr(ret,exp,sem) -> + print_string arity; mcode print_string ret; print_string " "; + expression exp; mcode print_string sem + | Ast.MetaRuleElem(name,_,_) -> + print_string arity; mcode print_meta name + | Ast.MetaStmt(name,_,_,_) -> + print_string arity; mcode print_meta name + | Ast.MetaStmtList(name,_,_) -> + print_string arity; mcode print_meta name + | Ast.Exp(exp) -> print_string arity; expression exp + | Ast.TopExp(exp) -> print_string arity; expression exp + | Ast.Ty(ty) -> print_string arity; fullType ty + | Ast.Include(inc,s) -> + mcode print_string inc; print_string " "; mcode inc_file s + | Ast.DefineHeader(def,id,params) -> + mcode print_string def; print_string " "; ident id; + print_define_parameters params + | Ast.Default(def,colon) -> + mcode print_string def; mcode print_string colon; print_string " " + | Ast.Case(case,exp,colon) -> + mcode print_string case; print_string " "; expression exp; + mcode print_string colon; print_string " " + | Ast.DisjRuleElem(res) -> + print_string arity; + force_newline(); print_string "("; force_newline(); + print_between + (function _ -> force_newline();print_string "|"; force_newline()) + (rule_elem arity) + res; + force_newline(); print_string ")" + + +and print_define_parameters params = + match Ast.unwrap params with + Ast.NoParams -> () + | Ast.DParams(lp,params,rp) -> + mcode print_string lp; + dots (function _ -> ()) print_define_param params; mcode print_string rp + +and print_define_param param = + match Ast.unwrap param with + Ast.DParam(id) -> ident id + | Ast.DPComma(comma) -> mcode print_string comma + | Ast.DPdots(dots) -> mcode print_string dots + | Ast.DPcircles(circles) -> mcode print_string circles + | Ast.OptDParam(dp) -> print_string "?"; print_define_param dp + | Ast.UniqueDParam(dp) -> print_string "!"; print_define_param dp + +and statement arity s = + match Ast.unwrap s with + Ast.Seq(lbrace,decls,body,rbrace) -> + rule_elem arity lbrace; + dots force_newline (statement arity) decls; + dots force_newline (statement arity) body; + rule_elem arity rbrace + | Ast.IfThen(header,branch,(_,_,_,aft)) -> + rule_elem arity header; statement arity branch; + mcode (function _ -> ()) ((),Ast.no_info,aft,Ast.NoMetaPos) + | Ast.IfThenElse(header,branch1,els,branch2,(_,_,_,aft)) -> + rule_elem arity header; statement arity branch1; print_string " "; + rule_elem arity els; statement arity branch2; + mcode (function _ -> ()) ((),Ast.no_info,aft,Ast.NoMetaPos) + | Ast.While(header,body,(_,_,_,aft)) -> + rule_elem arity header; statement arity body; + mcode (function _ -> ()) ((),Ast.no_info,aft,Ast.NoMetaPos) + | Ast.Do(header,body,tail) -> + rule_elem arity header; statement arity body; + rule_elem arity tail + | Ast.For(header,body,(_,_,_,aft)) -> + rule_elem arity header; statement arity body; + mcode (function _ -> ()) ((),Ast.no_info,aft,Ast.NoMetaPos) + | Ast.Iterator(header,body,(_,_,_,aft)) -> + rule_elem arity header; statement arity body; + mcode (function _ -> ()) ((),Ast.no_info,aft,Ast.NoMetaPos) + | Ast.Switch(header,lb,cases,rb) -> + rule_elem arity header; rule_elem arity lb; + List.iter (function x -> case_line arity x; force_newline()) cases; + rule_elem arity rb + | Ast.Atomic(re) -> rule_elem arity re + | Ast.FunDecl(header,lbrace,decls,body,rbrace) -> + rule_elem arity header; rule_elem arity lbrace; + dots force_newline (statement arity) decls; + dots force_newline (statement arity) body; + rule_elem arity rbrace + | Ast.Disj([stmt_dots]) -> + print_string arity; + dots (function _ -> if !print_newlines_disj then force_newline()) + (statement arity) stmt_dots + | Ast.Disj(stmt_dots_list) -> (* ignores newline directive for readability *) + print_string arity; + force_newline(); print_string "("; force_newline(); + print_between + (function _ -> force_newline();print_string "|"; force_newline()) + (dots force_newline (statement arity)) + stmt_dots_list; + force_newline(); print_string ")" + | Ast.Define(header,body) -> + rule_elem arity header; print_string " "; + dots force_newline (statement arity) body + | Ast.Nest(stmt_dots,whn,multi,_,_) -> + print_string arity; + nest_dots multi (statement arity) + (function _ -> + open_box 0; + print_between force_newline + (whencode (dots force_newline (statement "")) (statement "")) whn; + close_box(); force_newline()) + stmt_dots + | Ast.Dots(d,whn,_,_) | Ast.Circles(d,whn,_,_) | Ast.Stars(d,whn,_,_) -> + print_string arity; mcode print_string d; + open_box 0; + print_between force_newline + (whencode (dots force_newline (statement "")) (statement "")) whn; + close_box(); force_newline() + | Ast.OptStm(s) -> statement "?" s + | Ast.UniqueStm(s) -> statement "!" s + +and print_statement_when whencode = + print_string " WHEN != "; + open_box 0; + print_between (function _ -> print_string " &"; force_newline()) + (dots force_newline (statement "")) whencode; + close_box() + + +and whencode notfn alwaysfn = function + Ast.WhenNot a -> + print_string " WHEN != "; open_box 0; notfn a; close_box() + | Ast.WhenAlways a -> + print_string " WHEN = "; open_box 0; alwaysfn a; close_box() + | Ast.WhenModifier x -> print_string " WHEN "; print_when_modif x + +and print_when_modif = function + | Ast.WhenAny -> print_string "ANY" + | Ast.WhenStrict -> print_string "STRICT" + | Ast.WhenForall -> print_string "FORALL" + | Ast.WhenExists -> print_string "EXISTS" + +and case_line arity c = + match Ast.unwrap c with + Ast.CaseLine(header,code) -> + rule_elem arity header; print_string " "; + dots force_newline (statement arity) code + | Ast.OptCase(case) -> case_line "?" case + +(* --------------------------------------------------------------------- *) +(* CPP code *) + +and inc_file = function + Ast.Local(elems) -> + print_string "\""; + print_between (function _ -> print_string "/") inc_elem elems; + print_string "\"" + | Ast.NonLocal(elems) -> + print_string "<"; + print_between (function _ -> print_string "/") inc_elem elems; + print_string ">" + +and inc_elem = function + Ast.IncPath s -> print_string s + | Ast.IncDots -> print_string "..." + +(* for export only *) +let statement_dots l = dots force_newline (statement "") l + +let top_level t = + match Ast.unwrap t with + Ast.FILEINFO(old_file,new_file) -> + print_string "--- "; mcode print_string old_file; force_newline(); + print_string "+++ "; mcode print_string new_file + | Ast.DECL(stmt) -> statement "" stmt + | Ast.CODE(stmt_dots) -> + dots force_newline (statement "") stmt_dots + | Ast.ERRORWORDS(exps) -> + print_string "error words = ["; + print_between (function _ -> print_string ", ") expression exps; + print_string "]" + +let rule = + print_between (function _ -> force_newline(); force_newline()) top_level + +let pp_print_anything x = !anything x + +let _ = + anything := function + Ast.FullTypeTag(x) -> fullType x + | Ast.BaseTypeTag(x) -> baseType x + | Ast.StructUnionTag(x) -> structUnion x + | Ast.SignTag(x) -> sign x + | Ast.IdentTag(x) -> ident x + | Ast.ExpressionTag(x) -> expression x + | Ast.ConstantTag(x) -> constant x + | Ast.UnaryOpTag(x) -> unaryOp x + | Ast.AssignOpTag(x) -> assignOp x + | Ast.FixOpTag(x) -> fixOp x + | Ast.BinaryOpTag(x) -> binaryOp x + | Ast.ArithOpTag(x) -> arithOp x + | Ast.LogicalOpTag(x) -> logicalOp x + | Ast.InitTag(x) -> initialiser x + | Ast.DeclarationTag(x) -> declaration x + | Ast.StorageTag(x) -> storage x + | Ast.IncFileTag(x) -> inc_file x + | Ast.Rule_elemTag(x) -> rule_elem "" x + | Ast.StatementTag(x) -> statement "" x + | Ast.CaseLineTag(x) -> case_line "" x + | Ast.ConstVolTag(x) -> const_vol x + | Ast.Token(x,Some info) -> print_string_befaft print_string x info + | Ast.Token(x,None) -> print_string x + | Ast.Code(x) -> let _ = top_level x in () + | Ast.ExprDotsTag(x) -> dots (function _ -> ()) expression x + | Ast.ParamDotsTag(x) -> parameter_list x + | Ast.StmtDotsTag(x) -> dots (function _ -> ()) (statement "") x + | Ast.DeclDotsTag(x) -> dots (function _ -> ()) declaration x + | Ast.TypeCTag(x) -> typeC x + | Ast.ParamTag(x) -> parameterTypeDef x + | Ast.SgrepStartTag(x) -> print_string x + | Ast.SgrepEndTag(x) -> print_string x + +let rec dep in_and = function + Ast.Dep(s) -> print_string s + | Ast.AntiDep(s) -> print_string "!"; print_string s + | Ast.EverDep(s) -> print_string "ever "; print_string s + | Ast.NeverDep(s) -> print_string "never "; print_string s + | Ast.AndDep(s1,s2) -> + let print_and _ = dep true s1; print_string " && "; dep true s2 in + if in_and + then print_and () + else (print_string "("; print_and(); print_string ")") + | Ast.OrDep(s1,s2) -> + let print_or _ = dep false s1; print_string " || "; dep false s2 in + if not in_and + then print_or () + else (print_string "("; print_or(); print_string ")") + | Ast.NoDep -> failwith "not possible" + +let unparse z = + match z with + Ast.ScriptRule (lang,deps,bindings,code) -> + print_string "@@"; + force_newline(); + print_string ("script:" ^ lang); + (match deps with + Ast.NoDep -> () + | _ -> print_string " depends on "; dep true deps); + force_newline(); + print_string "@@"; + force_newline(); + print_string code; + force_newline() + | Ast.CocciRule (nm, (deps, drops, exists), x, _) -> + print_string "@@"; + force_newline(); + print_string nm; + (match deps with + Ast.NoDep -> () + | _ -> print_string " depends on "; dep true deps); + (* + print_string "line "; + print_int (Ast.get_line (List.hd x)); + *) + force_newline(); + print_string "@@"; + print_newlines_disj := true; + force_newline(); + force_newline(); + rule x; + force_newline() + +let rule_elem_to_string x = + print_newlines_disj := true; + Common.format_to_string (function _ -> rule_elem "" x) + +let ident_to_string x = + print_newlines_disj := true; + Common.format_to_string (function _ -> ident x) + +let unparse_to_string x = + print_newlines_disj := true; + Common.format_to_string (function _ -> unparse x) + +let print_rule_elem re = + let nl = !print_newlines_disj in + print_newlines_disj := false; + rule_elem "" re; + print_newlines_disj := nl + diff --git a/parsing_cocci/.#pretty_print_cocci.ml.1.128 b/parsing_cocci/.#pretty_print_cocci.ml.1.128 new file mode 100644 index 0000000..5ca7b08 --- /dev/null +++ b/parsing_cocci/.#pretty_print_cocci.ml.1.128 @@ -0,0 +1,859 @@ +(* +* 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 Ast = Ast_cocci + +let print_plus_flag = ref true +let print_minus_flag = ref true +let print_newlines_disj = ref true + +let start_block str = + force_newline(); print_string " "; open_box 0 + +let end_block str = + close_box(); force_newline () + +let print_string_box s = print_string s; open_box 0 + + +let print_option = Common.do_option +let print_between = Common.print_between + +(* --------------------------------------------------------------------- *) +(* Modified code *) + +(* avoid polyvariance problems *) +let anything : (Ast.anything -> unit) ref = ref (function _ -> ()) + +let rec print_anything str = function + [] -> () + | stream -> + start_block(); + print_between force_newline + (function x -> + print_string str; open_box 0; print_anything_list x; close_box()) + stream; + end_block() + +and print_anything_list = function + [] -> () + | [x] -> !anything x + | bef::((aft::_) as rest) -> + !anything bef; + let space = + (match bef with + Ast.Rule_elemTag(_) | Ast.AssignOpTag(_) | Ast.BinaryOpTag(_) + | Ast.ArithOpTag(_) | Ast.LogicalOpTag(_) + | Ast.Token("if",_) | Ast.Token("while",_) -> true | _ -> false) or + (match aft with + Ast.Rule_elemTag(_) | Ast.AssignOpTag(_) | Ast.BinaryOpTag(_) + | Ast.ArithOpTag(_) | Ast.LogicalOpTag(_) | Ast.Token("{",_) -> true + | _ -> false) in + if space then print_string " "; + print_anything_list rest + +let print_around printer term = function + Ast.NOTHING -> printer term + | Ast.BEFORE(bef) -> print_anything "<<< " bef; printer term + | Ast.AFTER(aft) -> printer term; print_anything ">>> " aft + | Ast.BEFOREAFTER(bef,aft) -> + print_anything "<<< " bef; printer term; print_anything ">>> " aft + +let print_string_befaft fn x info = + List.iter (function s -> print_string s; force_newline()) + info.Ast.strbef; + fn x; + List.iter (function s -> force_newline(); print_string s) + info.Ast.straft + +let print_meta (r,x) = print_string r; print_string ":"; print_string x + +let print_pos = function + Ast.MetaPos(name,_,_,_,_) -> + let name = Ast.unwrap_mcode name in + print_string "@"; print_meta name + | _ -> () + +let mcode fn = function + (x, _, Ast.MINUS(_,plus_stream), pos) -> + if !print_minus_flag + then print_string (if !Flag.sgrep_mode2 then "*" else "-"); + fn x; print_pos pos; + if !print_plus_flag + then print_anything ">>> " plus_stream + | (x, _, Ast.CONTEXT(_,plus_streams), pos) -> + if !print_plus_flag + then + let fn x = fn x; print_pos pos in + print_around fn x plus_streams + else (fn x; print_pos pos) + | (x, info, Ast.PLUS, pos) -> + let fn x = fn x; print_pos pos in + print_string_befaft fn x info + +let print_mcodekind = function + Ast.MINUS(_,plus_stream) -> + print_string "MINUS"; + print_anything ">>> " plus_stream + | Ast.CONTEXT(_,plus_streams) -> + print_around (function _ -> print_string "CONTEXT") () plus_streams + | Ast.PLUS -> print_string "PLUS" + +(* --------------------------------------------------------------------- *) +(* --------------------------------------------------------------------- *) +(* Dots *) + +let dots between fn d = + match Ast.unwrap d with + Ast.DOTS(l) -> print_between between fn l + | Ast.CIRCLES(l) -> print_between between fn l + | Ast.STARS(l) -> print_between between fn l + +let nest_dots multi fn f d = + let mo s = if multi then "<+"^s else "<"^s in + let mc s = if multi then s^"+>" else s^">" in + match Ast.unwrap d with + Ast.DOTS(l) -> + print_string (mo "..."); f(); start_block(); + print_between force_newline fn l; + end_block(); print_string (mc "...") + | Ast.CIRCLES(l) -> + print_string (mo "ooo"); f(); start_block(); + print_between force_newline fn l; + end_block(); print_string (mc "ooo") + | Ast.STARS(l) -> + print_string (mo "***"); f(); start_block(); + print_between force_newline fn l; + end_block(); print_string (mc "***") + +(* --------------------------------------------------------------------- *) + +let print_type keep info = function + None -> () + (* print_string "/* "; + print_string "keep:"; print_unitary keep; + print_string " inherited:"; print_bool inherited; + print_string " */"*) + | Some ty -> () + (*; + print_string "/* "; + print_between (function _ -> print_string ", ") Type_cocci.typeC ty;(* + print_string "keep:"; print_unitary keep; + print_string " inherited:"; print_bool inherited;*) + print_string " */"*) + +(* --------------------------------------------------------------------- *) +(* Identifier *) + +let rec ident i = + match Ast.unwrap i with + Ast.Id(name) -> mcode print_string name + | Ast.MetaId(name,_,keep,inherited) -> mcode print_meta name + | Ast.MetaFunc(name,_,_,_) -> mcode print_meta name + | Ast.MetaLocalFunc(name,_,_,_) -> mcode print_meta name + | Ast.OptIdent(id) -> print_string "?"; ident id + | Ast.UniqueIdent(id) -> print_string "!"; ident id + +and print_unitary = function + Type_cocci.Unitary -> print_string "unitary" + | Type_cocci.Nonunitary -> print_string "nonunitary" + | Type_cocci.Saved -> print_string "saved" + +(* --------------------------------------------------------------------- *) +(* Expression *) + +let print_disj_list fn l = + if !print_newlines_disj + then (force_newline(); print_string "("; force_newline()) + else print_string "("; + print_between + (function _ -> + if !print_newlines_disj + then (force_newline(); print_string "|"; force_newline()) + else print_string " | ") + fn l; + if !print_newlines_disj + then (force_newline(); print_string ")"; force_newline()) + else print_string ")" + +let rec expression e = + match Ast.unwrap e with + Ast.Ident(id) -> ident id + | Ast.Constant(const) -> mcode constant const + | Ast.FunCall(fn,lp,args,rp) -> + expression fn; mcode print_string_box lp; + dots (function _ -> ()) expression args; + close_box(); mcode print_string rp + | Ast.Assignment(left,op,right,simple) -> + expression left; print_string " "; mcode assignOp op; + print_string " "; expression right + | Ast.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 + | Ast.Postfix(exp,op) -> expression exp; mcode fixOp op + | Ast.Infix(exp,op) -> mcode fixOp op; expression exp + | Ast.Unary(exp,op) -> mcode unaryOp op; expression exp + | Ast.Binary(left,op,right) -> + expression left; print_string " "; mcode binaryOp op; print_string " "; + expression right + | Ast.Nested(left,op,right) -> + expression left; print_string " "; mcode binaryOp op; print_string " "; + expression right + | Ast.Paren(lp,exp,rp) -> + mcode print_string_box lp; expression exp; close_box(); + mcode print_string rp + | Ast.ArrayAccess(exp1,lb,exp2,rb) -> + expression exp1; mcode print_string_box lb; expression exp2; close_box(); + mcode print_string rb + | Ast.RecordAccess(exp,pt,field) -> + expression exp; mcode print_string pt; ident field + | Ast.RecordPtAccess(exp,ar,field) -> + expression exp; mcode print_string ar; ident field + | Ast.Cast(lp,ty,rp,exp) -> + mcode print_string_box lp; fullType ty; close_box(); + mcode print_string rp; expression exp + | Ast.SizeOfExpr(sizeof,exp) -> + mcode print_string sizeof; expression exp + | Ast.SizeOfType(sizeof,lp,ty,rp) -> + mcode print_string sizeof; + mcode print_string_box lp; fullType ty; close_box(); + mcode print_string rp + | Ast.TypeExp(ty) -> fullType ty + + | Ast.MetaErr(name,_,_,_) -> mcode print_meta name + | Ast.MetaExpr(name,_,keep,ty,form,inherited) -> + mcode print_meta name; print_type keep inherited ty + | Ast.MetaExprList(name,_,_,_) -> mcode print_meta name + | Ast.EComma(cm) -> mcode print_string cm; print_space() + | Ast.DisjExpr(exp_list) -> print_disj_list expression exp_list + | Ast.NestExpr(expr_dots,Some whencode,multi) -> + nest_dots multi expression + (function _ -> print_string " when != "; expression whencode) + expr_dots + | Ast.NestExpr(expr_dots,None,multi) -> + nest_dots multi expression (function _ -> ()) expr_dots + | Ast.Edots(dots,Some whencode) + | Ast.Ecircles(dots,Some whencode) + | Ast.Estars(dots,Some whencode) -> + mcode print_string dots; print_string " when != "; expression whencode + | Ast.Edots(dots,None) + | Ast.Ecircles(dots,None) + | Ast.Estars(dots,None) -> mcode print_string dots + | Ast.OptExp(exp) -> print_string "?"; expression exp + | Ast.UniqueExp(exp) -> print_string "!"; expression exp + +and unaryOp = function + Ast.GetRef -> print_string "&" + | Ast.DeRef -> print_string "*" + | Ast.UnPlus -> print_string "+" + | Ast.UnMinus -> print_string "-" + | Ast.Tilde -> print_string "~" + | Ast.Not -> print_string "!" + +and assignOp = function + Ast.SimpleAssign -> print_string "=" + | Ast.OpAssign(aop) -> arithOp aop; print_string "=" + +and fixOp = function + Ast.Dec -> print_string "--" + | Ast.Inc -> print_string "++" + +and binaryOp = function + Ast.Arith(aop) -> arithOp aop + | Ast.Logical(lop) -> logicalOp lop + +and arithOp = function + Ast.Plus -> print_string "+" + | Ast.Minus -> print_string "-" + | Ast.Mul -> print_string "*" + | Ast.Div -> print_string "/" + | Ast.Mod -> print_string "%" + | Ast.DecLeft -> print_string "<<" + | Ast.DecRight -> print_string ">>" + | Ast.And -> print_string "&" + | Ast.Or -> print_string "|" + | Ast.Xor -> print_string "^" + +and logicalOp = function + Ast.Inf -> print_string "<" + | Ast.Sup -> print_string ">" + | Ast.InfEq -> print_string "<=" + | Ast.SupEq -> print_string ">=" + | Ast.Eq -> print_string "==" + | Ast.NotEq -> print_string "!=" + | Ast.AndLog -> print_string "&&" + | Ast.OrLog -> print_string "||" + +and constant = function + Ast.String(s) -> print_string "\""; print_string s; print_string "\"" + | Ast.Char(s) -> print_string "'"; print_string s; print_string "'" + | Ast.Int(s) -> print_string s + | Ast.Float(s) -> print_string s + +(* --------------------------------------------------------------------- *) +(* Declarations *) + +and storage = function + Ast.Static -> print_string "static " + | Ast.Auto -> print_string "auto " + | Ast.Register -> print_string "register " + | Ast.Extern -> print_string "extern " + +(* --------------------------------------------------------------------- *) +(* Types *) + +and fullType ft = + match Ast.unwrap ft with + Ast.Type(cv,ty) -> + print_option (function x -> mcode const_vol x; print_string " ") cv; + typeC ty + | Ast.DisjType(decls) -> print_disj_list fullType decls + | Ast.OptType(ty) -> print_string "?"; fullType ty + | Ast.UniqueType(ty) -> print_string "!"; fullType ty + +and print_function_pointer (ty,lp1,star,rp1,lp2,params,rp2) fn = + fullType ty; mcode print_string lp1; mcode print_string star; fn(); + mcode print_string rp1; mcode print_string lp1; + parameter_list params; mcode print_string rp2 + +and print_function_type (ty,lp1,params,rp1) fn = + print_option fullType ty; fn(); mcode print_string lp1; + parameter_list params; mcode print_string rp1 + +and print_fninfo = function + Ast.FStorage(stg) -> mcode storage stg + | Ast.FType(ty) -> fullType ty + | Ast.FInline(inline) -> mcode print_string inline; print_string " " + | Ast.FAttr(attr) -> mcode print_string attr; print_string " " + +and typeC ty = + match Ast.unwrap ty with + Ast.BaseType(ty,sgn) -> print_option (mcode sign) sgn; mcode baseType ty + | Ast.ImplicitInt(sgn) -> mcode sign sgn + | Ast.Pointer(ty,star) -> fullType ty; mcode print_string star + | Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> + print_function_pointer (ty,lp1,star,rp1,lp2,params,rp2) + (function _ -> ()) + | Ast.FunctionType (_,ty,lp1,params,rp1) -> + print_function_type (ty,lp1,params,rp1) (function _ -> ()) + | Ast.Array(ty,lb,size,rb) -> + fullType ty; mcode print_string lb; print_option expression size; + mcode print_string rb + | Ast.StructUnionName(kind,name) -> + mcode structUnion kind; + print_option (function x -> ident x; print_string " ") name + | Ast.StructUnionDef(ty,lb,decls,rb) -> + fullType ty; mcode print_string lb; + dots force_newline declaration decls; + mcode print_string rb + | Ast.TypeName(name) -> mcode print_string name; print_string " " + | Ast.MetaType(name,_,_) -> + mcode print_meta name; print_string " " + +and baseType = function + Ast.VoidType -> print_string "void " + | Ast.CharType -> print_string "char " + | Ast.ShortType -> print_string "short " + | Ast.IntType -> print_string "int " + | Ast.DoubleType -> print_string "double " + | Ast.FloatType -> print_string "float " + | Ast.LongType -> print_string "long " + +and structUnion = function + Ast.Struct -> print_string "struct " + | Ast.Union -> print_string "union " + +and sign = function + Ast.Signed -> print_string "signed " + | Ast.Unsigned -> print_string "unsigned " + +and const_vol = function + Ast.Const -> print_string "const" + | Ast.Volatile -> print_string "volatile" + +(* --------------------------------------------------------------------- *) +(* 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 Ast.unwrap ty with + Ast.Type(None,ty1) -> + (match Ast.unwrap ty1 with + Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> + print_function_pointer (ty,lp1,star,rp1,lp2,params,rp2) + (function _ -> print_string " "; ident id) + | Ast.FunctionType(_,ty,lp1,params,rp1) -> + print_function_type (ty,lp1,params,rp1) + (function _ -> print_string " "; ident id) + | Ast.Array(ty,lb,size,rb) -> + let rec loop ty k = + match Ast.unwrap ty with + Ast.Array(ty,lb,size,rb) -> + (match Ast.unwrap ty with + Ast.Type(None,ty) -> + loop ty + (function _ -> + k (); + mcode print_string lb; + print_option expression size; + mcode print_string rb) + | _ -> failwith "complex array types not supported") + | _ -> typeC ty; ident id; k () in + loop ty1 (function _ -> ()) + | _ -> fullType ty; ident id) + | _ -> fullType ty; ident id + +and declaration d = + match Ast.unwrap d with + Ast.Init(stg,ty,id,eq,ini,sem) -> + print_option (mcode storage) stg; print_named_type ty id; + print_string " "; mcode print_string eq; + print_string " "; initialiser ini; mcode print_string sem + | Ast.UnInit(stg,ty,id,sem) -> + print_option (mcode storage) stg; print_named_type ty id; + mcode print_string sem + | Ast.MacroDecl(name,lp,args,rp,sem) -> + ident name; mcode print_string_box lp; + dots (function _ -> ()) expression args; + close_box(); mcode print_string rp; mcode print_string sem + | Ast.TyDecl(ty,sem) -> fullType ty; mcode print_string sem + | Ast.Typedef(stg,ty,id,sem) -> + mcode print_string stg; print_string " "; fullType ty; typeC id; + mcode print_string sem + | Ast.DisjDecl(decls) -> print_disj_list declaration decls + | Ast.Ddots(dots,Some whencode) -> + mcode print_string dots; print_string " when != "; declaration whencode + | Ast.Ddots(dots,None) -> mcode print_string dots + | Ast.MetaDecl(name,_,_) -> mcode print_meta name + | Ast.OptDecl(decl) -> print_string "?"; declaration decl + | Ast.UniqueDecl(decl) -> print_string "!"; declaration decl + +(* --------------------------------------------------------------------- *) +(* Initialiser *) + +and initialiser i = + match Ast.unwrap i with + Ast.InitExpr(exp) -> expression exp + | Ast.InitList(lb,initlist,rb,whencode) -> + mcode print_string lb; open_box 0; + if not (whencode = []) + then + (print_string " WHEN != "; + print_between (function _ -> print_string " v ") + initialiser whencode; + force_newline()); + List.iter initialiser initlist; close_box(); + mcode print_string rb + | Ast.InitGccDotName(dot,name,eq,ini) -> + mcode print_string dot; ident name; print_string " "; + mcode print_string eq; print_string " "; initialiser ini + | Ast.InitGccName(name,eq,ini) -> + ident name; mcode print_string eq; initialiser ini + | Ast.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 + | Ast.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 + | Ast.IComma(comma) -> mcode print_string comma; force_newline() + | Ast.OptIni(ini) -> print_string "?"; initialiser ini + | Ast.UniqueIni(ini) -> print_string "!"; initialiser ini + +(* --------------------------------------------------------------------- *) +(* Parameter *) + +and parameterTypeDef p = + match Ast.unwrap p with + Ast.VoidParam(ty) -> fullType ty + | Ast.Param(ty,Some id) -> print_named_type ty id + | Ast.Param(ty,None) -> fullType ty + | Ast.MetaParam(name,_,_) -> mcode print_meta name + | Ast.MetaParamList(name,_,_,_) -> mcode print_meta name + | Ast.PComma(cm) -> mcode print_string cm; print_space() + | Ast.Pdots(dots) -> mcode print_string dots + | Ast.Pcircles(dots) -> mcode print_string dots + | Ast.OptParam(param) -> print_string "?"; parameterTypeDef param + | Ast.UniqueParam(param) -> print_string "!"; parameterTypeDef param + +and parameter_list l = dots (function _ -> ()) parameterTypeDef l + +(* --------------------------------------------------------------------- *) +(* Top-level code *) + +let rec rule_elem arity re = + match Ast.unwrap re with + Ast.FunHeader(bef,allminus,fninfo,name,lp,params,rp) -> + mcode (function _ -> ()) ((),Ast.no_info,bef,Ast.NoMetaPos); + 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 " " + | Ast.Decl(bef,allminus,decl) -> + mcode (function _ -> ()) ((),Ast.no_info,bef,Ast.NoMetaPos); + print_string arity; + declaration decl + | Ast.SeqStart(brace) -> + print_string arity; mcode print_string brace; + if !print_newlines_disj then start_block() + | Ast.SeqEnd(brace) -> + if !print_newlines_disj then end_block(); + print_string arity; mcode print_string brace + | Ast.ExprStatement(exp,sem) -> + print_string arity; expression exp; mcode print_string sem + | Ast.IfHeader(iff,lp,exp,rp) -> + print_string arity; + mcode print_string iff; print_string " "; mcode print_string_box lp; + expression exp; close_box(); mcode print_string rp; print_string " " + | Ast.Else(els) -> + print_string arity; mcode print_string els; print_string " " + | Ast.WhileHeader(whl,lp,exp,rp) -> + print_string arity; + mcode print_string whl; print_string " "; mcode print_string_box lp; + expression exp; close_box(); mcode print_string rp; print_string " " + | Ast.DoHeader(d) -> + print_string arity; mcode print_string d; print_string " " + | Ast.WhileTail(whl,lp,exp,rp,sem) -> + 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 + | Ast.ForHeader(fr,lp,e1,sem1,e2,sem2,e3,rp) -> + 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 " " + | Ast.IteratorHeader(nm,lp,args,rp) -> + print_string arity; + ident nm; print_string " "; mcode print_string_box lp; + dots (function _ -> ()) expression args; close_box(); + mcode print_string rp; print_string " " + | Ast.SwitchHeader(switch,lp,exp,rp) -> + print_string arity; + mcode print_string switch; print_string " "; mcode print_string_box lp; + expression exp; close_box(); mcode print_string rp; print_string " " + | Ast.Break(br,sem) -> + print_string arity; mcode print_string br; mcode print_string sem + | Ast.Continue(cont,sem) -> + print_string arity; mcode print_string cont; mcode print_string sem + | Ast.Label(l,dd) -> ident l; mcode print_string dd + | Ast.Goto(goto,l,sem) -> + mcode print_string goto; ident l; mcode print_string sem + | Ast.Return(ret,sem) -> + print_string arity; mcode print_string ret; mcode print_string sem + | Ast.ReturnExpr(ret,exp,sem) -> + print_string arity; mcode print_string ret; print_string " "; + expression exp; mcode print_string sem + | Ast.MetaRuleElem(name,_,_) -> + print_string arity; mcode print_meta name + | Ast.MetaStmt(name,_,_,_) -> + print_string arity; mcode print_meta name + | Ast.MetaStmtList(name,_,_) -> + print_string arity; mcode print_meta name + | Ast.Exp(exp) -> print_string arity; expression exp + | Ast.TopExp(exp) -> print_string arity; expression exp + | Ast.Ty(ty) -> print_string arity; fullType ty + | Ast.Include(inc,s) -> + mcode print_string inc; print_string " "; mcode inc_file s + | Ast.DefineHeader(def,id,params) -> + mcode print_string def; print_string " "; ident id; + print_define_parameters params + | Ast.Default(def,colon) -> + mcode print_string def; mcode print_string colon; print_string " " + | Ast.Case(case,exp,colon) -> + mcode print_string case; print_string " "; expression exp; + mcode print_string colon; print_string " " + | Ast.DisjRuleElem(res) -> + print_string arity; + force_newline(); print_string "("; force_newline(); + print_between + (function _ -> force_newline();print_string "|"; force_newline()) + (rule_elem arity) + res; + force_newline(); print_string ")" + + +and print_define_parameters params = + match Ast.unwrap params with + Ast.NoParams -> () + | Ast.DParams(lp,params,rp) -> + mcode print_string lp; + dots (function _ -> ()) print_define_param params; mcode print_string rp + +and print_define_param param = + match Ast.unwrap param with + Ast.DParam(id) -> ident id + | Ast.DPComma(comma) -> mcode print_string comma + | Ast.DPdots(dots) -> mcode print_string dots + | Ast.DPcircles(circles) -> mcode print_string circles + | Ast.OptDParam(dp) -> print_string "?"; print_define_param dp + | Ast.UniqueDParam(dp) -> print_string "!"; print_define_param dp + +and statement arity s = + match Ast.unwrap s with + Ast.Seq(lbrace,decls,body,rbrace) -> + rule_elem arity lbrace; + dots force_newline (statement arity) decls; + dots force_newline (statement arity) body; + rule_elem arity rbrace + | Ast.IfThen(header,branch,(_,_,_,aft)) -> + rule_elem arity header; statement arity branch; + mcode (function _ -> ()) ((),Ast.no_info,aft,Ast.NoMetaPos) + | Ast.IfThenElse(header,branch1,els,branch2,(_,_,_,aft)) -> + rule_elem arity header; statement arity branch1; print_string " "; + rule_elem arity els; statement arity branch2; + mcode (function _ -> ()) ((),Ast.no_info,aft,Ast.NoMetaPos) + | Ast.While(header,body,(_,_,_,aft)) -> + rule_elem arity header; statement arity body; + mcode (function _ -> ()) ((),Ast.no_info,aft,Ast.NoMetaPos) + | Ast.Do(header,body,tail) -> + rule_elem arity header; statement arity body; + rule_elem arity tail + | Ast.For(header,body,(_,_,_,aft)) -> + rule_elem arity header; statement arity body; + mcode (function _ -> ()) ((),Ast.no_info,aft,Ast.NoMetaPos) + | Ast.Iterator(header,body,(_,_,_,aft)) -> + rule_elem arity header; statement arity body; + mcode (function _ -> ()) ((),Ast.no_info,aft,Ast.NoMetaPos) + | Ast.Switch(header,lb,cases,rb) -> + rule_elem arity header; rule_elem arity lb; + List.iter (function x -> case_line arity x; force_newline()) cases; + rule_elem arity rb + | Ast.Atomic(re) -> rule_elem arity re + | Ast.FunDecl(header,lbrace,decls,body,rbrace) -> + rule_elem arity header; rule_elem arity lbrace; + dots force_newline (statement arity) decls; + dots force_newline (statement arity) body; + rule_elem arity rbrace + | Ast.Disj([stmt_dots]) -> + print_string arity; + dots (function _ -> if !print_newlines_disj then force_newline()) + (statement arity) stmt_dots + | Ast.Disj(stmt_dots_list) -> (* ignores newline directive for readability *) + print_string arity; + force_newline(); print_string "("; force_newline(); + print_between + (function _ -> force_newline();print_string "|"; force_newline()) + (dots force_newline (statement arity)) + stmt_dots_list; + force_newline(); print_string ")" + | Ast.Define(header,body) -> + rule_elem arity header; print_string " "; + dots force_newline (statement arity) body + | Ast.Nest(stmt_dots,whn,multi,_,_) -> + print_string arity; + nest_dots multi (statement arity) + (function _ -> + open_box 0; + print_between force_newline + (whencode (dots force_newline (statement "")) (statement "")) whn; + close_box(); force_newline()) + stmt_dots + | Ast.Dots(d,whn,_,_) | Ast.Circles(d,whn,_,_) | Ast.Stars(d,whn,_,_) -> + print_string arity; mcode print_string d; + open_box 0; + print_between force_newline + (whencode (dots force_newline (statement "")) (statement "")) whn; + close_box(); force_newline() + | Ast.OptStm(s) -> statement "?" s + | Ast.UniqueStm(s) -> statement "!" s + +and print_statement_when whencode = + print_string " WHEN != "; + open_box 0; + print_between (function _ -> print_string " &"; force_newline()) + (dots force_newline (statement "")) whencode; + close_box() + + +and whencode notfn alwaysfn = function + Ast.WhenNot a -> + print_string " WHEN != "; open_box 0; notfn a; close_box() + | Ast.WhenAlways a -> + print_string " WHEN = "; open_box 0; alwaysfn a; close_box() + | Ast.WhenModifier x -> print_string " WHEN "; print_when_modif x + | Ast.WhenNotTrue a -> + print_string " WHEN != TRUE "; open_box 0; rule_elem "" a; close_box() + | Ast.WhenNotFalse a -> + print_string " WHEN != FALSE "; open_box 0; rule_elem "" a; close_box() + +and print_when_modif = function + | Ast.WhenAny -> print_string "ANY" + | Ast.WhenStrict -> print_string "STRICT" + | Ast.WhenForall -> print_string "FORALL" + | Ast.WhenExists -> print_string "EXISTS" + +and case_line arity c = + match Ast.unwrap c with + Ast.CaseLine(header,code) -> + rule_elem arity header; print_string " "; + dots force_newline (statement arity) code + | Ast.OptCase(case) -> case_line "?" case + +(* --------------------------------------------------------------------- *) +(* CPP code *) + +and inc_file = function + Ast.Local(elems) -> + print_string "\""; + print_between (function _ -> print_string "/") inc_elem elems; + print_string "\"" + | Ast.NonLocal(elems) -> + print_string "<"; + print_between (function _ -> print_string "/") inc_elem elems; + print_string ">" + +and inc_elem = function + Ast.IncPath s -> print_string s + | Ast.IncDots -> print_string "..." + +(* for export only *) +let statement_dots l = dots force_newline (statement "") l + +let top_level t = + match Ast.unwrap t with + Ast.FILEINFO(old_file,new_file) -> + print_string "--- "; mcode print_string old_file; force_newline(); + print_string "+++ "; mcode print_string new_file + | Ast.DECL(stmt) -> statement "" stmt + | Ast.CODE(stmt_dots) -> + dots force_newline (statement "") stmt_dots + | Ast.ERRORWORDS(exps) -> + print_string "error words = ["; + print_between (function _ -> print_string ", ") expression exps; + print_string "]" + +let rule = + print_between (function _ -> force_newline(); force_newline()) top_level + +let pp_print_anything x = !anything x + +let _ = + anything := function + Ast.FullTypeTag(x) -> fullType x + | Ast.BaseTypeTag(x) -> baseType x + | Ast.StructUnionTag(x) -> structUnion x + | Ast.SignTag(x) -> sign x + | Ast.IdentTag(x) -> ident x + | Ast.ExpressionTag(x) -> expression x + | Ast.ConstantTag(x) -> constant x + | Ast.UnaryOpTag(x) -> unaryOp x + | Ast.AssignOpTag(x) -> assignOp x + | Ast.FixOpTag(x) -> fixOp x + | Ast.BinaryOpTag(x) -> binaryOp x + | Ast.ArithOpTag(x) -> arithOp x + | Ast.LogicalOpTag(x) -> logicalOp x + | Ast.InitTag(x) -> initialiser x + | Ast.DeclarationTag(x) -> declaration x + | Ast.StorageTag(x) -> storage x + | Ast.IncFileTag(x) -> inc_file x + | Ast.Rule_elemTag(x) -> rule_elem "" x + | Ast.StatementTag(x) -> statement "" x + | Ast.CaseLineTag(x) -> case_line "" x + | Ast.ConstVolTag(x) -> const_vol x + | Ast.Token(x,Some info) -> print_string_befaft print_string x info + | Ast.Token(x,None) -> print_string x + | Ast.Code(x) -> let _ = top_level x in () + | Ast.ExprDotsTag(x) -> dots (function _ -> ()) expression x + | Ast.ParamDotsTag(x) -> parameter_list x + | Ast.StmtDotsTag(x) -> dots (function _ -> ()) (statement "") x + | Ast.DeclDotsTag(x) -> dots (function _ -> ()) declaration x + | Ast.TypeCTag(x) -> typeC x + | Ast.ParamTag(x) -> parameterTypeDef x + | Ast.SgrepStartTag(x) -> print_string x + | Ast.SgrepEndTag(x) -> print_string x + +let rec dep in_and = function + Ast.Dep(s) -> print_string s + | Ast.AntiDep(s) -> print_string "!"; print_string s + | Ast.EverDep(s) -> print_string "ever "; print_string s + | Ast.NeverDep(s) -> print_string "never "; print_string s + | Ast.AndDep(s1,s2) -> + let print_and _ = dep true s1; print_string " && "; dep true s2 in + if in_and + then print_and () + else (print_string "("; print_and(); print_string ")") + | Ast.OrDep(s1,s2) -> + let print_or _ = dep false s1; print_string " || "; dep false s2 in + if not in_and + then print_or () + else (print_string "("; print_or(); print_string ")") + | Ast.NoDep -> failwith "not possible" + +let unparse z = + match z with + Ast.ScriptRule (lang,deps,bindings,code) -> + print_string "@@"; + force_newline(); + print_string ("script:" ^ lang); + (match deps with + Ast.NoDep -> () + | _ -> print_string " depends on "; dep true deps); + force_newline(); + print_string "@@"; + force_newline(); + print_string code; + force_newline() + | Ast.CocciRule (nm, (deps, drops, exists), x, _) -> + print_string "@@"; + force_newline(); + print_string nm; + (match deps with + Ast.NoDep -> () + | _ -> print_string " depends on "; dep true deps); + (* + print_string "line "; + print_int (Ast.get_line (List.hd x)); + *) + force_newline(); + print_string "@@"; + print_newlines_disj := true; + force_newline(); + force_newline(); + rule x; + force_newline() + +let rule_elem_to_string x = + print_newlines_disj := true; + Common.format_to_string (function _ -> rule_elem "" x) + +let ident_to_string x = + print_newlines_disj := true; + Common.format_to_string (function _ -> ident x) + +let unparse_to_string x = + print_newlines_disj := true; + Common.format_to_string (function _ -> unparse x) + +let print_rule_elem re = + let nl = !print_newlines_disj in + print_newlines_disj := false; + rule_elem "" re; + print_newlines_disj := nl + diff --git a/parsing_cocci/.#single_statement.ml.1.51 b/parsing_cocci/.#single_statement.ml.1.51 new file mode 100644 index 0000000..d8b86c0 --- /dev/null +++ b/parsing_cocci/.#single_statement.ml.1.51 @@ -0,0 +1,596 @@ +(* +* 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. +*) + + +(* detect statements that are between dots in the minus code, because they +may need a special treatment if they are if branches *) + +module Ast0 = Ast0_cocci +module Ast = Ast_cocci +module V0 = Visitor_ast0 + +(* --------------------------------------------------------------------- *) +(* --------------------------------------------------------------------- *) +(* Helpers *) + +let left_dots f l = + match Ast0.undots l with + [] -> false + | x::xs -> f x + +let right_dots f l = + match List.rev (Ast0.undots l) with + [] -> false + | x::xs -> f x + +let modif_before_mcode mc = + match Ast0.get_mcode_mcodekind mc with + Ast0.MINUS mc -> true (*conservative; don't want to hunt right for + code*) + | Ast0.PLUS -> failwith "not possible" + | Ast0.CONTEXT mc -> + (match !mc with + (Ast.BEFORE _,_,_) -> true + | (Ast.BEFOREAFTER _,_,_) -> true + | _ -> false) + | Ast0.MIXED mc -> true (* don't think mcode can be mixed *) + +let modif_after_mcodekind = function + Ast0.MINUS mc -> true (*conservative; don't want to hunt right for + code*) + | Ast0.PLUS -> failwith "not possible" + | Ast0.CONTEXT mc -> + (match !mc with + (Ast.AFTER _,_,_) -> true + | (Ast.BEFOREAFTER _,_,_) -> true + | _ -> false) + | Ast0.MIXED mc -> true (* don't think mcode can be mixed *) + +let modif_after_mcode mc = modif_after_mcodekind (Ast0.get_mcode_mcodekind mc) + +let any_statements = + List.exists + (List.exists + (function + Ast.StatementTag(_) | Ast.StmtDotsTag(_) + | Ast.DeclarationTag(_) | Ast.DeclDotsTag(_) -> true | _ -> false)) + +let modif_before x = + match Ast0.get_mcodekind x with + Ast0.PLUS -> failwith "not possible" + | 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(_,_,_) -> true (* potentially dangerous *) + | _ -> false) + | (_,_) -> true) + | Ast0.CONTEXT mc | Ast0.MIXED mc -> + (match !mc with + (Ast.BEFORE _,_,_) -> true + | (Ast.BEFOREAFTER _,_,_) -> true + | _ -> false) + +let modif_after x = + match Ast0.get_mcodekind x with + Ast0.PLUS -> failwith "not possible" + | 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(_,_,_) -> true (* potentially dangerous *) + | _ -> false) + | (l,_) -> any_statements l) + | Ast0.CONTEXT mc | Ast0.MIXED mc -> + (match !mc with + (Ast.AFTER _,_,_) -> true + | (Ast.BEFOREAFTER _,_,_) -> true + | _ -> false) + +(* Identifier *) +let rec left_ident i = + modif_before i or + match Ast0.unwrap i with + Ast0.Id(name) -> modif_before_mcode name + | Ast0.MetaId(name,_,_) -> modif_before_mcode name + | Ast0.MetaFunc(name,_,_) -> modif_before_mcode name + | Ast0.MetaLocalFunc(name,_,_) -> modif_before_mcode name + | Ast0.OptIdent(id) -> left_ident id + | Ast0.UniqueIdent(id) -> left_ident id + +(* --------------------------------------------------------------------- *) +(* Expression *) + +let rec left_expression e = + modif_before e or + match Ast0.unwrap e with + Ast0.Ident(id) -> left_ident id + | Ast0.Constant(const) -> modif_before_mcode const + | Ast0.FunCall(fn,lp,args,rp) -> left_expression fn + | Ast0.Assignment(left,op,right,_) -> left_expression left + | Ast0.CondExpr(exp1,why,exp2,colon,exp3) -> left_expression exp1 + | Ast0.Postfix(exp,op) -> left_expression exp + | Ast0.Infix(exp,op) -> modif_before_mcode op + | Ast0.Unary(exp,op) -> modif_before_mcode op + | Ast0.Binary(left,op,right) -> left_expression left + | Ast0.Nested(left,op,right) -> left_expression left + | Ast0.Paren(lp,exp,rp) -> modif_before_mcode lp + | Ast0.ArrayAccess(exp1,lb,exp2,rb) -> left_expression exp1 + | Ast0.RecordAccess(exp,pt,field) -> left_expression exp + | Ast0.RecordPtAccess(exp,ar,field) -> left_expression exp + | Ast0.Cast(lp,ty,rp,exp) -> modif_before_mcode lp + | Ast0.SizeOfExpr(szf,exp) -> modif_before_mcode szf + | Ast0.SizeOfType(szf,lp,ty,rp) -> modif_before_mcode szf + | Ast0.TypeExp(ty) -> left_typeC ty + | Ast0.MetaErr(name,_,_) -> modif_before_mcode name + | Ast0.MetaExpr(name,_,ty,_,_) -> modif_before_mcode name + | Ast0.MetaExprList(name,_,_) -> modif_before_mcode name + | Ast0.EComma(cm) -> modif_before_mcode cm + | Ast0.DisjExpr(_,exp_list,_,_) -> List.exists left_expression exp_list + | Ast0.NestExpr(starter,expr_dots,ender,_,multi) -> + left_dots left_expression expr_dots + | Ast0.Edots(dots,_) | Ast0.Ecircles(dots,_) | Ast0.Estars(dots,_) -> false + | Ast0.OptExp(exp) -> left_expression exp + | Ast0.UniqueExp(exp) -> left_expression exp + +(* --------------------------------------------------------------------- *) +(* Types *) + +and left_typeC t = + modif_before t or + match Ast0.unwrap t with + Ast0.ConstVol(cv,ty) -> modif_before_mcode cv + | Ast0.BaseType(ty,Some sgn) -> modif_before_mcode sgn + | Ast0.BaseType(ty,None) -> modif_before_mcode ty + | Ast0.ImplicitInt(sgn) -> modif_before_mcode sgn + | Ast0.Pointer(ty,star) -> left_typeC ty + | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> left_typeC ty + | Ast0.FunctionType(Some ty,lp1,params,rp1) -> left_typeC ty + | Ast0.FunctionType(None,lp1,params,rp1) -> modif_before_mcode lp1 + | Ast0.Array(ty,lb,size,rb) -> left_typeC ty + | Ast0.StructUnionName(kind,name) -> modif_before_mcode kind + | Ast0.StructUnionDef(ty,lb,decls,rb) -> left_typeC ty + | Ast0.TypeName(name) -> modif_before_mcode name + | Ast0.MetaType(name,_) -> modif_before_mcode name + | Ast0.DisjType(lp,types,mids,rp) -> List.exists left_typeC types + | Ast0.OptType(ty) -> left_typeC ty + | Ast0.UniqueType(ty) -> left_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 left_declaration d = + modif_before d or + match Ast0.unwrap d with + Ast0.Init(Some stg,ty,id,eq,ini,sem) -> modif_before_mcode stg + | Ast0.Init(None,ty,id,eq,ini,sem) -> left_typeC ty + | Ast0.UnInit(Some stg,ty,id,sem) -> modif_before_mcode stg + | Ast0.UnInit(None,ty,id,sem) -> left_typeC ty + | Ast0.MacroDecl(name,lp,args,rp,sem) -> left_ident name + | Ast0.TyDecl(ty,sem) -> left_typeC ty + | Ast0.Typedef(stg,ty,id,sem) -> modif_before_mcode stg + | Ast0.DisjDecl(_,decls,_,_) -> List.exists left_declaration decls + | Ast0.Ddots(dots,_) -> false + | Ast0.OptDecl(decl) -> left_declaration decl + | Ast0.UniqueDecl(decl) -> left_declaration decl + +and right_declaration d = + modif_before d or + match Ast0.unwrap d with + Ast0.Init(_,ty,id,eq,ini,sem) -> modif_after_mcode sem + | Ast0.UnInit(_,ty,id,sem) -> modif_after_mcode sem + | Ast0.MacroDecl(name,lp,args,rp,sem) -> modif_after_mcode sem + | Ast0.TyDecl(ty,sem) -> modif_after_mcode sem + | Ast0.Typedef(stg,ty,id,sem) -> modif_after_mcode sem + | Ast0.DisjDecl(_,decls,_,_) -> List.exists right_declaration decls + | Ast0.Ddots(dots,_) -> false + | Ast0.OptDecl(decl) -> right_declaration decl + | Ast0.UniqueDecl(decl) -> right_declaration decl + +(* --------------------------------------------------------------------- *) +(* Top-level code *) + +and left_statement s = + modif_before s or + match Ast0.unwrap s with + Ast0.FunDecl(_,fninfo,name,lp,params,rp,lbrace,body,rbrace) -> + (* irrelevant *) false + | Ast0.Decl(_,decl) -> left_declaration decl + | Ast0.Seq(lbrace,body,rbrace) -> modif_before_mcode lbrace + | Ast0.ExprStatement(exp,sem) -> left_expression exp + | Ast0.IfThen(iff,lp,exp,rp,branch1,(info,aft)) -> modif_before_mcode iff + | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,(info,aft)) -> + modif_before_mcode iff + | Ast0.While(whl,lp,exp,rp,body,(info,aft)) -> modif_before_mcode whl + | Ast0.Do(d,body,whl,lp,exp,rp,sem) -> modif_before_mcode d + | Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,(info,aft)) -> + modif_before_mcode fr + | Ast0.Iterator(nm,lp,args,rp,body,(info,aft)) -> left_ident nm + | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) -> modif_before_mcode switch + | Ast0.Break(br,sem) -> modif_before_mcode br + | Ast0.Continue(cont,sem) -> modif_before_mcode cont + | Ast0.Label(l,dd) -> left_ident l + | Ast0.Goto(goto,l,sem) -> modif_before_mcode goto + | Ast0.Return(ret,sem) -> modif_before_mcode ret + | Ast0.ReturnExpr(ret,exp,sem) -> modif_before_mcode ret + | Ast0.MetaStmt(name,pure) -> modif_before_mcode name + | Ast0.MetaStmtList(name,_) -> modif_before_mcode name + | Ast0.Disj(_,statement_dots_list,_,_) -> + List.exists (left_dots left_statement) statement_dots_list + | Ast0.Nest(starter,stmt_dots,ender,whencode,multi) -> + left_dots left_statement stmt_dots + | Ast0.Exp(exp) -> false (* can only be replaced by an expression *) + | Ast0.TopExp(exp) -> false (* as above *) + | Ast0.Ty(ty) -> false (* can only be replaced by a type *) + | Ast0.Dots(d,whn) | Ast0.Circles(d,whn) | Ast0.Stars(d,whn) -> false + | Ast0.Include(inc,s) -> modif_before_mcode inc + | Ast0.Define(def,id,params,body) -> modif_before_mcode def + | Ast0.OptStm(re) -> left_statement re + | Ast0.UniqueStm(re) -> left_statement re + +and right_statement s = + modif_after s or + match Ast0.unwrap s with + Ast0.FunDecl(_,fninfo,name,lp,params,rp,lbrace,body,rbrace) -> + (* irrelevant *) false + | Ast0.Decl(_,decl) -> right_declaration decl + | Ast0.Seq(lbrace,body,rbrace) -> modif_after_mcode rbrace + | Ast0.ExprStatement(exp,sem) -> modif_after_mcode sem + | Ast0.IfThen(iff,lp,exp,rp,branch1,(info,aft)) -> modif_after_mcodekind aft + | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,(info,aft)) -> + modif_after_mcodekind aft + | Ast0.While(whl,lp,exp,rp,body,(info,aft)) -> modif_after_mcodekind aft + | Ast0.Do(d,body,whl,lp,exp,rp,sem) -> modif_after_mcode sem + | Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,(info,aft)) -> + modif_after_mcodekind aft + | Ast0.Iterator(nm,lp,args,rp,body,(info,aft)) -> + modif_after_mcodekind aft + | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) -> modif_after_mcode rb + | Ast0.Break(br,sem) -> modif_after_mcode sem + | Ast0.Continue(cont,sem) -> modif_after_mcode sem + | Ast0.Label(l,dd) -> modif_after_mcode dd + | Ast0.Goto(goto,l,sem) -> modif_after_mcode sem + | Ast0.Return(ret,sem) -> modif_after_mcode sem + | Ast0.ReturnExpr(ret,exp,sem) -> modif_after_mcode sem + | Ast0.MetaStmt(name,pure) -> modif_after_mcode name + | Ast0.MetaStmtList(name,_) -> modif_after_mcode name + | Ast0.Disj(_,statement_dots_list,_,_) -> + List.exists (right_dots right_statement) statement_dots_list + | Ast0.Nest(starter,stmt_dots,ender,whencode,multi) -> + right_dots right_statement stmt_dots + | Ast0.Exp(exp) -> false (* can only be replaced by an expression *) + | Ast0.TopExp(exp) -> false (* as above *) + | Ast0.Ty(ty) -> false (* can only be replaced by a type *) + | Ast0.Dots(d,whn) | Ast0.Circles(d,whn) | Ast0.Stars(d,whn) -> false + | Ast0.Include(inc,s) -> modif_after_mcode s + | Ast0.Define(def,id,params,body) -> right_dots right_statement body + | Ast0.OptStm(re) -> right_statement re + | Ast0.UniqueStm(re) -> right_statement re + +(* --------------------------------------------------------------------- *) + + +(* A very coarse approximation. We would really only like to return true +if a new statement is added. For this it would be best to correlate with the +plus slice. Or at least be sure that the new stuff is on the far left or +far right. *) + +let rec adding_something s = + match Ast0.get_mcodekind s with + 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(_,_,_) -> true (* potentially dangerous *) + | _ -> false) + | (_,_) -> true) + | Ast0.CONTEXT(mc) -> + let (text,tinfo1,tinfo2) = !mc in + (match text with Ast.NOTHING -> false | _ -> true) + | Ast0.MIXED(_) -> + not(contains_only_minus.V0.combiner_statement s) (*&& + (left_statement s) or (right_statement s)*) + | _ -> failwith "unexpected plus code" + +(* why do we need this; MINUS should mean the same thing *) +and contains_only_minus = + let bind x y = x && y in + let option_default = true in + let mcodekind = function + Ast0.MINUS(mc) -> + (match !mc with + ([],_) -> true + | _ -> false) + | Ast0.CONTEXT(mc) -> false + | _ -> false in + let mcode (_,_,_,mc,_) = mcodekind mc in + + let donothing r k e = mcodekind (Ast0.get_mcodekind e) && k e in + + let dots r k e = + match Ast0.unwrap e with + Ast0.DOTS([]) | Ast0.CIRCLES([]) | Ast0.STARS([]) -> true + | _ -> k e in + + let expression r k e = + mcodekind (Ast0.get_mcodekind e) && + match Ast0.unwrap e with + Ast0.DisjExpr(starter,expr_list,mids,ender) -> + List.for_all r.V0.combiner_expression expr_list + | _ -> k e in + + let declaration r k e = + mcodekind (Ast0.get_mcodekind e) && + match Ast0.unwrap e with + Ast0.DisjDecl(starter,decls,mids,ender) -> + List.for_all r.V0.combiner_declaration decls + | _ -> k e in + + let typeC r k e = + mcodekind (Ast0.get_mcodekind e) && + match Ast0.unwrap e with + Ast0.DisjType(starter,types,mids,ender) -> + List.for_all r.V0.combiner_typeC types + | _ -> k e in + + let statement r k e = + mcodekind (Ast0.get_mcodekind e) && + match Ast0.unwrap e with + Ast0.Disj(starter,statement_dots_list,mids,ender) -> + List.for_all r.V0.combiner_statement_dots statement_dots_list + | _ -> k e in + + V0.combiner bind option_default + mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode + mcode + dots dots dots dots dots dots + donothing expression typeC donothing donothing declaration + statement donothing donothing + + +(* needs a special case when there is a Disj or an empty DOTS *) +(* ---------------------------------------------------------------------- *) + +(* +Doesn't really work: + + if (acpi_device_dir(device)) ++ { + remove_proc_entry(acpi_device_bid(device), acpi_ac_dir); ++ acpi_device_dir(device) = NULL; ++ } + +The last two + lines get associated with the end of the if, not with the +branch, so the braces get added in oddly. +*) + +let add_braces orig_s = + let s = (Iso_pattern.rebuild_mcode None).V0.rebuilder_statement orig_s in + let new_mcodekind = + match Ast0.get_mcodekind s with + Ast0.MINUS(mc) -> + let (text,tinfo) = !mc in + Ast0.MINUS(ref([Ast.mkToken "{"]::text@[[Ast.mkToken "}"]],tinfo)) + | Ast0.CONTEXT(mc) -> + let (text,tinfo1,tinfo2) = !mc in + let new_text = + match text with + Ast.BEFORE(bef) -> + Ast.BEFOREAFTER([Ast.mkToken "{"]::bef,[[Ast.mkToken "}"]]) + | Ast.AFTER(aft) -> + Ast.BEFOREAFTER([[Ast.mkToken "{"]],aft@[[Ast.mkToken "}"]]) + | Ast.BEFOREAFTER(bef,aft) -> + Ast.BEFOREAFTER([Ast.mkToken "{"]::bef,aft@[[Ast.mkToken "}"]]) + | Ast.NOTHING -> + Ast.BEFOREAFTER([[Ast.mkToken "{"]],[[Ast.mkToken "}"]]) in + Ast0.CONTEXT(ref(new_text,tinfo1,tinfo2)) + | Ast0.MIXED(mc) -> + let (text,tinfo1,tinfo2) = !mc in + let new_text = + match text with + Ast.BEFORE(bef) -> + Ast.BEFOREAFTER([Ast.mkToken "{"]::bef,[[Ast.mkToken "}"]]) + | Ast.AFTER(aft) -> + Ast.BEFOREAFTER([[Ast.mkToken "{"]],aft@[[Ast.mkToken "}"]]) + | Ast.BEFOREAFTER(bef,aft) -> + Ast.BEFOREAFTER([Ast.mkToken "{"]::bef,aft@[[Ast.mkToken "}"]]) + | Ast.NOTHING -> + Ast.BEFOREAFTER([[Ast.mkToken "{"]],[[Ast.mkToken "}"]]) in + Ast0.MIXED(ref(new_text,tinfo1,tinfo2)) + | _ -> failwith "unexpected plus code" in + Ast0.set_mcodekind s new_mcodekind; + Compute_lines.statement s + +(* ---------------------------------------------------------------------- *) + +let is_dots x = + match Ast0.unwrap x with + Ast0.Dots(_,_) | Ast0.Circles(_,_) | Ast0.Stars(_,_) + | Ast0.Nest(_,_,_,_,_) -> true + | _ -> false + +let all_minus s = + match Ast0.get_mcodekind s with + Ast0.MINUS(_) -> true + | _ -> false + +let rec unchanged_minus s = + match Ast0.get_mcodekind s with + Ast0.MINUS(mc) -> (match !mc with ([],_) -> true | _ -> false) + | _ -> false + +let rec do_branch s = + if unchanged_minus s + then + Ast0.set_dots_bef_aft s (Ast0.DroppingBetweenDots(add_braces s)) + else + match Ast0.unwrap s with + Ast0.Disj(starter,statement_dots_list,mids,ender) -> + let stmts = + List.map + (function s -> + match Ast0.unwrap s with + Ast0.DOTS([s]) -> + Ast0.rewrap s (Ast0.DOTS([do_branch s])) + | Ast0.DOTS(_) -> s + | _ -> failwith "not supported") + statement_dots_list in + Ast0.rewrap s (Ast0.Disj(starter,stmts,mids,ender)) + | _ -> s + +let rec statement dots_before dots_after s = + let do_one s = + if dots_before && dots_after + then + if unchanged_minus s + then + (let with_braces = add_braces s in + Ast0.set_dots_bef_aft s (Ast0.DroppingBetweenDots(with_braces))) + else if adding_something s + then + (let with_braces = add_braces s in + Ast0.set_dots_bef_aft s (Ast0.AddingBetweenDots(with_braces))) + else s + else s in + + match Ast0.unwrap s with + Ast0.FunDecl(x,fninfo,name,lp,params,rp,lbrace,body,rbrace) -> + (* true for close brace, because that represents any way we can + exit the function, which is not necessarily followed by an explicit + close brace. *) + Ast0.rewrap s + (Ast0.FunDecl(x,fninfo,name,lp,params,rp,lbrace, + statement_dots false true body, + rbrace)) + | Ast0.Decl(_,_) -> s + | Ast0.Seq(lbrace,body,rbrace) -> + Ast0.rewrap s + (Ast0.Seq(lbrace,statement_dots false false body,rbrace)) + | Ast0.ExprStatement(exp,sem) -> do_one s + | Ast0.IfThen(iff,lp,exp,rp,branch1,x) -> + do_one + (Ast0.rewrap s + (Ast0.IfThen(iff,lp,exp,rp,statement false false branch1,x))) + | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,x) -> + do_one + (Ast0.rewrap s + (Ast0.IfThenElse + (iff,lp,exp,rp, + statement false false branch1,els, + statement false false branch2,x))) + | Ast0.While(whl,lp,exp,rp,body,x) -> + do_one + (Ast0.rewrap s + (Ast0.While(whl,lp,exp,rp,statement false false body,x))) + | Ast0.Do(d,body,whl,lp,exp,rp,sem) -> + do_one + (Ast0.rewrap s + (Ast0.Do(d,statement false false body,whl,lp,exp,rp,sem))) + | Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,x) -> + do_one + (Ast0.rewrap s + (Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp, + statement false false body,x))) + | Ast0.Iterator(nm,lp,args,rp,body,x) -> + do_one + (Ast0.rewrap s + (Ast0.Iterator(nm,lp,args,rp,statement false false body,x))) + | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) -> + do_one + (Ast0.rewrap s + (Ast0.Switch(switch,lp,exp,rp,lb, + Ast0.rewrap cases + (Ast0.DOTS(List.map case_line (Ast0.undots cases))), + rb))) + | Ast0.Break(br,sem) -> do_one s + | Ast0.Continue(cont,sem) -> do_one s + | Ast0.Label(l,dd) -> do_one s + | Ast0.Goto(goto,l,sem) -> do_one s + | Ast0.Return(ret,sem) -> do_one s + | Ast0.ReturnExpr(ret,exp,sem) -> do_one s + | Ast0.MetaStmt(name,_) -> do_one s + | Ast0.MetaStmtList(name,_) -> do_one s + | Ast0.Disj(starter,statement_dots_list,mids,ender) -> + Ast0.rewrap s + (Ast0.Disj(starter, + List.map (statement_dots dots_before dots_after) + statement_dots_list, + mids,ender)) + | Ast0.Nest(starter,stmt_dots,ender,whencode,multi) -> + Ast0.rewrap s + (Ast0.Nest + (starter,statement_dots true true stmt_dots,ender,whencode,multi)) + | Ast0.Exp(exp) -> s + | Ast0.TopExp(exp) -> s + | Ast0.Ty(ty) -> s + | Ast0.Dots(d,whn) | Ast0.Circles(d,whn) | Ast0.Stars(d,whn) -> s + | Ast0.Include(inc,string) -> s (* doesn't affect the need for braces *) + | Ast0.Define(def,id,params,body) -> s (* same as include *) + | Ast0.OptStm(re) -> + Ast0.rewrap s + (Ast0.OptStm(statement dots_before dots_after re)) + | Ast0.UniqueStm(re) -> + Ast0.rewrap s + (Ast0.UniqueStm(statement dots_before dots_after re)) + +and case_line c = + Ast0.rewrap c + (match Ast0.unwrap c with + Ast0.Default(def,colon,code) -> + Ast0.Default(def,colon,statement_dots false false code) + | Ast0.Case(case,exp,colon,code) -> + Ast0.Case(case,exp,colon,statement_dots false false code) + | Ast0.OptCase(case) -> Ast0.OptCase(case_line c)) + +and do_statement_dots dots_before dots_after = function + [] -> [] + | [x] -> [statement dots_before dots_after x] + | dots::rest when is_dots dots -> + dots::(do_statement_dots true dots_after rest) + | x::(dots::_ as rest) when is_dots dots -> + (statement dots_before true x):: + do_statement_dots false dots_after rest + | x::rest -> + (statement dots_before false x):: + do_statement_dots false dots_after rest + +and statement_dots dots_before dots_after d = + Ast0.rewrap d + (match Ast0.unwrap d with + Ast0.DOTS(l) -> + Ast0.DOTS(do_statement_dots dots_before dots_after l) + | Ast0.CIRCLES(l) -> + Ast0.CIRCLES(do_statement_dots dots_before dots_after l) + | Ast0.STARS(l) -> + Ast0.STARS(do_statement_dots dots_before dots_after l)) + +let top_level t = + Ast0.rewrap t + (match Ast0.unwrap t with + Ast0.DECL(stmt_dots) -> Ast0.DECL(statement true true stmt_dots) + | Ast0.CODE(stmt_dots) -> Ast0.CODE(statement_dots true true stmt_dots) + | t -> t) + +let single_statement l = + if !Flag_parsing_cocci.sgrep_mode then l else List.map top_level l diff --git a/parsing_cocci/.#test_exps.ml.1.3 b/parsing_cocci/.#test_exps.ml.1.3 new file mode 100644 index 0000000..528d7e2 --- /dev/null +++ b/parsing_cocci/.#test_exps.ml.1.3 @@ -0,0 +1,89 @@ +(* +* 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 +module V0 = Visitor_ast0 + +(* call set_test_pos on test expressions *) + +(* The goal of this is to identify test expressions in the SmPL file, so that +isomorphisms like X != NULL => X are only applied in a test expression context. + +There is a related check in cocci_vs_c3.ml that in x || ..., a match +without the || is only accepted in a test expression context. This uses +the annotations in the C file. *) + +let rec process_exp e = + let e = Ast0.set_test_pos e in + match Ast0.unwrap e with + Ast0.Paren(lp,e,rp) -> + Ast0.rewrap e (Ast0.Paren(lp,process_exp e,rp)) + | _ -> e + +let set_test_poss = + let donothing r k e = k e in + let mcode x = x in + + let expression r k e = + let e = k e in + match Ast0.unwrap e with + Ast0.CondExpr(e1,q,e2,c,e3) -> + Ast0.rewrap e (Ast0.CondExpr(process_exp e1,q,e2,c,e3)) + | Ast0.Binary(e1,op,e2) -> + (match Ast0.unwrap_mcode op with + Ast.Logical(Ast.AndLog) | Ast.Logical(Ast.OrLog) -> + Ast0.rewrap e (Ast0.Binary(process_exp e1,op,process_exp e2)) + | _ -> e) + | Ast0.Unary(e1,op) -> + (match Ast0.unwrap_mcode op with + Ast.Not -> Ast0.rewrap e (Ast0.Unary(process_exp e1,op)) + | _ -> e) + | _ -> e in + + let statement r k s = + let s = k s in + match Ast0.unwrap s with + Ast0.IfThen(i,lp,e,rp,s1,aft) -> + Ast0.rewrap s (Ast0.IfThen(i,lp,process_exp e,rp,s1,aft)) + | Ast0.IfThenElse(i,lp,e,rp,s1,e1,s2,aft) -> + Ast0.rewrap s (Ast0.IfThenElse(i,lp,process_exp e,rp,s1,e1,s2,aft)) + | Ast0.While(i,lp,e,rp,s1,aft) -> + Ast0.rewrap s (Ast0.While(i,lp,process_exp e,rp,s1,aft)) + | Ast0.Do(d,s1,w,lp,e,rp,sc) -> + Ast0.rewrap s (Ast0.Do(d,s1,w,lp,process_exp e,rp,sc)) + | Ast0.For(f,lp,e1,sc1,Some e2,sc2,e3,rp,s1,aft) -> + Ast0.rewrap s + (Ast0.For(f,lp,e1,sc1,Some (process_exp e2),sc2,e3,rp,s1,aft)) + | _ -> s in + + V0.rebuilder + mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode + mcode + donothing donothing donothing donothing donothing donothing + donothing expression donothing donothing donothing donothing statement + donothing donothing + +let process = List.map set_test_poss.V0.rebuilder_top_level + +let process_anything = set_test_poss.V0.rebuilder_anything + diff --git a/parsing_cocci/.#type_infer.ml.1.54 b/parsing_cocci/.#type_infer.ml.1.54 new file mode 100644 index 0000000..7ae9f85 --- /dev/null +++ b/parsing_cocci/.#type_infer.ml.1.54 @@ -0,0 +1,356 @@ +(* +* 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 T = Type_cocci +module Ast = Ast_cocci +module Ast0 = Ast0_cocci +module V0 = Visitor_ast0 + +(* Type inference: +Just propagates information based on declarations. Could try to infer +more precise information about expression metavariables, but not sure it is +worth it. The most obvious goal is to distinguish between test expressions +that have pointer, integer, and boolean type when matching isomorphisms, +but perhaps other needs will become apparent. *) + +(* "functions" that return a boolean value *) +let bool_functions = ["likely";"unlikely"] + +let err wrapped ty s = + T.typeC ty; Format.print_newline(); + failwith (Printf.sprintf "line %d: %s" (Ast0.get_line wrapped) s) + +type id = Id of string | Meta of (string * string) + +let rec lub_type t1 t2 = + match (t1,t2) with + (None,None) -> None + | (None,Some t) -> t2 + | (Some t,None) -> t1 + | (Some t1,Some t2) -> + let rec loop = function + (T.Unknown,t2) -> t2 + | (t1,T.Unknown) -> t1 + | (T.ConstVol(cv1,ty1),T.ConstVol(cv2,ty2)) when cv1 = cv2 -> + T.ConstVol(cv1,loop(ty1,ty2)) + | (T.Pointer(ty1),T.Pointer(ty2)) -> + T.Pointer(loop(ty1,ty2)) + | (ty1,T.Pointer(ty2)) -> T.Pointer(ty2) + | (T.Pointer(ty1),ty2) -> T.Pointer(ty1) + | (T.Array(ty1),T.Array(ty2)) -> T.Array(loop(ty1,ty2)) + | (T.TypeName(s1),t2) -> t2 + | (t1,T.TypeName(s1)) -> t1 + | (t1,_) -> t1 in (* arbitrarily pick the first, assume type correct *) + Some (loop (t1,t2)) + +let lub_envs envs = + List.fold_left + (function acc -> + function env -> + List.fold_left + (function acc -> + function (var,ty) -> + let (relevant,irrelevant) = + List.partition (function (x,_) -> x = var) acc in + match relevant with + [] -> (var,ty)::acc + | [(x,ty1)] -> + (match lub_type (Some ty) (Some ty1) with + Some new_ty -> (var,new_ty)::irrelevant + | None -> irrelevant) + | _ -> failwith "bad type environment") + acc env) + [] envs + +let rec propagate_types env = + let option_default = None in + let bind x y = option_default in (* no generic way of combining types *) + + let mcode x = option_default in + + let ident r k i = + match Ast0.unwrap i with + Ast0.Id(id) -> + (try Some(List.assoc (Id(Ast0.unwrap_mcode id)) env) + with Not_found -> None) + | Ast0.MetaId(id,_,_) -> + (try Some(List.assoc (Meta(Ast0.unwrap_mcode id)) env) + with Not_found -> None) + | _ -> k i in + + let strip_cv = function + Some (T.ConstVol(_,t)) -> Some t + | t -> t in + + let expression r k e = + let res = k e in + let ty = + match Ast0.unwrap e with + Ast0.Ident(id) -> Ast0.set_type e res; res + | Ast0.Constant(const) -> + (match Ast0.unwrap_mcode const with + Ast.String(_) -> Some (T.Pointer(T.BaseType(T.CharType,None))) + | Ast.Char(_) -> Some (T.BaseType(T.CharType,None)) + | Ast.Int(_) -> Some (T.BaseType(T.IntType,None)) + | Ast.Float(_) -> Some (T.BaseType(T.FloatType,None))) + | Ast0.FunCall(fn,lp,args,rp) -> + (match Ast0.get_type fn with + Some (T.FunctionPointer(ty)) -> Some ty + | _ -> + (match Ast0.unwrap fn with + Ast0.Ident(id) -> + (match Ast0.unwrap id with + Ast0.Id(id) -> + if List.mem (Ast0.unwrap_mcode id) bool_functions + then Some(T.BaseType(T.BoolType,None)) + else None + | _ -> None) + | _ -> None)) + | Ast0.Assignment(exp1,op,exp2,_) -> + let ty = lub_type (Ast0.get_type exp1) (Ast0.get_type exp2) in + Ast0.set_type exp1 ty; Ast0.set_type exp2 ty; ty + | Ast0.CondExpr(exp1,why,Some exp2,colon,exp3) -> + let ty = lub_type (Ast0.get_type exp2) (Ast0.get_type exp3) in + Ast0.set_type exp2 ty; Ast0.set_type exp3 ty; ty + | Ast0.CondExpr(exp1,why,None,colon,exp3) -> Ast0.get_type exp3 + | Ast0.Postfix(exp,op) | Ast0.Infix(exp,op) -> (* op is dec or inc *) + Ast0.get_type exp + | Ast0.Unary(exp,op) -> + (match Ast0.unwrap_mcode op with + Ast.GetRef -> + (match Ast0.get_type exp with + None -> Some (T.Pointer(T.Unknown)) + | Some t -> Some (T.Pointer(t))) + | Ast.DeRef -> + (match Ast0.get_type exp with + Some (T.Pointer(t)) -> Some t + | _ -> None) + | Ast.UnPlus -> Ast0.get_type exp + | Ast.UnMinus -> Ast0.get_type exp + | Ast.Tilde -> Ast0.get_type exp + | Ast.Not -> Some(T.BaseType(T.BoolType,None))) + | Ast0.Nested(exp1,op,exp2) -> failwith "nested in type inf not possible" + | Ast0.Binary(exp1,op,exp2) -> + let ty1 = Ast0.get_type exp1 in + let ty2 = Ast0.get_type exp2 in + let same_type = function + (None,None) -> Some (T.BaseType(T.IntType,None)) + | (Some (T.Pointer ty1),Some ty2) -> + Some (T.Pointer ty1) + | (Some ty1,Some (T.Pointer ty2)) -> + Some (T.Pointer ty2) + | (t1,t2) -> + let ty = lub_type t1 t2 in + Ast0.set_type exp1 ty; Ast0.set_type exp2 ty; ty in + (match Ast0.unwrap_mcode op with + Ast.Arith(op) -> same_type (ty1, ty2) + | Ast.Logical(op) -> + let ty = lub_type ty1 ty2 in + Ast0.set_type exp1 ty; Ast0.set_type exp2 ty; + Some(T.BaseType(T.BoolType,None))) + | Ast0.Paren(lp,exp,rp) -> Ast0.get_type exp + | Ast0.ArrayAccess(exp1,lb,exp2,rb) -> + (match strip_cv (Ast0.get_type exp2) with + None -> Ast0.set_type exp2 (Some(T.BaseType(T.IntType,None))) + | Some(T.BaseType(T.IntType,None)) -> () + | Some (T.MetaType(_,_,_)) -> () + | Some (T.TypeName _) -> () + | Some ty -> err exp2 ty "bad type for an array index"); + (match strip_cv (Ast0.get_type exp1) with + None -> None + | Some (T.Array(ty)) -> Some ty + | Some (T.Pointer(ty)) -> Some ty + | Some (T.MetaType(_,_,_)) -> None + | Some x -> err exp1 x "ill-typed array reference") + | Ast0.RecordAccess(exp,pt,field) -> + (match strip_cv (Ast0.get_type exp) with + None -> None + | Some (T.StructUnionName(_,_,_)) -> None + | Some (T.TypeName(_)) -> None + | Some (T.MetaType(_,_,_)) -> None + | Some x -> err exp x "non-structure type in field ref") + | Ast0.RecordPtAccess(exp,ar,field) -> + (match strip_cv (Ast0.get_type exp) with + None -> None + | Some (T.Pointer(t)) -> + (match strip_cv (Some t) with + | Some (T.Unknown) -> None + | Some (T.MetaType(_,_,_)) -> None + | Some (T.TypeName(_)) -> None + | Some (T.StructUnionName(_,_,_)) -> None + | Some x -> + err exp (T.Pointer(t)) + "non-structure pointer type in field ref" + | _ -> failwith "not possible") + | Some (T.MetaType(_,_,_)) -> None + | Some (T.TypeName(_)) -> None + | Some x -> err exp x "non-structure pointer type in field ref") + | Ast0.Cast(lp,ty,rp,exp) -> Some(Ast0.ast0_type_to_type ty) + | Ast0.SizeOfExpr(szf,exp) -> Some(T.BaseType(T.IntType,None)) + | Ast0.SizeOfType(szf,lp,ty,rp) -> Some(T.BaseType(T.IntType,None)) + | Ast0.TypeExp(ty) -> None + | Ast0.MetaErr(name,_,_) -> None + | Ast0.MetaExpr(name,_,Some [ty],_,_) -> Some ty + | Ast0.MetaExpr(name,_,ty,_,_) -> None + | Ast0.MetaExprList(name,_,_) -> None + | Ast0.EComma(cm) -> None + | Ast0.DisjExpr(_,exp_list,_,_) -> + let types = List.map Ast0.get_type exp_list in + let combined = List.fold_left lub_type None types in + (match combined with + None -> None + | Some t -> + List.iter (function e -> Ast0.set_type e (Some t)) exp_list; + Some t) + | Ast0.NestExpr(starter,expr_dots,ender,None,multi) -> + let _ = r.V0.combiner_expression_dots expr_dots in None + | Ast0.NestExpr(starter,expr_dots,ender,Some e,multi) -> + let _ = r.V0.combiner_expression_dots expr_dots in + let _ = r.V0.combiner_expression e in None + | Ast0.Edots(_,None) | Ast0.Ecircles(_,None) | Ast0.Estars(_,None) -> + None + | Ast0.Edots(_,Some e) | Ast0.Ecircles(_,Some e) + | Ast0.Estars(_,Some e) -> + let _ = r.V0.combiner_expression e in None + | Ast0.OptExp(exp) -> Ast0.get_type exp + | Ast0.UniqueExp(exp) -> Ast0.get_type exp in + Ast0.set_type e ty; + ty in + + let donothing r k e = k e in + + let rec strip id = + match Ast0.unwrap id with + Ast0.Id(name) -> Id(Ast0.unwrap_mcode name) + | Ast0.MetaId(name,_,_) -> Meta(Ast0.unwrap_mcode name) + | Ast0.MetaFunc(name,_,_) -> Meta(Ast0.unwrap_mcode name) + | Ast0.MetaLocalFunc(name,_,_) -> Meta(Ast0.unwrap_mcode name) + | Ast0.OptIdent(id) -> strip id + | Ast0.UniqueIdent(id) -> strip id in + + let process_whencode notfn allfn = function + Ast0.WhenNot(x) -> let _ = notfn x in () + | Ast0.WhenAlways(x) -> let _ = allfn x in () + | Ast0.WhenModifier(_) -> () in + + (* assume that all of the declarations are at the beginning of a statement + list, which is required by C, but not actually required by the cocci + parser *) + let rec process_statement_list r acc = function + [] -> acc + | (s::ss) -> + (match Ast0.unwrap s with + Ast0.Decl(_,decl) -> + let rec process_decl decl = + match Ast0.unwrap decl with + Ast0.Init(_,ty,id,_,exp,_) -> + let _ = + (propagate_types acc).V0.combiner_initialiser exp in + [(strip id,Ast0.ast0_type_to_type ty)] + | Ast0.UnInit(_,ty,id,_) -> + [(strip id,Ast0.ast0_type_to_type ty)] + | Ast0.MacroDecl(_,_,_,_,_) -> [] + | Ast0.TyDecl(ty,_) -> [] + | Ast0.Typedef(_,_,_,_) -> [] + | Ast0.DisjDecl(_,disjs,_,_) -> + List.concat(List.map process_decl disjs) + | Ast0.Ddots(_,_) -> [] (* not in a statement list anyway *) + | Ast0.OptDecl(decl) -> process_decl decl + | Ast0.UniqueDecl(decl) -> process_decl decl in + let new_acc = (process_decl decl)@acc in + process_statement_list r new_acc ss + | Ast0.Dots(_,wc) -> + List.iter + (process_whencode r.V0.combiner_statement_dots + r.V0.combiner_statement) + wc; + process_statement_list r acc ss + | Ast0.Disj(_,statement_dots_list,_,_) -> + let new_acc = + lub_envs + (List.map + (function x -> process_statement_list r acc (Ast0.undots x)) + statement_dots_list) in + process_statement_list r new_acc ss + | _ -> + let _ = (propagate_types acc).V0.combiner_statement s in + process_statement_list r acc ss) in + + let statement_dots r k d = + match Ast0.unwrap d with + Ast0.DOTS(l) | Ast0.CIRCLES(l) | Ast0.STARS(l) -> + let _ = process_statement_list r env l in option_default in + let statement r k s = + match Ast0.unwrap s with + Ast0.FunDecl(_,fninfo,name,lp,params,rp,lbrace,body,rbrace) -> + let rec get_binding p = + match Ast0.unwrap p with + Ast0.Param(ty,Some id) -> + [(strip id,Ast0.ast0_type_to_type ty)] + | Ast0.OptParam(param) -> get_binding param + | _ -> [] in + let fenv = List.concat (List.map get_binding (Ast0.undots params)) in + (propagate_types (fenv@env)).V0.combiner_statement_dots body + | Ast0.IfThen(_,_,exp,_,_,_) | Ast0.IfThenElse(_,_,exp,_,_,_,_,_) + | Ast0.While(_,_,exp,_,_,_) | Ast0.Do(_,_,_,_,exp,_,_) + | Ast0.For(_,_,_,_,Some exp,_,_,_,_,_) | Ast0.Switch(_,_,exp,_,_,_,_) -> + let _ = k s in + let rec process_test exp = + match (Ast0.unwrap exp,Ast0.get_type exp) with + (Ast0.Edots(_,_),_) -> None + | (Ast0.NestExpr(_,_,_,_,_),_) -> None + | (Ast0.MetaExpr(_,_,_,_,_),_) -> + (* if a type is known, it is specified in the decl *) + None + | (Ast0.Paren(lp,exp,rp),None) -> process_test exp + | (_,None) -> Some (T.BaseType(T.IntType,None)) + | _ -> None in + let new_expty = process_test exp in + (match new_expty with + None -> () (* leave things as they are *) + | Some ty -> Ast0.set_type exp new_expty); + None + | _ -> k s + + and case_line r k c = + match Ast0.unwrap c with + Ast0.Default(def,colon,code) -> let _ = k c in None + | Ast0.Case(case,exp,colon,code) -> + let _ = k c in + (match Ast0.get_type exp with + None -> Ast0.set_type exp (Some (T.BaseType(T.IntType,None))) + | _ -> ()); + None + | Ast0.OptCase(case) -> k c in + + V0.combiner bind option_default + mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode + mcode + donothing donothing donothing statement_dots donothing donothing + ident expression donothing donothing donothing donothing statement + case_line donothing + +let type_infer code = + let prop = propagate_types [(Id("NULL"),T.Pointer(T.Unknown))] in + let fn = prop.V0.combiner_top_level in + let _ = List.map fn code in + () diff --git a/parsing_cocci/.#unify_ast.ml.1.70 b/parsing_cocci/.#unify_ast.ml.1.70 new file mode 100644 index 0000000..a32476b --- /dev/null +++ b/parsing_cocci/.#unify_ast.ml.1.70 @@ -0,0 +1,565 @@ +(* +* 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. +*) + + +(* --------------------------------------------------------------------- *) +(* Given two patterns, A and B, determine whether B can match any matched +subterms of A. For simplicity, this doesn't maintain an environment; it +just assume metavariables match. Thus the result is either NO or MAYBE. *) + +module Ast = Ast_cocci +module V = Visitor_ast + +(* --------------------------------------------------------------------- *) + +type res = NO | MAYBE + +let return b = if b then MAYBE else NO + +let unify_mcode (x,_,_,_) (y,_,_,_) = x = y + +let unify_option f t1 t2 = + match (t1,t2) with + (Some t1, Some t2) -> f t1 t2 + | (None, None) -> return true + | _ -> return false + +let unify_true_option f t1 t2 = + match (t1,t2) with + (Some t1, Some t2) -> f t1 t2 + | (None, None) -> return true + | _ -> return true + +let bool_unify_option f t1 t2 = + match (t1,t2) with + (Some t1, Some t2) -> f t1 t2 + | (None, None) -> true + | _ -> false + +let conjunct_bindings b1 b2 = + match b1 with NO -> b1 | MAYBE -> b2 + +let disjunct_bindings b1 b2 = + match b1 with MAYBE -> b1 | NO -> b2 + +let disjunct_all_bindings = List.fold_left disjunct_bindings NO + +(* --------------------------------------------------------------------- *) + +(* compute the common prefix. if in at least one case, this ends with the +end of the pattern or a ..., then return true. *) + +let unify_lists fn dfn la lb = + let rec loop = function + ([],_) | (_,[]) -> return true + | (cura::resta,curb::restb) -> + (match fn cura curb with + MAYBE -> loop (resta,restb) + | NO -> if dfn cura or dfn curb then MAYBE else NO) in + loop (la,lb) + +let unify_dots fn dfn d1 d2 = + match (Ast.unwrap d1,Ast.unwrap d2) with + (Ast.DOTS(l1),Ast.DOTS(l2)) + | (Ast.CIRCLES(l1),Ast.CIRCLES(l2)) + | (Ast.STARS(l1),Ast.STARS(l2)) -> unify_lists fn dfn l1 l2 + | _ -> return false + +let edots e = + match Ast.unwrap e with + Ast.Edots(_,_) | Ast.Ecircles(_,_) | Ast.Estars(_,_) -> true + | _ -> false + +let ddots e = + match Ast.unwrap e with + Ast.Ddots(_,_) -> true + | _ -> false + +let pdots p = + match Ast.unwrap p with + Ast.Pdots(_) | Ast.Pcircles(_) -> true + | _ -> false + +let dpdots e = + match Ast.unwrap e with + Ast.DPdots(_) | Ast.DPcircles(_) -> true + | _ -> false + +let sdots s = + match Ast.unwrap s with + Ast.Dots(_,_,_,_) | Ast.Circles(_,_,_,_) | Ast.Stars(_,_,_,_) -> true + | _ -> false + +(* --------------------------------------------------------------------- *) +(* Identifier *) + +and unify_ident i1 i2 = + match (Ast.unwrap i1,Ast.unwrap i2) with + (Ast.Id(i1),Ast.Id(i2)) -> return (unify_mcode i1 i2) + + | (Ast.MetaId(_,_,_,_),_) + | (Ast.MetaFunc(_,_,_,_),_) + | (Ast.MetaLocalFunc(_,_,_,_),_) + | (_,Ast.MetaId(_,_,_,_)) + | (_,Ast.MetaFunc(_,_,_,_)) + | (_,Ast.MetaLocalFunc(_,_,_,_)) -> return true + + | (Ast.OptIdent(_),_) + | (Ast.UniqueIdent(_),_) + | (_,Ast.OptIdent(_)) + | (_,Ast.UniqueIdent(_)) -> failwith "unsupported ident" + +(* --------------------------------------------------------------------- *) +(* Expression *) + +let rec unify_expression e1 e2 = + match (Ast.unwrap e1,Ast.unwrap e2) with + (Ast.Ident(i1),Ast.Ident(i2)) -> unify_ident i1 i2 + | (Ast.Constant(c1),Ast.Constant(c2))-> return (unify_mcode c1 c2) + | (Ast.FunCall(f1,lp1,args1,rp1),Ast.FunCall(f2,lp2,args2,rp2)) -> + conjunct_bindings + (unify_expression f1 f2) + (unify_dots unify_expression edots args1 args2) + | (Ast.Assignment(l1,op1,r1,_),Ast.Assignment(l2,op2,r2,_)) -> + if unify_mcode op1 op2 + then conjunct_bindings (unify_expression l1 l2) (unify_expression r1 r2) + else return false + | (Ast.CondExpr(tst1,q1,thn1,c1,els1),Ast.CondExpr(tst2,q2,thn2,c2,els2)) -> + conjunct_bindings (unify_expression tst1 tst2) + (conjunct_bindings (unify_option unify_expression thn1 thn2) + (unify_expression els1 els2)) + | (Ast.Postfix(e1,op1),Ast.Postfix(e2,op2)) -> + if unify_mcode op1 op2 then unify_expression e1 e2 else return false + | (Ast.Infix(e1,op1),Ast.Infix(e2,op2)) -> + if unify_mcode op1 op2 then unify_expression e1 e2 else return false + | (Ast.Unary(e1,op1),Ast.Unary(e2,op2)) -> + if unify_mcode op1 op2 then unify_expression e1 e2 else return false + | (Ast.Binary(l1,op1,r1),Ast.Binary(l2,op2,r2)) -> + if unify_mcode op1 op2 + then conjunct_bindings (unify_expression l1 l2) (unify_expression r1 r2) + else return false + | (Ast.ArrayAccess(ar1,lb1,e1,rb1),Ast.ArrayAccess(ar2,lb2,e2,rb2)) -> + conjunct_bindings (unify_expression ar1 ar2) (unify_expression e1 e2) + | (Ast.RecordAccess(e1,d1,fld1),Ast.RecordAccess(e2,d2,fld2)) -> + conjunct_bindings (unify_expression e1 e2) (unify_ident fld1 fld2) + | (Ast.RecordPtAccess(e1,pt1,fld1),Ast.RecordPtAccess(e2,pt2,fld2)) -> + conjunct_bindings (unify_expression e1 e2) (unify_ident fld1 fld2) + | (Ast.Cast(lp1,ty1,rp1,e1),Ast.Cast(lp2,ty2,rp2,e2)) -> + conjunct_bindings (unify_fullType ty1 ty2) (unify_expression e1 e2) + | (Ast.SizeOfExpr(szf1,e1),Ast.SizeOfExpr(szf2,e2)) -> + unify_expression e1 e2 + | (Ast.SizeOfType(szf1,lp1,ty1,rp1),Ast.SizeOfType(szf2,lp2,ty2,rp2)) -> + unify_fullType ty1 ty2 + | (Ast.TypeExp(ty1),Ast.TypeExp(ty2)) -> unify_fullType ty1 ty2 + | (Ast.Paren(lp1,e1,rp1),Ast.Paren(lp2,e2,rp2)) -> + unify_expression e1 e2 + + | (Ast.MetaErr(_,_,_,_),_) + | (Ast.MetaExpr(_,_,_,_,_,_),_) + | (Ast.MetaExprList(_,_,_,_),_) + | (_,Ast.MetaErr(_,_,_,_)) + | (_,Ast.MetaExpr(_,_,_,_,_,_)) + | (_,Ast.MetaExprList(_,_,_,_)) -> return true + + | (Ast.EComma(cm1),Ast.EComma(cm2)) -> return true + + | (Ast.DisjExpr(e1),_) -> + disjunct_all_bindings (List.map (function x -> unify_expression x e2) e1) + | (_,Ast.DisjExpr(e2)) -> + disjunct_all_bindings (List.map (function x -> unify_expression e1 x) e2) + | (Ast.NestExpr(e1,_,_),Ast.NestExpr(e2,_,_)) -> + unify_dots unify_expression edots e1 e2 + + (* dots can match against anything. return true to be safe. *) + | (Ast.Edots(_,_),_) | (_,Ast.Edots(_,_)) + | (Ast.Ecircles(_,_),_) | (_,Ast.Ecircles(_,_)) + | (Ast.Estars(_,_),_) | (_,Ast.Estars(_,_)) -> return true + + | (Ast.OptExp(_),_) + | (Ast.UniqueExp(_),_) + | (_,Ast.OptExp(_)) + | (_,Ast.UniqueExp(_)) -> failwith "unsupported expression" + | _ -> return false + +(* --------------------------------------------------------------------- *) +(* Types *) + +and unify_fullType ft1 ft2 = + match (Ast.unwrap ft1,Ast.unwrap ft2) with + (Ast.Type(cv1,ty1),Ast.Type(cv2,ty2)) -> + if bool_unify_option unify_mcode cv1 cv2 + then unify_typeC ty1 ty2 + else return false + | (Ast.DisjType(ft1),_) -> + disjunct_all_bindings (List.map (function x -> unify_fullType x ft2) ft1) + | (_,Ast.DisjType(ft2)) -> + disjunct_all_bindings (List.map (function x -> unify_fullType ft1 x) ft2) + + | (Ast.OptType(_),_) + | (Ast.UniqueType(_),_) + | (_,Ast.OptType(_)) + | (_,Ast.UniqueType(_)) -> failwith "unsupported type" + +and unify_typeC t1 t2 = + match (Ast.unwrap t1,Ast.unwrap t2) with + (Ast.BaseType(ty1,sgn1),Ast.BaseType(ty2,sgn2)) -> + return (unify_mcode ty1 ty2 && bool_unify_option unify_mcode sgn1 sgn2) + | (Ast.ImplicitInt(sgn1),Ast.ImplicitInt(sgn2)) -> + return (unify_mcode sgn1 sgn2) + | (Ast.Pointer(ty1,s1),Ast.Pointer(ty2,s2)) -> unify_fullType ty1 ty2 + | (Ast.FunctionPointer(tya,lp1a,stara,rp1a,lp2a,paramsa,rp2a), + Ast.FunctionPointer(tyb,lp1b,starb,rp1b,lp2b,paramsb,rp2b)) -> + if List.for_all2 unify_mcode + [lp1a;stara;rp1a;lp2a;rp2a] [lp1b;starb;rp1b;lp2b;rp2b] + then + conjunct_bindings (unify_fullType tya tyb) + (unify_dots unify_parameterTypeDef pdots paramsa paramsb) + else return false + | (Ast.FunctionType(_,tya,lp1a,paramsa,rp1a), + Ast.FunctionType(_,tyb,lp1b,paramsb,rp1b)) -> + if List.for_all2 unify_mcode [lp1a;rp1a] [lp1b;rp1b] + then + conjunct_bindings (unify_option unify_fullType tya tyb) + (unify_dots unify_parameterTypeDef pdots paramsa paramsb) + else return false + | (Ast.FunctionType _ , _) -> failwith "not supported" + | (Ast.Array(ty1,lb1,e1,rb1),Ast.Array(ty2,lb2,e2,rb2)) -> + conjunct_bindings + (unify_fullType ty1 ty2) (unify_option unify_expression e1 e2) + | (Ast.StructUnionName(s1,Some ts1),Ast.StructUnionName(s2,Some ts2)) -> + if unify_mcode s1 s2 then unify_ident ts1 ts2 else return false + | (Ast.StructUnionName(s1,None),Ast.StructUnionName(s2,None)) -> + return true + | (Ast.StructUnionDef(ty1,lb1,decls1,rb1), + Ast.StructUnionDef(ty2,lb2,decls2,rb2)) -> + conjunct_bindings (unify_fullType ty1 ty2) + (unify_dots unify_declaration ddots decls1 decls2) + | (Ast.TypeName(t1),Ast.TypeName(t2)) -> return (unify_mcode t1 t2) + + | (Ast.MetaType(_,_,_),_) + | (_,Ast.MetaType(_,_,_)) -> return true + | _ -> return false + +(* --------------------------------------------------------------------- *) +(* 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 unify_declaration d1 d2 = + match (Ast.unwrap d1,Ast.unwrap d2) with + (Ast.Init(stg1,ft1,id1,eq1,i1,s1),Ast.Init(stg2,ft2,id2,eq2,i2,s2)) -> + if bool_unify_option unify_mcode stg1 stg2 + then + conjunct_bindings (unify_fullType ft1 ft2) + (conjunct_bindings (unify_ident id1 id2) (unify_initialiser i1 i2)) + else return false + | (Ast.UnInit(stg1,ft1,id1,s1),Ast.UnInit(stg2,ft2,id2,s2)) -> + if bool_unify_option unify_mcode stg1 stg2 + then conjunct_bindings (unify_fullType ft1 ft2) (unify_ident id1 id2) + else return false + | (Ast.MacroDecl(n1,lp1,args1,rp1,sem1), + Ast.MacroDecl(n2,lp2,args2,rp2,sem2)) -> + conjunct_bindings (unify_ident n1 n2) + (unify_dots unify_expression edots args1 args2) + | (Ast.TyDecl(ft1,s1),Ast.TyDecl(ft2,s2)) -> unify_fullType ft1 ft2 + | (Ast.Typedef(stg1,ft1,id1,s1),Ast.Typedef(stg2,ft2,id2,s2)) -> + conjunct_bindings (unify_fullType ft1 ft2) (unify_typeC id1 id2) + | (Ast.DisjDecl(d1),_) -> + disjunct_all_bindings + (List.map (function x -> unify_declaration x d2) d1) + | (_,Ast.DisjDecl(d2)) -> + disjunct_all_bindings + (List.map (function x -> unify_declaration d1 x) d2) + (* dots can match against anything. return true to be safe. *) + | (Ast.Ddots(_,_),_) | (_,Ast.Ddots(_,_)) -> return true + + | (Ast.OptDecl(_),_) + | (Ast.UniqueDecl(_),_) + | (_,Ast.OptDecl(_)) + | (_,Ast.UniqueDecl(_)) -> failwith "unsupported decl" + | _ -> return false + +(* --------------------------------------------------------------------- *) +(* Initializer *) + +and unify_initialiser i1 i2 = + match (Ast.unwrap i1,Ast.unwrap i2) with + (Ast.InitExpr(expa),Ast.InitExpr(expb)) -> + unify_expression expa expb + | (Ast.InitList(_,initlista,_,whena), + Ast.InitList(_,initlistb,_,whenb)) -> + (* ignore whencode - returns true safely *) + unify_lists unify_initialiser (function _ -> false) initlista initlistb + | (Ast.InitGccDotName(_,namea,_,inia), + Ast.InitGccDotName(_,nameb,_,inib)) -> + conjunct_bindings + (unify_ident namea nameb) (unify_initialiser inia inib) + | (Ast.InitGccName(namea,_,inia),Ast.InitGccName(nameb,_,inib)) -> + conjunct_bindings (unify_ident namea nameb) (unify_initialiser inia inib) + | (Ast.InitGccIndex(_,expa,_,_,inia), + Ast.InitGccIndex(_,expb,_,_,inib)) -> + conjunct_bindings + (unify_expression expa expb) (unify_initialiser inia inib) + | (Ast.InitGccRange(_,exp1a,_,exp2a,_,_,inia), + Ast.InitGccRange(_,exp1b,_,exp2b,_,_,inib)) -> + conjunct_bindings (unify_expression exp1a exp1b) + (conjunct_bindings (unify_expression exp2a exp2b) + (unify_initialiser inia inib)) + + | (Ast.OptIni(_),_) + | (Ast.UniqueIni(_),_) + | (_,Ast.OptIni(_)) + | (_,Ast.UniqueIni(_)) -> failwith "unsupported decl" + | _ -> return false + +(* --------------------------------------------------------------------- *) +(* Parameter *) + +and unify_parameterTypeDef p1 p2 = + match (Ast.unwrap p1,Ast.unwrap p2) with + (Ast.VoidParam(ft1),Ast.VoidParam(ft2)) -> unify_fullType ft1 ft2 + | (Ast.Param(ft1,i1),Ast.Param(ft2,i2)) -> + conjunct_bindings (unify_fullType ft1 ft2) + (unify_option unify_ident i1 i2) + + | (Ast.MetaParam(_,_,_),_) + | (Ast.MetaParamList(_,_,_,_),_) + | (_,Ast.MetaParam(_,_,_)) + | (_,Ast.MetaParamList(_,_,_,_)) -> return true + + | (Ast.PComma(_),Ast.PComma(_)) -> return true + + (* dots can match against anything. return true to be safe. *) + | (Ast.Pdots(_),_) | (_,Ast.Pdots(_)) + | (Ast.Pcircles(_),_) | (_,Ast.Pcircles(_)) -> return true + + | (Ast.OptParam(_),_) + | (Ast.UniqueParam(_),_) + | (_,Ast.OptParam(_)) + | (_,Ast.UniqueParam(_)) -> failwith "unsupported parameter" + | _ -> return false + +(* --------------------------------------------------------------------- *) +(* Define parameter *) + +and unify_define_parameters p1 p2 = + match (Ast.unwrap p1,Ast.unwrap p2) with + (Ast.NoParams,Ast.NoParams) -> return true + | (Ast.DParams(lp1,params1,rp1),Ast.DParams(lp2,params2,rp2)) -> + unify_dots unify_define_param dpdots params1 params2 + | _ -> return false + +and unify_define_param p1 p2 = + match (Ast.unwrap p1,Ast.unwrap p2) with + (Ast.DParam(i1),Ast.DParam(i2)) -> + (unify_ident i1 i2) + | (Ast.DPComma(_),Ast.DPComma(_)) -> return true + + (* dots can match against anything. return true to be safe. *) + | (Ast.DPdots(_),_) | (_,Ast.DPdots(_)) + | (Ast.DPcircles(_),_) | (_,Ast.DPcircles(_)) -> return true + + | (Ast.OptDParam(_),_) + | (Ast.UniqueDParam(_),_) + | (_,Ast.OptDParam(_)) + | (_,Ast.UniqueDParam(_)) -> failwith "unsupported parameter" + | _ -> return false + +(* --------------------------------------------------------------------- *) +(* Top-level code *) + +and unify_rule_elem re1 re2 = + match (Ast.unwrap re1,Ast.unwrap re2) with + (Ast.FunHeader(_,_,fi1,nm1,lp1,params1,rp1), + Ast.FunHeader(_,_,fi2,nm2,lp2,params2,rp2)) -> + conjunct_bindings (unify_fninfo fi1 fi2) + (conjunct_bindings (unify_ident nm1 nm2) + (unify_dots unify_parameterTypeDef pdots params1 params2)) + | (Ast.Decl(_,_,d1),Ast.Decl(_,_,d2)) -> unify_declaration d1 d2 + + | (Ast.SeqStart(lb1),Ast.SeqStart(lb2)) -> return true + | (Ast.SeqEnd(rb1),Ast.SeqEnd(rb2)) -> return true + + | (Ast.ExprStatement(e1,s1),Ast.ExprStatement(e2,s2)) -> + unify_expression e1 e2 + | (Ast.IfHeader(if1,lp1,e1,rp1),Ast.IfHeader(if2,lp2,e2,rp2)) -> + unify_expression e1 e2 + | (Ast.Else(e1),Ast.Else(e2)) -> return true + | (Ast.WhileHeader(wh1,lp1,e1,rp1),Ast.WhileHeader(wh2,lp2,e2,rp2)) -> + unify_expression e1 e2 + | (Ast.DoHeader(d1),Ast.DoHeader(d2)) -> return true + | (Ast.WhileTail(wh1,lp1,e1,rp1,s1),Ast.WhileTail(wh2,lp2,e2,rp2,s2)) -> + unify_expression e1 e2 + | (Ast.ForHeader(fr1,lp1,e11,s11,e21,s21,e31,rp1), + Ast.ForHeader(fr2,lp2,e12,s12,e22,s22,e32,rp2)) -> + conjunct_bindings + (unify_option unify_expression e11 e12) + (conjunct_bindings + (unify_option unify_expression e21 e22) + (unify_option unify_expression e31 e32)) + | (Ast.IteratorHeader(nm1,lp1,args1,rp1), + Ast.IteratorHeader(nm2,lp2,args2,rp2)) -> + conjunct_bindings (unify_ident nm1 nm2) + (unify_dots unify_expression edots args1 args2) + | (Ast.DefineHeader(_,n1,p1),Ast.DefineHeader(_,n2,p2)) -> + conjunct_bindings (unify_ident n1 n2) + (unify_define_parameters p1 p2) + | (Ast.Break(r1,s1),Ast.Break(r2,s2)) -> return true + | (Ast.Continue(r1,s1),Ast.Continue(r2,s2)) -> return true + | (Ast.Label(l1,dd1),Ast.Label(l2,dd2)) -> unify_ident l1 l2 + | (Ast.Goto(g1,l1,dd1),Ast.Goto(g2,l2,dd2)) -> unify_ident l1 l2 + | (Ast.Return(r1,s1),Ast.Return(r2,s2)) -> return true + | (Ast.ReturnExpr(r1,e1,s1),Ast.ReturnExpr(r2,e2,s2)) -> + unify_expression e1 e2 + + | (Ast.DisjRuleElem(res1),_) -> + disjunct_all_bindings + (List.map (function x -> unify_rule_elem x re2) res1) + | (_,Ast.DisjRuleElem(res2)) -> + disjunct_all_bindings + (List.map (function x -> unify_rule_elem re1 x) res2) + + | (Ast.MetaRuleElem(_,_,_),_) + | (Ast.MetaStmt(_,_,_,_),_) + | (Ast.MetaStmtList(_,_,_),_) + | (_,Ast.MetaRuleElem(_,_,_)) + | (_,Ast.MetaStmt(_,_,_,_)) + | (_,Ast.MetaStmtList(_,_,_)) -> return true + + (* can match a rule_elem in different parts *) + | (Ast.Exp(e1),Ast.Exp(e2)) -> return true + | (Ast.Exp(e1),_) -> subexp (unify_expression e1) re2 + | (_,Ast.Exp(e2)) -> subexp (unify_expression e2) re1 + + | (Ast.TopExp(e1),Ast.TopExp(e2)) -> unify_expression e1 e2 + + (* can match a rule_elem in different parts *) + | (Ast.Ty(t1),Ast.Ty(t2)) -> return true + | (Ast.Ty(t1),_) -> subtype (unify_fullType t1) re2 + | (_,Ast.Ty(t2)) -> subtype (unify_fullType t2) re1 + | _ -> return false + +and unify_fninfo patterninfo cinfo = + let patterninfo = List.sort compare patterninfo in + let cinfo = List.sort compare cinfo in + let rec loop = function + (Ast.FStorage(sta)::resta,Ast.FStorage(stb)::restb) -> + if unify_mcode sta stb then loop (resta,restb) else return false + | (Ast.FType(tya)::resta,Ast.FType(tyb)::restb) -> + conjunct_bindings (unify_fullType tya tyb) (loop (resta,restb)) + | (Ast.FInline(ia)::resta,Ast.FInline(ib)::restb) -> + if unify_mcode ia ib then loop (resta,restb) else return false + | (Ast.FAttr(ia)::resta,Ast.FAttr(ib)::restb) -> + if unify_mcode ia ib then 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 subexp f = + let bind = conjunct_bindings in + let option_default = return false in + let mcode r e = option_default in + let expr r k e = conjunct_bindings (f e) (k e) in + let donothing r k e = k e 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 expr donothing donothing donothing donothing donothing + donothing donothing donothing donothing donothing in + recursor.V.combiner_rule_elem + +and subtype f = + let bind = conjunct_bindings in + let option_default = return false in + let mcode r e = option_default in + let fullType r k e = conjunct_bindings (f e) (k e) in + let donothing r k e = k e 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 fullType donothing donothing donothing donothing + donothing donothing donothing donothing donothing in + recursor.V.combiner_rule_elem + +let rec unify_statement s1 s2 = + match (Ast.unwrap s1,Ast.unwrap s2) with + (Ast.Seq(lb1,d1,s1,rb1),Ast.Seq(lb2,d2,s2,rb2)) -> + conjunct_bindings (unify_rule_elem lb1 lb2) + (conjunct_bindings + (unify_dots unify_statement sdots s1 s2) + (conjunct_bindings + (unify_dots unify_statement sdots d1 d2) + (unify_rule_elem rb1 rb2))) + | (Ast.IfThen(h1,thn1,_),Ast.IfThen(h2,thn2,_)) -> + conjunct_bindings (unify_rule_elem h1 h2) (unify_statement thn1 thn2) + | (Ast.IfThenElse(h1,thn1,e1,els1,_),Ast.IfThenElse(h2,thn2,e2,els2,_)) -> + conjunct_bindings (unify_rule_elem h1 h2) + (conjunct_bindings (unify_statement thn1 thn2) + (conjunct_bindings (unify_rule_elem e1 e2) + (unify_statement els1 els2))) + | (Ast.While(h1,s1,_),Ast.While(h2,s2,_)) -> + conjunct_bindings (unify_rule_elem h1 h2) (unify_statement s1 s2) + | (Ast.Do(h1,s1,t1),Ast.Do(h2,s2,t2)) -> + conjunct_bindings (unify_rule_elem h1 h2) + (conjunct_bindings (unify_statement s1 s2) (unify_rule_elem t1 t2)) + | (Ast.For(h1,s1,_),Ast.For(h2,s2,_)) -> + conjunct_bindings (unify_rule_elem h1 h2) (unify_statement s1 s2) + | (Ast.Atomic(re1),Ast.Atomic(re2)) -> unify_rule_elem re1 re2 + | (Ast.Disj(s1),_) -> + let s2 = Ast.rewrap s2 (Ast.DOTS[s2]) in + disjunct_all_bindings + (List.map + (function x -> unify_dots unify_statement sdots x s2) + s1) + | (_,Ast.Disj(s2)) -> + let s1 = Ast.rewrap s1 (Ast.DOTS[s1]) in + disjunct_all_bindings + (List.map + (function x -> unify_dots unify_statement sdots s1 x) + s2) + | (Ast.Nest(s1,_,_,_,_),Ast.Nest(s2,_,_,_,_)) -> + unify_dots unify_statement sdots s1 s2 + | (Ast.FunDecl(h1,lb1,d1,s1,rb1),Ast.FunDecl(h2,lb2,d2,s2,rb2)) -> + conjunct_bindings (unify_rule_elem h1 h2) + (conjunct_bindings (unify_rule_elem lb1 lb2) + (conjunct_bindings (unify_dots unify_statement sdots d1 d2) + (conjunct_bindings (unify_dots unify_statement sdots s1 s2) + (unify_rule_elem rb1 rb2)))) + | (Ast.Define(h1,s1),Ast.Define(h2,s2)) -> + conjunct_bindings (unify_rule_elem h1 h2) + (unify_dots unify_statement sdots s1 s2) + (* dots can match against anything. return true to be safe. *) + | (Ast.Dots(_,_,_,_),_) | (_,Ast.Dots(_,_,_,_)) + | (Ast.Circles(_,_,_,_),_) | (_,Ast.Circles(_,_,_,_)) + | (Ast.Stars(_,_,_,_),_) | (_,Ast.Stars(_,_,_,_)) -> return true + | (Ast.OptStm(_),_) + | (Ast.UniqueStm(_),_) + | (_,Ast.OptStm(_)) + | (_,Ast.UniqueStm(_)) -> failwith "unsupported statement" + | _ -> return false + +let unify_statement_dots = unify_dots unify_statement sdots diff --git a/parsing_cocci/.#unitary_ast0.ml.1.28 b/parsing_cocci/.#unitary_ast0.ml.1.28 new file mode 100644 index 0000000..1110f58 --- /dev/null +++ b/parsing_cocci/.#unitary_ast0.ml.1.28 @@ -0,0 +1,284 @@ +(* +* 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 = function + Ast0.WhenNot(a) -> afn a + | Ast0.WhenAlways(b) -> bfn b + | Ast0.WhenModifier(_) -> option_default 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) + 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) + 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.107 b/parsing_cocci/.#unparse_ast0.ml.1.107 new file mode 100644 index 0000000..80ece57 --- /dev/null +++ b/parsing_cocci/.#unparse_ast0.ml.1.107 @@ -0,0 +1,651 @@ +(* +* 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.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 + +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.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/.#unparse_ast0.ml.1.108 b/parsing_cocci/.#unparse_ast0.ml.1.108 new file mode 100644 index 0000000..b76d3b9 --- /dev/null +++ b/parsing_cocci/.#unparse_ast0.ml.1.108 @@ -0,0 +1,657 @@ +(* +* 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.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_ast.ml.1.89 b/parsing_cocci/.#visitor_ast.ml.1.89 new file mode 100644 index 0000000..6338874 --- /dev/null +++ b/parsing_cocci/.#visitor_ast.ml.1.89 @@ -0,0 +1,1048 @@ +(* +* 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 + +(* --------------------------------------------------------------------- *) +(* Generic traversal: combiner *) +(* parameters: + combining function + treatment of: mcode, identifiers, expressions, fullTypes, types, + declarations, statements, toplevels + default value for options *) + +type 'a combiner = + {combiner_ident : Ast.ident -> 'a; + combiner_expression : Ast.expression -> 'a; + combiner_fullType : Ast.fullType -> 'a; + combiner_typeC : Ast.typeC -> 'a; + combiner_declaration : Ast.declaration -> 'a; + combiner_initialiser : Ast.initialiser -> 'a; + combiner_parameter : Ast.parameterTypeDef -> 'a; + combiner_parameter_list : Ast.parameter_list -> 'a; + combiner_rule_elem : Ast.rule_elem -> 'a; + combiner_statement : Ast.statement -> 'a; + combiner_case_line : Ast.case_line -> 'a; + combiner_top_level : Ast.top_level -> 'a; + combiner_anything : Ast.anything -> 'a; + combiner_expression_dots : Ast.expression Ast.dots -> 'a; + combiner_statement_dots : Ast.statement Ast.dots -> 'a; + combiner_declaration_dots : Ast.declaration Ast.dots -> 'a} + +type ('mc,'a) cmcode = 'a combiner -> 'mc Ast_cocci.mcode -> 'a +type ('cd,'a) ccode = 'a combiner -> ('cd -> 'a) -> 'cd -> 'a + + +let combiner bind option_default + meta_mcodefn string_mcodefn const_mcodefn assign_mcodefn fix_mcodefn + unary_mcodefn binary_mcodefn + cv_mcodefn base_mcodefn sign_mcodefn struct_mcodefn storage_mcodefn + inc_file_mcodefn + expdotsfn paramdotsfn stmtdotsfn decldotsfn + identfn exprfn ftfn tyfn initfn paramfn declfn rulefn stmtfn casefn + topfn anyfn = + 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 meta_mcode x = meta_mcodefn all_functions x + and string_mcode x = string_mcodefn all_functions x + and const_mcode x = const_mcodefn all_functions x + and assign_mcode x = assign_mcodefn all_functions x + and fix_mcode x = fix_mcodefn all_functions x + and unary_mcode x = unary_mcodefn all_functions x + and binary_mcode x = binary_mcodefn all_functions x + and cv_mcode x = cv_mcodefn all_functions x + and base_mcode x = base_mcodefn all_functions x + and sign_mcode x = sign_mcodefn all_functions x + and struct_mcode x = struct_mcodefn all_functions x + and storage_mcode x = storage_mcodefn all_functions x + and inc_file_mcode x = inc_file_mcodefn all_functions x + + and expression_dots d = + let k d = + match Ast.unwrap d with + Ast.DOTS(l) | Ast.CIRCLES(l) | Ast.STARS(l) -> + multibind (List.map expression l) in + expdotsfn all_functions k d + + and parameter_dots d = + let k d = + match Ast.unwrap d with + Ast.DOTS(l) | Ast.CIRCLES(l) | Ast.STARS(l) -> + multibind (List.map parameterTypeDef l) in + paramdotsfn all_functions k d + + and statement_dots d = + let k d = + match Ast.unwrap d with + Ast.DOTS(l) | Ast.CIRCLES(l) | Ast.STARS(l) -> + multibind (List.map statement l) in + stmtdotsfn all_functions k d + + and declaration_dots d = + let k d = + match Ast.unwrap d with + Ast.DOTS(l) | Ast.CIRCLES(l) | Ast.STARS(l) -> + multibind (List.map declaration l) in + decldotsfn all_functions k d + + and ident i = + let k i = + match Ast.unwrap i with + Ast.Id(name) -> string_mcode name + | Ast.MetaId(name,_,_,_) -> meta_mcode name + | Ast.MetaFunc(name,_,_,_) -> meta_mcode name + | Ast.MetaLocalFunc(name,_,_,_) -> meta_mcode name + | Ast.OptIdent(id) -> ident id + | Ast.UniqueIdent(id) -> ident id in + identfn all_functions k i + + and expression e = + let k e = + match Ast.unwrap e with + Ast.Ident(id) -> ident id + | Ast.Constant(const) -> const_mcode const + | Ast.FunCall(fn,lp,args,rp) -> + multibind [expression fn; string_mcode lp; expression_dots args; + string_mcode rp] + | Ast.Assignment(left,op,right,simple) -> + multibind [expression left; assign_mcode op; expression right] + | Ast.CondExpr(exp1,why,exp2,colon,exp3) -> + multibind [expression exp1; string_mcode why; + get_option expression exp2; string_mcode colon; + expression exp3] + | Ast.Postfix(exp,op) -> bind (expression exp) (fix_mcode op) + | Ast.Infix(exp,op) -> bind (fix_mcode op) (expression exp) + | Ast.Unary(exp,op) -> bind (unary_mcode op) (expression exp) + | Ast.Binary(left,op,right) -> + multibind [expression left; binary_mcode op; expression right] + | Ast.Nested(left,op,right) -> + multibind [expression left; binary_mcode op; expression right] + | Ast.Paren(lp,exp,rp) -> + multibind [string_mcode lp; expression exp; string_mcode rp] + | Ast.ArrayAccess(exp1,lb,exp2,rb) -> + multibind + [expression exp1; string_mcode lb; expression exp2; + string_mcode rb] + | Ast.RecordAccess(exp,pt,field) -> + multibind [expression exp; string_mcode pt; ident field] + | Ast.RecordPtAccess(exp,ar,field) -> + multibind [expression exp; string_mcode ar; ident field] + | Ast.Cast(lp,ty,rp,exp) -> + multibind + [string_mcode lp; fullType ty; string_mcode rp; expression exp] + | Ast.SizeOfExpr(szf,exp) -> + multibind [string_mcode szf; expression exp] + | Ast.SizeOfType(szf,lp,ty,rp) -> + multibind + [string_mcode szf; string_mcode lp; fullType ty; string_mcode rp] + | Ast.TypeExp(ty) -> fullType ty + | Ast.MetaErr(name,_,_,_) + | Ast.MetaExpr(name,_,_,_,_,_) + | Ast.MetaExprList(name,_,_,_) -> meta_mcode name + | Ast.EComma(cm) -> string_mcode cm + | Ast.DisjExpr(exp_list) -> multibind (List.map expression exp_list) + | Ast.NestExpr(expr_dots,whencode,multi) -> + bind (expression_dots expr_dots) (get_option expression whencode) + | Ast.Edots(dots,whencode) | Ast.Ecircles(dots,whencode) + | Ast.Estars(dots,whencode) -> + bind (string_mcode dots) (get_option expression whencode) + | Ast.OptExp(exp) | Ast.UniqueExp(exp) -> + expression exp in + exprfn all_functions k e + + and fullType ft = + let k ft = + match Ast.unwrap ft with + Ast.Type(cv,ty) -> bind (get_option cv_mcode cv) (typeC ty) + | Ast.DisjType(types) -> multibind (List.map fullType types) + | Ast.OptType(ty) -> fullType ty + | Ast.UniqueType(ty) -> fullType ty in + ftfn all_functions k ft + + and function_pointer (ty,lp1,star,rp1,lp2,params,rp2) extra = + (* have to put the treatment of the identifier into the right position *) + multibind + ([fullType 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 fullType ty] @ extra @ + [string_mcode lp1; parameter_dots params; string_mcode rp1]) + + and array_type (ty,lb,size,rb) extra = + multibind + ([fullType ty] @ extra @ + [string_mcode lb; get_option expression size; string_mcode rb]) + + and typeC ty = + let k ty = + match Ast.unwrap ty with + Ast.BaseType(ty,sgn) -> + bind (get_option sign_mcode sgn) (base_mcode ty) + | Ast.ImplicitInt(sgn) -> sign_mcode sgn + | Ast.Pointer(ty,star) -> + bind (fullType ty) (string_mcode star) + | Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> + function_pointer (ty,lp1,star,rp1,lp2,params,rp2) [] + | Ast.FunctionType (_,ty,lp1,params,rp1) -> + function_type (ty,lp1,params,rp1) [] + | Ast.Array(ty,lb,size,rb) -> array_type (ty,lb,size,rb) [] + | Ast.StructUnionName(kind,name) -> + bind (struct_mcode kind) (get_option ident name) + | Ast.StructUnionDef(ty,lb,decls,rb) -> + multibind + [fullType ty; string_mcode lb; declaration_dots decls; + string_mcode rb] + | Ast.TypeName(name) -> string_mcode name + | Ast.MetaType(name,_,_) -> meta_mcode name in + tyfn all_functions k ty + + and named_type ty id = + match Ast.unwrap ty with + Ast.Type(None,ty1) -> + (match Ast.unwrap ty1 with + Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> + function_pointer (ty,lp1,star,rp1,lp2,params,rp2) [ident id] + | Ast.FunctionType(_,ty,lp1,params,rp1) -> + function_type (ty,lp1,params,rp1) [ident id] + | Ast.Array(ty,lb,size,rb) -> array_type (ty,lb,size,rb) [ident id] + | _ -> bind (fullType ty) (ident id)) + | _ -> bind (fullType ty) (ident id) + + and declaration d = + let k d = + match Ast.unwrap d with + Ast.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])) + | Ast.UnInit(stg,ty,id,sem) -> + bind (get_option storage_mcode stg) + (bind (named_type ty id) (string_mcode sem)) + | Ast.MacroDecl(name,lp,args,rp,sem) -> + multibind + [ident name; string_mcode lp; expression_dots args; + string_mcode rp; string_mcode sem] + | Ast.TyDecl(ty,sem) -> bind (fullType ty) (string_mcode sem) + | Ast.Typedef(stg,ty,id,sem) -> + bind (string_mcode stg) + (bind (fullType ty) (bind (typeC id) (string_mcode sem))) + | Ast.DisjDecl(decls) -> multibind (List.map declaration decls) + | Ast.Ddots(dots,whencode) -> + bind (string_mcode dots) (get_option declaration whencode) + | Ast.MetaDecl(name,_,_) -> meta_mcode name + | Ast.OptDecl(decl) -> declaration decl + | Ast.UniqueDecl(decl) -> declaration decl in + declfn all_functions k d + + and initialiser i = + let k i = + match Ast.unwrap i with + Ast.InitExpr(exp) -> expression exp + | Ast.InitList(lb,initlist,rb,whencode) -> + multibind + [string_mcode lb; + multibind (List.map initialiser initlist); + string_mcode rb; + multibind (List.map initialiser whencode)] + | Ast.InitGccDotName(dot,name,eq,ini) -> + multibind + [string_mcode dot; ident name; string_mcode eq; initialiser ini] + | Ast.InitGccName(name,eq,ini) -> + multibind [ident name; string_mcode eq; initialiser ini] + | Ast.InitGccIndex(lb,exp,rb,eq,ini) -> + multibind + [string_mcode lb; expression exp; string_mcode rb; + string_mcode eq; initialiser ini] + | Ast.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] + | Ast.IComma(cm) -> string_mcode cm + | Ast.OptIni(i) -> initialiser i + | Ast.UniqueIni(i) -> initialiser i in + initfn all_functions k i + + and parameterTypeDef p = + let k p = + match Ast.unwrap p with + Ast.VoidParam(ty) -> fullType ty + | Ast.Param(ty,Some id) -> named_type ty id + | Ast.Param(ty,None) -> fullType ty + | Ast.MetaParam(name,_,_) -> meta_mcode name + | Ast.MetaParamList(name,_,_,_) -> meta_mcode name + | Ast.PComma(cm) -> string_mcode cm + | Ast.Pdots(dots) -> string_mcode dots + | Ast.Pcircles(dots) -> string_mcode dots + | Ast.OptParam(param) -> parameterTypeDef param + | Ast.UniqueParam(param) -> parameterTypeDef param in + paramfn all_functions k p + + and rule_elem re = + let k re = + match Ast.unwrap re with + Ast.FunHeader(_,_,fi,name,lp,params,rp) -> + multibind + ((List.map fninfo fi) @ + [ident name;string_mcode lp;parameter_dots params; + string_mcode rp]) + | Ast.Decl(_,_,decl) -> declaration decl + | Ast.SeqStart(brace) -> string_mcode brace + | Ast.SeqEnd(brace) -> string_mcode brace + | Ast.ExprStatement(exp,sem) -> + bind (expression exp) (string_mcode sem) + | Ast.IfHeader(iff,lp,exp,rp) -> + multibind [string_mcode iff; string_mcode lp; expression exp; + string_mcode rp] + | Ast.Else(els) -> string_mcode els + | Ast.WhileHeader(whl,lp,exp,rp) -> + multibind [string_mcode whl; string_mcode lp; expression exp; + string_mcode rp] + | Ast.DoHeader(d) -> string_mcode d + | Ast.WhileTail(whl,lp,exp,rp,sem) -> + multibind [string_mcode whl; string_mcode lp; expression exp; + string_mcode rp; string_mcode sem] + | Ast.ForHeader(fr,lp,e1,sem1,e2,sem2,e3,rp) -> + 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] + | Ast.IteratorHeader(nm,lp,args,rp) -> + multibind [ident nm; string_mcode lp; + expression_dots args; string_mcode rp] + | Ast.SwitchHeader(switch,lp,exp,rp) -> + multibind [string_mcode switch; string_mcode lp; expression exp; + string_mcode rp] + | Ast.Break(br,sem) -> bind (string_mcode br) (string_mcode sem) + | Ast.Continue(cont,sem) -> bind (string_mcode cont) (string_mcode sem) + | Ast.Label(l,dd) -> bind (ident l) (string_mcode dd) + | Ast.Goto(goto,l,sem) -> + bind (string_mcode goto) (bind (ident l) (string_mcode sem)) + | Ast.Return(ret,sem) -> bind (string_mcode ret) (string_mcode sem) + | Ast.ReturnExpr(ret,exp,sem) -> + multibind [string_mcode ret; expression exp; string_mcode sem] + | Ast.MetaStmt(name,_,_,_) -> meta_mcode name + | Ast.MetaStmtList(name,_,_) -> meta_mcode name + | Ast.MetaRuleElem(name,_,_) -> meta_mcode name + | Ast.Exp(exp) -> expression exp + | Ast.TopExp(exp) -> expression exp + | Ast.Ty(ty) -> fullType ty + | Ast.Include(inc,name) -> bind (string_mcode inc) (inc_file_mcode name) + | Ast.DefineHeader(def,id,params) -> + multibind [string_mcode def; ident id; define_parameters params] + | Ast.Default(def,colon) -> bind (string_mcode def) (string_mcode colon) + | Ast.Case(case,exp,colon) -> + multibind [string_mcode case; expression exp; string_mcode colon] + | Ast.DisjRuleElem(res) -> multibind (List.map rule_elem res) in + rulefn all_functions k re + + (* not parameterizable for now... *) + and define_parameters p = + let k p = + match Ast.unwrap p with + Ast.NoParams -> option_default + | Ast.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 Ast.unwrap d with + Ast.DOTS(l) | Ast.CIRCLES(l) | Ast.STARS(l) -> + multibind (List.map define_param l) in + k d + + and define_param p = + let k p = + match Ast.unwrap p with + Ast.DParam(id) -> ident id + | Ast.DPComma(comma) -> string_mcode comma + | Ast.DPdots(d) -> string_mcode d + | Ast.DPcircles(c) -> string_mcode c + | Ast.OptDParam(dp) -> define_param dp + | Ast.UniqueDParam(dp) -> define_param dp in + k p + + (* discard the result, because the statement is assumed to be already + represented elsewhere in the code *) + and process_bef_aft s = + match Ast.get_dots_bef_aft s with + Ast.NoDots -> () + | Ast.DroppingBetweenDots(stm,ind) -> let _ = statement stm in () + | Ast.AddingBetweenDots(stm,ind) -> let _ = statement stm in () + + and statement s = + process_bef_aft s; + let k s = + match Ast.unwrap s with + Ast.Seq(lbrace,decls,body,rbrace) -> + multibind [rule_elem lbrace; statement_dots decls; + statement_dots body; rule_elem rbrace] + | Ast.IfThen(header,branch,_) -> + multibind [rule_elem header; statement branch] + | Ast.IfThenElse(header,branch1,els,branch2,_) -> + multibind [rule_elem header; statement branch1; rule_elem els; + statement branch2] + | Ast.While(header,body,_) -> + multibind [rule_elem header; statement body] + | Ast.Do(header,body,tail) -> + multibind [rule_elem header; statement body; rule_elem tail] + | Ast.For(header,body,_) -> multibind [rule_elem header; statement body] + | Ast.Iterator(header,body,_) -> + multibind [rule_elem header; statement body] + | Ast.Switch(header,lb,cases,rb) -> + multibind [rule_elem header;rule_elem lb; + multibind (List.map case_line cases); + rule_elem rb] + | Ast.Atomic(re) -> rule_elem re + | Ast.Disj(stmt_dots_list) -> + multibind (List.map statement_dots stmt_dots_list) + | Ast.Nest(stmt_dots,whn,_,_,_) -> + bind (statement_dots stmt_dots) + (multibind (List.map (whencode statement_dots statement) whn)) + | Ast.FunDecl(header,lbrace,decls,body,rbrace) -> + multibind [rule_elem header; rule_elem lbrace; + statement_dots decls; statement_dots body; + rule_elem rbrace] + | Ast.Define(header,body) -> + bind (rule_elem header) (statement_dots body) + | Ast.Dots(d,whn,_,_) | Ast.Circles(d,whn,_,_) | Ast.Stars(d,whn,_,_) -> + bind (string_mcode d) + (multibind (List.map (whencode statement_dots statement) whn)) + | Ast.OptStm(stmt) | Ast.UniqueStm(stmt) -> + statement stmt in + stmtfn all_functions k s + + and fninfo = function + Ast.FStorage(stg) -> storage_mcode stg + | Ast.FType(ty) -> fullType ty + | Ast.FInline(inline) -> string_mcode inline + | Ast.FAttr(attr) -> string_mcode attr + + and whencode notfn alwaysfn = function + Ast.WhenNot a -> notfn a + | Ast.WhenAlways a -> alwaysfn a + | Ast.WhenModifier(_) -> option_default + + and case_line c = + let k c = + match Ast.unwrap c with + Ast.CaseLine(header,code) -> + bind (rule_elem header) (statement_dots code) + | Ast.OptCase(case) -> case_line case in + casefn all_functions k c + + and top_level t = + let k t = + match Ast.unwrap t with + Ast.FILEINFO(old_file,new_file) -> + bind (string_mcode old_file) (string_mcode new_file) + | Ast.DECL(stmt) -> statement stmt + | Ast.CODE(stmt_dots) -> statement_dots stmt_dots + | Ast.ERRORWORDS(exps) -> multibind (List.map expression exps) in + topfn all_functions k t + + and anything a = + let k = function + (*in many cases below, the thing is not even mcode, so we do nothing*) + Ast.FullTypeTag(ft) -> fullType ft + | Ast.BaseTypeTag(bt) -> option_default + | Ast.StructUnionTag(su) -> option_default + | Ast.SignTag(sgn) -> option_default + | Ast.IdentTag(id) -> ident id + | Ast.ExpressionTag(exp) -> expression exp + | Ast.ConstantTag(cst) -> option_default + | Ast.UnaryOpTag(unop) -> option_default + | Ast.AssignOpTag(asgnop) -> option_default + | Ast.FixOpTag(fixop) -> option_default + | Ast.BinaryOpTag(binop) -> option_default + | Ast.ArithOpTag(arithop) -> option_default + | Ast.LogicalOpTag(logop) -> option_default + | Ast.DeclarationTag(decl) -> declaration decl + | Ast.InitTag(ini) -> initialiser ini + | Ast.StorageTag(stg) -> option_default + | Ast.IncFileTag(stg) -> option_default + | Ast.Rule_elemTag(rule) -> rule_elem rule + | Ast.StatementTag(rule) -> statement rule + | Ast.CaseLineTag(case) -> case_line case + | Ast.ConstVolTag(cv) -> option_default + | Ast.Token(tok,info) -> option_default + | Ast.Code(cd) -> top_level cd + | Ast.ExprDotsTag(ed) -> expression_dots ed + | Ast.ParamDotsTag(pd) -> parameter_dots pd + | Ast.StmtDotsTag(sd) -> statement_dots sd + | Ast.DeclDotsTag(sd) -> declaration_dots sd + | Ast.TypeCTag(ty) -> typeC ty + | Ast.ParamTag(param) -> parameterTypeDef param + | Ast.SgrepStartTag(tok) -> option_default + | Ast.SgrepEndTag(tok) -> option_default in + anyfn all_functions k a + + and all_functions = + {combiner_ident = ident; + combiner_expression = expression; + combiner_fullType = fullType; + combiner_typeC = typeC; + combiner_declaration = declaration; + combiner_initialiser = initialiser; + combiner_parameter = parameterTypeDef; + combiner_parameter_list = parameter_dots; + combiner_rule_elem = rule_elem; + combiner_statement = statement; + combiner_case_line = case_line; + combiner_top_level = top_level; + combiner_anything = anything; + combiner_expression_dots = expression_dots; + combiner_statement_dots = statement_dots; + combiner_declaration_dots = declaration_dots} in + all_functions + +(* ---------------------------------------------------------------------- *) + +type 'a inout = 'a -> 'a (* for specifying the type of rebuilder *) + +type rebuilder = + {rebuilder_ident : Ast.ident inout; + rebuilder_expression : Ast.expression inout; + rebuilder_fullType : Ast.fullType inout; + rebuilder_typeC : Ast.typeC inout; + rebuilder_declaration : Ast.declaration inout; + rebuilder_initialiser : Ast.initialiser inout; + rebuilder_parameter : Ast.parameterTypeDef inout; + rebuilder_parameter_list : Ast.parameter_list inout; + rebuilder_statement : Ast.statement inout; + rebuilder_case_line : Ast.case_line inout; + rebuilder_rule_elem : Ast.rule_elem inout; + rebuilder_top_level : Ast.top_level inout; + rebuilder_expression_dots : Ast.expression Ast.dots inout; + rebuilder_statement_dots : Ast.statement Ast.dots inout; + rebuilder_declaration_dots : Ast.declaration Ast.dots inout; + rebuilder_define_param_dots : Ast.define_param Ast.dots inout; + rebuilder_define_param : Ast.define_param inout; + rebuilder_define_parameters : Ast.define_parameters inout; + rebuilder_anything : Ast.anything inout} + +type 'mc rmcode = 'mc Ast.mcode inout +type 'cd rcode = rebuilder -> ('cd inout) -> 'cd inout + + +let rebuilder + 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_file_mcode + expdotsfn paramdotsfn stmtdotsfn decldotsfn + identfn exprfn ftfn tyfn initfn paramfn declfn rulefn stmtfn casefn + topfn anyfn = + let get_option f = function + Some x -> Some (f x) + | None -> None in + let rec expression_dots d = + let k d = + Ast.rewrap d + (match Ast.unwrap d with + Ast.DOTS(l) -> Ast.DOTS(List.map expression l) + | Ast.CIRCLES(l) -> Ast.CIRCLES(List.map expression l) + | Ast.STARS(l) -> Ast.STARS(List.map expression l)) in + expdotsfn all_functions k d + + and parameter_dots d = + let k d = + Ast.rewrap d + (match Ast.unwrap d with + Ast.DOTS(l) -> Ast.DOTS(List.map parameterTypeDef l) + | Ast.CIRCLES(l) -> Ast.CIRCLES(List.map parameterTypeDef l) + | Ast.STARS(l) -> Ast.STARS(List.map parameterTypeDef l)) in + paramdotsfn all_functions k d + + and statement_dots d = + let k d = + Ast.rewrap d + (match Ast.unwrap d with + Ast.DOTS(l) -> Ast.DOTS(List.map statement l) + | Ast.CIRCLES(l) -> Ast.CIRCLES(List.map statement l) + | Ast.STARS(l) -> Ast.STARS(List.map statement l)) in + stmtdotsfn all_functions k d + + and declaration_dots d = + let k d = + Ast.rewrap d + (match Ast.unwrap d with + Ast.DOTS(l) -> Ast.DOTS(List.map declaration l) + | Ast.CIRCLES(l) -> Ast.CIRCLES(List.map declaration l) + | Ast.STARS(l) -> Ast.STARS(List.map declaration l)) in + decldotsfn all_functions k d + + and ident i = + let k i = + Ast.rewrap i + (match Ast.unwrap i with + Ast.Id(name) -> Ast.Id(string_mcode name) + | Ast.MetaId(name,constraints,keep,inherited) -> + Ast.MetaId(meta_mcode name,constraints,keep,inherited) + | Ast.MetaFunc(name,constraints,keep,inherited) -> + Ast.MetaFunc(meta_mcode name,constraints,keep,inherited) + | Ast.MetaLocalFunc(name,constraints,keep,inherited) -> + Ast.MetaLocalFunc(meta_mcode name,constraints,keep,inherited) + | Ast.OptIdent(id) -> Ast.OptIdent(ident id) + | Ast.UniqueIdent(id) -> Ast.UniqueIdent(ident id)) in + identfn all_functions k i + + and expression e = + let k e = + Ast.rewrap e + (match Ast.unwrap e with + Ast.Ident(id) -> Ast.Ident(ident id) + | Ast.Constant(const) -> Ast.Constant(const_mcode const) + | Ast.FunCall(fn,lp,args,rp) -> + Ast.FunCall(expression fn, string_mcode lp, expression_dots args, + string_mcode rp) + | Ast.Assignment(left,op,right,simple) -> + Ast.Assignment(expression left, assign_mcode op, expression right, + simple) + | Ast.CondExpr(exp1,why,exp2,colon,exp3) -> + Ast.CondExpr(expression exp1, string_mcode why, + get_option expression exp2, string_mcode colon, + expression exp3) + | Ast.Postfix(exp,op) -> Ast.Postfix(expression exp,fix_mcode op) + | Ast.Infix(exp,op) -> Ast.Infix(expression exp,fix_mcode op) + | Ast.Unary(exp,op) -> Ast.Unary(expression exp,unary_mcode op) + | Ast.Binary(left,op,right) -> + Ast.Binary(expression left, binary_mcode op, expression right) + | Ast.Nested(left,op,right) -> + Ast.Nested(expression left, binary_mcode op, expression right) + | Ast.Paren(lp,exp,rp) -> + Ast.Paren(string_mcode lp, expression exp, string_mcode rp) + | Ast.ArrayAccess(exp1,lb,exp2,rb) -> + Ast.ArrayAccess(expression exp1, string_mcode lb, expression exp2, + string_mcode rb) + | Ast.RecordAccess(exp,pt,field) -> + Ast.RecordAccess(expression exp, string_mcode pt, ident field) + | Ast.RecordPtAccess(exp,ar,field) -> + Ast.RecordPtAccess(expression exp, string_mcode ar, ident field) + | Ast.Cast(lp,ty,rp,exp) -> + Ast.Cast(string_mcode lp, fullType ty, string_mcode rp, + expression exp) + | Ast.SizeOfExpr(szf,exp) -> + Ast.SizeOfExpr(string_mcode szf, expression exp) + | Ast.SizeOfType(szf,lp,ty,rp) -> + Ast.SizeOfType(string_mcode szf,string_mcode lp, fullType ty, + string_mcode rp) + | Ast.TypeExp(ty) -> Ast.TypeExp(fullType ty) + | Ast.MetaErr(name,constraints,keep,inherited) -> + Ast.MetaErr(meta_mcode name,constraints,keep,inherited) + | Ast.MetaExpr(name,constraints,keep,ty,form,inherited) -> + Ast.MetaExpr(meta_mcode name,constraints,keep,ty,form,inherited) + | Ast.MetaExprList(name,lenname_inh,keep,inherited) -> + Ast.MetaExprList(meta_mcode name,lenname_inh,keep,inherited) + | Ast.EComma(cm) -> Ast.EComma(string_mcode cm) + | Ast.DisjExpr(exp_list) -> Ast.DisjExpr(List.map expression exp_list) + | Ast.NestExpr(expr_dots,whencode,multi) -> + Ast.NestExpr(expression_dots expr_dots, + get_option expression whencode,multi) + | Ast.Edots(dots,whencode) -> + Ast.Edots(string_mcode dots,get_option expression whencode) + | Ast.Ecircles(dots,whencode) -> + Ast.Ecircles(string_mcode dots,get_option expression whencode) + | Ast.Estars(dots,whencode) -> + Ast.Estars(string_mcode dots,get_option expression whencode) + | Ast.OptExp(exp) -> Ast.OptExp(expression exp) + | Ast.UniqueExp(exp) -> Ast.UniqueExp(expression exp)) in + exprfn all_functions k e + + and fullType ft = + let k ft = + Ast.rewrap ft + (match Ast.unwrap ft with + Ast.Type(cv,ty) -> Ast.Type (get_option cv_mcode cv, typeC ty) + | Ast.DisjType(types) -> Ast.DisjType(List.map fullType types) + | Ast.OptType(ty) -> Ast.OptType(fullType ty) + | Ast.UniqueType(ty) -> Ast.UniqueType(fullType ty)) in + ftfn all_functions k ft + + and typeC ty = + let k ty = + Ast.rewrap ty + (match Ast.unwrap ty with + Ast.BaseType(ty,sgn) -> + Ast.BaseType (base_mcode ty,get_option sign_mcode sgn) + | Ast.ImplicitInt(sgn) -> Ast.ImplicitInt (sign_mcode sgn) + | Ast.Pointer(ty,star) -> + Ast.Pointer (fullType ty, string_mcode star) + | Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> + Ast.FunctionPointer(fullType ty,string_mcode lp1,string_mcode star, + string_mcode rp1,string_mcode lp2, + parameter_dots params, + string_mcode rp2) + | Ast.FunctionType(allminus,ty,lp,params,rp) -> + Ast.FunctionType(allminus,get_option fullType ty,string_mcode lp, + parameter_dots params,string_mcode rp) + | Ast.Array(ty,lb,size,rb) -> + Ast.Array(fullType ty, string_mcode lb, + get_option expression size, string_mcode rb) + | Ast.StructUnionName(kind,name) -> + Ast.StructUnionName (struct_mcode kind, get_option ident name) + | Ast.StructUnionDef(ty,lb,decls,rb) -> + Ast.StructUnionDef (fullType ty, + string_mcode lb, declaration_dots decls, + string_mcode rb) + | Ast.TypeName(name) -> Ast.TypeName(string_mcode name) + | Ast.MetaType(name,keep,inherited) -> + Ast.MetaType(meta_mcode name,keep,inherited)) in + tyfn all_functions k ty + + and declaration d = + let k d = + Ast.rewrap d + (match Ast.unwrap d with + Ast.Init(stg,ty,id,eq,ini,sem) -> + Ast.Init(get_option storage_mcode stg, fullType ty, ident id, + string_mcode eq, initialiser ini, string_mcode sem) + | Ast.UnInit(stg,ty,id,sem) -> + Ast.UnInit(get_option storage_mcode stg, fullType ty, ident id, + string_mcode sem) + | Ast.MacroDecl(name,lp,args,rp,sem) -> + Ast.MacroDecl(ident name, string_mcode lp, expression_dots args, + string_mcode rp,string_mcode sem) + | Ast.TyDecl(ty,sem) -> Ast.TyDecl(fullType ty, string_mcode sem) + | Ast.Typedef(stg,ty,id,sem) -> + Ast.Typedef(string_mcode stg, fullType ty, typeC id, + string_mcode sem) + | Ast.DisjDecl(decls) -> Ast.DisjDecl(List.map declaration decls) + | Ast.Ddots(dots,whencode) -> + Ast.Ddots(string_mcode dots, get_option declaration whencode) + | Ast.MetaDecl(name,keep,inherited) -> + Ast.MetaDecl(meta_mcode name,keep,inherited) + | Ast.OptDecl(decl) -> Ast.OptDecl(declaration decl) + | Ast.UniqueDecl(decl) -> Ast.UniqueDecl(declaration decl)) in + declfn all_functions k d + + and initialiser i = + let k i = + Ast.rewrap i + (match Ast.unwrap i with + Ast.InitExpr(exp) -> Ast.InitExpr(expression exp) + | Ast.InitList(lb,initlist,rb,whencode) -> + Ast.InitList(string_mcode lb, List.map initialiser initlist, + string_mcode rb, List.map initialiser whencode) + | Ast.InitGccDotName(dot,name,eq,ini) -> + Ast.InitGccDotName + (string_mcode dot, ident name, string_mcode eq, initialiser ini) + | Ast.InitGccName(name,eq,ini) -> + Ast.InitGccName(ident name, string_mcode eq, initialiser ini) + | Ast.InitGccIndex(lb,exp,rb,eq,ini) -> + Ast.InitGccIndex + (string_mcode lb, expression exp, string_mcode rb, + string_mcode eq, initialiser ini) + | Ast.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini) -> + Ast.InitGccRange + (string_mcode lb, expression exp1, string_mcode dots, + expression exp2, string_mcode rb, string_mcode eq, + initialiser ini) + | Ast.IComma(cm) -> Ast.IComma(string_mcode cm) + | Ast.OptIni(i) -> Ast.OptIni(initialiser i) + | Ast.UniqueIni(i) -> Ast.UniqueIni(initialiser i)) in + initfn all_functions k i + + and parameterTypeDef p = + let k p = + Ast.rewrap p + (match Ast.unwrap p with + Ast.VoidParam(ty) -> Ast.VoidParam(fullType ty) + | Ast.Param(ty,id) -> Ast.Param(fullType ty, get_option ident id) + | Ast.MetaParam(name,keep,inherited) -> + Ast.MetaParam(meta_mcode name,keep,inherited) + | Ast.MetaParamList(name,lenname_inh,keep,inherited) -> + Ast.MetaParamList(meta_mcode name,lenname_inh,keep,inherited) + | Ast.PComma(cm) -> Ast.PComma(string_mcode cm) + | Ast.Pdots(dots) -> Ast.Pdots(string_mcode dots) + | Ast.Pcircles(dots) -> Ast.Pcircles(string_mcode dots) + | Ast.OptParam(param) -> Ast.OptParam(parameterTypeDef param) + | Ast.UniqueParam(param) -> Ast.UniqueParam(parameterTypeDef param)) in + paramfn all_functions k p + + and rule_elem re = + let k re = + Ast.rewrap re + (match Ast.unwrap re with + Ast.FunHeader(bef,allminus,fi,name,lp,params,rp) -> + Ast.FunHeader(bef,allminus,List.map fninfo fi,ident name, + string_mcode lp, parameter_dots params, + string_mcode rp) + | Ast.Decl(bef,allminus,decl) -> + Ast.Decl(bef,allminus,declaration decl) + | Ast.SeqStart(brace) -> Ast.SeqStart(string_mcode brace) + | Ast.SeqEnd(brace) -> Ast.SeqEnd(string_mcode brace) + | Ast.ExprStatement(exp,sem) -> + Ast.ExprStatement (expression exp, string_mcode sem) + | Ast.IfHeader(iff,lp,exp,rp) -> + Ast.IfHeader(string_mcode iff, string_mcode lp, expression exp, + string_mcode rp) + | Ast.Else(els) -> Ast.Else(string_mcode els) + | Ast.WhileHeader(whl,lp,exp,rp) -> + Ast.WhileHeader(string_mcode whl, string_mcode lp, expression exp, + string_mcode rp) + | Ast.DoHeader(d) -> Ast.DoHeader(string_mcode d) + | Ast.WhileTail(whl,lp,exp,rp,sem) -> + Ast.WhileTail(string_mcode whl, string_mcode lp, expression exp, + string_mcode rp, string_mcode sem) + | Ast.ForHeader(fr,lp,e1,sem1,e2,sem2,e3,rp) -> + Ast.ForHeader(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) + | Ast.IteratorHeader(whl,lp,args,rp) -> + Ast.IteratorHeader(ident whl, string_mcode lp, + expression_dots args, string_mcode rp) + | Ast.SwitchHeader(switch,lp,exp,rp) -> + Ast.SwitchHeader(string_mcode switch, string_mcode lp, + expression exp, string_mcode rp) + | Ast.Break(br,sem) -> + Ast.Break(string_mcode br, string_mcode sem) + | Ast.Continue(cont,sem) -> + Ast.Continue(string_mcode cont, string_mcode sem) + | Ast.Label(l,dd) -> Ast.Label(ident l, string_mcode dd) + | Ast.Goto(goto,l,sem) -> + Ast.Goto(string_mcode goto,ident l,string_mcode sem) + | Ast.Return(ret,sem) -> + Ast.Return(string_mcode ret, string_mcode sem) + | Ast.ReturnExpr(ret,exp,sem) -> + Ast.ReturnExpr(string_mcode ret, expression exp, string_mcode sem) + | Ast.MetaStmt(name,keep,seqible,inherited) -> + Ast.MetaStmt(meta_mcode name,keep,seqible,inherited) + | Ast.MetaStmtList(name,keep,inherited) -> + Ast.MetaStmtList(meta_mcode name,keep,inherited) + | Ast.MetaRuleElem(name,keep,inherited) -> + Ast.MetaRuleElem(meta_mcode name,keep,inherited) + | Ast.Exp(exp) -> Ast.Exp(expression exp) + | Ast.TopExp(exp) -> Ast.TopExp(expression exp) + | Ast.Ty(ty) -> Ast.Ty(fullType ty) + | Ast.Include(inc,name) -> + Ast.Include(string_mcode inc,inc_file_mcode name) + | Ast.DefineHeader(def,id,params) -> + Ast.DefineHeader(string_mcode def,ident id, + define_parameters params) + | Ast.Default(def,colon) -> + Ast.Default(string_mcode def,string_mcode colon) + | Ast.Case(case,exp,colon) -> + Ast.Case(string_mcode case,expression exp,string_mcode colon) + | Ast.DisjRuleElem(res) -> Ast.DisjRuleElem(List.map rule_elem res)) in + rulefn all_functions k re + + (* not parameterizable for now... *) + and define_parameters p = + let k p = + Ast.rewrap p + (match Ast.unwrap p with + Ast.NoParams -> Ast.NoParams + | Ast.DParams(lp,params,rp) -> + Ast.DParams(string_mcode lp,define_param_dots params, + string_mcode rp)) in + k p + + and define_param_dots d = + let k d = + Ast.rewrap d + (match Ast.unwrap d with + Ast.DOTS(l) -> Ast.DOTS(List.map define_param l) + | Ast.CIRCLES(l) -> Ast.CIRCLES(List.map define_param l) + | Ast.STARS(l) -> Ast.STARS(List.map define_param l)) in + k d + + and define_param p = + let k p = + Ast.rewrap p + (match Ast.unwrap p with + Ast.DParam(id) -> Ast.DParam(ident id) + | Ast.DPComma(comma) -> Ast.DPComma(string_mcode comma) + | Ast.DPdots(d) -> Ast.DPdots(string_mcode d) + | Ast.DPcircles(c) -> Ast.DPcircles(string_mcode c) + | Ast.OptDParam(dp) -> Ast.OptDParam(define_param dp) + | Ast.UniqueDParam(dp) -> Ast.UniqueDParam(define_param dp)) in + k p + + and process_bef_aft s = + Ast.set_dots_bef_aft + (match Ast.get_dots_bef_aft s with + Ast.NoDots -> Ast.NoDots + | Ast.DroppingBetweenDots(stm,ind) -> + Ast.DroppingBetweenDots(statement stm,ind) + | Ast.AddingBetweenDots(stm,ind) -> + Ast.AddingBetweenDots(statement stm,ind)) + s + + and statement s = + let k s = + Ast.rewrap s + (match Ast.unwrap s with + Ast.Seq(lbrace,decls,body,rbrace) -> + Ast.Seq(rule_elem lbrace, statement_dots decls, + statement_dots body, rule_elem rbrace) + | Ast.IfThen(header,branch,aft) -> + Ast.IfThen(rule_elem header, statement branch,aft) + | Ast.IfThenElse(header,branch1,els,branch2,aft) -> + Ast.IfThenElse(rule_elem header, statement branch1, rule_elem els, + statement branch2, aft) + | Ast.While(header,body,aft) -> + Ast.While(rule_elem header, statement body, aft) + | Ast.Do(header,body,tail) -> + Ast.Do(rule_elem header, statement body, rule_elem tail) + | Ast.For(header,body,aft) -> + Ast.For(rule_elem header, statement body, aft) + | Ast.Iterator(header,body,aft) -> + Ast.Iterator(rule_elem header, statement body, aft) + | Ast.Switch(header,lb,cases,rb) -> + Ast.Switch(rule_elem header,rule_elem lb, + List.map case_line cases,rule_elem rb) + | Ast.Atomic(re) -> Ast.Atomic(rule_elem re) + | Ast.Disj(stmt_dots_list) -> + Ast.Disj (List.map statement_dots stmt_dots_list) + | Ast.Nest(stmt_dots,whn,multi,bef,aft) -> + Ast.Nest(statement_dots stmt_dots, + List.map (whencode statement_dots statement) whn, + multi,bef,aft) + | Ast.FunDecl(header,lbrace,decls,body,rbrace) -> + Ast.FunDecl(rule_elem header,rule_elem lbrace, + statement_dots decls, + statement_dots body, rule_elem rbrace) + | Ast.Define(header,body) -> + Ast.Define(rule_elem header,statement_dots body) + | Ast.Dots(d,whn,bef,aft) -> + Ast.Dots(string_mcode d, + List.map (whencode statement_dots statement) whn,bef,aft) + | Ast.Circles(d,whn,bef,aft) -> + Ast.Circles(string_mcode d, + List.map (whencode statement_dots statement) whn, + bef,aft) + | Ast.Stars(d,whn,bef,aft) -> + Ast.Stars(string_mcode d, + List.map (whencode statement_dots statement) whn,bef,aft) + | Ast.OptStm(stmt) -> Ast.OptStm(statement stmt) + | Ast.UniqueStm(stmt) -> Ast.UniqueStm(statement stmt)) in + let s = stmtfn all_functions k s in + (* better to do this after, in case there is an equality test on the whole + statement, eg in free_vars. equality test would require that this + subterm not already be changed *) + process_bef_aft s + + and fninfo = function + Ast.FStorage(stg) -> Ast.FStorage(storage_mcode stg) + | Ast.FType(ty) -> Ast.FType(fullType ty) + | Ast.FInline(inline) -> Ast.FInline(string_mcode inline) + | Ast.FAttr(attr) -> Ast.FAttr(string_mcode attr) + + and whencode notfn alwaysfn = function + Ast.WhenNot a -> Ast.WhenNot (notfn a) + | Ast.WhenAlways a -> Ast.WhenAlways (alwaysfn a) + | Ast.WhenModifier(x) -> Ast.WhenModifier(x) + + and case_line c = + let k c = + Ast.rewrap c + (match Ast.unwrap c with + Ast.CaseLine(header,code) -> + Ast.CaseLine(rule_elem header,statement_dots code) + | Ast.OptCase(case) -> Ast.OptCase(case_line case)) in + casefn all_functions k c + + and top_level t = + let k t = + Ast.rewrap t + (match Ast.unwrap t with + Ast.FILEINFO(old_file,new_file) -> + Ast.FILEINFO (string_mcode old_file, string_mcode new_file) + | Ast.DECL(stmt) -> Ast.DECL(statement stmt) + | Ast.CODE(stmt_dots) -> Ast.CODE(statement_dots stmt_dots) + | Ast.ERRORWORDS(exps) -> Ast.ERRORWORDS (List.map expression exps)) in + topfn all_functions k t + + and anything a = + let k = function + (*in many cases below, the thing is not even mcode, so we do nothing*) + Ast.FullTypeTag(ft) -> Ast.FullTypeTag(fullType ft) + | Ast.BaseTypeTag(bt) as x -> x + | Ast.StructUnionTag(su) as x -> x + | Ast.SignTag(sgn) as x -> x + | Ast.IdentTag(id) -> Ast.IdentTag(ident id) + | Ast.ExpressionTag(exp) -> Ast.ExpressionTag(expression exp) + | Ast.ConstantTag(cst) as x -> x + | Ast.UnaryOpTag(unop) as x -> x + | Ast.AssignOpTag(asgnop) as x -> x + | Ast.FixOpTag(fixop) as x -> x + | Ast.BinaryOpTag(binop) as x -> x + | Ast.ArithOpTag(arithop) as x -> x + | Ast.LogicalOpTag(logop) as x -> x + | Ast.InitTag(decl) -> Ast.InitTag(initialiser decl) + | Ast.DeclarationTag(decl) -> Ast.DeclarationTag(declaration decl) + | Ast.StorageTag(stg) as x -> x + | Ast.IncFileTag(stg) as x -> x + | Ast.Rule_elemTag(rule) -> Ast.Rule_elemTag(rule_elem rule) + | Ast.StatementTag(rule) -> Ast.StatementTag(statement rule) + | Ast.CaseLineTag(case) -> Ast.CaseLineTag(case_line case) + | Ast.ConstVolTag(cv) as x -> x + | Ast.Token(tok,info) as x -> x + | Ast.Code(cd) -> Ast.Code(top_level cd) + | Ast.ExprDotsTag(ed) -> Ast.ExprDotsTag(expression_dots ed) + | Ast.ParamDotsTag(pd) -> Ast.ParamDotsTag(parameter_dots pd) + | Ast.StmtDotsTag(sd) -> Ast.StmtDotsTag(statement_dots sd) + | Ast.DeclDotsTag(sd) -> Ast.DeclDotsTag(declaration_dots sd) + | Ast.TypeCTag(ty) -> Ast.TypeCTag(typeC ty) + | Ast.ParamTag(param) -> Ast.ParamTag(parameterTypeDef param) + | Ast.SgrepStartTag(tok) as x -> x + | Ast.SgrepEndTag(tok) as x -> x in + anyfn all_functions k a + + and all_functions = + {rebuilder_ident = ident; + rebuilder_expression = expression; + rebuilder_fullType= fullType; + rebuilder_typeC = typeC; + rebuilder_declaration = declaration; + rebuilder_initialiser = initialiser; + rebuilder_parameter = parameterTypeDef; + rebuilder_parameter_list = parameter_dots; + rebuilder_rule_elem = rule_elem; + 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_define_param_dots = define_param_dots; + rebuilder_define_param = define_param; + rebuilder_define_parameters = define_parameters; + rebuilder_anything = anything} in + all_functions + diff --git a/parsing_cocci/.#visitor_ast.ml.1.90 b/parsing_cocci/.#visitor_ast.ml.1.90 new file mode 100644 index 0000000..6ac86e5 --- /dev/null +++ b/parsing_cocci/.#visitor_ast.ml.1.90 @@ -0,0 +1,1052 @@ +(* +* 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 + +(* --------------------------------------------------------------------- *) +(* Generic traversal: combiner *) +(* parameters: + combining function + treatment of: mcode, identifiers, expressions, fullTypes, types, + declarations, statements, toplevels + default value for options *) + +type 'a combiner = + {combiner_ident : Ast.ident -> 'a; + combiner_expression : Ast.expression -> 'a; + combiner_fullType : Ast.fullType -> 'a; + combiner_typeC : Ast.typeC -> 'a; + combiner_declaration : Ast.declaration -> 'a; + combiner_initialiser : Ast.initialiser -> 'a; + combiner_parameter : Ast.parameterTypeDef -> 'a; + combiner_parameter_list : Ast.parameter_list -> 'a; + combiner_rule_elem : Ast.rule_elem -> 'a; + combiner_statement : Ast.statement -> 'a; + combiner_case_line : Ast.case_line -> 'a; + combiner_top_level : Ast.top_level -> 'a; + combiner_anything : Ast.anything -> 'a; + combiner_expression_dots : Ast.expression Ast.dots -> 'a; + combiner_statement_dots : Ast.statement Ast.dots -> 'a; + combiner_declaration_dots : Ast.declaration Ast.dots -> 'a} + +type ('mc,'a) cmcode = 'a combiner -> 'mc Ast_cocci.mcode -> 'a +type ('cd,'a) ccode = 'a combiner -> ('cd -> 'a) -> 'cd -> 'a + + +let combiner bind option_default + meta_mcodefn string_mcodefn const_mcodefn assign_mcodefn fix_mcodefn + unary_mcodefn binary_mcodefn + cv_mcodefn base_mcodefn sign_mcodefn struct_mcodefn storage_mcodefn + inc_file_mcodefn + expdotsfn paramdotsfn stmtdotsfn decldotsfn + identfn exprfn ftfn tyfn initfn paramfn declfn rulefn stmtfn casefn + topfn anyfn = + 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 meta_mcode x = meta_mcodefn all_functions x + and string_mcode x = string_mcodefn all_functions x + and const_mcode x = const_mcodefn all_functions x + and assign_mcode x = assign_mcodefn all_functions x + and fix_mcode x = fix_mcodefn all_functions x + and unary_mcode x = unary_mcodefn all_functions x + and binary_mcode x = binary_mcodefn all_functions x + and cv_mcode x = cv_mcodefn all_functions x + and base_mcode x = base_mcodefn all_functions x + and sign_mcode x = sign_mcodefn all_functions x + and struct_mcode x = struct_mcodefn all_functions x + and storage_mcode x = storage_mcodefn all_functions x + and inc_file_mcode x = inc_file_mcodefn all_functions x + + and expression_dots d = + let k d = + match Ast.unwrap d with + Ast.DOTS(l) | Ast.CIRCLES(l) | Ast.STARS(l) -> + multibind (List.map expression l) in + expdotsfn all_functions k d + + and parameter_dots d = + let k d = + match Ast.unwrap d with + Ast.DOTS(l) | Ast.CIRCLES(l) | Ast.STARS(l) -> + multibind (List.map parameterTypeDef l) in + paramdotsfn all_functions k d + + and statement_dots d = + let k d = + match Ast.unwrap d with + Ast.DOTS(l) | Ast.CIRCLES(l) | Ast.STARS(l) -> + multibind (List.map statement l) in + stmtdotsfn all_functions k d + + and declaration_dots d = + let k d = + match Ast.unwrap d with + Ast.DOTS(l) | Ast.CIRCLES(l) | Ast.STARS(l) -> + multibind (List.map declaration l) in + decldotsfn all_functions k d + + and ident i = + let k i = + match Ast.unwrap i with + Ast.Id(name) -> string_mcode name + | Ast.MetaId(name,_,_,_) -> meta_mcode name + | Ast.MetaFunc(name,_,_,_) -> meta_mcode name + | Ast.MetaLocalFunc(name,_,_,_) -> meta_mcode name + | Ast.OptIdent(id) -> ident id + | Ast.UniqueIdent(id) -> ident id in + identfn all_functions k i + + and expression e = + let k e = + match Ast.unwrap e with + Ast.Ident(id) -> ident id + | Ast.Constant(const) -> const_mcode const + | Ast.FunCall(fn,lp,args,rp) -> + multibind [expression fn; string_mcode lp; expression_dots args; + string_mcode rp] + | Ast.Assignment(left,op,right,simple) -> + multibind [expression left; assign_mcode op; expression right] + | Ast.CondExpr(exp1,why,exp2,colon,exp3) -> + multibind [expression exp1; string_mcode why; + get_option expression exp2; string_mcode colon; + expression exp3] + | Ast.Postfix(exp,op) -> bind (expression exp) (fix_mcode op) + | Ast.Infix(exp,op) -> bind (fix_mcode op) (expression exp) + | Ast.Unary(exp,op) -> bind (unary_mcode op) (expression exp) + | Ast.Binary(left,op,right) -> + multibind [expression left; binary_mcode op; expression right] + | Ast.Nested(left,op,right) -> + multibind [expression left; binary_mcode op; expression right] + | Ast.Paren(lp,exp,rp) -> + multibind [string_mcode lp; expression exp; string_mcode rp] + | Ast.ArrayAccess(exp1,lb,exp2,rb) -> + multibind + [expression exp1; string_mcode lb; expression exp2; + string_mcode rb] + | Ast.RecordAccess(exp,pt,field) -> + multibind [expression exp; string_mcode pt; ident field] + | Ast.RecordPtAccess(exp,ar,field) -> + multibind [expression exp; string_mcode ar; ident field] + | Ast.Cast(lp,ty,rp,exp) -> + multibind + [string_mcode lp; fullType ty; string_mcode rp; expression exp] + | Ast.SizeOfExpr(szf,exp) -> + multibind [string_mcode szf; expression exp] + | Ast.SizeOfType(szf,lp,ty,rp) -> + multibind + [string_mcode szf; string_mcode lp; fullType ty; string_mcode rp] + | Ast.TypeExp(ty) -> fullType ty + | Ast.MetaErr(name,_,_,_) + | Ast.MetaExpr(name,_,_,_,_,_) + | Ast.MetaExprList(name,_,_,_) -> meta_mcode name + | Ast.EComma(cm) -> string_mcode cm + | Ast.DisjExpr(exp_list) -> multibind (List.map expression exp_list) + | Ast.NestExpr(expr_dots,whencode,multi) -> + bind (expression_dots expr_dots) (get_option expression whencode) + | Ast.Edots(dots,whencode) | Ast.Ecircles(dots,whencode) + | Ast.Estars(dots,whencode) -> + bind (string_mcode dots) (get_option expression whencode) + | Ast.OptExp(exp) | Ast.UniqueExp(exp) -> + expression exp in + exprfn all_functions k e + + and fullType ft = + let k ft = + match Ast.unwrap ft with + Ast.Type(cv,ty) -> bind (get_option cv_mcode cv) (typeC ty) + | Ast.DisjType(types) -> multibind (List.map fullType types) + | Ast.OptType(ty) -> fullType ty + | Ast.UniqueType(ty) -> fullType ty in + ftfn all_functions k ft + + and function_pointer (ty,lp1,star,rp1,lp2,params,rp2) extra = + (* have to put the treatment of the identifier into the right position *) + multibind + ([fullType 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 fullType ty] @ extra @ + [string_mcode lp1; parameter_dots params; string_mcode rp1]) + + and array_type (ty,lb,size,rb) extra = + multibind + ([fullType ty] @ extra @ + [string_mcode lb; get_option expression size; string_mcode rb]) + + and typeC ty = + let k ty = + match Ast.unwrap ty with + Ast.BaseType(ty,sgn) -> + bind (get_option sign_mcode sgn) (base_mcode ty) + | Ast.ImplicitInt(sgn) -> sign_mcode sgn + | Ast.Pointer(ty,star) -> + bind (fullType ty) (string_mcode star) + | Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> + function_pointer (ty,lp1,star,rp1,lp2,params,rp2) [] + | Ast.FunctionType (_,ty,lp1,params,rp1) -> + function_type (ty,lp1,params,rp1) [] + | Ast.Array(ty,lb,size,rb) -> array_type (ty,lb,size,rb) [] + | Ast.StructUnionName(kind,name) -> + bind (struct_mcode kind) (get_option ident name) + | Ast.StructUnionDef(ty,lb,decls,rb) -> + multibind + [fullType ty; string_mcode lb; declaration_dots decls; + string_mcode rb] + | Ast.TypeName(name) -> string_mcode name + | Ast.MetaType(name,_,_) -> meta_mcode name in + tyfn all_functions k ty + + and named_type ty id = + match Ast.unwrap ty with + Ast.Type(None,ty1) -> + (match Ast.unwrap ty1 with + Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> + function_pointer (ty,lp1,star,rp1,lp2,params,rp2) [ident id] + | Ast.FunctionType(_,ty,lp1,params,rp1) -> + function_type (ty,lp1,params,rp1) [ident id] + | Ast.Array(ty,lb,size,rb) -> array_type (ty,lb,size,rb) [ident id] + | _ -> bind (fullType ty) (ident id)) + | _ -> bind (fullType ty) (ident id) + + and declaration d = + let k d = + match Ast.unwrap d with + Ast.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])) + | Ast.UnInit(stg,ty,id,sem) -> + bind (get_option storage_mcode stg) + (bind (named_type ty id) (string_mcode sem)) + | Ast.MacroDecl(name,lp,args,rp,sem) -> + multibind + [ident name; string_mcode lp; expression_dots args; + string_mcode rp; string_mcode sem] + | Ast.TyDecl(ty,sem) -> bind (fullType ty) (string_mcode sem) + | Ast.Typedef(stg,ty,id,sem) -> + bind (string_mcode stg) + (bind (fullType ty) (bind (typeC id) (string_mcode sem))) + | Ast.DisjDecl(decls) -> multibind (List.map declaration decls) + | Ast.Ddots(dots,whencode) -> + bind (string_mcode dots) (get_option declaration whencode) + | Ast.MetaDecl(name,_,_) -> meta_mcode name + | Ast.OptDecl(decl) -> declaration decl + | Ast.UniqueDecl(decl) -> declaration decl in + declfn all_functions k d + + and initialiser i = + let k i = + match Ast.unwrap i with + Ast.InitExpr(exp) -> expression exp + | Ast.InitList(lb,initlist,rb,whencode) -> + multibind + [string_mcode lb; + multibind (List.map initialiser initlist); + string_mcode rb; + multibind (List.map initialiser whencode)] + | Ast.InitGccDotName(dot,name,eq,ini) -> + multibind + [string_mcode dot; ident name; string_mcode eq; initialiser ini] + | Ast.InitGccName(name,eq,ini) -> + multibind [ident name; string_mcode eq; initialiser ini] + | Ast.InitGccIndex(lb,exp,rb,eq,ini) -> + multibind + [string_mcode lb; expression exp; string_mcode rb; + string_mcode eq; initialiser ini] + | Ast.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] + | Ast.IComma(cm) -> string_mcode cm + | Ast.OptIni(i) -> initialiser i + | Ast.UniqueIni(i) -> initialiser i in + initfn all_functions k i + + and parameterTypeDef p = + let k p = + match Ast.unwrap p with + Ast.VoidParam(ty) -> fullType ty + | Ast.Param(ty,Some id) -> named_type ty id + | Ast.Param(ty,None) -> fullType ty + | Ast.MetaParam(name,_,_) -> meta_mcode name + | Ast.MetaParamList(name,_,_,_) -> meta_mcode name + | Ast.PComma(cm) -> string_mcode cm + | Ast.Pdots(dots) -> string_mcode dots + | Ast.Pcircles(dots) -> string_mcode dots + | Ast.OptParam(param) -> parameterTypeDef param + | Ast.UniqueParam(param) -> parameterTypeDef param in + paramfn all_functions k p + + and rule_elem re = + let k re = + match Ast.unwrap re with + Ast.FunHeader(_,_,fi,name,lp,params,rp) -> + multibind + ((List.map fninfo fi) @ + [ident name;string_mcode lp;parameter_dots params; + string_mcode rp]) + | Ast.Decl(_,_,decl) -> declaration decl + | Ast.SeqStart(brace) -> string_mcode brace + | Ast.SeqEnd(brace) -> string_mcode brace + | Ast.ExprStatement(exp,sem) -> + bind (expression exp) (string_mcode sem) + | Ast.IfHeader(iff,lp,exp,rp) -> + multibind [string_mcode iff; string_mcode lp; expression exp; + string_mcode rp] + | Ast.Else(els) -> string_mcode els + | Ast.WhileHeader(whl,lp,exp,rp) -> + multibind [string_mcode whl; string_mcode lp; expression exp; + string_mcode rp] + | Ast.DoHeader(d) -> string_mcode d + | Ast.WhileTail(whl,lp,exp,rp,sem) -> + multibind [string_mcode whl; string_mcode lp; expression exp; + string_mcode rp; string_mcode sem] + | Ast.ForHeader(fr,lp,e1,sem1,e2,sem2,e3,rp) -> + 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] + | Ast.IteratorHeader(nm,lp,args,rp) -> + multibind [ident nm; string_mcode lp; + expression_dots args; string_mcode rp] + | Ast.SwitchHeader(switch,lp,exp,rp) -> + multibind [string_mcode switch; string_mcode lp; expression exp; + string_mcode rp] + | Ast.Break(br,sem) -> bind (string_mcode br) (string_mcode sem) + | Ast.Continue(cont,sem) -> bind (string_mcode cont) (string_mcode sem) + | Ast.Label(l,dd) -> bind (ident l) (string_mcode dd) + | Ast.Goto(goto,l,sem) -> + bind (string_mcode goto) (bind (ident l) (string_mcode sem)) + | Ast.Return(ret,sem) -> bind (string_mcode ret) (string_mcode sem) + | Ast.ReturnExpr(ret,exp,sem) -> + multibind [string_mcode ret; expression exp; string_mcode sem] + | Ast.MetaStmt(name,_,_,_) -> meta_mcode name + | Ast.MetaStmtList(name,_,_) -> meta_mcode name + | Ast.MetaRuleElem(name,_,_) -> meta_mcode name + | Ast.Exp(exp) -> expression exp + | Ast.TopExp(exp) -> expression exp + | Ast.Ty(ty) -> fullType ty + | Ast.Include(inc,name) -> bind (string_mcode inc) (inc_file_mcode name) + | Ast.DefineHeader(def,id,params) -> + multibind [string_mcode def; ident id; define_parameters params] + | Ast.Default(def,colon) -> bind (string_mcode def) (string_mcode colon) + | Ast.Case(case,exp,colon) -> + multibind [string_mcode case; expression exp; string_mcode colon] + | Ast.DisjRuleElem(res) -> multibind (List.map rule_elem res) in + rulefn all_functions k re + + (* not parameterizable for now... *) + and define_parameters p = + let k p = + match Ast.unwrap p with + Ast.NoParams -> option_default + | Ast.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 Ast.unwrap d with + Ast.DOTS(l) | Ast.CIRCLES(l) | Ast.STARS(l) -> + multibind (List.map define_param l) in + k d + + and define_param p = + let k p = + match Ast.unwrap p with + Ast.DParam(id) -> ident id + | Ast.DPComma(comma) -> string_mcode comma + | Ast.DPdots(d) -> string_mcode d + | Ast.DPcircles(c) -> string_mcode c + | Ast.OptDParam(dp) -> define_param dp + | Ast.UniqueDParam(dp) -> define_param dp in + k p + + (* discard the result, because the statement is assumed to be already + represented elsewhere in the code *) + and process_bef_aft s = + match Ast.get_dots_bef_aft s with + Ast.NoDots -> () + | Ast.DroppingBetweenDots(stm,ind) -> let _ = statement stm in () + | Ast.AddingBetweenDots(stm,ind) -> let _ = statement stm in () + + and statement s = + process_bef_aft s; + let k s = + match Ast.unwrap s with + Ast.Seq(lbrace,decls,body,rbrace) -> + multibind [rule_elem lbrace; statement_dots decls; + statement_dots body; rule_elem rbrace] + | Ast.IfThen(header,branch,_) -> + multibind [rule_elem header; statement branch] + | Ast.IfThenElse(header,branch1,els,branch2,_) -> + multibind [rule_elem header; statement branch1; rule_elem els; + statement branch2] + | Ast.While(header,body,_) -> + multibind [rule_elem header; statement body] + | Ast.Do(header,body,tail) -> + multibind [rule_elem header; statement body; rule_elem tail] + | Ast.For(header,body,_) -> multibind [rule_elem header; statement body] + | Ast.Iterator(header,body,_) -> + multibind [rule_elem header; statement body] + | Ast.Switch(header,lb,cases,rb) -> + multibind [rule_elem header;rule_elem lb; + multibind (List.map case_line cases); + rule_elem rb] + | Ast.Atomic(re) -> rule_elem re + | Ast.Disj(stmt_dots_list) -> + multibind (List.map statement_dots stmt_dots_list) + | Ast.Nest(stmt_dots,whn,_,_,_) -> + bind (statement_dots stmt_dots) + (multibind (List.map (whencode statement_dots statement) whn)) + | Ast.FunDecl(header,lbrace,decls,body,rbrace) -> + multibind [rule_elem header; rule_elem lbrace; + statement_dots decls; statement_dots body; + rule_elem rbrace] + | Ast.Define(header,body) -> + bind (rule_elem header) (statement_dots body) + | Ast.Dots(d,whn,_,_) | Ast.Circles(d,whn,_,_) | Ast.Stars(d,whn,_,_) -> + bind (string_mcode d) + (multibind (List.map (whencode statement_dots statement) whn)) + | Ast.OptStm(stmt) | Ast.UniqueStm(stmt) -> + statement stmt in + stmtfn all_functions k s + + and fninfo = function + Ast.FStorage(stg) -> storage_mcode stg + | Ast.FType(ty) -> fullType ty + | Ast.FInline(inline) -> string_mcode inline + | Ast.FAttr(attr) -> string_mcode attr + + and whencode notfn alwaysfn = function + Ast.WhenNot a -> notfn a + | Ast.WhenAlways a -> alwaysfn a + | Ast.WhenModifier(_) -> option_default + | Ast.WhenNotTrue(e) -> rule_elem e + | Ast.WhenNotFalse(e) -> rule_elem e + + and case_line c = + let k c = + match Ast.unwrap c with + Ast.CaseLine(header,code) -> + bind (rule_elem header) (statement_dots code) + | Ast.OptCase(case) -> case_line case in + casefn all_functions k c + + and top_level t = + let k t = + match Ast.unwrap t with + Ast.FILEINFO(old_file,new_file) -> + bind (string_mcode old_file) (string_mcode new_file) + | Ast.DECL(stmt) -> statement stmt + | Ast.CODE(stmt_dots) -> statement_dots stmt_dots + | Ast.ERRORWORDS(exps) -> multibind (List.map expression exps) in + topfn all_functions k t + + and anything a = + let k = function + (*in many cases below, the thing is not even mcode, so we do nothing*) + Ast.FullTypeTag(ft) -> fullType ft + | Ast.BaseTypeTag(bt) -> option_default + | Ast.StructUnionTag(su) -> option_default + | Ast.SignTag(sgn) -> option_default + | Ast.IdentTag(id) -> ident id + | Ast.ExpressionTag(exp) -> expression exp + | Ast.ConstantTag(cst) -> option_default + | Ast.UnaryOpTag(unop) -> option_default + | Ast.AssignOpTag(asgnop) -> option_default + | Ast.FixOpTag(fixop) -> option_default + | Ast.BinaryOpTag(binop) -> option_default + | Ast.ArithOpTag(arithop) -> option_default + | Ast.LogicalOpTag(logop) -> option_default + | Ast.DeclarationTag(decl) -> declaration decl + | Ast.InitTag(ini) -> initialiser ini + | Ast.StorageTag(stg) -> option_default + | Ast.IncFileTag(stg) -> option_default + | Ast.Rule_elemTag(rule) -> rule_elem rule + | Ast.StatementTag(rule) -> statement rule + | Ast.CaseLineTag(case) -> case_line case + | Ast.ConstVolTag(cv) -> option_default + | Ast.Token(tok,info) -> option_default + | Ast.Code(cd) -> top_level cd + | Ast.ExprDotsTag(ed) -> expression_dots ed + | Ast.ParamDotsTag(pd) -> parameter_dots pd + | Ast.StmtDotsTag(sd) -> statement_dots sd + | Ast.DeclDotsTag(sd) -> declaration_dots sd + | Ast.TypeCTag(ty) -> typeC ty + | Ast.ParamTag(param) -> parameterTypeDef param + | Ast.SgrepStartTag(tok) -> option_default + | Ast.SgrepEndTag(tok) -> option_default in + anyfn all_functions k a + + and all_functions = + {combiner_ident = ident; + combiner_expression = expression; + combiner_fullType = fullType; + combiner_typeC = typeC; + combiner_declaration = declaration; + combiner_initialiser = initialiser; + combiner_parameter = parameterTypeDef; + combiner_parameter_list = parameter_dots; + combiner_rule_elem = rule_elem; + combiner_statement = statement; + combiner_case_line = case_line; + combiner_top_level = top_level; + combiner_anything = anything; + combiner_expression_dots = expression_dots; + combiner_statement_dots = statement_dots; + combiner_declaration_dots = declaration_dots} in + all_functions + +(* ---------------------------------------------------------------------- *) + +type 'a inout = 'a -> 'a (* for specifying the type of rebuilder *) + +type rebuilder = + {rebuilder_ident : Ast.ident inout; + rebuilder_expression : Ast.expression inout; + rebuilder_fullType : Ast.fullType inout; + rebuilder_typeC : Ast.typeC inout; + rebuilder_declaration : Ast.declaration inout; + rebuilder_initialiser : Ast.initialiser inout; + rebuilder_parameter : Ast.parameterTypeDef inout; + rebuilder_parameter_list : Ast.parameter_list inout; + rebuilder_statement : Ast.statement inout; + rebuilder_case_line : Ast.case_line inout; + rebuilder_rule_elem : Ast.rule_elem inout; + rebuilder_top_level : Ast.top_level inout; + rebuilder_expression_dots : Ast.expression Ast.dots inout; + rebuilder_statement_dots : Ast.statement Ast.dots inout; + rebuilder_declaration_dots : Ast.declaration Ast.dots inout; + rebuilder_define_param_dots : Ast.define_param Ast.dots inout; + rebuilder_define_param : Ast.define_param inout; + rebuilder_define_parameters : Ast.define_parameters inout; + rebuilder_anything : Ast.anything inout} + +type 'mc rmcode = 'mc Ast.mcode inout +type 'cd rcode = rebuilder -> ('cd inout) -> 'cd inout + + +let rebuilder + 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_file_mcode + expdotsfn paramdotsfn stmtdotsfn decldotsfn + identfn exprfn ftfn tyfn initfn paramfn declfn rulefn stmtfn casefn + topfn anyfn = + let get_option f = function + Some x -> Some (f x) + | None -> None in + let rec expression_dots d = + let k d = + Ast.rewrap d + (match Ast.unwrap d with + Ast.DOTS(l) -> Ast.DOTS(List.map expression l) + | Ast.CIRCLES(l) -> Ast.CIRCLES(List.map expression l) + | Ast.STARS(l) -> Ast.STARS(List.map expression l)) in + expdotsfn all_functions k d + + and parameter_dots d = + let k d = + Ast.rewrap d + (match Ast.unwrap d with + Ast.DOTS(l) -> Ast.DOTS(List.map parameterTypeDef l) + | Ast.CIRCLES(l) -> Ast.CIRCLES(List.map parameterTypeDef l) + | Ast.STARS(l) -> Ast.STARS(List.map parameterTypeDef l)) in + paramdotsfn all_functions k d + + and statement_dots d = + let k d = + Ast.rewrap d + (match Ast.unwrap d with + Ast.DOTS(l) -> Ast.DOTS(List.map statement l) + | Ast.CIRCLES(l) -> Ast.CIRCLES(List.map statement l) + | Ast.STARS(l) -> Ast.STARS(List.map statement l)) in + stmtdotsfn all_functions k d + + and declaration_dots d = + let k d = + Ast.rewrap d + (match Ast.unwrap d with + Ast.DOTS(l) -> Ast.DOTS(List.map declaration l) + | Ast.CIRCLES(l) -> Ast.CIRCLES(List.map declaration l) + | Ast.STARS(l) -> Ast.STARS(List.map declaration l)) in + decldotsfn all_functions k d + + and ident i = + let k i = + Ast.rewrap i + (match Ast.unwrap i with + Ast.Id(name) -> Ast.Id(string_mcode name) + | Ast.MetaId(name,constraints,keep,inherited) -> + Ast.MetaId(meta_mcode name,constraints,keep,inherited) + | Ast.MetaFunc(name,constraints,keep,inherited) -> + Ast.MetaFunc(meta_mcode name,constraints,keep,inherited) + | Ast.MetaLocalFunc(name,constraints,keep,inherited) -> + Ast.MetaLocalFunc(meta_mcode name,constraints,keep,inherited) + | Ast.OptIdent(id) -> Ast.OptIdent(ident id) + | Ast.UniqueIdent(id) -> Ast.UniqueIdent(ident id)) in + identfn all_functions k i + + and expression e = + let k e = + Ast.rewrap e + (match Ast.unwrap e with + Ast.Ident(id) -> Ast.Ident(ident id) + | Ast.Constant(const) -> Ast.Constant(const_mcode const) + | Ast.FunCall(fn,lp,args,rp) -> + Ast.FunCall(expression fn, string_mcode lp, expression_dots args, + string_mcode rp) + | Ast.Assignment(left,op,right,simple) -> + Ast.Assignment(expression left, assign_mcode op, expression right, + simple) + | Ast.CondExpr(exp1,why,exp2,colon,exp3) -> + Ast.CondExpr(expression exp1, string_mcode why, + get_option expression exp2, string_mcode colon, + expression exp3) + | Ast.Postfix(exp,op) -> Ast.Postfix(expression exp,fix_mcode op) + | Ast.Infix(exp,op) -> Ast.Infix(expression exp,fix_mcode op) + | Ast.Unary(exp,op) -> Ast.Unary(expression exp,unary_mcode op) + | Ast.Binary(left,op,right) -> + Ast.Binary(expression left, binary_mcode op, expression right) + | Ast.Nested(left,op,right) -> + Ast.Nested(expression left, binary_mcode op, expression right) + | Ast.Paren(lp,exp,rp) -> + Ast.Paren(string_mcode lp, expression exp, string_mcode rp) + | Ast.ArrayAccess(exp1,lb,exp2,rb) -> + Ast.ArrayAccess(expression exp1, string_mcode lb, expression exp2, + string_mcode rb) + | Ast.RecordAccess(exp,pt,field) -> + Ast.RecordAccess(expression exp, string_mcode pt, ident field) + | Ast.RecordPtAccess(exp,ar,field) -> + Ast.RecordPtAccess(expression exp, string_mcode ar, ident field) + | Ast.Cast(lp,ty,rp,exp) -> + Ast.Cast(string_mcode lp, fullType ty, string_mcode rp, + expression exp) + | Ast.SizeOfExpr(szf,exp) -> + Ast.SizeOfExpr(string_mcode szf, expression exp) + | Ast.SizeOfType(szf,lp,ty,rp) -> + Ast.SizeOfType(string_mcode szf,string_mcode lp, fullType ty, + string_mcode rp) + | Ast.TypeExp(ty) -> Ast.TypeExp(fullType ty) + | Ast.MetaErr(name,constraints,keep,inherited) -> + Ast.MetaErr(meta_mcode name,constraints,keep,inherited) + | Ast.MetaExpr(name,constraints,keep,ty,form,inherited) -> + Ast.MetaExpr(meta_mcode name,constraints,keep,ty,form,inherited) + | Ast.MetaExprList(name,lenname_inh,keep,inherited) -> + Ast.MetaExprList(meta_mcode name,lenname_inh,keep,inherited) + | Ast.EComma(cm) -> Ast.EComma(string_mcode cm) + | Ast.DisjExpr(exp_list) -> Ast.DisjExpr(List.map expression exp_list) + | Ast.NestExpr(expr_dots,whencode,multi) -> + Ast.NestExpr(expression_dots expr_dots, + get_option expression whencode,multi) + | Ast.Edots(dots,whencode) -> + Ast.Edots(string_mcode dots,get_option expression whencode) + | Ast.Ecircles(dots,whencode) -> + Ast.Ecircles(string_mcode dots,get_option expression whencode) + | Ast.Estars(dots,whencode) -> + Ast.Estars(string_mcode dots,get_option expression whencode) + | Ast.OptExp(exp) -> Ast.OptExp(expression exp) + | Ast.UniqueExp(exp) -> Ast.UniqueExp(expression exp)) in + exprfn all_functions k e + + and fullType ft = + let k ft = + Ast.rewrap ft + (match Ast.unwrap ft with + Ast.Type(cv,ty) -> Ast.Type (get_option cv_mcode cv, typeC ty) + | Ast.DisjType(types) -> Ast.DisjType(List.map fullType types) + | Ast.OptType(ty) -> Ast.OptType(fullType ty) + | Ast.UniqueType(ty) -> Ast.UniqueType(fullType ty)) in + ftfn all_functions k ft + + and typeC ty = + let k ty = + Ast.rewrap ty + (match Ast.unwrap ty with + Ast.BaseType(ty,sgn) -> + Ast.BaseType (base_mcode ty,get_option sign_mcode sgn) + | Ast.ImplicitInt(sgn) -> Ast.ImplicitInt (sign_mcode sgn) + | Ast.Pointer(ty,star) -> + Ast.Pointer (fullType ty, string_mcode star) + | Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> + Ast.FunctionPointer(fullType ty,string_mcode lp1,string_mcode star, + string_mcode rp1,string_mcode lp2, + parameter_dots params, + string_mcode rp2) + | Ast.FunctionType(allminus,ty,lp,params,rp) -> + Ast.FunctionType(allminus,get_option fullType ty,string_mcode lp, + parameter_dots params,string_mcode rp) + | Ast.Array(ty,lb,size,rb) -> + Ast.Array(fullType ty, string_mcode lb, + get_option expression size, string_mcode rb) + | Ast.StructUnionName(kind,name) -> + Ast.StructUnionName (struct_mcode kind, get_option ident name) + | Ast.StructUnionDef(ty,lb,decls,rb) -> + Ast.StructUnionDef (fullType ty, + string_mcode lb, declaration_dots decls, + string_mcode rb) + | Ast.TypeName(name) -> Ast.TypeName(string_mcode name) + | Ast.MetaType(name,keep,inherited) -> + Ast.MetaType(meta_mcode name,keep,inherited)) in + tyfn all_functions k ty + + and declaration d = + let k d = + Ast.rewrap d + (match Ast.unwrap d with + Ast.Init(stg,ty,id,eq,ini,sem) -> + Ast.Init(get_option storage_mcode stg, fullType ty, ident id, + string_mcode eq, initialiser ini, string_mcode sem) + | Ast.UnInit(stg,ty,id,sem) -> + Ast.UnInit(get_option storage_mcode stg, fullType ty, ident id, + string_mcode sem) + | Ast.MacroDecl(name,lp,args,rp,sem) -> + Ast.MacroDecl(ident name, string_mcode lp, expression_dots args, + string_mcode rp,string_mcode sem) + | Ast.TyDecl(ty,sem) -> Ast.TyDecl(fullType ty, string_mcode sem) + | Ast.Typedef(stg,ty,id,sem) -> + Ast.Typedef(string_mcode stg, fullType ty, typeC id, + string_mcode sem) + | Ast.DisjDecl(decls) -> Ast.DisjDecl(List.map declaration decls) + | Ast.Ddots(dots,whencode) -> + Ast.Ddots(string_mcode dots, get_option declaration whencode) + | Ast.MetaDecl(name,keep,inherited) -> + Ast.MetaDecl(meta_mcode name,keep,inherited) + | Ast.OptDecl(decl) -> Ast.OptDecl(declaration decl) + | Ast.UniqueDecl(decl) -> Ast.UniqueDecl(declaration decl)) in + declfn all_functions k d + + and initialiser i = + let k i = + Ast.rewrap i + (match Ast.unwrap i with + Ast.InitExpr(exp) -> Ast.InitExpr(expression exp) + | Ast.InitList(lb,initlist,rb,whencode) -> + Ast.InitList(string_mcode lb, List.map initialiser initlist, + string_mcode rb, List.map initialiser whencode) + | Ast.InitGccDotName(dot,name,eq,ini) -> + Ast.InitGccDotName + (string_mcode dot, ident name, string_mcode eq, initialiser ini) + | Ast.InitGccName(name,eq,ini) -> + Ast.InitGccName(ident name, string_mcode eq, initialiser ini) + | Ast.InitGccIndex(lb,exp,rb,eq,ini) -> + Ast.InitGccIndex + (string_mcode lb, expression exp, string_mcode rb, + string_mcode eq, initialiser ini) + | Ast.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini) -> + Ast.InitGccRange + (string_mcode lb, expression exp1, string_mcode dots, + expression exp2, string_mcode rb, string_mcode eq, + initialiser ini) + | Ast.IComma(cm) -> Ast.IComma(string_mcode cm) + | Ast.OptIni(i) -> Ast.OptIni(initialiser i) + | Ast.UniqueIni(i) -> Ast.UniqueIni(initialiser i)) in + initfn all_functions k i + + and parameterTypeDef p = + let k p = + Ast.rewrap p + (match Ast.unwrap p with + Ast.VoidParam(ty) -> Ast.VoidParam(fullType ty) + | Ast.Param(ty,id) -> Ast.Param(fullType ty, get_option ident id) + | Ast.MetaParam(name,keep,inherited) -> + Ast.MetaParam(meta_mcode name,keep,inherited) + | Ast.MetaParamList(name,lenname_inh,keep,inherited) -> + Ast.MetaParamList(meta_mcode name,lenname_inh,keep,inherited) + | Ast.PComma(cm) -> Ast.PComma(string_mcode cm) + | Ast.Pdots(dots) -> Ast.Pdots(string_mcode dots) + | Ast.Pcircles(dots) -> Ast.Pcircles(string_mcode dots) + | Ast.OptParam(param) -> Ast.OptParam(parameterTypeDef param) + | Ast.UniqueParam(param) -> Ast.UniqueParam(parameterTypeDef param)) in + paramfn all_functions k p + + and rule_elem re = + let k re = + Ast.rewrap re + (match Ast.unwrap re with + Ast.FunHeader(bef,allminus,fi,name,lp,params,rp) -> + Ast.FunHeader(bef,allminus,List.map fninfo fi,ident name, + string_mcode lp, parameter_dots params, + string_mcode rp) + | Ast.Decl(bef,allminus,decl) -> + Ast.Decl(bef,allminus,declaration decl) + | Ast.SeqStart(brace) -> Ast.SeqStart(string_mcode brace) + | Ast.SeqEnd(brace) -> Ast.SeqEnd(string_mcode brace) + | Ast.ExprStatement(exp,sem) -> + Ast.ExprStatement (expression exp, string_mcode sem) + | Ast.IfHeader(iff,lp,exp,rp) -> + Ast.IfHeader(string_mcode iff, string_mcode lp, expression exp, + string_mcode rp) + | Ast.Else(els) -> Ast.Else(string_mcode els) + | Ast.WhileHeader(whl,lp,exp,rp) -> + Ast.WhileHeader(string_mcode whl, string_mcode lp, expression exp, + string_mcode rp) + | Ast.DoHeader(d) -> Ast.DoHeader(string_mcode d) + | Ast.WhileTail(whl,lp,exp,rp,sem) -> + Ast.WhileTail(string_mcode whl, string_mcode lp, expression exp, + string_mcode rp, string_mcode sem) + | Ast.ForHeader(fr,lp,e1,sem1,e2,sem2,e3,rp) -> + Ast.ForHeader(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) + | Ast.IteratorHeader(whl,lp,args,rp) -> + Ast.IteratorHeader(ident whl, string_mcode lp, + expression_dots args, string_mcode rp) + | Ast.SwitchHeader(switch,lp,exp,rp) -> + Ast.SwitchHeader(string_mcode switch, string_mcode lp, + expression exp, string_mcode rp) + | Ast.Break(br,sem) -> + Ast.Break(string_mcode br, string_mcode sem) + | Ast.Continue(cont,sem) -> + Ast.Continue(string_mcode cont, string_mcode sem) + | Ast.Label(l,dd) -> Ast.Label(ident l, string_mcode dd) + | Ast.Goto(goto,l,sem) -> + Ast.Goto(string_mcode goto,ident l,string_mcode sem) + | Ast.Return(ret,sem) -> + Ast.Return(string_mcode ret, string_mcode sem) + | Ast.ReturnExpr(ret,exp,sem) -> + Ast.ReturnExpr(string_mcode ret, expression exp, string_mcode sem) + | Ast.MetaStmt(name,keep,seqible,inherited) -> + Ast.MetaStmt(meta_mcode name,keep,seqible,inherited) + | Ast.MetaStmtList(name,keep,inherited) -> + Ast.MetaStmtList(meta_mcode name,keep,inherited) + | Ast.MetaRuleElem(name,keep,inherited) -> + Ast.MetaRuleElem(meta_mcode name,keep,inherited) + | Ast.Exp(exp) -> Ast.Exp(expression exp) + | Ast.TopExp(exp) -> Ast.TopExp(expression exp) + | Ast.Ty(ty) -> Ast.Ty(fullType ty) + | Ast.Include(inc,name) -> + Ast.Include(string_mcode inc,inc_file_mcode name) + | Ast.DefineHeader(def,id,params) -> + Ast.DefineHeader(string_mcode def,ident id, + define_parameters params) + | Ast.Default(def,colon) -> + Ast.Default(string_mcode def,string_mcode colon) + | Ast.Case(case,exp,colon) -> + Ast.Case(string_mcode case,expression exp,string_mcode colon) + | Ast.DisjRuleElem(res) -> Ast.DisjRuleElem(List.map rule_elem res)) in + rulefn all_functions k re + + (* not parameterizable for now... *) + and define_parameters p = + let k p = + Ast.rewrap p + (match Ast.unwrap p with + Ast.NoParams -> Ast.NoParams + | Ast.DParams(lp,params,rp) -> + Ast.DParams(string_mcode lp,define_param_dots params, + string_mcode rp)) in + k p + + and define_param_dots d = + let k d = + Ast.rewrap d + (match Ast.unwrap d with + Ast.DOTS(l) -> Ast.DOTS(List.map define_param l) + | Ast.CIRCLES(l) -> Ast.CIRCLES(List.map define_param l) + | Ast.STARS(l) -> Ast.STARS(List.map define_param l)) in + k d + + and define_param p = + let k p = + Ast.rewrap p + (match Ast.unwrap p with + Ast.DParam(id) -> Ast.DParam(ident id) + | Ast.DPComma(comma) -> Ast.DPComma(string_mcode comma) + | Ast.DPdots(d) -> Ast.DPdots(string_mcode d) + | Ast.DPcircles(c) -> Ast.DPcircles(string_mcode c) + | Ast.OptDParam(dp) -> Ast.OptDParam(define_param dp) + | Ast.UniqueDParam(dp) -> Ast.UniqueDParam(define_param dp)) in + k p + + and process_bef_aft s = + Ast.set_dots_bef_aft + (match Ast.get_dots_bef_aft s with + Ast.NoDots -> Ast.NoDots + | Ast.DroppingBetweenDots(stm,ind) -> + Ast.DroppingBetweenDots(statement stm,ind) + | Ast.AddingBetweenDots(stm,ind) -> + Ast.AddingBetweenDots(statement stm,ind)) + s + + and statement s = + let k s = + Ast.rewrap s + (match Ast.unwrap s with + Ast.Seq(lbrace,decls,body,rbrace) -> + Ast.Seq(rule_elem lbrace, statement_dots decls, + statement_dots body, rule_elem rbrace) + | Ast.IfThen(header,branch,aft) -> + Ast.IfThen(rule_elem header, statement branch,aft) + | Ast.IfThenElse(header,branch1,els,branch2,aft) -> + Ast.IfThenElse(rule_elem header, statement branch1, rule_elem els, + statement branch2, aft) + | Ast.While(header,body,aft) -> + Ast.While(rule_elem header, statement body, aft) + | Ast.Do(header,body,tail) -> + Ast.Do(rule_elem header, statement body, rule_elem tail) + | Ast.For(header,body,aft) -> + Ast.For(rule_elem header, statement body, aft) + | Ast.Iterator(header,body,aft) -> + Ast.Iterator(rule_elem header, statement body, aft) + | Ast.Switch(header,lb,cases,rb) -> + Ast.Switch(rule_elem header,rule_elem lb, + List.map case_line cases,rule_elem rb) + | Ast.Atomic(re) -> Ast.Atomic(rule_elem re) + | Ast.Disj(stmt_dots_list) -> + Ast.Disj (List.map statement_dots stmt_dots_list) + | Ast.Nest(stmt_dots,whn,multi,bef,aft) -> + Ast.Nest(statement_dots stmt_dots, + List.map (whencode statement_dots statement) whn, + multi,bef,aft) + | Ast.FunDecl(header,lbrace,decls,body,rbrace) -> + Ast.FunDecl(rule_elem header,rule_elem lbrace, + statement_dots decls, + statement_dots body, rule_elem rbrace) + | Ast.Define(header,body) -> + Ast.Define(rule_elem header,statement_dots body) + | Ast.Dots(d,whn,bef,aft) -> + Ast.Dots(string_mcode d, + List.map (whencode statement_dots statement) whn,bef,aft) + | Ast.Circles(d,whn,bef,aft) -> + Ast.Circles(string_mcode d, + List.map (whencode statement_dots statement) whn, + bef,aft) + | Ast.Stars(d,whn,bef,aft) -> + Ast.Stars(string_mcode d, + List.map (whencode statement_dots statement) whn,bef,aft) + | Ast.OptStm(stmt) -> Ast.OptStm(statement stmt) + | Ast.UniqueStm(stmt) -> Ast.UniqueStm(statement stmt)) in + let s = stmtfn all_functions k s in + (* better to do this after, in case there is an equality test on the whole + statement, eg in free_vars. equality test would require that this + subterm not already be changed *) + process_bef_aft s + + and fninfo = function + Ast.FStorage(stg) -> Ast.FStorage(storage_mcode stg) + | Ast.FType(ty) -> Ast.FType(fullType ty) + | Ast.FInline(inline) -> Ast.FInline(string_mcode inline) + | Ast.FAttr(attr) -> Ast.FAttr(string_mcode attr) + + and whencode notfn alwaysfn = function + Ast.WhenNot a -> Ast.WhenNot (notfn a) + | Ast.WhenAlways a -> Ast.WhenAlways (alwaysfn a) + | Ast.WhenModifier(x) -> Ast.WhenModifier(x) + | Ast.WhenNotTrue(e) -> Ast.WhenNotTrue(rule_elem e) + | Ast.WhenNotFalse(e) -> Ast.WhenNotFalse(rule_elem e) + + and case_line c = + let k c = + Ast.rewrap c + (match Ast.unwrap c with + Ast.CaseLine(header,code) -> + Ast.CaseLine(rule_elem header,statement_dots code) + | Ast.OptCase(case) -> Ast.OptCase(case_line case)) in + casefn all_functions k c + + and top_level t = + let k t = + Ast.rewrap t + (match Ast.unwrap t with + Ast.FILEINFO(old_file,new_file) -> + Ast.FILEINFO (string_mcode old_file, string_mcode new_file) + | Ast.DECL(stmt) -> Ast.DECL(statement stmt) + | Ast.CODE(stmt_dots) -> Ast.CODE(statement_dots stmt_dots) + | Ast.ERRORWORDS(exps) -> Ast.ERRORWORDS (List.map expression exps)) in + topfn all_functions k t + + and anything a = + let k = function + (*in many cases below, the thing is not even mcode, so we do nothing*) + Ast.FullTypeTag(ft) -> Ast.FullTypeTag(fullType ft) + | Ast.BaseTypeTag(bt) as x -> x + | Ast.StructUnionTag(su) as x -> x + | Ast.SignTag(sgn) as x -> x + | Ast.IdentTag(id) -> Ast.IdentTag(ident id) + | Ast.ExpressionTag(exp) -> Ast.ExpressionTag(expression exp) + | Ast.ConstantTag(cst) as x -> x + | Ast.UnaryOpTag(unop) as x -> x + | Ast.AssignOpTag(asgnop) as x -> x + | Ast.FixOpTag(fixop) as x -> x + | Ast.BinaryOpTag(binop) as x -> x + | Ast.ArithOpTag(arithop) as x -> x + | Ast.LogicalOpTag(logop) as x -> x + | Ast.InitTag(decl) -> Ast.InitTag(initialiser decl) + | Ast.DeclarationTag(decl) -> Ast.DeclarationTag(declaration decl) + | Ast.StorageTag(stg) as x -> x + | Ast.IncFileTag(stg) as x -> x + | Ast.Rule_elemTag(rule) -> Ast.Rule_elemTag(rule_elem rule) + | Ast.StatementTag(rule) -> Ast.StatementTag(statement rule) + | Ast.CaseLineTag(case) -> Ast.CaseLineTag(case_line case) + | Ast.ConstVolTag(cv) as x -> x + | Ast.Token(tok,info) as x -> x + | Ast.Code(cd) -> Ast.Code(top_level cd) + | Ast.ExprDotsTag(ed) -> Ast.ExprDotsTag(expression_dots ed) + | Ast.ParamDotsTag(pd) -> Ast.ParamDotsTag(parameter_dots pd) + | Ast.StmtDotsTag(sd) -> Ast.StmtDotsTag(statement_dots sd) + | Ast.DeclDotsTag(sd) -> Ast.DeclDotsTag(declaration_dots sd) + | Ast.TypeCTag(ty) -> Ast.TypeCTag(typeC ty) + | Ast.ParamTag(param) -> Ast.ParamTag(parameterTypeDef param) + | Ast.SgrepStartTag(tok) as x -> x + | Ast.SgrepEndTag(tok) as x -> x in + anyfn all_functions k a + + and all_functions = + {rebuilder_ident = ident; + rebuilder_expression = expression; + rebuilder_fullType= fullType; + rebuilder_typeC = typeC; + rebuilder_declaration = declaration; + rebuilder_initialiser = initialiser; + rebuilder_parameter = parameterTypeDef; + rebuilder_parameter_list = parameter_dots; + rebuilder_rule_elem = rule_elem; + 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_define_param_dots = define_param_dots; + rebuilder_define_param = define_param; + rebuilder_define_parameters = define_parameters; + rebuilder_anything = anything} in + all_functions + diff --git a/parsing_cocci/.#visitor_ast0.ml.1.79 b/parsing_cocci/.#visitor_ast0.ml.1.79 new file mode 100644 index 0000000..6a70898 --- /dev/null +++ b/parsing_cocci/.#visitor_ast0.ml.1.79 @@ -0,0 +1,1028 @@ +(* +* 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.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 + + 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.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.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) + + 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.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/.#visitor_ast0.ml.1.80 b/parsing_cocci/.#visitor_ast0.ml.1.80 new file mode 100644 index 0000000..36ab172 --- /dev/null +++ b/parsing_cocci/.#visitor_ast0.ml.1.80 @@ -0,0 +1,1036 @@ +(* +* 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.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.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/.cvsignore b/parsing_cocci/.cvsignore new file mode 100644 index 0000000..ec28187 --- /dev/null +++ b/parsing_cocci/.cvsignore @@ -0,0 +1,6 @@ +.depend +*.cma +lexer_cocci.ml +lexer_script.ml +parser_cocci_menhir.ml +parser_cocci_menhir.mli diff --git a/parsing_cocci/arity.ml b/parsing_cocci/arity.ml index 2248a97..75b83b6 100644 --- a/parsing_cocci/arity.ml +++ b/parsing_cocci/arity.ml @@ -831,6 +831,15 @@ and statement tgt stm = | Ast0.UniqueType(ty) -> Ast0.UniqueStm(Ast0.rewrap stm (Ast0.Ty(ty))) | _ -> Ast0.Ty(new_ty)) + | Ast0.TopInit(init) -> + let new_init = initialiser tgt init in + Ast0.rewrap stm + (match Ast0.unwrap new_init with + Ast0.OptIni(init) -> + Ast0.OptStm(Ast0.rewrap stm (Ast0.TopInit(init))) + | Ast0.UniqueIni(init) -> + Ast0.UniqueStm(Ast0.rewrap stm (Ast0.TopInit(init))) + | _ -> Ast0.TopInit(new_init)) | Ast0.Disj(starter,rule_elem_dots_list,mids,ender) -> let stms = List.map (function x -> concat_dots (statement tgt) x) @@ -875,7 +884,8 @@ and statement tgt stm = concat_dots (statement Ast0.NONE) rule_elem_dots in let whn = List.map - (whencode (concat_dots (statement Ast0.NONE)) (statement Ast0.NONE)) + (whencode (concat_dots (statement Ast0.NONE)) (statement Ast0.NONE) + (expression Ast0.NONE)) whn in Ast0.rewrap stm (Ast0.Nest(starter,new_rule_elem_dots,ender,whn,multi)) @@ -884,7 +894,8 @@ and statement tgt stm = let dots = mcode dots in let whn = List.map - (whencode (concat_dots (statement Ast0.NONE)) (statement Ast0.NONE)) + (whencode (concat_dots (statement Ast0.NONE)) (statement Ast0.NONE) + (expression Ast0.NONE)) whn in make_rule_elem stm tgt arity (Ast0.Dots(dots,whn)) | Ast0.Circles(dots,whn) -> @@ -892,7 +903,8 @@ and statement tgt stm = let dots = mcode dots in let whn = List.map - (whencode (concat_dots (statement Ast0.NONE)) (statement Ast0.NONE)) + (whencode (concat_dots (statement Ast0.NONE)) (statement Ast0.NONE) + (expression Ast0.NONE)) whn in make_rule_elem stm tgt arity (Ast0.Circles(dots,whn)) | Ast0.Stars(dots,whn) -> @@ -900,7 +912,8 @@ and statement tgt stm = let dots = mcode dots in let whn = List.map - (whencode (concat_dots (statement Ast0.NONE)) (statement Ast0.NONE)) + (whencode (concat_dots (statement Ast0.NONE)) (statement Ast0.NONE) + (expression Ast0.NONE)) whn in make_rule_elem stm tgt arity (Ast0.Stars(dots,whn)) | Ast0.FunDecl(bef,fi,name,lp,params,rp,lbrace,body,rbrace) -> @@ -995,10 +1008,12 @@ and fninfo2arity fninfo = | Ast0.FAttr(attr) -> [mcode2arity attr]) fninfo) -and whencode notfn alwaysfn = function +and whencode notfn alwaysfn expression = function Ast0.WhenNot a -> Ast0.WhenNot (notfn a) | Ast0.WhenAlways a -> Ast0.WhenAlways (alwaysfn a) | Ast0.WhenModifier(x) -> Ast0.WhenModifier(x) + | Ast0.WhenNotTrue a -> Ast0.WhenNotTrue (expression a) + | Ast0.WhenNotFalse a -> Ast0.WhenNotFalse (expression a) and make_case_line = make_opt_unique diff --git a/parsing_cocci/ast0_cocci.ml b/parsing_cocci/ast0_cocci.ml index 5175cf7..5d9f214 100644 --- a/parsing_cocci/ast0_cocci.ml +++ b/parsing_cocci/ast0_cocci.ml @@ -306,6 +306,7 @@ and base_statement = | 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 * @@ -337,6 +338,8 @@ 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 @@ -397,6 +400,8 @@ and anything = | 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 diff --git a/parsing_cocci/ast0_cocci.mli b/parsing_cocci/ast0_cocci.mli index 1b448fa..b77ca37 100644 --- a/parsing_cocci/ast0_cocci.mli +++ b/parsing_cocci/ast0_cocci.mli @@ -279,6 +279,7 @@ and base_statement = | 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 * string mcode | Nest of string mcode * statement dots * string mcode * @@ -310,6 +311,8 @@ and ('a,'b) whencode = WhenNot of 'a | WhenAlways of 'b | WhenModifier of Ast_cocci.when_modifier + | WhenNotTrue of expression + | WhenNotFalse of expression and statement = base_statement wrap @@ -373,6 +376,8 @@ and anything = | CaseLineTag of case_line | TopTag of top_level | IsoWhenTag of Ast_cocci.when_modifier (*only for when code, in iso phase*) + | IsoWhenTTag of expression(*only for when code, in iso phase*) + | IsoWhenFTag of expression(*only for when code, in iso phase*) | MetaPosTag of meta_pos (* only in iso phase *) val dotsExpr : expression dots -> anything diff --git a/parsing_cocci/ast0toast.ml b/parsing_cocci/ast0toast.ml index ccc23cc..b04f31d 100644 --- a/parsing_cocci/ast0toast.ml +++ b/parsing_cocci/ast0toast.ml @@ -683,6 +683,8 @@ and statement s = Ast.Atomic(rewrap_rule_elem s (Ast.TopExp(expression exp))) | Ast0.Exp(exp) -> Ast.Atomic(rewrap_rule_elem s (Ast.Exp(expression exp))) + | Ast0.TopInit(init) -> + Ast.Atomic(rewrap_rule_elem s (Ast.TopInit(initialiser init))) | Ast0.Ty(ty) -> Ast.Atomic(rewrap_rule_elem s (Ast.Ty(typeC ty))) | Ast0.Disj(_,rule_elem_dots_list,_,_) -> @@ -770,6 +772,15 @@ and statement s = Ast0.WhenNot a -> Ast.WhenNot (notfn a) | Ast0.WhenAlways a -> Ast.WhenAlways (alwaysfn a) | Ast0.WhenModifier(x) -> Ast.WhenModifier(x) + | x -> + let rewrap_rule_elem ast0 ast = + rewrap ast0 (do_isos (Ast0.get_iso ast0)) ast in + match x with + Ast0.WhenNotTrue(e) -> + Ast.WhenNotTrue(rewrap_rule_elem e (Ast.Exp(expression e))) + | Ast0.WhenNotFalse(e) -> + Ast.WhenNotFalse(rewrap_rule_elem e (Ast.Exp(expression e))) + | _ -> failwith "not possible" and process_list seqible isos = function [] -> [] @@ -884,6 +895,8 @@ and anything = function | Ast0.CaseLineTag(d) -> Ast.CaseLineTag(case_line d) | Ast0.TopTag(d) -> Ast.Code(top_level d) | Ast0.IsoWhenTag(_) -> failwith "not possible" + | Ast0.IsoWhenTTag(_) -> failwith "not possible" + | Ast0.IsoWhenFTag(_) -> failwith "not possible" | Ast0.MetaPosTag _ -> failwith "not possible" (* --------------------------------------------------------------------- *) diff --git a/parsing_cocci/ast_cocci.ml b/parsing_cocci/ast_cocci.ml index a98a8dc..ef3d17f 100644 --- a/parsing_cocci/ast_cocci.ml +++ b/parsing_cocci/ast_cocci.ml @@ -408,6 +408,7 @@ and base_rule_elem = | TopExp of expression (* for macros body, exp at top level, not subexp *) | Ty of fullType (* only at SP top level, matches a subterm *) + | TopInit of initialiser (* only at top level *) | Include of string mcode (*#include*) * inc_file mcode (*file *) | DefineHeader of string mcode (* #define *) * ident (* name *) * define_parameters (*params*) @@ -462,6 +463,8 @@ and ('a,'b) whencode = WhenNot of 'a | WhenAlways of 'b | WhenModifier of when_modifier + | WhenNotTrue of rule_elem (* useful for fvs *) + | WhenNotFalse of rule_elem and when_modifier = (* The following removes the shortest path constraint. It can be used @@ -600,7 +603,9 @@ let get_wcfvs (whencode : ('a wrap, 'b wrap) whencode list) = (function WhenNot(a) -> get_fvs a | WhenAlways(a) -> get_fvs a - | WhenModifier(_) -> []) + | WhenModifier(_) -> [] + | WhenNotTrue(e) -> get_fvs e + | WhenNotFalse(e) -> get_fvs e) whencode) (* --------------------------------------------------------------------- *) diff --git a/parsing_cocci/ast_cocci.mli b/parsing_cocci/ast_cocci.mli index 0e5d0da..32fc4ca 100644 --- a/parsing_cocci/ast_cocci.mli +++ b/parsing_cocci/ast_cocci.mli @@ -374,6 +374,7 @@ and base_rule_elem = | Exp of expression | TopExp of expression (* for macros body *) | Ty of fullType (* only at top level *) + | TopInit of initialiser (* only at top level *) | Include of string mcode (*#include*) * inc_file mcode (*file *) | DefineHeader of string mcode (* #define *) * ident (* name *) * define_parameters (*params*) @@ -428,6 +429,8 @@ and ('a,'b) whencode = WhenNot of 'a | WhenAlways of 'b | WhenModifier of when_modifier + | WhenNotTrue of rule_elem + | WhenNotFalse of rule_elem and when_modifier = WhenAny diff --git a/parsing_cocci/check_meta.ml b/parsing_cocci/check_meta.ml index 28da910..e555f85 100644 --- a/parsing_cocci/check_meta.ml +++ b/parsing_cocci/check_meta.ml @@ -334,17 +334,20 @@ and statement old_metas table minus s = | Ast0.Exp(exp) -> expression ID old_metas table minus exp | Ast0.TopExp(exp) -> expression ID old_metas table minus exp | Ast0.Ty(ty) -> typeC old_metas table minus ty + | Ast0.TopInit(init) -> initialiser old_metas table minus init | Ast0.Disj(_,rule_elem_dots_list,_,_) -> List.iter (dots (statement old_metas table minus)) rule_elem_dots_list | Ast0.Nest(_,rule_elem_dots,_,w,_) -> dots (statement old_metas table minus) rule_elem_dots; List.iter (whencode (dots (statement old_metas table minus)) - (statement old_metas table minus)) + (statement old_metas table minus) + (expression ID old_metas table minus)) w | Ast0.Dots(_,x) | Ast0.Circles(_,x) | Ast0.Stars(_,x) -> List.iter (whencode (dots (statement old_metas table minus)) - (statement old_metas table minus)) x + (statement old_metas table minus) + (expression ID old_metas table minus)) x | Ast0.FunDecl(_,fi,name,lp,params,rp,lbrace,body,rbrace) -> ident FN old_metas table minus name; List.iter (fninfo old_metas table minus) fi; @@ -363,10 +366,12 @@ and fninfo old_metas table minus = function | Ast0.FInline(inline) -> () | Ast0.FAttr(attr) -> () -and whencode notfn alwaysfn = function +and whencode notfn alwaysfn expression = function Ast0.WhenNot a -> notfn a | Ast0.WhenAlways a -> alwaysfn a | Ast0.WhenModifier(_) -> () + | Ast0.WhenNotTrue a -> expression a + | Ast0.WhenNotFalse a -> expression a and case_line old_metas table minus c = match Ast0.unwrap c with diff --git a/parsing_cocci/compute_lines.ml b/parsing_cocci/compute_lines.ml index 5a08d1f..526d75e 100644 --- a/parsing_cocci/compute_lines.ml +++ b/parsing_cocci/compute_lines.ml @@ -633,6 +633,9 @@ let rec statement s = | Ast0.Ty(ty) -> let ty = typeC ty in mkres s (Ast0.Ty(ty)) ty ty + | Ast0.TopInit(init) -> + let init = initialiser init in + mkres s (Ast0.TopInit(init)) init init | Ast0.Disj(starter,rule_elem_dots_list,mids,ender) -> let starter = bad_mcode starter in let mids = List.map bad_mcode mids in diff --git a/parsing_cocci/context_neg.ml b/parsing_cocci/context_neg.ml index e20fe00..abc2054 100644 --- a/parsing_cocci/context_neg.ml +++ b/parsing_cocci/context_neg.ml @@ -54,6 +54,8 @@ let set_mcodekind x 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 = @@ -76,6 +78,8 @@ let set_index x 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 @@ -97,6 +101,8 @@ let get_index = function | 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" (* --------------------------------------------------------------------- *) @@ -638,6 +644,7 @@ let rec equal_statement s1 s2 = | (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 @@ -692,7 +699,9 @@ let root_equal e1 e2 = | (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.IsoWhenTag(_),_) | (_,Ast0.IsoWhenTag(_)) + | (Ast0.IsoWhenTTag(_),_) | (_,Ast0.IsoWhenTTag(_)) + | (Ast0.IsoWhenFTag(_),_) | (_,Ast0.IsoWhenFTag(_)) -> failwith "only within iso phase" | _ -> false @@ -758,7 +767,9 @@ let contextify_whencode = let whencode = function Ast0.WhenNot sd -> contextify_all.V0.combiner_statement_dots sd | Ast0.WhenAlways s -> contextify_all.V0.combiner_statement s - | Ast0.WhenModifier(_) -> () in + | 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; diff --git a/parsing_cocci/disjdistr.ml b/parsing_cocci/disjdistr.ml index c624418..bf5448a 100644 --- a/parsing_cocci/disjdistr.ml +++ b/parsing_cocci/disjdistr.ml @@ -271,6 +271,7 @@ let orify_rule_elem re exp rebuild = let orify_rule_elem_ty = generic_orify_rule_elem disjty let orify_rule_elem_param = generic_orify_rule_elem disjparam let orify_rule_elem_decl = generic_orify_rule_elem disjdecl +let orify_rule_elem_ini = generic_orify_rule_elem disjini let disj_rule_elem r k re = match Ast.unwrap re with @@ -323,6 +324,9 @@ let disj_rule_elem r k re = orify_rule_elem re exp (function exp -> Ast.rewrap exp (Ast.TopExp(exp))) | Ast.Ty(ty) -> orify_rule_elem_ty re ty (function ty -> Ast.rewrap ty (Ast.Ty(ty))) + | Ast.TopInit(init) -> + orify_rule_elem_ini re init + (function init -> Ast.rewrap init (Ast.TopInit(init))) | Ast.Include(inc,s) -> re | Ast.DefineHeader(def,id,params) -> re | Ast.Default(def,colon) -> re diff --git a/parsing_cocci/index.ml b/parsing_cocci/index.ml index e4b98a2..3396bd9 100644 --- a/parsing_cocci/index.ml +++ b/parsing_cocci/index.ml @@ -21,7 +21,7 @@ (* create an index for each constructor *) -(* current max is 145 *) +(* current max is 146 *) (* doesn't really work - requires that identical terms with no token subterms (eg dots) not appear on the same line *) @@ -195,6 +195,7 @@ let statement s = | Ast0.Exp(exp) -> [83] | Ast0.TopExp(exp) -> [141] | Ast0.Ty(ty) -> [124] + | Ast0.TopInit(init) -> [146] | Ast0.Dots(d,whencode) -> [84] | Ast0.Circles(d,whencode) -> [85] | Ast0.Stars(d,whencode) -> [86] diff --git a/parsing_cocci/insert_plus.ml b/parsing_cocci/insert_plus.ml index 12009c7..795d46c 100644 --- a/parsing_cocci/insert_plus.ml +++ b/parsing_cocci/insert_plus.ml @@ -137,6 +137,8 @@ let create_root_token_table minus = | Ast0.CaseLineTag(d) -> Ast0.get_index d | Ast0.TopTag(d) -> Ast0.get_index 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" in Hashtbl.add root_token_table key tokens) @@ -359,6 +361,8 @@ let call_collect_minus context_nodes : (Ast0.get_index e, (collect_minus_join_points e).V0.combiner_top_level e) | 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") context_nodes @@ -465,6 +469,7 @@ let collect_plus_nodes root = Ast0.Exp(exp) -> r.V0.combiner_expression exp | Ast0.TopExp(exp) -> r.V0.combiner_expression exp | Ast0.Ty(ty) -> r.V0.combiner_typeC ty + | Ast0.TopInit(init) -> r.V0.combiner_initialiser init | Ast0.Decl(_,decl) -> r.V0.combiner_declaration decl | _ -> do_nothing mk_statement r k e in @@ -551,6 +556,8 @@ let call_collect_plus context_nodes : (Ast0.get_index e, (collect_plus_nodes e).V0.combiner_top_level e) | 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") context_nodes @@ -674,8 +681,6 @@ let insert thing thinginfo into intoinfo = let into_end = intoinfo.Ast0.tline_end in let into_left_offset = intoinfo.Ast0.left_offset in let into_right_offset = intoinfo.Ast0.right_offset in - Printf.printf "thing start %d thing end %d into start %d into end %d\n" - thing_start thing_end into_start into_end; if thing_end < into_start && thing_start < into_start then (thing@into, {{intoinfo with Ast0.tline_start = thing_start} @@ -705,6 +710,7 @@ let insert thing thinginfo into intoinfo = Printf.printf "thing offset %d left offset %d right offset %d\n" thing_offset into_left_offset into_right_offset; Pretty_print_cocci.print_anything "" thing; + Pretty_print_cocci.print_anything "" into; failwith "can't figure out where to put the + code" end diff --git a/parsing_cocci/iso_pattern.ml b/parsing_cocci/iso_pattern.ml index 6bbf1a7..f7975b8 100644 --- a/parsing_cocci/iso_pattern.ml +++ b/parsing_cocci/iso_pattern.ml @@ -100,6 +100,10 @@ let anything_equal = function | (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 @@ -1020,6 +1024,7 @@ let match_maker checks_needed context_required whencode_allowed = | (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)) @@ -1041,6 +1046,14 @@ let match_maker checks_needed context_required whencode_allowed = | 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 @@ -1663,6 +1676,15 @@ let instantiate bindings mv_bindings = 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 @@ -1679,37 +1701,19 @@ let instantiate bindings mv_bindings = Ast0.rewrap e (Ast0.Dots (d, - List.map - (function (_,v) -> - match v with - Ast0.DotsStmtTag(stms) -> Ast0.WhenNot stms - | Ast0.StmtTag(stm) -> Ast0.WhenAlways stm - | Ast0.IsoWhenTag(x) -> Ast0.WhenModifier(x) - | _ -> failwith "unexpected binding") + List.map whenfn (List.filter (function (x,v) -> x = (dot_term d)) bindings))) | Ast0.Circles(d,_) -> Ast0.rewrap e (Ast0.Circles (d, - List.map - (function (_,v) -> - match v with - Ast0.DotsStmtTag(stms) -> Ast0.WhenNot stms - | Ast0.StmtTag(stm) -> Ast0.WhenAlways stm - | Ast0.IsoWhenTag(x) -> Ast0.WhenModifier(x) - | _ -> failwith "unexpected binding") + List.map whenfn (List.filter (function (x,v) -> x = (dot_term d)) bindings))) | Ast0.Stars(d,_) -> Ast0.rewrap e (Ast0.Stars (d, - List.map - (function (_,v) -> - match v with - Ast0.DotsStmtTag(stms) -> Ast0.WhenNot stms - | Ast0.StmtTag(stm) -> Ast0.WhenAlways stm - | Ast0.IsoWhenTag(x) -> Ast0.WhenModifier(x) - | _ -> failwith "unexpected binding") + List.map whenfn (List.filter (function (x,v) -> x = (dot_term d)) bindings))) | _ -> e in @@ -2276,7 +2280,8 @@ let rewrap_anything = function | 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(_) -> failwith "only for isos within iso phase" + | Ast0.IsoWhenTag(_) | Ast0.IsoWhenTTag(_) | Ast0.IsoWhenFTag(_) -> + failwith "only for isos within iso phase" | Ast0.MetaPosTag(p) -> Ast0.MetaPosTag(p) (* --------------------------------------------------------------------- *) diff --git a/parsing_cocci/lexer_cocci.mll b/parsing_cocci/lexer_cocci.mll index c066d1d..46d2768 100644 --- a/parsing_cocci/lexer_cocci.mll +++ b/parsing_cocci/lexer_cocci.mll @@ -219,6 +219,7 @@ let id_tokens lexbuf = | "exists" when in_rule_name -> check_context_linetype s; TExists | "forall" when in_rule_name -> check_context_linetype s; TForall | "reverse" when in_rule_name -> check_context_linetype s; TReverse + | "script" when in_rule_name -> check_context_linetype s; TScript | "char" -> Tchar linetype | "short" -> Tshort linetype diff --git a/parsing_cocci/parse_aux.ml b/parsing_cocci/parse_aux.ml index fb1ff7d..274b37f 100644 --- a/parsing_cocci/parse_aux.ml +++ b/parsing_cocci/parse_aux.ml @@ -459,9 +459,6 @@ let make_cocci_rule_name_result nm d i a e ee = Ast.CocciRulename (Some n,d,i,a,e,ee) | None -> Ast.CocciRulename (None,d,i,a,e,ee) -let make_script_rule_name_result scr lang deps = - let s = id2name scr in +let make_script_rule_name_result lang deps = let l = id2name lang in - if s <> "script" then - raise (Semantic_cocci.Semantic ("malformed script rule")); - Ast.ScriptRulename (l,deps) + Ast.ScriptRulename (l,deps) diff --git a/parsing_cocci/parse_cocci.ml b/parsing_cocci/parse_cocci.ml index 45938ff..b661baf 100644 --- a/parsing_cocci/parse_cocci.ml +++ b/parsing_cocci/parse_cocci.ml @@ -194,8 +194,11 @@ let token2c (tok,_) = | PC.TArobArob -> "@@" | PC.TArob -> "@" | PC.TPArob -> "P@" + | PC.TScript -> "script" | PC.TWhen(clt) -> "WHEN"^(line_type2c clt) + | PC.TWhenTrue(clt) -> "WHEN TRUE"^(line_type2c clt) + | PC.TWhenFalse(clt) -> "WHEN FALSE"^(line_type2c clt) | PC.TAny(clt) -> "ANY"^(line_type2c clt) | PC.TStrict(clt) -> "STRICT"^(line_type2c clt) | PC.TEllipsis(clt) -> "..."^(line_type2c clt) @@ -231,6 +234,7 @@ let token2c (tok,_) = | PC.TCBrace(clt) -> "}"^(line_type2c clt) | PC.TOCro(clt) -> "["^(line_type2c clt) | PC.TCCro(clt) -> "]"^(line_type2c clt) + | PC.TOInit(clt) -> "{"^(line_type2c clt) | PC.TPtrOp(clt) -> "->"^(line_type2c clt) @@ -302,13 +306,15 @@ let plus_attachable (tok,_) = | PC.TMetaStmList(_,_,clt) | PC.TMetaFunc(_,_,_,clt) | PC.TMetaLocalFunc(_,_,_,clt) - | PC.TWhen(clt) | PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt) + | PC.TWhen(clt) | PC.TWhenTrue(clt) | PC.TWhenFalse(clt) + | PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt) (* | PC.TCircles(clt) | PC.TStars(clt) *) | PC.TWhy(clt) | PC.TDotDot(clt) | PC.TBang(clt) | PC.TOPar(clt) | PC.TCPar(clt) | PC.TOBrace(clt) | PC.TCBrace(clt) | PC.TOCro(clt) | PC.TCCro(clt) + | PC.TOInit(clt) | PC.TPtrOp(clt) @@ -361,13 +367,15 @@ let get_clt (tok,_) = | PC.TMetaStmList(_,_,clt) | PC.TMetaFunc(_,_,_,clt) | PC.TMetaLocalFunc(_,_,_,clt) | PC.TMetaPos(_,_,_,clt) - | PC.TWhen(clt) | PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt) + | PC.TWhen(clt) | PC.TWhenTrue(clt) | PC.TWhenFalse(clt) | + PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt) (* | PC.TCircles(clt) | PC.TStars(clt) *) | PC.TWhy(clt) | PC.TDotDot(clt) | PC.TBang(clt) | PC.TOPar(clt) | PC.TCPar(clt) | PC.TOBrace(clt) | PC.TCBrace(clt) | PC.TOCro(clt) | PC.TCCro(clt) + | PC.TOInit(clt) | PC.TPtrOp(clt) @@ -469,6 +477,8 @@ let update_clt (tok,x) clt = | PC.TMetaLocalFunc(a,b,c,_) -> (PC.TMetaLocalFunc(a,b,c,clt),x) | PC.TWhen(_) -> (PC.TWhen(clt),x) + | PC.TWhenTrue(_) -> (PC.TWhenTrue(clt),x) + | PC.TWhenFalse(_) -> (PC.TWhenFalse(clt),x) | PC.TAny(_) -> (PC.TAny(clt),x) | PC.TStrict(_) -> (PC.TStrict(clt),x) | PC.TEllipsis(_) -> (PC.TEllipsis(clt),x) @@ -501,6 +511,7 @@ let update_clt (tok,x) clt = | PC.TCBrace(_) -> (PC.TCBrace(clt),x) | PC.TOCro(_) -> (PC.TOCro(clt),x) | PC.TCCro(_) -> (PC.TCCro(clt),x) + | PC.TOInit(_) -> (PC.TOInit(clt),x) | PC.TPtrOp(_) -> (PC.TPtrOp(clt),x) @@ -605,11 +616,12 @@ let split_token ((tok,_) as t) = | PC.TMetaStm(_,_,clt) | PC.TMetaStmList(_,_,clt) | PC.TMetaErr(_,_,_,clt) | PC.TMetaFunc(_,_,_,clt) | PC.TMetaLocalFunc(_,_,_,clt) | PC.TMetaDeclarer(_,_,_,clt) | PC.TMetaIterator(_,_,_,clt) -> split t clt - | PC.TMPtVirg | PC.TArob | PC.TArobArob -> ([t],[t]) + | PC.TMPtVirg | PC.TArob | PC.TArobArob | PC.TScript -> ([t],[t]) | PC.TPArob | PC.TMetaPos(_,_,_,_) -> ([t],[]) | PC.TFunDecl(clt) - | PC.TWhen(clt) | PC.TAny(clt) | PC.TStrict(clt) | PC.TLineEnd(clt) + | PC.TWhen(clt) | PC.TWhenTrue(clt) | PC.TWhenFalse(clt) + | PC.TAny(clt) | PC.TStrict(clt) | PC.TLineEnd(clt) | PC.TEllipsis(clt) (* | PC.TCircles(clt) | PC.TStars(clt) *) -> split t clt | PC.TOEllipsis(_) | PC.TCEllipsis(_) (* clt must be context *) @@ -635,7 +647,7 @@ let split_token ((tok,_) as t) = | PC.TShOp(_,clt) | PC.TPlus(clt) | PC.TMinus(clt) | PC.TMul(clt) | PC.TDmOp(_,clt) | PC.TTilde (clt) -> split t clt - | PC.TOBrace(clt) | PC.TCBrace(clt) -> split t clt + | PC.TOBrace(clt) | PC.TCBrace(clt) | PC.TOInit(clt) -> split t clt | PC.TOCro(clt) | PC.TCCro(clt) -> split t clt | PC.TPtrOp(clt) -> split t clt @@ -728,7 +740,8 @@ let detect_types in_meta_decls l = (PC.TOEllipsis(_),_) (* | (PC.TOCircles(_),_) | (PC.TOStars(_),_) *) | (PC.TPOEllipsis(_),_) (* | (PC.TOCircles(_),_) | (PC.TOStars(_),_) *) | (PC.TEllipsis(_),_) (* | (PC.TCircles(_),_) | (PC.TStars(_),_) *) - | (PC.TPtVirg(_),_) | (PC.TOBrace(_),_) | (PC.TCBrace(_),_) + | (PC.TPtVirg(_),_) | (PC.TOBrace(_),_) | (PC.TOInit(_),_) + | (PC.TCBrace(_),_) | (PC.TPure,_) | (PC.TContext,_) | (PC.Tstatic(_),_) | (PC.Textern(_),_) | (PC.Tinline(_),_) | (PC.Ttypedef(_),_) | (PC.Tattr(_),_) -> true @@ -841,7 +854,8 @@ let token2line (tok,_) = | PC.TMetaLocalFunc(_,_,_,clt) | PC.TMetaPos(_,_,_,clt) | PC.TFunDecl(clt) - | PC.TWhen(clt) | PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt) + | PC.TWhen(clt) | PC.TWhenTrue(clt) | PC.TWhenFalse(clt) + | PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt) (* | PC.TCircles(clt) | PC.TStars(clt) *) | PC.TOEllipsis(clt) | PC.TCEllipsis(clt) @@ -853,6 +867,7 @@ let token2line (tok,_) = | PC.TCPar0(clt) | PC.TOBrace(clt) | PC.TCBrace(clt) | PC.TOCro(clt) | PC.TCCro(clt) + | PC.TOInit(clt) | PC.TPtrOp(clt) @@ -897,6 +912,43 @@ and find_line_end inwhen line clt q = function | x::xs when token2line x = line -> x :: (find_line_end inwhen line clt q xs) | xs -> (PC.TLineEnd(clt),q)::(insert_line_end xs) +let rec translate_when_true_false = function + [] -> [] + | (PC.TWhen(clt),q)::((PC.TNotEq(_),_) as x)::(PC.TIdent("true",_),_)::xs -> + (PC.TWhenTrue(clt),q)::x::xs + | (PC.TWhen(clt),q)::((PC.TNotEq(_),_) as x)::(PC.TIdent("false",_),_)::xs -> + (PC.TWhenFalse(clt),q)::x::xs + | x::xs -> x :: (translate_when_true_false xs) + +(* ----------------------------------------------------------------------- *) +(* top level initializers: a sequence of braces followed by a dot *) + +let find_top_init tokens = + match tokens with + (PC.TOBrace(clt),q) :: rest -> + let rec dot_start acc = function + ((PC.TOBrace(_),_) as x) :: rest -> + dot_start (x::acc) rest + | ((PC.TDot(_),_) :: rest) as x -> + Some ((PC.TOInit(clt),q) :: (List.rev acc) @ x) + | l -> None in + let rec comma_end acc = function + ((PC.TCBrace(_),_) as x) :: rest -> + comma_end (x::acc) rest + | ((PC.TComma(_),_) :: rest) as x -> + Some ((PC.TOInit(clt),q) :: (List.rev x) @ acc) + | l -> None in + (match dot_start [] rest with + Some x -> x + | None -> + (match List.rev rest with + ((PC.EOF,_) as x)::rest -> + (match comma_end [x] rest with + Some x -> x + | None -> tokens) + | _ -> failwith "unexpected empty token list")) + | _ -> tokens + (* ----------------------------------------------------------------------- *) (* process pragmas: they can only be used in + code, and adjacent to another + token. They are concatenated to the string representation of @@ -1068,8 +1120,10 @@ let parse_one str parsefn file toks = | e -> raise e let prepare_tokens tokens = - insert_line_end - (detect_types false (find_function_names (detect_attr tokens))) + find_top_init + (translate_when_true_false (* after insert_line_end *) + (insert_line_end + (detect_types false (find_function_names (detect_attr tokens))))) let rec consume_minus_positions = function [] -> [] diff --git a/parsing_cocci/parser_cocci_menhir.ml b/parsing_cocci/parser_cocci_menhir.ml index 58c840f..e798752 100644 --- a/parsing_cocci/parser_cocci_menhir.ml +++ b/parsing_cocci/parser_cocci_menhir.ml @@ -136,278 +136,294 @@ type token = (Data.clt) # 138 "parser_cocci_menhir.ml" ) - | TWhen of ( + | TWhenTrue of ( # 73 "parser_cocci_menhir.mly" (Data.clt) # 143 "parser_cocci_menhir.ml" +) + | TWhenFalse of ( +# 73 "parser_cocci_menhir.mly" + (Data.clt) +# 148 "parser_cocci_menhir.ml" +) + | TWhen of ( +# 73 "parser_cocci_menhir.mly" + (Data.clt) +# 153 "parser_cocci_menhir.ml" ) | TUsing | TTypedef | TTypeId of ( # 59 "parser_cocci_menhir.mly" (string * Data.clt) -# 150 "parser_cocci_menhir.ml" +# 160 "parser_cocci_menhir.ml" ) | TType | TTilde of ( # 98 "parser_cocci_menhir.mly" (Data.clt) -# 156 "parser_cocci_menhir.ml" +# 166 "parser_cocci_menhir.ml" ) | TSwitch of ( # 57 "parser_cocci_menhir.mly" (Data.clt) -# 161 "parser_cocci_menhir.ml" +# 171 "parser_cocci_menhir.ml" ) | TString of ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 166 "parser_cocci_menhir.ml" +# 176 "parser_cocci_menhir.ml" ) | TStrict of ( # 73 "parser_cocci_menhir.mly" (Data.clt) -# 171 "parser_cocci_menhir.ml" +# 181 "parser_cocci_menhir.ml" ) | TStatement | TSizeof of ( # 58 "parser_cocci_menhir.mly" (Data.clt) -# 177 "parser_cocci_menhir.ml" +# 187 "parser_cocci_menhir.ml" ) | TShOp of ( # 95 "parser_cocci_menhir.mly" (Ast_cocci.arithOp * Data.clt) -# 182 "parser_cocci_menhir.ml" +# 192 "parser_cocci_menhir.ml" ) | TScriptData of ( # 70 "parser_cocci_menhir.mly" (string) -# 187 "parser_cocci_menhir.ml" +# 197 "parser_cocci_menhir.ml" ) + | TScript | TRuleName of ( # 47 "parser_cocci_menhir.mly" (string) -# 192 "parser_cocci_menhir.ml" +# 203 "parser_cocci_menhir.ml" ) | TRightIso | TReverse | TReturn of ( # 57 "parser_cocci_menhir.mly" (Data.clt) -# 199 "parser_cocci_menhir.ml" +# 210 "parser_cocci_menhir.ml" ) | TPure | TPtrOp of ( # 103 "parser_cocci_menhir.mly" (Data.clt) -# 205 "parser_cocci_menhir.ml" +# 216 "parser_cocci_menhir.ml" ) | TPtVirg of ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 210 "parser_cocci_menhir.ml" +# 221 "parser_cocci_menhir.ml" ) | TPragma of ( # 78 "parser_cocci_menhir.mly" (string) -# 215 "parser_cocci_menhir.ml" +# 226 "parser_cocci_menhir.ml" ) | TPosition | TPosAny | TPlusFile of ( # 82 "parser_cocci_menhir.mly" (string * Data.clt) -# 222 "parser_cocci_menhir.ml" +# 233 "parser_cocci_menhir.ml" ) | TPlus0 | TPlus of ( # 97 "parser_cocci_menhir.mly" (Data.clt) -# 228 "parser_cocci_menhir.ml" +# 239 "parser_cocci_menhir.ml" ) | TPathIsoFile of ( # 78 "parser_cocci_menhir.mly" (string) -# 233 "parser_cocci_menhir.ml" +# 244 "parser_cocci_menhir.ml" ) | TParameter | TPOEllipsis of ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 239 "parser_cocci_menhir.ml" +# 250 "parser_cocci_menhir.ml" ) | TPCEllipsis of ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 244 "parser_cocci_menhir.ml" +# 255 "parser_cocci_menhir.ml" ) | TPArob | TOrLog of ( # 88 "parser_cocci_menhir.mly" (Data.clt) -# 250 "parser_cocci_menhir.ml" +# 261 "parser_cocci_menhir.ml" ) | TOr of ( # 90 "parser_cocci_menhir.mly" (Data.clt) -# 255 "parser_cocci_menhir.ml" +# 266 "parser_cocci_menhir.ml" ) | TOn | TOPar0 of ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 261 "parser_cocci_menhir.ml" +# 272 "parser_cocci_menhir.ml" ) | TOPar of ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 266 "parser_cocci_menhir.ml" +# 277 "parser_cocci_menhir.ml" +) + | TOInit of ( +# 100 "parser_cocci_menhir.mly" + (Data.clt) +# 282 "parser_cocci_menhir.ml" ) | TOEllipsis of ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 271 "parser_cocci_menhir.ml" +# 287 "parser_cocci_menhir.ml" ) | TOCro of ( # 101 "parser_cocci_menhir.mly" (Data.clt) -# 276 "parser_cocci_menhir.ml" +# 292 "parser_cocci_menhir.ml" ) | TOBrace of ( # 100 "parser_cocci_menhir.mly" (Data.clt) -# 281 "parser_cocci_menhir.ml" +# 297 "parser_cocci_menhir.ml" ) | TNothing | TNotEq of ( # 93 "parser_cocci_menhir.mly" (Data.clt) -# 287 "parser_cocci_menhir.ml" +# 303 "parser_cocci_menhir.ml" ) | TNever | TName | TMul of ( # 98 "parser_cocci_menhir.mly" (Data.clt) -# 294 "parser_cocci_menhir.ml" +# 310 "parser_cocci_menhir.ml" ) | TMinusFile of ( # 82 "parser_cocci_menhir.mly" (string * Data.clt) -# 299 "parser_cocci_menhir.ml" +# 315 "parser_cocci_menhir.ml" ) | TMinus of ( # 97 "parser_cocci_menhir.mly" (Data.clt) -# 304 "parser_cocci_menhir.ml" +# 320 "parser_cocci_menhir.ml" ) | TMid0 of ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 309 "parser_cocci_menhir.ml" +# 325 "parser_cocci_menhir.ml" ) | TMetaType of ( # 64 "parser_cocci_menhir.mly" (Parse_aux.info) -# 314 "parser_cocci_menhir.ml" +# 330 "parser_cocci_menhir.ml" ) | TMetaStmList of ( # 64 "parser_cocci_menhir.mly" (Parse_aux.info) -# 319 "parser_cocci_menhir.ml" +# 335 "parser_cocci_menhir.ml" ) | TMetaStm of ( # 64 "parser_cocci_menhir.mly" (Parse_aux.info) -# 324 "parser_cocci_menhir.ml" +# 340 "parser_cocci_menhir.ml" ) | TMetaPos of ( # 67 "parser_cocci_menhir.mly" (Parse_aux.pos_info) -# 329 "parser_cocci_menhir.ml" +# 345 "parser_cocci_menhir.ml" ) | TMetaParamList of ( # 65 "parser_cocci_menhir.mly" (Parse_aux.list_info) -# 334 "parser_cocci_menhir.ml" +# 350 "parser_cocci_menhir.ml" ) | TMetaParam of ( # 64 "parser_cocci_menhir.mly" (Parse_aux.info) -# 339 "parser_cocci_menhir.ml" +# 355 "parser_cocci_menhir.ml" ) | TMetaLocalIdExp of ( # 66 "parser_cocci_menhir.mly" (Parse_aux.typed_info) -# 344 "parser_cocci_menhir.ml" +# 360 "parser_cocci_menhir.ml" ) | TMetaLocalFunc of ( # 61 "parser_cocci_menhir.mly" (Parse_aux.idinfo) -# 349 "parser_cocci_menhir.ml" +# 365 "parser_cocci_menhir.ml" ) | TMetaIterator of ( # 62 "parser_cocci_menhir.mly" (Parse_aux.idinfo) -# 354 "parser_cocci_menhir.ml" +# 370 "parser_cocci_menhir.ml" ) | TMetaIdExp of ( # 66 "parser_cocci_menhir.mly" (Parse_aux.typed_info) -# 359 "parser_cocci_menhir.ml" +# 375 "parser_cocci_menhir.ml" ) | TMetaId of ( # 61 "parser_cocci_menhir.mly" (Parse_aux.idinfo) -# 364 "parser_cocci_menhir.ml" +# 380 "parser_cocci_menhir.ml" ) | TMetaFunc of ( # 61 "parser_cocci_menhir.mly" (Parse_aux.idinfo) -# 369 "parser_cocci_menhir.ml" +# 385 "parser_cocci_menhir.ml" ) | TMetaExpList of ( # 65 "parser_cocci_menhir.mly" (Parse_aux.list_info) -# 374 "parser_cocci_menhir.ml" +# 390 "parser_cocci_menhir.ml" ) | TMetaExp of ( # 66 "parser_cocci_menhir.mly" (Parse_aux.typed_info) -# 379 "parser_cocci_menhir.ml" +# 395 "parser_cocci_menhir.ml" ) | TMetaErr of ( # 63 "parser_cocci_menhir.mly" (Parse_aux.expinfo) -# 384 "parser_cocci_menhir.ml" +# 400 "parser_cocci_menhir.ml" ) | TMetaDeclarer of ( # 62 "parser_cocci_menhir.mly" (Parse_aux.idinfo) -# 389 "parser_cocci_menhir.ml" +# 405 "parser_cocci_menhir.ml" ) | TMetaConst of ( # 66 "parser_cocci_menhir.mly" (Parse_aux.typed_info) -# 394 "parser_cocci_menhir.ml" +# 410 "parser_cocci_menhir.ml" ) | TMPtVirg | TLogOp of ( # 94 "parser_cocci_menhir.mly" (Ast_cocci.logicalOp * Data.clt) -# 400 "parser_cocci_menhir.ml" +# 416 "parser_cocci_menhir.ml" ) | TLocal | TLineEnd of ( # 73 "parser_cocci_menhir.mly" (Data.clt) -# 406 "parser_cocci_menhir.ml" +# 422 "parser_cocci_menhir.ml" ) | TIteratorId of ( # 59 "parser_cocci_menhir.mly" (string * Data.clt) -# 411 "parser_cocci_menhir.ml" +# 427 "parser_cocci_menhir.ml" ) | TIterator | TIsoType @@ -422,57 +438,57 @@ type token = | TInt of ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 426 "parser_cocci_menhir.ml" +# 442 "parser_cocci_menhir.ml" ) | TIncludeNL of ( # 79 "parser_cocci_menhir.mly" (string * Data.clt) -# 431 "parser_cocci_menhir.ml" +# 447 "parser_cocci_menhir.ml" ) | TIncludeL of ( # 79 "parser_cocci_menhir.mly" (string * Data.clt) -# 436 "parser_cocci_menhir.ml" +# 452 "parser_cocci_menhir.ml" ) | TInc of ( # 84 "parser_cocci_menhir.mly" (Data.clt) -# 441 "parser_cocci_menhir.ml" +# 457 "parser_cocci_menhir.ml" ) | TIf of ( # 57 "parser_cocci_menhir.mly" (Data.clt) -# 446 "parser_cocci_menhir.ml" +# 462 "parser_cocci_menhir.ml" ) | TIdentifier | TIdent of ( # 59 "parser_cocci_menhir.mly" (string * Data.clt) -# 452 "parser_cocci_menhir.ml" +# 468 "parser_cocci_menhir.ml" ) | TIdExpression | TGoto of ( # 58 "parser_cocci_menhir.mly" (Data.clt) -# 458 "parser_cocci_menhir.ml" +# 474 "parser_cocci_menhir.ml" ) | TFunction | TFunDecl of ( # 58 "parser_cocci_menhir.mly" (Data.clt) -# 464 "parser_cocci_menhir.ml" +# 480 "parser_cocci_menhir.ml" ) | TFresh | TForall | TFor of ( # 57 "parser_cocci_menhir.mly" (Data.clt) -# 471 "parser_cocci_menhir.ml" +# 487 "parser_cocci_menhir.ml" ) | TFloat of ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 476 "parser_cocci_menhir.ml" +# 492 "parser_cocci_menhir.ml" ) | TExtends | TExpression @@ -482,150 +498,150 @@ type token = | TEqEq of ( # 93 "parser_cocci_menhir.mly" (Data.clt) -# 486 "parser_cocci_menhir.ml" +# 502 "parser_cocci_menhir.ml" ) | TEq of ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 491 "parser_cocci_menhir.ml" +# 507 "parser_cocci_menhir.ml" ) | TElse of ( # 57 "parser_cocci_menhir.mly" (Data.clt) -# 496 "parser_cocci_menhir.ml" +# 512 "parser_cocci_menhir.ml" ) | TEllipsis of ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 501 "parser_cocci_menhir.ml" +# 517 "parser_cocci_menhir.ml" ) | TDotDot of ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 506 "parser_cocci_menhir.ml" +# 522 "parser_cocci_menhir.ml" ) | TDot of ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 511 "parser_cocci_menhir.ml" +# 527 "parser_cocci_menhir.ml" ) | TDo of ( # 57 "parser_cocci_menhir.mly" (Data.clt) -# 516 "parser_cocci_menhir.ml" +# 532 "parser_cocci_menhir.ml" ) | TDmOp of ( # 96 "parser_cocci_menhir.mly" (Ast_cocci.arithOp * Data.clt) -# 521 "parser_cocci_menhir.ml" +# 537 "parser_cocci_menhir.ml" ) | TDisable | TDepends | TDefineParam of ( # 81 "parser_cocci_menhir.mly" (Data.clt * token * int) -# 528 "parser_cocci_menhir.ml" +# 544 "parser_cocci_menhir.ml" ) | TDefine of ( # 80 "parser_cocci_menhir.mly" (Data.clt * token) -# 533 "parser_cocci_menhir.ml" +# 549 "parser_cocci_menhir.ml" ) | TDefault of ( # 57 "parser_cocci_menhir.mly" (Data.clt) -# 538 "parser_cocci_menhir.ml" +# 554 "parser_cocci_menhir.ml" ) | TDeclarerId of ( # 59 "parser_cocci_menhir.mly" (string * Data.clt) -# 543 "parser_cocci_menhir.ml" +# 559 "parser_cocci_menhir.ml" ) | TDeclarer | TDec of ( # 84 "parser_cocci_menhir.mly" (Data.clt) -# 549 "parser_cocci_menhir.ml" +# 565 "parser_cocci_menhir.ml" ) | TContinue of ( # 58 "parser_cocci_menhir.mly" (Data.clt) -# 554 "parser_cocci_menhir.ml" +# 570 "parser_cocci_menhir.ml" ) | TContext | TConstant | TComma of ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 561 "parser_cocci_menhir.ml" +# 577 "parser_cocci_menhir.ml" ) | TChar of ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 566 "parser_cocci_menhir.ml" +# 582 "parser_cocci_menhir.ml" ) | TCase of ( # 57 "parser_cocci_menhir.mly" (Data.clt) -# 571 "parser_cocci_menhir.ml" +# 587 "parser_cocci_menhir.ml" ) | TCPar0 of ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 576 "parser_cocci_menhir.ml" +# 592 "parser_cocci_menhir.ml" ) | TCPar of ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 581 "parser_cocci_menhir.ml" +# 597 "parser_cocci_menhir.ml" ) | TCEllipsis of ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 586 "parser_cocci_menhir.ml" +# 602 "parser_cocci_menhir.ml" ) | TCCro of ( # 101 "parser_cocci_menhir.mly" (Data.clt) -# 591 "parser_cocci_menhir.ml" +# 607 "parser_cocci_menhir.ml" ) | TCBrace of ( # 100 "parser_cocci_menhir.mly" (Data.clt) -# 596 "parser_cocci_menhir.ml" +# 612 "parser_cocci_menhir.ml" ) | TBreak of ( # 58 "parser_cocci_menhir.mly" (Data.clt) -# 601 "parser_cocci_menhir.ml" +# 617 "parser_cocci_menhir.ml" ) | TBang0 | TBang of ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 607 "parser_cocci_menhir.ml" +# 623 "parser_cocci_menhir.ml" ) | TAssign of ( # 107 "parser_cocci_menhir.mly" (Ast_cocci.assignOp * Data.clt) -# 612 "parser_cocci_menhir.ml" +# 628 "parser_cocci_menhir.ml" ) | TArobArob | TArob | TAny of ( # 73 "parser_cocci_menhir.mly" (Data.clt) -# 619 "parser_cocci_menhir.ml" +# 635 "parser_cocci_menhir.ml" ) | TAndLog of ( # 89 "parser_cocci_menhir.mly" (Data.clt) -# 624 "parser_cocci_menhir.ml" +# 640 "parser_cocci_menhir.ml" ) | TAnd of ( # 92 "parser_cocci_menhir.mly" (Data.clt) -# 629 "parser_cocci_menhir.ml" +# 645 "parser_cocci_menhir.ml" ) | EOF @@ -644,276 +660,284 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct fun _tok -> match _tok with | EOF -> - 162 + 166 | TAnd _ -> - 161 + 165 | TAndLog _ -> - 160 + 164 | TAny _ -> - 159 + 163 | TArob -> - 158 + 162 | TArobArob -> - 157 + 161 | TAssign _ -> - 156 + 160 | TBang _ -> - 155 + 159 | TBang0 -> - 154 + 158 | TBreak _ -> - 153 + 157 | TCBrace _ -> - 152 + 156 | TCCro _ -> - 151 + 155 | TCEllipsis _ -> - 150 + 154 | TCPar _ -> - 149 + 153 | TCPar0 _ -> - 148 + 152 | TCase _ -> - 147 + 151 | TChar _ -> - 146 + 150 | TComma _ -> - 145 + 149 | TConstant -> - 144 + 148 | TContext -> - 143 + 147 | TContinue _ -> - 142 + 146 | TDec _ -> - 141 + 145 | TDeclarer -> - 140 + 144 | TDeclarerId _ -> - 139 + 143 | TDefault _ -> - 138 + 142 | TDefine _ -> - 137 + 141 | TDefineParam _ -> - 136 + 140 | TDepends -> - 135 + 139 | TDisable -> - 134 + 138 | TDmOp _ -> - 133 + 137 | TDo _ -> - 132 + 136 | TDot _ -> - 131 + 135 | TDotDot _ -> - 130 + 134 | TEllipsis _ -> - 129 + 133 | TElse _ -> - 128 + 132 | TEq _ -> - 127 + 131 | TEqEq _ -> - 126 + 130 | TError -> - 125 + 129 | TEver -> - 124 + 128 | TExists -> - 123 + 127 | TExpression -> - 122 + 126 | TExtends -> - 121 + 125 | TFloat _ -> - 120 + 124 | TFor _ -> - 119 + 123 | TForall -> - 118 + 122 | TFresh -> - 117 + 121 | TFunDecl _ -> - 116 + 120 | TFunction -> - 115 + 119 | TGoto _ -> - 114 + 118 | TIdExpression -> - 113 + 117 | TIdent _ -> - 112 + 116 | TIdentifier -> - 111 + 115 | TIf _ -> - 110 + 114 | TInc _ -> - 109 + 113 | TIncludeL _ -> - 108 + 112 | TIncludeNL _ -> - 107 + 111 | TInt _ -> - 106 + 110 | TInvalid -> - 105 + 109 | TIso -> - 104 + 108 | TIsoArgExpression -> - 103 + 107 | TIsoDeclaration -> - 102 + 106 | TIsoExpression -> - 101 + 105 | TIsoStatement -> - 100 + 104 | TIsoTestExpression -> - 99 + 103 | TIsoTopLevel -> - 98 + 102 | TIsoType -> - 97 + 101 | TIterator -> - 96 + 100 | TIteratorId _ -> - 95 + 99 | TLineEnd _ -> - 94 + 98 | TLocal -> - 93 + 97 | TLogOp _ -> - 92 + 96 | TMPtVirg -> - 91 + 95 | TMetaConst _ -> - 90 + 94 | TMetaDeclarer _ -> - 89 + 93 | TMetaErr _ -> - 88 + 92 | TMetaExp _ -> - 87 + 91 | TMetaExpList _ -> - 86 + 90 | TMetaFunc _ -> - 85 + 89 | TMetaId _ -> - 84 + 88 | TMetaIdExp _ -> - 83 + 87 | TMetaIterator _ -> - 82 + 86 | TMetaLocalFunc _ -> - 81 + 85 | TMetaLocalIdExp _ -> - 80 + 84 | TMetaParam _ -> - 79 + 83 | TMetaParamList _ -> - 78 + 82 | TMetaPos _ -> - 77 + 81 | TMetaStm _ -> - 76 + 80 | TMetaStmList _ -> - 75 + 79 | TMetaType _ -> - 74 + 78 | TMid0 _ -> - 73 + 77 | TMinus _ -> - 72 + 76 | TMinusFile _ -> - 71 + 75 | TMul _ -> - 70 + 74 | TName -> - 69 + 73 | TNever -> - 68 + 72 | TNotEq _ -> - 67 + 71 | TNothing -> - 66 + 70 | TOBrace _ -> - 65 + 69 | TOCro _ -> - 64 + 68 | TOEllipsis _ -> - 63 + 67 + | TOInit _ -> + 66 | TOPar _ -> - 62 + 65 | TOPar0 _ -> - 61 + 64 | TOn -> - 60 + 63 | TOr _ -> - 59 + 62 | TOrLog _ -> - 58 + 61 | TPArob -> - 57 + 60 | TPCEllipsis _ -> - 56 + 59 | TPOEllipsis _ -> - 55 + 58 | TParameter -> - 54 + 57 | TPathIsoFile _ -> - 53 + 56 | TPlus _ -> - 52 + 55 | TPlus0 -> - 51 + 54 | TPlusFile _ -> - 50 + 53 | TPosAny -> - 49 + 52 | TPosition -> - 48 + 51 | TPragma _ -> - 47 + 50 | TPtVirg _ -> - 46 + 49 | TPtrOp _ -> - 45 + 48 | TPure -> - 44 + 47 | TReturn _ -> - 43 + 46 | TReverse -> - 42 + 45 | TRightIso -> - 41 + 44 | TRuleName _ -> - 40 + 43 + | TScript -> + 42 | TScriptData _ -> - 39 + 41 | TShOp _ -> - 38 + 40 | TSizeof _ -> - 37 + 39 | TStatement -> - 36 + 38 | TStrict _ -> - 35 + 37 | TString _ -> - 34 + 36 | TSwitch _ -> - 33 + 35 | TTilde _ -> - 32 + 34 | TType -> - 31 + 33 | TTypeId _ -> - 30 + 32 | TTypedef -> - 29 + 31 | TUsing -> - 28 + 30 | TWhen _ -> + 29 + | TWhenFalse _ -> + 28 + | TWhenTrue _ -> 27 | TWhile _ -> 26 @@ -1174,6 +1198,8 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct Obj.repr _v | TOEllipsis _v -> Obj.repr _v + | TOInit _v -> + Obj.repr _v | TOPar _v -> Obj.repr _v | TOPar0 _v -> @@ -1220,6 +1246,8 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct Obj.repr () | TRuleName _v -> Obj.repr _v + | TScript -> + Obj.repr () | TScriptData _v -> Obj.repr _v | TShOp _v -> @@ -1246,6 +1274,10 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct Obj.repr () | TWhen _v -> Obj.repr _v + | TWhenFalse _v -> + Obj.repr _v + | TWhenTrue _v -> + Obj.repr _v | TWhile _v -> Obj.repr _v | TWhy _v -> @@ -1300,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\213\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\249\0029\000\000\002\247\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\252\000\000\002S\000\000\000\000\002\246\002\248\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\245\000\000\002\220\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\250\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\221\002\219\000\000\002@\002\218\000\000\002[\000\000\000\000\001\189\000\000\001i\001\171\000\000\000\000\002Z\000\000\002\237\002Y\002X\002W\002V\002U\002Q\000\000\000\000\002R\000\000\002T\000\000\000\000\002\234\002(\000\000\000\000\002+\000\000\000\000\002.\000\000\000\000\002)\002,\000\000\002*\002-\002\\\002P\002\235\002\233\002\232\002\236\000\000\000\000\000\000\000g\000h\000\000\000\000\000W\000\000\000V\000\227\000\000\001\205\000\000\000\000\000\000\000\000\000\000\000\210\001\211\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\188\000\000\001g\001\170\000\000\000\000\000d\000\000\002\252\000\000\000\000\001\206\000\000\000\000\002\223\002\222\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\225\000\151\000\000\000\000\000n\000o\001\224\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\160\001\194\000\000\000\148\000\155\000\000\001\196\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\216\000\000\000\189\002\215\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\241\002/\000\000\000\000\0022\000\000\000\000\0025\000\000\000\000\0020\0023\000\000\0021\0024\002i\002]\002\242\002\240\002\239\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\244\002\243\000\000\002\172\000\000\002\171\000\000\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\230\002L\002K\002J\002I\002H\002D\000\000\000\000\002E\000\000\002G\000\000\000\000\002\227\002!\000\000\000\000\002$\000\000\000\000\002'\000\000\000\000\002\"\002%\000\000\002#\002&\002O\002C\002\228\002\226\002\225\002\229\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\198\000\000\002\205\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\199\000\167\000\000\002\200\000\000\002\207\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\208\002\209\000\000\002\210\000\000\002\211\000\000\001&\002\166\000\000\000\000\001\193\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\190\000\000\000\248\000\000\000\249\000\000\001k\001\173\000\000\000\000\000\000\001\201\000\000\001\199\000\000\000\000\001\203\001\197\000\000\001\204\001\198\000\000\002\179\001\207\000\000\000\165\000\000\000\000\001\191\000\000\001m\001\174\000\000\002\254\000\000\002\250\000\000\002\251\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\234\000\000\000\000\001\238\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\000\000\001\228\000\000\000\000\001\231\000\000\000\000\000\000\001\235\000\000\000\000\001\239\000\000\000\000\001\192\000\000\000\000\001\232\000\000\000\000\001\236\002z\001\229\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\240\000\000\000\000\001\243\000\000\002{\000\000\000\000\000\000\000\000\001\242\000\000\001\226\000\000\001\227\000\000\000\000\001\230\000\000\000\000\000\000\001\233\000\000\000\000\001\237\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\248\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\221\001\220\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\217\001\216\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\215\001\214\001\129\002u\000\000\000\127\000\000\000\000\002\156\000\000\000\000\000\000\000\000\001\219\001\218\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\001\187\000\000\000\000\000\000\000\000\002\201\002\212\000\000\002\202\000\000\002\203\001\127\000\000\001\177\001\185\000\000\000\000\000\000\000\000\001\223\000\000\000\000\000l\000m\000\000\000\000\000\000\001\222\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\213\000\000\002\214\000\000\000\000\001\210\001\208\000\000\001\209\000\008\000\000\000\t\000\000\002\011\002\012\002\n\000\000\000\000\002\t\000\000\000\n\000\000\002\014\002\015\002\013\000\000\000\000\000\000\000\000\002\003\000\000\000\000\002\005\000\000\001\255\000\000\002\001\000\000\002\006\000\000\002\007\002\000\001\254\002\017\001\137\000\000\002\008\000\000\002\019\000\000\002\018\000\000\002\020\000\000\002y\000\011\000\000\000\000\000\229\000\012\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\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") + (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") let error = - (163, "\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\000\000\000\000\004\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\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\001\252\000\000\000\000\000\000\000=j\184\001\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\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000@0\128\000 \152\019\000\128 \001\000\000\019!\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\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\002\000\128\000\004\000 \000\000\000\000\000\000\000\000\000\000\000%Q\128 \024@\000XL\t\128@\016\017\000\128\000\t\144\197\235U\192\008\002\000\000\016\128\128\000\000\000\002\000\001\000\000\000\000\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\000\000\000\000\018(\192\000\000 \000 $\004\192 \000\008\128@\000\004\192b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\002@\016\000\000\132\004\000\000\000\000\016\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=j\184\001\000@\000\002\016\016\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\128\000\000\008\000\000\000\000\000\000\245\170\224\004\001\000\000\008@@\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\004\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\000\000\132\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\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\128\000 \000\000\000\000\000\000\000@\000\017\000\000\000\000\000\005 \000H8\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\002\144\000$\028\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\001\n@\000\144p(\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\002A\192\1607h\000\t \016\001\008\004\016\000\000\000\005 \000H8\020\006\237\000\001$\004\002\000!\000\130z\213p\002\164\128\t\007\002\160\221\160\000$\128\128@\004 \016OZ\174\000T\144\001 \224T\027\180\000\004\144\016\008\000\132\002\008\000\000\000B\144\000$\028\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\n@\000\144p(\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\002A\192\1607h\000\t \000\001\008\004\016\000\000\000\005 \000H8\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\000R\000\004\131\129@n\208\000\018@@ \002\016\008 \000\000\000\n@\000\144p(\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\005 \000H8\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\020\128\001 \224P\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\000R\000\004\131\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\018\000\0180M\156\150\000\000P\004 \000;\160\"xw\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\001\235U\192\n\146\000$\028\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 \131\001,\000\000\160\000\000\000v@\004\208\238\000\000\000\001H\000\018\014\005\001\187@\000I\001\000\128\008@ \128\000\000\144\000\144\130lD\176\000\002\128 \000\001\217\000\019\195\184\000\000\000\005 \000H8\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\144\000\144\130lD\176\000\002\128 \000\001\153\000\019\193\184\000\000\000\005 \000H8\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\000H\000HA6\"X\000\001@\016\000\000\204\128\t\224\220\000\000\000\002\144\000$\028\n\003v\128\000\146\002\001\000\016\128A\000\000\001 \001!\004\216\137`\000\005\000@\000\0032\000'\131p\000\000\000\n@\000\144p(\013\218\000\002H\008\004\000B\001\004\000\000\004\128\004\132\019b%\128\000\020\001\000\000\012\200\000\158\013\192\000\000\000)\000\002A\192\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\164\000\t\007\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\002\144\000$\028\n\003v\128\000\146\002\001\000\016\128A\000\000\001 \001!\004\216\137`\000\005\000@\000\0032\000'\131p\000\000\000\n@\000\144p(\013\218\000\002H\008\004\000B\001\004\000\000\004\128\004\132\019b%\128\000\020\001\000\000\012\200\000\158\013\192\000\000\000)\000\002A\192\1607h\000\t \016\001\008\004\016\000\000\018\000\018\016M\136\150\000\000P\004\000\0003 \002x7\000\000\000\000\164\000\t\007\002\128\221\160\000$\128\128@\004 \016@\000\000H\000HA6\"X\000\001@\016\000\000\204\128\t\224\220\000\000\000\002\144\000$\028\n\003v\128\000\146\002\001\000\016\128A\000\000\001 \001!\004\216\137`\000\005\000@\000\0032\000'\131p\000\000\000\n@\000\144p(\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@\000\000\000\000\000\000\000)\000\002A\192\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\144p(\013\218\000\002H\008\004\000B\001\004\000\000\004\128\004\132\019b%\128\000\020\001\000\000\012\200\000\158\013\192\000\000\000)\000\002A\192\1607h\000\t \016\001\008\004\016\000\000\018\000\018\016M\136\150\000\000P\004\000\0003 \002x7\000\000\000\000\164\000\t\007\002\128\221\160\000$\128\128@\004 \016@\000\000H\000HA6\"X\000\001@\016\000\000\204\128\t\224\220\000\000\000\002\144\000$\028\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\001H\000\018\014\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\008\006\000\000\004\019\000\000\000\004\004\000 \000\002d\001\001*\140\001\000\194\000\002\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\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\011\244\224\008\006\016\000\020\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\000u\170\160\004\001\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\008\000\001\000\194\000\000\130`L\002\000\128\128\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\001\016\000=j\184\001R@\004\131\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\001H\000\018\014\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\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\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\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\004\000\000\000\000\000\n@\000\144p(\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\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\015Z\174\000T\144\001 \224T\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\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\n@\000\144p(\013\218\000\002H\008\000\000B\001\004\000\000\000\001H\000\018\014\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\005 \000H8\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\020\128\001 \224P\027\180\000\004\144\016\000\000\132\002\008\000\000\000\002\144\000$\028\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\004\128\004\136\017e%\000\000\016\001\008\000\006\168\008\134\017\192\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\000z\213p\002\164\128\t\007\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\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\000R\000\004\131\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\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\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\000z\213p\002\164\128\t\007\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\128\000\000\000\000\002\144\000$\028\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\004\128\004\128\017`%\000\000\016\001\000\000\006\136\000\134\017\192\000\000\000)\000\002A\192\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\164\000\t\007\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\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\001\000\000\000\000\000\000\000\000\000\128\000\004\000\000\000\000\004)\000\002A\192\1607h\000\t \000\001\008\004\016\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\t\007\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\n@\000\144p(\013\218\000\002H\008\000\000B\001\004\000\000\000\000\000\000\001\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\001 \001 \004X\t@\000\004\000@\000\001\"\000!\128p\000\000\000\n@\000\144p(\013\218\000\002H\008\000\000B\001\004\000\000\004\128\004\128\017`%\000\000\016\001\000\000\004\136\000\134\001\192\000\000\000)\000\002A\192\1607h\000\t \000\001\008\004\016\000\000\018\000\018\000E\128\148\000\000@\004\000\000\018 \002\024\007\000\000\000\000\164\000\t\007\002\128\221\160\000$\128\128\000\004 \016@\000\000H\000H\001\022\002P\000\001\000\016\000\000H\128\008`\028\000\000\000\002\144\000$\028\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\n@\000\144p(\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\002A\192\1607h\000\t \000\001\008\004\016\000\000\018\000\018\000E\128\148\000\000@\004\000\000\018 \002\024\007\000\000\000\000\164\000\t\007\002\128\221\160\000$\128\128\000\004 \016@\000\000H\000H\001\022\002P\000\001\000\016\000\000H\128\008`\028\000\000\000\002\144\000$\028\n\003v\128\000\146\002\000\000\016\128A\000\000\001 \001 \004X\t@\000\004\000@\000\001\"\000!\128p\000\000\000\n@\000\144p(\013\218\000\002H\008\000\000B\001\004\000\000\004\128\004\128\017`%\000\000\016\001\000\000\004\136\000\134\001\192\000\000\000)\000\002A\192\1607h\000\t \000\001\008\004\016\000\000\018\000\018\000E\128\148\000\000@\004\000\000\018 \002\024\007\000\000\000\000\164\000\t\007\002\128\221\160\000$\128\128`\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\002\144\000$\028\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\n@\000\144p(\013\218\000\002H\008\000\000B\001\004\000\000\004\128\004\128\017`%\000\000\016\001\000\000\004\136\000\134\001\192\000\000\000)\000\002A\192\1607h\000\t \000\001\008\004\016\000\000\018\000\018\000E\128\148\000\000@\004\000\000\018 \002\024\007\000\000\000\000\164\000\t\007\002\128\221\160\000$\128\128\000\004 \016@\000\000H\000H\001\022\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 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\016\000\000\000\000\000\000\000\000\002\000\003\214\171\128\016\004\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\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\000\000\000\001H\000\018\014\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\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\020\128\001 \224P\027\180\000\004\144\016\000\000\132\002\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\000\000\000\000\000\000\000\000\007\173W\000*H\000\144p*\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\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\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\001\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\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\t\020`\000\000\016\000\016\018\002`\016\000\004@ \000\002`1\001\"\140\000\000\002\000\002\000@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\008\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\004\000\000\000\000\000\000\000\000\000\000\000\000\030\181\\\000\128 \000\001\000\008\192\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\016\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\001\016\000=j\184\001\000@\000\002\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\016\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\001\000\000\000\016\000\000\000\000\128\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000=j\184\001\000@\000\002\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\004@\000\245\170\224\004\001\000\000\008\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\008\000\000\000\128\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\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\128\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\016\004\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\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\008\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\000z\213p\002\000\128\000\004 \000\000\000\000\128\000\000\000\000\128\015Z\174\000@\016\000\000\132\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\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\014\181T\000\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\000\004\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\149F\000\128a\000\001a0&\001\000@D\002\000\000&C\023\173W\000 \008\000\000B\002\000\000\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\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\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\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\023\173W\000 \008\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\030\181\\\000\128 \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\000\000\000\000\000 \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\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\007\255_\130.I\000\128f+\143\222\016\007\234\024\000\141b\005\004\002E\024\000\000\000\000\004\004\000\152\000\000\001\016\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\003\214\171\128\016\004\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\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=j\184\001\000@\000\002\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\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\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\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\002A\192\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 \228\016\008\006B\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\002\144\000$\028\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\002\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\008\000\000\000\003\255\175\193\023$\128H:\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\020\128\001\000\192P\027\180\000\012\144\016\000\000\132\002\008\000\000\000\002\144\000 \024\n\003v\128\001\146\002\000\000\016\128A=j\184\001R@\004\131\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@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\005 \000@0\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\005 \000@0\020\006\237\000\003$\004\000\000!\000\130\000\000\000\000\164\000\t\007\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\002\144\000 \024\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\n@\000\128`(\013\218\000\006H\008\000\000B\001\004\000\000\000\001H\000\016\012\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\002@\002F\t\179\146\192\000\n\000\132\000\007T\004\n\014\224\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=j\184\001R@\004\131\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@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\002A\192\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\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\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$ \155\017,\000\000\160\008\000\000t@\000\160\238\000\000\000\001H\000\018\014\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\005 \000H8\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\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\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\000H\000HA6\"X\000\001@\016\000\000\200\128\001@\220\000\000\000\002\144\000 \024\n\003v\128\001\146\002\000\000\016\128A\000\000\001 \001!\004\216\137`\000\005\000@\000\003\"\000\005\003p\000\000\000\n@\000\128`(\013\218\000\006H\008\000\000B\001\004\000\000\004\128\004\132\019b%\128\000\020\001\000\000\012\136\000\020\013\192\000\000\000)\000\002\001\128\1607h\000\025 \000\001\008\004\016\000\000\018\000\018\016M\136\150\000\000P\004\000\0002 \000P7\000\000\000\000\164\000\008\006\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\002\144\000 \024\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\n@\000\128`(\013\218\000\006H\008\000\000B\001\004\000\000\004\128\004\132\019b%\128\000\020\001\000\000\012\136\000\020\013\192\000\000\000)\000\002\001\128\1607h\000\025 \000\001\008\004\016\000\000\018\000\018\016M\136\150\000\000P\004\000\0002 \000P7\000\000\000\000\164\000\008\006\002\128\221\160\000d\128\128\000\004 \016@\000\000H\000HA6\"X\000\001@\016\000\000\200\128\001@\220\000\000\000\002\144\000 \024\n\003v\128\001\146\002\000\000\016\128A\000\000\001 \001!\004\216\137`\000\005\000@\000\003\"\000\005\003p\000\000\000\n@\000\128`(\013\218\000\006H\008\000\000B\001\004\000\000\004\128\004\132\019b%\128\000\020\001\000\000\012\136\000\020\013\192\000\000\000)\000\002A\192\1607h\000\t \024\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\164\000\008\006\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\002\144\000 \024\n\003v\128\001\146\002\000\000\016\128A\000\000\001 \001!\004\216\137`\000\005\000@\000\003\"\000\005\003p\000\000\000\n@\000\128`(\013\218\000\006H\008\000\000B\001\004\000\000\004\128\004\132\019b%\128\000\020\001\000\000\012\136\000\020\013\192\000\000\000)\000\002\001\128\1607h\000\025 \000\001\008\004\016\000\000\018\000\018\016M\136\150\000\000P\004\000\0002 \000P7z\213p\002\164\128\t\007\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\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\n@ \144p(\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\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\127\245\2482\228\144\008\006b\184\253\225\000~\161\128\008\214 P@\000\000\000\002\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?\250\252\017rH\004\003!\\~\240\128?P\192\004k\016('\255_\130.I\000\144t/\143\222\016\007\234\024\004\141b\133\004\255\235\240e\201 \016\012\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\003\255\191\225\151$\128@3\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\015\254\191\004\\\146\001\000\204W\031\188 \015\2120\001\026\196\n\t\255\215\224\139\146@$\029\011\227\247\132\001\250\134\001#X\161A?\250\252\017rH\004\131\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\018\000\0180M\156\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\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\018\014\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\001\000\000\000\000\001\007 \128@2\020G\237\008\003\245\012\000F1\002\130\000\000\000 \228\016\008\006B\136\253\161\000~\161\128\008\198 P@\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\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\001H\004\018\014\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \016H8\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\001 \224P\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\016\000\000\000\000\016r\008\004\003!D~\208\128?P\192\004c\016( \000\000\002\014A\000\128d(\143\218\016\007\234\024\000\140b\005\004\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\017\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\136\000\000\000\000\000\000\000\000\000\000\000\002\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\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\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000\144p(\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\008\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\002@\002\006\0082\146\192\000\008\000\004\000\0034\004H\008\192\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\001\235U\192\n\146\000$\028\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\002\000\000\000\000\002\014A\000\128d(\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\000\000\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?\250\252\017rH\004\131\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\255\239\248e\201 \016\012\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\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\001\235U\192\008\002\000\000\016\000\128\000\000\000\002\000\000\000\000\000\000\000\145F\000\000\000\000\001\001\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\245\170\224\004\001\000\000\008\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\001\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\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\001\000\000\000\000\000\000\000\000\000\000\128\000 \000\000\000\000\000\n@\000\144t(\013\218\000\002H\008\004\000B\001\004\000\000\000\001H\000\016\013\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\005 \000@0\020\006\237\000\003$\004\000\000!\000\130\000\000\000\000\164\000\t\007\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\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000=j\184\001R@\004\131\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@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\002\001\128\1607h\000\025 \000\001\008\004\016\000\000\000\005 \000H8\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\020\128\001\000\192P\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\000R\000\004\003\001@n\208\0002@@\000\002\016\008 \000\000\000\n@\000\128`(\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\016\000\016 A\148\148\000\000@\000 \000\016\160\"\000\006\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\001\235U\192\n\146\000$\028\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\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\001H\000\018\014\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\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\001\235U\192\n\146\000$\028\n\131v\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\002\000\000\000\000\000\n@\000\128`(\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\005 \000H8\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\001\000\000\000\000\000\020\128\001 \224P\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\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\n@\000\128l(\013\218\000\006H\008\001\000B\001\004\000\000\000\001H\000\016\013\133\001\187@\000\201\001\000\160\008A \128\000\000\004)\000\002\001\176\1607h\000\025 \020\001\008$\016\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\t\007B\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\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\002\000\000\000\000\000\000\000\000)\000\002\001\176\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\020\128\001\000\216P\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\131\001(\000\000\128\000\000\000 @\004\000\012\000\000\000\001H\000\016\012\005\001\187@\000\201\001\000\000\008@ \128\000\000\128\000\128\002\012\004\160\000\002\000\000\000\000\129\000\016\0000\000\000\000\005 \000@0\020\006\237\000\003$\004\000\000!\000\130\000\000\002\000\002\000\0080\018\128\000\008\000\000\000\002\004\000@\000\192\000\000\000\020\128\001\000\192P\027\180\000\012\144\016\000\000\132\002\008\000\000\008\000\008\000 \192J\000\000 \000\000\000\008\016\001\000\003\000\000\000\000R\000\004\003\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\001H\000\016\012\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\005 \000@0\020\006\237\000\003$\004\000\000!\000\130\000\000\002\000\002\000\0080\018\128\000\008\000\000\000\002\004\000@\000\192\000\000\000\020\128\001\000\192P\027\180\000\012\144\016\000\000\132\002\008\000\000\008\000\008\000 \192J\000\000 \000\000\000\008\016\001\000\003\000\000\000\000R\000\004\003\001@n\208\0002@@\000\002\016\008 \000\000 \000 \000\131\001(\000\000\128\000\000\000 @\004\000\012\000\000\000\001H\000\016\012\005\001\187@\000\201\001\000\000\008@ \128\000\000\128\000\128\002\012\004\160\000\002\000\000\000\000\129\000\016\0000\000\000\000\005 \000@0\020\006\237\000\003$\004\000\000!\000\130\000\000\002\000\002\000\0080\018\128\000\008\000\000\000\002\004\000@\000\192\000\000\000\020\128\001\000\192P\027\180\000\012\144\016\000\000\132\002\008\000\000\008\000\008\000 \192J\000\000 \000\000\000\008\016\001\000\003\000\000\000\000R\000\004\003\001@n\208\0002@@\000\002\016\008 \000\000 \000 \000\131\001(\000\000\128\000\000\000 @\004\000\012\000\000\000\001H\000\016\012\005\001\187@\000\201\001\000\000\008@ \128\000\000\128\000\128\002\012\004\160\000\002\000\000\000\000\129\000\016\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\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\n@\000\128l(\013\218\000\006H\008\005\000B\t\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\002\001\176\1607h\000\025 \020\001\008$\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\164\000\008\006\194\128\221\160\000d\128\128P\004 \144@\000\000\000\020\128\001\000\216P\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\001\000\000\000\000\000\000R\000\004\003a@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\002\144\000 \027\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\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\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\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\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\128\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\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\128\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000=j\184\001\000@\000\002\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\004\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\005 \000H:\020\006\237\000\001$\004\002\000!\000\130\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\0010\000\000\002\000\000\000\000\000\000\000\000\000\000\000\001\000\001@\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\004\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\030\181\\\000\128 \000\001\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\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\004\000\001\000\000\000\000\000\000R\000\004\131\161@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\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:\213P\002\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\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\004\000\001\000\000\000\000\000\000R\000\004\131\161@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\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\127\245\248\"\228\144\008\006b\184\253\227\000~\161\128\008\214 P@\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?\250\252\017rH\004\0031\\~\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\144\000\145\130l\228\176\002\002\128! \001\221\001\002\131\184\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\008\000\002\000\000\000\000\000\000\164\000\t\007B\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\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\128\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\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\128\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000=j\184\001\000@\000\002\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\004\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\005 \000H:\020\006\237\000\001$\004\002\000!\000\130\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\004\004\000\000\000\008\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\255\235\240E\201 \018\014\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\003\255\175\193\023$\128@3\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\000\000\000\000\000\000\000\000\000\000\001\235U\192\n\146\000$\028\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\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\128\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\000\002\000\000\000\000\000\000\000\000\000\000\000\000\015Z\174\000@\016\000\000\128\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\016\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\002\000\000\128\000\000\000\000\000)\000\002A\208\1607h\000\t \016\001\008\004\016\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\029j\168\001\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\128\000\000\008\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\002\000\000\128\000\000\000\000\000)\000\002A\208\1607h\000\t \016\001\008\004\016\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\255\235\240E\201 \018\014\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\002\001\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\001\255\215\224\139\146@$\029\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\004\192 \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\002\000\000\000\000\000\000\000\000\000@\000\000\000\000 \228\016\008\006B\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\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\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\016\000\000\002\000\000\000\000\000\000\000\000\000@\000\127\247\252\"\228\208\t\135B\248\253\227\000\254\169\132\200\246:\214`\000\000\004\028\130\001\000\200Q\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?\250\252\017rH\004\0031|~\240\128?P\192\004{\028h \000\000\000\000\000\000\016\016\000\000\000\000\000\000\000\004\000\000\000\000\255\235\240E\201 \016\012\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\016\008\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\015\254\191\004\\\146\001 \232_\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?\250\252\017rH\004\131\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\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\004\000\000\000\000\000\000\000\000\000\128\000\255\235\240E\201 \016\012\197\241\251\194\000\253C\000\017\172P\160\128\000\000\000\000\000\000@@\016\000\000\000\000\000\000\016\000\002\000\003\255\175\193\023$\128@3\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\001\000\128\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\255\235\240E\201 \018\014\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\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\008\000\000\001\0010\000\000\002\000\000\000\000 \000\000\000\000\000\000 \000\192\128\000\000\000\000@\000\000 \000\001\000\023\255_\130.I\000\128f+\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\016\128`@\000\000\000\000 \000\000\016\000\000\128\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\245\248\"\228\208\t\135B\184\253\225\000\254\161\128H\214\"Po\254\191\004\\\146\001\000\204W\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\007\255_\130.M\000\152t+\143\222\016\015\234\024\004\141b%\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\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\004\000\000\000\000\000\000\000\000\000\128\000\255\235\240E\201 \018\014\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\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\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 \016\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\031\253~\008\185$\002A\208\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\000\000\000\000\000\000\000\000\000\000\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\n\146@ \024\n\131w\128\001\146\002\000\000X\129A\000\000\000\000R\001\004\131\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\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\003\223\175\192\021$\128@0\021\006\239\000\003$\004\000\000\177\002\130\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\007\173W\000 \008\000\000@\002\000\000\000\000\008\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\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\164\000\t\007B\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\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\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\001\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000z\213p\002\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\128\000\000\000\000\000\000\008\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\n@\000\144t(\013\218\000\002H\008\004\000B\001\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\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\002\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\002\144\000$\029\n\003v\128\000\146\002\001\000\016\128A\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\000u\170\160\004\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\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\016\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\020\128\001 \232P\027\180\000\004\144\016\008\000\132\002\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\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\247\235\240\005I \016\012\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\018\000\0160A\148\150\000@@\000$\000\024\160 @F\000\000\000\000\000\002\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\002\144\000$\029\n\003v\128\000\146\002\001\000\016\128A\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\016\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\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\016\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000 \008\000\000@\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\008\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\164\000\t\007B\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\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\004\000\000\000\000\000\000\000\000\000\000\000\000\030\181\\\000\169 \002A\192\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\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\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\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\002A\208\1607h\000\t \016\001\008\004\016\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\007Z\170\000@\016\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 \000\000\002\000\000\000\000\000\000\000\000\000\000\000\001\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\001H\000\018\014\133\001\187@\000I\001\000\128\008@ \128\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\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\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\128\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\128\000\000\016\019\000\000\000 \000\000\000\002\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\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\128\000\000\000\000\000\004\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\000\000\000\000\000\000\000\000\000\000\127\245\248\"\228\144\008\006b\184\253\225\000~\161\128\008\214 P@\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\n@\000\144p(\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\031\253~\008\185$\002A\208\174?x@\031\168`\018=\1404\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\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\128B\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001\000\000\000\000\000\000\000_\253~\008\185$\002\001\152\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\127\245\248\"\228\144\008\006b\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\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\004\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\002A\192\1607h\000\t \000\001\008\004\016\000\000\000\000\002\000\000\000\000\000\000\000\004\000\000\000\000\000\000\001\000\000\000\000\164\000\t\007\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\002\144\000$\028\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\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\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 \228\016\008\006B\136\253\161\000~\161\128\008\198 P@\000\000\000\000\008\000\000\000\000\000\000\000\016\000\000\000\000\000\000\004\000\000\000\131\144@ \025\n#\246\132\001\250\134\000#\024\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\014A\000\128d(\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\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\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\144\000$\028\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\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\000\000\000\000\000\000\000\000\031\253~\000\128 \000\001\000\008\000\016\000\000 \000\000\004\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\000\000\000\000\000/\254\191\000@\016\000\000\128\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?\250\252\001\000@\000\002\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\002\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\020\128\001 \224P\027\180\000\004\144\016\000\000\132\002\008\000\000\000\000\001\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\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\030\181\\!\194\"$\129\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000p\136\136 D\002\000\000H\000\021B@\000\152\000\000\245\170\224\014\017\000\004\008\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@\000\008\004\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\001\000\000 \016\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\001\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\002\000\000\000\000\000\000\008\000\000\000 \000\004\002\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\001\000\000\001\000\000\000\000\000\000\004\000\000\000\000\000\000\001\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@\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\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\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\000p\136\128 D\002\000\000H\000\021B@\000\136\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\030\181\\\001\194 \000\129\016\008\000\001 \000U\t\000\002 \000\000\000@\000\008\004\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\002\000\000\000\000\000\000\008\000\000\000 \000\004\002\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\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\002\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\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\001\000\000 \016\000\000\000\000\000\000\000\000\016\000\128\000\000\000\000\000 \000\004\002\000\000\000\000\000\000@\000\002\000\016\000\001\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\008\004\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\008\000\001\000\128\000\000\128\000\000\016\000\000\128\004\000\000@\000\000\001\000\000 \016\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\004\000\000\004\000\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\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\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\001\235U\192\008\002\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\004\008\000\245\170\224\004\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\004\000\000\008\000\001\000\128\000\000\130\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\001@\000\000\000\000\000\000\004\000\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\002\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\016\000\000\016\000\000\000\000\000\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\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\002\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\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\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\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\002\000\000@ \000\000\001\000\000\000\000\000 \001\000\000\000\000\000\000@\000\008\004\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\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\128\000\016\008\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\008\004\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\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\004\000\000\000\000\000\000\000\004\000\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\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\002\000\000@ \000\000\000\128\000\000\000\000 \001\000\000\000\000\000\000@\000\008\004\000\000\004\128\000\000\128\000\004\000 \000\002\000\000\000\008\000\001\000\128\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\004\002\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\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\016\000\000\000\000\000\000@\000\000\001\000\000 \016\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\008\000\000\008\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\004\000\000\000\000\002\008\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\008\016\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\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\001\000\000 \016\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\008\000\000\000\000\000\000 \000\000\000\128\000\016\008\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\004\000\000\004\000\000\000\000\000\000\016\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\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\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\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\000\000\000\000\000\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\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\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\016\000\002\001\000\000\000\008\000\000\000\000\001\000\008\000\000\000\000\000\002\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\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=n\184\001\128@\000\002 \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\001\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\004\128\000\004\000\000 \001\000\000\016\000\000\000@\000\008\004\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\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\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\128\000\000\000\000\000\030\183\\\000\192 \000\001\016\136\000\000\000\000 \001\000\000\000\000\000\000@\000\008\004\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\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\004\002\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\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\008\004\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\001\000\000\001\000\000 \016\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\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\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\235U\194\028\"\"H\017\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\001H\000\018\014\007\001\187@\000I\001\000\128\008@ \128\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\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\001H\000\018\014\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\001\136\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\001\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\002\144\000$\028\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\004\016\000\000\000\000\001H\000\018\014\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\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\255\239\248E\201 \018\014\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\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?\251\254\017rH\004\131\161\\~\240\128?T\194$k\016+3\191}\192 \008\000\000\000\002\000\000\000\000\000\128\000\000\000\000\000\002E\024\000\000\000\000\000\004\000\000\000\000\000\016\000\000\000\000\000\014\253\247\000\128 \000\000\000\008\000\000\000\000\002\000\000\000\000\000\001\223\190\224\016\004\000\000\000\001\000\000\000\000\000@\000\000\000\000\000\001\"\140\000\000\000\000\000\002\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\145F\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\128\000\000\000\000\000\002E\024\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\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\030\253\255\000\128 \000\001\000\008\000\000\000\000\"\000\000\000\000\000\000\t\020`\000\000\000\000\016\000\000\000\000\000\000@\000\000\000\000\000\127\245\248\"\228\144\008\006b\184\253\225\000~\161\128\008\214 P@\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\000\000\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\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\031\253~\008\185$\002A\208\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\128\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\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\152\000\000\001\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\003\214\171\128\016\004\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\008\128\001\235U\192\008\002\000\000\016\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\004\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\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\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\136\000\030\181\\\000\128 \000\001\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\128\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000?\250\252\017rH\004\131\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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000H\163\000\000\000\000\000\128\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\016\008\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\015\254\191\004\\\146\001 \232W\031\188 \015\2120\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\001\000\000\000\000&\000\000\000@\002\000\000\000\003\016\000\000\000\000\016\016\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\002\144\000$\028\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\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\164\000\t\007\002\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\196\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000?\251\254\017rH\004\131\161\220~\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000\000\000\000\015\254\255\132\\\146\001 \232W\031\188 \015\2130\137\026\196\n\205\255\223\240\139\146@ \025\138\227\247\132\001\250\166\016#X\129Y\128\000\000\000\000\000\000\128\128\000\000\000\000\000\000\002 \000\000\003\023\255\127\194.I\000\128f+\143\222\016\007\234\152@\141b\005f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253\255\008\185$\002A\208\174?x@\031\170a\0185\136\021\155\255\191\225\023$\128@3\021\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\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?\251\254\017rH\004\131\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\255\239\248E\201 \018\014\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\003\255\191\225\023$\128H:\021\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\003\255\191\225\023$\128H:\021\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\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?\251\254\017rH\004\131\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\000\000\000\000\000\004\000\000\000\000\152\000\000\001\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\008\000 \000\000\000\000\000\000\000\000\130p\003\000\000\002\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\128\002\000\000\000\000\000\000\000\000\000'\0020\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\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\128\000\002\008\000\000\000\000\000\000\008\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\002\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\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\128\000\000\000\000\000\000\000\000\000\000\016\002\000\000\000\000\000@\000\001\004\000\000\000\000\000\000\004\000\000\000\008\000\000\000\000\128\002\000\002\000\000\000\000\000\000\000#\000 \000@(\000\000\000\000\001\000\000\004\016\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\008\000 \000 \000\000\000\000\000\000\0020\002\000\000\002\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\004\000\016\000\000\000\000\000\000\000\000\001\024\001\128\000\001\000\000\000\000\128\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\008\000\000\000\000\000\000\000\000\000\140\000\128\016\000\128\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\128\000\000\000\000\000\000\000\000\008\192\008\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\004`\000\000\000\004\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\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\0020\003\000\000\002\000\000\000\001\000\004\000\000\000\000\000\000\000\000\000F\000@\000\000@\000\000\000\000\000\128\000\000\000\000\000\000\000\000\008\192\008\000\000\008\000\000\000\000\000\016\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\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\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\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\008\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") + (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") let action = - ((16, "\000r\000r\000\000\000\000\000\211\000\000\000\000\000\000\000r\000\000\000m$\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\031\000\018\000\000$\152\"\212\024z\000\016%\018\000\000\000\000\000\000\000\000\021>\000\130\024z\000m\024z\000\000\000`\000\000\024z\000\000\000m\000\000\000\000\001\0203,\000\000\000\0004\208\000\0005~\001.3,3,\016X\016X5~\000\0007,\000\0007\1723,\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0005\2543,\000\000\000\0005\254\000\0005\254\000\0005\254\000\000\000\000\000\000\018\160\000m\000\000\016X\000\000*\2083,\022\2263,\000\000\000\000\000\000\000\000\000\000\000\000\025\1763,\000\000\026\1563,\026\2423,\027\2223,\000\0003,\000\0003,\02843,\029 3,\029v3,\030b3,\030\1843,\000\1783,\000\000\000\000\000\000\000\000\000\0003,\031\1643,\031\2503, \2303,\000\000\000\0003,\000\000\"\168$\222\000\000\000\000\000\182\000\000\000\000\000\000\024\026\000\000\000\000\000\000\000\000\000\000\025r\000<\000\000$\222\000\000\000\166\016X\000\0003,\000\222\000\000\000\000\000m\000\000\000\000\000\000\000\000\001\030\000\000\000\000\002.\000\000\000\0113,\000\000\000\011\000\000\000\000\016X\002f\000\000\002\204\000\000\000\000\000\000\000\000\000\000\000\000\000\0008,3,\000\0008,\000\0008,8,\000\000\000\000'\"\000m\000\000\016X\003\020\000\0003,\003\018\000\000\000\000\000m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016X\003>7,\000\000\000\000<\1523,\000\0003,\000\000\000\000\003\132\000\000\000p6\172\004B3,\004\018\000\000\000\0007,\000p\000\000\000\000\000\000\000\000\000\000'\1647,>B7,>\1427,>\2187,\000\0007,\000\0007,?&7,?r7,?\1907,@\n7,@V3,\003\2287,\000\0007,@\1627,@\2387,A:\003\208\000\000\004 \000\000\000\138$\152\000\000\000\138\000\000\000\000\00423,\000\000\004\166\000\0007,\004\246\000\000\016X\004T\000\000\000\000\004T\000\000\000\000\001\020\000\000\005(\000\000$\222A\204\005N\005L\000m\004\194\005tC\018\001\148\000\000\000\000\002\028C:\000\000\000\000\000\000\005x\005l\001$\005~C\018\002\\C\018\000\000\000\000\001\"\000\000\000\000\004\238\000\000\005\018\005\198C\018\005@\000\000\000\000\002\028\000\000\005X\006,\000\000C\218\026P\000\000\000m\006.\000\000(\250\000m\006B\000\000\000\000#\158\024z\005p\000\000\005\234\000\000\005z\000\000\001*$\152\000\000$\152\000\000\005h\000\000\001*\000\000\012\166\016\n\0064C\018\005\136\006X\000\000$\152\000\004\000\000\006\\\000\000\000\000\000\000\000\000\000\000\000\000\006@3,\005\148\016\252\006F3,\005\154\006D\002\012\005\212\006R\000\0008\1729,\016X\005\178\000\000\005\1829,\000\000\000\000\000\000\000\000\000\000\000\000\000\0009\1723,\000\0009\172\000\0009\1729\172\000\000\000\000\022\140\000m\000\000\016X\005\198\000\0003,\005\208\000\000\000\000\000m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000%\1843,\000\0003,\000\000\005\224\000\000\000\011\000\000\000\000\000\000\000\000\000\000+&9,,\0089,,^9,-@9,\000\0009,\000\0009,-\1509,.x9,.\2069,/\1769,0\0063,\006\0149,\000\0009,0\2329,1>9,2 \016X\005\236\000\000\000\0003,\000\000\006\188\000\000\001B\002\134\000\000\006R\006R\001B\000\000\001B\000\000\012\166\006R\006R\000\000\000\000\000\000\020\162\000\000\000\000\000\000\000\000\006\1583,\005\242\016\252\017\190\000m\006\194\000\000\006\1663\208\006\2123\208\006\2163,\006\014\016\252\016\252\003\170\002\244\001\"\000\000\000\000\000\000\002\244\000\000\003\146\001\128\000\000\000\000\006\020\000\000\000\000\000\000\006\234\000\000\006\236\000\000\000\000\007\028\006\2383,\006F\007\022\000\000\018\246\007\000\016X\006T\016\252\000\000\000\000\006|\000\000\000\011\000\000\003\202\000\000\001B\000\000\000\000\006\206\000\000&X\016\n\007\020C\018\006h\007R\000\000\000m\000\000\001\2083\208'\238\000\000:,3,\006\154\000\000\016X\006\156\000\000\006\158\000\000\000\000\000\000\000\000\000\000\000\000\000\000:\1723,\000\000:\172\000\000:\172:\172\000\000\000\000C\184\000m\000\000\016X\006\162\000\0003,\006\160\000\000\000\000\000m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016X\006\166;,\000\000\000\0003,\000i3,\006\188\006\240'\238(\178&\134\007j3\208\0076\000\000\000\000\000m\006\248'\238\000\000\006\244'\238\000\000\000\000\015x;,\019\250;,#\012;,)H;,\000\000;,\000\000;,*\012;,5P;,6~;,8\254;,9~;,9\254;,:~;,<\214\000\000\000\000\006\202\000\000\006\218)v\000\000*:\006\222*:2~\006\224*:\000\000\000\000\000\000\000\000\000\000\007\008'\238\000\000\000\000\006\218\000\000\007\176\000\000\000m\000\000\000\186\007\178\000\000\006p\007\144\000m\006\246\007\182C\018\007\n\000p\000\0003\208\007\230\000\000\000_\005\166\007h\007\208C\018\007$\007\244\000\000\002\1403\208\007\250\000\000\007\252\000\000(\250\000m\00363\208\007\254\000\000\008\000\000\000\011b\0009\000\000\011b\000\000\000\000\019\164\004z3\208\008\002\000\000\008\004\000\000\000\000\0076\007\214\000m\007J\007\252C\018\007R\002\016\000\0003\208\008\"\000\000\003H\000\000\000\000\007\150\000\000\011b\000\000\008\006\016X\007^\0080\000\000\000\022\000\000\008\018C\018\007h\0088\000\000\004\1523\208\008>\000\000\008@\000\000(\250\000m\004\1723\208\008D\000\000\008F\000\000\000\000\000\000\007\150\000\000\000\000\000\008\000\000\006R\000\000\000\254\000\000\000\000\001\030\017\190\000\000\001\030\000\000\000\000\007|\000\000\000\011\000\003\016\252\000\000\003\202\0009\003\202\000\000\000\008\000\000\006R\000\000\006R\000\000\000\000\000\000\007~\000\000\000\000\007\140\000\000\002\146\005\014\001\012\003\202\000\000\000\000\000\000\001\210\000\000\006R\000\000\002\146\000\000\000\000\014n\005\002\012\166\000\000\012\212\000\000\008\218\012\166\000\000\000\000\008\218\000\000\000\000\007\138\000\000\000\000\007\144\000\000\003j\006R\000\000\003j\000\000\000\000\008\002\000\000\000\008\000\000\006R\000\000\000\000\000\000\015 4P\000\000\008d\000\000\015 \008f\000\000\008j\000\000&X\000m\003>\000\0003\208\008n\000\000\008X\008J\000m\007\200\008zC\018\007\220\003\248\000\0003\208\008\172\000\000\000_\004\202\000\0003\208\008\180\000\000(\250\000m\005\012\000\0003\208\008\184\000\000\004$\015 \000\000\019\164\005\176\000\0003\208\008\202\000\000\000\000\000\000\008\172\008\170\000m\008\018\008\194C\018\008\022\005\184\000\0003\208\008\240\000\000\000X\000\000\008\210\016X\008&\008\246\000\000\000\148\000\000\005\216\000\0003\208\008\254\000\000(\250\000m\005\240\000\0003\208\t\004\000\000\004$\000\000\000\000\008<\000\000\000X\015\016\008\176\000\000\000\000\000\000\008\186\000\000\001N\002\134\000\000\012\166\t\022\000\000\000\0003,\008\140\006R\000\000\008b\000\000\002\012\000\000\000\000\003V\012\166\000\000\012\166\000\000\008P\000\000\003V\000\0007,\003\1667,\000\0007,\000\000\008R\000\000\003\166\000\000\016\252\003\190\016\252\000\000\016\252\000\000\008V\000\000\003\190\000\0007,\003\166\008X\000\000<\028\000m\004\018<\028\000\000<\028\000\000\008Z\000\000\004\018\000\0007,\003\166\008^\000\000\000\000\021\230\000\000\000\000\000\000\000\000\000\000\025\020!\130\000\000\003<\000\000\004\128\000\000\000\000\008\158\000m\000\000\000\000\000\000\002\138\004\128\000\000\002\146\003\184\003\184\000\000\000\179\003\184\000\000\008v\000\000\000\000\000\000\000\000\000\000\000\000\008\242\000\000\"L\000\000$\152\004\128\000\000\003n\004\128\000\000\t\002\000\000\004\128\t\006\000\000\007\202\012\192\t\n\000\000\t\012\000\000\t\190\012\192\004\128\008\164\004\128\t\"\000\000\t$\000\000\t*\000\000$\152\000\000\003d$\152\000\000\008\180\0032\000\000\000F\004\128\000\000\004\138\004\128\000\000\002\222\001\216\000m\000\000\000\204\000m\000\000\008\194\000\000\000\000\000\000\000\000\tB\000\000\004\128\004\128\tJ\000\000\tR\000\000\004\128\tT\000\000\004\128\t\\\000\000\t6\004\128\tb\000\000\004\174\021:\004\128\t\008\004\128\t\150\000\000\t\152\000\000\000\000\004\164\004\128\000\000\003t\002n\002n\000\000\000\000\000\000\004d\002n\000\000\t \000\000\000\000\000\000\000\000\004\128\000\000\004\184\004\128\000\000\004\"\002\208\000m\t$\000\000\000\000\000\000\000\000\t\160\000\000\t\162\000\000\004\128\t\180\000\000\0076\004\128\t\182\000\000\t\186\000\000>\028\tl\t\150\008~\004\128\t\194\000\000\000\000\t\196\000\000\t\156>\028\004\128\t\202\000\000\004\128\t\204\000\000\t\206\000\000\008\244\tZ\004\128\t\212\000\000\t\214\000\000\000m\tR\000\000\000\000\021\230\000\000\000\000\0026\n,\000\000\000\000\001\017\000\000\000\000\000\0003,\001\194\nf\t\152\n\0287,\000\000\004\1627,\000\000\tx\000\000\000\000\000\000\000\000\000\000\002\134\000\000\001\013\000\000\000\000\000\000\003\202B~\001zB~B~\001z\000\000\000\000\005\242\005\242\005\242\005\242\000\000\000\000\000\000\000\000\000\000\000\000\000\000<\152\006p\013\232\0009\000\000\000\000\003H\000\000\007\150\000\000\000\000\001\194\000\000\000\000\t\192\000R\n4Dz\000\000\004\178E\024\000\000\000\000\n>\n0\000m\000\000\000m\000\000\004\178\000\000\004\180Dz\000\000\000\000\t\160\nR\006R\t\166\000\000\0076\003H\000\000\007\150\000\000\000\254\002\132\000\000\000\000\n>\000\000\000\000\0026\000\000\004\002\000\000\000\000\000\0003,\001\194\000\000\002\134\000\000\0040\000\000\000\000\000\000\005\014\n\030\005\208\n\030\000\000\006R\n\030\000\000\005\208\000\000\006R\000\000\006R\000\000\006R\000\000\000\000\000\000\000\000\000\000\001\194\000\000\006R\000\000\005\208\000\000\006R\000\000\003\134\000\000\000\000\008\218\n\138\000\000\000\000\008\218\000m\003\020\nf\002p\000\000\002p\n\144\000\000\n\146\000\000\n\148\000\000\000\000\002\216\002p\012\164\002p\000\000\000\000\006\232\t\170\000\000\008,\t\014\n\164\tp\n\164\000\000\000\000\nP\000m\000\000\005D\t\254\000\000\000\000\000\000\001\230\000\000\t\176\000\000\000\000\000\000\008,\t\014\nP\005D\001\230\t\178\000\000\000m\000\000\n\176\n\176\t\254\000m\nR\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\182\n\141\n\141\n\141\n\141\n\141\n\141\n\141\n\141\n\141\020\011\020\015\020c\020g\n\141\020\019\008\002\020k\n\141\000\210\n\141\n\141\n\141\001.\008\022\n\141\011\174\001:\n\141\n\141\t*\n\141\000.\006\018\016:\016b\016\138\016\154\016\198\t*\n\141\000\023\000\027\n\141\n\141\017F\012\158\000\162\008\002\n\141\n\141\n\141\nA\n\141\000\162\011-\008\022\002\242\n\141\0055\n\141\n\141\n\141\n\141\n\141\0066\nF\000\146\n\141\n\141\n\141\n\141\n\141\n\141\000\006\n\141\n\141\n\141\n\141\015R\000\n\001.\n\141\n\141\011\174\001:\011-\011-\011F\000:\t6\011\154\n\141\n\141\n\141\n\141\n\141\n\141\n\141\000\014\n\141\005\197\n\141\000\162\n\141\000z\002\242\n\141\n\141\015n\000~\001.\000\162\n\141\0016\001:\013F\n\141\011-\011-\n\141\000\174\t6\011-\n\141\n\141\n\141\n\141\n)\n\141\n\141\004\158\005\157\nI\n\141\n\141\n\141\007\213\n\141\018\014\n\141\n\141\000\162\n\141\001.\n\141\n\141\011\174\001:\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\012\158\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\011\158\005=\003\218\000\162\005\205\008\006\008\002\005\242\005\205\005\157\005\205\005\205\005\205\0055\008\022\005\205\0055\000\194\005\205\000\222\0055\005\205\0055\005\197\003\233\001.\0055\0055\011\174\001:\005\205\005e\005e\013\"\005\149\000\250\002\026\nI\013\022\005\205\005\205\nI\nI\005\205\005\205\002\174\000\210\000\210\005\205\003i\005\205\005\205\005\205\005\205\005\205\011f\000\162\002r\005\205\005\205\005\205\005\205\005\205\005\205\0186\005\205\005\205\005\205\005\205\006\229\005\250\nI\005\205\005\205\000\162\000\162\002b\nI\n\025\002\190\t6\0055\005=\005\205\005\205\005\205\005\205\005\205\005\205\000\146\005\205\008\162\005\205\000\210\005\205\n)\t*\005\205\005\205\003\233\005=\006\229\006\229\005\205\005=\008\002\006\229\007\t\005\189\002\222\005\205\007\t\005J\008\022\005\205\005\205\005\205\005\205\018*\005\205\005\205\000\162\0055\003\233\005\205\005\205\005\205\012Z\005m\015\218\005\205\005\205\005\237\005\205\005\237\005\205\005\205\005\237\008\154\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\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\002U\000\162\005\237\020\030\002U\022f\005\237\019\250\005\237\005\237\005\237\008\n\tr\005\237\021w\t6\005\237\005\237\022\238\005\237\005\237\005\237\021{\005\237\005\237\n)\005\237\022j\005\237\018\214\011f\005\237\021~\022n\003\233\005\229\005\229\005\237\005\237\005\237\005\229\005\237\005\237\008\014\012^\005\237\005\237\019\250\005\237\0176\005\237\005\237\005\237\006z\004\217\013\150\005\237\005\237\005\237\005\237\005\237\005\237\015\242\005\237\005\237\005\237\005\237\005E\005.\nq\018\218\005\237\005U\006\021\0055\022\142\000\162\005\237\019\"\007\217\002\234\005\237\005\237\005\237\005\237\005\237\005\237\018&\005\237\022v\005\237\005\237\005\237\0055\014B\005\237\005\237\005\237\007\217\014F\005V\005\237\0055\014J\002y\005\237\011\206\007\217\005\237\003\014\n)\006\005\005\237\005\237\014~\005\237\017\002\005\237\005\237\t*\022~\016\026\005\237\017*\011f\000\162\0055\006\021\008\002\005\237\005\165\005\237\002b\005\237\005\237\015\198\008\022\005\237\005\237\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\012\158\000^\020r\000b\006N\000f\000j\000n\006R\020z\003\022\016B\018\210\014\022\006V\006\005\022\158\011-\000r\017\018\000\226\006f\006\130\016j\0055\006\134\008\158\022\150\000v\007\217\005]\007\242\022^\nQ\016\"\001.\005\253\0055\011\174\001:\000\238\011\238\007\217\008\002\017:\014\130\003j\003v\011-\008*\006\142\008\022\t6\008.\013R\003!\000\210\014\174\001\"\011f\001&\003\197\000\134\t2\0086\016\166\000\162\003\170\006\162\001.\008:\006\166\008>\001:\016J\006\170\006\174\008B\006\178\008=\011-\011-\017\246\008F\000\162\011-\016r\017\138\005\173\n!\005\253\017\n\005\133\006\182\006\186\008J\008N\006\190\008R\019\030\000\162\008\154\008f\003\210\003\161\008\186\014\246\008r\006\198\003\001\017\014\008=\008=\005\245\018\158\003\226\008=\t6\003\234\017\018\008\146\002\253\n)\006\013\008\150\008\210\003\197\t>\016\174\006\202\008\214\004j\005}\017\014\006\206\003\197\003\197\n)\014\178\004\142\003\197\008\222\017\018\006\210\005\141\005\245\005\245\n)\018^\001j\005\245\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\014\198\000^\020r\000b\006N\000f\000j\000n\006R\020z\000:\021\151\021\155\na\006V\006\013\021\159\004\150\000r\005\181\000\226\006f\006\130\007\029\005u\006\134\nY\004\182\000v\000\162\004\194\007\242\004\206\014\226\021\187\021\191\ni\008\002\007\029\021\195\000\238\012\"\017\030\008\002\004\218\008\022\004\230\004\250\018\234\008*\006\142\008\022\000\162\008.\013\154\n9\012\186\022\218\001\"\011f\001&\003\213\000\134\t2\0086\017\030\012\218\018\026\006\162\001.\008:\006\166\008>\001:\011f\006\170\006\174\008B\006\178\0206\018\198\014\202\005\n\008F\011f\n1\007\029\021\n\021:\005\014\019\018\005M\002m\006\182\006\186\008J\008N\006\190\008R\005\022\000\162\005\026\008f\005B\003\161\005F\005N\008r\006\198\006F\004q\t6\006J\006\029\014\230\015\006\020\146\t6\006N\015>\008\146\005r\006R\020\150\008\150\008\210\004\005\t>\004q\006\202\008\214\t*\007\029\022\226\006\206\015v\003\213\003\129\022\230\005z\008\002\008\222\005~\006\210\007\029\006\029\006\029\015\146\008\022\001j\006\029\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\005\134\000^\020r\000b\006N\000f\000j\000n\006R\020z\006F\003\129\005\154\006J\006V\005\158\005\182\020\146\000r\006N\000\226\006f\006\130\006R\020\150\006\134\005\198\005\218\000v\004q\005\226\007\242\005\234\006\007\015\n\006\030\006&\006*\015B\006>\000\238\006Z\006b\008\002\006j\006r\006v\004q\008\005\008\018\006\142\008\022\t6\008.\015z\006~\003\181\006\150\001\"\006\158\001&\003\241\000\134\0082\0086\011~\015\150\006\246\006\162\001.\008:\006\166\008>\001:\007\002\006\170\006\174\008B\006\178\007J\008\005\008\005\0115\008F\007\194\008\005\007\234\007\254\008V\008^\008n\003%\008v\006\182\006\186\008J\008N\006\190\008R\008~\000\162\008\134\008f\008\142\003\161\003%\008\202\008r\006\198\006F\008\218\008\226\006J\008\013\017\n\008\238\020\146\t6\006N\003\181\008\146\022\142\006R\020\150\008\150\008\210\003\241\t>\008\242\006\202\008\214\008\250\008\254\017\014\006\206\003\241\003\241\t\n\t\018\t\"\003\241\008\222\017\018\006\210\tF\008\013\008\013\tV\t^\001j\008\013\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\tb\000^\012>\000b\006N\000f\000j\000n\006R\019Z\t\138\004m\t\150\t\158\006V\t\242\t\254\n2\000r\003%\000\226\006f\006\130\003%\003%\006\134\017\170\004\001\000v\004m\nN\007\242\nR\nb\nj\003%\nz\n\134\011\n\011\018\000\238\011\"\011.\008\002\011J\017\014\011Z\011b\011v\008\018\006\142\008\022\000\162\008.\017\018\011\130\003\181\011\138\001\"\003%\001&\022\150\000\134\0082\0086\017\030\011\142\011\150\006\162\001.\008:\006\166\008>\001:\011\166\006\170\006\174\008B\006\178\011\186\011\194\011\198\0115\008F\011\214\011\222\011\246\011\254\012*\0122\012B\003!\004m\006\182\006\186\008J\008N\006\190\008R\012J\000\162\012N\008f\012V\012f\003!\012\138\008r\006\198\012\146\004m\012\150\012\166\0115\012\174\012\178\004a\t6\012\194\012\202\008\146\012\226\012\234\013:\008\150\008\210\000\162\t>\013\130\006\202\008\214\013\142\014\002\014\014\006\206\004a\014.\014Z\014f\017\030\014n\008\222\014\138\006\210\004a\0115\0115\014\146\014\150\001j\0115\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\014\158\000^\014\162\000b\006N\000f\000j\000n\006R\t\185\014\170\014\186\004a\017\n\006V\014\210\003\141\014\238\000r\003!\000\226\006f\006\130\003!\003!\006\134\015\018\015\"\000v\007%\003\141\007\242\017\014\t\185\015&\003!\022^\015.\0152\015:\000\238\017\018\022\182\008\002\007%\015J\015Z\015b\015f\008\018\006\142\008\022\015\130\008.\004a\015\158\005\213\015\178\001\"\003!\001&\015\194\000\134\0082\0086\019\194\015\210\004a\006\162\001.\008:\006\166\008>\001:\015\234\006\170\006\174\008B\006\178\015\250\016\006\016/\016W\008F\016\127\016\151\016\187\t\185\016\211\017\022\017R\017o\007%\006\182\006\186\008J\008N\006\190\008R\017\151\000\162\017\163\008f\017\179\017\187\n\017\003\141\008r\006\198\022F\003\141\003\141\017\206\000\162\017\194\017\215\017\223\t6\022V\017\231\008\146\018\002\003\141\003\141\008\150\008\210\017\030\t>\018B\006\202\008\214\018W\005\213\017\014\006\206\018g\005\213\005\213\007%\018o\018{\008\222\017\018\006\210\018\135\018\142\003\141\018\151\005\213\001j\007%\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\018\170\000^\020r\000b\006N\000f\000j\000n\006R\020z\005\213\018\179\018\187\018\246\006V\019*\019?\019G\000r\n\017\000\226\006f\006\130\n\017\n\017\006\134\019S\019c\000v\019k\019v\007\242\019z\019\135\019\147\n\017\019\154\019\167\019\179\019\187\000\238\019\198\019\207\019\215\019\227\019\254\022\190\020\"\020&\008*\006\142\020*\000\162\008.\021\206\005\221\020B\020\246\001\"\n\017\001&\020\254\000\134\t2\0086\017\030\021\026\021\030\006\162\001.\008:\006\166\008>\001:\021J\006\170\006\174\008B\006\178\021N\021V\021\131\022J\008F\022b\022r\022z\022\130\022\171\022\186\022\222\022\247\023\027\006\182\006\186\008J\008N\006\190\008R\023*\000\162\023.\008f\0232\003\161\023;\000\000\008r\006\198\000\000\000\000\000\000\000\000\007\241\000\000\000\000\000\000\000\000\000\000\000\000\008\146\000\000\000\000\000\000\008\150\008\210\000\000\t>\000\000\006\202\008\214\005\221\000\000\000\000\006\206\005\221\005\221\000\000\000\000\000\000\000\000\008\222\000\000\006\210\000\000\007\241\007\241\022\206\000\000\001j\007\241\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\000\000\000^\000\000\000b\006N\000f\000j\000n\006R\005\221\000\000\000\000\000\000\000\000\006V\000\000\000\000\000\000\000r\000\000\000\226\006f\006\130\000\000\000\000\006\134\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\008*\006\142\000\000\000\000\008.\012\006\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\134\t2\0086\000\000\000\000\000\000\006\162\001.\008:\006\166\008>\001:\000\000\006\170\006\174\008B\006\178\000\000\000\000\000\000\011\017\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\008f\000\000\000\000\000\000\000\000\008r\006\198\000\000\000\000\000\000\000\000\011\017\000\000\000\000\000\000\000\000\000\000\000\000\008\146\000\000\000\000\000\000\008\150\008\210\000\000\t>\000\000\006\202\008\214\000\000\000\000\000\000\006\206\000\000\000\000\000\000\000\000\000\000\000\000\008\222\000\000\006\210\000\000\011\017\011\017\000\000\000\000\001j\011\017\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\017\n\006V\003\029\000\000\000\000\000r\000\000\000\226\006f\006\130\000\000\000\000\006\134\000\000\000\000\000v\003\029\000\000\007\242\017\014\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\238\017\018\000\000\000\000\000\000\003\029\000\000\000\000\000\000\008*\006\142\000\000\007\029\008.\013\206\000\000\000\000\t*\001\"\000\000\001&\000\000\000\134\t2\0086\017\198\008\002\007\029\006\162\001.\008:\006\166\008>\001:\008\022\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\t\197\006\182\006\186\008J\008N\006\190\008R\000\000\000\162\000\000\008f\000\000\000\000\003\029\000\000\008r\006\198\003\029\003\029\000\000\000\000\000\162\000\000\007\029\000\000\000\000\000\000\000\000\008\146\003\029\000\000\000\000\008\150\008\210\017\030\t>\000\000\006\202\008\214\000\000\000\000\000\000\006\206\000\000\003\029\000\000\000\000\000\000\t6\008\222\000\000\006\210\000\000\003\029\t\197\022\150\000\000\001j\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\007\029\000^\000\000\000b\006N\000f\000j\000n\006R\000\000\000\000\000\000\007\029\000\000\006V\000\000\000\000\000\000\000r\000\000\000\226\006f\006\130\000\000\000\000\006\134\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\008*\006\142\000\000\000\000\008.\020\198\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\134\t2\0086\000\000\000\000\000\000\006\162\001.\008:\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\012\158\008f\000\000\000\000\000\000\000\000\008r\006\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\146\000\000\000\000\000\000\008\150\008\210\000\000\t>\004\158\006\202\008\214\000\000\000\000\000\000\006\206\000\000\001.\000\000\000\000\011\174\001:\008\222\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\000\000\162\000\000\000\000\000\000\000\000\000\000\000\000\000r\000\000\000\226\000\000\006\130\000\000\000\000\006\134\015n\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\000\000\000\000\000\000\005\149\000\000\014^\006\142\000\000\000\000\004\158\n\150\000\000\000\000\000\000\001\"\000\000\001&\001.\000\134\000\000\011\174\001:\000\000\000\000\006\162\001.\n\158\006\166\0016\001:\000\000\006\170\006\174\008B\006\178\000\000\000\000\000\000\000\000\000\000\n\166\000\000\000\000\000\000\000\000\000\000\n\230\n\238\000\162\006\182\006\186\000\000\000\000\006\190\000\000\n\198\000\162\000\000\n\174\000\000\n\190\000\000\000\000\000\000\006\198\000\000\000\000\000\000\0055\000\000\000\000\0055\000\000\000\000\000\000\0055\000\000\0055\000\000\000\000\n\206\0055\0055\t>\005\149\006\202\014b\000\000\000\000\000\000\006\206\000\000\000\000\000\000\000\000\000\000\000\000\014j\000\000\006\210\000\000\0002\0006\000F\000J\001j\000N\000\000\000R\000V\000\000\000Z\000\000\000^\n\214\000b\000\000\000f\000j\000n\000\000\n\182\000\000\0055\000\000\000\000\000\000\000\000\000\000\000\000\000r\000\146\000\226\004\169\000\230\000\000\000\000\000\234\000\000\000\000\000v\000\000\001.\000\000\000\000\0016\001:\000\000\n\246\n\222\000\000\000\000\000\238\000\000\000\000\000\242\000\000\000\000\000\000\000\000\000\000\001\006\001\002\001\n\000\000\000\000\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\162\000\134\000\000\000\000\0055\000\000\000\000\001*\001.\000\000\0012\0016\001:\001\142\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\006V\001N\000\000\000\000\000\162\000\000\000\226\006f\006\130\000\000\000\000\006\134\001V\000\000\000\000\000\000\000\000\007\242\000\000\000\000\000\000\001Z\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\000\000\000\000\000\000\000\001^\000\000\008b\006\142\000\000\001b\008.\000\000\003e\000\000\000\000\001\"\000\000\001&\001f\000\000\000\000\0086\000\000\000\000\001j\006\162\001.\008:\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\008f\000\000\000\000\000\000\000\000\008r\006\198\000\000\000\000\006V\000\000\000\000\000\000\000\000\000\000\000\226\006f\006\130\008\146\000\000\006\134\000\000\008\150\008\210\000\000\000\000\007\242\006\202\008\214\000\000\000\000\000\000\006\206\000\000\000\000\000\238\000\000\000\000\000\000\008\222\000\000\006\210\000\000\000\000\006\138\006\142\000\000\001j\008.\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\000\000\000\0086\000\000\000\000\000\000\006\162\001.\008:\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\008f\000\000\000\000\000\000\000\000\008r\006\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\146\000\000\000\000\011a\008\150\008\210\011a\000\000\000\000\006\202\008\214\000\000\000\000\000\000\006\206\000\000\000\000\000\000\000\000\011a\000\000\008\222\011a\006\210\000\000\000\000\001\130\011a\000\000\001j\000\000\000\000\000\000\011a\000\000\000\000\011a\011a\000\000\011a\011a\000\000\000\000\001\138\011a\002\182\004\001\000\000\011a\004\001\000\000\011a\000\000\011a\011a\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\001\000\000\000\000\000\000\000\000\000\000\000\000\004\001\004\001\000\000\000\000\011a\000\000\011a\004\001\000\000\000\000\000\000\000\000\000\000\004\001\004\001\000\000\011a\004\001\000\000\004\001\000\000\002\194\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\011a\011a\011a\000\000\011a\011a\002\198\000\000\011a\000\000\004\001\000\000\000\000\000\000\000\000\000\000\002\206\000\000\000\000\000\000\011a\000\000\000\000\011a\011a\011a\011a\004\001\000\000\000\000\004\001\011a\011a\011a\000\000\011a\011a\011a\000\000\000\000\000\000\000\000\000\000\004\001\004\001\004\001\004\001\000\000\004m\004\001\004\001\004\001\000\000\000\000\000\000\000\000\000\000\004\001\000\000\004\001\004\001\004\001\000\000\004\001\004\001\000\000\004\001\004\001\004\001\004\001\000\181\000\000\004\001\000\000\004\001\004\001\000\000\004\001\004\001\004\001\000\000\000\000\000\000\000\000\000\000\000\000\n\158\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\166\000\000\000\000\000\000\000\000\000\000\000\181\000\181\000\000\004\001\000\000\000\000\000\000\000\000\004\001\n\198\000\000\000\162\n\174\000\000\n\190\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\001\004\001\004\001\000\000\004\001\004m\004\001\000\000\004\001\000\000\n\206\000\000\000\000\000\000\000\000\000\000\004\001\000\000\000\000\000\000\000\000\000\000\000\000\004\001\004\005\004\001\000\000\004\005\000\000\000\000\000\000\004\001\004\001\004\001\000\000\004\001\004\001\004\001\000\000\000\000\004\005\000\000\000\000\004\005\n\214\000\000\000\000\004\005\004\005\000\000\000\000\n\182\000\000\000\000\004\005\000\000\000\000\004\005\004\005\000\000\004\005\004\005\000\000\000\181\004\005\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\181\n\222\000\000\003Q\003Q\003Q\003Q\000\000\003Q\000\000\003Q\003Q\017\n\003Q\000\000\003Q\004\005\003Q\004\005\003Q\003Q\003Q\000\000\000\000\000\000\000\000\000\000\000\000\004\005\000\170\000\000\017\014\003Q\004\005\000\000\000\000\000\000\000\000\000\000\000\000\017\018\000\000\003Q\000\000\000\000\000\000\000\000\000\000\000\000\004\005\004\005\004\005\000\000\004\005\004q\004\005\000\000\004\005\000\000\000\000\000\000\000\000\000\000\003Q\018\162\004\005\000\000\t\197\003Q\004\005\000\000\000\000\004\005\000\000\004\005\000\000\003Q\000\000\000\000\000\000\004\005\004\005\004\005\000\000\004\005\004\005\004\005\001=\001=\001=\001=\t\197\001=\000\000\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\222\000\000\000\162\000\000\003Q\001=\001=\001=\000\000\000\000\000\000\000\000\001=\000\000\000\000\017\030\001=\000\000\000\000\000\000\001=\000\000\000\000\000\000\001=\000\000\000\000\016\226\000\000\000\000\001=\000\000\000\000\000\000\000\000\t\197\000\000\001=\000\000\000\000\000\000\001=\000\000\000\000\003Q\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\001=\000\000\000\000\001=\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\181\000\000\000\000\011\181\000\000\000\000\001=\000\000\001=\000\000\001=\000\000\001=\000\000\000\000\000\000\011\181\001=\000\000\011\181\001=\000\000\000\000\006\230\011\181\000\000\000\000\000\000\000\000\000\000\011\181\000\000\000\000\011\181\011\181\001=\011\181\011\181\001=\001=\006\238\011\181\006\250\001\137\000\000\011\181\001\137\000\000\011\181\016\230\011\181\011\181\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\137\000\000\000\000\001\137\000\000\000\000\000\000\000\000\001\137\000\000\000\000\011\181\000\000\011\181\001\137\000\000\000\000\001\137\001\137\000\000\001\137\001\137\000\000\011\181\000\000\001\137\000\000\000\000\007\006\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\011\181\011\181\011\181\000\000\011\181\000\000\007\n\000\000\011\181\000\000\001\137\000\000\001\137\000\000\000\000\000\000\007\018\000\000\000\000\000\000\000\000\000\000\001\137\011\181\000\000\011\181\000\000\000\000\000\000\000\000\000\000\011\181\011\181\011\181\000\000\011\181\011\181\011\181\000\000\000\000\000\000\000\000\000\000\001\137\001\137\001\158\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\000\000\000\000\000\000\001\137\000\000\000\000\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\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\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\004%\004%\000\000\000\000\000\000\000\000\004%\000\000\000\000\0002\000\142\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\000\000\000^\004%\000b\004%\000f\000j\000n\000\000\000\000\004%\000\000\000\000\004%\004%\000\000\000\000\000\000\000r\000\000\000\000\004%\000\000\000\000\004%\004%\000\000\000\000\000v\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\130\000\000\000\000\004%\000\000\000\158\000\000\004%\000\000\000\000\000\000\000\000\000\000\000\134\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\004%\000\000\000\000\004%\004%\000\000\000\000\004%\000\000\t\181\t\181\t\181\004%\004%\000\000\000\162\t\181\004%\000\000\000\000\t\181\000\000\000\000\000\000\016\246\000\000\000\000\000\000\016\254\002\154\000F\000J\000\166\000N\t\181\000R\000V\000\000\000Z\000\000\000^\t\181\000b\000\000\000f\t\181\000n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\181\n\249\000\000\000r\000\000\000\000\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\t\181\000\000\000\000\t\181\000\000\000\000\000\000\001\190\000\000\000\000\002\018\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\181\000\000\t\181\000\000\t\181\001\202\t\181\000\000\002\001\000\000\000\134\t\181\000\000\002\001\t\181\000\000\000\000\000\000\000\000\001\210\000\000\000\000\002\001\002\001\000\000\0022\002:\000\000\000\000\t\181\002\001\000\000\017r\t\181\001\242\000\000\000\000\001\218\000\000\001\234\002\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\000\142\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\001\250\000^\002\001\000b\000\000\000f\000j\000n\000\000\000\000\000\000\000\000\002\001\000\000\000\000\000\000\000\000\000\000\000r\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000v\000\000\000\000\000\000\000\000\002\001\002\002\000\000\000\000\002\001\002\001\000\000\000\000\001\226\000\000\000\000\000\000\000\000\000\000\000\000\000}\000\130\000\000\000}\000\000\002\001\000\158\000\000\002\001\002\001\002\001\002\001\000\000\000\000\000\134\000\000\001\202\002\001\002\001\000}\002B\002\n\002\001\000\000\000}\000\000\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000}\000}\000\000\000}\000}\000\000\000\000\000\000\000}\000\000\000e\000\000\001\242\000e\000\000\001\218\000\000\001\234\000}\000\162\000\000\000\000\000\000\000\000\000\000\000\000\000e\000\000\000\000\000e\000\000\000\000\000\000\000\000\000e\000\000\000\166\001\250\000\000\000}\001\210\000\000\000\000\000e\000e\000\000\000e\000e\000\000\000}\000\000\000e\000\000\000\000\000\000\000e\000\000\000\000\001\218\002)\001\234\000e\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000}\002\002\000\000\000\000\000}\000}\000\000\000\000\001\226\000\000\000e\000\000\000e\000\000\000\000\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\000\000}\000}\000\000\000}\002\n\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\000a\000\000\000]\000a\000\000\001\218\000\000\000]\000]\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000a\000\000\000\000\000a\000\000\000\000\000\000\000\000\000a\000\000\000\000\000]\000\000\000]\000a\000\000\000\000\000a\000a\000\000\000a\000a\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]\000\000\000\000\000]\000]\000\000\000\000\001\226\000\000\000a\000\000\000a\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\000a\000a\000\000\000\000\000a\000a\000\000\000\000\001\226\000\000\000\000\000\000\000\000\000\000\000\000\000q\000\000\000\000\000q\000\000\000a\000\000\000\000\000a\000a\000a\000a\000\000\000\000\000\000\000\000\001\202\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\000q\000\000\000i\000\000\000q\000i\000\000\001\218\000\000\001\234\000q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\202\000\000\000\000\000i\000\000\000\000\000\000\000\000\000i\000\000\000\000\001\250\000\000\000q\001\210\000\000\000\000\000i\000i\000\000\000i\000i\000\000\000q\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\000\000\000\000\000\000\000\000\000\000\000q\000q\000\000\000\000\000q\000q\000\000\000\000\001\226\000\000\000i\000\000\000i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000q\000\000\000i\000q\000q\000q\000q\000\000\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\000i\000i\000\000\000\000\000i\000i\000\000\000\000\001\226\000\000\000\000\000\000\000\000\000\000\000\000\000m\000\000\000\000\000m\000\000\000i\000\000\000\000\000i\000i\000i\000i\000\000\000\000\000\000\000\000\001\202\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\000m\000\000\000u\000\000\000m\000u\000\000\001\218\000\000\001\234\000m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\202\000\000\000\000\000u\000\000\000\000\000\000\000\000\000u\000\000\000\000\001\250\000\000\000m\001\210\000\000\000\000\000u\000u\000\000\000u\000u\000\000\000m\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\000\000\000\000\000\000\000\000\000\000\000m\000m\000\000\000\000\000m\000m\000\000\000\000\001\226\000\000\001\250\000\000\000u\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000m\000\000\000u\000m\000m\000m\000m\000\000\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\000u\002\002\000\000\000\000\000u\000u\000\000\000\000\001\226\000\000\000\000\000\000\000\000\000\000\000\000\001\190\000\000\000\000\000\133\000\000\000u\000\000\000\000\000u\000u\000u\000u\000\000\000\000\000\000\000\000\001\202\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\133\000\000\001\190\000\000\001\242\000y\000\000\001\218\000\000\001\234\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\202\000\000\000\000\000y\000\000\000\000\000\000\000\000\000y\000\000\000\000\001\250\000\000\000\133\001\210\000\000\000\000\000y\000y\000\000\000y\000y\000\000\000\133\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\000\000\000\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\001\250\000\000\000y\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\133\000\000\000y\000\133\000\133\000\133\000\133\000\000\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\000y\002\002\000\000\000\000\000y\000y\000\000\000\000\001\226\000\000\000\000\000\000\000\000\000\000\000\000\001\190\000\000\000\000\000\129\000\000\000y\000\000\000\000\000y\000y\000y\000y\000\000\000\000\000\000\000\000\001\202\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\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\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\250\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\t\165\t\165\t\165\000\000\000\000\000\000\000\000\t\165\000\000\000\000\000\000\t\165\000\000\000\000\000\000\000\000\000\000\000\000\000\129\002\002\000\000\000\000\000\129\000\129\000\000\t\165\001\226\000\000\000\000\000\000\000\000\000\000\t\165\000\000\000\000\000\000\t\165\000\000\000\129\000\000\000\000\000\129\000\129\000\129\000\129\t\165\000\000\000\000\000\000\000\000\000\129\000\129\000\000\000\129\002\n\000\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\165\000\000\000\000\t\165\000\000\000\000\000\000\000\000\000\000\t\169\t\169\t\169\t\169\000\000\t\169\000\000\t\169\t\169\t\165\t\169\t\165\t\169\t\165\t\169\t\165\t\169\t\169\t\169\000\000\t\165\000\000\000\000\t\165\000\000\000\000\000\000\000\000\t\169\t\169\t\169\000\000\000\000\000\000\000\000\t\169\000\000\000\000\t\165\t\169\000\000\016\250\t\165\017v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\169\000\000\000\000\000\000\0055\000\000\000\000\t\169\000\000\000\000\000\000\t\169\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\169\004i\000\000\0055\004i\000\000\004i\000\000\004i\000\000\004i\000\000\0055\0055\004i\004i\000\000\000\000\000\000\t\169\000\000\000\000\t\169\000\000\000\000\004i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004i\004i\0055\t\169\000\000\t\169\004i\t\169\002b\t\169\000\157\0055\0055\000\000\t\169\000\000\000\000\t\169\000\000\000\000\000\000\000\000\004i\000\000\004i\000\138\000\157\000\000\000\000\000\000\004i\000\000\t\169\004i\004i\000\000\t\169\000\000\000\000\000\000\n\166\004i\0055\000\000\004i\004i\000\157\000\157\000\000\000\000\0055\000\000\000\000\000\000\004i\000\157\000\000\000\000\n\174\000\000\n\190\000\000\000\000\0055\004i\000\000\000\000\000\000\004Q\000\000\000\000\004Q\004i\004Q\000\000\004Q\004i\004Q\000\000\000\000\000\157\004Q\004Q\0055\000\000\004i\0055\0055\000\000\000\000\0055\000\000\004Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0055\004Q\004Q\000\000\000\000\004i\000\000\004Q\004i\004i\000\000\000\000\004i\000\000\000\157\000\000\000\000\004i\004i\000\000\000\000\n\182\004i\004Q\000\000\004Q\005\210\000\000\000\000\000\000\000\000\004Q\000\000\000\157\004Q\004Q\000\000\000\000\000\000\000\000\000\000\000\000\004Q\000\000\000\000\004Q\004Q\000\000\000\157\000\157\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\000\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\000\000\000\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\000\000b\000\000\000f\000j\000n\004Q\000\000\000\000\004Q\004Q\000\000\000\000\004Q\000\000\017~\000r\017\154\004Q\004Q\000\000\000\000\017\166\004Q\000\000\000\000\000v\000\000\0055\000\000\000\000\0055\000\000\0055\000\000\0055\000\000\0055\000\000\000\000\017\190\0055\0055\000\000\000\000\000\000\000\000\000\130\000\000\000\000\000\000\017\234\0055\000\000\0055\000\000\000\000\0055\000\000\000\000\000\134\0055\0055\0055\000\000\000\000\000\000\0055\0055\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018\n\000\000\000\000\018Z\0055\000\000\0055\000\000\000\000\000\000\000\000\000\000\002b\000\000\007M\0055\0055\000\000\018r\000\000\007\209\000\000\018~\0055\018\138\000\000\0055\0055\000\000\018\154\0055\000\000\019J\000\000\000\000\000\000\0055\000\000\000\146\000\000\000\000\007M\000\000\000\000\000\000\000\000\0055\019V\000\000\007M\000\000\019n\007M\007M\0055\000\000\000\000\000\000\0055\000\000\000\000\000\000\007M\000\000\000\000\000\000\000\000\0055\000\000\000\000\000\000\000\000\000\000\001\161\000\000\000\000\001\161\000\000\000\000\000\000\007M\000\000\000\000\000\000\0055\000\000\000\000\0055\000\000\001\161\0055\0055\001\161\007M\0055\000\000\000\000\001\161\000\000\0055\0055\000\000\000\000\001\161\0055\000\000\001\161\001\161\000\000\001\161\001\161\000\000\000\000\007M\001\161\000\000\007M\007M\001\161\000\000\000\000\001\161\000\000\001\161\001\161\007M\007M\000\000\000\000\000\000\007M\000\000\0002\tN\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\001\161\000^\001\161\000b\000\000\000f\000j\000n\000\000\000\000\000\000\000\000\001\161\000\000\000\000\000\000\000\000\000\000\000r\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000v\000\000\000\000\000\000\000\000\001\161\001\161\0076\000\000\001\161\n^\000\000\000\000\001\161\000\000\003I\000\000\003I\000\000\000\000\003I\000\130\000\000\000\000\000\000\000\000\000\000\000\000\001\161\000\000\001\161\000\000\000\000\000\000\000\134\003I\007>\001\161\001\161\000\000\001\161\001\161\001\161\000\000\003I\003I\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\162\003I\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\153\000\000\000\000\011\153\000\000\003I\003I\000\000\000\000\003I\000\000\000\000\003I\000\000\000\000\000\000\011\153\000\000\000\000\011\153\003I\000\000\000\000\003Z\000\000\000\000\000\000\000\000\000\000\003I\011\153\003I\000\000\000\000\011\153\000\000\011\153\011\153\000\000\000\000\003b\003I\003n\000\000\000\000\011\153\003I\000\000\011\153\000\000\011\153\000\000\003I\000\000\000\000\003I\000\000\000\000\000\000\000\000\000\000\003I\000\000\000\000\000\000\004\018\000\000\000\000\004b\000\000\011\153\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\026\011\153\000\000\002\t\000\000\000\000\003z\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\011\153\011\153\000\000\011\153\000\000\003~\004B\011\153\000\226\004*\tz\004:\000\000\t~\000\000\003\134\000\000\000\000\000\000\011\153\000\000\000\000\000\000\000\000\011\153\011\153\000\000\000\000\000\238\000\000\011\153\004J\000\000\000\000\011\153\011\153\011\153\t\130\n*\000\000\n>\nV\000\000\002\t\000\000\000\000\001\"\000\000\001&\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\162\001.\000\000\t\166\008>\001:\000\000\t\170\t\174\004R\t\178\000\000\002\t\000\000\000\000\000\000\0042\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\182\t\182\000\000\002\t\t\186\000\000\000\000\000\162\002\t\002\t\000\000\000\000\000\000\000\000\000\000\t\194\000\000\000\000\004\130\004Z\002\t\000\000\000\000\000\000\nZ\000\226\nr\tz\000\000\000\000\t~\002\154\000F\000J\000\000\000N\t\198\000R\000V\000\000\000Z\t\202\000^\000\000\000b\000\238\000f\011R\000n\000\000\t\206\000\000\000\000\000\000\t\130\n*\001j\n>\nV\000r\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\000\000\000\000v\000\000\000\000\000\000\t\162\001.\000\000\t\166\008>\001:\000\000\t\170\t\174\000\000\t\178\000\000\000\000\000\000\000\000\000\000\000\000\000\149\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\182\t\182\000\000\000\000\t\186\000\134\000\000\000\162\000\149\000\000\000\000\000\000\000\000\000\000\000\000\t\194\000\000\000\000\000\000\000\000\000\000\000\000\000\149\000\000\nZ\000\226\nr\tz\000\149\000\149\t~\000\000\000\000\000\000\000\000\000\000\t\198\000\149\000\000\000\000\n\174\t\202\000\149\000\162\000\000\000\238\000\000\n\254\000\000\000\000\t\206\000\000\000\000\000\000\t\130\n*\001j\n>\nV\000\000\000\000\000\000\000\149\001\"\000\000\001&\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\162\001.\000\000\t\166\008>\001:\000\000\t\170\t\174\000\000\t\178\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\149\000\000\006\182\t\182\000\000\000\000\t\186\n\182\000\000\000\162\000\153\000\000\000\000\000\000\000\000\000\000\000\000\t\194\000\000\000\149\000\000\000\000\000\000\000\000\000\153\000\000\nZ\000\226\nr\tz\000\153\000\153\t~\000\000\000\149\000\149\000\000\000\000\t\198\000\153\000\000\000\000\n\174\t\202\000\153\000\000\000\000\000\238\000\000\004\201\000\000\000\000\t\206\000\000\000\000\000\000\t\130\n*\001j\n>\nV\000\000\000\000\000\000\000\153\001\"\000\000\001&\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\162\001.\000\000\t\166\008>\001:\000\000\t\170\t\174\000\000\t\178\000\000\000\000\000\000\000\000\000\000\000\000\001\137\000\000\000\000\001\137\000\000\000\000\000\153\000\000\006\182\t\182\000\000\000\000\t\186\n\182\000\000\000\162\001\137\000\000\000\000\000\000\000\000\000\000\000\000\t\194\001\137\000\153\000\000\000\000\000\000\000\000\001\137\000\000\nZ\000\000\nr\000\000\001\137\001\137\000\000\000\000\000\153\000\153\000\000\007j\t\198\001\137\007\186\000\000\001\137\t\202\001\137\001\137\000\000\000\000\000\000\001\189\000\000\000\000\t\206\007r\000\000\000\000\002\017\000\000\001j\000\000\000\000\002\017\000\000\000\000\001\137\000\000\001\137\007z\000\000\000\000\002\017\002\017\000\000\007\202\007\210\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\137\001\137\001\150\000\000\001\137\001\137\000\000\000\000\001\137\000\000\007\162\000\000\002\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\137\000\000\002\017\001\137\001\137\000\000\001\137\000\000\000\000\000\000\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\002\017\007\170\000\000\000\000\002\017\000\000\000\000\000\000\007\138\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\002\017\000\000\002\017\007r\000\000\000\000\001%\000\000\000\000\002\017\002\017\001%\007\218\007\178\002\017\000\000\000\000\007z\000\000\000\000\001%\001%\000\000\001%\001%\000\000\000\000\000\000\001%\000\000\001\013\000\000\007\154\001\013\000\000\007\130\000\000\007\146\001%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\013\000\000\000\000\001\013\000\000\000\000\000\000\000\000\001\013\000\000\000\000\007\162\000\000\001%\007z\000\000\000\000\001\013\001\013\000\000\001\013\001\013\000\000\001%\000\000\001\013\000\000\000\000\000\000\001\013\000\000\000\000\007\130\000\000\007\146\001\013\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001%\007\170\000\000\000\000\001%\000\000\000\000\000\000\007\138\000\000\001\013\000\000\001\013\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\013\001%\000\000\001%\000\000\000\000\000\000\000\000\000\000\000\000\001%\001%\000\000\001%\007\178\001%\000\000\000\000\000\000\000\000\000\000\001\013\001\013\000\000\000\000\001\013\000\000\000\000\000\000\007\138\000\000\001\005\000\000\000\000\001\005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\013\000\000\001\013\001\005\000\000\000\000\001\005\000\000\000\000\001\013\001\013\001\005\001\013\001\013\001\013\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\005\000\000\001\t\000\000\001\005\001\t\000\000\007\130\000\000\001\005\001\005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\t\000\000\000\000\001\t\000\000\000\000\000\000\000\000\001\t\000\000\000\000\001\005\000\000\001\005\001\t\000\000\000\000\001\t\001\t\000\000\001\t\001\t\000\000\001\005\000\000\001\t\000\000\000\000\000\000\001\t\000\000\000\000\007\130\000\000\001\t\001\t\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\005\001\005\000\000\000\000\001\005\000\000\000\000\000\000\007\138\000\000\001\t\000\000\001\t\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\t\001\005\000\000\001\005\000\000\000\000\000\000\000\000\000\000\000\000\001\005\001\005\000\000\001\005\001\005\001\005\000\000\000\000\000\000\000\000\000\000\001\t\001\t\000\000\000\000\001\t\000\000\000\000\000\000\007\138\000\000\001\025\000\000\000\000\001\025\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\t\000\000\001\t\007r\000\000\000\000\001\025\000\000\000\000\001\t\001\t\001\025\001\t\001\t\001\t\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\001\025\000\000\001\017\000\000\001\025\001\017\000\000\007\130\000\000\007\146\001\025\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007r\000\000\000\000\001\017\000\000\000\000\000\000\000\000\001\017\000\000\000\000\007\162\000\000\001\025\007z\000\000\000\000\001\017\001\017\000\000\001\017\001\017\000\000\001\025\000\000\001\017\000\000\000\000\000\000\001\017\000\000\000\000\007\130\000\000\007\146\001\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\025\001\025\000\000\000\000\001\025\000\000\000\000\000\000\007\138\000\000\001\017\000\000\001\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\017\001\025\000\000\001\025\000\000\000\000\000\000\000\000\000\000\000\000\001\025\001\025\000\000\001\025\001\025\001\025\000\000\000\000\000\000\000\000\000\000\001\017\001\017\000\000\000\000\001\017\000\000\000\000\000\000\007\138\000\000\001\021\000\000\000\000\001\021\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\017\000\000\001\017\007r\000\000\000\000\001\021\000\000\000\000\001\017\001\017\001\021\001\017\001\017\001\017\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\001\021\000\000\001\029\000\000\001\021\001\029\000\000\007\130\000\000\007\146\001\021\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007r\000\000\000\000\001\029\000\000\000\000\000\000\000\000\001\029\000\000\000\000\007\162\000\000\001\021\007z\000\000\000\000\001\029\001\029\000\000\001\029\001\029\000\000\001\021\000\000\001\029\000\000\000\000\000\000\007\154\000\000\000\000\007\130\000\000\007\146\001\029\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\021\001\021\000\000\000\000\001\021\000\000\000\000\000\000\007\138\000\000\007\162\000\000\001\029\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\029\001\021\000\000\001\021\000\000\000\000\000\000\000\000\000\000\000\000\001\021\001\021\000\000\001\021\001\021\001\021\000\000\000\000\000\000\000\000\000\000\001\029\007\170\000\000\000\000\001\029\000\000\000\000\000\000\007\138\000\000\007j\000\000\000\000\001-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\029\000\000\001\029\007r\000\000\000\000\001-\000\000\000\000\001\029\001\029\001-\001\029\001\029\001\029\000\000\000\000\007z\000\000\000\000\001-\001-\000\000\001-\007\210\000\000\000\000\000\000\001-\000\000\007j\000\000\007\154\001!\000\000\007\130\000\000\007\146\001-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007r\000\000\000\000\001!\000\000\000\000\000\000\000\000\001!\000\000\000\000\007\162\000\000\001-\007z\000\000\000\000\001!\001!\000\000\001!\001!\000\000\001-\000\000\001!\000\000\000\000\000\000\007\154\000\000\000\000\007\130\000\000\007\146\001!\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001-\007\170\000\000\000\000\001-\000\000\000\000\000\000\007\138\000\000\007\162\000\000\001!\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001!\001-\000\000\001-\000\000\000\000\000\000\000\000\000\000\000\000\001-\001-\000\000\007\218\007\178\001-\000\000\000\000\000\000\000\000\000\000\001!\007\170\000\000\000\000\001!\000\000\000\000\000\000\007\138\000\000\007j\000\000\000\000\001)\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001!\000\000\001!\007r\000\000\000\000\001)\000\000\000\000\001!\001!\001)\001!\007\178\001!\000\000\000\000\007z\000\000\000\000\001)\001)\000\000\001)\007\210\000\000\000\000\000\000\001)\000\000\000\000\000\000\007\154\000\000\000\000\007\130\000\000\007\146\001)\000\000\000\000\000\000\000\000\000\000\000\226\000\000\tz\000\000\000\000\t~\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\000\238\000\000\000\000\000\000\000\000\001)\000\000\000\000\000\000\t\130\n*\000\000\n>\nV\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\000\000\000\000\000\000\000\001)\007\170\t\162\001.\001)\t\166\008>\001:\007\138\t\170\t\174\000\000\t\178\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\006\182\t\182\000\000\000\000\t\186\001)\001)\000\162\001)\007\178\001)\000\000\000\000\000\000\000\226\t\194\000\230\000\000\000\000\000\234\000\000\000\000\000\000\000\000\000\000\000\000\nr\000\000\007\246\000\000\000\000\000\000\000\000\000\000\000\238\000\000\t\198\000\242\000\000\000\000\000\000\t\202\000\000\000\254\001\002\001\n\000\000\001\201\000\000\000\000\t\206\000\000\001\"\000\000\001&\000\000\001j\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\226\000\000\000\230\000\000\000\000\000\234\001V\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\225\001Z\007\225\000\000\000\000\000\000\000\238\000\000\000\000\000\242\000\000\000\000\000\000\001^\000\000\000\254\001\002\001\n\001b\tv\000\000\007\225\000\000\007\225\001\"\000\000\001&\001f\000\000\000\000\000\000\000\000\000\000\001j\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\226\000\000\000\230\000\000\000\000\000\234\000\000\000\000\000\000\000\000\001J\000\000\000\000\001N\014R\000\000\000\162\000\000\000\000\000\000\000\238\000\000\000\000\000\242\001V\000\000\000\000\000\000\000\000\000\254\001\002\001\n\000\000\001Z\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\000\000\000\000\000\001^\000\000\000\000\001*\001.\001b\0012\0016\001:\000\000\001>\001B\000\000\001F\001f\000\000\000\000\000\000\000\000\000\226\001j\000\230\000\000\000\000\000\234\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\238\000\000\000\000\000\242\001V\000\000\000\000\000\000\000\000\000\254\004\210\001\n\000\000\001Z\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\000\000\000\000\000\001^\000\000\000\000\001*\001.\001b\0012\0016\001:\000\169\001>\001B\000\000\001F\001f\000\000\000\000\000\000\000\000\000\000\001j\000\000\000\000\000\000\000\000\n\158\000\000\000\000\000\000\001J\000\000\000\000\001N\000\000\000\000\000\162\000\000\000\246\000\000\n\166\000\000\000\000\007\233\001V\007\233\000\169\000\169\007\233\000\000\000\000\000\000\000\000\001Z\000\000\000\169\000\000\000\000\n\174\000\000\n\190\000\000\000\000\007\233\000\000\001^\007\233\000\000\000\000\000\000\001b\000\000\007\233\007\233\007\233\000\000\000\000\000\000\000\000\001f\n\206\007\233\000\000\007\233\000\000\001j\000\000\000\000\000\000\000\000\000\000\007\233\007\233\000\000\007\233\007\233\007\233\000\000\007\233\007\233\000\000\007\233\000\000\000\000\000\000\000\000\000\000\000\226\000\000\000\230\000\000\000\000\000\234\000\000\000\169\000\000\000\000\007\233\000\000\000\000\007\233\n\182\000\000\007\233\000\000\000\000\000\000\000\238\000\000\000\000\000\242\007\233\000\000\000\169\000\000\000\000\000\254\001R\001\n\000\000\000\000\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\169\000\169\000\000\000\000\007\233\000\000\000\000\001*\001.\007\233\0012\0016\001:\000\161\001>\001B\000\000\001F\007\233\000\000\000\000\000\000\000\000\000\000\007\233\000\000\000\000\000\000\000\000\n\158\000\000\000\000\000\000\001J\000\000\000\000\001N\000\000\000\000\000\162\000\000\003\222\000\000\n\166\000\000\000\000\003A\001V\003A\000\161\000\161\003A\000\000\000\000\000\000\000\000\001Z\000\000\000\161\000\000\000\000\n\174\000\000\n\190\000\000\000\000\003A\000\000\001^\003A\000\000\000\000\000\000\001b\000\000\003A\003A\003A\000\000\000\000\000\000\000\000\001f\000\161\003A\000\000\003A\000\000\001j\000\000\000\000\000\000\000\000\000\000\003A\003A\000\000\003A\003A\003A\000\000\003A\003A\000\000\003A\000\000\000\000\000\000\000\000\000\000\000\226\000\000\001\022\000\000\000\000\001\026\000\000\000\161\000\000\000\000\003A\000\000\000\000\003A\n\182\000\000\003A\000\000\000\000\000\000\000\238\000\000\000\000\000\242\003A\000\000\000\161\000\000\000\000\001\030\003\162\001\n\000\000\000\000\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\161\000\161\000\000\000\000\003A\000\000\000\000\003\026\001.\003A\003\030\0016\001:\000\000\003\"\003&\000\000\003*\003A\000\000\000\000\000\000\000\000\000\226\003A\001\022\000\000\000\000\001\026\000\000\000\000\000\000\000\000\003.\000\000\000\000\0032\000\000\000\000\000\162\000\000\000\000\000\000\000\238\000\000\000\000\000\242\003:\000\000\000\000\000\000\000\000\001\030\003\006\001\n\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\003\026\001.\003B\003\030\0016\001:\000\000\003\"\003&\000\000\003*\003F\000\000\000\000\000\000\000\000\000\226\001j\001\022\000\000\000\000\001\026\000\000\000\000\000\000\000\000\003.\000\000\000\000\0032\000\000\000\000\000\162\000\000\000\000\000\000\000\238\000\000\000\000\000\242\003:\000\000\000\000\000\000\000\000\001\030\0036\001\n\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\003\026\001.\003B\003\030\0016\001:\000\000\003\"\003&\000\000\003*\003F\000\000\000\000\000\000\000\000\000\226\001j\006\130\000\000\000\000\006\134\000\000\000\000\000\000\000\000\003.\000\000\000\000\0032\000\000\000\000\000\162\000\000\000\000\000\000\000\238\000\000\000\000\000\000\003:\000\000\000\000\000\000\000\000\006\138\007\226\000\165\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\n\158\006\162\001.\003B\006\166\0016\001:\000\000\006\170\006\174\000\000\006\178\003F\000\000\n\166\000\000\000\000\000\226\001j\006\130\000\165\000\165\006\134\000\000\000\000\000\000\006\182\006\186\000\000\000\165\006\190\000\000\n\174\000\162\n\190\000\000\000\000\000\238\000\000\000\000\000\000\006\198\000\000\000\000\000\000\000\000\006\138\006\142\000\173\000\000\000\000\000\000\000\000\000\000\n\206\001\"\000\000\001&\000\000\000\000\000\000\000\000\006\202\000\000\n\158\006\162\001.\006\206\006\166\0016\001:\000\000\006\170\006\174\000\000\006\178\006\210\000\000\n\166\000\000\000\000\000\226\001j\006\130\000\173\000\173\006\134\000\000\000\165\000\000\006\182\006\186\000\000\n\198\006\190\n\182\n\174\000\162\n\190\000\000\000\000\000\238\000\000\000\000\000\000\006\198\000\000\000\165\000\000\000\000\006\138\006\194\n\150\000\000\000\000\000\000\000\000\000\000\n\206\001\"\000\000\001&\000\165\000\165\000\000\000\000\006\202\000\000\n\158\006\162\001.\006\206\006\166\0016\001:\000\000\006\170\006\174\000\000\006\178\006\210\000\000\n\166\000\000\000\000\000\226\001j\tz\000\189\n\238\t~\000\000\n\214\000\000\006\182\006\186\000\000\n\198\006\190\n\182\n\174\000\162\n\190\000\000\000\000\000\238\000\000\000\000\000\000\006\198\000\000\000\173\000\000\000\000\t\130\t\142\n\150\000\000\000\000\000\000\000\000\000\000\n\206\001\"\000\000\001&\000\173\000\173\000\000\000\000\006\202\000\000\n\158\t\162\001.\006\206\t\166\0016\001:\000\000\t\170\t\174\000\000\t\178\006\210\000\000\n\166\000\000\000\000\000\226\001j\tz\000\177\000\177\t~\000\000\n\214\000\000\006\182\t\182\000\000\n\198\t\186\n\182\n\174\000\162\n\190\000\000\000\000\000\238\000\000\000\000\000\000\t\194\000\000\000\189\000\000\000\000\t\130\t\190\000\000\000\000\000\000\000\000\000\000\000\000\n\206\001\"\000\000\001&\n\246\n\222\000\000\000\000\t\198\000\000\000\000\t\162\001.\t\202\t\166\0016\001:\000\000\t\170\t\174\000\000\t\178\t\206\000\000\000\000\000\000\000\000\000\226\001j\tz\000\000\000\000\t~\000\000\n\214\000\000\006\182\t\182\000\000\000\000\t\186\n\182\000\000\000\162\000\000\000\000\000\000\000\238\000\000\000\000\000\000\t\194\000\000\000\177\000\000\000\000\t\130\n*\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\177\n\222\000\000\000\000\t\198\000\000\000\000\t\162\001.\t\202\t\166\0016\001:\000\000\t\170\t\174\000\000\t\178\t\206\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\182\000\000\000\000\t\186\000\000\000\000\000\162\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\194\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\000\000\000^\000\000\000b\006N\000f\000j\000n\006R\t\198\000\000\000\000\000\000\000\000\t\202\000\000\000\000\000\000\000r\000\000\000\000\000\000\000\000\t\206\000\000\000\000\000\000\000\000\000v\001j\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\0002\tN\000F\000J\000\000\000N\006F\000R\000V\006J\000Z\000\134\000^\020r\000b\006N\000f\000j\000n\006R\020z\001\153\000\000\000\000\001\153\000\000\008B\000\000\000\000\000r\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\153\000\000\000v\001\153\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\162\000\000\001\153\n\150\000\000\000\000\001\153\000\000\001\153\001\153\000\000\000\130\000\000\000\000\000\000\000\000\000\000\001\153\000\000\n\158\001\153\000\000\001\153\000\000\000\134\000\000\000\000\t>\000\000\000\000\000\000\000\000\000\000\n\166\000\000\000\000\007M\000\000\000\000\000\185\n\238\000\000\001\153\000\000\000\000\000\000\000\000\000\000\n\198\000\000\000\000\n\174\000\000\n\190\001\153\007M\000\000\000\000\000\000\000\000\000\000\000\000\000\162\000\000\007M\007M\003\161\000\000\000\000\000\000\007M\000\000\000\000\n\206\000\000\000\000\001\153\003\186\000\000\001\153\000\000\000\000\000\000\001\153\000\000\000\000\000\000\000\000\007M\000\000\000\000\000\000\000\000\000\000\000:\001\153\000\000\007M\007M\000\000\001\153\001\153\000\000\000\000\000\000\007M\003\194\n\214\007M\007M\001\153\001\153\001\153\000\000\n\182\000\000\000\000\000\000\007M\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\185\000\000\007M\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007M\000\000\000\000\000\000\000\000\000\185\n\222\000\000\000\000\0002\0006\000F\000J\007M\000N\000\000\000R\000V\000\000\000Z\017\n\000^\000\000\000b\000\000\000f\000j\000n\000\000\000\000\000\000\000\000\000\000\007M\000\000\000\000\007M\007M\000r\017\014\007M\000\000\000\000\000\000\000\000\007M\007M\000\000\019r\000\237\007M\000\000\000\237\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\026\000\000\000\000\000\237\000\130\000\000\000\000\000\000\017\234\000\000\000\000\000\000\000\000\000:\004\"\000\000\000\000\000\134\000\237\000\000\000\237\000\237\000\213\000\000\000\000\000\213\000\000\000\000\000\000\004B\000\000\000\000\004*\000\000\004:\000\000\000\000\000\000\000\213\000\000\000\000\000\213\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\"\000\000\004J\000\162\000\213\000\000\000\213\000\213\000\205\000\000\000\000\000\205\000\000\000\000\000\237\000\213\017\030\000\000\004*\000\000\004:\000\000\000\000\000\000\000\205\000\000\000\000\000\205\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004R\000\000\000\205\000\237\000\213\000\000\000\205\0042\000\205\000\205\000\209\000\000\000\000\000\209\000\000\000\000\000\213\000\205\000\000\000\237\004*\000\000\000\205\000\000\000\237\000\237\000\209\000\000\000\000\000\209\000\000\000\000\000\000\000\000\000\237\004Z\000\237\000\000\000\213\000\000\000\209\000\213\000\205\000\000\000\209\0042\000\209\000\209\000\225\000\000\000\000\000\225\000\000\000\000\000\205\000\209\000\000\000\213\004*\000\000\000\209\000\000\000\213\000\213\004\026\000\000\000\000\000\225\000\000\000\000\000\000\000\000\000\213\000\213\000\213\000\000\000\205\000\000\004\"\000\205\000\209\000\000\000\225\0042\000\225\000\225\000\217\000\000\000\000\000\217\000\000\000\000\000\209\000\225\000\000\000\205\004*\000\000\004:\000\000\000\205\000\205\004\026\000\000\000\000\000\217\000\000\000\000\000\000\000\000\000\205\000\205\000\205\000\000\000\209\000\000\004\"\000\209\004J\000\000\000\217\0042\000\217\000\217\000\221\000\000\000\000\000\221\000\000\000\000\000\225\000\217\000\000\000\209\004*\000\000\004:\000\000\000\209\000\209\004\026\000\000\000\000\000\221\000\000\000\000\000\000\000\000\000\209\000\209\000\209\000\000\000\225\000\000\004\"\000\225\000\217\000\000\000\221\0042\000\221\000\221\000\229\000\000\000\000\000\229\000\000\000\000\000\217\000\221\000\000\000\225\004*\000\000\004:\000\000\000\225\000\225\004\026\000\000\000\000\000\229\000\000\000\000\000\000\000\000\000\225\000\225\000\225\000\000\000\217\000\000\004\"\000\217\004J\000\000\000\229\0042\000\229\000\229\004\018\000\000\000\000\000\245\000\000\000\000\000\221\004B\000\000\000\217\004*\000\000\004:\000\000\000\217\000\217\004\026\000\000\000\000\000\245\000\000\000\000\000\000\000\000\000\217\000\217\000\217\000\000\000\221\000\000\004\"\000\221\004J\000\000\000\245\0042\000\245\004z\004\018\000\000\000\000\000\233\000\000\000\000\000\229\004B\000\000\000\221\004*\000\000\004:\000\000\000\221\000\221\004\026\000\000\000\000\000\233\000\000\000\000\000\000\000\000\000\221\000\221\000\221\000\000\004R\000\000\004\"\000\229\004J\000\000\000\233\0042\000\233\000\233\004\018\000\000\000\000\000\241\000\000\000\000\000\245\004B\000\000\000\229\004*\000\000\004:\000\000\000\229\000\229\004\026\000\000\000\000\000\241\000\000\000\000\000\000\000\000\000\229\000\229\000\229\000\000\004R\000\000\004\"\000\245\004J\000\000\000\241\0042\000\241\004z\000\000\000\000\000\000\000\000\000\000\000\000\000\233\004B\000\000\000\245\004*\000\000\004:\000\000\000\245\000\245\000\000\000\000\000\000\000\000\003\153\000\000\000\000\003\153\004\130\004Z\000\245\003\153\004R\003\153\000\000\000\233\004J\003\153\003\153\0042\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\241\000\000\000\000\000\233\000\000\000\000\000\000\000\000\000\233\000\233\000\000\000\000\000\000\000\000\000\000\002-\000\000\000\000\000\233\004Z\000\233\000\000\004R\000\000\000\000\000\241\000\000\000\000\000\000\0042\000\000\003\153\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\241\002-\000\000\000\000\000\000\000\241\000\241\000\000\000\000\002-\000\000\000\000\002-\002-\000\000\000\241\004Z\000\241\000\000\020v\000F\000J\002-\000N\006F\000R\000V\006J\000Z\000\000\000^\020r\000b\006N\000f\000\000\000n\006R\020z\000\000\002-\000\000\000\000\000\000\003\153\000\000\000\000\000r\000\000\000\000\000\000\000\000\000\000\002-\000\000\000\000\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\002-\000\000\000\000\002-\002-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002-\002-\000\000\000\000\000\000\002-\000\134\0002\005\030\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\0002\005\030\000F\000J\000\000\000N\000\000\000R\000V\000r\000Z\000\000\000^\000\000\000b\000\000\000f\000j\000n\000v\000\000\003\161\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000r\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000v\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\134\000\000\000\000\000\000\005\"\005&\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\134\000\000\000\000\000\000\005\"\005&\000\000\0002\000\142\000F\000J\011}\000N\000\000\000R\000V\000\000\000Z\000\000\000^\000\000\000b\000\000\000f\000j\000n\000\000\011}\000\000\000\000\000\000\000\000\000\000\000\000\t\226\005*\000r\000\000\000\000\000\000\000\000\011}\000\000\000\000\000\000\000\000\000v\011}\011}\000\000\000\000\t\234\000\000\t\246\000\000\0052\011}\000\000\000\000\011}\000\000\011}\000\000\000\000\000\000\000\000\000\000\000\130\000\000\000\000\000\000\000\000\000\158\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\134\011}\000\000\000\000\000\000\000\000\000\000\0002\005\030\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\n\002\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\011}\000r\000\000\000\162\000\000\n\006\000\000\011}\000\000\000\000\000\000\000v\000\000\000\000\000\000\n\014\000\000\000\000\000\000\011}\000\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\011}\011}\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002!\000\000\000\134\000\000\000\000\000\000\021\002\005&\0002\005\030\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\000r\000\000\000\000\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\000\000\000\000\000\000\021\006\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\134\000\000\000\000\000\000\021\002\005&\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\021\014")) + ((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")) 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\004\001\004\001\004\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\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\253\000\252\000\252\000\252\000\251\000\251\000\251\000\250\000\250\000\250\000\249\000\249\000\249\000\248\000\247\000\246\000\245\000\245\000\244\000\244\000\243\000\243\000\242\000\242\000\241\000\241\000\240\000\239\000\239\000\238\000\238\000\237\000\237\000\237\000\236\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\223\000\223\000\222\000\222\000\221\000\221\000\220\000\220\000\219\000\219\000\219\000\218\000\218\000\218\000\218\000\218\000\217\000\217\000\216\000\215\000\215\000\215\000\215\000\214\000\214\000\213\000\212\000\211\000\211\000\211\000\210\000\210\000\210\000\209\000\209\000\209\000\209\000\208\000\208\000\208\000\208\000\207\000\207\000\207\000\207\000\207\000\207\000\207\000\207\000\207\000\207\000\207\000\207\000\207\000\207\000\207\000\207\000\207\000\207\000\207\000\207\000\206\000\205\000\205\000\204\000\204\000\204\000\203\000\203\000\202\000\202\000\202\000\201\000\201\000\200\000\199\000\198\000\198\000\197\000\197\000\196\000\196\000\195\000\195\000\194\000\194\000\193\000\192\000\191\000\191\000\190\000\190\000\189\000\188\000\188\000\188\000\188\000\187\000\186\000\185\000\185\000\184\000\183\000\183\000\182\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\179\000\179\000\179\000\178\000\177\000\177\000\176\000\176\000\176\000\175\000\174\000\174\000\174\000\174\000\173\000\172\000\172\000\172\000\172\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\170\000\170\000\169\000\169\000\168\000\168\000\167\000\167\000\166\000\166\000\166\000\166\000\165\000\165\000\165\000\164\000\164\000\164\000\164\000\164\000\164\000\164\000\163\000\162\000\162\000\162\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\154\000\154\000\154\000\154\000\154\000\154\000\154\000\153\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\000x\000w\000v\000u\000u\000u\000u\000u\000u\000u\000u\000u\000u\000u\000u\000u\000u\000u\000u\000u\000u\000u\000u\000u\000u\000u\000u\000u\000u\000u\000u\000t\000s\000r\000q\000p\000o\000n\000m\000l\000k\000k\000k\000j\000j\000j\000i\000i\000i\000h\000g\000f\000e\000d\000c\000b\000b\000b\000a\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\000S\000S\000S\000S\000S\000S\000S\000S\000S\000S\000S\000S\000S\000S\000S\000S\000S\000S\000S\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\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\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") + (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") let goto = - ((16, "\0009\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\025\000\000\0011\001\020\000\000\000\163\000U\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001n\000\000\008^\000Y\000U\000\000\000\000\000\000\000\000\000\000\000\000\008\200\000s\012t\000\000\000\000\000\000\021\224\000\000\000\132\000\000\000\000\001\015\000\019\000\000\000\000\000h\000\000\0002\000\0001\\\003\162%\230$@\000h\000\000\005\\\000\000\011\026\011\164\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\250%\230\000\000\000\000\004\008\000\000\006r\000\000\008\014\000\000\000\000\000\000\000\000\000\170\000\000 \240\000\000\000\000\003\030\000\000\018Z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\224\000\000\000\000\0132\000\000\016r\000\000\"\164\000\000#\162\000\0007,\000\0007\218\000\0007\224\000\0007\244\000\0007\250\000\000\014\192\000\000\031\198\000\000\000\000\000\000\000\000\000\0008\000\000\0008\014\000\0008\"\000\000\022h\000\000\000\000 4\000\000\000`\000U\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\001\024\000\000\000\234\000\000\000\000$\248\000\0001\224\000\000\000\000\000\000\001J\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000g1\230\000\000\001\168\000\000\000\000&\020\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012\212&\020\000\000\018\180\000\000\025\180\027x\000\000\000\000\000\000\002\164\000\000!~\000\000\000\0001\254\000\000\000\000\000\000\002\210\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000&\144\000\000\nb\000\000\000\000\000\000$\148\000\000'R\000\000\000\000\000\000\000\000\001\198\000\000\000\0002~\000\000\000\000\000\000\021\134\002\028\000\000\000\000\000\000\000\000\000\000\000\000\004\196\000\000\017`\000\000 \214\000\000!\030\000\000*d\000\000+\206\000\0000\200\000\0001\198\000\0003\156\000\0008N\000\000\019~\000\000\027n\000\0008|\000\0008\158\000\0008\180\000\000\000\000\000\000\000\000\000\000\002\132\t~\000\000\003P\000\000\000\000\000\000\000\021\000\000\000\000\000\000\007\242\000\000\000\000'\002\000\000\000\000\000\000\000\000\000\000\000\000\000.\000\000\000\000\000\000\002\n\000\000\000\000\000\000\000\174\000\000\000\000\028\220\000Y\000\000\000\000\001\194\002\168\000\000\000\000\000\000\000\000\000\000\004N\000\000\"\168\000\000\000\017\000\000\000\000\004v\000\000\000\000\000\000\000\000\000\000\000\000%\016\000\000\000\000\000\000\001\202\000\000\000\000\000\000\000\000\005\254\029R\000\000\002\144\000\000\000\000\004\150\002\234\000\000\000\000\000\000\000\000\012\254\000\000\000\000\000\000\000\000\000\000\000\000\000\165\0128\000\000\013\230\000\000\000\000\000\000\004 \000\000\013\"\000I\000\000%\174\000\000\000\000\000\000\014\016\002\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\132\000\000\021X\000\0002\156\000\000\000\000\001X\000\000\007d\000\000\015\196\003\190'\128\000\000\000\000\000\000\000\140\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\216'\128\000\000\019`\000\000\021\016\023\176\000\000\000\000\000\000\004z\000\000!\148\000\000\000\0003\014\000\000\000\000\000\000\004\144\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0005l\000\0005\134\000\000\000\000\000\000\004b\000\000\000\000\000\000\000\000\000\000\000\000\030P\000\000\031\128\000\000)Z\000\000*\202\000\0001\206\000\0008j\000\0008\198\000\0008\220\000\0008\254\000\0009$\000\000\024\142\000\000\024D\000\0009n\000\0009\156\000\0009\172\000\000'\244\000\000\000\000\000\0003\140\000\000\000\000\000\000\002x\000*\000\000\024\192\000#\003\150\000\000\005\224\000\000\013\210\000\214\007\222\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0004\008\000\000(t%\196\004\148\000\000\000\000\000\000\031B\000\000(\160\000\000)\198\000\000(\230)B\004\030\000\251\005<\000\000\000\000\000\000\000P\000\000\000\000\003\132\000\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\":\000\000)z\000\000\000\000\000\000\000\000\000\000\000\000\014\194\000\000\007\136\000\000\000\000\000\000\000\000\024\156\002\188\000\000,\222\000\000\000\000\000\000\002\224\000\000\000\000+\246\001\232\000\000\008,,8\000\000\000\000)\244\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\013^)\244\000\000\028\140\000\000\028\204\029\140\000\000\000\000\000\000\005Z\000\000#V\000\000\000\0004z\000\000\000\000\000\000\005\210\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000*p\000\000\021J\000\000\000\0004\158\000\0004\194\000\000\000\000\004|\004(\000\000\000\000,\232\000\000\000\000\000\000\006\030\000\0004V\000\000\000\0005\244\000\000\000\000\000\000\006\252\000\000\007\238\000\000\"8\000\000-.\000\0004\200\000\0005J\000\0009\142\000\000:\012\000\000:\026\000\000:.\000\000::\000\000:\130\000\000:\166\000\000\000\000\000\000\000\000\000\000\000\000\nl\000\000\n\n\000\000\012\236\012\132\000\000\018H\000\000\000\000\000\000\000\000\000\000\000\0006\024\000\000\000\000\000\000\000\000\000\000\000\000\000\012\000\000\000\000\000\000\000\000\000\000\000\000\003*\000\000\000\0000\230\000\000\000\000\000\000-R\000\000\000\000\000\202\000\000\000\000\000\0006\012\000\000\000\000\000\000\000\000-h\000\000\000\000\000\000\000\000\004\180\003$\000\000-\156\000\000\000\000\000\000\000\000\025@\005\006\000\000\025\192\000\000\000\000\006&\000\000-\210\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\148\000\000\000\0006\020\000\000\000\000\000\000.&\000\000\000\000\005 \000\000\000\000\015r\000\000\026\132\000\000\000\000#\132\000\000\000\000\000\000\004H\000\000\000\0006*\000\000\000\000\000\000\000\000.Z\000\000\000\000\000\000\000\000\0068\008r\000\000.\218\000\000\000\000\000\000\000\000\000\000\000\000\015\238\000\000\000\000\005\"\000\000\016\186\000\000\004H\000\000\000\000\004\194\016j\000\000\005\180\000\000\000\000\000\000\000\000\004b\000\000*\232\000\000\027\004\000\t\027\132\000\000\000\188\000\000\0176\000\000\017\178\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\216\028\004\000\242\028\132\000\000\000\000\000\000\005\128\000\000\018~\000\000\006\006\000\000\000\000\006\020\003:\029\132\000\000\004\134\000\000\018\250\0302\000\000\000\000\019v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006P\008\170\000\000\006\174\000\000\000\000\000\000\000\000\005|\000\000\020B\000\000\000\000\000\000\031\1784\248\000\000\000\000\000\000\0312\000\000\000\000\000\000\000\000\0252\004\234\000\000\000\000.\240\000\000\000\000\000\000\000\000\006\016\000\000\000\0006<\000\000\000\000\000\000/$\000\000\000\000\005\170\000\000\000\000/D\000\000\000\000\006\178\006\026\000\000\000\000/p\000\000\000\000\006\240 v\000\000\007j\000\000\000\000/\174\000\000\000\000\000\000\000\000\000\000\000\000\007\148\000\000\000\0006\162\000\000\000\000\000\000/\206\000\000\000\000\000\000\000\000\000\000$\018\000\000\000\000\000\000\004\130\000\000\000\000\000\0000>\000\000\000\000\008\240\008:\000\000\000\0000\212\000\000\000\000\007\016\000\000\000\000\000\000\000\000\004b\004\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005,\000\000\020\190\000\000\000\000\000\00056\000\000\tb\000\000\000\000\000\000\005\208\000\000\000\000\004\168\021n\000\000\022Z\000\000\000\000\000\000\007P\000\000\022n\007h\023h\000\000\025n\000\000\000\000\000\000\007\186\000\000+Z\007\198+r\000\000+\238\000\000\000\000\000\000\007\242\000\000\025\170\008R\000\000\000\000\002\014\006&\008\178\008\004\000\000\028\234\000\000\000\000\000\000\008\200\000\000#\238\008\218\000\000\000\000\000\000\003D\000\000\000\000\000\000\000\000\000\000\003\174\000\000\000\000\004\020\000\000\000x\000\000\000\000\000\000\004\254\000\000\000\000\000\000\000\000\000/\000\000\006\186\004\140\000\178\000\000\000\000\003\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\001J\000\136\000\000\000\000\002\150\000\000\000\000\000\000\008\008\000\000\000\000\011\006\012\224\000\000\000\000\000\000\000\000\0146\014\188\000\246\000\000\015\172\000\000\000\000\000\000\000\000\000\000\000\000\004\238\000\000\000\000\008\232\000\000\000\000\004\190\000\000\000\000\000V\000\000\000\000\000=\000\000\006\218\005\136\002\240\000\000\000\000\0026\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\162\016\n\000\000\000\000\000\000\000\000\006\208\000\000\000\000\tL\000\000\000\000\000\000\017\196\000\000\000\000\000B\021P\004\176\000\000\021\210\000\000\000\000\000\000\000\000\000\000\000\000\0003\000\000\007H\003\\\001\n\000\000\000\000\000\000\000\000\002X\000\000\000\000\000\000\000\000\000\000\000\000\005\190\000\000\000\000\000%\000\000\007|\005\230\0050\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\188\000\000\000\000\012H\022\132\000\000\000\000\000\000\000\000\000\242\000\000\004\254\000\000\008h\000\000\000\000\000\000\000\000\000\000\000\000\019\148\nf\000\000\000\000\011\192\000\000\000\000\000\000\000\000\006b\000\000\012\024\000\000\000\000\000\000\000\000\003\240\000\000\000\000\000\000\000y\000\000\000\000\000\205\000\000\000\000\000\000\000\000\000\000\000\000\000\0000\236\005P\000\000\000\000\000\000\028\194\000\000\000\000\013\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\000Z\002\150\000Y\004\168\n\166\005\196\000\000\000\000\005\218\007\206\008\188\008\202\000\000\000\000\000\000\000\000\000\000\000\000\000\000\013\238\005\218\030\204\006\190\000\000\000\000\t\030\000\000\023<\000\000\000\000\006\166\000\000\000\000\000\000\004\208\000\000\001B\000\000\006\024\015\"\000\000\000\000\000\000\000\000\004N\000\000\004v\000\000\007d\000\000\000\000\001R\000\000\000\000\000\000\000\000\n.\000\000\000\000\005\218\t*\000\000\023\252\000\000\004H\006\216\000\000\000\000\000\000\000\000\000\000\003$\000\000\000\000\000\000\000\000\000\0001v\008\148\000\000\000c\000\000\000\000\000\000\000\000\000\000\002\030\n\170\001\164\011&\000\000\002\154\012\166\000\000\006\198\000\000\003\022\000\000\004\154\000\000\005\020\000\000\000\000\000\000\000\000\000\000\008\160\000\000\005\224\000\000\t^\000\000\006\152\000\000\004H\007*\000\000\003\166\000\000\000\000\000\000\006,\007P\006>\000\000\008\136\000\000\008\212\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\234\000\000\tn\000\000\000\000\000\000\000\000\000\000\006\140\007\232\007\226\000\000\007\250\000\000\000\000\000\181\t\182\000\000\006\232\000\000\000\000\000\000\000\000\0074\000\000\000\000\000\000\000\000\000\000\0074\008t\002\134\007\128\007\210\000\000\000\000\t\202\000\000\000\000\000\000\000\000\t\002\000\000\000\000"), (16, "\001\182\001\205\0046\0006\000\n\005\001\005\002\000\\\000\\\000\017\004\136\000q\000e\000-\001;\004L\004\179\002S\003T\003<\002+\004\198\000-\005m\000^\005\006\005n\004\134\000\t\004\137\004Y\003V\004J\004\177\004\180\004Y\004M\004Y\004\196\005\182\000D\004\199\004Y\003\007\005\023\001\184\000\017\005\024\000\016\001\185\000^\000^\000\191\002\219\000\017\000_\000_\004\252\004\253\000`\000`\001\129\001\182\001\205\000-\005\028\0006\000D\005.\000\\\003\243\0019\002,\0018\004\176\000-\001U\001\131\005r\005/\0051\003\006\005\021\004\133\000i\000i\000\193\001\182\001\203\004Z\001O\004\177\004\180\004Y\004Z\003\131\004Z\001\210\004I\001%\004\134\004Z\004\137\004Y\0012\003\007\000'\001\184\000&\005\191\004a\001\185\000^\001t\000'\004J\000\005\000_\001<\004M\004Y\000`\005\021\004\194\001\182\001\205\0006\004b\004Y\003V\000^\000E\001\184\004P\002B\005\021\001\185\000-\001\135\000\008\000\t\002S\003T\003<\001\198\0006\000i\0006\002[\002G\0059\000-\004Z\002H\001@\003\014\003h\001\199\003\133\003b\004\195\002\237\004Z\001@\000j\000j\003\015\003\007\000-\001\184\003P\005:\001=\001\185\003^\001P\0007\004\196\004\184\004Z\004\199\004Y\004s\004Y\000\137\002-\002L\004Z\000k\000k\003=\000-\003\\\004\185\004=\000-\002B\003\"\000\154\000-\000\160\003s\001W\0034\001\214\000\169\001\198\001X\004Q\000\160\001Y\002G\000\166\000-\000\138\002H\001@\003\014\005<\001\199\003c\001\210\002\220\001%\001\215\0006\000j\005=\005W\001\216\000\168\001\198\005X\001\217\001/\000m\0007\002,\001\218\000\139\004Z\004\224\004Z\000\140\001\199\005u\005N\004\230\002L\000o\000k\000\160\003\029\005Z\005N\000b\003\244\0007\002B\003\"\004\209\002u\000\160\005\\\002\142\0034\001\214\000\170\001\198\004\149\000\\\0007\003Y\002G\000\185\002\238\001<\002H\001@\003\014\003\246\001\199\001>\003e\004[\004\240\001\215\005\131\001\182\001\205\003\015\001\216\000\152\000-\003P\001\217\004e\002S\003j\001%\001\218\000-\004\186\001E\002A\005/\005s\003\006\002w\000\152\002L\001\204\002x\000^\003=\000\191\003\\\002\243\000_\004T\004\001\003\"\000`\004(\000\160\003s\004\143\0034\001\214\002\007\002\008\003\007\001@\001\184\002\247\000\179\000\152\001\185\000\160\004\227\001@\000\166\005\133\004\141\005F\004\188\004\228\000i\001\215\000\192\001\182\001\205\005F\001\216\000\152\000\160\001|\001\217\000\166\000\252\004\185\000-\001\218\000-\004\189\005 \001\143\005/\005x\003<\000-\001c\005Q\004d\005R\001e\005I\004\133\000\160\005J\005P\000\166\000\160\004\227\005I\000\166\000\160\005J\0006\000\166\004b\004Y\005\134\003\007\004\134\001\184\004\137\004Y\0006\001\185\000\160\001'\000\255\000\166\001\145\002\133\002\193\002\214\002\196\005\130\000^\001A\001\182\001\205\002\161\002[\000\\\004\003\002\134\004\140\000g\0006\002B\000\253\001N\000-\001*\000j\0006\005/\005x\003<\001\198\0006\001@\003\014\004\141\002G\001O\002\199\000\017\002H\001@\003\014\005\136\001\199\003\015\003\249\003u\002[\004Z\000k\005\196\005=\005W\003\007\004Z\001\184\005\138\000^\001,\001\185\0006\001d\000_\0006\000\253\001d\000`\004\186\004)\005}\002\007\002\008\002L\005d\005e\003\"\003\029\005\140\000\160\003'\000\\\0034\002B\003\"\000e\002\164\000\160\005\142\004\185\0034\001\214\000i\001\198\004S\001\182\001\205\0007\002G\000'\002\165\005!\002H\001@\003\014\005~\001\199\000\216\003\127\0006\001@\001\215\005-\005$\005=\005W\001\216\0006\005\148\002J\001\217\005\191\001P\002U\000^\001\218\005\149\001*\005i\000_\000\225\004_\000\\\000`\004;\002L\000\182\0007\000^\003=\001\184\005\128\0007\001m\001\185\002B\003\"\000\160\002u\000\160\003'\002\142\0034\001\214\001X\001\198\000\160\001Y\000i\000\166\002G\001+\004\155\004\248\002H\001@\003\014\005~\001\199\004Q\004<\0007\000j\001\215\0007\000^\005=\005W\001\216\001#\000_\002J\001\217\002\\\000`\005\021\0006\001\218\001q\002\n\002u\002A\001\210\002\142\002[\002w\000k\002L\004\191\002x\002\221\003=\004B\005\128\004\144\001\182\001\205\002\237\003\"\000i\0006\000\160\003'\003u\0034\001\214\000-\002\251\000-\002.\002\226\000l\005/\005x\003<\000-\000\211\0007\000\236\005 \0006\000-\0006\002A\002\255\001\215\002\237\002w\000j\001\198\001\216\002x\000m\0006\001\217\0006\001p\000\149\003\007\001\218\001\184\005\193\001\199\0020\001\185\004\250\000o\000\188\004\170\004Y\000-\002\250\000k\000\191\005\127\001\212\001\182\001\205\003\003\000^\001\132\004=\000\213\003\018\003x\000^\000\214\003\004\004|\000-\001*\003\028\003B\005/\005x\003<\001\131\000\138\0006\000j\003\004\003\004\002\133\002\193\002\194\002\196\002.\001\213\004G\001\214\004V\002\161\000\211\000\227\000\238\002\134\004\140\003K\000m\003\007\003\248\001\184\000\139\000k\001,\001\185\000\140\0007\004Z\001\215\001^\003)\000o\004\141\001\216\005\129\002\199\003\142\001\217\0006\0021\0022\0024\001\218\002\133\004\011\003\004\002\209\003h\002B\001Z\003M\001\187\002\161\0006\000^\0007\002\134\000\213\001\198\003)\004\013\000\214\001\196\002G\002\027\004\130\000\169\002H\001@\003\014\005~\001\199\003.\002\007\002\008\005!\004\146\001\182\001\205\005=\005W\000\169\004\195\002\164\002J\000\243\005,\005$\000\227\0032\000-\005'\000\228\002\237\005/\005x\003<\002\165\005?\004\196\002L\003\221\004\199\004Y\003=\000-\005\128\0007\001j\002B\000\152\003\"\000\160\0006\000\160\003'\005\018\0034\001\214\001\198\003\007\000\160\001\184\004\204\002G\002\164\001\185\000\160\002H\001@\003\014\005~\001\199\002[\000-\0004\005\137\003K\001\215\002\165\005=\005W\002[\001\216\0006\002J\002\237\001\217\002*\0006\000\\\0006\001\218\003\159\000\181\0006\000\160\004}\003p\000\166\001\001\002L\004Z\002z\0035\003=\004\176\005\128\000\228\001\182\001\205\003L\003\"\004\128\001\006\000\160\003'\005\019\0034\001\214\000\244\003p\000-\004\177\004\180\004Y\005/\005x\003<\003m\001*\002\t\003r\000^\000\246\000-\005\"\0053\000_\001\215\004\004\004\202\000`\0007\001\216\000\\\003\004\002\238\001\217\000q\005u\002B\003\007\001\218\001\184\003q\001\000\003\136\001\185\002u\004\133\001\198\002\142\002\131\001,\003\183\002G\000i\005\141\003\246\002H\001@\003\014\005~\001\199\005K\001\001\004\134\005+\004\137\004Y\001\002\005=\005W\004Z\001\003\001@\002J\000^\003\177\001\004\003\138\005{\000_\0007\004W\0007\000`\001B\0007\003)\002\158\000^\002L\003\136\0007\002w\003=\004\207\005\128\002x\001\182\001\205\004\147\003\"\000\169\005b\000\160\003'\005\144\0034\001\214\000i\005\172\000-\002\007\002\008\005;\002S\003T\003<\004X\000\160\001l\001s\001o\003\233\004\003\003\137\004Z\003\167\001\215\003.\002B\005\151\003\184\001\216\000j\005\170\004\148\001\217\003\008\003\233\001\198\003\007\001\218\001\184\0006\002G\0032\001\185\000\160\002H\001@\003\014\005~\001\199\005L\003\012\004\192\003\235\000k\001\182\001\205\005=\005W\000\169\004\195\0006\002J\002u\005'\000\211\002\142\000\238\000-\003\234\005\173\005\019\002S\003T\003<\004\245\004\205\004\196\002L\000\\\004\199\004Y\003=\000]\005\128\000j\002\133\000-\004\193\003\"\005\178\002S\000\160\003'\002u\0034\001\214\002\138\003\007\002\134\001\184\004a\005\177\005\187\001\185\000\160\000^\004\014\000^\000k\002w\000\213\004\206\005\189\002x\000\214\001\215\004(\004b\004Y\004\021\001\216\000^\004\013\005M\001\217\002O\000_\002B\004\158\001\218\000`\000-\000/\001z\0002\004\023\000^\001\198\000\243\004Z\002w\000\227\002G\0006\002x\004\195\002H\001@\003\014\0007\001\199\003\252\003b\005\194\000m\000i\001\182\001\205\002[\003\015\004\024\0004\004\196\002J\004\031\004\199\004Y\002\164\000r\000-\0007\0006\005\179\002S\003T\003<\004\023\004Z\005\197\002L\004!\002\167\005'\003=\000-\003\\\004\"\001x\002B\005'\003\"\005\198\005\162\000\160\003'\003\193\0034\001\214\001\198\003\007\000-\001\184\004!\002G\000-\001\185\002\133\002H\001@\003\014\005*\001\199\003`\003b\0004\005L\003\203\001\215\004\127\002\134\003\015\000\228\001\216\0056\002J\004Z\001\217\001@\003\014\005Y\005\162\001\218\003\004\0013\003\227\000j\004%\002\133\003\004\003\015\002L\005\162\005\195\005\206\003=\004\212\003\\\000\246\001\182\001\205\002\134\003\"\004\023\0007\000\160\003'\005k\0034\001\214\000k\004\133\000-\005\135\004+\005u\002S\003T\003<\000\000\001\000\003\"\000\000\001@\000\160\003'\000-\0034\004\134\001\215\004\137\004Y\0007\005\192\001\216\001B\004.\004h\001\217\002\164\001\001\002B\003\007\001\218\001\184\001\002\001i\0041\001\185\001\003\003\228\001\198\0040\002\169\001\004\0044\002G\005\139\005\162\000\000\002H\001@\003\014\0040\001\199\003\135\003b\005\181\005\019\000\160\001l\004\023\001o\003\015\005\019\005\169\001@\002J\0036\000\000\005)\000\000\004\225\002u\004\141\005\201\002\142\005(\001B\000\000\004Z\000\000\000\152\002L\005\202\003:\000\169\003=\000\000\003\\\000\000\001\182\001\205\005\192\003\"\000\000\000\000\000\160\003'\000\000\0034\001\214\000\000\005\163\000-\000\000\000\000\000\000\002S\003T\003<\000\000\000\160\001l\005\165\001o\002A\000\211\000\000\000\236\002w\001\215\002u\002B\002x\002\142\001\216\000\000\000\160\004}\001\217\000\166\000\160\001\198\003\007\001\218\001\184\000\000\002G\000\000\001\185\004\195\002H\001@\003\014\000\000\001\199\004\000\003b\000\000\000\000\000\000\000\000\001\182\001\205\003\015\000\000\000\152\004\196\002J\000^\004\199\004Y\000\213\000-\002A\000-\000\214\005 \002w\005/\000\000\003\006\002x\000\000\002L\000\000\000\000\000\000\003=\005\167\003\\\000\000\000\000\000\000\000\000\003\"\004\161\000\000\000\160\003'\000\000\0034\001\214\000\227\000\000\003\007\000\000\001\184\000\000\000\000\000\000\001\185\000\160\001)\000\000\000\166\000\000\000\000\000\211\000\000\000\232\000\000\001\215\005\132\001\182\001\205\002\133\001\216\000\000\002\200\004Z\001\217\000\000\004a\002B\002\161\001\218\000-\000\000\002\134\000\000\005/\000\000\003\006\001\198\000\000\000\000\000\000\000\000\002G\004b\004Y\000\000\002H\001@\003\014\000\000\001\199\005U\003b\002\202\000^\000\000\000\000\000\213\000\000\003\015\003\007\000\214\001\184\002J\000\000\000\000\001\185\000\000\002\133\002\198\000\000\002\196\000\000\000\000\000\000\000\000\000\228\002\161\005v\002L\000\\\002\134\000\000\003=\000e\003\\\000\000\000\000\000\227\002B\003\"\000\000\000\000\000\160\003'\002\208\0034\001\214\000\000\001\198\000\000\002\164\002\199\004Z\002G\000\000\000\000\005!\002H\001@\003\014\005w\001\199\000\000\000\000\002\165\004\195\001\215\005#\005$\005=\005W\001\216\000^\000\000\005z\001\217\000\000\000_\004\233\000\000\001\218\000`\004\196\000\000\000\000\004\199\004Y\000\000\000\000\000\000\002L\000\000\000\000\000\237\003\029\005|\000\000\000\000\000\000\002\164\002B\003\"\000\160\000\000\000\160\003'\000i\0034\001\214\004\195\001\198\000\000\000\000\002\165\000\000\002G\000-\000\228\000\000\002H\001@\003\014\005w\001\199\000\000\000\000\004\196\000\186\001\215\004\199\004Y\005=\005W\001\216\004\133\000\000\005z\001\217\000\000\000\000\000\000\002u\001\218\000\000\002\142\004Z\000-\000/\0000\0002\000\000\004\134\002L\004\137\004Y\000\000\003\029\005|\001\182\001\205\000\000\004n\000\000\003\"\000\000\000\000\000\160\003'\000\000\0034\001\214\000-\000\000\000\000\000\000\005/\0004\003\006\000\000\000\000\000\000\000\211\000\000\000\231\002A\000\000\000j\000\000\002w\004Z\001\215\000\000\002x\002u\000\000\001\216\002\142\000\000\000\000\001\217\000\000\003\007\000\000\001\184\001\218\000\188\000\000\001\185\000\000\000\211\000k\000\238\004a\004Z\000\000\000-\000/\001v\0002\005y\001\182\001\205\000\000\000\000\000^\000\000\000\000\000\213\000\\\004b\004Y\000\214\000q\000-\000\000\000\138\002A\002S\005\015\003\006\002w\000\000\000\000\000\000\002x\0004\000\000\000\000\000\000\000\000\002u\004\236\000^\002\137\000\000\000\213\000m\000\152\000\227\000\214\000\139\000\000\000\000\003\007\000\140\001\184\000\000\000\000\000\000\001\185\000o\000^\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\133\000\227\001@\002\203\004Z\000\000\000\000\002B\000^\002\161\004\243\004\006\002w\002\134\001B\003\130\002x\001\198\000\160\001~\000i\000\166\002G\001\182\001\205\001i\002H\001@\003\014\005w\001\199\000\000\000\000\000\000\000\000\004\218\000-\000\000\005=\005W\002S\000\000\003\006\005z\000\000\000\000\000-\000\000\000\160\001l\000-\001o\002\133\000\228\005 \002\200\000\000\000\000\000\000\002L\000\000\002\161\000\000\003\029\005|\002\134\003\007\000-\001\184\002B\003\"\001@\001\185\000\160\003'\002\206\0034\001\214\000\000\001\198\002Z\000\228\002\164\001B\002G\000\000\002\202\000\000\002H\001@\003\014\000\000\001\199\000\000\001i\000\000\002\165\001\215\004a\003\128\000j\003\015\001\216\003\130\000\000\003w\001\217\005\013\000\000\002\133\000\000\001\218\000\000\004l\000\000\004b\004Y\000\160\001l\000\000\001o\002L\002\134\000\000\000k\003\029\003y\000\000\002\207\001\000\000\000\000\000\003\"\000\000\002\164\000\160\003'\000\000\0034\001\214\000\000\000\000\000\\\001\182\001\205\000\000\000e\000\000\002\165\001\001\002Q\000\000\000\000\000\000\001\002\000\000\000-\002B\001\003\001\215\002S\003\001\003\006\001\004\001\216\004a\000\000\001\198\001\217\000\000\000m\000\000\002G\001\218\000\000\004Z\002H\001@\003\014\000\000\001\199\000\000\004b\004Y\000t\000^\003\007\000\152\001\184\003\015\000_\001@\001\185\003w\000`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005#\0050\000-\000\134\000\000\000\000\000\152\002L\000\000\000\000\000\000\003\029\003y\000\000\000\000\000\000\000\000\000i\003\"\000\000\000\000\000\160\003'\000\000\0034\001\214\000\000\000\000\000\000\001\182\001\205\000\160\001\128\000\000\000\166\000\160\002\235\003\031\002\249\000\000\004Z\000\000\000-\000\000\000\000\001\215\002S\003 \003<\000\000\001\216\000\000\000\160\001\141\001\217\000\166\000\000\005E\000\000\001\218\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\182\001\252\003\007\000\000\001\184\002B\000\000\000\000\001\185\000\000\001\182\001\202\004y\004a\000\000\001\198\000\000\000\000\000\000\000\000\002G\001\182\001\205\000\000\002H\001@\003\014\000j\001\199\003?\004b\004Y\000\000\000\000\000-\000\000\000\000\003\015\002S\003 \003<\003A\000\000\000^\000\000\001\184\000\137\000\000\000\000\001\185\000\000\000k\000\000\000^\000\000\001\184\000\000\002L\000\000\001\185\004a\003\029\003C\000\000\003\007\000\000\001\184\000\000\003\"\000\000\001\185\000\160\003E\001@\0034\001\214\000\138\004b\004Y\004w\000\000\000\000\000\000\001\182\001\205\005F\000\000\000\\\000\000\000\000\004Z\000q\000\000\002B\000\000\001\215\000\000\000m\000\000\000\000\001\216\000\139\003J\001\198\001\217\000\140\000\000\000\000\002G\001\218\000\000\000o\002H\001@\003\014\000\000\001\199\005I\000\000\000\160\005J\000\000\000\166\001\182\001\205\003\015\002A\000\000\001\184\002J\000^\003D\001\185\000\000\000\000\000_\000-\004Z\000\000\000`\002S\003 \003<\000\000\001\198\002L\000\000\000\000\000\000\003=\000\000\003>\000\000\000\000\001\198\002B\003\"\001\199\000\000\000\160\003'\000\000\0034\001\214\000i\001\198\003\007\001\199\001\184\000\000\002G\000\000\001\185\000\000\002H\001@\003\014\000\000\001\199\000\000\000\000\000\000\000\000\001\215\000\000\001\182\001\205\003\015\001\216\000\000\000\000\002J\001\217\000\000\000\000\000\000\000\000\001\218\000-\004u\000\000\000\000\002S\003T\003<\000\000\000\211\002L\000\236\000\000\000\000\003=\000\000\003>\000\000\000\000\000\000\002B\003\"\000\000\000\000\000\160\003'\000\000\0034\001\214\000\000\001\198\003\007\000\000\001\184\000\000\002G\000\000\001\185\000\000\002H\000\000\000\000\000\000\001\199\000\000\000\000\000\000\000j\001\215\004\153\001\182\001\205\000^\001\216\000\000\000\213\002J\001\217\000\000\000\214\002B\000\000\001\218\000-\000\000\000\000\000\000\002S\003T\003<\001\198\000k\002L\000\000\000\000\002G\000\000\000\000\000\000\002H\001@\003\014\000\000\001\199\004a\000\000\000\227\000\000\000\000\000\000\001\214\000\000\003\015\003\007\000\000\001\184\002J\000\000\000\000\001\185\000\000\004b\004Y\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\215\000\000\002L\000\000\000\000\001\216\003=\000m\003>\001\217\000\000\000\000\002B\003\"\001\218\002u\000\160\003'\002\142\0034\001\214\000v\001\198\000\000\000\\\000\000\000\000\002G\000g\000\000\000\000\002H\001@\003\014\000\000\001\199\000\000\003[\000\000\000\000\001\215\000\000\001\182\001\205\003\015\001\216\000\000\000\000\002J\001\217\000\000\004Z\000\000\000\000\001\218\000-\000\228\000\000\002A\002S\003T\003<\002w\000\000\002L\000\000\002x\000^\003=\000\211\003\\\000\230\000_\000\000\002B\003\"\000`\000\000\000\160\003'\000\000\0034\001\214\000\000\001\198\003\007\000\000\001\184\000\000\002G\000\000\001\185\000\000\002H\001@\003\014\000\000\001\199\000\000\003]\000\000\000i\001\215\000\000\001\182\001\205\003\015\001\216\000\000\000\000\002J\001\217\000^\000\000\000\000\000\213\001\218\000-\000\000\000\214\000\000\002S\003z\003<\001\001\000\000\002L\000\000\000\000\000\000\003=\000\000\003\\\000\000\000\000\000\000\000\000\003\"\001\008\000\000\000\160\003'\000\000\0034\001\214\000\000\000\227\003\007\000\000\001\184\000\000\000\000\000\000\001\185\000\000\001\182\001\201\000\000\000\000\002\133\004\165\000\000\002\200\000\000\001\215\000\000\001\182\001\205\002\161\001\216\000\\\000\000\002\134\001\217\000e\000\000\002B\000\000\001\218\000-\000\000\000j\003|\002S\003z\003<\001\198\000\000\000\000\000\000\000\000\002G\000\000\002\202\000-\002H\001@\003\014\000^\001\199\001\184\003o\000\000\004\195\001\185\000k\000\000\000\000\003\015\003\007\000\000\001\184\002J\000^\000\000\001\185\000\000\000\000\000_\000\000\004\196\000\000\000`\004\199\004Y\000\000\000\228\000\000\002L\000\000\000l\000\000\003=\001\026\003\\\002\205\000\000\000\000\002B\003\"\000\000\002\164\000\160\003'\003~\0034\001\214\000i\001\198\000\000\000\000\000m\000\000\002G\004\232\002\165\000n\002H\001@\003\014\000\000\001\199\000\000\000\000\000\000\000o\001\215\000\000\001\182\001\205\003\015\001\216\000\000\000\000\002J\001\217\003\144\000\000\000\000\000\000\001\218\000-\000\000\004Z\004\235\002S\003 \003<\000\000\000\000\002L\000\000\000\000\000\000\003=\000\000\003}\000\000\000\000\001\198\002B\003\"\000\000\000\000\000\160\003'\000\000\0034\001\214\000\000\001\198\003\007\001\199\001\184\000\000\002G\000\000\001\185\000\000\002H\001@\003\014\000\000\001\199\000\000\000\000\000\000\000j\001\215\000\000\001\182\001\205\003\015\001\216\000\000\000\152\002J\001\217\000\000\000\000\000\000\000\000\001\218\000-\000\000\000\000\000\137\002S\000\000\003\006\000\000\000k\002L\000\000\000\000\000\000\003=\000\000\003}\000\000\000\000\000\000\000\000\003\"\000\000\000\000\000\160\003'\000\000\0034\001\214\001\182\001\200\003\007\000\000\001\184\000\138\000\000\000\000\001\185\000\000\000\160\004\227\000\000\000\166\000\000\000\000\000\000\000\000\004\238\001\215\000\000\000\000\000\000\000\000\001\216\000\000\000m\000\000\001\217\002u\000\139\002B\002\142\001\218\000\140\003\250\001\182\001\205\000\000\003\130\000o\001\198\000\000\000^\000\000\001\184\002G\001\182\001\205\001\185\002H\001@\003\014\000\000\001\199\002:\004\005\004a\000\000\000\211\000-\000\238\000\000\003\015\002S\000\000\003\006\002J\000\000\000\000\000\000\000\000\000^\000\000\004b\004Y\002w\000\000\000\000\002A\002x\001\184\000\000\002L\000\000\001\185\000\000\003=\000\000\003>\003\007\000\000\001\184\002B\003\"\000\000\001\185\000\160\003'\000\000\0034\001\214\000^\001\198\000\000\000\213\000\000\000\000\002G\000\214\000\000\000\000\002H\001@\003\014\000\000\001\199\000-\0003\000\000\0002\001\215\004a\004\008\000\000\003\015\001\216\003\130\000\000\003w\001\217\000\000\000\000\000\000\004Z\001\218\000\227\000\000\000\000\004b\004Y\000\000\000\000\000\000\001\198\002L\000\000\0004\000\000\003\029\003y\000\000\000\000\000\000\000\000\000\000\003\"\001\199\000\000\000\160\003'\000\000\0034\001\214\000\000\001\182\001\205\000\000\000\000\000\000\002B\000\000\000\\\002\133\000\000\000\211\000g\000\238\000-\000\000\001\198\002B\002S\001\215\003\006\002G\002\134\000\000\001\216\002H\000\000\001\198\001\217\001\199\000\000\000\000\002G\001\218\000\000\004Z\002H\001@\003\014\000\000\001\199\000\000\002J\000\000\003\007\000\000\001\184\004a\000\000\003\015\001\185\000^\000\228\003w\000^\000\000\000_\000\213\002L\000\000\000`\000\214\000\000\000\000\004b\004Y\000\000\000\000\000\000\002L\000\000\000\000\000\000\003\029\003y\000\000\001\214\004\n\000\254\004\174\003\"\003\130\000\000\000\160\003'\000i\0034\001\214\000\227\000\000\000\000\002\143\000\000\000\000\001@\000\000\001\215\000\000\000\000\000\000\001\000\001\216\000\000\000\000\000\000\001\217\001B\001\215\000\000\000\000\001\218\000\000\001\216\000\000\001\182\001\205\001\217\001i\000\000\000\000\001\001\001\218\0058\000\000\004Z\001\002\000\000\000-\000\000\001\003\000\000\002S\003 \003<\001\004\002B\000\211\000\000\000\238\000\000\000\160\001l\000\000\001o\004\172\001\198\000\000\000\000\000\000\000\000\002G\000\000\000\000\000\000\002H\001@\003\014\003\007\001\199\001\184\000\000\000\000\000\000\001\185\000\000\000j\000\000\003\015\000\228\000\000\000\000\003w\001\182\001\183\000\000\000\000\000\000\000\000\000\000\000^\000\000\000\000\000\213\000\000\000\000\000\000\000\214\002L\000\000\000k\000\000\003\029\003y\000\000\004\016\000\000\000\000\000\000\003\"\000\000\000\000\000\160\003'\000\000\0034\001\214\000\000\000\000\000\000\000\000\001\182\001\205\000\000\000\227\000l\000^\001\000\001\184\005[\000\000\000\000\001\185\000\000\000-\000\000\001\215\000\000\002S\003 \003<\001\216\000\000\000\000\004\216\001\217\000m\001\001\000\000\000\000\001\218\000\148\001\002\000\000\000\000\000\000\001\003\001\182\001\203\002B\000o\001\004\000\000\000\000\003\007\000\000\001\184\000\000\000\000\001\198\001\185\000\000\000\000\000\000\002G\000\000\000\000\000\000\002H\001@\003\014\000\000\001\199\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\015\000\000\000\000\000\\\002J\000\000\000\000\000e\000\000\000^\000\000\001\184\000\000\000\228\000\000\001\185\000\000\000\000\000\000\000\000\002L\000\000\000\000\000-\003=\000\000\003>\003\139\001\182\001\205\000\000\003\"\000\000\000\000\000\160\003'\001\198\0034\001\214\004\018\000\000\000-\000\000\000\000\000\000\002S\000^\003<\000\000\001\199\000\000\000_\000\000\002Z\000\000\000`\000\000\000\000\001\215\000\000\000\000\001\000\000\000\001\216\002B\000\000\001\240\001\217\000\000\000\000\000\000\003\007\001\218\001\184\001\198\000\000\000\000\001\185\000\000\002G\000i\001\001\000\000\002H\001@\003\014\001\002\001\199\000\000\000\000\001\003\000\000\001\182\001\205\000\000\001\004\003\015\000\000\000-\000\000\002J\000\000\000\000\003@\000\000\000-\000\000\000\000\000\000\002S\001\198\003\006\000\000\000\000\000\000\000\211\002L\000\238\000\000\000\000\003=\000\000\003>\001\199\000\000\000\000\000\000\003\"\003\158\000\000\000\160\003'\000\000\0034\001\214\003\007\000\000\001\184\000\000\000\000\000\000\001\185\000\000\000\000\000\000\000\211\000\000\000\238\000\000\000\000\000\211\000\000\000\229\000\000\001\215\000\000\001\182\001\205\000^\001\216\000j\000\213\002B\001\217\001@\000\214\000\000\003\005\001\218\000-\001\242\000\000\001\198\002S\000\000\003\006\002\223\002G\000\000\000\137\000\000\002H\001@\003\014\000k\001\199\000\000\000\000\000^\000\000\001\215\000\213\000\227\000^\003\015\000\214\000\213\000\000\003\141\003\007\000\214\001\184\000\000\000\000\001\218\001\185\000\000\000\000\000\000\000\138\000\160\002\235\000\000\002\249\002L\000\000\000\000\000\000\003=\000\000\003\143\000\000\000\227\000\000\000\000\003\"\002B\000\227\000\160\003'\000m\0034\001\214\000\000\000\139\000\000\001\198\000\000\000\140\001@\000\000\002G\000\000\000\000\000o\002H\001@\003\014\000\000\001\199\000\000\003\164\001\215\000\000\001\182\001\205\000\000\001\216\003\015\000\000\000\000\001\217\003\027\000\000\000\000\003!\001\218\000-\000\000\000\000\000\000\002S\000\228\003\006\000\000\000\000\000\000\000\000\002L\000\000\000\000\000\000\003\029\003\030\000\000\000\160\003\176\000\000\003\182\003\"\002B\000\000\000\160\003'\000\000\0034\001\214\003\007\004\020\001\184\001\198\000\000\000\228\001\185\000\000\002G\000\000\000\228\000\000\002H\001@\003\014\000\000\001\199\000\000\000\000\001\215\000\000\001\182\001\205\001\000\001\216\003\015\000\000\000\000\001\217\003\027\000\000\004$\000\000\001\218\000-\000\000\000\000\000\000\002S\000\000\003\006\000\000\000\000\001\001\000\000\002L\000\000\000\000\001\002\003\029\003\030\000\000\001\003\001\000\000\000\000\000\003\"\001\004\000\000\000\160\003'\000\000\0034\001\214\003\007\000\000\001\184\000\000\000\000\000\000\001\185\000\000\000\000\001\001\000\211\000\000\000\236\000\000\001\002\000\211\000\000\000\212\001\003\001\215\000\000\001\182\001\205\001\004\001\216\000\000\000\000\002B\001\217\000\000\000\000\000\000\000\000\001\218\000-\000\000\000\000\001\198\002S\000\000\003\006\000\000\002G\000\000\000\000\000\000\002H\001@\003\014\000\000\001\199\000\000\000\000\000^\000\000\000\000\000\213\000\000\000^\003\015\000\214\000\213\000\000\003\027\003\007\000\214\001\184\000\000\000\000\000\000\001\185\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002L\000\000\000\000\000\000\003\029\003\030\001\182\001\205\000\227\000\000\000\000\003\"\002B\000\227\000\160\003'\000\000\0034\001\214\000-\000\000\000\000\001\198\002S\000\000\003\006\000\000\002G\000\000\000\000\000\000\002H\001@\003\014\000\000\001\199\000\000\000\000\001\215\000\000\000\000\003_\000\000\001\216\003\015\000\000\000\000\001\217\003X\003\007\000\000\001\184\001\218\000\000\000\000\001\185\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002L\000\000\000\000\000\000\003\029\003Z\001\182\001\205\000\000\000\000\002u\003\"\002B\002\136\000\160\003'\000\000\0034\001\214\000-\000\000\000\000\001\198\002S\000\228\003\006\000\000\002G\000\000\000\228\000\000\002H\001@\003\014\000\000\001\199\000\000\000\211\001\215\000\238\000\000\003W\002u\001\216\003\015\002\135\000\000\001\217\003X\003\007\000\000\001\184\001\218\000^\000\000\001\185\000\000\002w\000\000\000\000\000\000\002x\000\000\000-\002L\000\000\005\012\000\000\003\029\003Z\000-\000\000\001\028\000\000\002S\003\"\002B\000\000\000\160\003'\000^\0034\001\214\000\213\000\000\000^\001\198\000\214\000\000\002w\000\000\002G\001\001\002x\000\000\002H\001@\003\014\000\000\001\199\004(\000\000\001\215\000\000\003k\000\000\001\004\001\216\003\015\000\000\000\000\001\217\003l\000\000\000\227\000\000\001\218\001U\000\000\000\000\000\000\000\000\000-\001k\000\000\0002\000\000\000\000\002L\000\000\000\000\001O\003\029\003n\001\182\001\205\000\000\000\000\002u\003\"\002B\002v\000\160\003'\000\000\0034\001\214\000-\000\000\000\000\001\198\002S\0004\003\006\002\133\002G\000\000\000\000\000\000\002H\001@\003\014\000\000\001\199\000\000\000\000\001\215\002\134\000\000\003i\000\000\001\216\003\015\000\000\000\000\001\217\003X\003\007\000\000\001\184\001\218\000^\000\000\001\185\000\000\002w\002\133\000\000\000\000\002x\000\000\000\000\002L\000\000\000\228\000\000\003\029\003Z\000\000\002\134\000\000\000\000\000\000\003\"\001@\000\000\000\160\003'\000\000\0034\001\214\001@\003\014\000\000\003v\000\000\001P\000\000\000\000\000\000\005\013\001\182\001\205\003\015\000\000\000\000\000\000\000\000\000\000\000\000\001\215\000\000\000\000\000\000\000-\001\216\001\182\001\203\002S\001\217\003\006\000\000\001\000\001[\001\218\001f\000\000\004-\001X\000\000\000\160\001Y\005\016\000\166\003\"\000\000\000\000\000\160\003'\000\000\0034\000\000\001\001\001@\003\007\000\000\001\184\001\002\002B\000\000\001\185\001\003\000\000\000\000\000\000\001B\001\004\000\000\001\198\000^\000\000\001\184\002\133\002G\000\000\001\185\001i\002H\001@\003\014\000\000\001\199\000\000\000\000\000\000\002\134\000\000\000\000\001\182\001\205\003\015\003{\000\000\000\000\003w\000\000\000\000\000\000\0054\000\160\001l\000-\001o\000\000\000\000\002S\000\000\003\006\000\000\000\000\002L\000\000\000\000\000\000\003\029\003y\000\000\000\000\000\000\000\000\000\000\003\"\000\000\000\000\000\160\003'\000\000\0034\001\214\000\000\000\000\003\007\000\000\001\184\000\000\000\000\000\000\001\185\000\000\001\182\001\205\000\000\000\000\000\000\000\000\002B\000\000\000\\\001\215\000\000\000\000\000e\000-\001\216\000\000\001\198\003\157\001\217\000\000\000\000\002G\000\000\001\218\000\000\002H\001@\003\014\000\000\001\199\000\000\001\198\000\000\000\000\000\000\000\000\003\189\000\000\003\015\001\182\001\203\000\000\003w\003\192\001\199\001\184\000\000\000\000\000\000\001\185\000\000\000^\000\000\000\000\000\000\000\000\000_\000\000\002L\000\000\000`\000\000\003\029\003y\001\182\001\205\003\198\000\000\000\000\003\"\000\000\002\031\000\160\003'\000\\\0034\001\214\000-\000q\000\000\000\000\003\157\000^\002B\001\184\000i\000\000\000\000\001\185\000\000\000\000\000\000\000\000\001\198\003\236\000\000\001\215\001\210\002G\001%\003\240\001\216\002H\001@\003\014\001\217\001\199\003\192\000\000\001\184\001\218\001\215\000\000\001\185\000\000\003\015\000\000\000^\000\000\0055\000\000\000\000\000_\000\000\000\000\001\220\000`\000\000\000\000\000\\\003\198\000\000\000\000\000g\000\000\002L\000\000\000\000\000\000\003\029\0057\000\000\000\000\000\000\001\198\000\000\003\"\000\000\000\000\000\160\003'\000i\0034\001\214\001@\003\199\000\000\001\199\000\000\000\000\000\000\000\000\001\182\001\205\000\000\000j\003\200\000\000\000\000\000\000\003\238\000\000\000^\001\215\000\000\000-\000\000\000_\001\216\003\157\000\000\000`\001\217\001\198\000\137\000\000\000\000\001\218\000\000\000k\000\000\000\000\000\000\000\000\000\000\000\000\001\199\003\214\003\191\000\000\000\160\003\239\000\000\003\226\001\214\003\192\000i\001\184\001\198\000\000\000\211\001\185\000\236\000\000\000\138\000\000\000\000\000\000\001@\003\199\000\000\001\199\000\000\000\\\001\215\000\000\000\000\000e\003\198\001\216\003\200\000j\000\000\001\217\003\212\000m\000-\000\000\001\218\000\139\000\000\000\000\000\000\000\140\000\000\000\000\000\211\000\000\000\236\000o\000\000\000\000\000\000\000^\000\000\000k\000\213\000\000\000\000\000\000\000\214\003\214\000\000\001\215\000\160\003\219\000^\003\226\001\214\000\000\000\000\000_\000\000\000\000\000\000\000`\000\000\001\222\000\000\000\000\000\136\000\000\000\000\000\000\000\000\000\000\000j\000\227\001\215\000^\000\000\000\000\000\213\001\216\000\\\000\000\000\214\001\217\000e\000\000\000i\000m\001\218\000\000\000\000\000\\\001\198\000-\000\000\000e\000k\000\000\000\000\000\000\000\000\000o\001@\003\199\000-\001\199\000\000\000\000\000\000\000\227\000\000\000\000\000\000\000\000\003\200\000\000\000\000\000\000\003\212\000\000\000\000\000l\000\000\000^\000\000\000\000\000\000\000\000\000_\000\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\003\214\000\000\000\151\000\160\003\219\000\000\003\226\001\214\000\228\000\000\000\000\000o\000i\000\000\000\000\000\000\000\000\000\000\000\152\000\000\000\000\000j\000\000\000i\000\000\000\000\000\000\001\215\002u\000\\\000\000\002\142\001\216\000e\000\000\000\000\001\217\000\155\000\156\000\158\000\159\001\218\000-\000\000\000\228\000k\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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^\000^\000\000\000\000\002w\001\001\000_\000\000\002x\000\000\000`\000\\\000\000\000\000\000\000\000q\000\000\000\000\000\152\001\n\000m\000j\000\000\000\000\000\139\000\000\000-\000\000\000\140\000\152\000\000\000\000\000j\000\000\000o\000i\000\171\000\155\000\218\000\158\000\159\001\001\000\000\000\000\000\000\000k\000\000\000\000\000\155\001\189\000\158\000\159\000\000\000\000\000^\001\012\000k\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\000\000\000\000\000\000\000\000\160\000\165\000\000\000\166\000\000\001U\000\138\000\000\000\000\000\000\000\000\000\000\000\000\000i\000\000\000\000\000m\000\000\000\000\001O\000\139\000\000\000\000\000\000\000\140\000\\\002\133\000m\000\000\000e\000o\000\139\000\171\000\000\000\000\000\140\000\000\000\152\000-\002\134\000j\000o\000\000\000\171\000\000\000\000\000\000\000\000\000\\\000\000\000\000\000\000\000e\000\000\000\000\000\000\000\155\002D\000\158\000\159\000\000\000-\000\000\000\\\000k\000\000\000\000\000q\000^\000\000\000\000\000\000\000\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\000\000^\001@\000j\000\000\000\000\000_\000\000\000\000\000\000\000`\000\211\000i\000\238\001P\000\000\000^\000\000\002\164\000\000\000m\000_\000\000\000\000\000\139\000`\000\000\000k\000\140\000\\\000\000\000\000\002\171\000e\000o\000i\000\171\000\000\000\000\000\000\000\000\001[\000-\001\\\000\000\000\000\001X\000\000\000\160\001Y\000i\000\166\000\\\000\000\000^\000\000\000e\000\213\000\000\000\000\000\000\000\214\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\000_\000\000\000\000\000\000\000`\000\000\000\000\000\000\000\000\000\000\000x\000\227\000\152\000\000\000\000\000j\000\000\000\\\000^\000\000\000\000\000g\000\000\000_\000\000\000\000\000\000\000`\000\000\000i\000\000\000\155\002|\000\158\000\159\000\152\000\000\000\000\000j\000k\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\000j\000\155\003$\000\158\000\159\000\160\000\165\000^\000\166\000k\000\000\000\138\000_\000\000\000\\\000\000\000`\000\000\000e\000\000\001#\001%\000\000\000\000\000k\000\000\000\000\000-\000\160\000\165\000\000\000\166\000m\000\000\000\138\000\000\000\139\000\000\000\228\000-\000\140\000i\000\000\000\000\000\000\000\000\000o\000\000\000\171\000\000\000\000\000\000\000\000\000\152\000\000\000m\000j\000^\000\000\000\139\000\000\000\000\000_\000\140\0043\000\000\000`\000\000\000\000\000o\000m\000\171\000\155\003\216\000\158\000\159\000\152\000\000\000\000\000j\000k\000\000\000\000\000\000\000z\000\000\001\000\000\000\000\000\000\000\000\000\000i\000\000\001U\000\000\000\000\000\000\000\000\000\188\000\160\000\165\000\000\000\166\000k\000\000\000\138\001\001\001O\000\000\000\000\000\000\001\002\000\000\000\000\000\000\001\003\001\182\001\205\000-\000\000\001\004\000j\000\160\001'\000\000\000\166\000m\000\000\000\138\000\000\000\139\000\000\000\000\000\\\000\140\003H\000\000\000e\000\000\000\000\000o\000\000\000\171\000\000\000\000\000k\000-\000\000\000\000\000m\000\000\000\000\000\000\000\139\000\000\000\000\000\\\000\140\000\000\002A\000e\001\184\000\000\000o\000\000\001\185\000\000\000\000\000\152\000-\000l\000j\001U\000\000\000\000\000\000\000^\000\000\000\000\000\000\001@\000_\000\000\000\000\000\000\000`\001O\000\173\000\000\000\000\000\159\000m\001P\000\000\000\000\000k\000\240\000\000\000\000\000^\000\000\000\000\000\000\000\000\000_\000o\000\000\000\000\000`\003N\000i\000\000\000\000\001\210\000\160\000\165\000\000\000\166\000\\\001[\000\138\001a\000e\000\000\001X\000\000\000\160\001Y\000\000\000\166\000\000\000-\000\000\000i\000\000\000\000\000\000\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\002B\000\000\000\000\000\000\000\000\000o\000\000\000\171\000\000\001@\001\198\000^\000\000\000\000\000\000\002G\000_\000\000\000\000\002H\000`\001P\000\000\001\199\000\000\000\\\000\000\000\000\000\000\000e\000\000\000\000\000\000\000\000\000\000\000\000\003P\000\152\000-\000\000\000j\000\000\000\000\000\000\000\000\000i\000\000\000\000\001[\000\000\001\137\000\000\002L\001X\000\000\000\160\001Y\000\000\000\166\000\183\000\152\000\000\000\000\000j\000k\000\\\000\000\000\000\000^\000g\001\214\000\000\000\000\000_\000\000\000\000\000\000\000`\000\000\000\000\000\000\000\000\000\195\000\160\001-\000\000\000\166\000k\000\\\000\138\001\215\000\000\000e\000\000\000\000\001\216\000\000\000\000\000\000\001\217\000\000\000-\000i\000\000\001\218\000\000\000\160\000\197\000^\000\166\000m\000\000\000\138\000_\000\139\000\000\000\000\000`\000\140\000\000\000\000\000\000\000\152\000\000\000o\000j\000\000\000\000\000\000\000\000\000\000\000^\000\000\000m\000\000\000\000\000_\000\139\000\000\000\000\000`\000\140\000i\000\000\000\195\000\000\000\\\000o\000\000\000k\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\000i\000\000\000\000\000\160\000\234\000\000\000\166\000\000\000\000\000\138\000\000\000\000\000\000\000\000\000\152\000\000\000\000\000j\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\000\183\000\000\000\140\000\000\000\000\000k\000\000\000\000\000o\001\182\001\205\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000j\000i\000\000\000\160\0016\000\000\000\166\002:\003Q\000\138\000\\\000\000\000\000\000\000\000e\000\000\000\000\000\000\000\000\000\000\000\152\000\000\000\000\000j\000k\000\000\000\000\000\000\000\000\000\000\000m\002A\000\000\001\184\000\139\000\000\000\000\001\185\000\140\000\000\000\000\000\000\001\165\000\000\000o\001\182\001\205\000k\000\000\000l\000\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:\003G\000\160\001\167\000\000\000\166\000m\000\000\000\138\002!\000\000\000\242\000\000\000\000\000\152\000\000\000\000\000j\000\000\000\000\000o\000\000\000\000\000i\002A\000\000\001\184\001\182\001\205\000m\001\185\000\000\000\000\000\139\000\000\000\000\001\165\000\140\000\000\001\182\001\203\000k\000\000\000o\000\000\000\000\002:\002;\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\182\001\205\000\000\002B\000\000\000\160\001\250\000\000\000\166\000\000\000\000\000\138\000\000\001\198\000\000\002A\000\000\001\184\002G\002:\002F\001\185\002H\000\000\000\000\000\000\001\199\000^\000\000\001\184\000\000\000\000\000m\001\185\000\000\000\000\000\139\000\000\000\\\002J\000\140\000\000\000e\002A\000\000\001\184\000o\000\000\000j\001\185\000\000\000\000\000\000\000\000\000\000\002L\000\000\000\000\000\000\000\000\002B\000\\\000\000\000\000\000\000\000e\000\000\000\137\000\000\000\000\001\198\000\000\000k\001\214\000-\002G\000\000\000\000\000\000\002H\000\000\000^\000\000\001\199\000\000\000\000\000_\000\000\000\000\000\000\000`\000\000\000\000\001\215\000\000\000\000\002J\000\138\001\216\000\000\000\000\002#\001\217\000\000\000^\000\000\002B\001\218\000\000\000_\000\000\000\000\002L\000`\000\000\000i\001\198\000\211\000m\000\236\000\000\002G\000\139\000\\\000\000\002H\000\140\000e\001\198\001\199\001\214\000\000\000o\000\000\002B\000\000\000-\000\000\000i\000\000\000\000\001\199\002J\000\000\001\198\000\000\000\000\000\000\000\000\002G\001\215\000\000\000\000\002H\000\000\001\216\000\000\001\199\002L\001\217\000^\000\000\000\000\000\213\001\218\000\000\000^\000\214\001\182\001\203\002J\000_\000\000\000\000\000\000\000`\001\214\000\000\000\000\000\000\000\000\000\000\000\000\001\182\001\205\000\000\002L\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\227\000j\001\215\000\000\000\000\000\000\000i\001\216\002:\003S\001\214\001\217\000\000\000\000\001\215\000\000\001\218\000^\000\000\001\184\000\137\000\152\000\000\001\185\000j\000k\000\000\000\000\001\224\000\000\001\215\000\000\002A\000\000\001\184\001\216\000\000\000\000\001\185\001\217\000\000\000\000\000\000\002e\001\218\000\000\001\182\001\205\000k\000\000\000\138\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\182\001\205\000\000\000\000\000\000\000\000\000\000\002:\004\026\000\160\002g\000\000\000\166\000m\000\000\000\138\000\000\000\139\000\000\002:\004\028\000\140\000\228\000\000\000\000\000\152\000\000\000o\000j\000\000\000\000\002A\000\000\001\184\000\000\000\000\000m\001\185\000\000\000\000\000\139\000\000\000\000\002A\000\140\001\184\000\211\002e\000\236\001\185\000o\000\000\000k\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\198\000\000\001\182\001\205\000\000\002B\000\\\000\000\000\000\000\000\000e\000\160\002\140\001\199\000\166\001\198\000\000\000\138\000\000\000\000\002G\002:\004\030\000\000\002H\000\000\000\000\000\000\001\199\000^\001\001\000\000\000\213\000\000\000\000\000\000\000\214\000\000\000m\000\\\000\000\002J\000\139\000e\001\014\002A\000\140\001\184\000\000\000^\000\000\001\185\000o\000\000\000_\000\000\000\000\002L\000`\000\000\000\000\000\000\002B\000\227\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\198\000\000\002B\001\214\000\000\002G\000\000\000\000\001\215\002H\000^\000i\001\198\001\199\000\000\000_\000\000\002G\000\000\000`\000\000\002H\001\226\001\215\000\000\001\199\002J\000\000\001\216\000\000\000\000\000\000\001\217\000\000\000\000\000\000\000\000\001\218\002J\000\000\000\000\000\000\002L\000\000\000i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002L\000\\\000\000\000\000\000\000\000e\001\214\000\000\000\000\000-\002B\002b\000\000\000\000\000\000\000\000\000\000\000\228\001\214\000\000\001\198\000\000\000\000\000\000\000\000\002G\001\215\000\000\002\216\002H\000\000\001\216\000\000\001\199\000\000\001\217\002u\000j\001\215\002\142\001\218\000\000\000\000\001\216\000^\000\000\002J\001\217\000\000\000_\000\000\000\000\001\218\000`\000\\\000\000\002\156\000\000\000e\000\000\000\000\000k\002L\001U\000\000\000\\\000\000\000\000\000\000\000e\000j\000\000\000\000\000\000\000\000\000\000\000\000\001O\000i\000^\001\214\000\000\000\000\002w\000\000\001\001\000\138\002x\000\000\000\188\000\000\000\\\000\000\000\000\000k\000e\000\000\000^\000\000\001\016\001\215\000\000\000_\000\000\000\000\001\216\000`\000m\000^\001\217\000\000\000\139\000\000\000_\001\218\000\140\000\000\000`\000\\\000\138\000\000\000o\000e\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000i\000\000\000\000\000^\000\000\000\000\000\000\000\000\000_\000m\000\000\000i\000`\000\139\000\000\000\000\000\000\000\140\002\154\001@\000\000\000\000\000\000\000o\000\000\000\000\000\000\000j\000\000\000\\\000^\001P\000\000\000e\000\000\000_\000\000\000i\000\000\000`\000\000\000\000\000\000\000\000\000\000\000\000\002\156\000\000\000\000\002\133\000\000\000k\000\000\000\000\000\000\000\\\000\000\000\000\001[\000e\002W\000\000\002\134\001X\000i\000\160\001Y\000\000\000\166\000\000\000\000\002\233\000^\000\000\000\000\000\000\000\138\000_\000\000\000\000\000j\000`\002\245\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000j\000\000\000\000\000\000\000\000\000\000\000m\000^\002\156\000\000\000\139\000\000\000_\000k\000\140\000i\000`\002\253\000\000\002\156\000o\000\000\000\000\000\000\000k\000\000\000j\000\000\000\\\000\000\000\000\000\000\000e\000\000\000\000\000\000\000\000\000\000\000\138\000\\\002\164\000i\000\000\000e\003\n\002\156\000\000\000\000\000\000\000\138\000k\000\000\000\000\000j\002\173\000\000\000\000\000\000\000\000\000m\000\000\000\000\000\000\000\139\000\000\000\\\000\000\000\140\000\000\000e\000m\000^\002\156\000o\000\139\000\138\000_\000k\000\140\000\000\000`\000\\\000^\000\000\000o\000e\003\025\000_\000\000\000\000\000\000\000`\000\000\000\000\000\000\000j\000m\000\000\000\000\000\000\000\139\000\000\000\138\000\\\000\140\000i\000\000\000e\000^\000\000\000o\000\000\0030\000_\002\156\000\000\000i\000`\000\000\000k\000\000\000j\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\000e\000\000\002\156\000\000\000i\000\000\000\138\000k\000^\000\000\000\000\000\000\000\\\000_\000\000\000\000\000e\000`\000\000\000\000\000i\000\000\000\000\000\000\000\000\000\000\000\000\000m\000\000\000\000\000\000\000\139\000\138\000\000\000\000\000\140\000\000\000\000\0038\000^\000\000\000o\000i\000\000\000_\000\000\000\000\000j\000`\003\162\000\000\000\000\000\000\000m\000\000\000^\000\000\000\139\000j\000\000\000_\000\140\000\000\000\000\000`\000\000\002\156\000o\000\\\000\000\000\000\000k\000e\000i\000\000\003\174\000\000\002\156\000\000\000\000\000\000\000\000\000k\000\000\000j\000\000\000\000\000\000\000\000\000i\000\000\003\180\000\000\000\000\000\000\000\000\000\138\000\000\000\000\000\000\000j\000\000\000\000\002\156\000\000\000\000\000\000\000\138\000k\000\000\000\000\000^\000\000\003\187\000\000\000\000\000_\000m\000\000\002\156\000`\000\139\000j\000\000\000k\000\140\000\000\000\000\000m\000\000\000\000\000o\000\139\000\138\000\000\000\000\000\140\000\211\000\000\000\236\000\000\002\156\000o\000\\\003\196\000i\000k\000e\000\000\000\138\000\000\000\000\000\000\000j\000m\000\\\000\000\000\000\000\139\000e\003\210\000\000\000\140\000\000\000\000\000-\000\000\005\007\000o\000j\000m\000\138\002\156\000\000\000\139\000\000\000\000\000k\000\140\000\000\000^\000\000\000\000\000\213\000o\000\000\000^\000\214\002\156\000\000\000\000\000_\000m\000k\000\000\000`\000\139\000\000\000^\000\000\000\140\000\000\000\138\000_\000\000\000\000\000o\000`\000\000\000\000\000\000\000\\\000\000\000\000\000\227\000e\003\224\000\000\000\138\001U\000i\000\000\000\000\000m\000\\\000j\000\000\000\139\000e\000\000\000\000\000\140\000i\001O\000\000\000\000\005j\000o\000\000\000m\000\000\000\000\000\000\000\139\002\156\000\000\000\000\000\140\000\000\000k\000\000\000\000\000\000\000o\000^\000\000\000\000\000\000\000\000\000_\000\000\000\000\000\000\000`\000\211\000\000\000\236\000^\001\182\001\203\000\000\000\000\000_\000\000\000\138\000\000\000`\000\\\000\000\000\000\000\\\000e\000\000\000\000\000e\000\000\000\000\000\000\000i\000\000\000\000\003\231\000\\\000\000\000\228\000m\000e\000\000\000\000\000\139\000j\000i\000\000\000\140\000\000\000\000\001@\000^\000\000\000o\000\213\000^\000j\001\184\000\214\000\000\000\000\001\185\001P\002\156\000^\000\000\000\000\000^\000k\000_\000\000\000\000\000_\000`\000\000\005\020\000`\000\000\000\000\000^\000k\000\000\000\000\000\000\000_\000\227\000\000\000\000\000`\001[\000\000\002\229\000\000\000\138\001X\000\000\000\160\001Y\000i\000\166\000\\\000i\000\000\000\\\000e\000\138\001\001\000e\000\000\000\000\000\000\000\000\000j\000i\000m\000\\\000\000\000\000\000\139\000e\001\018\000\000\000\140\000\000\000\000\000j\000m\000\000\000o\000\000\000\139\0010\000\000\000\000\000\140\000\000\000k\000\000\000\000\000\000\000o\000\000\000\000\000^\005\020\000\000\000^\000\000\000_\000k\000\000\000_\000`\000\000\000\000\000`\001\198\000\000\000^\000\000\000\000\000\138\000\000\000_\000\000\000\228\000\000\000`\000\000\001\199\000\000\000\000\000\\\000\000\000\138\000\000\000e\000i\000j\000\000\000i\000j\000m\000\000\000\000\000\000\000\139\000\000\000\000\000\000\000\140\000\000\000i\000j\000\000\000m\000o\000\175\000\000\000\139\000\190\000\000\000k\000\140\000\000\000k\000\000\000\000\000\000\000o\000\000\000\000\000\221\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\138\000\000\000\000\000\138\000\000\000\000\001\001\000\000\000\\\001\215\000\000\000\000\000e\000\000\000\000\000\138\000\211\000\000\000\236\000\000\001\020\000m\000i\001\228\000m\000\139\000\000\000\000\000\139\000\140\000j\000\000\000\140\000j\000\000\000o\000m\000\000\000o\000\000\000\139\000\000\000\000\000\000\000\140\000j\000\000\000\000\000\000\000\250\000o\000^\001\152\000\000\000k\000\000\000_\000k\000\000\000^\000`\000\000\000\213\000\000\001\156\000\000\000\214\000\000\000\000\000k\000\\\000\000\000\000\000\000\000e\000\000\000\000\000\000\000\000\000\138\000\000\000\000\000\138\000\000\000\000\000i\000\000\000\\\000\000\000\000\000\000\000e\000\000\000\227\000\138\000\000\000\000\000\000\000\000\000\000\000m\000\000\000j\000m\000\139\000\000\000\000\000\139\000\140\002u\000\000\000\140\002\142\000^\000o\000m\000\000\000o\000_\000\139\000\000\001\192\000`\000\140\000\000\000\000\000k\000\\\000\000\000o\000^\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\000i\000\000\000e\000\000\000\138\002A\000\000\000\000\000\000\002w\000\000\000\000\000\000\002x\000\000\000\000\000\\\000i\000j\002u\000e\000\000\002\142\000^\000\000\000m\000\228\000\000\000_\000\139\000\000\000\000\000`\000\140\000\000\000\000\000\000\001\255\000\000\000o\000\000\000^\000k\000\\\000\000\000\000\000_\000e\000\000\000\000\000`\000\000\000\000\000\000\000\000\000\000\000\000\000i\000\000\000^\000\000\000\000\000^\000\000\000_\000\000\002w\000\138\000`\000\000\002x\000\000\000\000\000\000\000\\\000i\000\000\000\000\000e\000\000\000j\000\000\000\000\000\000\002u\000\000\000^\002\142\000m\000\000\000\000\000_\000\139\000i\001\001\000`\000\140\000j\000\000\002\023\000\000\000\\\000o\000\000\000k\000g\002\133\000\000\001\022\002\160\000\000\000\000\000\000\000\000\000\\\002\161\002>\000^\000g\002\134\000i\000k\000_\000\000\000\000\000\000\000`\000^\000\000\000\138\000\000\002w\000\000\000\000\000\000\002x\000\000\000j\000\000\000\000\000\000\000\000\000\000\000\000\000^\000\000\000\138\000\000\000\000\000_\000m\000i\000\000\000`\000\139\000j\002\127\000^\000\140\000\000\000\000\000k\000_\002\133\000o\000\000\000`\000m\000\000\002u\000\000\000\139\002\142\000j\002\145\000\140\002\134\000\000\000i\000k\000\000\000o\000\000\000\000\000\000\000\000\000\138\002u\002\164\000\000\002\142\000i\002\147\000\000\000-\000\000\000\000\000k\000-\000\000\000j\000\000\002\165\000\000\000\138\000\000\000\000\000m\000\000\000-\000\000\000\139\002A\000\000\000\000\000\140\002w\000\000\000-\003\150\002x\000o\000\138\000\000\000k\000m\000\000\000\000\002\133\000\139\002A\000j\000\000\000\140\002w\000\000\000\000\000\000\002x\000o\000\000\002\134\000\000\000m\000\000\002\164\000\000\000\139\001U\000\138\003\254\000\140\001U\000\000\000\000\000k\000\000\000o\000j\002\175\000\000\000\000\001O\001U\000\000\000\000\001O\000\000\000\000\000-\000m\000j\001U\000\000\000\139\000\000\000\000\001O\000\140\000\000\000\138\000\000\000k\000\000\000o\000\000\001O\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000k\000\000\000\000\000\000\000\000\000\000\000m\000\000\000\000\000\000\000\139\000\000\000l\000\000\000\140\002\164\000\000\000\000\002\133\000\000\000o\002\163\000\000\000\000\000\000\000l\000\000\002\161\001U\002\177\000\\\002\134\000\000\000m\000q\000\000\002\133\000\000\001\207\002\212\001@\000\000\001O\000\000\001@\002\161\000m\000o\000\000\002\134\000\000\001\209\001P\000\000\000\000\001@\001P\000\000\000\000\000\000\000o\000\000\000\000\000\000\001@\000\000\000\000\001P\000\000\000\000\000\000\000\000\000\000\000^\000\000\000\000\001P\000\000\000_\001[\000\000\002\240\000`\001[\001X\003\021\000\160\001Y\001X\000\166\000\160\001Y\000\000\000\166\001[\000\000\003+\000\000\000\000\001X\002\164\000\160\001Y\001[\000\166\003\170\000\000\000i\001X\000\000\000\160\001Y\000\000\000\166\002\165\001@\000\000\000\\\002\164\000\000\000\\\000q\000\000\000\000\000q\000\000\000\000\001P\000\000\000\000\000\\\000\000\002\165\000\\\000q\000\000\000\\\000q\000\000\000\000\000q\000\000\000\000\000\\\000\000\000\000\000\000\000q\000\000\000\000\000\000\000\000\000\000\000\\\001[\000\000\003\206\000q\000\000\001X\000^\000\160\001Y\000^\000\166\000_\000\000\000\000\000_\000`\000\000\000\000\000`\000^\000\000\000\211\000^\000\236\000_\000^\000\000\000_\000`\000\000\000_\000`\000^\000j\000`\001\182\001\203\000_\000\000\000\000\000i\000`\000^\000i\000\211\000\000\000\236\000_\000\000\000\000\000\000\000`\000\000\000i\000\000\000\000\000i\000k\000\000\000i\000\000\000\211\000\000\000\236\000^\000\000\000i\000\213\000\000\000\000\000\000\000\214\000\211\000\000\000\236\000\000\000i\000\000\000^\000\000\001\184\001\182\001\203\000\000\001\185\000\000\000\000\000^\000\000\000\000\000\213\000\000\001\182\001\203\000\214\000\000\000\000\000\000\000\227\000\000\000\000\000\000\000\000\000m\000^\000\000\000\000\000\213\000\000\001\182\001\203\000\214\000\000\000\000\000\000\000^\000\000\000|\000\213\000\000\000j\000\227\000\214\000j\000^\000\000\001\184\000\000\001\182\001\203\001\185\000\000\000\000\000j\000\000\000^\000j\001\184\000\227\000j\000\000\001\185\000\000\000\000\000k\000\000\000j\000k\000\000\000\227\000\000\000\000\000^\000\000\001\184\000\000\000j\000k\001\185\000\000\000k\000\000\000\000\000k\000\000\001\182\001\203\000\000\000\000\000\000\000k\000^\000\000\001\184\000\000\000\000\000\000\001\185\000\228\001\198\000k\002u\000\000\000\000\002\142\000\000\000\000\000\000\001\182\001\203\000m\000\000\001\199\000m\000\000\000\000\001\182\001\203\000\000\000\000\000\000\000\228\000\000\000m\000~\000\000\000m\000\128\000^\000m\001\184\000\000\000\000\000\000\001\185\000\000\000m\000\130\000\228\000\000\000\132\000\000\000\000\000\142\000^\001\198\000m\000\000\002w\000\228\000\144\000^\002x\001\184\000\000\000\000\001\198\001\185\001\199\000^\000\146\001\184\000\000\000\000\002u\001\185\001\001\002\142\000\000\001\199\000\000\002u\000\000\001\198\002\142\000\000\000\000\000\000\000\000\001\215\001\024\002u\000\000\000\000\002\142\000\000\001\199\002u\000\000\001\001\002\142\000\000\001\198\001\230\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\030\000\000\001\199\001\001\000^\000\000\000\000\000\000\002w\000\000\000\000\000^\002x\000\000\001\001\002w\000\000\001 \000\000\002x\002u\000^\001\215\002\142\000\000\002w\001\198\000^\001\"\002x\000\000\002w\000\000\001\215\000\000\002x\001\232\000\000\002u\001\199\000\000\002\142\002\133\000\000\000\000\000\000\000\000\001\234\000\000\001\198\001\215\000\000\000\000\000\000\000\000\002\134\000\000\001\198\000\000\000\000\000\000\000\000\001\199\000^\001\236\000\000\000\000\002w\000\000\001\215\001\199\002x\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000^\000\000\001\238\000\000\002w\000\000\000\000\000\000\002x\000\000\000\000\000\000\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\133\001\215\000\000\000\000\000\000\000\000\000\000\002\133\000\000\000\000\000\000\000\000\000\000\002\134\000\000\001\244\000\000\002\133\000\000\002\164\002\134\000\000\000\000\002\133\001\215\000\000\000\000\000\000\000\000\000\000\002\134\000\000\001\215\002\179\000\000\000\000\002\134\000\000\001\246\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\248\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\133\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\134\000\000\000\000\000\000\000\000\002\133\000\000\000\000\000\000\000\000\002\164\000\000\000\000\000\000\000\000\000\000\000\000\002\164\002\134\000\000\000\000\000\000\000\000\000\000\002\181\000\000\000\000\002\164\000\000\000\000\000\000\002\183\000\000\002\164\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\185\000\000\000\000\000\000\000\000\000\000\002\187\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\164\000\000\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\189\000\000\000\000\000\000\002\164\000\000\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\191")) + ((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")) let semantic_action = [| @@ -1459,9 +1491,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_aexpr = -# 1656 "parser_cocci_menhir.mly" +# 1662 "parser_cocci_menhir.mly" ( Ast0.set_arg_exp _1 ) -# 1465 "parser_cocci_menhir.ml" +# 1497 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -1482,12 +1514,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 65 "parser_cocci_menhir.mly" (Parse_aux.list_info) -# 1486 "parser_cocci_menhir.ml" +# 1518 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_aexpr = -# 1658 "parser_cocci_menhir.mly" +# 1664 "parser_cocci_menhir.mly" ( let (nm,lenname,pure,clt) = _1 in let nm = P.clt2mcode nm clt in let lenname = @@ -1495,7 +1527,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct Some nm -> Some(P.clt2mcode nm clt) | None -> None in Ast0.wrap(Ast0.MetaExprList(nm,lenname,pure)) ) -# 1499 "parser_cocci_menhir.ml" +# 1531 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -1517,9 +1549,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_aexpr = -# 1666 "parser_cocci_menhir.mly" +# 1672 "parser_cocci_menhir.mly" ( Ast0.set_arg_exp(Ast0.wrap(Ast0.TypeExp(_1))) ) -# 1523 "parser_cocci_menhir.ml" +# 1555 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -1539,9 +1571,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_any_strict = -# 1712 "parser_cocci_menhir.mly" +# 1716 "parser_cocci_menhir.mly" ( Ast.WhenAny ) -# 1545 "parser_cocci_menhir.ml" +# 1577 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -1561,9 +1593,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_any_strict = -# 1713 "parser_cocci_menhir.mly" +# 1717 "parser_cocci_menhir.mly" ( Ast.WhenStrict ) -# 1567 "parser_cocci_menhir.ml" +# 1599 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -1583,9 +1615,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_any_strict = -# 1714 "parser_cocci_menhir.mly" +# 1718 "parser_cocci_menhir.mly" ( Ast.WhenForall ) -# 1589 "parser_cocci_menhir.ml" +# 1621 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -1605,9 +1637,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_any_strict = -# 1715 "parser_cocci_menhir.mly" +# 1719 "parser_cocci_menhir.mly" ( Ast.WhenExists ) -# 1611 "parser_cocci_menhir.ml" +# 1643 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -1631,7 +1663,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_dot_expressions_ = # 1190 "parser_cocci_menhir.mly" ( _1 ) -# 1635 "parser_cocci_menhir.ml" +# 1667 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -1663,7 +1695,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 98 "parser_cocci_menhir.mly" (Data.clt) -# 1667 "parser_cocci_menhir.ml" +# 1699 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_dot_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -1671,7 +1703,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_dot_expressions_ = # 1192 "parser_cocci_menhir.mly" ( P.arith_op Ast.Mul _1 _2 _3 ) -# 1675 "parser_cocci_menhir.ml" +# 1707 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -1703,7 +1735,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 96 "parser_cocci_menhir.mly" (Ast_cocci.arithOp * Data.clt) -# 1707 "parser_cocci_menhir.ml" +# 1739 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_dot_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -1711,7 +1743,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_dot_expressions_ = # 1194 "parser_cocci_menhir.mly" ( let (op,clt) = _2 in P.arith_op op _1 clt _3 ) -# 1715 "parser_cocci_menhir.ml" +# 1747 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -1743,7 +1775,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 97 "parser_cocci_menhir.mly" (Data.clt) -# 1747 "parser_cocci_menhir.ml" +# 1779 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_dot_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -1751,7 +1783,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_dot_expressions_ = # 1196 "parser_cocci_menhir.mly" ( P.arith_op Ast.Plus _1 _2 _3 ) -# 1755 "parser_cocci_menhir.ml" +# 1787 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -1783,7 +1815,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 97 "parser_cocci_menhir.mly" (Data.clt) -# 1787 "parser_cocci_menhir.ml" +# 1819 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_dot_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -1791,7 +1823,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_dot_expressions_ = # 1198 "parser_cocci_menhir.mly" ( P.arith_op Ast.Minus _1 _2 _3 ) -# 1795 "parser_cocci_menhir.ml" +# 1827 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -1823,7 +1855,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 95 "parser_cocci_menhir.mly" (Ast_cocci.arithOp * Data.clt) -# 1827 "parser_cocci_menhir.ml" +# 1859 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_dot_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -1831,7 +1863,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_dot_expressions_ = # 1200 "parser_cocci_menhir.mly" ( let (op,clt) = _2 in P.arith_op op _1 clt _3 ) -# 1835 "parser_cocci_menhir.ml" +# 1867 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -1863,7 +1895,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 94 "parser_cocci_menhir.mly" (Ast_cocci.logicalOp * Data.clt) -# 1867 "parser_cocci_menhir.ml" +# 1899 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_dot_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -1871,7 +1903,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_dot_expressions_ = # 1202 "parser_cocci_menhir.mly" ( let (op,clt) = _2 in P.logic_op op _1 clt _3 ) -# 1875 "parser_cocci_menhir.ml" +# 1907 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -1903,7 +1935,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 93 "parser_cocci_menhir.mly" (Data.clt) -# 1907 "parser_cocci_menhir.ml" +# 1939 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_dot_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -1911,7 +1943,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_dot_expressions_ = # 1204 "parser_cocci_menhir.mly" ( P.logic_op Ast.Eq _1 _2 _3 ) -# 1915 "parser_cocci_menhir.ml" +# 1947 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -1943,7 +1975,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 93 "parser_cocci_menhir.mly" (Data.clt) -# 1947 "parser_cocci_menhir.ml" +# 1979 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_dot_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -1951,7 +1983,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_dot_expressions_ = # 1206 "parser_cocci_menhir.mly" ( P.logic_op Ast.NotEq _1 _2 _3 ) -# 1955 "parser_cocci_menhir.ml" +# 1987 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -1983,7 +2015,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 92 "parser_cocci_menhir.mly" (Data.clt) -# 1987 "parser_cocci_menhir.ml" +# 2019 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_dot_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -1991,7 +2023,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_dot_expressions_ = # 1208 "parser_cocci_menhir.mly" ( P.arith_op Ast.And _1 _2 _3 ) -# 1995 "parser_cocci_menhir.ml" +# 2027 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2023,7 +2055,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 90 "parser_cocci_menhir.mly" (Data.clt) -# 2027 "parser_cocci_menhir.ml" +# 2059 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_dot_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2031,7 +2063,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_dot_expressions_ = # 1210 "parser_cocci_menhir.mly" ( P.arith_op Ast.Or _1 _2 _3 ) -# 2035 "parser_cocci_menhir.ml" +# 2067 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2063,7 +2095,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 91 "parser_cocci_menhir.mly" (Data.clt) -# 2067 "parser_cocci_menhir.ml" +# 2099 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_dot_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2071,7 +2103,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_dot_expressions_ = # 1212 "parser_cocci_menhir.mly" ( P.arith_op Ast.Xor _1 _2 _3 ) -# 2075 "parser_cocci_menhir.ml" +# 2107 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2103,7 +2135,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 89 "parser_cocci_menhir.mly" (Data.clt) -# 2107 "parser_cocci_menhir.ml" +# 2139 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_dot_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2111,7 +2143,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_dot_expressions_ = # 1214 "parser_cocci_menhir.mly" ( P.logic_op Ast.AndLog _1 _2 _3 ) -# 2115 "parser_cocci_menhir.ml" +# 2147 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2143,7 +2175,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 88 "parser_cocci_menhir.mly" (Data.clt) -# 2147 "parser_cocci_menhir.ml" +# 2179 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_dot_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2151,7 +2183,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_dot_expressions_ = # 1216 "parser_cocci_menhir.mly" ( P.logic_op Ast.OrLog _1 _2 _3 ) -# 2155 "parser_cocci_menhir.ml" +# 2187 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2175,7 +2207,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_invalid_ = # 1190 "parser_cocci_menhir.mly" ( _1 ) -# 2179 "parser_cocci_menhir.ml" +# 2211 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2207,7 +2239,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 98 "parser_cocci_menhir.mly" (Data.clt) -# 2211 "parser_cocci_menhir.ml" +# 2243 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2215,7 +2247,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_invalid_ = # 1192 "parser_cocci_menhir.mly" ( P.arith_op Ast.Mul _1 _2 _3 ) -# 2219 "parser_cocci_menhir.ml" +# 2251 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2247,7 +2279,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 96 "parser_cocci_menhir.mly" (Ast_cocci.arithOp * Data.clt) -# 2251 "parser_cocci_menhir.ml" +# 2283 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2255,7 +2287,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_invalid_ = # 1194 "parser_cocci_menhir.mly" ( let (op,clt) = _2 in P.arith_op op _1 clt _3 ) -# 2259 "parser_cocci_menhir.ml" +# 2291 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2287,7 +2319,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 97 "parser_cocci_menhir.mly" (Data.clt) -# 2291 "parser_cocci_menhir.ml" +# 2323 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2295,7 +2327,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_invalid_ = # 1196 "parser_cocci_menhir.mly" ( P.arith_op Ast.Plus _1 _2 _3 ) -# 2299 "parser_cocci_menhir.ml" +# 2331 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2327,7 +2359,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 97 "parser_cocci_menhir.mly" (Data.clt) -# 2331 "parser_cocci_menhir.ml" +# 2363 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2335,7 +2367,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_invalid_ = # 1198 "parser_cocci_menhir.mly" ( P.arith_op Ast.Minus _1 _2 _3 ) -# 2339 "parser_cocci_menhir.ml" +# 2371 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2367,7 +2399,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 95 "parser_cocci_menhir.mly" (Ast_cocci.arithOp * Data.clt) -# 2371 "parser_cocci_menhir.ml" +# 2403 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2375,7 +2407,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_invalid_ = # 1200 "parser_cocci_menhir.mly" ( let (op,clt) = _2 in P.arith_op op _1 clt _3 ) -# 2379 "parser_cocci_menhir.ml" +# 2411 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2407,7 +2439,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 94 "parser_cocci_menhir.mly" (Ast_cocci.logicalOp * Data.clt) -# 2411 "parser_cocci_menhir.ml" +# 2443 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2415,7 +2447,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_invalid_ = # 1202 "parser_cocci_menhir.mly" ( let (op,clt) = _2 in P.logic_op op _1 clt _3 ) -# 2419 "parser_cocci_menhir.ml" +# 2451 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2447,7 +2479,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 93 "parser_cocci_menhir.mly" (Data.clt) -# 2451 "parser_cocci_menhir.ml" +# 2483 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2455,7 +2487,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_invalid_ = # 1204 "parser_cocci_menhir.mly" ( P.logic_op Ast.Eq _1 _2 _3 ) -# 2459 "parser_cocci_menhir.ml" +# 2491 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2487,7 +2519,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 93 "parser_cocci_menhir.mly" (Data.clt) -# 2491 "parser_cocci_menhir.ml" +# 2523 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2495,7 +2527,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_invalid_ = # 1206 "parser_cocci_menhir.mly" ( P.logic_op Ast.NotEq _1 _2 _3 ) -# 2499 "parser_cocci_menhir.ml" +# 2531 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2527,7 +2559,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 92 "parser_cocci_menhir.mly" (Data.clt) -# 2531 "parser_cocci_menhir.ml" +# 2563 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2535,7 +2567,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_invalid_ = # 1208 "parser_cocci_menhir.mly" ( P.arith_op Ast.And _1 _2 _3 ) -# 2539 "parser_cocci_menhir.ml" +# 2571 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2567,7 +2599,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 90 "parser_cocci_menhir.mly" (Data.clt) -# 2571 "parser_cocci_menhir.ml" +# 2603 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2575,7 +2607,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_invalid_ = # 1210 "parser_cocci_menhir.mly" ( P.arith_op Ast.Or _1 _2 _3 ) -# 2579 "parser_cocci_menhir.ml" +# 2611 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2607,7 +2639,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 91 "parser_cocci_menhir.mly" (Data.clt) -# 2611 "parser_cocci_menhir.ml" +# 2643 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2615,7 +2647,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_invalid_ = # 1212 "parser_cocci_menhir.mly" ( P.arith_op Ast.Xor _1 _2 _3 ) -# 2619 "parser_cocci_menhir.ml" +# 2651 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2647,7 +2679,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 89 "parser_cocci_menhir.mly" (Data.clt) -# 2651 "parser_cocci_menhir.ml" +# 2683 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2655,7 +2687,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_invalid_ = # 1214 "parser_cocci_menhir.mly" ( P.logic_op Ast.AndLog _1 _2 _3 ) -# 2659 "parser_cocci_menhir.ml" +# 2691 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2687,7 +2719,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 88 "parser_cocci_menhir.mly" (Data.clt) -# 2691 "parser_cocci_menhir.ml" +# 2723 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2695,7 +2727,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_invalid_ = # 1216 "parser_cocci_menhir.mly" ( P.logic_op Ast.OrLog _1 _2 _3 ) -# 2699 "parser_cocci_menhir.ml" +# 2731 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2719,7 +2751,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_nest_expressions_ = # 1190 "parser_cocci_menhir.mly" ( _1 ) -# 2723 "parser_cocci_menhir.ml" +# 2755 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2751,7 +2783,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 98 "parser_cocci_menhir.mly" (Data.clt) -# 2755 "parser_cocci_menhir.ml" +# 2787 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_nest_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2759,7 +2791,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_nest_expressions_ = # 1192 "parser_cocci_menhir.mly" ( P.arith_op Ast.Mul _1 _2 _3 ) -# 2763 "parser_cocci_menhir.ml" +# 2795 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2791,7 +2823,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 96 "parser_cocci_menhir.mly" (Ast_cocci.arithOp * Data.clt) -# 2795 "parser_cocci_menhir.ml" +# 2827 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_nest_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2799,7 +2831,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_nest_expressions_ = # 1194 "parser_cocci_menhir.mly" ( let (op,clt) = _2 in P.arith_op op _1 clt _3 ) -# 2803 "parser_cocci_menhir.ml" +# 2835 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2831,7 +2863,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 97 "parser_cocci_menhir.mly" (Data.clt) -# 2835 "parser_cocci_menhir.ml" +# 2867 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_nest_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2839,7 +2871,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_nest_expressions_ = # 1196 "parser_cocci_menhir.mly" ( P.arith_op Ast.Plus _1 _2 _3 ) -# 2843 "parser_cocci_menhir.ml" +# 2875 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2871,7 +2903,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 97 "parser_cocci_menhir.mly" (Data.clt) -# 2875 "parser_cocci_menhir.ml" +# 2907 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_nest_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2879,7 +2911,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_nest_expressions_ = # 1198 "parser_cocci_menhir.mly" ( P.arith_op Ast.Minus _1 _2 _3 ) -# 2883 "parser_cocci_menhir.ml" +# 2915 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2911,7 +2943,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 95 "parser_cocci_menhir.mly" (Ast_cocci.arithOp * Data.clt) -# 2915 "parser_cocci_menhir.ml" +# 2947 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_nest_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2919,7 +2951,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_nest_expressions_ = # 1200 "parser_cocci_menhir.mly" ( let (op,clt) = _2 in P.arith_op op _1 clt _3 ) -# 2923 "parser_cocci_menhir.ml" +# 2955 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2951,7 +2983,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 94 "parser_cocci_menhir.mly" (Ast_cocci.logicalOp * Data.clt) -# 2955 "parser_cocci_menhir.ml" +# 2987 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_nest_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2959,7 +2991,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_nest_expressions_ = # 1202 "parser_cocci_menhir.mly" ( let (op,clt) = _2 in P.logic_op op _1 clt _3 ) -# 2963 "parser_cocci_menhir.ml" +# 2995 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -2991,7 +3023,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 93 "parser_cocci_menhir.mly" (Data.clt) -# 2995 "parser_cocci_menhir.ml" +# 3027 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_nest_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -2999,7 +3031,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_nest_expressions_ = # 1204 "parser_cocci_menhir.mly" ( P.logic_op Ast.Eq _1 _2 _3 ) -# 3003 "parser_cocci_menhir.ml" +# 3035 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3031,7 +3063,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 93 "parser_cocci_menhir.mly" (Data.clt) -# 3035 "parser_cocci_menhir.ml" +# 3067 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_nest_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -3039,7 +3071,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_nest_expressions_ = # 1206 "parser_cocci_menhir.mly" ( P.logic_op Ast.NotEq _1 _2 _3 ) -# 3043 "parser_cocci_menhir.ml" +# 3075 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3071,7 +3103,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 92 "parser_cocci_menhir.mly" (Data.clt) -# 3075 "parser_cocci_menhir.ml" +# 3107 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_nest_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -3079,7 +3111,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_nest_expressions_ = # 1208 "parser_cocci_menhir.mly" ( P.arith_op Ast.And _1 _2 _3 ) -# 3083 "parser_cocci_menhir.ml" +# 3115 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3111,7 +3143,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 90 "parser_cocci_menhir.mly" (Data.clt) -# 3115 "parser_cocci_menhir.ml" +# 3147 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_nest_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -3119,7 +3151,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_nest_expressions_ = # 1210 "parser_cocci_menhir.mly" ( P.arith_op Ast.Or _1 _2 _3 ) -# 3123 "parser_cocci_menhir.ml" +# 3155 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3151,7 +3183,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 91 "parser_cocci_menhir.mly" (Data.clt) -# 3155 "parser_cocci_menhir.ml" +# 3187 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_nest_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -3159,7 +3191,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_nest_expressions_ = # 1212 "parser_cocci_menhir.mly" ( P.arith_op Ast.Xor _1 _2 _3 ) -# 3163 "parser_cocci_menhir.ml" +# 3195 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3191,7 +3223,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 89 "parser_cocci_menhir.mly" (Data.clt) -# 3195 "parser_cocci_menhir.ml" +# 3227 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_nest_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -3199,7 +3231,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_nest_expressions_ = # 1214 "parser_cocci_menhir.mly" ( P.logic_op Ast.AndLog _1 _2 _3 ) -# 3203 "parser_cocci_menhir.ml" +# 3235 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3231,7 +3263,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 88 "parser_cocci_menhir.mly" (Data.clt) -# 3235 "parser_cocci_menhir.ml" +# 3267 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_eexpr_nest_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -3239,7 +3271,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_eexpr_nest_expressions_ = # 1216 "parser_cocci_menhir.mly" ( P.logic_op Ast.OrLog _1 _2 _3 ) -# 3243 "parser_cocci_menhir.ml" +# 3275 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3263,7 +3295,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_expr_invalid_ = # 1190 "parser_cocci_menhir.mly" ( _1 ) -# 3267 "parser_cocci_menhir.ml" +# 3299 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3295,7 +3327,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 98 "parser_cocci_menhir.mly" (Data.clt) -# 3299 "parser_cocci_menhir.ml" +# 3331 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_expr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -3303,7 +3335,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_expr_invalid_ = # 1192 "parser_cocci_menhir.mly" ( P.arith_op Ast.Mul _1 _2 _3 ) -# 3307 "parser_cocci_menhir.ml" +# 3339 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3335,7 +3367,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 96 "parser_cocci_menhir.mly" (Ast_cocci.arithOp * Data.clt) -# 3339 "parser_cocci_menhir.ml" +# 3371 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_expr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -3343,7 +3375,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_expr_invalid_ = # 1194 "parser_cocci_menhir.mly" ( let (op,clt) = _2 in P.arith_op op _1 clt _3 ) -# 3347 "parser_cocci_menhir.ml" +# 3379 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3375,7 +3407,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 97 "parser_cocci_menhir.mly" (Data.clt) -# 3379 "parser_cocci_menhir.ml" +# 3411 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_expr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -3383,7 +3415,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_expr_invalid_ = # 1196 "parser_cocci_menhir.mly" ( P.arith_op Ast.Plus _1 _2 _3 ) -# 3387 "parser_cocci_menhir.ml" +# 3419 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3415,7 +3447,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 97 "parser_cocci_menhir.mly" (Data.clt) -# 3419 "parser_cocci_menhir.ml" +# 3451 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_expr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -3423,7 +3455,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_expr_invalid_ = # 1198 "parser_cocci_menhir.mly" ( P.arith_op Ast.Minus _1 _2 _3 ) -# 3427 "parser_cocci_menhir.ml" +# 3459 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3455,7 +3487,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 95 "parser_cocci_menhir.mly" (Ast_cocci.arithOp * Data.clt) -# 3459 "parser_cocci_menhir.ml" +# 3491 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_expr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -3463,7 +3495,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_expr_invalid_ = # 1200 "parser_cocci_menhir.mly" ( let (op,clt) = _2 in P.arith_op op _1 clt _3 ) -# 3467 "parser_cocci_menhir.ml" +# 3499 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3495,7 +3527,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 94 "parser_cocci_menhir.mly" (Ast_cocci.logicalOp * Data.clt) -# 3499 "parser_cocci_menhir.ml" +# 3531 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_expr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -3503,7 +3535,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_expr_invalid_ = # 1202 "parser_cocci_menhir.mly" ( let (op,clt) = _2 in P.logic_op op _1 clt _3 ) -# 3507 "parser_cocci_menhir.ml" +# 3539 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3535,7 +3567,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 93 "parser_cocci_menhir.mly" (Data.clt) -# 3539 "parser_cocci_menhir.ml" +# 3571 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_expr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -3543,7 +3575,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_expr_invalid_ = # 1204 "parser_cocci_menhir.mly" ( P.logic_op Ast.Eq _1 _2 _3 ) -# 3547 "parser_cocci_menhir.ml" +# 3579 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3575,7 +3607,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 93 "parser_cocci_menhir.mly" (Data.clt) -# 3579 "parser_cocci_menhir.ml" +# 3611 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_expr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -3583,7 +3615,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_expr_invalid_ = # 1206 "parser_cocci_menhir.mly" ( P.logic_op Ast.NotEq _1 _2 _3 ) -# 3587 "parser_cocci_menhir.ml" +# 3619 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3615,7 +3647,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 92 "parser_cocci_menhir.mly" (Data.clt) -# 3619 "parser_cocci_menhir.ml" +# 3651 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_expr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -3623,7 +3655,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_expr_invalid_ = # 1208 "parser_cocci_menhir.mly" ( P.arith_op Ast.And _1 _2 _3 ) -# 3627 "parser_cocci_menhir.ml" +# 3659 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3655,7 +3687,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 90 "parser_cocci_menhir.mly" (Data.clt) -# 3659 "parser_cocci_menhir.ml" +# 3691 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_expr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -3663,7 +3695,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_expr_invalid_ = # 1210 "parser_cocci_menhir.mly" ( P.arith_op Ast.Or _1 _2 _3 ) -# 3667 "parser_cocci_menhir.ml" +# 3699 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3695,7 +3727,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 91 "parser_cocci_menhir.mly" (Data.clt) -# 3699 "parser_cocci_menhir.ml" +# 3731 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_expr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -3703,7 +3735,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_expr_invalid_ = # 1212 "parser_cocci_menhir.mly" ( P.arith_op Ast.Xor _1 _2 _3 ) -# 3707 "parser_cocci_menhir.ml" +# 3739 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3735,7 +3767,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 89 "parser_cocci_menhir.mly" (Data.clt) -# 3739 "parser_cocci_menhir.ml" +# 3771 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_expr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -3743,7 +3775,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_expr_invalid_ = # 1214 "parser_cocci_menhir.mly" ( P.logic_op Ast.AndLog _1 _2 _3 ) -# 3747 "parser_cocci_menhir.ml" +# 3779 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3775,7 +3807,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 88 "parser_cocci_menhir.mly" (Data.clt) -# 3779 "parser_cocci_menhir.ml" +# 3811 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_arith_expr_expr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -3783,7 +3815,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arith_expr_expr_invalid_ = # 1216 "parser_cocci_menhir.mly" ( P.logic_op Ast.OrLog _1 _2 _3 ) -# 3787 "parser_cocci_menhir.ml" +# 3819 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3805,7 +3837,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arity = # 435 "parser_cocci_menhir.mly" ( Ast.UNIQUE ) -# 3809 "parser_cocci_menhir.ml" +# 3841 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3827,7 +3859,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arity = # 436 "parser_cocci_menhir.mly" ( Ast.OPT ) -# 3831 "parser_cocci_menhir.ml" +# 3863 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3849,7 +3881,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arity = # 437 "parser_cocci_menhir.mly" ( Ast.MULTI ) -# 3853 "parser_cocci_menhir.ml" +# 3885 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3866,7 +3898,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_arity = # 438 "parser_cocci_menhir.mly" ( Ast.NONE ) -# 3870 "parser_cocci_menhir.ml" +# 3902 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3897,20 +3929,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let r : ( # 101 "parser_cocci_menhir.mly" (Data.clt) -# 3901 "parser_cocci_menhir.ml" +# 3933 "parser_cocci_menhir.ml" ) = Obj.magic r in let i : 'tv_option_eexpr_ = Obj.magic i in let l : ( # 101 "parser_cocci_menhir.mly" (Data.clt) -# 3907 "parser_cocci_menhir.ml" +# 3939 "parser_cocci_menhir.ml" ) = Obj.magic l in let _startpos = _startpos_l_ in let _endpos = _endpos_r_ in let _v : 'tv_array_dec = # 1004 "parser_cocci_menhir.mly" ( (l,i,r) ) -# 3914 "parser_cocci_menhir.ml" +# 3946 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3934,7 +3966,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_assign_expr_eexpr_dot_expressions_ = # 1162 "parser_cocci_menhir.mly" ( _1 ) -# 3938 "parser_cocci_menhir.ml" +# 3970 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -3966,7 +3998,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 107 "parser_cocci_menhir.mly" (Ast_cocci.assignOp * Data.clt) -# 3970 "parser_cocci_menhir.ml" +# 4002 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_unary_expr_eexpr_dot_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -3976,7 +4008,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let (op,clt) = _2 in Ast0.wrap(Ast0.Assignment(_1,P.clt2mcode op clt, Ast0.set_arg_exp _3,false)) ) -# 3980 "parser_cocci_menhir.ml" +# 4012 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4008,7 +4040,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 4012 "parser_cocci_menhir.ml" +# 4044 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_unary_expr_eexpr_dot_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -4018,7 +4050,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( Ast0.wrap (Ast0.Assignment (_1,P.clt2mcode Ast.SimpleAssign _2,Ast0.set_arg_exp _3,false)) ) -# 4022 "parser_cocci_menhir.ml" +# 4054 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4042,7 +4074,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_assign_expr_eexpr_nest_expressions_ = # 1162 "parser_cocci_menhir.mly" ( _1 ) -# 4046 "parser_cocci_menhir.ml" +# 4078 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4074,7 +4106,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 107 "parser_cocci_menhir.mly" (Ast_cocci.assignOp * Data.clt) -# 4078 "parser_cocci_menhir.ml" +# 4110 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_unary_expr_eexpr_nest_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -4084,7 +4116,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let (op,clt) = _2 in Ast0.wrap(Ast0.Assignment(_1,P.clt2mcode op clt, Ast0.set_arg_exp _3,false)) ) -# 4088 "parser_cocci_menhir.ml" +# 4120 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4116,7 +4148,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 4120 "parser_cocci_menhir.ml" +# 4152 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_unary_expr_eexpr_nest_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -4126,7 +4158,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( Ast0.wrap (Ast0.Assignment (_1,P.clt2mcode Ast.SimpleAssign _2,Ast0.set_arg_exp _3,false)) ) -# 4130 "parser_cocci_menhir.ml" +# 4162 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4150,7 +4182,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_assign_expr_expr_invalid_ = # 1162 "parser_cocci_menhir.mly" ( _1 ) -# 4154 "parser_cocci_menhir.ml" +# 4186 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4182,7 +4214,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 107 "parser_cocci_menhir.mly" (Ast_cocci.assignOp * Data.clt) -# 4186 "parser_cocci_menhir.ml" +# 4218 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_unary_expr_expr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -4192,7 +4224,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let (op,clt) = _2 in Ast0.wrap(Ast0.Assignment(_1,P.clt2mcode op clt, Ast0.set_arg_exp _3,false)) ) -# 4196 "parser_cocci_menhir.ml" +# 4228 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4224,7 +4256,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 4228 "parser_cocci_menhir.ml" +# 4260 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_unary_expr_expr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -4234,7 +4266,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( Ast0.wrap (Ast0.Assignment (_1,P.clt2mcode Ast.SimpleAssign _2,Ast0.set_arg_exp _3,false)) ) -# 4238 "parser_cocci_menhir.ml" +# 4270 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4258,7 +4290,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_assign_expr_bis = # 1173 "parser_cocci_menhir.mly" ( _1 ) -# 4262 "parser_cocci_menhir.ml" +# 4294 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4290,7 +4322,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 107 "parser_cocci_menhir.mly" (Ast_cocci.assignOp * Data.clt) -# 4294 "parser_cocci_menhir.ml" +# 4326 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_unary_expr_eexpr_dot_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -4300,7 +4332,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let (op,clt) = _2 in Ast0.wrap(Ast0.Assignment(_1,P.clt2mcode op clt, Ast0.set_arg_exp _3,false)) ) -# 4304 "parser_cocci_menhir.ml" +# 4336 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4332,7 +4364,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 4336 "parser_cocci_menhir.ml" +# 4368 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_unary_expr_eexpr_dot_expressions_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -4342,7 +4374,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( Ast0.wrap (Ast0.Assignment (_1,P.clt2mcode Ast.SimpleAssign _2,Ast0.set_arg_exp _3,false)) ) -# 4346 "parser_cocci_menhir.ml" +# 4378 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4366,7 +4398,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_basic_expr_eexpr_dot_expressions_ = # 1159 "parser_cocci_menhir.mly" ( _1 ) -# 4370 "parser_cocci_menhir.ml" +# 4402 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4390,7 +4422,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_basic_expr_eexpr_nest_expressions_ = # 1159 "parser_cocci_menhir.mly" ( _1 ) -# 4394 "parser_cocci_menhir.ml" +# 4426 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4414,7 +4446,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_basic_expr_expr_invalid_ = # 1159 "parser_cocci_menhir.mly" ( _1 ) -# 4418 "parser_cocci_menhir.ml" +# 4450 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4446,19 +4478,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 4450 "parser_cocci_menhir.ml" +# 4482 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : ( # 57 "parser_cocci_menhir.mly" (Data.clt) -# 4455 "parser_cocci_menhir.ml" +# 4487 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : 'tv_case_line = # 876 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Default(P.clt2mcode "default" _1,P.clt2mcode ":" _2,_3)) ) -# 4462 "parser_cocci_menhir.ml" +# 4494 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4495,20 +4527,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _3 : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 4499 "parser_cocci_menhir.ml" +# 4531 "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) -# 4505 "parser_cocci_menhir.ml" +# 4537 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__4_ in let _v : 'tv_case_line = # 878 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Case(P.clt2mcode "case" _1,_2,P.clt2mcode ":" _3,_4)) ) -# 4512 "parser_cocci_menhir.ml" +# 4544 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4532,7 +4564,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_cast_expr_eexpr_dot_expressions_ = # 1219 "parser_cocci_menhir.mly" ( _1 ) -# 4536 "parser_cocci_menhir.ml" +# 4568 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4569,13 +4601,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let rp : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 4573 "parser_cocci_menhir.ml" +# 4605 "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) -# 4579 "parser_cocci_menhir.ml" +# 4611 "parser_cocci_menhir.ml" ) = Obj.magic lp in let _startpos = _startpos_lp_ in let _endpos = _endpos_e_ in @@ -4583,7 +4615,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1221 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Cast (P.clt2mcode "(" lp, t, P.clt2mcode ")" rp, e)) ) -# 4587 "parser_cocci_menhir.ml" +# 4619 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4607,7 +4639,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_cast_expr_eexpr_invalid_ = # 1219 "parser_cocci_menhir.mly" ( _1 ) -# 4611 "parser_cocci_menhir.ml" +# 4643 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4644,13 +4676,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let rp : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 4648 "parser_cocci_menhir.ml" +# 4680 "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) -# 4654 "parser_cocci_menhir.ml" +# 4686 "parser_cocci_menhir.ml" ) = Obj.magic lp in let _startpos = _startpos_lp_ in let _endpos = _endpos_e_ in @@ -4658,7 +4690,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1221 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Cast (P.clt2mcode "(" lp, t, P.clt2mcode ")" rp, e)) ) -# 4662 "parser_cocci_menhir.ml" +# 4694 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4682,7 +4714,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_cast_expr_eexpr_nest_expressions_ = # 1219 "parser_cocci_menhir.mly" ( _1 ) -# 4686 "parser_cocci_menhir.ml" +# 4718 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4719,13 +4751,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let rp : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 4723 "parser_cocci_menhir.ml" +# 4755 "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) -# 4729 "parser_cocci_menhir.ml" +# 4761 "parser_cocci_menhir.ml" ) = Obj.magic lp in let _startpos = _startpos_lp_ in let _endpos = _endpos_e_ in @@ -4733,7 +4765,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1221 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Cast (P.clt2mcode "(" lp, t, P.clt2mcode ")" rp, e)) ) -# 4737 "parser_cocci_menhir.ml" +# 4769 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4757,7 +4789,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_cast_expr_expr_invalid_ = # 1219 "parser_cocci_menhir.mly" ( _1 ) -# 4761 "parser_cocci_menhir.ml" +# 4793 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4794,13 +4826,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let rp : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 4798 "parser_cocci_menhir.ml" +# 4830 "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) -# 4804 "parser_cocci_menhir.ml" +# 4836 "parser_cocci_menhir.ml" ) = Obj.magic lp in let _startpos = _startpos_lp_ in let _endpos = _endpos_e_ in @@ -4808,7 +4840,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1221 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Cast (P.clt2mcode "(" lp, t, P.clt2mcode ")" rp, e)) ) -# 4812 "parser_cocci_menhir.ml" +# 4844 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4836,7 +4868,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_choose_iso = # 227 "parser_cocci_menhir.mly" ( List.map P.id2name _2 ) -# 4840 "parser_cocci_menhir.ml" +# 4872 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4862,12 +4894,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 4866 "parser_cocci_menhir.ml" +# 4898 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 4871 "parser_cocci_menhir.ml" +# 4903 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in @@ -4876,7 +4908,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( function dot_builder -> [Ast0.wrap(Ast0.PComma(P.clt2mcode "," _1)); dot_builder _2] ) -# 4880 "parser_cocci_menhir.ml" +# 4912 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4903,7 +4935,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 4907 "parser_cocci_menhir.ml" +# 4939 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in @@ -4911,7 +4943,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1474 "parser_cocci_menhir.mly" ( function dot_builder -> [Ast0.wrap(Ast0.PComma(P.clt2mcode "," _1)); _2] ) -# 4915 "parser_cocci_menhir.ml" +# 4947 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4937,12 +4969,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 4941 "parser_cocci_menhir.ml" +# 4973 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 4946 "parser_cocci_menhir.ml" +# 4978 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in @@ -4951,7 +4983,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( function dot_builder -> [Ast0.wrap(Ast0.PComma(P.clt2mcode "," _1)); dot_builder _2] ) -# 4955 "parser_cocci_menhir.ml" +# 4987 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -4978,7 +5010,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 4982 "parser_cocci_menhir.ml" +# 5014 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in @@ -4986,7 +5018,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1474 "parser_cocci_menhir.mly" ( function dot_builder -> [Ast0.wrap(Ast0.PComma(P.clt2mcode "," _1)); _2] ) -# 4990 "parser_cocci_menhir.ml" +# 5022 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5003,7 +5035,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_comma_initializers_edots_when_TEllipsis_initialize__ = # 1051 "parser_cocci_menhir.mly" ( [] ) -# 5007 "parser_cocci_menhir.ml" +# 5039 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5033,7 +5065,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_comma_initializers_edots_when_TEllipsis_initialize__ = # 1053 "parser_cocci_menhir.mly" ( (function dot_builder -> [dot_builder d])::r ) -# 5037 "parser_cocci_menhir.ml" +# 5069 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5065,7 +5097,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let c : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 5069 "parser_cocci_menhir.ml" +# 5101 "parser_cocci_menhir.ml" ) = Obj.magic c in let i : 'tv_initialize2 = Obj.magic i in let _startpos = _startpos_i_ in @@ -5074,7 +5106,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1055 "parser_cocci_menhir.mly" ( (function dot_builder -> [i; Ast0.wrap(Ast0.IComma(P.clt2mcode "," c))]):: r ) -# 5078 "parser_cocci_menhir.ml" +# 5110 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5091,7 +5123,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_comma_initializers2_edots_when_TEllipsis_initialize__ = # 1059 "parser_cocci_menhir.mly" ( [] ) -# 5095 "parser_cocci_menhir.ml" +# 5127 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5123,7 +5155,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let c : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 5127 "parser_cocci_menhir.ml" +# 5159 "parser_cocci_menhir.ml" ) = Obj.magic c in let i : 'tv_initialize2 = Obj.magic i in let _startpos = _startpos_i_ in @@ -5132,7 +5164,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1061 "parser_cocci_menhir.mly" ( (function dot_builder -> [i; Ast0.wrap(Ast0.IComma(P.clt2mcode "," c))]):: r ) -# 5136 "parser_cocci_menhir.ml" +# 5168 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5154,9 +5186,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_comma_list_any_strict_ = -# 1688 "parser_cocci_menhir.mly" +# 1694 "parser_cocci_menhir.mly" ( _1 ) -# 5160 "parser_cocci_menhir.ml" +# 5192 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5178,9 +5210,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_comma_list_ctype_ = -# 1688 "parser_cocci_menhir.mly" +# 1694 "parser_cocci_menhir.mly" ( _1 ) -# 5184 "parser_cocci_menhir.ml" +# 5216 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5202,9 +5234,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_comma_list_d_ident_ = -# 1688 "parser_cocci_menhir.mly" +# 1694 "parser_cocci_menhir.mly" ( _1 ) -# 5208 "parser_cocci_menhir.ml" +# 5240 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5226,9 +5258,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_comma_list_dexpr_ = -# 1688 "parser_cocci_menhir.mly" +# 1694 "parser_cocci_menhir.mly" ( _1 ) -# 5232 "parser_cocci_menhir.ml" +# 5264 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5250,9 +5282,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_comma_list_ident_or_const_ = -# 1688 "parser_cocci_menhir.mly" +# 1694 "parser_cocci_menhir.mly" ( _1 ) -# 5256 "parser_cocci_menhir.ml" +# 5288 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5274,9 +5306,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_comma_list_meta_ident_ = -# 1688 "parser_cocci_menhir.mly" +# 1694 "parser_cocci_menhir.mly" ( _1 ) -# 5280 "parser_cocci_menhir.ml" +# 5312 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5298,9 +5330,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_comma_list_pure_ident_ = -# 1688 "parser_cocci_menhir.mly" +# 1694 "parser_cocci_menhir.mly" ( _1 ) -# 5304 "parser_cocci_menhir.ml" +# 5336 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5322,9 +5354,9 @@ 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_ = -# 1688 "parser_cocci_menhir.mly" +# 1694 "parser_cocci_menhir.mly" ( _1 ) -# 5328 "parser_cocci_menhir.ml" +# 5360 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5346,9 +5378,9 @@ 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__ = -# 1688 "parser_cocci_menhir.mly" +# 1694 "parser_cocci_menhir.mly" ( _1 ) -# 5352 "parser_cocci_menhir.ml" +# 5384 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5370,9 +5402,9 @@ 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__ = -# 1688 "parser_cocci_menhir.mly" +# 1694 "parser_cocci_menhir.mly" ( _1 ) -# 5376 "parser_cocci_menhir.ml" +# 5408 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5394,9 +5426,9 @@ 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__ = -# 1688 "parser_cocci_menhir.mly" +# 1694 "parser_cocci_menhir.mly" ( _1 ) -# 5400 "parser_cocci_menhir.ml" +# 5432 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5418,9 +5450,9 @@ 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__ = -# 1688 "parser_cocci_menhir.mly" +# 1694 "parser_cocci_menhir.mly" ( _1 ) -# 5424 "parser_cocci_menhir.ml" +# 5456 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5444,7 +5476,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_cond_expr_eexpr_dot_expressions_ = # 1184 "parser_cocci_menhir.mly" ( _1 ) -# 5448 "parser_cocci_menhir.ml" +# 5480 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5486,13 +5518,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let dd : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 5490 "parser_cocci_menhir.ml" +# 5522 "parser_cocci_menhir.ml" ) = Obj.magic dd in let t : 'tv_option_eexpr_ = Obj.magic t in let w : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 5496 "parser_cocci_menhir.ml" +# 5528 "parser_cocci_menhir.ml" ) = Obj.magic w in let l : 'tv_arith_expr_eexpr_dot_expressions_ = Obj.magic l in let _startpos = _startpos_l_ in @@ -5501,7 +5533,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1186 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.CondExpr (l, P.clt2mcode "?" w, t, P.clt2mcode ":" dd, r)) ) -# 5505 "parser_cocci_menhir.ml" +# 5537 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5525,7 +5557,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_cond_expr_eexpr_nest_expressions_ = # 1184 "parser_cocci_menhir.mly" ( _1 ) -# 5529 "parser_cocci_menhir.ml" +# 5561 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5567,13 +5599,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let dd : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 5571 "parser_cocci_menhir.ml" +# 5603 "parser_cocci_menhir.ml" ) = Obj.magic dd in let t : 'tv_option_eexpr_ = Obj.magic t in let w : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 5577 "parser_cocci_menhir.ml" +# 5609 "parser_cocci_menhir.ml" ) = Obj.magic w in let l : 'tv_arith_expr_eexpr_nest_expressions_ = Obj.magic l in let _startpos = _startpos_l_ in @@ -5582,7 +5614,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1186 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.CondExpr (l, P.clt2mcode "?" w, t, P.clt2mcode ":" dd, r)) ) -# 5586 "parser_cocci_menhir.ml" +# 5618 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5606,7 +5638,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_cond_expr_expr_invalid_ = # 1184 "parser_cocci_menhir.mly" ( _1 ) -# 5610 "parser_cocci_menhir.ml" +# 5642 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5648,13 +5680,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let dd : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 5652 "parser_cocci_menhir.ml" +# 5684 "parser_cocci_menhir.ml" ) = Obj.magic dd in let t : 'tv_option_eexpr_ = Obj.magic t in let w : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 5658 "parser_cocci_menhir.ml" +# 5690 "parser_cocci_menhir.ml" ) = Obj.magic w in let l : 'tv_arith_expr_expr_invalid_ = Obj.magic l in let _startpos = _startpos_l_ in @@ -5663,7 +5695,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1186 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.CondExpr (l, P.clt2mcode "?" w, t, P.clt2mcode ":" dd, r)) ) -# 5667 "parser_cocci_menhir.ml" +# 5699 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5684,14 +5716,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 54 "parser_cocci_menhir.mly" (Data.clt) -# 5688 "parser_cocci_menhir.ml" +# 5720 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_const_vol = # 797 "parser_cocci_menhir.mly" ( P.clt2mcode Ast.Const _1 ) -# 5695 "parser_cocci_menhir.ml" +# 5727 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5712,14 +5744,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 54 "parser_cocci_menhir.mly" (Data.clt) -# 5716 "parser_cocci_menhir.ml" +# 5748 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_const_vol = # 798 "parser_cocci_menhir.mly" ( P.clt2mcode Ast.Volatile _1 ) -# 5723 "parser_cocci_menhir.ml" +# 5755 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5736,7 +5768,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_continue_struct_decl_list = # 516 "parser_cocci_menhir.mly" ( [] ) -# 5740 "parser_cocci_menhir.ml" +# 5772 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5766,7 +5798,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_continue_struct_decl_list = # 517 "parser_cocci_menhir.mly" ( _1@_2 ) -# 5770 "parser_cocci_menhir.ml" +# 5802 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5790,7 +5822,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_continue_struct_decl_list = # 518 "parser_cocci_menhir.mly" ( _1 ) -# 5794 "parser_cocci_menhir.ml" +# 5826 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5821,13 +5853,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 5825 "parser_cocci_menhir.ml" +# 5857 "parser_cocci_menhir.ml" in # 522 "parser_cocci_menhir.mly" ( P.pointerify (P.make_cv cv ty) m ) -# 5831 "parser_cocci_menhir.ml" +# 5863 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5865,13 +5897,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 5869 "parser_cocci_menhir.ml" +# 5901 "parser_cocci_menhir.ml" in # 522 "parser_cocci_menhir.mly" ( P.pointerify (P.make_cv cv ty) m ) -# 5875 "parser_cocci_menhir.ml" +# 5907 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5898,7 +5930,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let t : ( # 50 "parser_cocci_menhir.mly" (Data.clt) -# 5902 "parser_cocci_menhir.ml" +# 5934 "parser_cocci_menhir.ml" ) = Obj.magic t in let _startpos = _startpos_t_ in let _endpos = _endpos_m_ in @@ -5906,7 +5938,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 5910 "parser_cocci_menhir.ml" +# 5942 "parser_cocci_menhir.ml" in @@ -5914,7 +5946,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let ty = Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.VoidType t, None)) in P.pointerify (P.make_cv cv ty) m ) -# 5918 "parser_cocci_menhir.ml" +# 5950 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5946,7 +5978,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let t : ( # 50 "parser_cocci_menhir.mly" (Data.clt) -# 5950 "parser_cocci_menhir.ml" +# 5982 "parser_cocci_menhir.ml" ) = Obj.magic t in let x0 : 'tv_const_vol = Obj.magic x0 in let _startpos = _startpos_x0_ in @@ -5956,7 +5988,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 5960 "parser_cocci_menhir.ml" +# 5992 "parser_cocci_menhir.ml" in @@ -5964,7 +5996,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let ty = Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.VoidType t, None)) in P.pointerify (P.make_cv cv ty) m ) -# 5968 "parser_cocci_menhir.ml" +# 6000 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -5995,13 +6027,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let rp : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 5999 "parser_cocci_menhir.ml" +# 6031 "parser_cocci_menhir.ml" ) = Obj.magic rp in let t : 'tv_midzero_list_ctype_ctype_ = Obj.magic t in let lp : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 6005 "parser_cocci_menhir.ml" +# 6037 "parser_cocci_menhir.ml" ) = Obj.magic lp in let _startpos = _startpos_lp_ in let _endpos = _endpos_rp_ in @@ -6010,7 +6042,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let (mids,code) = t in Ast0.wrap (Ast0.DisjType(P.clt2mcode "(" lp,code,mids, P.clt2mcode ")" rp)) ) -# 6014 "parser_cocci_menhir.ml" +# 6046 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6031,14 +6063,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 51 "parser_cocci_menhir.mly" (Data.clt) -# 6035 "parser_cocci_menhir.ml" +# 6067 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_ctype_qualif = # 542 "parser_cocci_menhir.mly" ( P.clt2mcode Ast.Unsigned _1 ) -# 6042 "parser_cocci_menhir.ml" +# 6074 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6059,14 +6091,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 51 "parser_cocci_menhir.mly" (Data.clt) -# 6063 "parser_cocci_menhir.ml" +# 6095 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_ctype_qualif = # 543 "parser_cocci_menhir.mly" ( P.clt2mcode Ast.Signed _1 ) -# 6070 "parser_cocci_menhir.ml" +# 6102 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6103,7 +6135,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct Ast0.wrap (Ast0.Array(rest,P.clt2mcode "[" l,i,P.clt2mcode "]" r))) _2 t) ) -# 6107 "parser_cocci_menhir.ml" +# 6139 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6133,7 +6165,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_decl = # 768 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Param(t, Some i)) ) -# 6137 "parser_cocci_menhir.ml" +# 6169 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6189,29 +6221,29 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let rp1 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 6193 "parser_cocci_menhir.ml" +# 6225 "parser_cocci_menhir.ml" ) = Obj.magic rp1 in let d : 'tv_decl_list_name_opt_decl_ = Obj.magic d in let lp1 : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 6199 "parser_cocci_menhir.ml" +# 6231 "parser_cocci_menhir.ml" ) = Obj.magic lp1 in let rp : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 6204 "parser_cocci_menhir.ml" +# 6236 "parser_cocci_menhir.ml" ) = Obj.magic rp in let i : 'tv_ident = Obj.magic i in let s : ( # 98 "parser_cocci_menhir.mly" (Data.clt) -# 6210 "parser_cocci_menhir.ml" +# 6242 "parser_cocci_menhir.ml" ) = Obj.magic s in let lp : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 6215 "parser_cocci_menhir.ml" +# 6247 "parser_cocci_menhir.ml" ) = Obj.magic lp in let t : 'tv_fn_ctype = Obj.magic t in let _startpos = _startpos_t_ in @@ -6224,7 +6256,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (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)) ) -# 6228 "parser_cocci_menhir.ml" +# 6260 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6245,7 +6277,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let t : ( # 50 "parser_cocci_menhir.mly" (Data.clt) -# 6249 "parser_cocci_menhir.ml" +# 6281 "parser_cocci_menhir.ml" ) = Obj.magic t in let _startpos = _startpos_t_ in let _endpos = _endpos_t_ in @@ -6253,7 +6285,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 778 "parser_cocci_menhir.mly" ( let ty = Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.VoidType t, None)) in Ast0.wrap(Ast0.VoidParam(ty)) ) -# 6257 "parser_cocci_menhir.ml" +# 6289 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6274,7 +6306,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 64 "parser_cocci_menhir.mly" (Parse_aux.info) -# 6278 "parser_cocci_menhir.ml" +# 6310 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -6282,7 +6314,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 781 "parser_cocci_menhir.mly" ( let (nm,pure,clt) = _1 in Ast0.wrap(Ast0.MetaParam(P.clt2mcode nm clt,pure)) ) -# 6286 "parser_cocci_menhir.ml" +# 6318 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6303,14 +6335,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 59 "parser_cocci_menhir.mly" (string * Data.clt) -# 6307 "parser_cocci_menhir.ml" +# 6339 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_decl_ident = # 1420 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Id(P.id2mcode _1)) ) -# 6314 "parser_cocci_menhir.ml" +# 6346 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6331,7 +6363,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 62 "parser_cocci_menhir.mly" (Parse_aux.idinfo) -# 6335 "parser_cocci_menhir.ml" +# 6367 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -6339,7 +6371,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1422 "parser_cocci_menhir.mly" ( let (nm,constraints,pure,clt) = _1 in Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) ) -# 6343 "parser_cocci_menhir.ml" +# 6375 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6367,7 +6399,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct if List.exists circle _1 then Ast0.wrap(Ast0.CIRCLES(_1)) else Ast0.wrap(Ast0.DOTS(_1)) ) -# 6371 "parser_cocci_menhir.ml" +# 6403 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6395,7 +6427,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct if List.exists circle _1 then Ast0.wrap(Ast0.CIRCLES(_1)) else Ast0.wrap(Ast0.DOTS(_1)) ) -# 6399 "parser_cocci_menhir.ml" +# 6431 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6419,7 +6451,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_decl_list_start_decl_ = # 1450 "parser_cocci_menhir.mly" ( [_1] ) -# 6423 "parser_cocci_menhir.ml" +# 6455 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6451,7 +6483,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 6455 "parser_cocci_menhir.ml" +# 6487 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_one_dec_decl_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -6459,7 +6491,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_decl_list_start_decl_ = # 1452 "parser_cocci_menhir.mly" ( _1::Ast0.wrap(Ast0.PComma(P.clt2mcode "," _2))::_3 ) -# 6463 "parser_cocci_menhir.ml" +# 6495 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6486,7 +6518,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 6490 "parser_cocci_menhir.ml" +# 6522 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in @@ -6494,7 +6526,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1454 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Pdots(P.clt2mcode "..." _1)):: (List.concat(List.map (function x -> x (P.mkpdots "...")) _2)) ) -# 6498 "parser_cocci_menhir.ml" +# 6530 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6518,7 +6550,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_decl_list_start_name_opt_decl_ = # 1450 "parser_cocci_menhir.mly" ( [_1] ) -# 6522 "parser_cocci_menhir.ml" +# 6554 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6550,7 +6582,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 6554 "parser_cocci_menhir.ml" +# 6586 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_one_dec_name_opt_decl_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -6558,7 +6590,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_decl_list_start_name_opt_decl_ = # 1452 "parser_cocci_menhir.mly" ( _1::Ast0.wrap(Ast0.PComma(P.clt2mcode "," _2))::_3 ) -# 6562 "parser_cocci_menhir.ml" +# 6594 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6585,7 +6617,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 6589 "parser_cocci_menhir.ml" +# 6621 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in @@ -6593,7 +6625,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1454 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Pdots(P.clt2mcode "..." _1)):: (List.concat(List.map (function x -> x (P.mkpdots "...")) _2)) ) -# 6597 "parser_cocci_menhir.ml" +# 6629 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6614,7 +6646,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 64 "parser_cocci_menhir.mly" (Parse_aux.info) -# 6618 "parser_cocci_menhir.ml" +# 6650 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -6622,7 +6654,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1067 "parser_cocci_menhir.mly" ( let (nm,pure,clt) = _1 in [Ast0.wrap(Ast0.MetaStmt(P.clt2mcode nm clt,pure))] ) -# 6626 "parser_cocci_menhir.ml" +# 6658 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6650,7 +6682,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct Ast0.wrap (Ast0.Decl((Ast0.default_info(),Ast0.context_befaft()),x))) _1 ) -# 6654 "parser_cocci_menhir.ml" +# 6686 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6674,7 +6706,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_decl_statement = # 1075 "parser_cocci_menhir.mly" ( [_1] ) -# 6678 "parser_cocci_menhir.ml" +# 6710 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6705,13 +6737,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _3 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 6709 "parser_cocci_menhir.ml" +# 6741 "parser_cocci_menhir.ml" ) = Obj.magic _3 in let t : 'tv_midzero_list_fun_start_fun_start_ = Obj.magic t in let _1 : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 6715 "parser_cocci_menhir.ml" +# 6747 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in @@ -6726,7 +6758,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct else [Ast0.wrap(Ast0.Disj(P.clt2mcode "(" _1, code, mids, P.clt2mcode ")" _3))] ) -# 6730 "parser_cocci_menhir.ml" +# 6762 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6747,7 +6779,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 64 "parser_cocci_menhir.mly" (Parse_aux.info) -# 6751 "parser_cocci_menhir.ml" +# 6783 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -6755,7 +6787,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1097 "parser_cocci_menhir.mly" ( let (nm,pure,clt) = _1 in [Ast0.wrap(Ast0.MetaStmt(P.clt2mcode nm clt,pure))] ) -# 6759 "parser_cocci_menhir.ml" +# 6791 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6783,7 +6815,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct Ast0.wrap (Ast0.Decl((Ast0.default_info(),Ast0.context_befaft()),x))) _1 ) -# 6787 "parser_cocci_menhir.ml" +# 6819 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6807,7 +6839,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_decl_statement_expr = # 1105 "parser_cocci_menhir.mly" ( [_1] ) -# 6811 "parser_cocci_menhir.ml" +# 6843 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6838,13 +6870,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _3 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 6842 "parser_cocci_menhir.ml" +# 6874 "parser_cocci_menhir.ml" ) = Obj.magic _3 in let t : 'tv_midzero_list_fun_after_stm_fun_after_dots_or_ = Obj.magic t in let _1 : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 6848 "parser_cocci_menhir.ml" +# 6880 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in @@ -6858,7 +6890,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct List.map (function x -> Ast0.wrap(Ast0.DOTS x)) code in [Ast0.wrap(Ast0.Disj(P.clt2mcode "(" _1, dot_code, mids, P.clt2mcode ")" _3))] ) -# 6862 "parser_cocci_menhir.ml" +# 6894 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6884,7 +6916,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 6888 "parser_cocci_menhir.ml" +# 6920 "parser_cocci_menhir.ml" ) = Obj.magic pv in let t : 'tv_ctype = Obj.magic t in let _startpos = _startpos_t_ in @@ -6892,7 +6924,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_decl_var = # 886 "parser_cocci_menhir.mly" ( [Ast0.wrap(Ast0.TyDecl(t,P.clt2mcode ";" pv))] ) -# 6896 "parser_cocci_menhir.ml" +# 6928 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6923,7 +6955,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 6927 "parser_cocci_menhir.ml" +# 6959 "parser_cocci_menhir.ml" ) = Obj.magic pv in let d : 'tv_comma_list_d_ident_ = Obj.magic d in let t : 'tv_ctype = Obj.magic t in @@ -6933,7 +6965,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 6937 "parser_cocci_menhir.ml" +# 6969 "parser_cocci_menhir.ml" in @@ -6942,7 +6974,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (function (id,fn) -> Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv))) d ) -# 6946 "parser_cocci_menhir.ml" +# 6978 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -6978,7 +7010,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 6982 "parser_cocci_menhir.ml" +# 7014 "parser_cocci_menhir.ml" ) = Obj.magic pv in let d : 'tv_comma_list_d_ident_ = Obj.magic d in let t : 'tv_ctype = Obj.magic t in @@ -6990,7 +7022,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 6994 "parser_cocci_menhir.ml" +# 7026 "parser_cocci_menhir.ml" in @@ -6999,7 +7031,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (function (id,fn) -> Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv))) d ) -# 7003 "parser_cocci_menhir.ml" +# 7035 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -7023,7 +7055,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_decl_var = # 892 "parser_cocci_menhir.mly" ( [f] ) -# 7027 "parser_cocci_menhir.ml" +# 7059 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -7064,13 +7096,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 7068 "parser_cocci_menhir.ml" +# 7100 "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) -# 7074 "parser_cocci_menhir.ml" +# 7106 "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 @@ -7080,14 +7112,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 7084 "parser_cocci_menhir.ml" +# 7116 "parser_cocci_menhir.ml" in # 894 "parser_cocci_menhir.mly" (let (id,fn) = d in [Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv))]) -# 7091 "parser_cocci_menhir.ml" +# 7123 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -7133,13 +7165,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 7137 "parser_cocci_menhir.ml" +# 7169 "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) -# 7143 "parser_cocci_menhir.ml" +# 7175 "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 @@ -7151,14 +7183,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 7155 "parser_cocci_menhir.ml" +# 7187 "parser_cocci_menhir.ml" in # 894 "parser_cocci_menhir.mly" (let (id,fn) = d in [Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv))]) -# 7162 "parser_cocci_menhir.ml" +# 7194 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -7189,7 +7221,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 7193 "parser_cocci_menhir.ml" +# 7225 "parser_cocci_menhir.ml" ) = Obj.magic pv in let d : 'tv_comma_list_d_ident_ = Obj.magic d in let i : 'tv_pure_ident = Obj.magic i in @@ -7199,14 +7231,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 7203 "parser_cocci_menhir.ml" +# 7235 "parser_cocci_menhir.ml" in let s = # 39 "standard.mly" ( None ) -# 7210 "parser_cocci_menhir.ml" +# 7242 "parser_cocci_menhir.ml" in @@ -7217,7 +7249,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in Ast0.wrap(Ast0.UnInit(s,fn idtype,id,P.clt2mcode ";" pv))) d ) -# 7221 "parser_cocci_menhir.ml" +# 7253 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -7253,7 +7285,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 7257 "parser_cocci_menhir.ml" +# 7289 "parser_cocci_menhir.ml" ) = Obj.magic pv in let d : 'tv_comma_list_d_ident_ = Obj.magic d in let i : 'tv_pure_ident = Obj.magic i in @@ -7265,14 +7297,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 7269 "parser_cocci_menhir.ml" +# 7301 "parser_cocci_menhir.ml" in let s = # 39 "standard.mly" ( None ) -# 7276 "parser_cocci_menhir.ml" +# 7308 "parser_cocci_menhir.ml" in @@ -7283,7 +7315,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in Ast0.wrap(Ast0.UnInit(s,fn idtype,id,P.clt2mcode ";" pv))) d ) -# 7287 "parser_cocci_menhir.ml" +# 7319 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -7319,7 +7351,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 7323 "parser_cocci_menhir.ml" +# 7355 "parser_cocci_menhir.ml" ) = Obj.magic pv in let d : 'tv_comma_list_d_ident_ = Obj.magic d in let i : 'tv_pure_ident = Obj.magic i in @@ -7330,7 +7362,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 7334 "parser_cocci_menhir.ml" +# 7366 "parser_cocci_menhir.ml" in let s = @@ -7338,7 +7370,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 7342 "parser_cocci_menhir.ml" +# 7374 "parser_cocci_menhir.ml" in @@ -7349,7 +7381,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in Ast0.wrap(Ast0.UnInit(s,fn idtype,id,P.clt2mcode ";" pv))) d ) -# 7353 "parser_cocci_menhir.ml" +# 7385 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -7390,7 +7422,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 7394 "parser_cocci_menhir.ml" +# 7426 "parser_cocci_menhir.ml" ) = Obj.magic pv in let d : 'tv_comma_list_d_ident_ = Obj.magic d in let i : 'tv_pure_ident = Obj.magic i in @@ -7403,7 +7435,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 7407 "parser_cocci_menhir.ml" +# 7439 "parser_cocci_menhir.ml" in let s = @@ -7411,7 +7443,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 7415 "parser_cocci_menhir.ml" +# 7447 "parser_cocci_menhir.ml" in @@ -7422,7 +7454,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in Ast0.wrap(Ast0.UnInit(s,fn idtype,id,P.clt2mcode ";" pv))) d ) -# 7426 "parser_cocci_menhir.ml" +# 7458 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -7463,13 +7495,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 7467 "parser_cocci_menhir.ml" +# 7499 "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) -# 7473 "parser_cocci_menhir.ml" +# 7505 "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 @@ -7479,14 +7511,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 7483 "parser_cocci_menhir.ml" +# 7515 "parser_cocci_menhir.ml" in let s = # 39 "standard.mly" ( None ) -# 7490 "parser_cocci_menhir.ml" +# 7522 "parser_cocci_menhir.ml" in @@ -7496,7 +7528,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))] ) -# 7500 "parser_cocci_menhir.ml" +# 7532 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -7542,13 +7574,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 7546 "parser_cocci_menhir.ml" +# 7578 "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) -# 7552 "parser_cocci_menhir.ml" +# 7584 "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 @@ -7560,14 +7592,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 7564 "parser_cocci_menhir.ml" +# 7596 "parser_cocci_menhir.ml" in let s = # 39 "standard.mly" ( None ) -# 7571 "parser_cocci_menhir.ml" +# 7603 "parser_cocci_menhir.ml" in @@ -7577,7 +7609,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))] ) -# 7581 "parser_cocci_menhir.ml" +# 7613 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -7623,13 +7655,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 7627 "parser_cocci_menhir.ml" +# 7659 "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) -# 7633 "parser_cocci_menhir.ml" +# 7665 "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 @@ -7640,7 +7672,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 7644 "parser_cocci_menhir.ml" +# 7676 "parser_cocci_menhir.ml" in let s = @@ -7648,7 +7680,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 7652 "parser_cocci_menhir.ml" +# 7684 "parser_cocci_menhir.ml" in @@ -7658,7 +7690,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))] ) -# 7662 "parser_cocci_menhir.ml" +# 7694 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -7709,13 +7741,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 7713 "parser_cocci_menhir.ml" +# 7745 "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) -# 7719 "parser_cocci_menhir.ml" +# 7751 "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 @@ -7728,7 +7760,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 7732 "parser_cocci_menhir.ml" +# 7764 "parser_cocci_menhir.ml" in let s = @@ -7736,7 +7768,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 7740 "parser_cocci_menhir.ml" +# 7772 "parser_cocci_menhir.ml" in @@ -7746,7 +7778,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))] ) -# 7750 "parser_cocci_menhir.ml" +# 7782 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -7807,34 +7839,34 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 7811 "parser_cocci_menhir.ml" +# 7843 "parser_cocci_menhir.ml" ) = Obj.magic pv in let rp2 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 7816 "parser_cocci_menhir.ml" +# 7848 "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) -# 7822 "parser_cocci_menhir.ml" +# 7854 "parser_cocci_menhir.ml" ) = Obj.magic lp2 in let rp1 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 7827 "parser_cocci_menhir.ml" +# 7859 "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) -# 7833 "parser_cocci_menhir.ml" +# 7865 "parser_cocci_menhir.ml" ) = Obj.magic st in let lp1 : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 7838 "parser_cocci_menhir.ml" +# 7870 "parser_cocci_menhir.ml" ) = Obj.magic lp1 in let t : 'tv_fn_ctype = Obj.magic t in let _startpos = _startpos_t_ in @@ -7843,7 +7875,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 7847 "parser_cocci_menhir.ml" +# 7879 "parser_cocci_menhir.ml" in @@ -7855,7 +7887,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))] ) -# 7859 "parser_cocci_menhir.ml" +# 7891 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -7921,34 +7953,34 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 7925 "parser_cocci_menhir.ml" +# 7957 "parser_cocci_menhir.ml" ) = Obj.magic pv in let rp2 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 7930 "parser_cocci_menhir.ml" +# 7962 "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) -# 7936 "parser_cocci_menhir.ml" +# 7968 "parser_cocci_menhir.ml" ) = Obj.magic lp2 in let rp1 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 7941 "parser_cocci_menhir.ml" +# 7973 "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) -# 7947 "parser_cocci_menhir.ml" +# 7979 "parser_cocci_menhir.ml" ) = Obj.magic st in let lp1 : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 7952 "parser_cocci_menhir.ml" +# 7984 "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 @@ -7959,7 +7991,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 7963 "parser_cocci_menhir.ml" +# 7995 "parser_cocci_menhir.ml" in @@ -7971,7 +8003,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))] ) -# 7975 "parser_cocci_menhir.ml" +# 8007 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8012,18 +8044,18 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _5 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 8016 "parser_cocci_menhir.ml" +# 8048 "parser_cocci_menhir.ml" ) = Obj.magic _5 in let _4 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 8021 "parser_cocci_menhir.ml" +# 8053 "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) -# 8027 "parser_cocci_menhir.ml" +# 8059 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_decl_ident = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -8032,7 +8064,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 925 "parser_cocci_menhir.mly" ( [Ast0.wrap(Ast0.MacroDecl(_1,P.clt2mcode "(" _2,_3, P.clt2mcode ")" _4,P.clt2mcode ";" _5))] ) -# 8036 "parser_cocci_menhir.ml" +# 8068 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8103,40 +8135,40 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 8107 "parser_cocci_menhir.ml" +# 8139 "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) -# 8113 "parser_cocci_menhir.ml" +# 8145 "parser_cocci_menhir.ml" ) = Obj.magic q in let rp2 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 8118 "parser_cocci_menhir.ml" +# 8150 "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) -# 8124 "parser_cocci_menhir.ml" +# 8156 "parser_cocci_menhir.ml" ) = Obj.magic lp2 in let rp1 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 8129 "parser_cocci_menhir.ml" +# 8161 "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) -# 8135 "parser_cocci_menhir.ml" +# 8167 "parser_cocci_menhir.ml" ) = Obj.magic st in let lp1 : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 8140 "parser_cocci_menhir.ml" +# 8172 "parser_cocci_menhir.ml" ) = Obj.magic lp1 in let t : 'tv_fn_ctype = Obj.magic t in let _startpos = _startpos_t_ in @@ -8145,7 +8177,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 8149 "parser_cocci_menhir.ml" +# 8181 "parser_cocci_menhir.ml" in @@ -8157,7 +8189,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))]) -# 8161 "parser_cocci_menhir.ml" +# 8193 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8233,40 +8265,40 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 8237 "parser_cocci_menhir.ml" +# 8269 "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) -# 8243 "parser_cocci_menhir.ml" +# 8275 "parser_cocci_menhir.ml" ) = Obj.magic q in let rp2 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 8248 "parser_cocci_menhir.ml" +# 8280 "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) -# 8254 "parser_cocci_menhir.ml" +# 8286 "parser_cocci_menhir.ml" ) = Obj.magic lp2 in let rp1 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 8259 "parser_cocci_menhir.ml" +# 8291 "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) -# 8265 "parser_cocci_menhir.ml" +# 8297 "parser_cocci_menhir.ml" ) = Obj.magic st in let lp1 : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 8270 "parser_cocci_menhir.ml" +# 8302 "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 @@ -8277,7 +8309,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 8281 "parser_cocci_menhir.ml" +# 8313 "parser_cocci_menhir.ml" in @@ -8289,7 +8321,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))]) -# 8293 "parser_cocci_menhir.ml" +# 8325 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8325,14 +8357,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 8329 "parser_cocci_menhir.ml" +# 8361 "parser_cocci_menhir.ml" ) = Obj.magic pv in let id : 'tv_typedef_ident = Obj.magic id in let t : 'tv_ctype = Obj.magic t in let s : ( # 53 "parser_cocci_menhir.mly" (Data.clt) -# 8336 "parser_cocci_menhir.ml" +# 8368 "parser_cocci_menhir.ml" ) = Obj.magic s in let _startpos = _startpos_s_ in let _endpos = _endpos_pv_ in @@ -8340,7 +8372,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 939 "parser_cocci_menhir.mly" ( let s = P.clt2mcode "typedef" s in [Ast0.wrap(Ast0.Typedef(s,t,id,P.clt2mcode ";" pv))] ) -# 8344 "parser_cocci_menhir.ml" +# 8376 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8368,7 +8400,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct if List.exists circle _1 then Ast0.wrap(Ast0.CIRCLES(_1)) else Ast0.wrap(Ast0.DOTS(_1)) ) -# 8372 "parser_cocci_menhir.ml" +# 8404 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8392,7 +8424,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_define_param_list_option = # 684 "parser_cocci_menhir.mly" ( _1 ) -# 8396 "parser_cocci_menhir.ml" +# 8428 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8409,7 +8441,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_define_param_list_option = # 685 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.DOTS([])) ) -# 8413 "parser_cocci_menhir.ml" +# 8445 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8433,7 +8465,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_define_param_list_start = # 667 "parser_cocci_menhir.mly" ( [Ast0.wrap(Ast0.DParam _1)] ) -# 8437 "parser_cocci_menhir.ml" +# 8469 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8465,7 +8497,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 8469 "parser_cocci_menhir.ml" +# 8501 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_ident = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -8474,7 +8506,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 669 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.DParam _1):: Ast0.wrap(Ast0.DPComma(P.clt2mcode "," _2))::_3 ) -# 8478 "parser_cocci_menhir.ml" +# 8510 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8501,7 +8533,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let d : ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 8505 "parser_cocci_menhir.ml" +# 8537 "parser_cocci_menhir.ml" ) = Obj.magic d in let _startpos = _startpos_d_ in let _endpos = _endpos_r_ in @@ -8509,7 +8541,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 672 "parser_cocci_menhir.mly" ( (P.mkdpdots "..." d):: (List.concat (List.map (function x -> x (P.mkdpdots "...")) r)) ) -# 8513 "parser_cocci_menhir.ml" +# 8545 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8530,7 +8562,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 80 "parser_cocci_menhir.mly" (Data.clt * token) -# 8534 "parser_cocci_menhir.ml" +# 8566 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -8552,7 +8584,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct "unexpected name for a #define")), Ast0.wrap Ast0.NoParams, body)) ) -# 8556 "parser_cocci_menhir.ml" +# 8588 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8583,13 +8615,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _3 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 8587 "parser_cocci_menhir.ml" +# 8619 "parser_cocci_menhir.ml" ) = Obj.magic _3 in let _2 : 'tv_define_param_list_option = Obj.magic _2 in let _1 : ( # 81 "parser_cocci_menhir.mly" (Data.clt * token * int) -# 8593 "parser_cocci_menhir.ml" +# 8625 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in @@ -8613,7 +8645,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (Semantic_cocci.Semantic "unexpected name for a #define")), Ast0.wrap (Ast0.DParams (lp,_2,P.clt2mcode ")" _3)),body)) ) -# 8617 "parser_cocci_menhir.ml" +# 8649 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8637,7 +8669,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_dep = # 215 "parser_cocci_menhir.mly" ( _1 ) -# 8641 "parser_cocci_menhir.ml" +# 8673 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8671,7 +8703,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_dep = # 216 "parser_cocci_menhir.mly" ( Ast.AndDep(_1, _3) ) -# 8675 "parser_cocci_menhir.ml" +# 8707 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8705,7 +8737,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_dep = # 217 "parser_cocci_menhir.mly" ( Ast.OrDep (_1, _3) ) -# 8709 "parser_cocci_menhir.ml" +# 8741 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8722,7 +8754,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_depends = # 211 "parser_cocci_menhir.mly" ( Ast.NoDep ) -# 8726 "parser_cocci_menhir.ml" +# 8758 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8754,7 +8786,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_depends = # 212 "parser_cocci_menhir.mly" ( parents ) -# 8758 "parser_cocci_menhir.ml" +# 8790 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8778,7 +8810,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_dexpr = # 1134 "parser_cocci_menhir.mly" ( _1 ) -# 8782 "parser_cocci_menhir.ml" +# 8814 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8806,7 +8838,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_disable = # 230 "parser_cocci_menhir.mly" ( List.map P.id2name _2 ) -# 8810 "parser_cocci_menhir.ml" +# 8842 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8827,14 +8859,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 8831 "parser_cocci_menhir.ml" +# 8863 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_dot_expressions = # 1143 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Edots(P.clt2mcode "..." _1,None)) ) -# 8838 "parser_cocci_menhir.ml" +# 8870 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8858,7 +8890,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_dot_expressions = # 1144 "parser_cocci_menhir.mly" ( _1 ) -# 8862 "parser_cocci_menhir.ml" +# 8894 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8884,12 +8916,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let d : ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 8888 "parser_cocci_menhir.ml" +# 8920 "parser_cocci_menhir.ml" ) = Obj.magic d in let c : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 8893 "parser_cocci_menhir.ml" +# 8925 "parser_cocci_menhir.ml" ) = Obj.magic c in let _startpos = _startpos_c_ in let _endpos = _endpos_d_ in @@ -8897,7 +8929,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 677 "parser_cocci_menhir.mly" ( function dot_builder -> [Ast0.wrap(Ast0.DPComma(P.clt2mcode "," c)); dot_builder d] ) -# 8901 "parser_cocci_menhir.ml" +# 8933 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8924,7 +8956,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 8928 "parser_cocci_menhir.ml" +# 8960 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in @@ -8933,7 +8965,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( function dot_builder -> [Ast0.wrap(Ast0.DPComma(P.clt2mcode "," _1)); Ast0.wrap(Ast0.DParam _2)] ) -# 8937 "parser_cocci_menhir.ml" +# 8969 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -8954,14 +8986,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let d : ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 8958 "parser_cocci_menhir.ml" +# 8990 "parser_cocci_menhir.ml" ) = Obj.magic d in let _startpos = _startpos_d_ in let _endpos = _endpos_d_ in let _v : 'tv_edots_when_TEllipsis_eexpr_ = -# 1698 "parser_cocci_menhir.mly" +# 1704 "parser_cocci_menhir.mly" ( (d,None) ) -# 8965 "parser_cocci_menhir.ml" +# 8997 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9000,14 +9032,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let d : ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 9004 "parser_cocci_menhir.ml" +# 9036 "parser_cocci_menhir.ml" ) = Obj.magic d in let _startpos = _startpos_d_ in let _endpos = _endpos__5_ in let _v : 'tv_edots_when_TEllipsis_eexpr_ = -# 1699 "parser_cocci_menhir.mly" +# 1705 "parser_cocci_menhir.mly" ( (d,Some w) ) -# 9011 "parser_cocci_menhir.ml" +# 9043 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9028,14 +9060,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let d : ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 9032 "parser_cocci_menhir.ml" +# 9064 "parser_cocci_menhir.ml" ) = Obj.magic d in let _startpos = _startpos_d_ in let _endpos = _endpos_d_ in let _v : 'tv_edots_when_TEllipsis_initialize_ = -# 1698 "parser_cocci_menhir.mly" +# 1704 "parser_cocci_menhir.mly" ( (d,None) ) -# 9039 "parser_cocci_menhir.ml" +# 9071 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9074,14 +9106,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let d : ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 9078 "parser_cocci_menhir.ml" +# 9110 "parser_cocci_menhir.ml" ) = Obj.magic d in let _startpos = _startpos_d_ in let _endpos = _endpos__5_ in let _v : 'tv_edots_when_TEllipsis_initialize_ = -# 1699 "parser_cocci_menhir.mly" +# 1705 "parser_cocci_menhir.mly" ( (d,Some w) ) -# 9085 "parser_cocci_menhir.ml" +# 9117 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9102,14 +9134,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let d : ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 9106 "parser_cocci_menhir.ml" +# 9138 "parser_cocci_menhir.ml" ) = Obj.magic d in let _startpos = _startpos_d_ in let _endpos = _endpos_d_ in let _v : 'tv_edots_when_TEllipsis_struct_decl_ = -# 1698 "parser_cocci_menhir.mly" +# 1704 "parser_cocci_menhir.mly" ( (d,None) ) -# 9113 "parser_cocci_menhir.ml" +# 9145 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9148,14 +9180,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let d : ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 9152 "parser_cocci_menhir.ml" +# 9184 "parser_cocci_menhir.ml" ) = Obj.magic d in let _startpos = _startpos_d_ in let _endpos = _endpos__5_ in let _v : 'tv_edots_when_TEllipsis_struct_decl_ = -# 1699 "parser_cocci_menhir.mly" +# 1705 "parser_cocci_menhir.mly" ( (d,Some w) ) -# 9159 "parser_cocci_menhir.ml" +# 9191 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9179,7 +9211,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_eexpr = # 1132 "parser_cocci_menhir.mly" ( _1 ) -# 9183 "parser_cocci_menhir.ml" +# 9215 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9201,7 +9233,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_eexpr_list = -# 1642 "parser_cocci_menhir.mly" +# 1648 "parser_cocci_menhir.mly" (let circle x = match Ast0.unwrap x with Ast0.Ecircles(_) -> true | _ -> false in let star x = @@ -9212,7 +9244,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct if List.exists star _1 then Ast0.wrap(Ast0.STARS(_1)) else Ast0.wrap(Ast0.DOTS(_1)) ) -# 9216 "parser_cocci_menhir.ml" +# 9248 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9234,9 +9266,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_eexpr_list_option = -# 1681 "parser_cocci_menhir.mly" +# 1687 "parser_cocci_menhir.mly" ( _1 ) -# 9240 "parser_cocci_menhir.ml" +# 9272 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9251,9 +9283,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_eexpr_list_option = -# 1682 "parser_cocci_menhir.mly" +# 1688 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.DOTS([])) ) -# 9257 "parser_cocci_menhir.ml" +# 9289 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9275,9 +9307,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_eexpr_list_start = -# 1669 "parser_cocci_menhir.mly" +# 1675 "parser_cocci_menhir.mly" ( [_1] ) -# 9281 "parser_cocci_menhir.ml" +# 9313 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9309,15 +9341,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 9313 "parser_cocci_menhir.ml" +# 9345 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_aexpr = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : 'tv_eexpr_list_start = -# 1671 "parser_cocci_menhir.mly" +# 1677 "parser_cocci_menhir.mly" ( _1::Ast0.wrap(Ast0.EComma(P.clt2mcode "," _2))::_3 ) -# 9321 "parser_cocci_menhir.ml" +# 9353 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9361,7 +9393,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_error_words = # 1481 "parser_cocci_menhir.mly" ( [Ast0.wrap(Ast0.ERRORWORDS(cl))] ) -# 9365 "parser_cocci_menhir.ml" +# 9397 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9383,7 +9415,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_exists = # 233 "parser_cocci_menhir.mly" ( Ast.Exists ) -# 9387 "parser_cocci_menhir.ml" +# 9419 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9405,7 +9437,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_exists = # 234 "parser_cocci_menhir.mly" ( Ast.Forall ) -# 9409 "parser_cocci_menhir.ml" +# 9441 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9431,7 +9463,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_exists = # 235 "parser_cocci_menhir.mly" ( Ast.ReverseForall ) -# 9435 "parser_cocci_menhir.ml" +# 9467 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9448,7 +9480,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_exists = # 236 "parser_cocci_menhir.mly" ( Ast.Undetermined ) -# 9452 "parser_cocci_menhir.ml" +# 9484 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9472,7 +9504,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_expr = # 1130 "parser_cocci_menhir.mly" ( _1 ) -# 9476 "parser_cocci_menhir.ml" +# 9508 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9496,7 +9528,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_expr_dots_TEllipsis_ = # 1311 "parser_cocci_menhir.mly" ( r ) -# 9500 "parser_cocci_menhir.ml" +# 9532 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9513,7 +9545,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_extends = # 206 "parser_cocci_menhir.mly" ( () ) -# 9517 "parser_cocci_menhir.ml" +# 9549 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9538,14 +9570,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let parent : ( # 47 "parser_cocci_menhir.mly" (string) -# 9542 "parser_cocci_menhir.ml" +# 9574 "parser_cocci_menhir.ml" ) = Obj.magic parent in let _startpos = _startpos__1_ in let _endpos = _endpos_parent_ in let _v : 'tv_extends = # 208 "parser_cocci_menhir.mly" ( !Data.install_bindings (parent) ) -# 9549 "parser_cocci_menhir.ml" +# 9581 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9571,12 +9603,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 82 "parser_cocci_menhir.mly" (string * Data.clt) -# 9575 "parser_cocci_menhir.ml" +# 9607 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : ( # 82 "parser_cocci_menhir.mly" (string * Data.clt) -# 9580 "parser_cocci_menhir.ml" +# 9612 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in @@ -9585,7 +9617,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( [Ast0.wrap (Ast0.FILEINFO(P.id2mcode _1, P.id2mcode _2))] ) -# 9589 "parser_cocci_menhir.ml" +# 9621 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9615,7 +9647,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_fn_ctype = # 535 "parser_cocci_menhir.mly" ( P.pointerify ty m ) -# 9619 "parser_cocci_menhir.ml" +# 9651 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9642,7 +9674,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let t : ( # 50 "parser_cocci_menhir.mly" (Data.clt) -# 9646 "parser_cocci_menhir.ml" +# 9678 "parser_cocci_menhir.ml" ) = Obj.magic t in let _startpos = _startpos_t_ in let _endpos = _endpos_m_ in @@ -9651,7 +9683,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( P.pointerify (Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.VoidType t, None))) m ) -# 9655 "parser_cocci_menhir.ml" +# 9687 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9668,7 +9700,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_fninfo = # 723 "parser_cocci_menhir.mly" ( [] ) -# 9672 "parser_cocci_menhir.ml" +# 9704 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9702,7 +9734,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct List.find (function Ast0.FStorage(_) -> true | _ -> false) _2 in raise (Semantic_cocci.Semantic "duplicate storage") with Not_found -> (Ast0.FStorage(_1))::_2 ) -# 9706 "parser_cocci_menhir.ml" +# 9738 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9732,7 +9764,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_fninfo = # 730 "parser_cocci_menhir.mly" ( (Ast0.FType(t))::r ) -# 9736 "parser_cocci_menhir.ml" +# 9768 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9759,7 +9791,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 53 "parser_cocci_menhir.mly" (Data.clt) -# 9763 "parser_cocci_menhir.ml" +# 9795 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in @@ -9769,7 +9801,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 ) -# 9773 "parser_cocci_menhir.ml" +# 9805 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9796,7 +9828,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 55 "parser_cocci_menhir.mly" (string * Data.clt) -# 9800 "parser_cocci_menhir.ml" +# 9832 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in @@ -9806,7 +9838,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 ) -# 9810 "parser_cocci_menhir.ml" +# 9842 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9823,7 +9855,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_fninfo_nt = # 743 "parser_cocci_menhir.mly" ( [] ) -# 9827 "parser_cocci_menhir.ml" +# 9859 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9857,7 +9889,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct List.find (function Ast0.FStorage(_) -> true | _ -> false) _2 in raise (Semantic_cocci.Semantic "duplicate storage") with Not_found -> (Ast0.FStorage(_1))::_2 ) -# 9861 "parser_cocci_menhir.ml" +# 9893 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9884,7 +9916,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 53 "parser_cocci_menhir.mly" (Data.clt) -# 9888 "parser_cocci_menhir.ml" +# 9920 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in @@ -9894,7 +9926,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 ) -# 9898 "parser_cocci_menhir.ml" +# 9930 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9921,7 +9953,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 55 "parser_cocci_menhir.mly" (string * Data.clt) -# 9925 "parser_cocci_menhir.ml" +# 9957 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in @@ -9931,7 +9963,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 ) -# 9935 "parser_cocci_menhir.ml" +# 9967 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9946,9 +9978,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_fun_after_dots = -# 1590 "parser_cocci_menhir.mly" +# 1596 "parser_cocci_menhir.mly" ([]) -# 9952 "parser_cocci_menhir.ml" +# 9984 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -9974,9 +10006,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_fun_after_dots = -# 1591 "parser_cocci_menhir.mly" +# 1597 "parser_cocci_menhir.mly" (_2) -# 9980 "parser_cocci_menhir.ml" +# 10012 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10004,9 +10036,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_fun_after_dots = -# 1592 "parser_cocci_menhir.mly" +# 1598 "parser_cocci_menhir.mly" (Ast0.wrap(Ast0.Exp(_1))::_2) -# 10010 "parser_cocci_menhir.ml" +# 10042 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10034,9 +10066,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_fun_after_dots = -# 1593 "parser_cocci_menhir.mly" +# 1599 "parser_cocci_menhir.mly" (_1@_2) -# 10040 "parser_cocci_menhir.ml" +# 10072 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10051,9 +10083,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_fun_after_dots_or = -# 1600 "parser_cocci_menhir.mly" +# 1606 "parser_cocci_menhir.mly" ([]) -# 10057 "parser_cocci_menhir.ml" +# 10089 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10079,9 +10111,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_fun_after_dots_or = -# 1601 "parser_cocci_menhir.mly" +# 1607 "parser_cocci_menhir.mly" (_2) -# 10085 "parser_cocci_menhir.ml" +# 10117 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10109,9 +10141,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_fun_after_dots_or = -# 1602 "parser_cocci_menhir.mly" +# 1608 "parser_cocci_menhir.mly" (Ast0.wrap(Ast0.Exp(_1))::_2) -# 10115 "parser_cocci_menhir.ml" +# 10147 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10139,9 +10171,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_fun_after_dots_or = -# 1603 "parser_cocci_menhir.mly" +# 1609 "parser_cocci_menhir.mly" (_1@_2) -# 10145 "parser_cocci_menhir.ml" +# 10177 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10169,9 +10201,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_fun_after_exp = -# 1596 "parser_cocci_menhir.mly" +# 1602 "parser_cocci_menhir.mly" (_1::_2) -# 10175 "parser_cocci_menhir.ml" +# 10207 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10186,9 +10218,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_fun_after_exp_or = -# 1606 "parser_cocci_menhir.mly" +# 1612 "parser_cocci_menhir.mly" ([]) -# 10192 "parser_cocci_menhir.ml" +# 10224 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10216,9 +10248,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_fun_after_exp_or = -# 1607 "parser_cocci_menhir.mly" +# 1613 "parser_cocci_menhir.mly" (_1::_2) -# 10222 "parser_cocci_menhir.ml" +# 10254 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10233,9 +10265,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_fun_after_stm = -# 1585 "parser_cocci_menhir.mly" +# 1591 "parser_cocci_menhir.mly" ([]) -# 10239 "parser_cocci_menhir.ml" +# 10271 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10263,9 +10295,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_fun_after_stm = -# 1586 "parser_cocci_menhir.mly" +# 1592 "parser_cocci_menhir.mly" (_1::_2) -# 10269 "parser_cocci_menhir.ml" +# 10301 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10293,9 +10325,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_fun_after_stm = -# 1587 "parser_cocci_menhir.mly" +# 1593 "parser_cocci_menhir.mly" (_1@_2) -# 10299 "parser_cocci_menhir.ml" +# 10331 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10317,9 +10349,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_fun_start = -# 1582 "parser_cocci_menhir.mly" +# 1588 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.DOTS(_1)) ) -# 10323 "parser_cocci_menhir.ml" +# 10355 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10343,7 +10375,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_func_ident = # 1400 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Id(P.id2mcode _1)) ) -# 10347 "parser_cocci_menhir.ml" +# 10379 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10364,7 +10396,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 61 "parser_cocci_menhir.mly" (Parse_aux.idinfo) -# 10368 "parser_cocci_menhir.ml" +# 10400 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -10372,7 +10404,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1402 "parser_cocci_menhir.mly" ( let (nm,constraints,pure,clt) = _1 in Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) ) -# 10376 "parser_cocci_menhir.ml" +# 10408 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10393,7 +10425,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 61 "parser_cocci_menhir.mly" (Parse_aux.idinfo) -# 10397 "parser_cocci_menhir.ml" +# 10429 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -10401,7 +10433,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1405 "parser_cocci_menhir.mly" ( let (nm,constraints,pure,clt) = _1 in Ast0.wrap(Ast0.MetaFunc(P.clt2mcode nm clt,constraints,pure)) ) -# 10405 "parser_cocci_menhir.ml" +# 10437 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10422,7 +10454,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 61 "parser_cocci_menhir.mly" (Parse_aux.idinfo) -# 10426 "parser_cocci_menhir.ml" +# 10458 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -10431,7 +10463,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let (nm,constraints,pure,clt) = _1 in Ast0.wrap (Ast0.MetaLocalFunc(P.clt2mcode nm clt,constraints,pure)) ) -# 10435 "parser_cocci_menhir.ml" +# 10467 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10491,24 +10523,24 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let rb : ( # 100 "parser_cocci_menhir.mly" (Data.clt) -# 10495 "parser_cocci_menhir.ml" +# 10527 "parser_cocci_menhir.ml" ) = Obj.magic rb in let b : 'tv_fun_start = Obj.magic b in let lb : ( # 100 "parser_cocci_menhir.mly" (Data.clt) -# 10501 "parser_cocci_menhir.ml" +# 10533 "parser_cocci_menhir.ml" ) = Obj.magic lb in let rp : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 10506 "parser_cocci_menhir.ml" +# 10538 "parser_cocci_menhir.ml" ) = Obj.magic rp in let d : 'tv_decl_list_decl_ = Obj.magic d in let lp : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 10512 "parser_cocci_menhir.ml" +# 10544 "parser_cocci_menhir.ml" ) = Obj.magic lp in let i : 'tv_func_ident = Obj.magic i in let f : 'tv_fninfo = Obj.magic f in @@ -10522,7 +10554,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct P.clt2mcode ")" rp, P.clt2mcode "{" lb, b, P.clt2mcode "}" rb)) ) -# 10526 "parser_cocci_menhir.ml" +# 10558 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10568,18 +10600,18 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pt : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 10572 "parser_cocci_menhir.ml" +# 10604 "parser_cocci_menhir.ml" ) = Obj.magic pt in let rp : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 10577 "parser_cocci_menhir.ml" +# 10609 "parser_cocci_menhir.ml" ) = Obj.magic rp in let d : 'tv_decl_list_name_opt_decl_ = Obj.magic d in let lp : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 10583 "parser_cocci_menhir.ml" +# 10615 "parser_cocci_menhir.ml" ) = Obj.magic lp in let id : 'tv_func_ident = Obj.magic id in let t : 'tv_ctype = Obj.magic t in @@ -10589,7 +10621,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 10593 "parser_cocci_menhir.ml" +# 10625 "parser_cocci_menhir.ml" in @@ -10601,7 +10633,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (Ast0.FunctionType(Some t, P.clt2mcode "(" lp, d, P.clt2mcode ")" rp)), id, P.clt2mcode ";" pt)) ) -# 10605 "parser_cocci_menhir.ml" +# 10637 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10652,18 +10684,18 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pt : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 10656 "parser_cocci_menhir.ml" +# 10688 "parser_cocci_menhir.ml" ) = Obj.magic pt in let rp : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 10661 "parser_cocci_menhir.ml" +# 10693 "parser_cocci_menhir.ml" ) = Obj.magic rp in let d : 'tv_decl_list_name_opt_decl_ = Obj.magic d in let lp : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 10667 "parser_cocci_menhir.ml" +# 10699 "parser_cocci_menhir.ml" ) = Obj.magic lp in let id : 'tv_func_ident = Obj.magic id in let t : 'tv_ctype = Obj.magic t in @@ -10675,7 +10707,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 10679 "parser_cocci_menhir.ml" +# 10711 "parser_cocci_menhir.ml" in @@ -10687,7 +10719,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (Ast0.FunctionType(Some t, P.clt2mcode "(" lp, d, P.clt2mcode ")" rp)), id, P.clt2mcode ";" pt)) ) -# 10691 "parser_cocci_menhir.ml" +# 10723 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10733,24 +10765,24 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pt : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 10737 "parser_cocci_menhir.ml" +# 10769 "parser_cocci_menhir.ml" ) = Obj.magic pt in let rp : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 10742 "parser_cocci_menhir.ml" +# 10774 "parser_cocci_menhir.ml" ) = Obj.magic rp in let d : 'tv_decl_list_name_opt_decl_ = Obj.magic d in let lp : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 10748 "parser_cocci_menhir.ml" +# 10780 "parser_cocci_menhir.ml" ) = Obj.magic lp in let id : 'tv_func_ident = Obj.magic id in let t : ( # 50 "parser_cocci_menhir.mly" (Data.clt) -# 10754 "parser_cocci_menhir.ml" +# 10786 "parser_cocci_menhir.ml" ) = Obj.magic t in let _startpos = _startpos_t_ in let _endpos = _endpos_pt_ in @@ -10758,7 +10790,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 10762 "parser_cocci_menhir.ml" +# 10794 "parser_cocci_menhir.ml" in @@ -10771,7 +10803,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (Ast0.FunctionType(Some t, P.clt2mcode "(" lp, d, P.clt2mcode ")" rp)), id, P.clt2mcode ";" pt)) ) -# 10775 "parser_cocci_menhir.ml" +# 10807 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10822,24 +10854,24 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pt : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 10826 "parser_cocci_menhir.ml" +# 10858 "parser_cocci_menhir.ml" ) = Obj.magic pt in let rp : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 10831 "parser_cocci_menhir.ml" +# 10863 "parser_cocci_menhir.ml" ) = Obj.magic rp in let d : 'tv_decl_list_name_opt_decl_ = Obj.magic d in let lp : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 10837 "parser_cocci_menhir.ml" +# 10869 "parser_cocci_menhir.ml" ) = Obj.magic lp in let id : 'tv_func_ident = Obj.magic id in let t : ( # 50 "parser_cocci_menhir.mly" (Data.clt) -# 10843 "parser_cocci_menhir.ml" +# 10875 "parser_cocci_menhir.ml" ) = Obj.magic t in let x0 : 'tv_storage = Obj.magic x0 in let _startpos = _startpos_x0_ in @@ -10849,7 +10881,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 10853 "parser_cocci_menhir.ml" +# 10885 "parser_cocci_menhir.ml" in @@ -10862,7 +10894,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (Ast0.FunctionType(Some t, P.clt2mcode "(" lp, d, P.clt2mcode ")" rp)), id, P.clt2mcode ";" pt)) ) -# 10866 "parser_cocci_menhir.ml" +# 10898 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10886,7 +10918,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_generic_ctype = # 442 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.ImplicitInt(q)) ) -# 10890 "parser_cocci_menhir.ml" +# 10922 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10907,7 +10939,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let ty : ( # 49 "parser_cocci_menhir.mly" (Data.clt) -# 10911 "parser_cocci_menhir.ml" +# 10943 "parser_cocci_menhir.ml" ) = Obj.magic ty in let _startpos = _startpos_ty_ in let _endpos = _endpos_ty_ in @@ -10915,13 +10947,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 10919 "parser_cocci_menhir.ml" +# 10951 "parser_cocci_menhir.ml" in # 444 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.CharType ty, q)) ) -# 10925 "parser_cocci_menhir.ml" +# 10957 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10947,7 +10979,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let ty : ( # 49 "parser_cocci_menhir.mly" (Data.clt) -# 10951 "parser_cocci_menhir.ml" +# 10983 "parser_cocci_menhir.ml" ) = Obj.magic ty in let x0 : 'tv_ctype_qualif = Obj.magic x0 in let _startpos = _startpos_x0_ in @@ -10957,13 +10989,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 10961 "parser_cocci_menhir.ml" +# 10993 "parser_cocci_menhir.ml" in # 444 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.CharType ty, q)) ) -# 10967 "parser_cocci_menhir.ml" +# 10999 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -10984,7 +11016,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let ty : ( # 49 "parser_cocci_menhir.mly" (Data.clt) -# 10988 "parser_cocci_menhir.ml" +# 11020 "parser_cocci_menhir.ml" ) = Obj.magic ty in let _startpos = _startpos_ty_ in let _endpos = _endpos_ty_ in @@ -10992,13 +11024,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 10996 "parser_cocci_menhir.ml" +# 11028 "parser_cocci_menhir.ml" in # 446 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.ShortType ty, q)) ) -# 11002 "parser_cocci_menhir.ml" +# 11034 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11024,7 +11056,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let ty : ( # 49 "parser_cocci_menhir.mly" (Data.clt) -# 11028 "parser_cocci_menhir.ml" +# 11060 "parser_cocci_menhir.ml" ) = Obj.magic ty in let x0 : 'tv_ctype_qualif = Obj.magic x0 in let _startpos = _startpos_x0_ in @@ -11034,13 +11066,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 11038 "parser_cocci_menhir.ml" +# 11070 "parser_cocci_menhir.ml" in # 446 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.ShortType ty, q)) ) -# 11044 "parser_cocci_menhir.ml" +# 11076 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11061,7 +11093,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let ty : ( # 49 "parser_cocci_menhir.mly" (Data.clt) -# 11065 "parser_cocci_menhir.ml" +# 11097 "parser_cocci_menhir.ml" ) = Obj.magic ty in let _startpos = _startpos_ty_ in let _endpos = _endpos_ty_ in @@ -11069,13 +11101,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 11073 "parser_cocci_menhir.ml" +# 11105 "parser_cocci_menhir.ml" in # 448 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.IntType ty, q)) ) -# 11079 "parser_cocci_menhir.ml" +# 11111 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11101,7 +11133,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let ty : ( # 49 "parser_cocci_menhir.mly" (Data.clt) -# 11105 "parser_cocci_menhir.ml" +# 11137 "parser_cocci_menhir.ml" ) = Obj.magic ty in let x0 : 'tv_ctype_qualif = Obj.magic x0 in let _startpos = _startpos_x0_ in @@ -11111,13 +11143,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 11115 "parser_cocci_menhir.ml" +# 11147 "parser_cocci_menhir.ml" in # 448 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.IntType ty, q)) ) -# 11121 "parser_cocci_menhir.ml" +# 11153 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11138,14 +11170,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let t : ( # 49 "parser_cocci_menhir.mly" (Data.clt) -# 11142 "parser_cocci_menhir.ml" +# 11174 "parser_cocci_menhir.ml" ) = Obj.magic t in let _startpos = _startpos_t_ in let _endpos = _endpos_t_ in let _v : 'tv_generic_ctype = # 450 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.DoubleType t, None)) ) -# 11149 "parser_cocci_menhir.ml" +# 11181 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11166,14 +11198,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let t : ( # 49 "parser_cocci_menhir.mly" (Data.clt) -# 11170 "parser_cocci_menhir.ml" +# 11202 "parser_cocci_menhir.ml" ) = Obj.magic t in let _startpos = _startpos_t_ in let _endpos = _endpos_t_ in let _v : 'tv_generic_ctype = # 452 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.FloatType t, None)) ) -# 11177 "parser_cocci_menhir.ml" +# 11209 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11194,7 +11226,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let ty : ( # 49 "parser_cocci_menhir.mly" (Data.clt) -# 11198 "parser_cocci_menhir.ml" +# 11230 "parser_cocci_menhir.ml" ) = Obj.magic ty in let _startpos = _startpos_ty_ in let _endpos = _endpos_ty_ in @@ -11202,13 +11234,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 11206 "parser_cocci_menhir.ml" +# 11238 "parser_cocci_menhir.ml" in # 454 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.LongType ty, q)) ) -# 11212 "parser_cocci_menhir.ml" +# 11244 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11234,7 +11266,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let ty : ( # 49 "parser_cocci_menhir.mly" (Data.clt) -# 11238 "parser_cocci_menhir.ml" +# 11270 "parser_cocci_menhir.ml" ) = Obj.magic ty in let x0 : 'tv_ctype_qualif = Obj.magic x0 in let _startpos = _startpos_x0_ in @@ -11244,13 +11276,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 11248 "parser_cocci_menhir.ml" +# 11280 "parser_cocci_menhir.ml" in # 454 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.LongType ty, q)) ) -# 11254 "parser_cocci_menhir.ml" +# 11286 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11280,7 +11312,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_generic_ctype = # 456 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.StructUnionName(s, Some i)) ) -# 11284 "parser_cocci_menhir.ml" +# 11316 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11316,13 +11348,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let r : ( # 100 "parser_cocci_menhir.mly" (Data.clt) -# 11320 "parser_cocci_menhir.ml" +# 11352 "parser_cocci_menhir.ml" ) = Obj.magic r in let d : 'tv_struct_decl_list = Obj.magic d in let l : ( # 100 "parser_cocci_menhir.mly" (Data.clt) -# 11326 "parser_cocci_menhir.ml" +# 11358 "parser_cocci_menhir.ml" ) = Obj.magic l in let s : 'tv_struct_or_union = Obj.magic s in let _startpos = _startpos_s_ in @@ -11331,7 +11363,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 11335 "parser_cocci_menhir.ml" +# 11367 "parser_cocci_menhir.ml" in @@ -11341,7 +11373,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct Ast0.wrap(Ast0.StructUnionDef(Ast0.wrap(Ast0.StructUnionName(s, i)), P.clt2mcode "{" l, d, P.clt2mcode "}" r)) ) -# 11345 "parser_cocci_menhir.ml" +# 11377 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11382,13 +11414,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let r : ( # 100 "parser_cocci_menhir.mly" (Data.clt) -# 11386 "parser_cocci_menhir.ml" +# 11418 "parser_cocci_menhir.ml" ) = Obj.magic r in let d : 'tv_struct_decl_list = Obj.magic d in let l : ( # 100 "parser_cocci_menhir.mly" (Data.clt) -# 11392 "parser_cocci_menhir.ml" +# 11424 "parser_cocci_menhir.ml" ) = Obj.magic l in let x0 : 'tv_ident = Obj.magic x0 in let s : 'tv_struct_or_union = Obj.magic s in @@ -11399,7 +11431,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 11403 "parser_cocci_menhir.ml" +# 11435 "parser_cocci_menhir.ml" in @@ -11409,7 +11441,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct Ast0.wrap(Ast0.StructUnionDef(Ast0.wrap(Ast0.StructUnionName(s, i)), P.clt2mcode "{" l, d, P.clt2mcode "}" r)) ) -# 11413 "parser_cocci_menhir.ml" +# 11445 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11445,18 +11477,18 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let r : ( # 100 "parser_cocci_menhir.mly" (Data.clt) -# 11449 "parser_cocci_menhir.ml" +# 11481 "parser_cocci_menhir.ml" ) = Obj.magic r in let d : 'tv_struct_decl_list = Obj.magic d in let l : ( # 100 "parser_cocci_menhir.mly" (Data.clt) -# 11455 "parser_cocci_menhir.ml" +# 11487 "parser_cocci_menhir.ml" ) = Obj.magic l in let s : ( # 64 "parser_cocci_menhir.mly" (Parse_aux.info) -# 11460 "parser_cocci_menhir.ml" +# 11492 "parser_cocci_menhir.ml" ) = Obj.magic s in let _startpos = _startpos_s_ in let _endpos = _endpos_r_ in @@ -11467,7 +11499,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct Ast0.wrap(Ast0.MetaType(P.clt2mcode nm clt,pure)) in Ast0.wrap (Ast0.StructUnionDef(ty,P.clt2mcode "{" l,d,P.clt2mcode "}" r)) ) -# 11471 "parser_cocci_menhir.ml" +# 11503 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11497,12 +11529,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let p : ( # 59 "parser_cocci_menhir.mly" (string * Data.clt) -# 11501 "parser_cocci_menhir.ml" +# 11533 "parser_cocci_menhir.ml" ) = Obj.magic p in let r : ( # 47 "parser_cocci_menhir.mly" (string) -# 11506 "parser_cocci_menhir.ml" +# 11538 "parser_cocci_menhir.ml" ) = Obj.magic r in let _startpos = _startpos_r_ in let _endpos = _endpos_p_ in @@ -11514,7 +11546,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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*))) ) -# 11518 "parser_cocci_menhir.ml" +# 11550 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11535,14 +11567,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let p : ( # 59 "parser_cocci_menhir.mly" (string * Data.clt) -# 11539 "parser_cocci_menhir.ml" +# 11571 "parser_cocci_menhir.ml" ) = Obj.magic p in let _startpos = _startpos_p_ in let _endpos = _endpos_p_ in let _v : 'tv_generic_ctype = # 478 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.TypeName(P.id2mcode p)) ) -# 11546 "parser_cocci_menhir.ml" +# 11578 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11563,7 +11595,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let p : ( # 64 "parser_cocci_menhir.mly" (Parse_aux.info) -# 11567 "parser_cocci_menhir.ml" +# 11599 "parser_cocci_menhir.ml" ) = Obj.magic p in let _startpos = _startpos_p_ in let _endpos = _endpos_p_ in @@ -11571,7 +11603,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 480 "parser_cocci_menhir.mly" ( let (nm,pure,clt) = p in Ast0.wrap(Ast0.MetaType(P.clt2mcode nm clt,pure)) ) -# 11575 "parser_cocci_menhir.ml" +# 11607 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11595,7 +11627,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_ident = # 1413 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Id(P.id2mcode _1)) ) -# 11599 "parser_cocci_menhir.ml" +# 11631 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11616,7 +11648,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 61 "parser_cocci_menhir.mly" (Parse_aux.idinfo) -# 11620 "parser_cocci_menhir.ml" +# 11652 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -11624,7 +11656,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1415 "parser_cocci_menhir.mly" ( let (nm,constraints,pure,clt) = _1 in Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) ) -# 11628 "parser_cocci_menhir.ml" +# 11660 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11648,7 +11680,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_ident_or_const = # 1371 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Ident(Ast0.wrap(Ast0.Id(P.id2mcode i)))) ) -# 11652 "parser_cocci_menhir.ml" +# 11684 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11669,7 +11701,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 11673 "parser_cocci_menhir.ml" +# 11705 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -11677,7 +11709,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1373 "parser_cocci_menhir.mly" ( let (x,clt) = _1 in Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) ) -# 11681 "parser_cocci_menhir.ml" +# 11713 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11702,14 +11734,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 11706 "parser_cocci_menhir.ml" +# 11738 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_incl = # 247 "parser_cocci_menhir.mly" ( Common.Left(P.id2name _2) ) -# 11713 "parser_cocci_menhir.ml" +# 11745 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11734,14 +11766,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 78 "parser_cocci_menhir.mly" (string) -# 11738 "parser_cocci_menhir.ml" +# 11770 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_incl = # 248 "parser_cocci_menhir.mly" ( Common.Right _2 ) -# 11745 "parser_cocci_menhir.ml" +# 11777 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11769,11 +11801,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 145 "parser_cocci_menhir.mly" ((string,string) Common.either list) -# 11773 "parser_cocci_menhir.ml" +# 11805 "parser_cocci_menhir.ml" ) = # 243 "parser_cocci_menhir.mly" ( _1 ) -# 11777 "parser_cocci_menhir.ml" +# 11809 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11801,11 +11833,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 145 "parser_cocci_menhir.mly" ((string,string) Common.either list) -# 11805 "parser_cocci_menhir.ml" +# 11837 "parser_cocci_menhir.ml" ) = # 244 "parser_cocci_menhir.mly" ( _1 ) -# 11809 "parser_cocci_menhir.ml" +# 11841 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11826,7 +11858,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 79 "parser_cocci_menhir.mly" (string * Data.clt) -# 11830 "parser_cocci_menhir.ml" +# 11862 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -11841,7 +11873,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct P.clt2mcode (Ast.Local (Parse_aux.str2inc (P.id2name _1))) (P.drop_bef clt))) ) -# 11845 "parser_cocci_menhir.ml" +# 11877 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11862,7 +11894,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 79 "parser_cocci_menhir.mly" (string * Data.clt) -# 11866 "parser_cocci_menhir.ml" +# 11898 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -11877,7 +11909,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct P.clt2mcode (Ast.NonLocal (Parse_aux.str2inc (P.id2name _1))) (P.drop_bef clt))) ) -# 11881 "parser_cocci_menhir.ml" +# 11913 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11912,7 +11944,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 606 "parser_cocci_menhir.mly" ( let ty = Ast0.wrap(Ast0.TopExp(Ast0.wrap(Ast0.TypeExp(t)))) in d (Ast0.wrap(Ast0.DOTS([ty]))) ) -# 11916 "parser_cocci_menhir.ml" +# 11948 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11954,7 +11986,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct | _ -> b) | _ -> b in _1 (Ast0.wrap(Ast0.DOTS(body))) ) -# 11958 "parser_cocci_menhir.ml" +# 11990 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -11978,7 +12010,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_initialize = # 1008 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.InitExpr(_1)) ) -# 11982 "parser_cocci_menhir.ml" +# 12014 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12009,20 +12041,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _3 : ( # 100 "parser_cocci_menhir.mly" (Data.clt) -# 12013 "parser_cocci_menhir.ml" +# 12045 "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) -# 12019 "parser_cocci_menhir.ml" +# 12051 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : 'tv_initialize = # 1010 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.InitList(P.clt2mcode "{" _1,_2,P.clt2mcode "}" _3)) ) -# 12026 "parser_cocci_menhir.ml" +# 12058 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12048,12 +12080,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 100 "parser_cocci_menhir.mly" (Data.clt) -# 12052 "parser_cocci_menhir.ml" +# 12084 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : ( # 100 "parser_cocci_menhir.mly" (Data.clt) -# 12057 "parser_cocci_menhir.ml" +# 12089 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in @@ -12062,7 +12094,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( Ast0.wrap (Ast0.InitList(P.clt2mcode "{" _1,Ast0.wrap(Ast0.DOTS []), P.clt2mcode "}" _2)) ) -# 12066 "parser_cocci_menhir.ml" +# 12098 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12086,7 +12118,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_initialize2 = # 1019 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.InitExpr(_1)) ) -# 12090 "parser_cocci_menhir.ml" +# 12122 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12117,20 +12149,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _3 : ( # 100 "parser_cocci_menhir.mly" (Data.clt) -# 12121 "parser_cocci_menhir.ml" +# 12153 "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) -# 12127 "parser_cocci_menhir.ml" +# 12159 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : 'tv_initialize2 = # 1021 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.InitList(P.clt2mcode "{" _1,_2,P.clt2mcode "}" _3)) ) -# 12134 "parser_cocci_menhir.ml" +# 12166 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12156,12 +12188,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 100 "parser_cocci_menhir.mly" (Data.clt) -# 12160 "parser_cocci_menhir.ml" +# 12192 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : ( # 100 "parser_cocci_menhir.mly" (Data.clt) -# 12165 "parser_cocci_menhir.ml" +# 12197 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in @@ -12170,7 +12202,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( Ast0.wrap (Ast0.InitList(P.clt2mcode "{" _1,Ast0.wrap(Ast0.DOTS []), P.clt2mcode "}" _2)) ) -# 12174 "parser_cocci_menhir.ml" +# 12206 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12207,20 +12239,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _3 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 12211 "parser_cocci_menhir.ml" +# 12243 "parser_cocci_menhir.ml" ) = Obj.magic _3 in let _2 : 'tv_ident = Obj.magic _2 in let _1 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 12217 "parser_cocci_menhir.ml" +# 12249 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__4_ in let _v : 'tv_initialize2 = # 1028 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.InitGccDotName(P.clt2mcode "." _1,_2,P.clt2mcode "=" _3,_4)) ) -# 12224 "parser_cocci_menhir.ml" +# 12256 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12252,7 +12284,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 12256 "parser_cocci_menhir.ml" +# 12288 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_ident = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -12260,7 +12292,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_initialize2 = # 1030 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.InitGccName(_1,P.clt2mcode ":" _2,_3)) ) -# 12264 "parser_cocci_menhir.ml" +# 12296 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12302,18 +12334,18 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _4 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 12306 "parser_cocci_menhir.ml" +# 12338 "parser_cocci_menhir.ml" ) = Obj.magic _4 in let _3 : ( # 101 "parser_cocci_menhir.mly" (Data.clt) -# 12311 "parser_cocci_menhir.ml" +# 12343 "parser_cocci_menhir.ml" ) = Obj.magic _3 in let _2 : 'tv_eexpr = Obj.magic _2 in let _1 : ( # 101 "parser_cocci_menhir.mly" (Data.clt) -# 12317 "parser_cocci_menhir.ml" +# 12349 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__5_ in @@ -12321,7 +12353,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1032 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.InitGccIndex(P.clt2mcode "[" _1,_2,P.clt2mcode "]" _3, P.clt2mcode "=" _4,_5)) ) -# 12325 "parser_cocci_menhir.ml" +# 12357 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12373,24 +12405,24 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _6 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 12377 "parser_cocci_menhir.ml" +# 12409 "parser_cocci_menhir.ml" ) = Obj.magic _6 in let _5 : ( # 101 "parser_cocci_menhir.mly" (Data.clt) -# 12382 "parser_cocci_menhir.ml" +# 12414 "parser_cocci_menhir.ml" ) = Obj.magic _5 in let _4 : 'tv_eexpr = Obj.magic _4 in let _3 : ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 12388 "parser_cocci_menhir.ml" +# 12420 "parser_cocci_menhir.ml" ) = Obj.magic _3 in let _2 : 'tv_eexpr = Obj.magic _2 in let _1 : ( # 101 "parser_cocci_menhir.mly" (Data.clt) -# 12394 "parser_cocci_menhir.ml" +# 12426 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__7_ in @@ -12398,7 +12430,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1035 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.InitGccRange(P.clt2mcode "[" _1,_2,P.clt2mcode "..." _3, _4,P.clt2mcode "]" _5,P.clt2mcode "=" _6,_7)) ) -# 12402 "parser_cocci_menhir.ml" +# 12434 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12422,7 +12454,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_initialize_list = # 1039 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.DOTS(_1)) ) -# 12426 "parser_cocci_menhir.ml" +# 12458 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12448,7 +12480,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 12452 "parser_cocci_menhir.ml" +# 12484 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_initialize2 = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -12456,7 +12488,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_initialize_list_start = # 1042 "parser_cocci_menhir.mly" ( [_1;Ast0.wrap(Ast0.IComma(P.clt2mcode "," _2))] ) -# 12460 "parser_cocci_menhir.ml" +# 12492 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12488,7 +12520,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 12492 "parser_cocci_menhir.ml" +# 12524 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_initialize2 = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -12496,7 +12528,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_initialize_list_start = # 1044 "parser_cocci_menhir.mly" ( _1::Ast0.wrap(Ast0.IComma(P.clt2mcode "," _2))::_3 ) -# 12500 "parser_cocci_menhir.ml" +# 12532 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12527,7 +12559,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1047 "parser_cocci_menhir.mly" ( (P.mkidots "..." d):: (List.concat(List.map (function x -> x (P.mkidots "...")) r)) ) -# 12531 "parser_cocci_menhir.ml" +# 12563 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12549,7 +12581,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_invalid = # 1140 "parser_cocci_menhir.mly" ( raise (Semantic_cocci.Semantic "not matchable") ) -# 12553 "parser_cocci_menhir.ml" +# 12585 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12566,7 +12598,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_is_expression = # 239 "parser_cocci_menhir.mly" ( false ) -# 12570 "parser_cocci_menhir.ml" +# 12602 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12588,7 +12620,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_is_expression = # 240 "parser_cocci_menhir.mly" ( true ) -# 12592 "parser_cocci_menhir.ml" +# 12624 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12614,9 +12646,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos_t_ in let _v : 'tv_iso_ctype_ = -# 1752 "parser_cocci_menhir.mly" +# 1756 "parser_cocci_menhir.mly" ( Common.Left t ) -# 12620 "parser_cocci_menhir.ml" +# 12652 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12642,9 +12674,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos_t_ in let _v : 'tv_iso_ctype_ = -# 1753 "parser_cocci_menhir.mly" +# 1757 "parser_cocci_menhir.mly" ( Common.Right t ) -# 12648 "parser_cocci_menhir.ml" +# 12680 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12670,9 +12702,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos_t_ in let _v : 'tv_iso_decl_var_ = -# 1752 "parser_cocci_menhir.mly" +# 1756 "parser_cocci_menhir.mly" ( Common.Left t ) -# 12676 "parser_cocci_menhir.ml" +# 12708 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12698,9 +12730,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos_t_ in let _v : 'tv_iso_decl_var_ = -# 1753 "parser_cocci_menhir.mly" +# 1757 "parser_cocci_menhir.mly" ( Common.Right t ) -# 12704 "parser_cocci_menhir.ml" +# 12736 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12726,9 +12758,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos_t_ in let _v : 'tv_iso_dexpr_ = -# 1752 "parser_cocci_menhir.mly" +# 1756 "parser_cocci_menhir.mly" ( Common.Left t ) -# 12732 "parser_cocci_menhir.ml" +# 12764 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12754,9 +12786,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos_t_ in let _v : 'tv_iso_dexpr_ = -# 1753 "parser_cocci_menhir.mly" +# 1757 "parser_cocci_menhir.mly" ( Common.Right t ) -# 12760 "parser_cocci_menhir.ml" +# 12792 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12782,9 +12814,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos_t_ in let _v : 'tv_iso_nest_start_ = -# 1752 "parser_cocci_menhir.mly" +# 1756 "parser_cocci_menhir.mly" ( Common.Left t ) -# 12788 "parser_cocci_menhir.ml" +# 12820 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12810,9 +12842,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos_t_ in let _v : 'tv_iso_nest_start_ = -# 1753 "parser_cocci_menhir.mly" +# 1757 "parser_cocci_menhir.mly" ( Common.Right t ) -# 12816 "parser_cocci_menhir.ml" +# 12848 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12838,9 +12870,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos_t_ in let _v : 'tv_iso_single_statement_ = -# 1752 "parser_cocci_menhir.mly" +# 1756 "parser_cocci_menhir.mly" ( Common.Left t ) -# 12844 "parser_cocci_menhir.ml" +# 12876 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12866,9 +12898,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos_t_ in let _v : 'tv_iso_single_statement_ = -# 1753 "parser_cocci_menhir.mly" +# 1757 "parser_cocci_menhir.mly" ( Common.Right t ) -# 12872 "parser_cocci_menhir.ml" +# 12904 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12906,11 +12938,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 161 "parser_cocci_menhir.mly" (Ast0_cocci.anything list list) -# 12910 "parser_cocci_menhir.ml" +# 12942 "parser_cocci_menhir.ml" ) = -# 1724 "parser_cocci_menhir.mly" +# 1728 "parser_cocci_menhir.mly" ( P.iso_adjust (function x -> Ast0.ExprTag x) e1 el ) -# 12914 "parser_cocci_menhir.ml" +# 12946 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12948,11 +12980,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 161 "parser_cocci_menhir.mly" (Ast0_cocci.anything list list) -# 12952 "parser_cocci_menhir.ml" +# 12984 "parser_cocci_menhir.ml" ) = -# 1726 "parser_cocci_menhir.mly" +# 1730 "parser_cocci_menhir.mly" ( P.iso_adjust (function x -> Ast0.ArgExprTag x) e1 el ) -# 12956 "parser_cocci_menhir.ml" +# 12988 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -12990,11 +13022,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 161 "parser_cocci_menhir.mly" (Ast0_cocci.anything list list) -# 12994 "parser_cocci_menhir.ml" +# 13026 "parser_cocci_menhir.ml" ) = -# 1728 "parser_cocci_menhir.mly" +# 1732 "parser_cocci_menhir.mly" ( P.iso_adjust (function x -> Ast0.TestExprTag x) e1 el ) -# 12998 "parser_cocci_menhir.ml" +# 13030 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13032,11 +13064,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 161 "parser_cocci_menhir.mly" (Ast0_cocci.anything list list) -# 13036 "parser_cocci_menhir.ml" +# 13068 "parser_cocci_menhir.ml" ) = -# 1730 "parser_cocci_menhir.mly" +# 1734 "parser_cocci_menhir.mly" ( P.iso_adjust (function x -> Ast0.StmtTag x) s1 sl ) -# 13040 "parser_cocci_menhir.ml" +# 13072 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13074,11 +13106,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 161 "parser_cocci_menhir.mly" (Ast0_cocci.anything list list) -# 13078 "parser_cocci_menhir.ml" +# 13110 "parser_cocci_menhir.ml" ) = -# 1732 "parser_cocci_menhir.mly" +# 1736 "parser_cocci_menhir.mly" ( P.iso_adjust (function x -> Ast0.TypeCTag x) t1 tl ) -# 13082 "parser_cocci_menhir.ml" +# 13114 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13116,11 +13148,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 161 "parser_cocci_menhir.mly" (Ast0_cocci.anything list list) -# 13120 "parser_cocci_menhir.ml" +# 13152 "parser_cocci_menhir.ml" ) = -# 1734 "parser_cocci_menhir.mly" +# 1738 "parser_cocci_menhir.mly" ( P.iso_adjust (function x -> Ast0.DotsStmtTag x) e1 el ) -# 13124 "parser_cocci_menhir.ml" +# 13156 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13158,9 +13190,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 161 "parser_cocci_menhir.mly" (Ast0_cocci.anything list list) -# 13162 "parser_cocci_menhir.ml" +# 13194 "parser_cocci_menhir.ml" ) = -# 1736 "parser_cocci_menhir.mly" +# 1740 "parser_cocci_menhir.mly" ( let check_one = function [x] -> x | _ -> @@ -13175,7 +13207,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct | Common.Right x -> Common.Right(check_one x)) dl in P.iso_adjust (function x -> Ast0.DeclTag x) d1 dl ) -# 13179 "parser_cocci_menhir.ml" +# 13211 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13199,11 +13231,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 164 "parser_cocci_menhir.mly" ((Ast_cocci.metavar,Ast_cocci.metavar) Common.either list) -# 13203 "parser_cocci_menhir.ml" +# 13235 "parser_cocci_menhir.ml" ) = # 181 "parser_cocci_menhir.mly" ( m "" ) -# 13207 "parser_cocci_menhir.ml" +# 13239 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13231,11 +13263,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 148 "parser_cocci_menhir.mly" (Ast_cocci.rulename) -# 13235 "parser_cocci_menhir.ml" +# 13267 "parser_cocci_menhir.ml" ) = # 196 "parser_cocci_menhir.mly" ( P.make_iso_rule_name_result (P.id2name nm) ) -# 13239 "parser_cocci_menhir.ml" +# 13271 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13256,14 +13288,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 59 "parser_cocci_menhir.mly" (string * Data.clt) -# 13260 "parser_cocci_menhir.ml" +# 13292 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_iter_ident = # 1427 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Id(P.id2mcode _1)) ) -# 13267 "parser_cocci_menhir.ml" +# 13299 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13284,7 +13316,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 62 "parser_cocci_menhir.mly" (Parse_aux.idinfo) -# 13288 "parser_cocci_menhir.ml" +# 13320 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -13292,7 +13324,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1429 "parser_cocci_menhir.mly" ( let (nm,constraints,pure,clt) = _1 in Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) ) -# 13296 "parser_cocci_menhir.ml" +# 13328 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13309,7 +13341,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_TMul_ = # 114 "standard.mly" ( [] ) -# 13313 "parser_cocci_menhir.ml" +# 13345 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13336,14 +13368,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let x : ( # 98 "parser_cocci_menhir.mly" (Data.clt) -# 13340 "parser_cocci_menhir.ml" +# 13372 "parser_cocci_menhir.ml" ) = Obj.magic x in let _startpos = _startpos_x_ in let _endpos = _endpos_xs_ in let _v : 'tv_list_TMul_ = # 116 "standard.mly" ( x :: xs ) -# 13347 "parser_cocci_menhir.ml" +# 13379 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13360,7 +13392,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_array_dec_ = # 114 "standard.mly" ( [] ) -# 13364 "parser_cocci_menhir.ml" +# 13396 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13390,7 +13422,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_array_dec_ = # 116 "standard.mly" ( x :: xs ) -# 13394 "parser_cocci_menhir.ml" +# 13426 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13407,7 +13439,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_case_line_ = # 114 "standard.mly" ( [] ) -# 13411 "parser_cocci_menhir.ml" +# 13443 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13437,7 +13469,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_case_line_ = # 116 "standard.mly" ( x :: xs ) -# 13441 "parser_cocci_menhir.ml" +# 13473 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13454,7 +13486,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_comma_decls_TEllipsis_decl__ = # 114 "standard.mly" ( [] ) -# 13458 "parser_cocci_menhir.ml" +# 13490 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13484,7 +13516,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_comma_decls_TEllipsis_decl__ = # 116 "standard.mly" ( x :: xs ) -# 13488 "parser_cocci_menhir.ml" +# 13520 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13501,7 +13533,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_comma_decls_TEllipsis_name_opt_decl__ = # 114 "standard.mly" ( [] ) -# 13505 "parser_cocci_menhir.ml" +# 13537 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13531,7 +13563,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_comma_decls_TEllipsis_name_opt_decl__ = # 116 "standard.mly" ( x :: xs ) -# 13535 "parser_cocci_menhir.ml" +# 13567 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13548,7 +13580,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_dp_comma_args_TEllipsis__ = # 114 "standard.mly" ( [] ) -# 13552 "parser_cocci_menhir.ml" +# 13584 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13578,7 +13610,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_dp_comma_args_TEllipsis__ = # 116 "standard.mly" ( x :: xs ) -# 13582 "parser_cocci_menhir.ml" +# 13614 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13595,7 +13627,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_incl_ = # 114 "standard.mly" ( [] ) -# 13599 "parser_cocci_menhir.ml" +# 13631 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13625,7 +13657,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_incl_ = # 116 "standard.mly" ( x :: xs ) -# 13629 "parser_cocci_menhir.ml" +# 13661 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13642,7 +13674,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_iso_ctype__ = # 114 "standard.mly" ( [] ) -# 13646 "parser_cocci_menhir.ml" +# 13678 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13672,7 +13704,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_iso_ctype__ = # 116 "standard.mly" ( x :: xs ) -# 13676 "parser_cocci_menhir.ml" +# 13708 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13689,7 +13721,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_iso_decl_var__ = # 114 "standard.mly" ( [] ) -# 13693 "parser_cocci_menhir.ml" +# 13725 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13719,7 +13751,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_iso_decl_var__ = # 116 "standard.mly" ( x :: xs ) -# 13723 "parser_cocci_menhir.ml" +# 13755 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13736,7 +13768,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_iso_dexpr__ = # 114 "standard.mly" ( [] ) -# 13740 "parser_cocci_menhir.ml" +# 13772 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13766,7 +13798,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_iso_dexpr__ = # 116 "standard.mly" ( x :: xs ) -# 13770 "parser_cocci_menhir.ml" +# 13802 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13783,7 +13815,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_iso_nest_start__ = # 114 "standard.mly" ( [] ) -# 13787 "parser_cocci_menhir.ml" +# 13819 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13813,7 +13845,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_iso_nest_start__ = # 116 "standard.mly" ( x :: xs ) -# 13817 "parser_cocci_menhir.ml" +# 13849 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13830,7 +13862,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_iso_single_statement__ = # 114 "standard.mly" ( [] ) -# 13834 "parser_cocci_menhir.ml" +# 13866 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13860,7 +13892,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_iso_single_statement__ = # 116 "standard.mly" ( x :: xs ) -# 13864 "parser_cocci_menhir.ml" +# 13896 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13877,7 +13909,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_mzl_ctype__ = # 114 "standard.mly" ( [] ) -# 13881 "parser_cocci_menhir.ml" +# 13913 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13907,7 +13939,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_mzl_ctype__ = # 116 "standard.mly" ( x :: xs ) -# 13911 "parser_cocci_menhir.ml" +# 13943 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13924,7 +13956,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_mzl_eexpr__ = # 114 "standard.mly" ( [] ) -# 13928 "parser_cocci_menhir.ml" +# 13960 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13954,7 +13986,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_mzl_eexpr__ = # 116 "standard.mly" ( x :: xs ) -# 13958 "parser_cocci_menhir.ml" +# 13990 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -13971,7 +14003,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_mzl_fun_after_dots_or__ = # 114 "standard.mly" ( [] ) -# 13975 "parser_cocci_menhir.ml" +# 14007 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14001,7 +14033,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_mzl_fun_after_dots_or__ = # 116 "standard.mly" ( x :: xs ) -# 14005 "parser_cocci_menhir.ml" +# 14037 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14018,7 +14050,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_mzl_fun_start__ = # 114 "standard.mly" ( [] ) -# 14022 "parser_cocci_menhir.ml" +# 14054 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14048,7 +14080,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_mzl_fun_start__ = # 116 "standard.mly" ( x :: xs ) -# 14052 "parser_cocci_menhir.ml" +# 14084 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14065,7 +14097,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_mzl_rule_elem_statement__ = # 114 "standard.mly" ( [] ) -# 14069 "parser_cocci_menhir.ml" +# 14101 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14095,7 +14127,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_mzl_rule_elem_statement__ = # 116 "standard.mly" ( x :: xs ) -# 14099 "parser_cocci_menhir.ml" +# 14131 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14112,7 +14144,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_mzl_statement__ = # 114 "standard.mly" ( [] ) -# 14116 "parser_cocci_menhir.ml" +# 14148 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14142,7 +14174,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_mzl_statement__ = # 116 "standard.mly" ( x :: xs ) -# 14146 "parser_cocci_menhir.ml" +# 14178 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14159,7 +14191,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_pair_edots_when_TEllipsis_eexpr__dexpr__ = # 114 "standard.mly" ( [] ) -# 14163 "parser_cocci_menhir.ml" +# 14195 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14198,13 +14230,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 70 "standard.mly" ( (x, y) ) -# 14202 "parser_cocci_menhir.ml" +# 14234 "parser_cocci_menhir.ml" in # 116 "standard.mly" ( x :: xs ) -# 14208 "parser_cocci_menhir.ml" +# 14240 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14221,7 +14253,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_whenppdecs_ = # 114 "standard.mly" ( [] ) -# 14225 "parser_cocci_menhir.ml" +# 14257 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14251,7 +14283,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_list_whenppdecs_ = # 116 "standard.mly" ( x :: xs ) -# 14255 "parser_cocci_menhir.ml" +# 14287 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14268,7 +14300,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_loption_choose_iso_ = # 57 "standard.mly" ( [] ) -# 14272 "parser_cocci_menhir.ml" +# 14304 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14292,7 +14324,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_loption_choose_iso_ = # 59 "standard.mly" ( x ) -# 14296 "parser_cocci_menhir.ml" +# 14328 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14309,7 +14341,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_loption_disable_ = # 57 "standard.mly" ( [] ) -# 14313 "parser_cocci_menhir.ml" +# 14345 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14333,7 +14365,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_loption_disable_ = # 59 "standard.mly" ( x ) -# 14337 "parser_cocci_menhir.ml" +# 14369 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14350,7 +14382,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_loption_error_words_ = # 57 "standard.mly" ( [] ) -# 14354 "parser_cocci_menhir.ml" +# 14386 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14374,7 +14406,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_loption_error_words_ = # 59 "standard.mly" ( x ) -# 14378 "parser_cocci_menhir.ml" +# 14410 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14391,7 +14423,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_loption_filespec_ = # 57 "standard.mly" ( [] ) -# 14395 "parser_cocci_menhir.ml" +# 14427 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14415,7 +14447,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_loption_filespec_ = # 59 "standard.mly" ( x ) -# 14419 "parser_cocci_menhir.ml" +# 14451 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14432,7 +14464,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_loption_minus_start_ = # 57 "standard.mly" ( [] ) -# 14436 "parser_cocci_menhir.ml" +# 14468 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14456,7 +14488,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_loption_minus_start_ = # 59 "standard.mly" ( x ) -# 14460 "parser_cocci_menhir.ml" +# 14492 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14473,7 +14505,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_loption_not_ceq_ = # 57 "standard.mly" ( [] ) -# 14477 "parser_cocci_menhir.ml" +# 14509 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14497,7 +14529,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_loption_not_ceq_ = # 59 "standard.mly" ( x ) -# 14501 "parser_cocci_menhir.ml" +# 14533 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14514,7 +14546,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_loption_not_eq_ = # 57 "standard.mly" ( [] ) -# 14518 "parser_cocci_menhir.ml" +# 14550 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14538,7 +14570,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_loption_not_eq_ = # 59 "standard.mly" ( x ) -# 14542 "parser_cocci_menhir.ml" +# 14574 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14555,7 +14587,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_loption_not_eqe_ = # 57 "standard.mly" ( [] ) -# 14559 "parser_cocci_menhir.ml" +# 14591 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14579,7 +14611,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_loption_not_eqe_ = # 59 "standard.mly" ( x ) -# 14583 "parser_cocci_menhir.ml" +# 14615 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14596,7 +14628,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_loption_not_pos_ = # 57 "standard.mly" ( [] ) -# 14600 "parser_cocci_menhir.ml" +# 14632 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14620,7 +14652,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_loption_not_pos_ = # 59 "standard.mly" ( x ) -# 14624 "parser_cocci_menhir.ml" +# 14656 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14637,7 +14669,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_loption_plus_start_ = # 57 "standard.mly" ( [] ) -# 14641 "parser_cocci_menhir.ml" +# 14673 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14661,7 +14693,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_loption_plus_start_ = # 59 "standard.mly" ( x ) -# 14665 "parser_cocci_menhir.ml" +# 14697 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14685,7 +14717,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_meta_exp_type = # 429 "parser_cocci_menhir.mly" ( [Ast0_cocci.ast0_type_to_type t] ) -# 14689 "parser_cocci_menhir.ml" +# 14721 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14725,7 +14757,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( List.map (function x -> P.ty_pointerify (Ast0_cocci.ast0_type_to_type x) m) t ) -# 14729 "parser_cocci_menhir.ml" +# 14761 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14756,14 +14788,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 47 "parser_cocci_menhir.mly" (string) -# 14760 "parser_cocci_menhir.ml" +# 14792 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in let _v : 'tv_meta_ident = # 1325 "parser_cocci_menhir.mly" ( (Some _1,P.id2name _3) ) -# 14767 "parser_cocci_menhir.ml" +# 14799 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14787,11 +14819,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 156 "parser_cocci_menhir.mly" ((Ast_cocci.metavar,Ast_cocci.metavar) Common.either list) -# 14791 "parser_cocci_menhir.ml" +# 14823 "parser_cocci_menhir.ml" ) = # 180 "parser_cocci_menhir.mly" ( m (!Ast0.rule_name) ) -# 14795 "parser_cocci_menhir.ml" +# 14827 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14842,13 +14874,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( (fun arity name pure check_meta -> let tok = check_meta(Ast.MetaFreshIdDecl(arity,name)) in !Data.add_id_meta name [] pure; tok) ) -# 14846 "parser_cocci_menhir.ml" +# 14878 "parser_cocci_menhir.ml" in # 253 "parser_cocci_menhir.mly" ( P.create_metadec ar ispure kindfn ids ) -# 14852 "parser_cocci_menhir.ml" +# 14884 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14895,13 +14927,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( (fun arity name pure check_meta -> let tok = check_meta(Ast.MetaParamDecl(arity,name)) in !Data.add_param_meta name pure; tok) ) -# 14899 "parser_cocci_menhir.ml" +# 14931 "parser_cocci_menhir.ml" in # 253 "parser_cocci_menhir.mly" ( P.create_metadec ar ispure kindfn ids ) -# 14905 "parser_cocci_menhir.ml" +# 14937 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -14952,13 +14984,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( (fun arity name pure check_meta -> let tok = check_meta(Ast.MetaParamListDecl(arity,name,None)) in !Data.add_paramlist_meta name None pure; tok) ) -# 14956 "parser_cocci_menhir.ml" +# 14988 "parser_cocci_menhir.ml" in # 253 "parser_cocci_menhir.mly" ( P.create_metadec ar ispure kindfn ids ) -# 14962 "parser_cocci_menhir.ml" +# 14994 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -15009,13 +15041,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( (fun arity name pure check_meta -> let tok = check_meta(Ast.MetaExpListDecl(arity,name,None)) in !Data.add_explist_meta name None pure; tok) ) -# 15013 "parser_cocci_menhir.ml" +# 15045 "parser_cocci_menhir.ml" in # 253 "parser_cocci_menhir.mly" ( P.create_metadec ar ispure kindfn ids ) -# 15019 "parser_cocci_menhir.ml" +# 15051 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -15062,13 +15094,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( (fun arity name pure check_meta -> let tok = check_meta(Ast.MetaTypeDecl(arity,name)) in !Data.add_type_meta name pure; tok) ) -# 15066 "parser_cocci_menhir.ml" +# 15098 "parser_cocci_menhir.ml" in # 253 "parser_cocci_menhir.mly" ( P.create_metadec ar ispure kindfn ids ) -# 15072 "parser_cocci_menhir.ml" +# 15104 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -15115,13 +15147,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( (fun arity name pure check_meta -> let tok = check_meta(Ast.MetaStmDecl(arity,name)) in !Data.add_stm_meta name pure; tok) ) -# 15119 "parser_cocci_menhir.ml" +# 15151 "parser_cocci_menhir.ml" in # 253 "parser_cocci_menhir.mly" ( P.create_metadec ar ispure kindfn ids ) -# 15125 "parser_cocci_menhir.ml" +# 15157 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -15172,13 +15204,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( (fun arity name pure check_meta -> let tok = check_meta(Ast.MetaStmListDecl(arity,name)) in !Data.add_stmlist_meta name pure; tok) ) -# 15176 "parser_cocci_menhir.ml" +# 15208 "parser_cocci_menhir.ml" in # 253 "parser_cocci_menhir.mly" ( P.create_metadec ar ispure kindfn ids ) -# 15182 "parser_cocci_menhir.ml" +# 15214 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -15226,13 +15258,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct if arity = Ast.NONE && pure = Ast0.Impure then (!Data.add_type_name name; []) else raise (Semantic_cocci.Semantic "bad typedef")) ) -# 15230 "parser_cocci_menhir.ml" +# 15262 "parser_cocci_menhir.ml" in # 253 "parser_cocci_menhir.mly" ( P.create_metadec ar ispure kindfn ids ) -# 15236 "parser_cocci_menhir.ml" +# 15268 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -15284,13 +15316,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct if arity = Ast.NONE && pure = Ast0.Impure then (!Data.add_declarer_name name; []) else raise (Semantic_cocci.Semantic "bad declarer")) ) -# 15288 "parser_cocci_menhir.ml" +# 15320 "parser_cocci_menhir.ml" in # 253 "parser_cocci_menhir.mly" ( P.create_metadec ar ispure kindfn ids ) -# 15294 "parser_cocci_menhir.ml" +# 15326 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -15342,13 +15374,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct if arity = Ast.NONE && pure = Ast0.Impure then (!Data.add_iterator_name name; []) else raise (Semantic_cocci.Semantic "bad iterator")) ) -# 15346 "parser_cocci_menhir.ml" +# 15378 "parser_cocci_menhir.ml" in # 253 "parser_cocci_menhir.mly" ( P.create_metadec ar ispure kindfn ids ) -# 15352 "parser_cocci_menhir.ml" +# 15384 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -15395,13 +15427,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( (fun arity name pure check_meta constraints -> let tok = check_meta(Ast.MetaIdDecl(arity,name)) in !Data.add_id_meta name constraints pure; tok) ) -# 15399 "parser_cocci_menhir.ml" +# 15431 "parser_cocci_menhir.ml" in # 257 "parser_cocci_menhir.mly" ( P.create_metadec_ne ar ispure kindfn ids ) -# 15405 "parser_cocci_menhir.ml" +# 15437 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -15448,13 +15480,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( (fun arity name pure check_meta constraints -> let tok = check_meta(Ast.MetaFuncDecl(arity,name)) in !Data.add_func_meta name constraints pure; tok) ) -# 15452 "parser_cocci_menhir.ml" +# 15484 "parser_cocci_menhir.ml" in # 257 "parser_cocci_menhir.mly" ( P.create_metadec_ne ar ispure kindfn ids ) -# 15458 "parser_cocci_menhir.ml" +# 15490 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -15506,13 +15538,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let tok = check_meta(Ast.MetaLocalFuncDecl(arity,name)) in !Data.add_local_func_meta name constraints pure; tok) ) -# 15510 "parser_cocci_menhir.ml" +# 15542 "parser_cocci_menhir.ml" in # 257 "parser_cocci_menhir.mly" ( P.create_metadec_ne ar ispure kindfn ids ) -# 15516 "parser_cocci_menhir.ml" +# 15548 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -15559,13 +15591,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( (fun arity name pure check_meta constraints -> let tok = check_meta(Ast.MetaDeclarerDecl(arity,name)) in !Data.add_declarer_meta name constraints pure; tok) ) -# 15563 "parser_cocci_menhir.ml" +# 15595 "parser_cocci_menhir.ml" in # 257 "parser_cocci_menhir.mly" ( P.create_metadec_ne ar ispure kindfn ids ) -# 15569 "parser_cocci_menhir.ml" +# 15601 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -15612,13 +15644,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( (fun arity name pure check_meta constraints -> let tok = check_meta(Ast.MetaIteratorDecl(arity,name)) in !Data.add_iterator_meta name constraints pure; tok) ) -# 15616 "parser_cocci_menhir.ml" +# 15648 "parser_cocci_menhir.ml" in # 257 "parser_cocci_menhir.mly" ( P.create_metadec_ne ar ispure kindfn ids ) -# 15622 "parser_cocci_menhir.ml" +# 15654 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -15665,13 +15697,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( (fun arity name pure check_meta constraints -> let tok = check_meta(Ast.MetaErrDecl(arity,name)) in !Data.add_err_meta name constraints pure; tok) ) -# 15669 "parser_cocci_menhir.ml" +# 15701 "parser_cocci_menhir.ml" in # 261 "parser_cocci_menhir.mly" ( P.create_metadec_ne ar ispure kindfn ids ) -# 15675 "parser_cocci_menhir.ml" +# 15707 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -15724,7 +15756,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 15728 "parser_cocci_menhir.ml" +# 15760 "parser_cocci_menhir.ml" in @@ -15737,13 +15769,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct | Some _ -> !Data.add_local_idexp_meta ty name constraints pure; check_meta(Ast.MetaLocalIdExpDecl(arity,name,ty))) ) -# 15741 "parser_cocci_menhir.ml" +# 15773 "parser_cocci_menhir.ml" in # 261 "parser_cocci_menhir.mly" ( P.create_metadec_ne ar ispure kindfn ids ) -# 15747 "parser_cocci_menhir.ml" +# 15779 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -15804,7 +15836,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 15808 "parser_cocci_menhir.ml" +# 15840 "parser_cocci_menhir.ml" in @@ -15817,13 +15849,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct | Some _ -> !Data.add_local_idexp_meta ty name constraints pure; check_meta(Ast.MetaLocalIdExpDecl(arity,name,ty))) ) -# 15821 "parser_cocci_menhir.ml" +# 15853 "parser_cocci_menhir.ml" in # 261 "parser_cocci_menhir.mly" ( P.create_metadec_ne ar ispure kindfn ids ) -# 15827 "parser_cocci_menhir.ml" +# 15859 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -15890,13 +15922,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct | Some _ -> !Data.add_local_idexp_meta ty name constraints pure; check_meta(Ast.MetaLocalIdExpDecl(arity,name,ty))) ) -# 15894 "parser_cocci_menhir.ml" +# 15926 "parser_cocci_menhir.ml" in # 261 "parser_cocci_menhir.mly" ( P.create_metadec_ne ar ispure kindfn ids ) -# 15900 "parser_cocci_menhir.ml" +# 15932 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -15951,13 +15983,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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) ) -# 15955 "parser_cocci_menhir.ml" +# 15987 "parser_cocci_menhir.ml" in # 261 "parser_cocci_menhir.mly" ( P.create_metadec_ne ar ispure kindfn ids ) -# 15961 "parser_cocci_menhir.ml" +# 15993 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16016,13 +16048,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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) ) -# 16020 "parser_cocci_menhir.ml" +# 16052 "parser_cocci_menhir.ml" in # 261 "parser_cocci_menhir.mly" ( P.create_metadec_ne ar ispure kindfn ids ) -# 16026 "parser_cocci_menhir.ml" +# 16058 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16068,7 +16100,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 16072 "parser_cocci_menhir.ml" +# 16104 "parser_cocci_menhir.ml" in @@ -16076,13 +16108,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( (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) ) -# 16080 "parser_cocci_menhir.ml" +# 16112 "parser_cocci_menhir.ml" in # 261 "parser_cocci_menhir.mly" ( P.create_metadec_ne ar ispure kindfn ids ) -# 16086 "parser_cocci_menhir.ml" +# 16118 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16136,7 +16168,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 16140 "parser_cocci_menhir.ml" +# 16172 "parser_cocci_menhir.ml" in @@ -16144,13 +16176,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( (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) ) -# 16148 "parser_cocci_menhir.ml" +# 16180 "parser_cocci_menhir.ml" in # 261 "parser_cocci_menhir.mly" ( P.create_metadec_ne ar ispure kindfn ids ) -# 16154 "parser_cocci_menhir.ml" +# 16186 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16197,13 +16229,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( (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) ) -# 16201 "parser_cocci_menhir.ml" +# 16233 "parser_cocci_menhir.ml" in # 265 "parser_cocci_menhir.mly" ( P.create_metadec_ne ar ispure kindfn ids ) -# 16207 "parser_cocci_menhir.ml" +# 16239 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16269,13 +16301,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct constraints; let tok = check_meta(Ast.MetaExpDecl(arity,name,ty)) in !Data.add_exp_meta ty name constraints pure; tok) ) -# 16273 "parser_cocci_menhir.ml" +# 16305 "parser_cocci_menhir.ml" in # 265 "parser_cocci_menhir.mly" ( P.create_metadec_ne ar ispure kindfn ids ) -# 16279 "parser_cocci_menhir.ml" +# 16311 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16323,7 +16355,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct 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 ) -# 16327 "parser_cocci_menhir.ml" +# 16359 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16390,7 +16422,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct check_meta(Ast.MetaParamListDecl(arity,name,Some lenname)) in !Data.add_paramlist_meta name (Some lenname) pure; tok) id ids ) -# 16394 "parser_cocci_menhir.ml" +# 16426 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16457,7 +16489,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct check_meta(Ast.MetaExpListDecl(arity,name,Some lenname)) in !Data.add_explist_meta name (Some lenname) pure; tok) id ids ) -# 16461 "parser_cocci_menhir.ml" +# 16493 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16485,9 +16517,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos_a_ in let _endpos = _endpos_b_ in let _v : 'tv_midzero_list_ctype_ctype_ = -# 1692 "parser_cocci_menhir.mly" +# 1698 "parser_cocci_menhir.mly" ( let (mids,code) = List.split b in (mids,(a::code)) ) -# 16491 "parser_cocci_menhir.ml" +# 16523 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16515,9 +16547,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos_a_ in let _endpos = _endpos_b_ in let _v : 'tv_midzero_list_eexpr_eexpr_ = -# 1692 "parser_cocci_menhir.mly" +# 1698 "parser_cocci_menhir.mly" ( let (mids,code) = List.split b in (mids,(a::code)) ) -# 16521 "parser_cocci_menhir.ml" +# 16553 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16545,9 +16577,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos_a_ in let _endpos = _endpos_b_ in let _v : 'tv_midzero_list_expr_eexpr_ = -# 1692 "parser_cocci_menhir.mly" +# 1698 "parser_cocci_menhir.mly" ( let (mids,code) = List.split b in (mids,(a::code)) ) -# 16551 "parser_cocci_menhir.ml" +# 16583 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16575,9 +16607,9 @@ 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_ = -# 1692 "parser_cocci_menhir.mly" +# 1698 "parser_cocci_menhir.mly" ( let (mids,code) = List.split b in (mids,(a::code)) ) -# 16581 "parser_cocci_menhir.ml" +# 16613 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16605,9 +16637,9 @@ 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_ = -# 1692 "parser_cocci_menhir.mly" +# 1698 "parser_cocci_menhir.mly" ( let (mids,code) = List.split b in (mids,(a::code)) ) -# 16611 "parser_cocci_menhir.ml" +# 16643 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16635,9 +16667,9 @@ 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_ = -# 1692 "parser_cocci_menhir.mly" +# 1698 "parser_cocci_menhir.mly" ( let (mids,code) = List.split b in (mids,(a::code)) ) -# 16641 "parser_cocci_menhir.ml" +# 16673 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16665,9 +16697,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos_a_ in let _endpos = _endpos_b_ in let _v : 'tv_midzero_list_statement_statement_ = -# 1692 "parser_cocci_menhir.mly" +# 1698 "parser_cocci_menhir.mly" ( let (mids,code) = List.split b in (mids,(a::code)) ) -# 16671 "parser_cocci_menhir.ml" +# 16703 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16705,7 +16737,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( match f@b@ew with [] -> raise (Semantic_cocci.Semantic "minus slice can't be empty") | code -> Top_level.top_level code ) -# 16709 "parser_cocci_menhir.ml" +# 16741 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16743,7 +16775,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( match f@[b]@ew with [] -> raise (Semantic_cocci.Semantic "minus slice can't be empty") | code -> Top_level.top_level code ) -# 16747 "parser_cocci_menhir.ml" +# 16779 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16771,11 +16803,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 136 "parser_cocci_menhir.mly" (Ast0_cocci.rule) -# 16775 "parser_cocci_menhir.ml" +# 16807 "parser_cocci_menhir.ml" ) = # 176 "parser_cocci_menhir.mly" ( _1 ) -# 16779 "parser_cocci_menhir.ml" +# 16811 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16803,11 +16835,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 136 "parser_cocci_menhir.mly" (Ast0_cocci.rule) -# 16807 "parser_cocci_menhir.ml" +# 16839 "parser_cocci_menhir.ml" ) = # 176 "parser_cocci_menhir.mly" ( m ) -# 16811 "parser_cocci_menhir.ml" +# 16843 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16835,11 +16867,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 136 "parser_cocci_menhir.mly" (Ast0_cocci.rule) -# 16839 "parser_cocci_menhir.ml" +# 16871 "parser_cocci_menhir.ml" ) = # 177 "parser_cocci_menhir.mly" ( m ) -# 16843 "parser_cocci_menhir.ml" +# 16875 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16867,11 +16899,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 133 "parser_cocci_menhir.mly" (Ast0_cocci.rule) -# 16871 "parser_cocci_menhir.ml" +# 16903 "parser_cocci_menhir.ml" ) = # 172 "parser_cocci_menhir.mly" ( _1 ) -# 16875 "parser_cocci_menhir.ml" +# 16907 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16899,11 +16931,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 133 "parser_cocci_menhir.mly" (Ast0_cocci.rule) -# 16903 "parser_cocci_menhir.ml" +# 16935 "parser_cocci_menhir.ml" ) = # 172 "parser_cocci_menhir.mly" ( m ) -# 16907 "parser_cocci_menhir.ml" +# 16939 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16931,11 +16963,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 133 "parser_cocci_menhir.mly" (Ast0_cocci.rule) -# 16935 "parser_cocci_menhir.ml" +# 16967 "parser_cocci_menhir.ml" ) = # 173 "parser_cocci_menhir.mly" ( m ) -# 16939 "parser_cocci_menhir.ml" +# 16971 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16959,7 +16991,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_minus_start = # 1514 "parser_cocci_menhir.mly" ( [Ast0.wrap(Ast0.DECL(_1))] ) -# 16963 "parser_cocci_menhir.ml" +# 16995 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -16983,7 +17015,31 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_minus_start = # 1515 "parser_cocci_menhir.mly" ( [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Ty(_1))))] ) -# 16987 "parser_cocci_menhir.ml" +# 17019 "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 = _1; + MenhirLib.EngineTypes.startp = _startpos__1_; + MenhirLib.EngineTypes.endp = _endpos__1_; + MenhirLib.EngineTypes.next = _menhir_stack; + } = _menhir_stack in + let _1 : 'tv_top_init = Obj.magic _1 in + let _startpos = _startpos__1_ in + let _endpos = _endpos__1_ in + let _v : 'tv_minus_start = +# 1516 "parser_cocci_menhir.mly" + ( [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.TopInit(_1))))] ) +# 17043 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17005,9 +17061,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_minus_start = -# 1517 "parser_cocci_menhir.mly" +# 1518 "parser_cocci_menhir.mly" ( List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) _1 ) -# 17011 "parser_cocci_menhir.ml" +# 17067 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17034,14 +17090,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let a : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 17038 "parser_cocci_menhir.ml" +# 17094 "parser_cocci_menhir.ml" ) = Obj.magic a in let _startpos = _startpos_a_ in let _endpos = _endpos_b_ in let _v : 'tv_mzl_ctype_ = -# 1695 "parser_cocci_menhir.mly" +# 1701 "parser_cocci_menhir.mly" ( (P.clt2mcode "|" a, b) ) -# 17045 "parser_cocci_menhir.ml" +# 17101 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17068,14 +17124,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let a : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 17072 "parser_cocci_menhir.ml" +# 17128 "parser_cocci_menhir.ml" ) = Obj.magic a in let _startpos = _startpos_a_ in let _endpos = _endpos_b_ in let _v : 'tv_mzl_eexpr_ = -# 1695 "parser_cocci_menhir.mly" +# 1701 "parser_cocci_menhir.mly" ( (P.clt2mcode "|" a, b) ) -# 17079 "parser_cocci_menhir.ml" +# 17135 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17102,14 +17158,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let a : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 17106 "parser_cocci_menhir.ml" +# 17162 "parser_cocci_menhir.ml" ) = Obj.magic a in let _startpos = _startpos_a_ in let _endpos = _endpos_b_ in let _v : 'tv_mzl_fun_after_dots_or_ = -# 1695 "parser_cocci_menhir.mly" +# 1701 "parser_cocci_menhir.mly" ( (P.clt2mcode "|" a, b) ) -# 17113 "parser_cocci_menhir.ml" +# 17169 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17136,14 +17192,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let a : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 17140 "parser_cocci_menhir.ml" +# 17196 "parser_cocci_menhir.ml" ) = Obj.magic a in let _startpos = _startpos_a_ in let _endpos = _endpos_b_ in let _v : 'tv_mzl_fun_start_ = -# 1695 "parser_cocci_menhir.mly" +# 1701 "parser_cocci_menhir.mly" ( (P.clt2mcode "|" a, b) ) -# 17147 "parser_cocci_menhir.ml" +# 17203 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17170,14 +17226,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let a : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 17174 "parser_cocci_menhir.ml" +# 17230 "parser_cocci_menhir.ml" ) = Obj.magic a in let _startpos = _startpos_a_ in let _endpos = _endpos_b_ in let _v : 'tv_mzl_rule_elem_statement_ = -# 1695 "parser_cocci_menhir.mly" +# 1701 "parser_cocci_menhir.mly" ( (P.clt2mcode "|" a, b) ) -# 17181 "parser_cocci_menhir.ml" +# 17237 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17204,14 +17260,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let a : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 17208 "parser_cocci_menhir.ml" +# 17264 "parser_cocci_menhir.ml" ) = Obj.magic a in let _startpos = _startpos_a_ in let _endpos = _endpos_b_ in let _v : 'tv_mzl_statement_ = -# 1695 "parser_cocci_menhir.mly" +# 1701 "parser_cocci_menhir.mly" ( (P.clt2mcode "|" a, b) ) -# 17215 "parser_cocci_menhir.ml" +# 17271 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17235,7 +17291,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_name_opt_decl = # 785 "parser_cocci_menhir.mly" ( _1 ) -# 17239 "parser_cocci_menhir.ml" +# 17295 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17259,7 +17315,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_name_opt_decl = # 786 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Param(t, None)) ) -# 17263 "parser_cocci_menhir.ml" +# 17319 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17310,28 +17366,28 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let rp1 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 17314 "parser_cocci_menhir.ml" +# 17370 "parser_cocci_menhir.ml" ) = Obj.magic rp1 in let d : 'tv_decl_list_name_opt_decl_ = Obj.magic d in let lp1 : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 17320 "parser_cocci_menhir.ml" +# 17376 "parser_cocci_menhir.ml" ) = Obj.magic lp1 in let rp : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 17325 "parser_cocci_menhir.ml" +# 17381 "parser_cocci_menhir.ml" ) = Obj.magic rp in let s : ( # 98 "parser_cocci_menhir.mly" (Data.clt) -# 17330 "parser_cocci_menhir.ml" +# 17386 "parser_cocci_menhir.ml" ) = Obj.magic s in let lp : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 17335 "parser_cocci_menhir.ml" +# 17391 "parser_cocci_menhir.ml" ) = Obj.magic lp in let t : 'tv_fn_ctype = Obj.magic t in let _startpos = _startpos_t_ in @@ -17344,7 +17400,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (t,P.clt2mcode "(" lp,P.clt2mcode "*" s,P.clt2mcode ")" rp, P.clt2mcode "(" lp1,d,P.clt2mcode ")" rp1)) in Ast0.wrap(Ast0.Param(fnptr, None)) ) -# 17348 "parser_cocci_menhir.ml" +# 17404 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17372,9 +17428,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_nest_after_dots = -# 1616 "parser_cocci_menhir.mly" +# 1622 "parser_cocci_menhir.mly" (_1@_2) -# 17378 "parser_cocci_menhir.ml" +# 17434 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17400,9 +17456,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_nest_after_dots = -# 1617 "parser_cocci_menhir.mly" +# 1623 "parser_cocci_menhir.mly" (_2) -# 17406 "parser_cocci_menhir.ml" +# 17462 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17430,9 +17486,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_nest_after_dots = -# 1618 "parser_cocci_menhir.mly" +# 1624 "parser_cocci_menhir.mly" ((Ast0.wrap(Ast0.Exp(_1)))::_2) -# 17436 "parser_cocci_menhir.ml" +# 17492 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17447,9 +17503,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_nest_after_exp = -# 1626 "parser_cocci_menhir.mly" +# 1632 "parser_cocci_menhir.mly" ([]) -# 17453 "parser_cocci_menhir.ml" +# 17509 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17477,9 +17533,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_nest_after_exp = -# 1627 "parser_cocci_menhir.mly" +# 1633 "parser_cocci_menhir.mly" (_1::_2) -# 17483 "parser_cocci_menhir.ml" +# 17539 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17494,9 +17550,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_nest_after_stm = -# 1621 "parser_cocci_menhir.mly" +# 1627 "parser_cocci_menhir.mly" ([]) -# 17500 "parser_cocci_menhir.ml" +# 17556 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17524,9 +17580,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_nest_after_stm = -# 1622 "parser_cocci_menhir.mly" +# 1628 "parser_cocci_menhir.mly" (_1::_2) -# 17530 "parser_cocci_menhir.ml" +# 17586 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17554,9 +17610,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_nest_after_stm = -# 1623 "parser_cocci_menhir.mly" +# 1629 "parser_cocci_menhir.mly" (_1@_2) -# 17560 "parser_cocci_menhir.ml" +# 17616 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17592,14 +17648,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let c : ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 17596 "parser_cocci_menhir.ml" +# 17652 "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) -# 17603 "parser_cocci_menhir.ml" +# 17659 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos_c_ in @@ -17608,7 +17664,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( Ast0.wrap(Ast0.NestExpr(P.clt2mcode "<..." _1, Ast0.wrap(Ast0.DOTS(e (P.mkedots "..."))), P.clt2mcode "...>" c, w, false)) ) -# 17612 "parser_cocci_menhir.ml" +# 17668 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17644,14 +17700,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let c : ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 17648 "parser_cocci_menhir.ml" +# 17704 "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) -# 17655 "parser_cocci_menhir.ml" +# 17711 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos_c_ in @@ -17660,7 +17716,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( Ast0.wrap(Ast0.NestExpr(P.clt2mcode "<+..." _1, Ast0.wrap(Ast0.DOTS(e (P.mkedots "..."))), P.clt2mcode "...+>" c, w, true)) ) -# 17664 "parser_cocci_menhir.ml" +# 17720 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17682,9 +17738,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_nest_start = -# 1613 "parser_cocci_menhir.mly" +# 1619 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.DOTS(_1)) ) -# 17688 "parser_cocci_menhir.ml" +# 17744 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17706,11 +17762,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 167 "parser_cocci_menhir.mly" (unit) -# 17710 "parser_cocci_menhir.ml" +# 17766 "parser_cocci_menhir.ml" ) = -# 1760 "parser_cocci_menhir.mly" +# 1764 "parser_cocci_menhir.mly" ( () ) -# 17714 "parser_cocci_menhir.ml" +# 17770 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17736,11 +17792,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 167 "parser_cocci_menhir.mly" (unit) -# 17740 "parser_cocci_menhir.ml" +# 17796 "parser_cocci_menhir.ml" ) = -# 1761 "parser_cocci_menhir.mly" +# 1765 "parser_cocci_menhir.mly" ( () ) -# 17744 "parser_cocci_menhir.ml" +# 17800 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17762,11 +17818,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 167 "parser_cocci_menhir.mly" (unit) -# 17766 "parser_cocci_menhir.ml" +# 17822 "parser_cocci_menhir.ml" ) = -# 1762 "parser_cocci_menhir.mly" +# 1766 "parser_cocci_menhir.mly" ( () ) -# 17770 "parser_cocci_menhir.ml" +# 17826 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17797,7 +17853,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1316 "parser_cocci_menhir.mly" ( function dot_builder -> g :: (List.concat(List.map (function (d,g) -> [dot_builder d;g]) dg)) ) -# 17801 "parser_cocci_menhir.ml" +# 17857 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17818,14 +17874,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let x : ( # 98 "parser_cocci_menhir.mly" (Data.clt) -# 17822 "parser_cocci_menhir.ml" +# 17878 "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 ] ) -# 17829 "parser_cocci_menhir.ml" +# 17885 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17852,14 +17908,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let x : ( # 98 "parser_cocci_menhir.mly" (Data.clt) -# 17856 "parser_cocci_menhir.ml" +# 17912 "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 ) -# 17863 "parser_cocci_menhir.ml" +# 17919 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17889,7 +17945,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( (if !Data.in_iso then failwith "constraints not allowed in iso file"); [i] ) -# 17893 "parser_cocci_menhir.ml" +# 17949 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17927,7 +17983,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( (if !Data.in_iso then failwith "constraints not allowed in iso file"); l ) -# 17931 "parser_cocci_menhir.ml" +# 17987 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17957,7 +18013,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( (if !Data.in_iso then failwith "constraints not allowed in iso file"); [Ast0.wrap(Ast0.Id(P.id2mcode i))] ) -# 17961 "parser_cocci_menhir.ml" +# 18017 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -17995,7 +18051,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( (if !Data.in_iso then failwith "constraints not allowed in iso file"); List.map (function i -> Ast0.wrap(Ast0.Id(P.id2mcode i))) l ) -# 17999 "parser_cocci_menhir.ml" +# 18055 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -18025,7 +18081,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( (if !Data.in_iso then failwith "constraints not allowed in iso file"); [Ast0.wrap(Ast0.Ident(Ast0.wrap(Ast0.Id(P.id2mcode i))))] ) -# 18029 "parser_cocci_menhir.ml" +# 18085 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -18066,7 +18122,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct (function i -> Ast0.wrap(Ast0.Ident(Ast0.wrap(Ast0.Id(P.id2mcode i))))) l ) -# 18070 "parser_cocci_menhir.ml" +# 18126 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -18101,7 +18157,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let i = (rule,name) in P.check_meta(Ast.MetaPosDecl(Ast.NONE,i)); [i] ) -# 18105 "parser_cocci_menhir.ml" +# 18161 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -18147,7 +18203,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct P.check_meta(Ast.MetaPosDecl(Ast.NONE,i)); i) l ) -# 18151 "parser_cocci_menhir.ml" +# 18207 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -18171,7 +18227,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_one_dec_decl_ = # 1458 "parser_cocci_menhir.mly" ( _1 ) -# 18175 "parser_cocci_menhir.ml" +# 18231 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -18192,7 +18248,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 65 "parser_cocci_menhir.mly" (Parse_aux.list_info) -# 18196 "parser_cocci_menhir.ml" +# 18252 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -18205,7 +18261,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct Some nm -> Some(P.clt2mcode nm clt) | None -> None in Ast0.wrap(Ast0.MetaParamList(nm,lenname,pure)) ) -# 18209 "parser_cocci_menhir.ml" +# 18265 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -18229,7 +18285,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_one_dec_name_opt_decl_ = # 1458 "parser_cocci_menhir.mly" ( _1 ) -# 18233 "parser_cocci_menhir.ml" +# 18289 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -18250,7 +18306,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 65 "parser_cocci_menhir.mly" (Parse_aux.list_info) -# 18254 "parser_cocci_menhir.ml" +# 18310 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -18263,7 +18319,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct Some nm -> Some(P.clt2mcode nm clt) | None -> None in Ast0.wrap(Ast0.MetaParamList(nm,lenname,pure)) ) -# 18267 "parser_cocci_menhir.ml" +# 18323 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -18289,7 +18345,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 18293 "parser_cocci_menhir.ml" +# 18349 "parser_cocci_menhir.ml" ) = Obj.magic pv in let t : 'tv_ctype = Obj.magic t in let _startpos = _startpos_t_ in @@ -18297,7 +18353,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)) ) -# 18301 "parser_cocci_menhir.ml" +# 18357 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -18328,7 +18384,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 18332 "parser_cocci_menhir.ml" +# 18388 "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 @@ -18338,14 +18394,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 18342 "parser_cocci_menhir.ml" +# 18398 "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)) ) -# 18349 "parser_cocci_menhir.ml" +# 18405 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -18381,7 +18437,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 18385 "parser_cocci_menhir.ml" +# 18441 "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 @@ -18393,14 +18449,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 18397 "parser_cocci_menhir.ml" +# 18453 "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)) ) -# 18404 "parser_cocci_menhir.ml" +# 18460 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -18424,7 +18480,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_one_decl_var = # 948 "parser_cocci_menhir.mly" ( f ) -# 18428 "parser_cocci_menhir.ml" +# 18484 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -18465,13 +18521,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 18469 "parser_cocci_menhir.ml" +# 18525 "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) -# 18475 "parser_cocci_menhir.ml" +# 18531 "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 @@ -18481,14 +18537,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 18485 "parser_cocci_menhir.ml" +# 18541 "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)) ) -# 18492 "parser_cocci_menhir.ml" +# 18548 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -18534,13 +18590,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 18538 "parser_cocci_menhir.ml" +# 18594 "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) -# 18544 "parser_cocci_menhir.ml" +# 18600 "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 @@ -18552,14 +18608,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 18556 "parser_cocci_menhir.ml" +# 18612 "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)) ) -# 18563 "parser_cocci_menhir.ml" +# 18619 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -18590,7 +18646,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 18594 "parser_cocci_menhir.ml" +# 18650 "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 @@ -18600,14 +18656,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 18604 "parser_cocci_menhir.ml" +# 18660 "parser_cocci_menhir.ml" in let s = # 39 "standard.mly" ( None ) -# 18611 "parser_cocci_menhir.ml" +# 18667 "parser_cocci_menhir.ml" in @@ -18615,7 +18671,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)) ) -# 18619 "parser_cocci_menhir.ml" +# 18675 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -18651,7 +18707,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 18655 "parser_cocci_menhir.ml" +# 18711 "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 @@ -18663,14 +18719,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 18667 "parser_cocci_menhir.ml" +# 18723 "parser_cocci_menhir.ml" in let s = # 39 "standard.mly" ( None ) -# 18674 "parser_cocci_menhir.ml" +# 18730 "parser_cocci_menhir.ml" in @@ -18678,7 +18734,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)) ) -# 18682 "parser_cocci_menhir.ml" +# 18738 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -18714,7 +18770,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 18718 "parser_cocci_menhir.ml" +# 18774 "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 @@ -18725,7 +18781,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 18729 "parser_cocci_menhir.ml" +# 18785 "parser_cocci_menhir.ml" in let s = @@ -18733,7 +18789,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 18737 "parser_cocci_menhir.ml" +# 18793 "parser_cocci_menhir.ml" in @@ -18741,7 +18797,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)) ) -# 18745 "parser_cocci_menhir.ml" +# 18801 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -18782,7 +18838,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 18786 "parser_cocci_menhir.ml" +# 18842 "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 @@ -18795,7 +18851,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 18799 "parser_cocci_menhir.ml" +# 18855 "parser_cocci_menhir.ml" in let s = @@ -18803,7 +18859,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 18807 "parser_cocci_menhir.ml" +# 18863 "parser_cocci_menhir.ml" in @@ -18811,7 +18867,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)) ) -# 18815 "parser_cocci_menhir.ml" +# 18871 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -18852,13 +18908,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 18856 "parser_cocci_menhir.ml" +# 18912 "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) -# 18862 "parser_cocci_menhir.ml" +# 18918 "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 @@ -18868,14 +18924,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 18872 "parser_cocci_menhir.ml" +# 18928 "parser_cocci_menhir.ml" in let s = # 39 "standard.mly" ( None ) -# 18879 "parser_cocci_menhir.ml" +# 18935 "parser_cocci_menhir.ml" in @@ -18885,7 +18941,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)) ) -# 18889 "parser_cocci_menhir.ml" +# 18945 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -18931,13 +18987,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 18935 "parser_cocci_menhir.ml" +# 18991 "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) -# 18941 "parser_cocci_menhir.ml" +# 18997 "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 @@ -18949,14 +19005,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 18953 "parser_cocci_menhir.ml" +# 19009 "parser_cocci_menhir.ml" in let s = # 39 "standard.mly" ( None ) -# 18960 "parser_cocci_menhir.ml" +# 19016 "parser_cocci_menhir.ml" in @@ -18966,7 +19022,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)) ) -# 18970 "parser_cocci_menhir.ml" +# 19026 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -19012,13 +19068,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 19016 "parser_cocci_menhir.ml" +# 19072 "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) -# 19022 "parser_cocci_menhir.ml" +# 19078 "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 @@ -19029,7 +19085,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 19033 "parser_cocci_menhir.ml" +# 19089 "parser_cocci_menhir.ml" in let s = @@ -19037,7 +19093,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 19041 "parser_cocci_menhir.ml" +# 19097 "parser_cocci_menhir.ml" in @@ -19047,7 +19103,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)) ) -# 19051 "parser_cocci_menhir.ml" +# 19107 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -19098,13 +19154,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 19102 "parser_cocci_menhir.ml" +# 19158 "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) -# 19108 "parser_cocci_menhir.ml" +# 19164 "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 @@ -19117,7 +19173,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 19121 "parser_cocci_menhir.ml" +# 19177 "parser_cocci_menhir.ml" in let s = @@ -19125,7 +19181,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 19129 "parser_cocci_menhir.ml" +# 19185 "parser_cocci_menhir.ml" in @@ -19135,7 +19191,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)) ) -# 19139 "parser_cocci_menhir.ml" +# 19195 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -19196,34 +19252,34 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 19200 "parser_cocci_menhir.ml" +# 19256 "parser_cocci_menhir.ml" ) = Obj.magic pv in let rp2 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 19205 "parser_cocci_menhir.ml" +# 19261 "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) -# 19211 "parser_cocci_menhir.ml" +# 19267 "parser_cocci_menhir.ml" ) = Obj.magic lp2 in let rp1 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 19216 "parser_cocci_menhir.ml" +# 19272 "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) -# 19222 "parser_cocci_menhir.ml" +# 19278 "parser_cocci_menhir.ml" ) = Obj.magic st in let lp1 : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 19227 "parser_cocci_menhir.ml" +# 19283 "parser_cocci_menhir.ml" ) = Obj.magic lp1 in let t : 'tv_fn_ctype = Obj.magic t in let _startpos = _startpos_t_ in @@ -19232,7 +19288,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 19236 "parser_cocci_menhir.ml" +# 19292 "parser_cocci_menhir.ml" in @@ -19244,7 +19300,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)) ) -# 19248 "parser_cocci_menhir.ml" +# 19304 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -19310,34 +19366,34 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 19314 "parser_cocci_menhir.ml" +# 19370 "parser_cocci_menhir.ml" ) = Obj.magic pv in let rp2 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 19319 "parser_cocci_menhir.ml" +# 19375 "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) -# 19325 "parser_cocci_menhir.ml" +# 19381 "parser_cocci_menhir.ml" ) = Obj.magic lp2 in let rp1 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 19330 "parser_cocci_menhir.ml" +# 19386 "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) -# 19336 "parser_cocci_menhir.ml" +# 19392 "parser_cocci_menhir.ml" ) = Obj.magic st in let lp1 : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 19341 "parser_cocci_menhir.ml" +# 19397 "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 @@ -19348,7 +19404,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 19352 "parser_cocci_menhir.ml" +# 19408 "parser_cocci_menhir.ml" in @@ -19360,7 +19416,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)) ) -# 19364 "parser_cocci_menhir.ml" +# 19420 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -19401,18 +19457,18 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _5 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 19405 "parser_cocci_menhir.ml" +# 19461 "parser_cocci_menhir.ml" ) = Obj.magic _5 in let _4 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 19410 "parser_cocci_menhir.ml" +# 19466 "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) -# 19416 "parser_cocci_menhir.ml" +# 19472 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_decl_ident = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -19421,7 +19477,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)) ) -# 19425 "parser_cocci_menhir.ml" +# 19481 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -19492,40 +19548,40 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 19496 "parser_cocci_menhir.ml" +# 19552 "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) -# 19502 "parser_cocci_menhir.ml" +# 19558 "parser_cocci_menhir.ml" ) = Obj.magic q in let rp2 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 19507 "parser_cocci_menhir.ml" +# 19563 "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) -# 19513 "parser_cocci_menhir.ml" +# 19569 "parser_cocci_menhir.ml" ) = Obj.magic lp2 in let rp1 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 19518 "parser_cocci_menhir.ml" +# 19574 "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) -# 19524 "parser_cocci_menhir.ml" +# 19580 "parser_cocci_menhir.ml" ) = Obj.magic st in let lp1 : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 19529 "parser_cocci_menhir.ml" +# 19585 "parser_cocci_menhir.ml" ) = Obj.magic lp1 in let t : 'tv_fn_ctype = Obj.magic t in let _startpos = _startpos_t_ in @@ -19534,7 +19590,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 19538 "parser_cocci_menhir.ml" +# 19594 "parser_cocci_menhir.ml" in @@ -19546,7 +19602,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))) -# 19550 "parser_cocci_menhir.ml" +# 19606 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -19622,40 +19678,40 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 19626 "parser_cocci_menhir.ml" +# 19682 "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) -# 19632 "parser_cocci_menhir.ml" +# 19688 "parser_cocci_menhir.ml" ) = Obj.magic q in let rp2 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 19637 "parser_cocci_menhir.ml" +# 19693 "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) -# 19643 "parser_cocci_menhir.ml" +# 19699 "parser_cocci_menhir.ml" ) = Obj.magic lp2 in let rp1 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 19648 "parser_cocci_menhir.ml" +# 19704 "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) -# 19654 "parser_cocci_menhir.ml" +# 19710 "parser_cocci_menhir.ml" ) = Obj.magic st in let lp1 : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 19659 "parser_cocci_menhir.ml" +# 19715 "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 @@ -19666,7 +19722,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 19670 "parser_cocci_menhir.ml" +# 19726 "parser_cocci_menhir.ml" in @@ -19678,7 +19734,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))) -# 19682 "parser_cocci_menhir.ml" +# 19738 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -19695,7 +19751,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_option_TLocal_ = # 29 "standard.mly" ( None ) -# 19699 "parser_cocci_menhir.ml" +# 19755 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -19719,7 +19775,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_option_TLocal_ = # 31 "standard.mly" ( Some x ) -# 19723 "parser_cocci_menhir.ml" +# 19779 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -19736,7 +19792,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_option_TPosAny_ = # 29 "standard.mly" ( None ) -# 19740 "parser_cocci_menhir.ml" +# 19796 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -19760,7 +19816,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_option_TPosAny_ = # 31 "standard.mly" ( Some x ) -# 19764 "parser_cocci_menhir.ml" +# 19820 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -19777,7 +19833,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_option_eexpr_ = # 29 "standard.mly" ( None ) -# 19781 "parser_cocci_menhir.ml" +# 19837 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -19801,7 +19857,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_option_eexpr_ = # 31 "standard.mly" ( Some x ) -# 19805 "parser_cocci_menhir.ml" +# 19861 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -19818,7 +19874,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_option_whenexp_ = # 29 "standard.mly" ( None ) -# 19822 "parser_cocci_menhir.ml" +# 19878 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -19842,7 +19898,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_option_whenexp_ = # 31 "standard.mly" ( Some x ) -# 19846 "parser_cocci_menhir.ml" +# 19902 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -19857,9 +19913,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 = -# 1563 "parser_cocci_menhir.mly" +# 1569 "parser_cocci_menhir.mly" ([]) -# 19863 "parser_cocci_menhir.ml" +# 19919 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -19885,9 +19941,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_plus_after_dots = -# 1564 "parser_cocci_menhir.mly" +# 1570 "parser_cocci_menhir.mly" (_2) -# 19891 "parser_cocci_menhir.ml" +# 19947 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -19915,9 +19971,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_plus_after_dots = -# 1566 "parser_cocci_menhir.mly" +# 1572 "parser_cocci_menhir.mly" ( (Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Exp(_1)))))::_2 ) -# 19921 "parser_cocci_menhir.ml" +# 19977 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -19945,9 +20001,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_plus_after_dots = -# 1567 "parser_cocci_menhir.mly" +# 1573 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.DECL(_1))::_2 ) -# 19951 "parser_cocci_menhir.ml" +# 20007 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -19975,9 +20031,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_plus_after_dots = -# 1569 "parser_cocci_menhir.mly" +# 1575 "parser_cocci_menhir.mly" ( (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) _1)@_2 ) -# 19981 "parser_cocci_menhir.ml" +# 20037 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -19992,9 +20048,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 = -# 1559 "parser_cocci_menhir.mly" +# 1565 "parser_cocci_menhir.mly" ([]) -# 19998 "parser_cocci_menhir.ml" +# 20054 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20022,9 +20078,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_plus_after_exp = -# 1560 "parser_cocci_menhir.mly" +# 1566 "parser_cocci_menhir.mly" ( (Ast0.wrap(Ast0.OTHER(_1)))::_2 ) -# 20028 "parser_cocci_menhir.ml" +# 20084 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20039,9 +20095,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 = -# 1572 "parser_cocci_menhir.mly" +# 1578 "parser_cocci_menhir.mly" ([]) -# 20045 "parser_cocci_menhir.ml" +# 20101 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20069,9 +20125,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_plus_after_stm = -# 1573 "parser_cocci_menhir.mly" +# 1579 "parser_cocci_menhir.mly" ( (Ast0.wrap(Ast0.OTHER(_1)))::_2 ) -# 20075 "parser_cocci_menhir.ml" +# 20131 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20099,9 +20155,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_plus_after_stm = -# 1574 "parser_cocci_menhir.mly" +# 1580 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.DECL(_1))::_2 ) -# 20105 "parser_cocci_menhir.ml" +# 20161 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20129,9 +20185,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_plus_after_stm = -# 1576 "parser_cocci_menhir.mly" +# 1582 "parser_cocci_menhir.mly" ( (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) _1)@_2 ) -# 20135 "parser_cocci_menhir.ml" +# 20191 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20167,7 +20223,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_plus_body = # 562 "parser_cocci_menhir.mly" ( Top_level.top_level (f@b@ew) ) -# 20171 "parser_cocci_menhir.ml" +# 20227 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20203,7 +20259,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) ) -# 20207 "parser_cocci_menhir.ml" +# 20263 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20231,11 +20287,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 142 "parser_cocci_menhir.mly" (Ast0_cocci.rule) -# 20235 "parser_cocci_menhir.ml" +# 20291 "parser_cocci_menhir.ml" ) = # 178 "parser_cocci_menhir.mly" ( _1 ) -# 20239 "parser_cocci_menhir.ml" +# 20295 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20263,11 +20319,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 142 "parser_cocci_menhir.mly" (Ast0_cocci.rule) -# 20267 "parser_cocci_menhir.ml" +# 20323 "parser_cocci_menhir.ml" ) = # 178 "parser_cocci_menhir.mly" ( p ) -# 20271 "parser_cocci_menhir.ml" +# 20327 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20295,11 +20351,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 142 "parser_cocci_menhir.mly" (Ast0_cocci.rule) -# 20299 "parser_cocci_menhir.ml" +# 20355 "parser_cocci_menhir.ml" ) = # 179 "parser_cocci_menhir.mly" ( p ) -# 20303 "parser_cocci_menhir.ml" +# 20359 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20327,11 +20383,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 139 "parser_cocci_menhir.mly" (Ast0_cocci.rule) -# 20331 "parser_cocci_menhir.ml" +# 20387 "parser_cocci_menhir.ml" ) = # 174 "parser_cocci_menhir.mly" ( _1 ) -# 20335 "parser_cocci_menhir.ml" +# 20391 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20359,11 +20415,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 139 "parser_cocci_menhir.mly" (Ast0_cocci.rule) -# 20363 "parser_cocci_menhir.ml" +# 20419 "parser_cocci_menhir.ml" ) = # 174 "parser_cocci_menhir.mly" ( p ) -# 20367 "parser_cocci_menhir.ml" +# 20423 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20391,11 +20447,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 139 "parser_cocci_menhir.mly" (Ast0_cocci.rule) -# 20395 "parser_cocci_menhir.ml" +# 20451 "parser_cocci_menhir.ml" ) = # 175 "parser_cocci_menhir.mly" ( p ) -# 20399 "parser_cocci_menhir.ml" +# 20455 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20417,9 +20473,33 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in let _v : 'tv_plus_start = -# 1549 "parser_cocci_menhir.mly" +# 1554 "parser_cocci_menhir.mly" ( [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Ty(_1))))] ) -# 20423 "parser_cocci_menhir.ml" +# 20479 "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 = _1; + MenhirLib.EngineTypes.startp = _startpos__1_; + MenhirLib.EngineTypes.endp = _endpos__1_; + MenhirLib.EngineTypes.next = _menhir_stack; + } = _menhir_stack in + let _1 : 'tv_top_init = Obj.magic _1 in + let _startpos = _startpos__1_ in + let _endpos = _endpos__1_ in + let _v : 'tv_plus_start = +# 1555 "parser_cocci_menhir.mly" + ( [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.TopInit(_1))))] ) +# 20503 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20447,9 +20527,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_plus_start = -# 1551 "parser_cocci_menhir.mly" +# 1557 "parser_cocci_menhir.mly" ( (Ast0.wrap(Ast0.OTHER(_1)))::_2 ) -# 20453 "parser_cocci_menhir.ml" +# 20533 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20477,9 +20557,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_plus_start = -# 1553 "parser_cocci_menhir.mly" +# 1559 "parser_cocci_menhir.mly" ( (Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Exp(_1)))))::_2 ) -# 20483 "parser_cocci_menhir.ml" +# 20563 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20507,9 +20587,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_plus_start = -# 1554 "parser_cocci_menhir.mly" +# 1560 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.DECL(_1))::_2 ) -# 20513 "parser_cocci_menhir.ml" +# 20593 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20537,9 +20617,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_plus_start = -# 1556 "parser_cocci_menhir.mly" +# 1562 "parser_cocci_menhir.mly" ( (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) _1)@_2 ) -# 20543 "parser_cocci_menhir.ml" +# 20623 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20560,14 +20640,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 47 "parser_cocci_menhir.mly" (string) -# 20564 "parser_cocci_menhir.ml" +# 20644 "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 ) -# 20571 "parser_cocci_menhir.ml" +# 20651 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20592,14 +20672,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 47 "parser_cocci_menhir.mly" (string) -# 20596 "parser_cocci_menhir.ml" +# 20676 "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 ) -# 20603 "parser_cocci_menhir.ml" +# 20683 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20624,14 +20704,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 47 "parser_cocci_menhir.mly" (string) -# 20628 "parser_cocci_menhir.ml" +# 20708 "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 ) -# 20635 "parser_cocci_menhir.ml" +# 20715 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20656,14 +20736,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 47 "parser_cocci_menhir.mly" (string) -# 20660 "parser_cocci_menhir.ml" +# 20740 "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 ) -# 20667 "parser_cocci_menhir.ml" +# 20747 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20695,7 +20775,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_pnrule = # 224 "parser_cocci_menhir.mly" ( _2 ) -# 20699 "parser_cocci_menhir.ml" +# 20779 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20719,7 +20799,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_postfix_expr_eexpr_dot_expressions_ = # 1249 "parser_cocci_menhir.mly" ( _1 ) -# 20723 "parser_cocci_menhir.ml" +# 20803 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20755,13 +20835,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _4 : ( # 101 "parser_cocci_menhir.mly" (Data.clt) -# 20759 "parser_cocci_menhir.ml" +# 20839 "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) -# 20765 "parser_cocci_menhir.ml" +# 20845 "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 @@ -20770,7 +20850,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1251 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.ArrayAccess (_1,P.clt2mcode "[" _2,_3, P.clt2mcode "]" _4)) ) -# 20774 "parser_cocci_menhir.ml" +# 20854 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20802,7 +20882,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 20806 "parser_cocci_menhir.ml" +# 20886 "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 @@ -20810,7 +20890,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_postfix_expr_eexpr_dot_expressions_ = # 1254 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.RecordAccess(_1, P.clt2mcode "." _2, _3)) ) -# 20814 "parser_cocci_menhir.ml" +# 20894 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20842,7 +20922,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 103 "parser_cocci_menhir.mly" (Data.clt) -# 20846 "parser_cocci_menhir.ml" +# 20926 "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 @@ -20851,7 +20931,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1256 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.RecordPtAccess(_1, P.clt2mcode "->" _2, _3)) ) -# 20855 "parser_cocci_menhir.ml" +# 20935 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20877,7 +20957,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 84 "parser_cocci_menhir.mly" (Data.clt) -# 20881 "parser_cocci_menhir.ml" +# 20961 "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 @@ -20885,7 +20965,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_postfix_expr_eexpr_dot_expressions_ = # 1259 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Inc _2)) ) -# 20889 "parser_cocci_menhir.ml" +# 20969 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20911,7 +20991,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 84 "parser_cocci_menhir.mly" (Data.clt) -# 20915 "parser_cocci_menhir.ml" +# 20995 "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 @@ -20919,7 +20999,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_postfix_expr_eexpr_dot_expressions_ = # 1261 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Dec _2)) ) -# 20923 "parser_cocci_menhir.ml" +# 21003 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20955,13 +21035,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _4 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 20959 "parser_cocci_menhir.ml" +# 21039 "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) -# 20965 "parser_cocci_menhir.ml" +# 21045 "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 @@ -20971,7 +21051,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( Ast0.wrap(Ast0.FunCall(_1,P.clt2mcode "(" _2, _3, P.clt2mcode ")" _4)) ) -# 20975 "parser_cocci_menhir.ml" +# 21055 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -20995,7 +21075,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_postfix_expr_eexpr_invalid_ = # 1249 "parser_cocci_menhir.mly" ( _1 ) -# 20999 "parser_cocci_menhir.ml" +# 21079 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21031,13 +21111,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _4 : ( # 101 "parser_cocci_menhir.mly" (Data.clt) -# 21035 "parser_cocci_menhir.ml" +# 21115 "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) -# 21041 "parser_cocci_menhir.ml" +# 21121 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_postfix_expr_eexpr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -21046,7 +21126,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1251 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.ArrayAccess (_1,P.clt2mcode "[" _2,_3, P.clt2mcode "]" _4)) ) -# 21050 "parser_cocci_menhir.ml" +# 21130 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21078,7 +21158,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 21082 "parser_cocci_menhir.ml" +# 21162 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_postfix_expr_eexpr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -21086,7 +21166,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_postfix_expr_eexpr_invalid_ = # 1254 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.RecordAccess(_1, P.clt2mcode "." _2, _3)) ) -# 21090 "parser_cocci_menhir.ml" +# 21170 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21118,7 +21198,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 103 "parser_cocci_menhir.mly" (Data.clt) -# 21122 "parser_cocci_menhir.ml" +# 21202 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_postfix_expr_eexpr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -21127,7 +21207,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1256 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.RecordPtAccess(_1, P.clt2mcode "->" _2, _3)) ) -# 21131 "parser_cocci_menhir.ml" +# 21211 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21153,7 +21233,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 84 "parser_cocci_menhir.mly" (Data.clt) -# 21157 "parser_cocci_menhir.ml" +# 21237 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_postfix_expr_eexpr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -21161,7 +21241,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_postfix_expr_eexpr_invalid_ = # 1259 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Inc _2)) ) -# 21165 "parser_cocci_menhir.ml" +# 21245 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21187,7 +21267,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 84 "parser_cocci_menhir.mly" (Data.clt) -# 21191 "parser_cocci_menhir.ml" +# 21271 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_postfix_expr_eexpr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -21195,7 +21275,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_postfix_expr_eexpr_invalid_ = # 1261 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Dec _2)) ) -# 21199 "parser_cocci_menhir.ml" +# 21279 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21231,13 +21311,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _4 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 21235 "parser_cocci_menhir.ml" +# 21315 "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) -# 21241 "parser_cocci_menhir.ml" +# 21321 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_postfix_expr_eexpr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -21247,7 +21327,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( Ast0.wrap(Ast0.FunCall(_1,P.clt2mcode "(" _2, _3, P.clt2mcode ")" _4)) ) -# 21251 "parser_cocci_menhir.ml" +# 21331 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21271,7 +21351,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_postfix_expr_eexpr_nest_expressions_ = # 1249 "parser_cocci_menhir.mly" ( _1 ) -# 21275 "parser_cocci_menhir.ml" +# 21355 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21307,13 +21387,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _4 : ( # 101 "parser_cocci_menhir.mly" (Data.clt) -# 21311 "parser_cocci_menhir.ml" +# 21391 "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) -# 21317 "parser_cocci_menhir.ml" +# 21397 "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 @@ -21322,7 +21402,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1251 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.ArrayAccess (_1,P.clt2mcode "[" _2,_3, P.clt2mcode "]" _4)) ) -# 21326 "parser_cocci_menhir.ml" +# 21406 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21354,7 +21434,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 21358 "parser_cocci_menhir.ml" +# 21438 "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 @@ -21362,7 +21442,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_postfix_expr_eexpr_nest_expressions_ = # 1254 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.RecordAccess(_1, P.clt2mcode "." _2, _3)) ) -# 21366 "parser_cocci_menhir.ml" +# 21446 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21394,7 +21474,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 103 "parser_cocci_menhir.mly" (Data.clt) -# 21398 "parser_cocci_menhir.ml" +# 21478 "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 @@ -21403,7 +21483,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1256 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.RecordPtAccess(_1, P.clt2mcode "->" _2, _3)) ) -# 21407 "parser_cocci_menhir.ml" +# 21487 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21429,7 +21509,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 84 "parser_cocci_menhir.mly" (Data.clt) -# 21433 "parser_cocci_menhir.ml" +# 21513 "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 @@ -21437,7 +21517,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_postfix_expr_eexpr_nest_expressions_ = # 1259 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Inc _2)) ) -# 21441 "parser_cocci_menhir.ml" +# 21521 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21463,7 +21543,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 84 "parser_cocci_menhir.mly" (Data.clt) -# 21467 "parser_cocci_menhir.ml" +# 21547 "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 @@ -21471,7 +21551,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_postfix_expr_eexpr_nest_expressions_ = # 1261 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Dec _2)) ) -# 21475 "parser_cocci_menhir.ml" +# 21555 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21507,13 +21587,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _4 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 21511 "parser_cocci_menhir.ml" +# 21591 "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) -# 21517 "parser_cocci_menhir.ml" +# 21597 "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 @@ -21523,7 +21603,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( Ast0.wrap(Ast0.FunCall(_1,P.clt2mcode "(" _2, _3, P.clt2mcode ")" _4)) ) -# 21527 "parser_cocci_menhir.ml" +# 21607 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21547,7 +21627,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_postfix_expr_expr_invalid_ = # 1249 "parser_cocci_menhir.mly" ( _1 ) -# 21551 "parser_cocci_menhir.ml" +# 21631 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21583,13 +21663,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _4 : ( # 101 "parser_cocci_menhir.mly" (Data.clt) -# 21587 "parser_cocci_menhir.ml" +# 21667 "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) -# 21593 "parser_cocci_menhir.ml" +# 21673 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_postfix_expr_expr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -21598,7 +21678,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1251 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.ArrayAccess (_1,P.clt2mcode "[" _2,_3, P.clt2mcode "]" _4)) ) -# 21602 "parser_cocci_menhir.ml" +# 21682 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21630,7 +21710,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 21634 "parser_cocci_menhir.ml" +# 21714 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_postfix_expr_expr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -21638,7 +21718,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_postfix_expr_expr_invalid_ = # 1254 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.RecordAccess(_1, P.clt2mcode "." _2, _3)) ) -# 21642 "parser_cocci_menhir.ml" +# 21722 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21670,7 +21750,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 103 "parser_cocci_menhir.mly" (Data.clt) -# 21674 "parser_cocci_menhir.ml" +# 21754 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_postfix_expr_expr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -21679,7 +21759,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1256 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.RecordPtAccess(_1, P.clt2mcode "->" _2, _3)) ) -# 21683 "parser_cocci_menhir.ml" +# 21763 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21705,7 +21785,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 84 "parser_cocci_menhir.mly" (Data.clt) -# 21709 "parser_cocci_menhir.ml" +# 21789 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_postfix_expr_expr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -21713,7 +21793,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_postfix_expr_expr_invalid_ = # 1259 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Inc _2)) ) -# 21717 "parser_cocci_menhir.ml" +# 21797 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21739,7 +21819,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 84 "parser_cocci_menhir.mly" (Data.clt) -# 21743 "parser_cocci_menhir.ml" +# 21823 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_postfix_expr_expr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -21747,7 +21827,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_postfix_expr_expr_invalid_ = # 1261 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Dec _2)) ) -# 21751 "parser_cocci_menhir.ml" +# 21831 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21783,13 +21863,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _4 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 21787 "parser_cocci_menhir.ml" +# 21867 "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) -# 21793 "parser_cocci_menhir.ml" +# 21873 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_postfix_expr_expr_invalid_ = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -21799,7 +21879,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( Ast0.wrap(Ast0.FunCall(_1,P.clt2mcode "(" _2, _3, P.clt2mcode ")" _4)) ) -# 21803 "parser_cocci_menhir.ml" +# 21883 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21823,7 +21903,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_primary_expr_eexpr_dot_expressions_ = # 1268 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Ident(_1)) ) -# 21827 "parser_cocci_menhir.ml" +# 21907 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21844,7 +21924,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 21848 "parser_cocci_menhir.ml" +# 21928 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -21852,7 +21932,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1270 "parser_cocci_menhir.mly" ( let (x,clt) = _1 in Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) ) -# 21856 "parser_cocci_menhir.ml" +# 21936 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21873,7 +21953,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 21877 "parser_cocci_menhir.ml" +# 21957 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -21881,7 +21961,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1273 "parser_cocci_menhir.mly" ( let (x,clt) = _1 in Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Float x) clt)) ) -# 21885 "parser_cocci_menhir.ml" +# 21965 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21902,7 +21982,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 21906 "parser_cocci_menhir.ml" +# 21986 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -21910,7 +21990,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1276 "parser_cocci_menhir.mly" ( let (x,clt) = _1 in Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.String x) clt)) ) -# 21914 "parser_cocci_menhir.ml" +# 21994 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21931,7 +22011,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 21935 "parser_cocci_menhir.ml" +# 22015 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -21939,7 +22019,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1279 "parser_cocci_menhir.mly" ( let (x,clt) = _1 in Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Char x) clt)) ) -# 21943 "parser_cocci_menhir.ml" +# 22023 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21960,7 +22040,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 66 "parser_cocci_menhir.mly" (Parse_aux.typed_info) -# 21964 "parser_cocci_menhir.ml" +# 22044 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -21969,7 +22049,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let (nm,constraints,pure,ty,clt) = _1 in Ast0.wrap (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.CONST,pure)) ) -# 21973 "parser_cocci_menhir.ml" +# 22053 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -21990,7 +22070,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 63 "parser_cocci_menhir.mly" (Parse_aux.expinfo) -# 21994 "parser_cocci_menhir.ml" +# 22074 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -21998,7 +22078,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1286 "parser_cocci_menhir.mly" ( let (nm,constraints,pure,clt) = _1 in Ast0.wrap(Ast0.MetaErr(P.clt2mcode nm clt,constraints,pure)) ) -# 22002 "parser_cocci_menhir.ml" +# 22082 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22019,7 +22099,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 66 "parser_cocci_menhir.mly" (Parse_aux.typed_info) -# 22023 "parser_cocci_menhir.ml" +# 22103 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -22028,7 +22108,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let (nm,constraints,pure,ty,clt) = _1 in Ast0.wrap (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ANY,pure)) ) -# 22032 "parser_cocci_menhir.ml" +# 22112 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22049,7 +22129,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 66 "parser_cocci_menhir.mly" (Parse_aux.typed_info) -# 22053 "parser_cocci_menhir.ml" +# 22133 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -22058,7 +22138,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let (nm,constraints,pure,ty,clt) = _1 in Ast0.wrap (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ID,pure)) ) -# 22062 "parser_cocci_menhir.ml" +# 22142 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22079,7 +22159,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 66 "parser_cocci_menhir.mly" (Parse_aux.typed_info) -# 22083 "parser_cocci_menhir.ml" +# 22163 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -22088,7 +22168,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let (nm,constraints,pure,ty,clt) = _1 in Ast0.wrap (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.LocalID,pure)) ) -# 22092 "parser_cocci_menhir.ml" +# 22172 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22119,13 +22199,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _3 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 22123 "parser_cocci_menhir.ml" +# 22203 "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) -# 22129 "parser_cocci_menhir.ml" +# 22209 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in @@ -22133,7 +22213,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1301 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Paren(P.clt2mcode "(" _1,_2, P.clt2mcode ")" _3)) ) -# 22137 "parser_cocci_menhir.ml" +# 22217 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22164,13 +22244,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _3 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 22168 "parser_cocci_menhir.ml" +# 22248 "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) -# 22174 "parser_cocci_menhir.ml" +# 22254 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in @@ -22180,7 +22260,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct Ast0.wrap(Ast0.DisjExpr(P.clt2mcode "(" _1, code, mids, P.clt2mcode ")" _3)) ) -# 22184 "parser_cocci_menhir.ml" +# 22264 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22204,7 +22284,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_primary_expr_eexpr_dot_expressions_ = # 1308 "parser_cocci_menhir.mly" ( _1 ) -# 22208 "parser_cocci_menhir.ml" +# 22288 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22228,7 +22308,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_primary_expr_eexpr_invalid_ = # 1268 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Ident(_1)) ) -# 22232 "parser_cocci_menhir.ml" +# 22312 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22249,7 +22329,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 22253 "parser_cocci_menhir.ml" +# 22333 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -22257,7 +22337,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1270 "parser_cocci_menhir.mly" ( let (x,clt) = _1 in Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) ) -# 22261 "parser_cocci_menhir.ml" +# 22341 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22278,7 +22358,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 22282 "parser_cocci_menhir.ml" +# 22362 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -22286,7 +22366,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1273 "parser_cocci_menhir.mly" ( let (x,clt) = _1 in Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Float x) clt)) ) -# 22290 "parser_cocci_menhir.ml" +# 22370 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22307,7 +22387,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 22311 "parser_cocci_menhir.ml" +# 22391 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -22315,7 +22395,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1276 "parser_cocci_menhir.mly" ( let (x,clt) = _1 in Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.String x) clt)) ) -# 22319 "parser_cocci_menhir.ml" +# 22399 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22336,7 +22416,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 22340 "parser_cocci_menhir.ml" +# 22420 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -22344,7 +22424,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1279 "parser_cocci_menhir.mly" ( let (x,clt) = _1 in Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Char x) clt)) ) -# 22348 "parser_cocci_menhir.ml" +# 22428 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22365,7 +22445,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 66 "parser_cocci_menhir.mly" (Parse_aux.typed_info) -# 22369 "parser_cocci_menhir.ml" +# 22449 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -22374,7 +22454,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let (nm,constraints,pure,ty,clt) = _1 in Ast0.wrap (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.CONST,pure)) ) -# 22378 "parser_cocci_menhir.ml" +# 22458 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22395,7 +22475,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 63 "parser_cocci_menhir.mly" (Parse_aux.expinfo) -# 22399 "parser_cocci_menhir.ml" +# 22479 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -22403,7 +22483,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1286 "parser_cocci_menhir.mly" ( let (nm,constraints,pure,clt) = _1 in Ast0.wrap(Ast0.MetaErr(P.clt2mcode nm clt,constraints,pure)) ) -# 22407 "parser_cocci_menhir.ml" +# 22487 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22424,7 +22504,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 66 "parser_cocci_menhir.mly" (Parse_aux.typed_info) -# 22428 "parser_cocci_menhir.ml" +# 22508 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -22433,7 +22513,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let (nm,constraints,pure,ty,clt) = _1 in Ast0.wrap (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ANY,pure)) ) -# 22437 "parser_cocci_menhir.ml" +# 22517 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22454,7 +22534,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 66 "parser_cocci_menhir.mly" (Parse_aux.typed_info) -# 22458 "parser_cocci_menhir.ml" +# 22538 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -22463,7 +22543,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let (nm,constraints,pure,ty,clt) = _1 in Ast0.wrap (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ID,pure)) ) -# 22467 "parser_cocci_menhir.ml" +# 22547 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22484,7 +22564,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 66 "parser_cocci_menhir.mly" (Parse_aux.typed_info) -# 22488 "parser_cocci_menhir.ml" +# 22568 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -22493,7 +22573,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let (nm,constraints,pure,ty,clt) = _1 in Ast0.wrap (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.LocalID,pure)) ) -# 22497 "parser_cocci_menhir.ml" +# 22577 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22524,13 +22604,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _3 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 22528 "parser_cocci_menhir.ml" +# 22608 "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) -# 22534 "parser_cocci_menhir.ml" +# 22614 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in @@ -22538,7 +22618,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1301 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Paren(P.clt2mcode "(" _1,_2, P.clt2mcode ")" _3)) ) -# 22542 "parser_cocci_menhir.ml" +# 22622 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22569,13 +22649,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _3 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 22573 "parser_cocci_menhir.ml" +# 22653 "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) -# 22579 "parser_cocci_menhir.ml" +# 22659 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in @@ -22585,7 +22665,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct Ast0.wrap(Ast0.DisjExpr(P.clt2mcode "(" _1, code, mids, P.clt2mcode ")" _3)) ) -# 22589 "parser_cocci_menhir.ml" +# 22669 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22609,7 +22689,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_primary_expr_eexpr_invalid_ = # 1308 "parser_cocci_menhir.mly" ( _1 ) -# 22613 "parser_cocci_menhir.ml" +# 22693 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22633,7 +22713,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_primary_expr_eexpr_nest_expressions_ = # 1268 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Ident(_1)) ) -# 22637 "parser_cocci_menhir.ml" +# 22717 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22654,7 +22734,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 22658 "parser_cocci_menhir.ml" +# 22738 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -22662,7 +22742,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1270 "parser_cocci_menhir.mly" ( let (x,clt) = _1 in Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) ) -# 22666 "parser_cocci_menhir.ml" +# 22746 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22683,7 +22763,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 22687 "parser_cocci_menhir.ml" +# 22767 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -22691,7 +22771,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1273 "parser_cocci_menhir.mly" ( let (x,clt) = _1 in Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Float x) clt)) ) -# 22695 "parser_cocci_menhir.ml" +# 22775 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22712,7 +22792,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 22716 "parser_cocci_menhir.ml" +# 22796 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -22720,7 +22800,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1276 "parser_cocci_menhir.mly" ( let (x,clt) = _1 in Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.String x) clt)) ) -# 22724 "parser_cocci_menhir.ml" +# 22804 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22741,7 +22821,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 22745 "parser_cocci_menhir.ml" +# 22825 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -22749,7 +22829,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1279 "parser_cocci_menhir.mly" ( let (x,clt) = _1 in Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Char x) clt)) ) -# 22753 "parser_cocci_menhir.ml" +# 22833 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22770,7 +22850,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 66 "parser_cocci_menhir.mly" (Parse_aux.typed_info) -# 22774 "parser_cocci_menhir.ml" +# 22854 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -22779,7 +22859,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let (nm,constraints,pure,ty,clt) = _1 in Ast0.wrap (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.CONST,pure)) ) -# 22783 "parser_cocci_menhir.ml" +# 22863 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22800,7 +22880,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 63 "parser_cocci_menhir.mly" (Parse_aux.expinfo) -# 22804 "parser_cocci_menhir.ml" +# 22884 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -22808,7 +22888,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1286 "parser_cocci_menhir.mly" ( let (nm,constraints,pure,clt) = _1 in Ast0.wrap(Ast0.MetaErr(P.clt2mcode nm clt,constraints,pure)) ) -# 22812 "parser_cocci_menhir.ml" +# 22892 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22829,7 +22909,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 66 "parser_cocci_menhir.mly" (Parse_aux.typed_info) -# 22833 "parser_cocci_menhir.ml" +# 22913 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -22838,7 +22918,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let (nm,constraints,pure,ty,clt) = _1 in Ast0.wrap (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ANY,pure)) ) -# 22842 "parser_cocci_menhir.ml" +# 22922 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22859,7 +22939,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 66 "parser_cocci_menhir.mly" (Parse_aux.typed_info) -# 22863 "parser_cocci_menhir.ml" +# 22943 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -22868,7 +22948,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let (nm,constraints,pure,ty,clt) = _1 in Ast0.wrap (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ID,pure)) ) -# 22872 "parser_cocci_menhir.ml" +# 22952 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22889,7 +22969,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 66 "parser_cocci_menhir.mly" (Parse_aux.typed_info) -# 22893 "parser_cocci_menhir.ml" +# 22973 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -22898,7 +22978,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let (nm,constraints,pure,ty,clt) = _1 in Ast0.wrap (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.LocalID,pure)) ) -# 22902 "parser_cocci_menhir.ml" +# 22982 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22929,13 +23009,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _3 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 22933 "parser_cocci_menhir.ml" +# 23013 "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) -# 22939 "parser_cocci_menhir.ml" +# 23019 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in @@ -22943,7 +23023,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1301 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Paren(P.clt2mcode "(" _1,_2, P.clt2mcode ")" _3)) ) -# 22947 "parser_cocci_menhir.ml" +# 23027 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -22974,13 +23054,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _3 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 22978 "parser_cocci_menhir.ml" +# 23058 "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) -# 22984 "parser_cocci_menhir.ml" +# 23064 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in @@ -22990,7 +23070,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct Ast0.wrap(Ast0.DisjExpr(P.clt2mcode "(" _1, code, mids, P.clt2mcode ")" _3)) ) -# 22994 "parser_cocci_menhir.ml" +# 23074 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23014,7 +23094,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_primary_expr_eexpr_nest_expressions_ = # 1308 "parser_cocci_menhir.mly" ( _1 ) -# 23018 "parser_cocci_menhir.ml" +# 23098 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23038,7 +23118,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_primary_expr_expr_invalid_ = # 1268 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Ident(_1)) ) -# 23042 "parser_cocci_menhir.ml" +# 23122 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23059,7 +23139,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 23063 "parser_cocci_menhir.ml" +# 23143 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -23067,7 +23147,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1270 "parser_cocci_menhir.mly" ( let (x,clt) = _1 in Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) ) -# 23071 "parser_cocci_menhir.ml" +# 23151 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23088,7 +23168,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 23092 "parser_cocci_menhir.ml" +# 23172 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -23096,7 +23176,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1273 "parser_cocci_menhir.mly" ( let (x,clt) = _1 in Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Float x) clt)) ) -# 23100 "parser_cocci_menhir.ml" +# 23180 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23117,7 +23197,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 23121 "parser_cocci_menhir.ml" +# 23201 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -23125,7 +23205,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1276 "parser_cocci_menhir.mly" ( let (x,clt) = _1 in Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.String x) clt)) ) -# 23129 "parser_cocci_menhir.ml" +# 23209 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23146,7 +23226,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 23150 "parser_cocci_menhir.ml" +# 23230 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -23154,7 +23234,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1279 "parser_cocci_menhir.mly" ( let (x,clt) = _1 in Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Char x) clt)) ) -# 23158 "parser_cocci_menhir.ml" +# 23238 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23175,7 +23255,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 66 "parser_cocci_menhir.mly" (Parse_aux.typed_info) -# 23179 "parser_cocci_menhir.ml" +# 23259 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -23184,7 +23264,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let (nm,constraints,pure,ty,clt) = _1 in Ast0.wrap (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.CONST,pure)) ) -# 23188 "parser_cocci_menhir.ml" +# 23268 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23205,7 +23285,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 63 "parser_cocci_menhir.mly" (Parse_aux.expinfo) -# 23209 "parser_cocci_menhir.ml" +# 23289 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -23213,7 +23293,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1286 "parser_cocci_menhir.mly" ( let (nm,constraints,pure,clt) = _1 in Ast0.wrap(Ast0.MetaErr(P.clt2mcode nm clt,constraints,pure)) ) -# 23217 "parser_cocci_menhir.ml" +# 23297 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23234,7 +23314,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 66 "parser_cocci_menhir.mly" (Parse_aux.typed_info) -# 23238 "parser_cocci_menhir.ml" +# 23318 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -23243,7 +23323,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let (nm,constraints,pure,ty,clt) = _1 in Ast0.wrap (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ANY,pure)) ) -# 23247 "parser_cocci_menhir.ml" +# 23327 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23264,7 +23344,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 66 "parser_cocci_menhir.mly" (Parse_aux.typed_info) -# 23268 "parser_cocci_menhir.ml" +# 23348 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -23273,7 +23353,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let (nm,constraints,pure,ty,clt) = _1 in Ast0.wrap (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ID,pure)) ) -# 23277 "parser_cocci_menhir.ml" +# 23357 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23294,7 +23374,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 66 "parser_cocci_menhir.mly" (Parse_aux.typed_info) -# 23298 "parser_cocci_menhir.ml" +# 23378 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -23303,7 +23383,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( let (nm,constraints,pure,ty,clt) = _1 in Ast0.wrap (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.LocalID,pure)) ) -# 23307 "parser_cocci_menhir.ml" +# 23387 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23334,13 +23414,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _3 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 23338 "parser_cocci_menhir.ml" +# 23418 "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) -# 23344 "parser_cocci_menhir.ml" +# 23424 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in @@ -23348,7 +23428,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1301 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.Paren(P.clt2mcode "(" _1,_2, P.clt2mcode ")" _3)) ) -# 23352 "parser_cocci_menhir.ml" +# 23432 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23379,13 +23459,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _3 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 23383 "parser_cocci_menhir.ml" +# 23463 "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) -# 23389 "parser_cocci_menhir.ml" +# 23469 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in @@ -23395,7 +23475,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct Ast0.wrap(Ast0.DisjExpr(P.clt2mcode "(" _1, code, mids, P.clt2mcode ")" _3)) ) -# 23399 "parser_cocci_menhir.ml" +# 23479 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23419,7 +23499,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_primary_expr_expr_invalid_ = # 1308 "parser_cocci_menhir.mly" ( _1 ) -# 23423 "parser_cocci_menhir.ml" +# 23503 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23441,7 +23521,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_pure = # 189 "parser_cocci_menhir.mly" ( Ast0.Pure ) -# 23445 "parser_cocci_menhir.ml" +# 23525 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23463,7 +23543,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_pure = # 190 "parser_cocci_menhir.mly" ( Ast0.Context ) -# 23467 "parser_cocci_menhir.ml" +# 23547 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23489,7 +23569,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_pure = # 191 "parser_cocci_menhir.mly" ( Ast0.PureContext ) -# 23493 "parser_cocci_menhir.ml" +# 23573 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23515,7 +23595,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_pure = # 192 "parser_cocci_menhir.mly" ( Ast0.PureContext ) -# 23519 "parser_cocci_menhir.ml" +# 23599 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23532,7 +23612,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_pure = # 193 "parser_cocci_menhir.mly" ( Ast0.Impure ) -# 23536 "parser_cocci_menhir.ml" +# 23616 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23553,14 +23633,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 59 "parser_cocci_menhir.mly" (string * Data.clt) -# 23557 "parser_cocci_menhir.ml" +# 23637 "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" ( _1 ) -# 23564 "parser_cocci_menhir.ml" +# 23644 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23584,7 +23664,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_pure_ident_or_meta_ident = # 1328 "parser_cocci_menhir.mly" ( (None,P.id2name _1) ) -# 23588 "parser_cocci_menhir.ml" +# 23668 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23608,7 +23688,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_pure_ident_or_meta_ident = # 1329 "parser_cocci_menhir.mly" ( _1 ) -# 23612 "parser_cocci_menhir.ml" +# 23692 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23630,7 +23710,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_pure_ident_or_meta_ident = # 1330 "parser_cocci_menhir.mly" ( (None,"list") ) -# 23634 "parser_cocci_menhir.ml" +# 23714 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23652,7 +23732,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_pure_ident_or_meta_ident = # 1331 "parser_cocci_menhir.mly" ( (None,"error") ) -# 23656 "parser_cocci_menhir.ml" +# 23736 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23674,7 +23754,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_pure_ident_or_meta_ident = # 1332 "parser_cocci_menhir.mly" ( (None,"type") ) -# 23678 "parser_cocci_menhir.ml" +# 23758 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23704,7 +23784,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_pure_ident_or_meta_ident_with_not_eq_not_ceq_ = # 1335 "parser_cocci_menhir.mly" ( (i,l) ) -# 23708 "parser_cocci_menhir.ml" +# 23788 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23734,7 +23814,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_pure_ident_or_meta_ident_with_not_eq_not_eq_ = # 1335 "parser_cocci_menhir.mly" ( (i,l) ) -# 23738 "parser_cocci_menhir.ml" +# 23818 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23764,7 +23844,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_pure_ident_or_meta_ident_with_not_eq_not_eqe_ = # 1335 "parser_cocci_menhir.mly" ( (i,l) ) -# 23768 "parser_cocci_menhir.ml" +# 23848 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23794,7 +23874,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_pure_ident_or_meta_ident_with_not_eq_not_pos_ = # 1335 "parser_cocci_menhir.mly" ( (i,l) ) -# 23798 "parser_cocci_menhir.ml" +# 23878 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23811,11 +23891,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 130 "parser_cocci_menhir.mly" (unit) -# 23815 "parser_cocci_menhir.ml" +# 23895 "parser_cocci_menhir.ml" ) = # 171 "parser_cocci_menhir.mly" ( ) -# 23819 "parser_cocci_menhir.ml" +# 23899 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23839,7 +23919,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)) ) -# 23843 "parser_cocci_menhir.ml" +# 23923 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23865,7 +23945,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 23869 "parser_cocci_menhir.ml" +# 23949 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_expr = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -23873,7 +23953,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_rule_elem_statement = # 850 "parser_cocci_menhir.mly" ( P.exp_stm _1 _2 ) -# 23877 "parser_cocci_menhir.ml" +# 23957 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23904,20 +23984,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _3 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 23908 "parser_cocci_menhir.ml" +# 23988 "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) -# 23914 "parser_cocci_menhir.ml" +# 23994 "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 ) -# 23921 "parser_cocci_menhir.ml" +# 24001 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23943,19 +24023,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 23947 "parser_cocci_menhir.ml" +# 24027 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : ( # 57 "parser_cocci_menhir.mly" (Data.clt) -# 23952 "parser_cocci_menhir.ml" +# 24032 "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 ) -# 23959 "parser_cocci_menhir.ml" +# 24039 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -23981,19 +24061,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 23985 "parser_cocci_menhir.ml" +# 24065 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : ( # 58 "parser_cocci_menhir.mly" (Data.clt) -# 23990 "parser_cocci_menhir.ml" +# 24070 "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 ) -# 23997 "parser_cocci_menhir.ml" +# 24077 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24019,19 +24099,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 24023 "parser_cocci_menhir.ml" +# 24103 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : ( # 58 "parser_cocci_menhir.mly" (Data.clt) -# 24028 "parser_cocci_menhir.ml" +# 24108 "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 ) -# 24035 "parser_cocci_menhir.ml" +# 24115 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24062,13 +24142,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _3 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 24066 "parser_cocci_menhir.ml" +# 24146 "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) -# 24072 "parser_cocci_menhir.ml" +# 24152 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in @@ -24079,7 +24159,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)) ) -# 24083 "parser_cocci_menhir.ml" +# 24163 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24135,18 +24215,18 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 152 "parser_cocci_menhir.mly" (Ast_cocci.rulename) -# 24139 "parser_cocci_menhir.ml" +# 24219 "parser_cocci_menhir.ml" ) = let nm = # 39 "standard.mly" ( None ) -# 24144 "parser_cocci_menhir.ml" +# 24224 "parser_cocci_menhir.ml" in # 201 "parser_cocci_menhir.mly" ( P.make_cocci_rule_name_result nm d i a e ee ) -# 24150 "parser_cocci_menhir.ml" +# 24230 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24208,19 +24288,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 152 "parser_cocci_menhir.mly" (Ast_cocci.rulename) -# 24212 "parser_cocci_menhir.ml" +# 24292 "parser_cocci_menhir.ml" ) = let nm = let x = x0 in # 41 "standard.mly" ( Some x ) -# 24218 "parser_cocci_menhir.ml" +# 24298 "parser_cocci_menhir.ml" in # 201 "parser_cocci_menhir.mly" ( P.make_cocci_rule_name_result nm d i a e ee ) -# 24224 "parser_cocci_menhir.ml" +# 24304 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24247,9 +24327,8 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct MenhirLib.EngineTypes.endp = _endpos__2_; MenhirLib.EngineTypes.next = { MenhirLib.EngineTypes.state = _menhir_s; - MenhirLib.EngineTypes.semv = scr; - MenhirLib.EngineTypes.startp = _startpos_scr_; - MenhirLib.EngineTypes.endp = _endpos_scr_; + MenhirLib.EngineTypes.startp = _startpos__1_; + MenhirLib.EngineTypes.endp = _endpos__1_; MenhirLib.EngineTypes.next = _menhir_stack; }; }; @@ -24258,17 +24337,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct } = _menhir_stack in let d : 'tv_depends = Obj.magic d in let lang : 'tv_pure_ident = Obj.magic lang in - let scr : 'tv_pure_ident = Obj.magic scr in - let _startpos = _startpos_scr_ in + let _startpos = _startpos__1_ in let _endpos = _endpos__5_ in let _v : ( # 152 "parser_cocci_menhir.mly" (Ast_cocci.rulename) -# 24268 "parser_cocci_menhir.ml" +# 24346 "parser_cocci_menhir.ml" ) = # 203 "parser_cocci_menhir.mly" - ( P.make_script_rule_name_result scr lang d ) -# 24272 "parser_cocci_menhir.ml" + ( P.make_script_rule_name_result lang d ) +# 24350 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24312,7 +24390,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _3 : ( # 47 "parser_cocci_menhir.mly" (string) -# 24316 "parser_cocci_menhir.ml" +# 24394 "parser_cocci_menhir.ml" ) = Obj.magic _3 in let py : 'tv_pure_ident = Obj.magic py in let _startpos = _startpos_py_ in @@ -24320,11 +24398,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : ( # 158 "parser_cocci_menhir.mly" (string * (string * string)) -# 24324 "parser_cocci_menhir.ml" +# 24402 "parser_cocci_menhir.ml" ) = -# 1765 "parser_cocci_menhir.mly" +# 1769 "parser_cocci_menhir.mly" ( (P.id2name py, (_3, P.id2name cocci)) ) -# 24328 "parser_cocci_menhir.ml" +# 24406 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24345,14 +24423,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let x : ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 24349 "parser_cocci_menhir.ml" +# 24427 "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 ] ) -# 24356 "parser_cocci_menhir.ml" +# 24434 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24383,14 +24461,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let x : ( # 86 "parser_cocci_menhir.mly" (string * Data.clt) -# 24387 "parser_cocci_menhir.ml" +# 24465 "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 ) -# 24394 "parser_cocci_menhir.ml" +# 24472 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24414,7 +24492,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_separated_nonempty_list_TComma_any_strict_ = # 144 "standard.mly" ( [ x ] ) -# 24418 "parser_cocci_menhir.ml" +# 24496 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24448,7 +24526,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_separated_nonempty_list_TComma_any_strict_ = # 146 "standard.mly" ( x :: xs ) -# 24452 "parser_cocci_menhir.ml" +# 24530 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24472,7 +24550,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_separated_nonempty_list_TComma_ctype_ = # 144 "standard.mly" ( [ x ] ) -# 24476 "parser_cocci_menhir.ml" +# 24554 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24506,7 +24584,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_separated_nonempty_list_TComma_ctype_ = # 146 "standard.mly" ( x :: xs ) -# 24510 "parser_cocci_menhir.ml" +# 24588 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24530,7 +24608,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_separated_nonempty_list_TComma_d_ident_ = # 144 "standard.mly" ( [ x ] ) -# 24534 "parser_cocci_menhir.ml" +# 24612 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24564,7 +24642,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_separated_nonempty_list_TComma_d_ident_ = # 146 "standard.mly" ( x :: xs ) -# 24568 "parser_cocci_menhir.ml" +# 24646 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24588,7 +24666,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_separated_nonempty_list_TComma_dexpr_ = # 144 "standard.mly" ( [ x ] ) -# 24592 "parser_cocci_menhir.ml" +# 24670 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24622,7 +24700,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_separated_nonempty_list_TComma_dexpr_ = # 146 "standard.mly" ( x :: xs ) -# 24626 "parser_cocci_menhir.ml" +# 24704 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24646,7 +24724,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_separated_nonempty_list_TComma_ident_or_const_ = # 144 "standard.mly" ( [ x ] ) -# 24650 "parser_cocci_menhir.ml" +# 24728 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24680,7 +24758,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_separated_nonempty_list_TComma_ident_or_const_ = # 146 "standard.mly" ( x :: xs ) -# 24684 "parser_cocci_menhir.ml" +# 24762 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24704,7 +24782,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_separated_nonempty_list_TComma_meta_ident_ = # 144 "standard.mly" ( [ x ] ) -# 24708 "parser_cocci_menhir.ml" +# 24786 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24738,7 +24816,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_separated_nonempty_list_TComma_meta_ident_ = # 146 "standard.mly" ( x :: xs ) -# 24742 "parser_cocci_menhir.ml" +# 24820 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24762,7 +24840,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_separated_nonempty_list_TComma_pure_ident_ = # 144 "standard.mly" ( [ x ] ) -# 24766 "parser_cocci_menhir.ml" +# 24844 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24796,7 +24874,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_separated_nonempty_list_TComma_pure_ident_ = # 146 "standard.mly" ( x :: xs ) -# 24800 "parser_cocci_menhir.ml" +# 24878 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24820,7 +24898,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_ = # 144 "standard.mly" ( [ x ] ) -# 24824 "parser_cocci_menhir.ml" +# 24902 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24854,7 +24932,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_ = # 146 "standard.mly" ( x :: xs ) -# 24858 "parser_cocci_menhir.ml" +# 24936 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24878,7 +24956,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 ] ) -# 24882 "parser_cocci_menhir.ml" +# 24960 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24912,7 +24990,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 ) -# 24916 "parser_cocci_menhir.ml" +# 24994 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24936,7 +25014,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 ] ) -# 24940 "parser_cocci_menhir.ml" +# 25018 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24970,7 +25048,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 ) -# 24974 "parser_cocci_menhir.ml" +# 25052 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -24994,7 +25072,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 ] ) -# 24998 "parser_cocci_menhir.ml" +# 25076 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -25028,7 +25106,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 ) -# 25032 "parser_cocci_menhir.ml" +# 25110 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -25052,7 +25130,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 ] ) -# 25056 "parser_cocci_menhir.ml" +# 25134 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -25086,7 +25164,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 ) -# 25090 "parser_cocci_menhir.ml" +# 25168 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -25110,7 +25188,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_single_statement = # 864 "parser_cocci_menhir.mly" ( _1 ) -# 25114 "parser_cocci_menhir.ml" +# 25192 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -25141,13 +25219,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _3 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 25145 "parser_cocci_menhir.ml" +# 25223 "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) -# 25151 "parser_cocci_menhir.ml" +# 25229 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__3_ in @@ -25158,7 +25236,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)) ) -# 25162 "parser_cocci_menhir.ml" +# 25240 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -25182,7 +25260,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_statement = # 803 "parser_cocci_menhir.mly" ( _1 ) -# 25186 "parser_cocci_menhir.ml" +# 25264 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -25203,14 +25281,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 64 "parser_cocci_menhir.mly" (Parse_aux.info) -# 25207 "parser_cocci_menhir.ml" +# 25285 "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 ) -# 25214 "parser_cocci_menhir.ml" +# 25292 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -25236,7 +25314,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 25240 "parser_cocci_menhir.ml" +# 25318 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_expr = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -25244,7 +25322,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_statement = # 807 "parser_cocci_menhir.mly" ( P.exp_stm _1 _2 ) -# 25248 "parser_cocci_menhir.ml" +# 25326 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -25286,25 +25364,25 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _4 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 25290 "parser_cocci_menhir.ml" +# 25368 "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) -# 25296 "parser_cocci_menhir.ml" +# 25374 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : ( # 57 "parser_cocci_menhir.mly" (Data.clt) -# 25301 "parser_cocci_menhir.ml" +# 25379 "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 ) -# 25308 "parser_cocci_menhir.ml" +# 25386 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -25356,31 +25434,31 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _6 : ( # 57 "parser_cocci_menhir.mly" (Data.clt) -# 25360 "parser_cocci_menhir.ml" +# 25438 "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) -# 25366 "parser_cocci_menhir.ml" +# 25444 "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) -# 25372 "parser_cocci_menhir.ml" +# 25450 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : ( # 57 "parser_cocci_menhir.mly" (Data.clt) -# 25377 "parser_cocci_menhir.ml" +# 25455 "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 ) -# 25384 "parser_cocci_menhir.ml" +# 25462 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -25442,37 +25520,37 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _8 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 25446 "parser_cocci_menhir.ml" +# 25524 "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) -# 25452 "parser_cocci_menhir.ml" +# 25530 "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) -# 25458 "parser_cocci_menhir.ml" +# 25536 "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) -# 25464 "parser_cocci_menhir.ml" +# 25542 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : ( # 57 "parser_cocci_menhir.mly" (Data.clt) -# 25469 "parser_cocci_menhir.ml" +# 25547 "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 ) -# 25476 "parser_cocci_menhir.ml" +# 25554 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -25514,25 +25592,25 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _4 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 25518 "parser_cocci_menhir.ml" +# 25596 "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) -# 25524 "parser_cocci_menhir.ml" +# 25602 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : ( # 57 "parser_cocci_menhir.mly" (Data.clt) -# 25529 "parser_cocci_menhir.ml" +# 25607 "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 ) -# 25536 "parser_cocci_menhir.ml" +# 25614 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -25583,36 +25661,36 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _7 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 25587 "parser_cocci_menhir.ml" +# 25665 "parser_cocci_menhir.ml" ) = Obj.magic _7 in let _6 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 25592 "parser_cocci_menhir.ml" +# 25670 "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) -# 25598 "parser_cocci_menhir.ml" +# 25676 "parser_cocci_menhir.ml" ) = Obj.magic _4 in let _3 : ( # 57 "parser_cocci_menhir.mly" (Data.clt) -# 25603 "parser_cocci_menhir.ml" +# 25681 "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) -# 25609 "parser_cocci_menhir.ml" +# 25687 "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 ) -# 25616 "parser_cocci_menhir.ml" +# 25694 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -25654,13 +25732,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _4 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 25658 "parser_cocci_menhir.ml" +# 25736 "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) -# 25664 "parser_cocci_menhir.ml" +# 25742 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_iter_ident = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -25668,7 +25746,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_statement = # 820 "parser_cocci_menhir.mly" ( P.iterator _1 _2 _3 _4 _5 ) -# 25672 "parser_cocci_menhir.ml" +# 25750 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -25719,36 +25797,36 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _7 : ( # 100 "parser_cocci_menhir.mly" (Data.clt) -# 25723 "parser_cocci_menhir.ml" +# 25801 "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) -# 25729 "parser_cocci_menhir.ml" +# 25807 "parser_cocci_menhir.ml" ) = Obj.magic _5 in let _4 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 25734 "parser_cocci_menhir.ml" +# 25812 "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) -# 25740 "parser_cocci_menhir.ml" +# 25818 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : ( # 57 "parser_cocci_menhir.mly" (Data.clt) -# 25745 "parser_cocci_menhir.ml" +# 25823 "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 ) -# 25752 "parser_cocci_menhir.ml" +# 25830 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -25779,20 +25857,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _3 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 25783 "parser_cocci_menhir.ml" +# 25861 "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) -# 25789 "parser_cocci_menhir.ml" +# 25867 "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 ) -# 25796 "parser_cocci_menhir.ml" +# 25874 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -25818,19 +25896,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 25822 "parser_cocci_menhir.ml" +# 25900 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : ( # 57 "parser_cocci_menhir.mly" (Data.clt) -# 25827 "parser_cocci_menhir.ml" +# 25905 "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 ) -# 25834 "parser_cocci_menhir.ml" +# 25912 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -25856,19 +25934,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 25860 "parser_cocci_menhir.ml" +# 25938 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : ( # 58 "parser_cocci_menhir.mly" (Data.clt) -# 25865 "parser_cocci_menhir.ml" +# 25943 "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 ) -# 25872 "parser_cocci_menhir.ml" +# 25950 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -25894,19 +25972,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 25898 "parser_cocci_menhir.ml" +# 25976 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : ( # 58 "parser_cocci_menhir.mly" (Data.clt) -# 25903 "parser_cocci_menhir.ml" +# 25981 "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 ) -# 25910 "parser_cocci_menhir.ml" +# 25988 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -25932,7 +26010,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _2 : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 25936 "parser_cocci_menhir.ml" +# 26014 "parser_cocci_menhir.ml" ) = Obj.magic _2 in let _1 : 'tv_ident = Obj.magic _1 in let _startpos = _startpos__1_ in @@ -25940,7 +26018,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_statement = # 827 "parser_cocci_menhir.mly" ( P.label _1 _2 ) -# 25944 "parser_cocci_menhir.ml" +# 26022 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -25971,20 +26049,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _3 : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 25975 "parser_cocci_menhir.ml" +# 26053 "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) -# 25981 "parser_cocci_menhir.ml" +# 26059 "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 ) -# 25988 "parser_cocci_menhir.ml" +# 26066 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26015,20 +26093,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _3 : ( # 100 "parser_cocci_menhir.mly" (Data.clt) -# 26019 "parser_cocci_menhir.ml" +# 26097 "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) -# 26025 "parser_cocci_menhir.ml" +# 26103 "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 ) -# 26032 "parser_cocci_menhir.ml" +# 26110 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26055,14 +26133,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 26059 "parser_cocci_menhir.ml" +# 26137 "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)) ) -# 26066 "parser_cocci_menhir.ml" +# 26144 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26098,14 +26176,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let c : ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 26102 "parser_cocci_menhir.ml" +# 26180 "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) -# 26109 "parser_cocci_menhir.ml" +# 26187 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos_c_ in @@ -26113,7 +26191,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)) ) -# 26117 "parser_cocci_menhir.ml" +# 26195 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26149,14 +26227,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let c : ( # 72 "parser_cocci_menhir.mly" (Data.clt) -# 26153 "parser_cocci_menhir.ml" +# 26231 "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) -# 26160 "parser_cocci_menhir.ml" +# 26238 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos_c_ in @@ -26164,7 +26242,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)) ) -# 26168 "parser_cocci_menhir.ml" +# 26246 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26185,14 +26263,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let s : ( # 53 "parser_cocci_menhir.mly" (Data.clt) -# 26189 "parser_cocci_menhir.ml" +# 26267 "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 ) -# 26196 "parser_cocci_menhir.ml" +# 26274 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26213,14 +26291,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let s : ( # 53 "parser_cocci_menhir.mly" (Data.clt) -# 26217 "parser_cocci_menhir.ml" +# 26295 "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 ) -# 26224 "parser_cocci_menhir.ml" +# 26302 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26241,14 +26319,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let s : ( # 53 "parser_cocci_menhir.mly" (Data.clt) -# 26245 "parser_cocci_menhir.ml" +# 26323 "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 ) -# 26252 "parser_cocci_menhir.ml" +# 26330 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26269,14 +26347,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let s : ( # 53 "parser_cocci_menhir.mly" (Data.clt) -# 26273 "parser_cocci_menhir.ml" +# 26351 "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 ) -# 26280 "parser_cocci_menhir.ml" +# 26358 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26298,7 +26376,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_struct_decl = # 488 "parser_cocci_menhir.mly" ( [] ) -# 26302 "parser_cocci_menhir.ml" +# 26380 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26329,7 +26407,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 26333 "parser_cocci_menhir.ml" +# 26411 "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 @@ -26339,7 +26417,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))] ) -# 26343 "parser_cocci_menhir.ml" +# 26421 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26400,34 +26478,34 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 26404 "parser_cocci_menhir.ml" +# 26482 "parser_cocci_menhir.ml" ) = Obj.magic pv in let rp2 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 26409 "parser_cocci_menhir.ml" +# 26487 "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) -# 26415 "parser_cocci_menhir.ml" +# 26493 "parser_cocci_menhir.ml" ) = Obj.magic lp2 in let rp1 : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 26420 "parser_cocci_menhir.ml" +# 26498 "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) -# 26426 "parser_cocci_menhir.ml" +# 26504 "parser_cocci_menhir.ml" ) = Obj.magic st in let lp1 : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 26431 "parser_cocci_menhir.ml" +# 26509 "parser_cocci_menhir.ml" ) = Obj.magic lp1 in let t : 'tv_fn_ctype = Obj.magic t in let _startpos = _startpos_t_ in @@ -26441,7 +26519,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))] ) -# 26445 "parser_cocci_menhir.ml" +# 26523 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26472,7 +26550,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 26476 "parser_cocci_menhir.ml" +# 26554 "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 @@ -26482,7 +26560,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 39 "standard.mly" ( None ) -# 26486 "parser_cocci_menhir.ml" +# 26564 "parser_cocci_menhir.ml" in @@ -26490,7 +26568,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))] ) -# 26494 "parser_cocci_menhir.ml" +# 26572 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26526,7 +26604,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let pv : ( # 106 "parser_cocci_menhir.mly" (Data.clt) -# 26530 "parser_cocci_menhir.ml" +# 26608 "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 @@ -26538,7 +26616,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 41 "standard.mly" ( Some x ) -# 26542 "parser_cocci_menhir.ml" +# 26620 "parser_cocci_menhir.ml" in @@ -26546,7 +26624,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))] ) -# 26550 "parser_cocci_menhir.ml" +# 26628 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26570,7 +26648,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_struct_decl_list = # 507 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.DOTS(_1)) ) -# 26574 "parser_cocci_menhir.ml" +# 26652 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26594,7 +26672,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_struct_decl_list_start = # 510 "parser_cocci_menhir.mly" ( _1 ) -# 26598 "parser_cocci_menhir.ml" +# 26676 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26624,7 +26702,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_struct_decl_list_start = # 511 "parser_cocci_menhir.mly" ( _1@_2 ) -# 26628 "parser_cocci_menhir.ml" +# 26706 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26654,7 +26732,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_struct_decl_list_start = # 513 "parser_cocci_menhir.mly" ( (P.mkddots "..." d)::r ) -# 26658 "parser_cocci_menhir.ml" +# 26736 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26675,14 +26753,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let s : ( # 50 "parser_cocci_menhir.mly" (Data.clt) -# 26679 "parser_cocci_menhir.ml" +# 26757 "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 ) -# 26686 "parser_cocci_menhir.ml" +# 26764 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26703,14 +26781,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let u : ( # 50 "parser_cocci_menhir.mly" (Data.clt) -# 26707 "parser_cocci_menhir.ml" +# 26785 "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 ) -# 26714 "parser_cocci_menhir.ml" +# 26792 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26734,7 +26812,51 @@ 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)))) ) -# 26738 "parser_cocci_menhir.ml" +# 26816 "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.semv = _3; + MenhirLib.EngineTypes.startp = _startpos__3_; + MenhirLib.EngineTypes.endp = _endpos__3_; + MenhirLib.EngineTypes.next = { + MenhirLib.EngineTypes.semv = _2; + MenhirLib.EngineTypes.startp = _startpos__2_; + MenhirLib.EngineTypes.endp = _endpos__2_; + 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; + }; + }; + } = _menhir_stack in + let _3 : ( +# 100 "parser_cocci_menhir.mly" + (Data.clt) +# 26847 "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" + ) = Obj.magic _1 in + let _startpos = _startpos__1_ in + let _endpos = _endpos__3_ in + let _v : 'tv_top_init = +# 1547 "parser_cocci_menhir.mly" + ( Ast0.wrap(Ast0.InitList(P.clt2mcode "{" _1,_2,P.clt2mcode "}" _3)) ) +# 26860 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26749,9 +26871,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 = -# 1534 "parser_cocci_menhir.mly" +# 1535 "parser_cocci_menhir.mly" ([]) -# 26755 "parser_cocci_menhir.ml" +# 26877 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26777,9 +26899,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_toplevel_after_dots = -# 1535 "parser_cocci_menhir.mly" +# 1536 "parser_cocci_menhir.mly" (_2) -# 26783 "parser_cocci_menhir.ml" +# 26905 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26807,9 +26929,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" ((Ast0.wrap(Ast0.Exp(_1)))::_2) -# 26813 "parser_cocci_menhir.ml" +# 26935 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26837,9 +26959,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" (_1@_2) -# 26843 "parser_cocci_menhir.ml" +# 26965 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26865,9 +26987,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_toplevel_after_dots_init = -# 1525 "parser_cocci_menhir.mly" +# 1526 "parser_cocci_menhir.mly" (_2) -# 26871 "parser_cocci_menhir.ml" +# 26993 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26895,9 +27017,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" ((Ast0.wrap(Ast0.Exp(_1)))::_2) -# 26901 "parser_cocci_menhir.ml" +# 27023 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26925,9 +27047,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" (_1@_2) -# 26931 "parser_cocci_menhir.ml" +# 27053 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26942,9 +27064,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 = -# 1530 "parser_cocci_menhir.mly" +# 1531 "parser_cocci_menhir.mly" ([]) -# 26948 "parser_cocci_menhir.ml" +# 27070 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26972,9 +27094,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_toplevel_after_exp = -# 1531 "parser_cocci_menhir.mly" +# 1532 "parser_cocci_menhir.mly" (_1::_2) -# 26978 "parser_cocci_menhir.ml" +# 27100 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -26989,9 +27111,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 = -# 1540 "parser_cocci_menhir.mly" +# 1541 "parser_cocci_menhir.mly" ([]) -# 26995 "parser_cocci_menhir.ml" +# 27117 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27019,9 +27141,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_toplevel_after_stm = -# 1541 "parser_cocci_menhir.mly" +# 1542 "parser_cocci_menhir.mly" (_1::_2) -# 27025 "parser_cocci_menhir.ml" +# 27147 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27049,9 +27171,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) -# 27055 "parser_cocci_menhir.ml" +# 27177 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27079,9 +27201,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_ = -# 1520 "parser_cocci_menhir.mly" +# 1521 "parser_cocci_menhir.mly" ( _1::_2 ) -# 27085 "parser_cocci_menhir.ml" +# 27207 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27109,9 +27231,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" ( (Ast0.wrap(Ast0.Exp(_1)))::_2 ) -# 27115 "parser_cocci_menhir.ml" +# 27237 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27139,9 +27261,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" ( _1@_2 ) -# 27145 "parser_cocci_menhir.ml" +# 27267 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27169,9 +27291,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_ = -# 1520 "parser_cocci_menhir.mly" +# 1521 "parser_cocci_menhir.mly" ( _1::_2 ) -# 27175 "parser_cocci_menhir.ml" +# 27297 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27199,9 +27321,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" ( (Ast0.wrap(Ast0.Exp(_1)))::_2 ) -# 27205 "parser_cocci_menhir.ml" +# 27327 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27229,9 +27351,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" ( _1@_2 ) -# 27235 "parser_cocci_menhir.ml" +# 27357 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27255,7 +27377,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_typedef_ident = # 1434 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.TypeName(P.id2mcode _1)) ) -# 27259 "parser_cocci_menhir.ml" +# 27381 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27276,7 +27398,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 64 "parser_cocci_menhir.mly" (Parse_aux.info) -# 27280 "parser_cocci_menhir.ml" +# 27402 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__1_ in @@ -27284,7 +27406,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1436 "parser_cocci_menhir.mly" ( let (nm,pure,clt) = _1 in Ast0.wrap(Ast0.MetaType(P.clt2mcode nm clt,pure)) ) -# 27288 "parser_cocci_menhir.ml" +# 27410 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27308,7 +27430,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_unary_expr_eexpr_dot_expressions_ = # 1225 "parser_cocci_menhir.mly" ( _1 ) -# 27312 "parser_cocci_menhir.ml" +# 27434 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27335,14 +27457,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 84 "parser_cocci_menhir.mly" (Data.clt) -# 27339 "parser_cocci_menhir.ml" +# 27461 "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" ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Inc _1)) ) -# 27346 "parser_cocci_menhir.ml" +# 27468 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27369,14 +27491,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 84 "parser_cocci_menhir.mly" (Data.clt) -# 27373 "parser_cocci_menhir.ml" +# 27495 "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" ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Dec _1)) ) -# 27380 "parser_cocci_menhir.ml" +# 27502 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27406,7 +27528,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_unary_expr_eexpr_dot_expressions_ = # 1231 "parser_cocci_menhir.mly" ( let mcode = _1 in Ast0.wrap(Ast0.Unary(_2, mcode)) ) -# 27410 "parser_cocci_menhir.ml" +# 27532 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27433,7 +27555,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 27437 "parser_cocci_menhir.ml" +# 27559 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in @@ -27441,7 +27563,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1233 "parser_cocci_menhir.mly" ( let mcode = P.clt2mcode Ast.Not _1 in Ast0.wrap(Ast0.Unary(_2, mcode)) ) -# 27445 "parser_cocci_menhir.ml" +# 27567 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27468,14 +27590,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 58 "parser_cocci_menhir.mly" (Data.clt) -# 27472 "parser_cocci_menhir.ml" +# 27594 "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" ( Ast0.wrap(Ast0.SizeOfExpr (P.clt2mcode "sizeof" _1, _2)) ) -# 27479 "parser_cocci_menhir.ml" +# 27601 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27511,18 +27633,18 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let rp : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 27515 "parser_cocci_menhir.ml" +# 27637 "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) -# 27521 "parser_cocci_menhir.ml" +# 27643 "parser_cocci_menhir.ml" ) = Obj.magic lp in let s : ( # 58 "parser_cocci_menhir.mly" (Data.clt) -# 27526 "parser_cocci_menhir.ml" +# 27648 "parser_cocci_menhir.ml" ) = Obj.magic s in let _startpos = _startpos_s_ in let _endpos = _endpos_rp_ in @@ -27531,7 +27653,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( Ast0.wrap(Ast0.SizeOfType (P.clt2mcode "sizeof" s, P.clt2mcode "(" lp,t, P.clt2mcode ")" rp)) ) -# 27535 "parser_cocci_menhir.ml" +# 27657 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27555,7 +27677,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_unary_expr_eexpr_invalid_ = # 1225 "parser_cocci_menhir.mly" ( _1 ) -# 27559 "parser_cocci_menhir.ml" +# 27681 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27582,14 +27704,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 84 "parser_cocci_menhir.mly" (Data.clt) -# 27586 "parser_cocci_menhir.ml" +# 27708 "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" ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Inc _1)) ) -# 27593 "parser_cocci_menhir.ml" +# 27715 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27616,14 +27738,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 84 "parser_cocci_menhir.mly" (Data.clt) -# 27620 "parser_cocci_menhir.ml" +# 27742 "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" ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Dec _1)) ) -# 27627 "parser_cocci_menhir.ml" +# 27749 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27653,7 +27775,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_unary_expr_eexpr_invalid_ = # 1231 "parser_cocci_menhir.mly" ( let mcode = _1 in Ast0.wrap(Ast0.Unary(_2, mcode)) ) -# 27657 "parser_cocci_menhir.ml" +# 27779 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27680,7 +27802,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 27684 "parser_cocci_menhir.ml" +# 27806 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in @@ -27688,7 +27810,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1233 "parser_cocci_menhir.mly" ( let mcode = P.clt2mcode Ast.Not _1 in Ast0.wrap(Ast0.Unary(_2, mcode)) ) -# 27692 "parser_cocci_menhir.ml" +# 27814 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27715,14 +27837,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 58 "parser_cocci_menhir.mly" (Data.clt) -# 27719 "parser_cocci_menhir.ml" +# 27841 "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" ( Ast0.wrap(Ast0.SizeOfExpr (P.clt2mcode "sizeof" _1, _2)) ) -# 27726 "parser_cocci_menhir.ml" +# 27848 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27758,18 +27880,18 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let rp : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 27762 "parser_cocci_menhir.ml" +# 27884 "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) -# 27768 "parser_cocci_menhir.ml" +# 27890 "parser_cocci_menhir.ml" ) = Obj.magic lp in let s : ( # 58 "parser_cocci_menhir.mly" (Data.clt) -# 27773 "parser_cocci_menhir.ml" +# 27895 "parser_cocci_menhir.ml" ) = Obj.magic s in let _startpos = _startpos_s_ in let _endpos = _endpos_rp_ in @@ -27778,7 +27900,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( Ast0.wrap(Ast0.SizeOfType (P.clt2mcode "sizeof" s, P.clt2mcode "(" lp,t, P.clt2mcode ")" rp)) ) -# 27782 "parser_cocci_menhir.ml" +# 27904 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27802,7 +27924,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_unary_expr_eexpr_nest_expressions_ = # 1225 "parser_cocci_menhir.mly" ( _1 ) -# 27806 "parser_cocci_menhir.ml" +# 27928 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27829,14 +27951,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 84 "parser_cocci_menhir.mly" (Data.clt) -# 27833 "parser_cocci_menhir.ml" +# 27955 "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" ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Inc _1)) ) -# 27840 "parser_cocci_menhir.ml" +# 27962 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27863,14 +27985,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 84 "parser_cocci_menhir.mly" (Data.clt) -# 27867 "parser_cocci_menhir.ml" +# 27989 "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" ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Dec _1)) ) -# 27874 "parser_cocci_menhir.ml" +# 27996 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27900,7 +28022,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_unary_expr_eexpr_nest_expressions_ = # 1231 "parser_cocci_menhir.mly" ( let mcode = _1 in Ast0.wrap(Ast0.Unary(_2, mcode)) ) -# 27904 "parser_cocci_menhir.ml" +# 28026 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27927,7 +28049,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 27931 "parser_cocci_menhir.ml" +# 28053 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in @@ -27935,7 +28057,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1233 "parser_cocci_menhir.mly" ( let mcode = P.clt2mcode Ast.Not _1 in Ast0.wrap(Ast0.Unary(_2, mcode)) ) -# 27939 "parser_cocci_menhir.ml" +# 28061 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -27962,14 +28084,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 58 "parser_cocci_menhir.mly" (Data.clt) -# 27966 "parser_cocci_menhir.ml" +# 28088 "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" ( Ast0.wrap(Ast0.SizeOfExpr (P.clt2mcode "sizeof" _1, _2)) ) -# 27973 "parser_cocci_menhir.ml" +# 28095 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -28005,18 +28127,18 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let rp : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 28009 "parser_cocci_menhir.ml" +# 28131 "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) -# 28015 "parser_cocci_menhir.ml" +# 28137 "parser_cocci_menhir.ml" ) = Obj.magic lp in let s : ( # 58 "parser_cocci_menhir.mly" (Data.clt) -# 28020 "parser_cocci_menhir.ml" +# 28142 "parser_cocci_menhir.ml" ) = Obj.magic s in let _startpos = _startpos_s_ in let _endpos = _endpos_rp_ in @@ -28025,7 +28147,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( Ast0.wrap(Ast0.SizeOfType (P.clt2mcode "sizeof" s, P.clt2mcode "(" lp,t, P.clt2mcode ")" rp)) ) -# 28029 "parser_cocci_menhir.ml" +# 28151 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -28049,7 +28171,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_unary_expr_expr_invalid_ = # 1225 "parser_cocci_menhir.mly" ( _1 ) -# 28053 "parser_cocci_menhir.ml" +# 28175 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -28076,14 +28198,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 84 "parser_cocci_menhir.mly" (Data.clt) -# 28080 "parser_cocci_menhir.ml" +# 28202 "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" ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Inc _1)) ) -# 28087 "parser_cocci_menhir.ml" +# 28209 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -28110,14 +28232,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 84 "parser_cocci_menhir.mly" (Data.clt) -# 28114 "parser_cocci_menhir.ml" +# 28236 "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" ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Dec _1)) ) -# 28121 "parser_cocci_menhir.ml" +# 28243 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -28147,7 +28269,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_unary_expr_expr_invalid_ = # 1231 "parser_cocci_menhir.mly" ( let mcode = _1 in Ast0.wrap(Ast0.Unary(_2, mcode)) ) -# 28151 "parser_cocci_menhir.ml" +# 28273 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -28174,7 +28296,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 75 "parser_cocci_menhir.mly" (Data.clt) -# 28178 "parser_cocci_menhir.ml" +# 28300 "parser_cocci_menhir.ml" ) = Obj.magic _1 in let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in @@ -28182,7 +28304,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 1233 "parser_cocci_menhir.mly" ( let mcode = P.clt2mcode Ast.Not _1 in Ast0.wrap(Ast0.Unary(_2, mcode)) ) -# 28186 "parser_cocci_menhir.ml" +# 28308 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -28209,14 +28331,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 58 "parser_cocci_menhir.mly" (Data.clt) -# 28213 "parser_cocci_menhir.ml" +# 28335 "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" ( Ast0.wrap(Ast0.SizeOfExpr (P.clt2mcode "sizeof" _1, _2)) ) -# 28220 "parser_cocci_menhir.ml" +# 28342 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -28252,18 +28374,18 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let rp : ( # 76 "parser_cocci_menhir.mly" (Data.clt) -# 28256 "parser_cocci_menhir.ml" +# 28378 "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) -# 28262 "parser_cocci_menhir.ml" +# 28384 "parser_cocci_menhir.ml" ) = Obj.magic lp in let s : ( # 58 "parser_cocci_menhir.mly" (Data.clt) -# 28267 "parser_cocci_menhir.ml" +# 28389 "parser_cocci_menhir.ml" ) = Obj.magic s in let _startpos = _startpos_s_ in let _endpos = _endpos_rp_ in @@ -28272,7 +28394,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct ( Ast0.wrap(Ast0.SizeOfType (P.clt2mcode "sizeof" s, P.clt2mcode "(" lp,t, P.clt2mcode ")" rp)) ) -# 28276 "parser_cocci_menhir.ml" +# 28398 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -28293,14 +28415,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 92 "parser_cocci_menhir.mly" (Data.clt) -# 28297 "parser_cocci_menhir.ml" +# 28419 "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" ( P.clt2mcode Ast.GetRef _1 ) -# 28304 "parser_cocci_menhir.ml" +# 28426 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -28321,14 +28443,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 98 "parser_cocci_menhir.mly" (Data.clt) -# 28325 "parser_cocci_menhir.ml" +# 28447 "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" ( P.clt2mcode Ast.DeRef _1 ) -# 28332 "parser_cocci_menhir.ml" +# 28454 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -28349,14 +28471,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 97 "parser_cocci_menhir.mly" (Data.clt) -# 28353 "parser_cocci_menhir.ml" +# 28475 "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" ( P.clt2mcode Ast.UnPlus _1 ) -# 28360 "parser_cocci_menhir.ml" +# 28482 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -28377,14 +28499,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 97 "parser_cocci_menhir.mly" (Data.clt) -# 28381 "parser_cocci_menhir.ml" +# 28503 "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" ( P.clt2mcode Ast.UnMinus _1 ) -# 28388 "parser_cocci_menhir.ml" +# 28510 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -28405,14 +28527,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _1 : ( # 98 "parser_cocci_menhir.mly" (Data.clt) -# 28409 "parser_cocci_menhir.ml" +# 28531 "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" ( P.clt2mcode Ast.Tilde _1 ) -# 28416 "parser_cocci_menhir.ml" +# 28538 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -28440,9 +28562,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_when_start = -# 1634 "parser_cocci_menhir.mly" +# 1640 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.DOTS((Ast0.wrap(Ast0.Exp(_1)))::_2)) ) -# 28446 "parser_cocci_menhir.ml" +# 28568 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -28470,9 +28592,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _startpos = _startpos__1_ in let _endpos = _endpos__2_ in let _v : 'tv_when_start = -# 1636 "parser_cocci_menhir.mly" +# 1642 "parser_cocci_menhir.mly" ( Ast0.wrap(Ast0.DOTS(_1@_2)) ) -# 28476 "parser_cocci_menhir.ml" +# 28598 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -28508,7 +28630,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_whenexp = # 1156 "parser_cocci_menhir.mly" ( w ) -# 28512 "parser_cocci_menhir.ml" +# 28634 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -28532,7 +28654,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _v : 'tv_whenppdecs = # 843 "parser_cocci_menhir.mly" ( w ) -# 28536 "parser_cocci_menhir.ml" +# 28658 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -28566,9 +28688,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_ = -# 1706 "parser_cocci_menhir.mly" +# 1708 "parser_cocci_menhir.mly" ( [Ast0.WhenNot w] ) -# 28572 "parser_cocci_menhir.ml" +# 28694 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -28602,9 +28724,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_ = -# 1707 "parser_cocci_menhir.mly" +# 1709 "parser_cocci_menhir.mly" ( [Ast0.WhenAlways w] ) -# 28608 "parser_cocci_menhir.ml" +# 28730 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -28634,9 +28756,81 @@ 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_ = -# 1709 "parser_cocci_menhir.mly" +# 1711 "parser_cocci_menhir.mly" ( List.map (function x -> Ast0.WhenModifier(x)) _2 ) -# 28640 "parser_cocci_menhir.ml" +# 28762 "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 = e; + MenhirLib.EngineTypes.startp = _startpos_e_; + MenhirLib.EngineTypes.endp = _endpos_e_; + 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 e : 'tv_eexpr = Obj.magic e in + let _startpos = _startpos__1_ in + let _endpos = _endpos__4_ in + let _v : 'tv_whens_when_start_rule_elem_statement_ = +# 1712 "parser_cocci_menhir.mly" + ( [Ast0.WhenNotTrue e] ) +# 28798 "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 = e; + MenhirLib.EngineTypes.startp = _startpos_e_; + MenhirLib.EngineTypes.endp = _endpos_e_; + 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 e : 'tv_eexpr = Obj.magic e in + let _startpos = _startpos__1_ in + let _endpos = _endpos__4_ in + let _v : 'tv_whens_when_start_rule_elem_statement_ = +# 1713 "parser_cocci_menhir.mly" + ( [Ast0.WhenNotFalse e] ) +# 28834 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { MenhirLib.EngineTypes.state = _menhir_s; @@ -28657,90 +28851,90 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let rec script_meta_main = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1479 lexer lexbuf) : ( + (Obj.magic (MenhirInterpreter.entry 1493 lexer lexbuf) : ( # 158 "parser_cocci_menhir.mly" (string * (string * string)) -# 28664 "parser_cocci_menhir.ml" +# 28858 "parser_cocci_menhir.ml" )) and rule_name = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1424 lexer lexbuf) : ( + (Obj.magic (MenhirInterpreter.entry 1437 lexer lexbuf) : ( # 152 "parser_cocci_menhir.mly" (Ast_cocci.rulename) -# 28672 "parser_cocci_menhir.ml" +# 28866 "parser_cocci_menhir.ml" )) and reinit = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1422 lexer lexbuf) : ( + (Obj.magic (MenhirInterpreter.entry 1435 lexer lexbuf) : ( # 130 "parser_cocci_menhir.mly" (unit) -# 28680 "parser_cocci_menhir.ml" +# 28874 "parser_cocci_menhir.ml" )) and plus_main = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1387 lexer lexbuf) : ( + (Obj.magic (MenhirInterpreter.entry 1399 lexer lexbuf) : ( # 139 "parser_cocci_menhir.mly" (Ast0_cocci.rule) -# 28688 "parser_cocci_menhir.ml" +# 28882 "parser_cocci_menhir.ml" )) and plus_exp_main = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1378 lexer lexbuf) : ( + (Obj.magic (MenhirInterpreter.entry 1390 lexer lexbuf) : ( # 142 "parser_cocci_menhir.mly" (Ast0_cocci.rule) -# 28696 "parser_cocci_menhir.ml" +# 28890 "parser_cocci_menhir.ml" )) and never_used = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1372 lexer lexbuf) : ( + (Obj.magic (MenhirInterpreter.entry 1384 lexer lexbuf) : ( # 167 "parser_cocci_menhir.mly" (unit) -# 28704 "parser_cocci_menhir.ml" +# 28898 "parser_cocci_menhir.ml" )) and minus_main = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1301 lexer lexbuf) : ( + (Obj.magic (MenhirInterpreter.entry 1309 lexer lexbuf) : ( # 133 "parser_cocci_menhir.mly" (Ast0_cocci.rule) -# 28712 "parser_cocci_menhir.ml" +# 28906 "parser_cocci_menhir.ml" )) and minus_exp_main = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1277 lexer lexbuf) : ( + (Obj.magic (MenhirInterpreter.entry 1285 lexer lexbuf) : ( # 136 "parser_cocci_menhir.mly" (Ast0_cocci.rule) -# 28720 "parser_cocci_menhir.ml" +# 28914 "parser_cocci_menhir.ml" )) and meta_main = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1274 lexer lexbuf) : ( + (Obj.magic (MenhirInterpreter.entry 1282 lexer lexbuf) : ( # 156 "parser_cocci_menhir.mly" ((Ast_cocci.metavar,Ast_cocci.metavar) Common.either list) -# 28728 "parser_cocci_menhir.ml" +# 28922 "parser_cocci_menhir.ml" )) and iso_rule_name = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1270 lexer lexbuf) : ( + (Obj.magic (MenhirInterpreter.entry 1278 lexer lexbuf) : ( # 148 "parser_cocci_menhir.mly" (Ast_cocci.rulename) -# 28736 "parser_cocci_menhir.ml" +# 28930 "parser_cocci_menhir.ml" )) and iso_meta_main = fun lexer lexbuf -> - (Obj.magic (MenhirInterpreter.entry 1078 lexer lexbuf) : ( + (Obj.magic (MenhirInterpreter.entry 1086 lexer lexbuf) : ( # 164 "parser_cocci_menhir.mly" ((Ast_cocci.metavar,Ast_cocci.metavar) Common.either list) -# 28744 "parser_cocci_menhir.ml" +# 28938 "parser_cocci_menhir.ml" )) and iso_main = @@ -28748,7 +28942,7 @@ and iso_main = (Obj.magic (MenhirInterpreter.entry 10 lexer lexbuf) : ( # 161 "parser_cocci_menhir.mly" (Ast0_cocci.anything list list) -# 28752 "parser_cocci_menhir.ml" +# 28946 "parser_cocci_menhir.ml" )) and include_main = @@ -28756,7 +28950,7 @@ and include_main = (Obj.magic (MenhirInterpreter.entry 0 lexer lexbuf) : ( # 145 "parser_cocci_menhir.mly" ((string,string) Common.either list) -# 28760 "parser_cocci_menhir.ml" +# 28954 "parser_cocci_menhir.ml" )) diff --git a/parsing_cocci/parser_cocci_menhir.mli b/parsing_cocci/parser_cocci_menhir.mli index 3acc076..d0c52e8 100644 --- a/parsing_cocci/parser_cocci_menhir.mli +++ b/parsing_cocci/parser_cocci_menhir.mli @@ -27,6 +27,8 @@ type token = | TWhy0 | TWhy of (Data.clt) | TWhile of (Data.clt) + | TWhenTrue of (Data.clt) + | TWhenFalse of (Data.clt) | TWhen of (Data.clt) | TUsing | TTypedef @@ -40,6 +42,7 @@ type token = | TSizeof of (Data.clt) | TShOp of (Ast_cocci.arithOp * Data.clt) | TScriptData of (string) + | TScript | TRuleName of (string) | TRightIso | TReverse @@ -63,6 +66,7 @@ type token = | TOn | TOPar0 of (Data.clt) | TOPar of (Data.clt) + | TOInit of (Data.clt) | TOEllipsis of (Data.clt) | TOCro of (Data.clt) | TOBrace of (Data.clt) diff --git a/parsing_cocci/parser_cocci_menhir.mly b/parsing_cocci/parser_cocci_menhir.mly index a3be6b6..1e71638 100644 --- a/parsing_cocci/parser_cocci_menhir.mly +++ b/parsing_cocci/parser_cocci_menhir.mly @@ -42,7 +42,7 @@ module P = Parse_aux %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 +%token TUsing TDisable TExtends TDepends TOn TEver TNever TExists TForall TScript %token TReverse TNothing %token TRuleName @@ -70,7 +70,7 @@ module P = Parse_aux %token TScriptData %token TEllipsis TOEllipsis TCEllipsis TPOEllipsis TPCEllipsis -%token TWhen TAny TStrict TLineEnd +%token TWhen TWhenTrue TWhenFalse TAny TStrict TLineEnd %token TWhy TDotDot TBang TOPar TOPar0 %token TMid0 TCPar TCPar0 @@ -97,7 +97,7 @@ module P = Parse_aux %token TPlus TMinus %token TMul TTilde -%token TOBrace TCBrace +%token TOBrace TCBrace TOInit %token TOCro TCCro %token TPtrOp @@ -199,8 +199,8 @@ 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 } - | scr=pure_ident TDotDot lang=pure_ident d=depends TArob - { P.make_script_rule_name_result scr lang d } + | TScript TDotDot lang=pure_ident d=depends TArob + { P.make_script_rule_name_result lang d } extends: /* empty */ { () } @@ -1513,6 +1513,7 @@ when_body_sequence. 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 } @@ -1541,12 +1542,17 @@ toplevel_after_stm: | 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 @@ -1698,15 +1704,13 @@ edots_when(dotter,when_grammar): d=dotter { (d,None) } | d=dotter TWhen TNotEq w=when_grammar TLineEnd { (d,Some w) } -dots_when(dotter,when_grammar,simple_when_grammar): - d=dotter w=list(whens(when_grammar,simple_when_grammar)) - { (d,List.concat 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 } diff --git a/parsing_cocci/pretty_print_cocci.ml b/parsing_cocci/pretty_print_cocci.ml index 308a25e..ede9f3f 100644 --- a/parsing_cocci/pretty_print_cocci.ml +++ b/parsing_cocci/pretty_print_cocci.ml @@ -579,6 +579,7 @@ let rec rule_elem arity re = | Ast.Exp(exp) -> print_string arity; expression exp | Ast.TopExp(exp) -> print_string arity; expression exp | Ast.Ty(ty) -> print_string arity; fullType ty + | Ast.TopInit(init) -> initialiser init | Ast.Include(inc,s) -> mcode print_string inc; print_string " "; mcode inc_file s | Ast.DefineHeader(def,id,params) -> @@ -698,6 +699,10 @@ and whencode notfn alwaysfn = function | Ast.WhenAlways a -> print_string " WHEN = "; open_box 0; alwaysfn a; close_box() | Ast.WhenModifier x -> print_string " WHEN "; print_when_modif x + | Ast.WhenNotTrue a -> + print_string " WHEN != TRUE "; open_box 0; rule_elem "" a; close_box() + | Ast.WhenNotFalse a -> + print_string " WHEN != FALSE "; open_box 0; rule_elem "" a; close_box() and print_when_modif = function | Ast.WhenAny -> print_string "ANY" diff --git a/parsing_cocci/single_statement.ml b/parsing_cocci/single_statement.ml index d8b86c0..847a83c 100644 --- a/parsing_cocci/single_statement.ml +++ b/parsing_cocci/single_statement.ml @@ -242,6 +242,7 @@ and left_statement s = | Ast0.Exp(exp) -> false (* can only be replaced by an expression *) | Ast0.TopExp(exp) -> false (* as above *) | Ast0.Ty(ty) -> false (* can only be replaced by a type *) + | Ast0.TopInit(init) -> false (* can only be replaced by an init *) | Ast0.Dots(d,whn) | Ast0.Circles(d,whn) | Ast0.Stars(d,whn) -> false | Ast0.Include(inc,s) -> modif_before_mcode inc | Ast0.Define(def,id,params,body) -> modif_before_mcode def @@ -281,6 +282,7 @@ and right_statement s = | Ast0.Exp(exp) -> false (* can only be replaced by an expression *) | Ast0.TopExp(exp) -> false (* as above *) | Ast0.Ty(ty) -> false (* can only be replaced by a type *) + | Ast0.TopInit(init) -> false (* can only be replaced by an init *) | Ast0.Dots(d,whn) | Ast0.Circles(d,whn) | Ast0.Stars(d,whn) -> false | Ast0.Include(inc,s) -> modif_after_mcode s | Ast0.Define(def,id,params,body) -> right_dots right_statement body @@ -544,6 +546,7 @@ let rec statement dots_before dots_after s = | Ast0.Exp(exp) -> s | Ast0.TopExp(exp) -> s | Ast0.Ty(ty) -> s + | Ast0.TopInit(init) -> s | Ast0.Dots(d,whn) | Ast0.Circles(d,whn) | Ast0.Stars(d,whn) -> s | Ast0.Include(inc,string) -> s (* doesn't affect the need for braces *) | Ast0.Define(def,id,params,body) -> s (* same as include *) diff --git a/parsing_cocci/test_exps.ml b/parsing_cocci/test_exps.ml index 528d7e2..815a8ea 100644 --- a/parsing_cocci/test_exps.ml +++ b/parsing_cocci/test_exps.ml @@ -60,6 +60,11 @@ let set_test_poss = | _ -> e) | _ -> e in + let process_wc = function + Ast0.WhenNotTrue(e) -> Ast0.WhenNotTrue(process_exp e) + | Ast0.WhenNotFalse(e) -> Ast0.WhenNotFalse(process_exp e) + | wc -> wc in + let statement r k s = let s = k s in match Ast0.unwrap s with @@ -74,6 +79,10 @@ let set_test_poss = | Ast0.For(f,lp,e1,sc1,Some e2,sc2,e3,rp,s1,aft) -> Ast0.rewrap s (Ast0.For(f,lp,e1,sc1,Some (process_exp e2),sc2,e3,rp,s1,aft)) + | Ast0.Dots(d,wc) -> + Ast0.rewrap s (Ast0.Dots(d,List.map process_wc wc)) + | Ast0.Nest(l,s1,r,wc,m) -> + Ast0.rewrap s (Ast0.Nest(l,s1,r,List.map process_wc wc,m)) | _ -> s in V0.rebuilder diff --git a/parsing_cocci/type_infer.ml b/parsing_cocci/type_infer.ml index 7ae9f85..1d566ea 100644 --- a/parsing_cocci/type_infer.ml +++ b/parsing_cocci/type_infer.ml @@ -247,10 +247,12 @@ let rec propagate_types env = | Ast0.OptIdent(id) -> strip id | Ast0.UniqueIdent(id) -> strip id in - let process_whencode notfn allfn = function + let process_whencode notfn allfn exp = function Ast0.WhenNot(x) -> let _ = notfn x in () | Ast0.WhenAlways(x) -> let _ = allfn x in () - | Ast0.WhenModifier(_) -> () in + | Ast0.WhenModifier(_) -> () + | Ast0.WhenNotTrue(x) -> let _ = exp x in () + | Ast0.WhenNotFalse(x) -> let _ = exp x in () in (* assume that all of the declarations are at the beginning of a statement list, which is required by C, but not actually required by the cocci @@ -279,9 +281,10 @@ let rec propagate_types env = let new_acc = (process_decl decl)@acc in process_statement_list r new_acc ss | Ast0.Dots(_,wc) -> + (* why is this case here? why is there none for nests? *) List.iter (process_whencode r.V0.combiner_statement_dots - r.V0.combiner_statement) + r.V0.combiner_statement r.V0.combiner_expression) wc; process_statement_list r acc ss | Ast0.Disj(_,statement_dots_list,_,_) -> diff --git a/parsing_cocci/unify_ast.ml b/parsing_cocci/unify_ast.ml index a32476b..a6dc6e5 100644 --- a/parsing_cocci/unify_ast.ml +++ b/parsing_cocci/unify_ast.ml @@ -450,6 +450,7 @@ and unify_rule_elem re1 re2 = | (_,Ast.Exp(e2)) -> subexp (unify_expression e2) re1 | (Ast.TopExp(e1),Ast.TopExp(e2)) -> unify_expression e1 e2 + | (Ast.TopInit(i1),Ast.TopInit(i2)) -> unify_initialiser i1 i2 (* can match a rule_elem in different parts *) | (Ast.Ty(t1),Ast.Ty(t2)) -> return true diff --git a/parsing_cocci/unitary_ast0.ml b/parsing_cocci/unitary_ast0.ml index 1110f58..31ad2c0 100644 --- a/parsing_cocci/unitary_ast0.ml +++ b/parsing_cocci/unitary_ast0.ml @@ -77,10 +77,12 @@ let get_free checker t = List.filter (function x -> not (List.mem x nonunitary)) unitary in unitary@nonunitary@nonunitary in - let whencode afn bfn = function + let whencode afn bfn expression = function Ast0.WhenNot(a) -> afn a | Ast0.WhenAlways(b) -> bfn b - | Ast0.WhenModifier(_) -> option_default in + | 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 @@ -123,12 +125,14 @@ let get_free checker t = bind (r.V0.combiner_statement_dots stmt_dots) (detect_unitary_frees (List.map - (whencode r.V0.combiner_statement_dots r.V0.combiner_statement) + (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) + (whencode r.V0.combiner_statement_dots r.V0.combiner_statement + r.V0.combiner_expression) whn) | _ -> k s in diff --git a/parsing_cocci/unparse_ast0.ml b/parsing_cocci/unparse_ast0.ml index 80ece57..7fb2c75 100644 --- a/parsing_cocci/unparse_ast0.ml +++ b/parsing_cocci/unparse_ast0.ml @@ -513,6 +513,7 @@ and statement arity s = | 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 @@ -556,6 +557,10 @@ and whencode notfn alwaysfn = function | 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 @@ -637,6 +642,8 @@ let unparse_anything x = | 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() diff --git a/parsing_cocci/visitor_ast.ml b/parsing_cocci/visitor_ast.ml index 6338874..5a0014f 100644 --- a/parsing_cocci/visitor_ast.ml +++ b/parsing_cocci/visitor_ast.ml @@ -359,6 +359,7 @@ let combiner bind option_default | Ast.Exp(exp) -> expression exp | Ast.TopExp(exp) -> expression exp | Ast.Ty(ty) -> fullType ty + | Ast.TopInit(init) -> initialiser init | Ast.Include(inc,name) -> bind (string_mcode inc) (inc_file_mcode name) | Ast.DefineHeader(def,id,params) -> multibind [string_mcode def; ident id; define_parameters params] @@ -456,6 +457,8 @@ let combiner bind option_default Ast.WhenNot a -> notfn a | Ast.WhenAlways a -> alwaysfn a | Ast.WhenModifier(_) -> option_default + | Ast.WhenNotTrue(e) -> rule_elem e + | Ast.WhenNotFalse(e) -> rule_elem e and case_line c = let k c = @@ -849,6 +852,7 @@ let rebuilder | Ast.Exp(exp) -> Ast.Exp(expression exp) | Ast.TopExp(exp) -> Ast.TopExp(expression exp) | Ast.Ty(ty) -> Ast.Ty(fullType ty) + | Ast.TopInit(init) -> Ast.TopInit(initialiser init) | Ast.Include(inc,name) -> Ast.Include(string_mcode inc,inc_file_mcode name) | Ast.DefineHeader(def,id,params) -> @@ -967,6 +971,8 @@ let rebuilder Ast.WhenNot a -> Ast.WhenNot (notfn a) | Ast.WhenAlways a -> Ast.WhenAlways (alwaysfn a) | Ast.WhenModifier(x) -> Ast.WhenModifier(x) + | Ast.WhenNotTrue(e) -> Ast.WhenNotTrue(rule_elem e) + | Ast.WhenNotFalse(e) -> Ast.WhenNotFalse(rule_elem e) and case_line c = let k c = diff --git a/parsing_cocci/visitor_ast0.ml b/parsing_cocci/visitor_ast0.ml index 6a70898..2e258a9 100644 --- a/parsing_cocci/visitor_ast0.ml +++ b/parsing_cocci/visitor_ast0.ml @@ -419,6 +419,7 @@ let combiner bind option_default | 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)) @@ -468,6 +469,8 @@ let combiner bind option_default 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 = @@ -500,6 +503,8 @@ let combiner bind option_default | 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 @@ -893,6 +898,7 @@ let rebuilder = fun | 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) @@ -954,7 +960,9 @@ let rebuilder = fun 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.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 = @@ -1002,6 +1010,8 @@ let rebuilder = fun | 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 diff --git a/popl09/.cvsignore b/popl09/.cvsignore new file mode 100644 index 0000000..0a2d2b3 --- /dev/null +++ b/popl09/.cvsignore @@ -0,0 +1,2 @@ +.depend +*.cma diff --git a/pycaml/.cvsignore b/pycaml/.cvsignore new file mode 100644 index 0000000..3245aa2 --- /dev/null +++ b/pycaml/.cvsignore @@ -0,0 +1,3 @@ +._d +pycaml.cma +pycaml.customtop diff --git a/python/.cvsignore b/python/.cvsignore new file mode 100644 index 0000000..0a2d2b3 --- /dev/null +++ b/python/.cvsignore @@ -0,0 +1,2 @@ +.depend +*.cma diff --git a/tests/.cvsignore b/tests/.cvsignore new file mode 100644 index 0000000..dc63c7c --- /dev/null +++ b/tests/.cvsignore @@ -0,0 +1 @@ +score_cocci_best.marshalled diff --git a/tests/double_assign.cocci b/tests/double_assign.cocci index 584085d..d97ba97 100644 --- a/tests/double_assign.cocci +++ b/tests/double_assign.cocci @@ -14,7 +14,7 @@ i =@p0 ...; ... i =@p <+... i ...+>; -@@ +@x@ identifier s.i; position s.p0; position p != r.p; diff --git a/tests/if.c b/tests/if.c new file mode 100644 index 0000000..b7204ae --- /dev/null +++ b/tests/if.c @@ -0,0 +1,28 @@ +int main () { + f(x); + g(x); +} + +int main1 () { + f(x); + if (x == NULL) { + g(x); + } +} + +int main1 () { + f(x); + while (x == NULL) { + if (q == 3) { + g(x); + } + } + x = 6; +} +int main2 () { + f(x); + if (x == NULL || y == 2) { + g(x); + } +} + diff --git a/tests/if.cocci b/tests/if.cocci new file mode 100644 index 0000000..b6bc92e --- /dev/null +++ b/tests/if.cocci @@ -0,0 +1,21 @@ +@exists@ +expression x; +statement S1,S2; +@@ + +f(x); ++ after(); + ... when != true x == NULL || ... +g(x); ++ after(); + +@exists@ +expression x; +statement S1,S2; +@@ + ++before(); +f(x); + ... when != false x == NULL || ... ++before(); +g(x); diff --git a/tests/if.res b/tests/if.res new file mode 100644 index 0000000..f5620ce --- /dev/null +++ b/tests/if.res @@ -0,0 +1,38 @@ +int main () { + before(); + f(x); + after(); + before(); + g(x); + after(); +} + +int main1 () { + before(); + f(x); + if (x == NULL) { + before(); + g(x); + } +} + +int main1 () { + before(); + f(x); + while (x == NULL) { + if (q == 3) { + before(); + g(x); + } + } + x = 6; +} +int main2 () { + before(); + f(x); + if (x == NULL || y == 2) { + before(); + g(x); + } +} + diff --git a/tests/substruct.c b/tests/substruct.c new file mode 100644 index 0000000..482fb12 --- /dev/null +++ b/tests/substruct.c @@ -0,0 +1,5 @@ +struct a { int a; } x[2] = +{ + { .a = 7, }, + { .a = 17, }, +}; diff --git a/tests/substruct.cocci b/tests/substruct.cocci new file mode 100644 index 0000000..b8b0eea --- /dev/null +++ b/tests/substruct.cocci @@ -0,0 +1,9 @@ +@@ +expression E; +@@ + +{ +- .a = E, ++ DECLARE_A(E), +} + diff --git a/tests/substruct.res b/tests/substruct.res new file mode 100644 index 0000000..861f6b2 --- /dev/null +++ b/tests/substruct.res @@ -0,0 +1,5 @@ +struct a { int a; } x[2] = +{ + { DECLARE_A(7), }, + { DECLARE_A(17), }, +}; diff --git a/tests/testifdef.c b/tests/testifdef.c new file mode 100644 index 0000000..b25972a --- /dev/null +++ b/tests/testifdef.c @@ -0,0 +1,2601 @@ +/* + * + * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400 + * + * (c) 1998-2002 Petr Vandrovec + * + * Portions Copyright (c) 2001 Matrox Graphics Inc. + * + * Version: 1.65 2002/08/14 + * + * MTRR stuff: 1998 Tom Rini + * + * Contributors: "menion?" + * Betatesting, fixes, ideas + * + * "Kurt Garloff" + * Betatesting, fixes, ideas, videomodes, videomodes timmings + * + * "Tom Rini" + * MTRR stuff, PPC cleanups, betatesting, fixes, ideas + * + * "Bibek Sahu" + * Access device through readb|w|l and write b|w|l + * Extensive debugging stuff + * + * "Daniel Haun" + * Testing, hardware cursor fixes + * + * "Scott Wood" + * Fixes + * + * "Gerd Knorr" + * Betatesting + * + * "Kelly French" + * "Fernando Herrera" + * Betatesting, bug reporting + * + * "Pablo Bianucci" + * Fixes, ideas, betatesting + * + * "Inaky Perez Gonzalez" + * Fixes, enhandcements, ideas, betatesting + * + * "Ryuichi Oikawa" + * PPC betatesting, PPC support, backward compatibility + * + * "Paul Womar" + * "Owen Waller" + * PPC betatesting + * + * "Thomas Pornin" + * Alpha betatesting + * + * "Pieter van Leuven" + * "Ulf Jaenicke-Roessler" + * G100 testing + * + * "H. Peter Arvin" + * Ideas + * + * "Cort Dougan" + * CHRP fixes and PReP cleanup + * + * "Mark Vojkovich" + * G400 support + * + * "Samuel Hocevar" + * Fixes + * + * "Anton Altaparmakov" + * G400 MAX/non-MAX distinction + * + * "Ken Aaker" + * memtype extension (needed for GXT130P RS/6000 adapter) + * + * "Uns Lider" + * G100 PLNWT fixes + * + * "Denis Zaitsev" + * Fixes + * + * "Mike Pieper" + * TVOut enhandcements, V4L2 control interface. + * + * "Diego Biurrun" + * DFP testing + * + * (following author is not in any relation with this code, but his code + * is included in this driver) + * + * Based on framebuffer driver for VBE 2.0 compliant graphic boards + * (c) 1998 Gerd Knorr + * + * (following author is not in any relation with this code, but his ideas + * were used when writing this driver) + * + * FreeVBE/AF (Matrox), "Shawn Hargreaves" + * + */ + +#include + +#define __OLD_VIDIOC_ + +#include "matroxfb_base.h" +#include "matroxfb_misc.h" +#include "matroxfb_accel.h" +#include "matroxfb_DAC1064.h" +#include "matroxfb_Ti3026.h" +#include "matroxfb_maven.h" +#include "matroxfb_crtc2.h" +#include "matroxfb_g450.h" +#include +#include +#include + +#ifdef CONFIG_PPC_PMAC +#include +unsigned char nvram_read_byte(int); +static int default_vmode = VMODE_NVRAM; +static int default_cmode = CMODE_NVRAM; +#endif + +static void matroxfb_unregister_device(struct matrox_fb_info* minfo); + +/* --------------------------------------------------------------------- */ + +/* + * card parameters + */ + +/* --------------------------------------------------------------------- */ + +static struct fb_var_screeninfo vesafb_defined = { + 640,480,640,480,/* W,H, W, H (virtual) load xres,xres_virtual*/ + 0,0, /* virtual -> visible no offset */ + 8, /* depth -> load bits_per_pixel */ + 0, /* greyscale ? */ + {0,0,0}, /* R */ + {0,0,0}, /* G */ + {0,0,0}, /* B */ + {0,0,0}, /* transparency */ + 0, /* standard pixel format */ + FB_ACTIVATE_NOW, + -1,-1, + FB_ACCELF_TEXT, /* accel flags */ + 39721L,48L,16L,33L,10L, + 96L,2L,~0, /* No sync info */ + FB_VMODE_NONINTERLACED, + 0, {0,0,0,0,0} +}; + + + +/* --------------------------------------------------------------------- */ +static void update_crtc2(WPMINFO unsigned int pos) { + struct matroxfb_dh_fb_info* info = ACCESS_FBINFO(crtc2.info); + + /* Make sure that displays are compatible */ + if (info && (info->fbcon.var.bits_per_pixel == ACCESS_FBINFO(fbcon).var.bits_per_pixel) + && (info->fbcon.var.xres_virtual == ACCESS_FBINFO(fbcon).var.xres_virtual) + && (info->fbcon.var.green.length == ACCESS_FBINFO(fbcon).var.green.length) + ) { + switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) { + case 16: + case 32: + pos = pos * 8; + if (info->interlaced) { + mga_outl(0x3C2C, pos); + mga_outl(0x3C28, pos + ACCESS_FBINFO(fbcon).var.xres_virtual * ACCESS_FBINFO(fbcon).var.bits_per_pixel / 8); + } else { + mga_outl(0x3C28, pos); + } + break; + } + } +} + +static void matroxfb_crtc1_panpos(WPMINFO2) { + if (ACCESS_FBINFO(crtc1.panpos) >= 0) { + unsigned long flags; + int panpos; + + matroxfb_DAC_lock_irqsave(flags); + panpos = ACCESS_FBINFO(crtc1.panpos); + if (panpos >= 0) { + unsigned int extvga_reg; + + ACCESS_FBINFO(crtc1.panpos) = -1; /* No update pending anymore */ + extvga_reg = mga_inb(M_EXTVGA_INDEX); + mga_setr(M_EXTVGA_INDEX, 0x00, panpos); + if (extvga_reg != 0x00) { + mga_outb(M_EXTVGA_INDEX, extvga_reg); + } + } + matroxfb_DAC_unlock_irqrestore(flags); + } +} + +static irqreturn_t matrox_irq(int irq, void *dev_id) +{ + u_int32_t status; + int handled = 0; + + MINFO_FROM(dev_id); + + status = mga_inl(M_STATUS); + + if (status & 0x20) { + mga_outl(M_ICLEAR, 0x20); + ACCESS_FBINFO(crtc1.vsync.cnt)++; + matroxfb_crtc1_panpos(PMINFO2); + wake_up_interruptible(&ACCESS_FBINFO(crtc1.vsync.wait)); + handled = 1; + } + if (status & 0x200) { + mga_outl(M_ICLEAR, 0x200); + ACCESS_FBINFO(crtc2.vsync.cnt)++; + wake_up_interruptible(&ACCESS_FBINFO(crtc2.vsync.wait)); + handled = 1; + } + return IRQ_RETVAL(handled); +} + +int matroxfb_enable_irq(WPMINFO int reenable) { + u_int32_t bm; + + if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) + bm = 0x220; + else + bm = 0x020; + + if (!test_and_set_bit(0, &ACCESS_FBINFO(irq_flags))) { + if (request_irq(ACCESS_FBINFO(pcidev)->irq, matrox_irq, + IRQF_SHARED, "matroxfb", MINFO)) { + clear_bit(0, &ACCESS_FBINFO(irq_flags)); + return -EINVAL; + } + /* Clear any pending field interrupts */ + mga_outl(M_ICLEAR, bm); + mga_outl(M_IEN, mga_inl(M_IEN) | bm); + } else if (reenable) { + u_int32_t ien; + + ien = mga_inl(M_IEN); + if ((ien & bm) != bm) { + printk(KERN_DEBUG "matroxfb: someone disabled IRQ [%08X]\n", ien); + mga_outl(M_IEN, ien | bm); + } + } + return 0; +} + +static void matroxfb_disable_irq(WPMINFO2) { + if (test_and_clear_bit(0, &ACCESS_FBINFO(irq_flags))) { + /* Flush pending pan-at-vbl request... */ + matroxfb_crtc1_panpos(PMINFO2); + if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) + mga_outl(M_IEN, mga_inl(M_IEN) & ~0x220); + else + mga_outl(M_IEN, mga_inl(M_IEN) & ~0x20); + free_irq(ACCESS_FBINFO(pcidev)->irq, MINFO); + } +} + +int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc) { + struct matrox_vsync *vs; + unsigned int cnt; + int ret; + + switch (crtc) { + case 0: + vs = &ACCESS_FBINFO(crtc1.vsync); + break; + case 1: + if (ACCESS_FBINFO(devflags.accelerator) != FB_ACCEL_MATROX_MGAG400) { + return -ENODEV; + } + vs = &ACCESS_FBINFO(crtc2.vsync); + break; + default: + return -ENODEV; + } + ret = matroxfb_enable_irq(PMINFO 0); + if (ret) { + return ret; + } + + cnt = vs->cnt; + ret = wait_event_interruptible_timeout(vs->wait, cnt != vs->cnt, HZ/10); + if (ret < 0) { + return ret; + } + if (ret == 0) { + matroxfb_enable_irq(PMINFO 1); + return -ETIMEDOUT; + } + return 0; +} + +/* --------------------------------------------------------------------- */ + +static void matrox_pan_var(WPMINFO struct fb_var_screeninfo *var) { + unsigned int pos; + unsigned short p0, p1, p2; +#ifdef CONFIG_FB_MATROX_32MB + unsigned int p3; +#endif + int vbl; + unsigned long flags; + + CRITFLAGS + + DBG(__FUNCTION__) + + if (ACCESS_FBINFO(dead)) + return; + + ACCESS_FBINFO(fbcon).var.xoffset = var->xoffset; + ACCESS_FBINFO(fbcon).var.yoffset = var->yoffset; + pos = (ACCESS_FBINFO(fbcon).var.yoffset * ACCESS_FBINFO(fbcon).var.xres_virtual + ACCESS_FBINFO(fbcon).var.xoffset) * ACCESS_FBINFO(curr.final_bppShift) / 32; + pos += ACCESS_FBINFO(curr.ydstorg.chunks); + p0 = ACCESS_FBINFO(hw).CRTC[0x0D] = pos & 0xFF; + p1 = ACCESS_FBINFO(hw).CRTC[0x0C] = (pos & 0xFF00) >> 8; + p2 = ACCESS_FBINFO(hw).CRTCEXT[0] = (ACCESS_FBINFO(hw).CRTCEXT[0] & 0xB0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40); +#ifdef CONFIG_FB_MATROX_32MB + p3 = ACCESS_FBINFO(hw).CRTCEXT[8] = pos >> 21; +#endif + + /* FB_ACTIVATE_VBL and we can acquire interrupts? Honor FB_ACTIVATE_VBL then... */ + vbl = (var->activate & FB_ACTIVATE_VBL) && (matroxfb_enable_irq(PMINFO 0) == 0); + + CRITBEGIN + + matroxfb_DAC_lock_irqsave(flags); + mga_setr(M_CRTC_INDEX, 0x0D, p0); + mga_setr(M_CRTC_INDEX, 0x0C, p1); +#ifdef CONFIG_FB_MATROX_32MB + if (ACCESS_FBINFO(devflags.support32MB)) + mga_setr(M_EXTVGA_INDEX, 0x08, p3); +#endif + if (vbl) { + ACCESS_FBINFO(crtc1.panpos) = p2; + } else { + /* Abort any pending change */ + ACCESS_FBINFO(crtc1.panpos) = -1; + mga_setr(M_EXTVGA_INDEX, 0x00, p2); + } + matroxfb_DAC_unlock_irqrestore(flags); + + update_crtc2(PMINFO pos); + + CRITEND +} + +static void matroxfb_remove(WPMINFO int dummy) { + /* Currently we are holding big kernel lock on all dead & usecount updates. + * Destroy everything after all users release it. Especially do not unregister + * framebuffer and iounmap memory, neither fbmem nor fbcon-cfb* does not check + * for device unplugged when in use. + * In future we should point mmio.vbase & video.vbase somewhere where we can + * write data without causing too much damage... + */ + + ACCESS_FBINFO(dead) = 1; + if (ACCESS_FBINFO(usecount)) { + /* destroy it later */ + return; + } + matroxfb_unregister_device(MINFO); + unregister_framebuffer(&ACCESS_FBINFO(fbcon)); + matroxfb_g450_shutdown(PMINFO2); +#ifdef CONFIG_MTRR + if (ACCESS_FBINFO(mtrr.vram_valid)) + mtrr_del(ACCESS_FBINFO(mtrr.vram), ACCESS_FBINFO(video.base), ACCESS_FBINFO(video.len)); +#endif + mga_iounmap(ACCESS_FBINFO(mmio.vbase)); + mga_iounmap(ACCESS_FBINFO(video.vbase)); + release_mem_region(ACCESS_FBINFO(video.base), ACCESS_FBINFO(video.len_maximum)); + release_mem_region(ACCESS_FBINFO(mmio.base), 16384); +#ifdef CONFIG_FB_MATROX_MULTIHEAD + kfree(minfo); +#endif +} + + /* + * Open/Release the frame buffer device + */ + +static int matroxfb_open(struct fb_info *info, int user) +{ + MINFO_FROM_INFO(info); + + DBG_LOOP(__FUNCTION__) + + if (ACCESS_FBINFO(dead)) { + return -ENXIO; + } + ACCESS_FBINFO(usecount)++; + if (user) { + ACCESS_FBINFO(userusecount)++; + } + return(0); +} + +static int matroxfb_release(struct fb_info *info, int user) +{ + MINFO_FROM_INFO(info); + + DBG_LOOP(__FUNCTION__) + + if (user) { + if (0 == --ACCESS_FBINFO(userusecount)) { + matroxfb_disable_irq(PMINFO2); + } + } + if (!(--ACCESS_FBINFO(usecount)) && ACCESS_FBINFO(dead)) { + matroxfb_remove(PMINFO 0); + } + return(0); +} + +static int matroxfb_pan_display(struct fb_var_screeninfo *var, + struct fb_info* info) { + MINFO_FROM_INFO(info); + + DBG(__FUNCTION__) + + matrox_pan_var(PMINFO var); + return 0; +} + +static int matroxfb_get_final_bppShift(CPMINFO int bpp) { + int bppshft2; + + DBG(__FUNCTION__) + + bppshft2 = bpp; + if (!bppshft2) { + return 8; + } + if (isInterleave(MINFO)) + bppshft2 >>= 1; + if (ACCESS_FBINFO(devflags.video64bits)) + bppshft2 >>= 1; + return bppshft2; +} + +static int matroxfb_test_and_set_rounding(CPMINFO int xres, int bpp) { + int over; + int rounding; + + DBG(__FUNCTION__) + + switch (bpp) { + case 0: return xres; + case 4: rounding = 128; + break; + case 8: rounding = 64; /* doc says 64; 32 is OK for G400 */ + break; + case 16: rounding = 32; + break; + case 24: rounding = 64; /* doc says 64; 32 is OK for G400 */ + break; + default: rounding = 16; + /* on G400, 16 really does not work */ + if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) + rounding = 32; + break; + } + if (isInterleave(MINFO)) { + rounding *= 2; + } + over = xres % rounding; + if (over) + xres += rounding-over; + return xres; +} + +static int matroxfb_pitch_adjust(CPMINFO int xres, int bpp) { + const int* width; + int xres_new; + + DBG(__FUNCTION__) + + if (!bpp) return xres; + + width = ACCESS_FBINFO(capable.vxres); + + if (ACCESS_FBINFO(devflags.precise_width)) { + while (*width) { + if ((*width >= xres) && (matroxfb_test_and_set_rounding(PMINFO *width, bpp) == *width)) { + break; + } + width++; + } + xres_new = *width; + } else { + xres_new = matroxfb_test_and_set_rounding(PMINFO xres, bpp); + } + return xres_new; +} + +static int matroxfb_get_cmap_len(struct fb_var_screeninfo *var) { + + DBG(__FUNCTION__) + + switch (var->bits_per_pixel) { + case 4: + return 16; /* pseudocolor... 16 entries HW palette */ + case 8: + return 256; /* pseudocolor... 256 entries HW palette */ + case 16: + return 16; /* directcolor... 16 entries SW palette */ + /* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */ + case 24: + return 16; /* directcolor... 16 entries SW palette */ + /* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */ + case 32: + return 16; /* directcolor... 16 entries SW palette */ + /* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */ + } + return 16; /* return something reasonable... or panic()? */ +} + +static int matroxfb_decode_var(CPMINFO struct fb_var_screeninfo *var, int *visual, int *video_cmap_len, unsigned int* ydstorg) { + struct RGBT { + unsigned char bpp; + struct { + unsigned char offset, + length; + } red, + green, + blue, + transp; + signed char visual; + }; + static const struct RGBT table[]= { + { 8,{ 0,8},{0,8},{0,8},{ 0,0},MX_VISUAL_PSEUDOCOLOR}, + {15,{10,5},{5,5},{0,5},{15,1},MX_VISUAL_DIRECTCOLOR}, + {16,{11,5},{5,6},{0,5},{ 0,0},MX_VISUAL_DIRECTCOLOR}, + {24,{16,8},{8,8},{0,8},{ 0,0},MX_VISUAL_DIRECTCOLOR}, + {32,{16,8},{8,8},{0,8},{24,8},MX_VISUAL_DIRECTCOLOR} + }; + struct RGBT const *rgbt; + unsigned int bpp = var->bits_per_pixel; + unsigned int vramlen; + unsigned int memlen; + + DBG(__FUNCTION__) + + switch (bpp) { + case 4: if (!ACCESS_FBINFO(capable.cfb4)) return -EINVAL; + break; + case 8: break; + case 16: break; + case 24: break; + case 32: break; + default: return -EINVAL; + } + *ydstorg = 0; + vramlen = ACCESS_FBINFO(video.len_usable); + if (var->yres_virtual < var->yres) + var->yres_virtual = var->yres; + if (var->xres_virtual < var->xres) + var->xres_virtual = var->xres; + + var->xres_virtual = matroxfb_pitch_adjust(PMINFO var->xres_virtual, bpp); + memlen = var->xres_virtual * bpp * var->yres_virtual / 8; + if (memlen > vramlen) { + var->yres_virtual = vramlen * 8 / (var->xres_virtual * bpp); + memlen = var->xres_virtual * bpp * var->yres_virtual / 8; + } + /* There is hardware bug that no line can cross 4MB boundary */ + /* give up for CFB24, it is impossible to easy workaround it */ + /* for other try to do something */ + if (!ACCESS_FBINFO(capable.cross4MB) && (memlen > 0x400000)) { + if (bpp == 24) { + /* sorry */ + } else { + unsigned int linelen; + unsigned int m1 = linelen = var->xres_virtual * bpp / 8; + unsigned int m2 = PAGE_SIZE; /* or 128 if you do not need PAGE ALIGNED address */ + unsigned int max_yres; + + while (m1) { + int t; + + while (m2 >= m1) m2 -= m1; + t = m1; + m1 = m2; + m2 = t; + } + m2 = linelen * PAGE_SIZE / m2; + *ydstorg = m2 = 0x400000 % m2; + max_yres = (vramlen - m2) / linelen; + if (var->yres_virtual > max_yres) + var->yres_virtual = max_yres; + } + } + /* YDSTLEN contains only signed 16bit value */ + if (var->yres_virtual > 32767) + var->yres_virtual = 32767; + /* we must round yres/xres down, we already rounded y/xres_virtual up + if it was possible. We should return -EINVAL, but I disagree */ + if (var->yres_virtual < var->yres) + var->yres = var->yres_virtual; + if (var->xres_virtual < var->xres) + var->xres = var->xres_virtual; + if (var->xoffset + var->xres > var->xres_virtual) + var->xoffset = var->xres_virtual - var->xres; + if (var->yoffset + var->yres > var->yres_virtual) + var->yoffset = var->yres_virtual - var->yres; + + if (bpp == 16 && var->green.length == 5) { + bpp--; /* an artifical value - 15 */ + } + + for (rgbt = table; rgbt->bpp < bpp; rgbt++); +#define SETCLR(clr)\ + var->clr.offset = rgbt->clr.offset;\ + var->clr.length = rgbt->clr.length + SETCLR(red); + SETCLR(green); + SETCLR(blue); + SETCLR(transp); +#undef SETCLR + *visual = rgbt->visual; + + if (bpp > 8) + dprintk("matroxfb: truecolor: " + "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n", + var->transp.length, var->red.length, var->green.length, var->blue.length, + var->transp.offset, var->red.offset, var->green.offset, var->blue.offset); + + *video_cmap_len = matroxfb_get_cmap_len(var); + dprintk(KERN_INFO "requested %d*%d/%dbpp (%d*%d)\n", var->xres, var->yres, var->bits_per_pixel, + var->xres_virtual, var->yres_virtual); + return 0; +} + +static int matroxfb_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, + struct fb_info *fb_info) +{ +#ifdef CONFIG_FB_MATROX_MULTIHEAD + struct matrox_fb_info* minfo = container_of(fb_info, struct matrox_fb_info, fbcon); +#endif + + DBG(__FUNCTION__) + + /* + * Set a single color register. The values supplied are + * already rounded down to the hardware's capabilities + * (according to the entries in the `var' structure). Return + * != 0 for invalid regno. + */ + + if (regno >= ACCESS_FBINFO(curr.cmap_len)) + return 1; + + if (ACCESS_FBINFO(fbcon).var.grayscale) { + /* gray = 0.30*R + 0.59*G + 0.11*B */ + red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; + } + + red = CNVT_TOHW(red, ACCESS_FBINFO(fbcon).var.red.length); + green = CNVT_TOHW(green, ACCESS_FBINFO(fbcon).var.green.length); + blue = CNVT_TOHW(blue, ACCESS_FBINFO(fbcon).var.blue.length); + transp = CNVT_TOHW(transp, ACCESS_FBINFO(fbcon).var.transp.length); + + switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) { + case 4: + case 8: + mga_outb(M_DAC_REG, regno); + mga_outb(M_DAC_VAL, red); + mga_outb(M_DAC_VAL, green); + mga_outb(M_DAC_VAL, blue); + break; + case 16: + if (regno >= 16) + break; + { + u_int16_t col = + (red << ACCESS_FBINFO(fbcon).var.red.offset) | + (green << ACCESS_FBINFO(fbcon).var.green.offset) | + (blue << ACCESS_FBINFO(fbcon).var.blue.offset) | + (transp << ACCESS_FBINFO(fbcon).var.transp.offset); /* for 1:5:5:5 */ + ACCESS_FBINFO(cmap[regno]) = col | (col << 16); + } + break; + case 24: + case 32: + if (regno >= 16) + break; + ACCESS_FBINFO(cmap[regno]) = + (red << ACCESS_FBINFO(fbcon).var.red.offset) | + (green << ACCESS_FBINFO(fbcon).var.green.offset) | + (blue << ACCESS_FBINFO(fbcon).var.blue.offset) | + (transp << ACCESS_FBINFO(fbcon).var.transp.offset); /* 8:8:8:8 */ + break; + } + return 0; +} + +static void matroxfb_init_fix(WPMINFO2) +{ + struct fb_fix_screeninfo *fix = &ACCESS_FBINFO(fbcon).fix; + DBG(__FUNCTION__) + + strcpy(fix->id,"MATROX"); + + fix->xpanstep = 8; /* 8 for 8bpp, 4 for 16bpp, 2 for 32bpp */ + fix->ypanstep = 1; + fix->ywrapstep = 0; + fix->mmio_start = ACCESS_FBINFO(mmio.base); + fix->mmio_len = ACCESS_FBINFO(mmio.len); + fix->accel = ACCESS_FBINFO(devflags.accelerator); +} + +static void matroxfb_update_fix(WPMINFO2) +{ + struct fb_fix_screeninfo *fix = &ACCESS_FBINFO(fbcon).fix; + DBG(__FUNCTION__) + + fix->smem_start = ACCESS_FBINFO(video.base) + ACCESS_FBINFO(curr.ydstorg.bytes); + fix->smem_len = ACCESS_FBINFO(video.len_usable) - ACCESS_FBINFO(curr.ydstorg.bytes); +} + +static int matroxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) +{ + int err; + int visual; + int cmap_len; + unsigned int ydstorg; + MINFO_FROM_INFO(info); + + if (ACCESS_FBINFO(dead)) { + return -ENXIO; + } + if ((err = matroxfb_decode_var(PMINFO var, &visual, &cmap_len, &ydstorg)) != 0) + return err; + return 0; +} + +static int matroxfb_set_par(struct fb_info *info) +{ + int err; + int visual; + int cmap_len; + unsigned int ydstorg; + struct fb_var_screeninfo *var; + MINFO_FROM_INFO(info); + + DBG(__FUNCTION__) + + if (ACCESS_FBINFO(dead)) { + return -ENXIO; + } + + var = &info->var; + if ((err = matroxfb_decode_var(PMINFO var, &visual, &cmap_len, &ydstorg)) != 0) + return err; + ACCESS_FBINFO(fbcon.screen_base) = vaddr_va(ACCESS_FBINFO(video.vbase)) + ydstorg; + matroxfb_update_fix(PMINFO2); + ACCESS_FBINFO(fbcon).fix.visual = visual; + ACCESS_FBINFO(fbcon).fix.type = FB_TYPE_PACKED_PIXELS; + ACCESS_FBINFO(fbcon).fix.type_aux = 0; + ACCESS_FBINFO(fbcon).fix.line_length = (var->xres_virtual * var->bits_per_pixel) >> 3; + { + unsigned int pos; + + ACCESS_FBINFO(curr.cmap_len) = cmap_len; + ydstorg += ACCESS_FBINFO(devflags.ydstorg); + ACCESS_FBINFO(curr.ydstorg.bytes) = ydstorg; + ACCESS_FBINFO(curr.ydstorg.chunks) = ydstorg >> (isInterleave(MINFO)?3:2); + if (var->bits_per_pixel == 4) + ACCESS_FBINFO(curr.ydstorg.pixels) = ydstorg; + else + ACCESS_FBINFO(curr.ydstorg.pixels) = (ydstorg * 8) / var->bits_per_pixel; + ACCESS_FBINFO(curr.final_bppShift) = matroxfb_get_final_bppShift(PMINFO var->bits_per_pixel); + { struct my_timming mt; + struct matrox_hw_state* hw; + int out; + + matroxfb_var2my(var, &mt); + mt.crtc = MATROXFB_SRC_CRTC1; + /* CRTC1 delays */ + switch (var->bits_per_pixel) { + case 0: mt.delay = 31 + 0; break; + case 16: mt.delay = 21 + 8; break; + case 24: mt.delay = 17 + 8; break; + case 32: mt.delay = 16 + 8; break; + default: mt.delay = 31 + 8; break; + } + + hw = &ACCESS_FBINFO(hw); + + down_read(&ACCESS_FBINFO(altout).lock); + for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { + if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC1 && + ACCESS_FBINFO(outputs[out]).output->compute) { + ACCESS_FBINFO(outputs[out]).output->compute(ACCESS_FBINFO(outputs[out]).data, &mt); + } + } + up_read(&ACCESS_FBINFO(altout).lock); + ACCESS_FBINFO(crtc1).pixclock = mt.pixclock; + ACCESS_FBINFO(crtc1).mnp = mt.mnp; + ACCESS_FBINFO(hw_switch->init(PMINFO &mt)); + pos = (var->yoffset * var->xres_virtual + var->xoffset) * ACCESS_FBINFO(curr.final_bppShift) / 32; + pos += ACCESS_FBINFO(curr.ydstorg.chunks); + + hw->CRTC[0x0D] = pos & 0xFF; + hw->CRTC[0x0C] = (pos & 0xFF00) >> 8; + hw->CRTCEXT[0] = (hw->CRTCEXT[0] & 0xF0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40); + hw->CRTCEXT[8] = pos >> 21; + ACCESS_FBINFO(hw_switch->restore(PMINFO2)); + update_crtc2(PMINFO pos); + down_read(&ACCESS_FBINFO(altout).lock); + for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { + if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC1 && + ACCESS_FBINFO(outputs[out]).output->program) { + ACCESS_FBINFO(outputs[out]).output->program(ACCESS_FBINFO(outputs[out]).data); + } + } + for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) { + if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC1 && + ACCESS_FBINFO(outputs[out]).output->start) { + ACCESS_FBINFO(outputs[out]).output->start(ACCESS_FBINFO(outputs[out]).data); + } + } + up_read(&ACCESS_FBINFO(altout).lock); + matrox_cfbX_init(PMINFO2); + } + } + ACCESS_FBINFO(initialized) = 1; + return 0; +} + +static int matroxfb_get_vblank(WPMINFO struct fb_vblank *vblank) +{ + unsigned int sts1; + + matroxfb_enable_irq(PMINFO 0); + memset(vblank, 0, sizeof(*vblank)); + vblank->flags = FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VSYNC | + FB_VBLANK_HAVE_VBLANK | FB_VBLANK_HAVE_HBLANK; + sts1 = mga_inb(M_INSTS1); + vblank->vcount = mga_inl(M_VCOUNT); + /* BTW, on my PIII/450 with G400, reading M_INSTS1 + byte makes this call about 12% slower (1.70 vs. 2.05 us + per ioctl()) */ + if (sts1 & 1) + vblank->flags |= FB_VBLANK_HBLANKING; + if (sts1 & 8) + vblank->flags |= FB_VBLANK_VSYNCING; + if (vblank->vcount >= ACCESS_FBINFO(fbcon).var.yres) + vblank->flags |= FB_VBLANK_VBLANKING; + if (test_bit(0, &ACCESS_FBINFO(irq_flags))) { + vblank->flags |= FB_VBLANK_HAVE_COUNT; + /* Only one writer, aligned int value... + it should work without lock and without atomic_t */ + vblank->count = ACCESS_FBINFO(crtc1).vsync.cnt; + } + return 0; +} + +static struct matrox_altout panellink_output = { + .name = "Panellink output", +}; + +static int matroxfb_ioctl(struct fb_info *info, + unsigned int cmd, unsigned long arg) +{ + void __user *argp = (void __user *)arg; + MINFO_FROM_INFO(info); + + DBG(__FUNCTION__) + + if (ACCESS_FBINFO(dead)) { + return -ENXIO; + } + + switch (cmd) { + case FBIOGET_VBLANK: + { + struct fb_vblank vblank; + int err; + + err = matroxfb_get_vblank(PMINFO &vblank); + if (err) + return err; + if (copy_to_user(argp, &vblank, sizeof(vblank))) + return -EFAULT; + return 0; + } + case FBIO_WAITFORVSYNC: + { + u_int32_t crt; + + if (get_user(crt, (u_int32_t __user *)arg)) + return -EFAULT; + + return matroxfb_wait_for_sync(PMINFO crt); + } + case MATROXFB_SET_OUTPUT_MODE: + { + struct matroxioc_output_mode mom; + struct matrox_altout *oproc; + int val; + + if (copy_from_user(&mom, argp, sizeof(mom))) + return -EFAULT; + if (mom.output >= MATROXFB_MAX_OUTPUTS) + return -ENXIO; + down_read(&ACCESS_FBINFO(altout.lock)); + oproc = ACCESS_FBINFO(outputs[mom.output]).output; + if (!oproc) { + val = -ENXIO; + } else if (!oproc->verifymode) { + if (mom.mode == MATROXFB_OUTPUT_MODE_MONITOR) { + val = 0; + } else { + val = -EINVAL; + } + } else { + val = oproc->verifymode(ACCESS_FBINFO(outputs[mom.output]).data, mom.mode); + } + if (!val) { + if (ACCESS_FBINFO(outputs[mom.output]).mode != mom.mode) { + ACCESS_FBINFO(outputs[mom.output]).mode = mom.mode; + val = 1; + } + } + up_read(&ACCESS_FBINFO(altout.lock)); + if (val != 1) + return val; + switch (ACCESS_FBINFO(outputs[mom.output]).src) { + case MATROXFB_SRC_CRTC1: + matroxfb_set_par(info); + break; + case MATROXFB_SRC_CRTC2: + { + struct matroxfb_dh_fb_info* crtc2; + + down_read(&ACCESS_FBINFO(crtc2.lock)); + crtc2 = ACCESS_FBINFO(crtc2.info); + if (crtc2) + crtc2->fbcon.fbops->fb_set_par(&crtc2->fbcon); + up_read(&ACCESS_FBINFO(crtc2.lock)); + } + break; + } + return 0; + } + case MATROXFB_GET_OUTPUT_MODE: + { + struct matroxioc_output_mode mom; + struct matrox_altout *oproc; + int val; + + if (copy_from_user(&mom, argp, sizeof(mom))) + return -EFAULT; + if (mom.output >= MATROXFB_MAX_OUTPUTS) + return -ENXIO; + down_read(&ACCESS_FBINFO(altout.lock)); + oproc = ACCESS_FBINFO(outputs[mom.output]).output; + if (!oproc) { + val = -ENXIO; + } else { + mom.mode = ACCESS_FBINFO(outputs[mom.output]).mode; + val = 0; + } + up_read(&ACCESS_FBINFO(altout.lock)); + if (val) + return val; + if (copy_to_user(argp, &mom, sizeof(mom))) + return -EFAULT; + return 0; + } + case MATROXFB_SET_OUTPUT_CONNECTION: + { + u_int32_t tmp; + int i; + int changes; + + if (copy_from_user(&tmp, argp, sizeof(tmp))) + return -EFAULT; + for (i = 0; i < 32; i++) { + if (tmp & (1 << i)) { + if (i >= MATROXFB_MAX_OUTPUTS) + return -ENXIO; + if (!ACCESS_FBINFO(outputs[i]).output) + return -ENXIO; + switch (ACCESS_FBINFO(outputs[i]).src) { + case MATROXFB_SRC_NONE: + case MATROXFB_SRC_CRTC1: + break; + default: + return -EBUSY; + } + } + } + if (ACCESS_FBINFO(devflags.panellink)) { + if (tmp & MATROXFB_OUTPUT_CONN_DFP) { + if (tmp & MATROXFB_OUTPUT_CONN_SECONDARY) + return -EINVAL; + for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { + if (ACCESS_FBINFO(outputs[i]).src == MATROXFB_SRC_CRTC2) { + return -EBUSY; + } + } + } + } + changes = 0; + for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { + if (tmp & (1 << i)) { + if (ACCESS_FBINFO(outputs[i]).src != MATROXFB_SRC_CRTC1) { + changes = 1; + ACCESS_FBINFO(outputs[i]).src = MATROXFB_SRC_CRTC1; + } + } else if (ACCESS_FBINFO(outputs[i]).src == MATROXFB_SRC_CRTC1) { + changes = 1; + ACCESS_FBINFO(outputs[i]).src = MATROXFB_SRC_NONE; + } + } + if (!changes) + return 0; + matroxfb_set_par(info); + return 0; + } + case MATROXFB_GET_OUTPUT_CONNECTION: + { + u_int32_t conn = 0; + int i; + + for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { + if (ACCESS_FBINFO(outputs[i]).src == MATROXFB_SRC_CRTC1) { + conn |= 1 << i; + } + } + if (put_user(conn, (u_int32_t __user *)arg)) + return -EFAULT; + return 0; + } + case MATROXFB_GET_AVAILABLE_OUTPUTS: + { + u_int32_t conn = 0; + int i; + + for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { + if (ACCESS_FBINFO(outputs[i]).output) { + switch (ACCESS_FBINFO(outputs[i]).src) { + case MATROXFB_SRC_NONE: + case MATROXFB_SRC_CRTC1: + conn |= 1 << i; + break; + } + } + } + if (ACCESS_FBINFO(devflags.panellink)) { + if (conn & MATROXFB_OUTPUT_CONN_DFP) + conn &= ~MATROXFB_OUTPUT_CONN_SECONDARY; + if (conn & MATROXFB_OUTPUT_CONN_SECONDARY) + conn &= ~MATROXFB_OUTPUT_CONN_DFP; + } + if (put_user(conn, (u_int32_t __user *)arg)) + return -EFAULT; + return 0; + } + case MATROXFB_GET_ALL_OUTPUTS: + { + u_int32_t conn = 0; + int i; + + for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { + if (ACCESS_FBINFO(outputs[i]).output) { + conn |= 1 << i; + } + } + if (put_user(conn, (u_int32_t __user *)arg)) + return -EFAULT; + return 0; + } + case VIDIOC_QUERYCAP: + { + struct v4l2_capability r; + + memset(&r, 0, sizeof(r)); + strcpy(r.driver, "matroxfb"); + strcpy(r.card, "Matrox"); + sprintf(r.bus_info, "PCI:%s", pci_name(ACCESS_FBINFO(pcidev))); + r.version = KERNEL_VERSION(1,0,0); + r.capabilities = V4L2_CAP_VIDEO_OUTPUT; + if (copy_to_user(argp, &r, sizeof(r))) + return -EFAULT; + return 0; + + } + case VIDIOC_QUERYCTRL: + { + struct v4l2_queryctrl qctrl; + int err; + + if (copy_from_user(&qctrl, argp, sizeof(qctrl))) + return -EFAULT; + + down_read(&ACCESS_FBINFO(altout).lock); + if (!ACCESS_FBINFO(outputs[1]).output) { + err = -ENXIO; + } else if (ACCESS_FBINFO(outputs[1]).output->getqueryctrl) { + err = ACCESS_FBINFO(outputs[1]).output->getqueryctrl(ACCESS_FBINFO(outputs[1]).data, &qctrl); + } else { + err = -EINVAL; + } + up_read(&ACCESS_FBINFO(altout).lock); + if (err >= 0 && + copy_to_user(argp, &qctrl, sizeof(qctrl))) + return -EFAULT; + return err; + } + case VIDIOC_G_CTRL: + { + struct v4l2_control ctrl; + int err; + + if (copy_from_user(&ctrl, argp, sizeof(ctrl))) + return -EFAULT; + + down_read(&ACCESS_FBINFO(altout).lock); + if (!ACCESS_FBINFO(outputs[1]).output) { + err = -ENXIO; + } else if (ACCESS_FBINFO(outputs[1]).output->getctrl) { + err = ACCESS_FBINFO(outputs[1]).output->getctrl(ACCESS_FBINFO(outputs[1]).data, &ctrl); + } else { + err = -EINVAL; + } + up_read(&ACCESS_FBINFO(altout).lock); + if (err >= 0 && + copy_to_user(argp, &ctrl, sizeof(ctrl))) + return -EFAULT; + return err; + } + case VIDIOC_S_CTRL_OLD: + case VIDIOC_S_CTRL: + { + struct v4l2_control ctrl; + int err; + + if (copy_from_user(&ctrl, argp, sizeof(ctrl))) + return -EFAULT; + + down_read(&ACCESS_FBINFO(altout).lock); + if (!ACCESS_FBINFO(outputs[1]).output) { + err = -ENXIO; + } else if (ACCESS_FBINFO(outputs[1]).output->setctrl) { + err = ACCESS_FBINFO(outputs[1]).output->setctrl(ACCESS_FBINFO(outputs[1]).data, &ctrl); + } else { + err = -EINVAL; + } + up_read(&ACCESS_FBINFO(altout).lock); + return err; + } + } + return -ENOTTY; +} + +/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */ + +static int matroxfb_blank(int blank, struct fb_info *info) +{ + int seq; + int crtc; + CRITFLAGS + MINFO_FROM_INFO(info); + + DBG(__FUNCTION__) + + if (ACCESS_FBINFO(dead)) + return 1; + + switch (blank) { + case FB_BLANK_NORMAL: seq = 0x20; crtc = 0x00; break; /* works ??? */ + case FB_BLANK_VSYNC_SUSPEND: seq = 0x20; crtc = 0x10; break; + case FB_BLANK_HSYNC_SUSPEND: seq = 0x20; crtc = 0x20; break; + case FB_BLANK_POWERDOWN: seq = 0x20; crtc = 0x30; break; + default: seq = 0x00; crtc = 0x00; break; + } + + CRITBEGIN + + mga_outb(M_SEQ_INDEX, 1); + mga_outb(M_SEQ_DATA, (mga_inb(M_SEQ_DATA) & ~0x20) | seq); + mga_outb(M_EXTVGA_INDEX, 1); + mga_outb(M_EXTVGA_DATA, (mga_inb(M_EXTVGA_DATA) & ~0x30) | crtc); + + CRITEND + return 0; +} + +static struct fb_ops matroxfb_ops = { + .owner = THIS_MODULE, + .fb_open = matroxfb_open, + .fb_release = matroxfb_release, + .fb_check_var = matroxfb_check_var, + .fb_set_par = matroxfb_set_par, + .fb_setcolreg = matroxfb_setcolreg, + .fb_pan_display =matroxfb_pan_display, + .fb_blank = matroxfb_blank, + .fb_ioctl = matroxfb_ioctl, +/* .fb_fillrect = , */ +/* .fb_copyarea = , */ +/* .fb_imageblit = , */ +/* .fb_cursor = , */ +}; + +#define RSDepth(X) (((X) >> 8) & 0x0F) +#define RS8bpp 0x1 +#define RS15bpp 0x2 +#define RS16bpp 0x3 +#define RS32bpp 0x4 +#define RS4bpp 0x5 +#define RS24bpp 0x6 +#define RSText 0x7 +#define RSText8 0x8 +/* 9-F */ +static struct { struct fb_bitfield red, green, blue, transp; int bits_per_pixel; } colors[] = { + { { 0, 8, 0}, { 0, 8, 0}, { 0, 8, 0}, { 0, 0, 0}, 8 }, + { { 10, 5, 0}, { 5, 5, 0}, { 0, 5, 0}, { 15, 1, 0}, 16 }, + { { 11, 5, 0}, { 5, 6, 0}, { 0, 5, 0}, { 0, 0, 0}, 16 }, + { { 16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, { 24, 8, 0}, 32 }, + { { 0, 8, 0}, { 0, 8, 0}, { 0, 8, 0}, { 0, 0, 0}, 4 }, + { { 16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, { 0, 0, 0}, 24 }, + { { 0, 6, 0}, { 0, 6, 0}, { 0, 6, 0}, { 0, 0, 0}, 0 }, /* textmode with (default) VGA8x16 */ + { { 0, 6, 0}, { 0, 6, 0}, { 0, 6, 0}, { 0, 0, 0}, 0 }, /* textmode hardwired to VGA8x8 */ +}; + +/* initialized by setup, see explanation at end of file (search for MODULE_PARM_DESC) */ +static unsigned int mem; /* "matrox:mem:xxxxxM" */ +static int option_precise_width = 1; /* cannot be changed, option_precise_width==0 must imply noaccel */ +static int inv24; /* "matrox:inv24" */ +static int cross4MB = -1; /* "matrox:cross4MB" */ +static int disabled; /* "matrox:disabled" */ +static int noaccel; /* "matrox:noaccel" */ +static int nopan; /* "matrox:nopan" */ +static int no_pci_retry; /* "matrox:nopciretry" */ +static int novga; /* "matrox:novga" */ +static int nobios; /* "matrox:nobios" */ +static int noinit = 1; /* "matrox:init" */ +static int inverse; /* "matrox:inverse" */ +static int sgram; /* "matrox:sgram" */ +#ifdef CONFIG_MTRR +static int mtrr = 1; /* "matrox:nomtrr" */ +#endif +static int grayscale; /* "matrox:grayscale" */ +static int dev = -1; /* "matrox:dev:xxxxx" */ +static unsigned int vesa = ~0; /* "matrox:vesa:xxxxx" */ +static int depth = -1; /* "matrox:depth:xxxxx" */ +static unsigned int xres; /* "matrox:xres:xxxxx" */ +static unsigned int yres; /* "matrox:yres:xxxxx" */ +static unsigned int upper = ~0; /* "matrox:upper:xxxxx" */ +static unsigned int lower = ~0; /* "matrox:lower:xxxxx" */ +static unsigned int vslen; /* "matrox:vslen:xxxxx" */ +static unsigned int left = ~0; /* "matrox:left:xxxxx" */ +static unsigned int right = ~0; /* "matrox:right:xxxxx" */ +static unsigned int hslen; /* "matrox:hslen:xxxxx" */ +static unsigned int pixclock; /* "matrox:pixclock:xxxxx" */ +static int sync = -1; /* "matrox:sync:xxxxx" */ +static unsigned int fv; /* "matrox:fv:xxxxx" */ +static unsigned int fh; /* "matrox:fh:xxxxxk" */ +static unsigned int maxclk; /* "matrox:maxclk:xxxxM" */ +static int dfp; /* "matrox:dfp */ +static int dfp_type = -1; /* "matrox:dfp:xxx */ +static int memtype = -1; /* "matrox:memtype:xxx" */ +static char outputs[8]; /* "matrox:outputs:xxx" */ + +#ifndef MODULE +static char videomode[64]; /* "matrox:mode:xxxxx" or "matrox:xxxxx" */ +#endif + +static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSize){ + vaddr_t vm; + unsigned int offs; + unsigned int offs2; + unsigned char orig; + unsigned char bytes[32]; + unsigned char* tmp; + + DBG(__FUNCTION__) + + vm = ACCESS_FBINFO(video.vbase); + maxSize &= ~0x1FFFFF; /* must be X*2MB (really it must be 2 or X*4MB) */ + /* at least 2MB */ + if (maxSize < 0x0200000) return 0; + if (maxSize > 0x2000000) maxSize = 0x2000000; + + mga_outb(M_EXTVGA_INDEX, 0x03); + orig = mga_inb(M_EXTVGA_DATA); + mga_outb(M_EXTVGA_DATA, orig | 0x80); + + tmp = bytes; + for (offs = 0x100000; offs < maxSize; offs += 0x200000) + *tmp++ = mga_readb(vm, offs); + for (offs = 0x100000; offs < maxSize; offs += 0x200000) + mga_writeb(vm, offs, 0x02); + mga_outb(M_CACHEFLUSH, 0x00); + for (offs = 0x100000; offs < maxSize; offs += 0x200000) { + if (mga_readb(vm, offs) != 0x02) + break; + mga_writeb(vm, offs, mga_readb(vm, offs) - 0x02); + if (mga_readb(vm, offs)) + break; + } + tmp = bytes; + for (offs2 = 0x100000; offs2 < maxSize; offs2 += 0x200000) + mga_writeb(vm, offs2, *tmp++); + + mga_outb(M_EXTVGA_INDEX, 0x03); + mga_outb(M_EXTVGA_DATA, orig); + + *realSize = offs - 0x100000; +#ifdef CONFIG_FB_MATROX_MILLENIUM + ACCESS_FBINFO(interleave) = !(!isMillenium(MINFO) || ((offs - 0x100000) & 0x3FFFFF)); +#endif + return 1; +} + +struct video_board { + int maxvram; + int maxdisplayable; + int accelID; + struct matrox_switch* lowlevel; + }; +#ifdef CONFIG_FB_MATROX_MILLENIUM +static struct video_board vbMillennium = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGA2064W, &matrox_millennium}; +static struct video_board vbMillennium2 = {0x1000000, 0x0800000, FB_ACCEL_MATROX_MGA2164W, &matrox_millennium}; +static struct video_board vbMillennium2A = {0x1000000, 0x0800000, FB_ACCEL_MATROX_MGA2164W_AGP, &matrox_millennium}; +#endif /* CONFIG_FB_MATROX_MILLENIUM */ +#ifdef CONFIG_FB_MATROX_MYSTIQUE +static struct video_board vbMystique = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGA1064SG, &matrox_mystique}; +#endif /* CONFIG_FB_MATROX_MYSTIQUE */ +#ifdef CONFIG_FB_MATROX_G +static struct video_board vbG100 = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGAG100, &matrox_G100}; +static struct video_board vbG200 = {0x1000000, 0x1000000, FB_ACCEL_MATROX_MGAG200, &matrox_G100}; +#ifdef CONFIG_FB_MATROX_32MB +/* from doc it looks like that accelerator can draw only to low 16MB :-( Direct accesses & displaying are OK for + whole 32MB */ +static struct video_board vbG400 = {0x2000000, 0x1000000, FB_ACCEL_MATROX_MGAG400, &matrox_G100}; +#else +static struct video_board vbG400 = {0x2000000, 0x1000000, FB_ACCEL_MATROX_MGAG400, &matrox_G100}; +#endif +#endif + +#define DEVF_VIDEO64BIT 0x0001 +#define DEVF_SWAPS 0x0002 +#define DEVF_SRCORG 0x0004 +#define DEVF_DUALHEAD 0x0008 +#define DEVF_CROSS4MB 0x0010 +#define DEVF_TEXT4B 0x0020 +/* #define DEVF_recycled 0x0040 */ +/* #define DEVF_recycled 0x0080 */ +#define DEVF_SUPPORT32MB 0x0100 +#define DEVF_ANY_VXRES 0x0200 +#define DEVF_TEXT16B 0x0400 +#define DEVF_CRTC2 0x0800 +#define DEVF_MAVEN_CAPABLE 0x1000 +#define DEVF_PANELLINK_CAPABLE 0x2000 +#define DEVF_G450DAC 0x4000 + +#define DEVF_GCORE (DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB) +#define DEVF_G2CORE (DEVF_GCORE | DEVF_ANY_VXRES | DEVF_MAVEN_CAPABLE | DEVF_PANELLINK_CAPABLE | DEVF_SRCORG | DEVF_DUALHEAD) +#define DEVF_G100 (DEVF_GCORE) /* no doc, no vxres... */ +#define DEVF_G200 (DEVF_G2CORE) +#define DEVF_G400 (DEVF_G2CORE | DEVF_SUPPORT32MB | DEVF_TEXT16B | DEVF_CRTC2) +/* if you'll find how to drive DFP... */ +#define DEVF_G450 (DEVF_GCORE | DEVF_ANY_VXRES | DEVF_SUPPORT32MB | DEVF_TEXT16B | DEVF_CRTC2 | DEVF_G450DAC | DEVF_SRCORG | DEVF_DUALHEAD) +#define DEVF_G550 (DEVF_G450) + +static struct board { + unsigned short vendor, device, rev, svid, sid; + unsigned int flags; + unsigned int maxclk; + enum mga_chip chip; + struct video_board* base; + const char* name; + } dev_list[] = { +#ifdef CONFIG_FB_MATROX_MILLENIUM + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL, 0xFF, + 0, 0, + DEVF_TEXT4B, + 230000, + MGA_2064, + &vbMillennium, + "Millennium (PCI)"}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL_2, 0xFF, + 0, 0, + DEVF_SWAPS, + 220000, + MGA_2164, + &vbMillennium2, + "Millennium II (PCI)"}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL_2_AGP, 0xFF, + 0, 0, + DEVF_SWAPS, + 250000, + MGA_2164, + &vbMillennium2A, + "Millennium II (AGP)"}, +#endif +#ifdef CONFIG_FB_MATROX_MYSTIQUE + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MYS, 0x02, + 0, 0, + DEVF_VIDEO64BIT | DEVF_CROSS4MB, + 180000, + MGA_1064, + &vbMystique, + "Mystique (PCI)"}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MYS, 0xFF, + 0, 0, + DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB, + 220000, + MGA_1164, + &vbMystique, + "Mystique 220 (PCI)"}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MYS_AGP, 0x02, + 0, 0, + DEVF_VIDEO64BIT | DEVF_CROSS4MB, + 180000, + MGA_1064, + &vbMystique, + "Mystique (AGP)"}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MYS_AGP, 0xFF, + 0, 0, + DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB, + 220000, + MGA_1164, + &vbMystique, + "Mystique 220 (AGP)"}, +#endif +#ifdef CONFIG_FB_MATROX_G + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_MM, 0xFF, + 0, 0, + DEVF_G100, + 230000, + MGA_G100, + &vbG100, + "MGA-G100 (PCI)"}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, 0xFF, + 0, 0, + DEVF_G100, + 230000, + MGA_G100, + &vbG100, + "MGA-G100 (AGP)"}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, 0xFF, + 0, 0, + DEVF_G200, + 250000, + MGA_G200, + &vbG200, + "MGA-G200 (PCI)"}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF, + PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_GENERIC, + DEVF_G200, + 220000, + MGA_G200, + &vbG200, + "MGA-G200 (AGP)"}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF, + PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MYSTIQUE_G200_AGP, + DEVF_G200, + 230000, + MGA_G200, + &vbG200, + "Mystique G200 (AGP)"}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF, + PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MILLENIUM_G200_AGP, + DEVF_G200, + 250000, + MGA_G200, + &vbG200, + "Millennium G200 (AGP)"}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF, + PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MARVEL_G200_AGP, + DEVF_G200, + 230000, + MGA_G200, + &vbG200, + "Marvel G200 (AGP)"}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF, + PCI_SS_VENDOR_ID_SIEMENS_NIXDORF, PCI_SS_ID_SIEMENS_MGA_G200_AGP, + DEVF_G200, + 230000, + MGA_G200, + &vbG200, + "MGA-G200 (AGP)"}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF, + 0, 0, + DEVF_G200, + 230000, + MGA_G200, + &vbG200, + "G200 (AGP)"}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400, 0x80, + PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MILLENNIUM_G400_MAX_AGP, + DEVF_G400, + 360000, + MGA_G400, + &vbG400, + "Millennium G400 MAX (AGP)"}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400, 0x80, + 0, 0, + DEVF_G400, + 300000, + MGA_G400, + &vbG400, + "G400 (AGP)"}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400, 0xFF, + 0, 0, + DEVF_G450, + 360000, + MGA_G450, + &vbG400, + "G450"}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G550, 0xFF, + 0, 0, + DEVF_G550, + 360000, + MGA_G550, + &vbG400, + "G550"}, +#endif + {0, 0, 0xFF, + 0, 0, + 0, + 0, + 0, + NULL, + NULL}}; + +#ifndef MODULE +static struct fb_videomode defaultmode = { + /* 640x480 @ 60Hz, 31.5 kHz */ + NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2, + 0, FB_VMODE_NONINTERLACED +}; +#endif /* !MODULE */ + +static int hotplug = 0; + +static void setDefaultOutputs(WPMINFO2) { + unsigned int i; + const char* ptr; + + ACCESS_FBINFO(outputs[0]).default_src = MATROXFB_SRC_CRTC1; + if (ACCESS_FBINFO(devflags.g450dac)) { + ACCESS_FBINFO(outputs[1]).default_src = MATROXFB_SRC_CRTC1; + ACCESS_FBINFO(outputs[2]).default_src = MATROXFB_SRC_CRTC1; + } else if (dfp) { + ACCESS_FBINFO(outputs[2]).default_src = MATROXFB_SRC_CRTC1; + } + ptr = outputs; + for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { + char c = *ptr++; + + if (c == 0) { + break; + } + if (c == '0') { + ACCESS_FBINFO(outputs[i]).default_src = MATROXFB_SRC_NONE; + } else if (c == '1') { + ACCESS_FBINFO(outputs[i]).default_src = MATROXFB_SRC_CRTC1; + } else if (c == '2' && ACCESS_FBINFO(devflags.crtc2)) { + ACCESS_FBINFO(outputs[i]).default_src = MATROXFB_SRC_CRTC2; + } else { + printk(KERN_ERR "matroxfb: Unknown outputs setting\n"); + break; + } + } + /* Nullify this option for subsequent adapters */ + outputs[0] = 0; +} + +static int initMatrox2(WPMINFO struct board* b){ + unsigned long ctrlptr_phys = 0; + unsigned long video_base_phys = 0; + unsigned int memsize; + int err; + + static struct pci_device_id intel_82437[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437) }, + { }, + }; + + DBG(__FUNCTION__) + + /* set default values... */ + vesafb_defined.accel_flags = FB_ACCELF_TEXT; + + ACCESS_FBINFO(hw_switch) = b->base->lowlevel; + ACCESS_FBINFO(devflags.accelerator) = b->base->accelID; + ACCESS_FBINFO(max_pixel_clock) = b->maxclk; + + printk(KERN_INFO "matroxfb: Matrox %s detected\n", b->name); + ACCESS_FBINFO(capable.plnwt) = 1; + ACCESS_FBINFO(chip) = b->chip; + ACCESS_FBINFO(capable.srcorg) = b->flags & DEVF_SRCORG; + ACCESS_FBINFO(devflags.video64bits) = b->flags & DEVF_VIDEO64BIT; + if (b->flags & DEVF_TEXT4B) { + ACCESS_FBINFO(devflags.vgastep) = 4; + ACCESS_FBINFO(devflags.textmode) = 4; + ACCESS_FBINFO(devflags.text_type_aux) = FB_AUX_TEXT_MGA_STEP16; + } else if (b->flags & DEVF_TEXT16B) { + ACCESS_FBINFO(devflags.vgastep) = 16; + ACCESS_FBINFO(devflags.textmode) = 1; + ACCESS_FBINFO(devflags.text_type_aux) = FB_AUX_TEXT_MGA_STEP16; + } else { + ACCESS_FBINFO(devflags.vgastep) = 8; + ACCESS_FBINFO(devflags.textmode) = 1; + ACCESS_FBINFO(devflags.text_type_aux) = FB_AUX_TEXT_MGA_STEP8; + } +#ifdef CONFIG_FB_MATROX_32MB + ACCESS_FBINFO(devflags.support32MB) = (b->flags & DEVF_SUPPORT32MB) != 0; +#endif + ACCESS_FBINFO(devflags.precise_width) = !(b->flags & DEVF_ANY_VXRES); + ACCESS_FBINFO(devflags.crtc2) = (b->flags & DEVF_CRTC2) != 0; + ACCESS_FBINFO(devflags.maven_capable) = (b->flags & DEVF_MAVEN_CAPABLE) != 0; + ACCESS_FBINFO(devflags.dualhead) = (b->flags & DEVF_DUALHEAD) != 0; + ACCESS_FBINFO(devflags.dfp_type) = dfp_type; + ACCESS_FBINFO(devflags.g450dac) = (b->flags & DEVF_G450DAC) != 0; + ACCESS_FBINFO(devflags.textstep) = ACCESS_FBINFO(devflags.vgastep) * ACCESS_FBINFO(devflags.textmode); + ACCESS_FBINFO(devflags.textvram) = 65536 / ACCESS_FBINFO(devflags.textmode); + setDefaultOutputs(PMINFO2); + if (b->flags & DEVF_PANELLINK_CAPABLE) { + ACCESS_FBINFO(outputs[2]).data = MINFO; + ACCESS_FBINFO(outputs[2]).output = &panellink_output; + ACCESS_FBINFO(outputs[2]).src = ACCESS_FBINFO(outputs[2]).default_src; + ACCESS_FBINFO(outputs[2]).mode = MATROXFB_OUTPUT_MODE_MONITOR; + ACCESS_FBINFO(devflags.panellink) = 1; + } + + if (ACCESS_FBINFO(capable.cross4MB) < 0) + ACCESS_FBINFO(capable.cross4MB) = b->flags & DEVF_CROSS4MB; + if (b->flags & DEVF_SWAPS) { + ctrlptr_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 1); + video_base_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 0); + ACCESS_FBINFO(devflags.fbResource) = PCI_BASE_ADDRESS_0; + } else { + ctrlptr_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 0); + video_base_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 1); + ACCESS_FBINFO(devflags.fbResource) = PCI_BASE_ADDRESS_1; + } + err = -EINVAL; + if (!ctrlptr_phys) { + printk(KERN_ERR "matroxfb: control registers are not available, matroxfb disabled\n"); + goto fail; + } + if (!video_base_phys) { + printk(KERN_ERR "matroxfb: video RAM is not available in PCI address space, matroxfb disabled\n"); + goto fail; + } + memsize = b->base->maxvram; + if (!request_mem_region(ctrlptr_phys, 16384, "matroxfb MMIO")) { + goto fail; + } + if (!request_mem_region(video_base_phys, memsize, "matroxfb FB")) { + goto failCtrlMR; + } + ACCESS_FBINFO(video.len_maximum) = memsize; + /* convert mem (autodetect k, M) */ + if (mem < 1024) mem *= 1024; + if (mem < 0x00100000) mem *= 1024; + + if (mem && (mem < memsize)) + memsize = mem; + err = -ENOMEM; + if (mga_ioremap(ctrlptr_phys, 16384, MGA_IOREMAP_MMIO, &ACCESS_FBINFO(mmio.vbase))) { + printk(KERN_ERR "matroxfb: cannot ioremap(%lX, 16384), matroxfb disabled\n", ctrlptr_phys); + goto failVideoMR; + } + ACCESS_FBINFO(mmio.base) = ctrlptr_phys; + ACCESS_FBINFO(mmio.len) = 16384; + ACCESS_FBINFO(video.base) = video_base_phys; + if (mga_ioremap(video_base_phys, memsize, MGA_IOREMAP_FB, &ACCESS_FBINFO(video.vbase))) { + printk(KERN_ERR "matroxfb: cannot ioremap(%lX, %d), matroxfb disabled\n", + video_base_phys, memsize); + goto failCtrlIO; + } + { + u_int32_t cmd; + u_int32_t mga_option; + + pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, &mga_option); + pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_COMMAND, &cmd); + mga_option &= 0x7FFFFFFF; /* clear BIG_ENDIAN */ + mga_option |= MX_OPTION_BSWAP; + /* disable palette snooping */ + cmd &= ~PCI_COMMAND_VGA_PALETTE; + if (pci_dev_present(intel_82437)) { + if (!(mga_option & 0x20000000) && !ACCESS_FBINFO(devflags.nopciretry)) { + printk(KERN_WARNING "matroxfb: Disabling PCI retries due to i82437 present\n"); + } + mga_option |= 0x20000000; + ACCESS_FBINFO(devflags.nopciretry) = 1; + } + pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_COMMAND, cmd); + pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mga_option); + ACCESS_FBINFO(hw).MXoptionReg = mga_option; + + /* select non-DMA memory for PCI_MGA_DATA, otherwise dump of PCI cfg space can lock PCI bus */ + /* maybe preinit() candidate, but it is same... for all devices... at this time... */ + pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_MGA_INDEX, 0x00003C00); + } + + err = -ENXIO; + matroxfb_read_pins(PMINFO2); + if (ACCESS_FBINFO(hw_switch)->preinit(PMINFO2)) { + goto failVideoIO; + } + + err = -ENOMEM; + if (!matroxfb_getmemory(PMINFO memsize, &ACCESS_FBINFO(video.len)) || !ACCESS_FBINFO(video.len)) { + printk(KERN_ERR "matroxfb: cannot determine memory size\n"); + goto failVideoIO; + } + ACCESS_FBINFO(devflags.ydstorg) = 0; + + ACCESS_FBINFO(video.base) = video_base_phys; + ACCESS_FBINFO(video.len_usable) = ACCESS_FBINFO(video.len); + if (ACCESS_FBINFO(video.len_usable) > b->base->maxdisplayable) + ACCESS_FBINFO(video.len_usable) = b->base->maxdisplayable; +#ifdef CONFIG_MTRR + if (mtrr) { + ACCESS_FBINFO(mtrr.vram) = mtrr_add(video_base_phys, ACCESS_FBINFO(video.len), MTRR_TYPE_WRCOMB, 1); + ACCESS_FBINFO(mtrr.vram_valid) = 1; + printk(KERN_INFO "matroxfb: MTRR's turned on\n"); + } +#endif /* CONFIG_MTRR */ + + if (!ACCESS_FBINFO(devflags.novga)) + request_region(0x3C0, 32, "matrox"); + matroxfb_g450_connect(PMINFO2); + ACCESS_FBINFO(hw_switch->reset(PMINFO2)); + + ACCESS_FBINFO(fbcon.monspecs.hfmin) = 0; + ACCESS_FBINFO(fbcon.monspecs.hfmax) = fh; + ACCESS_FBINFO(fbcon.monspecs.vfmin) = 0; + ACCESS_FBINFO(fbcon.monspecs.vfmax) = fv; + ACCESS_FBINFO(fbcon.monspecs.dpms) = 0; /* TBD */ + + /* static settings */ + vesafb_defined.red = colors[depth-1].red; + vesafb_defined.green = colors[depth-1].green; + vesafb_defined.blue = colors[depth-1].blue; + vesafb_defined.bits_per_pixel = colors[depth-1].bits_per_pixel; + vesafb_defined.grayscale = grayscale; + vesafb_defined.vmode = 0; + if (noaccel) + vesafb_defined.accel_flags &= ~FB_ACCELF_TEXT; + + ACCESS_FBINFO(fbops) = matroxfb_ops; + ACCESS_FBINFO(fbcon.fbops) = &ACCESS_FBINFO(fbops); + ACCESS_FBINFO(fbcon.pseudo_palette) = ACCESS_FBINFO(cmap); + /* after __init time we are like module... no logo */ + ACCESS_FBINFO(fbcon.flags) = hotplug ? FBINFO_FLAG_MODULE : FBINFO_FLAG_DEFAULT; + ACCESS_FBINFO(fbcon.flags) |= FBINFO_PARTIAL_PAN_OK | /* Prefer panning for scroll under MC viewer/edit */ + FBINFO_HWACCEL_COPYAREA | /* We have hw-assisted bmove */ + FBINFO_HWACCEL_FILLRECT | /* And fillrect */ + FBINFO_HWACCEL_IMAGEBLIT | /* And imageblit */ + FBINFO_HWACCEL_XPAN | /* And we support both horizontal */ + FBINFO_HWACCEL_YPAN; /* And vertical panning */ + ACCESS_FBINFO(video.len_usable) &= PAGE_MASK; + fb_alloc_cmap(&ACCESS_FBINFO(fbcon.cmap), 256, 1); + +#ifndef MODULE + /* mode database is marked __init!!! */ + if (!hotplug) { + fb_find_mode(&vesafb_defined, &ACCESS_FBINFO(fbcon), videomode[0]?videomode:NULL, + NULL, 0, &defaultmode, vesafb_defined.bits_per_pixel); + } +#endif /* !MODULE */ + + /* mode modifiers */ + if (hslen) + vesafb_defined.hsync_len = hslen; + if (vslen) + vesafb_defined.vsync_len = vslen; + if (left != ~0) + vesafb_defined.left_margin = left; + if (right != ~0) + vesafb_defined.right_margin = right; + if (upper != ~0) + vesafb_defined.upper_margin = upper; + if (lower != ~0) + vesafb_defined.lower_margin = lower; + if (xres) + vesafb_defined.xres = xres; + if (yres) + vesafb_defined.yres = yres; + if (sync != -1) + vesafb_defined.sync = sync; + else if (vesafb_defined.sync == ~0) { + vesafb_defined.sync = 0; + if (yres < 400) + vesafb_defined.sync |= FB_SYNC_HOR_HIGH_ACT; + else if (yres < 480) + vesafb_defined.sync |= FB_SYNC_VERT_HIGH_ACT; + } + + /* fv, fh, maxclk limits was specified */ + { + unsigned int tmp; + + if (fv) { + tmp = fv * (vesafb_defined.upper_margin + vesafb_defined.yres + + vesafb_defined.lower_margin + vesafb_defined.vsync_len); + if ((tmp < fh) || (fh == 0)) fh = tmp; + } + if (fh) { + tmp = fh * (vesafb_defined.left_margin + vesafb_defined.xres + + vesafb_defined.right_margin + vesafb_defined.hsync_len); + if ((tmp < maxclk) || (maxclk == 0)) maxclk = tmp; + } + tmp = (maxclk + 499) / 500; + if (tmp) { + tmp = (2000000000 + tmp) / tmp; + if (tmp > pixclock) pixclock = tmp; + } + } + if (pixclock) { + if (pixclock < 2000) /* > 500MHz */ + pixclock = 4000; /* 250MHz */ + if (pixclock > 1000000) + pixclock = 1000000; /* 1MHz */ + vesafb_defined.pixclock = pixclock; + } + + /* FIXME: Where to move this?! */ +#if defined(CONFIG_PPC_PMAC) +#ifndef MODULE + if (machine_is(powermac)) { + struct fb_var_screeninfo var; + if (default_vmode <= 0 || default_vmode > VMODE_MAX) + default_vmode = VMODE_640_480_60; +#ifdef CONFIG_NVRAM + if (default_cmode == CMODE_NVRAM) + default_cmode = nvram_read_byte(NV_CMODE); +#endif + if (default_cmode < CMODE_8 || default_cmode > CMODE_32) + default_cmode = CMODE_8; + if (!mac_vmode_to_var(default_vmode, default_cmode, &var)) { + var.accel_flags = vesafb_defined.accel_flags; + var.xoffset = var.yoffset = 0; + /* Note: mac_vmode_to_var() does not set all parameters */ + vesafb_defined = var; + } + } +#endif /* !MODULE */ +#endif /* CONFIG_PPC_PMAC */ + vesafb_defined.xres_virtual = vesafb_defined.xres; + if (nopan) { + vesafb_defined.yres_virtual = vesafb_defined.yres; + } else { + vesafb_defined.yres_virtual = 65536; /* large enough to be INF, but small enough + to yres_virtual * xres_virtual < 2^32 */ + } + matroxfb_init_fix(PMINFO2); + ACCESS_FBINFO(fbcon.screen_base) = vaddr_va(ACCESS_FBINFO(video.vbase)); + matroxfb_update_fix(PMINFO2); + /* Normalize values (namely yres_virtual) */ + matroxfb_check_var(&vesafb_defined, &ACCESS_FBINFO(fbcon)); + /* And put it into "current" var. Do NOT program hardware yet, or we'll not take over + * vgacon correctly. fbcon_startup will call fb_set_par for us, WITHOUT check_var, + * and unfortunately it will do it BEFORE vgacon contents is saved, so it won't work + * anyway. But we at least tried... */ + ACCESS_FBINFO(fbcon.var) = vesafb_defined; + err = -EINVAL; + + printk(KERN_INFO "matroxfb: %dx%dx%dbpp (virtual: %dx%d)\n", + vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, + vesafb_defined.xres_virtual, vesafb_defined.yres_virtual); + printk(KERN_INFO "matroxfb: framebuffer at 0x%lX, mapped to 0x%p, size %d\n", + ACCESS_FBINFO(video.base), vaddr_va(ACCESS_FBINFO(video.vbase)), ACCESS_FBINFO(video.len)); + +/* We do not have to set currcon to 0... register_framebuffer do it for us on first console + * and we do not want currcon == 0 for subsequent framebuffers */ + + ACCESS_FBINFO(fbcon).device = &ACCESS_FBINFO(pcidev)->dev; + if (register_framebuffer(&ACCESS_FBINFO(fbcon)) < 0) { + goto failVideoIO; + } + printk("fb%d: %s frame buffer device\n", + ACCESS_FBINFO(fbcon.node), ACCESS_FBINFO(fbcon.fix.id)); + + /* there is no console on this fb... but we have to initialize hardware + * until someone tells me what is proper thing to do */ + if (!ACCESS_FBINFO(initialized)) { + printk(KERN_INFO "fb%d: initializing hardware\n", + ACCESS_FBINFO(fbcon.node)); + /* We have to use FB_ACTIVATE_FORCE, as we had to put vesafb_defined to the fbcon.var + * already before, so register_framebuffer works correctly. */ + vesafb_defined.activate |= FB_ACTIVATE_FORCE; + fb_set_var(&ACCESS_FBINFO(fbcon), &vesafb_defined); + } + + return 0; +failVideoIO:; + matroxfb_g450_shutdown(PMINFO2); + mga_iounmap(ACCESS_FBINFO(video.vbase)); +failCtrlIO:; + mga_iounmap(ACCESS_FBINFO(mmio.vbase)); +failVideoMR:; + release_mem_region(video_base_phys, ACCESS_FBINFO(video.len_maximum)); +failCtrlMR:; + release_mem_region(ctrlptr_phys, 16384); +fail:; + return err; +} + +static LIST_HEAD(matroxfb_list); +static LIST_HEAD(matroxfb_driver_list); + +#define matroxfb_l(x) list_entry(x, struct matrox_fb_info, next_fb) +#define matroxfb_driver_l(x) list_entry(x, struct matroxfb_driver, node) +int matroxfb_register_driver(struct matroxfb_driver* drv) { + struct matrox_fb_info* minfo; + + list_add(&drv->node, &matroxfb_driver_list); + for (minfo = matroxfb_l(matroxfb_list.next); + minfo != matroxfb_l(&matroxfb_list); + minfo = matroxfb_l(minfo->next_fb.next)) { + void* p; + + if (minfo->drivers_count == MATROXFB_MAX_FB_DRIVERS) + continue; + p = drv->probe(minfo); + if (p) { + minfo->drivers_data[minfo->drivers_count] = p; + minfo->drivers[minfo->drivers_count++] = drv; + } + } + return 0; +} + +void matroxfb_unregister_driver(struct matroxfb_driver* drv) { + struct matrox_fb_info* minfo; + + list_del(&drv->node); + for (minfo = matroxfb_l(matroxfb_list.next); + minfo != matroxfb_l(&matroxfb_list); + minfo = matroxfb_l(minfo->next_fb.next)) { + int i; + + for (i = 0; i < minfo->drivers_count; ) { + if (minfo->drivers[i] == drv) { + if (drv && drv->remove) + drv->remove(minfo, minfo->drivers_data[i]); + minfo->drivers[i] = minfo->drivers[--minfo->drivers_count]; + minfo->drivers_data[i] = minfo->drivers_data[minfo->drivers_count]; + } else + i++; + } + } +} + +static void matroxfb_register_device(struct matrox_fb_info* minfo) { + struct matroxfb_driver* drv; + int i = 0; + list_add(&ACCESS_FBINFO(next_fb), &matroxfb_list); + for (drv = matroxfb_driver_l(matroxfb_driver_list.next); + drv != matroxfb_driver_l(&matroxfb_driver_list); + drv = matroxfb_driver_l(drv->node.next)) { + if (drv && drv->probe) { + void *p = drv->probe(minfo); + if (p) { + minfo->drivers_data[i] = p; + minfo->drivers[i++] = drv; + if (i == MATROXFB_MAX_FB_DRIVERS) + break; + } + } + } + minfo->drivers_count = i; +} + +static void matroxfb_unregister_device(struct matrox_fb_info* minfo) { + int i; + + list_del(&ACCESS_FBINFO(next_fb)); + for (i = 0; i < minfo->drivers_count; i++) { + struct matroxfb_driver* drv = minfo->drivers[i]; + + if (drv && drv->remove) + drv->remove(minfo, minfo->drivers_data[i]); + } +} + +static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dummy) { + struct board* b; + u_int16_t svid; + u_int16_t sid; + struct matrox_fb_info* minfo; + int err; + u_int32_t cmd; +#ifndef CONFIG_FB_MATROX_MULTIHEAD + static int registered = 0; +#endif + DBG(__FUNCTION__) + + svid = pdev->subsystem_vendor; + sid = pdev->subsystem_device; + for (b = dev_list; b->vendor; b++) { + if ((b->vendor != pdev->vendor) || (b->device != pdev->device) || (b->rev < pdev->revision)) continue; + if (b->svid) + if ((b->svid != svid) || (b->sid != sid)) continue; + break; + } + /* not match... */ + if (!b->vendor) + return -ENODEV; + if (dev > 0) { + /* not requested one... */ + dev--; + return -ENODEV; + } + pci_read_config_dword(pdev, PCI_COMMAND, &cmd); + if (pci_enable_device(pdev)) { + return -1; + } + +#ifdef CONFIG_FB_MATROX_MULTIHEAD + minfo = kmalloc(sizeof(*minfo), GFP_KERNEL); + if (!minfo) + return -1; +#else + if (registered) /* singlehead driver... */ + return -1; + minfo = &matroxfb_global_mxinfo; +#endif + memset(MINFO, 0, sizeof(*MINFO)); + + ACCESS_FBINFO(pcidev) = pdev; + ACCESS_FBINFO(dead) = 0; + ACCESS_FBINFO(usecount) = 0; + ACCESS_FBINFO(userusecount) = 0; + + pci_set_drvdata(pdev, MINFO); + /* DEVFLAGS */ + ACCESS_FBINFO(devflags.memtype) = memtype; + if (memtype != -1) + noinit = 0; + if (cmd & PCI_COMMAND_MEMORY) { + ACCESS_FBINFO(devflags.novga) = novga; + ACCESS_FBINFO(devflags.nobios) = nobios; + ACCESS_FBINFO(devflags.noinit) = noinit; + /* subsequent heads always needs initialization and must not enable BIOS */ + novga = 1; + nobios = 1; + noinit = 0; + } else { + ACCESS_FBINFO(devflags.novga) = 1; + ACCESS_FBINFO(devflags.nobios) = 1; + ACCESS_FBINFO(devflags.noinit) = 0; + } + + ACCESS_FBINFO(devflags.nopciretry) = no_pci_retry; + ACCESS_FBINFO(devflags.mga_24bpp_fix) = inv24; + ACCESS_FBINFO(devflags.precise_width) = option_precise_width; + ACCESS_FBINFO(devflags.sgram) = sgram; + ACCESS_FBINFO(capable.cross4MB) = cross4MB; + + spin_lock_init(&ACCESS_FBINFO(lock.DAC)); + spin_lock_init(&ACCESS_FBINFO(lock.accel)); + init_rwsem(&ACCESS_FBINFO(crtc2.lock)); + init_rwsem(&ACCESS_FBINFO(altout.lock)); + ACCESS_FBINFO(irq_flags) = 0; + init_waitqueue_head(&ACCESS_FBINFO(crtc1.vsync.wait)); + init_waitqueue_head(&ACCESS_FBINFO(crtc2.vsync.wait)); + ACCESS_FBINFO(crtc1.panpos) = -1; + + err = initMatrox2(PMINFO b); + if (!err) { +#ifndef CONFIG_FB_MATROX_MULTIHEAD + registered = 1; +#endif + matroxfb_register_device(MINFO); + return 0; + } +#ifdef CONFIG_FB_MATROX_MULTIHEAD + kfree(minfo); +#endif + return -1; +} + +static void pci_remove_matrox(struct pci_dev* pdev) { + struct matrox_fb_info* minfo; + + minfo = pci_get_drvdata(pdev); + matroxfb_remove(PMINFO 1); +} + +static struct pci_device_id matroxfb_devices[] = { +#ifdef CONFIG_FB_MATROX_MILLENIUM + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL_2, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL_2_AGP, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, +#endif +#ifdef CONFIG_FB_MATROX_MYSTIQUE + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MYS, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, +#endif +#ifdef CONFIG_FB_MATROX_G + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_MM, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G550, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, +#endif + {0, 0, + 0, 0, 0, 0, 0} +}; + +MODULE_DEVICE_TABLE(pci, matroxfb_devices); + + +static struct pci_driver matroxfb_driver = { + .name = "matroxfb", + .id_table = matroxfb_devices, + .probe = matroxfb_probe, + .remove = pci_remove_matrox, +}; + +/* **************************** init-time only **************************** */ + +#define RSResolution(X) ((X) & 0x0F) +#define RS640x400 1 +#define RS640x480 2 +#define RS800x600 3 +#define RS1024x768 4 +#define RS1280x1024 5 +#define RS1600x1200 6 +#define RS768x576 7 +#define RS960x720 8 +#define RS1152x864 9 +#define RS1408x1056 10 +#define RS640x350 11 +#define RS1056x344 12 /* 132 x 43 text */ +#define RS1056x400 13 /* 132 x 50 text */ +#define RS1056x480 14 /* 132 x 60 text */ +#define RSNoxNo 15 +/* 10-FF */ +static struct { int xres, yres, left, right, upper, lower, hslen, vslen, vfreq; } timmings[] __initdata = { + { 640, 400, 48, 16, 39, 8, 96, 2, 70 }, + { 640, 480, 48, 16, 33, 10, 96, 2, 60 }, + { 800, 600, 144, 24, 28, 8, 112, 6, 60 }, + { 1024, 768, 160, 32, 30, 4, 128, 4, 60 }, + { 1280, 1024, 224, 32, 32, 4, 136, 4, 60 }, + { 1600, 1200, 272, 48, 32, 5, 152, 5, 60 }, + { 768, 576, 144, 16, 28, 6, 112, 4, 60 }, + { 960, 720, 144, 24, 28, 8, 112, 4, 60 }, + { 1152, 864, 192, 32, 30, 4, 128, 4, 60 }, + { 1408, 1056, 256, 40, 32, 5, 144, 5, 60 }, + { 640, 350, 48, 16, 39, 8, 96, 2, 70 }, + { 1056, 344, 96, 24, 59, 44, 160, 2, 70 }, + { 1056, 400, 96, 24, 39, 8, 160, 2, 70 }, + { 1056, 480, 96, 24, 36, 12, 160, 3, 60 }, + { 0, 0, ~0, ~0, ~0, ~0, 0, 0, 0 } +}; + +#define RSCreate(X,Y) ((X) | ((Y) << 8)) +static struct { unsigned int vesa; unsigned int info; } *RSptr, vesamap[] __initdata = { +/* default must be first */ + { ~0, RSCreate(RSNoxNo, RS8bpp ) }, + { 0x101, RSCreate(RS640x480, RS8bpp ) }, + { 0x100, RSCreate(RS640x400, RS8bpp ) }, + { 0x180, RSCreate(RS768x576, RS8bpp ) }, + { 0x103, RSCreate(RS800x600, RS8bpp ) }, + { 0x188, RSCreate(RS960x720, RS8bpp ) }, + { 0x105, RSCreate(RS1024x768, RS8bpp ) }, + { 0x190, RSCreate(RS1152x864, RS8bpp ) }, + { 0x107, RSCreate(RS1280x1024, RS8bpp ) }, + { 0x198, RSCreate(RS1408x1056, RS8bpp ) }, + { 0x11C, RSCreate(RS1600x1200, RS8bpp ) }, + { 0x110, RSCreate(RS640x480, RS15bpp) }, + { 0x181, RSCreate(RS768x576, RS15bpp) }, + { 0x113, RSCreate(RS800x600, RS15bpp) }, + { 0x189, RSCreate(RS960x720, RS15bpp) }, + { 0x116, RSCreate(RS1024x768, RS15bpp) }, + { 0x191, RSCreate(RS1152x864, RS15bpp) }, + { 0x119, RSCreate(RS1280x1024, RS15bpp) }, + { 0x199, RSCreate(RS1408x1056, RS15bpp) }, + { 0x11D, RSCreate(RS1600x1200, RS15bpp) }, + { 0x111, RSCreate(RS640x480, RS16bpp) }, + { 0x182, RSCreate(RS768x576, RS16bpp) }, + { 0x114, RSCreate(RS800x600, RS16bpp) }, + { 0x18A, RSCreate(RS960x720, RS16bpp) }, + { 0x117, RSCreate(RS1024x768, RS16bpp) }, + { 0x192, RSCreate(RS1152x864, RS16bpp) }, + { 0x11A, RSCreate(RS1280x1024, RS16bpp) }, + { 0x19A, RSCreate(RS1408x1056, RS16bpp) }, + { 0x11E, RSCreate(RS1600x1200, RS16bpp) }, + { 0x1B2, RSCreate(RS640x480, RS24bpp) }, + { 0x184, RSCreate(RS768x576, RS24bpp) }, + { 0x1B5, RSCreate(RS800x600, RS24bpp) }, + { 0x18C, RSCreate(RS960x720, RS24bpp) }, + { 0x1B8, RSCreate(RS1024x768, RS24bpp) }, + { 0x194, RSCreate(RS1152x864, RS24bpp) }, + { 0x1BB, RSCreate(RS1280x1024, RS24bpp) }, + { 0x19C, RSCreate(RS1408x1056, RS24bpp) }, + { 0x1BF, RSCreate(RS1600x1200, RS24bpp) }, + { 0x112, RSCreate(RS640x480, RS32bpp) }, + { 0x183, RSCreate(RS768x576, RS32bpp) }, + { 0x115, RSCreate(RS800x600, RS32bpp) }, + { 0x18B, RSCreate(RS960x720, RS32bpp) }, + { 0x118, RSCreate(RS1024x768, RS32bpp) }, + { 0x193, RSCreate(RS1152x864, RS32bpp) }, + { 0x11B, RSCreate(RS1280x1024, RS32bpp) }, + { 0x19B, RSCreate(RS1408x1056, RS32bpp) }, + { 0x11F, RSCreate(RS1600x1200, RS32bpp) }, + { 0x010, RSCreate(RS640x350, RS4bpp ) }, + { 0x012, RSCreate(RS640x480, RS4bpp ) }, + { 0x102, RSCreate(RS800x600, RS4bpp ) }, + { 0x104, RSCreate(RS1024x768, RS4bpp ) }, + { 0x106, RSCreate(RS1280x1024, RS4bpp ) }, + { 0, 0 }}; + +static void __init matroxfb_init_params(void) { + /* fh from kHz to Hz */ + if (fh < 1000) + fh *= 1000; /* 1kHz minimum */ + /* maxclk */ + if (maxclk < 1000) maxclk *= 1000; /* kHz -> Hz, MHz -> kHz */ + if (maxclk < 1000000) maxclk *= 1000; /* kHz -> Hz, 1MHz minimum */ + /* fix VESA number */ + if (vesa != ~0) + vesa &= 0x1DFF; /* mask out clearscreen, acceleration and so on */ + + /* static settings */ + for (RSptr = vesamap; RSptr->vesa; RSptr++) { + if (RSptr->vesa == vesa) break; + } + if (!RSptr->vesa) { + printk(KERN_ERR "Invalid vesa mode 0x%04X\n", vesa); + RSptr = vesamap; + } + { + int res = RSResolution(RSptr->info)-1; + if (left == ~0) + left = timmings[res].left; + if (!xres) + xres = timmings[res].xres; + if (right == ~0) + right = timmings[res].right; + if (!hslen) + hslen = timmings[res].hslen; + if (upper == ~0) + upper = timmings[res].upper; + if (!yres) + yres = timmings[res].yres; + if (lower == ~0) + lower = timmings[res].lower; + if (!vslen) + vslen = timmings[res].vslen; + if (!(fv||fh||maxclk||pixclock)) + fv = timmings[res].vfreq; + if (depth == -1) + depth = RSDepth(RSptr->info); + } +} + +static int __init matrox_init(void) { + int err; + + matroxfb_init_params(); + err = pci_register_driver(&matroxfb_driver); + dev = -1; /* accept all new devices... */ + return err; +} + +/* **************************** exit-time only **************************** */ + +static void __exit matrox_done(void) { + pci_unregister_driver(&matroxfb_driver); +} + +#ifndef MODULE + +/* ************************* init in-kernel code ************************** */ + +static int __init matroxfb_setup(char *options) { + char *this_opt; + + DBG(__FUNCTION__) + + if (!options || !*options) + return 0; + + while ((this_opt = strsep(&options, ",")) != NULL) { + if (!*this_opt) continue; + + dprintk("matroxfb_setup: option %s\n", this_opt); + + if (!strncmp(this_opt, "dev:", 4)) + dev = simple_strtoul(this_opt+4, NULL, 0); + else if (!strncmp(this_opt, "depth:", 6)) { + switch (simple_strtoul(this_opt+6, NULL, 0)) { + case 0: depth = RSText; break; + case 4: depth = RS4bpp; break; + case 8: depth = RS8bpp; break; + case 15:depth = RS15bpp; break; + case 16:depth = RS16bpp; break; + case 24:depth = RS24bpp; break; + case 32:depth = RS32bpp; break; + default: + printk(KERN_ERR "matroxfb: unsupported color depth\n"); + } + } else if (!strncmp(this_opt, "xres:", 5)) + xres = simple_strtoul(this_opt+5, NULL, 0); + else if (!strncmp(this_opt, "yres:", 5)) + yres = simple_strtoul(this_opt+5, NULL, 0); + else if (!strncmp(this_opt, "vslen:", 6)) + vslen = simple_strtoul(this_opt+6, NULL, 0); + else if (!strncmp(this_opt, "hslen:", 6)) + hslen = simple_strtoul(this_opt+6, NULL, 0); + else if (!strncmp(this_opt, "left:", 5)) + left = simple_strtoul(this_opt+5, NULL, 0); + else if (!strncmp(this_opt, "right:", 6)) + right = simple_strtoul(this_opt+6, NULL, 0); + else if (!strncmp(this_opt, "upper:", 6)) + upper = simple_strtoul(this_opt+6, NULL, 0); + else if (!strncmp(this_opt, "lower:", 6)) + lower = simple_strtoul(this_opt+6, NULL, 0); + else if (!strncmp(this_opt, "pixclock:", 9)) + pixclock = simple_strtoul(this_opt+9, NULL, 0); + else if (!strncmp(this_opt, "sync:", 5)) + sync = simple_strtoul(this_opt+5, NULL, 0); + else if (!strncmp(this_opt, "vesa:", 5)) + vesa = simple_strtoul(this_opt+5, NULL, 0); + else if (!strncmp(this_opt, "maxclk:", 7)) + maxclk = simple_strtoul(this_opt+7, NULL, 0); + else if (!strncmp(this_opt, "fh:", 3)) + fh = simple_strtoul(this_opt+3, NULL, 0); + else if (!strncmp(this_opt, "fv:", 3)) + fv = simple_strtoul(this_opt+3, NULL, 0); + else if (!strncmp(this_opt, "mem:", 4)) + mem = simple_strtoul(this_opt+4, NULL, 0); + else if (!strncmp(this_opt, "mode:", 5)) + strlcpy(videomode, this_opt+5, sizeof(videomode)); + else if (!strncmp(this_opt, "outputs:", 8)) + strlcpy(outputs, this_opt+8, sizeof(outputs)); + else if (!strncmp(this_opt, "dfp:", 4)) { + dfp_type = simple_strtoul(this_opt+4, NULL, 0); + dfp = 1; + } +#ifdef CONFIG_PPC_PMAC + else if (!strncmp(this_opt, "vmode:", 6)) { + unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0); + if (vmode > 0 && vmode <= VMODE_MAX) + default_vmode = vmode; + } else if (!strncmp(this_opt, "cmode:", 6)) { + unsigned int cmode = simple_strtoul(this_opt+6, NULL, 0); + switch (cmode) { + case 0: + case 8: + default_cmode = CMODE_8; + break; + case 15: + case 16: + default_cmode = CMODE_16; + break; + case 24: + case 32: + default_cmode = CMODE_32; + break; + } + } +#endif + else if (!strcmp(this_opt, "disabled")) /* nodisabled does not exist */ + disabled = 1; + else if (!strcmp(this_opt, "enabled")) /* noenabled does not exist */ + disabled = 0; + else if (!strcmp(this_opt, "sgram")) /* nosgram == sdram */ + sgram = 1; + else if (!strcmp(this_opt, "sdram")) + sgram = 0; + else if (!strncmp(this_opt, "memtype:", 8)) + memtype = simple_strtoul(this_opt+8, NULL, 0); + else { + int value = 1; + + if (!strncmp(this_opt, "no", 2)) { + value = 0; + this_opt += 2; + } + if (! strcmp(this_opt, "inverse")) + inverse = value; + else if (!strcmp(this_opt, "accel")) + noaccel = !value; + else if (!strcmp(this_opt, "pan")) + nopan = !value; + else if (!strcmp(this_opt, "pciretry")) + no_pci_retry = !value; + else if (!strcmp(this_opt, "vga")) + novga = !value; + else if (!strcmp(this_opt, "bios")) + nobios = !value; + else if (!strcmp(this_opt, "init")) + noinit = !value; +#ifdef CONFIG_MTRR + else if (!strcmp(this_opt, "mtrr")) + mtrr = value; +#endif + else if (!strcmp(this_opt, "inv24")) + inv24 = value; + else if (!strcmp(this_opt, "cross4MB")) + cross4MB = value; + else if (!strcmp(this_opt, "grayscale")) + grayscale = value; + else if (!strcmp(this_opt, "dfp")) + dfp = value; + else { + strlcpy(videomode, this_opt, sizeof(videomode)); + } + } + } + return 0; +} + +static int __initdata initialized = 0; + +static int __init matroxfb_init(void) +{ + char *option = NULL; + int err = 0; + + DBG(__FUNCTION__) + + if (fb_get_options("matroxfb", &option)) + return -ENODEV; + matroxfb_setup(option); + + if (disabled) + return -ENXIO; + if (!initialized) { + initialized = 1; + err = matrox_init(); + } + hotplug = 1; + /* never return failure, user can hotplug matrox later... */ + return err; +} + +module_init(matroxfb_init); + +#else + +/* *************************** init module code **************************** */ + +MODULE_AUTHOR("(c) 1998-2002 Petr Vandrovec "); +MODULE_DESCRIPTION("Accelerated FBDev driver for Matrox Millennium/Mystique/G100/G200/G400/G450/G550"); +MODULE_LICENSE("GPL"); + +module_param(mem, int, 0); +MODULE_PARM_DESC(mem, "Size of available memory in MB, KB or B (2,4,8,12,16MB, default=autodetect)"); +module_param(disabled, int, 0); +MODULE_PARM_DESC(disabled, "Disabled (0 or 1=disabled) (default=0)"); +module_param(noaccel, int, 0); +MODULE_PARM_DESC(noaccel, "Do not use accelerating engine (0 or 1=disabled) (default=0)"); +module_param(nopan, int, 0); +MODULE_PARM_DESC(nopan, "Disable pan on startup (0 or 1=disabled) (default=0)"); +module_param(no_pci_retry, int, 0); +MODULE_PARM_DESC(no_pci_retry, "PCI retries enabled (0 or 1=disabled) (default=0)"); +module_param(novga, int, 0); +MODULE_PARM_DESC(novga, "VGA I/O (0x3C0-0x3DF) disabled (0 or 1=disabled) (default=0)"); +module_param(nobios, int, 0); +MODULE_PARM_DESC(nobios, "Disables ROM BIOS (0 or 1=disabled) (default=do not change BIOS state)"); +module_param(noinit, int, 0); +MODULE_PARM_DESC(noinit, "Disables W/SG/SD-RAM and bus interface initialization (0 or 1=do not initialize) (default=0)"); +module_param(memtype, int, 0); +MODULE_PARM_DESC(memtype, "Memory type for G200/G400 (see Documentation/fb/matroxfb.txt for explanation) (default=3 for G200, 0 for G400)"); +#ifdef CONFIG_MTRR +module_param(mtrr, int, 0); +MODULE_PARM_DESC(mtrr, "This speeds up video memory accesses (0=disabled or 1) (default=1)"); +#endif +module_param(sgram, int, 0); +MODULE_PARM_DESC(sgram, "Indicates that G100/G200/G400 has SGRAM memory (0=SDRAM, 1=SGRAM) (default=0)"); +module_param(inv24, int, 0); +MODULE_PARM_DESC(inv24, "Inverts clock polarity for 24bpp and loop frequency > 100MHz (default=do not invert polarity)"); +module_param(inverse, int, 0); +MODULE_PARM_DESC(inverse, "Inverse (0 or 1) (default=0)"); +#ifdef CONFIG_FB_MATROX_MULTIHEAD +module_param(dev, int, 0); +MODULE_PARM_DESC(dev, "Multihead support, attach to device ID (0..N) (default=all working)"); +#else +module_param(dev, int, 0); +MODULE_PARM_DESC(dev, "Multihead support, attach to device ID (0..N) (default=first working)"); +#endif +module_param(vesa, int, 0); +MODULE_PARM_DESC(vesa, "Startup videomode (0x000-0x1FF) (default=0x101)"); +module_param(xres, int, 0); +MODULE_PARM_DESC(xres, "Horizontal resolution (px), overrides xres from vesa (default=vesa)"); +module_param(yres, int, 0); +MODULE_PARM_DESC(yres, "Vertical resolution (scans), overrides yres from vesa (default=vesa)"); +module_param(upper, int, 0); +MODULE_PARM_DESC(upper, "Upper blank space (scans), overrides upper from vesa (default=vesa)"); +module_param(lower, int, 0); +MODULE_PARM_DESC(lower, "Lower blank space (scans), overrides lower from vesa (default=vesa)"); +module_param(vslen, int, 0); +MODULE_PARM_DESC(vslen, "Vertical sync length (scans), overrides lower from vesa (default=vesa)"); +module_param(left, int, 0); +MODULE_PARM_DESC(left, "Left blank space (px), overrides left from vesa (default=vesa)"); +module_param(right, int, 0); +MODULE_PARM_DESC(right, "Right blank space (px), overrides right from vesa (default=vesa)"); +module_param(hslen, int, 0); +MODULE_PARM_DESC(hslen, "Horizontal sync length (px), overrides hslen from vesa (default=vesa)"); +module_param(pixclock, int, 0); +MODULE_PARM_DESC(pixclock, "Pixelclock (ns), overrides pixclock from vesa (default=vesa)"); +module_param(sync, int, 0); +MODULE_PARM_DESC(sync, "Sync polarity, overrides sync from vesa (default=vesa)"); +module_param(depth, int, 0); +MODULE_PARM_DESC(depth, "Color depth (0=text,8,15,16,24,32) (default=vesa)"); +module_param(maxclk, int, 0); +MODULE_PARM_DESC(maxclk, "Startup maximal clock, 0-999MHz, 1000-999999kHz, 1000000-INF Hz"); +module_param(fh, int, 0); +MODULE_PARM_DESC(fh, "Startup horizontal frequency, 0-999kHz, 1000-INF Hz"); +module_param(fv, int, 0); +MODULE_PARM_DESC(fv, "Startup vertical frequency, 0-INF Hz\n" +"You should specify \"fv:max_monitor_vsync,fh:max_monitor_hsync,maxclk:max_monitor_dotclock\"\n"); +module_param(grayscale, int, 0); +MODULE_PARM_DESC(grayscale, "Sets display into grayscale. Works perfectly with paletized videomode (4, 8bpp), some limitations apply to 16, 24 and 32bpp videomodes (default=nograyscale)"); +module_param(cross4MB, int, 0); +MODULE_PARM_DESC(cross4MB, "Specifies that 4MB boundary can be in middle of line. (default=autodetected)"); +module_param(dfp, int, 0); +MODULE_PARM_DESC(dfp, "Specifies whether to use digital flat panel interface of G200/G400 (0 or 1) (default=0)"); +module_param(dfp_type, int, 0); +MODULE_PARM_DESC(dfp_type, "Specifies DFP interface type (0 to 255) (default=read from hardware)"); +module_param_string(outputs, outputs, sizeof(outputs), 0); +MODULE_PARM_DESC(outputs, "Specifies which CRTC is mapped to which output (string of up to three letters, consisting of 0 (disabled), 1 (CRTC1), 2 (CRTC2)) (default=111 for Gx50, 101 for G200/G400 with DFP, and 100 for all other devices)"); +#ifdef CONFIG_PPC_PMAC +module_param_named(vmode, default_vmode, int, 0); +MODULE_PARM_DESC(vmode, "Specify the vmode mode number that should be used (640x480 default)"); +module_param_named(cmode, default_cmode, int, 0); +MODULE_PARM_DESC(cmode, "Specify the video depth that should be used (8bit default)"); +#endif + +int __init init_module(void){ + + DBG(__FUNCTION__) + + if (disabled) + return -ENXIO; + + if (depth == 0) + depth = RSText; + else if (depth == 4) + depth = RS4bpp; + else if (depth == 8) + depth = RS8bpp; + else if (depth == 15) + depth = RS15bpp; + else if (depth == 16) + depth = RS16bpp; + else if (depth == 24) + depth = RS24bpp; + else if (depth == 32) + depth = RS32bpp; + else if (depth != -1) { + printk(KERN_ERR "matroxfb: depth %d is not supported, using default\n", depth); + depth = -1; + } + matrox_init(); + /* never return failure; user can hotplug matrox later... */ + return 0; +} +#endif /* MODULE */ + +module_exit(matrox_done); +EXPORT_SYMBOL(matroxfb_register_driver); +EXPORT_SYMBOL(matroxfb_unregister_driver); +EXPORT_SYMBOL(matroxfb_wait_for_sync); +EXPORT_SYMBOL(matroxfb_enable_irq); + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ + diff --git a/tests/testifdef.cocci b/tests/testifdef.cocci new file mode 100644 index 0000000..6abb400 --- /dev/null +++ b/tests/testifdef.cocci @@ -0,0 +1,12 @@ +@exists@ +local idexpression x; +statement S; +constant C; +@@ + +* x = kmalloc(...) +... +if (x == NULL) S +... when != x + when != if (...) { <+...x...+> } +* return \(-C\|NULL\); -- 2.20.1