Release coccinelle-0.1.2
authorCoccinelle <cocci@diku.dk>
Sun, 3 Oct 2010 11:56:16 +0000 (13:56 +0200)
committerRene Rydhof Hansen <rrh@cs.aau.dk>
Sun, 3 Oct 2010 11:56:16 +0000 (13:56 +0200)
** Bugfix:
   - better handling of ifdef on statements in control flow graph.
   - transform files even if they do not end in .c (thanks to Vegard Nossum)

** Internals:
   - merge code of yacfe

130 files changed:
.depend
Makefile
changes.txt
cocci.ml
commitmsg
commons/.depend
commons/Makefile
commons/backtrace.ml
commons/common.ml
commons/common.mli
commons/ocollection.ml
commons/ocollection.mli
commons/ograph_extended.ml
commons/ograph_extended.mli
commons/parser_combinators.ml [moved from commons/ocamlextra/parser_combinators.ml with 100% similarity]
commons/parser_combinators.mli [moved from commons/ocamlextra/parser_combinators.mli with 100% similarity]
ctl/.#ctl_engine.ml.1.185 [new file with mode: 0644]
ctl/.#ctl_engine.ml.1.187 [new file with mode: 0644]
ctl/.#flag_ctl.ml.1.12 [copied from engine/flag_engine.ml with 71% similarity]
ctl/.#flag_ctl.ml.1.13 [new file with mode: 0644]
ctl/ctl_engine.ml
ctl/ctl_engine.mli
ctl/flag_ctl.ml
engine/.#Makefile.1.49 [new file with mode: 0644]
engine/.#asttoctl2.ml.1.138 [deleted file]
engine/.#asttoctl2.ml.1.144 [moved from engine/.#asttoctl2.ml.1.141 with 99% similarity]
engine/.#c_vs_c.ml.1.9 [new file with mode: 0644]
engine/.#check_exhaustive_pattern.ml.1.39 [deleted file]
engine/.#check_reachability.ml.1.18 [new file with mode: 0644]
engine/.#cocci_vs_c_3.ml.1.154 [deleted file]
engine/.#ctlcocci_integration.ml.1.116 [moved from engine/.#ctlcocci_integration.ml.1.111 with 97% similarity]
engine/.#pattern3.ml.1.56 [deleted file]
engine/.#pattern3.ml.1.57 [deleted file]
engine/.#postprocess_transinfo.ml.1.12 [new file with mode: 0644]
engine/.#pretty_print_engine.ml.1.42 [new file with mode: 0644]
engine/.#transformation3.ml.1.47 [deleted file]
engine/.#transformation3.ml.1.48 [deleted file]
engine/.depend
engine/Makefile
engine/asttoctl2.ml
engine/c_vs_c.ml
engine/check_reachability.ml
engine/cocci_vs_c.ml [moved from engine/cocci_vs_c_3.ml with 92% similarity]
engine/cocci_vs_c.mli [moved from engine/cocci_vs_c_3.mli with 98% similarity]
engine/ctlcocci_integration.ml
engine/flag_engine.ml
engine/flag_matcher.ml [new file with mode: 0644]
engine/lib_engine.ml
engine/pattern_c.ml [moved from engine/pattern3.ml with 92% similarity]
engine/pattern_c.mli [moved from engine/pattern3.mli with 100% similarity]
engine/postprocess_transinfo.ml
engine/pretty_print_engine.ml
engine/transformation_c.ml [moved from engine/transformation3.ml with 94% similarity]
engine/transformation_c.mli [moved from engine/transformation3.mli with 100% similarity]
extra/.depend
flag_cocci.ml
globals/.#config.ml.1.2 [new file with mode: 0644]
globals/config.ml
globals/flag.ml
install.txt
main.ml
parsing_c/.depend
parsing_c/Makefile
parsing_c/ast_c.ml
parsing_c/ast_to_flow.ml
parsing_c/compare_c.ml
parsing_c/control_flow_c.ml
parsing_c/control_flow_c.mli
parsing_c/copyright.txt
parsing_c/cpp_ast_c.ml [new file with mode: 0644]
parsing_c/cpp_ast_c.mli [new file with mode: 0644]
parsing_c/credits.txt
parsing_c/flag_parsing_c.ml
parsing_c/lexer_c.mll
parsing_c/lexer_parser.ml
parsing_c/lexer_parser.mli
parsing_c/lib_parsing_c.ml
parsing_c/parse_c.ml
parsing_c/parse_c.mli
parsing_c/parser_c.mly
parsing_c/parsing_hacks.ml
parsing_c/parsing_hacks.mli
parsing_c/parsing_stat.ml [new file with mode: 0644]
parsing_c/pretty_print_c.ml
parsing_c/pretty_print_c.mli
parsing_c/test_parsing_c.ml
parsing_c/test_parsing_c.mli
parsing_c/token_helpers.ml
parsing_c/token_helpers.mli
parsing_c/type_annoter_c.ml
parsing_c/unparse_c.ml [moved from parsing_c/unparse_c2.ml with 95% similarity]
parsing_c/unparse_c.mli [moved from parsing_c/unparse_c2.mli with 75% similarity]
parsing_c/unparse_cocci.ml [moved from parsing_c/unparse_cocci2.ml with 100% similarity]
parsing_c/unparse_cocci.mli [moved from parsing_c/unparse_cocci2.mli with 100% similarity]
parsing_c/unparse_hrule.ml
parsing_c/visitor_c.ml
parsing_c/visitor_c.mli
parsing_cocci/.#ast0_cocci.ml.1.107 [new file with mode: 0644]
parsing_cocci/.#context_neg.ml.1.97 [new file with mode: 0644]
parsing_cocci/.#iso_pattern.ml.1.138 [new file with mode: 0644]
parsing_cocci/.#parser_cocci_menhir.mly.1.156 [new file with mode: 0644]
parsing_cocci/.#unitary_ast0.ml.1.29 [new file with mode: 0644]
parsing_cocci/.#unparse_ast0.ml.1.109 [new file with mode: 0644]
parsing_cocci/.#visitor_ast0.ml.1.81 [new file with mode: 0644]
parsing_cocci/ast0_cocci.ml
parsing_cocci/context_neg.ml
parsing_cocci/iso_pattern.ml
parsing_cocci/parser_cocci_menhir.ml
parsing_cocci/parser_cocci_menhir.mly
parsing_cocci/unitary_ast0.ml
parsing_cocci/unparse_ast0.ml
popl09/.#Makefile.1.3 [new file with mode: 0644]
popl09/Makefile
pycaml/pycaml.ml
python/.#yes_pycocci.ml.1.1 [new file with mode: 0644]
python/coccilib/elems.py
python/yes_pycocci.ml
standard.iso
testing.ml
tests/error.c [new file with mode: 0644]
tests/sys.cocci [new file with mode: 0644]
tests/sys.iso [new file with mode: 0644]
tests/testprint.c [new file with mode: 0644]
tests/testprint.cocci [new file with mode: 0644]
tests/warnon.cocci [new file with mode: 0644]
tools/Makefile
tools/distributed/spatch_linux_script
tools/extract_c_and_res.ml
tools/generate_dependencies.ml
tools/split_patch.ml

diff --git a/.depend b/.depend
index 0df0e6f..30da4d6 100644 (file)
--- a/.depend
+++ b/.depend
@@ -1,37 +1,39 @@
 cocci.cmi: commons/common.cmi parsing_cocci/ast_cocci.cmi 
 testing.cmi: commons/common.cmi parsing_cocci/ast_cocci.cmi 
 cocci.cmo: parsing_cocci/visitor_ast.cmi parsing_c/unparse_hrule.cmi \
-    parsing_c/unparse_c2.cmi parsing_c/type_annoter_c.cmi \
-    engine/transformation3.cmi python/pycocci.cmo \
+    parsing_c/unparse_c.cmi parsing_c/type_annoter_c.cmi \
+    engine/transformation_c.cmi python/pycocci.cmo \
     engine/pretty_print_engine.cmi parsing_cocci/pretty_print_cocci.cmi \
     popl09/popl.cmi parsing_c/parsing_hacks.cmi parsing_cocci/parse_cocci.cmi \
     parsing_c/parse_c.cmi commons/ograph_extended.cmi engine/lib_engine.cmo \
     parsing_c/flag_parsing_c.cmo ctl/flag_ctl.cmo flag_cocci.cmo \
     globals/flag.cmo engine/ctltotex.cmi engine/ctlcocci_integration.cmi \
-    parsing_c/control_flow_c.cmi parsing_c/compare_c.cmi commons/common.cmi \
-    engine/asttomember.cmi engine/asttoctl2.cmi parsing_c/ast_to_flow.cmi \
+    parsing_c/cpp_ast_c.cmi parsing_c/control_flow_c.cmi \
+    parsing_c/compare_c.cmi commons/common.cmi engine/asttomember.cmi \
+    engine/asttoctl2.cmi parsing_c/ast_to_flow.cmi \
     parsing_cocci/ast_cocci.cmi parsing_c/ast_c.cmo cocci.cmi 
 cocci.cmx: parsing_cocci/visitor_ast.cmx parsing_c/unparse_hrule.cmx \
-    parsing_c/unparse_c2.cmx parsing_c/type_annoter_c.cmx \
-    engine/transformation3.cmx python/pycocci.cmx \
+    parsing_c/unparse_c.cmx parsing_c/type_annoter_c.cmx \
+    engine/transformation_c.cmx python/pycocci.cmx \
     engine/pretty_print_engine.cmx parsing_cocci/pretty_print_cocci.cmx \
     popl09/popl.cmx parsing_c/parsing_hacks.cmx parsing_cocci/parse_cocci.cmx \
     parsing_c/parse_c.cmx commons/ograph_extended.cmx engine/lib_engine.cmx \
     parsing_c/flag_parsing_c.cmx ctl/flag_ctl.cmx flag_cocci.cmx \
     globals/flag.cmx engine/ctltotex.cmx engine/ctlcocci_integration.cmx \
-    parsing_c/control_flow_c.cmx parsing_c/compare_c.cmx commons/common.cmx \
-    engine/asttomember.cmx engine/asttoctl2.cmx parsing_c/ast_to_flow.cmx \
+    parsing_c/cpp_ast_c.cmx parsing_c/control_flow_c.cmx \
+    parsing_c/compare_c.cmx commons/common.cmx engine/asttomember.cmx \
+    engine/asttoctl2.cmx parsing_c/ast_to_flow.cmx \
     parsing_cocci/ast_cocci.cmx parsing_c/ast_c.cmx cocci.cmi 
 main.cmo: testing.cmi parsing_c/test_parsing_c.cmi python/pycocci.cmo \
     parsing_c/parse_c.cmi extra/kbuild.cmi popl09/flag_popl.cmo \
     parsing_cocci/flag_parsing_cocci.cmo parsing_c/flag_parsing_c.cmo \
-    engine/flag_engine.cmo ctl/flag_ctl.cmo flag_cocci.cmo globals/flag.cmo \
+    engine/flag_matcher.cmo ctl/flag_ctl.cmo flag_cocci.cmo globals/flag.cmo \
     engine/ctlcocci_integration.cmi globals/config.cmo commons/common.cmi \
     cocci.cmi 
 main.cmx: testing.cmx parsing_c/test_parsing_c.cmx python/pycocci.cmx \
     parsing_c/parse_c.cmx extra/kbuild.cmx popl09/flag_popl.cmx \
     parsing_cocci/flag_parsing_cocci.cmx parsing_c/flag_parsing_c.cmx \
-    engine/flag_engine.cmx ctl/flag_ctl.cmx flag_cocci.cmx globals/flag.cmx \
+    engine/flag_matcher.cmx ctl/flag_ctl.cmx flag_cocci.cmx globals/flag.cmx \
     engine/ctlcocci_integration.cmx globals/config.cmx commons/common.cmx \
     cocci.cmx 
 testing.cmo: parsing_cocci/pretty_print_cocci.cmi \
index 06b01a5..36cac02 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -107,13 +107,10 @@ BYTECODE_STATIC=-custom
 ##############################################################################
 # Top rules
 ##############################################################################
-eclipse: depend all
-configure:
-       ./configure
-
 all: rec $(EXEC)
 opt: rec.opt $(EXEC).opt
 all.opt: opt
+top: $(EXEC).top
 
 rec:
        set -e; for i in $(MAKESUBDIRS); \
@@ -123,6 +120,9 @@ rec.opt:
 clean::
        set -e; for i in $(MAKESUBDIRS); do $(MAKE) -C $$i clean; done 
 
+eclipse: depend all
+configure:
+       ./configure
 
 $(EXEC): $(LIBS) $(OBJS)
        $(OCAMLC) $(BYTECODE_STATIC) -o $@ $(SYSLIBS)  $^
@@ -214,6 +214,7 @@ OCAMLVERSION=$(shell ocaml -version |perl -p -e 's/.*version (.*)/$$1/;')
 #  cvs update -d -P
 #  touch **/*
 #  make licensify
+#  remember to comment the -g -dtypes in this Makefile
 
 # Procedure to do each time:
 #  cvs update
@@ -319,6 +320,17 @@ syncwiki:
 darcsweb:
 #      @echo pull from ~/public_html/darcs/c-coccinelle and c-commons and lib-xxx
 
+DARCSFORESTS=commons \
+ parsing_c parsing_cocci engine
+
+update_darcs:
+       darcs pull
+       set -e; for i in $(DARCSFORESTS); do cd $$i; darcs pull; cd ..; done 
+
+#darcs diff -u
+diff_darcs:
+       set -e; for i in $(DARCSFORESTS); do cd $$i; darcs diff -u; cd ..; done 
+
 
 ##############################################################################
 # Developer rules
@@ -346,8 +358,9 @@ tags:
 
 dependencygraph:
        find  -name "*.ml" |grep -v "scripts" | xargs ocamldep -I commons -I globals -I ctl -I parsing_cocci -I parsing_c -I engine -I popl09 -I extra > /tmp/dependfull.depend
-       ocamldot -fullgraph /tmp/dependfull.depend > /tmp/dependfull.dot
+       ocamldot -lr /tmp/dependfull.depend > /tmp/dependfull.dot
        dot -Tps /tmp/dependfull.dot > /tmp/dependfull.ps
+       ps2pdf /tmp/dependfull.ps /tmp/dependfull.pdf
 
 ##############################################################################
 # Misc rules
index 0a0013d..c1493ab 100644 (file)
@@ -1,8 +1,18 @@
 -*- org -*-
 
+* 0.1.2
+
+** Bugfix:
+- better handling of ifdef on statements in control flow graph.
+- transform files even if they do not end in .c (thanks to Vegard Nossum)
+
+** Internals: 
+- merge code of yacfe
+
 * 0.1.1
 
-** better support for initializer, cf -test substruct
+** Langage: 
+ - support for initializer at toplevel, cf -test substruct
 
 * 0.1
 
index b55eb06..6ab9293 100644 (file)
--- a/cocci.ml
+++ b/cocci.ml
@@ -46,11 +46,15 @@ let cprogram_of_file file =
 
 let cprogram_of_file_cached file = 
   let (program2, _stat) = Parse_c.parse_cache file in
-  program2
-
+  if !Flag_cocci.ifdef_to_if
+  then 
+    program2 +> Parse_c.with_program2 (fun asts -> 
+      Cpp_ast_c.cpp_ifdef_statementize asts
+    )
+  else program2
 
 let cfile_of_program program2_with_ppmethod outf = 
-  Unparse_c2.pp_program program2_with_ppmethod outf
+  Unparse_c.pp_program program2_with_ppmethod outf
 
 (* for memoization, contains only one entry, the one for the SP *)
 let _hparse = Hashtbl.create 101
@@ -272,18 +276,29 @@ let show_or_not_ctl_text a b c =
 
 
 (* running information *)
+let get_celem celem : string = 
+  match celem with 
+      Ast_c.Definition ({Ast_c.f_name = funcs;},_) -> funcs
+    | Ast_c.Declaration
+       (Ast_c.DeclList ([{Ast_c.v_namei = Some ((s, _),_);}, _], _)) -> s
+    | _ -> ""
 
 let show_or_not_celem2 prelude celem = 
-  if !Flag.show_trying then 
+  let (tag,trying) =
   (match celem with 
-  | Ast_c.Definition ((funcs,_,_,_c),_) -> 
-      pr2 (prelude ^ " function: " ^ funcs);
+  | Ast_c.Definition ({Ast_c.f_name = funcs;},_) -> 
+      Flag.current_element := funcs;
+      (" function: ",funcs)
   | Ast_c.Declaration
-      (Ast_c.DeclList ([(Some ((s, _),_), typ, sto, _local), _], _)) ->
-      pr2 (prelude ^ " variable " ^ s);
-  | _ -> 
-      pr2 (prelude ^ " something else");
-  )
+      (Ast_c.DeclList ([{Ast_c.v_namei = Some ((s, _),_);}, _], _)) ->
+      Flag.current_element := s;
+      (" variable ",s);
+  | _ ->
+      Flag.current_element := "something_else";
+      (" ","something else");
+  ) in
+  if !Flag.show_trying then pr2 (prelude ^ tag ^ trying)
+  
 let show_or_not_celem a b  = 
   Common.profile_code "show_xxx" (fun () -> show_or_not_celem2 a b)
 
@@ -437,7 +452,7 @@ let sp_contain_typed_metavar rules =
  * serio.c is related we think to #include <linux/serio.h> 
  *)
 
-let includes_to_parse xs = 
+let (includes_to_parse: (Common.filename * Parse_c.program2) list -> 'a) = fun xs ->
   if !Flag_cocci.no_includes
   then []
   else
@@ -446,7 +461,8 @@ let includes_to_parse xs =
       
       cs +> Common.map_filter (fun (c,_info_item) -> 
        match c with
-       | Ast_c.Include ((x,ii),info_h_pos)  -> 
+       | Ast_c.CppTop (Ast_c.Include {Ast_c.i_include = ((x,ii));
+                         i_rel_pos = info_h_pos;})  -> 
             (match x with
             | Ast_c.Local xs -> 
                let f = Filename.concat dir (Common.join "/" xs) in
@@ -567,7 +583,9 @@ let compute_new_prefixes xs =
 let rec update_include_rel_pos cs =
   let only_include = cs +> Common.map_filter (fun c -> 
     match c with 
-    | Ast_c.Include ((x,_),(aref, inifdef)) ->
+    | Ast_c.CppTop (Ast_c.Include {Ast_c.i_include = ((x,_));
+                     i_rel_pos = aref;
+                     i_is_in_ifdef = inifdef}) ->
         (match x with
         | Ast_c.Wierd _ -> None
         | _ -> 
@@ -676,14 +694,37 @@ let g_contain_typedmetavar = ref false
 let last_env_toplevel_c_info xs =
   (Common.last xs).env_typing_after
 
-let concat_headers_and_c ccs = 
-  (List.concat (ccs +> List.map (fun x -> x.asts)))
+let concat_headers_and_c (ccs: file_info list) 
+    : (toplevel_c_info * string) list = 
+  (List.concat (ccs +> List.map (fun x -> 
+                                  x.asts +> List.map (fun x' ->
+                                                        (x', x.fname)))))
 
 let for_unparser xs = 
   xs +> List.map (fun x -> 
-    (x.ast_c, (x.fullstring, x.tokens_c)), Unparse_c2.PPviastr
+    (x.ast_c, (x.fullstring, x.tokens_c)), Unparse_c.PPviastr
   )
 
+let gen_pdf_graph () =
+  (Ctl_engine.get_graph_files ()) +> List.iter (fun outfile -> 
+  Printf.printf "Generation of %s%!" outfile;
+  let filename_stack = Ctl_engine.get_graph_comp_files outfile in
+  List.iter (fun filename ->
+    ignore (Unix.system ("dot " ^ filename ^ " -Tpdf  -o " ^ filename ^ ".pdf;"))
+           ) filename_stack;
+  let (head,tail) = (List.hd filename_stack, List.tl filename_stack) in
+    ignore(Unix.system ("cp " ^ head ^ ".pdf " ^ outfile ^ ".pdf;"));
+    tail +> List.iter (fun filename ->
+      ignore(Unix.system ("mv " ^ outfile ^ ".pdf /tmp/tmp.pdf;"));
+      ignore(Unix.system ("pdftk " ^ filename ^ ".pdf /tmp/tmp.pdf cat output " ^ outfile ^ ".pdf"));
+             );
+    ignore(Unix.system ("rm /tmp/tmp.pdf;"));
+    List.iter (fun filename ->
+       ignore (Unix.system ("rm " ^ filename ^ " " ^ filename ^ ".pdf;"))
+           ) filename_stack;
+  Printf.printf " - Done\n")
+
+
 (* --------------------------------------------------------------------- *)
 let prepare_cocci ctls free_var_lists negated_pos_lists
     used_after_lists positions_list astcocci = 
@@ -789,7 +830,7 @@ let rebuild_info_program cs file isexp =
       |        None ->
          let file = Common.new_temp_file "cocci_small_output" ".c" in
          cfile_of_program 
-            [(c.ast_c, (c.fullstring, c.tokens_c)), Unparse_c2.PPnormal] 
+            [(c.ast_c, (c.fullstring, c.tokens_c)), Unparse_c.PPnormal] 
             file;
          
           (* Common.command2 ("cat " ^ file); *)
@@ -822,7 +863,7 @@ let rebuild_info_c_and_headers ccs isexp =
 
 
 
-let prepare_c files = 
+let prepare_c files : file_info list 
   let cprograms = List.map cprogram_of_file_cached files in
   let includes = includes_to_parse (zip files cprograms) in
 
@@ -976,7 +1017,7 @@ let rec apply_python_rule r cache newes e rules_that_have_matched
       else (cache, merge_env [(e, rules_that_have_matched)] newes)
     end
 
-and apply_cocci_rule r rules_that_have_ever_matched es ccs =
+and apply_cocci_rule r rules_that_have_ever_matched es (ccs:file_info list ref) =
   Common.profile_code r.rulename (fun () -> 
     show_or_not_rule_name r.ast_rule r.ruleid;
     show_or_not_ctl_text r.ctl r.ast_rule r.ruleid;
@@ -1020,13 +1061,13 @@ and apply_cocci_rule r rules_that_have_ever_matched es ccs =
       
                       (* looping over the functions and toplevel elements in
                         .c and .h *)
-                   concat_headers_and_c !ccs +> List.iter (fun c -> 
+                   concat_headers_and_c !ccs +> List.iter (fun (c,f) -> 
                      if c.flow <> None 
                      then
                         (* does also some side effects on c and r *)
                        let processed =
                          process_a_ctl_a_env_a_toplevel r relevant_bindings
-                           c in
+                           c in
                        match processed with
                        | None -> ()
                        | Some newbindings -> 
@@ -1098,7 +1139,7 @@ and merge_env new_e old_e =
        | _ -> failwith "duplicate environment entries")
     old_e new_e
 
-and bigloop2 rs ccs = 
+and bigloop2 rs (ccs: file_info list) = 
   let es = ref [(Ast_c.emptyMetavarsBinding,[])] in
   let ccs = ref ccs in
   let rules_that_have_ever_matched = ref [] in
@@ -1131,7 +1172,7 @@ and bigloop2 rs ccs =
                    apply_python_rule r cache newes e rules_that_have_matched
                      rules_that_have_ever_matched
                | "test" ->
-                   concat_headers_and_c !ccs +> List.iter (fun c -> 
+                   concat_headers_and_c !ccs +> List.iter (fun (c,_) -> 
                      if c.flow <> None 
                      then
                        Printf.printf "Flow: %s\r\nFlow!\r\n%!" c.fullstring);
@@ -1248,9 +1289,10 @@ and bigloop a b =
 
 
 (* does side effects on C ast and on Cocci info rule *)
-and process_a_ctl_a_env_a_toplevel2 r e c = 
+and process_a_ctl_a_env_a_toplevel2 r e c 
  indent_do (fun () -> 
   show_or_not_celem "trying" c.ast_c;
+  Flag.currentfile := Some (f ^ ":" ^get_celem c.ast_c);
   let (trans_info, returned_any_states, inherited_bindings, newbindings) = 
     Common.save_excursion Flag_ctl.loop_in_src_code (fun () -> 
       Flag_ctl.loop_in_src_code := !Flag_ctl.loop_in_src_code||c.contain_loop;
@@ -1281,7 +1323,7 @@ and process_a_ctl_a_env_a_toplevel2 r e c =
          * trasformation au fichier concerne. *)
 
         (* modify ast via side effect *)
-        ignore(Transformation3.transform r.rulename r.dropped_isos
+        ignore(Transformation_c.transform r.rulename r.dropped_isos
                   inherited_bindings trans_info (Common.some c.flow));
       with Timeout -> raise Timeout | UnixExit i -> raise (UnixExit i)
     end;
@@ -1290,9 +1332,9 @@ and process_a_ctl_a_env_a_toplevel2 r e c =
   end
  )
    
-and process_a_ctl_a_env_a_toplevel  a b c = 
+and process_a_ctl_a_env_a_toplevel  a b c f
   Common.profile_code "process_a_ctl_a_env_a_toplevel" 
-    (fun () -> process_a_ctl_a_env_a_toplevel2 a b c)
+    (fun () -> process_a_ctl_a_env_a_toplevel2 a b c f)
    
 
 
@@ -1355,6 +1397,7 @@ let full_engine2 (coccifile, isofile) cfiles =
 
     if !Flag.show_misc then Common.pr_xxxxxxxxxxxxxxxxx ();
     if !Flag.show_misc then pr "Finished";
+    if !Flag_ctl.graphical_trace then gen_pdf_graph ();
     if !Flag.show_misc then Common.pr_xxxxxxxxxxxxxxxxx();
 
     c_infos' +> List.map (fun c_or_h -> 
index 2df494c..62edc40 100644 (file)
--- a/commitmsg
+++ b/commitmsg
@@ -1,4 +1,8 @@
-Release coccinelle-0.1.1
+Release coccinelle-0.1.2
 
-** Language:
-    - support for initializer at toplevel, cf -test substruct
+** Bugfix:
+   - better handling of ifdef on statements in control flow graph.
+   - transform files even if they do not end in .c (thanks to Vegard Nossum)
+
+** Internals:
+   - merge code of yacfe
index 39a569b..eae66ad 100644 (file)
@@ -71,6 +71,8 @@ oseti.cmo: seti.cmo oset.cmi ocollection.cmi
 oseti.cmx: seti.cmx oset.cmx ocollection.cmx 
 osetpt.cmo: ocamlextra/setPt.cmo oset.cmi ocollection.cmi 
 osetpt.cmx: ocamlextra/setPt.cmx oset.cmx ocollection.cmx 
+parser_combinators.cmo: common.cmi parser_combinators.cmi 
+parser_combinators.cmx: common.cmx parser_combinators.cmi 
 seti.cmo: common.cmi 
 seti.cmx: common.cmx 
 ocamlextra/ANSITerminal.cmo: ocamlextra/ANSITerminal.cmi 
@@ -81,10 +83,6 @@ ocamlextra/dynArray.cmo: ocamlextra/enum.cmi ocamlextra/dynArray.cmi
 ocamlextra/dynArray.cmx: ocamlextra/enum.cmx ocamlextra/dynArray.cmi 
 ocamlextra/enum.cmo: ocamlextra/enum.cmi 
 ocamlextra/enum.cmx: ocamlextra/enum.cmi 
-ocamlextra/parser_combinators.cmo: common.cmi \
-    ocamlextra/parser_combinators.cmi 
-ocamlextra/parser_combinators.cmx: common.cmx \
-    ocamlextra/parser_combinators.cmi 
 ocamlextra/setb.cmo: ocamlextra/setb.cmi 
 ocamlextra/setb.cmx: ocamlextra/setb.cmi 
 ocamlextra/suffix_tree.cmo: ocamlextra/suffix_tree.cmi 
index c36c18f..c5878f5 100644 (file)
@@ -14,7 +14,7 @@ MYSRC=common.ml common_extra.ml \
       oarray.ml \
       ograph2way.ml ograph_extended.ml \
       ofullcommon.ml \
-      glimpse.ml
+      glimpse.ml parser_combinators.ml
 
 # src from other authors, got from the web or caml hump
 SRC=ocamlextra/dumper.ml 
@@ -23,7 +23,6 @@ SRC+=ocamlextra/setb.ml ocamlextra/mapb.ml # defunctorized version of standard s
 SRC+=ocamlextra/setPt.ml
 SRC+=$(MYSRC)
 SRC+=ocamlextra/enum.ml ocamlextra/dynArray.ml
-SRC+=ocamlextra/parser_combinators.ml
 SRC+=ocamlextra/suffix_tree.ml ocamlextra/suffix_tree_ext.ml 
 
 SYSLIBS=str.cma unix.cma   
@@ -60,12 +59,6 @@ MPIINCLUDES=-I ../ocamlmpi -I ../../ocamlmpi -I +ocamlmpi
 MYMPISRC=distribution.ml
 MPISYSLIBS=mpi.cma
 
-#ocamlmpi
-MPIINCLUDES=-I ../ocamlmpi -I ../../ocamlmpi -I +ocamlmpi 
-MYMPISRC=distribution.ml
-MPISYSLIBS=mpi.cma
-
-
 #-----------------------------------------------------------------------------
 # Other stuff
 #-----------------------------------------------------------------------------
index 85a61b3..9a0ee50 100644 (file)
@@ -5,6 +5,8 @@ open Common
  * where I can not allow any exception to stop mount.lfs.
  * 
  * src: Jane Street Core library.
+ * update: Normally no more needed in OCaml 3.11 as part of the 
+ *  default runtime.
  *)
 external print : unit -> unit = "print_exception_backtrace_stub" "noalloc"
 
index ee2b75e..d891cc5 100644 (file)
@@ -190,6 +190,8 @@ let (with_open_stringbuf: (((string -> unit) * Buffer.t) -> unit) -> string) =
   Buffer.contents buf
 
 
+let foldl1 p = function x::xs -> List.fold_left p x xs | _ -> failwith "foldl1"
+
 (*****************************************************************************)
 (* Debugging/logging *)
 (*****************************************************************************)
@@ -545,6 +547,7 @@ let time_func f =
 
 type prof = PALL | PNONE | PSOME of string list
 let profile = ref PNONE
+let show_trace_profile = ref false
 
 let check_profile category =
   match !profile with
@@ -553,9 +556,24 @@ let check_profile category =
   | PSOME l -> List.mem category l
 
 let _profile_table = ref (Hashtbl.create 100)
+
+let adjust_profile_entry category difftime =
+  let (xtime, xcount) = 
+    (try Hashtbl.find !_profile_table category
+    with Not_found -> 
+      let xtime = ref 0.0 in
+      let xcount = ref 0 in
+      Hashtbl.add !_profile_table category (xtime, xcount);
+      (xtime, xcount)
+    ) in
+  xtime := !xtime +. difftime;
+  xcount := !xcount + 1;
+  ()
+
 let profile_start category = failwith "todo"
 let profile_end category = failwith "todo"
 
+
 (* subtil: don't forget to give all argumens to f, otherwise partial app
  * and will profile nothing.
  *)  
@@ -563,6 +581,7 @@ let profile_code category f =
   if not (check_profile category)
   then f() 
   else begin
+  if !show_trace_profile then pr2 (spf "p: %s" category);
   let t = Unix.gettimeofday () in
   let res, prefix = 
     try Some (f ()), ""
@@ -570,22 +589,41 @@ let profile_code category f =
   in
   let category = prefix ^ category in (* add a '*' to indicate timeout func *)
   let t' = Unix.gettimeofday () in
-  let (xtime, xcount) = 
-    (try Hashtbl.find !_profile_table category
-    with Not_found -> 
-      let xtime = ref 0.0 in
-      let xcount = ref 0 in
-      Hashtbl.add !_profile_table category (xtime, xcount);
-      (xtime, xcount)
-    ) in
-  xtime := !xtime +. (t' -. t);
-  xcount := !xcount + 1;
+
+  adjust_profile_entry category (t' -. t);
   (match res with
   | Some res -> res
   | None -> raise Timeout
   );
   end
 
+
+let _is_in_exclusif = ref (None: string option) 
+
+let profile_code_exclusif category f = 
+  if not (check_profile category)
+  then f() 
+  else begin
+
+  match !_is_in_exclusif with
+  | Some s -> 
+      failwith (spf "profile_code_exclusif: %s but already in %s " category s);
+  | None -> 
+      _is_in_exclusif := (Some category);
+      finalize 
+        (fun () -> 
+          profile_code category f
+        ) 
+        (fun () -> 
+          _is_in_exclusif := None
+        )
+
+  end
+
+let profile_code_inside_exclusif_ok category f = 
+  failwith "Todo"
+
+
 (* todo: also put  % ? also add % to see if coherent numbers *)
 let profile_diagnostic () = 
   if !profile = PNONE then "" else
@@ -892,6 +930,8 @@ let write_back func filename =
   write_value (func (get_value filename)) filename
 
 
+let read_value f = get_value f
+
 
 (*****************************************************************************)
 (* Counter *)
@@ -2017,7 +2057,28 @@ let all_match re s =
 
 let _ = example (all_match "\\(@[A-Za-z]+\\)" "ca va @Et toi @Comment" 
                   = ["@Et";"@Comment"])
-  
+
+
+let global_replace_regexp re f_on_substr s = 
+  let regexp = Str.regexp re in
+  Str.global_substitute regexp (fun _wholestr -> 
+
+    let substr = Str.matched_string s in
+    f_on_substr substr
+  ) s
+
+
+let regexp_word_str = 
+  "\\([a-zA-Z_][A-Za-z_0-9]*\\)"
+let regexp_word = Str.regexp regexp_word_str
+
+let regular_words s = 
+  all_match regexp_word_str s
+
+let contain_regular_word s = 
+  let xs = regular_words s in
+  List.length xs >= 1
+
 
 
 (*****************************************************************************)
@@ -2104,6 +2165,9 @@ let size_ko i =
 
 
 
+
+
 (* done in summer 2007 for julia 
  * Reference: P216 of gusfeld book
  * For two strings S1 and S2, D(i,j) is defined to be the edit distance of S1[1..i] to S2[1..j]
@@ -2170,6 +2234,7 @@ let dirname = Filename.dirname
 let basename = Filename.basename
 
 type filename = string (* TODO could check that exist :) type sux *)
+type dirname = string (* TODO could check that exist :) type sux *)
 
 module BasicType = struct
   type filename = string
@@ -2577,15 +2642,34 @@ let rough_days_since_jesus (DMY (Day nday, month, Year year)) =
 
 
 
+let is_more_recent d1 d2 = 
+  let (Days n1) = rough_days_since_jesus d1 in
+  let (Days n2) = rough_days_since_jesus d2 in
+  (n1 > n2) 
+
+
+let max_dmy d1 d2 = 
+  if is_more_recent d1 d2 
+  then d1
+  else d2
+
+let min_dmy d1 d2 = 
+  if is_more_recent d1 d2 
+  then d2
+  else d1
+
+
+let maximum_dmy ds = 
+  foldl1 max_dmy ds
+
+let minimum_dmy ds = 
+  foldl1 min_dmy ds
+  
+
 
 let rough_days_between_dates d1 d2 = 
   let (Days n1) = rough_days_since_jesus d1 in
   let (Days n2) = rough_days_since_jesus d2 in
-  if (n2 < n1) 
-  then pr2 (spf "wierd date, d1 < d2: %s  vs %s " 
-               (string_of_date_dmy d1)
-               (string_of_date_dmy d2));
-
   Days (n2 - n1)
 
 let _ = example 
@@ -3327,6 +3411,25 @@ let (exclude_but_keep_attached: ('a -> bool) -> 'a list -> ('a * 'a list) list)=
 let _ = example
   (exclude_but_keep_attached (fun x -> x = 3) [3;3;1;3;2;3;3;3] = 
       [(1,[3;3]);(2,[3])])
+
+let (group_by_post: ('a -> bool) -> 'a list -> ('a list * 'a) list * 'a list)=
+ fun f xs -> 
+   let rec aux_filter grouped_acc acc = function
+   | [] -> 
+       List.rev grouped_acc, List.rev acc
+   | x::xs -> 
+       if f x 
+       then 
+         aux_filter ((List.rev acc,x)::grouped_acc) [] xs
+       else 
+         aux_filter grouped_acc (x::acc) xs
+   in
+   aux_filter [] [] xs
+
+let _ = example
+  (group_by_post (fun x -> x = 3) [1;1;3;2;3;4;5;3;6;6;6] = 
+      ([([1;1],3);([2],3);[4;5],3], [6;6;6]))
+
                                            
 
 let rec (split_when: ('a -> bool) -> 'a list -> 'a list * 'a * 'a list) = 
@@ -3396,6 +3499,10 @@ let index_list_1 xs =
 let or_list  = List.fold_left (||) false
 let and_list = List.fold_left (&&) true
 
+let avg_list xs = 
+  let sum = sum_int xs in
+  (float_of_int sum) /. (float_of_int (List.length xs))
+
 let snoc x xs = xs @ [x]
 let cons x xs = x::xs
 
@@ -3428,7 +3535,8 @@ let remove x xs =
 let exclude p xs = 
   List.filter (fun x -> not (p x)) xs
 
-let foldl1 p = function x::xs -> List.fold_left p x xs | _ -> failwith "foldl1"
+(* now in prelude 
+*)
 
 let fold_k f lastk acc xs = 
   let rec fold_k_aux acc = function
@@ -4111,6 +4219,12 @@ let _ = example (lookup_list2 "c" [["a",1;"b",2];["a",1;"b",3];["a",1;"c",7]] =
 let assoc_option  k l = 
   optionise (fun () -> List.assoc k l)
 
+let assoc_with_err_msg k l =
+  try List.assoc k l 
+  with Not_found -> 
+    pr2 (spf "pb assoc_with_err_msg: %s" (dump k));
+    raise Not_found
+
 (*****************************************************************************)
 (* Assoc int -> xxx with binary tree.  Have a look too at Mapb.mli *)
 (*****************************************************************************)
@@ -4706,6 +4820,8 @@ let fake_parse_info = {
 
 let string_of_parse_info x = 
   spf "%s at %s:%d:%d" x.str x.file x.line x.column
+let string_of_parse_info_bis x = 
+  spf "%s:%d:%d" x.file x.line x.column
 
 
 let (info_from_charpos2: int -> filename -> (int * int * string)) = 
@@ -5155,6 +5271,8 @@ let cmdline_flags_verbose () =
     " <int> guess what";
     "-disable_pr2_once",     Arg.Set disable_pr2_once, 
     "   to print more messages";
+    "-show_trace_profile",          Arg.Set show_trace_profile, 
+    "   show trace";
   ]
 
 let cmdline_flags_other () = 
@@ -5259,6 +5377,18 @@ let main_boilerplate f =
 (* let _ = if not !Sys.interactive then (main ()) *)
 
 
+(* based on code found in cameleon from maxence guesdon *)
+let md5sum_of_string s =
+  let com = spf "echo %s | md5sum | cut -d\" \" -f 1"
+      (Filename.quote s)
+  in
+  match cmd_to_list com with
+  | [s] -> 
+      (*pr2 s;*)
+      s
+  | _ -> failwith "md5sum_of_string wrong output"
+
+
 (*****************************************************************************)
 (* Misc/test *)
 (*****************************************************************************)
index a0cdac7..04fdd01 100644 (file)
@@ -31,6 +31,8 @@ val debugger : bool ref
 
 type prof = PALL | PNONE | PSOME of string list
 val profile : prof ref
+val show_trace_profile : bool ref
+
 
 val verbose_level : int ref
 
@@ -63,6 +65,7 @@ val save_tmp_files : bool ref
 (*###########################################################################*)
 
 type filename = string
+type dirname = string
 
 (* Trick in case you dont want to do an 'open Common' while still wanting
  * more pervasive types than the one in Pervasives. Just do the selective
@@ -214,6 +217,9 @@ val _profile_table : (string, (float ref * int ref)) Hashtbl.t ref
 val profile_code : string -> (unit -> 'a) -> 'a
 val profile_diagnostic : unit -> string
 
+val profile_code_exclusif : string -> (unit -> 'a) -> 'a
+val profile_code_inside_exclusif_ok : string -> (unit -> 'a) -> 'a
+
 val report_if_take_time : int -> string -> (unit -> 'a) -> 'a
 
 (* similar to profile_code but print some information during execution too *)
@@ -276,6 +282,7 @@ val laws2 :
 
 (* just wrappers around Marshall *)
 val get_value : filename -> 'a
+val read_value : filename -> 'a (* alias *)
 val write_value : 'a -> filename -> unit
 val write_back : ('a -> 'b) -> filename -> unit
 
@@ -591,9 +598,6 @@ val ( /! ) : int -> int -> int
 val do_n : int -> (unit -> unit) -> unit
 val foldn : ('a -> int -> 'a) -> 'a -> int -> 'a
 
-val sum_float : float list -> float
-val sum_int : int list -> int
-
 val pi : float
 val pi2 : float
 val pi4 : float
@@ -786,11 +790,14 @@ val size_ko : int -> string
 
 val edit_distance: string -> string -> int 
 
+val md5sum_of_string : string -> string 
+
 (*****************************************************************************)
 (* Regexp *)
 (*****************************************************************************)
 
 val regexp_alpha : Str.regexp
+val regexp_word : Str.regexp
 
 val _memo_compiled_regexp : (string, Str.regexp) Hashtbl.t
 val ( =~ ) : string -> string -> bool
@@ -819,6 +826,11 @@ val join : string (* sep *) -> string list -> string
 val split_list_regexp : string -> string list -> (string * string list) list
 
 val all_match : string (* regexp *) -> string -> string list
+val global_replace_regexp : 
+  string (* regexp *) -> (string -> string) -> string -> string
+
+val regular_words: string -> string list
+val contain_regular_word: string -> bool
 
 (*****************************************************************************)
 (* Filenames *)
@@ -948,6 +960,11 @@ val rough_days_between_dates : date_dmy -> date_dmy -> days
 
 val string_of_unix_time_lfs : Unix.tm -> string
 
+val is_more_recent : date_dmy -> date_dmy -> bool
+val max_dmy : date_dmy -> date_dmy -> date_dmy
+val min_dmy : date_dmy -> date_dmy -> date_dmy
+val maximum_dmy : date_dmy list -> date_dmy
+val minimum_dmy : date_dmy list -> date_dmy
 
 (*****************************************************************************)
 (* Lines/Words/Strings *)
@@ -1087,6 +1104,7 @@ val exn_to_real_unixexit : (unit -> 'a) -> 'a
 (* List *)
 (*****************************************************************************)
 
+
 (* tail recursive efficient map (but that also reverse the element!) *)
 val map_eff_rev : ('a -> 'b) -> 'a list -> 'b list
 (* tail recursive efficient map, use accumulator  *)
@@ -1116,6 +1134,7 @@ val fpartition : ('a -> 'b option) -> 'a list -> 'b list * 'a list
 
 val groupBy : ('a -> 'a -> bool) -> 'a list -> 'a list list
 val exclude_but_keep_attached: ('a -> bool) -> 'a list -> ('a * 'a list) list
+val group_by_post: ('a -> bool) -> 'a list -> ('a list * 'a) list * 'a list
 
 (* use hash internally to not be in O(n2) *)
 val group_assoc_bykey_eff : ('a * 'b) list -> ('a * 'b list) list
@@ -1214,6 +1233,10 @@ val prepare_want_all_assoc : ('a * 'b) list -> ('a * 'b list) list
 val or_list : bool list -> bool
 val and_list : bool list -> bool
 
+val sum_float : float list -> float
+val sum_int : int list -> int
+val avg_list: int list -> float 
+
 val return_when : ('a -> 'b option) -> 'a list -> 'b
 
 
@@ -1379,6 +1402,7 @@ val lookup_list : 'a -> ('a, 'b) assoc list -> 'b
 val lookup_list2 : 'a -> ('a, 'b) assoc list -> 'b * int
 
 val assoc_option : 'a -> ('a, 'b) assoc -> 'b option
+val assoc_with_err_msg : 'a -> ('a, 'b) assoc -> 'b
 
 (*****************************************************************************)
 (* Assoc, specialized. *)
@@ -1696,6 +1720,7 @@ type parse_info = {
   } 
 val fake_parse_info : parse_info
 val string_of_parse_info : parse_info -> string
+val string_of_parse_info_bis : parse_info -> string
 
 (* array[i] will contain the (line x col) of the i char position *)
 val full_charpos_to_pos : filename -> (int * int) array
index 6869f4b..38e4b96 100644 (file)
@@ -71,6 +71,11 @@ object(o: 'o)
   method virtual null: bool      (* can do default with: lenght(tolist)= 0 *)
 
 
+  method add2: 'a -> unit = fun a -> 
+    o#add a +> ignore;
+    ()
+
+
 
   method fold: 'b. ('b -> 'a -> 'b) -> 'b -> 'b = fun f a -> 
     let a = ref a in 
index 03d2d83..c23dced 100644 (file)
@@ -17,6 +17,8 @@ object ('o)
   method virtual mem : 'a -> bool
   method virtual null : bool
 
+  (* effect version *)
+  method add2: 'a -> unit
 
 
   method fold : ('c -> 'a -> 'c) -> 'c -> 'c
index a11d494..a481249 100644 (file)
@@ -227,6 +227,41 @@ let dfs_iter_with_path xi f g =
   
     
 
+let generate_ograph_generic g label fnode filename =
+  with_open_outfile filename (fun (pr,_) ->
+    pr "digraph misc {\n" ;
+    pr "size = \"10,10\";\n" ;
+    (match label with
+      None -> ()
+    | Some x -> pr (Printf.sprintf "label = \"%s\";\n" x));
+
+    let nodes = g#nodes in
+    nodes#iter (fun (k,node) -> 
+      let (str,border_color,inner_color) = fnode (k, node) in
+      let color =
+       match inner_color with
+         None ->
+           (match border_color with
+             None -> ""
+           | Some x -> Printf.sprintf ", style=\"setlinewidth(3)\", color = %s" x)
+       | Some x ->
+           (match border_color with
+             None -> Printf.sprintf ", style=\"setlinewidth(3),filled\", fillcolor = %s" x 
+           | Some x' -> Printf.sprintf ", style=\"setlinewidth(3),filled\", fillcolor = %s, color = %s" x x') in
+     (* so can see if nodes without arcs were created *) 
+      pr (sprintf "%d [label=\"%s   [%d]\"%s];\n" k str k color)
+    );
+
+    nodes#iter (fun (k,node) -> 
+      let succ = g#successors k in
+      succ#iter (fun (j,edge) ->
+        pr (sprintf "%d -> %d;\n" k j);
+      );
+    );
+    pr "}\n" ;
+    );
+  ()
+
 
 let generate_ograph_xxx g filename =
   with_open_outfile filename (fun (pr,_) ->
@@ -236,7 +271,7 @@ let generate_ograph_xxx g filename =
     let nodes = g#nodes in
     nodes#iter (fun (k,(node, s)) -> 
      (* so can see if nodes without arcs were created *) 
-      pr (sprintf "%d [label=\"%s   [%d]\"];" k s k); 
+      pr (sprintf "%d [label=\"%s   [%d]\"];\n" k s k)
     );
 
     nodes#iter (fun (k,node) -> 
@@ -247,11 +282,12 @@ let generate_ograph_xxx g filename =
     );
     pr "}\n" ;
     );
-  let _status = 
-    Unix.system ("dot " ^ filename ^ " -Tps  -o " ^ filename ^ ".ps;") in
   ()
 
-let launch_gv filename =
+
+let launch_gv_cmd filename =
+  let _status = 
+    Unix.system ("dot " ^ filename ^ " -Tps  -o " ^ filename ^ ".ps;") in
   let _status = Unix.system ("gv " ^ filename ^ ".ps &")
   in
   (* zarb: I need this when I launch the program via eshell, otherwise gv
@@ -261,8 +297,12 @@ let launch_gv filename =
 
 let print_ograph_extended g filename launchgv = 
   generate_ograph_xxx g filename;
-  if launchgv then launch_gv filename
+  if launchgv then launch_gv_cmd filename
 
 let print_ograph_mutable g filename launchgv = 
   generate_ograph_xxx g filename;
-  if launchgv then launch_gv filename
+  if launchgv then launch_gv_cmd filename
+
+let print_ograph_mutable_generic g label fnode ~output_file ~launch_gv = 
+  generate_ograph_generic g label fnode output_file;
+  if launch_gv then launch_gv_cmd output_file
index 5b9908a..c9f3936 100644 (file)
@@ -58,6 +58,15 @@ val dfs_iter_with_path :
   nodei -> (nodei -> nodei list -> unit) -> ('node, 'edge) ograph_mutable -> 
   unit
 
+val print_ograph_mutable_generic : 
+  ('node, 'edge) ograph_mutable -> 
+  string option -> (* label for the entire graph *)
+  (* what string to print for a node and how to color it *)
+  ((nodei * 'node) -> (string * string option * string option)) ->
+  output_file:filename -> 
+  launch_gv:bool -> 
+  unit
+
 
 val print_ograph_extended : 
   ('node * string, 'edge) ograph_extended -> 
@@ -70,4 +79,3 @@ val print_ograph_mutable :
   filename (* output file *) -> 
   bool (* launch gv ? *) -> 
   unit
-
diff --git a/ctl/.#ctl_engine.ml.1.185 b/ctl/.#ctl_engine.ml.1.185
new file mode 100644 (file)
index 0000000..cee310c
--- /dev/null
@@ -0,0 +1,2418 @@
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+* 
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+* 
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
+* 
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+(*external c_counter : unit -> int = "c_counter"*)
+let timeout = 800
+(* Optimize triples_conj by first extracting the intersection of the two sets,
+which can certainly be in the intersection *)
+let pTRIPLES_CONJ_OPT = ref true
+(* For complement, make NegState for the negation of a single state *)
+let pTRIPLES_COMPLEMENT_OPT = ref true
+(* For complement, do something special for the case where the environment
+and witnesses are empty *)
+let pTRIPLES_COMPLEMENT_SIMPLE_OPT = ref true
+(* "Double negate" the arguments of the path operators *)
+let pDOUBLE_NEGATE_OPT = ref true
+(* Only do pre_forall/pre_exists on new elements in fixpoint iteration *)
+let pNEW_INFO_OPT = ref true
+(* Filter the result of the label function to drop entries that aren't
+compatible with any of the available environments *)
+let pREQUIRED_ENV_OPT = ref true
+(* Memoize the raw result of the label function *)
+let pSATLABEL_MEMO_OPT = ref true
+(* Filter results according to the required states *)
+let pREQUIRED_STATES_OPT = ref true
+(* Drop negative witnesses at Uncheck *)
+let pUNCHECK_OPT = ref true
+let pANY_NEG_OPT = ref true
+let pLazyOpt = ref true
+
+(*
+let pTRIPLES_CONJ_OPT = ref false
+let pTRIPLES_COMPLEMENT_OPT = ref false
+let pTRIPLES_COMPLEMENT_SIMPLE_OPT = ref false
+let pDOUBLE_NEGATE_OPT = ref false
+let pNEW_INFO_OPT = ref false
+let pREQUIRED_ENV_OPT = ref false
+let pSATLABEL_MEMO_OPT = ref false
+let pREQUIRED_STATES_OPT = ref false
+let pUNCHECK_OPT = ref false
+let pANY_NEG_OPT = ref false
+let pLazyOpt = ref false
+*)
+
+
+let step_count = ref 0
+exception Steps
+let inc_step _ =
+  if not (!step_count = 0)
+  then
+    begin
+      step_count := !step_count - 1;
+      if !step_count = 0 then raise Steps
+    end
+
+let inc cell = cell := !cell + 1
+
+let satEU_calls = ref 0
+let satAW_calls = ref 0
+let satAU_calls = ref 0
+let satEF_calls = ref 0
+let satAF_calls = ref 0
+let satEG_calls = ref 0
+let satAG_calls = ref 0
+
+let triples = ref 0
+
+let ctr = ref 0
+let new_let _ =
+  let c = !ctr in
+  ctr := c + 1;
+  Printf.sprintf "_fresh_r_%d" c
+
+(* **********************************************************************
+ *
+ * Implementation of a Witness Tree model checking engine for CTL-FVex 
+ * 
+ *
+ * **********************************************************************)
+
+(* ********************************************************************** *)
+(* Module: SUBST (substitutions: meta. vars and values)                   *)
+(* ********************************************************************** *)
+
+module type SUBST =
+  sig
+    type value
+    type mvar
+    val eq_mvar: mvar -> mvar -> bool
+    val eq_val: value -> value -> bool
+    val merge_val: value -> value -> value
+    val print_mvar : mvar -> unit
+    val print_value : value -> unit
+  end
+;;
+
+(* ********************************************************************** *)
+(* Module: GRAPH (control flow graphs / model)                            *)
+(* ********************************************************************** *)
+
+module type GRAPH =
+  sig
+    type node
+    type cfg
+    val predecessors:     cfg -> node -> node list
+    val successors:       cfg -> node -> node list
+    val extract_is_loop : cfg -> node -> bool
+    val print_node :      node -> unit
+    val size :            cfg -> int
+  end
+;;
+
+module OGRAPHEXT_GRAPH = 
+  struct
+    type node = int;;
+    type cfg = (string,unit) Ograph_extended.ograph_mutable;;
+    let predecessors cfg n = List.map fst ((cfg#predecessors n)#tolist);;
+    let print_node i = Format.print_string (Common.i_to_s i)
+  end
+;;
+
+(* ********************************************************************** *)
+(* Module: PREDICATE (predicates for CTL formulae)                        *)
+(* ********************************************************************** *)
+
+module type PREDICATE =
+sig
+  type t
+  val print_predicate : t -> unit
+end
+
+
+(* ********************************************************************** *)
+
+(* ---------------------------------------------------------------------- *)
+(* Misc. useful generic functions                                         *)
+(* ---------------------------------------------------------------------- *)
+
+let head = List.hd
+
+let tail l = 
+  match l with
+    [] -> []
+  | (x::xs) -> xs
+;;
+
+let foldl = List.fold_left;;
+
+let foldl1 f xs = foldl f (head xs) (tail xs)
+
+type 'a esc = ESC of 'a | CONT of 'a
+
+let foldr = List.fold_right;;
+
+let concat = List.concat;;
+
+let map = List.map;;
+
+let filter = List.filter;;
+
+let partition = List.partition;;
+
+let concatmap f l = List.concat (List.map f l);;
+
+let maybe f g opt =
+  match opt with
+    | None -> g
+    | Some x -> f x
+;;
+
+let some_map f opts = map (maybe (fun x -> Some (f x)) None) opts
+
+let some_tolist_alt opts = concatmap (maybe (fun x -> [x]) []) opts
+
+let rec some_tolist opts =
+  match opts with
+    | []             -> []
+    | (Some x)::rest -> x::(some_tolist rest)
+    | _::rest        -> some_tolist rest 
+;;
+
+let rec groupBy eq l =
+    match l with
+      [] -> []
+    | (x::xs) -> 
+       let (xs1,xs2) = partition (fun x' -> eq x x') xs in
+       (x::xs1)::(groupBy eq xs2)
+;;
+
+let group l = groupBy (=) l;;
+
+let rec memBy eq x l =
+  match l with
+    [] -> false
+  | (y::ys) -> if (eq x y) then true else (memBy eq x ys)
+;;
+
+let rec nubBy eq ls =
+  match ls with
+    [] -> []
+  | (x::xs) when (memBy eq x xs) -> nubBy eq xs
+  | (x::xs) -> x::(nubBy eq xs)
+;;
+
+let rec nub ls =
+  match ls with
+    [] -> []
+  | (x::xs) when (List.mem x xs) -> nub xs
+  | (x::xs) -> x::(nub xs)
+;;
+
+let state_compare (s1,_,_) (s2,_,_) = compare s1 s2
+
+let setifyBy eq xs = nubBy eq xs;;
+
+let setify xs = nub xs;;
+
+let inner_setify xs = List.sort compare (nub xs);;
+
+let unionBy compare eq xs = function
+    [] -> xs
+  | ys ->
+      let rec loop = function
+         [] -> ys
+       | x::xs -> if memBy eq x ys then loop xs else x::(loop xs) in
+      List.sort compare (loop xs)
+;;
+
+let union xs ys = unionBy state_compare (=) xs ys;;
+
+let setdiff xs ys = filter (fun x -> not (List.mem x ys)) xs;;
+
+let subseteqBy eq xs ys = List.for_all (fun x -> memBy eq x ys) xs;;
+
+let subseteq xs ys = List.for_all (fun x -> List.mem x ys) xs;;
+let supseteq xs ys = subseteq ys xs
+
+let setequalBy eq xs ys = (subseteqBy eq xs ys) & (subseteqBy eq ys xs);;
+
+let setequal xs ys = (subseteq xs ys) & (subseteq ys xs);;
+
+(* Fix point calculation *)
+let rec fix eq f x =
+  let x' = f x in if (eq x' x) then x' else fix eq f x'
+;;
+
+(* Fix point calculation on set-valued functions *)
+let setfix f x = (fix subseteq f x) (*if new is a subset of old, stop*)
+let setgfix f x = (fix supseteq f x) (*if new is a supset of old, stop*)
+
+let get_states l = nub (List.map (function (s,_,_) -> s) l)
+
+(* ********************************************************************** *)
+(* Module: CTL_ENGINE                                                     *)
+(* ********************************************************************** *)
+
+module CTL_ENGINE =
+  functor (SUB : SUBST) -> 
+    functor (G : GRAPH) ->
+      functor (P : PREDICATE) ->
+struct
+
+module A = Ast_ctl
+
+type substitution = (SUB.mvar, SUB.value) Ast_ctl.generic_substitution
+
+type ('pred,'anno) witness =
+    (G.node, substitution,
+     ('pred, SUB.mvar, 'anno) Ast_ctl.generic_ctl list)
+      Ast_ctl.generic_witnesstree
+
+type ('pred,'anno) triples =
+    (G.node * substitution * ('pred,'anno) witness list) list
+
+(* ---------------------------------------------------------------------- *)
+(* Pretty printing functions *)
+(* ---------------------------------------------------------------------- *)
+
+let (print_generic_substitution : substitution -> unit) = fun substxs ->
+  let print_generic_subst = function
+      A.Subst (mvar, v) ->
+       SUB.print_mvar mvar; Format.print_string " --> "; SUB.print_value v
+    | A.NegSubst (mvar, v) -> 
+       SUB.print_mvar mvar; Format.print_string " -/-> "; SUB.print_value v in
+  Format.print_string "[";
+  Common.print_between (fun () -> Format.print_string ";" )
+    print_generic_subst substxs;
+  Format.print_string "]"
+
+let rec (print_generic_witness: ('pred, 'anno) witness -> unit) =
+  function
+  | A.Wit (state, subst, anno, childrens) -> 
+      Format.print_string "wit ";
+      G.print_node state;
+      print_generic_substitution subst;
+      (match childrens with
+       [] -> Format.print_string "{}"
+      |        _ -> 
+         Format.force_newline(); Format.print_string "   "; Format.open_box 0;
+         print_generic_witnesstree childrens; Format.close_box())
+  | A.NegWit(wit) -> 
+      Format.print_string "!";
+      print_generic_witness wit
+
+and (print_generic_witnesstree: ('pred,'anno) witness list -> unit) =
+  fun witnesstree ->
+    Format.open_box 1;
+    Format.print_string "{";
+    Common.print_between
+      (fun () -> Format.print_string ";"; Format.force_newline() ) 
+      print_generic_witness witnesstree;
+    Format.print_string "}";
+    Format.close_box()
+      
+and print_generic_triple (node,subst,tree) =
+  G.print_node node;
+  print_generic_substitution subst;
+  print_generic_witnesstree tree
+
+and (print_generic_algo : ('pred,'anno) triples -> unit) = fun xs -> 
+  Format.print_string "<";
+  Common.print_between
+    (fun () -> Format.print_string ";"; Format.force_newline())
+    print_generic_triple xs;
+  Format.print_string ">"
+;;
+
+let print_state (str : string) (l : ('pred,'anno) triples) =
+  Printf.printf "%s\n" str;
+  List.iter (function x ->
+    print_generic_triple x; Format.print_newline(); flush stdout)
+    (List.sort compare l);
+  Printf.printf "\n"
+    
+let print_required_states = function
+    None -> Printf.printf "no required states\n"
+  | Some states ->
+      Printf.printf "required states: ";
+      List.iter
+       (function x ->
+         G.print_node x; Format.print_string " "; Format.print_flush())
+       states;
+      Printf.printf "\n"
+
+let mkstates states = function
+    None -> states
+  | Some states -> states
+    
+(* ---------------------------------------------------------------------- *)
+(*                                                                        *)
+(* ---------------------------------------------------------------------- *)
+    
+    
+(* ************************* *)
+(* Substitutions             *)
+(* ************************* *)
+    
+let dom_sub sub =
+  match sub with
+  | A.Subst(x,_)    -> x
+  | A.NegSubst(x,_) -> x
+;;
+       
+let ran_sub sub =
+  match sub with
+  | A.Subst(_,x)    -> x
+  | A.NegSubst(_,x) -> x
+;;
+       
+let eq_subBy eqx eqv sub sub' =
+  match (sub,sub') with 
+    | (A.Subst(x,v),A.Subst(x',v'))       -> (eqx x x') && (eqv v v')
+    | (A.NegSubst(x,v),A.NegSubst(x',v')) -> (eqx x x') && (eqv v v')
+    | _                               -> false
+;;
+
+(* NOTE: functor *)
+let eq_sub sub sub' = eq_subBy SUB.eq_mvar SUB.eq_val sub sub'
+
+let eq_subst th th' = setequalBy eq_sub th th';;
+
+let merge_subBy eqx (===) (>+<) sub sub' =
+  (* variable part is guaranteed to be the same *)
+  match (sub,sub') with
+    (A.Subst (x,v),A.Subst (x',v')) -> 
+      if (v === v')
+      then Some [A.Subst(x, v >+< v')]
+      else None
+  | (A.NegSubst(x,v),A.Subst(x',v')) ->
+      if (not (v === v'))
+      then Some [A.Subst(x',v')]
+      else None
+  | (A.Subst(x,v),A.NegSubst(x',v')) ->
+      if (not (v === v'))
+      then Some [A.Subst(x,v)]
+      else None
+  | (A.NegSubst(x,v),A.NegSubst(x',v')) ->
+      if (v === v')
+      then
+       let merged = v >+< v' in
+       if merged = v && merged = v'
+       then Some [A.NegSubst(x,v >+< v')]
+       else
+         (* positions are compatible, but not identical. keep apart. *)
+         Some [A.NegSubst(x,v);A.NegSubst(x',v')]
+      else Some [A.NegSubst(x,v);A.NegSubst(x',v')]
+;;
+
+(* NOTE: functor *)
+let merge_sub sub sub' = 
+  merge_subBy SUB.eq_mvar SUB.eq_val SUB.merge_val sub sub'
+
+let clean_substBy eq cmp theta = List.sort cmp (nubBy eq theta);;
+
+(* NOTE: we sort by using the generic "compare" on (meta-)variable
+ *   names; we could also require a definition of compare for meta-variables 
+ *   or substitutions but that seems like overkill for sorting
+ *)
+let clean_subst theta = 
+  let res = 
+    clean_substBy eq_sub
+      (fun s s' ->
+       let res = compare (dom_sub s) (dom_sub s') in
+       if res = 0
+       then
+         match (s,s') with
+           (A.Subst(_,_),A.NegSubst(_,_)) -> -1
+         | (A.NegSubst(_,_),A.Subst(_,_)) -> 1
+         | _ -> compare (ran_sub s) (ran_sub s')
+       else res)
+      theta in
+  let rec loop = function
+      [] -> []
+    | (A.Subst(x,v)::A.NegSubst(y,v')::rest) when SUB.eq_mvar x y ->
+       loop (A.Subst(x,v)::rest)
+    | x::xs -> x::(loop xs) in
+  loop res
+
+let top_subst = [];;                   (* Always TRUE subst. *)
+
+(* Split a theta in two parts: one with (only) "x" and one without *)
+(* NOTE: functor *)
+let split_subst theta x = 
+  partition (fun sub -> SUB.eq_mvar (dom_sub sub) x) theta;;
+
+exception SUBST_MISMATCH
+let conj_subst theta theta' =
+  match (theta,theta') with
+    | ([],_) -> Some theta'
+    | (_,[]) -> Some theta
+    | _ ->
+       let rec classify = function
+           [] -> []
+         | [x] -> [(dom_sub x,[x])]
+         | x::xs ->
+             (match classify xs with
+               ((nm,y)::ys) as res ->
+                 if dom_sub x = nm
+                 then (nm,x::y)::ys
+                 else (dom_sub x,[x])::res
+             | _ -> failwith "not possible") in
+       let merge_all theta theta' =
+         foldl
+           (function rest ->
+             function sub ->
+               foldl
+                 (function rest ->
+                   function sub' ->
+                     match (merge_sub sub sub') with
+                       Some subs -> subs @ rest
+                     | _         -> raise SUBST_MISMATCH)
+                 rest theta')
+           [] theta in
+       let rec loop = function
+           ([],ctheta') ->
+             List.concat (List.map (function (_,ths) -> ths) ctheta')
+         | (ctheta,[]) ->
+             List.concat (List.map (function (_,ths) -> ths) ctheta)
+         | ((x,ths)::xs,(y,ths')::ys) ->
+             (match compare x y with
+               0 -> (merge_all ths ths') @ loop (xs,ys)
+             | -1 -> ths @ loop (xs,((y,ths')::ys))
+             | 1 -> ths' @ loop (((x,ths)::xs),ys)
+             | _ -> failwith "not possible") in
+       try Some (clean_subst(loop (classify theta, classify theta')))
+       with SUBST_MISMATCH -> None
+;;
+
+(* theta' must be a subset of theta *)
+let conj_subst_none theta theta' =
+  match (theta,theta') with
+    | (_,[]) -> Some theta
+    | ([],_) -> None
+    | _ ->
+       let rec classify = function
+           [] -> []
+         | [x] -> [(dom_sub x,[x])]
+         | x::xs ->
+             (match classify xs with
+               ((nm,y)::ys) as res ->
+                 if dom_sub x = nm
+                 then (nm,x::y)::ys
+                 else (dom_sub x,[x])::res
+             | _ -> failwith "not possible") in
+       let merge_all theta theta' =
+         foldl
+           (function rest ->
+             function sub ->
+               foldl
+                 (function rest ->
+                   function sub' ->
+                     match (merge_sub sub sub') with
+                       Some subs -> subs @ rest
+                     | _         -> raise SUBST_MISMATCH)
+                 rest theta')
+           [] theta in
+       let rec loop = function
+           (ctheta,[]) ->
+             List.concat (List.map (function (_,ths) -> ths) ctheta)
+         | ([],ctheta') -> raise SUBST_MISMATCH
+         | ((x,ths)::xs,(y,ths')::ys) ->
+             (match compare x y with
+               0 -> (merge_all ths ths') @ loop (xs,ys)
+             | -1 -> ths @ loop (xs,((y,ths')::ys))
+             | 1 -> raise SUBST_MISMATCH
+             | _ -> failwith "not possible") in
+       try Some (clean_subst(loop (classify theta, classify theta')))
+       with SUBST_MISMATCH -> None
+;;
+
+let negate_sub sub =
+  match sub with
+    | A.Subst(x,v)    -> A.NegSubst (x,v)
+    | A.NegSubst(x,v) -> A.Subst(x,v)
+;;
+
+(* Turn a (big) theta into a list of (small) thetas *)
+let negate_subst theta = (map (fun sub -> [negate_sub sub]) theta);;
+
+
+(* ************************* *)
+(* Witnesses                 *)
+(* ************************* *)
+
+(* Always TRUE witness *)
+let top_wit = ([] : (('pred, 'anno) witness list));;
+
+let eq_wit wit wit' = wit = wit';;
+
+let union_wit wit wit' = (*List.sort compare (wit' @ wit) for popl*)
+  let res = unionBy compare (=) wit wit' in
+  let anynegwit = (* if any is neg, then all are *)
+    List.exists (function A.NegWit _ -> true | A.Wit _ -> false) in
+  if anynegwit res
+  then List.filter (function A.NegWit _ -> true | A.Wit _ -> false) res
+  else res
+
+let negate_wit wit = A.NegWit wit (*
+  match wit with
+    | A.Wit(s,th,anno,ws)    -> A.NegWitWit(s,th,anno,ws)
+    | A.NegWitWit(s,th,anno,ws) -> A.Wit(s,th,anno,ws)*)
+;;
+
+let negate_wits wits =
+  List.sort compare (map (fun wit -> [negate_wit wit]) wits);;
+
+let unwitify trips =
+  let anynegwit = (* if any is neg, then all are *)
+    List.exists (function A.NegWit _ -> true | A.Wit _ -> false) in
+  setify
+    (List.fold_left
+       (function prev ->
+        function (s,th,wit) ->
+          if anynegwit wit then prev else (s,th,top_wit)::prev)
+       [] trips)
+
+(* ************************* *)
+(* Triples                   *)
+(* ************************* *)
+
+(* Triples are equal when the constituents are equal *)
+let eq_trip (s,th,wit) (s',th',wit') =
+  (s = s') && (eq_wit wit wit') && (eq_subst th th');;
+
+let triples_top states = map (fun s -> (s,top_subst,top_wit)) states;;
+
+let normalize trips =
+  List.map
+    (function (st,th,wit) -> (st,List.sort compare th,List.sort compare wit))
+    trips
+       
+
+(* conj opt doesn't work ((1,[],{{x=3}}) v (1,[],{{x=4}})) & (1,[],{{x=4}}) =
+(1,[],{{x=3},{x=4}}), not (1,[],{{x=4}}) *)
+let triples_conj trips trips' =
+  let (trips,shared,trips') =
+    if false && !pTRIPLES_CONJ_OPT (* see comment above *)
+    then
+      let (shared,trips) =
+       List.partition (function t -> List.mem t trips') trips in
+      let trips' =
+       List.filter (function t -> not(List.mem t shared)) trips' in
+      (trips,shared,trips')
+    else (trips,[],trips') in
+  foldl (* returns a set - setify inlined *)
+    (function rest ->
+      function (s1,th1,wit1) ->
+       foldl
+         (function rest ->
+           function (s2,th2,wit2) ->
+             if (s1 = s2) then
+               (match (conj_subst th1 th2) with
+                 Some th ->
+                   let t = (s1,th,union_wit wit1 wit2) in
+                   if List.mem t rest then rest else t::rest
+               | _       -> rest)
+             else rest)
+         rest trips')
+    shared trips
+;;
+
+(* ignore the state in the right argument.  always pretend it is the same as
+the left one *)
+(* env on right has to be a subset of env on left *)
+let triples_conj_none trips trips' =
+  let (trips,shared,trips') =
+    if false && !pTRIPLES_CONJ_OPT (* see comment above *)
+    then
+      let (shared,trips) =
+       List.partition (function t -> List.mem t trips') trips in
+      let trips' =
+       List.filter (function t -> not(List.mem t shared)) trips' in
+      (trips,shared,trips')
+    else (trips,[],trips') in
+  foldl (* returns a set - setify inlined *)
+    (function rest ->
+      function (s1,th1,wit1) ->
+       foldl
+         (function rest ->
+           function (s2,th2,wit2) ->
+             match (conj_subst_none th1 th2) with
+               Some th ->
+                 let t = (s1,th,union_wit wit1 wit2) in
+                 if List.mem t rest then rest else t::rest
+             | _       -> rest)
+         rest trips')
+    shared trips
+;;
+
+exception AW
+
+let triples_conj_AW trips trips' =
+  let (trips,shared,trips') =
+    if false && !pTRIPLES_CONJ_OPT
+    then
+      let (shared,trips) =
+       List.partition (function t -> List.mem t trips') trips in
+      let trips' =
+       List.filter (function t -> not(List.mem t shared)) trips' in
+      (trips,shared,trips')
+    else (trips,[],trips') in
+  foldl (* returns a set - setify inlined *)
+    (function rest ->
+      function (s1,th1,wit1) ->
+       foldl
+         (function rest ->
+           function (s2,th2,wit2) ->
+             if (s1 = s2) then
+               (match (conj_subst th1 th2) with
+                 Some th ->
+                   let t = (s1,th,union_wit wit1 wit2) in
+                   if List.mem t rest then rest else t::rest
+               | _ -> raise AW)
+             else rest)
+         rest trips')
+    shared trips
+;;
+
+(* *************************** *)
+(* NEGATION (NegState style)   *)
+(* *************************** *)
+
+(* Constructive negation at the state level *)
+type ('a) state =
+    PosState of 'a
+  | NegState of 'a list
+;;
+
+let compatible_states = function
+    (PosState s1, PosState s2) -> 
+      if s1 = s2 then Some (PosState s1) else None
+  | (PosState s1, NegState s2) -> 
+      if List.mem s1 s2 then None else Some (PosState s1)
+  | (NegState s1, PosState s2) -> 
+      if List.mem s2 s1 then None else Some (PosState s2)
+  | (NegState s1, NegState s2) -> Some (NegState (s1 @ s2))
+;;
+
+(* Conjunction on triples with "special states" *)
+let triples_state_conj trips trips' =
+  let (trips,shared,trips') =
+    if !pTRIPLES_CONJ_OPT
+    then
+      let (shared,trips) =
+       List.partition (function t -> List.mem t trips') trips in
+      let trips' =
+       List.filter (function t -> not(List.mem t shared)) trips' in
+      (trips,shared,trips')
+    else (trips,[],trips') in
+  foldl
+    (function rest ->
+      function (s1,th1,wit1) ->
+       foldl
+         (function rest ->
+           function (s2,th2,wit2) ->
+             match compatible_states(s1,s2) with
+               Some s ->
+                 (match (conj_subst th1 th2) with
+                   Some th ->
+                     let t = (s,th,union_wit wit1 wit2) in
+                     if List.mem t rest then rest else t::rest
+                 | _ -> rest)
+             | _ -> rest)
+         rest trips')
+    shared trips
+;;
+
+let triple_negate (s,th,wits) = 
+  let negstates = (NegState [s],top_subst,top_wit) in
+  let negths = map (fun th -> (PosState s,th,top_wit)) (negate_subst th) in
+  let negwits = map (fun nwit -> (PosState s,th,nwit)) (negate_wits wits) in
+    negstates :: (negths @ negwits) (* all different *)
+
+(* FIX ME: it is not necessary to do full conjunction *)
+let triples_complement states (trips : ('pred, 'anno) triples) =
+  if !pTRIPLES_COMPLEMENT_OPT
+  then
+    (let cleanup (s,th,wit) =
+      match s with
+       PosState s' -> [(s',th,wit)]
+      | NegState ss ->
+         assert (th=top_subst);
+         assert (wit=top_wit);
+         map (fun st -> (st,top_subst,top_wit)) (setdiff states ss) in
+    let (simple,complex) =
+      if !pTRIPLES_COMPLEMENT_SIMPLE_OPT
+      then
+       let (simple,complex) =
+         List.partition (function (s,[],[]) -> true | _ -> false) trips in
+       let simple =
+         [(NegState(List.map (function (s,_,_) -> s) simple),
+           top_subst,top_wit)] in
+       (simple,complex)
+      else ([(NegState [],top_subst,top_wit)],trips) in
+    let rec compl trips =
+      match trips with
+       [] -> simple
+      | (t::ts) -> triples_state_conj (triple_negate t) (compl ts) in
+    let compld = (compl complex) in
+    let compld = concatmap cleanup compld in
+    compld)
+  else
+    let negstates (st,th,wits) =
+      map (function st -> (st,top_subst,top_wit)) (setdiff states [st]) in
+    let negths (st,th,wits) =
+      map (function th -> (st,th,top_wit)) (negate_subst th) in
+    let negwits (st,th,wits) =
+      map (function nwit -> (st,th,nwit)) (negate_wits wits) in
+    match trips with
+      [] -> map (function st -> (st,top_subst,top_wit)) states
+    | x::xs ->
+       setify
+         (foldl
+            (function prev ->
+              function cur ->
+                triples_conj (negstates cur @ negths cur @ negwits cur) prev)
+            (negstates x @ negths x @ negwits x) xs)
+;;
+
+let triple_negate (s,th,wits) = 
+  let negths = map (fun th -> (s,th,top_wit)) (negate_subst th) in
+  let negwits = map (fun nwit -> (s,th,nwit)) (negate_wits wits) in
+  ([s], negths @ negwits) (* all different *)
+
+let print_compl_state str (n,p) =
+  Printf.printf "%s neg: " str;
+  List.iter
+    (function x -> G.print_node x; Format.print_flush(); Printf.printf " ")
+    n;
+  Printf.printf "\n";
+  print_state "pos" p
+
+let triples_complement states (trips : ('pred, 'anno) triples) =
+  if trips = []
+  then map (function st -> (st,top_subst,top_wit)) states
+  else
+    let cleanup (neg,pos) =
+      let keep_pos =
+       List.filter (function (s,_,_) -> List.mem s neg) pos in
+      (map (fun st -> (st,top_subst,top_wit)) (setdiff states neg)) @
+      keep_pos in
+    let trips = List.sort state_compare trips in
+    let all_negated = List.map triple_negate trips in
+    let merge_one (neg1,pos1) (neg2,pos2) =
+      let (pos1conj,pos1keep) =
+       List.partition (function (s,_,_) -> List.mem s neg2) pos1 in
+      let (pos2conj,pos2keep) =
+       List.partition (function (s,_,_) -> List.mem s neg1) pos2 in
+      (Common.union_set neg1 neg2,
+       (triples_conj pos1conj pos2conj) @ pos1keep @ pos2keep) in
+    let rec inner_loop = function
+       x1::x2::rest -> (merge_one x1 x2) :: (inner_loop rest)
+      | l -> l in
+    let rec outer_loop = function
+       [x] -> x
+      | l -> outer_loop (inner_loop l) in
+    cleanup (outer_loop all_negated)
+
+(* ********************************** *)
+(* END OF NEGATION (NegState style)   *)
+(* ********************************** *)
+
+(* now this is always true, so we could get rid of it *)
+let something_dropped = ref true
+
+let triples_union trips trips' =
+  (*unionBy compare eq_trip trips trips';;*)
+  (* returns -1 is t1 > t2, 1 if t2 >= t1, and 0 otherwise *)
+(*
+The following does not work.  Suppose we have ([x->3],{A}) and ([],{A,B}).
+Then, the following says that since the first is a more restrictive
+environment and has fewer witnesses, then it should be dropped. But having
+fewer witnesses is not necessarily less informative than having more,
+because fewer witnesses can mean the absence of the witness-causing thing.
+So the fewer witnesses have to be kept around.
+subseteq changed to = to make it hopefully work
+*)
+  if !pNEW_INFO_OPT
+  then
+    begin
+      something_dropped := false;
+      if trips = trips'
+      then (something_dropped := true; trips)
+      else
+       let subsumes (s1,th1,wit1) (s2,th2,wit2) =
+         if s1 = s2
+         then
+           (match conj_subst th1 th2 with
+             Some conj ->
+               if conj = th1
+               then if (*subseteq*) wit1 = wit2 then 1 else 0
+               else
+                 if conj = th2
+                 then if (*subseteq*) wit2 = wit1 then (-1) else 0
+                 else 0
+           | None -> 0)
+         else 0 in
+       let rec first_loop second = function
+           [] -> second
+         | x::xs -> first_loop (second_loop x second) xs
+       and second_loop x = function
+           [] -> [x]
+         | (y::ys) as all ->
+             match subsumes x y with
+               1 -> something_dropped := true; all
+             | (-1) -> second_loop x ys
+             | _ -> y::(second_loop x ys) in
+       first_loop trips trips'
+    end
+  else unionBy compare eq_trip trips trips'
+
+
+let triples_witness x unchecked not_keep trips =
+  let anyneg = (* if any is neg, then all are *)
+    List.exists (function A.NegSubst _ -> true | A.Subst _ -> false) in
+  let anynegwit = (* if any is neg, then all are *)
+    List.exists (function A.NegWit _ -> true | A.Wit _ -> false) in
+  let allnegwit = (* if any is neg, then all are *)
+    List.for_all (function A.NegWit _ -> true | A.Wit _ -> false) in
+  let negtopos =
+    List.map (function A.NegWit w -> w | A.Wit _ -> failwith "bad wit")in
+  let res = 
+    List.fold_left
+      (function prev ->
+       function (s,th,wit) as t ->
+         let (th_x,newth) = split_subst th x in
+         match th_x with
+           [] ->
+             (* one consider whether if not not_keep is true, then we should
+                fail.  but it could be that the variable is a used_after and
+                then it is the later rule that should fail and not this one *)
+             if not not_keep && !Flag_ctl.verbose_ctl_engine
+             then
+               (SUB.print_mvar x; Format.print_flush();
+                print_state ": empty witness from" [t]);
+             t::prev
+         | l when anyneg l && !pANY_NEG_OPT -> prev
+             (* see tests/nestseq for how neg bindings can come up even
+                without eg partial matches
+              (* negated substitution only allowed with negwits.
+                just dropped *)
+             if anynegwit wit && allnegwit wit (* nonempty negwit list *)
+             then prev
+             else
+               (print_generic_substitution l; Format.print_newline();
+               failwith"unexpected negative binding with positive witnesses")*)
+         | _ ->
+             let new_triple =
+               if unchecked or not_keep
+               then (s,newth,wit)
+               else
+                 if anynegwit wit && allnegwit wit
+                 then (s,newth,[A.NegWit(A.Wit(s,th_x,[],negtopos wit))])
+                 else (s,newth,[A.Wit(s,th_x,[],wit)]) in
+             new_triple::prev)
+      [] trips in
+  if unchecked || !Flag_ctl.partial_match (* the only way to have a NegWit *)
+  then setify res
+  else List.rev res
+;;
+
+
+(* ---------------------------------------------------------------------- *)
+(* SAT  - Model Checking Algorithm for CTL-FVex                           *)
+(*                                                                        *)
+(* TODO: Implement _all_ operators (directly)                             *)
+(* ---------------------------------------------------------------------- *)
+
+
+(* ************************************* *)
+(* The SAT algorithm and special helpers *)
+(* ************************************* *)
+
+let rec pre_exist dir (grp,_,_) y reqst =
+  let check s =
+    match reqst with None -> true | Some reqst -> List.mem s reqst in
+  let exp (s,th,wit) =
+    concatmap
+      (fun s' -> if check s' then [(s',th,wit)] else [])
+      (match dir with
+       A.FORWARD -> G.predecessors grp s
+      | A.BACKWARD -> G.successors grp s) in
+  setify (concatmap exp y)
+;;
+
+exception Empty
+
+let pre_forall dir (grp,_,states) y all reqst =
+  let check s =
+    match reqst with
+      None -> true | Some reqst -> List.mem s reqst in
+  let pred =
+    match dir with
+      A.FORWARD -> G.predecessors | A.BACKWARD -> G.successors in
+  let succ =
+    match dir with
+      A.FORWARD -> G.successors | A.BACKWARD -> G.predecessors in
+  let neighbors =
+    List.map
+      (function p -> (p,succ grp p))
+      (setify
+        (concatmap
+           (function (s,_,_) -> List.filter check (pred grp s)) y)) in
+  (* would a hash table be more efficient? *)
+  let all = List.sort state_compare all in
+  let rec up_nodes child s = function
+      [] -> []
+    | (s1,th,wit)::xs ->
+       (match compare s1 child with
+         -1 -> up_nodes child s xs
+       | 0 -> (s,th,wit)::(up_nodes child s xs)
+       | _ -> []) in
+  let neighbor_triples =
+    List.fold_left
+      (function rest ->
+       function (s,children) ->
+         try
+           (List.map
+              (function child ->
+                match up_nodes child s all with [] -> raise Empty | l -> l)
+              children) :: rest
+         with Empty -> rest)
+      [] neighbors in
+  match neighbor_triples with
+    [] -> []
+  | _ ->
+      (*normalize*)
+        (foldl1 (@) (List.map (foldl1 triples_conj) neighbor_triples))
+       
+let pre_forall_AW dir (grp,_,states) y all reqst =
+  let check s =
+    match reqst with
+      None -> true | Some reqst -> List.mem s reqst in
+  let pred =
+    match dir with
+      A.FORWARD -> G.predecessors | A.BACKWARD -> G.successors in
+  let succ =
+    match dir with
+      A.FORWARD -> G.successors | A.BACKWARD -> G.predecessors in
+  let neighbors =
+    List.map
+      (function p -> (p,succ grp p))
+      (setify
+        (concatmap
+           (function (s,_,_) -> List.filter check (pred grp s)) y)) in
+  (* would a hash table be more efficient? *)
+  let all = List.sort state_compare all in
+  let rec up_nodes child s = function
+      [] -> []
+    | (s1,th,wit)::xs ->
+       (match compare s1 child with
+         -1 -> up_nodes child s xs
+       | 0 -> (s,th,wit)::(up_nodes child s xs)
+       | _ -> []) in
+  let neighbor_triples =
+    List.fold_left
+      (function rest ->
+       function (s,children) ->
+         (List.map
+            (function child ->
+              match up_nodes child s all with [] -> raise AW | l -> l)
+            children) :: rest)
+      [] neighbors in
+  match neighbor_triples with
+    [] -> []
+  | _ -> foldl1 (@) (List.map (foldl1 triples_conj_AW) neighbor_triples)
+       
+(* drop_negwits will call setify *)
+let satEX dir m s reqst = pre_exist dir m s reqst;;
+    
+let satAX dir m s reqst = pre_forall dir m s s reqst
+;;
+
+(* E[phi1 U phi2] == phi2 \/ (phi1 /\ EXE[phi1 U phi2]) *)
+let satEU dir ((_,_,states) as m) s1 s2 reqst = 
+  inc satEU_calls;
+  if s1 = []
+  then s2
+  else
+    (*let ctr = ref 0 in*)
+    if !pNEW_INFO_OPT
+    then
+      let rec f y new_info =
+       inc_step();
+       match new_info with
+         [] -> y
+       | new_info ->
+           ctr := !ctr + 1;
+           let first = triples_conj s1 (pre_exist dir m new_info reqst) in
+           let res = triples_union first y in
+           let new_info = setdiff res y in
+           (*Printf.printf "iter %d res %d new_info %d\n"
+           !ctr (List.length res) (List.length new_info);
+           flush stdout;*)
+           f res new_info in
+      f s2 s2
+    else
+      let f y =
+       inc_step();
+       let pre = pre_exist dir m y reqst in
+       triples_union s2 (triples_conj s1 pre) in
+      setfix f s2
+;;
+
+(* EF phi == E[true U phi] *)
+let satEF dir m s2 reqst = 
+  inc satEF_calls;
+  (*let ctr = ref 0 in*)
+  if !pNEW_INFO_OPT
+  then
+    let rec f y new_info =
+      inc_step();
+      match new_info with
+       [] -> y
+      | new_info ->
+         (*ctr := !ctr + 1;
+         print_state (Printf.sprintf "iteration %d\n" !ctr) y;*)
+         let first = pre_exist dir m new_info reqst in
+         let res = triples_union first y in
+         let new_info = setdiff res y in
+         (*Printf.printf "EF %s iter %d res %d new_info %d\n"
+           (if dir = A.BACKWARD then "reachable" else "real ef")
+           !ctr (List.length res) (List.length new_info);
+         print_state "new info" new_info;
+         flush stdout;*)
+         f res new_info in
+    f s2 s2
+  else
+    let f y =
+      inc_step();
+      let pre = pre_exist dir m y reqst in
+      triples_union s2 pre in
+    setfix f s2
+
+
+type ('pred,'anno) auok =
+    AUok of ('pred,'anno) triples | AUfailed of ('pred,'anno) triples
+
+(* A[phi1 U phi2] == phi2 \/ (phi1 /\ AXA[phi1 U phi2]) *)
+let satAU dir ((cfg,_,states) as m) s1 s2 reqst =
+  inc satAU_calls;
+  if s1 = []
+  then AUok s2
+  else
+    (*let ctr = ref 0 in*)
+    let pre_forall =
+      if !Flag_ctl.loop_in_src_code
+      then pre_forall_AW
+      else pre_forall in
+    if !pNEW_INFO_OPT
+    then
+      let rec f y newinfo =
+       inc_step();
+       match newinfo with
+         [] -> AUok y
+       | new_info ->
+           (*ctr := !ctr + 1;
+           print_state (Printf.sprintf "iteration %d\n" !ctr) y;
+           flush stdout;*)
+           let pre =
+             try Some (pre_forall dir m new_info y reqst)
+             with AW -> None in
+           match pre with
+             None -> AUfailed y
+           | Some pre ->
+               match triples_conj s1 pre with
+                 [] -> AUok y
+               | first ->
+                   (*print_state "s1" s1;
+                   print_state "pre" pre;
+                   print_state "first" first;*)
+                   let res = triples_union first y in
+                   let new_info =
+                     if not !something_dropped
+                     then first
+                     else setdiff res y in
+                 (*Printf.printf
+                    "iter %d res %d new_info %d\n"
+                    !ctr (List.length res) (List.length new_info);
+                    flush stdout;*)
+                   f res new_info in
+      f s2 s2
+    else
+      if !Flag_ctl.loop_in_src_code
+      then AUfailed s2
+      else
+       (*let setfix =
+         fix (function s1 -> function s2 ->
+           let s1 = List.map (function (s,th,w) -> (s,th,nub w)) s1 in
+           let s2 = List.map (function (s,th,w) -> (s,th,nub w)) s2 in
+           subseteq s1 s2) in for popl *)
+       let f y =
+         inc_step();
+         let pre = pre_forall dir m y y reqst in
+         triples_union s2 (triples_conj s1 pre) in
+       AUok (setfix f s2)
+;;
+
+
+(* reqst could be the states of s1 *)
+      (*
+      let lstates = mkstates states reqst in
+      let initial_removed =
+       triples_complement lstates (triples_union s1 s2) in
+      let initial_base = triples_conj s1 (triples_complement lstates s2) in
+      let rec loop base removed =
+       let new_removed =
+         triples_conj base (pre_exist dir m removed reqst) in
+       let new_base =
+         triples_conj base (triples_complement lstates new_removed) in
+       if supseteq new_base base
+       then triples_union base s2
+       else loop new_base new_removed in
+      loop initial_base initial_removed *)
+
+let satAW dir ((grp,_,states) as m) s1 s2 reqst =
+  inc satAW_calls;
+  if s1 = []
+  then s2
+  else
+    (*
+       This works extremely badly when the region is small and the end of the
+       region is very ambiguous, eg free(x) ... x
+       see free.c
+    if !pNEW_INFO_OPT
+    then
+      let get_states l = setify(List.map (function (s,_,_) -> s) l) in
+      let ostates = Common.union_set (get_states s1) (get_states s2) in
+      let succ =
+       (match dir with
+         A.FORWARD -> G.successors grp
+       | A.BACKWARD -> G.predecessors grp) in
+      let states =
+       List.fold_left Common.union_set ostates (List.map succ ostates) in
+      let negphi = triples_complement states s1 in
+      let negpsi = triples_complement states s2 in
+      triples_complement ostates
+       (satEU dir m negpsi (triples_conj negphi negpsi) (Some ostates))
+    else
+       *)
+      (*let ctr = ref 0 in*)
+      let f y =
+       inc_step();
+       (*ctr := !ctr + 1;
+       Printf.printf "iter %d y %d\n" !ctr (List.length y);
+       print_state "y" y;
+       flush stdout;*)
+       let pre = pre_forall dir m y y reqst in
+       let conj = triples_conj s1 pre in (* or triples_conj_AW *)
+       triples_union s2 conj in
+      setgfix f (triples_union s1 s2)
+;;
+
+let satAF dir m s reqst = 
+  inc satAF_calls;
+  if !pNEW_INFO_OPT
+  then
+    let rec f y newinfo =
+      inc_step();
+      match newinfo with
+       [] -> y
+      | new_info ->
+         let first = pre_forall dir m new_info y reqst in
+         let res = triples_union first y in
+         let new_info = setdiff res y in
+         f res new_info in
+    f s s
+  else
+    let f y =
+      inc_step();
+      let pre = pre_forall dir m y y reqst in
+      triples_union s pre in
+    setfix f s
+
+let satAG dir ((_,_,states) as m) s reqst =
+  inc satAG_calls;
+  let f y =
+    inc_step();
+    let pre = pre_forall dir m y y reqst in
+    triples_conj y pre in
+  setgfix f s
+
+let satEG dir ((_,_,states) as m) s reqst =
+  inc satEG_calls;
+  let f y =
+    inc_step();
+    let pre = pre_exist dir m y reqst in
+    triples_conj y pre in
+  setgfix f s
+
+(* **************************************************************** *)
+(* Inner And - a way of dealing with multiple matches within a node *)
+(* **************************************************************** *)
+(* applied to the result of matching a node.  collect witnesses when the
+states and environments are the same *)
+
+let inner_and trips =
+  let rec loop = function
+      [] -> ([],[])
+    | (s,th,w)::trips ->
+       let (cur,acc) = loop trips in
+       (match cur with
+         (s',_,_)::_ when s = s' ->
+           let rec loop' = function
+               [] -> [(s,th,w)]
+             | ((_,th',w') as t')::ts' ->
+                 (match conj_subst th th' with
+                   Some th'' -> (s,th'',union_wit w w')::ts'
+                 | None -> t'::(loop' ts')) in
+           (loop' cur,acc)
+       | _ -> ([(s,th,w)],cur@acc)) in
+  let (cur,acc) =
+    loop (List.sort state_compare trips) (* is this sort needed? *) in
+  cur@acc
+
+(* *************** *)
+(* Partial matches *)
+(* *************** *)
+
+let filter_conj states unwanted partial_matches =
+  let x =
+    triples_conj (triples_complement states (unwitify unwanted))
+      partial_matches in
+  triples_conj (unwitify x) (triples_complement states x)
+
+let strict_triples_conj strict states trips trips' =
+  let res = triples_conj trips trips' in
+  if !Flag_ctl.partial_match && strict = A.STRICT
+  then
+    let fail_left = filter_conj states trips trips' in
+    let fail_right = filter_conj states trips' trips in
+    let ors = triples_union fail_left fail_right in
+    triples_union res ors
+  else res
+
+let strict_triples_conj_none strict states trips trips' =
+  let res = triples_conj_none trips trips' in
+  if !Flag_ctl.partial_match && strict = A.STRICT
+  then
+    let fail_left = filter_conj states trips trips' in
+    let fail_right = filter_conj states trips' trips in
+    let ors = triples_union fail_left fail_right in
+    triples_union res ors
+  else res
+
+let left_strict_triples_conj strict states trips trips' =
+  let res = triples_conj trips trips' in
+  if !Flag_ctl.partial_match && strict = A.STRICT
+  then
+    let fail_left = filter_conj states trips trips' in
+    triples_union res fail_left
+  else res
+
+let strict_A1 strict op failop dir ((_,_,states) as m) trips required_states = 
+  let res = op dir m trips required_states in
+  if !Flag_ctl.partial_match && strict = A.STRICT
+  then
+    let states = mkstates states required_states in
+    let fail = filter_conj states res (failop dir m trips required_states) in
+    triples_union res fail
+  else res
+
+let strict_A2 strict op failop dir ((_,_,states) as m) trips trips'
+    required_states = 
+  let res = op dir m trips trips' required_states in
+  if !Flag_ctl.partial_match && strict = A.STRICT
+  then
+    let states = mkstates states required_states in
+    let fail = filter_conj states res (failop dir m trips' required_states) in
+    triples_union res fail
+  else res
+      
+let strict_A2au strict op failop dir ((_,_,states) as m) trips trips'
+    required_states = 
+  match op dir m trips trips' required_states with
+    AUok res ->
+      if !Flag_ctl.partial_match && strict = A.STRICT
+      then
+       let states = mkstates states required_states in
+       let fail =
+         filter_conj states res (failop dir m trips' required_states) in
+       AUok (triples_union res fail)
+      else AUok res
+  | AUfailed res -> AUfailed res
+      
+(* ********************* *)
+(* Environment functions *)
+(* ********************* *)
+
+let drop_wits required_states s phi =
+  match required_states with
+    None -> s
+  | Some states -> List.filter (function (s,_,_) -> List.mem s states) s
+
+
+let print_required required =
+  List.iter
+    (function l ->
+      Format.print_string "{";
+      List.iter
+       (function reqd ->
+         print_generic_substitution reqd; Format.print_newline())
+       l;
+      Format.print_string "}";
+      Format.print_newline())
+    required
+
+exception Too_long
+
+let extend_required trips required =
+  if !Flag_ctl.partial_match
+  then required
+  else
+      if !pREQUIRED_ENV_OPT
+      then
+    (* make it a set *)
+       let envs =
+         List.fold_left
+           (function rest ->
+             function (_,t,_) -> if List.mem t rest then rest else t::rest)
+           [] trips in
+       let envs = if List.mem [] envs then [] else envs in
+       match (envs,required) with
+         ([],_) -> required
+       | (envs,hd::tl) ->
+           (try
+             let hdln = List.length hd + 5 (* let it grow a little bit *) in
+             let (_,merged) =
+               let add x (ln,y) =
+                 if List.mem x y
+                 then (ln,y)
+                 else if ln + 1 > hdln then raise Too_long else (ln+1,x::y) in
+               foldl
+                 (function rest ->
+                   function t ->
+                     foldl
+                       (function rest ->
+                         function r ->
+                           match conj_subst t r with
+                             None -> rest | Some th -> add th rest)
+                       rest hd)
+                 (0,[]) envs in
+             merged :: tl
+           with Too_long -> envs :: required)
+       | (envs,_) -> envs :: required
+      else required
+
+let drop_required v required =
+  if !pREQUIRED_ENV_OPT
+  then
+    let res =
+    inner_setify
+      (List.map
+        (function l ->
+          inner_setify
+            (List.map (List.filter (function sub -> not(dom_sub sub = v))) l))
+        required) in
+    (* check whether an entry has become useless *)
+    List.filter (function l -> not (List.exists (function x -> x = []) l)) res
+  else required
+
+(* no idea how to write this function ... *)
+let memo_label =
+  (Hashtbl.create(50) : (P.t, (G.node * substitution) list) Hashtbl.t)
+
+let satLabel label required p =
+    let triples =
+    if !pSATLABEL_MEMO_OPT
+    then
+      try
+       let states_subs = Hashtbl.find memo_label p in
+       List.map (function (st,th) -> (st,th,[])) states_subs
+      with
+       Not_found ->
+         let triples = setify(label p) in
+         Hashtbl.add memo_label p
+           (List.map (function (st,th,_) -> (st,th)) triples);
+         triples
+    else setify(label p) in
+    normalize
+      (if !pREQUIRED_ENV_OPT
+      then
+       foldl
+         (function rest ->
+           function ((s,th,_) as t) ->
+             if List.for_all
+                 (List.exists (function th' -> not(conj_subst th th' = None)))
+                 required
+             then t::rest
+             else rest)
+         [] triples
+      else triples)
+
+let get_required_states l =
+  if !pREQUIRED_STATES_OPT && not !Flag_ctl.partial_match
+  then
+    Some(inner_setify (List.map (function (s,_,_) -> s) l))
+  else None
+
+let get_children_required_states dir (grp,_,_) required_states =
+  if !pREQUIRED_STATES_OPT && not !Flag_ctl.partial_match
+  then
+    match required_states with
+      None -> None
+    | Some states ->
+       let fn =
+         match dir with
+           A.FORWARD -> G.successors
+         | A.BACKWARD -> G.predecessors in
+       Some (inner_setify (List.concat (List.map (fn grp) states)))
+  else None
+
+let reachable_table =
+  (Hashtbl.create(50) : (G.node * A.direction, G.node list) Hashtbl.t)
+
+(* like satEF, but specialized for get_reachable *)
+let reachsatEF dir (grp,_,_) s2 =
+  let dirop =
+    match dir with A.FORWARD -> G.successors | A.BACKWARD -> G.predecessors in
+  let union = unionBy compare (=) in
+  let rec f y = function
+      [] -> y
+    | new_info ->
+       let (pre_collected,new_info) =
+         List.partition (function Common.Left x -> true | _ -> false)
+           (List.map
+              (function x ->
+                try Common.Left (Hashtbl.find reachable_table (x,dir))
+                with Not_found -> Common.Right x)
+              new_info) in
+       let y =
+         List.fold_left
+           (function rest ->
+             function Common.Left x -> union x rest
+               | _ -> failwith "not possible")
+           y pre_collected in
+       let new_info =
+         List.map
+           (function Common.Right x -> x | _ -> failwith "not possible")
+           new_info in
+       let first = inner_setify (concatmap (dirop grp) new_info) in
+       let new_info = setdiff first y in
+       let res = new_info @ y in
+       f res new_info in
+  List.rev(f s2 s2) (* put root first *)
+
+let get_reachable dir m required_states =
+  match required_states with
+    None -> None
+  | Some states ->
+      Some
+       (List.fold_left
+          (function rest ->
+            function cur ->
+              if List.mem cur rest
+              then rest
+              else
+                Common.union_set
+                  (try Hashtbl.find reachable_table (cur,dir)
+                  with
+                    Not_found ->
+                      let states = reachsatEF dir m [cur] in
+                      Hashtbl.add reachable_table (cur,dir) states;
+                      states)
+                  rest)
+          [] states)
+
+let ctr = ref 0
+let new_var _ =
+  let c = !ctr in
+  ctr := !ctr + 1;
+  Printf.sprintf "_c%d" c
+
+(* **************************** *)
+(* End of environment functions *)
+(* **************************** *)
+
+type ('code,'value) cell = Frozen of 'code | Thawed of 'value
+
+let rec satloop unchecked required required_states
+    ((grp,label,states) as m) phi env =
+  let rec loop unchecked required required_states phi =
+    (*Common.profile_code "satloop" (fun _ -> *)
+    let res =
+      match phi with
+      A.False              -> []
+    | A.True               -> triples_top states
+    | A.Pred(p)            -> satLabel label required p
+    | A.Uncheck(phi1) ->
+       let unchecked = if !pUNCHECK_OPT then true else false in
+       loop unchecked required required_states phi1
+    | A.Not(phi)           ->
+       let phires = loop unchecked required required_states phi in
+       (*let phires =
+         List.map (function (s,th,w) -> (s,th,[])) phires in*)
+       triples_complement (mkstates states required_states)
+         phires
+    | A.Or(phi1,phi2)      ->
+       triples_union
+         (loop unchecked required required_states phi1)
+         (loop unchecked required required_states phi2)
+    | A.SeqOr(phi1,phi2)      ->
+       let res1 = loop unchecked required required_states phi1 in
+       let res2 = loop unchecked required required_states phi2 in
+       let res1neg = unwitify res1 in
+       triples_union res1
+         (triples_conj
+            (triples_complement (mkstates states required_states) res1neg)
+            res2)
+    | A.And(strict,phi1,phi2)     ->
+       (* phi1 is considered to be more likely to be [], because of the
+          definition of asttoctl.  Could use heuristics such as the size of
+          the term *)
+       let pm = !Flag_ctl.partial_match in
+       (match (pm,loop unchecked required required_states phi1) with
+         (false,[]) when !pLazyOpt -> []
+       | (_,phi1res) ->
+           let new_required = extend_required phi1res required in
+           let new_required_states = get_required_states phi1res in
+           (match (pm,loop unchecked new_required new_required_states phi2)
+           with
+             (false,[]) when !pLazyOpt -> []
+           | (_,phi2res) ->
+               strict_triples_conj strict
+                 (mkstates states required_states)
+                 phi1res phi2res))
+    | A.AndAny(dir,strict,phi1,phi2)     ->
+       (* phi2 can appear anywhere that is reachable *)
+       let pm = !Flag_ctl.partial_match in
+       (match (pm,loop unchecked required required_states phi1) with
+         (false,[]) -> []
+       | (_,phi1res) ->
+           let new_required = extend_required phi1res required in
+           let new_required_states = get_required_states phi1res in
+           let new_required_states =
+             get_reachable dir m new_required_states in
+           (match (pm,loop unchecked new_required new_required_states phi2)
+           with
+             (false,[]) -> phi1res
+           | (_,phi2res) ->
+               (match phi1res with
+                 [] -> (* !Flag_ctl.partial_match must be true *)
+                   if phi2res = []
+                   then []
+                   else
+                     let s = mkstates states required_states in
+                     List.fold_left
+                       (function a -> function b ->
+                         strict_triples_conj strict s a [b])
+                       [List.hd phi2res] (List.tl phi2res)
+               | [(state,_,_)] ->
+                   let phi2res =
+                     List.map (function (s,e,w) -> [(state,e,w)]) phi2res in
+                   let s = mkstates states required_states in
+                   List.fold_left
+                     (function a -> function b ->
+                       strict_triples_conj strict s a b)
+                     phi1res phi2res
+               | _ ->
+                   failwith
+                     "only one result allowed for the left arg of AndAny")))
+    | A.HackForStmt(dir,strict,phi1,phi2)     ->
+       (* phi2 can appear anywhere that is reachable *)
+       let pm = !Flag_ctl.partial_match in
+       (match (pm,loop unchecked required required_states phi1) with
+         (false,[]) -> []
+       | (_,phi1res) ->
+           let new_required = extend_required phi1res required in
+           let new_required_states = get_required_states phi1res in
+           let new_required_states =
+             get_reachable dir m new_required_states in
+           (match (pm,loop unchecked new_required new_required_states phi2)
+           with
+             (false,[]) -> phi1res
+           | (_,phi2res) ->
+                   (* if there is more than one state, something about the
+                      environment has to ensure that the right triples of
+                      phi2 get associated with the triples of phi1.
+                      the asttoctl2 has to ensure that that is the case.
+                      these should thus be structural properties.
+                      env of phi2 has to be a proper subset of env of phi1
+                      to ensure all end up being consistent.  no new triples
+                      should be generated.  strict_triples_conj_none takes
+                      care of this.
+                   *)
+                   let s = mkstates states required_states in
+                   List.fold_left
+                     (function acc ->
+                       function (st,th,_) as phi2_elem ->
+                         let inverse =
+                           triples_complement [st] [(st,th,[])] in
+                         strict_triples_conj_none strict s acc
+                           (phi2_elem::inverse))
+                     phi1res phi2res))
+    | A.InnerAnd(phi) ->
+       inner_and(loop unchecked required required_states phi)
+    | A.EX(dir,phi)      ->
+       let new_required_states =
+         get_children_required_states dir m required_states in
+       satEX dir m (loop unchecked required new_required_states phi)
+         required_states
+    | A.AX(dir,strict,phi)      ->
+       let new_required_states =
+         get_children_required_states dir m required_states in
+       let res = loop unchecked required new_required_states phi in
+       strict_A1 strict satAX satEX dir m res required_states
+    | A.EF(dir,phi)            ->
+       let new_required_states = get_reachable dir m required_states in
+       satEF dir m (loop unchecked required new_required_states phi)
+         new_required_states
+    | A.AF(dir,strict,phi)            ->
+       if !Flag_ctl.loop_in_src_code
+       then
+         loop unchecked required required_states
+           (A.AU(dir,strict,A.True,phi))
+       else
+         let new_required_states = get_reachable dir m required_states in
+         let res = loop unchecked required new_required_states phi in
+         strict_A1 strict satAF satEF dir m res new_required_states
+    | A.EG(dir,phi)            ->
+       let new_required_states = get_reachable dir m required_states in
+       satEG dir m (loop unchecked required new_required_states phi)
+         new_required_states
+    | A.AG(dir,strict,phi)            ->
+       let new_required_states = get_reachable dir m required_states in
+       let res = loop unchecked required new_required_states phi in
+       strict_A1 strict satAG satEF dir m res new_required_states
+    | A.EU(dir,phi1,phi2)      ->
+       let new_required_states = get_reachable dir m required_states in
+       (match loop unchecked required new_required_states phi2 with
+         [] when !pLazyOpt -> []
+       | s2 ->
+           let new_required = extend_required s2 required in
+           let s1 = loop unchecked new_required new_required_states phi1 in
+           satEU dir m s1 s2 new_required_states)
+    | A.AW(dir,strict,phi1,phi2) ->
+       let new_required_states = get_reachable dir m required_states in
+       (match loop unchecked required new_required_states phi2 with
+         [] when !pLazyOpt -> []
+       | s2 ->
+           let new_required = extend_required s2 required in
+           let s1 = loop unchecked new_required new_required_states phi1 in
+           strict_A2 strict satAW satEF dir m s1 s2 new_required_states)
+    | A.AU(dir,strict,phi1,phi2) ->
+       (*Printf.printf "using AU\n"; flush stdout;*)
+       let new_required_states = get_reachable dir m required_states in
+       (match loop unchecked required new_required_states phi2 with
+         [] when !pLazyOpt -> []
+       | s2 ->
+           let new_required = extend_required s2 required in
+           let s1 = loop unchecked new_required new_required_states phi1 in
+           let res =
+             strict_A2au strict satAU satEF dir m s1 s2 new_required_states in
+           match res with
+             AUok res -> res
+           | AUfailed tmp_res ->
+               (* found a loop, have to try AW *)
+               (* the formula is
+                  A[E[phi1 U phi2] & phi1 W phi2]
+                  the and is nonstrict *)
+               (* tmp_res is bigger than s2, so perhaps closer to s1 *)
+               (*Printf.printf "using AW\n"; flush stdout;*)
+               let s1 =
+                 triples_conj (satEU dir m s1 tmp_res new_required_states)
+                   s1 in
+               strict_A2 strict satAW satEF dir m s1 s2 new_required_states)
+    | A.Implies(phi1,phi2) ->
+       loop unchecked required required_states (A.Or(A.Not phi1,phi2))
+    | A.Exists (keep,v,phi)     ->
+       let new_required = drop_required v required in
+       triples_witness v unchecked (not keep)
+         (loop unchecked new_required required_states phi)
+    | A.Let(v,phi1,phi2)   ->
+       (* should only be used when the properties unchecked, required,
+          and required_states are known to be the same or at least
+          compatible between all the uses.  this is not checked. *)
+       let res = loop unchecked required required_states phi1 in
+       satloop unchecked required required_states m phi2 ((v,res) :: env)
+    | A.LetR(dir,v,phi1,phi2)   ->
+       (* should only be used when the properties unchecked, required,
+          and required_states are known to be the same or at least
+          compatible between all the uses.  this is not checked. *)
+       let new_required_states = get_reachable dir m required_states in
+       let res = loop unchecked required new_required_states phi1 in
+       satloop unchecked required required_states m phi2 ((v,res) :: env)
+    | A.Ref(v)             ->
+       let res = List.assoc v env in
+       if unchecked
+       then List.map (function (s,th,_) -> (s,th,[])) res
+       else res
+    | A.XX(phi) -> failwith "should have been removed" in
+    if !Flag_ctl.bench > 0 then triples := !triples + (List.length res);
+    drop_wits required_states res phi (* ) *) in
+  
+  loop unchecked required required_states phi
+;;    
+
+
+(* SAT with tracking *)
+let rec sat_verbose_loop unchecked required required_states annot maxlvl lvl
+    ((_,label,states) as m) phi env =
+  let anno res children = (annot lvl phi res children,res) in
+  let satv unchecked required required_states phi0 env =
+    sat_verbose_loop unchecked required required_states annot maxlvl (lvl+1)
+      m phi0 env in
+  if (lvl > maxlvl) && (maxlvl > -1) then
+    anno (satloop unchecked required required_states m phi env) []
+  else
+    let (child,res) =
+      match phi with
+      A.False              -> anno [] []
+    | A.True               -> anno (triples_top states) []
+    | A.Pred(p)            ->
+       Printf.printf "label\n"; flush stdout;
+       anno (satLabel label required p) []
+    | A.Uncheck(phi1) ->
+       let unchecked = if !pUNCHECK_OPT then true else false in
+       let (child1,res1) = satv unchecked required required_states phi1 env in
+       Printf.printf "uncheck\n"; flush stdout;
+       anno res1 [child1]
+    | A.Not(phi1)          -> 
+       let (child,res) =
+         satv unchecked required required_states phi1 env in
+       Printf.printf "not\n"; flush stdout;
+       anno (triples_complement (mkstates states required_states) res) [child]
+    | A.Or(phi1,phi2)      -> 
+       let (child1,res1) =
+         satv unchecked required required_states phi1 env in
+       let (child2,res2) =
+         satv unchecked required required_states phi2 env in
+       Printf.printf "or\n"; flush stdout;
+       anno (triples_union res1 res2) [child1; child2]
+    | A.SeqOr(phi1,phi2)      -> 
+       let (child1,res1) =
+         satv unchecked required required_states phi1 env in
+       let (child2,res2) =
+         satv unchecked required required_states phi2 env in
+       let res1neg =
+         List.map (function (s,th,_) -> (s,th,[])) res1 in
+       Printf.printf "seqor\n"; flush stdout;
+       anno (triples_union res1
+               (triples_conj
+                  (triples_complement (mkstates states required_states)
+                     res1neg)
+                  res2))
+         [child1; child2]
+    | A.And(strict,phi1,phi2)     -> 
+       let pm = !Flag_ctl.partial_match in
+       (match (pm,satv unchecked required required_states phi1 env) with
+         (false,(child1,[])) ->
+           Printf.printf "and\n"; flush stdout; anno [] [child1]
+       | (_,(child1,res1)) ->
+           let new_required = extend_required res1 required in
+           let new_required_states = get_required_states res1 in
+           (match (pm,satv unchecked new_required new_required_states phi2
+                     env) with
+             (false,(child2,[])) ->
+               Printf.printf "and\n"; flush stdout; anno [] [child1;child2]
+           | (_,(child2,res2)) ->
+               Printf.printf "and\n"; flush stdout;
+               let res =
+                 strict_triples_conj strict
+                   (mkstates states required_states)
+                   res1 res2 in
+               anno res [child1; child2]))
+    | A.AndAny(dir,strict,phi1,phi2)     ->
+       let pm = !Flag_ctl.partial_match in 
+       (match (pm,satv unchecked required required_states phi1 env) with
+         (false,(child1,[])) ->
+           Printf.printf "and\n"; flush stdout; anno [] [child1]
+       | (_,(child1,res1)) ->
+           let new_required = extend_required res1 required in
+           let new_required_states = get_required_states res1 in
+           let new_required_states =
+             get_reachable dir m new_required_states in
+           (match (pm,satv unchecked new_required new_required_states phi2
+               env) with
+             (false,(child2,[])) ->
+               Printf.printf "andany\n"; flush stdout;
+               anno res1 [child1;child2]
+           | (_,(child2,res2)) ->
+               (match res1 with
+                 [] -> (* !Flag_ctl.partial_match must be true *)
+                   if res2 = []
+                   then anno [] [child1; child2]
+                   else 
+                     let res =
+                       let s = mkstates states required_states in
+                       List.fold_left
+                         (function a -> function b ->
+                           strict_triples_conj strict s a [b])
+                         [List.hd res2] (List.tl res2) in
+                     anno res [child1; child2]
+               | [(state,_,_)] ->
+                   let res2 =
+                     List.map (function (s,e,w) -> [(state,e,w)]) res2 in
+                   Printf.printf "andany\n"; flush stdout;
+                   let res =
+                     let s = mkstates states required_states in
+                     List.fold_left
+                       (function a -> function b ->
+                         strict_triples_conj strict s a b)
+                       res1 res2 in
+                   anno res [child1; child2]
+               | _ ->
+                   failwith
+                     "only one result allowed for the left arg of AndAny")))
+    | A.HackForStmt(dir,strict,phi1,phi2)     ->
+       let pm = !Flag_ctl.partial_match in 
+       (match (pm,satv unchecked required required_states phi1 env) with
+         (false,(child1,[])) ->
+           Printf.printf "and\n"; flush stdout; anno [] [child1]
+       | (_,(child1,res1)) ->
+           let new_required = extend_required res1 required in
+           let new_required_states = get_required_states res1 in
+           let new_required_states =
+             get_reachable dir m new_required_states in
+           (match (pm,satv unchecked new_required new_required_states phi2
+               env) with
+             (false,(child2,[])) ->
+               Printf.printf "andany\n"; flush stdout;
+               anno res1 [child1;child2]
+           | (_,(child2,res2)) ->
+               let res =
+                 let s = mkstates states required_states in
+                 List.fold_left
+                   (function acc ->
+                     function (st,th,_) as phi2_elem ->
+                       let inverse =
+                         triples_complement [st] [(st,th,[])] in
+                       strict_triples_conj_none strict s acc
+                         (phi2_elem::inverse))
+                   res1 res2 in
+               anno res [child1; child2]))
+    | A.InnerAnd(phi1) ->
+       let (child1,res1) = satv unchecked required required_states phi1 env in
+       Printf.printf "uncheck\n"; flush stdout;
+       anno (inner_and res1) [child1]
+    | A.EX(dir,phi1)       -> 
+       let new_required_states =
+         get_children_required_states dir m required_states in
+       let (child,res) =
+         satv unchecked required new_required_states phi1 env in
+       Printf.printf "EX\n"; flush stdout;
+       anno (satEX dir m res required_states) [child]
+    | A.AX(dir,strict,phi1)       -> 
+       let new_required_states =
+         get_children_required_states dir m required_states in
+       let (child,res) =
+         satv unchecked required new_required_states phi1 env in
+       Printf.printf "AX\n"; flush stdout;
+       let res = strict_A1 strict satAX satEX dir m res required_states in
+       anno res [child]
+    | A.EF(dir,phi1)       -> 
+       let new_required_states = get_reachable dir m required_states in
+       let (child,res) =
+         satv unchecked required new_required_states phi1 env in
+       Printf.printf "EF\n"; flush stdout;
+       anno (satEF dir m res new_required_states) [child]
+    | A.AF(dir,strict,phi1) -> 
+       if !Flag_ctl.loop_in_src_code
+       then
+         satv unchecked required required_states
+           (A.AU(dir,strict,A.True,phi1))
+           env
+       else
+         (let new_required_states = get_reachable dir m required_states in
+         let (child,res) =
+           satv unchecked required new_required_states phi1 env in
+         Printf.printf "AF\n"; flush stdout;
+         let res =
+           strict_A1 strict satAF satEF dir m res new_required_states in
+         anno res [child])
+    | A.EG(dir,phi1)       -> 
+       let new_required_states = get_reachable dir m required_states in
+       let (child,res) =
+         satv unchecked required new_required_states phi1 env in
+       Printf.printf "EG\n"; flush stdout;
+       anno (satEG dir m res new_required_states) [child]
+    | A.AG(dir,strict,phi1)       -> 
+       let new_required_states = get_reachable dir m required_states in
+       let (child,res) =
+         satv unchecked required new_required_states phi1 env in
+       Printf.printf "AG\n"; flush stdout;
+       let res = strict_A1 strict satAG satEF dir m res new_required_states in
+       anno res [child]
+         
+    | A.EU(dir,phi1,phi2)  -> 
+       let new_required_states = get_reachable dir m required_states in
+       (match satv unchecked required new_required_states phi2 env with
+         (child2,[]) ->
+           Printf.printf "EU\n"; flush stdout;
+           anno [] [child2]
+       | (child2,res2) ->
+           let new_required = extend_required res2 required in
+           let (child1,res1) =
+             satv unchecked new_required new_required_states phi1 env in
+           Printf.printf "EU\n"; flush stdout;
+           anno (satEU dir m res1 res2 new_required_states) [child1; child2])
+    | A.AW(dir,strict,phi1,phi2)      -> 
+       failwith "should not be used" (*
+         let new_required_states = get_reachable dir m required_states in
+         (match satv unchecked required new_required_states phi2 env with
+           (child2,[]) ->
+             Printf.printf "AW %b\n" unchecked; flush stdout; anno [] [child2]
+         | (child2,res2) ->
+             let new_required = extend_required res2 required in
+             let (child1,res1) =
+               satv unchecked new_required new_required_states phi1 env in
+             Printf.printf "AW %b\n" unchecked; flush stdout;
+             let res =
+               strict_A2 strict satAW satEF dir m res1 res2
+                 new_required_states in
+             anno res [child1; child2]) *)
+    | A.AU(dir,strict,phi1,phi2)      -> 
+       let new_required_states = get_reachable dir m required_states in
+       (match satv unchecked required new_required_states phi2 env with
+         (child2,[]) ->
+           Printf.printf "AU\n"; flush stdout; anno [] [child2]
+       | (child2,s2) ->
+           let new_required = extend_required s2 required in
+           let (child1,s1) =
+             satv unchecked new_required new_required_states phi1 env in
+           Printf.printf "AU\n"; flush stdout;
+           let res =
+             strict_A2au strict satAU satEF dir m s1 s2 new_required_states in
+           (match res with
+             AUok res ->
+               anno res [child1; child2]
+           | AUfailed tmp_res ->
+               (* found a loop, have to try AW *)
+               (* the formula is
+                  A[E[phi1 U phi2] & phi1 W phi2]
+                  the and is nonstrict *)
+               (* tmp_res is bigger than s2, so perhaps closer to s1 *)
+             Printf.printf "AW\n"; flush stdout;
+             let s1 =
+               triples_conj (satEU dir m s1 tmp_res new_required_states) s1 in
+             let res =
+               strict_A2 strict satAW satEF dir m s1 s2 new_required_states in
+             anno res [child1; child2]))
+    | A.Implies(phi1,phi2) -> 
+       satv unchecked required required_states
+         (A.Or(A.Not phi1,phi2))
+         env
+    | A.Exists (keep,v,phi1)    -> 
+       let new_required = drop_required v required in
+       let (child,res) =
+         satv unchecked new_required required_states phi1 env in
+       Printf.printf "exists\n"; flush stdout;
+       anno (triples_witness v unchecked (not keep) res) [child]
+    | A.Let(v,phi1,phi2)   ->
+       let (child1,res1) =
+         satv unchecked required required_states phi1 env in
+       let (child2,res2) =
+         satv unchecked required required_states phi2 ((v,res1) :: env) in
+       anno res2 [child1;child2]
+    | A.LetR(dir,v,phi1,phi2)   ->
+       let new_required_states = get_reachable dir m required_states in
+       let (child1,res1) =
+         satv unchecked required new_required_states phi1 env in
+       let (child2,res2) =
+         satv unchecked required required_states phi2 ((v,res1) :: env) in
+       anno res2 [child1;child2]
+    | A.Ref(v)             ->
+       Printf.printf "Ref\n"; flush stdout;
+       let res = List.assoc v env in
+       let res =
+         if unchecked
+         then List.map (function (s,th,_) -> (s,th,[])) res
+         else res in
+       anno res []
+    | A.XX(phi) -> failwith "should have been removed" in
+    let res1 = drop_wits required_states res phi in
+    if not(res1 = res)
+    then
+      begin
+       print_required_states required_states;
+      print_state "after drop_wits" res1 end;
+    (child,res1)
+       
+;;
+
+let sat_verbose annotate maxlvl lvl m phi =
+  sat_verbose_loop false [] None annotate maxlvl lvl m phi []
+
+(* Type for annotations collected in a tree *)
+type ('a) witAnnoTree = WitAnno of ('a * ('a witAnnoTree) list);;
+
+let sat_annotree annotate m phi =
+  let tree_anno l phi res chld = WitAnno(annotate l phi res,chld) in
+    sat_verbose_loop false [] None tree_anno (-1) 0 m phi []
+;;
+
+(*
+let sat m phi = satloop m phi []
+;;
+*)
+
+let simpleanno l phi res =
+  let pp s = 
+    Format.print_string ("\n" ^ s ^ "\n------------------------------\n"); 
+    print_generic_algo (List.sort compare res);
+    Format.print_string "\n------------------------------\n\n" in
+  let pp_dir = function
+      A.FORWARD -> ()
+    | A.BACKWARD -> pp "^" in
+  match phi with
+    | A.False              -> pp "False"
+    | A.True               -> pp "True"
+    | A.Pred(p)            -> pp ("Pred" ^ (Common.dump p))
+    | A.Not(phi)           -> pp "Not"
+    | A.Exists(_,v,phi)    -> pp ("Exists " ^ (Common.dump(v)))
+    | A.And(_,phi1,phi2)   -> pp "And"
+    | A.AndAny(dir,_,phi1,phi2) -> pp "AndAny"
+    | A.HackForStmt(dir,_,phi1,phi2) -> pp "HackForStmt"
+    | A.Or(phi1,phi2)      -> pp "Or"
+    | A.SeqOr(phi1,phi2)   -> pp "SeqOr"
+    | A.Implies(phi1,phi2) -> pp "Implies"
+    | A.AF(dir,_,phi1)     -> pp "AF"; pp_dir dir
+    | A.AX(dir,_,phi1)     -> pp "AX"; pp_dir dir
+    | A.AG(dir,_,phi1)     -> pp "AG"; pp_dir dir
+    | A.AW(dir,_,phi1,phi2)-> pp "AW"; pp_dir dir
+    | A.AU(dir,_,phi1,phi2)-> pp "AU"; pp_dir dir
+    | A.EF(dir,phi1)       -> pp "EF"; pp_dir dir
+    | A.EX(dir,phi1)      -> pp "EX"; pp_dir dir
+    | A.EG(dir,phi1)      -> pp "EG"; pp_dir dir
+    | A.EU(dir,phi1,phi2)  -> pp "EU"; pp_dir dir
+    | A.Let (x,phi1,phi2)  -> pp ("Let"^" "^x)
+    | A.LetR (dir,x,phi1,phi2) -> pp ("LetR"^" "^x); pp_dir dir
+    | A.Ref(s)             -> pp ("Ref("^s^")")
+    | A.Uncheck(s)         -> pp "Uncheck"
+    | A.InnerAnd(s)        -> pp "InnerAnd"
+    | A.XX(phi1)           -> pp "XX"
+;;
+
+
+(* pad: Rene, you can now use the module pretty_print_ctl.ml to
+   print a ctl formula more accurately if you want.
+   Use the print_xxx provided in the different module to call 
+   Pretty_print_ctl.pp_ctl.
+ *)
+
+let simpleanno2 l phi res = 
+  begin
+    Pretty_print_ctl.pp_ctl (P.print_predicate, SUB.print_mvar) false phi;
+    Format.print_newline ();
+    Format.print_string "----------------------------------------------------";
+    Format.print_newline ();
+    print_generic_algo (List.sort compare res);
+    Format.print_newline ();
+    Format.print_string "----------------------------------------------------";
+    Format.print_newline ();
+    Format.print_newline ();
+  end
+
+
+(* ---------------------------------------------------------------------- *)
+(* Benchmarking                                                           *)
+(* ---------------------------------------------------------------------- *)
+
+type optentry = bool ref * string
+type options = {label : optentry; unch : optentry;
+                conj : optentry; compl1 : optentry; compl2 : optentry;
+                newinfo : optentry;
+                reqenv : optentry; reqstates : optentry}
+
+let options =
+  {label = (pSATLABEL_MEMO_OPT,"satlabel_memo_opt");
+    unch = (pUNCHECK_OPT,"uncheck_opt");
+    conj = (pTRIPLES_CONJ_OPT,"triples_conj_opt");
+    compl1 = (pTRIPLES_COMPLEMENT_OPT,"triples_complement_opt");
+    compl2 = (pTRIPLES_COMPLEMENT_SIMPLE_OPT,"triples_complement_simple_opt");
+    newinfo = (pNEW_INFO_OPT,"new_info_opt");
+    reqenv = (pREQUIRED_ENV_OPT,"required_env_opt");
+    reqstates = (pREQUIRED_STATES_OPT,"required_states_opt")}
+
+let baseline =
+  [("none                    ",[]);
+    ("label                   ",[options.label]);
+    ("unch                    ",[options.unch]);
+    ("unch and label          ",[options.label;options.unch])]
+
+let conjneg =
+  [("conj                    ", [options.conj]);
+    ("compl1                  ", [options.compl1]);
+    ("compl12                 ", [options.compl1;options.compl2]);
+    ("conj/compl12            ", [options.conj;options.compl1;options.compl2]);
+    ("conj unch satl          ", [options.conj;options.unch;options.label]);
+(*
+    ("compl1 unch satl        ", [options.compl1;options.unch;options.label]);
+    ("compl12 unch satl       ",
+     [options.compl1;options.compl2;options.unch;options.label]); *)
+    ("conj/compl12 unch satl  ",
+     [options.conj;options.compl1;options.compl2;options.unch;options.label])]
+
+let path =
+  [("newinfo                 ", [options.newinfo]);
+    ("newinfo unch satl       ", [options.newinfo;options.unch;options.label])]
+
+let required =
+  [("reqenv                  ", [options.reqenv]);
+    ("reqstates               ", [options.reqstates]);
+    ("reqenv/states           ", [options.reqenv;options.reqstates]);
+(*  ("reqenv unch satl        ", [options.reqenv;options.unch;options.label]);
+    ("reqstates unch satl     ",
+     [options.reqstates;options.unch;options.label]);*)
+    ("reqenv/states unch satl ",
+     [options.reqenv;options.reqstates;options.unch;options.label])]
+
+let all_options =
+  [options.label;options.unch;options.conj;options.compl1;options.compl2;
+    options.newinfo;options.reqenv;options.reqstates]
+
+let all =
+  [("all                     ",all_options)]
+
+let all_options_but_path =
+  [options.label;options.unch;options.conj;options.compl1;options.compl2;
+    options.reqenv;options.reqstates]
+
+let all_but_path = ("all but path            ",all_options_but_path)
+
+let counters =
+  [(satAW_calls, "satAW", ref 0);
+    (satAU_calls, "satAU", ref 0);
+    (satEF_calls, "satEF", ref 0);
+    (satAF_calls, "satAF", ref 0);
+    (satEG_calls, "satEG", ref 0);
+    (satAG_calls, "satAG", ref 0);
+  (satEU_calls, "satEU", ref 0)]
+
+let perms =
+  map
+    (function (opt,x) ->
+      (opt,x,ref 0.0,ref 0,
+       List.map (function _ -> (ref 0, ref 0, ref 0)) counters))
+    [List.hd all;all_but_path]
+  (*(all@baseline@conjneg@path@required)*)
+
+exception Out
+
+let rec iter fn = function
+    1 -> fn()
+  | n -> let _ = fn() in
+    (Hashtbl.clear reachable_table;
+     Hashtbl.clear memo_label;
+     triples := 0;
+     iter fn (n-1))
+
+let copy_to_stderr fl =
+  let i = open_in fl in
+  let rec loop _ =
+    Printf.fprintf stderr "%s\n" (input_line i);
+    loop() in
+  try loop() with _ -> ();
+  close_in i
+
+let bench_sat (_,_,states) fn =
+  List.iter (function (opt,_) -> opt := false) all_options;
+  let answers =
+    concatmap
+      (function (name,options,time,trips,counter_info) ->
+       let iterct = !Flag_ctl.bench in
+       if !time > float_of_int timeout then time := -100.0;
+       if not (!time = -100.0)
+       then
+         begin
+           Hashtbl.clear reachable_table;
+           Hashtbl.clear memo_label;
+           List.iter (function (opt,_) -> opt := true) options;
+           List.iter (function (calls,_,save_calls) -> save_calls := !calls)
+             counters;
+           triples := 0;
+           let res =
+             let bef = Sys.time() in
+             try
+               Common.timeout_function timeout
+                 (fun () ->
+                   let bef = Sys.time() in
+                   let res = iter fn iterct in
+                   let aft = Sys.time() in
+                   time := !time +. (aft -. bef);
+                   trips := !trips + !triples;
+                   List.iter2
+                     (function (calls,_,save_calls) ->
+                       function (current_calls,current_cfg,current_max_cfg) ->
+                         current_calls :=
+                           !current_calls + (!calls - !save_calls);
+                         if (!calls - !save_calls) > 0
+                         then
+                           (let st = List.length states in
+                           current_cfg := !current_cfg + st;
+                           if st > !current_max_cfg
+                           then current_max_cfg := st))
+                     counters counter_info;
+                   [res])
+             with
+               Common.Timeout ->
+                 begin
+                   let aft = Sys.time() in
+                   time := -100.0;
+                   Printf.fprintf stderr "Timeout at %f on: %s\n"
+                     (aft -. bef) name;
+                   []
+                 end in
+           List.iter (function (opt,_) -> opt := false) options;
+           res
+         end
+       else [])
+      perms in
+  Printf.fprintf stderr "\n";
+  match answers with
+    [] -> []
+  | res::rest ->
+      (if not(List.for_all (function x -> x = res) rest)
+      then
+       (List.iter (print_state "a state") answers;
+        Printf.printf "something doesn't work\n");
+      res)
+      
+let print_bench _ =
+  let iterct = !Flag_ctl.bench in
+  if iterct > 0
+  then
+    (List.iter
+       (function (name,options,time,trips,counter_info) ->
+        Printf.fprintf stderr "%s Numbers: %f %d "
+          name (!time /. (float_of_int iterct)) !trips;
+        List.iter
+          (function (calls,cfg,max_cfg) ->
+            Printf.fprintf stderr "%d %d %d " (!calls / iterct) !cfg !max_cfg)
+          counter_info;
+        Printf.fprintf stderr "\n")
+       perms)
+
+(* ---------------------------------------------------------------------- *)
+(* preprocessing: ignore irrelevant functions *)
+
+let preprocess (cfg,_,_) label = function
+    [] -> true (* no information, try everything *)
+  | l ->
+      let sz = G.size cfg in
+      let verbose_output pred = function
+         [] ->
+           Printf.printf "did not find:\n";
+           P.print_predicate pred; Format.print_newline()
+       | _ ->
+           Printf.printf "found:\n";
+           P.print_predicate pred; Format.print_newline();
+           Printf.printf "but it was not enough\n" in
+      let get_any verbose x =
+       let res =
+         try Hashtbl.find memo_label x
+         with
+           Not_found ->
+             (let triples = label x in
+             let filtered =
+               List.map (function (st,th,_) -> (st,th)) triples in
+             Hashtbl.add memo_label x filtered;
+             filtered) in
+       if verbose then verbose_output x res;
+       not([] = res) in
+      let get_all l =
+       (* don't bother testing when there are more patterns than nodes *)
+       if List.length l > sz-2
+       then false
+       else List.for_all (get_any false) l in
+      if List.exists get_all l
+      then true
+      else
+       (if !Flag_ctl.verbose_match
+       then
+          List.iter (List.iter (function x -> let _ = get_any true x in ()))
+           l;
+        false)
+
+let filter_partial_matches trips =
+  if !Flag_ctl.partial_match
+  then
+    let anynegwit = (* if any is neg, then all are *)
+      List.exists (function A.NegWit _ -> true | A.Wit _ -> false) in
+    let (bad,good) =
+      List.partition (function (s,th,wit) -> anynegwit wit) trips in
+    (match bad with
+      [] -> ()
+    | _ -> print_state "partial matches" bad; Format.print_newline());
+    good
+  else trips
+
+(* ---------------------------------------------------------------------- *)
+(* Main entry point for engine *)
+let sat m phi reqopt =
+  try
+    (match !Flag_ctl.steps with
+      None -> step_count := 0
+    | Some x -> step_count := x);
+    Hashtbl.clear reachable_table;
+    Hashtbl.clear memo_label;
+    let (x,label,states) = m in
+    if (!Flag_ctl.bench > 0) or (preprocess m label reqopt)
+    then
+      ((* to drop when Yoann initialized this flag *)
+      if List.exists (G.extract_is_loop x) states
+      then Flag_ctl.loop_in_src_code := true;
+      let m = (x,label,List.sort compare states) in
+      let res =
+       if(!Flag_ctl.verbose_ctl_engine)
+       then
+         let fn _ = snd (sat_annotree simpleanno2 m phi) in
+         if !Flag_ctl.bench > 0
+         then bench_sat m fn
+         else fn()
+       else
+         let fn _ = satloop false [] None m phi [] in
+         if !Flag_ctl.bench > 0
+         then bench_sat m fn
+         else Common.profile_code "ctl" (fun _ -> fn()) in
+      let res = filter_partial_matches res in
+      (*
+      Printf.printf "steps: start %d, stop %d\n"
+       (match !Flag_ctl.steps with Some x -> x | _ -> 0)
+       !step_count;
+      Printf.printf "triples: %d\n" !triples;
+      print_state "final result" res;
+      *)
+      res)
+    else
+      (if !Flag_ctl.verbose_ctl_engine
+      then Common.pr2 "missing something required";
+       [])
+  with Steps -> []
+;;
+
+(* ********************************************************************** *)
+(* End of Module: CTL_ENGINE                                              *)
+(* ********************************************************************** *)
+end
+;;
+
diff --git a/ctl/.#ctl_engine.ml.1.187 b/ctl/.#ctl_engine.ml.1.187
new file mode 100644 (file)
index 0000000..cee310c
--- /dev/null
@@ -0,0 +1,2418 @@
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+* 
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+* 
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
+* 
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+(*external c_counter : unit -> int = "c_counter"*)
+let timeout = 800
+(* Optimize triples_conj by first extracting the intersection of the two sets,
+which can certainly be in the intersection *)
+let pTRIPLES_CONJ_OPT = ref true
+(* For complement, make NegState for the negation of a single state *)
+let pTRIPLES_COMPLEMENT_OPT = ref true
+(* For complement, do something special for the case where the environment
+and witnesses are empty *)
+let pTRIPLES_COMPLEMENT_SIMPLE_OPT = ref true
+(* "Double negate" the arguments of the path operators *)
+let pDOUBLE_NEGATE_OPT = ref true
+(* Only do pre_forall/pre_exists on new elements in fixpoint iteration *)
+let pNEW_INFO_OPT = ref true
+(* Filter the result of the label function to drop entries that aren't
+compatible with any of the available environments *)
+let pREQUIRED_ENV_OPT = ref true
+(* Memoize the raw result of the label function *)
+let pSATLABEL_MEMO_OPT = ref true
+(* Filter results according to the required states *)
+let pREQUIRED_STATES_OPT = ref true
+(* Drop negative witnesses at Uncheck *)
+let pUNCHECK_OPT = ref true
+let pANY_NEG_OPT = ref true
+let pLazyOpt = ref true
+
+(*
+let pTRIPLES_CONJ_OPT = ref false
+let pTRIPLES_COMPLEMENT_OPT = ref false
+let pTRIPLES_COMPLEMENT_SIMPLE_OPT = ref false
+let pDOUBLE_NEGATE_OPT = ref false
+let pNEW_INFO_OPT = ref false
+let pREQUIRED_ENV_OPT = ref false
+let pSATLABEL_MEMO_OPT = ref false
+let pREQUIRED_STATES_OPT = ref false
+let pUNCHECK_OPT = ref false
+let pANY_NEG_OPT = ref false
+let pLazyOpt = ref false
+*)
+
+
+let step_count = ref 0
+exception Steps
+let inc_step _ =
+  if not (!step_count = 0)
+  then
+    begin
+      step_count := !step_count - 1;
+      if !step_count = 0 then raise Steps
+    end
+
+let inc cell = cell := !cell + 1
+
+let satEU_calls = ref 0
+let satAW_calls = ref 0
+let satAU_calls = ref 0
+let satEF_calls = ref 0
+let satAF_calls = ref 0
+let satEG_calls = ref 0
+let satAG_calls = ref 0
+
+let triples = ref 0
+
+let ctr = ref 0
+let new_let _ =
+  let c = !ctr in
+  ctr := c + 1;
+  Printf.sprintf "_fresh_r_%d" c
+
+(* **********************************************************************
+ *
+ * Implementation of a Witness Tree model checking engine for CTL-FVex 
+ * 
+ *
+ * **********************************************************************)
+
+(* ********************************************************************** *)
+(* Module: SUBST (substitutions: meta. vars and values)                   *)
+(* ********************************************************************** *)
+
+module type SUBST =
+  sig
+    type value
+    type mvar
+    val eq_mvar: mvar -> mvar -> bool
+    val eq_val: value -> value -> bool
+    val merge_val: value -> value -> value
+    val print_mvar : mvar -> unit
+    val print_value : value -> unit
+  end
+;;
+
+(* ********************************************************************** *)
+(* Module: GRAPH (control flow graphs / model)                            *)
+(* ********************************************************************** *)
+
+module type GRAPH =
+  sig
+    type node
+    type cfg
+    val predecessors:     cfg -> node -> node list
+    val successors:       cfg -> node -> node list
+    val extract_is_loop : cfg -> node -> bool
+    val print_node :      node -> unit
+    val size :            cfg -> int
+  end
+;;
+
+module OGRAPHEXT_GRAPH = 
+  struct
+    type node = int;;
+    type cfg = (string,unit) Ograph_extended.ograph_mutable;;
+    let predecessors cfg n = List.map fst ((cfg#predecessors n)#tolist);;
+    let print_node i = Format.print_string (Common.i_to_s i)
+  end
+;;
+
+(* ********************************************************************** *)
+(* Module: PREDICATE (predicates for CTL formulae)                        *)
+(* ********************************************************************** *)
+
+module type PREDICATE =
+sig
+  type t
+  val print_predicate : t -> unit
+end
+
+
+(* ********************************************************************** *)
+
+(* ---------------------------------------------------------------------- *)
+(* Misc. useful generic functions                                         *)
+(* ---------------------------------------------------------------------- *)
+
+let head = List.hd
+
+let tail l = 
+  match l with
+    [] -> []
+  | (x::xs) -> xs
+;;
+
+let foldl = List.fold_left;;
+
+let foldl1 f xs = foldl f (head xs) (tail xs)
+
+type 'a esc = ESC of 'a | CONT of 'a
+
+let foldr = List.fold_right;;
+
+let concat = List.concat;;
+
+let map = List.map;;
+
+let filter = List.filter;;
+
+let partition = List.partition;;
+
+let concatmap f l = List.concat (List.map f l);;
+
+let maybe f g opt =
+  match opt with
+    | None -> g
+    | Some x -> f x
+;;
+
+let some_map f opts = map (maybe (fun x -> Some (f x)) None) opts
+
+let some_tolist_alt opts = concatmap (maybe (fun x -> [x]) []) opts
+
+let rec some_tolist opts =
+  match opts with
+    | []             -> []
+    | (Some x)::rest -> x::(some_tolist rest)
+    | _::rest        -> some_tolist rest 
+;;
+
+let rec groupBy eq l =
+    match l with
+      [] -> []
+    | (x::xs) -> 
+       let (xs1,xs2) = partition (fun x' -> eq x x') xs in
+       (x::xs1)::(groupBy eq xs2)
+;;
+
+let group l = groupBy (=) l;;
+
+let rec memBy eq x l =
+  match l with
+    [] -> false
+  | (y::ys) -> if (eq x y) then true else (memBy eq x ys)
+;;
+
+let rec nubBy eq ls =
+  match ls with
+    [] -> []
+  | (x::xs) when (memBy eq x xs) -> nubBy eq xs
+  | (x::xs) -> x::(nubBy eq xs)
+;;
+
+let rec nub ls =
+  match ls with
+    [] -> []
+  | (x::xs) when (List.mem x xs) -> nub xs
+  | (x::xs) -> x::(nub xs)
+;;
+
+let state_compare (s1,_,_) (s2,_,_) = compare s1 s2
+
+let setifyBy eq xs = nubBy eq xs;;
+
+let setify xs = nub xs;;
+
+let inner_setify xs = List.sort compare (nub xs);;
+
+let unionBy compare eq xs = function
+    [] -> xs
+  | ys ->
+      let rec loop = function
+         [] -> ys
+       | x::xs -> if memBy eq x ys then loop xs else x::(loop xs) in
+      List.sort compare (loop xs)
+;;
+
+let union xs ys = unionBy state_compare (=) xs ys;;
+
+let setdiff xs ys = filter (fun x -> not (List.mem x ys)) xs;;
+
+let subseteqBy eq xs ys = List.for_all (fun x -> memBy eq x ys) xs;;
+
+let subseteq xs ys = List.for_all (fun x -> List.mem x ys) xs;;
+let supseteq xs ys = subseteq ys xs
+
+let setequalBy eq xs ys = (subseteqBy eq xs ys) & (subseteqBy eq ys xs);;
+
+let setequal xs ys = (subseteq xs ys) & (subseteq ys xs);;
+
+(* Fix point calculation *)
+let rec fix eq f x =
+  let x' = f x in if (eq x' x) then x' else fix eq f x'
+;;
+
+(* Fix point calculation on set-valued functions *)
+let setfix f x = (fix subseteq f x) (*if new is a subset of old, stop*)
+let setgfix f x = (fix supseteq f x) (*if new is a supset of old, stop*)
+
+let get_states l = nub (List.map (function (s,_,_) -> s) l)
+
+(* ********************************************************************** *)
+(* Module: CTL_ENGINE                                                     *)
+(* ********************************************************************** *)
+
+module CTL_ENGINE =
+  functor (SUB : SUBST) -> 
+    functor (G : GRAPH) ->
+      functor (P : PREDICATE) ->
+struct
+
+module A = Ast_ctl
+
+type substitution = (SUB.mvar, SUB.value) Ast_ctl.generic_substitution
+
+type ('pred,'anno) witness =
+    (G.node, substitution,
+     ('pred, SUB.mvar, 'anno) Ast_ctl.generic_ctl list)
+      Ast_ctl.generic_witnesstree
+
+type ('pred,'anno) triples =
+    (G.node * substitution * ('pred,'anno) witness list) list
+
+(* ---------------------------------------------------------------------- *)
+(* Pretty printing functions *)
+(* ---------------------------------------------------------------------- *)
+
+let (print_generic_substitution : substitution -> unit) = fun substxs ->
+  let print_generic_subst = function
+      A.Subst (mvar, v) ->
+       SUB.print_mvar mvar; Format.print_string " --> "; SUB.print_value v
+    | A.NegSubst (mvar, v) -> 
+       SUB.print_mvar mvar; Format.print_string " -/-> "; SUB.print_value v in
+  Format.print_string "[";
+  Common.print_between (fun () -> Format.print_string ";" )
+    print_generic_subst substxs;
+  Format.print_string "]"
+
+let rec (print_generic_witness: ('pred, 'anno) witness -> unit) =
+  function
+  | A.Wit (state, subst, anno, childrens) -> 
+      Format.print_string "wit ";
+      G.print_node state;
+      print_generic_substitution subst;
+      (match childrens with
+       [] -> Format.print_string "{}"
+      |        _ -> 
+         Format.force_newline(); Format.print_string "   "; Format.open_box 0;
+         print_generic_witnesstree childrens; Format.close_box())
+  | A.NegWit(wit) -> 
+      Format.print_string "!";
+      print_generic_witness wit
+
+and (print_generic_witnesstree: ('pred,'anno) witness list -> unit) =
+  fun witnesstree ->
+    Format.open_box 1;
+    Format.print_string "{";
+    Common.print_between
+      (fun () -> Format.print_string ";"; Format.force_newline() ) 
+      print_generic_witness witnesstree;
+    Format.print_string "}";
+    Format.close_box()
+      
+and print_generic_triple (node,subst,tree) =
+  G.print_node node;
+  print_generic_substitution subst;
+  print_generic_witnesstree tree
+
+and (print_generic_algo : ('pred,'anno) triples -> unit) = fun xs -> 
+  Format.print_string "<";
+  Common.print_between
+    (fun () -> Format.print_string ";"; Format.force_newline())
+    print_generic_triple xs;
+  Format.print_string ">"
+;;
+
+let print_state (str : string) (l : ('pred,'anno) triples) =
+  Printf.printf "%s\n" str;
+  List.iter (function x ->
+    print_generic_triple x; Format.print_newline(); flush stdout)
+    (List.sort compare l);
+  Printf.printf "\n"
+    
+let print_required_states = function
+    None -> Printf.printf "no required states\n"
+  | Some states ->
+      Printf.printf "required states: ";
+      List.iter
+       (function x ->
+         G.print_node x; Format.print_string " "; Format.print_flush())
+       states;
+      Printf.printf "\n"
+
+let mkstates states = function
+    None -> states
+  | Some states -> states
+    
+(* ---------------------------------------------------------------------- *)
+(*                                                                        *)
+(* ---------------------------------------------------------------------- *)
+    
+    
+(* ************************* *)
+(* Substitutions             *)
+(* ************************* *)
+    
+let dom_sub sub =
+  match sub with
+  | A.Subst(x,_)    -> x
+  | A.NegSubst(x,_) -> x
+;;
+       
+let ran_sub sub =
+  match sub with
+  | A.Subst(_,x)    -> x
+  | A.NegSubst(_,x) -> x
+;;
+       
+let eq_subBy eqx eqv sub sub' =
+  match (sub,sub') with 
+    | (A.Subst(x,v),A.Subst(x',v'))       -> (eqx x x') && (eqv v v')
+    | (A.NegSubst(x,v),A.NegSubst(x',v')) -> (eqx x x') && (eqv v v')
+    | _                               -> false
+;;
+
+(* NOTE: functor *)
+let eq_sub sub sub' = eq_subBy SUB.eq_mvar SUB.eq_val sub sub'
+
+let eq_subst th th' = setequalBy eq_sub th th';;
+
+let merge_subBy eqx (===) (>+<) sub sub' =
+  (* variable part is guaranteed to be the same *)
+  match (sub,sub') with
+    (A.Subst (x,v),A.Subst (x',v')) -> 
+      if (v === v')
+      then Some [A.Subst(x, v >+< v')]
+      else None
+  | (A.NegSubst(x,v),A.Subst(x',v')) ->
+      if (not (v === v'))
+      then Some [A.Subst(x',v')]
+      else None
+  | (A.Subst(x,v),A.NegSubst(x',v')) ->
+      if (not (v === v'))
+      then Some [A.Subst(x,v)]
+      else None
+  | (A.NegSubst(x,v),A.NegSubst(x',v')) ->
+      if (v === v')
+      then
+       let merged = v >+< v' in
+       if merged = v && merged = v'
+       then Some [A.NegSubst(x,v >+< v')]
+       else
+         (* positions are compatible, but not identical. keep apart. *)
+         Some [A.NegSubst(x,v);A.NegSubst(x',v')]
+      else Some [A.NegSubst(x,v);A.NegSubst(x',v')]
+;;
+
+(* NOTE: functor *)
+let merge_sub sub sub' = 
+  merge_subBy SUB.eq_mvar SUB.eq_val SUB.merge_val sub sub'
+
+let clean_substBy eq cmp theta = List.sort cmp (nubBy eq theta);;
+
+(* NOTE: we sort by using the generic "compare" on (meta-)variable
+ *   names; we could also require a definition of compare for meta-variables 
+ *   or substitutions but that seems like overkill for sorting
+ *)
+let clean_subst theta = 
+  let res = 
+    clean_substBy eq_sub
+      (fun s s' ->
+       let res = compare (dom_sub s) (dom_sub s') in
+       if res = 0
+       then
+         match (s,s') with
+           (A.Subst(_,_),A.NegSubst(_,_)) -> -1
+         | (A.NegSubst(_,_),A.Subst(_,_)) -> 1
+         | _ -> compare (ran_sub s) (ran_sub s')
+       else res)
+      theta in
+  let rec loop = function
+      [] -> []
+    | (A.Subst(x,v)::A.NegSubst(y,v')::rest) when SUB.eq_mvar x y ->
+       loop (A.Subst(x,v)::rest)
+    | x::xs -> x::(loop xs) in
+  loop res
+
+let top_subst = [];;                   (* Always TRUE subst. *)
+
+(* Split a theta in two parts: one with (only) "x" and one without *)
+(* NOTE: functor *)
+let split_subst theta x = 
+  partition (fun sub -> SUB.eq_mvar (dom_sub sub) x) theta;;
+
+exception SUBST_MISMATCH
+let conj_subst theta theta' =
+  match (theta,theta') with
+    | ([],_) -> Some theta'
+    | (_,[]) -> Some theta
+    | _ ->
+       let rec classify = function
+           [] -> []
+         | [x] -> [(dom_sub x,[x])]
+         | x::xs ->
+             (match classify xs with
+               ((nm,y)::ys) as res ->
+                 if dom_sub x = nm
+                 then (nm,x::y)::ys
+                 else (dom_sub x,[x])::res
+             | _ -> failwith "not possible") in
+       let merge_all theta theta' =
+         foldl
+           (function rest ->
+             function sub ->
+               foldl
+                 (function rest ->
+                   function sub' ->
+                     match (merge_sub sub sub') with
+                       Some subs -> subs @ rest
+                     | _         -> raise SUBST_MISMATCH)
+                 rest theta')
+           [] theta in
+       let rec loop = function
+           ([],ctheta') ->
+             List.concat (List.map (function (_,ths) -> ths) ctheta')
+         | (ctheta,[]) ->
+             List.concat (List.map (function (_,ths) -> ths) ctheta)
+         | ((x,ths)::xs,(y,ths')::ys) ->
+             (match compare x y with
+               0 -> (merge_all ths ths') @ loop (xs,ys)
+             | -1 -> ths @ loop (xs,((y,ths')::ys))
+             | 1 -> ths' @ loop (((x,ths)::xs),ys)
+             | _ -> failwith "not possible") in
+       try Some (clean_subst(loop (classify theta, classify theta')))
+       with SUBST_MISMATCH -> None
+;;
+
+(* theta' must be a subset of theta *)
+let conj_subst_none theta theta' =
+  match (theta,theta') with
+    | (_,[]) -> Some theta
+    | ([],_) -> None
+    | _ ->
+       let rec classify = function
+           [] -> []
+         | [x] -> [(dom_sub x,[x])]
+         | x::xs ->
+             (match classify xs with
+               ((nm,y)::ys) as res ->
+                 if dom_sub x = nm
+                 then (nm,x::y)::ys
+                 else (dom_sub x,[x])::res
+             | _ -> failwith "not possible") in
+       let merge_all theta theta' =
+         foldl
+           (function rest ->
+             function sub ->
+               foldl
+                 (function rest ->
+                   function sub' ->
+                     match (merge_sub sub sub') with
+                       Some subs -> subs @ rest
+                     | _         -> raise SUBST_MISMATCH)
+                 rest theta')
+           [] theta in
+       let rec loop = function
+           (ctheta,[]) ->
+             List.concat (List.map (function (_,ths) -> ths) ctheta)
+         | ([],ctheta') -> raise SUBST_MISMATCH
+         | ((x,ths)::xs,(y,ths')::ys) ->
+             (match compare x y with
+               0 -> (merge_all ths ths') @ loop (xs,ys)
+             | -1 -> ths @ loop (xs,((y,ths')::ys))
+             | 1 -> raise SUBST_MISMATCH
+             | _ -> failwith "not possible") in
+       try Some (clean_subst(loop (classify theta, classify theta')))
+       with SUBST_MISMATCH -> None
+;;
+
+let negate_sub sub =
+  match sub with
+    | A.Subst(x,v)    -> A.NegSubst (x,v)
+    | A.NegSubst(x,v) -> A.Subst(x,v)
+;;
+
+(* Turn a (big) theta into a list of (small) thetas *)
+let negate_subst theta = (map (fun sub -> [negate_sub sub]) theta);;
+
+
+(* ************************* *)
+(* Witnesses                 *)
+(* ************************* *)
+
+(* Always TRUE witness *)
+let top_wit = ([] : (('pred, 'anno) witness list));;
+
+let eq_wit wit wit' = wit = wit';;
+
+let union_wit wit wit' = (*List.sort compare (wit' @ wit) for popl*)
+  let res = unionBy compare (=) wit wit' in
+  let anynegwit = (* if any is neg, then all are *)
+    List.exists (function A.NegWit _ -> true | A.Wit _ -> false) in
+  if anynegwit res
+  then List.filter (function A.NegWit _ -> true | A.Wit _ -> false) res
+  else res
+
+let negate_wit wit = A.NegWit wit (*
+  match wit with
+    | A.Wit(s,th,anno,ws)    -> A.NegWitWit(s,th,anno,ws)
+    | A.NegWitWit(s,th,anno,ws) -> A.Wit(s,th,anno,ws)*)
+;;
+
+let negate_wits wits =
+  List.sort compare (map (fun wit -> [negate_wit wit]) wits);;
+
+let unwitify trips =
+  let anynegwit = (* if any is neg, then all are *)
+    List.exists (function A.NegWit _ -> true | A.Wit _ -> false) in
+  setify
+    (List.fold_left
+       (function prev ->
+        function (s,th,wit) ->
+          if anynegwit wit then prev else (s,th,top_wit)::prev)
+       [] trips)
+
+(* ************************* *)
+(* Triples                   *)
+(* ************************* *)
+
+(* Triples are equal when the constituents are equal *)
+let eq_trip (s,th,wit) (s',th',wit') =
+  (s = s') && (eq_wit wit wit') && (eq_subst th th');;
+
+let triples_top states = map (fun s -> (s,top_subst,top_wit)) states;;
+
+let normalize trips =
+  List.map
+    (function (st,th,wit) -> (st,List.sort compare th,List.sort compare wit))
+    trips
+       
+
+(* conj opt doesn't work ((1,[],{{x=3}}) v (1,[],{{x=4}})) & (1,[],{{x=4}}) =
+(1,[],{{x=3},{x=4}}), not (1,[],{{x=4}}) *)
+let triples_conj trips trips' =
+  let (trips,shared,trips') =
+    if false && !pTRIPLES_CONJ_OPT (* see comment above *)
+    then
+      let (shared,trips) =
+       List.partition (function t -> List.mem t trips') trips in
+      let trips' =
+       List.filter (function t -> not(List.mem t shared)) trips' in
+      (trips,shared,trips')
+    else (trips,[],trips') in
+  foldl (* returns a set - setify inlined *)
+    (function rest ->
+      function (s1,th1,wit1) ->
+       foldl
+         (function rest ->
+           function (s2,th2,wit2) ->
+             if (s1 = s2) then
+               (match (conj_subst th1 th2) with
+                 Some th ->
+                   let t = (s1,th,union_wit wit1 wit2) in
+                   if List.mem t rest then rest else t::rest
+               | _       -> rest)
+             else rest)
+         rest trips')
+    shared trips
+;;
+
+(* ignore the state in the right argument.  always pretend it is the same as
+the left one *)
+(* env on right has to be a subset of env on left *)
+let triples_conj_none trips trips' =
+  let (trips,shared,trips') =
+    if false && !pTRIPLES_CONJ_OPT (* see comment above *)
+    then
+      let (shared,trips) =
+       List.partition (function t -> List.mem t trips') trips in
+      let trips' =
+       List.filter (function t -> not(List.mem t shared)) trips' in
+      (trips,shared,trips')
+    else (trips,[],trips') in
+  foldl (* returns a set - setify inlined *)
+    (function rest ->
+      function (s1,th1,wit1) ->
+       foldl
+         (function rest ->
+           function (s2,th2,wit2) ->
+             match (conj_subst_none th1 th2) with
+               Some th ->
+                 let t = (s1,th,union_wit wit1 wit2) in
+                 if List.mem t rest then rest else t::rest
+             | _       -> rest)
+         rest trips')
+    shared trips
+;;
+
+exception AW
+
+let triples_conj_AW trips trips' =
+  let (trips,shared,trips') =
+    if false && !pTRIPLES_CONJ_OPT
+    then
+      let (shared,trips) =
+       List.partition (function t -> List.mem t trips') trips in
+      let trips' =
+       List.filter (function t -> not(List.mem t shared)) trips' in
+      (trips,shared,trips')
+    else (trips,[],trips') in
+  foldl (* returns a set - setify inlined *)
+    (function rest ->
+      function (s1,th1,wit1) ->
+       foldl
+         (function rest ->
+           function (s2,th2,wit2) ->
+             if (s1 = s2) then
+               (match (conj_subst th1 th2) with
+                 Some th ->
+                   let t = (s1,th,union_wit wit1 wit2) in
+                   if List.mem t rest then rest else t::rest
+               | _ -> raise AW)
+             else rest)
+         rest trips')
+    shared trips
+;;
+
+(* *************************** *)
+(* NEGATION (NegState style)   *)
+(* *************************** *)
+
+(* Constructive negation at the state level *)
+type ('a) state =
+    PosState of 'a
+  | NegState of 'a list
+;;
+
+let compatible_states = function
+    (PosState s1, PosState s2) -> 
+      if s1 = s2 then Some (PosState s1) else None
+  | (PosState s1, NegState s2) -> 
+      if List.mem s1 s2 then None else Some (PosState s1)
+  | (NegState s1, PosState s2) -> 
+      if List.mem s2 s1 then None else Some (PosState s2)
+  | (NegState s1, NegState s2) -> Some (NegState (s1 @ s2))
+;;
+
+(* Conjunction on triples with "special states" *)
+let triples_state_conj trips trips' =
+  let (trips,shared,trips') =
+    if !pTRIPLES_CONJ_OPT
+    then
+      let (shared,trips) =
+       List.partition (function t -> List.mem t trips') trips in
+      let trips' =
+       List.filter (function t -> not(List.mem t shared)) trips' in
+      (trips,shared,trips')
+    else (trips,[],trips') in
+  foldl
+    (function rest ->
+      function (s1,th1,wit1) ->
+       foldl
+         (function rest ->
+           function (s2,th2,wit2) ->
+             match compatible_states(s1,s2) with
+               Some s ->
+                 (match (conj_subst th1 th2) with
+                   Some th ->
+                     let t = (s,th,union_wit wit1 wit2) in
+                     if List.mem t rest then rest else t::rest
+                 | _ -> rest)
+             | _ -> rest)
+         rest trips')
+    shared trips
+;;
+
+let triple_negate (s,th,wits) = 
+  let negstates = (NegState [s],top_subst,top_wit) in
+  let negths = map (fun th -> (PosState s,th,top_wit)) (negate_subst th) in
+  let negwits = map (fun nwit -> (PosState s,th,nwit)) (negate_wits wits) in
+    negstates :: (negths @ negwits) (* all different *)
+
+(* FIX ME: it is not necessary to do full conjunction *)
+let triples_complement states (trips : ('pred, 'anno) triples) =
+  if !pTRIPLES_COMPLEMENT_OPT
+  then
+    (let cleanup (s,th,wit) =
+      match s with
+       PosState s' -> [(s',th,wit)]
+      | NegState ss ->
+         assert (th=top_subst);
+         assert (wit=top_wit);
+         map (fun st -> (st,top_subst,top_wit)) (setdiff states ss) in
+    let (simple,complex) =
+      if !pTRIPLES_COMPLEMENT_SIMPLE_OPT
+      then
+       let (simple,complex) =
+         List.partition (function (s,[],[]) -> true | _ -> false) trips in
+       let simple =
+         [(NegState(List.map (function (s,_,_) -> s) simple),
+           top_subst,top_wit)] in
+       (simple,complex)
+      else ([(NegState [],top_subst,top_wit)],trips) in
+    let rec compl trips =
+      match trips with
+       [] -> simple
+      | (t::ts) -> triples_state_conj (triple_negate t) (compl ts) in
+    let compld = (compl complex) in
+    let compld = concatmap cleanup compld in
+    compld)
+  else
+    let negstates (st,th,wits) =
+      map (function st -> (st,top_subst,top_wit)) (setdiff states [st]) in
+    let negths (st,th,wits) =
+      map (function th -> (st,th,top_wit)) (negate_subst th) in
+    let negwits (st,th,wits) =
+      map (function nwit -> (st,th,nwit)) (negate_wits wits) in
+    match trips with
+      [] -> map (function st -> (st,top_subst,top_wit)) states
+    | x::xs ->
+       setify
+         (foldl
+            (function prev ->
+              function cur ->
+                triples_conj (negstates cur @ negths cur @ negwits cur) prev)
+            (negstates x @ negths x @ negwits x) xs)
+;;
+
+let triple_negate (s,th,wits) = 
+  let negths = map (fun th -> (s,th,top_wit)) (negate_subst th) in
+  let negwits = map (fun nwit -> (s,th,nwit)) (negate_wits wits) in
+  ([s], negths @ negwits) (* all different *)
+
+let print_compl_state str (n,p) =
+  Printf.printf "%s neg: " str;
+  List.iter
+    (function x -> G.print_node x; Format.print_flush(); Printf.printf " ")
+    n;
+  Printf.printf "\n";
+  print_state "pos" p
+
+let triples_complement states (trips : ('pred, 'anno) triples) =
+  if trips = []
+  then map (function st -> (st,top_subst,top_wit)) states
+  else
+    let cleanup (neg,pos) =
+      let keep_pos =
+       List.filter (function (s,_,_) -> List.mem s neg) pos in
+      (map (fun st -> (st,top_subst,top_wit)) (setdiff states neg)) @
+      keep_pos in
+    let trips = List.sort state_compare trips in
+    let all_negated = List.map triple_negate trips in
+    let merge_one (neg1,pos1) (neg2,pos2) =
+      let (pos1conj,pos1keep) =
+       List.partition (function (s,_,_) -> List.mem s neg2) pos1 in
+      let (pos2conj,pos2keep) =
+       List.partition (function (s,_,_) -> List.mem s neg1) pos2 in
+      (Common.union_set neg1 neg2,
+       (triples_conj pos1conj pos2conj) @ pos1keep @ pos2keep) in
+    let rec inner_loop = function
+       x1::x2::rest -> (merge_one x1 x2) :: (inner_loop rest)
+      | l -> l in
+    let rec outer_loop = function
+       [x] -> x
+      | l -> outer_loop (inner_loop l) in
+    cleanup (outer_loop all_negated)
+
+(* ********************************** *)
+(* END OF NEGATION (NegState style)   *)
+(* ********************************** *)
+
+(* now this is always true, so we could get rid of it *)
+let something_dropped = ref true
+
+let triples_union trips trips' =
+  (*unionBy compare eq_trip trips trips';;*)
+  (* returns -1 is t1 > t2, 1 if t2 >= t1, and 0 otherwise *)
+(*
+The following does not work.  Suppose we have ([x->3],{A}) and ([],{A,B}).
+Then, the following says that since the first is a more restrictive
+environment and has fewer witnesses, then it should be dropped. But having
+fewer witnesses is not necessarily less informative than having more,
+because fewer witnesses can mean the absence of the witness-causing thing.
+So the fewer witnesses have to be kept around.
+subseteq changed to = to make it hopefully work
+*)
+  if !pNEW_INFO_OPT
+  then
+    begin
+      something_dropped := false;
+      if trips = trips'
+      then (something_dropped := true; trips)
+      else
+       let subsumes (s1,th1,wit1) (s2,th2,wit2) =
+         if s1 = s2
+         then
+           (match conj_subst th1 th2 with
+             Some conj ->
+               if conj = th1
+               then if (*subseteq*) wit1 = wit2 then 1 else 0
+               else
+                 if conj = th2
+                 then if (*subseteq*) wit2 = wit1 then (-1) else 0
+                 else 0
+           | None -> 0)
+         else 0 in
+       let rec first_loop second = function
+           [] -> second
+         | x::xs -> first_loop (second_loop x second) xs
+       and second_loop x = function
+           [] -> [x]
+         | (y::ys) as all ->
+             match subsumes x y with
+               1 -> something_dropped := true; all
+             | (-1) -> second_loop x ys
+             | _ -> y::(second_loop x ys) in
+       first_loop trips trips'
+    end
+  else unionBy compare eq_trip trips trips'
+
+
+let triples_witness x unchecked not_keep trips =
+  let anyneg = (* if any is neg, then all are *)
+    List.exists (function A.NegSubst _ -> true | A.Subst _ -> false) in
+  let anynegwit = (* if any is neg, then all are *)
+    List.exists (function A.NegWit _ -> true | A.Wit _ -> false) in
+  let allnegwit = (* if any is neg, then all are *)
+    List.for_all (function A.NegWit _ -> true | A.Wit _ -> false) in
+  let negtopos =
+    List.map (function A.NegWit w -> w | A.Wit _ -> failwith "bad wit")in
+  let res = 
+    List.fold_left
+      (function prev ->
+       function (s,th,wit) as t ->
+         let (th_x,newth) = split_subst th x in
+         match th_x with
+           [] ->
+             (* one consider whether if not not_keep is true, then we should
+                fail.  but it could be that the variable is a used_after and
+                then it is the later rule that should fail and not this one *)
+             if not not_keep && !Flag_ctl.verbose_ctl_engine
+             then
+               (SUB.print_mvar x; Format.print_flush();
+                print_state ": empty witness from" [t]);
+             t::prev
+         | l when anyneg l && !pANY_NEG_OPT -> prev
+             (* see tests/nestseq for how neg bindings can come up even
+                without eg partial matches
+              (* negated substitution only allowed with negwits.
+                just dropped *)
+             if anynegwit wit && allnegwit wit (* nonempty negwit list *)
+             then prev
+             else
+               (print_generic_substitution l; Format.print_newline();
+               failwith"unexpected negative binding with positive witnesses")*)
+         | _ ->
+             let new_triple =
+               if unchecked or not_keep
+               then (s,newth,wit)
+               else
+                 if anynegwit wit && allnegwit wit
+                 then (s,newth,[A.NegWit(A.Wit(s,th_x,[],negtopos wit))])
+                 else (s,newth,[A.Wit(s,th_x,[],wit)]) in
+             new_triple::prev)
+      [] trips in
+  if unchecked || !Flag_ctl.partial_match (* the only way to have a NegWit *)
+  then setify res
+  else List.rev res
+;;
+
+
+(* ---------------------------------------------------------------------- *)
+(* SAT  - Model Checking Algorithm for CTL-FVex                           *)
+(*                                                                        *)
+(* TODO: Implement _all_ operators (directly)                             *)
+(* ---------------------------------------------------------------------- *)
+
+
+(* ************************************* *)
+(* The SAT algorithm and special helpers *)
+(* ************************************* *)
+
+let rec pre_exist dir (grp,_,_) y reqst =
+  let check s =
+    match reqst with None -> true | Some reqst -> List.mem s reqst in
+  let exp (s,th,wit) =
+    concatmap
+      (fun s' -> if check s' then [(s',th,wit)] else [])
+      (match dir with
+       A.FORWARD -> G.predecessors grp s
+      | A.BACKWARD -> G.successors grp s) in
+  setify (concatmap exp y)
+;;
+
+exception Empty
+
+let pre_forall dir (grp,_,states) y all reqst =
+  let check s =
+    match reqst with
+      None -> true | Some reqst -> List.mem s reqst in
+  let pred =
+    match dir with
+      A.FORWARD -> G.predecessors | A.BACKWARD -> G.successors in
+  let succ =
+    match dir with
+      A.FORWARD -> G.successors | A.BACKWARD -> G.predecessors in
+  let neighbors =
+    List.map
+      (function p -> (p,succ grp p))
+      (setify
+        (concatmap
+           (function (s,_,_) -> List.filter check (pred grp s)) y)) in
+  (* would a hash table be more efficient? *)
+  let all = List.sort state_compare all in
+  let rec up_nodes child s = function
+      [] -> []
+    | (s1,th,wit)::xs ->
+       (match compare s1 child with
+         -1 -> up_nodes child s xs
+       | 0 -> (s,th,wit)::(up_nodes child s xs)
+       | _ -> []) in
+  let neighbor_triples =
+    List.fold_left
+      (function rest ->
+       function (s,children) ->
+         try
+           (List.map
+              (function child ->
+                match up_nodes child s all with [] -> raise Empty | l -> l)
+              children) :: rest
+         with Empty -> rest)
+      [] neighbors in
+  match neighbor_triples with
+    [] -> []
+  | _ ->
+      (*normalize*)
+        (foldl1 (@) (List.map (foldl1 triples_conj) neighbor_triples))
+       
+let pre_forall_AW dir (grp,_,states) y all reqst =
+  let check s =
+    match reqst with
+      None -> true | Some reqst -> List.mem s reqst in
+  let pred =
+    match dir with
+      A.FORWARD -> G.predecessors | A.BACKWARD -> G.successors in
+  let succ =
+    match dir with
+      A.FORWARD -> G.successors | A.BACKWARD -> G.predecessors in
+  let neighbors =
+    List.map
+      (function p -> (p,succ grp p))
+      (setify
+        (concatmap
+           (function (s,_,_) -> List.filter check (pred grp s)) y)) in
+  (* would a hash table be more efficient? *)
+  let all = List.sort state_compare all in
+  let rec up_nodes child s = function
+      [] -> []
+    | (s1,th,wit)::xs ->
+       (match compare s1 child with
+         -1 -> up_nodes child s xs
+       | 0 -> (s,th,wit)::(up_nodes child s xs)
+       | _ -> []) in
+  let neighbor_triples =
+    List.fold_left
+      (function rest ->
+       function (s,children) ->
+         (List.map
+            (function child ->
+              match up_nodes child s all with [] -> raise AW | l -> l)
+            children) :: rest)
+      [] neighbors in
+  match neighbor_triples with
+    [] -> []
+  | _ -> foldl1 (@) (List.map (foldl1 triples_conj_AW) neighbor_triples)
+       
+(* drop_negwits will call setify *)
+let satEX dir m s reqst = pre_exist dir m s reqst;;
+    
+let satAX dir m s reqst = pre_forall dir m s s reqst
+;;
+
+(* E[phi1 U phi2] == phi2 \/ (phi1 /\ EXE[phi1 U phi2]) *)
+let satEU dir ((_,_,states) as m) s1 s2 reqst = 
+  inc satEU_calls;
+  if s1 = []
+  then s2
+  else
+    (*let ctr = ref 0 in*)
+    if !pNEW_INFO_OPT
+    then
+      let rec f y new_info =
+       inc_step();
+       match new_info with
+         [] -> y
+       | new_info ->
+           ctr := !ctr + 1;
+           let first = triples_conj s1 (pre_exist dir m new_info reqst) in
+           let res = triples_union first y in
+           let new_info = setdiff res y in
+           (*Printf.printf "iter %d res %d new_info %d\n"
+           !ctr (List.length res) (List.length new_info);
+           flush stdout;*)
+           f res new_info in
+      f s2 s2
+    else
+      let f y =
+       inc_step();
+       let pre = pre_exist dir m y reqst in
+       triples_union s2 (triples_conj s1 pre) in
+      setfix f s2
+;;
+
+(* EF phi == E[true U phi] *)
+let satEF dir m s2 reqst = 
+  inc satEF_calls;
+  (*let ctr = ref 0 in*)
+  if !pNEW_INFO_OPT
+  then
+    let rec f y new_info =
+      inc_step();
+      match new_info with
+       [] -> y
+      | new_info ->
+         (*ctr := !ctr + 1;
+         print_state (Printf.sprintf "iteration %d\n" !ctr) y;*)
+         let first = pre_exist dir m new_info reqst in
+         let res = triples_union first y in
+         let new_info = setdiff res y in
+         (*Printf.printf "EF %s iter %d res %d new_info %d\n"
+           (if dir = A.BACKWARD then "reachable" else "real ef")
+           !ctr (List.length res) (List.length new_info);
+         print_state "new info" new_info;
+         flush stdout;*)
+         f res new_info in
+    f s2 s2
+  else
+    let f y =
+      inc_step();
+      let pre = pre_exist dir m y reqst in
+      triples_union s2 pre in
+    setfix f s2
+
+
+type ('pred,'anno) auok =
+    AUok of ('pred,'anno) triples | AUfailed of ('pred,'anno) triples
+
+(* A[phi1 U phi2] == phi2 \/ (phi1 /\ AXA[phi1 U phi2]) *)
+let satAU dir ((cfg,_,states) as m) s1 s2 reqst =
+  inc satAU_calls;
+  if s1 = []
+  then AUok s2
+  else
+    (*let ctr = ref 0 in*)
+    let pre_forall =
+      if !Flag_ctl.loop_in_src_code
+      then pre_forall_AW
+      else pre_forall in
+    if !pNEW_INFO_OPT
+    then
+      let rec f y newinfo =
+       inc_step();
+       match newinfo with
+         [] -> AUok y
+       | new_info ->
+           (*ctr := !ctr + 1;
+           print_state (Printf.sprintf "iteration %d\n" !ctr) y;
+           flush stdout;*)
+           let pre =
+             try Some (pre_forall dir m new_info y reqst)
+             with AW -> None in
+           match pre with
+             None -> AUfailed y
+           | Some pre ->
+               match triples_conj s1 pre with
+                 [] -> AUok y
+               | first ->
+                   (*print_state "s1" s1;
+                   print_state "pre" pre;
+                   print_state "first" first;*)
+                   let res = triples_union first y in
+                   let new_info =
+                     if not !something_dropped
+                     then first
+                     else setdiff res y in
+                 (*Printf.printf
+                    "iter %d res %d new_info %d\n"
+                    !ctr (List.length res) (List.length new_info);
+                    flush stdout;*)
+                   f res new_info in
+      f s2 s2
+    else
+      if !Flag_ctl.loop_in_src_code
+      then AUfailed s2
+      else
+       (*let setfix =
+         fix (function s1 -> function s2 ->
+           let s1 = List.map (function (s,th,w) -> (s,th,nub w)) s1 in
+           let s2 = List.map (function (s,th,w) -> (s,th,nub w)) s2 in
+           subseteq s1 s2) in for popl *)
+       let f y =
+         inc_step();
+         let pre = pre_forall dir m y y reqst in
+         triples_union s2 (triples_conj s1 pre) in
+       AUok (setfix f s2)
+;;
+
+
+(* reqst could be the states of s1 *)
+      (*
+      let lstates = mkstates states reqst in
+      let initial_removed =
+       triples_complement lstates (triples_union s1 s2) in
+      let initial_base = triples_conj s1 (triples_complement lstates s2) in
+      let rec loop base removed =
+       let new_removed =
+         triples_conj base (pre_exist dir m removed reqst) in
+       let new_base =
+         triples_conj base (triples_complement lstates new_removed) in
+       if supseteq new_base base
+       then triples_union base s2
+       else loop new_base new_removed in
+      loop initial_base initial_removed *)
+
+let satAW dir ((grp,_,states) as m) s1 s2 reqst =
+  inc satAW_calls;
+  if s1 = []
+  then s2
+  else
+    (*
+       This works extremely badly when the region is small and the end of the
+       region is very ambiguous, eg free(x) ... x
+       see free.c
+    if !pNEW_INFO_OPT
+    then
+      let get_states l = setify(List.map (function (s,_,_) -> s) l) in
+      let ostates = Common.union_set (get_states s1) (get_states s2) in
+      let succ =
+       (match dir with
+         A.FORWARD -> G.successors grp
+       | A.BACKWARD -> G.predecessors grp) in
+      let states =
+       List.fold_left Common.union_set ostates (List.map succ ostates) in
+      let negphi = triples_complement states s1 in
+      let negpsi = triples_complement states s2 in
+      triples_complement ostates
+       (satEU dir m negpsi (triples_conj negphi negpsi) (Some ostates))
+    else
+       *)
+      (*let ctr = ref 0 in*)
+      let f y =
+       inc_step();
+       (*ctr := !ctr + 1;
+       Printf.printf "iter %d y %d\n" !ctr (List.length y);
+       print_state "y" y;
+       flush stdout;*)
+       let pre = pre_forall dir m y y reqst in
+       let conj = triples_conj s1 pre in (* or triples_conj_AW *)
+       triples_union s2 conj in
+      setgfix f (triples_union s1 s2)
+;;
+
+let satAF dir m s reqst = 
+  inc satAF_calls;
+  if !pNEW_INFO_OPT
+  then
+    let rec f y newinfo =
+      inc_step();
+      match newinfo with
+       [] -> y
+      | new_info ->
+         let first = pre_forall dir m new_info y reqst in
+         let res = triples_union first y in
+         let new_info = setdiff res y in
+         f res new_info in
+    f s s
+  else
+    let f y =
+      inc_step();
+      let pre = pre_forall dir m y y reqst in
+      triples_union s pre in
+    setfix f s
+
+let satAG dir ((_,_,states) as m) s reqst =
+  inc satAG_calls;
+  let f y =
+    inc_step();
+    let pre = pre_forall dir m y y reqst in
+    triples_conj y pre in
+  setgfix f s
+
+let satEG dir ((_,_,states) as m) s reqst =
+  inc satEG_calls;
+  let f y =
+    inc_step();
+    let pre = pre_exist dir m y reqst in
+    triples_conj y pre in
+  setgfix f s
+
+(* **************************************************************** *)
+(* Inner And - a way of dealing with multiple matches within a node *)
+(* **************************************************************** *)
+(* applied to the result of matching a node.  collect witnesses when the
+states and environments are the same *)
+
+let inner_and trips =
+  let rec loop = function
+      [] -> ([],[])
+    | (s,th,w)::trips ->
+       let (cur,acc) = loop trips in
+       (match cur with
+         (s',_,_)::_ when s = s' ->
+           let rec loop' = function
+               [] -> [(s,th,w)]
+             | ((_,th',w') as t')::ts' ->
+                 (match conj_subst th th' with
+                   Some th'' -> (s,th'',union_wit w w')::ts'
+                 | None -> t'::(loop' ts')) in
+           (loop' cur,acc)
+       | _ -> ([(s,th,w)],cur@acc)) in
+  let (cur,acc) =
+    loop (List.sort state_compare trips) (* is this sort needed? *) in
+  cur@acc
+
+(* *************** *)
+(* Partial matches *)
+(* *************** *)
+
+let filter_conj states unwanted partial_matches =
+  let x =
+    triples_conj (triples_complement states (unwitify unwanted))
+      partial_matches in
+  triples_conj (unwitify x) (triples_complement states x)
+
+let strict_triples_conj strict states trips trips' =
+  let res = triples_conj trips trips' in
+  if !Flag_ctl.partial_match && strict = A.STRICT
+  then
+    let fail_left = filter_conj states trips trips' in
+    let fail_right = filter_conj states trips' trips in
+    let ors = triples_union fail_left fail_right in
+    triples_union res ors
+  else res
+
+let strict_triples_conj_none strict states trips trips' =
+  let res = triples_conj_none trips trips' in
+  if !Flag_ctl.partial_match && strict = A.STRICT
+  then
+    let fail_left = filter_conj states trips trips' in
+    let fail_right = filter_conj states trips' trips in
+    let ors = triples_union fail_left fail_right in
+    triples_union res ors
+  else res
+
+let left_strict_triples_conj strict states trips trips' =
+  let res = triples_conj trips trips' in
+  if !Flag_ctl.partial_match && strict = A.STRICT
+  then
+    let fail_left = filter_conj states trips trips' in
+    triples_union res fail_left
+  else res
+
+let strict_A1 strict op failop dir ((_,_,states) as m) trips required_states = 
+  let res = op dir m trips required_states in
+  if !Flag_ctl.partial_match && strict = A.STRICT
+  then
+    let states = mkstates states required_states in
+    let fail = filter_conj states res (failop dir m trips required_states) in
+    triples_union res fail
+  else res
+
+let strict_A2 strict op failop dir ((_,_,states) as m) trips trips'
+    required_states = 
+  let res = op dir m trips trips' required_states in
+  if !Flag_ctl.partial_match && strict = A.STRICT
+  then
+    let states = mkstates states required_states in
+    let fail = filter_conj states res (failop dir m trips' required_states) in
+    triples_union res fail
+  else res
+      
+let strict_A2au strict op failop dir ((_,_,states) as m) trips trips'
+    required_states = 
+  match op dir m trips trips' required_states with
+    AUok res ->
+      if !Flag_ctl.partial_match && strict = A.STRICT
+      then
+       let states = mkstates states required_states in
+       let fail =
+         filter_conj states res (failop dir m trips' required_states) in
+       AUok (triples_union res fail)
+      else AUok res
+  | AUfailed res -> AUfailed res
+      
+(* ********************* *)
+(* Environment functions *)
+(* ********************* *)
+
+let drop_wits required_states s phi =
+  match required_states with
+    None -> s
+  | Some states -> List.filter (function (s,_,_) -> List.mem s states) s
+
+
+let print_required required =
+  List.iter
+    (function l ->
+      Format.print_string "{";
+      List.iter
+       (function reqd ->
+         print_generic_substitution reqd; Format.print_newline())
+       l;
+      Format.print_string "}";
+      Format.print_newline())
+    required
+
+exception Too_long
+
+let extend_required trips required =
+  if !Flag_ctl.partial_match
+  then required
+  else
+      if !pREQUIRED_ENV_OPT
+      then
+    (* make it a set *)
+       let envs =
+         List.fold_left
+           (function rest ->
+             function (_,t,_) -> if List.mem t rest then rest else t::rest)
+           [] trips in
+       let envs = if List.mem [] envs then [] else envs in
+       match (envs,required) with
+         ([],_) -> required
+       | (envs,hd::tl) ->
+           (try
+             let hdln = List.length hd + 5 (* let it grow a little bit *) in
+             let (_,merged) =
+               let add x (ln,y) =
+                 if List.mem x y
+                 then (ln,y)
+                 else if ln + 1 > hdln then raise Too_long else (ln+1,x::y) in
+               foldl
+                 (function rest ->
+                   function t ->
+                     foldl
+                       (function rest ->
+                         function r ->
+                           match conj_subst t r with
+                             None -> rest | Some th -> add th rest)
+                       rest hd)
+                 (0,[]) envs in
+             merged :: tl
+           with Too_long -> envs :: required)
+       | (envs,_) -> envs :: required
+      else required
+
+let drop_required v required =
+  if !pREQUIRED_ENV_OPT
+  then
+    let res =
+    inner_setify
+      (List.map
+        (function l ->
+          inner_setify
+            (List.map (List.filter (function sub -> not(dom_sub sub = v))) l))
+        required) in
+    (* check whether an entry has become useless *)
+    List.filter (function l -> not (List.exists (function x -> x = []) l)) res
+  else required
+
+(* no idea how to write this function ... *)
+let memo_label =
+  (Hashtbl.create(50) : (P.t, (G.node * substitution) list) Hashtbl.t)
+
+let satLabel label required p =
+    let triples =
+    if !pSATLABEL_MEMO_OPT
+    then
+      try
+       let states_subs = Hashtbl.find memo_label p in
+       List.map (function (st,th) -> (st,th,[])) states_subs
+      with
+       Not_found ->
+         let triples = setify(label p) in
+         Hashtbl.add memo_label p
+           (List.map (function (st,th,_) -> (st,th)) triples);
+         triples
+    else setify(label p) in
+    normalize
+      (if !pREQUIRED_ENV_OPT
+      then
+       foldl
+         (function rest ->
+           function ((s,th,_) as t) ->
+             if List.for_all
+                 (List.exists (function th' -> not(conj_subst th th' = None)))
+                 required
+             then t::rest
+             else rest)
+         [] triples
+      else triples)
+
+let get_required_states l =
+  if !pREQUIRED_STATES_OPT && not !Flag_ctl.partial_match
+  then
+    Some(inner_setify (List.map (function (s,_,_) -> s) l))
+  else None
+
+let get_children_required_states dir (grp,_,_) required_states =
+  if !pREQUIRED_STATES_OPT && not !Flag_ctl.partial_match
+  then
+    match required_states with
+      None -> None
+    | Some states ->
+       let fn =
+         match dir with
+           A.FORWARD -> G.successors
+         | A.BACKWARD -> G.predecessors in
+       Some (inner_setify (List.concat (List.map (fn grp) states)))
+  else None
+
+let reachable_table =
+  (Hashtbl.create(50) : (G.node * A.direction, G.node list) Hashtbl.t)
+
+(* like satEF, but specialized for get_reachable *)
+let reachsatEF dir (grp,_,_) s2 =
+  let dirop =
+    match dir with A.FORWARD -> G.successors | A.BACKWARD -> G.predecessors in
+  let union = unionBy compare (=) in
+  let rec f y = function
+      [] -> y
+    | new_info ->
+       let (pre_collected,new_info) =
+         List.partition (function Common.Left x -> true | _ -> false)
+           (List.map
+              (function x ->
+                try Common.Left (Hashtbl.find reachable_table (x,dir))
+                with Not_found -> Common.Right x)
+              new_info) in
+       let y =
+         List.fold_left
+           (function rest ->
+             function Common.Left x -> union x rest
+               | _ -> failwith "not possible")
+           y pre_collected in
+       let new_info =
+         List.map
+           (function Common.Right x -> x | _ -> failwith "not possible")
+           new_info in
+       let first = inner_setify (concatmap (dirop grp) new_info) in
+       let new_info = setdiff first y in
+       let res = new_info @ y in
+       f res new_info in
+  List.rev(f s2 s2) (* put root first *)
+
+let get_reachable dir m required_states =
+  match required_states with
+    None -> None
+  | Some states ->
+      Some
+       (List.fold_left
+          (function rest ->
+            function cur ->
+              if List.mem cur rest
+              then rest
+              else
+                Common.union_set
+                  (try Hashtbl.find reachable_table (cur,dir)
+                  with
+                    Not_found ->
+                      let states = reachsatEF dir m [cur] in
+                      Hashtbl.add reachable_table (cur,dir) states;
+                      states)
+                  rest)
+          [] states)
+
+let ctr = ref 0
+let new_var _ =
+  let c = !ctr in
+  ctr := !ctr + 1;
+  Printf.sprintf "_c%d" c
+
+(* **************************** *)
+(* End of environment functions *)
+(* **************************** *)
+
+type ('code,'value) cell = Frozen of 'code | Thawed of 'value
+
+let rec satloop unchecked required required_states
+    ((grp,label,states) as m) phi env =
+  let rec loop unchecked required required_states phi =
+    (*Common.profile_code "satloop" (fun _ -> *)
+    let res =
+      match phi with
+      A.False              -> []
+    | A.True               -> triples_top states
+    | A.Pred(p)            -> satLabel label required p
+    | A.Uncheck(phi1) ->
+       let unchecked = if !pUNCHECK_OPT then true else false in
+       loop unchecked required required_states phi1
+    | A.Not(phi)           ->
+       let phires = loop unchecked required required_states phi in
+       (*let phires =
+         List.map (function (s,th,w) -> (s,th,[])) phires in*)
+       triples_complement (mkstates states required_states)
+         phires
+    | A.Or(phi1,phi2)      ->
+       triples_union
+         (loop unchecked required required_states phi1)
+         (loop unchecked required required_states phi2)
+    | A.SeqOr(phi1,phi2)      ->
+       let res1 = loop unchecked required required_states phi1 in
+       let res2 = loop unchecked required required_states phi2 in
+       let res1neg = unwitify res1 in
+       triples_union res1
+         (triples_conj
+            (triples_complement (mkstates states required_states) res1neg)
+            res2)
+    | A.And(strict,phi1,phi2)     ->
+       (* phi1 is considered to be more likely to be [], because of the
+          definition of asttoctl.  Could use heuristics such as the size of
+          the term *)
+       let pm = !Flag_ctl.partial_match in
+       (match (pm,loop unchecked required required_states phi1) with
+         (false,[]) when !pLazyOpt -> []
+       | (_,phi1res) ->
+           let new_required = extend_required phi1res required in
+           let new_required_states = get_required_states phi1res in
+           (match (pm,loop unchecked new_required new_required_states phi2)
+           with
+             (false,[]) when !pLazyOpt -> []
+           | (_,phi2res) ->
+               strict_triples_conj strict
+                 (mkstates states required_states)
+                 phi1res phi2res))
+    | A.AndAny(dir,strict,phi1,phi2)     ->
+       (* phi2 can appear anywhere that is reachable *)
+       let pm = !Flag_ctl.partial_match in
+       (match (pm,loop unchecked required required_states phi1) with
+         (false,[]) -> []
+       | (_,phi1res) ->
+           let new_required = extend_required phi1res required in
+           let new_required_states = get_required_states phi1res in
+           let new_required_states =
+             get_reachable dir m new_required_states in
+           (match (pm,loop unchecked new_required new_required_states phi2)
+           with
+             (false,[]) -> phi1res
+           | (_,phi2res) ->
+               (match phi1res with
+                 [] -> (* !Flag_ctl.partial_match must be true *)
+                   if phi2res = []
+                   then []
+                   else
+                     let s = mkstates states required_states in
+                     List.fold_left
+                       (function a -> function b ->
+                         strict_triples_conj strict s a [b])
+                       [List.hd phi2res] (List.tl phi2res)
+               | [(state,_,_)] ->
+                   let phi2res =
+                     List.map (function (s,e,w) -> [(state,e,w)]) phi2res in
+                   let s = mkstates states required_states in
+                   List.fold_left
+                     (function a -> function b ->
+                       strict_triples_conj strict s a b)
+                     phi1res phi2res
+               | _ ->
+                   failwith
+                     "only one result allowed for the left arg of AndAny")))
+    | A.HackForStmt(dir,strict,phi1,phi2)     ->
+       (* phi2 can appear anywhere that is reachable *)
+       let pm = !Flag_ctl.partial_match in
+       (match (pm,loop unchecked required required_states phi1) with
+         (false,[]) -> []
+       | (_,phi1res) ->
+           let new_required = extend_required phi1res required in
+           let new_required_states = get_required_states phi1res in
+           let new_required_states =
+             get_reachable dir m new_required_states in
+           (match (pm,loop unchecked new_required new_required_states phi2)
+           with
+             (false,[]) -> phi1res
+           | (_,phi2res) ->
+                   (* if there is more than one state, something about the
+                      environment has to ensure that the right triples of
+                      phi2 get associated with the triples of phi1.
+                      the asttoctl2 has to ensure that that is the case.
+                      these should thus be structural properties.
+                      env of phi2 has to be a proper subset of env of phi1
+                      to ensure all end up being consistent.  no new triples
+                      should be generated.  strict_triples_conj_none takes
+                      care of this.
+                   *)
+                   let s = mkstates states required_states in
+                   List.fold_left
+                     (function acc ->
+                       function (st,th,_) as phi2_elem ->
+                         let inverse =
+                           triples_complement [st] [(st,th,[])] in
+                         strict_triples_conj_none strict s acc
+                           (phi2_elem::inverse))
+                     phi1res phi2res))
+    | A.InnerAnd(phi) ->
+       inner_and(loop unchecked required required_states phi)
+    | A.EX(dir,phi)      ->
+       let new_required_states =
+         get_children_required_states dir m required_states in
+       satEX dir m (loop unchecked required new_required_states phi)
+         required_states
+    | A.AX(dir,strict,phi)      ->
+       let new_required_states =
+         get_children_required_states dir m required_states in
+       let res = loop unchecked required new_required_states phi in
+       strict_A1 strict satAX satEX dir m res required_states
+    | A.EF(dir,phi)            ->
+       let new_required_states = get_reachable dir m required_states in
+       satEF dir m (loop unchecked required new_required_states phi)
+         new_required_states
+    | A.AF(dir,strict,phi)            ->
+       if !Flag_ctl.loop_in_src_code
+       then
+         loop unchecked required required_states
+           (A.AU(dir,strict,A.True,phi))
+       else
+         let new_required_states = get_reachable dir m required_states in
+         let res = loop unchecked required new_required_states phi in
+         strict_A1 strict satAF satEF dir m res new_required_states
+    | A.EG(dir,phi)            ->
+       let new_required_states = get_reachable dir m required_states in
+       satEG dir m (loop unchecked required new_required_states phi)
+         new_required_states
+    | A.AG(dir,strict,phi)            ->
+       let new_required_states = get_reachable dir m required_states in
+       let res = loop unchecked required new_required_states phi in
+       strict_A1 strict satAG satEF dir m res new_required_states
+    | A.EU(dir,phi1,phi2)      ->
+       let new_required_states = get_reachable dir m required_states in
+       (match loop unchecked required new_required_states phi2 with
+         [] when !pLazyOpt -> []
+       | s2 ->
+           let new_required = extend_required s2 required in
+           let s1 = loop unchecked new_required new_required_states phi1 in
+           satEU dir m s1 s2 new_required_states)
+    | A.AW(dir,strict,phi1,phi2) ->
+       let new_required_states = get_reachable dir m required_states in
+       (match loop unchecked required new_required_states phi2 with
+         [] when !pLazyOpt -> []
+       | s2 ->
+           let new_required = extend_required s2 required in
+           let s1 = loop unchecked new_required new_required_states phi1 in
+           strict_A2 strict satAW satEF dir m s1 s2 new_required_states)
+    | A.AU(dir,strict,phi1,phi2) ->
+       (*Printf.printf "using AU\n"; flush stdout;*)
+       let new_required_states = get_reachable dir m required_states in
+       (match loop unchecked required new_required_states phi2 with
+         [] when !pLazyOpt -> []
+       | s2 ->
+           let new_required = extend_required s2 required in
+           let s1 = loop unchecked new_required new_required_states phi1 in
+           let res =
+             strict_A2au strict satAU satEF dir m s1 s2 new_required_states in
+           match res with
+             AUok res -> res
+           | AUfailed tmp_res ->
+               (* found a loop, have to try AW *)
+               (* the formula is
+                  A[E[phi1 U phi2] & phi1 W phi2]
+                  the and is nonstrict *)
+               (* tmp_res is bigger than s2, so perhaps closer to s1 *)
+               (*Printf.printf "using AW\n"; flush stdout;*)
+               let s1 =
+                 triples_conj (satEU dir m s1 tmp_res new_required_states)
+                   s1 in
+               strict_A2 strict satAW satEF dir m s1 s2 new_required_states)
+    | A.Implies(phi1,phi2) ->
+       loop unchecked required required_states (A.Or(A.Not phi1,phi2))
+    | A.Exists (keep,v,phi)     ->
+       let new_required = drop_required v required in
+       triples_witness v unchecked (not keep)
+         (loop unchecked new_required required_states phi)
+    | A.Let(v,phi1,phi2)   ->
+       (* should only be used when the properties unchecked, required,
+          and required_states are known to be the same or at least
+          compatible between all the uses.  this is not checked. *)
+       let res = loop unchecked required required_states phi1 in
+       satloop unchecked required required_states m phi2 ((v,res) :: env)
+    | A.LetR(dir,v,phi1,phi2)   ->
+       (* should only be used when the properties unchecked, required,
+          and required_states are known to be the same or at least
+          compatible between all the uses.  this is not checked. *)
+       let new_required_states = get_reachable dir m required_states in
+       let res = loop unchecked required new_required_states phi1 in
+       satloop unchecked required required_states m phi2 ((v,res) :: env)
+    | A.Ref(v)             ->
+       let res = List.assoc v env in
+       if unchecked
+       then List.map (function (s,th,_) -> (s,th,[])) res
+       else res
+    | A.XX(phi) -> failwith "should have been removed" in
+    if !Flag_ctl.bench > 0 then triples := !triples + (List.length res);
+    drop_wits required_states res phi (* ) *) in
+  
+  loop unchecked required required_states phi
+;;    
+
+
+(* SAT with tracking *)
+let rec sat_verbose_loop unchecked required required_states annot maxlvl lvl
+    ((_,label,states) as m) phi env =
+  let anno res children = (annot lvl phi res children,res) in
+  let satv unchecked required required_states phi0 env =
+    sat_verbose_loop unchecked required required_states annot maxlvl (lvl+1)
+      m phi0 env in
+  if (lvl > maxlvl) && (maxlvl > -1) then
+    anno (satloop unchecked required required_states m phi env) []
+  else
+    let (child,res) =
+      match phi with
+      A.False              -> anno [] []
+    | A.True               -> anno (triples_top states) []
+    | A.Pred(p)            ->
+       Printf.printf "label\n"; flush stdout;
+       anno (satLabel label required p) []
+    | A.Uncheck(phi1) ->
+       let unchecked = if !pUNCHECK_OPT then true else false in
+       let (child1,res1) = satv unchecked required required_states phi1 env in
+       Printf.printf "uncheck\n"; flush stdout;
+       anno res1 [child1]
+    | A.Not(phi1)          -> 
+       let (child,res) =
+         satv unchecked required required_states phi1 env in
+       Printf.printf "not\n"; flush stdout;
+       anno (triples_complement (mkstates states required_states) res) [child]
+    | A.Or(phi1,phi2)      -> 
+       let (child1,res1) =
+         satv unchecked required required_states phi1 env in
+       let (child2,res2) =
+         satv unchecked required required_states phi2 env in
+       Printf.printf "or\n"; flush stdout;
+       anno (triples_union res1 res2) [child1; child2]
+    | A.SeqOr(phi1,phi2)      -> 
+       let (child1,res1) =
+         satv unchecked required required_states phi1 env in
+       let (child2,res2) =
+         satv unchecked required required_states phi2 env in
+       let res1neg =
+         List.map (function (s,th,_) -> (s,th,[])) res1 in
+       Printf.printf "seqor\n"; flush stdout;
+       anno (triples_union res1
+               (triples_conj
+                  (triples_complement (mkstates states required_states)
+                     res1neg)
+                  res2))
+         [child1; child2]
+    | A.And(strict,phi1,phi2)     -> 
+       let pm = !Flag_ctl.partial_match in
+       (match (pm,satv unchecked required required_states phi1 env) with
+         (false,(child1,[])) ->
+           Printf.printf "and\n"; flush stdout; anno [] [child1]
+       | (_,(child1,res1)) ->
+           let new_required = extend_required res1 required in
+           let new_required_states = get_required_states res1 in
+           (match (pm,satv unchecked new_required new_required_states phi2
+                     env) with
+             (false,(child2,[])) ->
+               Printf.printf "and\n"; flush stdout; anno [] [child1;child2]
+           | (_,(child2,res2)) ->
+               Printf.printf "and\n"; flush stdout;
+               let res =
+                 strict_triples_conj strict
+                   (mkstates states required_states)
+                   res1 res2 in
+               anno res [child1; child2]))
+    | A.AndAny(dir,strict,phi1,phi2)     ->
+       let pm = !Flag_ctl.partial_match in 
+       (match (pm,satv unchecked required required_states phi1 env) with
+         (false,(child1,[])) ->
+           Printf.printf "and\n"; flush stdout; anno [] [child1]
+       | (_,(child1,res1)) ->
+           let new_required = extend_required res1 required in
+           let new_required_states = get_required_states res1 in
+           let new_required_states =
+             get_reachable dir m new_required_states in
+           (match (pm,satv unchecked new_required new_required_states phi2
+               env) with
+             (false,(child2,[])) ->
+               Printf.printf "andany\n"; flush stdout;
+               anno res1 [child1;child2]
+           | (_,(child2,res2)) ->
+               (match res1 with
+                 [] -> (* !Flag_ctl.partial_match must be true *)
+                   if res2 = []
+                   then anno [] [child1; child2]
+                   else 
+                     let res =
+                       let s = mkstates states required_states in
+                       List.fold_left
+                         (function a -> function b ->
+                           strict_triples_conj strict s a [b])
+                         [List.hd res2] (List.tl res2) in
+                     anno res [child1; child2]
+               | [(state,_,_)] ->
+                   let res2 =
+                     List.map (function (s,e,w) -> [(state,e,w)]) res2 in
+                   Printf.printf "andany\n"; flush stdout;
+                   let res =
+                     let s = mkstates states required_states in
+                     List.fold_left
+                       (function a -> function b ->
+                         strict_triples_conj strict s a b)
+                       res1 res2 in
+                   anno res [child1; child2]
+               | _ ->
+                   failwith
+                     "only one result allowed for the left arg of AndAny")))
+    | A.HackForStmt(dir,strict,phi1,phi2)     ->
+       let pm = !Flag_ctl.partial_match in 
+       (match (pm,satv unchecked required required_states phi1 env) with
+         (false,(child1,[])) ->
+           Printf.printf "and\n"; flush stdout; anno [] [child1]
+       | (_,(child1,res1)) ->
+           let new_required = extend_required res1 required in
+           let new_required_states = get_required_states res1 in
+           let new_required_states =
+             get_reachable dir m new_required_states in
+           (match (pm,satv unchecked new_required new_required_states phi2
+               env) with
+             (false,(child2,[])) ->
+               Printf.printf "andany\n"; flush stdout;
+               anno res1 [child1;child2]
+           | (_,(child2,res2)) ->
+               let res =
+                 let s = mkstates states required_states in
+                 List.fold_left
+                   (function acc ->
+                     function (st,th,_) as phi2_elem ->
+                       let inverse =
+                         triples_complement [st] [(st,th,[])] in
+                       strict_triples_conj_none strict s acc
+                         (phi2_elem::inverse))
+                   res1 res2 in
+               anno res [child1; child2]))
+    | A.InnerAnd(phi1) ->
+       let (child1,res1) = satv unchecked required required_states phi1 env in
+       Printf.printf "uncheck\n"; flush stdout;
+       anno (inner_and res1) [child1]
+    | A.EX(dir,phi1)       -> 
+       let new_required_states =
+         get_children_required_states dir m required_states in
+       let (child,res) =
+         satv unchecked required new_required_states phi1 env in
+       Printf.printf "EX\n"; flush stdout;
+       anno (satEX dir m res required_states) [child]
+    | A.AX(dir,strict,phi1)       -> 
+       let new_required_states =
+         get_children_required_states dir m required_states in
+       let (child,res) =
+         satv unchecked required new_required_states phi1 env in
+       Printf.printf "AX\n"; flush stdout;
+       let res = strict_A1 strict satAX satEX dir m res required_states in
+       anno res [child]
+    | A.EF(dir,phi1)       -> 
+       let new_required_states = get_reachable dir m required_states in
+       let (child,res) =
+         satv unchecked required new_required_states phi1 env in
+       Printf.printf "EF\n"; flush stdout;
+       anno (satEF dir m res new_required_states) [child]
+    | A.AF(dir,strict,phi1) -> 
+       if !Flag_ctl.loop_in_src_code
+       then
+         satv unchecked required required_states
+           (A.AU(dir,strict,A.True,phi1))
+           env
+       else
+         (let new_required_states = get_reachable dir m required_states in
+         let (child,res) =
+           satv unchecked required new_required_states phi1 env in
+         Printf.printf "AF\n"; flush stdout;
+         let res =
+           strict_A1 strict satAF satEF dir m res new_required_states in
+         anno res [child])
+    | A.EG(dir,phi1)       -> 
+       let new_required_states = get_reachable dir m required_states in
+       let (child,res) =
+         satv unchecked required new_required_states phi1 env in
+       Printf.printf "EG\n"; flush stdout;
+       anno (satEG dir m res new_required_states) [child]
+    | A.AG(dir,strict,phi1)       -> 
+       let new_required_states = get_reachable dir m required_states in
+       let (child,res) =
+         satv unchecked required new_required_states phi1 env in
+       Printf.printf "AG\n"; flush stdout;
+       let res = strict_A1 strict satAG satEF dir m res new_required_states in
+       anno res [child]
+         
+    | A.EU(dir,phi1,phi2)  -> 
+       let new_required_states = get_reachable dir m required_states in
+       (match satv unchecked required new_required_states phi2 env with
+         (child2,[]) ->
+           Printf.printf "EU\n"; flush stdout;
+           anno [] [child2]
+       | (child2,res2) ->
+           let new_required = extend_required res2 required in
+           let (child1,res1) =
+             satv unchecked new_required new_required_states phi1 env in
+           Printf.printf "EU\n"; flush stdout;
+           anno (satEU dir m res1 res2 new_required_states) [child1; child2])
+    | A.AW(dir,strict,phi1,phi2)      -> 
+       failwith "should not be used" (*
+         let new_required_states = get_reachable dir m required_states in
+         (match satv unchecked required new_required_states phi2 env with
+           (child2,[]) ->
+             Printf.printf "AW %b\n" unchecked; flush stdout; anno [] [child2]
+         | (child2,res2) ->
+             let new_required = extend_required res2 required in
+             let (child1,res1) =
+               satv unchecked new_required new_required_states phi1 env in
+             Printf.printf "AW %b\n" unchecked; flush stdout;
+             let res =
+               strict_A2 strict satAW satEF dir m res1 res2
+                 new_required_states in
+             anno res [child1; child2]) *)
+    | A.AU(dir,strict,phi1,phi2)      -> 
+       let new_required_states = get_reachable dir m required_states in
+       (match satv unchecked required new_required_states phi2 env with
+         (child2,[]) ->
+           Printf.printf "AU\n"; flush stdout; anno [] [child2]
+       | (child2,s2) ->
+           let new_required = extend_required s2 required in
+           let (child1,s1) =
+             satv unchecked new_required new_required_states phi1 env in
+           Printf.printf "AU\n"; flush stdout;
+           let res =
+             strict_A2au strict satAU satEF dir m s1 s2 new_required_states in
+           (match res with
+             AUok res ->
+               anno res [child1; child2]
+           | AUfailed tmp_res ->
+               (* found a loop, have to try AW *)
+               (* the formula is
+                  A[E[phi1 U phi2] & phi1 W phi2]
+                  the and is nonstrict *)
+               (* tmp_res is bigger than s2, so perhaps closer to s1 *)
+             Printf.printf "AW\n"; flush stdout;
+             let s1 =
+               triples_conj (satEU dir m s1 tmp_res new_required_states) s1 in
+             let res =
+               strict_A2 strict satAW satEF dir m s1 s2 new_required_states in
+             anno res [child1; child2]))
+    | A.Implies(phi1,phi2) -> 
+       satv unchecked required required_states
+         (A.Or(A.Not phi1,phi2))
+         env
+    | A.Exists (keep,v,phi1)    -> 
+       let new_required = drop_required v required in
+       let (child,res) =
+         satv unchecked new_required required_states phi1 env in
+       Printf.printf "exists\n"; flush stdout;
+       anno (triples_witness v unchecked (not keep) res) [child]
+    | A.Let(v,phi1,phi2)   ->
+       let (child1,res1) =
+         satv unchecked required required_states phi1 env in
+       let (child2,res2) =
+         satv unchecked required required_states phi2 ((v,res1) :: env) in
+       anno res2 [child1;child2]
+    | A.LetR(dir,v,phi1,phi2)   ->
+       let new_required_states = get_reachable dir m required_states in
+       let (child1,res1) =
+         satv unchecked required new_required_states phi1 env in
+       let (child2,res2) =
+         satv unchecked required required_states phi2 ((v,res1) :: env) in
+       anno res2 [child1;child2]
+    | A.Ref(v)             ->
+       Printf.printf "Ref\n"; flush stdout;
+       let res = List.assoc v env in
+       let res =
+         if unchecked
+         then List.map (function (s,th,_) -> (s,th,[])) res
+         else res in
+       anno res []
+    | A.XX(phi) -> failwith "should have been removed" in
+    let res1 = drop_wits required_states res phi in
+    if not(res1 = res)
+    then
+      begin
+       print_required_states required_states;
+      print_state "after drop_wits" res1 end;
+    (child,res1)
+       
+;;
+
+let sat_verbose annotate maxlvl lvl m phi =
+  sat_verbose_loop false [] None annotate maxlvl lvl m phi []
+
+(* Type for annotations collected in a tree *)
+type ('a) witAnnoTree = WitAnno of ('a * ('a witAnnoTree) list);;
+
+let sat_annotree annotate m phi =
+  let tree_anno l phi res chld = WitAnno(annotate l phi res,chld) in
+    sat_verbose_loop false [] None tree_anno (-1) 0 m phi []
+;;
+
+(*
+let sat m phi = satloop m phi []
+;;
+*)
+
+let simpleanno l phi res =
+  let pp s = 
+    Format.print_string ("\n" ^ s ^ "\n------------------------------\n"); 
+    print_generic_algo (List.sort compare res);
+    Format.print_string "\n------------------------------\n\n" in
+  let pp_dir = function
+      A.FORWARD -> ()
+    | A.BACKWARD -> pp "^" in
+  match phi with
+    | A.False              -> pp "False"
+    | A.True               -> pp "True"
+    | A.Pred(p)            -> pp ("Pred" ^ (Common.dump p))
+    | A.Not(phi)           -> pp "Not"
+    | A.Exists(_,v,phi)    -> pp ("Exists " ^ (Common.dump(v)))
+    | A.And(_,phi1,phi2)   -> pp "And"
+    | A.AndAny(dir,_,phi1,phi2) -> pp "AndAny"
+    | A.HackForStmt(dir,_,phi1,phi2) -> pp "HackForStmt"
+    | A.Or(phi1,phi2)      -> pp "Or"
+    | A.SeqOr(phi1,phi2)   -> pp "SeqOr"
+    | A.Implies(phi1,phi2) -> pp "Implies"
+    | A.AF(dir,_,phi1)     -> pp "AF"; pp_dir dir
+    | A.AX(dir,_,phi1)     -> pp "AX"; pp_dir dir
+    | A.AG(dir,_,phi1)     -> pp "AG"; pp_dir dir
+    | A.AW(dir,_,phi1,phi2)-> pp "AW"; pp_dir dir
+    | A.AU(dir,_,phi1,phi2)-> pp "AU"; pp_dir dir
+    | A.EF(dir,phi1)       -> pp "EF"; pp_dir dir
+    | A.EX(dir,phi1)      -> pp "EX"; pp_dir dir
+    | A.EG(dir,phi1)      -> pp "EG"; pp_dir dir
+    | A.EU(dir,phi1,phi2)  -> pp "EU"; pp_dir dir
+    | A.Let (x,phi1,phi2)  -> pp ("Let"^" "^x)
+    | A.LetR (dir,x,phi1,phi2) -> pp ("LetR"^" "^x); pp_dir dir
+    | A.Ref(s)             -> pp ("Ref("^s^")")
+    | A.Uncheck(s)         -> pp "Uncheck"
+    | A.InnerAnd(s)        -> pp "InnerAnd"
+    | A.XX(phi1)           -> pp "XX"
+;;
+
+
+(* pad: Rene, you can now use the module pretty_print_ctl.ml to
+   print a ctl formula more accurately if you want.
+   Use the print_xxx provided in the different module to call 
+   Pretty_print_ctl.pp_ctl.
+ *)
+
+let simpleanno2 l phi res = 
+  begin
+    Pretty_print_ctl.pp_ctl (P.print_predicate, SUB.print_mvar) false phi;
+    Format.print_newline ();
+    Format.print_string "----------------------------------------------------";
+    Format.print_newline ();
+    print_generic_algo (List.sort compare res);
+    Format.print_newline ();
+    Format.print_string "----------------------------------------------------";
+    Format.print_newline ();
+    Format.print_newline ();
+  end
+
+
+(* ---------------------------------------------------------------------- *)
+(* Benchmarking                                                           *)
+(* ---------------------------------------------------------------------- *)
+
+type optentry = bool ref * string
+type options = {label : optentry; unch : optentry;
+                conj : optentry; compl1 : optentry; compl2 : optentry;
+                newinfo : optentry;
+                reqenv : optentry; reqstates : optentry}
+
+let options =
+  {label = (pSATLABEL_MEMO_OPT,"satlabel_memo_opt");
+    unch = (pUNCHECK_OPT,"uncheck_opt");
+    conj = (pTRIPLES_CONJ_OPT,"triples_conj_opt");
+    compl1 = (pTRIPLES_COMPLEMENT_OPT,"triples_complement_opt");
+    compl2 = (pTRIPLES_COMPLEMENT_SIMPLE_OPT,"triples_complement_simple_opt");
+    newinfo = (pNEW_INFO_OPT,"new_info_opt");
+    reqenv = (pREQUIRED_ENV_OPT,"required_env_opt");
+    reqstates = (pREQUIRED_STATES_OPT,"required_states_opt")}
+
+let baseline =
+  [("none                    ",[]);
+    ("label                   ",[options.label]);
+    ("unch                    ",[options.unch]);
+    ("unch and label          ",[options.label;options.unch])]
+
+let conjneg =
+  [("conj                    ", [options.conj]);
+    ("compl1                  ", [options.compl1]);
+    ("compl12                 ", [options.compl1;options.compl2]);
+    ("conj/compl12            ", [options.conj;options.compl1;options.compl2]);
+    ("conj unch satl          ", [options.conj;options.unch;options.label]);
+(*
+    ("compl1 unch satl        ", [options.compl1;options.unch;options.label]);
+    ("compl12 unch satl       ",
+     [options.compl1;options.compl2;options.unch;options.label]); *)
+    ("conj/compl12 unch satl  ",
+     [options.conj;options.compl1;options.compl2;options.unch;options.label])]
+
+let path =
+  [("newinfo                 ", [options.newinfo]);
+    ("newinfo unch satl       ", [options.newinfo;options.unch;options.label])]
+
+let required =
+  [("reqenv                  ", [options.reqenv]);
+    ("reqstates               ", [options.reqstates]);
+    ("reqenv/states           ", [options.reqenv;options.reqstates]);
+(*  ("reqenv unch satl        ", [options.reqenv;options.unch;options.label]);
+    ("reqstates unch satl     ",
+     [options.reqstates;options.unch;options.label]);*)
+    ("reqenv/states unch satl ",
+     [options.reqenv;options.reqstates;options.unch;options.label])]
+
+let all_options =
+  [options.label;options.unch;options.conj;options.compl1;options.compl2;
+    options.newinfo;options.reqenv;options.reqstates]
+
+let all =
+  [("all                     ",all_options)]
+
+let all_options_but_path =
+  [options.label;options.unch;options.conj;options.compl1;options.compl2;
+    options.reqenv;options.reqstates]
+
+let all_but_path = ("all but path            ",all_options_but_path)
+
+let counters =
+  [(satAW_calls, "satAW", ref 0);
+    (satAU_calls, "satAU", ref 0);
+    (satEF_calls, "satEF", ref 0);
+    (satAF_calls, "satAF", ref 0);
+    (satEG_calls, "satEG", ref 0);
+    (satAG_calls, "satAG", ref 0);
+  (satEU_calls, "satEU", ref 0)]
+
+let perms =
+  map
+    (function (opt,x) ->
+      (opt,x,ref 0.0,ref 0,
+       List.map (function _ -> (ref 0, ref 0, ref 0)) counters))
+    [List.hd all;all_but_path]
+  (*(all@baseline@conjneg@path@required)*)
+
+exception Out
+
+let rec iter fn = function
+    1 -> fn()
+  | n -> let _ = fn() in
+    (Hashtbl.clear reachable_table;
+     Hashtbl.clear memo_label;
+     triples := 0;
+     iter fn (n-1))
+
+let copy_to_stderr fl =
+  let i = open_in fl in
+  let rec loop _ =
+    Printf.fprintf stderr "%s\n" (input_line i);
+    loop() in
+  try loop() with _ -> ();
+  close_in i
+
+let bench_sat (_,_,states) fn =
+  List.iter (function (opt,_) -> opt := false) all_options;
+  let answers =
+    concatmap
+      (function (name,options,time,trips,counter_info) ->
+       let iterct = !Flag_ctl.bench in
+       if !time > float_of_int timeout then time := -100.0;
+       if not (!time = -100.0)
+       then
+         begin
+           Hashtbl.clear reachable_table;
+           Hashtbl.clear memo_label;
+           List.iter (function (opt,_) -> opt := true) options;
+           List.iter (function (calls,_,save_calls) -> save_calls := !calls)
+             counters;
+           triples := 0;
+           let res =
+             let bef = Sys.time() in
+             try
+               Common.timeout_function timeout
+                 (fun () ->
+                   let bef = Sys.time() in
+                   let res = iter fn iterct in
+                   let aft = Sys.time() in
+                   time := !time +. (aft -. bef);
+                   trips := !trips + !triples;
+                   List.iter2
+                     (function (calls,_,save_calls) ->
+                       function (current_calls,current_cfg,current_max_cfg) ->
+                         current_calls :=
+                           !current_calls + (!calls - !save_calls);
+                         if (!calls - !save_calls) > 0
+                         then
+                           (let st = List.length states in
+                           current_cfg := !current_cfg + st;
+                           if st > !current_max_cfg
+                           then current_max_cfg := st))
+                     counters counter_info;
+                   [res])
+             with
+               Common.Timeout ->
+                 begin
+                   let aft = Sys.time() in
+                   time := -100.0;
+                   Printf.fprintf stderr "Timeout at %f on: %s\n"
+                     (aft -. bef) name;
+                   []
+                 end in
+           List.iter (function (opt,_) -> opt := false) options;
+           res
+         end
+       else [])
+      perms in
+  Printf.fprintf stderr "\n";
+  match answers with
+    [] -> []
+  | res::rest ->
+      (if not(List.for_all (function x -> x = res) rest)
+      then
+       (List.iter (print_state "a state") answers;
+        Printf.printf "something doesn't work\n");
+      res)
+      
+let print_bench _ =
+  let iterct = !Flag_ctl.bench in
+  if iterct > 0
+  then
+    (List.iter
+       (function (name,options,time,trips,counter_info) ->
+        Printf.fprintf stderr "%s Numbers: %f %d "
+          name (!time /. (float_of_int iterct)) !trips;
+        List.iter
+          (function (calls,cfg,max_cfg) ->
+            Printf.fprintf stderr "%d %d %d " (!calls / iterct) !cfg !max_cfg)
+          counter_info;
+        Printf.fprintf stderr "\n")
+       perms)
+
+(* ---------------------------------------------------------------------- *)
+(* preprocessing: ignore irrelevant functions *)
+
+let preprocess (cfg,_,_) label = function
+    [] -> true (* no information, try everything *)
+  | l ->
+      let sz = G.size cfg in
+      let verbose_output pred = function
+         [] ->
+           Printf.printf "did not find:\n";
+           P.print_predicate pred; Format.print_newline()
+       | _ ->
+           Printf.printf "found:\n";
+           P.print_predicate pred; Format.print_newline();
+           Printf.printf "but it was not enough\n" in
+      let get_any verbose x =
+       let res =
+         try Hashtbl.find memo_label x
+         with
+           Not_found ->
+             (let triples = label x in
+             let filtered =
+               List.map (function (st,th,_) -> (st,th)) triples in
+             Hashtbl.add memo_label x filtered;
+             filtered) in
+       if verbose then verbose_output x res;
+       not([] = res) in
+      let get_all l =
+       (* don't bother testing when there are more patterns than nodes *)
+       if List.length l > sz-2
+       then false
+       else List.for_all (get_any false) l in
+      if List.exists get_all l
+      then true
+      else
+       (if !Flag_ctl.verbose_match
+       then
+          List.iter (List.iter (function x -> let _ = get_any true x in ()))
+           l;
+        false)
+
+let filter_partial_matches trips =
+  if !Flag_ctl.partial_match
+  then
+    let anynegwit = (* if any is neg, then all are *)
+      List.exists (function A.NegWit _ -> true | A.Wit _ -> false) in
+    let (bad,good) =
+      List.partition (function (s,th,wit) -> anynegwit wit) trips in
+    (match bad with
+      [] -> ()
+    | _ -> print_state "partial matches" bad; Format.print_newline());
+    good
+  else trips
+
+(* ---------------------------------------------------------------------- *)
+(* Main entry point for engine *)
+let sat m phi reqopt =
+  try
+    (match !Flag_ctl.steps with
+      None -> step_count := 0
+    | Some x -> step_count := x);
+    Hashtbl.clear reachable_table;
+    Hashtbl.clear memo_label;
+    let (x,label,states) = m in
+    if (!Flag_ctl.bench > 0) or (preprocess m label reqopt)
+    then
+      ((* to drop when Yoann initialized this flag *)
+      if List.exists (G.extract_is_loop x) states
+      then Flag_ctl.loop_in_src_code := true;
+      let m = (x,label,List.sort compare states) in
+      let res =
+       if(!Flag_ctl.verbose_ctl_engine)
+       then
+         let fn _ = snd (sat_annotree simpleanno2 m phi) in
+         if !Flag_ctl.bench > 0
+         then bench_sat m fn
+         else fn()
+       else
+         let fn _ = satloop false [] None m phi [] in
+         if !Flag_ctl.bench > 0
+         then bench_sat m fn
+         else Common.profile_code "ctl" (fun _ -> fn()) in
+      let res = filter_partial_matches res in
+      (*
+      Printf.printf "steps: start %d, stop %d\n"
+       (match !Flag_ctl.steps with Some x -> x | _ -> 0)
+       !step_count;
+      Printf.printf "triples: %d\n" !triples;
+      print_state "final result" res;
+      *)
+      res)
+    else
+      (if !Flag_ctl.verbose_ctl_engine
+      then Common.pr2 "missing something required";
+       [])
+  with Steps -> []
+;;
+
+(* ********************************************************************** *)
+(* End of Module: CTL_ENGINE                                              *)
+(* ********************************************************************** *)
+end
+;;
+
similarity index 71%
copy from engine/flag_engine.ml
copy to ctl/.#flag_ctl.ml.1.12
index 3140109..97a487d 100644 (file)
 *)
 
 
-let debug_engine = ref false
+(* option -verbose_ctl_engine *)
+let verbose_ctl_engine = ref false
 
-(* false = simpler formulas, only for debugging *)
-let useEU = ref true
+(* cheap partial matches using assttomember *)
+let verbose_match = ref false
 
-let disallow_nested_exps = ref false
+let partial_match = ref false
 
-(* if this flag is not set, then break and continue are also error exits *)
-let only_return_is_error_exit = ref false
+let poswits_only = ref false
+
+let loop_in_src_code = ref false
+
+let bench = ref 0
+
+let steps = ref (None : int option)
 
-(* a hack to allow adding code in some more sgrep-like uses *)
-let allow_inconsistent_paths = ref false
diff --git a/ctl/.#flag_ctl.ml.1.13 b/ctl/.#flag_ctl.ml.1.13
new file mode 100644 (file)
index 0000000..6bbb66a
--- /dev/null
@@ -0,0 +1,39 @@
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+* 
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+* 
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
+* 
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+(* option -verbose_ctl_engine *)
+let verbose_ctl_engine = ref false
+
+(* cheap partial matches using assttomember *)
+let verbose_match = ref false
+
+let partial_match = ref false
+
+let poswits_only = ref false
+
+let loop_in_src_code = ref false
+
+let bench = ref 0
+
+let steps = ref (None : int option)
+
+let graphical_trace = ref false
index cee310c..c19260f 100644 (file)
@@ -46,6 +46,10 @@ let pUNCHECK_OPT = ref true
 let pANY_NEG_OPT = ref true
 let pLazyOpt = ref true
 
+(* Nico: This stack is use for graphical traces *)
+let graph_stack = ref ([] : string list)
+let graph_hash = (Hashtbl.create 101)
+
 (*
 let pTRIPLES_CONJ_OPT = ref false
 let pTRIPLES_COMPLEMENT_OPT = ref false
@@ -125,6 +129,8 @@ module type GRAPH =
     val extract_is_loop : cfg -> node -> bool
     val print_node :      node -> unit
     val size :            cfg -> int
+    val print_graph :     cfg -> string option ->
+      (node * string) list -> (node * string) list -> string -> unit
   end
 ;;
 
@@ -154,6 +160,9 @@ end
 (* Misc. useful generic functions                                         *)
 (* ---------------------------------------------------------------------- *)
 
+let get_graph_files () = !graph_stack
+let get_graph_comp_files outfile = Hashtbl.find_all graph_hash outfile
+
 let head = List.hd
 
 let tail l = 
@@ -363,7 +372,44 @@ let print_required_states = function
 let mkstates states = function
     None -> states
   | Some states -> states
-    
+
+let print_graph grp required_states res str = function
+    A.Exists (keep,v,phi)     -> ()
+  | phi ->
+      if !Flag_ctl.graphical_trace && not !Flag_ctl.checking_reachability
+      then
+        match phi with
+       | A.Exists (keep,v,phi)     -> ()
+       | _ ->
+           let label =
+             Printf.sprintf "%s%s"
+               (String.escaped
+                  (Common.format_to_string
+                     (function _ ->
+                       Pretty_print_ctl.pp_ctl
+                         (P.print_predicate, SUB.print_mvar)
+                         false phi)))
+               str in
+           let file = (match !Flag.currentfile with
+             None -> "graphical_trace"
+           | Some f -> f
+                 ) in
+             (if not (List.mem file !graph_stack) then
+               graph_stack := file :: !graph_stack);
+           let filename = Filename.temp_file (file^":") ".dot" in         
+           Hashtbl.add graph_hash file filename;  
+           G.print_graph grp
+             (if !Flag_ctl.gt_without_label then None else (Some label))
+             (match required_states with
+               None -> []
+             | Some required_states ->
+                 (List.map (function s -> (s,"blue")) required_states))
+             (List.map (function (s,_,_) -> (s,"\"#FF8080\"")) res)  filename
+
+let print_graph_c grp required_states res ctr phi =
+  let str = "iter: "^(string_of_int !ctr) in
+  print_graph grp required_states res str phi
+
 (* ---------------------------------------------------------------------- *)
 (*                                                                        *)
 (* ---------------------------------------------------------------------- *)
@@ -1050,7 +1096,8 @@ let satAX dir m s reqst = pre_forall dir m s s reqst
 ;;
 
 (* E[phi1 U phi2] == phi2 \/ (phi1 /\ EXE[phi1 U phi2]) *)
-let satEU dir ((_,_,states) as m) s1 s2 reqst = 
+let satEU dir ((_,_,states) as m) s1 s2 reqst print_graph = 
+  let ctr = ref 0 in
   inc satEU_calls;
   if s1 = []
   then s2
@@ -1064,6 +1111,7 @@ let satEU dir ((_,_,states) as m) s1 s2 reqst =
          [] -> y
        | new_info ->
            ctr := !ctr + 1;
+           print_graph y ctr;
            let first = triples_conj s1 (pre_exist dir m new_info reqst) in
            let res = triples_union first y in
            let new_info = setdiff res y in
@@ -1075,6 +1123,8 @@ let satEU dir ((_,_,states) as m) s1 s2 reqst =
     else
       let f y =
        inc_step();
+       ctr := !ctr + 1;
+       print_graph y ctr;
        let pre = pre_exist dir m y reqst in
        triples_union s2 (triples_conj s1 pre) in
       setfix f s2
@@ -1115,7 +1165,8 @@ type ('pred,'anno) auok =
     AUok of ('pred,'anno) triples | AUfailed of ('pred,'anno) triples
 
 (* A[phi1 U phi2] == phi2 \/ (phi1 /\ AXA[phi1 U phi2]) *)
-let satAU dir ((cfg,_,states) as m) s1 s2 reqst =
+let satAU dir ((cfg,_,states) as m) s1 s2 reqst print_graph =
+  let ctr = ref 0 in
   inc satAU_calls;
   if s1 = []
   then AUok s2
@@ -1132,9 +1183,10 @@ let satAU dir ((cfg,_,states) as m) s1 s2 reqst =
        match newinfo with
          [] -> AUok y
        | new_info ->
-           (*ctr := !ctr + 1;
-           print_state (Printf.sprintf "iteration %d\n" !ctr) y;
+           ctr := !ctr + 1;
+           (*print_state (Printf.sprintf "iteration %d\n" !ctr) y;
            flush stdout;*)
+           print_graph y ctr;
            let pre =
              try Some (pre_forall dir m new_info y reqst)
              with AW -> None in
@@ -1169,6 +1221,8 @@ let satAU dir ((cfg,_,states) as m) s1 s2 reqst =
            subseteq s1 s2) in for popl *)
        let f y =
          inc_step();
+         ctr := !ctr + 1;
+         print_graph y ctr;
          let pre = pre_forall dir m y y reqst in
          triples_union s2 (triples_conj s1 pre) in
        AUok (setfix f s2)
@@ -1349,8 +1403,8 @@ let strict_A2 strict op failop dir ((_,_,states) as m) trips trips'
   else res
       
 let strict_A2au strict op failop dir ((_,_,states) as m) trips trips'
-    required_states = 
-  match op dir m trips trips' required_states with
+    required_states print_graph 
+  match op dir m trips trips' required_states print_graph with
     AUok res ->
       if !Flag_ctl.partial_match && strict = A.STRICT
       then
@@ -1710,7 +1764,8 @@ let rec satloop unchecked required required_states
        | s2 ->
            let new_required = extend_required s2 required in
            let s1 = loop unchecked new_required new_required_states phi1 in
-           satEU dir m s1 s2 new_required_states)
+           satEU dir m s1 s2 new_required_states
+             (fun y ctr -> print_graph_c grp new_required_states y ctr phi))
     | A.AW(dir,strict,phi1,phi2) ->
        let new_required_states = get_reachable dir m required_states in
        (match loop unchecked required new_required_states phi2 with
@@ -1728,7 +1783,9 @@ let rec satloop unchecked required required_states
            let new_required = extend_required s2 required in
            let s1 = loop unchecked new_required new_required_states phi1 in
            let res =
-             strict_A2au strict satAU satEF dir m s1 s2 new_required_states in
+             strict_A2au strict satAU satEF dir m s1 s2 new_required_states
+               (fun y ctr ->
+                 print_graph_c grp new_required_states y ctr phi) in
            match res with
              AUok res -> res
            | AUfailed tmp_res ->
@@ -1739,7 +1796,10 @@ let rec satloop unchecked required required_states
                (* tmp_res is bigger than s2, so perhaps closer to s1 *)
                (*Printf.printf "using AW\n"; flush stdout;*)
                let s1 =
-                 triples_conj (satEU dir m s1 tmp_res new_required_states)
+                 triples_conj
+                   (satEU dir m s1 tmp_res new_required_states
+                      (* no graph, for the moment *)
+                      (fun y str -> ()))
                    s1 in
                strict_A2 strict satAW satEF dir m s1 s2 new_required_states)
     | A.Implies(phi1,phi2) ->
@@ -1758,6 +1818,7 @@ let rec satloop unchecked required required_states
        (* should only be used when the properties unchecked, required,
           and required_states are known to be the same or at least
           compatible between all the uses.  this is not checked. *)
+       (* doesn't seem to be used any more *)
        let new_required_states = get_reachable dir m required_states in
        let res = loop unchecked required new_required_states phi1 in
        satloop unchecked required required_states m phi2 ((v,res) :: env)
@@ -1768,7 +1829,9 @@ let rec satloop unchecked required required_states
        else res
     | A.XX(phi) -> failwith "should have been removed" in
     if !Flag_ctl.bench > 0 then triples := !triples + (List.length res);
-    drop_wits required_states res phi (* ) *) in
+    let res = drop_wits required_states res phi (* ) *) in
+    print_graph grp required_states res "" phi;
+    res in
   
   loop unchecked required required_states phi
 ;;    
@@ -1974,7 +2037,8 @@ let rec sat_verbose_loop unchecked required required_states annot maxlvl lvl
            let (child1,res1) =
              satv unchecked new_required new_required_states phi1 env in
            Printf.printf "EU\n"; flush stdout;
-           anno (satEU dir m res1 res2 new_required_states) [child1; child2])
+           anno (satEU dir m res1 res2 new_required_states (fun y str -> ()))
+             [child1; child2])
     | A.AW(dir,strict,phi1,phi2)      -> 
        failwith "should not be used" (*
          let new_required_states = get_reachable dir m required_states in
@@ -2001,7 +2065,8 @@ let rec sat_verbose_loop unchecked required required_states annot maxlvl lvl
              satv unchecked new_required new_required_states phi1 env in
            Printf.printf "AU\n"; flush stdout;
            let res =
-             strict_A2au strict satAU satEF dir m s1 s2 new_required_states in
+             strict_A2au strict satAU satEF dir m s1 s2 new_required_states
+               (fun y str -> ()) in
            (match res with
              AUok res ->
                anno res [child1; child2]
@@ -2013,7 +2078,11 @@ let rec sat_verbose_loop unchecked required required_states annot maxlvl lvl
                (* tmp_res is bigger than s2, so perhaps closer to s1 *)
              Printf.printf "AW\n"; flush stdout;
              let s1 =
-               triples_conj (satEU dir m s1 tmp_res new_required_states) s1 in
+               triples_conj
+                 (satEU dir m s1 tmp_res new_required_states
+                    (* no graph, for the moment *)
+                    (fun y str -> ()))
+                 s1 in
              let res =
                strict_A2 strict satAW satEF dir m s1 s2 new_required_states in
              anno res [child1; child2]))
index 05e2f5e..ba21a17 100644 (file)
@@ -20,6 +20,8 @@ module type GRAPH =
     val extract_is_loop : cfg -> node -> bool
     val print_node :      node -> unit
     val size :            cfg -> int
+    val print_graph :     cfg -> string option ->
+      (node * string) list -> (node * string) list -> string -> unit
   end
 
 module OGRAPHEXT_GRAPH :
@@ -62,3 +64,7 @@ module CTL_ENGINE :
 
        val print_bench : unit -> unit
       end
+
+val get_graph_files : unit -> string list
+val get_graph_comp_files : string -> string list
+         
index 97a487d..e78fb19 100644 (file)
@@ -36,3 +36,7 @@ let bench = ref 0
 
 let steps = ref (None : int option)
 
+let graphical_trace = ref false
+let gt_without_label = ref false
+
+let checking_reachability = ref false
diff --git a/engine/.#Makefile.1.49 b/engine/.#Makefile.1.49
new file mode 100644 (file)
index 0000000..4103bca
--- /dev/null
@@ -0,0 +1,126 @@
+# Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+# Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+# This file is part of Coccinelle.
+# 
+# Coccinelle is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, according to version 2 of the License.
+# 
+# Coccinelle is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
+# 
+# The authors reserve the right to distribute this or future versions of
+# Coccinelle under other licenses.
+
+
+##############################################################################
+# Variables
+##############################################################################
+#TARGET=matcher
+TARGET=cocciengine
+CTLTARGET=engine
+
+SRC= flag_matcher.ml lib_engine.ml pretty_print_engine.ml \
+      check_exhaustive_pattern.ml \
+      check_reachability.ml \
+      c_vs_c.ml isomorphisms_c_c.ml \
+      cocci_vs_c.ml pattern_c.ml sgrep.ml transformation_c.ml  \
+      asttomember.ml asttoctl2.ml ctltotex.ml \
+      postprocess_transinfo.ml ctlcocci_integration.ml
+
+#c_vs_c.ml
+#SRC= flag_matcher.ml \
+#  c_vs_c.ml cocci_vs_c.ml \
+#  lib_engine.ml \
+#  pattern_c.ml transformation_c.ml 
+
+#LIBS=../commons/commons.cma ../parsing_c/parsing_c.cma
+#INCLUDES= -I ../commons -I ../parsing_c
+INCLUDES = -I ../commons -I ../commons/ocamlextra -I ../globals \
+              -I ../ctl -I ../parsing_cocci -I ../parsing_c 
+LIBS=../commons/commons.cma ../globals/globals.cma \
+     ../ctl/ctl.cma ../parsing_c/c_parser.cma ../parsing_cocci/cocci_parser.cma
+
+SYSLIBS= str.cma unix.cma 
+
+
+# just to test asttoctl
+# CTLSOURCES = lib_engine.ml pretty_print_engine.ml asttoctl.ml ctltotex.ml \
+#      main.ml
+
+##############################################################################
+# Generic variables
+##############################################################################
+
+#for warning:  -w A 
+#for profiling:  -p -inline 0   with OCAMLOPT
+OCAMLCFLAGS ?= -g -dtypes
+
+OCAMLC=ocamlc$(OPTBIN) $(OCAMLCFLAGS) $(INCLUDES)
+OCAMLOPT=ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
+OCAMLLEX=ocamllex$(OPTBIN) #-ml
+OCAMLYACC=ocamlyacc -v
+OCAMLDEP=ocamldep$(OPTBIN) $(INCLUDES)
+OCAMLMKTOP=ocamlmktop -g -custom $(INCLUDES)
+
+
+OBJS = $(SRC:.ml=.cmo)
+OPTOBJS = $(SRC:.ml=.cmx)
+
+
+##############################################################################
+# Top rules
+##############################################################################
+all: $(TARGET).cma
+all.opt: $(TARGET).cmxa
+
+$(TARGET).cma: $(OBJS)
+       $(OCAMLC) -a -o $(TARGET).cma $(OBJS)
+
+$(TARGET).cmxa: $(OPTOBJS) $(LIBS:.cma=.cmxa)
+       $(OCAMLOPT) -a -o $(TARGET).cmxa $(OPTOBJS)
+
+$(TARGET).top: $(OBJS) $(LIBS)
+       $(OCAMLMKTOP) -o $(TARGET).top $(SYSLIBS) $(LIBS) $(OBJS)
+
+clean::
+       rm -f $(TARGET).top
+
+
+
+##############################################################################
+# Pad's rules
+##############################################################################
+
+##############################################################################
+# Generic rules
+##############################################################################
+
+.SUFFIXES: .ml .mli .cmo .cmi .cmx
+
+.ml.cmo:
+       $(OCAMLC) -c $<
+.mli.cmi:
+       $(OCAMLC) -c $<
+.ml.cmx:
+       $(OCAMLOPT) -c $<
+
+.ml.mldepend: 
+       $(OCAMLC) -i $<
+
+clean::
+       rm -f *.cm[ioxa] *.o *.a *.cmxa *.annot
+clean::
+       rm -f *~ .*~ gmon.out #*#
+
+beforedepend::
+
+depend:: beforedepend
+       $(OCAMLDEP) *.mli *.ml    > .depend
+
+-include .depend
diff --git a/engine/.#asttoctl2.ml.1.138 b/engine/.#asttoctl2.ml.1.138
deleted file mode 100644 (file)
index bf9268b..0000000
+++ /dev/null
@@ -1,2222 +0,0 @@
-(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-* 
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-* 
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-* 
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
-* 
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
-
-(* for MINUS and CONTEXT, pos is always None in this file *)
-(*search for require*)
-(* true = don't see all matched nodes, only modified ones *)
-let onlyModif = ref true(*false*)
-
-type ex = Exists | Forall | ReverseForall
-let exists = ref Forall
-
-module Ast = Ast_cocci
-module V = Visitor_ast
-module CTL = Ast_ctl
-
-let warning s = Printf.fprintf stderr "warning: %s\n" s
-
-type cocci_predicate = Lib_engine.predicate * Ast.meta_name Ast_ctl.modif
-type formula =
-    (cocci_predicate,Ast.meta_name, Wrapper_ctl.info) Ast_ctl.generic_ctl
-
-let union = Common.union_set
-let intersect l1 l2 = List.filter (function x -> List.mem x l2) l1
-let subset l1 l2 = List.for_all (function x -> List.mem x l2) l1
-
-let foldl1 f xs = List.fold_left f (List.hd xs) (List.tl xs)
-let foldr1 f xs =
-  let xs = List.rev xs in List.fold_left f (List.hd xs) (List.tl xs)
-
-let used_after = ref ([] : Ast.meta_name list)
-let guard_to_strict guard = if guard then CTL.NONSTRICT else CTL.STRICT
-
-let saved = ref ([] : Ast.meta_name list)
-
-let string2var x = ("",x)
-
-(* --------------------------------------------------------------------- *)
-(* predicates matching various nodes in the graph *)
-
-let ctl_and s x y    =
-  match (x,y) with
-    (CTL.False,_) | (_,CTL.False) -> CTL.False
-  | (CTL.True,a) | (a,CTL.True) -> a
-  | _ -> CTL.And(s,x,y)
-
-let ctl_or x y     =
-  match (x,y) with
-    (CTL.True,_) | (_,CTL.True) -> CTL.True
-  | (CTL.False,a) | (a,CTL.False) -> a
-  | _ -> CTL.Or(x,y)
-
-let ctl_or_fl x y     =
-  match (x,y) with
-    (CTL.True,_) | (_,CTL.True) -> CTL.True
-  | (CTL.False,a) | (a,CTL.False) -> a
-  | _ -> CTL.Or(y,x)
-
-let ctl_seqor x y     =
-  match (x,y) with
-    (CTL.True,_) | (_,CTL.True) -> CTL.True
-  | (CTL.False,a) | (a,CTL.False) -> a
-  | _ -> CTL.SeqOr(x,y)
-
-let ctl_not = function
-    CTL.True -> CTL.False
-  | CTL.False -> CTL.True
-  | x -> CTL.Not(x)
-
-let ctl_ax s = function
-    CTL.True -> CTL.True
-  | CTL.False -> CTL.False
-  | x ->
-      match !exists with
-       Exists -> CTL.EX(CTL.FORWARD,x)
-      |        Forall -> CTL.AX(CTL.FORWARD,s,x)
-      |        ReverseForall -> failwith "not supported"
-
-let ctl_ax_absolute s = function
-    CTL.True -> CTL.True
-  | CTL.False -> CTL.False
-  | x -> CTL.AX(CTL.FORWARD,s,x)
-
-let ctl_ex = function
-    CTL.True -> CTL.True
-  | CTL.False -> CTL.False
-  | x -> CTL.EX(CTL.FORWARD,x)
-
-(* This stays being AX even for sgrep_mode, because it is used to identify
-the structure of the term, not matching the pattern. *)
-let ctl_back_ax = function
-    CTL.True -> CTL.True
-  | CTL.False -> CTL.False
-  | x -> CTL.AX(CTL.BACKWARD,CTL.NONSTRICT,x)
-
-let ctl_back_ex = function
-    CTL.True -> CTL.True
-  | CTL.False -> CTL.False
-  | x -> CTL.EX(CTL.BACKWARD,x)
-
-let ctl_ef = function
-    CTL.True -> CTL.True
-  | CTL.False -> CTL.False
-  | x -> CTL.EF(CTL.FORWARD,x)
-
-let ctl_ag s = function
-    CTL.True -> CTL.True
-  | CTL.False -> CTL.False
-  | x -> CTL.AG(CTL.FORWARD,s,x)
-
-let ctl_au s x y =
-  match (x,!exists) with
-    (CTL.True,Exists) -> CTL.EF(CTL.FORWARD,y)
-  | (CTL.True,Forall) -> CTL.AF(CTL.FORWARD,s,y)
-  | (CTL.True,ReverseForall) -> failwith "not supported"
-  | (_,Exists) -> CTL.EU(CTL.FORWARD,x,y)
-  | (_,Forall) -> CTL.AU(CTL.FORWARD,s,x,y)
-  | (_,ReverseForall) -> failwith "not supported"
-
-let ctl_anti_au s x y = (* only for ..., where the quantifier is changed *)
-  CTL.XX
-    (match (x,!exists) with
-      (CTL.True,Exists) -> CTL.AF(CTL.FORWARD,s,y)
-    | (CTL.True,Forall) -> CTL.EF(CTL.FORWARD,y)
-    | (CTL.True,ReverseForall) -> failwith "not supported"
-    | (_,Exists) -> CTL.AU(CTL.FORWARD,s,x,y)
-    | (_,Forall) -> CTL.EU(CTL.FORWARD,x,y)
-    | (_,ReverseForall) -> failwith "not supported")
-
-let ctl_uncheck = function
-    CTL.True -> CTL.True
-  | CTL.False -> CTL.False
-  | x -> CTL.Uncheck x
-
-let label_pred_maker = function
-    None -> CTL.True
-  | Some (label_var,used) ->
-      used := true;
-      CTL.Pred(Lib_engine.PrefixLabel(label_var),CTL.Control)
-
-let bclabel_pred_maker = function
-    None -> CTL.True
-  | Some (label_var,used) ->
-      used := true;
-      CTL.Pred(Lib_engine.BCLabel(label_var),CTL.Control)
-
-let predmaker guard pred label =
-  ctl_and (guard_to_strict guard) (CTL.Pred pred) (label_pred_maker label)
-
-let aftpred     = predmaker false (Lib_engine.After,       CTL.Control)
-let retpred     = predmaker false (Lib_engine.Return,      CTL.Control)
-let funpred     = predmaker false (Lib_engine.FunHeader,   CTL.Control)
-let toppred     = predmaker false (Lib_engine.Top,         CTL.Control)
-let exitpred    = predmaker false (Lib_engine.ErrorExit,   CTL.Control)
-let endpred     = predmaker false (Lib_engine.Exit,        CTL.Control)
-let gotopred    = predmaker false (Lib_engine.Goto,        CTL.Control)
-let inlooppred  = predmaker false (Lib_engine.InLoop,      CTL.Control)
-let truepred    = predmaker false (Lib_engine.TrueBranch,  CTL.Control)
-let falsepred   = predmaker false (Lib_engine.FalseBranch, CTL.Control)
-let fallpred    = predmaker false (Lib_engine.FallThrough, CTL.Control)
-
-let aftret label_var f = ctl_or (aftpred label_var) (exitpred label_var)
-
-let letctr = ref 0
-let get_let_ctr _ =
-  let cur = !letctr in
-  letctr := cur + 1;
-  Printf.sprintf "r%d" cur
-
-(* --------------------------------------------------------------------- *)
-(* --------------------------------------------------------------------- *)
-(* Eliminate OptStm *)
-
-(* for optional thing with nothing after, should check that the optional thing
-never occurs.  otherwise the matching stops before it occurs *)
-let elim_opt =
-  let mcode x = x in
-  let donothing r k e = k e in
-
-  let fvlist l =
-    List.fold_left Common.union_set [] (List.map Ast.get_fvs l) in
-
-  let mfvlist l =
-    List.fold_left Common.union_set [] (List.map Ast.get_mfvs l) in
-
-  let freshlist l =
-    List.fold_left Common.union_set [] (List.map Ast.get_fresh l) in
-
-  let inheritedlist l =
-    List.fold_left Common.union_set [] (List.map Ast.get_inherited l) in
-
-  let savedlist l =
-    List.fold_left Common.union_set [] (List.map Ast.get_saved l) in
-
-  let varlists l =
-    (fvlist l, mfvlist l, freshlist l, inheritedlist l, savedlist l) in
-
-  let rec dots_list unwrapped wrapped =
-    match (unwrapped,wrapped) with
-      ([],_) -> []
-
-    | (Ast.Dots(_,_,_,_)::Ast.OptStm(stm)::(Ast.Dots(_,_,_,_) as u)::urest,
-       d0::s::d1::rest)
-    | (Ast.Nest(_,_,_,_,_)::Ast.OptStm(stm)::(Ast.Dots(_,_,_,_) as u)::urest,
-       d0::s::d1::rest) ->
-        let l = Ast.get_line stm in
-        let new_rest1 = stm :: (dots_list (u::urest) (d1::rest)) in
-        let new_rest2 = dots_list urest rest in
-        let (fv_rest1,mfv_rest1,fresh_rest1,inherited_rest1,s1) =
-          varlists new_rest1 in
-        let (fv_rest2,mfv_rest2,fresh_rest2,inherited_rest2,s2) =
-          varlists new_rest2 in
-        [d0;
-          {(Ast.make_term
-              (Ast.Disj
-                 [{(Ast.make_term(Ast.DOTS(new_rest1))) with
-                    Ast.node_line = l;
-                    Ast.free_vars = fv_rest1;
-                    Ast.minus_free_vars = mfv_rest1;
-                    Ast.fresh_vars = fresh_rest1;
-                    Ast.inherited = inherited_rest1;
-                    Ast.saved_witness = s1};
-                   {(Ast.make_term(Ast.DOTS(new_rest2))) with
-                     Ast.node_line = l;
-                     Ast.free_vars = fv_rest2;
-                     Ast.minus_free_vars = mfv_rest2;
-                     Ast.fresh_vars = fresh_rest2;
-                     Ast.inherited = inherited_rest2;
-                     Ast.saved_witness = s2}])) with
-            Ast.node_line = l;
-            Ast.free_vars = fv_rest1;
-            Ast.minus_free_vars = mfv_rest1;
-            Ast.fresh_vars = fresh_rest1;
-            Ast.inherited = inherited_rest1;
-            Ast.saved_witness = s1}]
-
-    | (Ast.OptStm(stm)::urest,_::rest) ->
-        let l = Ast.get_line stm in
-        let new_rest1 = dots_list urest rest in
-        let new_rest2 = stm::new_rest1 in
-        let (fv_rest1,mfv_rest1,fresh_rest1,inherited_rest1,s1) =
-          varlists new_rest1 in
-        let (fv_rest2,mfv_rest2,fresh_rest2,inherited_rest2,s2) =
-          varlists new_rest2 in
-        [{(Ast.make_term
-              (Ast.Disj
-                 [{(Ast.make_term(Ast.DOTS(new_rest2))) with
-                     Ast.node_line = l;
-                     Ast.free_vars = fv_rest2;
-                     Ast.minus_free_vars = mfv_rest2;
-                     Ast.fresh_vars = fresh_rest2;
-                     Ast.inherited = inherited_rest2;
-                     Ast.saved_witness = s2};
-                   {(Ast.make_term(Ast.DOTS(new_rest1))) with
-                    Ast.node_line = l;
-                    Ast.free_vars = fv_rest1;
-                    Ast.minus_free_vars = mfv_rest1;
-                    Ast.fresh_vars = fresh_rest1;
-                    Ast.inherited = inherited_rest1;
-                    Ast.saved_witness = s1}])) with
-            Ast.node_line = l;
-            Ast.free_vars = fv_rest2;
-            Ast.minus_free_vars = mfv_rest2;
-            Ast.fresh_vars = fresh_rest2;
-            Ast.inherited = inherited_rest2;
-            Ast.saved_witness = s2}]
-
-    | ([Ast.Dots(_,_,_,_);Ast.OptStm(stm)],[d1;_]) ->
-       let l = Ast.get_line stm in
-       let fv_stm = Ast.get_fvs stm in
-       let mfv_stm = Ast.get_mfvs stm in
-       let fresh_stm = Ast.get_fresh stm in
-       let inh_stm = Ast.get_inherited stm in
-       let saved_stm = Ast.get_saved stm in
-       let fv_d1 = Ast.get_fvs d1 in
-       let mfv_d1 = Ast.get_mfvs d1 in
-       let fresh_d1 = Ast.get_fresh d1 in
-       let inh_d1 = Ast.get_inherited d1 in
-       let saved_d1 = Ast.get_saved d1 in
-       let fv_both = Common.union_set fv_stm fv_d1 in
-       let mfv_both = Common.union_set mfv_stm mfv_d1 in
-       let fresh_both = Common.union_set fresh_stm fresh_d1 in
-       let inh_both = Common.union_set inh_stm inh_d1 in
-       let saved_both = Common.union_set saved_stm saved_d1 in
-       [d1;
-         {(Ast.make_term
-             (Ast.Disj
-                [{(Ast.make_term(Ast.DOTS([stm]))) with
-                   Ast.node_line = l;
-                   Ast.free_vars = fv_stm;
-                   Ast.minus_free_vars = mfv_stm;
-                   Ast.fresh_vars = fresh_stm;
-                   Ast.inherited = inh_stm;
-                   Ast.saved_witness = saved_stm};
-                  {(Ast.make_term(Ast.DOTS([d1]))) with
-                    Ast.node_line = l;
-                    Ast.free_vars = fv_d1;
-                    Ast.minus_free_vars = mfv_d1;
-                    Ast.fresh_vars = fresh_d1;
-                    Ast.inherited = inh_d1;
-                    Ast.saved_witness = saved_d1}])) with
-            Ast.node_line = l;
-            Ast.free_vars = fv_both;
-            Ast.minus_free_vars = mfv_both;
-            Ast.fresh_vars = fresh_both;
-            Ast.inherited = inh_both;
-            Ast.saved_witness = saved_both}]
-
-    | ([Ast.Nest(_,_,_,_,_);Ast.OptStm(stm)],[d1;_]) ->
-       let l = Ast.get_line stm in
-       let rw = Ast.rewrap stm in
-       let rwd = Ast.rewrap stm in
-       let dots = Ast.Dots(Ast.make_mcode "...",[],[],[]) in
-       [d1;rw(Ast.Disj
-                [rwd(Ast.DOTS([stm]));
-                  {(Ast.make_term(Ast.DOTS([rw dots])))
-                  with Ast.node_line = l}])]
-
-    | (_::urest,stm::rest) -> stm :: (dots_list urest rest)
-    | _ -> failwith "not possible" in
-
-  let stmtdotsfn r k d =
-    let d = k d in
-    Ast.rewrap d
-      (match Ast.unwrap d with
-       Ast.DOTS(l) -> Ast.DOTS(dots_list (List.map Ast.unwrap l) l)
-      | Ast.CIRCLES(l) -> failwith "elimopt: not supported"
-      | Ast.STARS(l) -> failwith "elimopt: not supported") in
-  
-  V.rebuilder
-    mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
-    mcode
-    donothing donothing stmtdotsfn donothing
-    donothing donothing donothing donothing donothing donothing donothing
-    donothing donothing donothing donothing donothing
-
-(* --------------------------------------------------------------------- *)
-(* after management *)
-(* We need Guard for the following case:
-<...
- a
- <...
-  b
- ...>
-...>
-foo();
-
-Here the inner <... b ...> should not go past foo.  But foo is not the
-"after" of the body of the outer nest, because we don't want to search for
-it in the case where the body of the outer nest ends in something other
-than dots or a nest. *)
-
-(* what is the difference between tail and end??? *)
-
-type after = After of formula | Guard of formula | Tail | End | VeryEnd
-
-let a2n = function After x -> Guard x | a -> a
-
-let print_ctl x =
-  let pp_pred (x,_) = Pretty_print_engine.pp_predicate x in
-  let pp_meta (_,x) = Common.pp x in
-  Pretty_print_ctl.pp_ctl (pp_pred,pp_meta) false x;
-  Format.print_newline()
-
-let print_after = function
-    After ctl -> Printf.printf "After:\n"; print_ctl ctl
-  | Guard ctl -> Printf.printf "Guard:\n"; print_ctl ctl
-  | Tail -> Printf.printf "Tail\n"
-  | VeryEnd -> Printf.printf "Very End\n"
-  | End -> Printf.printf "End\n"
-
-(* --------------------------------------------------------------------- *)
-(* Top-level code *)
-
-let fresh_var _ = string2var "_v"
-let fresh_pos _ = string2var "_pos" (* must be a constant *)
-
-let fresh_metavar _ = "_S"
-
-(* fvinfo is going to end up being from the whole associated statement.
-   it would be better if it were just the free variables in d, but free_vars.ml
-   doesn't keep track of free variables on + code *)
-let make_meta_rule_elem d fvinfo =
-  let nm = fresh_metavar() in
-  Ast.make_meta_rule_elem nm d fvinfo
-
-let get_unquantified quantified vars =
-  List.filter (function x -> not (List.mem x quantified)) vars
-
-let make_seq guard l =
-  let s = guard_to_strict guard in
-  foldr1 (function rest -> function cur -> ctl_and s cur (ctl_ax s rest)) l
-
-let make_seq_after2 guard first rest =
-  let s = guard_to_strict guard in
-  match rest with
-    After rest -> ctl_and s first (ctl_ax s (ctl_ax s rest))
-  | _ -> first
-
-let make_seq_after guard first rest =
-  match rest with
-    After rest -> make_seq guard [first;rest]
-  | _ -> first
-
-let opt_and guard first rest =
-  let s = guard_to_strict guard in
-  match first with
-    None -> rest
-  | Some first -> ctl_and s first rest
-
-let and_after guard first rest =
-  let s = guard_to_strict guard in
-  match rest with After rest -> ctl_and s first rest | _ -> first
-
-let contains_modif =
-  let bind x y = x or y in
-  let option_default = false in
-  let mcode r (_,_,kind,_) =
-    match kind with
-      Ast.MINUS(_,_) -> true
-    | Ast.PLUS -> failwith "not possible"
-    | Ast.CONTEXT(_,info) -> not (info = Ast.NOTHING) in
-  let do_nothing r k e = k e in
-  let rule_elem r k re =
-    let res = k re in
-    match Ast.unwrap re with
-      Ast.FunHeader(bef,_,fninfo,name,lp,params,rp) ->
-       bind (mcode r ((),(),bef,Ast.NoMetaPos)) res
-    | Ast.Decl(bef,_,decl) -> bind (mcode r ((),(),bef,Ast.NoMetaPos)) res
-    | _ -> res in
-  let recursor =
-    V.combiner bind option_default
-      mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
-      mcode
-      do_nothing do_nothing do_nothing do_nothing
-      do_nothing do_nothing do_nothing do_nothing do_nothing do_nothing
-      do_nothing rule_elem do_nothing do_nothing do_nothing do_nothing in
-  recursor.V.combiner_rule_elem
-
-(* code is not a DisjRuleElem *)
-let make_match label guard code =
-  let v = fresh_var() in
-  let matcher = Lib_engine.Match(code) in
-  if contains_modif code && not guard
-  then CTL.Exists(true,v,predmaker guard (matcher,CTL.Modif v) label)
-  else
-    let iso_info = !Flag.track_iso_usage && not (Ast.get_isos code = []) in
-    (match (iso_info,!onlyModif,guard,
-           intersect !used_after (Ast.get_fvs code)) with
-      (false,true,_,[]) | (_,_,true,_) ->
-       predmaker guard (matcher,CTL.Control) label
-    | _ -> CTL.Exists(true,v,predmaker guard (matcher,CTL.UnModif v) label))
-
-let make_raw_match label guard code =
-  predmaker guard (Lib_engine.Match(code),CTL.Control) label
-    
-let rec seq_fvs quantified = function
-    [] -> []
-  | fv1::fvs ->
-      let t1fvs = get_unquantified quantified fv1 in
-      let termfvs =
-       List.fold_left Common.union_set []
-         (List.map (get_unquantified quantified) fvs) in
-      let bothfvs = Common.inter_set t1fvs termfvs in
-      let t1onlyfvs = Common.minus_set t1fvs bothfvs in
-      let new_quantified = Common.union_set bothfvs quantified in
-      (t1onlyfvs,bothfvs)::(seq_fvs new_quantified fvs)
-
-let quantify guard =
-  List.fold_right
-    (function cur ->
-      function code -> CTL.Exists (not guard && List.mem cur !saved,cur,code))
-
-let non_saved_quantify =
-  List.fold_right
-    (function cur -> function code -> CTL.Exists (false,cur,code))
-
-let intersectll lst nested_list =
-  List.filter (function x -> List.exists (List.mem x) nested_list) lst
-
-(* --------------------------------------------------------------------- *)
-(* Count depth of braces.  The translation of a closed brace appears deeply
-nested within the translation of the sequence term, so the name of the
-paren var has to take into account the names of the nested braces.  On the
-other hand the close brace does not escape, so we don't have to take into
-account other paren variable names. *)
-
-(* called repetitively, which is inefficient, but less trouble than adding a
-new field to Seq and FunDecl *)
-let count_nested_braces s =
-  let bind x y = max x y in
-  let option_default = 0 in
-  let stmt_count r k s =
-    match Ast.unwrap s with
-      Ast.Seq(_,_,_,_) | Ast.FunDecl(_,_,_,_,_) -> (k s) + 1
-    | _ -> k s in
-  let donothing r k e = k e in
-  let mcode r x = 0 in
-  let recursor = V.combiner bind option_default
-      mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
-      mcode
-      donothing donothing donothing donothing
-      donothing donothing donothing donothing donothing donothing
-      donothing donothing stmt_count donothing donothing donothing in
-  let res = string_of_int (recursor.V.combiner_statement s) in
-  string2var ("p"^res)
-
-let labelctr = ref 0
-let get_label_ctr _ =
-  let cur = !labelctr in
-  labelctr := cur + 1;
-  string2var (Printf.sprintf "l%d" cur)
-
-(* --------------------------------------------------------------------- *)
-(* annotate dots with before and after neighbors *)
-
-let print_bef_aft = function
-    Ast.WParen (re,n) ->
-      Printf.printf "bef/aft\n";
-      Pretty_print_cocci.rule_elem "" re;
-      Format.print_newline()
-  | Ast.Other s ->
-      Printf.printf "bef/aft\n";
-      Pretty_print_cocci.statement "" s;
-      Format.print_newline()
-  | Ast.Other_dots d ->
-      Printf.printf "bef/aft\n";
-      Pretty_print_cocci.statement_dots d;
-      Format.print_newline()
-
-(* [] can only occur if we are in a disj, where it comes from a ?  In that
-case, we want to use a, which accumulates all of the previous patterns in
-their entirety. *)
-let rec get_before_elem sl a =
-  match Ast.unwrap sl with
-    Ast.DOTS(x) ->
-      let rec loop sl a =
-       match sl with
-         [] -> ([],Common.Right a)
-       | [e] ->
-           let (e,ea) = get_before_e e a in
-           ([e],Common.Left ea)
-       | e::sl ->
-           let (e,ea) = get_before_e e a in
-           let (sl,sla) = loop sl ea in
-           (e::sl,sla) in
-      let (l,a) = loop x a in
-      (Ast.rewrap sl (Ast.DOTS(l)),a)
-  | Ast.CIRCLES(x) -> failwith "not supported"
-  | Ast.STARS(x) -> failwith "not supported"
-
-and get_before sl a =
-  match get_before_elem sl a with
-    (term,Common.Left x) -> (term,x)
-  | (term,Common.Right x) -> (term,x)
-
-and get_before_whencode wc =
-  List.map
-    (function
-       Ast.WhenNot w -> let (w,_) = get_before w [] in Ast.WhenNot w
-      | Ast.WhenAlways w -> let (w,_) = get_before_e w [] in Ast.WhenAlways w
-      |        Ast.WhenModifier(x) -> Ast.WhenModifier(x))
-    wc
-
-and get_before_e s a =
-  match Ast.unwrap s with
-    Ast.Dots(d,w,_,aft) ->
-      (Ast.rewrap s (Ast.Dots(d,get_before_whencode w,a,aft)),a)
-  | Ast.Nest(stmt_dots,w,multi,_,aft) ->
-      let w = get_before_whencode w in
-      let (sd,_) = get_before stmt_dots a in
-      let a =
-       List.filter
-         (function
-             Ast.Other a ->
-               let unifies =
-                 Unify_ast.unify_statement_dots
-                   (Ast.rewrap s (Ast.DOTS([a]))) stmt_dots in
-               (match unifies with
-                 Unify_ast.MAYBE -> false
-               | _ -> true)
-           | Ast.Other_dots a ->
-               let unifies = Unify_ast.unify_statement_dots a stmt_dots in
-               (match unifies with
-                 Unify_ast.MAYBE -> false
-               | _ -> true)
-           | _ -> true)
-         a in
-      (Ast.rewrap s (Ast.Nest(sd,w,multi,a,aft)),[Ast.Other_dots stmt_dots])
-  | Ast.Disj(stmt_dots_list) ->
-      let (dsl,dsla) =
-       List.split (List.map (function e -> get_before e a) stmt_dots_list) in
-      (Ast.rewrap s (Ast.Disj(dsl)),List.fold_left Common.union_set [] dsla)
-  | Ast.Atomic(ast) ->
-      (match Ast.unwrap ast with
-       Ast.MetaStmt(_,_,_,_) -> (s,[])
-      |        _ -> (s,[Ast.Other s]))
-  | Ast.Seq(lbrace,decls,body,rbrace) ->
-      let index = count_nested_braces s in
-      let (de,dea) = get_before decls [Ast.WParen(lbrace,index)] in
-      let (bd,_) = get_before body dea in
-      (Ast.rewrap s (Ast.Seq(lbrace,de,bd,rbrace)),
-       [Ast.WParen(rbrace,index)])
-  | Ast.Define(header,body) ->
-      let (body,_) = get_before body [] in
-      (Ast.rewrap s (Ast.Define(header,body)), [Ast.Other s])
-  | Ast.IfThen(ifheader,branch,aft) ->
-      let (br,_) = get_before_e branch [] in
-      (Ast.rewrap s (Ast.IfThen(ifheader,br,aft)), [Ast.Other s])
-  | Ast.IfThenElse(ifheader,branch1,els,branch2,aft) ->
-      let (br1,_) = get_before_e branch1 [] in
-      let (br2,_) = get_before_e branch2 [] in
-      (Ast.rewrap s (Ast.IfThenElse(ifheader,br1,els,br2,aft)),[Ast.Other s])
-  | Ast.While(header,body,aft) ->
-      let (bd,_) = get_before_e body [] in
-      (Ast.rewrap s (Ast.While(header,bd,aft)),[Ast.Other s])
-  | Ast.For(header,body,aft) ->
-      let (bd,_) = get_before_e body [] in
-      (Ast.rewrap s (Ast.For(header,bd,aft)),[Ast.Other s])
-  | Ast.Do(header,body,tail) ->
-      let (bd,_) = get_before_e body [] in
-      (Ast.rewrap s (Ast.Do(header,bd,tail)),[Ast.Other s])
-  | Ast.Iterator(header,body,aft) ->
-      let (bd,_) = get_before_e body [] in
-      (Ast.rewrap s (Ast.Iterator(header,bd,aft)),[Ast.Other s])
-  | Ast.Switch(header,lb,cases,rb) ->
-      let cases =
-       List.map
-         (function case_line ->
-           match Ast.unwrap case_line with
-             Ast.CaseLine(header,body) ->
-               let (body,_) = get_before body [] in
-               Ast.rewrap case_line (Ast.CaseLine(header,body))
-           | Ast.OptCase(case_line) -> failwith "not supported")
-         cases in
-      (Ast.rewrap s (Ast.Switch(header,lb,cases,rb)),[Ast.Other s])
-  | Ast.FunDecl(header,lbrace,decls,body,rbrace) ->
-      let (de,dea) = get_before decls [] in
-      let (bd,_) = get_before body dea in
-      (Ast.rewrap s (Ast.FunDecl(header,lbrace,de,bd,rbrace)),[])
-  | _ -> failwith "get_before_e: not supported"
-
-let rec get_after sl a =
-  match Ast.unwrap sl with
-    Ast.DOTS(x) ->
-      let rec loop sl =
-       match sl with
-         [] -> ([],a)
-       | e::sl ->
-           let (sl,sla) = loop sl in
-           let (e,ea) = get_after_e e sla in
-           (e::sl,ea) in
-      let (l,a) = loop x in
-      (Ast.rewrap sl (Ast.DOTS(l)),a)
-  | Ast.CIRCLES(x) -> failwith "not supported"
-  | Ast.STARS(x) -> failwith "not supported"
-
-and get_after_whencode a wc =
-  List.map
-    (function
-       Ast.WhenNot w -> let (w,_) = get_after w a (*?*) in Ast.WhenNot w
-      | Ast.WhenAlways w -> let (w,_) = get_after_e w a in Ast.WhenAlways w
-      |        Ast.WhenModifier(x) -> Ast.WhenModifier(x))
-    wc
-
-and get_after_e s a =
-  match Ast.unwrap s with
-    Ast.Dots(d,w,bef,_) ->
-      (Ast.rewrap s (Ast.Dots(d,get_after_whencode a w,bef,a)),a)
-  | Ast.Nest(stmt_dots,w,multi,bef,_) ->
-      let w = get_after_whencode a w in
-      let (sd,_) = get_after stmt_dots a in
-      let a =
-       List.filter
-         (function
-             Ast.Other a ->
-               let unifies =
-                 Unify_ast.unify_statement_dots
-                   (Ast.rewrap s (Ast.DOTS([a]))) stmt_dots in
-               (match unifies with
-                 Unify_ast.MAYBE -> false
-               | _ -> true)
-           | Ast.Other_dots a ->
-               let unifies = Unify_ast.unify_statement_dots a stmt_dots in
-               (match unifies with
-                 Unify_ast.MAYBE -> false
-               | _ -> true)
-           | _ -> true)
-         a in
-      (Ast.rewrap s (Ast.Nest(sd,w,multi,bef,a)),[Ast.Other_dots stmt_dots])
-  | Ast.Disj(stmt_dots_list) ->
-      let (dsl,dsla) =
-       List.split (List.map (function e -> get_after e a) stmt_dots_list) in
-      (Ast.rewrap s (Ast.Disj(dsl)),List.fold_left Common.union_set [] dsla)
-  | Ast.Atomic(ast) ->
-      (match Ast.unwrap ast with
-       Ast.MetaStmt(nm,keep,Ast.SequencibleAfterDots _,i) ->
-         (* check "after" information for metavar optimization *)
-         (* if the error is not desired, could just return [], then
-            the optimization (check for EF) won't take place *)
-         List.iter
-           (function
-               Ast.Other x ->
-                 (match Ast.unwrap x with
-                   Ast.Dots(_,_,_,_) | Ast.Nest(_,_,_,_,_) ->
-                     failwith
-                       "dots/nest not allowed before and after stmt metavar"
-                 | _ -> ())
-             | Ast.Other_dots x ->
-                 (match Ast.undots x with
-                   x::_ ->
-                     (match Ast.unwrap x with
-                       Ast.Dots(_,_,_,_) | Ast.Nest(_,_,_,_,_) ->
-                         failwith
-                           ("dots/nest not allowed before and after stmt "^
-                            "metavar")
-                     | _ -> ())
-                 | _ -> ())
-             | _ -> ())
-           a;
-         (Ast.rewrap s
-            (Ast.Atomic
-               (Ast.rewrap s
-                  (Ast.MetaStmt(nm,keep,Ast.SequencibleAfterDots a,i)))),[])
-      |        Ast.MetaStmt(_,_,_,_) -> (s,[])
-      |        _ -> (s,[Ast.Other s]))
-  | Ast.Seq(lbrace,decls,body,rbrace) ->
-      let index = count_nested_braces s in
-      let (bd,bda) = get_after body [Ast.WParen(rbrace,index)] in
-      let (de,_) = get_after decls bda in
-      (Ast.rewrap s (Ast.Seq(lbrace,de,bd,rbrace)),
-       [Ast.WParen(lbrace,index)])
-  | Ast.Define(header,body) ->
-      let (body,_) = get_after body a in
-      (Ast.rewrap s (Ast.Define(header,body)), [Ast.Other s])
-  | Ast.IfThen(ifheader,branch,aft) ->
-      let (br,_) = get_after_e branch a in
-      (Ast.rewrap s (Ast.IfThen(ifheader,br,aft)),[Ast.Other s])
-  | Ast.IfThenElse(ifheader,branch1,els,branch2,aft) ->
-      let (br1,_) = get_after_e branch1 a in
-      let (br2,_) = get_after_e branch2 a in
-      (Ast.rewrap s (Ast.IfThenElse(ifheader,br1,els,br2,aft)),[Ast.Other s])
-  | Ast.While(header,body,aft) ->
-      let (bd,_) = get_after_e body a in
-      (Ast.rewrap s (Ast.While(header,bd,aft)),[Ast.Other s])
-  | Ast.For(header,body,aft) ->
-      let (bd,_) = get_after_e body a in
-      (Ast.rewrap s (Ast.For(header,bd,aft)),[Ast.Other s])
-  | Ast.Do(header,body,tail) ->
-      let (bd,_) = get_after_e body a in
-      (Ast.rewrap s (Ast.Do(header,bd,tail)),[Ast.Other s])
-  | Ast.Iterator(header,body,aft) ->
-      let (bd,_) = get_after_e body a in
-      (Ast.rewrap s (Ast.Iterator(header,bd,aft)),[Ast.Other s])
-  | Ast.Switch(header,lb,cases,rb) ->
-      let cases =
-       List.map
-         (function case_line ->
-           match Ast.unwrap case_line with
-             Ast.CaseLine(header,body) ->
-               let (body,_) = get_after body [] in
-               Ast.rewrap case_line (Ast.CaseLine(header,body))
-           | Ast.OptCase(case_line) -> failwith "not supported")
-         cases in
-      (Ast.rewrap s (Ast.Switch(header,lb,cases,rb)),[Ast.Other s])
-  | Ast.FunDecl(header,lbrace,decls,body,rbrace) ->
-      let (bd,bda) = get_after body [] in
-      let (de,_) = get_after decls bda in
-      (Ast.rewrap s (Ast.FunDecl(header,lbrace,de,bd,rbrace)),[])
-  | _ -> failwith "get_after_e: not supported"
-
-let preprocess_dots sl =
-  let (sl,_) = get_before sl [] in
-  let (sl,_) = get_after sl [] in
-  sl
-
-let preprocess_dots_e sl =
-  let (sl,_) = get_before_e sl [] in
-  let (sl,_) = get_after_e sl [] in
-  sl
-
-(* --------------------------------------------------------------------- *)
-(* various return_related things *)
-
-let rec ends_in_return stmt_list =
-  match Ast.unwrap stmt_list with
-    Ast.DOTS(x) ->
-      (match List.rev x with
-       x::_ ->
-         (match Ast.unwrap x with
-           Ast.Atomic(x) ->
-             (match Ast.unwrap x with
-               Ast.Return(_,_) | Ast.ReturnExpr(_,_,_) -> true
-             | _ -> false)
-         | Ast.Disj(disjs) -> List.for_all ends_in_return disjs
-         | _ -> false)
-      |        _ -> false)
-  | Ast.CIRCLES(x) -> failwith "not supported"
-  | Ast.STARS(x) -> failwith "not supported"
-
-(* --------------------------------------------------------------------- *)
-(* expressions *)
-
-let exptymatch l make_match make_guard_match =
-  let pos = fresh_pos() in
-  let matches_guard_matches =
-    List.map
-      (function x ->
-       let pos = Ast.make_mcode pos in
-       (make_match (Ast.set_pos x (Some pos)),
-        make_guard_match (Ast.set_pos x (Some pos))))
-      l in
-  let (matches,guard_matches) = List.split matches_guard_matches in
-  let rec suffixes = function
-      [] -> []
-    | x::xs -> xs::(suffixes xs) in
-  let prefixes = List.rev (suffixes (List.rev guard_matches)) in
-  let info = (* not null *)
-    List.map2
-      (function matcher ->
-       function negates ->
-         CTL.Exists
-           (false,pos,
-            ctl_and CTL.NONSTRICT matcher
-              (ctl_not
-                 (ctl_uncheck (List.fold_left ctl_or_fl CTL.False negates)))))
-      matches prefixes in
-  CTL.InnerAnd(List.fold_left ctl_or_fl CTL.False (List.rev info))
-
-(* code might be a DisjRuleElem, in which case we break it apart
-   code might contain an Exp or Ty
-   this one pushes the quantifier inwards *)
-let do_re_matches label guard res quantified minus_quantified =
-  let make_guard_match x =
-    let stmt_fvs = Ast.get_mfvs x in
-    let fvs = get_unquantified minus_quantified stmt_fvs in
-    non_saved_quantify fvs (make_match None true x) in
-  let make_match x =
-    let stmt_fvs = Ast.get_fvs x in
-    let fvs = get_unquantified quantified stmt_fvs in
-    quantify guard fvs (make_match None guard x) in
-  ctl_and CTL.NONSTRICT (label_pred_maker label)
-    (match List.map Ast.unwrap res with
-      [] -> failwith "unexpected empty disj"
-    | Ast.Exp(e)::rest -> exptymatch res make_match make_guard_match
-    | Ast.Ty(t)::rest  -> exptymatch res make_match make_guard_match
-    | all ->
-       if List.exists (function Ast.Exp(_) | Ast.Ty(_) -> true | _ -> false)
-           all
-       then failwith "unexpected exp or ty";
-       List.fold_left ctl_seqor CTL.False
-         (List.rev (List.map make_match res)))
-
-(* code might be a DisjRuleElem, in which case we break it apart
-   code doesn't contain an Exp or Ty
-   this one is for use when it is not practical to push the quantifier inwards
- *)
-let header_match label guard code : ('a, Ast.meta_name, 'b) CTL.generic_ctl =
-  match Ast.unwrap code with
-    Ast.DisjRuleElem(res) ->
-      let make_match = make_match None guard in
-      let orop = if guard then ctl_or else ctl_seqor in
-      ctl_and CTL.NONSTRICT (label_pred_maker label)
-      (List.fold_left orop CTL.False (List.map make_match res))
-  | _ -> make_match label guard code
-
-(* --------------------------------------------------------------------- *)
-(* control structures *)
-
-let end_control_structure fvs header body after_pred
-    after_checks no_after_checks (afvs,afresh,ainh,aft) after label guard =
-  (* aft indicates what is added after the whole if, which has to be added
-     to the endif node *)
-  let (aft_needed,after_branch) =
-    match aft with
-      Ast.CONTEXT(_,Ast.NOTHING) ->
-       (false,make_seq_after2 guard after_pred after)
-    | _ ->
-       let match_endif =
-         make_match label guard
-           (make_meta_rule_elem aft (afvs,afresh,ainh)) in
-       (true,
-        make_seq_after guard after_pred
-          (After(make_seq_after guard match_endif after))) in
-  let body = body after_branch in
-  let s = guard_to_strict guard in
-  (* the code *)
-  quantify guard fvs
-    (ctl_and s header
-       (opt_and guard
-         (match (after,aft_needed) with
-           (After _,_) (* pattern doesn't end here *)
-         | (_,true) (* + code added after *) -> after_checks
-         | _ -> no_after_checks)
-         (ctl_ax_absolute s body)))
-
-let ifthen ifheader branch ((afvs,_,_,_) as aft) after
-    quantified minus_quantified label llabel slabel recurse make_match guard =
-(* "if (test) thn" becomes:
-    if(test) & AX((TrueBranch & AX thn) v FallThrough v After)
-
-    "if (test) thn; after" becomes:
-    if(test) & AX((TrueBranch & AX thn) v FallThrough v (After & AXAX after))
-             & EX After
-*)
-  (* free variables *) 
-  let (efvs,bfvs) =
-    match seq_fvs quantified
-       [Ast.get_fvs ifheader;Ast.get_fvs branch;afvs] with
-      [(efvs,b1fvs);(_,b2fvs);_] -> (efvs,Common.union_set b1fvs b2fvs)
-    | _ -> failwith "not possible" in
-  let new_quantified = Common.union_set bfvs quantified in
-  let (mefvs,mbfvs) =
-    match seq_fvs minus_quantified
-       [Ast.get_mfvs ifheader;Ast.get_mfvs branch;[]] with
-      [(efvs,b1fvs);(_,b2fvs);_] -> (efvs,Common.union_set b1fvs b2fvs)
-    | _ -> failwith "not possible" in
-  let new_mquantified = Common.union_set mbfvs minus_quantified in
-  (* if header *)
-  let if_header = quantify guard efvs (make_match ifheader) in
-  (* then branch and after *)
-  let lv = get_label_ctr() in
-  let used = ref false in
-  let true_branch =
-    make_seq guard
-      [truepred label; recurse branch Tail new_quantified new_mquantified
-         (Some (lv,used)) llabel slabel guard] in
-  let after_pred = aftpred label in
-  let or_cases after_branch =
-    ctl_or true_branch (ctl_or (fallpred label) after_branch) in
-  let (if_header,wrapper) =
-    if !used
-    then
-      let label_pred = CTL.Pred (Lib_engine.Label(lv),CTL.Control) in
-      (ctl_and CTL.NONSTRICT(*???*) if_header label_pred,
-       (function body -> quantify true [lv] body))
-    else (if_header,function x -> x) in
-  wrapper
-    (end_control_structure bfvs if_header or_cases after_pred
-       (Some(ctl_ex after_pred)) None aft after label guard)
-
-let ifthenelse ifheader branch1 els branch2 ((afvs,_,_,_) as aft) after
-    quantified minus_quantified label llabel slabel recurse make_match guard =
-(*  "if (test) thn else els" becomes:
-    if(test) & AX((TrueBranch & AX thn) v
-                  (FalseBranch & AX (else & AX els)) v After)
-             & EX FalseBranch
-
-    "if (test) thn else els; after" becomes:
-    if(test) & AX((TrueBranch & AX thn) v
-                  (FalseBranch & AX (else & AX els)) v
-                  (After & AXAX after))
-             & EX FalseBranch
-             & EX After
-*)
-  (* free variables *)
-  let (e1fvs,b1fvs,s1fvs) =
-    match seq_fvs quantified
-       [Ast.get_fvs ifheader;Ast.get_fvs branch1;afvs] with
-      [(e1fvs,b1fvs);(s1fvs,b1afvs);_] ->
-       (e1fvs,Common.union_set b1fvs b1afvs,s1fvs)
-    | _ -> failwith "not possible" in
-  let (e2fvs,b2fvs,s2fvs) =
-    (* fvs on else? *)
-    match seq_fvs quantified
-       [Ast.get_fvs ifheader;Ast.get_fvs branch2;afvs] with
-      [(e2fvs,b2fvs);(s2fvs,b2afvs);_] ->
-       (e2fvs,Common.union_set b2fvs b2afvs,s2fvs)
-    | _ -> failwith "not possible" in
-  let bothfvs        = union (union b1fvs b2fvs) (intersect s1fvs s2fvs) in
-  let exponlyfvs     = intersect e1fvs e2fvs in
-  let new_quantified = union bothfvs quantified in
-  (* minus free variables *)
-  let (me1fvs,mb1fvs,ms1fvs) =
-    match seq_fvs minus_quantified
-       [Ast.get_mfvs ifheader;Ast.get_mfvs branch1;[]] with
-      [(e1fvs,b1fvs);(s1fvs,b1afvs);_] ->
-       (e1fvs,Common.union_set b1fvs b1afvs,s1fvs)
-    | _ -> failwith "not possible" in
-  let (me2fvs,mb2fvs,ms2fvs) =
-    (* fvs on else? *)
-    match seq_fvs minus_quantified
-       [Ast.get_mfvs ifheader;Ast.get_mfvs branch2;[]] with
-      [(e2fvs,b2fvs);(s2fvs,b2afvs);_] ->
-       (e2fvs,Common.union_set b2fvs b2afvs,s2fvs)
-    | _ -> failwith "not possible" in
-  let mbothfvs       = union (union mb1fvs mb2fvs) (intersect ms1fvs ms2fvs) in
-  let new_mquantified = union mbothfvs minus_quantified in
-  (* if header *)
-  let if_header = quantify guard exponlyfvs (make_match ifheader) in
-  (* then and else branches *)
-  let lv = get_label_ctr() in
-  let used = ref false in
-  let true_branch =
-    make_seq guard
-      [truepred label; recurse branch1 Tail new_quantified new_mquantified
-         (Some (lv,used)) llabel slabel guard] in
-  let false_branch =
-    make_seq guard
-      [falsepred label; make_match els;
-       recurse branch2 Tail new_quantified new_mquantified
-         (Some (lv,used)) llabel slabel guard] in
-  let after_pred = aftpred label in
-  let or_cases after_branch =
-    ctl_or true_branch (ctl_or false_branch after_branch) in
-  let s = guard_to_strict guard in
-  let (if_header,wrapper) =
-    if !used
-    then
-      let label_pred = CTL.Pred (Lib_engine.Label(lv),CTL.Control) in
-      (ctl_and CTL.NONSTRICT(*???*) if_header label_pred,
-       (function body -> quantify true [lv] body))
-    else (if_header,function x -> x) in
-  wrapper
-    (end_control_structure bothfvs if_header or_cases after_pred
-      (Some(ctl_and s (ctl_ex (falsepred label)) (ctl_ex after_pred)))
-      (Some(ctl_ex (falsepred label)))
-      aft after label guard)
-
-let forwhile header body ((afvs,_,_,_) as aft) after
-    quantified minus_quantified label recurse make_match guard =
-  let process _ =
-    (* the translation in this case is similar to that of an if with no else *)
-    (* free variables *) 
-    let (efvs,bfvs) =
-      match seq_fvs quantified [Ast.get_fvs header;Ast.get_fvs body;afvs] with
-       [(efvs,b1fvs);(_,b2fvs);_] -> (efvs,Common.union_set b1fvs b2fvs)
-      | _ -> failwith "not possible" in
-    let new_quantified = Common.union_set bfvs quantified in
-    (* minus free variables *) 
-    let (mefvs,mbfvs) =
-      match seq_fvs minus_quantified
-         [Ast.get_mfvs header;Ast.get_mfvs body;[]] with
-       [(efvs,b1fvs);(_,b2fvs);_] -> (efvs,Common.union_set b1fvs b2fvs)
-      | _ -> failwith "not possible" in
-    let new_mquantified = Common.union_set mbfvs minus_quantified in
-    (* loop header *)
-    let header = quantify guard efvs (make_match header) in
-    let lv = get_label_ctr() in
-    let used = ref false in
-    let body =
-      make_seq guard
-       [inlooppred label;
-         recurse body Tail new_quantified new_mquantified
-           (Some (lv,used)) (Some (lv,used)) None guard] in
-    let after_pred = fallpred label in
-    let or_cases after_branch = ctl_or body after_branch in
-    let (header,wrapper) =
-      if !used
-      then
-       let label_pred = CTL.Pred (Lib_engine.Label(lv),CTL.Control) in
-       (ctl_and CTL.NONSTRICT(*???*) header label_pred,
-        (function body -> quantify true [lv] body))
-      else (header,function x -> x) in
-    wrapper
-      (end_control_structure bfvs header or_cases after_pred
-        (Some(ctl_ex after_pred)) None aft after label guard) in
-  match (Ast.unwrap body,aft) with
-    (Ast.Atomic(re),(_,_,_,Ast.CONTEXT(_,Ast.NOTHING))) ->
-      (match Ast.unwrap re with
-       Ast.MetaStmt((_,_,Ast.CONTEXT(_,Ast.NOTHING),_),
-                    Type_cocci.Unitary,_,false) ->
-         let (efvs) =
-           match seq_fvs quantified [Ast.get_fvs header] with
-             [(efvs,_)] -> efvs
-           | _ -> failwith "not possible" in
-         quantify guard efvs (make_match header)
-      | _ -> process())
-  | _ -> process()
-  
-(* --------------------------------------------------------------------- *)
-(* statement metavariables *)
-
-(* issue: an S metavariable that is not an if branch/loop body
-   should not match an if branch/loop body, so check that the labels
-   of the nodes before the first node matched by the S are different
-   from the label of the first node matched by the S *)
-let sequencibility body label_pred process_bef_aft = function
-    Ast.Sequencible | Ast.SequencibleAfterDots [] ->
-      body
-       (function x ->
-         (ctl_and CTL.NONSTRICT (ctl_not (ctl_back_ax label_pred)) x))
-  | Ast.SequencibleAfterDots l ->
-      (* S appears after some dots.  l is the code that comes after the S.
-        want to search for that first, because S can match anything, while
-        the stuff after is probably more restricted *)
-      let afts = List.map process_bef_aft l in
-      let ors = foldl1 ctl_or afts in
-      ctl_and CTL.NONSTRICT
-       (ctl_ef (ctl_and CTL.NONSTRICT ors (ctl_back_ax label_pred)))
-       (body
-          (function x ->
-            ctl_and CTL.NONSTRICT (ctl_not (ctl_back_ax label_pred)) x))
-  | Ast.NotSequencible -> body (function x -> x)
-
-let svar_context_with_add_after stmt s label quantified d ast
-    seqible after process_bef_aft guard fvinfo =
-  let label_var = (*fresh_label_var*) string2var "_lab" in
-  let label_pred =
-    CTL.Pred (Lib_engine.Label(label_var),CTL.Control) in
-  let prelabel_pred =
-    CTL.Pred (Lib_engine.PrefixLabel(label_var),CTL.Control) in
-  let matcher d = make_match None guard (make_meta_rule_elem d fvinfo) in
-  let full_metamatch = matcher d in
-  let first_metamatch =
-    matcher
-      (match d with
-       Ast.CONTEXT(pos,Ast.BEFOREAFTER(bef,_)) ->
-         Ast.CONTEXT(pos,Ast.BEFORE(bef))
-      |        Ast.CONTEXT(pos,_) -> Ast.CONTEXT(pos,Ast.NOTHING)
-      | Ast.MINUS(_,_) | Ast.PLUS -> failwith "not possible") in
-  let middle_metamatch =
-    matcher
-      (match d with
-       Ast.CONTEXT(pos,_) -> Ast.CONTEXT(pos,Ast.NOTHING)
-      | Ast.MINUS(_,_) | Ast.PLUS -> failwith "not possible") in
-  let last_metamatch =
-    matcher
-      (match d with
-       Ast.CONTEXT(pos,Ast.BEFOREAFTER(_,aft)) ->
-         Ast.CONTEXT(pos,Ast.AFTER(aft))
-      |        Ast.CONTEXT(_,_) -> d
-      | Ast.MINUS(_,_) | Ast.PLUS -> failwith "not possible") in
-
-  let rest_nodes =
-    ctl_and CTL.NONSTRICT middle_metamatch prelabel_pred in  
-  let left_or = (* the whole statement is one node *)
-    make_seq guard
-      [full_metamatch; and_after guard (ctl_not prelabel_pred) after] in
-  let right_or = (* the statement covers multiple nodes *)
-    make_seq guard
-      [first_metamatch;
-        ctl_au CTL.NONSTRICT
-         rest_nodes
-         (make_seq guard
-            [ctl_and CTL.NONSTRICT last_metamatch label_pred;
-              and_after guard
-                (ctl_not prelabel_pred) after])] in
-  let body f =
-    ctl_and CTL.NONSTRICT label_pred
-       (f (ctl_and CTL.NONSTRICT
-           (make_raw_match label false ast) (ctl_or left_or right_or))) in
-  let stmt_fvs = Ast.get_fvs stmt in
-  let fvs = get_unquantified quantified stmt_fvs in
-  quantify guard (label_var::fvs)
-    (sequencibility body label_pred process_bef_aft seqible)
-
-let svar_minus_or_no_add_after stmt s label quantified d ast
-    seqible after process_bef_aft guard fvinfo =
-  let label_var = (*fresh_label_var*) string2var "_lab" in
-  let label_pred =
-    CTL.Pred (Lib_engine.Label(label_var),CTL.Control) in
-  let prelabel_pred =
-    CTL.Pred (Lib_engine.PrefixLabel(label_var),CTL.Control) in
-  let matcher d = make_match None guard (make_meta_rule_elem d fvinfo) in
-  let pure_d =
-    (* don't have to put anything before the beginning, so don't have to
-       distinguish the first node.  so don't have to bother about paths,
-       just use the label. label ensures that found nodes match up with
-       what they should because it is in the lhs of the andany. *)
-    match d with
-       Ast.MINUS(pos,[]) -> true
-      | Ast.CONTEXT(pos,Ast.NOTHING) -> true
-      | _ -> false in
-  let ender =
-    match (pure_d,after) with
-      (true,Tail) | (true,End) | (true,VeryEnd) ->
-       (* the label sharing makes it safe to use AndAny *)
-       CTL.HackForStmt(CTL.FORWARD,CTL.NONSTRICT,
-                       ctl_and CTL.NONSTRICT label_pred
-                         (make_raw_match label false ast),
-                       ctl_and CTL.NONSTRICT (matcher d) prelabel_pred)
-    | _ ->
-       (* more safe but less efficient *)
-       let first_metamatch = matcher d in
-       let rest_metamatch =
-         matcher
-           (match d with
-             Ast.MINUS(pos,_) -> Ast.MINUS(pos,[])
-           | Ast.CONTEXT(pos,_) -> Ast.CONTEXT(pos,Ast.NOTHING)
-           | Ast.PLUS -> failwith "not possible") in
-       let rest_nodes = ctl_and CTL.NONSTRICT rest_metamatch prelabel_pred in
-       let last_node = and_after guard (ctl_not prelabel_pred) after in
-       (ctl_and CTL.NONSTRICT (make_raw_match label false ast)
-          (make_seq guard
-             [first_metamatch;
-               ctl_au CTL.NONSTRICT rest_nodes last_node])) in
-  let body f = ctl_and CTL.NONSTRICT label_pred (f ender) in
-  let stmt_fvs = Ast.get_fvs stmt in
-  let fvs = get_unquantified quantified stmt_fvs in
-  quantify guard (label_var::fvs)
-    (sequencibility body label_pred process_bef_aft seqible)
-
-(* --------------------------------------------------------------------- *)
-(* dots and nests *)
-
-let dots_au is_strict toend label s wrapcode x seq_after y quantifier =
-  let matchgoto = gotopred None in
-  let matchbreak =
-    make_match None false
-      (wrapcode
-        (Ast.Break(Ast.make_mcode "break",Ast.make_mcode ";"))) in
-  let matchcontinue =
-     make_match None false
-      (wrapcode
-        (Ast.Continue(Ast.make_mcode "continue",Ast.make_mcode ";"))) in
-  let stop_early v =
-    if !exists = Exists
-    then CTL.False
-    else if toend
-    then CTL.Or(aftpred label,exitpred label)
-    else if is_strict
-    then aftpred label
-    else
-      let lv = get_label_ctr() in
-      let labelpred = CTL.Pred(Lib_engine.Label lv,CTL.Control) in
-      let preflabelpred = label_pred_maker (Some (lv,ref true)) in
-      ctl_or (aftpred label)
-       (quantify false [lv]
-          (ctl_and CTL.NONSTRICT
-             (ctl_and CTL.NONSTRICT (truepred label) labelpred)
-             (ctl_au CTL.NONSTRICT
-                (ctl_and CTL.NONSTRICT (ctl_not v) preflabelpred)
-                (ctl_and CTL.NONSTRICT preflabelpred
-                   (ctl_or (retpred None)
-                      (if !Flag_engine.only_return_is_error_exit
-                      then CTL.True
-                      else
-                        (ctl_or matchcontinue
-                           (ctl_and CTL.NONSTRICT
-                              (ctl_or matchgoto matchbreak)
-                              (ctl_ag s (ctl_not seq_after)))))))))) in
-  let v = get_let_ctr() in
-  let op = if quantifier = !exists then ctl_au else ctl_anti_au in
-  op s x (CTL.Let(v,y,ctl_or (CTL.Ref v) (stop_early (CTL.Ref v))))
-
-let rec dots_and_nests plus nest whencodes bef aft dotcode after label
-    process_bef_aft statement_list statement guard wrapcode =
-  let ctl_and_ns = ctl_and CTL.NONSTRICT in
-  (* proces bef_aft *)
-  let shortest l =
-    List.fold_left ctl_or_fl CTL.False (List.map process_bef_aft l) in
-  let bef_aft = (* to be negated *)
-    try
-      let _ =
-       List.find
-         (function Ast.WhenModifier(Ast.WhenAny) -> true | _ -> false)
-         whencodes in
-      CTL.False
-    with Not_found -> shortest (Common.union_set bef aft) in
-  let is_strict =
-    List.exists
-      (function Ast.WhenModifier(Ast.WhenStrict) -> true | _ -> false)
-      whencodes in
-  let check_quantifier quant other =
-    if List.exists
-       (function Ast.WhenModifier(x) -> x = quant | _ -> false)
-       whencodes
-    then
-      if List.exists
-         (function Ast.WhenModifier(x) -> x = other | _ -> false)
-         whencodes
-      then failwith "inconsistent annotation on dots"
-      else true
-    else false in
-  let quantifier =
-    if check_quantifier Ast.WhenExists Ast.WhenForall
-    then Exists
-    else
-      if check_quantifier Ast.WhenExists Ast.WhenForall
-      then Forall
-      else !exists in
-  (* the following is used when we find a goto, etc and consider accepting
-     without finding the rest of the pattern *)
-  let aft = shortest aft in
-  (* process whencode *)
-  let labelled = label_pred_maker label in
-  let whencodes arg =
-    let (poswhen,negwhen) =
-      List.fold_left
-       (function (poswhen,negwhen) ->
-         function
-             Ast.WhenNot whencodes ->
-               (poswhen,ctl_or (statement_list whencodes) negwhen)
-           | Ast.WhenAlways stm ->
-               (ctl_and CTL.NONSTRICT (statement stm) poswhen,negwhen)
-           | Ast.WhenModifier(_) -> (poswhen,negwhen))
-       (CTL.True,bef_aft) (List.rev whencodes) in
-    let poswhen = ctl_and_ns arg poswhen in
-    let negwhen =
-(*    if !exists
-      then*)
-        (* add in After, because it's not part of the program *)
-       ctl_or (aftpred label) negwhen
-      (*else negwhen*) in
-    ctl_and_ns poswhen (ctl_not negwhen) in
-  (* process dot code, if any *)
-  let dotcode =
-    match (dotcode,guard) with
-      (None,_) | (_,true) -> CTL.True
-    | (Some dotcode,_) -> dotcode in
-  (* process nest code, if any *)
-  (* whencode goes in the negated part of the nest; if no nest, just goes
-      on the "true" in between code *)
-  let plus_var = if plus then get_label_ctr() else string2var "" in
-  let plus_var2 = if plus then get_label_ctr() else string2var "" in
-  let ornest =
-    match (nest,guard && not plus) with
-      (None,_) | (_,true) -> whencodes CTL.True
-    | (Some nest,false) ->
-       let v = get_let_ctr() in
-       let is_plus x =
-         if plus
-         then
-           (* the idea is that BindGood is sort of a witness; a witness to
-              having found the subterm in at least one place.  If there is
-              not a witness, then there is a risk that it will get thrown
-              away, if it is merged with a node that has an empty
-              environment.  See tests/nestplus.  But this all seems
-              rather suspicious *)
-           CTL.And(CTL.NONSTRICT,x,
-                   CTL.Exists(true,plus_var2,
-                              CTL.Pred(Lib_engine.BindGood(plus_var),
-                                       CTL.Modif plus_var2)))
-         else x in
-        CTL.Let(v,nest,
-               CTL.Or(is_plus (CTL.Ref v),
-                      whencodes (CTL.Not(ctl_uncheck (CTL.Ref v))))) in
-  let plus_modifier x =
-    if plus
-    then
-      CTL.Exists
-       (false,plus_var,
-        (CTL.And
-           (CTL.NONSTRICT,x,
-            CTL.Not(CTL.Pred(Lib_engine.BindBad(plus_var),CTL.Control)))))
-    else x in
-
-  let ender =
-    match after with
-      After f -> f
-    | Guard f -> ctl_uncheck f
-    | VeryEnd ->
-       let exit = endpred label in
-       let errorexit = exitpred label in
-       ctl_or exit errorexit
-    (* not at all sure what the next two mean... *)
-    | End -> CTL.True
-    | Tail ->
-       (match label with
-         Some (lv,used) -> used := true;
-           ctl_or (CTL.Pred(Lib_engine.Label lv,CTL.Control))
-             (ctl_back_ex (ctl_or (retpred label) (gotopred label)))
-       | None -> endpred label)
-         (* was the following, but not clear why sgrep should allow
-            incomplete patterns
-       let exit = endpred label in
-       let errorexit = exitpred label in
-       if !exists
-       then ctl_or exit errorexit (* end anywhere *)
-       else exit (* end at the real end of the function *) *) in
-  plus_modifier
-    (dots_au is_strict ((after = Tail) or (after = VeryEnd))
-       label (guard_to_strict guard) wrapcode
-      (ctl_and_ns dotcode (ctl_and_ns ornest labelled))
-      aft ender quantifier)
-
-(* --------------------------------------------------------------------- *)
-(* the main translation loop *)
-  
-let rec statement_list stmt_list after quantified minus_quantified
-    label llabel slabel dots_before guard =
-  let isdots x =
-    (* include Disj to be on the safe side *)
-    match Ast.unwrap x with
-      Ast.Dots _ | Ast.Nest _ | Ast.Disj _ -> true | _ -> false in
-  let compute_label l e db = if db or isdots e then l else None in
-  match Ast.unwrap stmt_list with
-    Ast.DOTS(x) ->
-      let rec loop quantified minus_quantified dots_before label llabel slabel
-         = function
-         ([],_,_) -> (match after with After f -> f | _ -> CTL.True)
-       | ([e],_,_) ->
-           statement e after quantified minus_quantified
-             (compute_label label e dots_before)
-             llabel slabel guard
-       | (e::sl,fv::fvs,mfv::mfvs) ->
-           let shared = intersectll fv fvs in
-           let unqshared = get_unquantified quantified shared in
-           let new_quantified = Common.union_set unqshared quantified in
-           let minus_shared = intersectll mfv mfvs in
-           let munqshared =
-             get_unquantified minus_quantified minus_shared in
-           let new_mquantified =
-             Common.union_set munqshared minus_quantified in
-           quantify guard unqshared
-             (statement e
-                (After
-                   (let (label1,llabel1,slabel1) =
-                     match Ast.unwrap e with
-                       Ast.Atomic(re) ->
-                         (match Ast.unwrap re with
-                           Ast.Goto _ -> (None,None,None)
-                         | _ -> (label,llabel,slabel))
-                     | _ -> (label,llabel,slabel) in
-                   loop new_quantified new_mquantified (isdots e)
-                     label1 llabel1 slabel1
-                     (sl,fvs,mfvs)))
-                new_quantified new_mquantified
-                (compute_label label e dots_before) llabel slabel guard)
-       | _ -> failwith "not possible" in
-      loop quantified minus_quantified dots_before
-       label llabel slabel
-       (x,List.map Ast.get_fvs x,List.map Ast.get_mfvs x)
-  | Ast.CIRCLES(x) -> failwith "not supported"
-  | Ast.STARS(x) -> failwith "not supported"
-
-(* llabel is the label of the enclosing loop and slabel is the label of the
-   enclosing switch *)
-and statement stmt after quantified minus_quantified
-    label llabel slabel guard =
-  let ctl_au     = ctl_au CTL.NONSTRICT in
-  let ctl_ax     = ctl_ax CTL.NONSTRICT in
-  let ctl_and    = ctl_and CTL.NONSTRICT in
-  let make_seq   = make_seq guard in
-  let make_seq_after = make_seq_after guard in
-  let real_make_match = make_match in
-  let make_match = header_match label guard in
-
-  let dots_done = ref false in (* hack for dots cases we can easily handle *)
-
-  let term =
-  match Ast.unwrap stmt with
-    Ast.Atomic(ast) ->
-      (match Ast.unwrap ast with
-       (* the following optimisation is not a good idea, because when S
-          is alone, we would like it not to match a declaration.
-          this makes more matching for things like when (...) S, but perhaps
-          that matching is not so costly anyway *)
-       (*Ast.MetaStmt(_,Type_cocci.Unitary,_,false) when guard -> CTL.True*)
-      |        Ast.MetaStmt((s,_,(Ast.CONTEXT(_,Ast.BEFOREAFTER(_,_)) as d),_),
-                    keep,seqible,_)
-      | Ast.MetaStmt((s,_,(Ast.CONTEXT(_,Ast.AFTER(_)) as d),_),
-                    keep,seqible,_)->
-         svar_context_with_add_after stmt s label quantified d ast seqible
-           after
-           (process_bef_aft quantified minus_quantified
-              label llabel slabel true)
-           guard
-           (Ast.get_fvs stmt, Ast.get_fresh stmt, Ast.get_inherited stmt)
-
-      |        Ast.MetaStmt((s,_,d,_),keep,seqible,_) ->
-         svar_minus_or_no_add_after stmt s label quantified d ast seqible
-           after
-           (process_bef_aft quantified minus_quantified
-              label llabel slabel true)
-           guard
-           (Ast.get_fvs stmt, Ast.get_fresh stmt, Ast.get_inherited stmt)
-
-      |        _ ->
-         let term =
-           match Ast.unwrap ast with
-             Ast.DisjRuleElem(res) ->
-               do_re_matches label guard res quantified minus_quantified
-           | Ast.Exp(_) | Ast.Ty(_) ->
-               let stmt_fvs = Ast.get_fvs stmt in
-               let fvs = get_unquantified quantified stmt_fvs in
-               CTL.InnerAnd(quantify guard fvs (make_match ast))
-           | _ ->
-               let stmt_fvs = Ast.get_fvs stmt in
-               let fvs = get_unquantified quantified stmt_fvs in
-               quantify guard fvs (make_match ast) in
-         match Ast.unwrap ast with
-           Ast.Break(brk,semi) ->
-             (match (llabel,slabel) with
-               (_,Some(lv,used)) -> (* use switch label if there is one *)
-                 ctl_and term (bclabel_pred_maker slabel)
-             | _ -> ctl_and term (bclabel_pred_maker llabel))
-         | Ast.Continue(brk,semi) -> ctl_and term (bclabel_pred_maker llabel)
-          | Ast.Return((_,info,retmc,pos),(_,_,semmc,_)) ->
-             (* discard pattern that comes after return *)
-             let normal_res = make_seq_after term after in
-             (* the following code tries to propagate the modifications on
-                return; to a close brace, in the case where the final return
-                is absent *)
-             let new_mc =
-               match (retmc,semmc) with
-                 (Ast.MINUS(_,l1),Ast.MINUS(_,l2)) when !Flag.sgrep_mode2 ->
-                   (* in sgrep mode, we can propagate the - *)
-                   Some (Ast.MINUS(Ast.NoPos,l1@l2))
-               | (Ast.MINUS(_,l1),Ast.MINUS(_,l2))
-               | (Ast.CONTEXT(_,Ast.BEFORE(l1)),
-                  Ast.CONTEXT(_,Ast.AFTER(l2))) ->
-                   Some (Ast.CONTEXT(Ast.NoPos,Ast.BEFORE(l1@l2)))
-               | (Ast.CONTEXT(_,Ast.BEFORE(_)),Ast.CONTEXT(_,Ast.NOTHING))
-               | (Ast.CONTEXT(_,Ast.NOTHING),Ast.CONTEXT(_,Ast.NOTHING)) ->
-                   Some retmc
-               | (Ast.CONTEXT(_,Ast.NOTHING),Ast.CONTEXT(_,Ast.AFTER(l))) ->
-                   Some (Ast.CONTEXT(Ast.NoPos,Ast.BEFORE(l)))
-               | _ -> None in
-             let ret = Ast.make_mcode "return" in
-             let edots =
-               Ast.rewrap ast (Ast.Edots(Ast.make_mcode "...",None)) in
-             let semi = Ast.make_mcode ";" in
-             let simple_return =
-               make_match(Ast.rewrap ast (Ast.Return(ret,semi))) in
-             let return_expr =
-               make_match(Ast.rewrap ast (Ast.ReturnExpr(ret,edots,semi))) in
-             (match new_mc with
-               Some new_mc ->
-                 let exit = endpred None in
-                 let mod_rbrace =
-                   Ast.rewrap ast (Ast.SeqEnd (("}",info,new_mc,pos))) in
-                 let stripped_rbrace =
-                   Ast.rewrap ast (Ast.SeqEnd(Ast.make_mcode "}")) in
-                 ctl_or normal_res
-                   (ctl_and (make_match mod_rbrace)
-                      (ctl_and
-                         (ctl_back_ax
-                            (ctl_not
-                               (ctl_uncheck
-                                  (ctl_or simple_return return_expr))))
-                         (ctl_au
-                            (make_match stripped_rbrace)
-                            (* error exit not possible; it is in the middle
-                               of code, so a return is needed *)
-                            exit)))
-             | _ ->
-                 (* some change in the middle of the return, so have to
-                    find an actual return *)
-                 normal_res)
-          | _ ->
-             (* should try to deal with the dots_bef_aft problem elsewhere,
-                but don't have the courage... *)
-             let term =
-               if guard
-               then term
-               else
-                 do_between_dots stmt term End
-                   quantified minus_quantified label llabel slabel guard in
-             dots_done := true;
-             make_seq_after term after)
-  | Ast.Seq(lbrace,decls,body,rbrace) ->
-      let (lbfvs,b1fvs,b2fvs,b3fvs,rbfvs) =
-       match
-         seq_fvs quantified
-           [Ast.get_fvs lbrace;Ast.get_fvs decls;
-             Ast.get_fvs body;Ast.get_fvs rbrace]
-       with
-         [(lbfvs,b1fvs);(_,b2fvs);(_,b3fvs);(rbfvs,_)] ->
-           (lbfvs,b1fvs,b2fvs,b3fvs,rbfvs)
-       | _ -> failwith "not possible" in
-      let (mlbfvs,mb1fvs,mb2fvs,mb3fvs,mrbfvs) =
-       match
-         seq_fvs minus_quantified
-           [Ast.get_mfvs lbrace;Ast.get_mfvs decls;
-             Ast.get_mfvs body;Ast.get_mfvs rbrace]
-       with
-         [(lbfvs,b1fvs);(_,b2fvs);(_,b3fvs);(rbfvs,_)] ->
-           (lbfvs,b1fvs,b2fvs,b3fvs,rbfvs)
-       | _ -> failwith "not possible" in
-      let pv = count_nested_braces stmt in
-      let lv = get_label_ctr() in
-      let paren_pred = CTL.Pred(Lib_engine.Paren pv,CTL.Control) in
-      let label_pred = CTL.Pred(Lib_engine.Label lv,CTL.Control) in
-      let start_brace =
-       ctl_and
-         (quantify guard lbfvs (make_match lbrace))
-         (ctl_and paren_pred label_pred) in
-      let end_brace =
-       (* label is not needed; paren_pred is enough *)
-       ctl_and
-         (quantify guard rbfvs (real_make_match None guard rbrace))
-         paren_pred in
-      let new_quantified2 =
-       Common.union_set b1fvs (Common.union_set b2fvs quantified) in
-      let new_quantified3 = Common.union_set b3fvs new_quantified2 in
-      let new_mquantified2 =
-       Common.union_set mb1fvs (Common.union_set mb2fvs minus_quantified) in
-      let new_mquantified3 = Common.union_set mb3fvs new_mquantified2 in
-      let pattern_as_given =
-       let new_quantified2 = Common.union_set [pv] new_quantified2 in
-       let new_quantified3 = Common.union_set [pv] new_quantified3 in
-       quantify true [pv;lv]
-         (quantify guard b1fvs
-            (make_seq
-               [start_brace;
-                 quantify guard b2fvs
-                   (statement_list decls
-                      (After
-                         (quantify guard b3fvs
-                            (statement_list body
-                               (After (make_seq_after end_brace after))
-                               new_quantified3 new_mquantified3
-                               (Some (lv,ref true)) (* label mostly useful *)
-                               llabel slabel true guard)))
-                      new_quantified2 new_mquantified2
-                      (Some (lv,ref true)) llabel slabel false guard)])) in
-      if ends_in_return body
-      then
-       (* matching error handling code *)
-       (* Cases:
-          1. The pattern as given
-          2. A goto, and then some close braces, and then the pattern as
-          given, but without the braces (only possible if there are no
-          decls, and open and close braces are unmodified)
-          3. Part of the pattern as given, then a goto, and then the rest
-          of the pattern.  For this case, we just check that all paths have
-          a goto within the current braces.  checking for a goto at every
-          point in the pattern seems expensive and not worthwhile. *)
-       let pattern2 =
-         let empty_rbrace =
-           match Ast.unwrap rbrace with
-             Ast.SeqEnd((data,info,_,pos)) ->
-               Ast.rewrap rbrace(Ast.SeqEnd(Ast.make_mcode data))
-           | _ -> failwith "unexpected close brace" in
-         let body = preprocess_dots body in (* redo, to drop braces *)
-         make_seq
-           [gotopred label;
-             ctl_au
-               (make_match empty_rbrace)
-               (ctl_ax (* skip the destination label *)
-                  (quantify guard b3fvs
-                     (statement_list body End
-                        new_quantified3 new_mquantified3 None llabel slabel
-                        true guard)))] in
-       let pattern3 =
-         let new_quantified2 = Common.union_set [pv] new_quantified2 in
-         let new_quantified3 = Common.union_set [pv] new_quantified3 in
-         quantify true [pv;lv]
-           (quantify guard b1fvs
-              (make_seq
-                 [start_brace;
-                   ctl_and
-                     (CTL.AU (* want AF even for sgrep *)
-                        (CTL.FORWARD,CTL.STRICT,
-                         CTL.Pred(Lib_engine.PrefixLabel(lv),CTL.Control),
-                         ctl_and (* brace must be eventually after goto *)
-                           (gotopred (Some (lv,ref true)))
-                           (* want AF even for sgrep *)
-                           (CTL.AF(CTL.FORWARD,CTL.STRICT,end_brace))))
-                     (quantify guard b2fvs
-                        (statement_list decls
-                           (After
-                              (quantify guard b3fvs
-                                 (statement_list body Tail
-                                       (*After
-                                          (make_seq_after
-                                             nopv_end_brace after)*)
-                                    new_quantified3 new_mquantified3
-                                    None llabel slabel true guard)))
-                           new_quantified2 new_mquantified2
-                           (Some (lv,ref true))
-                           llabel slabel false guard))])) in
-       ctl_or pattern_as_given
-         (match Ast.unwrap decls with
-           Ast.DOTS([]) -> ctl_or pattern2 pattern3
-         | Ast.DOTS(l) -> pattern3
-         | _ -> failwith "circles and stars not supported")
-      else pattern_as_given
-  | Ast.IfThen(ifheader,branch,aft) ->
-      ifthen ifheader branch aft after quantified minus_quantified
-         label llabel slabel statement make_match guard
-        
-  | Ast.IfThenElse(ifheader,branch1,els,branch2,aft) ->
-      ifthenelse ifheader branch1 els branch2 aft after quantified
-         minus_quantified label llabel slabel statement make_match guard
-
-  | Ast.While(header,body,aft) | Ast.For(header,body,aft)
-  | Ast.Iterator(header,body,aft) ->
-      forwhile header body aft after quantified minus_quantified
-       label statement make_match guard
-
-  | Ast.Disj(stmt_dots_list) -> (* list shouldn't be empty *)
-      ctl_and
-       (label_pred_maker label)
-       (List.fold_left ctl_seqor CTL.False
-          (List.map
-             (function sl ->
-               statement_list sl after quantified minus_quantified label
-                 llabel slabel true guard)
-             stmt_dots_list))
-
-  | Ast.Nest(stmt_dots,whencode,multi,bef,aft) ->
-      (* label in recursive call is None because label check is already
-        wrapped around the corresponding code *)
-
-      let bfvs =
-       match seq_fvs quantified [Ast.get_wcfvs whencode;Ast.get_fvs stmt_dots]
-       with
-         [(wcfvs,bothfvs);(bdfvs,_)] -> bothfvs
-       | _ -> failwith "not possible" in
-
-      (* no minus version because when code doesn't contain any minus code *)
-      let new_quantified = Common.union_set bfvs quantified in
-
-      quantify guard bfvs
-       (let dots_pattern =
-         statement_list stmt_dots (a2n after) new_quantified minus_quantified
-           None llabel slabel true guard in
-       dots_and_nests multi
-         (Some dots_pattern) whencode bef aft None after label
-         (process_bef_aft new_quantified minus_quantified
-            None llabel slabel true)
-         (function x ->
-           statement_list x Tail new_quantified minus_quantified None
-             llabel slabel true true)
-         (function x ->
-           statement x Tail new_quantified minus_quantified None
-             llabel slabel true)
-         guard (function x -> Ast.set_fvs [] (Ast.rewrap stmt x)))
-
-  | Ast.Dots((_,i,d,_),whencodes,bef,aft) ->
-      let dot_code =
-       match d with
-         Ast.MINUS(_,_) ->
-            (* no need for the fresh metavar, but ... is a bit wierd as a
-              variable name *)
-           Some(make_match (make_meta_rule_elem d ([],[],[])))
-       | _ -> None in
-      dots_and_nests false None whencodes bef aft dot_code after label
-       (process_bef_aft quantified minus_quantified None llabel slabel true)
-       (function x ->
-         statement_list x Tail quantified minus_quantified
-           None llabel slabel true true)
-       (function x ->
-         statement x Tail quantified minus_quantified None llabel slabel true)
-       guard (function x -> Ast.set_fvs [] (Ast.rewrap stmt x))
-
-  | Ast.Switch(header,lb,cases,rb) ->
-      let rec intersect_all = function
-         [] -> []
-       | [x] -> x
-       | x::xs -> intersect x (intersect_all xs) in
-      let rec union_all l = List.fold_left union [] l in
-      (* start normal variables *)
-      let header_fvs = Ast.get_fvs header in
-      let lb_fvs = Ast.get_fvs lb in
-      let case_fvs = List.map Ast.get_fvs cases in
-      let rb_fvs = Ast.get_fvs rb in
-      let (all_efvs,all_b1fvs,all_lbfvs,all_b2fvs,
-          all_casefvs,all_b3fvs,all_rbfvs) =
-       List.fold_left
-         (function (all_efvs,all_b1fvs,all_lbfvs,all_b2fvs,
-                    all_casefvs,all_b3fvs,all_rbfvs) ->
-           function case_fvs ->
-             match seq_fvs quantified [header_fvs;lb_fvs;case_fvs;rb_fvs] with
-               [(efvs,b1fvs);(lbfvs,b2fvs);(casefvs,b3fvs);(rbfvs,_)] ->
-                 (efvs::all_efvs,b1fvs::all_b1fvs,lbfvs::all_lbfvs,
-                  b2fvs::all_b2fvs,casefvs::all_casefvs,b3fvs::all_b3fvs,
-                  rbfvs::all_rbfvs)
-             | _ -> failwith "not possible")
-         ([],[],[],[],[],[],[]) case_fvs in
-      let (all_efvs,all_b1fvs,all_lbfvs,all_b2fvs,
-          all_casefvs,all_b3fvs,all_rbfvs) =
-       (List.rev all_efvs,List.rev all_b1fvs,List.rev all_lbfvs,
-        List.rev all_b2fvs,List.rev all_casefvs,List.rev all_b3fvs,
-        List.rev all_rbfvs) in
-      let exponlyfvs = intersect_all all_efvs in
-      let lbonlyfvs = intersect_all all_lbfvs in
-(* don't do anything with right brace.  Hope there is no + code on it *)
-(*      let rbonlyfvs = intersect_all all_rbfvs in*)
-      let b1fvs = union_all all_b1fvs in
-      let new1_quantified = union b1fvs quantified in
-      let b2fvs = union (union_all all_b1fvs) (intersect_all all_casefvs) in
-      let new2_quantified = union b2fvs new1_quantified in
-(*      let b3fvs = union_all all_b3fvs in*)
-      (* ------------------- start minus free variables *)
-      let header_mfvs = Ast.get_mfvs header in
-      let lb_mfvs = Ast.get_mfvs lb in
-      let case_mfvs = List.map Ast.get_mfvs cases in
-      let rb_mfvs = Ast.get_mfvs rb in
-      let (all_mefvs,all_mb1fvs,all_mlbfvs,all_mb2fvs,
-          all_mcasefvs,all_mb3fvs,all_mrbfvs) =
-       List.fold_left
-         (function (all_efvs,all_b1fvs,all_lbfvs,all_b2fvs,
-                    all_casefvs,all_b3fvs,all_rbfvs) ->
-           function case_mfvs ->
-             match
-               seq_fvs quantified
-                 [header_mfvs;lb_mfvs;case_mfvs;rb_mfvs] with
-               [(efvs,b1fvs);(lbfvs,b2fvs);(casefvs,b3fvs);(rbfvs,_)] ->
-                 (efvs::all_efvs,b1fvs::all_b1fvs,lbfvs::all_lbfvs,
-                  b2fvs::all_b2fvs,casefvs::all_casefvs,b3fvs::all_b3fvs,
-                  rbfvs::all_rbfvs)
-             | _ -> failwith "not possible")
-         ([],[],[],[],[],[],[]) case_mfvs in
-      let (all_mefvs,all_mb1fvs,all_mlbfvs,all_mb2fvs,
-          all_mcasefvs,all_mb3fvs,all_mrbfvs) =
-       (List.rev all_mefvs,List.rev all_mb1fvs,List.rev all_mlbfvs,
-        List.rev all_mb2fvs,List.rev all_mcasefvs,List.rev all_mb3fvs,
-        List.rev all_mrbfvs) in
-(* don't do anything with right brace.  Hope there is no + code on it *)
-(*      let rbonlyfvs = intersect_all all_rbfvs in*)
-      let mb1fvs = union_all all_mb1fvs in
-      let new1_mquantified = union mb1fvs quantified in
-      let mb2fvs = union (union_all all_mb1fvs) (intersect_all all_mcasefvs) in
-      let new2_mquantified = union mb2fvs new1_mquantified in
-(*      let b3fvs = union_all all_b3fvs in*)
-      (* ------------------- end collection of free variables *)
-      let switch_header = quantify guard exponlyfvs (make_match header) in
-      let lb = quantify guard lbonlyfvs (make_match lb) in
-(*      let rb = quantify guard rbonlyfvs (make_match rb) in*)
-      let case_headers =
-       List.map
-         (function case_line ->
-           match Ast.unwrap case_line with
-             Ast.CaseLine(header,body) ->
-               let e1fvs =
-                 match seq_fvs new2_quantified [Ast.get_fvs header] with
-                   [(e1fvs,_)] -> e1fvs
-                 | _ -> failwith "not possible" in
-               quantify guard e1fvs (real_make_match label true header)
-           | Ast.OptCase(case_line) -> failwith "not supported")
-         cases in
-      let no_header =
-       ctl_not (List.fold_left ctl_or_fl CTL.False case_headers) in
-      let lv = get_label_ctr() in
-      let used = ref false in
-      let case_code =
-       List.map
-         (function case_line ->
-           match Ast.unwrap case_line with
-             Ast.CaseLine(header,body) ->
-                 let (e1fvs,b1fvs,s1fvs) =
-                   let fvs = [Ast.get_fvs header;Ast.get_fvs body] in
-                   match seq_fvs new2_quantified fvs with
-                     [(e1fvs,b1fvs);(s1fvs,_)] -> (e1fvs,b1fvs,s1fvs)
-                   | _ -> failwith "not possible" in
-                 let (me1fvs,mb1fvs,ms1fvs) =
-                   let fvs = [Ast.get_mfvs header;Ast.get_mfvs body] in
-                   match seq_fvs new2_mquantified fvs with
-                     [(e1fvs,b1fvs);(s1fvs,_)] -> (e1fvs,b1fvs,s1fvs)
-                   | _ -> failwith "not possible" in
-                 let case_header =
-                   quantify guard e1fvs (make_match header) in
-                 let new3_quantified = union b1fvs new2_quantified in
-                 let new3_mquantified = union mb1fvs new2_mquantified in
-                 let body =
-                   statement_list body Tail
-                     new3_quantified new3_mquantified label llabel
-                     (Some (lv,used)) true(*?*) guard in
-                 quantify guard b1fvs (make_seq [case_header; body])
-           | Ast.OptCase(case_line) -> failwith "not supported")
-         cases in
-      let default_required =
-       if List.exists
-           (function case ->
-             match Ast.unwrap case with
-               Ast.CaseLine(header,_) ->
-                 (match Ast.unwrap header with
-                   Ast.Default(_,_) -> true
-                 | _ -> false)
-             | _ -> false)
-           cases
-       then function x -> x
-       else function x -> ctl_or (fallpred label) x in
-      let after_pred = aftpred label in
-      let body after_branch =
-       ctl_or
-         (default_required
-            (quantify guard b2fvs
-               (make_seq
-                  [ctl_and lb
-                      (List.fold_left ctl_and CTL.True
-                         (List.map ctl_ex case_headers));
-                    List.fold_left ctl_or_fl no_header case_code])))
-         after_branch in
-      let aft =
-       (rb_fvs,Ast.get_fresh rb,Ast.get_inherited rb,
-       match Ast.unwrap rb with
-         Ast.SeqEnd(rb) -> Ast.get_mcodekind rb
-       | _ -> failwith "not possible") in
-      let (switch_header,wrapper) =
-       if !used
-       then
-         let label_pred = CTL.Pred (Lib_engine.Label(lv),CTL.Control) in
-         (ctl_and switch_header label_pred,
-          (function body -> quantify true [lv] body))
-       else (switch_header,function x -> x) in
-      wrapper
-       (end_control_structure b1fvs switch_header body
-          after_pred (Some(ctl_ex after_pred)) None aft after label guard)
-  | Ast.FunDecl(header,lbrace,decls,body,rbrace) ->
-      let (hfvs,b1fvs,lbfvs,b2fvs,b3fvs,b4fvs,rbfvs) =
-       match
-         seq_fvs quantified
-           [Ast.get_fvs header;Ast.get_fvs lbrace;Ast.get_fvs decls;
-             Ast.get_fvs body;Ast.get_fvs rbrace]
-       with
-         [(hfvs,b1fvs);(lbfvs,b2fvs);(_,b3fvs);(_,b4fvs);(rbfvs,_)] ->
-           (hfvs,b1fvs,lbfvs,b2fvs,b3fvs,b4fvs,rbfvs)
-       | _ -> failwith "not possible" in
-      let (mhfvs,mb1fvs,mlbfvs,mb2fvs,mb3fvs,mb4fvs,mrbfvs) =
-       match
-         seq_fvs quantified
-           [Ast.get_mfvs header;Ast.get_mfvs lbrace;Ast.get_mfvs decls;
-             Ast.get_mfvs body;Ast.get_mfvs rbrace]
-       with
-         [(hfvs,b1fvs);(lbfvs,b2fvs);(_,b3fvs);(_,b4fvs);(rbfvs,_)] ->
-           (hfvs,b1fvs,lbfvs,b2fvs,b3fvs,b4fvs,rbfvs)
-       | _ -> failwith "not possible" in
-      let function_header = quantify guard hfvs (make_match header) in
-      let start_brace = quantify guard lbfvs (make_match lbrace) in
-      let stripped_rbrace =
-       match Ast.unwrap rbrace with
-         Ast.SeqEnd((data,info,_,_)) ->
-           Ast.rewrap rbrace(Ast.SeqEnd (Ast.make_mcode data))
-       | _ -> failwith "unexpected close brace" in
-      let end_brace =
-       let exit = CTL.Pred (Lib_engine.Exit,CTL.Control) in
-       let errorexit = CTL.Pred (Lib_engine.ErrorExit,CTL.Control) in
-       let fake_brace = CTL.Pred (Lib_engine.FakeBrace,CTL.Control) in
-       ctl_and
-         (quantify guard rbfvs (make_match rbrace))
-         (ctl_and
-            (* the following finds the beginning of the fake braces,
-               if there are any, not completely sure how this works.
-            sse the examples sw and return *)
-            (ctl_back_ex (ctl_not fake_brace))
-            (ctl_au (make_match stripped_rbrace) (ctl_or exit errorexit))) in
-      let new_quantified3 =
-       Common.union_set b1fvs
-         (Common.union_set b2fvs (Common.union_set b3fvs quantified)) in
-      let new_quantified4 = Common.union_set b4fvs new_quantified3 in
-      let new_mquantified3 =
-       Common.union_set mb1fvs
-         (Common.union_set mb2fvs
-            (Common.union_set mb3fvs minus_quantified)) in
-      let new_mquantified4 = Common.union_set mb4fvs new_mquantified3 in
-      let fn_nest =
-       match (Ast.undots decls,Ast.undots body,contains_modif rbrace) with
-         ([],[body],false) ->
-           (match Ast.unwrap body with
-             Ast.Nest(stmt_dots,[],multi,_,_) ->
-               if multi
-               then None (* not sure how to optimize this case *)
-               else Some (Common.Left stmt_dots)
-           | Ast.Dots(_,whencode,_,_) -> Some (Common.Right whencode)
-           | _ -> None)
-       | _ -> None in
-      let body_code =
-       match fn_nest with
-         Some (Common.Left stmt_dots) ->
-           (* special case for function header + body - header is unambiguous
-              and unique, so we can just look for the nested body anywhere
-              else in the CFG *)
-           CTL.AndAny
-             (CTL.FORWARD,guard_to_strict guard,start_brace,
-              statement_list stmt_dots
-                (* discards match on right brace, but don't need it *)
-                (Guard (make_seq_after end_brace after))
-                new_quantified4 new_mquantified4
-                None llabel slabel true guard)
-       | Some (Common.Right whencode) ->
-           (* try to be more efficient for the case where the body is just
-              ...  Perhaps this is too much of a special case, but useful
-              for dropping a parameter and checking that it is never used. *)
-           make_seq
-             [start_brace;
-               match whencode with
-                 [] -> CTL.True
-               | _ ->
-                   let leftarg =
-                     ctl_and
-                       (ctl_not
-                          (List.fold_left
-                             (function prev ->
-                               function
-                                   Ast.WhenAlways(s) -> prev
-                                 | Ast.WhenNot(sl) ->
-                                     let x =
-                                       statement_list sl Tail
-                                         new_quantified4 new_mquantified4
-                                         label llabel slabel true true in
-                                     ctl_or prev x
-                                 | Ast.WhenModifier(Ast.WhenAny) -> CTL.False
-                                 | Ast.WhenModifier(_) -> prev)
-                             CTL.False whencode))
-                        (List.fold_left
-                          (function prev ->
-                            function
-                                Ast.WhenAlways(s) ->
-                                  let x =
-                                    statement s Tail
-                                      new_quantified4 new_mquantified4
-                                      label llabel slabel true in
-                                  ctl_and prev x
-                              | Ast.WhenNot(sl) -> prev
-                              | Ast.WhenModifier(Ast.WhenAny) -> CTL.True
-                              | Ast.WhenModifier(_) -> prev)
-                          CTL.True whencode) in
-                   ctl_au leftarg (make_match stripped_rbrace)]
-       | None ->
-           make_seq
-             [start_brace;
-               quantify guard b3fvs
-                 (statement_list decls
-                    (After
-                       (quantify guard b4fvs
-                          (statement_list body
-                             (After (make_seq_after end_brace after))
-                             new_quantified4 new_mquantified4
-                             None llabel slabel true guard)))
-                    new_quantified3 new_mquantified3 None llabel slabel
-                    false guard)] in
-      quantify guard b1fvs
-       (make_seq [function_header; quantify guard b2fvs body_code])
-  | Ast.Define(header,body) ->
-      let (hfvs,bfvs,bodyfvs) =
-       match seq_fvs quantified [Ast.get_fvs header;Ast.get_fvs body]
-       with
-         [(hfvs,b1fvs);(bodyfvs,_)] -> (hfvs,b1fvs,bodyfvs)
-       | _ -> failwith "not possible" in
-      let (mhfvs,mbfvs,mbodyfvs) =
-       match seq_fvs minus_quantified [Ast.get_mfvs header;Ast.get_mfvs body]
-       with
-         [(hfvs,b1fvs);(bodyfvs,_)] -> (hfvs,b1fvs,bodyfvs)
-       | _ -> failwith "not possible" in
-      let define_header = quantify guard hfvs (make_match header) in
-      let body_code =
-       statement_list body after
-         (Common.union_set bfvs quantified)
-         (Common.union_set mbfvs minus_quantified)
-         None llabel slabel true guard in
-      quantify guard bfvs (make_seq [define_header; body_code])
-  | Ast.OptStm(stm) ->
-      failwith "OptStm should have been compiled away\n"
-  | Ast.UniqueStm(stm) -> failwith "arities not yet supported"
-  | _ -> failwith "not supported" in
-  if guard or !dots_done
-  then term
-  else
-    do_between_dots stmt term after quantified minus_quantified
-      label llabel slabel guard
-
-(* term is the translation of stmt *)
-and do_between_dots stmt term after quantified minus_quantified
-    label llabel slabel guard =
-    match Ast.get_dots_bef_aft stmt with
-      Ast.AddingBetweenDots (brace_term,n)
-    | Ast.DroppingBetweenDots (brace_term,n) ->
-       let match_brace =
-         statement brace_term after quantified minus_quantified
-           label llabel slabel guard in
-       let v = Printf.sprintf "_r_%d" n in
-       let case1 = ctl_and CTL.NONSTRICT (CTL.Ref v) match_brace in
-       let case2 = ctl_and CTL.NONSTRICT (ctl_not (CTL.Ref v)) term in
-       CTL.Let
-         (v,ctl_or
-            (ctl_back_ex (ctl_or (truepred label) (inlooppred label)))
-            (ctl_back_ex (ctl_back_ex (falsepred label))),
-          ctl_or case1 case2)   
-    | Ast.NoDots -> term
-
-(* un_process_bef_aft is because we don't want to do transformation in this
-  code, and thus don't case about braces before or after it *)
-and process_bef_aft quantified minus_quantified label llabel slabel guard =
-  function
-    Ast.WParen (re,n) ->
-      let paren_pred = CTL.Pred (Lib_engine.Paren n,CTL.Control) in
-      let s = guard_to_strict guard in
-      quantify true (get_unquantified quantified [n])
-       (ctl_and s (make_raw_match None guard re) paren_pred)
-  | Ast.Other s ->
-      statement s Tail quantified minus_quantified label llabel slabel guard
-  | Ast.Other_dots d ->
-      statement_list d Tail quantified minus_quantified
-       label llabel slabel true guard
-
-(* --------------------------------------------------------------------- *)
-(* cleanup: convert AX to EX for pdots.
-Concretely: AX(A[...] & E[...]) becomes AX(A[...]) & EX(E[...])
-This is what we wanted in the first place, but it wasn't possible to make
-because the AX and its argument are not created in the same place.
-Rather clunky... *)
-(* also cleanup XX, which is a marker for the case where the programmer
-specifies to change the quantifier on .... Assumed to only occur after one AX
-or EX, or at top level. *)
-
-let rec cleanup c =
-  let c = match c with CTL.XX(c) -> c | _ -> c in
-  match c with
-    CTL.False    -> CTL.False
-  | CTL.True     -> CTL.True
-  | CTL.Pred(p)  -> CTL.Pred(p)
-  | CTL.Not(phi) -> CTL.Not(cleanup phi)
-  | CTL.Exists(keep,v,phi) -> CTL.Exists(keep,v,cleanup phi)
-  | CTL.AndAny(dir,s,phi1,phi2) ->
-      CTL.AndAny(dir,s,cleanup phi1,cleanup phi2)
-  | CTL.HackForStmt(dir,s,phi1,phi2) ->
-      CTL.HackForStmt(dir,s,cleanup phi1,cleanup phi2)
-  | CTL.And(s,phi1,phi2)   -> CTL.And(s,cleanup phi1,cleanup phi2)
-  | CTL.Or(phi1,phi2)      -> CTL.Or(cleanup phi1,cleanup phi2)
-  | CTL.SeqOr(phi1,phi2)   -> CTL.SeqOr(cleanup phi1,cleanup phi2)
-  | CTL.Implies(phi1,phi2) -> CTL.Implies(cleanup phi1,cleanup phi2)
-  | CTL.AF(dir,s,phi1) -> CTL.AF(dir,s,cleanup phi1)
-  | CTL.AX(CTL.FORWARD,s,
-          CTL.Let(v1,e1,
-                  CTL.And(CTL.NONSTRICT,CTL.AU(CTL.FORWARD,s2,e2,e3),
-                          CTL.EU(CTL.FORWARD,e4,e5)))) ->
-    CTL.Let(v1,e1,
-           CTL.And(CTL.NONSTRICT,
-                   CTL.AX(CTL.FORWARD,s,CTL.AU(CTL.FORWARD,s2,e2,e3)),
-                   CTL.EX(CTL.FORWARD,CTL.EU(CTL.FORWARD,e4,e5))))
-  | CTL.AX(dir,s,CTL.XX(phi)) -> CTL.EX(dir,CTL.XX(cleanup phi))
-  | CTL.EX(dir,CTL.XX((CTL.AU(_,s,_,_)) as phi)) ->
-      CTL.AX(dir,s,CTL.XX(cleanup phi))
-  | CTL.XX(phi)               -> failwith "bad XX"
-  | CTL.AX(dir,s,phi1) -> CTL.AX(dir,s,cleanup phi1)
-  | CTL.AG(dir,s,phi1) -> CTL.AG(dir,s,cleanup phi1)
-  | CTL.EF(dir,phi1)   -> CTL.EF(dir,cleanup phi1)
-  | CTL.EX(dir,phi1)   -> CTL.EX(dir,cleanup phi1)
-  | CTL.EG(dir,phi1)   -> CTL.EG(dir,cleanup phi1)
-  | CTL.AW(dir,s,phi1,phi2) -> CTL.AW(dir,s,cleanup phi1,cleanup phi2)
-  | CTL.AU(dir,s,phi1,phi2) -> CTL.AU(dir,s,cleanup phi1,cleanup phi2)
-  | CTL.EU(dir,phi1,phi2)   -> CTL.EU(dir,cleanup phi1,cleanup phi2)
-  | CTL.Let (x,phi1,phi2)   -> CTL.Let (x,cleanup phi1,cleanup phi2)
-  | CTL.LetR (dir,x,phi1,phi2) -> CTL.LetR (dir,x,cleanup phi1,cleanup phi2)
-  | CTL.Ref(s) -> CTL.Ref(s)
-  | CTL.Uncheck(phi1)  -> CTL.Uncheck(cleanup phi1)
-  | CTL.InnerAnd(phi1) -> CTL.InnerAnd(cleanup phi1)
-
-(* --------------------------------------------------------------------- *)
-(* Function declaration *)
-
-let top_level name (ua,pos) t =
-  let ua = List.filter (function (nm,_) -> nm = name) ua in
-  used_after := ua;
-  saved := Ast.get_saved t;
-  let quantified = Common.minus_set ua pos in
-  quantify false quantified
-    (match Ast.unwrap t with
-      Ast.FILEINFO(old_file,new_file) -> failwith "not supported fileinfo"
-    | Ast.DECL(stmt) ->
-       let unopt = elim_opt.V.rebuilder_statement stmt in
-       let unopt = preprocess_dots_e unopt in
-       cleanup(statement unopt VeryEnd quantified [] None None None false)
-    | Ast.CODE(stmt_dots) ->
-       let unopt = elim_opt.V.rebuilder_statement_dots stmt_dots in
-       let unopt = preprocess_dots unopt in
-       let starts_with_dots =
-         match Ast.undots stmt_dots with
-           d::ds ->
-             (match Ast.unwrap d with
-               Ast.Dots(_,_,_,_) | Ast.Circles(_,_,_,_)
-             | Ast.Stars(_,_,_,_) -> true
-             | _ -> false)
-         | _ -> false in
-       let starts_with_brace =
-         match Ast.undots stmt_dots with
-           d::ds ->
-             (match Ast.unwrap d with
-               Ast.Seq(_) -> true
-             | _ -> false)
-         | _ -> false in
-       let res =
-         statement_list unopt VeryEnd quantified [] None None None
-           false false in
-       cleanup
-         (if starts_with_dots
-         then
-         (* EX because there is a loop on enter/top *)
-           ctl_and CTL.NONSTRICT (toppred None) (ctl_ex res)
-         else if starts_with_brace
-         then
-            ctl_and CTL.NONSTRICT
-             (ctl_not(CTL.EX(CTL.BACKWARD,(funpred None)))) res
-         else res)
-    | Ast.ERRORWORDS(exps) -> failwith "not supported errorwords")
-
-(* --------------------------------------------------------------------- *)
-(* Entry points *)
-
-let asttoctlz (name,(_,_,exists_flag),l) used_after positions =
-  letctr := 0;
-  labelctr := 0;
-  (match exists_flag with
-    Ast.Exists -> exists := Exists
-  | Ast.Forall -> exists := Forall
-  | Ast.ReverseForall -> exists := ReverseForall
-  | Ast.Undetermined ->
-      exists := if !Flag.sgrep_mode2 then Exists else Forall);
-
-  let (l,used_after) =
-    List.split
-      (List.filter
-        (function (t,_) ->
-          match Ast.unwrap t with Ast.ERRORWORDS(exps) -> false | _ -> true)
-        (List.combine l (List.combine used_after positions))) in
-  let res = List.map2 (top_level name) used_after l in
-  exists := Forall;
-  res
-
-let asttoctl r used_after positions =
-  match r with
-    Ast.ScriptRule _ -> []
-  | Ast.CocciRule (a,b,c,_) -> asttoctlz (a,b,c) used_after positions
-
-let pp_cocci_predicate (pred,modif) =
-  Pretty_print_engine.pp_predicate pred
-
-let cocci_predicate_to_string (pred,modif) =
-  Pretty_print_engine.predicate_to_string pred
similarity index 99%
rename from engine/.#asttoctl2.ml.1.141
rename to engine/.#asttoctl2.ml.1.144
index 6f1f8f6..0691c57 100644 (file)
@@ -1230,7 +1230,7 @@ let dots_au is_strict toend label s wrapcode x seq_after y quantifier =
       (wrapcode
         (Ast.Continue(Ast.make_mcode "continue",Ast.make_mcode ";"))) in
   let stop_early v =
-    if !exists = Exists
+    if quantifier = Exists
     then CTL.False
     else if toend
     then CTL.Or(aftpred label,exitpred label)
@@ -1248,7 +1248,7 @@ let dots_au is_strict toend label s wrapcode x seq_after y quantifier =
                 (ctl_and CTL.NONSTRICT (ctl_not v) preflabelpred)
                 (ctl_and CTL.NONSTRICT preflabelpred
                    (ctl_or (retpred None)
-                      (if !Flag_engine.only_return_is_error_exit
+                      (if !Flag_matcher.only_return_is_error_exit
                       then CTL.True
                       else
                         (ctl_or matchcontinue
@@ -2027,7 +2027,13 @@ and statement stmt after quantified minus_quantified
                if multi
                then None (* not sure how to optimize this case *)
                else Some (Common.Left stmt_dots)
-           | Ast.Dots(_,whencode,_,_) -> Some (Common.Right whencode)
+           | Ast.Dots(_,whencode,_,_) when
+               (List.for_all
+                  (* flow sensitive, so not optimizable *)
+                  (function Ast.WhenNotTrue(_) | Ast.WhenNotFalse(_) ->
+                     false
+                | _ -> true) whencode) ->
+               Some (Common.Right whencode)
            | _ -> None)
        | _ -> None in
       let body_code =
@@ -2065,6 +2071,8 @@ and statement stmt after quantified minus_quantified
                                          new_quantified4 new_mquantified4
                                          label llabel slabel true true in
                                      ctl_or prev x
+                                 | Ast.WhenNotTrue(_) | Ast.WhenNotFalse(_) ->
+                                     failwith "unexpected"
                                  | Ast.WhenModifier(Ast.WhenAny) -> CTL.False
                                  | Ast.WhenModifier(_) -> prev)
                              CTL.False whencode))
@@ -2078,6 +2086,8 @@ and statement stmt after quantified minus_quantified
                                       label llabel slabel true in
                                   ctl_and prev x
                               | Ast.WhenNot(sl) -> prev
+                              | Ast.WhenNotTrue(_) | Ast.WhenNotFalse(_) ->
+                                  failwith "unexpected"
                               | Ast.WhenModifier(Ast.WhenAny) -> CTL.True
                               | Ast.WhenModifier(_) -> prev)
                           CTL.True whencode) in
diff --git a/engine/.#c_vs_c.ml.1.9 b/engine/.#c_vs_c.ml.1.9
new file mode 100644 (file)
index 0000000..4391933
--- /dev/null
@@ -0,0 +1,294 @@
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+* 
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+* 
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
+* 
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+open Common
+
+open Ast_c
+
+(* For the moment I do only eq_type and not eq_expr, etc. The reason
+ * for eq_type is related to the typedef and struct isomorphism. Sometimes
+ * one use the typedef and sometimes the structname.
+ * 
+ * TODO: should use the isomorphisms engine of julia.
+ * Maybe I can transform my ast_c in ast_cocci, and use julia's code ?
+ * Maybe I can add some Disj in my ast_c ?
+ *)
+
+
+module type PARAM = 
+  sig 
+    type tin
+    type 'x tout
+
+    type 'a matcher = 'a -> 'a  -> tin -> 'a tout
+
+    val (>>=): 
+      (tin -> 'a tout)  -> 
+      ('a -> (tin -> 'b tout)) -> 
+      (tin -> 'b tout)
+
+    val (>&&>) : bool -> (tin -> 'x tout) -> (tin -> 'x tout)
+
+    val return : 'a -> tin -> 'a tout
+    val fail : tin -> 'a tout
+end
+
+
+module C_VS_C =
+  functor (X : PARAM) -> 
+struct
+
+type 'a matcher = 'a -> 'a  -> X.tin -> 'a X.tout
+
+let (>>=) = X.(>>=)
+let (>&&>) = X.(>&&>)
+let return = X.return
+let fail = X.fail
+
+let (option: 'a matcher -> ('a option matcher)) = fun f t1 t2 ->
+  match (t1,t2) with
+  | (Some t1, Some t2) -> 
+      f t1 t2 >>= (fun t -> 
+        return (Some t)
+      )
+  | (None, None) -> return None
+  | _ -> fail
+
+
+let rec fullType a b = 
+  let ((qua,iiqa), tya) = a in
+  let ((qub,iiqb), tyb) = b in
+  (qua.const =:= qub.const && qua.volatile =:= qub.volatile) >&&>
+
+    let (qu,iiq) = (qua, iiqa) in 
+    typeC tya tyb >>= (fun ty -> 
+      return ((qu,iiq), ty)
+    )
+
+and typeC tya tyb = 
+  let (a, iia) = tya in
+  let (b, iib) = tyb in
+
+  let iix = iia in
+
+  match a, b with
+  | BaseType a, BaseType b -> 
+      a =*= b >&&> return (BaseType a, iix)
+  | Pointer a, Pointer b -> 
+      fullType a b >>= (fun x -> return (Pointer x, iix))
+
+  | StructUnionName (sua, sa), StructUnionName (sub, sb) -> 
+      (sua =*= sub && sa =$= sb) >&&> 
+        return (StructUnionName (sua, sa), iix)
+
+  | TypeName (sa, opta), TypeName (sb, optb) -> 
+      (* assert compatible opta optb ? *)
+      (*option fullType opta optb*)
+      sa =$= sb >&&> 
+       let opt = 
+         (match opta, optb with
+         | None, None -> None
+         | Some x, _ 
+         | _, Some x 
+             -> Some x
+         ) 
+       in
+       return (TypeName (sa, opt), iix)
+      
+
+  | Array (ea, a), Array (eb,b) -> 
+      let get_option f = function Some x -> Some (f x) | None -> None in
+      let ea = get_option Lib_parsing_c.al_expr ea in
+      let eb = get_option Lib_parsing_c.al_expr eb in
+      ea =*= eb >&&> fullType a b >>= (fun x -> return (Array (ea, x), iix))
+
+  | FunctionType (returna, paramsa), FunctionType (returnb, paramsb) -> 
+      let (tsa, (ba,iihas3dotsa)) = paramsa in
+      let (tsb, (bb,iihas3dotsb)) = paramsb in
+
+      let bx = ba in
+      let iihas3dotsx = iihas3dotsa in
+
+      (ba = bb && List.length tsa = List.length tsb) >&&>
+      fullType returna returnb >>= (fun returnx -> 
+
+      Common.zip tsa tsb +> List.fold_left 
+        (fun acc ((parama,iia),(paramb,iib))->
+          let iix = iia in
+          acc >>= (fun xs -> 
+
+            let (((ba, saopt, ta), ii_b_sa)) = parama in
+            let (((bb, sbopt, tb), ii_b_sb)) = paramb in
+
+            let bx = ba in
+            let sxopt = saopt in
+            let ii_b_sx = ii_b_sa in
+
+            (ba =:= bb && saopt =*= sbopt) >&&>
+            fullType ta tb >>= (fun tx -> 
+              let paramx = (((bx, sxopt, tx), ii_b_sx)) in
+              return ((paramx,iix)::xs)
+            )
+          )
+        ) (return [])
+      >>= (fun tsx -> 
+        let paramsx = (List.rev tsx, (bx, iihas3dotsx)) in
+        return (FunctionType (returnx, paramsx), iix)
+      ))
+
+  | Enum (saopt, enuma), Enum (sbopt, enumb) -> 
+      (saopt =*= sbopt &&
+      List.length enuma = List.length enumb && 
+      Common.zip enuma enumb +> List.for_all (fun 
+        ((((sa, eopta),ii_s_eqa), iicommaa), (((sb, eoptb),ii_s_eqb),iicommab))
+          -> 
+            sa =$= sb && 
+            eopta =*= eoptb 
+        )
+      ) >&&>
+        return (Enum (saopt, enuma), iix)
+
+  | EnumName sa, EnumName sb -> sa =$= sb >&&> return (EnumName sa, iix)
+
+  | ParenType a, ParenType b -> 
+      (* iso here ? *)
+      fullType a b >>= (fun x -> 
+        return (ParenType x, iix)
+      )
+
+  | TypeOfExpr ea, TypeOfExpr eb -> 
+      let ea = Lib_parsing_c.al_expr ea in
+      let eb = Lib_parsing_c.al_expr eb in
+      ea =*= eb >&&> return (TypeOfExpr ea, iix)
+
+  | TypeOfType a, TypeOfType b -> 
+      fullType a b >>= (fun x -> return (TypeOfType x, iix))
+
+(*  | TypeOfType a, b -> 
+    | a, TypeOfType b -> 
+*)
+
+
+  | StructUnion (sua, saopt, sta), StructUnion (sub, sbopt, stb) -> 
+      (sua =*= sub && saopt =*= sbopt && List.length sta = List.length stb) 
+      >&&> 
+      Common.zip sta stb +> List.fold_left 
+        (fun acc ((xfielda, iia), (xfieldb, iib)) -> 
+          let iix = iia in
+          acc >>= (fun xs -> 
+            match xfielda, xfieldb with 
+            | EmptyField, EmptyField -> return ((EmptyField, iix)::xs)
+
+            | DeclarationField (FieldDeclList (fa, iipta)), 
+              DeclarationField (FieldDeclList (fb, iiptb)) -> 
+                let iipt = iipta in (* TODO ?*)
+                (List.length fa =|= List.length fb) >&&> 
+
+                Common.zip fa fb +> List.fold_left 
+                  (fun acc2 ((fielda,iia),(fieldb,iib))-> 
+                    let iix = iia in
+                    acc2 >>= (fun xs -> 
+                      let (fa, ii2a) = fielda in
+                      let (fb, ii2b) = fieldb in
+                      let ii2x = ii2a in
+                      match fa, fb with
+                      | Simple (saopt, ta), Simple (sbopt, tb) -> 
+                          saopt =*= sbopt >&&> 
+                          fullType ta tb >>= (fun tx -> 
+                            return (((Simple (saopt, tx), ii2x), iix)::xs)
+                          )
+                          
+                      | BitField (sopta, ta, ea), BitField (soptb, tb, eb) -> 
+                          (sopta =*= soptb && ea =*= eb) >&&> 
+                          fullType ta tb >>= (fun tx -> 
+                            return (((BitField (sopta,tx,ea), ii2x), iix)::xs)
+                          )
+                      | _,_ -> fail
+                    )
+                  ) (return [])
+                 >>= (fun fx -> 
+                   return (((DeclarationField 
+                               (FieldDeclList (List.rev fx,iipt))), iix)::xs)
+                 )
+            | _ -> fail
+          )
+
+
+        ) (return [])
+        >>= (fun stx -> 
+          return (StructUnion (sua, saopt, List.rev stx), iix)
+        )
+
+
+
+  (* choose the lub.
+   * subtil: in the return must put iia, not iix, and in following case
+   * must put iib and not iix, because we want the token corresponding
+   * to the typedef.
+   *)
+  | TypeName (s, Some a), _ -> 
+      fullType a (Ast_c.nQ, tyb) >>= (fun x -> 
+        return (TypeName (s, Some x), iia) 
+      )
+
+  | _, TypeName (s, Some b) -> 
+      fullType b (Ast_c.nQ, tya) >>= (fun x -> 
+        return (TypeName (s, Some x), iib) (* subtil: *)
+      )
+
+  | _, _ -> fail
+
+
+
+end
+
+module XEQ = struct
+  type tin = unit
+  type 'a tout = 'a option
+
+  type 'a matcher = 'a -> 'a -> tin -> 'a tout
+
+  let return x = fun tin -> Some x
+  let fail = fun tin -> None
+
+  let (>>=) m f = fun tin -> 
+    match m tin with
+    | None -> None
+    | Some x -> f x tin
+
+  let (>&&>) b m = fun tin -> 
+    if b then m tin
+    else fail tin
+
+end
+
+module EQ = C_VS_C (XEQ)
+
+
+let eq_type2 a b = EQ.fullType a b () <> None
+let merge_type2 a b = Common.some (EQ.fullType a b ())
+
+let eq_type a b = 
+  Common.profile_code "C_vs_c" (fun () -> eq_type2 a b)
+
+let merge_type a b = 
+  Common.profile_code "C_vs_c" (fun () -> merge_type2 a b)
diff --git a/engine/.#check_exhaustive_pattern.ml.1.39 b/engine/.#check_exhaustive_pattern.ml.1.39
deleted file mode 100644 (file)
index a716d1b..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-* 
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-* 
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-* 
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
-* 
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
-
-
-(* Just to warn me when there is some news in the types in
- * ast_cocci.ml or even ast_c.ml, so that I can then adjust my code in
- * pattern.ml or transformation.ml.
- * 
- * For the moment I do it only for myself (pad), that is I check only
- * for news in ast_cocci.ml, because I already know when I add stuff in
- * my code in ast_c.ml or control_flow_c.ml. *)
-
-module A = Ast_cocci
-module B = Ast_c
-module F = Control_flow_c
-
-(* dependencies_to_adjust: pattern.ml, transformaton.ml *)
-
-let dumb_astcocci_rule_elem = function
- | A.MetaRuleElem _ -> ()
- | A.MetaStmt (ida,_,_,_) -> ()
- | A.MetaStmtList _ -> ()
- | A.Exp expr -> ()
- | A.TopExp expr -> ()
- | A.Ty ty -> ()
- | A.FunHeader (bef,allminus, fninfo, ida, _, paramsa, _) -> ()
- | A.Decl (bef,allminus,decla) -> ()
- | A.SeqStart _ -> ()
- | A.SeqEnd _ -> ()
- | A.ExprStatement (ea, _) -> ()
- | A.IfHeader (_,_, ea, _) -> ()
- | A.Else _ -> ()
- | A.WhileHeader (_, _, ea, _) -> ()
- | A.DoHeader _ -> ()
- | A.WhileTail (_,_,ea,_,_) -> ()
- | A.ForHeader (_, _, ea1opt, _, ea2opt, _, ea3opt, _) -> ()
- | A.IteratorHeader (ia1, ia2, ea, ia3) -> ()
- | A.SwitchHeader _ -> ()
- | A.Break _ -> ()
- | A.Continue _ -> ()
- | A.Label _ -> ()
- | A.Goto(_,_,_) -> ()
- | A.Return _ -> ()
- | A.ReturnExpr (_, ea, _) -> ()
- | A.DefineHeader _ -> ()
- | A.Include _ -> ()
- | A.Default _ -> ()
- | A.Case _ -> ()
- | A.DisjRuleElem _ -> failwith "not possible - compiled away in asttoctl"
-
-let dumb_astcocci_decl = function
- | A.UnInit (stg, typa, sa, _)     -> ()
- | A.Init (stg, typa, sa, _, expa, _) -> ()
- | A.TyDecl (typa, _)     -> ()
- | A.MacroDecl(fn, _, eas, _, _) -> ()
- | A.Ddots(dots,whencode) -> ()
- | A.MetaDecl _ -> ()
- | A.Typedef(d,ty1,ty2,pv) -> ()
- | A.DisjDecl xs -> ()
- | A.OptDecl _ | A.UniqueDecl _ -> ()
-
-let dumb_astcocci_initialiser = function
-    A.Init(stg,ty,id,eq,ini,sem) -> ()
-  | A.UnInit(stg,ty,id,sem) -> ()
-  | A.MacroDecl(fn, _, eas, _, _) -> ()
-  | A.TyDecl(ty,sem) -> ()
-  | A.Typedef(d,ty1,ty2,pv) -> ()
-  | A.DisjDecl(decls) -> ()
-  | A.Ddots(dots,whencode) -> ()
-  | A.MetaDecl(name,_,_) -> ()
-  | A.OptDecl(decl) -> ()
-  | A.UniqueDecl(decl) -> ()
-
-let dumb_astcocci_expr = function
- | A.MetaExpr (ida,_,_, opttypa, _, _) -> ()
- | A.Edots (_,_) -> ()
- | A.MetaErr _ -> ()
- | A.Ident ida -> ()
- | A.Constant (A.String sa,_,_,_) -> ()
- | A.Constant (A.Char sa,_,_,_) -> ()
- | A.Constant (A.Int sa,_,_,_) -> ()
- | A.Constant (A.Float sa,_,_,_) -> ()
- | A.FunCall (ea1, _, eas, _) -> ()
- | A.Assignment (ea1, opa, ea2, _) -> ()
- | A.CondExpr (ea1,_,ea2opt,_,ea3) -> ()
- | A.Postfix (ea, opa) -> ()
- | A.Infix (ea, opa) -> ()
- | A.Unary (ea, opa) -> ()
- | A.Binary (ea1, opa, ea2) -> ()
- | A.Nested (ea1, opa, ea2) -> ()
- | A.ArrayAccess (ea1, _, ea2, _) -> ()
- | A.RecordAccess (ea, _, ida) -> ()
- | A.RecordPtAccess (ea, _, ida) -> ()
- | A.Cast (_, typa, _, ea) -> ()
- | A.SizeOfExpr (_, ea) -> ()
- | A.SizeOfType (_, _, typa, _) -> ()
- | A.TypeExp (typa) -> ()
- | A.Paren (_, ea, _) -> ()
- | A.NestExpr _ -> ()
- | A.MetaExprList _ -> ()
- | A.EComma _ -> ()
- | A.Ecircles _ -> ()
- | A.Estars _ -> ()
- | A.DisjExpr eas -> ()
- | A.UniqueExp _ -> ()
- | A.OptExp _ -> ()
-
-let dumb_astcocci_fulltype = function
-    A.Type(cv,ty) -> ()
-  | A.DisjType(types) -> ()
-  | A.OptType(ty) -> ()
-  | A.UniqueType(ty) -> ()
-
-let dumb_astcocci_type = function
- | A.MetaType(ida,_,_) -> ()
- | A.BaseType (basea, signaopt) -> ()
- | A.ImplicitInt (signa) -> ()
- | A.Pointer (typa, _) -> ()
- | A.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> ()
- | A.FunctionType _ -> ()
- | A.Array (typa, _, eaopt, _) -> ()
- | A.StructUnionName(sa, sua) -> ()
- | A.StructUnionDef(ty, lb, decls, rb) -> ()
- | A.TypeName sa -> ()
-
-
-(* ------------------------------------------------------------------------- *)
-(* for C *)
-(*
-  | (Ident (_) | Constant _ | FunCall (_,_) | CondExpr (_,_,_) 
-    | Sequence (_,_)
-    | Assignment (_,_,_) 
-    | Postfix (_,_) | Infix (_,_) | Unary (_,_) | Binary (_,_,_)
-    | ArrayAccess (_,_) | RecordAccess (_,_) | RecordPtAccess (_,_)
-    | SizeOfExpr (_) | SizeOfType (_) | Cast (_,_) 
-    | StatementExpr (_) | Constructor 
-    | ParenExpr (_) | MacroCall (_) | MacroCall2 (_)
-    ),_ -> 
-
-  | ( Labeled (Label (_,_)) | Labeled (Case  (_,_)) 
-    | Labeled (CaseRange  (_,_,_)) | Labeled (Default _)
-    | Compound _ | ExprStatement _ 
-    | Selection  (If (_, _, _)) | Selection  (Switch (_, _))
-    | Iteration  (While (_, _)) | Iteration  (DoWhile (_, _)) 
-    | Iteration  (For ((_,_), (_,_), (_, _), _))
-    | Jump (Goto _) | Jump ((Continue|Break|Return)) | Jump (ReturnExpr _)
-    | Decl _ | Asm | Selection (IfCpp (_,_))
-    ), _ -> 
-*)
-
-(* for control flow nodes 
-
-  | ( F.ExprStatement (_, _) 
-    | F.IfHeader  (_, _) | F.SwitchHeader (_, _)
-    | F.WhileHeader (_, _) | (* F.DoHeader (_, _) | *) F.DoWhileTail (_, _) 
-    | F.ForHeader (_, _)
-    | F.Return     (_, _)  | F.ReturnExpr (_, _)
-        (* no counter part in cocci *)
-    | F.Label (_, _) 
-    | F.Case  (_,_) | (* F.CaseRange (_, _) | *) F.Default   (_, _)
-    | F.Goto (_, _) | F.Continue (_, _) | F.Break    (_, _)
-    ) -> raise Impossible
-
-*)
diff --git a/engine/.#check_reachability.ml.1.18 b/engine/.#check_reachability.ml.1.18
new file mode 100644 (file)
index 0000000..297a7d4
--- /dev/null
@@ -0,0 +1,208 @@
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+* 
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+* 
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
+* 
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+(* ---------------------------------------------------------------- *)
+(* code to check for ambiguities *)
+
+(* Idea: for each node that is said to be modified in any witness tree, we
+  check that all backward paths end up at the root of some witness tree
+  that says that the node should be modified.  We then give a warning, if
+  the node itself appears more than once in such a path, because then there
+  could be some instances that are modified and some that are not.  An
+  example is as follows:
+
+  f(); ... g(); ... - h();
+
+  with C code: f(); while(E) { h(); g(); } g(); h();
+
+  Then the h() in the while loop matches both the first ... and the - h();
+
+  Concretely, if a node 47 is in the witness tree rooted at 1 and the
+  witness tree rooted at 2, then we give an error if 47 is not in the set
+  of nodes satisfying AF[1v2] and give a warning if 47 is in the set of
+  nodes satisfying EXEF(47 & EXEF(1v2)). (Note that the root of a witness
+  tree here is the node causing the pattern to match; there might not be
+  any witnesses associated with this node.)
+
+  Another try on the exists formula:
+  !(1v2) & EXE[!(1v2) U 47]
+  The first !(1v2) is to discard immediately cases where the beginning and
+  end of the path are the same.  Afterwards, it would only seem necessary to
+  serach up to the next occurrence of 47 (leaf), ensuring that there are not
+  1s or 2s (starting points) along the way.  Then the second 47 would be in
+  the path, but possible not transformed.
+ *)
+
+module G = Ograph_extended
+module CTL = Ast_ctl
+
+(* Step 1: for each tree, make a mapping from the modified nodes to the root
+of the tree *)
+
+let modified = (Hashtbl.create(25) : (G.nodei, G.nodei list ref) Hashtbl.t)
+
+let build_modified (n,_,wits) =
+  let rec loop = function
+      CTL.Wit(st,[CTL.Subst(x,Wrapper_ctl.PredVal(CTL.Modif(v)))],anno,wit) ->
+       let cell =
+         try Hashtbl.find modified st
+         with Not_found ->
+           let cell = ref [] in Hashtbl.add modified st cell; cell in
+       cell := n :: !cell;
+       List.iter loop wit
+    |  CTL.Wit(st,_,anno,wit) -> List.iter loop wit
+    |  CTL.NegWit(wit) -> () in
+  List.iter loop wits
+    
+(* Step 2: For each node in the hash table, create the error and warning
+   formulas *)
+
+type 'a nodes = Node of 'a | After
+    
+let create_formulas _ =
+  Hashtbl.fold
+    (function node ->
+      function roots ->
+       function acc ->
+         (*let exef f =
+           wrap
+             (Ast_ctl.EX
+                (Ast_ctl.BACKWARD,wrap(Ast_ctl.EF(Ast_ctl.BACKWARD,f)))) in*)
+         let match_node = Ast_ctl.Pred(Node(node)) in
+         let match_roots =
+           List.map (function n -> Ast_ctl.Pred(Node(n)))
+             (List.sort compare !roots) in
+         let roots =
+           List.fold_left
+             (function prev -> function cur -> Ast_ctl.Or(prev,cur))
+             (List.hd match_roots) (List.tl match_roots) in
+         (node,
+          Ast_ctl.AF(Ast_ctl.BACKWARD,Ast_ctl.NONSTRICT,
+                     Ast_ctl.Or(roots,Ast_ctl.Pred(After))),
+          Ast_ctl.And
+            (Ast_ctl.NONSTRICT,
+             Ast_ctl.Not(roots),
+             Ast_ctl.EX
+               (Ast_ctl.BACKWARD,
+                Ast_ctl.EU(Ast_ctl.BACKWARD,roots,match_node))))
+          (*exef
+             (wrap(Ast_ctl.And(Ast_ctl.NONSTRICT,match_node,exef(roots))))*)
+         :: acc)
+    modified []
+
+(* Step 3: check the formula on the control-flow graph *)
+
+module PRED = 
+  struct
+    type t = Ograph_extended.nodei nodes
+    let print_predicate = function
+       After -> Format.print_string "after"
+      |        Node x -> Format.print_string (string_of_int x)
+  end
+
+module ENV =
+  struct
+    type value = unit
+    type mvar = unit
+    let eq_mvar x x'   = failwith "should not be invoked"
+    let eq_val v v'    = failwith "should not be invoked"
+    let merge_val v v' = failwith "should not be invoked"
+
+    let print_mvar s   = failwith "should not be invoked"
+    let print_value x  = failwith "should not be invoked"
+  end
+
+
+module CFG = 
+  struct
+    type node = Ograph_extended.nodei
+    type cfg = 
+        (Control_flow_c.node, Control_flow_c.edge) 
+          Ograph_extended.ograph_mutable
+    let predecessors cfg n = List.map fst ((cfg#predecessors n)#tolist)
+    let successors   cfg n = List.map fst ((cfg#successors n)#tolist)
+    let extract_is_loop cfg n =
+      Control_flow_c.extract_is_loop (cfg#nodes#find n)
+    let print_node i = Format.print_string (string_of_int i)
+    let size cfg = cfg#nodes#length
+  end
+
+module ENGINE = Ctl_engine.CTL_ENGINE (ENV) (CFG) (PRED)
+
+let test_formula state formula cfg =
+    let label = function
+       Node pred -> [(pred,[],[])]
+      |        After ->
+         List.concat
+           (List.map
+              (fun (nodei, node) ->
+                match Control_flow_c.unwrap node with
+                  Control_flow_c.AfterNode -> [(nodei,[],[])]
+                | _ -> [])
+              cfg#nodes#tolist) in
+    let verbose = !Flag_ctl.verbose_ctl_engine in
+    let pm = !Flag_ctl.partial_match in
+    Flag_ctl.verbose_ctl_engine := false;
+    Flag_ctl.partial_match := false;
+    let res =
+      ENGINE.sat (cfg,label,List.map fst cfg#nodes#tolist)
+       (CTL.And(CTL.NONSTRICT,CTL.Pred(Node(state)),formula))
+       [[Node(state)]] in
+    Flag_ctl.verbose_ctl_engine := verbose;
+    Flag_ctl.partial_match := pm;
+    match res with [] -> false | _ -> true
+
+(* ---------------------------------------------------------------- *)
+(* Entry point *)
+
+(* The argument is a list of triples with a node name, an empty environment
+and a witness tree *)
+
+type witness =
+    (Ograph_extended.nodei, unit,
+     (Ograph_extended.nodei, unit, unit) Ast_ctl.generic_ctl list)
+      Ast_ctl.generic_witnesstree
+
+type ('a,'b,'c,'d,'e) triples =
+    (Ograph_extended.nodei * 'a *
+     (Ograph_extended.nodei,
+      ('b, ('c, 'd) Wrapper_ctl.wrapped_binding) CTL.generic_subst list, 'e)
+     CTL.generic_witnesstree list) list
+
+let check_reachability triples cfg =
+  Hashtbl.clear modified;
+  List.iter build_modified triples;
+  let formulas = create_formulas() in
+  List.iter
+    (function (node,af_formula,ef_formula) ->
+      if test_formula node af_formula cfg
+      then
+       if test_formula node ef_formula cfg
+       then
+         Printf.printf "warning: node %d may be inconsistently modified\n"
+           node
+       else ()
+      else
+       failwith
+         (Printf.sprintf
+            "node %d reachable by inconsistent control-flow paths" node))
+    formulas
diff --git a/engine/.#cocci_vs_c_3.ml.1.154 b/engine/.#cocci_vs_c_3.ml.1.154
deleted file mode 100644 (file)
index fc1f4c0..0000000
+++ /dev/null
@@ -1,3419 +0,0 @@
-(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-* 
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-* 
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-* 
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
-* 
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
-
-open Common
-
-module A = Ast_cocci
-module B = Ast_c
-
-module F = Control_flow_c
-
-(*****************************************************************************)
-(* Wrappers *)
-(*****************************************************************************)
-
-(*****************************************************************************)
-(* Helpers *)
-(*****************************************************************************)
-
-type sequence = Ordered | Unordered
-
-let seqstyle eas =      
-   match A.unwrap eas with 
-   | A.DOTS _ -> Ordered 
-   | A.CIRCLES _ -> Unordered 
-   | A.STARS _ -> failwith "not handling stars"
-
-let (redots : 'a A.dots -> 'a list -> 'a A.dots)=fun eas easundots ->
-  A.rewrap eas ( 
-    match A.unwrap eas with 
-    | A.DOTS _ -> A.DOTS easundots
-    | A.CIRCLES _ -> A.CIRCLES easundots
-    | A.STARS _ -> A.STARS easundots
-  )
-
-
-let (need_unordered_initialisers : B.initialiser B.wrap2 list -> bool) = 
- fun ibs -> 
-   ibs +> List.exists (fun (ib, icomma) -> 
-     match B.unwrap ib with
-     | B.InitDesignators _ 
-     | B.InitFieldOld _ 
-     | B.InitIndexOld _
-         -> true
-     | B.InitExpr _ 
-     | B.InitList _ 
-         -> false
-   )
-
-(* For the #include <linux/...> in the .cocci, need to find where is
- * the '+' attached to this element, to later find the first concrete
- * #include <linux/xxx.h> or last one in the serie of #includes in the
- * .c.
- *)
-type include_requirement = 
-  | IncludeMcodeBefore
-  | IncludeMcodeAfter 
-  | IncludeNothing
-
-
-        
-(* todo? put in semantic_c.ml *)
-type info_ident = 
-  | Function 
-  | LocalFunction (* entails Function *)
-  | DontKnow
-
-
-let term      mc = A.unwrap_mcode mc
-let mcodekind mc = A.get_mcodekind mc
-
-
-let mcode_contain_plus = function
-  | A.CONTEXT (_,A.NOTHING) -> false
-  | A.CONTEXT _ -> true
-  | A.MINUS (_,[]) -> false
-  | A.MINUS (_,x::xs) -> true
-  | A.PLUS -> raise Impossible
-
-let mcode_simple_minus = function
-  | A.MINUS (_,[]) -> true
-  | _ -> false
-
-
-(* In transformation.ml sometime I build some mcodekind myself and
- * julia has put None for the pos. But there is no possible raise
- * NoMatch in those cases because it is for the minusall trick or for
- * the distribute, so either have to build those pos, in fact a range,
- * because for the distribute have to erase a fullType with one
- * mcodekind, or add an argument to tag_with_mck such as "safe" that
- * don't do the check_pos. Hence this DontCarePos constructor. *)
-
-let minusizer = 
-  ("fake","fake"), 
-  {A.line = 0; column =0; A.strbef=[]; A.straft=[];},
-  (A.MINUS(A.DontCarePos, [])),
-  A.NoMetaPos
-
-let generalize_mcode ia = 
-  let (s1, i, mck, pos) = ia in
-  let new_mck =
-    match mck with
-    | A.PLUS -> raise Impossible
-    | A.CONTEXT (A.NoPos,x) -> 
-       A.CONTEXT (A.DontCarePos,x)
-    | A.MINUS   (A.NoPos,x) -> 
-       A.MINUS   (A.DontCarePos,x)
-    | _ -> raise Impossible in
-  (s1, i, new_mck, pos)
-
-
-
-(*---------------------------------------------------------------------------*)
-
-(* 0x0 is equivalent to 0,  value format isomorphism *)
-let equal_c_int s1 s2 = 
-  try 
-    int_of_string s1 = int_of_string s2
-  with Failure("int_of_string") -> 
-    s1 =$= s2
-
-
-
-(*---------------------------------------------------------------------------*)
-(* Normally A should reuse some types of Ast_c, so those
- * functions should not exist.
- * 
- * update: but now Ast_c depends on A, so can't make too
- * A depends on Ast_c, so have to stay with those equal_xxx
- * functions. 
- *)
-
-let equal_unaryOp a b = 
-  match a, b with
-  | A.GetRef   , B.GetRef  -> true
-  | A.DeRef    , B.DeRef   -> true
-  | A.UnPlus   , B.UnPlus  -> true
-  | A.UnMinus  , B.UnMinus -> true
-  | A.Tilde    , B.Tilde   -> true
-  | A.Not      , B.Not     -> true
-  | _, _ -> false
-
-let equal_arithOp a b = 
-  match a, b with
-  | A.Plus     , B.Plus     -> true
-  | A.Minus    , B.Minus    -> true
-  | A.Mul      , B.Mul      -> true
-  | A.Div      , B.Div      -> true
-  | A.Mod      , B.Mod      -> true
-  | A.DecLeft  , B.DecLeft  -> true
-  | A.DecRight , B.DecRight -> true
-  | A.And      , B.And      -> true
-  | A.Or       , B.Or       -> true
-  | A.Xor      , B.Xor      -> true
-  | _          , _          -> false
-
-let equal_logicalOp a b = 
-  match a, b with
-  | A.Inf    , B.Inf    -> true
-  | A.Sup    , B.Sup    -> true
-  | A.InfEq  , B.InfEq  -> true
-  | A.SupEq  , B.SupEq  -> true
-  | A.Eq     , B.Eq     -> true
-  | A.NotEq  , B.NotEq  -> true
-  | A.AndLog , B.AndLog -> true
-  | A.OrLog  , B.OrLog  -> true
-  | _          , _          -> false
-
-let equal_assignOp a b = 
-  match a, b with
-  | A.SimpleAssign, B.SimpleAssign -> true
-  | A.OpAssign a,   B.OpAssign b -> equal_arithOp a b
-  | _ -> false
-
-let equal_fixOp a b = 
-  match a, b with
-  | A.Dec, B.Dec -> true
-  | A.Inc, B.Inc -> true
-  | _ -> false
-
-let equal_binaryOp a b = 
-  match a, b with
-  | A.Arith a,    B.Arith b ->   equal_arithOp a b
-  | A.Logical a,  B.Logical b -> equal_logicalOp a b
-  | _ -> false
-
-let equal_structUnion a b = 
-  match a, b with
-  | A.Struct, B.Struct -> true
-  | A.Union,  B.Union -> true
-  | _, _ -> false
-
-let equal_sign a b = 
-  match a, b with
-  | A.Signed,    B.Signed   -> true
-  | A.Unsigned,  B.UnSigned -> true
-  | _, _ -> false
-
-let equal_storage a b = 
-  match a, b with
-  | A.Static   , B.Sto B.Static
-  | A.Auto     , B.Sto B.Auto
-  | A.Register , B.Sto B.Register
-  | A.Extern   , B.Sto B.Extern 
-      -> true
-  | _ -> false
-
-(*---------------------------------------------------------------------------*)
-
-let equal_metavarval valu valu' =
-  match valu, valu' with
-  | Ast_c.MetaIdVal a, Ast_c.MetaIdVal b -> a =$= b
-  | Ast_c.MetaFuncVal a, Ast_c.MetaFuncVal b -> a =$= b
-  | Ast_c.MetaLocalFuncVal a, Ast_c.MetaLocalFuncVal b -> 
-      (* do something more ? *)
-      a =$= b
-
-  (* al_expr before comparing !!! and accept when they match.
-   * Note that here we have Astc._expression, so it is a match
-   * modulo isomorphism (there is no metavariable involved here,
-   * just isomorphisms). => TODO call isomorphism_c_c instead of
-   * =*=. Maybe would be easier to transform ast_c in ast_cocci
-   * and call the iso engine of julia. *)
-  | Ast_c.MetaExprVal a, Ast_c.MetaExprVal b -> 
-      Lib_parsing_c.al_expr a =*= Lib_parsing_c.al_expr b
-  | Ast_c.MetaExprListVal a, Ast_c.MetaExprListVal b -> 
-      Lib_parsing_c.al_arguments a =*= Lib_parsing_c.al_arguments b
-
-  | Ast_c.MetaStmtVal a, Ast_c.MetaStmtVal b -> 
-      Lib_parsing_c.al_statement a =*= Lib_parsing_c.al_statement b
-  | Ast_c.MetaTypeVal a, Ast_c.MetaTypeVal b -> 
-      (* old: Lib_parsing_c.al_type a =*= Lib_parsing_c.al_type b *)
-      C_vs_c.eq_type a b
-        
-  | Ast_c.MetaListlenVal a, Ast_c.MetaListlenVal b -> a =|= b
-
-  | Ast_c.MetaParamVal a, Ast_c.MetaParamVal b -> 
-      Lib_parsing_c.al_param a =*= Lib_parsing_c.al_param b
-  | Ast_c.MetaParamListVal a, Ast_c.MetaParamListVal b -> 
-      Lib_parsing_c.al_params a =*= Lib_parsing_c.al_params b
-
-  | Ast_c.MetaPosVal (posa1,posa2), Ast_c.MetaPosVal (posb1,posb2) -> 
-      Ast_cocci.equal_pos posa1 posb1 && Ast_cocci.equal_pos posa2 posb2
-        
-  | Ast_c.MetaPosValList l1, Ast_c.MetaPosValList l2 ->
-      List.exists
-       (function (fla,posa1,posa2) ->
-         List.exists
-           (function (flb,posb1,posb2) ->
-             fla = flb &&
-             Ast_c.equal_posl posa1 posb1 && Ast_c.equal_posl posa2 posb2)
-            l2)
-       l1
-  | _ -> raise Impossible
-
-
-
-(*---------------------------------------------------------------------------*)
-(* could put in ast_c.ml, next to the split/unsplit_comma *)
-let split_signb_baseb_ii (baseb, ii) = 
-  let iis = ii +> List.map (fun info -> (B.str_of_info info), info) in
-  match baseb, iis with
-  
-  | B.Void, ["void",i1] -> None, [i1]
-      
-  | B.FloatType (B.CFloat),["float",i1] -> None, [i1]
-  | B.FloatType (B.CDouble),["double",i1] -> None, [i1]
-  | B.FloatType (B.CLongDouble),["long",i1;"double",i2] -> None,[i1;i2]
-      
-  | B.IntType (B.CChar), ["char",i1] -> None, [i1]
-
-
-  | B.IntType (B.Si (sign, base)), xs -> 
-      (match sign, base, xs with
-      | B.Signed, B.CChar2,   ["signed",i1;"char",i2] -> 
-          Some (B.Signed, i1), [i2]
-      | B.UnSigned, B.CChar2,   ["unsigned",i1;"char",i2] -> 
-          Some (B.UnSigned, i1), [i2]
-
-      | B.Signed, B.CShort, ["short",i1] -> 
-          None, [i1]
-      | B.Signed, B.CShort, ["signed",i1;"short",i2] -> 
-          Some (B.Signed, i1), [i2]
-      | B.UnSigned, B.CShort, ["unsigned",i1;"short",i2] -> 
-          Some (B.UnSigned, i1), [i2]
-      | B.Signed, B.CShort, ["short",i1;"int",i2] -> 
-          None, [i1;i2]
-
-      | B.Signed, B.CInt, ["int",i1] -> 
-          None, [i1]
-      | B.Signed, B.CInt, ["signed",i1;"int",i2] -> 
-          Some (B.Signed, i1), [i2]
-      | B.UnSigned, B.CInt, ["unsigned",i1;"int",i2] -> 
-          Some (B.UnSigned, i1), [i2]
-
-      | B.Signed, B.CInt, ["signed",i1;] -> 
-          Some (B.Signed, i1), []
-      | B.UnSigned, B.CInt, ["unsigned",i1;] -> 
-          Some (B.UnSigned, i1), []
-
-      | B.Signed, B.CLong, ["long",i1] -> 
-          None, [i1]
-      | B.Signed, B.CLong, ["long",i1;"int",i2] -> 
-          None, [i1;i2]
-      | B.Signed, B.CLong, ["signed",i1;"long",i2] -> 
-          Some (B.Signed, i1), [i2]
-      | B.UnSigned, B.CLong, ["unsigned",i1;"long",i2] -> 
-          Some (B.UnSigned, i1), [i2]
-
-      | B.Signed, B.CLongLong, ["long",i1;"long",i2] -> None, [i1;i2]
-      | B.Signed, B.CLongLong, ["signed",i1;"long",i2;"long",i3] -> 
-          Some (B.Signed, i1), [i2;i3]
-      | B.UnSigned, B.CLongLong, ["unsigned",i1;"long",i2;"long",i3] -> 
-          Some (B.UnSigned, i1), [i2;i3]
-
-
-      | B.UnSigned, B.CShort, ["unsigned",i1;"short",i2; "int", i3] -> 
-          Some (B.UnSigned, i1), [i2;i3]
-          
-
-
-      | _ -> failwith "strange type1, maybe because of weird order"
-      )
-  | _ -> failwith "strange type2, maybe because of weird order"
-
-(*---------------------------------------------------------------------------*)
-
-let rec unsplit_icomma xs = 
-  match xs with
-  | [] -> []
-  | x::y::xs -> 
-      (match A.unwrap y with
-      | A.IComma mcode -> 
-          (x, y)::unsplit_icomma xs
-      | _ -> failwith "wrong ast_cocci in initializer"
-      )
-  | _ -> 
-      failwith ("wrong ast_cocci in initializer, should have pair " ^
-                "number of Icomma")
-
-
-
-let resplit_initialiser ibs iicomma = 
-  match iicomma, ibs with
-  | [], [] -> []
-  | [], _ -> 
-      failwith "should have a iicomma, do you generate fakeInfo in parser?"
-  | _, [] -> 
-      failwith "shouldn't have a iicomma"
-  | [iicomma], x::xs -> 
-      let elems = List.map fst (x::xs) in
-      let commas = List.map snd (x::xs) +> List.flatten in
-      let commas = commas @ [iicomma] in
-      zip elems commas 
-  | _ -> raise Impossible
-
-
-
-let rec split_icomma xs = 
-  match xs with
-  | [] -> []
-  | (x,y)::xs -> x::y::split_icomma xs
-
-let rec unsplit_initialiser ibs_unsplit = 
-  match ibs_unsplit with
-  | [] -> [],  [] (* empty iicomma *)
-  | (x, commax)::xs -> 
-      let (xs, lastcomma) = unsplit_initialiser_bis commax xs in
-      (x, [])::xs,  lastcomma
-
-and unsplit_initialiser_bis comma_before = function
-  | [] -> [], [comma_before]
-  | (x, commax)::xs -> 
-      let (xs, lastcomma) = unsplit_initialiser_bis commax xs in
-      (x, [comma_before])::xs,  lastcomma
-
-
-
-
-(*---------------------------------------------------------------------------*)
-(* coupling: same in type_annotater_c.ml *)
-let structdef_to_struct_name ty = 
-  match ty with 
-  | qu, (B.StructUnion (su, sopt, fields), iis) -> 
-      (match sopt,iis with
-      | Some s , [i1;i2;i3;i4] -> 
-          qu, (B.StructUnionName (su, s), [i1;i2])
-      | None, _ -> 
-          ty
-          
-      | x -> raise Impossible
-      )
-  | _ -> raise Impossible
-
-(*---------------------------------------------------------------------------*)
-let initialisation_to_affectation decl = 
-  match decl with
-  | B.MacroDecl _ -> F.Decl decl
-  | B.DeclList (xs, iis) -> 
-      
-      (* todo?: should not do that if the variable is an array cos
-       *  will have x[] = , mais de toute facon ca sera pas un InitExp
-       *)
-      (match xs with
-      | [] -> raise Impossible
-      | [x] -> 
-          let ((var, returnType, storage, local),iisep) = x in
-
-          (match var with
-          | Some ((s, ini),  iis::iini) -> 
-              (match ini with
-              | Some (B.InitExpr e, ii_empty2) -> 
-                 let local =
-                   match local with
-                     Ast_c.NotLocalDecl -> Ast_c.NotLocalVar
-                   | Ast_c.LocalDecl -> Ast_c.LocalVar (iis.Ast_c.pinfo) in
-          
-                  let typ =
-                   ref (Some ((Lib_parsing_c.al_type returnType),local),
-                              Ast_c.NotTest) in
-                  let id = (B.Ident s, typ),[iis] in
-                  F.DefineExpr
-                    ((B.Assignment (id, B.SimpleAssign, e), 
-                     Ast_c.noType()), iini)
-              | _ -> F.Decl decl
-              )
-          | _ -> F.Decl decl
-          )
-      | x::xs -> 
-          pr2_once "TODO: initialisation_to_affectation for multi vars";
-          (* todo? do a fold_left and generate 'x = a, y = b' etc, use
-           * the Sequence expression operator of C and make an 
-           * ExprStatement from that.
-           *)
-          F.Decl decl
-      )
-
-
-
-
-
-(*****************************************************************************)
-(* Functor parameter combinators *)
-(*****************************************************************************)
-(* monad like stuff
- * src: papers on parser combinators in haskell (cf a pearl by meijer in ICFP)
- * 
- * version0: was not tagging the SP, so just tag the C
- *  val (>>=): 
- *   (tin -> 'c tout)  -> ('c -> (tin -> 'b tout)) -> (tin -> 'b tout)
- *   val return : 'b -> tin -> 'b tout
- *   val fail : tin -> 'b tout
- * 
- * version1: now also tag the SP so return a ('a * 'b)
- *)
-
-type mode = PatternMode | TransformMode
-
-module type PARAM = 
-  sig 
-    type tin
-    type 'x tout
-
-
-    type ('a, 'b) matcher = 'a -> 'b  -> tin -> ('a * 'b) tout
-
-    val mode : mode
-
-    val (>>=): 
-      (tin -> ('a * 'b) tout)  -> 
-      ('a -> 'b -> (tin -> ('c * 'd) tout)) -> 
-      (tin -> ('c * 'd) tout)
-
-    val return : ('a * 'b) -> tin -> ('a *'b) tout
-    val fail : tin -> ('a * 'b) tout
-
-    val (>||>) : 
-      (tin -> 'x tout) ->
-      (tin -> 'x tout) -> 
-      (tin -> 'x tout)
-
-    val (>|+|>) : 
-      (tin -> 'x tout) ->
-      (tin -> 'x tout) -> 
-      (tin -> 'x tout)
-
-    val (>&&>) : (tin -> bool) -> (tin -> 'x tout) -> (tin -> 'x tout)
-
-    val tokenf : ('a A.mcode, B.info) matcher
-    val tokenf_mck : (A.mcodekind, B.info) matcher
-
-    val distrf_e : 
-      (A.meta_name A.mcode, B.expression) matcher
-    val distrf_args : 
-      (A.meta_name A.mcode, (Ast_c.argument, Ast_c.il) either list) matcher
-    val distrf_type : 
-      (A.meta_name A.mcode, Ast_c.fullType) matcher
-    val distrf_params : 
-      (A.meta_name A.mcode,
-       (Ast_c.parameterType, Ast_c.il) either list) matcher
-    val distrf_param : 
-      (A.meta_name A.mcode, Ast_c.parameterType) matcher
-    val distrf_ini : 
-      (A.meta_name A.mcode, Ast_c.initialiser) matcher
-    val distrf_node : 
-      (A.meta_name A.mcode, Control_flow_c.node) matcher
-
-    val distrf_define_params : 
-      (A.meta_name A.mcode, (string Ast_c.wrap, Ast_c.il) either list)
-      matcher
-
-    val distrf_struct_fields : 
-      (A.meta_name A.mcode, B.field B.wrap list) matcher
-
-    val distrf_cst : 
-      (A.meta_name A.mcode, (B.constant, string) either B.wrap) matcher
-
-    val cocciExp : 
-      (A.expression, B.expression) matcher -> (A.expression, F.node) matcher
-
-    val cocciExpExp : 
-      (A.expression, B.expression) matcher ->
-       (A.expression, B.expression) matcher
-
-    val cocciTy : 
-      (A.fullType, B.fullType) matcher -> (A.fullType, F.node) matcher
-
-    val envf :
-      A.keep_binding -> A.inherited -> 
-      A.meta_name A.mcode * Ast_c.metavar_binding_kind *
-         (unit -> Common.filename * Ast_c.posl * Ast_c.posl) ->
-      (unit -> tin -> 'x tout) -> (tin -> 'x tout)
-
-    val check_constraints :
-      ('a, 'b) matcher -> 'a list -> 'b ->
-       (unit -> tin -> 'x tout) -> (tin -> 'x tout)
-
-    val all_bound : A.meta_name list -> (tin -> bool)
-
-    val optional_storage_flag : (bool -> tin -> 'x tout) -> (tin -> 'x tout)
-    val optional_qualifier_flag : (bool -> tin -> 'x tout) -> (tin -> 'x tout)
-    val value_format_flag: (bool -> tin -> 'x tout) -> (tin -> 'x tout)
-
-
-  end
-
-(*****************************************************************************)
-(* Functor code, "Cocci vs C" *)
-(*****************************************************************************)
-
-module COCCI_VS_C =
-  functor (X : PARAM) -> 
-struct
-
-type ('a, 'b) matcher = 'a -> 'b  -> X.tin -> ('a * 'b) X.tout
-
-let (>>=) = X.(>>=)
-let return = X.return
-let fail = X.fail
-
-let (>||>) = X.(>||>)
-let (>|+|>) = X.(>|+|>)
-let (>&&>) = X.(>&&>)
-
-let tokenf = X.tokenf
-
-(* should be raise Impossible when called from transformation.ml *)
-let fail2 () = 
-  match X.mode with
-  | PatternMode -> fail
-  | TransformMode -> raise Impossible
-
-
-let (option: ('a,'b) matcher -> ('a option,'b option) matcher)= fun f t1 t2 ->
-  match (t1,t2) with
-  | (Some t1, Some t2) -> 
-      f t1 t2 >>= (fun t1 t2 -> 
-        return (Some t1, Some t2)
-      )
-  | (None, None) -> return (None, None)
-  | _ -> fail
-
-(* Dots are sometimes used as metavariables, since like metavariables they
-can match other things.  But they no longer have the same type.  Perhaps these
-functions could be avoided by introducing an appropriate level of polymorphism,
-but I don't know how to declare polymorphism across functors *)
-let dots2metavar (_,info,mcodekind,pos) = (("","..."),info,mcodekind,pos)
-let metavar2dots (_,info,mcodekind,pos) = ("...",info,mcodekind,pos)
-
-(*---------------------------------------------------------------------------*)
-(* toc: 
- *  - expression
- *  - ident
- *  - arguments
- *  - parameters
- *  - declaration
- *  - initialisers
- *  - type       
- *  - node
- *)
-
-(*---------------------------------------------------------------------------*)
-let rec (expression: (A.expression, Ast_c.expression) matcher) =
- fun ea eb -> 
-  X.all_bound (A.get_inherited ea) >&&>
-  let wa x = A.rewrap ea x  in
-  match A.unwrap ea, eb with
-  
-  (* general case: a MetaExpr can match everything *)
-  | A.MetaExpr (ida,constraints,keep,opttypa,form,inherited),
-    (((expr, opttypb), ii) as expb) ->
-
-      (* old: before have a MetaConst. Now we factorize and use 'form' to 
-       * differentiate between different cases *)
-      let rec matches_id = function
-         B.Ident(c) -> true
-       | B.Cast(ty,e) -> matches_id (B.unwrap_expr e)
-       | _ -> false in
-      let form_ok =
-       match (form,expr) with
-         (A.ANY,_) -> true
-       | (A.CONST,e) ->
-           let rec matches = function
-               B.Constant(c) -> true
-              | B.Ident idb when idb =~ "^[A-Z_][A-Z_0-9]*$" -> 
-                 pr2_once ("warning: I consider " ^ idb ^ " as a constant");
-                 true
-             | B.Cast(ty,e) -> matches (B.unwrap_expr e)
-             | B.Unary(e,B.UnMinus) -> matches (B.unwrap_expr e)
-             | B.SizeOfExpr(exp) -> true
-             | B.SizeOfType(ty) -> true
-             | _ -> false in
-           matches e
-       | (A.LocalID,e) ->
-           (matches_id e) &&
-           (match !opttypb with
-             (Some (_,Ast_c.LocalVar _),_) -> true
-           | _ -> false)
-       | (A.ID,e) -> matches_id e in
-
-      if form_ok
-      then
-       (let (opttypb,_testb) = !opttypb in
-       match opttypa, opttypb with
-        | None, _ -> return ((),())
-        | Some _, None -> 
-            pr2_once ("Missing type information. Certainly a pb in " ^
-                      "annotate_typer.ml");
-            fail
-             
-        | Some tas, Some tb -> 
-            tas +> List.fold_left (fun acc ta ->  
-              acc >|+|> compatible_type ta tb) fail
-       ) >>=
-       (fun () () ->
-         X.check_constraints expression constraints eb
-            (fun () ->
-         let max_min _ =
-           Lib_parsing_c.lin_col_by_pos (Lib_parsing_c.ii_of_expr expb) in
-         X.envf keep inherited (ida, Ast_c.MetaExprVal expb, max_min)
-           (fun () -> 
-         X.distrf_e ida expb >>= (fun ida expb -> 
-            return (
-              A.MetaExpr (ida,constraints,keep,opttypa,form,inherited)+>
-                  A.rewrap ea,
-              expb
-            ))
-         )))
-      else fail
-         
-  (* old: 
-   * | A.MetaExpr(ida,false,opttypa,_inherited), expb ->
-   *   D.distribute_mck (mcodekind ida) D.distribute_mck_e expb binding
-   * 
-   * but bug! because if have not tagged SP, then transform without doing
-   * any checks. Hopefully now have tagged SP technique.
-   *)
-         
-         
-  (* old: 
-   * | A.Edots _, _ -> raise Impossible. 
-   * 
-   * In fact now can also have the Edots inside normal expression, not 
-   * just in arg lists. in 'x[...];' less: in if(<... x ... y ...>) 
-   *)
-  | A.Edots (mcode, None), expb    -> 
-      X.distrf_e (dots2metavar mcode) expb >>= (fun mcode expb -> 
-        return (
-        A.Edots (metavar2dots mcode, None) +> A.rewrap ea , 
-        expb
-          ))
-       
-       
-  | A.Edots (_, Some expr), _    -> failwith "not handling when on Edots"
-       
-       
-  | A.Ident ida,   ((B.Ident idb, typ),ii) ->
-      let ib1 = tuple_of_list1 ii in
-      ident DontKnow ida (idb, ib1) >>= (fun ida (idb, ib1) -> 
-        return (
-        ((A.Ident ida)) +> wa, 
-        ((B.Ident idb, typ),[ib1])
-          ))
-        
-       
-       
-
-  | A.MetaErr _, _ -> failwith "not handling MetaErr"
-
-  (* todo?: handle some isomorphisms in int/float ? can have different
-   * format : 1l can match a 1.
-   * 
-   * todo: normally string can contain some metavar too, so should
-   * recurse on the string 
-   *)
-  | A.Constant (ia1), ((B.Constant (ib) , typ),ii) -> 
-      (* for everything except the String case where can have multi elems *)
-      let do1 () = 
-        let ib1 = tuple_of_list1 ii in 
-        tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-          return ( 
-            ((A.Constant ia1)) +> wa, 
-            ((B.Constant (ib), typ),[ib1])
-          ))
-      in
-      (match term ia1, ib with 
-      | A.Int x, B.Int y -> 
-          X.value_format_flag (fun use_value_equivalence -> 
-            if use_value_equivalence 
-            then 
-              if equal_c_int x y
-              then do1()
-              else fail
-            else 
-              if x =$= y
-              then do1()
-            else fail
-          )
-      | A.Char x, B.Char (y,_) when x =$= y  (* todo: use kind ? *)
-          -> do1()
-      | A.Float x, B.Float (y,_) when x =$= y (* todo: use floatType ? *)
-          -> do1()
-
-      | A.String sa, B.String (sb,_kind) when sa =$= sb ->
-          (match ii with
-          | [ib1] -> 
-            tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-              return ( 
-                ((A.Constant ia1)) +> wa, 
-                ((B.Constant (ib), typ),[ib1])
-              ))
-          | _ -> fail (* multi string, not handled *)
-          )
-      | _, _ -> fail
-      )
-
-
-  | A.FunCall (ea, ia1, eas, ia2),  ((B.FunCall (eb, ebs), typ),ii) -> 
-      (* todo: do special case to allow IdMetaFunc, cos doing the
-       * recursive call will be too late, match_ident will not have the
-       * info whether it was a function. todo: but how detect when do
-       * x.field = f; how know that f is a Func ? By having computed
-       * some information before the matching!
-       * 
-       * Allow match with FunCall containing types. Now ast_cocci allow
-       * type in parameter, and morover ast_cocci allow f(...) and those
-       * ... could match type. 
-       *)
-      let (ib1, ib2) = tuple_of_list2 ii in
-      expression ea eb >>= (fun ea eb -> 
-      tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-      tokenf ia2 ib2 >>= (fun ia2 ib2 -> 
-      arguments (seqstyle eas) (A.undots eas) ebs >>= (fun easundots ebs -> 
-        let eas = redots eas easundots in
-        return (
-          ((A.FunCall (ea, ia1, eas, ia2)) +> wa,
-          ((B.FunCall (eb, ebs),typ), [ib1;ib2])
-        ))))))
-
-
-
-
-  | A.Assignment (ea1, opa, ea2, simple),
-      ((B.Assignment (eb1, opb, eb2), typ),ii) -> 
-      let (opbi) = tuple_of_list1 ii in
-      if equal_assignOp (term opa) opb 
-      then
-        expression ea1 eb1 >>= (fun ea1 eb1 -> 
-        expression ea2 eb2 >>= (fun ea2 eb2 -> 
-        tokenf opa opbi >>= (fun opa opbi -> 
-          return (
-            ((A.Assignment (ea1, opa, ea2, simple))) +> wa,
-            ((B.Assignment (eb1, opb, eb2), typ), [opbi])
-        ))))
-      else fail
-
-  | A.CondExpr(ea1,ia1,ea2opt,ia2,ea3),((B.CondExpr(eb1,eb2opt,eb3),typ),ii) ->
-      let (ib1, ib2) = tuple_of_list2 ii in
-      expression ea1 eb1 >>= (fun ea1 eb1 -> 
-      option expression ea2opt eb2opt >>= (fun  ea2opt eb2opt -> 
-      expression ea3 eb3 >>= (fun ea3 eb3 -> 
-      tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-      tokenf ia2 ib2 >>= (fun ia2 ib2 -> 
-        return (
-          ((A.CondExpr(ea1,ia1,ea2opt,ia2,ea3))) +> wa,
-          ((B.CondExpr (eb1, eb2opt, eb3),typ), [ib1;ib2])
-        ))))))
-
-  (* todo?: handle some isomorphisms here ? *)
-  | A.Postfix (ea, opa), ((B.Postfix (eb, opb), typ),ii) -> 
-      let opbi = tuple_of_list1 ii in
-      if equal_fixOp (term opa) opb
-      then
-        expression ea eb >>= (fun ea eb -> 
-        tokenf opa opbi >>= (fun opa opbi -> 
-          return (
-            ((A.Postfix (ea, opa))) +> wa,
-            ((B.Postfix (eb, opb), typ),[opbi])
-        )))
-      else fail
-        
-        
-  | A.Infix (ea, opa), ((B.Infix (eb, opb), typ),ii) -> 
-      let opbi = tuple_of_list1 ii in
-      if equal_fixOp (term opa) opb
-      then
-        expression ea eb >>= (fun ea eb -> 
-        tokenf opa opbi >>= (fun opa opbi -> 
-          return (
-            ((A.Infix (ea, opa))) +> wa,
-            ((B.Infix (eb, opb), typ),[opbi])
-        )))
-      else fail
-
-  | A.Unary (ea, opa), ((B.Unary (eb, opb), typ),ii) -> 
-      let opbi = tuple_of_list1 ii in
-      if equal_unaryOp (term opa) opb
-      then
-        expression ea eb >>= (fun ea eb -> 
-        tokenf opa opbi >>= (fun opa opbi -> 
-          return (
-            ((A.Unary (ea, opa))) +> wa,
-            ((B.Unary (eb, opb), typ),[opbi])
-        )))
-      else fail
-
-  | A.Binary (ea1, opa, ea2), ((B.Binary (eb1, opb, eb2), typ),ii) -> 
-      let opbi = tuple_of_list1 ii in
-      if equal_binaryOp (term opa) opb
-      then 
-        expression ea1 eb1 >>= (fun ea1 eb1 -> 
-        expression ea2 eb2 >>= (fun ea2 eb2 -> 
-        tokenf opa opbi >>= (fun opa opbi -> 
-          return (
-            ((A.Binary (ea1, opa, ea2))) +> wa,
-            ((B.Binary (eb1, opb, eb2), typ),[opbi]
-          )))))
-      else fail
-
-  | A.Nested (ea1, opa, ea2), eb -> 
-      let rec loop eb =
-       (if A.get_test_exp ea1 && not (Ast_c.is_test eb) then fail
-       else expression ea1 eb) >|+|>
-       (match eb with
-         ((B.Binary (eb1, opb, eb2), typ),ii)
-         when equal_binaryOp (term opa) opb ->
-           let opbi = tuple_of_list1 ii in
-           let left_to_right =
-              (expression ea1 eb1 >>= (fun ea1 eb1 -> 
-               expression ea2 eb2 >>= (fun ea2 eb2 -> 
-                 tokenf opa opbi >>= (fun opa opbi -> 
-                   return (
-                   ((A.Nested (ea1, opa, ea2))) +> wa,
-                   ((B.Binary (eb1, opb, eb2), typ),[opbi]
-                      )))))) in
-           let right_to_left =
-              (expression ea2 eb1 >>= (fun ea2 eb1 -> 
-               expression ea1 eb2 >>= (fun ea1 eb2 -> 
-                 tokenf opa opbi >>= (fun opa opbi -> 
-                   return (
-                   ((A.Nested (ea1, opa, ea2))) +> wa,
-                   ((B.Binary (eb1, opb, eb2), typ),[opbi]
-                      )))))) in
-           let in_left =
-              (loop eb1 >>= (fun ea1 eb1 -> 
-               expression ea2 eb2 >>= (fun ea2 eb2 -> 
-                 tokenf opa opbi >>= (fun opa opbi -> 
-                   return (
-                   ((A.Nested (ea1, opa, ea2))) +> wa,
-                   ((B.Binary (eb1, opb, eb2), typ),[opbi]
-                      )))))) in
-           let in_right =
-              (expression ea2 eb1 >>= (fun ea2 eb1 -> 
-               loop eb2 >>= (fun ea1 eb2 -> 
-                 tokenf opa opbi >>= (fun opa opbi -> 
-                   return (
-                   ((A.Nested (ea1, opa, ea2))) +> wa,
-                   ((B.Binary (eb1, opb, eb2), typ),[opbi]
-                      )))))) in
-           left_to_right >|+|> right_to_left >|+|> in_left >|+|> in_right
-       | _ -> fail) in
-      loop eb
-
-  (* todo?: handle some isomorphisms here ?  (with pointers = Unary Deref) *)
-  | A.ArrayAccess (ea1, ia1, ea2, ia2),((B.ArrayAccess (eb1, eb2), typ),ii) -> 
-      let (ib1, ib2) = tuple_of_list2 ii in
-      expression ea1 eb1 >>= (fun ea1 eb1 -> 
-      expression ea2 eb2 >>= (fun ea2 eb2 -> 
-      tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-      tokenf ia2 ib2 >>= (fun ia2 ib2 -> 
-        return (
-          ((A.ArrayAccess (ea1, ia1, ea2, ia2))) +> wa,
-          ((B.ArrayAccess (eb1, eb2),typ), [ib1;ib2])
-        )))))
-
-  (* todo?: handle some isomorphisms here ? *)
-  | A.RecordAccess (ea, ia1, ida), ((B.RecordAccess (eb, idb), typ),ii) ->
-      let (ib1, ib2) = tuple_of_list2 ii in
-      ident DontKnow ida (idb, ib2) >>= (fun ida (idb, ib2) -> 
-      tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-      expression ea eb >>= (fun ea eb -> 
-        return (
-          ((A.RecordAccess (ea, ia1, ida))) +> wa,
-          ((B.RecordAccess (eb, idb), typ), [ib1;ib2])
-        ))))
-
-
-
-  | A.RecordPtAccess (ea,ia1,ida),((B.RecordPtAccess (eb, idb), typ), ii) ->
-      let (ib1, ib2) = tuple_of_list2 ii in
-      ident DontKnow ida (idb, ib2) >>= (fun ida (idb, ib2) -> 
-      tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-      expression ea eb >>= (fun ea eb -> 
-        return (
-          ((A.RecordPtAccess (ea, ia1, ida))) +> wa,
-          ((B.RecordPtAccess (eb, idb), typ), [ib1;ib2])
-        ))))
-
-
-  (* todo?: handle some isomorphisms here ? 
-   * todo?: do some iso-by-absence on cast ? 
-   *    by trying | ea, B.Case (typb, eb) -> match_e_e ea eb ?
-   *)
-
-  | A.Cast (ia1, typa, ia2, ea), ((B.Cast (typb, eb), typ),ii) -> 
-      let (ib1, ib2) = tuple_of_list2 ii in
-      fullType typa typb >>= (fun typa typb -> 
-      expression ea eb >>= (fun ea eb -> 
-      tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-      tokenf ia2 ib2 >>= (fun ia2 ib2 -> 
-        return (
-          ((A.Cast (ia1, typa, ia2, ea))) +> wa,
-          ((B.Cast (typb, eb),typ),[ib1;ib2])
-        )))))
-
-  | A.SizeOfExpr (ia1, ea), ((B.SizeOfExpr (eb), typ),ii) -> 
-      let ib1 = tuple_of_list1 ii in
-      expression ea eb >>= (fun ea eb -> 
-      tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-        return (
-          ((A.SizeOfExpr (ia1, ea))) +> wa,
-          ((B.SizeOfExpr (eb), typ),[ib1])
-      )))
-
-  | A.SizeOfType (ia1, ia2, typa, ia3), ((B.SizeOfType typb, typ),ii) -> 
-      let (ib1,ib2,ib3) = tuple_of_list3 ii in
-      fullType typa typb >>= (fun typa typb -> 
-      tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-      tokenf ia2 ib2 >>= (fun ia2 ib2 -> 
-      tokenf ia3 ib3 >>= (fun ia3 ib3 -> 
-        return (
-          ((A.SizeOfType (ia1, ia2, typa, ia3))) +> wa,
-          ((B.SizeOfType (typb),typ),[ib1;ib2;ib3])
-      )))))
-
-
-  (* todo? iso ? allow all the combinations ? *)
-  | A.Paren (ia1, ea, ia2), ((B.ParenExpr (eb), typ),ii) -> 
-      let (ib1, ib2) = tuple_of_list2 ii in
-      expression ea eb >>= (fun ea eb -> 
-      tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-      tokenf ia2 ib2 >>= (fun ia2 ib2 -> 
-        return (
-          ((A.Paren (ia1, ea, ia2))) +> wa,
-          ((B.ParenExpr (eb), typ), [ib1;ib2])
-      ))))
-
-  | A.NestExpr(exps,None,true), eb ->
-      (match A.unwrap exps with
-       A.DOTS [exp] ->
-         X.cocciExpExp expression exp eb >>= (fun exp eb -> 
-            return (
-            (A.NestExpr(A.rewrap exps (A.DOTS [exp]),None,true)) +> wa,
-            eb
-            )
-         )
-      |        _ ->
-         failwith
-           "for nestexpr, only handling the case with dots and only one exp")
-
-  | A.NestExpr _, _ ->
-      failwith "only handling multi and no when code in a nest expr"
-
-  (* only in arg lists or in define body *)  
-  | A.TypeExp _, _ -> fail
-
-  (* only in arg lists *)
-  | A.MetaExprList _, _   
-  | A.EComma _, _  
-  | A.Ecircles _, _ 
-  | A.Estars _, _   
-      ->
-       raise Impossible
-
-  | A.DisjExpr eas, eb -> 
-      eas +> List.fold_left (fun acc ea -> acc >|+|> (expression ea eb)) fail
-
-  | A.UniqueExp _,_ | A.OptExp _,_ -> 
-      failwith "not handling Opt/Unique/Multi on expr"
-
- (* Because of Exp cant put a raise Impossible; have to put a fail *)
-
- (* have not a counter part in coccinelle, for the moment *) 
-  | _, ((B.Sequence _,_),_) 
-  | _, ((B.StatementExpr _,_),_) 
-  | _, ((B.Constructor _,_),_) 
-    -> fail
-
-  | _, _ -> fail
-
-
-
-(* ------------------------------------------------------------------------- *)
-and (ident: info_ident -> (A.ident, string * Ast_c.info) matcher) = 
- fun infoidb ida ((idb, iib) as ib) -> 
-  X.all_bound (A.get_inherited ida) >&&>
-  match A.unwrap ida with
-  | A.Id sa -> 
-      if (term sa) =$= idb then
-      tokenf sa iib >>= (fun sa iib -> 
-        return (
-          ((A.Id sa)) +> A.rewrap ida,
-          (idb, iib)
-        ))
-      else fail
-
-
-  | A.MetaId(mida,constraints,keep,inherited) -> 
-      X.check_constraints (ident infoidb) constraints ib
-        (fun () ->
-      let max_min _ = Lib_parsing_c.lin_col_by_pos [iib] in
-      (* use drop_pos for ids so that the pos is not added a second time in
-        the call to tokenf *)
-      X.envf keep inherited (A.drop_pos mida, Ast_c.MetaIdVal (idb), max_min)
-       (fun () -> 
-        tokenf mida iib >>= (fun mida iib -> 
-          return (
-            ((A.MetaId (mida, constraints, keep, inherited)) +> A.rewrap ida,
-            (idb, iib)
-            )))
-      ))
-
-  | A.MetaFunc(mida,constraints,keep,inherited) -> 
-      let is_function _ =
-       X.check_constraints (ident infoidb) constraints ib
-            (fun () ->
-          let max_min _ = Lib_parsing_c.lin_col_by_pos [iib] in
-          X.envf keep inherited (A.drop_pos mida,Ast_c.MetaFuncVal idb,max_min)
-           (fun () ->
-            tokenf mida iib >>= (fun mida iib -> 
-              return (
-                ((A.MetaFunc(mida,constraints,keep,inherited)))+>A.rewrap ida,
-                (idb, iib)
-              ))
-          )) in
-      (match infoidb with 
-      | LocalFunction | Function -> is_function()
-      | DontKnow ->
-         failwith "MetaFunc, need more semantic info about id"
-         (* the following implementation could possibly be useful, if one
-            follows the convention that a macro is always in capital letters
-            and that a macro is not a function.
-         (if idb =~ "^[A-Z_][A-Z_0-9]*$" then fail else is_function())*)
-      )
-
-  | A.MetaLocalFunc(mida,constraints,keep,inherited) -> 
-      (match infoidb with 
-      | LocalFunction -> 
-         X.check_constraints (ident infoidb) constraints ib
-            (fun () ->
-          let max_min _ = Lib_parsing_c.lin_col_by_pos [iib] in
-          X.envf keep inherited
-           (A.drop_pos mida,Ast_c.MetaLocalFuncVal idb, max_min)
-           (fun () ->
-            tokenf mida iib >>= (fun mida iib -> 
-              return (
-                ((A.MetaLocalFunc(mida,constraints,keep,inherited)))
-                  +> A.rewrap ida,
-                (idb, iib)
-              ))
-          ))
-      | Function -> fail
-      | DontKnow -> failwith "MetaLocalFunc, need more semantic info about id"
-      )
-
-  | A.OptIdent _ | A.UniqueIdent _ -> 
-      failwith "not handling Opt/Unique for ident"
-
-
-
-(* ------------------------------------------------------------------------- *)
-and (arguments: sequence -> 
-      (A.expression list, Ast_c.argument Ast_c.wrap2 list) matcher) = 
- fun seqstyle eas ebs ->
-  match seqstyle with
-  | Unordered -> failwith "not handling ooo"
-  | Ordered -> 
-      arguments_bis eas (Ast_c.split_comma ebs) >>= (fun eas ebs_splitted -> 
-        return (eas, (Ast_c.unsplit_comma ebs_splitted))
-      )
-(* because '...' can match nothing, need to take care when have 
- * ', ...'   or '...,'  as in  f(..., X, Y, ...). It must match
- * f(1,2) for instance.
- * So I have added special cases such as (if startxs = []) and code
- * in the Ecomma matching rule.
- * 
- * old: Must do some try, for instance when f(...,X,Y,...) have to
- * test the transfo for all the combinaitions    and if multiple transfo
- * possible ? pb ? => the type is to return a expression option ? use
- * some combinators to help ?
- * update: with the tag-SP approach, no more a problem.
- *)
-
-and arguments_bis = fun eas ebs -> 
-  match eas, ebs with
-  | [], [] -> return ([], [])
-  | [], eb::ebs -> fail
-  | ea::eas, ebs -> 
-      X.all_bound (A.get_inherited ea) >&&>
-      (match A.unwrap ea, ebs with
-      | A.Edots (mcode, optexpr), ys -> 
-          (* todo: if optexpr, then a WHEN and so may have to filter yys *)
-          if optexpr <> None then failwith "not handling when in argument";
-
-          (* '...' can take more or less the beginnings of the arguments *)
-          let startendxs = Common.zip (Common.inits ys) (Common.tails ys) in
-          startendxs +> List.fold_left (fun acc (startxs, endxs) -> 
-            acc >||> (
-
-              (* allow '...', and maybe its associated ',' to match nothing.
-               * for the associated ',' see below how we handle the EComma
-               * to match nothing.
-               *)
-              (if startxs = []
-              then
-                if mcode_contain_plus (mcodekind mcode)
-                then fail 
-                  (* failwith "I have no token that I could accroche myself on" *)
-                else return (dots2metavar mcode, [])
-              else 
-                (* subtil: we dont want the '...' to match until the
-                 * comma. cf -test pb_params_iso. We would get at
-                 * "already tagged" error.
-                 * this is because both f (... x, ...) and f (..., x, ...)
-                 * would match a  f(x,3)  with our "optional-comma" strategy.
-                 *)
-                  (match Common.last startxs with
-                  | Right _ -> fail
-                  | Left _ -> 
-                      X.distrf_args (dots2metavar mcode) startxs
-                  )
-              )
-              >>= (fun mcode startxs ->
-               let mcode = metavar2dots mcode in
-                arguments_bis eas endxs >>= (fun eas endxs -> 
-                  return (
-                    (A.Edots (mcode, optexpr) +> A.rewrap ea) ::eas,
-                    startxs ++ endxs
-                  )))
-            )
-          ) fail 
-
-      | A.EComma ia1, Right ii::ebs -> 
-          let ib1 = tuple_of_list1 ii in
-          tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-            arguments_bis eas ebs >>= (fun eas ebs -> 
-              return (
-                (A.EComma ia1 +> A.rewrap ea)::eas,
-                (Right [ib1])::ebs
-              )
-            ))
-      | A.EComma ia1, ebs -> 
-          (* allow ',' to maching nothing. optional comma trick *)
-          if mcode_contain_plus (mcodekind ia1)
-          then fail
-          else arguments_bis eas ebs
-
-      | A.MetaExprList(ida,leninfo,keep,inherited),ys ->
-          let startendxs = Common.zip (Common.inits ys) (Common.tails ys) in
-          startendxs +> List.fold_left (fun acc (startxs, endxs) -> 
-            acc >||> (
-              let ok =
-                if startxs = []
-                then
-                  if mcode_contain_plus (mcodekind ida)
-                  then false 
-                    (* failwith "no token that I could accroche myself on" *)
-                  else true
-                else 
-                  (match Common.last startxs with
-                  | Right _ -> false
-                  | Left _ -> true
-                  )
-              in
-              if not ok
-              then fail
-              else 
-                let startxs' = Ast_c.unsplit_comma startxs in
-                let len = List.length  startxs' in
-
-               (match leninfo with
-               | Some (lenname,lenkeep,leninherited) ->
-                   let max_min _ = failwith "no pos" in
-                    X.envf lenkeep leninherited
-                      (lenname, Ast_c.MetaListlenVal (len), max_min)
-               | None -> function f -> f()
-                )
-                (fun () -> 
-                 let max_min _ =
-                   Lib_parsing_c.lin_col_by_pos
-                     (Lib_parsing_c.ii_of_args startxs) in
-                  X.envf keep inherited
-                    (ida, Ast_c.MetaExprListVal startxs', max_min)
-                (fun () -> 
-                 if startxs = []
-                 then return (ida, [])
-                  else X.distrf_args ida (Ast_c.split_comma startxs')
-                )
-                >>= (fun ida startxs -> 
-                  arguments_bis eas endxs >>= (fun eas endxs -> 
-                    return (
-                      (A.MetaExprList(ida,leninfo,keep,inherited))
-                     +> A.rewrap ea::eas,
-                      startxs ++ endxs
-                    ))
-                  )
-                )
-            )) fail 
-
-
-      | _unwrapx, (Left eb)::ebs -> 
-          argument ea eb >>= (fun ea eb -> 
-          arguments_bis eas ebs >>= (fun eas ebs -> 
-            return (ea::eas, Left eb::ebs)
-          ))
-      | _unwrapx, (Right y)::ys -> raise Impossible
-      | _unwrapx, [] -> fail
-      )
-            
-      
-and argument arga argb = 
-  X.all_bound (A.get_inherited arga) >&&>
-   match A.unwrap arga, argb with
-  | A.TypeExp tya,  Right (B.ArgType (((b, sopt, tyb), ii_b_s))) ->
-
-      if b || sopt <> None
-      then 
-        (* failwith "the argument have a storage and ast_cocci does not have"*)
-        fail
-      else 
-        fullType tya tyb >>= (fun tya tyb -> 
-          return (
-            (A.TypeExp tya) +> A.rewrap arga,
-            (Right (B.ArgType (((b, sopt, tyb), ii_b_s))))
-        ))
-
-  | A.TypeExp tya,  _                                  -> fail
-  | _,              Right (B.ArgType (tyb, sto_iisto)) -> fail
-  | _, Left argb -> 
-      expression arga argb >>= (fun arga argb -> 
-        return (arga, Left argb)
-      )
-  | _, Right (B.ArgAction y) -> fail
-
-
-(* ------------------------------------------------------------------------- *)
-(* todo? facto code with argument ? *)
-and (parameters: sequence -> 
-      (A.parameterTypeDef list, Ast_c.parameterType Ast_c.wrap2 list)
-        matcher) = 
- fun seqstyle eas ebs ->
-  match seqstyle with
-  | Unordered -> failwith "not handling ooo"
-  | Ordered -> 
-      parameters_bis eas (Ast_c.split_comma ebs) >>= (fun eas ebs_splitted -> 
-        return (eas, (Ast_c.unsplit_comma ebs_splitted))
-      )
-
-
-and parameters_bis eas ebs = 
-  match eas, ebs with
-  | [], [] -> return ([], [])
-  | [], eb::ebs -> fail
-  | ea::eas, ebs ->
-      (* the management of positions is inlined into each case, because
-        sometimes there is a Param and sometimes a ParamList *)
-      X.all_bound (A.get_inherited ea) >&&>
-      (match A.unwrap ea, ebs with
-      | A.Pdots (mcode), ys -> 
-
-          (* '...' can take more or less the beginnings of the arguments *)
-          let startendxs = Common.zip (Common.inits ys) (Common.tails ys) in
-          startendxs +> List.fold_left (fun acc (startxs, endxs) -> 
-            acc >||> (
-
-              (if startxs = []
-              then
-                if mcode_contain_plus (mcodekind mcode)
-                then fail 
-                (* failwith "I have no token that I could accroche myself on"*)
-                else return (dots2metavar mcode, [])
-              else 
-                (match Common.last startxs with
-                | Right _ -> fail
-                | Left _ -> 
-                    X.distrf_params (dots2metavar mcode) startxs
-                )
-              ) >>= (fun mcode startxs ->
-               let mcode = metavar2dots mcode in
-                parameters_bis eas endxs >>= (fun eas endxs -> 
-                  return (
-                    (A.Pdots (mcode) +> A.rewrap ea) ::eas,
-                    startxs ++ endxs
-                  )))
-            )
-          ) fail 
-
-      | A.PComma ia1, Right ii::ebs -> 
-          let ib1 = tuple_of_list1 ii in
-          tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-          parameters_bis eas ebs >>= (fun eas ebs -> 
-            return (
-              (A.PComma ia1 +> A.rewrap ea)::eas,
-              (Right [ib1])::ebs
-            )
-          ))
-
-      | A.PComma ia1, ebs -> 
-          (* try optional comma trick *)
-          if mcode_contain_plus (mcodekind ia1)
-          then fail
-          else parameters_bis eas ebs
-
-
-      | A.MetaParamList(ida,leninfo,keep,inherited),ys->
-          let startendxs = Common.zip (Common.inits ys) (Common.tails ys) in
-          startendxs +> List.fold_left (fun acc (startxs, endxs) -> 
-            acc >||> (
-              let ok =
-                if startxs = []
-                then
-                  if mcode_contain_plus (mcodekind ida)
-                  then false 
-               (* failwith "I have no token that I could accroche myself on" *)
-                  else true
-                else 
-                  (match Common.last startxs with
-                  | Right _ -> false
-                  | Left _ -> true
-                  )
-              in
-              if not ok
-              then fail
-              else 
-                let startxs' = Ast_c.unsplit_comma startxs in
-                let len = List.length  startxs' in
-
-               (match leninfo with
-                 Some (lenname,lenkeep,leninherited) ->
-                   let max_min _ = failwith "no pos" in
-                    X.envf lenkeep leninherited
-                     (lenname, Ast_c.MetaListlenVal (len), max_min)
-               | None -> function f -> f()
-                )
-               (fun () ->
-                 let max_min _ =
-                   Lib_parsing_c.lin_col_by_pos
-                     (Lib_parsing_c.ii_of_params startxs) in
-                  X.envf keep inherited 
-                    (ida, Ast_c.MetaParamListVal startxs', max_min)
-                (fun () -> 
-                 if startxs = []
-                 then return (ida, [])
-                 else X.distrf_params ida (Ast_c.split_comma startxs')
-               ) >>= (fun ida startxs -> 
-                  parameters_bis eas endxs >>= (fun eas endxs -> 
-                    return (
-                      (A.MetaParamList(ida,leninfo,keep,inherited))
-                        +> A.rewrap ea::eas,
-                      startxs ++ endxs
-                   ))
-                )
-                ))
-          ) fail 
-
-
-      | A.VoidParam ta, ys -> 
-          (match eas, ebs with
-          | [], [Left eb] -> 
-              let ((hasreg, idbopt, tb), ii_b_s) = eb in
-              if idbopt = None && null ii_b_s 
-              then 
-                match tb with 
-                | (qub, (B.BaseType B.Void,_)) -> 
-                    fullType ta tb >>= (fun ta tb -> 
-                      return (
-                        [(A.VoidParam ta) +> A.rewrap ea],
-                        [Left ((hasreg, idbopt, tb), ii_b_s)]
-                      ))
-                | _ -> fail
-              else fail
-          | _ -> fail
-          )
-
-      | (A.OptParam _ | A.UniqueParam _), _ -> 
-              failwith "handling Opt/Unique for Param"
-
-      | A.Pcircles (_), ys -> raise Impossible (* in Ordered mode *)
-
-
-      | A.MetaParam (ida,keep,inherited), (Left eb)::ebs -> 
-          (* todo: use quaopt, hasreg ? *)
-         let max_min _ =
-           Lib_parsing_c.lin_col_by_pos (Lib_parsing_c.ii_of_param eb) in
-          X.envf keep inherited (ida,Ast_c.MetaParamVal eb,max_min) (fun () -> 
-            X.distrf_param ida eb
-          ) >>= (fun ida eb -> 
-              parameters_bis eas ebs >>= (fun eas ebs -> 
-                return (
-                  (A.MetaParam(ida,keep,inherited))+> A.rewrap ea::eas,
-                  (Left eb)::ebs
-                )))
-
-
-      | A.Param (typa, idaopt), (Left eb)::ebs -> 
-         (*this should succeed if the C code has a name, and fail otherwise*)
-          parameter (idaopt, typa) eb >>= (fun (idaopt, typa) eb -> 
-          parameters_bis eas ebs >>= (fun eas ebs -> 
-            return (
-              (A.Param (typa, idaopt))+> A.rewrap ea :: eas,
-              (Left eb)::ebs
-            )))
-          
-      | _unwrapx, (Right y)::ys -> raise Impossible
-      | _unwrapx, [] -> fail
-      )
-  
-
-
-
-
-and parameter = fun (idaopt, typa)   ((hasreg, idbopt, typb), ii_b_s) ->
-  fullType typa typb >>= (fun typa typb -> 
-  match idaopt, Ast_c.split_register_param (hasreg, idbopt, ii_b_s) with
-  | Some ida, Left (idb, iihasreg, iidb) -> 
-      (* todo: if minus on ida, should also minus the iihasreg ? *)
-      ident DontKnow ida (idb,iidb) >>= (fun ida (idb,iidb) -> 
-        return (
-          (Some ida, typa),
-          ((hasreg, Some idb, typb), iihasreg++[iidb])
-        ))
-        
-  | None, Right iihasreg -> 
-      return (
-        (None, typa),
-        ((hasreg, None, typb), iihasreg)
-      )
-      
-
-  (* why handle this case ? because of transform_proto ? we may not
-   * have an ident in the proto.
-   * If have some plus on ida ? do nothing about ida ? 
-   *)
- (* not anymore !!! now that julia is handling the proto.
-  | _, Right iihasreg -> 
-      return (
-        (idaopt, typa),
-        ((hasreg, None, typb), iihasreg)
-      )
- *)
-
-  | Some _, Right _ -> fail
-  | None, Left _ -> fail
-  )
-
-
-
-
-(* ------------------------------------------------------------------------- *)
-and (declaration: (A.mcodekind * bool * A.declaration,B.declaration) matcher) =
- fun (mckstart, allminus, decla) declb -> 
-  X.all_bound (A.get_inherited decla) >&&>
-  match A.unwrap decla, declb with
-
-  (* Un MetaDecl est introduit dans l'asttoctl pour sauter au dessus
-   * de toutes les declarations qui sont au debut d'un fonction et
-   * commencer le reste du match au premier statement. Alors, ca matche
-   * n'importe quelle declaration. On n'a pas besoin d'ajouter
-   * quoi que ce soit dans l'environnement. C'est une sorte de DDots.
-   * 
-   * When the SP want to remove the whole function, the minus is not
-   * on the MetaDecl but on the MetaRuleElem. So there should
-   * be no transform of MetaDecl, just matching are allowed.
-   *)
-
-  | A.MetaDecl(ida,_keep,_inherited), _ -> (* keep ? inherited ? *)
-      (* todo: should not happen in transform mode *)
-      return ((mckstart, allminus, decla), declb)
-
-
-
-  | _, (B.DeclList ([var], iiptvirgb::iifakestart::iisto)) -> 
-      onedecl allminus decla (var,iiptvirgb,iisto) >>=
-      (fun decla (var,iiptvirgb,iisto)->
-        X.tokenf_mck mckstart iifakestart >>= (fun mckstart iifakestart -> 
-          return (
-            (mckstart, allminus, decla),
-            (B.DeclList ([var], iiptvirgb::iifakestart::iisto))
-          )))
-        
-  | _, (B.DeclList (xs, iiptvirgb::iifakestart::iisto)) -> 
-      if X.mode = PatternMode
-      then
-        xs +> List.fold_left (fun acc var -> 
-          acc >||> (
-            X.tokenf_mck mckstart iifakestart >>= (fun mckstart iifakestart ->
-              onedecl allminus decla (var, iiptvirgb, iisto) >>= 
-                (fun decla (var, iiptvirgb, iisto) -> 
-                  return (
-                    (mckstart, allminus, decla),
-                    (B.DeclList ([var], iiptvirgb::iifakestart::iisto))
-                  )))))
-          fail
-      else 
-        failwith "More that one variable in decl. Have to split to transform."
-
-  | A.MacroDecl (sa,lpa,eas,rpa,enda), B.MacroDecl ((sb,ebs),ii) ->
-      let (iisb, lpb, rpb, iiendb, iifakestart, iistob) = 
-        (match ii with
-        | iisb::lpb::rpb::iiendb::iifakestart::iisto -> 
-            (iisb,lpb,rpb,iiendb, iifakestart,iisto)
-        | _ -> raise Impossible
-        ) in
-      (if allminus 
-      then minusize_list iistob
-      else return ((), iistob)
-      ) >>= (fun () iistob ->
-
-        X.tokenf_mck mckstart iifakestart >>= (fun mckstart iifakestart -> 
-       ident DontKnow sa (sb, iisb) >>= (fun sa (sb, iisb) ->
-        tokenf lpa lpb >>= (fun lpa lpb -> 
-        tokenf rpa rpb >>= (fun rpa rpb -> 
-        tokenf enda iiendb >>= (fun enda iiendb -> 
-        arguments (seqstyle eas) (A.undots eas) ebs >>= (fun easundots ebs -> 
-        let eas = redots eas easundots in
-
-          return (
-            (mckstart, allminus, 
-            (A.MacroDecl (sa,lpa,eas,rpa,enda)) +> A.rewrap decla), 
-            (B.MacroDecl ((sb,ebs),
-                         [iisb;lpb;rpb;iiendb;iifakestart] ++ iistob))
-          ))))))))
-  
-  | _ -> fail
-
-
-
-and onedecl = fun allminus decla (declb, iiptvirgb, iistob) -> 
- X.all_bound (A.get_inherited decla) >&&>
- match A.unwrap decla, declb with
-
- (* kind of typedef iso, we must unfold, it's for the case 
-  * T { }; that we want to match against typedef struct { } xx_t;
-  *)
- | A.TyDecl (tya0, ptvirga), 
-   ((Some ((idb, None),[iidb]), typb0, (B.StoTypedef, inl), local), iivirg) ->
-
-   (match A.unwrap tya0, typb0 with
-   | A.Type(cv1,tya1), ((qu,il),typb1) ->
-
-     (match A.unwrap tya1, typb1 with
-     | A.StructUnionDef(tya2, lba, declsa, rba), 
-      (B.StructUnion (sub, sbopt, declsb), ii) -> 
-
-       let (iisub, iisbopt, lbb, rbb) = 
-         match sbopt with
-         | None -> 
-             let (iisub, lbb, rbb) = tuple_of_list3 ii in
-             (iisub, [], lbb, rbb)
-         | Some s -> 
-             pr2 (sprintf 
-              "warning: both a typedef (%s) and struct name introduction (%s)"
-              idb s
-             );
-             pr2 "warning: I will consider only the typedef";
-             let (iisub, iisb, lbb, rbb) = tuple_of_list4 ii in
-             (iisub, [iisb], lbb, rbb)
-       in
-       let structnameb = 
-         structdef_to_struct_name
-           (Ast_c.nQ, (B.StructUnion (sub, sbopt, declsb), ii))
-       in
-       let fake_typeb = 
-         Ast_c.nQ,((B.TypeName (idb, Some 
-           (Lib_parsing_c.al_type structnameb))), [iidb]) 
-       in
-
-       tokenf ptvirga iiptvirgb >>= (fun ptvirga iiptvirgb -> 
-       tokenf lba lbb >>= (fun lba lbb -> 
-       tokenf rba rbb >>= (fun rba rbb -> 
-       struct_fields (A.undots declsa) declsb >>=(fun undeclsa declsb ->
-         let declsa = redots declsa undeclsa in
-
-         (match A.unwrap tya2 with
-         | A.Type(cv3, tya3) -> 
-           (match A.unwrap tya3 with
-           | A.MetaType(ida,keep, inherited) -> 
-
-               fullType tya2 fake_typeb >>= (fun tya2 fake_typeb -> 
-                let tya1 =
-                  A.StructUnionDef(tya2,lba,declsa,rba)+> A.rewrap tya1 in
-                let tya0 = A.Type(cv1, tya1) +> A.rewrap tya0 in
-               
-                   
-                let typb1 = B.StructUnion (sub,sbopt, declsb),
-                   [iisub] @ iisbopt @ [lbb;rbb] in
-                let typb0 = ((qu, il), typb1) in
-               
-                match fake_typeb with 
-                | _nQ, ((B.TypeName (idb,_typ)), [iidb]) -> 
-
-                     return (
-                     (A.TyDecl (tya0, ptvirga)) +> A.rewrap decla,
-                     (((Some ((idb, None),[iidb]), typb0, (B.StoTypedef, inl),
-                       local),
-                       iivirg),iiptvirgb,iistob)
-                     )
-                | _ -> raise Impossible    
-             )
-
-           | A.StructUnionName(sua, sa) -> 
-
-             fullType tya2 structnameb >>= (fun tya2 structnameb -> 
-
-               let tya1 = A.StructUnionDef(tya2,lba,declsa,rba)+> A.rewrap tya1
-               in
-               let tya0 = A.Type(cv1, tya1) +> A.rewrap tya0 in
-
-               match structnameb with 
-               | _nQ, (B.StructUnionName (sub, s), [iisub;iisbopt]) ->
-
-                   let typb1 = B.StructUnion (sub,sbopt, declsb),
-                     [iisub;iisbopt;lbb;rbb] in
-                   let typb0 = ((qu, il), typb1) in
-               
-                   return (
-                     (A.TyDecl (tya0, ptvirga)) +> A.rewrap decla,
-                     (((Some ((idb, None),[iidb]), typb0,
-                       (B.StoTypedef, inl), local),
-                      iivirg),iiptvirgb,iistob)
-                   )
-               | _ -> raise Impossible    
-             )
-           | _ -> raise Impossible
-           )
-         | _ -> fail
-       )))))
-     | _ -> fail
-     )
-   | _ -> fail
-   )
-         
-   | A.UnInit (stoa, typa, ida, ptvirga), 
-     ((Some ((idb, _),[iidb]), typb, (B.StoTypedef,_), _local), iivirg) -> 
-       fail
-
-   | A.Init (stoa, typa, ida, eqa, inia, ptvirga), 
-     ((Some ((idb, _),[iidb]), typb, (B.StoTypedef,_), _local), iivirg) -> 
-       fail
-
-
-
-    (* could handle iso here but handled in standard.iso *)
-   | A.UnInit (stoa, typa, ida, ptvirga), 
-     ((Some ((idb, None),[iidb]), typb, stob, local), iivirg) -> 
-       tokenf ptvirga iiptvirgb >>= (fun ptvirga iiptvirgb -> 
-       fullType typa typb >>= (fun typa typb -> 
-       ident DontKnow ida (idb, iidb) >>= (fun ida (idb, iidb) -> 
-       storage_optional_allminus allminus stoa (stob, iistob) >>= 
-        (fun stoa (stob, iistob) -> 
-         return (
-           (A.UnInit (stoa, typa, ida, ptvirga)) +>  A.rewrap decla,
-           (((Some ((idb,None),[iidb]),typb,stob,local),iivirg),
-           iiptvirgb,iistob)
-         )))))
-
-   | A.Init (stoa, typa, ida, eqa, inia, ptvirga), 
-     ((Some((idb,Some inib),[iidb;iieqb]),typb,stob,local),iivirg)
-       ->
-       tokenf ptvirga iiptvirgb >>= (fun ptvirga iiptvirgb -> 
-       tokenf eqa iieqb >>= (fun eqa iieqb -> 
-       fullType typa typb >>= (fun typa typb -> 
-       ident DontKnow ida (idb, iidb) >>= (fun ida (idb, iidb) -> 
-       storage_optional_allminus allminus stoa (stob, iistob) >>= 
-       (fun stoa (stob, iistob) -> 
-       initialiser inia inib >>= (fun inia inib -> 
-         return (
-           (A.Init (stoa, typa, ida, eqa, inia, ptvirga)) +> A.rewrap decla,
-           (((Some((idb,Some inib),[iidb;iieqb]),typb,stob,local),iivirg),
-           iiptvirgb,iistob)
-         )))))))
-           
-   (* do iso-by-absence here ? allow typedecl and var ? *)
-   | A.TyDecl (typa, ptvirga), ((None, typb, stob, local), iivirg)  ->
-       if stob = (B.NoSto, false)
-       then
-         tokenf ptvirga iiptvirgb >>= (fun ptvirga iiptvirgb -> 
-         fullType typa typb >>= (fun typa typb -> 
-           return (
-             (A.TyDecl (typa, ptvirga)) +> A.rewrap decla,
-             (((None, typb, stob, local), iivirg), iiptvirgb, iistob)
-           )))
-       else fail
-
-
-   | A.Typedef (stoa, typa, ida, ptvirga), 
-     ((Some ((idb, None),[iidb]),typb,(B.StoTypedef,inline),local),iivirg) ->
-
-       tokenf ptvirga iiptvirgb >>= (fun ptvirga iiptvirgb -> 
-       fullType typa typb >>= (fun typa typb -> 
-       (match iistob with
-       | [iitypedef] -> 
-           tokenf stoa iitypedef >>= (fun stoa iitypedef -> 
-             return (stoa, [iitypedef])
-           )
-       | _ -> failwith "wierd, have both typedef and inline or nothing";
-       ) >>= (fun stoa iistob -> 
-       (match A.unwrap ida with
-       | A.MetaType(_,_,_) -> 
-
-           let fake_typeb = 
-             Ast_c.nQ, ((B.TypeName (idb, Ast_c.noTypedefDef())), [iidb]) 
-           in
-           fullTypebis ida fake_typeb >>= (fun ida fake_typeb -> 
-             match fake_typeb with
-             | _nQ, ((B.TypeName (idb,_typ)), [iidb]) -> 
-                 return (ida, (idb, iidb))
-             | _ -> raise Impossible
-           )
-
-       | A.TypeName sa -> 
-           if (term sa) =$= idb
-           then 
-             tokenf sa iidb >>= (fun sa iidb -> 
-               return (
-                 (A.TypeName sa) +> A.rewrap ida,
-                 (idb, iidb)
-               ))
-             else fail
-       | _ -> raise Impossible
-
-       ) >>= (fun ida (idb, iidb) ->
-         return (
-           (A.Typedef (stoa, typa, ida, ptvirga)) +> A.rewrap decla,
-           (((Some ((idb, None),[iidb]), typb, (B.StoTypedef,inline),local),
-            iivirg),
-            iiptvirgb, iistob)
-         )
-       ))))
-             
-       
-   | _, ((None, typb, sto, _local), _) -> 
-       (* old:   failwith "no variable in this declaration, wierd" *)
-       fail
-
-
-
-  | A.DisjDecl declas, declb -> 
-      declas +> List.fold_left (fun acc decla -> 
-        acc >|+|> 
-            (* (declaration (mckstart, allminus, decla) declb) *)
-            (onedecl allminus decla (declb,iiptvirgb, iistob))
-      ) fail
-
-
-     
-   (* only in struct type decls *)
-   | A.Ddots(dots,whencode), _ ->
-       raise Impossible
-            
-   | A.OptDecl _, _ | A.UniqueDecl _, _ -> 
-       failwith "not handling Opt/Unique Decl"
-
-
-   | _, _ -> fail
-
-
-
-(* ------------------------------------------------------------------------- *)
-
-and (initialiser: (A.initialiser, Ast_c.initialiser) matcher) =  fun ia ib -> 
-    X.all_bound (A.get_inherited ia) >&&>
-    match (A.unwrap ia,ib) with
-
-    | (A.InitExpr expa, ib) -> 
-        (match A.unwrap expa, ib with
-        | A.Edots (mcode, None), ib    -> 
-            X.distrf_ini (dots2metavar mcode) ib >>= (fun mcode ib -> 
-              return (
-                A.InitExpr 
-                  (A.Edots (metavar2dots mcode, None) +> A.rewrap expa) 
-                    +>  A.rewrap ia,
-                ib
-               ))
-
-        | A.Edots (_, Some expr), _    -> failwith "not handling when on Edots"
-
-        | _, (B.InitExpr expb, ii) -> 
-            assert (null ii);
-            expression expa expb >>= (fun expa expb -> 
-              return (
-                (A.InitExpr expa) +> A.rewrap ia,
-                (B.InitExpr expb, ii)
-              ))
-        | _ -> fail
-        )
-
-    | (A.InitList (ia1, ias, ia2, []), (B.InitList ibs, ii)) -> 
-        (match ii with 
-        | ib1::ib2::iicommaopt -> 
-            tokenf ia1 ib1 >>= (fun ia1 ib1 ->
-            tokenf ia2 ib2 >>= (fun ia2 ib2 ->
-            initialisers ias (ibs, iicommaopt) >>= (fun ias (ibs,iicommaopt) ->
-              return (
-                (A.InitList (ia1, ias, ia2, [])) +> A.rewrap ia,
-                (B.InitList ibs, ib1::ib2::iicommaopt)
-              ))))
-              
-        | _ -> raise Impossible
-        )
-
-    | (A.InitList (i1, ias, i2, whencode),(B.InitList ibs, _ii)) ->
-        failwith "TODO: not handling whencode in initialisers"
-
-
-    | (A.InitGccDotName (ia1, ida, ia2, inia), 
-      (B.InitDesignators ([B.DesignatorField idb,ii1], inib), ii2))->
-
-        let (iidot, iidb) = tuple_of_list2 ii1 in
-        let iieq = tuple_of_list1 ii2 in
-
-        tokenf ia1 iidot >>= (fun ia1 iidot -> 
-        tokenf ia2 iieq >>= (fun ia2 iieq -> 
-        ident DontKnow ida (idb, iidb) >>= (fun ida (idb, iidb) -> 
-        initialiser inia inib >>= (fun inia inib -> 
-          return (
-            (A.InitGccDotName (ia1, ida, ia2, inia)) +> A.rewrap ia,
-            (B.InitDesignators 
-                ([B.DesignatorField idb, [iidot;iidb]], inib), [iieq])
-          )))))
-
-
-    | (A.InitGccIndex (ia1,ea,ia2,ia3,inia), 
-      (B.InitDesignators ([B.DesignatorIndex eb, ii1], inib), ii2)) -> 
-        
-        let (ib1, ib2) = tuple_of_list2 ii1 in
-        let ib3 = tuple_of_list1 ii2 in
-        tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-        tokenf ia2 ib2 >>= (fun ia2 ib2 -> 
-        tokenf ia3 ib3 >>= (fun ia3 ib3 -> 
-        expression ea eb >>= (fun ea eb -> 
-        initialiser inia inib >>= (fun inia inib -> 
-          return (
-            (A.InitGccIndex (ia1,ea,ia2,ia3,inia)) +> A.rewrap ia,
-            (B.InitDesignators 
-                ([B.DesignatorIndex eb, [ib1;ib2]], inib), [ib3])
-          ))))))
-
-
-    | (A.InitGccRange (ia1,e1a,ia2,e2a,ia3,ia4,inia), 
-      (B.InitDesignators ([B.DesignatorRange (e1b, e2b), ii1], inib), ii2)) -> 
-
-        let (ib1, ib2, ib3) = tuple_of_list3 ii1 in
-        let (ib4) = tuple_of_list1 ii2 in
-        tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-        tokenf ia2 ib2 >>= (fun ia2 ib2 -> 
-        tokenf ia3 ib3 >>= (fun ia3 ib3 -> 
-        tokenf ia4 ib4 >>= (fun ia4 ib4 -> 
-        expression e1a e1b >>= (fun e1a e1b -> 
-        expression e2a e2b >>= (fun e2a e2b -> 
-        initialiser inia inib >>= (fun inia inib -> 
-          return (
-            (A.InitGccRange (ia1,e1a,ia2,e2a,ia3,ia4,inia)) +> A.rewrap ia,
-            (B.InitDesignators 
-                ([B.DesignatorRange (e1b, e2b),[ib1;ib2;ib3]], inib), [ib4])
-          ))))))))
-
-
-
-
-    | (A.InitGccName (ida, ia1, inia), (B.InitFieldOld (idb, inib), ii)) -> 
-        (match ii with 
-        | [iidb;iicolon] -> 
-            ident DontKnow ida (idb, iidb) >>= (fun ida (idb, iidb) -> 
-            initialiser inia inib >>= (fun inia inib -> 
-            tokenf ia1 iicolon >>= (fun ia1 iicolon -> 
-              return (
-                (A.InitGccName (ida, ia1, inia)) +> A.rewrap ia,
-                (B.InitFieldOld (idb, inib), [iidb;iicolon])
-              ))))
-        | _ -> fail
-        )
-
-
-
-    | A.IComma(comma), _ ->
-        raise Impossible
-
-    | A.UniqueIni _,_ | A.OptIni _,_ -> 
-      failwith "not handling Opt/Unique on initialisers"
-          
-    | _, _ -> fail
-
-
-
-
-
-and initialisers = fun ias (ibs, iicomma) ->
-  let ias_unsplit = unsplit_icomma      ias in
-  let ibs_split   = resplit_initialiser ibs iicomma in
-
-  let f = 
-    if need_unordered_initialisers ibs 
-    then initialisers_unordered2
-    else initialisers_ordered2
-  in
-  f ias_unsplit ibs_split >>= 
-      (fun ias_unsplit ibs_split -> 
-        return (
-          split_icomma ias_unsplit,
-          unsplit_initialiser ibs_split
-        )
-      )
-
-(* todo: one day julia will reput a IDots *)
-and initialisers_ordered2 = fun ias ibs -> 
-  match ias, ibs with
-  | [], [] -> return ([], [])
-  | (x, xcomma)::xs, (y, commay)::ys -> 
-      (match A.unwrap xcomma with
-      | A.IComma commax -> 
-          tokenf commax commay >>= (fun commax commay -> 
-          initialiser x y >>= (fun x y -> 
-          initialisers_ordered2 xs ys >>= (fun xs ys -> 
-            return (
-                    (x, (A.IComma commax) +> A.rewrap xcomma)::xs, 
-                    (y, commay)::ys
-            )
-          )))
-      | _ -> raise Impossible (* unsplit_iicomma wrong *)
-      )
-  | _ -> fail
-
-          
-
-and initialisers_unordered2 = fun ias ibs -> 
-
-  match ias, ibs with
-  | [], ys -> return ([], ys)
-  | (x,xcomma)::xs, ys -> 
-
-      let permut = Common.uncons_permut_lazy ys in
-      permut +> List.fold_left (fun acc ((e, pos), rest) -> 
-        acc >||> 
-          (
-            (match A.unwrap xcomma, e with 
-            | A.IComma commax, (y, commay) -> 
-                tokenf commax commay >>= (fun commax commay -> 
-                initialiser x y >>= (fun x y -> 
-                  return (
-                    (x, (A.IComma commax) +> A.rewrap xcomma), 
-                    (y, commay))
-                )
-                )
-            | _ -> raise Impossible (* unsplit_iicomma wrong *)
-            ) 
-            >>= (fun x e -> 
-              let rest = Lazy.force rest in
-              initialisers_unordered2 xs rest >>= (fun xs rest -> 
-                return (
-                  x::xs,
-                  Common.insert_elem_pos (e, pos) rest
-                ))))
-      ) fail
-       
-
-(* ------------------------------------------------------------------------- *)
-and (struct_fields: (A.declaration list, B.field B.wrap list) matcher) =
- fun eas ebs -> 
-  match eas, ebs with
-  | [], [] -> return ([], [])
-  | [], eb::ebs -> fail
-  | ea::eas, ebs -> 
-      X.all_bound (A.get_inherited ea) >&&>
-      (match A.unwrap ea, ebs with
-      | A.Ddots (mcode, optwhen), ys -> 
-          if optwhen <> None then failwith "not handling when in argument";
-
-          (* '...' can take more or less the beginnings of the arguments *)
-          let startendxs = Common.zip (Common.inits ys) (Common.tails ys) in
-          startendxs +> List.fold_left (fun acc (startxs, endxs) -> 
-            acc >||> (
-              
-              (if startxs = []
-              then
-                if mcode_contain_plus (mcodekind mcode)
-                then fail 
-                  (* failwith "I have no token that I could accroche myself on" *)
-                else return (dots2metavar mcode, [])
-              else 
-
-                  X.distrf_struct_fields (dots2metavar mcode) startxs
-              ) >>= (fun mcode startxs ->
-               let mcode = metavar2dots mcode in
-                struct_fields eas endxs >>= (fun eas endxs -> 
-                  return (
-                    (A.Ddots (mcode, optwhen) +> A.rewrap ea) ::eas,
-                    startxs ++ endxs
-                  )))
-            )
-          ) fail 
-      | _unwrapx, eb::ebs -> 
-          struct_field ea eb >>= (fun ea eb -> 
-          struct_fields eas ebs >>= (fun eas ebs -> 
-            return (ea::eas, eb::ebs)
-          ))
-
-      | _unwrapx, [] -> fail
-      )
-
-and (struct_field: (A.declaration, B.field B.wrap) matcher) = fun fa fb -> 
-  let (xfield, ii) = fb in
-  let iiptvirgb = tuple_of_list1 ii in
-
-  match xfield with 
-  | B.FieldDeclList onefield_multivars -> 
-
-    (match onefield_multivars with
-    | [] -> raise Impossible
-    | [onevar,iivirg] -> 
-      assert (null iivirg);
-      (match onevar with
-      | B.BitField (sopt, typb, expr), ii -> 
-          pr2_once "warning: bitfield not handled by ast_cocci";
-          fail
-      | B.Simple (None, typb), ii -> 
-          pr2_once "warning: unamed struct field not handled by ast_cocci";
-          fail
-      | B.Simple (Some idb, typb), ii -> 
-          let (iidb) = tuple_of_list1 ii in
-
-          (* build a declaration from a struct field *)
-          let allminus = false in
-          let iisto = [] in
-          let stob = B.NoSto, false in
-          let fake_var = 
-            ((Some ((idb, None),[iidb]), typb, stob, Ast_c.NotLocalDecl),
-            iivirg)            
-          in
-          onedecl allminus fa (fake_var,iiptvirgb,iisto) >>= 
-            (fun fa (var,iiptvirgb,iisto) -> 
-
-              match fake_var with
-              | ((Some ((idb, None),[iidb]), typb, stob, local), iivirg) -> 
-                  let onevar = B.Simple (Some idb, typb), [iidb] in
-                  
-                  return (
-                    (fa),
-                    (B.FieldDeclList [onevar, iivirg], [iiptvirgb])
-                  )
-              | _ -> raise Impossible
-            )
-      )
-
-    | x::y::xs -> 
-      pr2_once "PB: More that one variable in decl. Have to split";
-      fail
-    )
-  | B.EmptyField -> fail
-
-
-
-(* ------------------------------------------------------------------------- *)
-and (fullType: (A.fullType, Ast_c.fullType) matcher) = 
- fun typa typb -> 
-   X.optional_qualifier_flag (fun optional_qualifier -> 
-   X.all_bound (A.get_inherited typa) >&&>
-   match A.unwrap typa, typb with
-   | A.Type(cv,ty1), ((qu,il),ty2) ->
-
-       if qu.B.const && qu.B.volatile 
-       then
-        pr2_once
-          ("warning: the type is both const & volatile but cocci " ^ 
-            "does not handle that");
-
-       (* Drop out the const/volatile part that has been matched.
-         * This is because a SP can contain  const T v; in which case
-         * later in match_t_t when we encounter a T, we must not add in
-         * the environment the whole type.
-         *)
-       
-
-       (match cv with
-       (* "iso-by-absence" *)
-       | None -> 
-           let do_stuff () = 
-             fullTypebis ty1 ((qu,il), ty2) >>= (fun ty1 fullty2 -> 
-               return (
-                 (A.Type(None, ty1)) +> A.rewrap typa,
-                 fullty2
-               ))
-           in
-           (match optional_qualifier, qu.B.const || qu.B.volatile with
-           | false, false -> do_stuff ()
-           | false, true -> fail
-           | true, false -> do_stuff ()
-           | true, true -> 
-               if !Flag.show_misc 
-               then pr2_once "USING optional_qualifier builtin isomorphism";
-               do_stuff()
-           )
-             
-           
-       | Some x -> 
-          (* todo: can be __const__ ? can be const & volatile so 
-           * should filter instead ? 
-           *)
-           (match term x, il with 
-           | A.Const, [i1] when qu.B.const -> 
-               
-               tokenf x i1 >>= (fun x i1 -> 
-               fullTypebis ty1 (Ast_c.nQ,ty2) >>= (fun ty1 (_, ty2) -> 
-                 return (
-                   (A.Type(Some x, ty1)) +> A.rewrap typa,
-                   ((qu, [i1]), ty2)
-                 )))
-               
-           | A.Volatile, [i1] when qu.B.volatile -> 
-               tokenf x i1 >>= (fun x i1 -> 
-               fullTypebis ty1 (Ast_c.nQ,ty2) >>= (fun ty1 (_, ty2) -> 
-                 return (
-                   (A.Type(Some x, ty1)) +> A.rewrap typa,
-                   ((qu, [i1]), ty2)
-                 )))
-               
-           | _ -> fail
-           )
-       )
-
-  | A.DisjType typas, typb -> 
-      typas +>
-      List.fold_left (fun acc typa -> acc >|+|> (fullType typa typb)) fail
-
-   | A.OptType(_), _  | A.UniqueType(_), _
-       -> failwith "not handling Opt/Unique on type"
-   )
-
-(*
- * Why not (A.typeC, Ast_c.typeC) matcher ?
- * because when there is MetaType, we want that T record the whole type, 
- * including the qualifier, and so this type (and the new_il function in
- * preceding function).
-*)
-
-and (fullTypebis: (A.typeC, Ast_c.fullType) matcher) = 
-  fun ta tb -> 
-  X.all_bound (A.get_inherited ta) >&&> 
-  match A.unwrap ta, tb with
-
-  (* cas general *)
-  | A.MetaType(ida,keep, inherited),  typb -> 
-      let max_min _ =
-       Lib_parsing_c.lin_col_by_pos (Lib_parsing_c.ii_of_type typb) in
-      X.envf keep inherited (ida, B.MetaTypeVal typb, max_min) (fun () -> 
-        X.distrf_type ida typb >>= (fun ida typb -> 
-          return (
-            A.MetaType(ida,keep, inherited) +> A.rewrap ta,
-            typb
-          ))
-      )
-  | unwrap, (qub, typb) -> 
-      typeC ta typb >>= (fun ta typb -> 
-        return (ta, (qub, typb))
-      )
-
-
-and (typeC: (A.typeC, Ast_c.typeC) matcher) = 
-  fun ta tb -> 
-  match A.unwrap ta, tb with
-  | A.BaseType (basea, signaopt), (B.BaseType baseb, ii) -> 
-      (* In ii there is a list, sometimes of length 1 or 2 or 3.
-       * And even if in baseb we have a Signed Int, that does not mean
-       * that ii is of length 2, cos Signed is the default, so if in signa
-       * we have Signed explicitely ? we cant "accrocher" this mcode to 
-       * something :( So for the moment when there is signed in cocci,
-       * we force that there is a signed in c too (done in pattern.ml).
-       *)
-      let signbopt, iibaseb = split_signb_baseb_ii (baseb, ii) in
-
-        
-      (* handle some iso on type ? (cf complex C rule for possible implicit
-        casting) *)
-      (match term basea, baseb with
-      | A.VoidType,  B.Void 
-      | A.FloatType, B.FloatType (B.CFloat)
-      | A.DoubleType, B.FloatType (B.CDouble) -> 
-           assert (signaopt = None); 
-           let (ibaseb) = tuple_of_list1 ii in 
-           tokenf basea ibaseb >>= (fun basea ibaseb -> 
-             return (
-               (A.BaseType (basea, signaopt)) +> A.rewrap ta,
-               (B.BaseType baseb, [ibaseb])
-             ))
-            
-      | A.CharType,  B.IntType B.CChar when signaopt = None -> 
-          let ibaseb = tuple_of_list1 ii in
-           tokenf basea ibaseb >>= (fun basea ibaseb -> 
-             return (
-               (A.BaseType (basea, signaopt)) +> A.rewrap ta,
-               (B.BaseType (B.IntType B.CChar), [ibaseb])
-             ))
-            
-      | A.CharType,B.IntType (B.Si (_sign, B.CChar2)) when signaopt <> None -> 
-          let ibaseb = tuple_of_list1 iibaseb in
-          sign signaopt signbopt >>= (fun signaopt iisignbopt -> 
-          tokenf basea ibaseb >>= (fun basea ibaseb -> 
-            return (
-               (A.BaseType (basea, signaopt)) +> A.rewrap ta,
-               (B.BaseType (baseb), iisignbopt ++ [ibaseb])
-               )))
-          
-      | A.ShortType, B.IntType (B.Si (_, B.CShort)) 
-      | A.IntType,   B.IntType (B.Si (_, B.CInt))   
-      | A.LongType,  B.IntType (B.Si (_, B.CLong))  ->
-          (match iibaseb with 
-          | [] -> 
-              (* iso-by-presence ? *)
-              (* when unsigned int in SP,  allow have just unsigned in C ? *)
-              if mcode_contain_plus (mcodekind basea)
-              then fail
-              else 
-                
-                sign signaopt signbopt >>= (fun signaopt iisignbopt -> 
-                    return (
-                      (A.BaseType (basea, signaopt)) +> A.rewrap ta,
-                      (B.BaseType (baseb), iisignbopt ++ [])
-                    ))
-              
-
-          | [x;y] -> 
-              pr2_once 
-                "warning: long int or short int not handled by ast_cocci";
-              fail
-
-          | [ibaseb] -> 
-          sign signaopt signbopt >>= (fun signaopt iisignbopt -> 
-          tokenf basea ibaseb >>= (fun basea ibaseb -> 
-            return (
-               (A.BaseType (basea, signaopt)) +> A.rewrap ta,
-               (B.BaseType (baseb), iisignbopt ++ [ibaseb])
-               )))
-          | _ -> raise Impossible
-
-          )
-
-            
-      | _, B.IntType (B.Si (_, B.CLongLong)) 
-      | _, B.FloatType B.CLongDouble 
-          -> 
-          pr2_once 
-            "warning: long long or long double not handled by ast_cocci";
-          fail
-          
-          
-      | _, _ -> fail
-          
-          
-      )
-
-    | A.ImplicitInt (signa),   (B.BaseType baseb, ii) -> 
-        let signbopt, iibaseb = split_signb_baseb_ii (baseb, ii) in
-        (match iibaseb, baseb with
-        | [], B.IntType (B.Si (_sign, B.CInt)) -> 
-            sign (Some signa) signbopt >>= (fun signaopt iisignbopt -> 
-              match signaopt with
-              | None -> raise Impossible
-              | Some signa -> 
-                  return (
-                    (A.ImplicitInt (signa)) +> A.rewrap ta,
-                    (B.BaseType baseb, iisignbopt)
-                  )
-            )
-        | _ -> fail
-        )
-
-
-
-    (* todo? iso with array *)
-    | A.Pointer (typa, iamult),            (B.Pointer typb, ii) -> 
-        let (ibmult) = tuple_of_list1 ii in 
-        fullType typa typb >>= (fun typa typb -> 
-        tokenf iamult ibmult >>= (fun iamult ibmult -> 
-          return (
-            (A.Pointer (typa, iamult)) +> A.rewrap ta,
-            (B.Pointer typb, [ibmult])
-          )))
-
-    | A.FunctionType(allminus,tyaopt,lpa,paramsa,rpa), 
-      (B.FunctionType(tyb, (paramsb, (isvaargs, iidotsb))), ii) -> 
-
-        let (lpb, rpb) = tuple_of_list2 ii in
-        if isvaargs 
-        then
-          pr2_once
-           ("Not handling well variable length arguments func. "^
-             "You have been warned");
-        tokenf lpa lpb >>= (fun lpa lpb -> 
-        tokenf rpa rpb >>= (fun rpa rpb -> 
-        fullType_optional_allminus allminus tyaopt tyb >>= (fun tyaopt tyb -> 
-        parameters (seqstyle paramsa) (A.undots paramsa) paramsb >>=
-          (fun paramsaundots paramsb -> 
-            let paramsa = redots paramsa paramsaundots in
-            return (
-              (A.FunctionType(allminus,tyaopt,lpa,paramsa,rpa) +> A.rewrap ta,
-              (B.FunctionType(tyb, (paramsb, (isvaargs, iidotsb))), [lpb;rpb])
-              )
-            )))))
-            
-        
-
-          
-
-    | A.FunctionPointer(tya,lp1a,stara,rp1a,lp2a,paramsa,rp2a), 
-        (B.ParenType t1, ii) ->
-        let (lp1b, rp1b) = tuple_of_list2 ii in
-        let (qu1b, t1b) = t1 in
-        (match t1b with
-        | B.Pointer t2, ii -> 
-            let (starb) = tuple_of_list1 ii in
-            let (qu2b, t2b) = t2 in
-            (match t2b with
-            | B.FunctionType (tyb, (paramsb, (isvaargs, iidotsb))), ii -> 
-                let (lp2b, rp2b) = tuple_of_list2 ii in
-
-                if isvaargs
-                then
-                 pr2_once
-                   ("Not handling well variable length arguments func. "^
-                    "You have been warned");
-
-                fullType tya tyb >>= (fun tya tyb -> 
-                tokenf lp1a lp1b >>= (fun lp1a lp1b -> 
-                tokenf rp1a rp1b >>= (fun rp1a rp1b -> 
-                tokenf lp2a lp2b >>= (fun lp2a lp2b -> 
-                tokenf rp2a rp2b >>= (fun rp2a rp2b -> 
-                tokenf stara starb >>= (fun stara starb -> 
-                parameters (seqstyle paramsa) (A.undots paramsa) paramsb >>=
-                (fun paramsaundots paramsb -> 
-                  let paramsa = redots paramsa paramsaundots in
-
-                  let t2 = 
-                    (qu2b, 
-                    (B.FunctionType (tyb, (paramsb, (isvaargs, iidotsb))),
-                    [lp2b;rp2b])) 
-                  in
-                  let t1 = 
-                    (qu1b,
-                    (B.Pointer t2, [starb]))
-                  in
-                  
-                  return (
-                    (A.FunctionPointer(tya,lp1a,stara,rp1a,lp2a,paramsa,rp2a))
-                    +> A.rewrap ta,
-                    (B.ParenType t1, [lp1b;rp1b])
-                  )
-                )))))))
-
-
-
-            | _ -> fail
-            )
-        | _ -> fail
-        )
-        
-        
-
-    (* todo: handle the iso on optionnal size specifification ? *)
-    | A.Array (typa, ia1, eaopt, ia2), (B.Array (ebopt, typb), ii) -> 
-        let (ib1, ib2) = tuple_of_list2 ii in
-        fullType typa typb >>= (fun typa typb -> 
-        option expression eaopt ebopt >>= (fun eaopt ebopt -> 
-        tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-        tokenf ia2 ib2 >>= (fun ia2 ib2 -> 
-          return (
-            (A.Array (typa, ia1, eaopt, ia2)) +> A.rewrap ta,
-            (B.Array (ebopt, typb), [ib1;ib2])
-          )))))
-
-
-     (* todo: could also match a Struct that has provided a name *)
-     (* This is for the case where the SmPL code contains "struct x", without
-       a definition.  In this case, the name field is always present.
-        This case is also called from the case for A.StructUnionDef when
-        a name is present in the C code. *)
-    | A.StructUnionName(sua, Some sa), (B.StructUnionName (sub, sb), ii) -> 
-        (* sa is now an ident, not an mcode, old: ... && (term sa) =$= sb *)
-        let (ib1, ib2) = tuple_of_list2 ii in
-        if equal_structUnion  (term sua) sub 
-        then
-          ident DontKnow sa (sb, ib2) >>= (fun sa (sb, ib2) -> 
-          tokenf sua ib1 >>= (fun sua ib1 -> 
-            return (
-              (A.StructUnionName (sua, Some sa)) +> A.rewrap ta,
-              (B.StructUnionName (sub, sb), [ib1;ib2])
-              )))
-        else fail
-        
-
-    | A.StructUnionDef(ty, lba, declsa, rba), 
-     (B.StructUnion (sub, sbopt, declsb), ii) -> 
-
-       let (ii_sub_sb, lbb, rbb) =
-        match ii with
-          [iisub; lbb; rbb] -> (Common.Left iisub,lbb,rbb)
-        | [iisub; iisb; lbb; rbb] -> (Common.Right (iisub,iisb),lbb,rbb)
-        | _ -> failwith "list of length 3 or 4 expected" in
-
-       let process_type =
-         match (sbopt,ii_sub_sb) with
-           (None,Common.Left iisub) ->
-            (* the following doesn't reconstruct the complete SP code, just
-               the part that matched *)
-            let rec loop s =
-              match A.unwrap s with
-                A.Type(None,ty) ->
-                  (match A.unwrap ty with
-                    A.StructUnionName(sua, None) ->
-                      tokenf sua iisub >>= (fun sua iisub ->
-                        let ty =
-                          A.Type(None,
-                                 A.StructUnionName(sua, None) +> A.rewrap ty)
-                            +> A.rewrap s in
-                        return (ty,[iisub]))
-                  | _ -> fail)
-              | A.DisjType(disjs) ->
-                  disjs +>
-                  List.fold_left (fun acc disj -> acc >|+|> (loop disj)) fail
-              | _ -> fail in
-            loop ty
-              
-         | (Some sb,Common.Right (iisub,iisb)) ->
-
-             (* build a StructUnionName from a StructUnion *)
-             let fake_su = B.nQ, (B.StructUnionName (sub, sb), [iisub;iisb]) in
-            
-             fullType ty fake_su >>= (fun ty fake_su -> 
-               match fake_su with
-               | _nQ, (B.StructUnionName (sub, sb), [iisub;iisb]) -> 
-                   return (ty,  [iisub; iisb])
-               | _ -> raise Impossible)
-        | _ -> fail in
-
-       process_type
-        >>= (fun ty ii_sub_sb -> 
-
-            tokenf lba lbb >>= (fun lba lbb -> 
-            tokenf rba rbb >>= (fun rba rbb -> 
-            struct_fields (A.undots declsa) declsb >>=(fun undeclsa declsb ->
-              let declsa = redots declsa undeclsa in
-
-              return (
-                (A.StructUnionDef(ty, lba, declsa, rba)) +> A.rewrap ta,
-                (B.StructUnion (sub, sbopt, declsb),ii_sub_sb@[lbb;rbb])
-              )))))
-
-
-   (* todo? handle isomorphisms ? because Unsigned Int can be match on a 
-    * uint in the C code. But some CEs consists in renaming some types,
-    * so we don't want apply isomorphisms every time. 
-    *) 
-    | A.TypeName sa,  (B.TypeName (sb,typb), ii) ->
-        let (isb) = tuple_of_list1 ii in
-        if (term sa) =$= sb
-        then 
-          tokenf sa isb >>= (fun sa isb -> 
-          return (
-            (A.TypeName sa) +> A.rewrap ta,
-            (B.TypeName (sb,typb), [isb])
-          ))
-        else fail
-
-    | _, (B.TypeOfExpr e, ii) -> fail
-    | _, (B.TypeOfType e, ii) -> fail
-          
-    | _, _ -> fail
-
-(* todo: iso on sign, if not mentioned then free.  tochange? 
- * but that require to know if signed int because explicit
- * signed int,  or because implicit signed int.
- *)
-
-and sign signa signb = 
-  match signa, signb with
-  | None, None -> return (None, [])
-  | Some signa,  Some (signb, ib) -> 
-      if equal_sign (term signa) signb
-      then tokenf signa ib >>= (fun signa ib -> 
-        return (Some signa, [ib])
-      )
-      else fail
-  | _, _ -> fail
-
-
-and minusize_list iixs = 
-  iixs +> List.fold_left (fun acc ii -> 
-    acc >>= (fun xs ys -> 
-    tokenf minusizer ii >>= (fun minus ii -> 
-      return (minus::xs, ii::ys)
-    ))) (return ([],[]))
-   >>= (fun _xsminys ys -> 
-     return ((), List.rev ys)
-   )
-
-and storage_optional_allminus allminus stoa (stob, iistob) = 
-  (* "iso-by-absence" for storage, and return type. *)
-  X.optional_storage_flag (fun optional_storage -> 
-  match stoa, stob with
-  | None, (stobis, inline) -> 
-      let do_minus () = 
-        if allminus 
-        then 
-          minusize_list iistob >>= (fun () iistob -> 
-            return (None, (stob, iistob))
-          )
-        else return (None, (stob, iistob))
-      in
-
-      (match optional_storage, stobis with
-      | false, B.NoSto -> do_minus ()
-      | false, _ -> fail
-      | true, B.NoSto -> do_minus ()
-      | true, _ -> 
-          if !Flag.show_misc 
-          then pr2_once "USING optional_storage builtin isomorphism";
-          do_minus()
-      )
-
-  | Some x, ((stobis, inline)) -> 
-      if equal_storage (term x) stobis
-      then 
-        match iistob with
-        | [i1] ->
-           tokenf x i1 >>= (fun x i1 -> 
-             return (Some x,  ((stobis, inline), [i1]))
-           )
-       (* or if have inline ? have to do a split_storage_inline a la 
-        * split_signb_baseb_ii *)
-        | _ -> raise Impossible 
-      else fail
-  )
-
-
-
-
-and fullType_optional_allminus allminus tya retb = 
-  match tya with 
-  | None -> 
-      if allminus
-      then 
-        X.distrf_type minusizer retb >>= (fun _x retb -> 
-          return (None, retb)
-        )
-
-      else return (None, retb)
-  | Some tya -> 
-      fullType tya retb >>= (fun tya retb -> 
-        return (Some tya, retb)
-      )
-
-
-
-(*---------------------------------------------------------------------------*)
-and compatible_type a (b,_local) = 
-  let ok  = return ((),()) in
-
-  let rec loop = function
-    | Type_cocci.BaseType (a, signa), (qua, (B.BaseType b,ii)) -> 
-       (match a, b with
-       | Type_cocci.VoidType, B.Void -> 
-            assert (signa = None);
-            ok
-       | Type_cocci.CharType, B.IntType B.CChar when signa = None -> 
-            ok
-       | Type_cocci.CharType, B.IntType (B.Si (signb, B.CChar2)) -> 
-            compatible_sign signa signb 
-       | Type_cocci.ShortType, B.IntType (B.Si (signb, B.CShort)) -> 
-            compatible_sign signa signb
-       | Type_cocci.IntType, B.IntType (B.Si (signb, B.CInt)) -> 
-            compatible_sign signa signb
-       | Type_cocci.LongType, B.IntType (B.Si (signb, B.CLong)) -> 
-            compatible_sign signa signb
-       | _, B.IntType (B.Si (signb, B.CLongLong)) -> 
-            pr2_once "no longlong in cocci";
-            fail
-       | Type_cocci.FloatType, B.FloatType B.CFloat ->
-           assert (signa = None); 
-            ok
-       | Type_cocci.DoubleType, B.FloatType B.CDouble ->
-           assert (signa = None); 
-            ok
-       | _, B.FloatType B.CLongDouble -> 
-            pr2_once "no longdouble in cocci";
-            fail
-       | Type_cocci.BoolType, _ -> failwith "no booltype in C"
-       | _ -> fail
-             
-      )
-    | Type_cocci.Pointer  a, (qub, (B.Pointer b, ii)) -> 
-       loop (a,b)
-    | Type_cocci.FunctionPointer a, _ ->
-       failwith
-         "TODO: function pointer type doesn't store enough information to determine compatability"
-    | Type_cocci.Array   a, (qub, (B.Array (eopt, b),ii)) ->
-      (* no size info for cocci *)
-       loop (a,b)
-    | Type_cocci.StructUnionName (sua, _, sa),
-       (qub, (B.StructUnionName (sub, sb),ii)) -> 
-         if equal_structUnion_type_cocci sua sub && sa = sb
-         then ok
-         else fail
-
-    | Type_cocci.TypeName sa, (qub, (B.TypeName (sb,_typb), ii)) -> 
-       if sa = sb 
-       then ok
-       else fail
-
-    | Type_cocci.ConstVol (qua, a),      (qub, b) -> 
-       if (fst qub).B.const && (fst qub).B.volatile 
-       then
-         begin
-           pr2_once ("warning: the type is both const & volatile but cocci " ^
-                      "does not handle that");
-            fail
-         end
-       else 
-          if 
-            (match qua with 
-            | Type_cocci.Const -> (fst qub).B.const
-            | Type_cocci.Volatile -> (fst qub).B.volatile
-           )
-          then loop (a,(Ast_c.nQ, b))
-          else fail
-
-    | Type_cocci.MetaType (ida,keep,inherited),     typb -> 
-       let max_min _ =
-         Lib_parsing_c.lin_col_by_pos (Lib_parsing_c.ii_of_type typb) in
-       X.envf keep inherited (A.make_mcode ida, B.MetaTypeVal typb, max_min)
-         (fun () -> ok
-        )
-
-  (* subtil: must be after the MetaType case *)
-    | a, (qub, (B.TypeName (sb,Some b), ii)) -> 
-      (* kind of typedef iso *)
-       loop (a,b)
-
-
-
-
-
-  (* for metavariables of type expression *^* *)
-    | Type_cocci.Unknown , _ -> ok
-
-    | _ -> fail in
-  loop (a,b)
-
-and compatible_sign signa signb = 
-  let ok  = return ((),()) in
-  match signa, signb with
-  | None, B.Signed 
-  | Some Type_cocci.Signed, B.Signed
-  | Some Type_cocci.Unsigned, B.UnSigned
-      -> ok
-  | _ -> fail
-
-
-and equal_structUnion_type_cocci a b = 
-  match a, b with
-  | Type_cocci.Struct, B.Struct -> true
-  | Type_cocci.Union,  B.Union -> true
-  | _, _ -> false
-
-
-
-(*---------------------------------------------------------------------------*)
-and inc_file (a, before_after) (b, h_rel_pos) = 
-
-  let rec aux_inc (ass, bss) passed = 
-    match ass, bss with
-    | [], [] -> true
-    | [A.IncDots], _ -> 
-        let passed = List.rev passed in
-
-        (match before_after, !h_rel_pos with
-        | IncludeNothing, _ -> true
-        | IncludeMcodeBefore, Some x -> 
-            List.mem passed (x.Ast_c.first_of)
-
-        | IncludeMcodeAfter, Some x -> 
-            List.mem passed (x.Ast_c.last_of)
-
-        (* no info, maybe cos of a #include <xx.h> that was already in a .h *)
-        | _, None -> false 
-        )
-
-    | (A.IncPath x)::xs, y::ys -> x = y && aux_inc (xs, ys) (x::passed)
-    | _ -> failwith "IncDots not in last place or other pb"
-        
-  in
-
-  match a, b with
-  | A.Local ass, B.Local bss -> 
-      aux_inc (ass, bss) []
-  | A.NonLocal ass, B.NonLocal bss -> 
-      aux_inc (ass, bss) []
-  | _ -> false
-       
-
-
-(*---------------------------------------------------------------------------*)
-
-and (define_params: sequence -> 
-  (A.define_param list, (string B.wrap) B.wrap2 list) matcher) = 
- fun seqstyle eas ebs -> 
-  match seqstyle with
-  | Unordered -> failwith "not handling ooo"
-  | Ordered -> 
-      define_paramsbis eas (Ast_c.split_comma ebs) >>= (fun eas ebs_splitted ->
-        return (eas, (Ast_c.unsplit_comma ebs_splitted))
-      )
-
-(* todo? facto code with argument and parameters ? *)
-and define_paramsbis = fun eas ebs -> 
-  match eas, ebs with
-  | [], [] -> return ([], [])
-  | [], eb::ebs -> fail
-  | ea::eas, ebs -> 
-      X.all_bound (A.get_inherited ea) >&&>
-      (match A.unwrap ea, ebs with
-      | A.DPdots (mcode), ys -> 
-
-          (* '...' can take more or less the beginnings of the arguments *)
-          let startendxs = Common.zip (Common.inits ys) (Common.tails ys) in
-          startendxs +> List.fold_left (fun acc (startxs, endxs) -> 
-            acc >||> (
-
-              (if startxs = []
-              then
-                if mcode_contain_plus (mcodekind mcode)
-                then fail 
-                  (* failwith "I have no token that I could accroche myself on" *)
-                else return (dots2metavar mcode, [])
-              else 
-                (match Common.last startxs with
-                | Right _ -> fail
-                | Left _ -> 
-                    X.distrf_define_params (dots2metavar mcode) startxs
-                )
-              ) >>= (fun mcode startxs ->
-               let mcode = metavar2dots mcode in
-                define_paramsbis eas endxs >>= (fun eas endxs -> 
-                  return (
-                    (A.DPdots (mcode) +> A.rewrap ea) ::eas,
-                    startxs ++ endxs
-                  )))
-              )
-            ) fail 
-
-      | A.DPComma ia1, Right ii::ebs -> 
-          let ib1 = tuple_of_list1 ii in
-          tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-          define_paramsbis eas ebs >>= (fun eas ebs -> 
-            return (
-              (A.DPComma ia1 +> A.rewrap ea)::eas,
-              (Right [ib1])::ebs
-            )
-          ))
-
-      | A.DPComma ia1, ebs -> 
-          if mcode_contain_plus (mcodekind ia1)
-          then fail
-          else 
-            (define_paramsbis eas ebs) (* try optional comma trick *)
-
-      | (A.OptDParam _ | A.UniqueDParam _), _ -> 
-              failwith "handling Opt/Unique for define parameters"
-
-      | A.DPcircles (_), ys -> raise Impossible (* in Ordered mode *)
-
-      | A.DParam ida, (Left (idb, ii))::ebs -> 
-          let ib1 = tuple_of_list1 ii in
-          ident DontKnow ida (idb, ib1) >>= (fun ida (idb, ib1) -> 
-          define_paramsbis eas ebs >>= (fun eas ebs -> 
-            return (
-              (A.DParam ida)+> A.rewrap ea :: eas,
-              (Left (idb, [ib1]))::ebs
-            )))
-          
-      | _unwrapx, (Right y)::ys -> raise Impossible
-      | _unwrapx, [] -> fail
-      )
-  
-
-
-(*****************************************************************************)
-(* Entry points *)
-(*****************************************************************************)
-
-(* no global solution for positions here, because for a statement metavariable
-we want a MetaStmtVal, and for the others, it's not clear what we want *)
-
-let rec (rule_elem_node: (A.rule_elem, Control_flow_c.node) matcher) = 
- fun re node -> 
-  let rewrap x = 
-    x >>= (fun a b -> return (A.rewrap re a, F.rewrap node b))
-  in
-  X.all_bound (A.get_inherited re) >&&>
-
-  rewrap (
-  match A.unwrap re, F.unwrap node with
-
-  (* note: the order of the clauses is important. *)
-
-  | _, F.Enter | _, F.Exit | _, F.ErrorExit -> fail2()
-
-  (* the metaRuleElem contains just '-' information. We dont need to add
-   * stuff in the environment. If we need stuff in environment, because
-   * there is a + S somewhere, then this will be done via MetaStmt, not
-   * via MetaRuleElem. 
-   * Can match TrueNode/FalseNode/... so must be placed before those cases.
-   *)
-
-  | A.MetaRuleElem(mcode,keep,inherited), unwrap_node -> 
-      let default = A.MetaRuleElem(mcode,keep,inherited), unwrap_node in
-      (match unwrap_node with
-      | F.CaseNode _
-      | F.TrueNode | F.FalseNode | F.AfterNode | F.FallThroughNode 
-      | F.InLoopNode -> 
-          if X.mode = PatternMode 
-          then return default 
-          else
-            if mcode_contain_plus (mcodekind mcode)
-            then failwith "try add stuff on fake node"
-              (* minusize or contextize a fake node is ok *)
-            else return default
-
-      | F.EndStatement None -> 
-          if X.mode = PatternMode then return default 
-          else 
-              (* DEAD CODE NOW ? only useful in -no_cocci_vs_c_3 ?
-                 if mcode_contain_plus (mcodekind mcode)
-                 then
-                 let fake_info = Ast_c.fakeInfo() in
-                 distrf distrf_node (mcodekind mcode) 
-                 (F.EndStatement (Some fake_info)) 
-                 else return unwrap_node
-              *)
-            raise Todo
-              
-      | F.EndStatement (Some i1) -> 
-          tokenf mcode i1 >>= (fun mcode i1 -> 
-            return (
-              A.MetaRuleElem (mcode,keep, inherited),
-              F.EndStatement (Some i1)
-            ))
-
-      | F.FunHeader _ -> 
-          if X.mode = PatternMode then return default
-          else failwith "a MetaRuleElem can't transform a headfunc"
-      | _n -> 
-          if X.mode = PatternMode then return default 
-          else 
-          X.distrf_node (generalize_mcode mcode) node >>= (fun mcode node -> 
-            return (
-              A.MetaRuleElem(mcode,keep, inherited),
-              F.unwrap node
-            ))
-      )
-
-
-  (* rene cant have found that a state containing a fake/exit/... should be 
-   * transformed 
-   * TODO: and F.Fake ?
-   *)
-  | _, F.EndStatement _ | _, F.CaseNode _
-  | _, F.TrueNode | _, F.FalseNode | _, F.AfterNode | _, F.FallThroughNode
-  | _, F.InLoopNode
-    -> fail2()
-
-  (* really ? diff between pattern.ml and transformation.ml *)
-  | _, F.Fake -> fail2()
-
-
-  (* cas general: a Meta can match everything. It matches only
-   * "header"-statement. We transform only MetaRuleElem, not MetaStmt.
-   * So can't have been called in transform. 
-   *)
-  | A.MetaStmt (ida,keep,metainfoMaybeTodo,inherited),  F.Decl(_) -> fail
-
-  | A.MetaStmt (ida,keep,metainfoMaybeTodo,inherited),  unwrap_node -> 
-      (* todo: should not happen in transform mode *)
-
-      (match Control_flow_c.extract_fullstatement node with
-      | Some stb -> 
-           let max_min _ =
-             Lib_parsing_c.lin_col_by_pos (Lib_parsing_c.ii_of_stmt stb) in
-            X.envf keep inherited (ida, Ast_c.MetaStmtVal stb, max_min)
-             (fun () -> 
-              (* no need tag ida, we can't be called in transform-mode *)
-               return (
-               A.MetaStmt (ida, keep, metainfoMaybeTodo, inherited),
-               unwrap_node
-             )
-           )
-      | None -> fail
-      )
-
-  (* not me?: *)
-  | A.MetaStmtList _, _ -> 
-      failwith "not handling MetaStmtList"
-
-  | A.TopExp ea, F.DefineExpr eb  ->
-      expression ea eb >>= (fun ea eb -> 
-        return (
-          A.TopExp ea,
-          F.DefineExpr eb
-        ))
-         
-  | A.TopExp ea, F.DefineType eb  ->
-      (match A.unwrap ea with
-       A.TypeExp(ft) ->
-         fullType ft eb >>= (fun ft eb -> 
-            return (
-              A.TopExp (A.rewrap ea (A.TypeExp(ft))),
-              F.DefineType eb
-            ))
-      |        _ -> fail)
-         
-
-
-  (* It is important to put this case before the one that fails because
-   * of the lack of the counter part of a C construct in SmPL (for instance
-   * there is not yet a CaseRange in SmPL). Even if SmPL don't handle
-   * yet certain constructs, those constructs may contain expression
-   * that we still want and can transform.
-   *)
-
-  | A.Exp exp, nodeb -> 
-
-      (* kind of iso, initialisation vs affectation *)
-      let node = 
-        match A.unwrap exp, nodeb with
-        | A.Assignment (ea, op, eb, true), F.Decl decl -> 
-            initialisation_to_affectation decl +> F.rewrap node
-        | _ -> node
-      in
-
-
-     (* Now keep fullstatement inside the control flow node, 
-      * so that can then get in a MetaStmtVar the fullstatement to later
-      * pp back when the S is in a +. But that means that 
-      * Exp will match an Ifnode even if there is no such exp
-      * inside the condition of the Ifnode (because the exp may
-      * be deeper, in the then branch). So have to not visit
-      * all inside a node anymore.
-      * 
-      * update: j'ai choisi d'accrocher au noeud du CFG Ã  la
-      * fois le fullstatement et le partialstatement et appeler le 
-      * visiteur que sur le partialstatement.
-      *)
-      let expfn = 
-        match Ast_cocci.get_pos re with
-        | None -> expression
-        | Some pos -> 
-            (fun ea eb -> 
-              let (max,min) = 
-                Lib_parsing_c.max_min_by_pos (Lib_parsing_c.ii_of_expr eb) in
-              let keep = Type_cocci.Unitary in
-              let inherited = false in
-             let max_min _ = failwith "no pos" in
-              X.envf keep inherited (pos, B.MetaPosVal (min,max), max_min)
-               (fun () -> 
-                  expression ea eb
-              )
-            )
-      in
-      X.cocciExp expfn exp node >>= (fun exp node -> 
-        return (
-          A.Exp exp,
-          F.unwrap node
-        )
-      )
-
-
-
-  | A.Ty ty, nodeb -> 
-      X.cocciTy fullType ty node >>= (fun ty node -> 
-        return (
-          A.Ty ty,
-          F.unwrap node
-        )
-      )
-
-
-  | A.FunHeader (mckstart, allminus, fninfoa, ida, oparen, paramsa, cparen),
-    F.FunHeader ((idb, (retb, (paramsb, (isvaargs, iidotsb))), stob), ii) -> 
-
-      (* fninfoa records the order in which the SP specified the various
-        information, but this isn't taken into account in the matching.
-        Could this be a problem for transformation? *)
-      let stoa =
-       match
-         List.filter (function A.FStorage(s) -> true | _ -> false) fninfoa
-       with [A.FStorage(s)] -> Some s | _ -> None in
-      let tya = 
-       match List.filter (function A.FType(s) -> true | _ -> false) fninfoa
-       with [A.FType(t)] -> Some t | _ -> None in
-
-      (match List.filter (function A.FInline(i) -> true | _ -> false) fninfoa
-      with [A.FInline(i)] -> failwith "not checking inline" | _ -> ());
-
-      (match List.filter (function A.FAttr(a) -> true | _ -> false) fninfoa
-      with [A.FAttr(a)] -> failwith "not checking attributes" | _ -> ());
-
-      (match ii with
-      | iidb::ioparenb::icparenb::iifakestart::iistob -> 
-
-          (* maybe important to put ident as the first tokens to transform.
-           * It's related to transform_proto. So don't change order
-           * between the >>=.
-           *)
-          ident LocalFunction ida (idb, iidb) >>= (fun ida (idb, iidb) -> 
-          X.tokenf_mck mckstart iifakestart >>= (fun mckstart iifakestart -> 
-          tokenf oparen ioparenb >>= (fun oparen ioparenb ->
-          tokenf cparen icparenb >>= (fun cparen icparenb ->
-          parameters (seqstyle paramsa) 
-            (A.undots paramsa) paramsb >>=
-            (fun paramsaundots paramsb -> 
-              let paramsa = redots paramsa paramsaundots in
-          storage_optional_allminus allminus 
-            stoa (stob, iistob) >>= (fun stoa (stob, iistob) -> 
-              (
-                if isvaargs 
-                then 
-                 pr2_once
-                   ("Not handling well variable length arguments func. "^
-                    "You have been warned");
-                if allminus
-                then minusize_list iidotsb
-                else return ((),iidotsb)
-              ) >>= (fun () iidotsb -> 
-            
-           fullType_optional_allminus allminus tya retb >>= (fun tya retb -> 
-
-             let fninfoa = 
-               (match stoa with Some st -> [A.FStorage st] | None -> []) ++
-               (match tya  with Some t -> [A.FType t] | None -> [])
-
-             in
-
-             return (
-               A.FunHeader(mckstart,allminus,fninfoa,ida,oparen,
-                          paramsa,cparen),
-               F.FunHeader ((idb, (retb, (paramsb, (isvaargs, iidotsb))), 
-                            stob), 
-                           iidb::ioparenb::icparenb::iifakestart::iistob)
-                )
-              ))))))))
-      | _ -> raise Impossible
-      )
-
-
-
-
-
-
-  | A.Decl (mckstart,allminus,decla), F.Decl declb -> 
-      declaration (mckstart,allminus,decla) declb >>= 
-       (fun (mckstart,allminus,decla) declb -> 
-        return (
-          A.Decl (mckstart,allminus,decla),
-          F.Decl declb
-        ))
-
-
-  | A.SeqStart mcode, F.SeqStart (st, level, i1) -> 
-      tokenf mcode i1 >>= (fun mcode i1 -> 
-        return (
-          A.SeqStart mcode, 
-          F.SeqStart (st, level, i1)
-        ))
-
-  | A.SeqEnd mcode, F.SeqEnd (level, i1) -> 
-      tokenf mcode i1 >>= (fun mcode i1 -> 
-        return (
-          A.SeqEnd mcode,
-          F.SeqEnd (level, i1)
-          ))
-
-  | A.ExprStatement (ea, ia1), F.ExprStatement (st, (Some eb, ii)) -> 
-      let ib1 = tuple_of_list1 ii in 
-      expression ea eb >>= (fun ea eb -> 
-      tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-        return (
-          A.ExprStatement (ea, ia1),
-          F.ExprStatement (st, (Some eb, [ib1]))
-        )
-      ))
-
-
-  | A.IfHeader (ia1,ia2, ea, ia3), F.IfHeader (st, (eb,ii)) -> 
-      let (ib1, ib2, ib3) = tuple_of_list3 ii in
-      expression ea eb >>= (fun ea eb -> 
-      tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-      tokenf ia2 ib2 >>= (fun ia2 ib2 -> 
-      tokenf ia3 ib3 >>= (fun ia3 ib3 -> 
-        return (
-          A.IfHeader (ia1, ia2, ea, ia3),
-          F.IfHeader (st, (eb,[ib1;ib2;ib3]))
-        )))))
-
-  | A.Else ia, F.Else ib -> 
-      tokenf ia ib >>= (fun ia ib -> 
-        return (A.Else ia, F.Else ib)
-      )
-
-  | A.WhileHeader (ia1, ia2, ea, ia3), F.WhileHeader (st, (eb, ii)) -> 
-      let (ib1, ib2, ib3) = tuple_of_list3 ii in
-      expression ea eb >>= (fun ea eb -> 
-      tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-      tokenf ia2 ib2 >>= (fun ia2 ib2 -> 
-      tokenf ia3 ib3 >>= (fun ia3 ib3 -> 
-        return (
-          A.WhileHeader (ia1, ia2, ea, ia3), 
-          F.WhileHeader (st, (eb, [ib1;ib2;ib3]))
-        )))))
-
-  | A.DoHeader ia, F.DoHeader (st, ib) -> 
-      tokenf ia ib >>= (fun ia ib -> 
-        return (
-          A.DoHeader ia, 
-          F.DoHeader (st, ib)
-        ))
-  | A.WhileTail (ia1,ia2,ea,ia3,ia4), F.DoWhileTail (eb, ii) -> 
-      let (ib1, ib2, ib3, ib4) = tuple_of_list4 ii in
-      expression ea eb >>= (fun ea eb -> 
-      tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-      tokenf ia2 ib2 >>= (fun ia2 ib2 -> 
-      tokenf ia3 ib3 >>= (fun ia3 ib3 -> 
-      tokenf ia4 ib4 >>= (fun ia4 ib4 -> 
-        return (
-          A.WhileTail (ia1,ia2,ea,ia3,ia4), 
-          F.DoWhileTail (eb, [ib1;ib2;ib3;ib4])
-        ))))))
-  | A.IteratorHeader (ia1, ia2, eas, ia3), F.MacroIterHeader (st, ((s,ebs),ii))
-      -> 
-      let (ib1, ib2, ib3) = tuple_of_list3 ii in
-
-      ident DontKnow ia1 (s, ib1) >>= (fun ia1 (s, ib1) -> 
-      tokenf ia2 ib2 >>= (fun ia2 ib2 -> 
-      tokenf ia3 ib3 >>= (fun ia3 ib3 -> 
-      arguments (seqstyle eas) (A.undots eas) ebs >>= (fun easundots ebs -> 
-       let eas = redots eas easundots in
-       return (
-         A.IteratorHeader (ia1, ia2, eas, ia3), 
-         F.MacroIterHeader (st, ((s,ebs), [ib1;ib2;ib3]))
-       )))))
-
-     
-
-  | A.ForHeader (ia1, ia2, ea1opt, ia3, ea2opt, ia4, ea3opt, ia5), 
-    F.ForHeader (st, (((eb1opt,ib3s), (eb2opt,ib4s), (eb3opt,ib4vide)), ii))
-    -> 
-      assert (null ib4vide);
-      let (ib1, ib2, ib5) = tuple_of_list3 ii in
-      let ib3 = tuple_of_list1 ib3s in
-      let ib4 = tuple_of_list1 ib4s in
-      
-      tokenf ia1 ib1 >>= (fun ia1 ib1 ->
-      tokenf ia2 ib2 >>= (fun ia2 ib2 ->
-      tokenf ia3 ib3 >>= (fun ia3 ib3 ->
-      tokenf ia4 ib4 >>= (fun ia4 ib4 ->
-      tokenf ia5 ib5 >>= (fun ia5 ib5 ->
-      option expression ea1opt eb1opt >>= (fun ea1opt eb1opt ->
-      option expression ea2opt eb2opt >>= (fun ea2opt eb2opt ->
-      option expression ea3opt eb3opt >>= (fun ea3opt eb3opt ->
-        return (
-          A.ForHeader (ia1, ia2, ea1opt, ia3, ea2opt, ia4, ea3opt, ia5),
-          F.ForHeader (st, (((eb1opt,[ib3]), (eb2opt,[ib4]), (eb3opt,[])),
-                           [ib1;ib2;ib5]))
-
-        )))))))))
-
-
-  | A.SwitchHeader(ia1,ia2,ea,ia3), F.SwitchHeader (st, (eb,ii)) ->
-      let (ib1, ib2, ib3) = tuple_of_list3 ii in
-      tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-      tokenf ia2 ib2 >>= (fun ia2 ib2 -> 
-      tokenf ia3 ib3 >>= (fun ia3 ib3 -> 
-      expression ea eb >>= (fun ea eb -> 
-        return (
-          A.SwitchHeader(ia1,ia2,ea,ia3), 
-          F.SwitchHeader (st, (eb,[ib1;ib2;ib3]))
-        )))))
-      
-  | A.Break (ia1, ia2), F.Break (st, ((),ii)) -> 
-      let (ib1, ib2) = tuple_of_list2 ii in
-      tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-      tokenf ia2 ib2 >>= (fun ia2 ib2 -> 
-        return (
-          A.Break (ia1, ia2), 
-          F.Break (st, ((),[ib1;ib2]))
-        )))
-
-  | A.Continue (ia1, ia2), F.Continue (st, ((),ii)) -> 
-      let (ib1, ib2) = tuple_of_list2 ii in
-      tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-      tokenf ia2 ib2 >>= (fun ia2 ib2 -> 
-        return (
-          A.Continue (ia1, ia2), 
-          F.Continue (st, ((),[ib1;ib2]))
-        )))
-
-  | A.Return (ia1, ia2), F.Return (st, ((),ii)) -> 
-      let (ib1, ib2) = tuple_of_list2 ii in
-      tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-      tokenf ia2 ib2 >>= (fun ia2 ib2 -> 
-        return (
-          A.Return (ia1, ia2), 
-          F.Return (st, ((),[ib1;ib2]))
-        )))
-
-  | A.ReturnExpr (ia1, ea, ia2), F.ReturnExpr (st, (eb, ii)) -> 
-      let (ib1, ib2) = tuple_of_list2 ii in
-      tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
-      tokenf ia2 ib2 >>= (fun ia2 ib2 -> 
-      expression ea eb >>= (fun ea eb -> 
-        return (
-          A.ReturnExpr (ia1, ea, ia2), 
-          F.ReturnExpr (st, (eb, [ib1;ib2]))
-        ))))
-
-
-
-  | A.Include(incla,filea), F.Include ((fileb, ii), (h_rel_pos, inifdef)) ->
-
-      let include_requirment = 
-        match mcodekind incla, mcodekind filea with
-        | A.CONTEXT (_, A.BEFORE _), _ -> 
-            IncludeMcodeBefore
-        | _, A.CONTEXT (_, A.AFTER _) -> 
-            IncludeMcodeAfter
-        | _ -> 
-            IncludeNothing
-      in
-
-      let (inclb, iifileb) = tuple_of_list2 ii in 
-      if inc_file (term filea, include_requirment) (fileb, h_rel_pos)
-      then 
-        tokenf incla inclb >>= (fun incla inclb -> 
-        tokenf filea iifileb >>= (fun filea iifileb -> 
-          return (
-            A.Include(incla, filea),
-            F.Include ((fileb, [inclb;iifileb]), (h_rel_pos, inifdef))
-          )))
-      else fail
-
-
-
-  | A.DefineHeader(definea,ida,params), F.DefineHeader ((idb, ii), defkind) ->
-      let (defineb, iidb, ieol) = tuple_of_list3 ii in
-      ident DontKnow ida (idb, iidb) >>= (fun ida (idb, iidb) -> 
-      tokenf definea defineb >>= (fun definea defineb -> 
-      (match A.unwrap params, defkind with
-      | A.NoParams, B.DefineVar -> 
-          return (
-            A.NoParams +> A.rewrap params, 
-            B.DefineVar
-          )
-      | A.DParams(lpa,eas,rpa), (B.DefineFunc (ebs, ii)) -> 
-          let (lpb, rpb) = tuple_of_list2 ii in
-          tokenf lpa lpb >>= (fun lpa lpb -> 
-          tokenf rpa rpb >>= (fun rpa rpb -> 
-
-          define_params (seqstyle eas) (A.undots eas) ebs >>= 
-            (fun easundots ebs -> 
-              let eas = redots eas easundots in
-              return (
-                A.DParams (lpa,eas,rpa) +> A.rewrap params,
-                B.DefineFunc (ebs,[lpb;rpb])
-                )
-            )))
-      | _ -> fail
-      ) >>= (fun params defkind -> 
-        return (
-          A.DefineHeader (definea, ida, params),
-          F.DefineHeader ((idb,[defineb;iidb;ieol]),defkind)
-        ))
-      ))
-
-
-  | A.Default(def,colon), F.Default (st, ((),ii)) -> 
-      let (ib1, ib2) = tuple_of_list2 ii in
-      tokenf def ib1 >>= (fun def ib1 -> 
-      tokenf colon ib2 >>= (fun colon ib2 -> 
-        return (
-          A.Default(def,colon), 
-          F.Default (st, ((),[ib1;ib2]))
-        )))
-
-      
-      
-  | A.Case(case,ea,colon), F.Case (st, (eb,ii)) -> 
-      let (ib1, ib2) = tuple_of_list2 ii in
-      tokenf case ib1 >>= (fun case ib1 -> 
-      expression ea eb >>= (fun ea eb -> 
-      tokenf colon ib2 >>= (fun colon ib2 -> 
-        return (
-          A.Case(case,ea,colon), 
-          F.Case (st, (eb,[ib1;ib2]))
-        ))))
-
-  (* only occurs in the predicates generated by asttomember *)
-  | A.DisjRuleElem eas, _ -> 
-      (eas +>
-      List.fold_left (fun acc ea -> acc >|+|> (rule_elem_node ea node)) fail)
-       >>= (fun ea eb -> return (A.unwrap ea,F.unwrap eb))
-
-  | _, F.ExprStatement (_, (None, ii)) -> fail (* happen ? *)
-
-  | A.Label(id,dd), F.Label (st,(s,ii)) ->
-      let (ib1,ib2) = tuple_of_list2 ii in
-      let (string_of_id,rebuild) =
-       match A.unwrap id with
-         A.Id(s) -> (s,function s -> A.rewrap id (A.Id(s)))
-       | _ -> failwith "labels with metavariables not supported" in
-      if (term string_of_id) =$= s
-      then
-       tokenf string_of_id ib1 >>= (fun string_of_id ib1 ->
-       tokenf dd ib2 >>= (fun dd ib2 ->
-         return (
-           A.Label(rebuild string_of_id,dd),
-           F.Label (st,(s,[ib1;ib2]))
-         )))
-      else fail
-
-  | A.Goto(goto,id,sem),          F.Goto (st,(s,ii))       ->
-      let (ib1,ib2,ib3) = tuple_of_list3 ii in
-      tokenf goto ib1 >>= (fun goto ib1 ->
-      ident DontKnow id (s, ib2) >>= (fun id (s, ib2) ->
-      tokenf sem ib3 >>= (fun sem ib3 ->
-       return(
-           A.Goto(goto,id,sem),
-            F.Goto (st,(s,[ib1;ib2;ib3]))
-          ))))
-
-  (* have not a counter part in coccinelle, for the moment *)
-  (* todo?: print a warning at least ? *)
-  | _, F.CaseRange _  
-  | _, F.Asm _
-  | _, F.Ifdef _
-  | _, F.MacroTop _
-    -> fail2()
-
-
-  | _, _ -> fail  
-  )
-end
-
similarity index 97%
rename from engine/.#ctlcocci_integration.ml.1.111
rename to engine/.#ctlcocci_integration.ml.1.116
index 5f736aa..134089c 100644 (file)
@@ -30,7 +30,7 @@ module F = Control_flow_c
 (* Debugging functions *)
 (*****************************************************************************)
 let show_or_not_predicate pred = 
-  if !Flag_engine.debug_engine then begin 
+  if !Flag_matcher.debug_engine then begin 
     indent_do (fun () -> 
       adjust_pp_with_indent_and_header "labeling: pred = " (fun () -> 
         Pretty_print_engine.pp_predicate pred;
@@ -39,7 +39,7 @@ let show_or_not_predicate pred =
   end
 
 let show_or_not_nodes nodes =
-  if !Flag_engine.debug_engine  then begin 
+  if !Flag_matcher.debug_engine  then begin 
     indent_do (fun () -> 
       adjust_pp_with_indent_and_header "labeling: result = " (fun () -> 
         Common.pp_do_in_box (fun () -> 
@@ -116,7 +116,7 @@ let (labels_for_ctl: string list (* dropped isos *) ->
 
       | Lib_engine.Match (re), _unwrapnode -> 
           let substs = 
-            Pattern3.match_re_node dropped_isos re node binding
+            Pattern_c.match_re_node dropped_isos re node binding
             +> List.map (fun (re', subst) -> 
               Lib_engine.Match (re'), subst
             )
@@ -400,14 +400,15 @@ let (mysat2:
   Lib_engine.model ->
   (Lib_engine.ctlcocci * (pred list list)) -> 
   (Lib_engine.mvar list*Lib_engine.metavars_binding) ->
-  (Lib_engine.transformation_info * bool * Lib_engine.metavars_binding list)) =
+  (Lib_engine.transformation_info * bool * Lib_engine.metavars_binding *
+     Lib_engine.metavars_binding list)) =
   fun (flow, label, states) ctl (used_after, binding) -> 
     let binding2 = metavars_binding_to_binding2 binding in
     let (triples,(trans_info2, returned_any_states, used_after_envs)) = 
       WRAPPED_ENGINE.satbis (flow, label, states) ctl (used_after, binding2)
     in
     if not (!Flag_parsing_cocci.sgrep_mode || !Flag.sgrep_mode2 ||
-            !Flag_engine.allow_inconsistent_paths)
+            !Flag_matcher.allow_inconsistent_paths)
     then Check_reachability.check_reachability triples flow;
     let (trans_info2,used_after_fresh_envs) =
       Postprocess_transinfo.process used_after binding2 trans_info2 in
@@ -416,7 +417,7 @@ let (mysat2:
     let trans_info = satbis_to_trans_info trans_info2 in
     let newbindings = List.map metavars_binding2_to_binding used_after_envs in
     let newbindings = List.map coalesce_positions newbindings in
-    (trans_info, returned_any_states, newbindings)
+    (trans_info, returned_any_states, binding, newbindings)
 
 let mysat a b c = 
   Common.profile_code "mysat" (fun () -> mysat2 a b c)
diff --git a/engine/.#pattern3.ml.1.56 b/engine/.#pattern3.ml.1.56
deleted file mode 100644 (file)
index 5b04d31..0000000
+++ /dev/null
@@ -1,467 +0,0 @@
-(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-* 
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-* 
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-* 
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
-* 
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
-
-open Common
-
-(*****************************************************************************)
-(* The functor argument  *) 
-(*****************************************************************************)
-
-(* info passed recursively in monad in addition to binding *)
-type xinfo = { 
-  optional_storage_iso : bool;
-  optional_qualifier_iso : bool;
-  value_format_iso : bool;
-}
-
-module XMATCH = struct
-
-  (* ------------------------------------------------------------------------*)
-  (* Combinators history *) 
-  (* ------------------------------------------------------------------------*)
-  (*
-   * version0: 
-   *   type ('a, 'b) matcher = 'a -> 'b -> bool
-   *
-   * version1: same but with a global variable holding the current binding
-   *  BUT bug
-   *   - can have multiple possibilities
-   *   - globals sux
-   *   - sometimes have to undo, cos if start match, then it binds, 
-   *     and if later it does not match, then must undo the first binds.
-   *     ex: when match parameters, can  try to match, but then we found far 
-   *     later that the last argument of a function does not match
-   *      => have to uando the binding !!!
-   *      (can handle that too with a global, by saving the 
-   *      global, ... but sux)
-   *   => better not use global
-   * 
-   * version2: 
-   *    type ('a, 'b) matcher = binding -> 'a -> 'b -> binding list
-   *
-   * Empty list mean failure (let matchfailure = []).
-   * To be able to have pretty code, have to use partial application 
-   * powa, and so the type is in fact
-   *
-   * version3:
-   *    type ('a, 'b) matcher =  'a -> 'b -> binding -> binding list
-   *
-   * Then by defining the correct combinators, can have quite pretty code (that
-   * looks like the clean code of version0).
-   * 
-   * opti: return a lazy list of possible matchs ?
-   * 
-   * version4: type tin = Lib_engine.metavars_binding
-   *)
-
-  (* ------------------------------------------------------------------------*)
-  (* Standard type and operators  *) 
-  (* ------------------------------------------------------------------------*)
-
-  type tin = { 
-    extra: xinfo;
-    binding: Lib_engine.metavars_binding;
-  }
-  (* 'x is a ('a * 'b) but in fact dont care about 'b, we just tag the SP *)
-  (* opti? use set instead of list *)
-  type 'x tout = ('x * Lib_engine.metavars_binding) list 
-
-  type ('a, 'b) matcher = 'a -> 'b  -> tin -> ('a * 'b) tout
-
-  (* was >&&> *)
-  let (>>=) m1 m2 = fun tin ->
-    let xs = m1 tin in
-    let xxs = xs +> List.map (fun ((a,b), binding) -> 
-      m2 a b {extra = tin.extra; binding = binding}
-    ) in
-    List.flatten xxs
-
-  (* Je compare les bindings retournés par les differentes branches.
-   * Si la deuxieme branche amene a des bindings qui sont deja presents
-   * dans la premiere branche, alors je ne les accepte pas.
-   * 
-   * update: still useful now that julia better handle Exp directly via
-   * ctl tricks using positions ?
-   *)
-  let (>|+|>) m1 m2 = fun tin -> 
-(* CHOICE
-      let xs = m1 tin in
-      if null xs
-      then m2 tin
-      else xs
-*)
-    let res1 = m1 tin in
-    let res2 = m2 tin in
-    let list_bindings_already = List.map snd res1 in
-    res1 ++ 
-      (res2 +> List.filter (fun (x, binding) -> 
-        not 
-          (list_bindings_already +> List.exists (fun already -> 
-            Lib_engine.equal_binding binding already))
-      ))
-
-          
-     
-      
-  let (>||>) m1 m2 = fun tin ->
-(* CHOICE
-      let xs = m1 tin in
-      if null xs
-      then m2 tin
-      else xs
-*)
-    (* opti? use set instead of list *)
-    m1 tin ++ m2 tin
-
-
-  let return res = fun tin -> 
-    [res, tin.binding]
-
-  let fail = fun tin -> 
-    []
-
-  let (>&&>) f m = fun tin -> 
-    if f tin
-    then m tin
-    else fail tin
-
-
-  let mode = Cocci_vs_c_3.PatternMode
-
-  (* ------------------------------------------------------------------------*)
-  (* Exp  *) 
-  (* ------------------------------------------------------------------------*)
-  let cocciExp = fun expf expa node -> fun tin -> 
-
-    let globals = ref [] in
-    let bigf = { 
-      (* julia's style *)
-      Visitor_c.default_visitor_c with 
-      Visitor_c.kexpr = (fun (k, bigf) expb ->
-       match expf expa expb tin with
-       | [] -> (* failed *) k expb
-       | xs -> 
-            globals := xs @ !globals; 
-            if not !Flag_engine.disallow_nested_exps then k expb (* CHOICE *)
-      );
-      (* pad's style.
-       * push2 expr globals;  k expr
-       *  ...
-       *  !globals +> List.fold_left (fun acc e -> acc >||> match_e_e expr e) 
-       * (return false)
-       * 
-       *)
-    }
-    in
-    Visitor_c.vk_node bigf node;
-    !globals +> List.map (fun ((a, _exp), binding) -> 
-      (a, node), binding
-    )
-
-  (* same as cocciExp, but for expressions in an expression, not expressions
-     in a node *)
-  let cocciExpExp = fun expf expa expb -> fun tin -> 
-
-    let globals = ref [] in
-    let bigf = { 
-      (* julia's style *)
-      Visitor_c.default_visitor_c with 
-      Visitor_c.kexpr = (fun (k, bigf) expb ->
-       match expf expa expb tin with
-       | [] -> (* failed *) k expb
-       | xs -> 
-            globals := xs @ !globals; 
-            if not !Flag_engine.disallow_nested_exps then k expb (* CHOICE *)
-      );
-      (* pad's style.
-       * push2 expr globals;  k expr
-       *  ...
-       *  !globals +> List.fold_left (fun acc e -> acc >||> match_e_e expr e) 
-       * (return false)
-       * 
-       *)
-    }
-    in
-    Visitor_c.vk_expr bigf expb;
-    !globals +> List.map (fun ((a, _exp), binding) -> 
-      (a, expb), binding
-    )
-
-  let cocciTy = fun expf expa node -> fun tin -> 
-
-    let globals = ref [] in
-    let bigf = { 
-      Visitor_c.default_visitor_c with 
-        Visitor_c.ktype = (fun (k, bigf) expb -> 
-       match expf expa expb tin with
-       | [] -> (* failed *) k expb
-       | xs -> globals := xs @ !globals);
-
-    } 
-    in
-    Visitor_c.vk_node bigf node;
-    !globals +> List.map (fun ((a, _exp), binding) -> 
-      (a, node), binding
-    )
-
-
-  (* ------------------------------------------------------------------------*)
-  (* Distribute mcode *) 
-  (* ------------------------------------------------------------------------*)
-  let tag_mck_pos mck posmck =
-    match mck with 
-    | Ast_cocci.PLUS -> Ast_cocci.PLUS
-    | Ast_cocci.CONTEXT (pos, xs) -> 
-        assert (pos = Ast_cocci.NoPos || pos = Ast_cocci.DontCarePos);
-        Ast_cocci.CONTEXT (posmck, xs)
-    | Ast_cocci.MINUS (pos, xs) -> 
-        assert (pos = Ast_cocci.NoPos || pos = Ast_cocci.DontCarePos);
-        Ast_cocci.MINUS (posmck, xs)
-  
-
-  let tag_mck_pos_mcode (x,info,mck,pos) posmck stuff = fun tin -> 
-    [((x, info, tag_mck_pos mck posmck, pos),stuff), tin.binding]
-    
-
-  let distrf (ii_of_x_f) =
-    fun mcode x -> fun tin -> 
-    let (max, min) = Lib_parsing_c.max_min_by_pos (ii_of_x_f x)
-    in
-    let posmck = Ast_cocci.FixPos (min, max) (* subtil: and not max, min !!*) 
-    in
-    tag_mck_pos_mcode mcode posmck x tin
-
-  let distrf_e    = distrf (Lib_parsing_c.ii_of_expr)
-  let distrf_args = distrf (Lib_parsing_c.ii_of_args)
-  let distrf_type = distrf (Lib_parsing_c.ii_of_type)
-  let distrf_param = distrf (Lib_parsing_c.ii_of_param)
-  let distrf_params = distrf (Lib_parsing_c.ii_of_params)
-  let distrf_ini   = distrf (Lib_parsing_c.ii_of_ini)
-  let distrf_node   = distrf (Lib_parsing_c.ii_of_node)
-  let distrf_struct_fields   = distrf (Lib_parsing_c.ii_of_struct_fields)
-  let distrf_cst = distrf (Lib_parsing_c.ii_of_cst)
-  let distrf_define_params = distrf (Lib_parsing_c.ii_of_define_params)
-
-
-  (* ------------------------------------------------------------------------*)
-  (* Constraints on metavariable values *) 
-  (* ------------------------------------------------------------------------*)
-  let check_constraints matcher constraints exp = fun f tin ->
-    let rec loop = function
-       [] -> f () tin (* success *)
-      |        c::cs ->
-         match matcher c exp tin with
-           [] (* failure *) -> loop cs
-         | _ (* success *) -> fail tin in
-    loop constraints
-
-  let check_pos_constraints constraints pvalu f tin =
-    check_constraints
-      (fun c exp tin ->
-       let success = [[]] in
-       let failure = [] in
-       (match Common.optionise (fun () -> tin.binding +> List.assoc c) with
-         Some valu' ->
-           if Cocci_vs_c_3.equal_metavarval exp valu'
-           then success else failure
-       | None ->
-           (* if the variable is not there, it puts no constraints *)
-           (* not sure this is still useful *)
-           failure))
-      constraints pvalu f tin
-
-  (* ------------------------------------------------------------------------*)
-  (* Environment *) 
-  (* ------------------------------------------------------------------------*)
-  (* pre: if have declared a new metavar that hide another one, then
-   * must be passed with a binding that deleted this metavar
-   * 
-   * Here we dont use the keep argument of julia. cf f(X,X), J'ai
-   * besoin de garder le X en interne, meme si julia s'en fout elle du
-   * X et qu'elle a mis X a DontSaved.
-   *)
-  let check_add_metavars_binding strip _keep inherited = fun (k, valu) tin ->
-    (match Common.optionise (fun () -> tin.binding +> List.assoc k) with
-    | Some (valu') ->
-        if Cocci_vs_c_3.equal_metavarval valu valu'
-        then Some tin.binding
-        else None
-
-    | None ->
-        if inherited 
-        then None
-        else 
-          let valu' = 
-            match valu with
-              Ast_c.MetaIdVal a        -> Ast_c.MetaIdVal a
-            | Ast_c.MetaFuncVal a      -> Ast_c.MetaFuncVal a
-            | Ast_c.MetaLocalFuncVal a -> Ast_c.MetaLocalFuncVal a (*more?*)
-            | Ast_c.MetaExprVal a -> 
-                Ast_c.MetaExprVal
-                 (if strip
-                 then Lib_parsing_c.al_expr a
-                 else Lib_parsing_c.semi_al_expr a)
-            | Ast_c.MetaExprListVal a ->  
-                Ast_c.MetaExprListVal
-                 (if strip
-                 then Lib_parsing_c.al_arguments a
-                 else Lib_parsing_c.semi_al_arguments a)
-                 
-            | Ast_c.MetaStmtVal a -> 
-                Ast_c.MetaStmtVal
-                 (if strip
-                 then Lib_parsing_c.al_statement a
-                 else Lib_parsing_c.semi_al_statement a)
-            | Ast_c.MetaTypeVal a -> 
-                Ast_c.MetaTypeVal
-                 (if strip
-                 then Lib_parsing_c.al_type a
-                 else Lib_parsing_c.semi_al_type a)
-
-            | Ast_c.MetaListlenVal a -> Ast_c.MetaListlenVal a
-
-            | Ast_c.MetaParamVal a -> failwith "not handling MetaParamVal"
-            | Ast_c.MetaParamListVal a -> 
-                Ast_c.MetaParamListVal
-                 (if strip
-                 then Lib_parsing_c.al_params a
-                 else Lib_parsing_c.semi_al_params a)
-
-            | Ast_c.MetaPosVal (pos1,pos2) -> Ast_c.MetaPosVal (pos1,pos2)
-            | Ast_c.MetaPosValList l -> Ast_c.MetaPosValList l
-          in Some (tin.binding +> Common.insert_assoc (k, valu'))
-    )
-
-  let envf keep inherited = fun (k, valu, get_max_min) f tin ->
-    let x = Ast_cocci.unwrap_mcode k in
-    match check_add_metavars_binding true keep inherited (x, valu) tin with
-    | Some binding ->
-       let new_tin = {extra = tin.extra; binding = binding} in
-       (match Ast_cocci.get_pos_var k with
-         Ast_cocci.MetaPos(name,constraints,per,keep,inherited) ->
-           let pvalu =
-             let (file,min,max) = get_max_min() in
-             Ast_c.MetaPosValList[(file,min,max)] in
-           (* check constraints.  success means that there is a match with
-              one of the constraints, which will ultimately result in
-              failure. *)
-           check_pos_constraints constraints pvalu
-             (function () ->
-               (* constraints are satisfied, now see if we are compatible
-                  with existing bindings *)
-               function new_tin ->
-                 let x = Ast_cocci.unwrap_mcode name in
-                 (match
-                   check_add_metavars_binding false keep inherited (x, pvalu)
-                     new_tin with
-                 | Some binding ->
-                     f () {extra = new_tin.extra; binding = binding}
-                 | None -> fail tin))
-             new_tin
-       | Ast_cocci.NoMetaPos -> f () new_tin)
-    | None -> fail tin
-
-  (* ------------------------------------------------------------------------*)
-  (* Environment, allbounds *) 
-  (* ------------------------------------------------------------------------*)
-  (* all referenced inherited variables have to be bound. This would
-   * be naturally checked for the minus or context ones in the
-   * matching process, but have to check the plus ones as well. The
-   * result of get_inherited contains all of these, but the potential
-   * redundant checking for the minus and context ones is probably not
-   * a big deal. If it's a problem, could fix free_vars to distinguish
-   * between + variables and the other ones. *)
-
-  let (all_bound : Ast_cocci.meta_name list -> tin -> bool) = fun l tin ->
-    l +> List.for_all (fun inhvar -> 
-      match Common.optionise (fun () -> tin.binding +> List.assoc inhvar) with
-      | Some _ -> true
-      | None -> false
-    )
-
-  let optional_storage_flag f = fun tin -> 
-    f (tin.extra.optional_storage_iso) tin
-
-  let optional_qualifier_flag f = fun tin -> 
-    f (tin.extra.optional_qualifier_iso) tin
-
-  let value_format_flag f = fun tin -> 
-    f (tin.extra.value_format_iso) tin
-
-
-  (* ------------------------------------------------------------------------*)
-  (* Tokens *) 
-  (* ------------------------------------------------------------------------*)
-  let tokenf ia ib = fun tin ->
-    let pos = Ast_c.info_to_fixpos ib in
-    let posmck = Ast_cocci.FixPos (pos, pos) in
-    let finish tin = tag_mck_pos_mcode ia posmck ib tin in
-    match Ast_cocci.get_pos_var ia with
-      Ast_cocci.MetaPos(name,constraints,per,keep,inherited) ->
-       let mpos = Lib_parsing_c.lin_col_by_pos [ib] in
-       let pvalu = Ast_c.MetaPosValList [mpos] in
-       check_pos_constraints constraints pvalu
-         (function () ->
-           (* constraints are satisfied, now see if we are compatible
-              with existing bindings *)
-           function new_tin ->
-             let x = Ast_cocci.unwrap_mcode name in
-             (match
-               check_add_metavars_binding false keep inherited (x, pvalu) tin
-             with
-               Some binding -> finish {extra = tin.extra; binding = binding}
-             | None -> fail tin))
-         tin
-    | _ -> finish tin
-
-  let tokenf_mck mck ib = fun tin -> 
-    let pos = Ast_c.info_to_fixpos ib in
-    let posmck = Ast_cocci.FixPos (pos, pos) in
-    [(tag_mck_pos mck posmck, ib), tin.binding]
-    
-end
-
-(*****************************************************************************)
-(* Entry point  *) 
-(*****************************************************************************)
-module MATCH  = Cocci_vs_c_3.COCCI_VS_C (XMATCH)
-
-
-let match_re_node2 dropped_isos a b binding = 
-
-  let tin = { 
-    XMATCH.extra = {
-      optional_storage_iso   = not(List.mem "optional_storage"   dropped_isos);
-      optional_qualifier_iso = not(List.mem "optional_qualifier" dropped_isos);
-      value_format_iso       = not(List.mem "value_format"       dropped_isos);
-    };
-    XMATCH.binding = binding;
-  } in
-
-  MATCH.rule_elem_node a b tin
-  (* take only the tagged-SP, the 'a' *)
-  +> List.map (fun ((a,_b), binding) -> a, binding)
-
-
-let match_re_node a b c d = 
-  Common.profile_code "Pattern3.match_re_node" 
-    (fun () -> match_re_node2 a b c d)
diff --git a/engine/.#pattern3.ml.1.57 b/engine/.#pattern3.ml.1.57
deleted file mode 100644 (file)
index 9a7c6ce..0000000
+++ /dev/null
@@ -1,476 +0,0 @@
-(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-* 
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-* 
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-* 
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
-* 
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
-
-open Common
-
-(*****************************************************************************)
-(* The functor argument  *) 
-(*****************************************************************************)
-
-(* info passed recursively in monad in addition to binding *)
-type xinfo = { 
-  optional_storage_iso : bool;
-  optional_qualifier_iso : bool;
-  value_format_iso : bool;
-}
-
-module XMATCH = struct
-
-  (* ------------------------------------------------------------------------*)
-  (* Combinators history *) 
-  (* ------------------------------------------------------------------------*)
-  (*
-   * version0: 
-   *   type ('a, 'b) matcher = 'a -> 'b -> bool
-   *
-   * version1: same but with a global variable holding the current binding
-   *  BUT bug
-   *   - can have multiple possibilities
-   *   - globals sux
-   *   - sometimes have to undo, cos if start match, then it binds, 
-   *     and if later it does not match, then must undo the first binds.
-   *     ex: when match parameters, can  try to match, but then we found far 
-   *     later that the last argument of a function does not match
-   *      => have to uando the binding !!!
-   *      (can handle that too with a global, by saving the 
-   *      global, ... but sux)
-   *   => better not use global
-   * 
-   * version2: 
-   *    type ('a, 'b) matcher = binding -> 'a -> 'b -> binding list
-   *
-   * Empty list mean failure (let matchfailure = []).
-   * To be able to have pretty code, have to use partial application 
-   * powa, and so the type is in fact
-   *
-   * version3:
-   *    type ('a, 'b) matcher =  'a -> 'b -> binding -> binding list
-   *
-   * Then by defining the correct combinators, can have quite pretty code (that
-   * looks like the clean code of version0).
-   * 
-   * opti: return a lazy list of possible matchs ?
-   * 
-   * version4: type tin = Lib_engine.metavars_binding
-   *)
-
-  (* ------------------------------------------------------------------------*)
-  (* Standard type and operators  *) 
-  (* ------------------------------------------------------------------------*)
-
-  type tin = { 
-    extra: xinfo;
-    binding: Lib_engine.metavars_binding;
-    binding0: Lib_engine.metavars_binding; (* inherited bindings *)
-  }
-  (* 'x is a ('a * 'b) but in fact dont care about 'b, we just tag the SP *)
-  (* opti? use set instead of list *)
-  type 'x tout = ('x * Lib_engine.metavars_binding) list 
-
-  type ('a, 'b) matcher = 'a -> 'b  -> tin -> ('a * 'b) tout
-
-  (* was >&&> *)
-  let (>>=) m1 m2 = fun tin ->
-    let xs = m1 tin in
-    let xxs = xs +> List.map (fun ((a,b), binding) -> 
-      m2 a b {tin with binding = binding}
-    ) in
-    List.flatten xxs
-
-  (* Je compare les bindings retournés par les differentes branches.
-   * Si la deuxieme branche amene a des bindings qui sont deja presents
-   * dans la premiere branche, alors je ne les accepte pas.
-   * 
-   * update: still useful now that julia better handle Exp directly via
-   * ctl tricks using positions ?
-   *)
-  let (>|+|>) m1 m2 = fun tin -> 
-(* CHOICE
-      let xs = m1 tin in
-      if null xs
-      then m2 tin
-      else xs
-*)
-    let res1 = m1 tin in
-    let res2 = m2 tin in
-    let list_bindings_already = List.map snd res1 in
-    res1 ++ 
-      (res2 +> List.filter (fun (x, binding) -> 
-        not 
-          (list_bindings_already +> List.exists (fun already -> 
-            Lib_engine.equal_binding binding already))
-      ))
-
-          
-     
-      
-  let (>||>) m1 m2 = fun tin ->
-(* CHOICE
-      let xs = m1 tin in
-      if null xs
-      then m2 tin
-      else xs
-*)
-    (* opti? use set instead of list *)
-    m1 tin ++ m2 tin
-
-
-  let return res = fun tin -> 
-    [res, tin.binding]
-
-  let fail = fun tin -> 
-    []
-
-  let (>&&>) f m = fun tin -> 
-    if f tin
-    then m tin
-    else fail tin
-
-
-  let mode = Cocci_vs_c_3.PatternMode
-
-  (* ------------------------------------------------------------------------*)
-  (* Exp  *) 
-  (* ------------------------------------------------------------------------*)
-  let cocciExp = fun expf expa node -> fun tin -> 
-
-    let globals = ref [] in
-    let bigf = { 
-      (* julia's style *)
-      Visitor_c.default_visitor_c with 
-      Visitor_c.kexpr = (fun (k, bigf) expb ->
-       match expf expa expb tin with
-       | [] -> (* failed *) k expb
-       | xs -> 
-            globals := xs @ !globals; 
-            if not !Flag_engine.disallow_nested_exps then k expb (* CHOICE *)
-      );
-      (* pad's style.
-       * push2 expr globals;  k expr
-       *  ...
-       *  !globals +> List.fold_left (fun acc e -> acc >||> match_e_e expr e) 
-       * (return false)
-       * 
-       *)
-    }
-    in
-    Visitor_c.vk_node bigf node;
-    !globals +> List.map (fun ((a, _exp), binding) -> 
-      (a, node), binding
-    )
-
-  (* same as cocciExp, but for expressions in an expression, not expressions
-     in a node *)
-  let cocciExpExp = fun expf expa expb -> fun tin -> 
-
-    let globals = ref [] in
-    let bigf = { 
-      (* julia's style *)
-      Visitor_c.default_visitor_c with 
-      Visitor_c.kexpr = (fun (k, bigf) expb ->
-       match expf expa expb tin with
-       | [] -> (* failed *) k expb
-       | xs -> 
-            globals := xs @ !globals; 
-            if not !Flag_engine.disallow_nested_exps then k expb (* CHOICE *)
-      );
-      (* pad's style.
-       * push2 expr globals;  k expr
-       *  ...
-       *  !globals +> List.fold_left (fun acc e -> acc >||> match_e_e expr e) 
-       * (return false)
-       * 
-       *)
-    }
-    in
-    Visitor_c.vk_expr bigf expb;
-    !globals +> List.map (fun ((a, _exp), binding) -> 
-      (a, expb), binding
-    )
-
-  let cocciTy = fun expf expa node -> fun tin -> 
-
-    let globals = ref [] in
-    let bigf = { 
-      Visitor_c.default_visitor_c with 
-        Visitor_c.ktype = (fun (k, bigf) expb -> 
-       match expf expa expb tin with
-       | [] -> (* failed *) k expb
-       | xs -> globals := xs @ !globals);
-
-    } 
-    in
-    Visitor_c.vk_node bigf node;
-    !globals +> List.map (fun ((a, _exp), binding) -> 
-      (a, node), binding
-    )
-
-
-  (* ------------------------------------------------------------------------*)
-  (* Distribute mcode *) 
-  (* ------------------------------------------------------------------------*)
-  let tag_mck_pos mck posmck =
-    match mck with 
-    | Ast_cocci.PLUS -> Ast_cocci.PLUS
-    | Ast_cocci.CONTEXT (pos, xs) -> 
-        assert (pos = Ast_cocci.NoPos || pos = Ast_cocci.DontCarePos);
-        Ast_cocci.CONTEXT (posmck, xs)
-    | Ast_cocci.MINUS (pos, xs) -> 
-        assert (pos = Ast_cocci.NoPos || pos = Ast_cocci.DontCarePos);
-        Ast_cocci.MINUS (posmck, xs)
-  
-
-  let tag_mck_pos_mcode (x,info,mck,pos) posmck stuff = fun tin -> 
-    [((x, info, tag_mck_pos mck posmck, pos),stuff), tin.binding]
-    
-
-  let distrf (ii_of_x_f) =
-    fun mcode x -> fun tin -> 
-    let (max, min) = Lib_parsing_c.max_min_by_pos (ii_of_x_f x)
-    in
-    let posmck = Ast_cocci.FixPos (min, max) (* subtil: and not max, min !!*) 
-    in
-    tag_mck_pos_mcode mcode posmck x tin
-
-  let distrf_e    = distrf (Lib_parsing_c.ii_of_expr)
-  let distrf_args = distrf (Lib_parsing_c.ii_of_args)
-  let distrf_type = distrf (Lib_parsing_c.ii_of_type)
-  let distrf_param = distrf (Lib_parsing_c.ii_of_param)
-  let distrf_params = distrf (Lib_parsing_c.ii_of_params)
-  let distrf_ini   = distrf (Lib_parsing_c.ii_of_ini)
-  let distrf_node   = distrf (Lib_parsing_c.ii_of_node)
-  let distrf_struct_fields   = distrf (Lib_parsing_c.ii_of_struct_fields)
-  let distrf_cst = distrf (Lib_parsing_c.ii_of_cst)
-  let distrf_define_params = distrf (Lib_parsing_c.ii_of_define_params)
-
-
-  (* ------------------------------------------------------------------------*)
-  (* Constraints on metavariable values *) 
-  (* ------------------------------------------------------------------------*)
-  let check_constraints matcher constraints exp = fun f tin ->
-    let rec loop = function
-       [] -> f () tin (* success *)
-      |        c::cs ->
-         match matcher c exp tin with
-           [] (* failure *) -> loop cs
-         | _ (* success *) -> fail tin in
-    loop constraints
-
-  let check_pos_constraints constraints pvalu f tin =
-    check_constraints
-      (fun c exp tin ->
-       let success = [[]] in
-       let failure = [] in
-       (* relies on the fact that constraints on pos variables must refer to
-          inherited variables *)
-       (match Common.optionise (fun () -> tin.binding0 +> List.assoc c) with
-         Some valu' ->
-           if Cocci_vs_c_3.equal_metavarval exp valu'
-           then success else failure
-       | None ->
-           (* if the variable is not there, it puts no constraints *)
-           (* not sure this is still useful *)
-           failure))
-      constraints pvalu f tin
-
-  (* ------------------------------------------------------------------------*)
-  (* Environment *) 
-  (* ------------------------------------------------------------------------*)
-  (* pre: if have declared a new metavar that hide another one, then
-   * must be passed with a binding that deleted this metavar
-   * 
-   * Here we dont use the keep argument of julia. cf f(X,X), J'ai
-   * besoin de garder le X en interne, meme si julia s'en fout elle du
-   * X et qu'elle a mis X a DontSaved.
-   *)
-  let check_add_metavars_binding strip _keep inherited = fun (k, valu) tin ->
-    if inherited
-    then
-      match Common.optionise (fun () -> tin.binding0 +> List.assoc k) with
-      | Some (valu') ->
-          if Cocci_vs_c_3.equal_metavarval valu valu'
-          then Some tin.binding
-          else None
-      |        None -> None
-    else
-      match Common.optionise (fun () -> tin.binding +> List.assoc k) with
-      | Some (valu') ->
-          if Cocci_vs_c_3.equal_metavarval valu valu'
-          then Some tin.binding
-          else None
-             
-      | None ->
-          let valu' = 
-            match valu with
-              Ast_c.MetaIdVal a        -> Ast_c.MetaIdVal a
-            | Ast_c.MetaFuncVal a      -> Ast_c.MetaFuncVal a
-            | Ast_c.MetaLocalFuncVal a -> Ast_c.MetaLocalFuncVal a (*more?*)
-            | Ast_c.MetaExprVal a -> 
-               Ast_c.MetaExprVal
-                 (if strip
-                 then Lib_parsing_c.al_expr a
-                 else Lib_parsing_c.semi_al_expr a)
-            | Ast_c.MetaExprListVal a ->  
-               Ast_c.MetaExprListVal
-                 (if strip
-                 then Lib_parsing_c.al_arguments a
-                 else Lib_parsing_c.semi_al_arguments a)
-                 
-            | Ast_c.MetaStmtVal a -> 
-               Ast_c.MetaStmtVal
-                 (if strip
-                 then Lib_parsing_c.al_statement a
-                 else Lib_parsing_c.semi_al_statement a)
-            | Ast_c.MetaTypeVal a -> 
-               Ast_c.MetaTypeVal
-                 (if strip
-                 then Lib_parsing_c.al_type a
-                 else Lib_parsing_c.semi_al_type a)
-                 
-            | Ast_c.MetaListlenVal a -> Ast_c.MetaListlenVal a
-                 
-            | Ast_c.MetaParamVal a -> failwith "not handling MetaParamVal"
-            | Ast_c.MetaParamListVal a -> 
-               Ast_c.MetaParamListVal
-                 (if strip
-                 then Lib_parsing_c.al_params a
-                 else Lib_parsing_c.semi_al_params a)
-                 
-            | Ast_c.MetaPosVal (pos1,pos2) -> Ast_c.MetaPosVal (pos1,pos2)
-            | Ast_c.MetaPosValList l -> Ast_c.MetaPosValList l
-          in Some (tin.binding +> Common.insert_assoc (k, valu'))
-
-  let envf keep inherited = fun (k, valu, get_max_min) f tin ->
-    let x = Ast_cocci.unwrap_mcode k in
-    match check_add_metavars_binding true keep inherited (x, valu) tin with
-    | Some binding ->
-       let new_tin = {tin with binding = binding} in
-       (match Ast_cocci.get_pos_var k with
-         Ast_cocci.MetaPos(name,constraints,per,keep,inherited) ->
-           let pvalu =
-             let (file,min,max) = get_max_min() in
-             Ast_c.MetaPosValList[(file,min,max)] in
-           (* check constraints.  success means that there is a match with
-              one of the constraints, which will ultimately result in
-              failure. *)
-           check_pos_constraints constraints pvalu
-             (function () ->
-               (* constraints are satisfied, now see if we are compatible
-                  with existing bindings *)
-               function new_tin ->
-                 let x = Ast_cocci.unwrap_mcode name in
-                 (match
-                   check_add_metavars_binding false keep inherited (x, pvalu)
-                     new_tin with
-                 | Some binding ->
-                     f () {new_tin with binding = binding}
-                 | None -> fail tin))
-             new_tin
-       | Ast_cocci.NoMetaPos -> f () new_tin)
-    | None -> fail tin
-
-  (* ------------------------------------------------------------------------*)
-  (* Environment, allbounds *) 
-  (* ------------------------------------------------------------------------*)
-  (* all referenced inherited variables have to be bound. This would
-   * be naturally checked for the minus or context ones in the
-   * matching process, but have to check the plus ones as well. The
-   * result of get_inherited contains all of these, but the potential
-   * redundant checking for the minus and context ones is probably not
-   * a big deal. If it's a problem, could fix free_vars to distinguish
-   * between + variables and the other ones. *)
-
-  let (all_bound : Ast_cocci.meta_name list -> tin -> bool) = fun l tin ->
-    l +> List.for_all (fun inhvar -> 
-      match Common.optionise (fun () -> tin.binding0 +> List.assoc inhvar) with
-      | Some _ -> true
-      | None -> false
-    )
-
-  let optional_storage_flag f = fun tin -> 
-    f (tin.extra.optional_storage_iso) tin
-
-  let optional_qualifier_flag f = fun tin -> 
-    f (tin.extra.optional_qualifier_iso) tin
-
-  let value_format_flag f = fun tin -> 
-    f (tin.extra.value_format_iso) tin
-
-
-  (* ------------------------------------------------------------------------*)
-  (* Tokens *) 
-  (* ------------------------------------------------------------------------*)
-  let tokenf ia ib = fun tin ->
-    let pos = Ast_c.info_to_fixpos ib in
-    let posmck = Ast_cocci.FixPos (pos, pos) in
-    let finish tin = tag_mck_pos_mcode ia posmck ib tin in
-    match Ast_cocci.get_pos_var ia with
-      Ast_cocci.MetaPos(name,constraints,per,keep,inherited) ->
-       let mpos = Lib_parsing_c.lin_col_by_pos [ib] in
-       let pvalu = Ast_c.MetaPosValList [mpos] in
-       check_pos_constraints constraints pvalu
-         (function () ->
-           (* constraints are satisfied, now see if we are compatible
-              with existing bindings *)
-           function new_tin ->
-             let x = Ast_cocci.unwrap_mcode name in
-             (match
-               check_add_metavars_binding false keep inherited (x, pvalu) tin
-             with
-               Some binding -> finish {tin with binding = binding}
-             | None -> fail tin))
-         tin
-    | _ -> finish tin
-
-  let tokenf_mck mck ib = fun tin -> 
-    let pos = Ast_c.info_to_fixpos ib in
-    let posmck = Ast_cocci.FixPos (pos, pos) in
-    [(tag_mck_pos mck posmck, ib), tin.binding]
-    
-end
-
-(*****************************************************************************)
-(* Entry point  *) 
-(*****************************************************************************)
-module MATCH  = Cocci_vs_c_3.COCCI_VS_C (XMATCH)
-
-
-let match_re_node2 dropped_isos a b binding0 = 
-
-  let tin = { 
-    XMATCH.extra = {
-      optional_storage_iso   = not(List.mem "optional_storage"   dropped_isos);
-      optional_qualifier_iso = not(List.mem "optional_qualifier" dropped_isos);
-      value_format_iso       = not(List.mem "value_format"       dropped_isos);
-    };
-    XMATCH.binding = [];
-    XMATCH.binding0 = binding0;
-  } in
-
-  MATCH.rule_elem_node a b tin
-  (* take only the tagged-SP, the 'a' *)
-  +> List.map (fun ((a,_b), binding) -> a, binding)
-
-
-let match_re_node a b c d = 
-  Common.profile_code "Pattern3.match_re_node" 
-    (fun () -> match_re_node2 a b c d)
diff --git a/engine/.#postprocess_transinfo.ml.1.12 b/engine/.#postprocess_transinfo.ml.1.12
new file mode 100644 (file)
index 0000000..89b30b7
--- /dev/null
@@ -0,0 +1,105 @@
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+* 
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+* 
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
+* 
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+(* two goals: first drop from the environments things that are not used,
+   and second prompt for the names of fresh variables that are used *)
+
+(* have to add in the whole inherited env because inherited variables are
+not returned by get_fvs.  It would be better if that were the case, but
+since at the moment I think we can only inherit one value per variable,
+perhaps it doesn't matter - these bindings will always be the same no matter
+how we reached a particular match *)
+
+module Ast = Ast_cocci
+
+let extra_counter = ref 0
+let get_extra _ =
+  let ctr = !extra_counter in
+  extra_counter := !extra_counter + 1;
+  "__extra_counter__"^(string_of_int ctr)
+
+let read_fresh_id () =
+  try 
+    let s = read_line () in
+    match Parse_c.tokens_string s with
+      [Parser_c.TIdent _; Parser_c.EOF _] -> s
+    | _ -> failwith ("wrong fresh id: " ^ s)
+  with End_of_file -> get_extra()
+
+let get_vars = function
+    Lib_engine.Match(re) -> (Ast.get_fvs re, Ast.get_fresh re)
+  | _ -> ([],[])
+
+let string2val str = Lib_engine.NormalMetaVal(Ast_c.MetaIdVal(str))
+
+(* ----------------------------------------------------------------------- *)
+(* Get values for fresh variables *)
+
+let process_tree inherited_env l =
+  let (all_fresh,local_freshs,new_triples) =
+    List.fold_left
+      (function (all_fresh,local_freshs,new_triples) ->
+       function (node,env,pred) ->
+         let (other,fresh) = get_vars pred in
+         let env = List.filter (function (x,_) -> List.mem x other) env in
+         (Common.union_set fresh all_fresh,
+          fresh::local_freshs,
+          (node,env@inherited_env,pred)::new_triples))
+      ([],[],[]) l in
+  let local_freshs = List.rev local_freshs in
+  let new_triples = List.rev new_triples in
+  let fresh_env =
+    List.map
+      (function ((r,n) as fresh) ->
+       Printf.printf "%s: name for %s: " r n; (* not debugging code!!! *)
+       flush stdout;
+       (fresh,string2val(read_fresh_id())))
+      all_fresh in
+  let (_,res) =
+    List.split
+      (List.fold_left
+        (function freshs_node_env_preds ->
+          function (fresh,_) as elem ->
+            List.map
+              (function (freshs,((node,env,pred) as cur)) ->
+                if List.mem fresh freshs
+                then (freshs,(node,elem::env,pred))
+                else (freshs,cur))
+              freshs_node_env_preds)
+        (List.combine local_freshs new_triples)
+        fresh_env) in
+  (List.rev res, fresh_env)
+
+(* ----------------------------------------------------------------------- *)
+(* Create the environment to be used afterwards *)
+
+let collect_used_after used_after envs =
+  List.map (List.filter (function (v,vl) -> List.mem v used_after)) envs
+
+(* ----------------------------------------------------------------------- *)
+(* entry point *)
+
+let process used_after inherited_env l =
+  extra_counter := 0;
+  let (trees, fresh_envs) =
+    List.split (List.map (process_tree inherited_env) l) in
+  (Common.uniq(List.concat trees), collect_used_after used_after fresh_envs)
diff --git a/engine/.#pretty_print_engine.ml.1.42 b/engine/.#pretty_print_engine.ml.1.42
new file mode 100644 (file)
index 0000000..0dd3bb3
--- /dev/null
@@ -0,0 +1,161 @@
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+* 
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+* 
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
+* 
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+open Common.Infix
+
+open Lib_engine
+
+
+let pp = Common.pp 
+
+let pp_meta (_,x) = pp x
+
+let rec pp_binding_kind = function
+  | Ast_c.MetaIdVal        s -> pp ("id " ^ s)
+  | Ast_c.MetaFuncVal      s -> pp ("func " ^ s)
+  | Ast_c.MetaLocalFuncVal s -> pp ("localfunc " ^ s)
+  | Ast_c.MetaExprVal      expr -> 
+      Pretty_print_c.pp_expression_simple expr
+  | Ast_c.MetaExprListVal  expr_list -> pp "<<exprlist>>"
+  | Ast_c.MetaTypeVal      typ -> 
+      Pretty_print_c.pp_type_simple typ
+  | Ast_c.MetaStmtVal      statement -> 
+      Pretty_print_c.pp_statement_simple statement
+  | Ast_c.MetaParamVal     params -> pp "<<param>>"
+  | Ast_c.MetaParamListVal params -> pp "<<paramlist>>"
+  | Ast_c.MetaListlenVal n -> pp (string_of_int n)
+  | Ast_c.MetaPosVal (pos1, pos2) ->
+      let print_pos = function
+         Ast_cocci.Real x -> string_of_int x
+       | Ast_cocci.Virt(x,off) -> Printf.sprintf "%d+%d" x off in
+      pp (Common.sprintf ("pos(%s,%s)") (print_pos pos1) (print_pos pos2))
+  | Ast_c.MetaPosValList l -> 
+      pp (Common.sprintf ("poss[%s]")
+           (String.concat ", "
+              (List.map
+                 (function (fl,(minl,minc),(maxl,maxc)) ->
+                   Printf.sprintf "(%s,(%d,%d),(%d,%d))"
+                     fl minl minc maxl maxc)
+                 l)))
+
+and pp_binding subst = 
+  begin
+    pp "[";
+    Common.print_between (fun () -> pp ";"; Format.print_cut() ) 
+      (fun ((_,s), kind) -> pp s; pp " --> "; pp_binding_kind kind)
+      subst;
+    pp "]";
+  end
+
+
+let pp_binding_kind2 = function
+  | ParenVal s -> pp "pv("; pp_meta s; pp ")"
+  | NormalMetaVal x -> pp_binding_kind x
+  | LabelVal xs -> 
+      begin
+        pp "labelval";
+        pp "(";
+        Common.print_between (fun () -> pp ",") Format.print_int xs;
+        pp ")";
+      end
+  | GoodVal -> pp "goodval"
+  | BadVal ->  pp "badval"
+
+  
+let rec pp_predicate = function 
+  | InLoop -> pp "InLoop"
+  | TrueBranch -> pp "TrueBranch"
+  | FalseBranch -> pp "FalseBranch"
+  | After -> pp "After"
+  | FallThrough -> pp "FallThrough"
+  | Return -> pp "Return"
+  | FunHeader -> pp "FunHeader"
+  | Top -> pp "Top"
+  | ErrorExit -> pp "ErrorExit"
+  | Exit -> pp "Exit"
+  | Goto -> pp "Goto"
+  | Paren s -> pp "Paren("; pp_meta s; pp ")"
+  | Match (re) -> Pretty_print_cocci.print_rule_elem re
+  | Label s -> pp "Label("; pp_meta s; pp ")"
+  | BCLabel s -> pp "BreakContinueLabel("; pp_meta s; pp ")"
+  | PrefixLabel s -> pp "PrefixLabel("; pp_meta s; pp ")"
+  | BindGood s -> pp "BindGood("; pp_meta s; pp ")"
+  | BindBad s ->  pp "BindBad(";  pp_meta s; pp ")"
+  | FakeBrace -> pp "FakeBrace"
+
+and pp_binding2 subst = 
+  begin
+    pp "[";
+    Common.print_between (fun () -> pp ";";Format.print_cut(); ) 
+      (fun (s, kind) -> pp s; pp " --> "; pp_binding_kind2 kind)
+      subst;
+    pp "]";
+  end
+
+and pp_binding2_ctlsubst subst = 
+  begin
+    pp "[";
+    Common.print_between (fun () -> pp ";"; Format.print_cut(); ) 
+      (function
+          Ast_ctl.Subst (s, kind) ->
+           pp_meta s; pp " --> ";  pp_binding_kind2 kind;
+       | Ast_ctl.NegSubst (s, kind) ->
+          pp_meta s; pp " -/-> "; pp_binding_kind2 kind;
+      )
+      subst;
+    pp "]";
+  end
+
+let predicate_to_string pred =
+  Common.format_to_string (function _ -> pp_predicate pred)
+
+
+let pp_pred_smodif = fun (pred, smodif) -> 
+  begin
+    pp_predicate pred;
+(*
+  (match smodif with
+  |  Ast_ctl.Modif x | Ast_ctl.UnModif x -> pp " with <modifTODO>"
+  | Ast_ctl.Control -> ()
+  )
+*)
+  end
+
+
+let pp_ctlcocci show_plus inline_let_def ctl = 
+  begin
+    if show_plus 
+    then begin
+      Pretty_print_cocci.print_plus_flag := true;
+      Pretty_print_cocci.print_minus_flag := true;
+    end
+    else begin
+      Pretty_print_cocci.print_plus_flag := false;
+      Pretty_print_cocci.print_minus_flag := false;
+    end;
+    Common.pp_do_in_box (fun () -> 
+      Pretty_print_ctl.pp_ctl (pp_pred_smodif,(fun s -> pp_meta s))
+        inline_let_def ctl;
+      );
+  end
+
+
diff --git a/engine/.#transformation3.ml.1.47 b/engine/.#transformation3.ml.1.47
deleted file mode 100644 (file)
index 5691a73..0000000
+++ /dev/null
@@ -1,526 +0,0 @@
-(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-* 
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-* 
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-* 
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
-* 
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
-
-open Common
-
-module F = Control_flow_c
-
-(*****************************************************************************)
-(* The functor argument  *) 
-(*****************************************************************************)
-
-(* info passed recursively in monad in addition to binding *)
-type xinfo = { 
-  optional_storage_iso : bool;
-  optional_qualifier_iso : bool;
-  value_format_iso : bool;
-  current_rule_name : string; (* used for errors *)
-}
-
-module XTRANS = struct
-
-  (* ------------------------------------------------------------------------*)
-  (* Combinators history *) 
-  (* ------------------------------------------------------------------------*)
-  (*
-   * version0: 
-   *  type ('a, 'b) transformer = 
-   *    'a -> 'b -> Lib_engine.metavars_binding -> 'b
-   *  exception NoMatch 
-   * 
-   * version1:
-   *   type ('a, 'b) transformer = 
-   *    'a -> 'b -> Lib_engine.metavars_binding -> 'b option
-   * use an exception monad 
-   * 
-   * version2:
-   *    type tin = Lib_engine.metavars_binding
-   *)
-
-  (* ------------------------------------------------------------------------*)
-  (* Standard type and operators  *) 
-  (* ------------------------------------------------------------------------*)
-
-  type tin = { 
-    extra: xinfo;
-    binding: Lib_engine.metavars_binding;
-  }
-  type 'x tout = 'x option
-
-  type ('a, 'b) matcher = 'a -> 'b  -> tin -> ('a * 'b) tout
-
-  let (>>=) m f = fun tin -> 
-     match m tin with
-     | None -> None
-     | Some (a,b) -> f a b tin
-
-  let return = fun x -> fun tin -> 
-    Some x
-
-  (* can have fail in transform now that the process is deterministic ? *)
-  let fail = fun tin -> 
-    None
-
-  let (>||>) m1 m2 = fun tin -> 
-    match m1 tin with
-    | None -> m2 tin
-    | Some x -> Some x (* stop as soon as have found something *)
-
-  let (>|+|>) m1 m2 = m1 >||> m2
-
-  let (>&&>) f m = fun tin -> 
-    if f tin then m tin else fail tin
-
-  let optional_storage_flag f = fun tin -> 
-    f (tin.extra.optional_storage_iso) tin
-
-  let optional_qualifier_flag f = fun tin -> 
-    f (tin.extra.optional_qualifier_iso) tin
-
-  let value_format_flag f = fun tin -> 
-    f (tin.extra.value_format_iso) tin
-
-  let mode = Cocci_vs_c_3.TransformMode
-
-  (* ------------------------------------------------------------------------*)
-  (* Exp  *) 
-  (* ------------------------------------------------------------------------*)
-  let cocciExp = fun expf expa node -> fun tin -> 
-
-    let bigf = { 
-      Visitor_c.default_visitor_c_s with 
-      Visitor_c.kexpr_s = (fun (k, bigf) expb ->
-       match expf expa expb tin with
-       | None -> (* failed *) k expb
-       | Some (x, expb) -> expb);
-    }
-    in
-    Some (expa, Visitor_c.vk_node_s bigf node)
-
-
-  (* same as cocciExp, but for expressions in an expression, not expressions
-     in a node *)
-  let cocciExpExp = fun expf expa expb -> fun tin -> 
-
-    let bigf = { 
-      Visitor_c.default_visitor_c_s with 
-      Visitor_c.kexpr_s = (fun (k, bigf) expb ->
-       match expf expa expb tin with
-       | None -> (* failed *) k expb
-       | Some (x, expb) -> expb);
-    }
-    in
-    Some (expa, Visitor_c.vk_expr_s bigf expb)
-
-
-  let cocciTy = fun expf expa node -> fun tin -> 
-
-    let bigf = { 
-      Visitor_c.default_visitor_c_s with 
-      Visitor_c.ktype_s = (fun (k, bigf) expb ->
-       match expf expa expb tin with
-       | None -> (* failed *) k expb
-       | Some (x, expb) -> expb);
-    }
-    in
-    Some (expa, Visitor_c.vk_node_s bigf node)
-
-
-  (* ------------------------------------------------------------------------*)
-  (* Tokens *) 
-  (* ------------------------------------------------------------------------*)
-   let check_pos info mck pos = 
-     match mck with
-     | Ast_cocci.PLUS -> raise Impossible
-     | Ast_cocci.CONTEXT (Ast_cocci.FixPos (i1,i2),_) 
-     | Ast_cocci.MINUS   (Ast_cocci.FixPos (i1,i2),_) -> 
-         pos <= i2 && pos >= i1
-     | Ast_cocci.CONTEXT (Ast_cocci.DontCarePos,_) 
-     | Ast_cocci.MINUS   (Ast_cocci.DontCarePos,_) -> 
-         true
-     | _ ->
-        match info with
-          Some info ->
-            failwith
-              (Printf.sprintf
-                 "wierd: dont have position info for the mcodekind in line %d column %d"
-                 info.Ast_cocci.line info.Ast_cocci.column)
-        | None ->
-            failwith "wierd: dont have position info for the mcodekind"
-
-
-  let tag_with_mck mck ib = fun tin -> 
-
-    let cocciinforef = ib.Ast_c.cocci_tag in
-    let (oldmcode, oldenv) = !cocciinforef in
-
-    let mck =
-      if !Flag_parsing_cocci.sgrep_mode
-      then Sgrep.process_sgrep ib mck
-      else mck 
-    in
-    (match mck, Ast_c.pinfo_of_info ib with
-    | _,                  Ast_c.AbstractLineTok _ -> raise Impossible
-    | Ast_cocci.MINUS(_), Ast_c.ExpandedTok _ -> 
-        failwith ("try to delete an expanded token: " ^ (Ast_c.str_of_info ib))
-    | _ -> ()
-    );
-
-    match (oldmcode,mck) with
-    | (Ast_cocci.CONTEXT(_,Ast_cocci.NOTHING),      _)
-    | (_,   Ast_cocci.CONTEXT(_,Ast_cocci.NOTHING)) 
-      ->
-        cocciinforef := (mck, tin.binding);
-        ib
-
-    | _ -> 
-        if (oldmcode, oldenv) = (mck, tin.binding)
-        then begin
-          if !Flag.show_misc 
-          then pr2 "already tagged but with same mcode, so safe";
-          ib
-        end
-        else 
-          if !Flag.sgrep_mode2
-          then ib (* safe *)
-          else 
-            begin
-             Format.set_formatter_out_channel stderr;
-              Common.pr2 "SP mcode ";
-              Pretty_print_cocci.print_mcodekind oldmcode;
-              Format.print_newline();
-              Common.pr2 "C code mcode ";
-              Pretty_print_cocci.print_mcodekind mck;
-              Format.print_newline();
-              Format.print_flush();
-              failwith
-               (Common.sprintf "%s: already tagged token:\n%s"
-                  tin.extra.current_rule_name
-                  (Common.error_message (Ast_c.file_of_info ib)
-                     (Ast_c.str_of_info ib, Ast_c.opos_of_info ib)))
-            end
-
-  let tokenf ia ib = fun tin -> 
-    let (_,i,mck,_) = ia in
-    let pos = Ast_c.info_to_fixpos ib in
-    if check_pos (Some i) mck pos 
-    then return (ia, tag_with_mck mck ib tin) tin
-    else fail tin
-
-  let tokenf_mck mck ib = fun tin -> 
-    let pos = Ast_c.info_to_fixpos ib in
-    if check_pos None mck pos 
-    then return (mck, tag_with_mck mck ib tin) tin
-    else fail tin
-
-
-  (* ------------------------------------------------------------------------*)
-  (* Distribute mcode *) 
-  (* ------------------------------------------------------------------------*)
-
-  (* When in the SP we attach something to a metavariable, or delete it, as in
-   * - S
-   * + foo();
-   * we have to minusize all the token that compose S in the C code, and 
-   * attach the 'foo();'  to the right token, the one at the very right. 
-   *)
-
-  type 'a distributer = 
-      (Ast_c.info -> Ast_c.info) *  (* what to do on left *)
-      (Ast_c.info -> Ast_c.info) *  (* what to do on middle *)
-      (Ast_c.info -> Ast_c.info) *  (* what to do on right *)
-      (Ast_c.info -> Ast_c.info) -> (* what to do on both *)
-      'a -> 'a
-
-  let distribute_mck mcodekind distributef expr tin =
-    match mcodekind with
-    | Ast_cocci.MINUS (pos,any_xxs) -> 
-        distributef (
-          (fun ib -> tag_with_mck (Ast_cocci.MINUS (pos,any_xxs)) ib tin),
-          (fun ib -> tag_with_mck (Ast_cocci.MINUS (pos,[])) ib tin),
-          (fun ib -> tag_with_mck (Ast_cocci.MINUS (pos,[])) ib tin),
-          (fun ib -> tag_with_mck (Ast_cocci.MINUS (pos,any_xxs)) ib tin)
-        ) expr
-    | Ast_cocci.CONTEXT (pos,any_befaft) -> 
-        (match any_befaft with
-        | Ast_cocci.NOTHING -> expr
-            
-        | Ast_cocci.BEFORE xxs -> 
-            distributef (
-              (fun ib -> tag_with_mck 
-                (Ast_cocci.CONTEXT (pos,Ast_cocci.BEFORE xxs)) ib tin),
-              (fun x -> x), 
-              (fun x -> x), 
-              (fun ib -> tag_with_mck 
-                (Ast_cocci.CONTEXT (pos,Ast_cocci.BEFORE xxs)) ib tin)
-            ) expr
-        | Ast_cocci.AFTER xxs -> 
-            distributef (
-              (fun x -> x), 
-              (fun x -> x), 
-              (fun ib -> tag_with_mck 
-                (Ast_cocci.CONTEXT (pos,Ast_cocci.AFTER xxs)) ib tin),
-              (fun ib -> tag_with_mck 
-                (Ast_cocci.CONTEXT (pos,Ast_cocci.AFTER xxs)) ib tin)
-            ) expr
-
-        | Ast_cocci.BEFOREAFTER (xxs, yys) -> 
-            distributef (
-              (fun ib -> tag_with_mck 
-                (Ast_cocci.CONTEXT (pos,Ast_cocci.BEFORE xxs)) ib tin),
-              (fun x -> x), 
-              (fun ib -> tag_with_mck 
-                (Ast_cocci.CONTEXT (pos,Ast_cocci.AFTER yys)) ib tin),
-              (fun ib -> tag_with_mck 
-                (Ast_cocci.CONTEXT (pos,Ast_cocci.BEFOREAFTER (xxs,yys)))
-                ib tin)
-            ) expr
-
-        )
-    | Ast_cocci.PLUS -> raise Impossible
-
-
-  (* use new strategy, collect ii, sort, recollect and tag *)
-
-  let mk_bigf (maxpos, minpos) (lop,mop,rop,bop) = 
-    let bigf = { 
-      Visitor_c.default_visitor_c_s with
-        Visitor_c.kinfo_s = (fun (k,bigf) i -> 
-          let pos = Ast_c.info_to_fixpos i in
-          match () with
-          | _ when Ast_cocci.equal_pos pos maxpos &&
-             Ast_cocci.equal_pos pos minpos -> bop i
-          | _ when Ast_cocci.equal_pos pos maxpos -> rop i
-          | _ when Ast_cocci.equal_pos pos minpos -> lop i
-          | _ -> mop i
-        )
-    } in
-    bigf
-
-  let distribute_mck_expr (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
-    Visitor_c.vk_expr_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
-
-  let distribute_mck_args (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
-    Visitor_c.vk_args_splitted_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
-
-  let distribute_mck_type (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
-    Visitor_c.vk_type_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
-
-  let distribute_mck_ini (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
-    Visitor_c.vk_ini_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
-
-  let distribute_mck_param (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
-    Visitor_c.vk_param_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
-
-  let distribute_mck_params (maxpos, minpos) = fun (lop,mop,rop,bop) ->fun x ->
-    Visitor_c.vk_params_splitted_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop))
-      x
-
-  let distribute_mck_node (maxpos, minpos) = fun (lop,mop,rop,bop) ->fun x ->
-    Visitor_c.vk_node_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop))
-      x
-
-  let distribute_mck_struct_fields (maxpos, minpos) = 
-    fun (lop,mop,rop,bop) ->fun x ->
-      Visitor_c.vk_struct_fields_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop))
-        x
-
-  let distribute_mck_cst (maxpos, minpos) = 
-    fun (lop,mop,rop,bop) ->fun x ->
-      Visitor_c.vk_cst_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop))
-        x
-
-
-  let distribute_mck_define_params (maxpos, minpos) = fun (lop,mop,rop,bop) -> 
-   fun x ->
-    Visitor_c.vk_define_params_splitted_s 
-      (mk_bigf (maxpos, minpos) (lop,mop,rop,bop))
-      x
-
-   let get_pos mck = 
-     match mck with
-     | Ast_cocci.PLUS -> raise Impossible
-     | Ast_cocci.CONTEXT (Ast_cocci.FixPos (i1,i2),_) 
-     | Ast_cocci.MINUS   (Ast_cocci.FixPos (i1,i2),_) -> 
-         Ast_cocci.FixPos (i1,i2)
-     | Ast_cocci.CONTEXT (Ast_cocci.DontCarePos,_) 
-     | Ast_cocci.MINUS   (Ast_cocci.DontCarePos,_) -> 
-         Ast_cocci.DontCarePos
-     | _ -> failwith "wierd: dont have position info for the mcodekind"      
-      
-  let distrf (ii_of_x_f, distribute_mck_x_f) = 
-    fun ia x -> fun tin -> 
-    let mck = Ast_cocci.get_mcodekind ia in
-    let (max, min) = Lib_parsing_c.max_min_by_pos (ii_of_x_f x)
-    in
-    if 
-      (* bug: check_pos mck max && check_pos mck min
-       * 
-       * if do that then if have - f(...); and in C f(1,2); then we
-       * would get a "already tagged" because the '...' would sucess in
-       * transformaing both '1' and '1,2'. So being in the range is not
-       * enough. We must be equal exactly to the range! 
-       *)
-      (match get_pos mck with 
-      | Ast_cocci.DontCarePos -> true
-      | Ast_cocci.FixPos (i1, i2) -> 
-          i1 = min && i2 = max
-      | _ -> raise Impossible
-      )
-
-    then 
-      return (
-        ia, 
-        distribute_mck mck (distribute_mck_x_f (max,min))  x tin
-      ) tin
-    else fail tin
-
-
-  let distrf_e    = distrf (Lib_parsing_c.ii_of_expr,  distribute_mck_expr)
-  let distrf_args = distrf (Lib_parsing_c.ii_of_args,  distribute_mck_args)
-  let distrf_type = distrf (Lib_parsing_c.ii_of_type,  distribute_mck_type)
-  let distrf_param  = distrf (Lib_parsing_c.ii_of_param, distribute_mck_param)
-  let distrf_params = distrf (Lib_parsing_c.ii_of_params,distribute_mck_params)
-  let distrf_ini = distrf (Lib_parsing_c.ii_of_ini,distribute_mck_ini)
-  let distrf_node = distrf (Lib_parsing_c.ii_of_node,distribute_mck_node)
-  let distrf_struct_fields = 
-    distrf (Lib_parsing_c.ii_of_struct_fields, distribute_mck_struct_fields)
-  let distrf_cst = 
-    distrf (Lib_parsing_c.ii_of_cst, distribute_mck_cst)
-  let distrf_define_params = 
-    distrf (Lib_parsing_c.ii_of_define_params,distribute_mck_define_params)
-
-
-  (* ------------------------------------------------------------------------*)
-  (* Environment *) 
-  (* ------------------------------------------------------------------------*)
-  let meta_name_to_str (s1, s2) = 
-    s1 ^ "." ^ s2
-
-  let envf keep _inherited = fun (s, value, _) f tin -> 
-    let s = Ast_cocci.unwrap_mcode s in
-    let v = 
-      if keep = Type_cocci.Saved
-      then (
-        try Some (List.assoc s tin.binding)
-        with Not_found -> 
-          pr2(sprintf
-               "Don't find value for metavariable %s in the environment"
-                (meta_name_to_str s));
-          None)
-      else
-        (* not raise Impossible! *)
-        Some (value)
-    in
-    match v with
-    | None -> fail tin
-    | Some (value') ->
-
-        (* Ex: in cocci_vs_c someone wants to add a binding. Here in
-         * transformation3 the value for this var may be already in the 
-         * env, because for instance its value were fixed in a previous
-         * SmPL rule. So here we want to check that this is the same value.
-         * If forget to do the check, what can happen ? Because of Exp
-         * and other disjunctive feature of cocci_vs_c (>||>), we 
-         * may accept a match at a wrong position. Maybe later this
-         * will be detected via the pos system on tokens, but maybe
-         * not. So safer to keep the check.
-         *)
-
-        (*f () tin*)
-        if Cocci_vs_c_3.equal_metavarval value value' 
-        then f () tin
-        else fail tin
-
-    
-  let check_constraints matcher constraints exp = fun f tin -> f () tin
-
-  (* ------------------------------------------------------------------------*)
-  (* Environment, allbounds *) 
-  (* ------------------------------------------------------------------------*)
-  let (all_bound : Ast_cocci.meta_name list -> tin -> bool) = fun l tin ->
-    true (* in transform we don't care ? *)
-
-end
-
-(*****************************************************************************)
-(* Entry point  *) 
-(*****************************************************************************)
-module TRANS  = Cocci_vs_c_3.COCCI_VS_C (XTRANS)
-
-
-let transform_re_node a b tin = 
-  match TRANS.rule_elem_node a b tin with 
-  | None -> raise Impossible
-  | Some (_sp, b') -> b'
-
-
-let (transform2: string (* rule name *) -> string list (* dropped_isos *) ->
-  Lib_engine.transformation_info -> F.cflow -> F.cflow) = 
- fun rule_name dropped_isos xs cflow -> 
-
-   let extra = { 
-     optional_storage_iso   = not(List.mem "optional_storage" dropped_isos);
-     optional_qualifier_iso = not(List.mem "optional_qualifier" dropped_isos);
-     value_format_iso = not(List.mem "value_format" dropped_isos);
-     current_rule_name = rule_name;
-   } in
-
-  (* find the node, transform, update the node,  and iter for all elements *)
-
-   xs +> List.fold_left (fun acc (nodei, binding, rule_elem) -> 
-      (* subtil: not cflow#nodes but acc#nodes *)
-      let node  = acc#nodes#assoc nodei in 
-
-      if !Flag.show_misc 
-      then pr2 "transform one node";
-      
-      let tin = {
-        XTRANS.extra = extra;
-        XTRANS.binding = binding;
-      } in
-
-      let node' = transform_re_node rule_elem node tin in
-
-      (* assert that have done something. But with metaruleElem sometimes 
-         dont modify fake nodes. So special case before on Fake nodes. *)
-      (match F.unwrap node with
-      | F.Enter | F.Exit | F.ErrorExit
-      | F.EndStatement _ | F.CaseNode _        
-      | F.Fake
-      | F.TrueNode | F.FalseNode | F.AfterNode | F.FallThroughNode 
-          -> ()
-      | _ -> () (* assert (not (node =*= node')); *)
-      );
-
-      (* useless, we dont go back from flow to ast now *)
-      (* let node' = lastfix_comma_struct node' in *)
-      
-      acc#replace_node (nodei, node');
-      acc
-   ) cflow
-
-
-
-let transform a b c d = 
-  Common.profile_code "Transformation3.transform" 
-    (fun () -> transform2 a b c d)
diff --git a/engine/.#transformation3.ml.1.48 b/engine/.#transformation3.ml.1.48
deleted file mode 100644 (file)
index 5ade85b..0000000
+++ /dev/null
@@ -1,528 +0,0 @@
-(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-* 
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-* 
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-* 
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
-* 
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
-
-open Common
-
-module F = Control_flow_c
-
-(*****************************************************************************)
-(* The functor argument  *) 
-(*****************************************************************************)
-
-(* info passed recursively in monad in addition to binding *)
-type xinfo = { 
-  optional_storage_iso : bool;
-  optional_qualifier_iso : bool;
-  value_format_iso : bool;
-  current_rule_name : string; (* used for errors *)
-}
-
-module XTRANS = struct
-
-  (* ------------------------------------------------------------------------*)
-  (* Combinators history *) 
-  (* ------------------------------------------------------------------------*)
-  (*
-   * version0: 
-   *  type ('a, 'b) transformer = 
-   *    'a -> 'b -> Lib_engine.metavars_binding -> 'b
-   *  exception NoMatch 
-   * 
-   * version1:
-   *   type ('a, 'b) transformer = 
-   *    'a -> 'b -> Lib_engine.metavars_binding -> 'b option
-   * use an exception monad 
-   * 
-   * version2:
-   *    type tin = Lib_engine.metavars_binding
-   *)
-
-  (* ------------------------------------------------------------------------*)
-  (* Standard type and operators  *) 
-  (* ------------------------------------------------------------------------*)
-
-  type tin = { 
-    extra: xinfo;
-    binding: Lib_engine.metavars_binding;
-    binding0: Lib_engine.metavars_binding; (* inherited variable *)
-  }
-  type 'x tout = 'x option
-
-  type ('a, 'b) matcher = 'a -> 'b  -> tin -> ('a * 'b) tout
-
-  let (>>=) m f = fun tin -> 
-     match m tin with
-     | None -> None
-     | Some (a,b) -> f a b tin
-
-  let return = fun x -> fun tin -> 
-    Some x
-
-  (* can have fail in transform now that the process is deterministic ? *)
-  let fail = fun tin -> 
-    None
-
-  let (>||>) m1 m2 = fun tin -> 
-    match m1 tin with
-    | None -> m2 tin
-    | Some x -> Some x (* stop as soon as have found something *)
-
-  let (>|+|>) m1 m2 = m1 >||> m2
-
-  let (>&&>) f m = fun tin -> 
-    if f tin then m tin else fail tin
-
-  let optional_storage_flag f = fun tin -> 
-    f (tin.extra.optional_storage_iso) tin
-
-  let optional_qualifier_flag f = fun tin -> 
-    f (tin.extra.optional_qualifier_iso) tin
-
-  let value_format_flag f = fun tin -> 
-    f (tin.extra.value_format_iso) tin
-
-  let mode = Cocci_vs_c_3.TransformMode
-
-  (* ------------------------------------------------------------------------*)
-  (* Exp  *) 
-  (* ------------------------------------------------------------------------*)
-  let cocciExp = fun expf expa node -> fun tin -> 
-
-    let bigf = { 
-      Visitor_c.default_visitor_c_s with 
-      Visitor_c.kexpr_s = (fun (k, bigf) expb ->
-       match expf expa expb tin with
-       | None -> (* failed *) k expb
-       | Some (x, expb) -> expb);
-    }
-    in
-    Some (expa, Visitor_c.vk_node_s bigf node)
-
-
-  (* same as cocciExp, but for expressions in an expression, not expressions
-     in a node *)
-  let cocciExpExp = fun expf expa expb -> fun tin -> 
-
-    let bigf = { 
-      Visitor_c.default_visitor_c_s with 
-      Visitor_c.kexpr_s = (fun (k, bigf) expb ->
-       match expf expa expb tin with
-       | None -> (* failed *) k expb
-       | Some (x, expb) -> expb);
-    }
-    in
-    Some (expa, Visitor_c.vk_expr_s bigf expb)
-
-
-  let cocciTy = fun expf expa node -> fun tin -> 
-
-    let bigf = { 
-      Visitor_c.default_visitor_c_s with 
-      Visitor_c.ktype_s = (fun (k, bigf) expb ->
-       match expf expa expb tin with
-       | None -> (* failed *) k expb
-       | Some (x, expb) -> expb);
-    }
-    in
-    Some (expa, Visitor_c.vk_node_s bigf node)
-
-
-  (* ------------------------------------------------------------------------*)
-  (* Tokens *) 
-  (* ------------------------------------------------------------------------*)
-   let check_pos info mck pos = 
-     match mck with
-     | Ast_cocci.PLUS -> raise Impossible
-     | Ast_cocci.CONTEXT (Ast_cocci.FixPos (i1,i2),_) 
-     | Ast_cocci.MINUS   (Ast_cocci.FixPos (i1,i2),_) -> 
-         pos <= i2 && pos >= i1
-     | Ast_cocci.CONTEXT (Ast_cocci.DontCarePos,_) 
-     | Ast_cocci.MINUS   (Ast_cocci.DontCarePos,_) -> 
-         true
-     | _ ->
-        match info with
-          Some info ->
-            failwith
-              (Printf.sprintf
-                 "wierd: dont have position info for the mcodekind in line %d column %d"
-                 info.Ast_cocci.line info.Ast_cocci.column)
-        | None ->
-            failwith "wierd: dont have position info for the mcodekind"
-
-
-  let tag_with_mck mck ib = fun tin -> 
-
-    let cocciinforef = ib.Ast_c.cocci_tag in
-    let (oldmcode, oldenv) = !cocciinforef in
-
-    let mck =
-      if !Flag_parsing_cocci.sgrep_mode
-      then Sgrep.process_sgrep ib mck
-      else mck 
-    in
-    (match mck, Ast_c.pinfo_of_info ib with
-    | _,                  Ast_c.AbstractLineTok _ -> raise Impossible
-    | Ast_cocci.MINUS(_), Ast_c.ExpandedTok _ -> 
-        failwith ("try to delete an expanded token: " ^ (Ast_c.str_of_info ib))
-    | _ -> ()
-    );
-
-    match (oldmcode,mck) with
-    | (Ast_cocci.CONTEXT(_,Ast_cocci.NOTHING),      _)
-    | (_,   Ast_cocci.CONTEXT(_,Ast_cocci.NOTHING)) 
-      ->
-        cocciinforef := (mck, tin.binding);
-        ib
-
-    | _ -> 
-        if (oldmcode, oldenv) = (mck, tin.binding)
-        then begin
-          if !Flag.show_misc 
-          then pr2 "already tagged but with same mcode, so safe";
-          ib
-        end
-        else 
-          if !Flag.sgrep_mode2
-          then ib (* safe *)
-          else 
-            begin
-             Format.set_formatter_out_channel stderr;
-              Common.pr2 "SP mcode ";
-              Pretty_print_cocci.print_mcodekind oldmcode;
-              Format.print_newline();
-              Common.pr2 "C code mcode ";
-              Pretty_print_cocci.print_mcodekind mck;
-              Format.print_newline();
-              Format.print_flush();
-              failwith
-               (Common.sprintf "%s: already tagged token:\n%s"
-                  tin.extra.current_rule_name
-                  (Common.error_message (Ast_c.file_of_info ib)
-                     (Ast_c.str_of_info ib, Ast_c.opos_of_info ib)))
-            end
-
-  let tokenf ia ib = fun tin -> 
-    let (_,i,mck,_) = ia in
-    let pos = Ast_c.info_to_fixpos ib in
-    if check_pos (Some i) mck pos 
-    then return (ia, tag_with_mck mck ib tin) tin
-    else fail tin
-
-  let tokenf_mck mck ib = fun tin -> 
-    let pos = Ast_c.info_to_fixpos ib in
-    if check_pos None mck pos 
-    then return (mck, tag_with_mck mck ib tin) tin
-    else fail tin
-
-
-  (* ------------------------------------------------------------------------*)
-  (* Distribute mcode *) 
-  (* ------------------------------------------------------------------------*)
-
-  (* When in the SP we attach something to a metavariable, or delete it, as in
-   * - S
-   * + foo();
-   * we have to minusize all the token that compose S in the C code, and 
-   * attach the 'foo();'  to the right token, the one at the very right. 
-   *)
-
-  type 'a distributer = 
-      (Ast_c.info -> Ast_c.info) *  (* what to do on left *)
-      (Ast_c.info -> Ast_c.info) *  (* what to do on middle *)
-      (Ast_c.info -> Ast_c.info) *  (* what to do on right *)
-      (Ast_c.info -> Ast_c.info) -> (* what to do on both *)
-      'a -> 'a
-
-  let distribute_mck mcodekind distributef expr tin =
-    match mcodekind with
-    | Ast_cocci.MINUS (pos,any_xxs) -> 
-        distributef (
-          (fun ib -> tag_with_mck (Ast_cocci.MINUS (pos,any_xxs)) ib tin),
-          (fun ib -> tag_with_mck (Ast_cocci.MINUS (pos,[])) ib tin),
-          (fun ib -> tag_with_mck (Ast_cocci.MINUS (pos,[])) ib tin),
-          (fun ib -> tag_with_mck (Ast_cocci.MINUS (pos,any_xxs)) ib tin)
-        ) expr
-    | Ast_cocci.CONTEXT (pos,any_befaft) -> 
-        (match any_befaft with
-        | Ast_cocci.NOTHING -> expr
-            
-        | Ast_cocci.BEFORE xxs -> 
-            distributef (
-              (fun ib -> tag_with_mck 
-                (Ast_cocci.CONTEXT (pos,Ast_cocci.BEFORE xxs)) ib tin),
-              (fun x -> x), 
-              (fun x -> x), 
-              (fun ib -> tag_with_mck 
-                (Ast_cocci.CONTEXT (pos,Ast_cocci.BEFORE xxs)) ib tin)
-            ) expr
-        | Ast_cocci.AFTER xxs -> 
-            distributef (
-              (fun x -> x), 
-              (fun x -> x), 
-              (fun ib -> tag_with_mck 
-                (Ast_cocci.CONTEXT (pos,Ast_cocci.AFTER xxs)) ib tin),
-              (fun ib -> tag_with_mck 
-                (Ast_cocci.CONTEXT (pos,Ast_cocci.AFTER xxs)) ib tin)
-            ) expr
-
-        | Ast_cocci.BEFOREAFTER (xxs, yys) -> 
-            distributef (
-              (fun ib -> tag_with_mck 
-                (Ast_cocci.CONTEXT (pos,Ast_cocci.BEFORE xxs)) ib tin),
-              (fun x -> x), 
-              (fun ib -> tag_with_mck 
-                (Ast_cocci.CONTEXT (pos,Ast_cocci.AFTER yys)) ib tin),
-              (fun ib -> tag_with_mck 
-                (Ast_cocci.CONTEXT (pos,Ast_cocci.BEFOREAFTER (xxs,yys)))
-                ib tin)
-            ) expr
-
-        )
-    | Ast_cocci.PLUS -> raise Impossible
-
-
-  (* use new strategy, collect ii, sort, recollect and tag *)
-
-  let mk_bigf (maxpos, minpos) (lop,mop,rop,bop) = 
-    let bigf = { 
-      Visitor_c.default_visitor_c_s with
-        Visitor_c.kinfo_s = (fun (k,bigf) i -> 
-          let pos = Ast_c.info_to_fixpos i in
-          match () with
-          | _ when Ast_cocci.equal_pos pos maxpos &&
-             Ast_cocci.equal_pos pos minpos -> bop i
-          | _ when Ast_cocci.equal_pos pos maxpos -> rop i
-          | _ when Ast_cocci.equal_pos pos minpos -> lop i
-          | _ -> mop i
-        )
-    } in
-    bigf
-
-  let distribute_mck_expr (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
-    Visitor_c.vk_expr_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
-
-  let distribute_mck_args (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
-    Visitor_c.vk_args_splitted_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
-
-  let distribute_mck_type (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
-    Visitor_c.vk_type_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
-
-  let distribute_mck_ini (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
-    Visitor_c.vk_ini_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
-
-  let distribute_mck_param (maxpos, minpos) = fun (lop,mop,rop,bop) -> fun x ->
-    Visitor_c.vk_param_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop)) x
-
-  let distribute_mck_params (maxpos, minpos) = fun (lop,mop,rop,bop) ->fun x ->
-    Visitor_c.vk_params_splitted_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop))
-      x
-
-  let distribute_mck_node (maxpos, minpos) = fun (lop,mop,rop,bop) ->fun x ->
-    Visitor_c.vk_node_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop))
-      x
-
-  let distribute_mck_struct_fields (maxpos, minpos) = 
-    fun (lop,mop,rop,bop) ->fun x ->
-      Visitor_c.vk_struct_fields_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop))
-        x
-
-  let distribute_mck_cst (maxpos, minpos) = 
-    fun (lop,mop,rop,bop) ->fun x ->
-      Visitor_c.vk_cst_s (mk_bigf (maxpos, minpos) (lop,mop,rop,bop))
-        x
-
-
-  let distribute_mck_define_params (maxpos, minpos) = fun (lop,mop,rop,bop) -> 
-   fun x ->
-    Visitor_c.vk_define_params_splitted_s 
-      (mk_bigf (maxpos, minpos) (lop,mop,rop,bop))
-      x
-
-   let get_pos mck = 
-     match mck with
-     | Ast_cocci.PLUS -> raise Impossible
-     | Ast_cocci.CONTEXT (Ast_cocci.FixPos (i1,i2),_) 
-     | Ast_cocci.MINUS   (Ast_cocci.FixPos (i1,i2),_) -> 
-         Ast_cocci.FixPos (i1,i2)
-     | Ast_cocci.CONTEXT (Ast_cocci.DontCarePos,_) 
-     | Ast_cocci.MINUS   (Ast_cocci.DontCarePos,_) -> 
-         Ast_cocci.DontCarePos
-     | _ -> failwith "wierd: dont have position info for the mcodekind"      
-      
-  let distrf (ii_of_x_f, distribute_mck_x_f) = 
-    fun ia x -> fun tin -> 
-    let mck = Ast_cocci.get_mcodekind ia in
-    let (max, min) = Lib_parsing_c.max_min_by_pos (ii_of_x_f x)
-    in
-    if 
-      (* bug: check_pos mck max && check_pos mck min
-       * 
-       * if do that then if have - f(...); and in C f(1,2); then we
-       * would get a "already tagged" because the '...' would sucess in
-       * transformaing both '1' and '1,2'. So being in the range is not
-       * enough. We must be equal exactly to the range! 
-       *)
-      (match get_pos mck with 
-      | Ast_cocci.DontCarePos -> true
-      | Ast_cocci.FixPos (i1, i2) -> 
-          i1 = min && i2 = max
-      | _ -> raise Impossible
-      )
-
-    then 
-      return (
-        ia, 
-        distribute_mck mck (distribute_mck_x_f (max,min))  x tin
-      ) tin
-    else fail tin
-
-
-  let distrf_e    = distrf (Lib_parsing_c.ii_of_expr,  distribute_mck_expr)
-  let distrf_args = distrf (Lib_parsing_c.ii_of_args,  distribute_mck_args)
-  let distrf_type = distrf (Lib_parsing_c.ii_of_type,  distribute_mck_type)
-  let distrf_param  = distrf (Lib_parsing_c.ii_of_param, distribute_mck_param)
-  let distrf_params = distrf (Lib_parsing_c.ii_of_params,distribute_mck_params)
-  let distrf_ini = distrf (Lib_parsing_c.ii_of_ini,distribute_mck_ini)
-  let distrf_node = distrf (Lib_parsing_c.ii_of_node,distribute_mck_node)
-  let distrf_struct_fields = 
-    distrf (Lib_parsing_c.ii_of_struct_fields, distribute_mck_struct_fields)
-  let distrf_cst = 
-    distrf (Lib_parsing_c.ii_of_cst, distribute_mck_cst)
-  let distrf_define_params = 
-    distrf (Lib_parsing_c.ii_of_define_params,distribute_mck_define_params)
-
-
-  (* ------------------------------------------------------------------------*)
-  (* Environment *) 
-  (* ------------------------------------------------------------------------*)
-  let meta_name_to_str (s1, s2) = 
-    s1 ^ "." ^ s2
-
-  let envf keep _inherited = fun (s, value, _) f tin -> 
-    let s = Ast_cocci.unwrap_mcode s in
-    let v = 
-      if keep = Type_cocci.Saved
-      then (
-        try Some (List.assoc s tin.binding)
-        with Not_found -> 
-          pr2(sprintf
-               "Don't find value for metavariable %s in the environment"
-                (meta_name_to_str s));
-          None)
-      else
-        (* not raise Impossible! *)
-        Some (value)
-    in
-    match v with
-    | None -> fail tin
-    | Some (value') ->
-
-        (* Ex: in cocci_vs_c someone wants to add a binding. Here in
-         * transformation3 the value for this var may be already in the 
-         * env, because for instance its value were fixed in a previous
-         * SmPL rule. So here we want to check that this is the same value.
-         * If forget to do the check, what can happen ? Because of Exp
-         * and other disjunctive feature of cocci_vs_c (>||>), we 
-         * may accept a match at a wrong position. Maybe later this
-         * will be detected via the pos system on tokens, but maybe
-         * not. So safer to keep the check.
-         *)
-
-        (*f () tin*)
-        if Cocci_vs_c_3.equal_metavarval value value' 
-        then f () tin
-        else fail tin
-
-    
-  let check_constraints matcher constraints exp = fun f tin -> f () tin
-
-  (* ------------------------------------------------------------------------*)
-  (* Environment, allbounds *) 
-  (* ------------------------------------------------------------------------*)
-  let (all_bound : Ast_cocci.meta_name list -> tin -> bool) = fun l tin ->
-    true (* in transform we don't care ? *)
-
-end
-
-(*****************************************************************************)
-(* Entry point  *) 
-(*****************************************************************************)
-module TRANS  = Cocci_vs_c_3.COCCI_VS_C (XTRANS)
-
-
-let transform_re_node a b tin = 
-  match TRANS.rule_elem_node a b tin with 
-  | None -> raise Impossible
-  | Some (_sp, b') -> b'
-
-let (transform2: string (* rule name *) -> string list (* dropped_isos *) ->
-  Lib_engine.metavars_binding (* inherited bindings *) ->
-  Lib_engine.transformation_info -> F.cflow -> F.cflow) = 
- fun rule_name dropped_isos binding0 xs cflow -> 
-
-   let extra = { 
-     optional_storage_iso   = not(List.mem "optional_storage" dropped_isos);
-     optional_qualifier_iso = not(List.mem "optional_qualifier" dropped_isos);
-     value_format_iso = not(List.mem "value_format" dropped_isos);
-     current_rule_name = rule_name;
-   } in
-
-  (* find the node, transform, update the node,  and iter for all elements *)
-
-   xs +> List.fold_left (fun acc (nodei, binding, rule_elem) -> 
-      (* subtil: not cflow#nodes but acc#nodes *)
-      let node  = acc#nodes#assoc nodei in 
-
-      if !Flag.show_misc 
-      then pr2 "transform one node";
-      
-      let tin = {
-        XTRANS.extra = extra;
-        XTRANS.binding = binding0@binding;
-        XTRANS.binding0 = []; (* not used - everything constant for trans *)
-      } in
-
-      let node' = transform_re_node rule_elem node tin in
-
-      (* assert that have done something. But with metaruleElem sometimes 
-         dont modify fake nodes. So special case before on Fake nodes. *)
-      (match F.unwrap node with
-      | F.Enter | F.Exit | F.ErrorExit
-      | F.EndStatement _ | F.CaseNode _        
-      | F.Fake
-      | F.TrueNode | F.FalseNode | F.AfterNode | F.FallThroughNode 
-          -> ()
-      | _ -> () (* assert (not (node =*= node')); *)
-      );
-
-      (* useless, we dont go back from flow to ast now *)
-      (* let node' = lastfix_comma_struct node' in *)
-      
-      acc#replace_node (nodei, node');
-      acc
-   ) cflow
-
-
-
-let transform a b c d e = 
-  Common.profile_code "Transformation3.transform" 
-    (fun () -> transform2 a b c d e)
index 301f8e4..cd7367f 100644 (file)
@@ -7,20 +7,20 @@ asttomember.cmi: lib_engine.cmo ../ctl/ast_ctl.cmo \
 c_vs_c.cmi: ../parsing_c/ast_c.cmo 
 check_reachability.cmi: ../ctl/wrapper_ctl.cmi ../commons/ograph_extended.cmi \
     ../parsing_c/control_flow_c.cmi ../ctl/ast_ctl.cmo 
-cocci_vs_c_3.cmi: ../parsing_c/control_flow_c.cmi ../commons/common.cmi \
+cocci_vs_c.cmi: ../parsing_c/control_flow_c.cmi ../commons/common.cmi \
     ../parsing_cocci/ast_cocci.cmi ../parsing_c/ast_c.cmo 
 ctlcocci_integration.cmi: ../commons/ograph_extended.cmi lib_engine.cmo \
     ../parsing_c/control_flow_c.cmi ../ctl/ast_ctl.cmo \
     ../parsing_cocci/ast_cocci.cmi 
 ctltotex.cmi: ../ctl/wrapper_ctl.cmi lib_engine.cmo ../ctl/ast_ctl.cmo \
     ../parsing_cocci/ast_cocci.cmi 
-pattern3.cmi: lib_engine.cmo ../parsing_c/control_flow_c.cmi \
+pattern_c.cmi: lib_engine.cmo ../parsing_c/control_flow_c.cmi \
     ../parsing_cocci/ast_cocci.cmi 
 postprocess_transinfo.cmi: ../commons/ograph_extended.cmi lib_engine.cmo \
     ../parsing_cocci/ast_cocci.cmi 
 pretty_print_engine.cmi: lib_engine.cmo ../ctl/ast_ctl.cmo \
     ../parsing_c/ast_c.cmo 
-transformation3.cmi: lib_engine.cmo ../parsing_c/control_flow_c.cmi 
+transformation_c.cmi: lib_engine.cmo ../parsing_c/control_flow_c.cmi 
 asttoctl.cmo: ../ctl/wrapper_ctl.cmi ../parsing_cocci/visitor_ast.cmi \
     ../parsing_cocci/unify_ast.cmi pretty_print_engine.cmi lib_engine.cmo \
     ../parsing_cocci/free_vars.cmi ../commons/common.cmi ../ctl/ast_ctl.cmo \
@@ -32,13 +32,13 @@ asttoctl.cmx: ../ctl/wrapper_ctl.cmx ../parsing_cocci/visitor_ast.cmx \
 asttoctl2.cmo: ../ctl/wrapper_ctl.cmi ../parsing_cocci/visitor_ast.cmi \
     ../parsing_cocci/unify_ast.cmi ../parsing_cocci/type_cocci.cmi \
     pretty_print_engine.cmi ../ctl/pretty_print_ctl.cmi \
-    ../parsing_cocci/pretty_print_cocci.cmi lib_engine.cmo flag_engine.cmo \
+    ../parsing_cocci/pretty_print_cocci.cmi lib_engine.cmo flag_matcher.cmo \
     ../globals/flag.cmo ../commons/common.cmi ../ctl/ast_ctl.cmo \
     ../parsing_cocci/ast_cocci.cmi asttoctl2.cmi 
 asttoctl2.cmx: ../ctl/wrapper_ctl.cmx ../parsing_cocci/visitor_ast.cmx \
     ../parsing_cocci/unify_ast.cmx ../parsing_cocci/type_cocci.cmx \
     pretty_print_engine.cmx ../ctl/pretty_print_ctl.cmx \
-    ../parsing_cocci/pretty_print_cocci.cmx lib_engine.cmx flag_engine.cmx \
+    ../parsing_cocci/pretty_print_cocci.cmx lib_engine.cmx flag_matcher.cmx \
     ../globals/flag.cmx ../commons/common.cmx ../ctl/ast_ctl.cmx \
     ../parsing_cocci/ast_cocci.cmx asttoctl2.cmi 
 asttomember.cmo: ../parsing_cocci/visitor_ast.cmi \
@@ -63,26 +63,26 @@ check_reachability.cmo: ../ctl/wrapper_ctl.cmi ../commons/ograph_extended.cmi \
 check_reachability.cmx: ../ctl/wrapper_ctl.cmx ../commons/ograph_extended.cmx \
     ../ctl/flag_ctl.cmx ../ctl/ctl_engine.cmx ../parsing_c/control_flow_c.cmx \
     ../ctl/ast_ctl.cmx check_reachability.cmi 
-cocci_vs_c_3.cmo: ../parsing_cocci/type_cocci.cmi \
-    ../parsing_c/lib_parsing_c.cmo ../globals/flag.cmo \
+cocci_vs_c.cmo: ../parsing_cocci/type_cocci.cmi \
+    ../parsing_c/lib_parsing_c.cmo flag_matcher.cmo \
     ../parsing_c/control_flow_c.cmi ../commons/common.cmi c_vs_c.cmi \
-    ../parsing_cocci/ast_cocci.cmi ../parsing_c/ast_c.cmo cocci_vs_c_3.cmi 
-cocci_vs_c_3.cmx: ../parsing_cocci/type_cocci.cmx \
-    ../parsing_c/lib_parsing_c.cmx ../globals/flag.cmx \
+    ../parsing_cocci/ast_cocci.cmi ../parsing_c/ast_c.cmo cocci_vs_c.cmi 
+cocci_vs_c.cmx: ../parsing_cocci/type_cocci.cmx \
+    ../parsing_c/lib_parsing_c.cmx flag_matcher.cmx \
     ../parsing_c/control_flow_c.cmx ../commons/common.cmx c_vs_c.cmx \
-    ../parsing_cocci/ast_cocci.cmx ../parsing_c/ast_c.cmx cocci_vs_c_3.cmi 
+    ../parsing_cocci/ast_cocci.cmx ../parsing_c/ast_c.cmx cocci_vs_c.cmi 
 ctlcocci_integration.cmo: ../ctl/wrapper_ctl.cmi pretty_print_engine.cmi \
     ../parsing_cocci/pretty_print_cocci.cmi postprocess_transinfo.cmi \
-    pattern3.cmi ../commons/ograph_extended.cmi lib_engine.cmo \
-    ../parsing_cocci/flag_parsing_cocci.cmo flag_engine.cmo \
+    pattern_c.cmi ../commons/ograph_extended.cmi lib_engine.cmo \
+    ../parsing_cocci/flag_parsing_cocci.cmo flag_matcher.cmo \
     ../globals/flag.cmo ../parsing_c/control_flow_c.cmi ../commons/common.cmi \
     check_reachability.cmi c_vs_c.cmi ../ctl/ast_ctl.cmo \
     ../parsing_cocci/ast_cocci.cmi ../parsing_c/ast_c.cmo \
     ctlcocci_integration.cmi 
 ctlcocci_integration.cmx: ../ctl/wrapper_ctl.cmx pretty_print_engine.cmx \
     ../parsing_cocci/pretty_print_cocci.cmx postprocess_transinfo.cmx \
-    pattern3.cmx ../commons/ograph_extended.cmx lib_engine.cmx \
-    ../parsing_cocci/flag_parsing_cocci.cmx flag_engine.cmx \
+    pattern_c.cmx ../commons/ograph_extended.cmx lib_engine.cmx \
+    ../parsing_cocci/flag_parsing_cocci.cmx flag_matcher.cmx \
     ../globals/flag.cmx ../parsing_c/control_flow_c.cmx ../commons/common.cmx \
     check_reachability.cmx c_vs_c.cmx ../ctl/ast_ctl.cmx \
     ../parsing_cocci/ast_cocci.cmx ../parsing_c/ast_c.cmx \
@@ -101,12 +101,12 @@ lib_engine.cmx: ../ctl/wrapper_ctl.cmx ../commons/ograph_extended.cmx \
     ../parsing_cocci/ast_cocci.cmx ../parsing_c/ast_c.cmx 
 main.cmo: ../parsing_cocci/parse_cocci.cmi ctltotex.cmi asttoctl.cmi 
 main.cmx: ../parsing_cocci/parse_cocci.cmx ctltotex.cmx asttoctl.cmx 
-pattern3.cmo: ../parsing_c/visitor_c.cmi ../parsing_c/lib_parsing_c.cmo \
-    lib_engine.cmo flag_engine.cmo ../commons/common.cmi cocci_vs_c_3.cmi \
-    ../parsing_cocci/ast_cocci.cmi ../parsing_c/ast_c.cmo pattern3.cmi 
-pattern3.cmx: ../parsing_c/visitor_c.cmx ../parsing_c/lib_parsing_c.cmx \
-    lib_engine.cmx flag_engine.cmx ../commons/common.cmx cocci_vs_c_3.cmx \
-    ../parsing_cocci/ast_cocci.cmx ../parsing_c/ast_c.cmx pattern3.cmi 
+pattern_c.cmo: ../parsing_c/visitor_c.cmi ../parsing_c/lib_parsing_c.cmo \
+    lib_engine.cmo flag_matcher.cmo ../commons/common.cmi cocci_vs_c.cmi \
+    ../parsing_cocci/ast_cocci.cmi ../parsing_c/ast_c.cmo pattern_c.cmi 
+pattern_c.cmx: ../parsing_c/visitor_c.cmx ../parsing_c/lib_parsing_c.cmx \
+    lib_engine.cmx flag_matcher.cmx ../commons/common.cmx cocci_vs_c.cmx \
+    ../parsing_cocci/ast_cocci.cmx ../parsing_c/ast_c.cmx pattern_c.cmi 
 postprocess_transinfo.cmo: ../parsing_c/parser_c.cmi ../parsing_c/parse_c.cmi \
     lib_engine.cmo ../commons/common.cmi ../parsing_cocci/ast_cocci.cmi \
     ../parsing_c/ast_c.cmo postprocess_transinfo.cmi 
@@ -125,17 +125,13 @@ pretty_print_engine.cmx: ../ctl/pretty_print_ctl.cmx \
     pretty_print_engine.cmi 
 sgrep.cmo: ../parsing_cocci/ast_cocci.cmi ../parsing_c/ast_c.cmo 
 sgrep.cmx: ../parsing_cocci/ast_cocci.cmx ../parsing_c/ast_c.cmx 
-transformation3.cmo: ../parsing_c/visitor_c.cmi \
-    ../parsing_cocci/type_cocci.cmi sgrep.cmo \
-    ../parsing_cocci/pretty_print_cocci.cmi ../parsing_c/lib_parsing_c.cmo \
-    lib_engine.cmo ../parsing_cocci/flag_parsing_cocci.cmo \
-    ../globals/flag.cmo ../parsing_c/control_flow_c.cmi ../commons/common.cmi \
-    cocci_vs_c_3.cmi ../parsing_cocci/ast_cocci.cmi ../parsing_c/ast_c.cmo \
-    transformation3.cmi 
-transformation3.cmx: ../parsing_c/visitor_c.cmx \
-    ../parsing_cocci/type_cocci.cmx sgrep.cmx \
-    ../parsing_cocci/pretty_print_cocci.cmx ../parsing_c/lib_parsing_c.cmx \
-    lib_engine.cmx ../parsing_cocci/flag_parsing_cocci.cmx \
-    ../globals/flag.cmx ../parsing_c/control_flow_c.cmx ../commons/common.cmx \
-    cocci_vs_c_3.cmx ../parsing_cocci/ast_cocci.cmx ../parsing_c/ast_c.cmx \
-    transformation3.cmi 
+transformation_c.cmo: ../parsing_c/visitor_c.cmi \
+    ../parsing_cocci/type_cocci.cmi ../parsing_c/lib_parsing_c.cmo \
+    lib_engine.cmo flag_matcher.cmo ../parsing_c/control_flow_c.cmi \
+    ../commons/common.cmi cocci_vs_c.cmi ../parsing_cocci/ast_cocci.cmi \
+    ../parsing_c/ast_c.cmo transformation_c.cmi 
+transformation_c.cmx: ../parsing_c/visitor_c.cmx \
+    ../parsing_cocci/type_cocci.cmx ../parsing_c/lib_parsing_c.cmx \
+    lib_engine.cmx flag_matcher.cmx ../parsing_c/control_flow_c.cmx \
+    ../commons/common.cmx cocci_vs_c.cmx ../parsing_cocci/ast_cocci.cmx \
+    ../parsing_c/ast_c.cmx transformation_c.cmi 
index 044cc14..105528d 100644 (file)
 # Coccinelle under other licenses.
 
 
+##############################################################################
+# Variables
+##############################################################################
+#TARGET=matcher
 TARGET=cocciengine
 CTLTARGET=engine
 
-SOURCES = flag_engine.ml lib_engine.ml pretty_print_engine.ml \
-         check_exhaustive_pattern.ml \
-         check_reachability.ml \
-         c_vs_c.ml isomorphisms_c_c.ml \
-          cocci_vs_c_3.ml pattern3.ml sgrep.ml transformation3.ml  \
-         asttomember.ml asttoctl2.ml ctltotex.ml \
-         postprocess_transinfo.ml ctlcocci_integration.ml
+SRC= flag_matcher.ml lib_engine.ml pretty_print_engine.ml \
+      check_exhaustive_pattern.ml \
+      check_reachability.ml \
+      c_vs_c.ml isomorphisms_c_c.ml \
+      cocci_vs_c.ml pattern_c.ml sgrep.ml transformation_c.ml  \
+      asttomember.ml asttoctl2.ml ctltotex.ml \
+      postprocess_transinfo.ml ctlcocci_integration.ml
+
+#c_vs_c.ml
+#SRC= flag_matcher.ml \
+#  c_vs_c.ml cocci_vs_c.ml \
+#  lib_engine.ml \
+#  pattern_c.ml transformation_c.ml 
+
+#LIBS=../commons/commons.cma ../parsing_c/parsing_c.cma
+#INCLUDES= -I ../commons -I ../parsing_c
+INCLUDES = -I ../commons -I ../commons/ocamlextra -I ../globals \
+              -I ../ctl -I ../parsing_cocci -I ../parsing_c 
+LIBS=../commons/commons.cma ../globals/globals.cma \
+     ../ctl/ctl.cma ../parsing_c/parsing_c.cma ../parsing_cocci/cocci_parser.cma
+
+SYSLIBS= str.cma unix.cma 
+
 
 # just to test asttoctl
 # CTLSOURCES = lib_engine.ml pretty_print_engine.ml asttoctl.ml ctltotex.ml \
 #      main.ml
 
-INCLUDES = -I ../commons -I ../commons/ocamlextra -I ../globals \
-              -I ../ctl -I ../parsing_c -I ../parsing_cocci
-
-SYSLIBS = str.cma unix.cma
-LIBS=../commons/commons.cma ../globals/globals.cma \
-     ../ctl/ctl.cma ../parsing_c/c_parser.cma ../parsing_cocci/cocci_parser.cma
-
+##############################################################################
+# Generic variables
+##############################################################################
 
-# The Caml compilers.
+#for warning:  -w A 
+#for profiling:  -p -inline 0   with OCAMLOPT
 OCAMLCFLAGS ?= -g -dtypes
-OCAMLC =ocamlc$(OPTBIN) $(OCAMLCFLAGS) $(INCLUDES)
-OCAMLOPT = ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
-OCAMLDEP = ocamldep$(OPTBIN) $(INCLUDES)
-
-EXEC=$(TARGET).byte
-LIB=$(TARGET).cma
-OPTLIB=$(LIB:.cma=.cmxa)
-
-CTLEXEC=$(CTLTARGET)
 
-OBJS = $(SOURCES:.ml=.cmo)
-OPTOBJS = $(OBJS:.cmo=.cmx)
+OCAMLC=ocamlc$(OPTBIN) $(OCAMLCFLAGS) $(INCLUDES)
+OCAMLOPT=ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
+OCAMLLEX=ocamllex$(OPTBIN) #-ml
+OCAMLYACC=ocamlyacc -v
+OCAMLDEP=ocamldep$(OPTBIN) $(INCLUDES)
+OCAMLMKTOP=ocamlmktop -g -custom $(INCLUDES)
 
-CTLOBJS = $(CTLSOURCES:.ml=.cmo)
-CTLOPTOBJS = $(CTLOBJS:.cmo=.cmx)
 
+OBJS = $(SRC:.ml=.cmo)
+OPTOBJS = $(SRC:.ml=.cmx)
 
-#all: $(EXEC) $(LIB)
-all: $(LIB)
 
-all.opt: $(OPTLIB)
+##############################################################################
+# Top rules
+##############################################################################
+all: $(TARGET).cma
+all.opt: $(TARGET).cmxa
 
-ctl: $(CTLEXEC)
+$(TARGET).cma: $(OBJS)
+       $(OCAMLC) -a -o $(TARGET).cma $(OBJS)
 
+$(TARGET).cmxa: $(OPTOBJS) $(LIBS:.cma=.cmxa)
+       $(OCAMLOPT) -a -o $(TARGET).cmxa $(OPTOBJS)
 
-$(LIB): $(OBJS)
-       $(OCAMLC) -a -o $(LIB) $(OBJS)
+$(TARGET).top: $(OBJS) $(LIBS)
+       $(OCAMLMKTOP) -o $(TARGET).top $(SYSLIBS) $(LIBS) $(OBJS)
 
-# clean rule for LIB
 clean::
-       rm -f $(LIB)
+       rm -f $(TARGET).top
 
 
-$(OPTLIB): $(OPTOBJS) 
-       $(OCAMLOPT) -a -o $(OPTLIB) $(OPTOBJS)
 
+##############################################################################
+# Pad's rules
+##############################################################################
 
-$(EXEC): $(OBJS) main.cmo $(LIBS)
-       $(OCAMLC) -o $(EXEC) $(SYSLIBS) $(LIBS) $(OBJS) main.cmo
+##############################################################################
+# Generic rules
+##############################################################################
 
-$(CTLEXEC): $(CTLOBJS) $(LIBS)
-       $(OCAMLC) -o $(CTLEXEC) $(SYSLIBS) $(LIBS) $(CTLOBJS)
-
-
-# clean rule for LIB.opt
-clean::
-       rm -f $(OPTLIB) $(LIB:.cma=.a)  
-       rm -f $(TARGET) rm -f $(TARGET).byte
-       rm -f $(CTLTARGET)
-
-
-.SUFFIXES:
 .SUFFIXES: .ml .mli .cmo .cmi .cmx
 
 .ml.cmo:
        $(OCAMLC) -c $<
-
 .mli.cmi:
        $(OCAMLC) -c $<
-
 .ml.cmx:
        $(OCAMLOPT) -c $<
 
+.ml.mldepend: 
+       $(OCAMLC) -i $<
 
-# clean rule for others files
 clean::
-       rm -f *.cm[iox] *.o  *.annot
-       rm -f *~ .*~ #*# 
-
-beforedepend:
+       rm -f *.cm[ioxa] *.o *.a *.cmxa *.annot
+clean::
+       rm -f *~ .*~ gmon.out #*#
 
-depend: beforedepend
-       $(OCAMLDEP) *.mli *.ml > .depend
+beforedepend::
 
-.depend: 
-       $(OCAMLDEP) *.mli *.ml > .depend
+depend:: beforedepend
+       $(OCAMLDEP) *.mli *.ml    > .depend
 
 -include .depend
index fca5fcf..6b2a340 100644 (file)
@@ -1229,35 +1229,41 @@ let dots_au is_strict toend label s wrapcode x seq_after y quantifier =
      make_match None false
       (wrapcode
         (Ast.Continue(Ast.make_mcode "continue",Ast.make_mcode ";"))) in
-  let stop_early =
+  let stop_early =
     if quantifier = Exists
-    then CTL.False
+    then Common.Left(CTL.False)
     else if toend
-    then CTL.Or(aftpred label,exitpred label)
+    then Common.Left(CTL.Or(aftpred label,exitpred label))
     else if is_strict
-    then aftpred label
+    then Common.Left(aftpred label)
     else
-      let lv = get_label_ctr() in
-      let labelpred = CTL.Pred(Lib_engine.Label lv,CTL.Control) in
-      let preflabelpred = label_pred_maker (Some (lv,ref true)) in
-      ctl_or (aftpred label)
-       (quantify false [lv]
-          (ctl_and CTL.NONSTRICT
-             (ctl_and CTL.NONSTRICT (truepred label) labelpred)
-             (ctl_au CTL.NONSTRICT
-                (ctl_and CTL.NONSTRICT (ctl_not v) preflabelpred)
-                (ctl_and CTL.NONSTRICT preflabelpred
-                   (ctl_or (retpred None)
-                      (if !Flag_engine.only_return_is_error_exit
-                      then CTL.True
-                      else
-                        (ctl_or matchcontinue
-                           (ctl_and CTL.NONSTRICT
-                              (ctl_or matchgoto matchbreak)
-                              (ctl_ag s (ctl_not seq_after)))))))))) in
-  let v = get_let_ctr() in
+      Common.Right
+       (function v ->
+         let lv = get_label_ctr() in
+         let labelpred = CTL.Pred(Lib_engine.Label lv,CTL.Control) in
+         let preflabelpred = label_pred_maker (Some (lv,ref true)) in
+         ctl_or (aftpred label)
+           (quantify false [lv]
+              (ctl_and CTL.NONSTRICT
+                 (ctl_and CTL.NONSTRICT (truepred label) labelpred)
+                 (ctl_au CTL.NONSTRICT
+                    (ctl_and CTL.NONSTRICT (ctl_not v) preflabelpred)
+                    (ctl_and CTL.NONSTRICT preflabelpred
+                       (ctl_or (retpred None)
+                          (if !Flag_matcher.only_return_is_error_exit
+                          then CTL.True
+                          else
+                            (ctl_or matchcontinue
+                               (ctl_and CTL.NONSTRICT
+                                  (ctl_or matchgoto matchbreak)
+                                  (ctl_ag s (ctl_not seq_after))))))))))) in
   let op = if quantifier = !exists then ctl_au else ctl_anti_au in
-  op s x (CTL.Let(v,y,ctl_or (CTL.Ref v) (stop_early (CTL.Ref v))))
+  let v = get_let_ctr() in
+  op s x
+    (match stop_early with
+      Common.Left x -> ctl_or y x
+    | Common.Right stop_early ->
+       CTL.Let(v,y,ctl_or (CTL.Ref v) (stop_early (CTL.Ref v))))
 
 let rec dots_and_nests plus nest whencodes bef aft dotcode after label
     process_bef_aft statement_list statement guard quantified wrapcode =
index 440f7ba..303be64 100644 (file)
@@ -143,6 +143,7 @@ and typeC tya tyb =
             let sxopt = saopt in
             let ii_b_sx = ii_b_sa in
 
+            (* todo?  iso on name or argument ? *)
             (ba =:= bb && saopt =*= sbopt) >&&>
             fullType ta tb >>= (fun tx -> 
               let paramx = (((bx, sxopt, tx), ii_b_sx)) in
@@ -198,7 +199,9 @@ and typeC tya tyb =
             match xfielda, xfieldb with 
             | EmptyField, EmptyField -> return ((EmptyField, iix)::xs)
 
-            | FieldDeclList fa, FieldDeclList fb -> 
+            | DeclarationField (FieldDeclList (fa, iipta)), 
+              DeclarationField (FieldDeclList (fb, iiptb)) -> 
+                let iipt = iipta in (* TODO ?*)
                 (List.length fa =|= List.length fb) >&&> 
 
                 Common.zip fa fb +> List.fold_left 
@@ -224,7 +227,8 @@ and typeC tya tyb =
                     )
                   ) (return [])
                  >>= (fun fx -> 
-                   return ((FieldDeclList (List.rev fx), iix)::xs)
+                   return (((DeclarationField 
+                               (FieldDeclList (List.rev fx,iipt))), iix)::xs)
                  )
             | _ -> fail
           )
index 297a7d4..53e041f 100644 (file)
@@ -144,6 +144,7 @@ module CFG =
       Control_flow_c.extract_is_loop (cfg#nodes#find n)
     let print_node i = Format.print_string (string_of_int i)
     let size cfg = cfg#nodes#length
+    let print_graph cfg label border_nodes fill_nodes filename = ()
   end
 
 module ENGINE = Ctl_engine.CTL_ENGINE (ENV) (CFG) (PRED)
@@ -161,14 +162,19 @@ let test_formula state formula cfg =
               cfg#nodes#tolist) in
     let verbose = !Flag_ctl.verbose_ctl_engine in
     let pm = !Flag_ctl.partial_match in
+(*     let gt = !Flag_ctl.graphical_trace in *)
     Flag_ctl.verbose_ctl_engine := false;
     Flag_ctl.partial_match := false;
+    Flag_ctl.checking_reachability := true;
+(*     Flag_ctl.graphical_trace := ""; *)
     let res =
       ENGINE.sat (cfg,label,List.map fst cfg#nodes#tolist)
        (CTL.And(CTL.NONSTRICT,CTL.Pred(Node(state)),formula))
        [[Node(state)]] in
     Flag_ctl.verbose_ctl_engine := verbose;
     Flag_ctl.partial_match := pm;
+    Flag_ctl.checking_reachability := false;
+(*     Flag_ctl.graphical_trace := gt; *)
     match res with [] -> false | _ -> true
 
 (* ---------------------------------------------------------------- *)
similarity index 92%
rename from engine/cocci_vs_c_3.ml
rename to engine/cocci_vs_c.ml
index f2348f3..ed20853 100644 (file)
@@ -1,24 +1,16 @@
-(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-* 
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-* 
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-* 
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
-* 
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
+(* Copyright (C) 2006, 2007, 2008 Yoann Padioleau
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License (GPL)
+ * version 2 as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * file license.txt for more details.
+ * 
+ * This file was part of Coccinelle.
+ *)
 
 open Common
 
@@ -27,6 +19,8 @@ module B = Ast_c
 
 module F = Control_flow_c
 
+module Flag = Flag_matcher
+
 (*****************************************************************************)
 (* Wrappers *)
 (*****************************************************************************)
@@ -123,7 +117,12 @@ let generalize_mcode ia =
        A.CONTEXT (A.DontCarePos,x)
     | A.MINUS   (A.NoPos,x) -> 
        A.MINUS   (A.DontCarePos,x)
-    | _ -> raise Impossible in
+
+    | A.CONTEXT ((A.FixPos _|A.DontCarePos), _) 
+    | A.MINUS ((A.FixPos _|A.DontCarePos), _)
+        ->
+        raise Impossible
+  in
   (s1, i, new_mck, pos)
 
 
@@ -156,7 +155,10 @@ let equal_unaryOp a b =
   | A.UnMinus  , B.UnMinus -> true
   | A.Tilde    , B.Tilde   -> true
   | A.Not      , B.Not     -> true
-  | _, _ -> false
+  | _, B.GetRefLabel -> false (* todo cocci? *)
+  | _, (B.Not|B.Tilde|B.UnMinus|B.UnPlus|B.DeRef|B.GetRef) -> false
+      
+
 
 let equal_arithOp a b = 
   match a, b with
@@ -170,7 +172,8 @@ let equal_arithOp a b =
   | A.And      , B.And      -> true
   | A.Or       , B.Or       -> true
   | A.Xor      , B.Xor      -> true
-  | _          , _          -> false
+  | _, (B.Xor|B.Or|B.And|B.DecRight|B.DecLeft|B.Mod|B.Div|B.Mul|B.Minus|B.Plus)
+      -> false
 
 let equal_logicalOp a b = 
   match a, b with
@@ -182,37 +185,38 @@ let equal_logicalOp a b =
   | A.NotEq  , B.NotEq  -> true
   | A.AndLog , B.AndLog -> true
   | A.OrLog  , B.OrLog  -> true
-  | _          , _          -> false
+  | _, (B.OrLog|B.AndLog|B.NotEq|B.Eq|B.SupEq|B.InfEq|B.Sup|B.Inf)
+      -> false
 
 let equal_assignOp a b = 
   match a, b with
   | A.SimpleAssign, B.SimpleAssign -> true
   | A.OpAssign a,   B.OpAssign b -> equal_arithOp a b
-  | _ -> false
+  | _, (B.OpAssign _|B.SimpleAssign) -> false
 
 let equal_fixOp a b = 
   match a, b with
   | A.Dec, B.Dec -> true
   | A.Inc, B.Inc -> true
-  | _ -> false
+  | _, (B.Inc|B.Dec) -> false
 
 let equal_binaryOp a b = 
   match a, b with
   | A.Arith a,    B.Arith b ->   equal_arithOp a b
   | A.Logical a,  B.Logical b -> equal_logicalOp a b
-  | _ -> false
+  | _, (B.Logical _ | B.Arith _) -> false
 
 let equal_structUnion a b = 
   match a, b with
   | A.Struct, B.Struct -> true
   | A.Union,  B.Union -> true
-  | _, _ -> false
+  | _, (B.Struct|B.Union) -> false
 
 let equal_sign a b = 
   match a, b with
   | A.Signed,    B.Signed   -> true
   | A.Unsigned,  B.UnSigned -> true
-  | _, _ -> false
+  | _, (B.UnSigned|B.Signed) -> false
 
 let equal_storage a b = 
   match a, b with
@@ -221,7 +225,9 @@ let equal_storage a b =
   | A.Register , B.Sto B.Register
   | A.Extern   , B.Sto B.Extern 
       -> true
-  | _ -> false
+  | _, (B.NoSto | B.StoTypedef) -> false
+  | _, (B.Sto (B.Register|B.Static|B.Auto|B.Extern)) -> false
+
 
 (*---------------------------------------------------------------------------*)
 
@@ -262,15 +268,20 @@ let equal_metavarval valu valu' =
         
   | Ast_c.MetaPosValList l1, Ast_c.MetaPosValList l2 ->
       List.exists
-       (function (fla,posa1,posa2) ->
+       (function (fla,cea,posa1,posa2) ->
          List.exists
-           (function (flb,posb1,posb2) ->
-             fla = flb &&
+           (function (flb,ceb,posb1,posb2) ->
+             fla = flb && cea = ceb &&
              Ast_c.equal_posl posa1 posb1 && Ast_c.equal_posl posa2 posb2)
             l2)
        l1
-  | _ -> raise Impossible
 
+  | (B.MetaPosValList _|B.MetaListlenVal _|B.MetaPosVal _|B.MetaStmtVal _
+      |B.MetaTypeVal _
+      |B.MetaParamListVal _|B.MetaParamVal _|B.MetaExprListVal _
+      |B.MetaExprVal _|B.MetaLocalFuncVal _|B.MetaFuncVal _|B.MetaIdVal _
+    ), _
+      -> raise Impossible
 
 
 (*---------------------------------------------------------------------------*)
@@ -422,7 +433,11 @@ let initialisation_to_affectation decl =
       (match xs with
       | [] -> raise Impossible
       | [x] -> 
-          let ((var, returnType, storage, local),iisep) = x in
+          let ({B.v_namei = var;
+                B.v_type = returnType;
+                B.v_storage = storage;
+                B.v_local = local},
+              iisep) = x in
 
           (match var with
           | Some ((s, ini),  iis::iini) -> 
@@ -528,7 +543,7 @@ module type PARAM =
       matcher
 
     val distrf_struct_fields : 
-      (A.meta_name A.mcode, B.field B.wrap list) matcher
+      (A.meta_name A.mcode, B.field list) matcher
 
     val distrf_cst : 
       (A.meta_name A.mcode, (B.constant, string) either B.wrap) matcher
@@ -549,7 +564,7 @@ module type PARAM =
     val envf :
       A.keep_binding -> A.inherited -> 
       A.meta_name A.mcode * Ast_c.metavar_binding_kind *
-         (unit -> Common.filename * Ast_c.posl * Ast_c.posl) ->
+         (unit -> Common.filename * string * Ast_c.posl * Ast_c.posl) ->
       (unit -> tin -> 'x tout) -> (tin -> 'x tout)
 
     val check_constraints :
@@ -726,7 +741,7 @@ let rec (expression: (A.expression, Ast_c.expression) matcher) =
        
        
 
-  | A.MetaErr _, _ -> failwith "not handling MetaErr"
+  | A.MetaErr _,     _ -> failwith "not handling MetaErr"
 
   (* todo?: handle some isomorphisms in int/float ? can have different
    * format : 1l can match a 1.
@@ -772,7 +787,9 @@ let rec (expression: (A.expression, Ast_c.expression) matcher) =
               ))
           | _ -> fail (* multi string, not handled *)
           )
-      | _, _ -> fail
+
+      | _, B.MultiString -> (* todo cocci? *) fail
+      | _, (B.String _ | B.Float _ | B.Char _ | B.Int _) -> fail
       )
 
 
@@ -1019,17 +1036,17 @@ let rec (expression: (A.expression, Ast_c.expression) matcher) =
          failwith
            "for nestexpr, only handling the case with dots and only one exp")
 
-  | A.NestExpr _, _ ->
+  | A.NestExpr _,     _ ->
       failwith "only handling multi and no when code in a nest expr"
 
   (* only in arg lists or in define body *)  
-  | A.TypeExp _, _ -> fail
+  | A.TypeExp _,    _ -> fail
 
   (* only in arg lists *)
-  | A.MetaExprList _, _   
-  | A.EComma _, _  
-  | A.Ecircles _, _ 
-  | A.Estars _, _   
+  | A.MetaExprList _,    _   
+  | A.EComma _,    _  
+  | A.Ecircles _,    
+  | A.Estars _,    _   
       ->
        raise Impossible
 
@@ -1047,7 +1064,20 @@ let rec (expression: (A.expression, Ast_c.expression) matcher) =
   | _, ((B.Constructor _,_),_) 
     -> fail
 
-  | _, _ -> fail
+
+  | _, 
+     (((B.Cast (_, _)|B.ParenExpr _|B.SizeOfType _|B.SizeOfExpr _|
+     B.RecordPtAccess (_, _)|
+     B.RecordAccess (_, _)|B.ArrayAccess (_, _)|
+     B.Binary (_, _, _)|B.Unary (_, _)|
+     B.Infix (_, _)|B.Postfix (_, _)|
+     B.Assignment (_, _, _)|B.CondExpr (_, _, _)|
+     B.FunCall (_, _)|B.Constant _|B.Ident _),
+     _),_)
+       -> fail
+
+
+
 
 
 
@@ -1591,8 +1621,8 @@ and (declaration: (A.mcodekind * bool * A.declaration,B.declaration) matcher) =
             (B.MacroDecl ((sb,ebs),
                          [iisb;lpb;rpb;iiendb;iifakestart] ++ iistob))
           ))))))))
-  
-  | _ -> fail
+
+  | _, (B.MacroDecl _ |B.DeclList _) -> fail
 
 
 
@@ -1604,7 +1634,12 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) ->
   * T { }; that we want to match against typedef struct { } xx_t;
   *)
  | A.TyDecl (tya0, ptvirga), 
-   ((Some ((idb, None),[iidb]), typb0, (B.StoTypedef, inl), local), iivirg) ->
+   ({B.v_namei = Some ((idb, None),[iidb]);
+     B.v_type = typb0;
+     B.v_storage = (B.StoTypedef, inl);
+     B.v_local = local; 
+     B.v_attr = attrs;
+   }, iivirg) ->
 
    (match A.unwrap tya0, typb0 with
    | A.Type(cv1,tya1), ((qu,il),typb1) ->
@@ -1662,8 +1697,12 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) ->
 
                      return (
                      (A.TyDecl (tya0, ptvirga)) +> A.rewrap decla,
-                     (((Some ((idb, None),[iidb]), typb0, (B.StoTypedef, inl),
-                       local),
+                     (({B.v_namei = Some ((idb, None),[iidb]);
+                        B.v_type = typb0;
+                        B.v_storage = (B.StoTypedef, inl);
+                        B.v_local = local;
+                        B.v_attr = attrs;
+                     },
                        iivirg),iiptvirgb,iistob)
                      )
                 | _ -> raise Impossible    
@@ -1686,8 +1725,12 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) ->
                
                    return (
                      (A.TyDecl (tya0, ptvirga)) +> A.rewrap decla,
-                     (((Some ((idb, None),[iidb]), typb0,
-                       (B.StoTypedef, inl), local),
+                     (({B.v_namei = Some ((idb, None),[iidb]);
+                        B.v_type = typb0;
+                        B.v_storage = (B.StoTypedef, inl);
+                        B.v_local = local;
+                        B.v_attr = attrs;
+                     },
                       iivirg),iiptvirgb,iistob)
                    )
                | _ -> raise Impossible    
@@ -1702,18 +1745,28 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) ->
    )
          
    | A.UnInit (stoa, typa, ida, ptvirga), 
-     ((Some ((idb, _),[iidb]), typb, (B.StoTypedef,_), _local), iivirg) -> 
+     ({B.v_namei = Some ((idb, _),[iidb]);
+       B.v_storage = (B.StoTypedef,_);
+     }, iivirg) -> 
        fail
 
    | A.Init (stoa, typa, ida, eqa, inia, ptvirga), 
-     ((Some ((idb, _),[iidb]), typb, (B.StoTypedef,_), _local), iivirg) -> 
+     ({B.v_namei = Some ((idb, _),[iidb]);
+       B.v_storage = (B.StoTypedef,_);
+     }, iivirg) -> 
        fail
 
 
 
     (* could handle iso here but handled in standard.iso *)
    | A.UnInit (stoa, typa, ida, ptvirga), 
-     ((Some ((idb, None),[iidb]), typb, stob, local), iivirg) -> 
+     ({B.v_namei = Some ((idb, None),[iidb]);
+       B.v_type = typb;
+       B.v_storage = stob;
+       B.v_local = local;
+       B.v_attr = attrs;
+     }, iivirg) -> 
+
        tokenf ptvirga iiptvirgb >>= (fun ptvirga iiptvirgb -> 
        fullType typa typb >>= (fun typa typb -> 
        ident DontKnow ida (idb, iidb) >>= (fun ida (idb, iidb) -> 
@@ -1721,12 +1774,22 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) ->
         (fun stoa (stob, iistob) -> 
          return (
            (A.UnInit (stoa, typa, ida, ptvirga)) +>  A.rewrap decla,
-           (((Some ((idb,None),[iidb]),typb,stob,local),iivirg),
+           (({B.v_namei = Some ((idb,None),[iidb]);
+              B.v_type = typb;
+              B.v_storage = stob;
+              B.v_local = local;
+              B.v_attr = attrs;
+           },iivirg),
            iiptvirgb,iistob)
          )))))
 
    | A.Init (stoa, typa, ida, eqa, inia, ptvirga), 
-     ((Some((idb,Some inib),[iidb;iieqb]),typb,stob,local),iivirg)
+     ({B.v_namei = Some((idb,Some inib),[iidb;iieqb]);
+       B.v_type = typb;
+       B.v_storage = stob;
+       B.v_local = local;
+       B.v_attr = attrs;
+     },iivirg)
        ->
        tokenf ptvirga iiptvirgb >>= (fun ptvirga iiptvirgb -> 
        tokenf eqa iieqb >>= (fun eqa iieqb -> 
@@ -1737,25 +1800,46 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) ->
        initialiser inia inib >>= (fun inia inib -> 
          return (
            (A.Init (stoa, typa, ida, eqa, inia, ptvirga)) +> A.rewrap decla,
-           (((Some((idb,Some inib),[iidb;iieqb]),typb,stob,local),iivirg),
+           (({B.v_namei = Some((idb,Some inib),[iidb;iieqb]);
+              B.v_type = typb;
+              B.v_storage = stob;
+              B.v_local = local;
+              B.v_attr = attrs;
+           },iivirg),
            iiptvirgb,iistob)
          )))))))
            
    (* do iso-by-absence here ? allow typedecl and var ? *)
-   | A.TyDecl (typa, ptvirga), ((None, typb, stob, local), iivirg)  ->
+   | A.TyDecl (typa, ptvirga), 
+     ({B.v_namei = None; B.v_type = typb; 
+       B.v_storage = stob; 
+       B.v_local = local;
+       B.v_attr = attrs;
+     }, iivirg)  ->
+
        if stob = (B.NoSto, false)
        then
          tokenf ptvirga iiptvirgb >>= (fun ptvirga iiptvirgb -> 
          fullType typa typb >>= (fun typa typb -> 
            return (
              (A.TyDecl (typa, ptvirga)) +> A.rewrap decla,
-             (((None, typb, stob, local), iivirg), iiptvirgb, iistob)
+             (({B.v_namei = None;
+                B.v_type = typb;
+                B.v_storage = stob;
+                B.v_local = local;
+                B.v_attr = attrs;
+             }, iivirg), iiptvirgb, iistob)
            )))
        else fail
 
 
    | A.Typedef (stoa, typa, ida, ptvirga), 
-     ((Some ((idb, None),[iidb]),typb,(B.StoTypedef,inline),local),iivirg) ->
+     ({B.v_namei = Some ((idb, None),[iidb]);
+       B.v_type = typb;
+       B.v_storage = (B.StoTypedef,inline);
+       B.v_local = local;
+       B.v_attr = attrs;
+     },iivirg) ->
 
        tokenf ptvirga iiptvirgb >>= (fun ptvirga iiptvirgb -> 
        fullType typa typb >>= (fun typa typb -> 
@@ -1793,14 +1877,19 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) ->
        ) >>= (fun ida (idb, iidb) ->
          return (
            (A.Typedef (stoa, typa, ida, ptvirga)) +> A.rewrap decla,
-           (((Some ((idb, None),[iidb]), typb, (B.StoTypedef,inline),local),
+           (({B.v_namei = Some ((idb, None),[iidb]);
+              B.v_type = typb;
+              B.v_storage = (B.StoTypedef,inline);
+              B.v_local = local;
+              B.v_attr = attrs;
+           },
             iivirg),
             iiptvirgb, iistob)
          )
        ))))
              
        
-   | _, ((None, typb, sto, _local), _) -> 
+   | _, ({B.v_namei = None;}, _) -> 
        (* old:   failwith "no variable in this declaration, wierd" *)
        fail
 
@@ -1819,11 +1908,12 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) ->
    | A.Ddots(dots,whencode), _ ->
        raise Impossible
             
-   | A.OptDecl _, _ | A.UniqueDecl _, _ -> 
+   | A.OptDecl _,    _ | A.UniqueDecl _,     _ -> 
        failwith "not handling Opt/Unique Decl"
 
+   | _, ({B.v_namei=Some _}, _)
+       -> fail
 
-   | _, _ -> fail
 
 
 
@@ -1949,8 +2039,13 @@ and (initialiser: (A.initialiser, Ast_c.initialiser) matcher) =  fun ia ib ->
 
     | A.UniqueIni _,_ | A.OptIni _,_ -> 
       failwith "not handling Opt/Unique on initialisers"
-          
-    | _, _ -> fail
+
+    | _, (B.InitIndexOld (_, _), _) -> fail 
+    | _, (B.InitFieldOld (_, _), _) -> fail 
+
+    | _, ((B.InitDesignators (_, _)|B.InitList _|B.InitExpr _), _)
+        -> fail
+
 
 
 
@@ -2026,7 +2121,7 @@ and initialisers_unordered2 = fun ias ibs ->
        
 
 (* ------------------------------------------------------------------------- *)
-and (struct_fields: (A.declaration list, B.field B.wrap list) matcher) =
+and (struct_fields: (A.declaration list, B.field list) matcher) =
  fun eas ebs -> 
   match eas, ebs with
   | [], [] -> return ([], [])
@@ -2069,12 +2164,13 @@ and (struct_fields: (A.declaration list, B.field B.wrap list) matcher) =
       | _unwrapx, [] -> fail
       )
 
-and (struct_field: (A.declaration, B.field B.wrap) matcher) = fun fa fb -> 
-  let (xfield, ii) = fb in
-  let iiptvirgb = tuple_of_list1 ii in
+and (struct_field: (A.declaration, B.field) matcher) = fun fa fb -> 
+  let (xfield, iifield) = fb in
 
   match xfield with 
-  | B.FieldDeclList onefield_multivars -> 
+  | B.DeclarationField (B.FieldDeclList (onefield_multivars,iiptvirg)) -> 
+
+    let iiptvirgb = tuple_of_list1 iiptvirg in
 
     (match onefield_multivars with
     | [] -> raise Impossible
@@ -2095,19 +2191,29 @@ and (struct_field: (A.declaration, B.field B.wrap) matcher) = fun fa fb ->
           let iisto = [] in
           let stob = B.NoSto, false in
           let fake_var = 
-            ((Some ((idb, None),[iidb]), typb, stob, Ast_c.NotLocalDecl),
+            ({B.v_namei = Some ((idb, None),[iidb]);
+              B.v_type = typb;
+              B.v_storage = stob;
+              B.v_local = Ast_c.NotLocalDecl;
+              B.v_attr = Ast_c.noattr;
+            },
             iivirg)            
           in
           onedecl allminus fa (fake_var,iiptvirgb,iisto) >>= 
             (fun fa (var,iiptvirgb,iisto) -> 
 
               match fake_var with
-              | ((Some ((idb, None),[iidb]), typb, stob, local), iivirg) -> 
+              | ({B.v_namei = Some ((idb, None),[iidb]);
+                  B.v_type = typb;
+                  B.v_storage = stob;
+                }, iivirg) -> 
                   let onevar = B.Simple (Some idb, typb), [iidb] in
                   
                   return (
                     (fa),
-                    (B.FieldDeclList [onevar, iivirg], [iiptvirgb])
+                    ((B.DeclarationField 
+                        (B.FieldDeclList ([onevar, iivirg], [iiptvirgb]))),
+                    iifield)
                   )
               | _ -> raise Impossible
             )
@@ -2117,7 +2223,13 @@ and (struct_field: (A.declaration, B.field B.wrap) matcher) = fun fa fb ->
       pr2_once "PB: More that one variable in decl. Have to split";
       fail
     )
-  | B.EmptyField -> fail
+  | B.EmptyField -> 
+      let _iiptvirgb = tuple_of_list1 iifield in
+      fail
+
+  | B.MacroStructDeclTodo -> fail
+  | B.CppDirectiveStruct directive -> fail
+  | B.IfdefStruct directive -> fail
 
 
 
@@ -2313,10 +2425,9 @@ and (typeC: (A.typeC, Ast_c.typeC) matcher) =
           pr2_once 
             "warning: long long or long double not handled by ast_cocci";
           fail
-          
-          
-      | _, _ -> fail
-          
+
+      | _, (B.Void|B.FloatType _|B.IntType _) -> fail
+
           
       )
 
@@ -2534,8 +2645,19 @@ and (typeC: (A.typeC, Ast_c.typeC) matcher) =
 
     | _, (B.TypeOfExpr e, ii) -> fail
     | _, (B.TypeOfType e, ii) -> fail
-          
-    | _, _ -> fail
+
+    | _, (B.ParenType e, ii) -> fail (* todo ?*)
+    | _, (B.EnumName _, _) -> fail (* todo cocci ?*)
+    | _, (B.Enum _, _) -> fail (* todo cocci ?*)
+
+    | _,
+     ((B.TypeName (_, _)|B.StructUnionName (_, _)|
+      B.StructUnion (_, _, _)|
+      B.FunctionType _|B.Array (_, _)|B.Pointer _|
+      B.BaseType _),
+     _)
+     -> fail
+
 
 (* todo: iso on sign, if not mentioned then free.  tochange? 
  * but that require to know if signed int because explicit
@@ -2656,9 +2778,13 @@ and compatible_type a (b,_local) =
             pr2_once "no longdouble in cocci";
             fail
        | Type_cocci.BoolType, _ -> failwith "no booltype in C"
-       | _ -> fail
-             
+
+
+        | _, (B.Void|B.FloatType _|B.IntType _) -> fail
       )
+
+
+
     | Type_cocci.Pointer  a, (qub, (B.Pointer b, ii)) -> 
        loop (a,b)
     | Type_cocci.FunctionPointer a, _ ->
@@ -2714,7 +2840,26 @@ and compatible_type a (b,_local) =
   (* for metavariables of type expression *^* *)
     | Type_cocci.Unknown , _ -> ok
 
-    | _ -> fail in
+    | (_,
+      (_,
+      ((
+       B.TypeOfType _|B.TypeOfExpr _|B.ParenType _|
+       B.EnumName _|B.StructUnion (_, _, _)|B.Enum (_, _)
+      ),
+      _))) -> fail
+
+    | (_,
+      (_,
+      ((
+       B.StructUnionName (_, _)|
+       B.FunctionType _|
+       B.Array (_, _)|B.Pointer _|B.TypeName _|
+       B.BaseType _
+      ),
+      _))) -> fail
+
+
+  in
   loop (a,b)
 
 and compatible_sign signa signb = 
@@ -2731,7 +2876,7 @@ and equal_structUnion_type_cocci a b =
   match a, b with
   | Type_cocci.Struct, B.Struct -> true
   | Type_cocci.Union,  B.Union -> true
-  | _, _ -> false
+  | _, (B.Struct | B.Union) -> false
 
 
 
@@ -3062,7 +3207,13 @@ let rec (rule_elem_node: (A.rule_elem, Control_flow_c.node) matcher) =
 
 
   | A.FunHeader (mckstart, allminus, fninfoa, ida, oparen, paramsa, cparen),
-    F.FunHeader ((idb, (retb, (paramsb, (isvaargs, iidotsb))), stob), ii) -> 
+    F.FunHeader ({B.f_name = idb;
+                  f_type = (retb, (paramsb, (isvaargs, iidotsb)));
+                  f_storage = stob;
+                  f_attr = attrs;
+                  f_body = body;
+                  }, ii) -> 
+      assert (null body);
 
       (* fninfoa records the order in which the SP specified the various
         information, but this isn't taken into account in the matching.
@@ -3120,8 +3271,12 @@ let rec (rule_elem_node: (A.rule_elem, Control_flow_c.node) matcher) =
              return (
                A.FunHeader(mckstart,allminus,fninfoa,ida,oparen,
                           paramsa,cparen),
-               F.FunHeader ((idb, (retb, (paramsb, (isvaargs, iidotsb))), 
-                            stob), 
+               F.FunHeader ({B.f_name = idb;
+                             f_type = (retb, (paramsb, (isvaargs, iidotsb)));
+                             f_storage = stob;
+                             f_attr = attrs;
+                             f_body = body;
+                           },
                            iidb::ioparenb::icparenb::iifakestart::iistob)
                 )
               ))))))))
@@ -3301,8 +3456,14 @@ let rec (rule_elem_node: (A.rule_elem, Control_flow_c.node) matcher) =
 
 
 
-  | A.Include(incla,filea), F.Include ((fileb, ii), (h_rel_pos, inifdef)) ->
-
+  | A.Include(incla,filea), 
+    F.Include {B.i_include = (fileb, ii);
+               B.i_rel_pos = h_rel_pos;
+               B.i_is_in_ifdef = inifdef;
+               B.i_content = copt;
+              } ->
+      assert (copt = None);
+      
       let include_requirment = 
         match mcodekind incla, mcodekind filea with
         | A.CONTEXT (_, A.BEFORE _), _ -> 
@@ -3320,7 +3481,11 @@ let rec (rule_elem_node: (A.rule_elem, Control_flow_c.node) matcher) =
         tokenf filea iifileb >>= (fun filea iifileb -> 
           return (
             A.Include(incla, filea),
-            F.Include ((fileb, [inclb;iifileb]), (h_rel_pos, inifdef))
+            F.Include {B.i_include = (fileb, [inclb;iifileb]);
+                       B.i_rel_pos = h_rel_pos;
+                       B.i_is_in_ifdef = inifdef;
+                       B.i_content = copt;
+            }
           )))
       else fail
 
@@ -3417,12 +3582,27 @@ let rec (rule_elem_node: (A.rule_elem, Control_flow_c.node) matcher) =
   (* todo?: print a warning at least ? *)
   | _, F.CaseRange _  
   | _, F.Asm _
-  | _, F.Ifdef _
   | _, F.MacroTop _
     -> fail2()
 
+  | _, (F.IfdefEndif _|F.IfdefElse _|F.IfdefHeader _)
+    -> fail2 ()
+
+  | _, 
+    (F.MacroStmt (_, _)| F.DefineDoWhileZeroHeader _| F.EndNode|F.TopNode)
+      -> fail
+  | _, 
+    (F.Label (_, _)|F.Break (_, _)|F.Continue (_, _)|F.Default (_, _)|
+    F.Case (_, _)|F.Include _|F.Goto _|F.ExprStatement _|
+    F.DefineType _|F.DefineExpr _|F.DefineTodo|
+    F.DefineHeader (_, _)|F.ReturnExpr (_, _)|F.Return (_, _)|F.MacroIterHeader (_, _)|
+    F.SwitchHeader (_, _)|F.ForHeader (_, _)|F.DoWhileTail _|F.DoHeader (_, _)|
+    F.WhileHeader (_, _)|F.Else _|F.IfHeader (_, _)|
+    F.SeqEnd (_, _)|F.SeqStart (_, _, _)|
+    F.Decl _|F.FunHeader _)
+      -> fail
+
 
-  | _, _ -> fail  
   )
 end
 
similarity index 98%
rename from engine/cocci_vs_c_3.mli
rename to engine/cocci_vs_c.mli
index 514ef64..3e28251 100644 (file)
@@ -109,7 +109,7 @@ module type PARAM =
       matcher
 
     val distrf_struct_fields :
-      (Ast_cocci.meta_name Ast_cocci.mcode, Ast_c.field Ast_c.wrap list) 
+      (Ast_cocci.meta_name Ast_cocci.mcode, Ast_c.field list) 
       matcher
 
     val distrf_cst :
@@ -145,7 +145,7 @@ module type PARAM =
       Ast_cocci.inherited ->
       Ast_cocci.meta_name Ast_cocci.mcode * Ast_c.metavar_binding_kind *
          (* pos info, if needed *)
-         (unit -> Common.filename * Ast_c.posl * Ast_c.posl) ->
+         (unit -> Common.filename * string * Ast_c.posl * Ast_c.posl) ->
       (unit -> tin -> 'x tout) -> (tin -> 'x tout)
 
     val check_constraints :
index 2b6c75f..1c04b18 100644 (file)
@@ -30,7 +30,7 @@ module F = Control_flow_c
 (* Debugging functions *)
 (*****************************************************************************)
 let show_or_not_predicate pred = 
-  if !Flag_engine.debug_engine then begin 
+  if !Flag_matcher.debug_engine then begin 
     indent_do (fun () -> 
       adjust_pp_with_indent_and_header "labeling: pred = " (fun () -> 
         Pretty_print_engine.pp_predicate pred;
@@ -39,7 +39,7 @@ let show_or_not_predicate pred =
   end
 
 let show_or_not_nodes nodes =
-  if !Flag_engine.debug_engine  then begin 
+  if !Flag_matcher.debug_engine  then begin 
     indent_do (fun () -> 
       adjust_pp_with_indent_and_header "labeling: result = " (fun () -> 
         Common.pp_do_in_box (fun () -> 
@@ -116,7 +116,7 @@ let (labels_for_ctl: string list (* dropped isos *) ->
 
       | Lib_engine.Match (re), _unwrapnode -> 
           let substs = 
-            Pattern3.match_re_node dropped_isos re node binding
+            Pattern_c.match_re_node dropped_isos re node binding
             +> List.map (fun (re', subst) -> 
               Lib_engine.Match (re'), subst
             )
@@ -327,7 +327,7 @@ module ENV =
 
 module CFG = 
   struct
-    type node = int
+    type node = Ograph_extended.nodei
     type cfg = (F.node, F.edge) Ograph_extended.ograph_mutable
     let predecessors cfg n = List.map fst ((cfg#predecessors n)#tolist)
     let successors   cfg n = List.map fst ((cfg#successors n)#tolist)
@@ -335,6 +335,24 @@ module CFG =
       Control_flow_c.extract_is_loop (cfg#nodes#find n)
     let print_node i = Format.print_string (i_to_s i)
     let size cfg = cfg#nodes#length
+
+    (* In ctl_engine, we use 'node' for the node but in the Ograph_extended 
+     * terminology, this 'node' is in fact an index to access the real
+     * node information (that ctl/ wants to abstract away to be more generic),
+     * the 'Ograph_extended.nodei'.
+     *)
+    let print_graph cfg label border_colors fill_colors filename = 
+      Ograph_extended.print_ograph_mutable_generic cfg label
+        (fun (nodei, (node: F.node)) -> 
+          (* the string julia wants to put ? *)
+          let bc = try Some(List.assoc nodei border_colors) with _ -> None in
+          let fc = try Some(List.assoc nodei fill_colors) with _ -> None in
+          (* the string yoann put as debug information in the cfg *)
+          let str = snd node in
+          (str,bc,fc)
+        )
+        ~output_file:filename
+        ~launch_gv:false
   end
 
 
@@ -408,7 +426,7 @@ let (mysat2:
       WRAPPED_ENGINE.satbis (flow, label, states) ctl (used_after, binding2)
     in
     if not (!Flag_parsing_cocci.sgrep_mode || !Flag.sgrep_mode2 ||
-            !Flag_engine.allow_inconsistent_paths)
+            !Flag_matcher.allow_inconsistent_paths)
     then Check_reachability.check_reachability triples flow;
     let (trans_info2,used_after_fresh_envs) =
       Postprocess_transinfo.process used_after binding2 trans_info2 in
dissimilarity index 71%
index 3140109..950835c 100644 (file)
@@ -1,34 +1,12 @@
-(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-* 
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-* 
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-* 
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
-* 
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
-
-let debug_engine = ref false
-
-(* false = simpler formulas, only for debugging *)
-let useEU = ref true
-
-let disallow_nested_exps = ref false
-
-(* if this flag is not set, then break and continue are also error exits *)
-let only_return_is_error_exit = ref false
-
-(* a hack to allow adding code in some more sgrep-like uses *)
-let allow_inconsistent_paths = ref false
+let debug_engine = ref false
+
+(* false = simpler formulas, only for debugging *)
+let useEU = ref true
+
+let disallow_nested_exps = ref false
+
+(* if this flag is not set, then break and continue are also error exits *)
+let only_return_is_error_exit = ref false
+
+(* a hack to allow adding code in some more sgrep-like uses *)
+let allow_inconsistent_paths = ref false
diff --git a/engine/flag_matcher.ml b/engine/flag_matcher.ml
new file mode 100644 (file)
index 0000000..885eb3d
--- /dev/null
@@ -0,0 +1,14 @@
+let debug_engine = ref false
+
+(* false = simpler formulas, only for debugging *)
+let useEU = ref true
+
+let disallow_nested_exps = ref false
+
+(* if this flag is not set, then break and continue are also error exits *)
+let only_return_is_error_exit = ref false
+
+(* a hack to allow adding code in some more sgrep-like uses *)
+let allow_inconsistent_paths = ref false
+
+let show_misc = ref true
index ba36fc4..8b9bf26 100644 (file)
@@ -42,6 +42,7 @@ type predicate =
   | BindBad  of Ast_cocci.meta_name
   | FakeBrace
 
+(* coccionly: *)
 type ctlcocci = (predicate, Ast_cocci.meta_name) Wrapper_ctl.wrapped_ctl
 
 
@@ -64,6 +65,7 @@ and metavars_binding2 = (mvar, metavar_binding_kind2) Common.assoc
 (*****************************************************************************)
 (* the CTL model related types *)
 (*****************************************************************************)
+(* coccionly: *)
 type label_ctlcocci = 
  predicate -> 
  (nodei * 
similarity index 92%
rename from engine/pattern3.ml
rename to engine/pattern_c.ml
index 88560ee..68cde1e 100644 (file)
@@ -1,27 +1,19 @@
-(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-* 
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-* 
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-* 
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
-* 
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
-
+(* Copyright (C) 2006, 2007 Yoann Padioleau
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License (GPL)
+ * version 2 as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * file license.txt for more details.
+ * 
+ * This file was part of Coccinelle.
+ *)
 open Common
 
+module Flag_engine = Flag_matcher
 (*****************************************************************************)
 (* The functor argument  *) 
 (*****************************************************************************)
@@ -146,7 +138,7 @@ module XMATCH = struct
     else fail tin
 
 
-  let mode = Cocci_vs_c_3.PatternMode
+  let mode = Cocci_vs_c.PatternMode
 
   (* ------------------------------------------------------------------------*)
   (* Exp  *) 
@@ -301,7 +293,7 @@ module XMATCH = struct
           inherited variables *)
        (match Common.optionise (fun () -> tin.binding0 +> List.assoc c) with
          Some valu' ->
-           if Cocci_vs_c_3.equal_metavarval exp valu'
+           if Cocci_vs_c.equal_metavarval exp valu'
            then success else failure
        | None ->
            (* if the variable is not there, it puts no constraints *)
@@ -324,14 +316,14 @@ module XMATCH = struct
     then
       match Common.optionise (fun () -> tin.binding0 +> List.assoc k) with
       | Some (valu') ->
-          if Cocci_vs_c_3.equal_metavarval valu valu'
+          if Cocci_vs_c.equal_metavarval valu valu'
           then Some tin.binding
           else None
       |        None -> None
     else
       match Common.optionise (fun () -> tin.binding +> List.assoc k) with
       | Some (valu') ->
-          if Cocci_vs_c_3.equal_metavarval valu valu'
+          if Cocci_vs_c.equal_metavarval valu valu'
           then Some tin.binding
           else None
              
@@ -384,8 +376,8 @@ module XMATCH = struct
        (match Ast_cocci.get_pos_var k with
          Ast_cocci.MetaPos(name,constraints,per,keep,inherited) ->
            let pvalu =
-             let (file,min,max) = get_max_min() in
-             Ast_c.MetaPosValList[(file,min,max)] in
+             let (file,current_element,min,max) = get_max_min() in
+             Ast_c.MetaPosValList[(file,current_element,min,max)] in
            (* check constraints.  success means that there is a match with
               one of the constraints, which will ultimately result in
               failure. *)
@@ -468,7 +460,7 @@ end
 (*****************************************************************************)
 (* Entry point  *) 
 (*****************************************************************************)
-module MATCH  = Cocci_vs_c_3.COCCI_VS_C (XMATCH)
+module MATCH  = Cocci_vs_c.COCCI_VS_C (XMATCH)
 
 
 let match_re_node2 dropped_isos a b binding0 = 
similarity index 100%
rename from engine/pattern3.mli
rename to engine/pattern_c.mli
index 89b30b7..f442ef3 100644 (file)
@@ -40,7 +40,7 @@ let get_extra _ =
 let read_fresh_id () =
   try 
     let s = read_line () in
-    match Parse_c.tokens_string s with
+    match Parse_c.tokens_of_string s with
       [Parser_c.TIdent _; Parser_c.EOF _] -> s
     | _ -> failwith ("wrong fresh id: " ^ s)
   with End_of_file -> get_extra()
index 0dd3bb3..0b913a4 100644 (file)
@@ -52,9 +52,9 @@ let rec pp_binding_kind = function
       pp (Common.sprintf ("poss[%s]")
            (String.concat ", "
               (List.map
-                 (function (fl,(minl,minc),(maxl,maxc)) ->
-                   Printf.sprintf "(%s,(%d,%d),(%d,%d))"
-                     fl minl minc maxl maxc)
+                 (function (fl,ce,(minl,minc),(maxl,maxc)) ->
+                   Printf.sprintf "(%s,%s,(%d,%d),(%d,%d))"
+                     fl ce minl minc maxl maxc)
                  l)))
 
 and pp_binding subst = 
similarity index 94%
rename from engine/transformation3.ml
rename to engine/transformation_c.ml
index 84a3d33..ec3a2b0 100644 (file)
@@ -1,29 +1,21 @@
-(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-* 
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-* 
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-* 
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
-* 
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
-
-
+(* Copyright (C) 2006, 2007 Yoann Padioleau
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License (GPL)
+ * version 2 as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * file license.txt for more details.
+ * 
+ * This file was part of Coccinelle.
+ *)
 open Common
 
 module F = Control_flow_c
 
+module Flag = Flag_matcher
 (*****************************************************************************)
 (* The functor argument  *) 
 (*****************************************************************************)
@@ -100,7 +92,7 @@ module XTRANS = struct
   let value_format_flag f = fun tin -> 
     f (tin.extra.value_format_iso) tin
 
-  let mode = Cocci_vs_c_3.TransformMode
+  let mode = Cocci_vs_c.TransformMode
 
   (* ------------------------------------------------------------------------*)
   (* Exp  *) 
@@ -187,9 +179,12 @@ module XTRANS = struct
     let (oldmcode, oldenv) = !cocciinforef in
 
     let mck =
+      (* coccionly: 
       if !Flag_parsing_cocci.sgrep_mode
       then Sgrep.process_sgrep ib mck
-      else mck 
+      else 
+      *)
+        mck 
     in
     (match mck, Ast_c.pinfo_of_info ib with
     | _,                  Ast_c.AbstractLineTok _ -> raise Impossible
@@ -213,10 +208,13 @@ module XTRANS = struct
           ib
         end
         else 
+          (* coccionly: 
           if !Flag.sgrep_mode2
           then ib (* safe *)
           else 
-            begin
+          *)
+             begin
+            (* coccionly:
              Format.set_formatter_out_channel stderr;
               Common.pr2 "SP mcode ";
               Pretty_print_cocci.print_mcodekind oldmcode;
@@ -225,6 +223,7 @@ module XTRANS = struct
               Pretty_print_cocci.print_mcodekind mck;
               Format.print_newline();
               Format.print_flush();
+            *)
               failwith
                (Common.sprintf "%s: already tagged token:\n%s"
                   tin.extra.current_rule_name
@@ -460,7 +459,7 @@ module XTRANS = struct
          *)
 
         (*f () tin*)
-        if Cocci_vs_c_3.equal_metavarval value value' 
+        if Cocci_vs_c.equal_metavarval value value' 
         then f () tin
         else fail tin
 
@@ -478,7 +477,7 @@ end
 (*****************************************************************************)
 (* Entry point  *) 
 (*****************************************************************************)
-module TRANS  = Cocci_vs_c_3.COCCI_VS_C (XTRANS)
+module TRANS  = Cocci_vs_c.COCCI_VS_C (XTRANS)
 
 
 let transform_re_node a b tin = 
index a321b42..8c6112e 100644 (file)
@@ -1,14 +1,6 @@
-c_info.cmi: ../commons/ograph_extended.cmi ../commons/common.cmi \
-    ../parsing_c/ast_c.cmo 
 classic_patch.cmi: ../commons/common.cmi 
 kbuild.cmi: ../commons/common.cmi 
 maintainers.cmi: ../commons/common.cmi 
-c_info.cmo: ../parsing_c/visitor_c.cmi ../commons/ograph_extended.cmi \
-    ../globals/flag.cmo ../commons/common.cmi ../parsing_c/ast_c.cmo \
-    c_info.cmi 
-c_info.cmx: ../parsing_c/visitor_c.cmx ../commons/ograph_extended.cmx \
-    ../globals/flag.cmx ../commons/common.cmx ../parsing_c/ast_c.cmx \
-    c_info.cmi 
 classic_patch.cmo: ../commons/common.cmi classic_patch.cmi 
 classic_patch.cmx: ../commons/common.cmx classic_patch.cmi 
 kbuild.cmo: ../commons/common.cmi kbuild.cmi 
index af2b9b5..fae3229 100644 (file)
@@ -46,6 +46,8 @@ let windows = ref false
 
 let popl = ref false
 
+let ifdef_to_if = ref false
+
 let all_includes = ref false
 let include_path = ref "include"
 (* if true then when have a #include "../../xx.h", we look also for xx.h in
diff --git a/globals/.#config.ml.1.2 b/globals/.#config.ml.1.2
new file mode 100644 (file)
index 0000000..c5516d9
--- /dev/null
@@ -0,0 +1,8 @@
+let version = "0.1.1"
+
+let path = 
+  try (Sys.getenv "COCCINELLE_HOME") 
+  with Not_found->"/usr/local/share/coccinelle"
+
+let std_iso = ref (Filename.concat path "standard.iso")
+let std_h   = ref (Filename.concat path "standard.h")
index c5516d9..f2d0bbd 100644 (file)
@@ -1,4 +1,4 @@
-let version = "0.1.1"
+let version = "0.1.2"
 
 let path = 
   try (Sys.getenv "COCCINELLE_HOME") 
index 222e4bb..ebee85e 100644 (file)
@@ -14,3 +14,8 @@ let pyoutput = ref "coccilib.output.Console"
 let patch = ref (None : string option)
 
 let make_hrule = ref (None : string (*dir*) option)
+
+let currentfile = ref (None : string option)
+
+let current_element = ref ""
+
index b9ee270..6568c4f 100644 (file)
@@ -7,7 +7,8 @@ You must first install a recent version of
    the SmPL parser pre-generated)
  - Python and its development files (python-dev)
    (unless you run configure with the --without-python option)
-   
+ - pdftk and graphviz (with PDF support) if you want to use
+   the -graphical_trace option   
 
 Then simply type 
  ./configure
diff --git a/main.ml b/main.ml
index 75ca33d..1b00f0d 100644 (file)
--- a/main.ml
+++ b/main.ml
@@ -89,7 +89,7 @@ let quiet_profile = (
     Flag_parsing_cocci.show_iso_failures;
     Flag_ctl.verbose_ctl_engine;
     Flag_ctl.verbose_match;
-    Flag_engine.debug_engine;
+    Flag_matcher.debug_engine;
     Flag_parsing_c.debug_unparsing;
     Flag_parsing_c.verbose_type;
     Flag_parsing_c.verbose_parsing;
@@ -116,7 +116,7 @@ let pad_profile = (
     Flag_parsing_cocci.show_iso_failures;
     Flag_ctl.verbose_ctl_engine;
     Flag_ctl.verbose_match;
-    Flag_engine.debug_engine;
+    Flag_matcher.debug_engine;
     Flag_parsing_c.debug_unparsing;
     Flag_parsing_c.verbose_type;
     Flag_parsing_c.verbose_parsing;
@@ -197,7 +197,7 @@ let short_options = [
     "  guess what";
 
   "-date",   Arg.Unit (fun () -> 
-    pr2 "version: $Date: 2008/10/11 16:22:38 $";
+    pr2 "version: $Date: 2008/11/18 20:37:55 $";
     raise (Common.UnixExit 0)
     ), 
   "   guess what";
@@ -264,8 +264,10 @@ let other_options = [
   "",
   [
     "-verbose_ctl_engine",   Arg.Set Flag_ctl.verbose_ctl_engine, " ";
-    "-verbose_match",   Arg.Set Flag_ctl.verbose_match, " ";
-    "-verbose_engine",       Arg.Set Flag_engine.debug_engine,    " ";
+    "-verbose_match",        Arg.Set Flag_ctl.verbose_match, " ";
+    "-verbose_engine",       Arg.Set Flag_matcher.debug_engine,    " ";
+    "-graphical_trace",      Arg.Set Flag_ctl.graphical_trace, "  generate a pdf file representing the matching process";
+    "-gt_without_label",     Arg.Set Flag_ctl.gt_without_label, "  remove graph label (requires option -graphical_trace)";
 
     "-no_parse_error_msg", Arg.Clear Flag_parsing_c.verbose_parsing, " ";
     "-no_type_error_msg",  Arg.Clear Flag_parsing_c.verbose_type, " ";
@@ -294,7 +296,7 @@ let other_options = [
     "-filter_msg",      Arg.Set  Flag_parsing_c.filter_msg , 
     "  filter some cpp message when the macro is a \"known\" cpp construct";
     "-filter_define_error",Arg.Set Flag_parsing_c.filter_define_error,"  ";
-    "-filter_classic_passed",Arg.Set Flag_parsing_c.filter_classic_passed,"  ";
+    "-filter_passed_level", Arg.Set_int Flag_parsing_c.filter_passed_level,"  ";
 
     "-debug_cfg",          Arg.Set Flag_parsing_c.debug_cfg , "  ";
     "-debug_unparsing",      Arg.Set  Flag_parsing_c.debug_unparsing, "  ";
@@ -365,26 +367,27 @@ let other_options = [
     "-loop",              Arg.Set Flag_ctl.loop_in_src_code,    " ";
 
     "-l1",                Arg.Clear Flag_parsing_c.label_strategy_2, " ";
-    "-ifdef",              Arg.Set Flag_parsing_c.ifdef_to_if, 
-    "   convert ifdef to if (buggy!)";
+    "-ifdef_to_if",              Arg.Set Flag_cocci.ifdef_to_if, 
+    "   convert ifdef to if (experimental)";
+
     "-noif0_passing",   Arg.Clear Flag_parsing_c.if0_passing, 
     " ";
     "-noadd_typedef_root",   Arg.Clear Flag_parsing_c.add_typedef_root, " ";
     (* could use Flag_parsing_c.options_algo instead *)
 
 
-    "-disallow_nested_exps", Arg.Set Flag_engine.disallow_nested_exps,
+    "-disallow_nested_exps", Arg.Set Flag_matcher.disallow_nested_exps,
        "disallow an expresion pattern from matching a term and its subterm";
     "-disable_worth_trying_opt", Arg.Clear Flag_cocci.worth_trying_opt,
     "  ";
     "-only_return_is_error_exit",
-    Arg.Set Flag_engine.only_return_is_error_exit,
+    Arg.Set Flag_matcher.only_return_is_error_exit,
     "if this flag is not set, then break and continue are also error exits";
     (* the following is a hack to make it easier to add code in sgrep-like
        code, essentially to compensate for the fact that we don't have
        any way of printing things out *)
     "-allow_inconsistent_paths",
-    Arg.Set Flag_engine.allow_inconsistent_paths,
+    Arg.Set Flag_matcher.allow_inconsistent_paths,
     "if this flag is set don't check for inconsistent paths; dangerous";    
   ];
 
@@ -504,11 +507,14 @@ let adjust_stdin cfile k =
   then k()
   else
     let newin = 
-      let (dir, base, ext) = Common.dbe_of_filename cfile in
-      let varfile = Common.filename_of_dbe (dir, base, "var") in
-      if ext = "c" && Common.lfile_exists varfile
-      then Some varfile
-      else None in
+      try
+        let (dir, base, ext) = Common.dbe_of_filename cfile in
+        let varfile = Common.filename_of_dbe (dir, base, "var") in
+        if ext = "c" && Common.lfile_exists varfile
+        then Some varfile
+        else None 
+      with Invalid_argument("Filename.chop_extension") -> None
+    in
     Common.redirect_stdin_opt newin k
 
 let glimpse_filter (coccifile, isofile) dir = 
index 70d620d..33810a6 100644 (file)
@@ -1,15 +1,20 @@
 ast_to_flow.cmi: control_flow_c.cmi ../commons/common.cmi ast_c.cmo 
 compare_c.cmi: ../commons/common.cmi 
 control_flow_c.cmi: ../commons/ograph_extended.cmi ast_c.cmo 
+cpp_ast_c.cmi: ../commons/common.cmi ast_c.cmo 
 lexer_parser.cmi: ../commons/common.cmi 
-parse_c.cmi: parsing_hacks.cmi parser_c.cmi ../commons/common.cmi ast_c.cmo 
+parse_c.cmi: parsing_stat.cmo parsing_hacks.cmi parser_c.cmi \
+    ../commons/common.cmi ast_c.cmo 
 parser_c.cmi: ast_c.cmo 
 parsing_hacks.cmi: parser_c.cmi ../commons/common.cmi 
-pretty_print_c.cmi: ast_c.cmo 
+pretty_print_c.cmi: control_flow_c.cmi ast_c.cmo 
 test_parsing_c.cmi: ../commons/common.cmi 
 token_helpers.cmi: parser_c.cmi ../commons/common.cmi ast_c.cmo 
 type_annoter_c.cmi: ../commons/common.cmi ast_c.cmo 
+unparse_c.cmi: parse_c.cmi ../commons/common.cmi 
 unparse_c2.cmi: parse_c.cmi ../commons/common.cmi 
+unparse_cocci.cmi: pretty_print_c.cmi ../parsing_cocci/ast_cocci.cmi \
+    ast_c.cmo 
 unparse_cocci2.cmi: pretty_print_c.cmi ../parsing_cocci/ast_cocci.cmi \
     ast_c.cmo 
 unparse_hrule.cmi: parse_c.cmi ../commons/common.cmi 
@@ -32,6 +37,10 @@ control_flow_c.cmo: ../commons/ograph_extended.cmi flag_parsing_c.cmo \
     ../commons/common.cmi ast_c.cmo control_flow_c.cmi 
 control_flow_c.cmx: ../commons/ograph_extended.cmx flag_parsing_c.cmx \
     ../commons/common.cmx ast_c.cmx control_flow_c.cmi 
+cpp_ast_c.cmo: visitor_c.cmi parse_c.cmi flag_parsing_c.cmo \
+    ../commons/common.cmi ast_c.cmo cpp_ast_c.cmi 
+cpp_ast_c.cmx: visitor_c.cmx parse_c.cmx flag_parsing_c.cmx \
+    ../commons/common.cmx ast_c.cmx cpp_ast_c.cmi 
 flag_parsing_c.cmo: ../commons/common.cmi 
 flag_parsing_c.cmx: ../commons/common.cmx 
 lexer_c.cmo: parser_c.cmi flag_parsing_c.cmo ../commons/common.cmi ast_c.cmo 
@@ -42,32 +51,38 @@ lib_parsing_c.cmo: visitor_c.cmi ../commons/common.cmi \
     ../parsing_cocci/ast_cocci.cmi ast_c.cmo 
 lib_parsing_c.cmx: visitor_c.cmx ../commons/common.cmx \
     ../parsing_cocci/ast_cocci.cmx ast_c.cmx 
-parse_c.cmo: visitor_c.cmi token_helpers.cmi semantic_c.cmo parsing_hacks.cmi \
-    parser_c.cmi lexer_parser.cmi lexer_c.cmo flag_parsing_c.cmo \
-    ../globals/config.cmo ../commons/common.cmi ast_c.cmo parse_c.cmi 
-parse_c.cmx: visitor_c.cmx token_helpers.cmx semantic_c.cmx parsing_hacks.cmx \
-    parser_c.cmx lexer_parser.cmx lexer_c.cmx flag_parsing_c.cmx \
-    ../globals/config.cmx ../commons/common.cmx ast_c.cmx parse_c.cmi 
-parser_c.cmo: semantic_c.cmo lexer_parser.cmi flag_parsing_c.cmo \
-    ../commons/common.cmi ast_c.cmo parser_c.cmi 
-parser_c.cmx: semantic_c.cmx lexer_parser.cmx flag_parsing_c.cmx \
-    ../commons/common.cmx ast_c.cmx parser_c.cmi 
-parsing_hacks.cmo: token_helpers.cmi parser_c.cmi lexer_parser.cmi \
-    flag_parsing_c.cmo ../commons/common.cmi ast_c.cmo parsing_hacks.cmi 
-parsing_hacks.cmx: token_helpers.cmx parser_c.cmx lexer_parser.cmx \
-    flag_parsing_c.cmx ../commons/common.cmx ast_c.cmx parsing_hacks.cmi 
-pretty_print_c.cmo: flag_parsing_c.cmo ../commons/common.cmi ast_c.cmo \
-    pretty_print_c.cmi 
-pretty_print_c.cmx: flag_parsing_c.cmx ../commons/common.cmx ast_c.cmx \
-    pretty_print_c.cmi 
+parse_c.cmo: visitor_c.cmi token_helpers.cmi semantic_c.cmo parsing_stat.cmo \
+    parsing_hacks.cmi parser_c.cmi lexer_parser.cmi lexer_c.cmo \
+    flag_parsing_c.cmo ../commons/common.cmi ast_c.cmo parse_c.cmi 
+parse_c.cmx: visitor_c.cmx token_helpers.cmx semantic_c.cmx parsing_stat.cmx \
+    parsing_hacks.cmx parser_c.cmx lexer_parser.cmx lexer_c.cmx \
+    flag_parsing_c.cmx ../commons/common.cmx ast_c.cmx parse_c.cmi 
+parser_c.cmo: semantic_c.cmo parsing_stat.cmo lexer_parser.cmi \
+    flag_parsing_c.cmo ../commons/common.cmi ast_c.cmo parser_c.cmi 
+parser_c.cmx: semantic_c.cmx parsing_stat.cmx lexer_parser.cmx \
+    flag_parsing_c.cmx ../commons/common.cmx ast_c.cmx parser_c.cmi 
+parsing_hacks.cmo: token_helpers.cmi parsing_stat.cmo parser_c.cmi \
+    lexer_parser.cmi flag_parsing_c.cmo ../commons/common.cmi ast_c.cmo \
+    parsing_hacks.cmi 
+parsing_hacks.cmx: token_helpers.cmx parsing_stat.cmx parser_c.cmx \
+    lexer_parser.cmx flag_parsing_c.cmx ../commons/common.cmx ast_c.cmx \
+    parsing_hacks.cmi 
+parsing_stat.cmo: ../commons/common.cmi 
+parsing_stat.cmx: ../commons/common.cmx 
+pretty_print_c.cmo: flag_parsing_c.cmo control_flow_c.cmi \
+    ../commons/common.cmi ast_c.cmo pretty_print_c.cmi 
+pretty_print_c.cmx: flag_parsing_c.cmx control_flow_c.cmx \
+    ../commons/common.cmx ast_c.cmx pretty_print_c.cmi 
 semantic_c.cmo: ../commons/common.cmi 
 semantic_c.cmx: ../commons/common.cmx 
-test_parsing_c.cmo: unparse_c2.cmi type_annoter_c.cmi parse_c.cmi \
-    ../commons/ograph_extended.cmi flag_parsing_c.cmo compare_c.cmi \
-    ../commons/common.cmi ast_to_flow.cmi ast_c.cmo test_parsing_c.cmi 
-test_parsing_c.cmx: unparse_c2.cmx type_annoter_c.cmx parse_c.cmx \
-    ../commons/ograph_extended.cmx flag_parsing_c.cmx compare_c.cmx \
-    ../commons/common.cmx ast_to_flow.cmx ast_c.cmx test_parsing_c.cmi 
+test_parsing_c.cmo: unparse_c.cmi type_annoter_c.cmi parsing_stat.cmo \
+    parse_c.cmi ../commons/ograph_extended.cmi flag_parsing_c.cmo \
+    compare_c.cmi ../commons/common.cmi ast_to_flow.cmi ast_c.cmo \
+    test_parsing_c.cmi 
+test_parsing_c.cmx: unparse_c.cmx type_annoter_c.cmx parsing_stat.cmx \
+    parse_c.cmx ../commons/ograph_extended.cmx flag_parsing_c.cmx \
+    compare_c.cmx ../commons/common.cmx ast_to_flow.cmx ast_c.cmx \
+    test_parsing_c.cmi 
 token_helpers.cmo: parser_c.cmi ../commons/common.cmi ast_c.cmo \
     token_helpers.cmi 
 token_helpers.cmx: parser_c.cmx ../commons/common.cmx ast_c.cmx \
@@ -76,20 +91,30 @@ type_annoter_c.cmo: visitor_c.cmi parse_c.cmi lib_parsing_c.cmo \
     flag_parsing_c.cmo ../commons/common.cmi ast_c.cmo type_annoter_c.cmi 
 type_annoter_c.cmx: visitor_c.cmx parse_c.cmx lib_parsing_c.cmx \
     flag_parsing_c.cmx ../commons/common.cmx ast_c.cmx type_annoter_c.cmi 
+unparse_c.cmo: visitor_c.cmi unparse_cocci.cmi token_helpers.cmi \
+    pretty_print_c.cmi parser_c.cmi flag_parsing_c.cmo ../commons/common.cmi \
+    ../parsing_cocci/ast_cocci.cmi ast_c.cmo unparse_c.cmi 
+unparse_c.cmx: visitor_c.cmx unparse_cocci.cmx token_helpers.cmx \
+    pretty_print_c.cmx parser_c.cmx flag_parsing_c.cmx ../commons/common.cmx \
+    ../parsing_cocci/ast_cocci.cmx ast_c.cmx unparse_c.cmi 
 unparse_c2.cmo: visitor_c.cmi unparse_cocci2.cmi token_helpers.cmi \
     pretty_print_c.cmi parser_c.cmi flag_parsing_c.cmo ../commons/common.cmi \
     ../parsing_cocci/ast_cocci.cmi ast_c.cmo unparse_c2.cmi 
 unparse_c2.cmx: visitor_c.cmx unparse_cocci2.cmx token_helpers.cmx \
     pretty_print_c.cmx parser_c.cmx flag_parsing_c.cmx ../commons/common.cmx \
     ../parsing_cocci/ast_cocci.cmx ast_c.cmx unparse_c2.cmi 
+unparse_cocci.cmo: pretty_print_c.cmi ../commons/common.cmi \
+    ../parsing_cocci/ast_cocci.cmi ast_c.cmo unparse_cocci.cmi 
+unparse_cocci.cmx: pretty_print_c.cmx ../commons/common.cmx \
+    ../parsing_cocci/ast_cocci.cmx ast_c.cmx unparse_cocci.cmi 
 unparse_cocci2.cmo: pretty_print_c.cmi ../commons/common.cmi \
     ../parsing_cocci/ast_cocci.cmi ast_c.cmo unparse_cocci2.cmi 
 unparse_cocci2.cmx: pretty_print_c.cmx ../commons/common.cmx \
     ../parsing_cocci/ast_cocci.cmx ast_c.cmx unparse_cocci2.cmi 
-unparse_hrule.cmo: unparse_c2.cmi token_helpers.cmi pretty_print_c.cmi \
+unparse_hrule.cmo: unparse_c.cmi token_helpers.cmi pretty_print_c.cmi \
     parser_c.cmi ../commons/common.cmi ../parsing_cocci/ast_cocci.cmi \
     ast_c.cmo unparse_hrule.cmi 
-unparse_hrule.cmx: unparse_c2.cmx token_helpers.cmx pretty_print_c.cmx \
+unparse_hrule.cmx: unparse_c.cmx token_helpers.cmx pretty_print_c.cmx \
     parser_c.cmx ../commons/common.cmx ../parsing_cocci/ast_cocci.cmx \
     ast_c.cmx unparse_hrule.cmi 
 visitor_c.cmo: control_flow_c.cmi ../commons/common.cmi ast_c.cmo \
index c0d1df0..ea1b150 100644 (file)
@@ -3,28 +3,37 @@
 ##############################################################################
 TARGET=parsing_c
 
-SRC= \
- flag_parsing_c.ml ast_c.ml control_flow_c.ml semantic_c.ml \
+
+# - type_cocci.ml ast_cocci.ml  # + unparse_hrule 
+SRC= flag_parsing_c.ml parsing_stat.ml \
+ ast_c.ml control_flow_c.ml \
  visitor_c.ml lib_parsing_c.ml \
  ast_to_flow.ml \
- lexer_parser.ml parser_c.ml lexer_c.ml \
- token_helpers.ml parsing_hacks.ml parse_c.ml \
- compare_c.ml type_annoter_c.ml  pretty_print_c.ml \
- unparse_cocci2.ml unparse_c2.ml unparse_hrule.ml \
+ pretty_print_c.ml \
+ semantic_c.ml lexer_parser.ml parser_c.ml lexer_c.ml \
+ token_helpers.ml parsing_hacks.ml \
+ unparse_cocci.ml unparse_c.ml unparse_hrule.ml  \
+ parse_c.ml \
+ cpp_ast_c.ml \
+ compare_c.ml type_annoter_c.ml \
  test_parsing_c.ml
 
 
-SYSLIBS= str.cma unix.cma 
 
-# parsing_c now depends on cocci_parser because in addition to decorate the
-# token in Ast_c with some parse info, we now also make some place to
+# ast_cocci.ml and unparse_cocci.ml should be deleted in the futur
+# to make parsing_c really independent of coccinelle. 
+# control_flow_c have also coccinelle dependencies.
+# old: parsing_c now depends on cocci_parser because in addition to decorate 
+# the token in Ast_c with some parse info, we now also make some place to
 # welcome some mcodekind of Ast_cocci.
 LIBS=../commons/commons.cma ../globals/globals.cma \
      ../parsing_cocci/cocci_parser.cma
 
-INCLUDES= -I ../commons -I ../commons/ocamlextra \
-       -I ../globals -I  ../parsing_cocci 
+INCLUDES= -I ../commons -I ../globals -I  ../parsing_cocci 
 
+#LIBS=../commons/commons.cma
+#INCLUDES= -I ../commons
+SYSLIBS= str.cma unix.cma 
 
 ##############################################################################
 # Generic variables
@@ -80,6 +89,33 @@ clean::
 beforedepend:: parser_c.ml parser_c.mli
 
 
+##############################################################################
+# Pad's rules
+##############################################################################
+# visitor_c.ml lib_parsing_c.ml \
+# type_annoter_c.ml  \
+# statistics_c.ml  \
+# pretty_print_c.ml unparse_c.ml \
+# test_parsing_c.ml
+#toreput: compare_c.ml ast_to_flow.ml
+
+COREPARSING= flag_parsing_c.ml parsing_stat.ml \
+ ast_cocci.ml \
+ ast_c.ml control_flow_c.ml \
+ semantic_c.ml lexer_parser.ml parser_c.mly lexer_c.mll \
+ token_helpers.ml parsing_hacks.ml parse_c.ml \
+
+locparsing:
+       wc -l $(COREPARSING)
+
+locindiv:
+       wc -l lexer_c.mll
+       wc -l parser_c.mly
+       wc -l parsing_hacks.ml
+       wc -l ast_c.ml
+       wc -l parse_c.ml
+
+
 ##############################################################################
 # Generic rules
 ##############################################################################
index 877cb51..5d74a7d 100644 (file)
@@ -1,4 +1,4 @@
-(* Copyright (C) 2002-2008 Yoann Padioleau
+(* Copyright (C) 2002, 2006, 2007, 2008 Yoann Padioleau
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License (GPL)
@@ -15,7 +15,44 @@ open Common
 (* The AST C related types *)
 (*****************************************************************************)
 
-(* Cocci: Each token will be decorated in the future by the mcodekind
+(* To allow some transformations over the AST, we keep as much information 
+ * as possible in the AST such as the tokens content and their locations. 
+ * Those info are called 'info' (how original) and can be tagged.
+ * For instance one tag may say that the unparser should remove this token.
+ * 
+ * Update: Now I use a ref! in those 'info' so take care.
+ * 
+ * Sometimes we want to add someting at the beginning or at the end 
+ * of a construct. For 'function' and 'decl' we want to add something
+ * to their left and for 'if' 'while' et 'for' and so on at their right.
+ * We want some kinds of "virtual placeholders" that represent the start or
+ * end of a construct. We use fakeInfo for that purpose.
+ * To identify those cases I have added a fakestart/fakeend comment.
+ * 
+ * convention: I often use 'ii' for the name of a list of info. 
+ * 
+ * update: I now allow ifdefs in the ast but there must be only between
+ * "sequencable" elements. They can be put in a type only if this type
+ * is used only in a list, like at toplevel, used in 'toplevel list', 
+ * or inside compound, used in 'statement list'. I must not allow 
+ * ifdef anywhere. For instance I can not make ifdef a statement 
+ * cos some instruction like If accept only one statement and the
+ * ifdef directive must not take the place of a legitimate instruction.
+ * We had a similar phenomena in SmPL where we have the notion
+ * of statement and sequencable statement too. Once you have 
+ * such a type of sequencable thing, then s/xx list/xx_sequencable list/
+ * and introduce the ifdef.
+ * 
+ * update: those ifdefs are either passed, or present in the AST but in
+ * a flat form. To structure those flat ifdefs you have to run
+ * a transformation that will put in a tree the statements inside
+ * ifdefs branches. Cf cpp_ast_c.ml. This is for instance the difference
+ * between a IfdefStmt (flat) and IfdefStmt2 (tree structured).
+ * 
+ * Some stuff are tagged semantic: which means that they are computed
+ * after parsing. 
+ * 
+ * cocci: Each token will be decorated in the future by the mcodekind
  * of cocci. It is the job of the pretty printer to look at this
  * information and decide to print or not the token (and also the
  * pending '+' associated sometimes with the token).
@@ -28,23 +65,19 @@ open Common
  * because the pending '+' may contain metavariables that refer to some
  * C code.
  * 
- * Update: Now I use a ref! so take care.
- * 
- * Sometimes we want to add someting at the beginning or at the end 
- * of a construct. For 'function' and 'decl' we want add something
- * to their left and for 'if' 'while' et 'for' and so on at their right.
- * We want some kinds of "virtual placeholders" that represent the start or
- * end of a construct. We use fakeInfo for that purpose.
- * To identify those cases I have added a fakestart/fakeend comment.
- * 
- * convention: I often use 'ii' for the name of a list of info. 
  * 
+ * All of this means that some elements in this AST are present only if 
+ * some annotation/transformation has been done on the original AST returned
+ * by the parser. Cf type_annotater, comment_annotater, cpp_ast_c, etc.
  *)
 
 (* forunparser: *)
 
 type posl = int * int (* lin-col, for MetaPosValList, for position variables *)
+
+(* the virtual position is set in Parsing_hacks.insert_virtual_positions *)
 type virtual_position = Common.parse_info * int (* character offset *)
+
 type parse_info = 
   (* Present both in ast and list of tokens *)
   | OriginTok of Common.parse_info
@@ -61,8 +94,12 @@ type parse_info =
 
 type info = { 
   pinfo : parse_info;
+  (* this tag can be changed, which is how we can express some progra
+   * transformations by tagging the tokens involved in this transformation. 
+   *)
   cocci_tag: (Ast_cocci.mcodekind * metavars_binding) ref;
-  comments_tag: comments_around ref; (* set in comment_annotater.ml *)
+  (* set in comment_annotater.ml *)
+  comments_tag: comments_around ref;
   (* todo? token_info : sometimes useful to know what token it was *)
   }
 and il = info list
@@ -95,7 +132,8 @@ and 'a wrap2 = 'a * il
  * Constructor.
  * 
  * Some stuff are tagged semantic: which means that they are computed
- * after parsing. *)
+ * after parsing. 
+*)
 
 
 and fullType = typeQualifier * typeC
@@ -118,15 +156,21 @@ and typeCbis =
  
   | ParenType of fullType (* forunparser: *)
 
-  (* gccext: TypeOfType may seems useless, why declare a __typeof__(int)
-   * x; ? But when used with macro, it allows to fix a problem of C which
+  (* gccext: TypeOfType may seems useless; why declare a 
+   *     __typeof__(int) x; ? 
+   * But when used with macro, it allows to fix a problem of C which
    * is that type declaration can be spread around the ident. Indeed it
-   * may be difficult to have a macro such as '#define macro(type,
-   * ident) type ident;' because when you want to do a macro(char[256],
-   * x), then it will generate invalid code, but with a '#define
-   * macro(type, ident) __typeof(type) ident;' it will work. *)
+   * may be difficult to have a macro such as 
+   *    '#define macro(type, ident) type ident;' 
+   * because when you want to do a 
+   *     macro(char[256], x), 
+   * then it will generate invalid code, but with a 
+   *       '#define macro(type, ident) __typeof(type) ident;' 
+   * it will work. *)
   | TypeOfExpr of expression  
   | TypeOfType of fullType    
+
+  (* cppext: IfdefType TODO *)
       
 (* -------------------------------------- *)    
      and  baseType = Void 
@@ -149,11 +193,22 @@ and typeCbis =
 
      (* -------------------------------------- *)    
      and structUnion = Struct | Union
-     and structType  = (field wrap) list  (* ; *)
+     and structType  = field list 
+        and field = fieldbis wrap 
+         and fieldbis = 
+           | DeclarationField of field_declaration
+           | EmptyField (* gccext: *)
+            (* cppext: *)
+           | MacroStructDeclTodo
+
+            (* cppext: *)
+           | CppDirectiveStruct of cpp_directive
+           | IfdefStruct of ifdef_directive (* * field list list *)
+
 
         (* before unparser, I didn't have a FieldDeclList but just a Field. *)
-         and field  = FieldDeclList of fieldkind wrap2 list (* , *)
-                    | EmptyField (* gccext: *) 
+         and field_declaration  = 
+           | FieldDeclList of fieldkind wrap2 list (* , *) wrap  (* ; *)
 
           (* At first I thought that a bitfield could be only Signed/Unsigned.
            * But it seems that gcc allow char i:4. C rule must say that you
@@ -182,16 +237,21 @@ and typeCbis =
 and typeQualifier = typeQualifierbis wrap 
 and typeQualifierbis = {const: bool; volatile: bool}
 
+(* gccext: cppext: *)
+and attribute = attributebis wrap
+  and attributebis =
+    | Attribute of string 
 
 (* ------------------------------------------------------------------------- *)
 (* C expression *)
 (* ------------------------------------------------------------------------- *)
 and expression = (expressionbis * exp_info ref (* semantic: *)) wrap
-and local = LocalVar of parse_info | NotLocalVar
-and test = Test | NotTest
-and exp_type = fullType * local
-and exp_info = exp_type option * test
-and expressionbis = 
+ and exp_info = exp_type option * test
+  and exp_type = fullType * local
+    and local = LocalVar of parse_info | NotLocalVar (* cocci: *)
+  and test = Test | NotTest (* cocci: *)
+
+ and expressionbis = 
 
   (* Ident can be a enumeration constant, a simple variable, a name of a func.
    * With cppext, Ident can also be the name of a macro. Sparse says
@@ -228,12 +288,15 @@ and expressionbis =
   (* forunparser: *)
   | ParenExpr of expression 
 
+  (* cppext: IfdefExpr TODO *)
+
   (* cppext: normmally just expression *)
   and argument = (expression, wierd_argument) either
    and wierd_argument = 
        | ArgType of parameterType
        | ArgAction of action_macro
       and action_macro = 
+        (* todo: ArgStatement of statement, possibly have ghost token *)
          | ActMisc of il 
 
 
@@ -247,15 +310,16 @@ and expressionbis =
 
   and constant = 
     | String of (string * isWchar) 
-    | MultiString  (* can contain MacroString *)
+    | MultiString  (* can contain MacroString, todo: more info *)
     | Char   of (string * isWchar) (* normally it is equivalent to Int *)
     | Int    of (string  (* * intType*)) 
     | Float  of (string * floatType)
 
     and isWchar = IsWchar | IsChar
 
-  (* gccext: GetRefLabel, via &&label notation *)
-  and unaryOp  = GetRef | DeRef | UnPlus |  UnMinus | Tilde | Not | GetRefLabel
+  
+  and unaryOp  = GetRef | DeRef | UnPlus |  UnMinus | Tilde | Not 
+                 | GetRefLabel (* gccext: GetRefLabel, via &&label notation *)
   and assignOp = SimpleAssign | OpAssign of arithOp
   and fixOp    = Dec | Inc
 
@@ -274,6 +338,7 @@ and expressionbis =
  and constExpression = expression (* => int *)
 
 
+
 (* ------------------------------------------------------------------------- *)
 (* C statement *)
 (* ------------------------------------------------------------------------- *)
@@ -313,8 +378,20 @@ and statementbis =
    * old: compound = (declaration list * statement list) 
    * old: (declaration, statement) either list 
    * Simplify cocci to just have statement list, by integrating Decl in stmt.
+   * 
+   * update: now introduce also the _sequencable to allow ifdef in the middle.
    *)
-  and compound = statement list 
+  and compound = statement_sequencable list 
+
+  (* cppext: easier to put at statement_list level than statement level *)
+  and statement_sequencable = 
+    | StmtElem of statement
+    (* cppext: *) 
+    | CppDirectiveStmt of cpp_directive
+    | IfdefStmt of ifdef_directive 
+
+    (* this will be build in cpp_ast_c from the previous flat IfdefStmt *)
+    | IfdefStmt2 of ifdef_directive list * (statement_sequencable list) list
 
   and exprStatement = expression option
 
@@ -324,13 +401,14 @@ and statementbis =
   and selection     = 
    | If     of expression * statement * statement
    | Switch of expression * statement 
-   | Ifdef of statement list * statement list    (* cppext: *)
+
 
   and iteration     = 
     | While   of expression * statement
     | DoWhile of statement * expression
     | For     of exprStatement wrap * exprStatement wrap * exprStatement wrap *
                  statement
+    (* cppext: *)
     | MacroIteration of string * argument wrap2 list * statement
 
   and jump  = Goto of string
@@ -354,7 +432,7 @@ and statementbis =
  *   
  * Before I had Typedef constructor, but why make this special case and not 
  * have StructDef, EnumDef, ... so that 'struct t {...} v' will generate 2 
- * declarations ? So I try to generalise and not have not Typedef too. This
+ * declarations ? So I try to generalise and not have Typedef either. This
  * requires more work in parsing. Better to separate concern.
  * 
  * Before the need for unparser, I didn't have a DeclList but just a Decl.
@@ -371,9 +449,13 @@ and declaration =
   | MacroDecl of (string * argument wrap2 list) wrap
 
      and onedecl = 
-       ((string * initialiser option) wrap (* s = *) option) * 
-         fullType * storage * local_decl
-     and storage       = storagebis * bool (* inline or not, gccext: *)
+       { v_namei: (string * initialiser option) wrap (* s = *) option;
+         v_type: fullType;
+         v_storage: storage;
+         v_local: local_decl; (* cocci: *)
+         v_attr: attribute list; (* gccext: *)
+       }
+     and storage       = storagebis * bool (* gccext: inline or not *)
      and storagebis    = NoSto | StoTypedef | Sto of storageClass
      and storageClass  = Auto  | Static | Register | Extern
 
@@ -403,52 +485,96 @@ and declaration =
  * as 'f(void) {', there is no name too, so I simplified and reused the 
  * same functionType type for both declaration and function definition.
  *)
-and definition = (string * functionType * storage * compound) 
-                 wrap (* s ( ) { } fakestart sto *)
+and definition = definitionbis wrap (* s ( ) { } fakestart sto *)
+  and definitionbis = 
+  { f_name: string;
+    f_type: functionType;
+    f_storage: storage;
+    f_body: compound;
+    f_attr: attribute list; (* gccext: *)
+  }
+  (* cppext: IfdefFunHeader TODO *)
 
 (* ------------------------------------------------------------------------- *)
-(* #define and #include body *)
+(* cppext: cpp directives, #ifdef, #define and #include body *)
 (* ------------------------------------------------------------------------- *)
+and cpp_directive =
+  | Include of includ 
+  | Define of define 
+  | Undef of string wrap
+  | PragmaAndCo of il 
+
+(* to specialize if someone need more info *)
+and ifdef_directive = (* or and 'a ifdefed = 'a list wrap *)
+  | IfdefDirective of (ifdefkind * matching_tag) wrap
+  and ifdefkind = 
+    | Ifdef (* todo? of string ? of formula_cpp *)
+    | IfdefElseif (* same *)
+    | IfdefElse (* same *)
+    | IfdefEndif 
+  (* set in Parsing_hacks.set_ifdef_parenthize_info. It internally use 
+   * a global so it means if you parse same file twice you may get
+   * different id. I try now to avoid this pb by resetting it each 
+   * time I parse a file.
+   *)
+  and matching_tag = 
+    IfdefTag of (int (* tag *) * int (* total with this tag *))
 
-(* cppext *) 
 and define = string wrap * define_body   (* #define s *)
  and define_body = define_kind * define_val
    and define_kind =
    | DefineVar
-   | DefineFunc   of ((string wrap) wrap2 list) wrap
+   | DefineFunc   of ((string wrap) wrap2 list) wrap (* () *)
    and define_val = 
      | DefineExpr of expression
      | DefineStmt of statement
      | DefineType of fullType
-     | DefineDoWhileZero of statement wrap (* do { } while(0) *)
+     | DefineDoWhileZero of (statement * expression) wrap (* do { } while(0) *)
      | DefineFunction of definition
+     | DefineInit of initialiser (* in practice only { } with possible ',' *)
+     (* TODO DefineMulti of define_val list *)
+
      | DefineText of string wrap
      | DefineEmpty
 
+     | DefineTodo
 
 
-and includ = inc_file wrap (* #include s *) * 
-  (include_rel_pos option ref * bool (* is in ifdef, cf -test incl *) )
+
+and includ = 
+  { i_include: inc_file wrap; (* #include s *)
+    (* cocci: computed in ? *)
+    i_rel_pos: include_rel_pos option ref;
+    (* cocci: cf -test incl *)
+    i_is_in_ifdef: bool; 
+    (* cf cpp_ast_c.ml. set to None at parsing time. *)
+    i_content: (Common.filename (* full path *) * program) option;
+  }
  and inc_file = 
   | Local    of inc_elem list
   | NonLocal of inc_elem list
   | Wierd of string (* ex: #include SYSTEM_H *)
   and inc_elem = string
 
-(* Cocci: to tag the first of #include <xx/> and last of #include <yy/>
- * 
- * The first_of and last_of store the list of prefixes that was
- * introduced by the include. On #include <a/b/x>, if the include was
- * the first in the file, it would give in first_of the following
- * prefixes a/b/c; a/b/; a/ ; <empty> 
- * 
- * This is set after parsing, in cocci.ml, in update_rel_pos.
- *)
+ (* cocci: to tag the first of #include <xx/> and last of #include <yy/>
 
 * The first_of and last_of store the list of prefixes that was
 * introduced by the include. On #include <a/b/x>, if the include was
 * the first in the file, it would give in first_of the following
 * prefixes a/b/c; a/b/; a/ ; <empty> 
 
 * This is set after parsing, in cocci.ml, in update_rel_pos.
 *)
  and include_rel_pos = { 
-  first_of : string list list;
-  last_of :  string list list;
+   first_of : string list list;
+   last_of :  string list list;
  }
 
+
+
+
+
+
 (* ------------------------------------------------------------------------- *)
 (* The toplevels elements *)
 (* ------------------------------------------------------------------------- *)
@@ -457,15 +583,15 @@ and toplevel =
   | Definition of definition
          
   (* cppext: *)
-  | Include of includ 
-  | Define of define 
+  | CppTop of cpp_directive
+  | IfdefTop of ifdef_directive (* * toplevel list *)
+
   (* cppext: *)
   | MacroTop of string * argument wrap2 list * il 
          
   | EmptyDef of il      (* gccext: allow redundant ';' *)
   | NotParsedCorrectly of il
 
-
   | FinalDef of info (* EOF *)
 
 (* ------------------------------------------------------------------------- *)
@@ -499,7 +625,8 @@ and metavars_binding = (Ast_cocci.meta_name, metavar_binding_kind) assoc
    * variables accessible via SmPL whereas the position can be one day
    * so I think it's better to put MetaPosVal here *)
   | MetaPosVal       of (Ast_cocci.fixpos * Ast_cocci.fixpos) (* max, min *)
-  | MetaPosValList   of (Common.filename * posl * posl) list (* min, max *)
+  | MetaPosValList   of
+      (Common.filename * string (*element*) * posl * posl) list (* min, max *)
   | MetaListlenVal   of int
 
 
@@ -507,8 +634,8 @@ and metavars_binding = (Ast_cocci.meta_name, metavar_binding_kind) assoc
 (* C comments *)
 (*****************************************************************************)
 
-(* I often use m for comments as I can not use c (already use for c stuff) 
- * and com is too long.
+(* convention: I often use "m" for comments as I can not use "c" 
+ * (already use for c stuff) and "com" is too long.
  *)
 
 (* this type will be associated to each token *)
@@ -537,7 +664,7 @@ and com = comment list ref
 
 
 (*****************************************************************************)
-(* Cpp constructs, put it comments in lexer *)
+(* Cpp constructs put it comments in lexer or parsing_hack *)
 (*****************************************************************************)
 
 (* This type is not in the Ast but is associated with the TCommentCpp token.
@@ -545,7 +672,11 @@ and com = comment list ref
  * it also in lexer_parser.
  *)
 type cppcommentkind = 
-  CppDirective | CppAttr | CppMacro | CppOther
+  | CppDirective 
+  | CppAttr 
+  | CppMacro 
+  | CppPassingNormal (* ifdef 0, cplusplus, etc *) 
+  | CppPassingCosWouldGetError (* expr passsing *)
 
 
 
@@ -595,6 +726,9 @@ let fakeInfo pi  =
     comments_tag = ref emptyComments;
   }
 
+let noii = []
+let noattr = []
+let noi_content = (None: ((Common.filename * program) option))
 
 (*****************************************************************************)
 (* Wrappers *)
@@ -640,11 +774,6 @@ let get_opi = function
   | FakeTok (_,_) -> failwith "no position information"
   | AbstractLineTok pi -> pi
 
-let is_fake ii =
-  match ii.pinfo with
-    FakeTok (_,_) -> true
-  | _ -> false
-
 let str_of_info ii =
   match ii.pinfo with
     OriginTok pi -> pi.Common.str
@@ -678,7 +807,18 @@ let mcode_of_info ii = fst (!(ii.cocci_tag))
 let pinfo_of_info ii = ii.pinfo
 let parse_info_of_info ii = get_pi ii.pinfo
 
+let is_fake ii =
+  match ii.pinfo with
+    FakeTok (_,_) -> true
+  | _ -> false
+
+let is_origintok ii = 
+  match ii.pinfo with
+  | OriginTok pi -> true
+  | _ -> false
+
 type posrv = Real of Common.parse_info | Virt of virtual_position
+
 let compare_pos ii1 ii2 =
   let get_pos = function
       OriginTok pi -> Real pi
@@ -713,6 +853,7 @@ let info_to_fixpos ii =
       Ast_cocci.Virt (pi.Common.charpos,offset)
   | AbstractLineTok pi -> failwith "unexpected abstract"
 
+(* cocci: *)
 let is_test (e : expression) =
   let (_,info) = unwrap e in
   let (_,test) = !info in
@@ -788,3 +929,46 @@ let split_register_param = fun (hasreg, idb, ii_b_s) ->
   | _, None, ii -> Right ii
   | _ -> raise Impossible
 
+
+
+(*****************************************************************************)
+(* Helpers, could also be put in lib_parsing_c.ml instead *)
+(*****************************************************************************)
+
+let rec stmt_elems_of_sequencable xs = 
+  xs +> Common.map (fun x -> 
+    match x with
+    | StmtElem e -> [e]
+    | CppDirectiveStmt _
+    | IfdefStmt _ 
+        -> 
+        pr2 ("stmt_elems_of_sequencable: filter a directive");
+        []
+    | IfdefStmt2 (_ifdef, xxs) -> 
+        pr2 ("stmt_elems_of_sequencable: IfdefStm2 TODO?");
+        xxs +> List.map (fun xs -> 
+          let xs' = stmt_elems_of_sequencable xs in
+          xs'
+        ) +> List.flatten
+  ) +> List.flatten
+        
+  
+
+
+let s_of_inc_file inc_file = 
+  match inc_file with
+  | Local xs -> xs +> Common.join "/"
+  | NonLocal xs -> xs +> Common.join "/"
+  | Wierd s -> s
+
+let s_of_inc_file_bis inc_file = 
+  match inc_file with
+  | Local xs -> "\"" ^ xs +> Common.join "/" ^ "\""
+  | NonLocal xs -> "<" ^ xs +> Common.join "/" ^ ">"
+  | Wierd s -> s
+
+let fieldname_of_fieldkind fieldkind = 
+  match unwrap fieldkind with
+  | Simple (sopt, ft) -> sopt
+  | BitField (sopt, ft, expr) -> sopt
+
index 608d3f3..3a12704 100644 (file)
@@ -26,6 +26,10 @@ open Oassocb
  * todo?: steal code from CIL ? (but seems complicated ... again) *)
 (*****************************************************************************)
 
+(*****************************************************************************)
+(* Types *)
+(*****************************************************************************)
+
 type error = 
   | DeadCode          of Common.parse_info option
   | CaseNoSwitch      of Common.parse_info
@@ -304,17 +308,7 @@ let rec (aux_statement: (nodei option * xinfo) -> statement -> nodei option) =
       !g +> add_arc_opt (starti, newi);
       let starti = Some newi in
 
-      statxs +> List.fold_left (fun starti statement ->
-        if !Flag_parsing_c.label_strategy_2
-        then incr counter_for_labels;
-
-        let newxi' = 
-          if !Flag_parsing_c.label_strategy_2
-          then { newxi with labels = xi.labels @ [ !counter_for_labels ] } 
-          else newxi
-        in
-        aux_statement (starti, newxi') statement
-      ) starti
+      aux_statement_list starti (xi, newxi) statxs
 
       (* braces: *)
       +> Common.fmap (fun starti -> 
@@ -477,46 +471,6 @@ let rec (aux_statement: (nodei option * xinfo) -> statement -> nodei option) =
            end)
         
       
-  | Selection  (Ast_c.Ifdef (st1s, st2s)), ii -> 
-      let (ii,iifakeend) = 
-        match ii with
-        | [i1;i2;i3;i4] -> [i1;i2;i3], i4
-        | [i1;i2;i3] -> [i1;i2], i3
-        | _ -> raise Impossible
-      in
-
-      let newi = !g +> add_node (Ifdef (stmt, ((), ii))) lbl "ifcpp" in
-      !g +> add_arc_opt (starti, newi);
-      let newfakethen = !g +> add_node TrueNode  lbl "[then]" in
-      let newfakeelse = !g +> add_node FalseNode lbl "[else]" in
-
-      !g#add_arc ((newi, newfakethen), Direct);
-      !g#add_arc ((newi, newfakeelse), Direct);
-
-      let aux_statement_list (starti, newxi) statxs =
-        statxs +> List.fold_left (fun starti statement ->
-          aux_statement (starti, newxi) statement
-        ) starti
-      in
-
-
-      let finalthen = aux_statement_list (Some newfakethen, xi_lbl) st1s in
-      let finalelse = aux_statement_list (Some newfakeelse, xi_lbl) st2s in
-
-      (match finalthen, finalelse with 
-        | (None, None) -> None
-        | _ -> 
-            let lasti =  
-              !g +> add_node (EndStatement (Some iifakeend)) lbl "[endifcpp]" 
-            in
-            begin
-              !g +> add_arc_opt (finalthen, lasti);
-              !g +> add_arc_opt (finalelse, lasti);
-              Some lasti
-           end
-      )
-      
-
    (* ------------------------- *)        
   | Selection  (Ast_c.Switch (e, st)), ii -> 
       let (i1,i2,i3, iifakeend) = tuple_of_list4 ii in
@@ -538,6 +492,7 @@ let rec (aux_statement: (nodei option * xinfo) -> statement -> nodei option) =
        let finalthen = 
          match st with
          | Ast_c.Compound statxs, ii -> 
+             let statxs = Ast_c.stmt_elems_of_sequencable statxs in
              
              (* todo? we should not allow to match a stmt that corresponds
               * to a compound of a switch, so really SeqStart (stmt, ...)
@@ -945,7 +900,8 @@ let rec (aux_statement: (nodei option * xinfo) -> statement -> nodei option) =
   | Ast_c.Decl decl, ii -> 
      let s = 
        match decl with
-       | (Ast_c.DeclList ([(Some ((s, _),_), typ, sto, _), _], _)) ->
+       | (Ast_c.DeclList 
+             ([{v_namei = Some ((s, _),_); v_type = typ; v_storage = sto}, _], _)) ->
           "decl:" ^ s
        | _ -> "decl_novar_or_multivar"
      in
@@ -973,6 +929,61 @@ let rec (aux_statement: (nodei option * xinfo) -> statement -> nodei option) =
 
 
 
+
+
+
+and aux_statement_list starti (xi, newxi) statxs = 
+  statxs 
+  +> List.fold_left (fun starti statement_seq ->
+    if !Flag_parsing_c.label_strategy_2
+    then incr counter_for_labels;
+    
+    let newxi' = 
+      if !Flag_parsing_c.label_strategy_2
+      then { newxi with labels = xi.labels @ [ !counter_for_labels ] } 
+      else newxi
+    in
+
+    match statement_seq with
+    | Ast_c.StmtElem statement -> 
+        aux_statement (starti, newxi') statement
+
+    | Ast_c.CppDirectiveStmt directive -> 
+        pr2_once ("ast_to_flow: filter a directive");
+        starti
+
+    | Ast_c.IfdefStmt ifdef -> 
+        pr2_once ("ast_to_flow: filter a directive");
+        starti
+
+    | Ast_c.IfdefStmt2 (ifdefs, xxs) -> 
+
+        let (head, body, tail) = Common.head_middle_tail ifdefs in
+
+        let newi = !g +> add_node (IfdefHeader (head)) newxi'.labels "[ifdef]" in
+        let taili = !g +> add_node (IfdefEndif (tail)) newxi'.labels "[endif]" in
+        !g +> add_arc_opt (starti, newi);
+
+        let elsenodes = 
+          body +> List.map (fun elseif -> 
+            let elsei = 
+              !g +> add_node (IfdefElse (elseif)) newxi'.labels "[elseif]" in
+            !g#add_arc ((newi, elsei), Direct);
+            elsei
+          ) in
+
+        let finalxs = 
+          Common.zip (newi::elsenodes) xxs +> List.map (fun (start_nodei, xs)-> 
+            let finalthen = 
+              aux_statement_list (Some start_nodei) (newxi, newxi) xs in
+            !g +> add_arc_opt (finalthen, taili);
+          ) 
+        in
+        Some taili
+
+  ) starti
+
+
 (*****************************************************************************)
 (* Definition of function *)
 (*****************************************************************************)
@@ -981,7 +992,12 @@ let (aux_definition: nodei -> definition -> unit) = fun topi funcdef ->
 
   let lbl_start = [!counter_for_labels] in
 
-  let ((funcs, functype, sto, compound), ii) = funcdef in
+  let ({f_name = funcs; 
+        f_type = functype; 
+        f_storage= sto; 
+        f_body= compound;
+        f_attr= attrs;
+        }, ii) = funcdef in
   let iifunheader, iicompound = 
     (match ii with 
     | is::ioparen::icparen::iobrace::icbrace::iifake::isto -> 
@@ -993,8 +1009,15 @@ let (aux_definition: nodei -> definition -> unit) = fun topi funcdef ->
 
   let topstatement = Ast_c.Compound compound, iicompound in
 
-  let headi = !g +> add_node (FunHeader ((funcs, functype, sto), iifunheader))
-                         lbl_start ("function " ^ funcs) in
+  let headi = !g +> add_node 
+    (FunHeader ({ 
+      Ast_c.f_name = funcs;
+      f_type = functype;
+      f_storage = sto;
+      f_attr = attrs;
+      f_body = [] (* empty body *)
+      }, iifunheader))
+    lbl_start ("function " ^ funcs) in
   let enteri     = !g +> add_node Enter     lbl_0 "[enter]"     in
   let exiti      = !g +> add_node Exit      lbl_0 "[exit]"      in
   let errorexiti = !g +> add_node ErrorExit lbl_0 "[errorexit]" in
@@ -1048,21 +1071,23 @@ let ast_to_control_flow e =
   let topi = !g +> add_node TopNode lbl_0 "[top]" in
 
   match e with 
-  | Ast_c.Definition (((funcs, _, _, c),_) as def) -> 
+  | Ast_c.Definition ((defbis,_) as def) -> 
+      let _funcs = defbis.f_name in
+      let _c = defbis.f_body in
       (* if !Flag.show_misc then pr2 ("build info function " ^ funcs); *)
       aux_definition topi def;
       Some !g
 
   | Ast_c.Declaration _ 
-  | Ast_c.Include _ 
+  | Ast_c.CppTop (Ast_c.Include _)
   | Ast_c.MacroTop _
     -> 
       let (elem, str) = 
         match e with 
         | Ast_c.Declaration decl -> 
             (Control_flow_c.Decl decl),  "decl"
-        | Ast_c.Include (a,b) -> 
-            (Control_flow_c.Include (a,b)), "#include"
+        | Ast_c.CppTop (Ast_c.Include inc) -> 
+            (Control_flow_c.Include inc), "#include"
         | Ast_c.MacroTop (s, args, ii) -> 
             let (st, (e, ii)) = specialdeclmacro_to_stmt (s, args, ii) in
             (Control_flow_c.ExprStatement (st, (Some e, ii))), "macrotoplevel"
@@ -1076,7 +1101,7 @@ let ast_to_control_flow e =
       !g#add_arc ((ei, endi),Direct);
       Some !g
 
-  | Ast_c.Define ((id,ii), (defkind, defval))  -> 
+  | Ast_c.CppTop (Ast_c.Define ((id,ii), (defkind, defval)))  -> 
       let s = ("#define " ^ id) in
       let headeri = !g+>add_node (DefineHeader ((id, ii), defkind)) lbl_0 s in
       !g#add_arc ((topi, headeri),Direct);
@@ -1116,7 +1141,7 @@ let ast_to_control_flow e =
           )
           
 
-      | Ast_c.DefineDoWhileZero (st, ii) -> 
+      | Ast_c.DefineDoWhileZero ((st,_e), ii) -> 
           let headerdoi = 
             !g +> add_node (DefineDoWhileZeroHeader ((),ii)) lbl_0 "do0" in
           !g#add_arc ((headeri, headerdoi), Direct);
@@ -1135,6 +1160,10 @@ let ast_to_control_flow e =
       | Ast_c.DefineEmpty -> 
           let endi = !g +> add_node EndNode lbl_0 "[end]" in
           !g#add_arc ((headeri, endi),Direct);
+      | Ast_c.DefineInit _ -> 
+          raise Todo
+      | Ast_c.DefineTodo -> 
+          raise Todo
       );
 
       Some !g
index efea7d1..4070927 100644 (file)
@@ -67,7 +67,7 @@ let normal_form_program xs =
     );
     Visitor_c.ktoplevel_s = (fun (k,bigf) p -> 
       match p with
-      | Define _ -> 
+      | CppTop (Define _) -> 
           raise Todo
           (*
           let (i1, i2, i3) = Common.tuple_of_list3 ii in
@@ -175,8 +175,9 @@ let compare_ast filename1 filename2  =
         | EmptyDef a, EmptyDef b ->       if not (a =*= b) then incr error
         | MacroTop (a1,b1,c1), MacroTop (a2,b2,c2) -> 
             if not ((a1,b1,c1) =*= (a2,b2,c2)) then incr error
-        | Include (a,_), Include (b,_) -> if not (a =*= b) then incr error
-        | Define _, Define _ ->   
+        | CppTop (Include {i_include = a}), CppTop (Include {i_include = b}) -> 
+            if not (a =*= b) then incr error
+        | CppTop Define _, CppTop Define _ ->   
             raise Todo
             (* if not (a =*= b) then incr error *)
         | NotParsedCorrectly a, NotParsedCorrectly b -> 
@@ -188,7 +189,13 @@ let compare_ast filename1 filename2  =
         | _, NotParsedCorrectly b -> 
             incr pb_notparsed
         | FinalDef a, FinalDef b -> if not (a =*= b) then incr error
-        | _, _ -> incr error
+
+        | IfdefTop a, IfdefTop b -> if not (a =*= b) then incr error
+
+        | (FinalDef _|EmptyDef _|
+           MacroTop (_, _, _)|IfdefTop _|
+           CppTop _|Definition _|Declaration _), _ -> incr error
+    
         );
         (match () with
         | _ when !pb_notparsed > 0 && !error = 0 -> 
index 7c6d07f..2b23662 100644 (file)
@@ -70,6 +70,7 @@ open Ast_c
 (*****************************************************************************)
 
 
+(* ---------------------------------------------------------------------- *)
 (* The string is for debugging. Used by Ograph_extended.print_graph. 
  * The int list are Labels. Trick used for CTL engine. Must not 
  * transform that in a triple or record because print_graph would
@@ -85,6 +86,7 @@ type node = node1 * string
     }
     and node2 =
 
+  (* ------------------------ *)
   (* For CTL to work, we need that some nodes loop over itself. We
    * need that every nodes have a successor. Julia also want to go back
    * indefinitely. So must tag some nodes as the beginning and end of
@@ -101,10 +103,12 @@ type node = node1 * string
    | TopNode 
    | EndNode 
 
-   | FunHeader of (string * functionType * storage) wrap
+   (* ------------------------ *)
+   | FunHeader of definition (* but empty body *)
 
    | Decl   of declaration
 
+   (* ------------------------ *)
    (* flow_to_ast: cocci: Need the { and } in the control flow graph also
     * because the coccier can express patterns containing such { }.
     *
@@ -183,6 +187,11 @@ type node = node1 * string
   | Return     of statement * unit wrap
   | ReturnExpr of statement * expression wrap
 
+  (* ------------------------ *)
+  | IfdefHeader of ifdef_directive
+  | IfdefElse of ifdef_directive
+  | IfdefEndif of ifdef_directive
+
 
   (* ------------------------ *)
   | DefineHeader of string wrap * define_kind
@@ -190,8 +199,9 @@ type node = node1 * string
   | DefineExpr of expression 
   | DefineType of fullType
   | DefineDoWhileZeroHeader of unit wrap
+  | DefineTodo
 
-  | Include of inc_file wrap * (include_rel_pos option ref * bool)
+  | Include of includ
 
   (* obsolete? *)
   | MacroTop of string * argument wrap2 list * il 
@@ -212,8 +222,6 @@ type node = node1 * string
   | Asm of statement * asmbody wrap
   | MacroStmt of statement * unit wrap
 
-  | Ifdef of statement * unit wrap
-
   (* ------------------------ *)
   (* some control nodes *)
   | Enter 
@@ -316,13 +324,15 @@ let extract_fullstatement node =
   | MacroStmt (st, _) -> Some st
   | MacroIterHeader (st, _) -> Some st
 
-  | Ifdef _ -> None (* other ? *)
-
   | Include _ 
   | DefineHeader _ | DefineType _ | DefineExpr  _ | DefineDoWhileZeroHeader _
+  | DefineTodo
   | MacroTop _
       -> None
 
+  | IfdefHeader _ | IfdefElse _ | IfdefEndif _ 
+      -> None
+
   | SeqStart (st,_,_) 
   | ExprStatement (st, _)
   | IfHeader  (st, _) 
index 0bd1ecf..3938bb4 100644 (file)
@@ -12,7 +12,7 @@ type node = node1 * string (* For debugging. Used by print_graph *)
   | TopNode 
   | EndNode
 
-  | FunHeader     of (string * functionType * storage) wrap
+  | FunHeader     of definition (* but empty body *)
   | Decl          of declaration
 
   | SeqStart      of statement * int * info
@@ -37,6 +37,11 @@ type node = node1 * string (* For debugging. Used by print_graph *)
   | ReturnExpr    of statement * expression wrap
 
 
+  (* ------------------------ *)
+  | IfdefHeader of ifdef_directive
+  | IfdefElse of ifdef_directive
+  | IfdefEndif of ifdef_directive
+
   (* ------------------------ *)
   | DefineHeader of string wrap * define_kind
 
@@ -44,7 +49,9 @@ type node = node1 * string (* For debugging. Used by print_graph *)
   | DefineType of fullType
   | DefineDoWhileZeroHeader of unit wrap
 
-  | Include of inc_file wrap * (include_rel_pos option ref * bool)
+  | DefineTodo
+
+  | Include of includ
 
   | MacroTop of string * argument wrap2 list * il 
 
@@ -64,8 +71,6 @@ type node = node1 * string (* For debugging. Used by print_graph *)
   | Asm of statement * asmbody wrap
   | MacroStmt of statement * unit wrap
 
-  | Ifdef of statement * unit wrap
-
 
   (* ------------------------ *)
   | Enter 
index 6a6a6be..1931509 100644 (file)
@@ -1,6 +1,6 @@
 parsing_c library - Yoann Padioleau
 
-Copyright (C) 2002-2008 Yoann Padioleau
+Copyright (C) 2002, 2005, 2006, 2007, 2008 Yoann Padioleau
 
   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License (GPL)
@@ -10,9 +10,3 @@ Copyright (C) 2002-2008 Yoann Padioleau
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   file license.txt for more details.
-
-
-The contents of some files in this directory was derived from external
-sources with compatible licenses.  The original copyright and license
-notice was preserved in the affected files.
-
diff --git a/parsing_c/cpp_ast_c.ml b/parsing_c/cpp_ast_c.ml
new file mode 100644 (file)
index 0000000..df0718b
--- /dev/null
@@ -0,0 +1,277 @@
+open Common
+
+open Ast_c
+
+(*****************************************************************************)
+(* Cpp Ast Manipulations *)
+(*****************************************************************************)
+
+(*
+ * cpp-include-expander-builtin.
+ * 
+ * alternative1: parse and call cpp tour a tour ?
+ * alternative2: apply cpp at the very end. Process that go through ast
+ * and do the stuff such as #include,  macro expand, 
+ * ifdef. 
+ * 
+ * But need keep those info in ast at least, even bad
+ * macro for instance, and for parse error region ? maybe can 
+ * get another chance ?
+ * I think it's better to do the cpp-include-expander in a different step
+ * rather than embedding it in the parser. The parser is already too complex. 
+ * Also keep with the tradition to try to parse as-is.
+ * 
+ * todo? but maybe could discover new info that could help reparse
+ * the ParseError in original file. Try again parsing it by
+ * putting it in a minifile ? 
+ * 
+ * 
+ * todo? maybe can do some pass that work at the ifdef level and for instance
+ * try to paren them, so have in Ast some stuff that are not
+ * present at parsing time but that can then be constructed after
+ * some processing (a little bit like my type for expression filler,
+ * or position info filler, or include relative position filler).
+ * 
+ * ??add such info about what was done somewhere ? could build new
+ * ??ast each time but too tedious (maybe need delta-programming!)
+ *
+ * 
+ * TODO: macro expand, 
+ * TODO: handle ifdef
+ * 
+ * 
+ * 
+ * cpp_ifdef_statementize: again better to separate concern and in parser
+ *  just add the directives in a flat way (IfdefStmt) and later do more
+ *  processing and transform them in a tree with some IfdefStmt2.
+ *)
+
+
+
+(*****************************************************************************)
+(* Types  *)
+(*****************************************************************************)
+
+type cpp_option = 
+  | I of Common.filename
+  | D of string * string option
+
+
+
+let i_of_cpp_options xs = 
+  xs +> Common.map_filter (function
+  | I f -> Some f
+  | D _ -> None
+  )
+
+let cpp_option_of_cmdline (xs, ys) = 
+  (xs +> List.map (fun s -> I s)) ++
+  (ys +> List.map (fun s -> 
+    if s =~ "\\([A-Z][A-Z0-9_]*\\)=\\(.*\\)"
+    then
+      let (def, value) = matched2 s in
+      D (def, Some value)
+    else 
+      D (s, None)
+  ))
+
+(*****************************************************************************)
+(* Helpers *)
+(*****************************************************************************)
+
+(* may return a list of match ? *)
+let find_header_file cppopts dirname inc_file =
+  match inc_file with
+  | Local f -> 
+      let finalfile = 
+        Filename.concat dirname (Ast_c.s_of_inc_file inc_file) in
+      if Sys.file_exists finalfile 
+      then [finalfile]
+      else []
+  | NonLocal f -> 
+      i_of_cpp_options cppopts +> Common.map_filter (fun dirname -> 
+        let finalfile = 
+          Filename.concat dirname (Ast_c.s_of_inc_file inc_file) in
+        if Sys.file_exists finalfile 
+        then Some finalfile
+        else None
+      )
+  | Wierd s -> 
+      pr2 ("CPPAST: wierd include not handled:" ^ s);
+      []
+
+
+let trace_cpp_process depth mark inc_file =
+  pr2 (spf "%s>%s %s" 
+          (Common.repeat "-" depth +> Common.join "")
+          mark
+          (s_of_inc_file_bis inc_file));
+  ()
+
+
+(*****************************************************************************)
+(* Main entry *)
+(*****************************************************************************)
+
+
+let (cpp_expand_include: 
+ cpp_option list -> Common.dirname -> Ast_c.program -> Ast_c.program) =
+ fun iops dirname ast -> 
+
+  pr2_xxxxxxxxxxxxxxxxx();
+  let already_included = ref [] in
+
+  let rec aux stack dirname ast = 
+    let depth = List.length stack in
+
+    ast +> Visitor_c.vk_program_s { Visitor_c.default_visitor_c_s with
+      Visitor_c.kcppdirective_s = (fun (k, bigf) cpp -> 
+        match cpp with 
+        | Include {i_include = (inc_file, ii);
+                   i_rel_pos = h_rel_pos;
+                   i_is_in_ifdef = b;
+                   i_content = copt;
+                   } 
+          -> 
+            (match find_header_file iops dirname inc_file with
+            | [file] -> 
+                if List.mem file !already_included
+                then begin 
+                  (* pr2 ("already included: " ^ file); *)
+                  trace_cpp_process depth "*" inc_file;
+                  k cpp
+                end else begin
+                  trace_cpp_process depth "" inc_file;
+                  Common.push2 file already_included;
+                  (* CONFIG *)
+                  Flag_parsing_c.verbose_parsing := false; 
+                  Flag_parsing_c.verbose_lexing := false; 
+                  let (ast2, _stat) = Parse_c.parse_c_and_cpp file in
+
+                  let ast = Parse_c.program_of_program2 ast2 in
+                  let dirname' = Filename.dirname file in 
+
+                  (* recurse *)
+                  let ast' = aux (file::stack) dirname' ast in
+
+                  Include {i_include = (inc_file, ii);
+                           i_rel_pos = h_rel_pos;
+                           i_is_in_ifdef = b;
+                           i_content = Some (file, ast');
+                  }
+                end
+            | [] -> 
+                trace_cpp_process depth "!!" inc_file;
+                pr2 "CPPAST: file not found";
+                k cpp
+            | x::y::zs -> 
+                trace_cpp_process depth "!!" inc_file;
+                pr2 "CPPAST: too much candidates";
+                k cpp
+            )
+        | _ -> k cpp
+      );
+    }
+  in
+  aux [] dirname ast
+    
+
+
+(* 
+let unparse_showing_include_content ?
+*)
+
+
+(*****************************************************************************)
+(* Ifdef-statementize *)
+(*****************************************************************************)
+
+
+let is_ifdef_and_same_tag tag x = 
+  match x with
+  | IfdefStmt (IfdefDirective ((_, tag2),_)) -> 
+      tag = tag2
+  | StmtElem _ | CppDirectiveStmt _ -> false
+  | IfdefStmt2 _ -> raise Impossible
+
+
+
+(* What if I skipped in the parser only some of the ifdef elements
+ * of the same tag. Once I passed one, I should pass all of them and so
+ * at least should detect here that one tag is not "valid". Maybe in the parser
+ * can return or marked some tags as "partially_passed_ifdef_tag".
+ * Maybe could do in ast_c a MatchingTag of int * bool ref (* one_was_passed *)
+ * where the ref will be shared by the ifdefs with the same matching tag
+ * indice. Or simply count  the number of directives with the same tag and
+ * put this information in the tag. Hence the total_with_this_tag below.
+ *)
+let should_ifdefize tag ifdefs_directives xxs = 
+  let IfdefTag (_tag, total_with_this_tag) = tag in
+  
+  if total_with_this_tag <> List.length ifdefs_directives
+  then begin
+    pr2 "CPPASTC: can not ifdefize, some of its directives were passed";
+    false 
+  end else 
+    (* todo? put more condition ? dont ifdefize declaration ? *)
+    true
+
+
+
+
+
+(* return a triple, (ifdefs directive * grouped xs * remaining sequencable) 
+ * XXX1 XXX2 elsif YYY1 else ZZZ1 endif WWW1 WWW2 
+ * => [elsif, else, endif], [XXX1 XXX2; YYY1; ZZZ1], [WWW1 WWW2]
+ *)
+let group_ifdef tag xs = 
+  let (xxs, xs) = group_by_post (is_ifdef_and_same_tag tag) xs in
+  
+  xxs +> List.map snd +> List.map (fun x -> 
+    match x with 
+    | IfdefStmt y -> y
+    | StmtElem _ | CppDirectiveStmt _ | IfdefStmt2 _ -> raise Impossible
+  ),
+  xxs +> List.map fst, 
+  xs
+
+
+let rec cpp_ifdef_statementize ast = 
+  Visitor_c.vk_program_s { Visitor_c.default_visitor_c_s with
+    Visitor_c.kstatementseq_list_s = (fun (k, bigf) xs -> 
+      
+      let rec aux xs = 
+        match xs with
+        | [] -> []
+        | stseq::xs -> 
+            (match stseq with
+            | StmtElem st -> 
+                Visitor_c.vk_statement_sequencable_s bigf stseq::aux xs
+            | CppDirectiveStmt directive -> 
+                Visitor_c.vk_statement_sequencable_s bigf stseq::aux xs
+            | IfdefStmt ifdef -> 
+                (match ifdef with
+                | IfdefDirective ((Ifdef,tag),ii) -> 
+
+                    let (restifdefs, xxs, xs') = group_ifdef tag xs in
+                    if should_ifdefize tag (ifdef::restifdefs) xxs 
+                    then
+                      let res = IfdefStmt2 (ifdef::restifdefs, xxs) in
+                      Visitor_c.vk_statement_sequencable_s bigf res::aux xs'
+                    else 
+                      Visitor_c.vk_statement_sequencable_s bigf stseq::aux xs
+                      
+                | IfdefDirective (((IfdefElseif|IfdefElse|IfdefEndif),b),ii) -> 
+                    pr2 "wierd: first directive is not a ifdef";
+                    (* maybe not wierd, just that should_ifdefize 
+                     * returned false *)
+                    Visitor_c.vk_statement_sequencable_s bigf stseq::aux xs
+                )
+
+            | IfdefStmt2 (ifdef, xxs) -> 
+                failwith "already applied cpp_ifdef_statementize"
+            )
+      in
+      aux xs
+    );
+  } ast
diff --git a/parsing_c/cpp_ast_c.mli b/parsing_c/cpp_ast_c.mli
new file mode 100644 (file)
index 0000000..401fe1b
--- /dev/null
@@ -0,0 +1,14 @@
+type cpp_option = 
+  | I of Common.filename
+  | D of string * string option
+
+val cpp_option_of_cmdline: 
+  Common.dirname list (* -I *) * string list (* -D *) -> cpp_option list
+
+val cpp_expand_include: 
+  cpp_option list -> Common.dirname (* start point for relative paths *) -> 
+  Ast_c.program -> Ast_c.program
+
+
+val cpp_ifdef_statementize: Ast_c.program -> Ast_c.program
+
index 29a9218..6ee963d 100644 (file)
@@ -3,7 +3,10 @@ indentation information for heuristic-based parsing. Thanks to Julia
 again for many other things too long to enumerate.
 
 Inspiration:
- - C grammar found on the web
+ - C yacc grammar published in 1985 by Jeff Lee:
+    lex:  http://www.lysator.liu.se/c/ANSI-C-grammar-l.html
+    yacc: http://www.lysator.liu.se/c/ANSI-C-grammar-y.html
+
  - FrontC of hughes casse ?
  - CIL ?
  - EDG ?
index c1b1b54..049e3ff 100644 (file)
@@ -1,15 +1,32 @@
 (*****************************************************************************)
 (* convenient globals to pass to parse_c.init_defs *)
 (*****************************************************************************)
-let path = Filename.concat (Sys.getenv "HOME") "coccinelle"
-let std_h   = ref (Filename.concat path "standard.h")
+let path = ref 
+  (try (Sys.getenv "YACFE_HOME")
+    with Not_found-> "/home/pad/c-yacfe"
+  )
+let std_h   = ref (Filename.concat !path "data/standard.h")
+let common_h   = ref (Filename.concat !path "data/common_macros.h")
+
 
 let cmdline_flags_macrofile () = 
   [
     "-macro_file", Arg.Set_string std_h,
     " <file> (default=" ^ !std_h ^ ")";
-    "-D",   Arg.Set_string std_h,     
-    " short option of -macro_file";
+  ]
+
+
+(*****************************************************************************)
+(* used only by cpp_ast_c, not by the parser *)
+(*****************************************************************************)
+let cpp_i_opts = ref []
+let cpp_d_opts = ref []
+
+let cmdline_flags_cpp () = [
+    "-D",   Arg.String (fun s -> Common.push2 s cpp_d_opts),
+    " <x=y>";
+    "-I", Arg.String (fun s -> Common.push2 s cpp_i_opts),
+    " <dir>"
   ]
 
 (*****************************************************************************)
@@ -21,8 +38,11 @@ let verbose_parsing = ref true
 let verbose_type    = ref true
 
 let filter_msg = ref false
+let filter_msg_define_error = ref false
+
 let filter_define_error = ref false
-let filter_classic_passed = ref false
+
+let filter_passed_level = ref 0
 
 let pretty_print_type_info = ref false
 
@@ -40,8 +60,12 @@ let cmdline_flags_verbose () =
     
     "-filter_msg",      Arg.Set  filter_msg , 
     "  filter some cpp message when the macro is a \"known\" cpp construct";
-    "-filter_define_error",Arg.Set filter_define_error,"  ";
-    "-filter_classic_passed",Arg.Set filter_classic_passed,"  ";
+    "-filter_msg_define_error",Arg.Set filter_msg_define_error,
+    "  filter the error msg";
+
+    "-filter_define_error",Arg.Set filter_define_error,
+    "  filter the error, which will not be added in the stat";
+    "-filter_passed_level",Arg.Set_int filter_passed_level,"  ";
   ]
 
 
@@ -74,23 +98,41 @@ let cmdline_flags_debugging () =
 (* change algo *)
 (*****************************************************************************)
 
-let ifdef_to_if = ref false
-let if0_passing = ref true
-let add_typedef_root = ref true
-
 (* cocci specific *)
 let label_strategy_2 = ref false
 
 let cmdline_flags_algos () =
   [
-    "-ifdef",              Arg.Set ifdef_to_if, 
-    "   convert ifdef to if (buggy!)";
+    "-l1",                Arg.Clear label_strategy_2, " ";
+  ]
+
+(*****************************************************************************)
+(* Disable parsing feature (for CC09 and also to see if useful) *)
+(*****************************************************************************)
+
+let cpp_directive_passing = ref false
+let ifdef_directive_passing = ref false 
+
+let disable_two_pass = ref false
+let disable_add_typedef = ref false
+
+let if0_passing = ref true
+let add_typedef_root = ref true
+
+let cmdline_flags_parsing_algos () = [
+
+    "-directive_passing",              Arg.Set cpp_directive_passing, 
+    "   pass most cpp directives, especially when inside function";
+    "-ifdef_passing",              Arg.Set ifdef_directive_passing, 
+    "   pass ifdef directives ";
+
     "-noif0_passing",   Arg.Clear if0_passing, 
     " ";
     "-noadd_typedef_root",   Arg.Clear add_typedef_root, " ";
+    "-noadd_typedef",   Arg.Set disable_add_typedef, " ";
 
-    "-l1",                Arg.Clear label_strategy_2, " ";
-  ]
+    "-disable_two_pass", Arg.Set disable_two_pass, " ";
+]
 
 (*****************************************************************************)
 (* other *)
index 12727e5..5dd00d7 100644 (file)
@@ -1,5 +1,5 @@
 {
-(* Copyright (C) 2002-2008 Yoann Padioleau
+(* Copyright (C) 2002, 2006, 2007, 2008 Yoann Padioleau
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License (GPL)
@@ -67,12 +67,16 @@ let tokinfo lexbuf  =
     comments_tag = ref Ast_c.emptyComments;
   }
 
+(* must generate a new ref each time, otherwise share *)
+let no_ifdef_mark () = ref (None: (int * int) option)
+
 let tok_add_s s ii = Ast_c.rewrap_str ((Ast_c.str_of_info ii) ^ s) ii
     
 
 (* opti: less convenient, but using a hash is faster than using a match *)
 let keyword_table = Common.hash_of_list [
 
+  (* c: *)
   "void",   (fun ii -> Tvoid ii); 
   "char",   (fun ii -> Tchar ii);    
   "short",  (fun ii -> Tshort ii); 
@@ -121,16 +125,16 @@ let keyword_table = Common.hash_of_list [
   "inline",     (fun ii -> Tinline ii);
   "__inline__", (fun ii -> Tinline ii);
   "__inline",   (fun ii -> Tinline ii);
-  "INLINE",     (fun ii -> Tinline ii); 
-  "_INLINE_",   (fun ii -> Tinline ii); 
-  "__INLINE__",   (fun ii -> Tinline ii); 
 
   "__attribute__", (fun ii -> Tattribute ii);
   "__attribute", (fun ii -> Tattribute ii);
 
   "typeof", (fun ii -> Ttypeof ii);
   "__typeof__", (fun ii -> Ttypeof ii);
+  "__typeof", (fun ii -> Ttypeof ii);
+
 
+  (* gccext: alias *)
   "__signed__",     (fun ii -> Tsigned ii);
 
   "__const__",     (fun ii -> Tconst ii);
@@ -138,6 +142,14 @@ let keyword_table = Common.hash_of_list [
 
   "__volatile__",  (fun ii -> Tvolatile ii); 
   "__volatile",    (fun ii -> Tvolatile ii);  
+
+
+  (* c99:  *)
+  (* no just "restrict" ? maybe for backward compatibility they avoided 
+   * to use restrict which people may have used in their program already 
+   *)
+  "__restrict",    (fun ii -> Trestrict ii);  
+  "__restrict__",    (fun ii -> Trestrict ii);  
   
  ]
 
@@ -207,6 +219,7 @@ rule token = parse
 
   (* C++ comment are allowed via gccext, but normally they are deleted by cpp.
    * So need this here only when dont call cpp before.
+   * note that we don't keep the trailing \n; it will be in another token.
    *)
   | "//" [^'\r' '\n' '\011']*    { TComment (tokinfo lexbuf) } 
 
@@ -240,39 +253,27 @@ rule token = parse
   (* misc *)
   (* ---------------------- *)
       
-   (* #pragma pack
-    * #pragma GCC set_debug_pwd
-    * #pragma alloc_text
-    * #pragma options align=packed
-    * #pragma options align=reset
-    * #pragma options align=power
-    * #pragma  pack(2)
-    * etc
-    *)
-  | "#pragma" sp  [^'\n']* '\n'  
-      { TCommentCpp (CppDirective, tokinfo lexbuf) }
-
-  | "#" [' ' '\t']* "ident"   [' ' '\t']+  [^'\n']+ '\n' 
-
-  | "#" [' ' '\t']* "line"   [' ' '\t']+  [^'\n']+ '\n' 
+  (* bugfix: I want now to keep comments for the cComment study 
+   * so cant do:    sp [^'\n']+ '\n' 
+   * http://gcc.gnu.org/onlinedocs/gcc/Pragmas.html
+   *)
 
-  | "#" [' ' '\t']* "error"   [' ' '\t']+  [^'\n']* '\n' 
-  | "#" [' ' '\t']* "warning" [' ' '\t']+  [^'\n']* '\n'                     
-  | "#" [' ' '\t']* "abort"   [' ' '\t']+  [^'\n']* '\n'
+  | "#" spopt "pragma"  sp [^'\n']*  '\n'
+  | "#" spopt "ident"   sp  [^'\n']* '\n' 
+  | "#" spopt "line"    sp  [^'\n']* '\n' 
+  | "#" spopt "error"   sp  [^'\n']* '\n' 
+  | "#" spopt "warning" sp  [^'\n']* '\n'                     
+  | "#" spopt "abort"   sp  [^'\n']* '\n'
+      { TCppDirectiveOther (tokinfo lexbuf) }
 
-      { TCommentCpp (CppDirective, tokinfo lexbuf) }
+  | "#" [' ' '\t']* '\n' 
+      { TCppDirectiveOther (tokinfo lexbuf) }
 
   (* only after cpp, ex: # 1 "include/linux/module.h" 1 *)
   | "#" sp pent sp  '"' [^ '"']* '"' (spopt pent)*  spopt '\n'
-      { TCommentCpp (CppDirective, tokinfo lexbuf) }
+      { TCppDirectiveOther (tokinfo lexbuf) }
 
 
-  (* in drivers/char/tpqic02.c, in old version of the kernel *)
-  | "#" [' ' '\t']* "error"     { TCommentCpp (CppDirective,tokinfo lexbuf) }
-
-
-  | "#" [' ' '\t']* '\n'        { TCommentCpp (CppDirective,tokinfo lexbuf) }
-
 
   (* ---------------------- *)
   (* #define, #undef *)
@@ -283,90 +284,84 @@ rule token = parse
    *)
   | "#" [' ' '\t']* "define" { TDefine (tokinfo lexbuf) } 
 
-  | "#" [' ' '\t']* "undef" [' ' '\t']+ id
-      { let info = tokinfo lexbuf in 
-        TCommentCpp (CppDirective,info +> tok_add_s (cpp_eat_until_nl lexbuf))
-      }
-
-
-  (* could generate separate token for #, ## and then exten grammar,
-   * but there can be ident in many different places, in expression
-   * but also in declaration, in function name. So having 3 tokens
-   * for an ident does not work well with how we add info in
-   * ast_c. So better to generate just one token, just one info,
-   * even if have later to reanalyse those tokens and unsplit.
+  (* note: in some cases can have stuff after the ident as in #undef XXX 50, 
+   * but I currently don't handle it cos I think it's bad code.
    *)
-
-  | ((id as s)  "...")
-      { TDefParamVariadic (s, tokinfo lexbuf) }
-
-  (* cppext: string concatenation *)
-  |  id   ([' ''\t']* "##" [' ''\t']* id)+ 
-      { let info = tokinfo lexbuf in
-        TIdent (tok lexbuf, info)
-      }
-
-  (* cppext: stringification *)
-  |  "#" id  
-      { let info = tokinfo lexbuf in
-        TIdent (tok lexbuf, info)
-      }
-
-  (* cppext: gccext: ##args for variadic macro *)
-  |  "##" [' ''\t']* id
-      { let info = tokinfo lexbuf in
-        TIdent (tok lexbuf, info)
+  | (("#" [' ' '\t']* "undef" [' ' '\t']+) as _undef) (id as id)
+      { let info = tokinfo lexbuf in 
+        TUndef (id, info)
+        (*+> tok_add_s (cpp_eat_until_nl lexbuf))*)
       }
 
-  (* only in cpp directives normally *)
-  | "\\" '\n' { TCppEscapedNewline (tokinfo lexbuf) }
-
 
   (* ---------------------- *)
   (* #include *)
   (* ---------------------- *)
 
   (* The difference between a local "" and standard <> include is computed
-   * later in parser_c.mly. So redo a little bit of lexing there. Ugly but
+   * later in parser_c.mly. So redo a little bit of lexing there; ugly but
    * simpler to generate a single token here.  *)
   | (("#" [' ''\t']* "include" [' ' '\t']*) as includes) 
     (('"' ([^ '"']+) '"' | 
      '<' [^ '>']+ '>' | 
       ['A'-'Z''_']+ 
     ) as filename)
-      {
-        let info = tokinfo lexbuf in 
+      { let info = tokinfo lexbuf in 
+        TInclude (includes, filename, Ast_c.noInIfdef(), info)
+      }
+  (* gccext: found in glibc *)
+  | (("#" [' ''\t']* "include_next" [' ' '\t']*) as includes) 
+    (('"' ([^ '"']+) '"' | 
+     '<' [^ '>']+ '>' | 
+      ['A'-'Z''_']+ 
+    ) as filename)
+      { let info = tokinfo lexbuf in 
         TInclude (includes, filename, Ast_c.noInIfdef(), info)
       }
-
-   (* linuxext: special_for_no_exn: in atm/ambassador.c *)
-  | "#include UCODE(" [^'\n']+  '\n'    
-      { TCommentCpp (CppDirective, tokinfo lexbuf) }
-
 
   (* ---------------------- *)
   (* #ifdef *)
   (* ---------------------- *)
 
+  (* The ifdef_mark will be set later in Parsing_hacks.set_ifdef_parenthize_info
+   * when working on the ifdef view.
+   *)
+
   (* '0'+ because sometimes it is a #if 000 *)
   | "#" [' ' '\t']* "if" [' ' '\t']* '0'+           (* [^'\n']*  '\n' *)
       { let info = tokinfo lexbuf in 
-        TIfdefBool (false, info +> tok_add_s (cpp_eat_until_nl lexbuf)) 
+        TIfdefBool (false, no_ifdef_mark(), info)
+          (* +> tok_add_s (cpp_eat_until_nl lexbuf)*) 
       }
 
-  | "#" [' ' '\t']* "if" [' ' '\t']* '1'   [^'\n']*  '\n'
+  | "#" [' ' '\t']* "if" [' ' '\t']* '1'   (* [^'\n']*  '\n' *)
       { let info = tokinfo lexbuf in 
-        TIfdefBool (true, info) 
+        TIfdefBool (true, no_ifdef_mark(), info) 
 
       } 
+  
+ (* DO NOT cherry pick to lexer_cplusplus !!! often used for the extern "C" { *)
+  | "#" [' ' '\t']* "if" sp "defined" sp "(" spopt "__cplusplus" spopt ")" [^'\n']* '\n'
+      { let info = tokinfo lexbuf in 
+        TIfdefMisc (false, no_ifdef_mark(), info) 
+      }
 
+ (* DO NOT cherry pick to lexer_cplusplus !!! *)
   | "#" [' ' '\t']* "ifdef" [' ' '\t']* "__cplusplus"   [^'\n']*  '\n'
       { let info = tokinfo lexbuf in 
-        TIfdefMisc (false, info) 
+        TIfdefMisc (false, no_ifdef_mark(), info) 
       }
 
+  (* in glibc *)
+  | "#" spopt ("ifdef"|"if") sp "__STDC__"
+      { let info = tokinfo lexbuf in 
+        TIfdefVersion (true, no_ifdef_mark(), 
+                      info +> tok_add_s (cpp_eat_until_nl lexbuf)) 
+      } 
+
+
+  (* linuxext: different possible variations (we do not manage all of them):
 
-  (* linuxext: different possible variations (we not manage all of them):
     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
     #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,2)
     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
@@ -391,49 +386,105 @@ rule token = parse
     
   *)
 
-  (* linuxext: *)
+  (* linuxext: must be before the generic rules for if and ifdef *)
   | "#" spopt "if" sp "("?  "LINUX_VERSION_CODE" sp (">=" | ">") sp
       { let info = tokinfo lexbuf in 
-        TIfdefVersion (true, info +> tok_add_s (cpp_eat_until_nl lexbuf)) 
+        TIfdefVersion (true, no_ifdef_mark(), 
+                      info +> tok_add_s (cpp_eat_until_nl lexbuf)) 
       } 
   (* linuxext: *)
   | "#" spopt "if" sp "!" "("?  "LINUX_VERSION_CODE" sp (">=" | ">") sp
   | "#" spopt "if" sp ['(']?  "LINUX_VERSION_CODE" sp ("<=" | "<") sp
       
       { let info = tokinfo lexbuf in 
-        TIfdefVersion (false, info +> tok_add_s (cpp_eat_until_nl lexbuf)) 
+        TIfdefVersion (false, no_ifdef_mark(), 
+                      info +> tok_add_s (cpp_eat_until_nl lexbuf)) 
       } 
 
 
+
+
   (* can have some ifdef 0  hence the letter|digit even at beginning of word *)
   | "#" [' ''\t']* "ifdef"  [' ''\t']+ (letter|digit) ((letter|digit)*) [' ''\t']*  
-      { TIfdef (tokinfo lexbuf) }
+      { TIfdef (no_ifdef_mark(), tokinfo lexbuf) }
   | "#" [' ''\t']* "ifndef" [' ''\t']+ (letter|digit) ((letter|digit)*) [' ''\t']*  
-      { TIfdef (tokinfo lexbuf) }
+      { TIfdef (no_ifdef_mark(), tokinfo lexbuf) }
   | "#" [' ''\t']* "if" [' ' '\t']+                                           
       { let info = tokinfo lexbuf in 
-        TIfdef (info +> tok_add_s (cpp_eat_until_nl lexbuf)) 
+        TIfdef (no_ifdef_mark(), info +> tok_add_s (cpp_eat_until_nl lexbuf)) 
       }
   | "#" [' ' '\t']* "if" '('                
       { let info = tokinfo lexbuf in 
-        TIfdef (info +> tok_add_s (cpp_eat_until_nl lexbuf))
+        TIfdef (no_ifdef_mark(), info +> tok_add_s (cpp_eat_until_nl lexbuf))
       }
 
   | "#" [' ' '\t']* "elif" [' ' '\t']+ 
       { let info = tokinfo lexbuf in 
-        TIfdefelif (info +> tok_add_s (cpp_eat_until_nl lexbuf)) 
+        TIfdefelif (no_ifdef_mark(), info +> tok_add_s (cpp_eat_until_nl lexbuf)) 
       } 
 
 
-  (* can have #endif LINUX *)
-  | "#" [' ' '\t']* "endif" [^'\n']* '\n'    { TEndif     (tokinfo lexbuf) }
+  (* bugfix: can have #endif LINUX  but at the same time if I eat everything
+   * until next line, I may miss some TComment which for some tools
+   * are important such as aComment 
+   *)
+  | "#" [' ' '\t']* "endif" (*[^'\n']* '\n'*) { 
+      TEndif     (no_ifdef_mark(), tokinfo lexbuf) 
+    }
   (* can be at eof *)
-  | "#" [' ' '\t']* "endif"                  { TEndif     (tokinfo lexbuf) }
+  (*| "#" [' ' '\t']* "endif"                { TEndif     (tokinfo lexbuf) }*)
+
+  | "#" [' ' '\t']* "else" [' ' '\t' '\n']   
+      { TIfdefelse (no_ifdef_mark(), tokinfo lexbuf) }
+
+
+
+
+  (* ---------------------- *)
+  (* #define body *)
+  (* ---------------------- *)
+
+  (* only in cpp directives normally *)
+  | "\\" '\n' { TCppEscapedNewline (tokinfo lexbuf) }
+
+
+  | ((id as s)  "...")
+      { TDefParamVariadic (s, tokinfo lexbuf) }
+
+
+  (* could generate separate token for #, ## and then extend grammar,
+   * but there can be ident in many different places, in expression
+   * but also in declaration, in function name. So having 3 tokens
+   * for an ident does not work well with how we add info in
+   * ast_c. So better to generate just one token, for now, just one info,
+   * even if have later to reanalyse those tokens and unsplit.
+   * 
+   * todo: our heuristics in parsing_hacks rely on TIdent. So maybe
+   * an easier solution would be to augment the TIdent type such as 
+   *   TIdent of string * info * cpp_ident_additionnal_info
+   *)
+
 
-  | "#" [' ' '\t']* "else" [' ' '\t' '\n']   { TIfdefelse (tokinfo lexbuf) }
-  (* there is a file in 2.6 that have this *)
-  | "##" [' ' '\t']* "else" [' ' '\t' '\n']  { TIfdefelse (tokinfo lexbuf) }
+  (* cppext: string concatenation of idents *)
+  |  id   ([' ''\t']* "##" [' ''\t']* id)+ 
+      { let info = tokinfo lexbuf in
+        TIdent (tok lexbuf, info)
+      }
+
+  (* cppext: stringification.
+   * bugfix: this case must be after the other cases such as #endif
+   * otherwise take precedent.
+   *)
+  |  "#" spopt id  
+      { let info = tokinfo lexbuf in
+        TIdent (tok lexbuf, info)
+      }
 
+  (* cppext: gccext: ##args for variadic macro *)
+  |  "##" spopt id
+      { let info = tokinfo lexbuf in
+        TIdent (tok lexbuf, info)
+      }
 
 
 
@@ -511,19 +562,32 @@ rule token = parse
           with
           | Some f -> f info
 
-           (* parse_typedef_fix. note: now this is no more useful, cos
-            * as we use tokens_all, it first parse all as an ident and
-            * later transform an indent in a typedef. so this job is
-            * now done in parse_c.ml.
-            * 
+           (* parse_typedef_fix. 
             *    if Lexer_parser.is_typedef s 
             *    then TypedefIdent (s, info)
             *    else TIdent (s, info)
+            * 
+            * update: now this is no more useful, cos
+            * as we use tokens_all, it first parse all as an ident and
+            * later transform an indent in a typedef. so the typedef job is
+            * now done in parse_c.ml.
             *)
 
           | None -> TIdent (s, info)
-        )            
-      }        
+        )
+      }
+  (* gccext: apparently gcc allows dollar in variable names. found such 
+   * thing a few time in linux and in glibc. No need look in keyword_table
+   * here.
+   *)
+  | (letter | '$') (letter | digit | '$') *  
+      { 
+        let info = tokinfo lexbuf in
+        let s = tok lexbuf in
+        pr2 ("LEXER: identifier with dollar: "  ^ s);
+        TIdent (s, info)
+      }
+
 
   (* ----------------------------------------------------------------------- *)
   (* C constant *)
@@ -574,11 +638,11 @@ rule token = parse
 
   | ['0'] ['0'-'9']+  
       { pr2 ("LEXER: " ^ error_radix "octal" ^ tok lexbuf); 
-        TCommentMisc (tokinfo lexbuf)
+        TUnknown (tokinfo lexbuf)
       }
   | ("0x" |"0X") ['0'-'9' 'a'-'z' 'A'-'Z']+ 
       { pr2 ("LEXER: " ^ error_radix "hexa" ^ tok lexbuf);
-        TCommentMisc (tokinfo lexbuf)
+        TUnknown (tokinfo lexbuf)
       }
 
 
@@ -662,6 +726,8 @@ and string  = parse
           x ^ string lexbuf
        }
 
+  | eof { pr2 "LEXER: WIERD end of file in string"; ""}
+
  (* Bug if add following code, cos match also the '"' that is needed
   * to finish the string, and so go until end of file.
   *)
@@ -694,7 +760,7 @@ and comment = parse
 
 (* cpp recognize C comments, so when #define xx (yy) /* comment \n ... */
  * then he has already erased the /* comment. So:
- * - dont eat the start of the comment otherwiseafterwards we are in the middle
+ * - dont eat the start of the comment otherwise afterwards we are in the middle
  *   of a comment and so will problably get a parse error somewhere.
  * - have to recognize comments in cpp_eat_until_nl.
  *)
index 1c6eee4..cf18a58 100644 (file)
@@ -87,25 +87,42 @@ let restore_typedef_state () =
 
 
 
+type context = 
+  | InTopLevel
+  | InFunction
+  | InStruct
+  | InParameter
+  | InInitializer
+  | InEnum
+
+let is_top_or_struct = function
+  | InTopLevel
+  | InStruct 
+      -> true
+  | _ -> false
+
 type lexer_hint = { 
-    mutable parameterDeclaration: bool;
-    mutable structDefinition: int; (* depth in struct def, 0 = not in struct *)
-    mutable toplevel: bool;
-  }
+  mutable context_stack: context Common.stack;
+ }
 
 let default_hint () = { 
-  parameterDeclaration = false;
-  structDefinition = 0;
-  toplevel = false;
+  context_stack = [InTopLevel];
 }
 
 let _lexer_hint = ref (default_hint())
 
+let current_context () = List.hd !_lexer_hint.context_stack 
+let push_context ctx = 
+  !_lexer_hint.context_stack <- ctx::!_lexer_hint.context_stack
+let pop_context () = 
+  !_lexer_hint.context_stack <- List.tl !_lexer_hint.context_stack
+
+
 
 let lexer_reset_typedef () = 
   begin
   _handle_typedef := true;
   _typedef := Common.empty_scoped_h_env ();
-  _lexer_hint := { (default_hint ()) with toplevel = true; } ;
+  _lexer_hint := (default_hint ());
   end
 
index 2f6287f..30d161f 100644 (file)
@@ -27,13 +27,23 @@ val save_typedef_state : unit -> unit
 val restore_typedef_state : unit -> unit
 
 
+type context = 
+  | InTopLevel
+  | InFunction
+  | InStruct
+  | InParameter
+  | InInitializer
+  | InEnum
+
+val is_top_or_struct : context -> bool
+
 type lexer_hint = { 
-    mutable parameterDeclaration: bool;
-    mutable structDefinition: int; (* depth in struct def, 0 = not in struct *)
-(*    mutable statements: bool; *)
-    mutable toplevel: bool;
-  }
+  mutable context_stack: context Common.stack;
+ }
 
 val _lexer_hint : lexer_hint ref
+val current_context: unit -> context
+val push_context: context -> unit
+val pop_context: unit -> unit
 
 val default_hint : unit -> lexer_hint
index 6e3c26e..fd87d49 100644 (file)
@@ -1,4 +1,4 @@
-(* Copyright (C) 2002-2008 Yoann Padioleau
+(* Copyright (C) 2007, 2008 Yoann Padioleau
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License (GPL)
@@ -102,11 +102,14 @@ let ii_of_ini  = extract_info_visitor Visitor_c.vk_ini
 let ii_of_param = extract_info_visitor Visitor_c.vk_param
 let ii_of_params = extract_info_visitor Visitor_c.vk_params_splitted
 let ii_of_struct_fields = extract_info_visitor Visitor_c.vk_struct_fields
-let ii_of_struct_field = extract_info_visitor Visitor_c.vk_struct_field
+(*let ii_of_struct_field = extract_info_visitor Visitor_c.vk_struct_field*)
+let ii_of_struct_fieldkinds = extract_info_visitor Visitor_c.vk_struct_fieldkinds
 let ii_of_cst = extract_info_visitor Visitor_c.vk_cst
 let ii_of_define_params = 
   extract_info_visitor Visitor_c.vk_define_params_splitted
+let ii_of_toplevel = extract_info_visitor Visitor_c.vk_toplevel
 
+(*****************************************************************************)
 let max_min_ii_by_pos xs = 
   match xs with
   | [] -> failwith "empty list, max_min_ii_by_pos"
@@ -137,7 +140,7 @@ let lin_col_by_pos xs =
   let (i2, i1) = max_min_ii_by_pos xs in
   let posf x = Ast_c.col_of_info x in
   let mposf x = Ast_c.col_of_info x + String.length (Ast_c.str_of_info x) in
-  (Ast_c.file_of_info i1,
+  (Ast_c.file_of_info i1,!Flag.current_element,
    (Ast_c.line_of_info i1, posf i1), (Ast_c.line_of_info i2, mposf i2))
 
 
index 6450692..00c62f7 100644 (file)
@@ -1,4 +1,4 @@
-(* Copyright (C) 2002-2008 Yoann Padioleau
+(* Copyright (C) 2006, 2007, 2008 Yoann Padioleau
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License (GPL)
@@ -15,12 +15,18 @@ open Common
 module TH = Token_helpers 
 module LP = Lexer_parser
 
+module Stat = Parsing_stat
+
 (*****************************************************************************)
 (* Wrappers *)
 (*****************************************************************************)
 let pr2 s = 
   if !Flag_parsing_c.verbose_parsing 
   then Common.pr2 s
+
+let pr2_once s = 
+  if !Flag_parsing_c.verbose_parsing 
+  then Common.pr2_once s
     
 (*****************************************************************************)
 (* Helpers *)
@@ -41,14 +47,15 @@ let error_msg_tok tok =
 
 
 let print_bad line_error (start_line, end_line) filelines  = 
-  if !Flag_parsing_c.verbose_parsing
-  then
   begin
     pr2 ("badcount: " ^ i_to_s (end_line - start_line));
+
     for i = start_line to end_line do 
+      let line = filelines.(i) in 
+
       if i = line_error 
-      then  pr2 ("BAD:!!!!!" ^ " " ^ filelines.(i)
-      else  pr2 ("bad:" ^ " " ^      filelines.(i)
+      then  pr2 ("BAD:!!!!!" ^ " " ^ line
+      else  pr2 ("bad:" ^ " " ^      line
     done
   end
 
@@ -76,106 +83,6 @@ let mk_info_item a b =
 
 
 
-(*****************************************************************************)
-(* Stat *)
-(*****************************************************************************)
-type parsing_stat = {
-    filename: filename;
-    mutable have_timeout: bool;
-
-    mutable correct: int;  
-    mutable bad: int;
-
-    mutable commentized: int; (* by our cpp commentizer *)
-
-    (* if want to know exactly what was passed through, uncomment:
-     *  
-     * mutable passing_through_lines: int;
-     * 
-     * it differs from bad by starting from the error to
-     * the synchro point instead of starting from start of
-     * function to end of function.
-     *)
-
-  } 
-
-let default_stat file =  { 
-    filename = file;
-    have_timeout = false;
-    correct = 0; bad = 0;
-    commentized = 0;
-  }
-
-(* todo: stat per dir ?  give in terms of func_or_decl numbers:   
- * nbfunc_or_decl pbs / nbfunc_or_decl total ?/ 
- *
- * note: cela dit si y'a des fichiers avec des #ifdef dont on connait pas les 
- * valeurs alors on parsera correctement tout le fichier et pourtant y'aura 
- * aucune def  et donc aucune couverture en fait.   
- * ==> TODO evaluer les parties non parsé ? 
- *)
-
-let print_parsing_stat_list = fun statxs -> 
-  let total = (List.length statxs) in
-  let perfect = 
-    statxs 
-      +> List.filter (function 
-          {have_timeout = false; bad = 0} -> true | _ -> false)
-      +> List.length 
-  in
-  pr2 "\n\n\n---------------------------------------------------------------";
-  pr2 "pbs with files:";
-  statxs 
-    +> List.filter (function 
-      | {have_timeout = true} -> true 
-      | {bad = n} when n > 0 -> true 
-      | _ -> false)
-    +> List.iter (function 
-        {filename = file; have_timeout = timeout; bad = n} -> 
-          pr2 (file ^ "  " ^ (if timeout then "TIMEOUT" else i_to_s n));
-        );
-
-  pr2 "\n\n\n";
-  pr2 "files with lots of tokens passed/commentized:";
-  let threshold_passed = 100 in
-  statxs 
-    +> List.filter (function 
-      | {commentized = n} when n > threshold_passed -> true
-      | _ -> false)
-    +> List.iter (function 
-        {filename = file; commentized = n} -> 
-          pr2 (file ^ "  " ^ (i_to_s n));
-        );
-
-  pr2 "\n\n\n---------------------------------------------------------------";
-  pr2 (
-  (sprintf "NB total files = %d; " total) ^
-  (sprintf "perfect = %d; " perfect) ^
-  (sprintf "pbs = %d; "     (statxs +> List.filter (function 
-      {have_timeout = b; bad = n} when n > 0 -> true | _ -> false) 
-                               +> List.length)) ^
-  (sprintf "timeout = %d; " (statxs +> List.filter (function 
-      {have_timeout = true; bad = n} -> true | _ -> false) 
-                               +> List.length)) ^
-  (sprintf "=========> %d" ((100 * perfect) / total)) ^ "%"
-                                                          
- );
-  let good = statxs +> List.fold_left (fun acc {correct = x} -> acc+x) 0 in
-  let bad  = statxs +> List.fold_left (fun acc {bad = x} -> acc+x) 0  in
-  let passed = statxs +> List.fold_left (fun acc {commentized = x} -> acc+x) 0
-  in
-  let gf, badf = float_of_int good, float_of_int bad in
-  let passedf = float_of_int passed in
-  pr2 (
-  (sprintf "nb good = %d,  nb passed = %d " good passed) ^
-  (sprintf "=========> %f"  (100.0 *. (passedf /. gf)) ^ "%")
-   );
-  pr2 (
-  (sprintf "nb good = %d,  nb bad = %d " good bad) ^
-  (sprintf "=========> %f"  (100.0 *. (gf /. (gf +. badf))) ^ "%"
-   )
-  )
-
 
 (*****************************************************************************)
 (* Stats on what was passed/commentized  *)
@@ -183,21 +90,50 @@ let print_parsing_stat_list = fun statxs ->
 
 let commentized xs = xs +> Common.map_filter (function
   | Parser_c.TCommentCpp (cppkind, ii) -> 
-      if !Flag_parsing_c.filter_classic_passed
-      then 
-        (match cppkind with
+      let s = Ast_c.str_of_info ii in
+      let legal_passing = 
+        match !Flag_parsing_c.filter_passed_level with 
+        | 0 -> false
+        | 1 -> 
+            List.mem cppkind [Ast_c.CppAttr]
+            || 
+            (s =~ "__.*")
+        | 2 -> 
+            List.mem cppkind [Ast_c.CppAttr;Ast_c.CppPassingNormal]
+            || 
+            (s =~ "__.*")
+        | 3 -> 
+            List.mem cppkind [Ast_c.CppAttr;Ast_c.CppPassingNormal;Ast_c.CppDirective]
+            || 
+            (s =~ "__.*")
+        | 4 -> 
+            List.mem cppkind [Ast_c.CppAttr;Ast_c.CppPassingNormal;Ast_c.CppMacro]
+            || 
+            (s =~ "__.*")
+
+
+        | 5 -> 
+            List.mem cppkind [Ast_c.CppAttr;Ast_c.CppPassingNormal;Ast_c.CppDirective;Ast_c.CppMacro]
+            || 
+            (s =~ "__.*")
+
+
+
+
+        | _ -> failwith "not valid level passing number"
+      in
+      if legal_passing then None else Some (ii.Ast_c.pinfo)
+
+        (*
         | Ast_c.CppOther -> 
-            let s = Ast_c.str_of_info ii in
             (match s with
             | s when s =~ "KERN_.*" -> None
             | s when s =~ "__.*" -> None
-            | _ -> Some (ii.Ast_c.pinfo)
+            | _ -> 
+                Some (ii.Ast_c.pinfo)
             )
-             
-        | Ast_c.CppDirective | Ast_c.CppAttr | Ast_c.CppMacro
-            -> None
-        )
-      else Some (ii.Ast_c.pinfo)
+        *)
+
       
   | Parser_c.TCommentMisc ii
   | Parser_c.TAction ii 
@@ -295,11 +231,15 @@ let tokens2 file =
     | e -> raise e
  )
 
-let tokens a = 
-  Common.profile_code "C parsing.tokens" (fun () -> tokens2 a)
+let time_lexing ?(profile=true) a = 
+  if profile 
+  then Common.profile_code_exclusif "LEXING" (fun () -> tokens2 a)
+  else tokens2 a 
+let tokens ?profile a = 
+  Common.profile_code "C parsing.tokens" (fun () -> time_lexing ?profile a)
 
 
-let tokens_string string = 
+let tokens_of_string string = 
   let lexbuf = Lexing.from_string string in
   try 
     let rec tokens_s_aux () = 
@@ -369,7 +309,7 @@ let parse_print_error file =
  *)
 
 let parse_gen parsefunc s = 
-  let toks = tokens_string s +> List.filter TH.is_not_comment in
+  let toks = tokens_of_string s +> List.filter TH.is_not_comment in
 
 
   (* Why use this lexing scheme ? Why not classically give lexer func
@@ -509,7 +449,11 @@ let consistency_checking2 xs =
     end
   );
 
-  (* third phase, update ast *)
+  (* third phase, update ast. 
+   * todo? but normally should try to handle correctly scope ? maybe sometime
+   * sizeof(id) and even if id was for a long time an identifier, maybe 
+   * a few time, because of the scope it's actually really a type.
+   *)
   if (null !ident_to_type)
   then xs 
   else 
@@ -613,7 +557,7 @@ and find_next_synchro_define next already_passed =
       pr2 "ERROR-RECOV: end of file while in recovery mode"; 
       already_passed, []
   | (Parser_c.TDefEOL i as v)::xs  -> 
-      pr2 ("ERROR-RECOV: found sync end of #define "^i_to_s(TH.line_of_tok v));
+      pr2 ("ERROR-RECOV: found sync end of #define, line "^i_to_s(TH.line_of_tok v));
       v::already_passed, xs
   | v::xs -> 
       find_next_synchro_define xs (v::already_passed)
@@ -678,6 +622,20 @@ and find_next_synchro_orig next already_passed =
 (* Include/Define hacks *)
 (*****************************************************************************)
 
+(* Sometimes I prefer to generate a single token for a list of things in the
+ * lexer so that if I have to passed them, like for passing TInclude then
+ * it's easy. Also if I don't do a single token, then I need to 
+ * parse the rest which may not need special stuff, like detecting 
+ * end of line which the parser is not really ready for. So for instance
+ * could I parse a #include <a/b/c/xxx.h> as 2 or more tokens ? just
+ * lex #include ? so then need recognize <a/b/c/xxx.h> as one token ? 
+ * but this kind of token is valid only after a #include and the
+ * lexing and parsing rules are different for such tokens so not that
+ * easy to parse such things in parser_c.mly. Hence the following hacks.
+ * 
+ * less?: maybe could get rid of this like I get rid of some of fix_define.
+ *)
+
 (* ------------------------------------------------------------------------- *)
 (* helpers *)
 (* ------------------------------------------------------------------------- *)
@@ -705,8 +663,13 @@ let rec comment_until_defeol xs =
           Parser_c.TCommentCpp (Ast_c.CppDirective, TH.info_of_tok x)
           ::xs
       | _ -> 
-          Parser_c.TCommentCpp (Ast_c.CppOther, TH.info_of_tok x)
-          ::comment_until_defeol xs
+          let x' = 
+            (* bugfix: otherwise may lose a TComment token *)
+            if TH.is_real_comment x
+            then x
+            else Parser_c.TCommentCpp (Ast_c.CppPassingNormal (*good?*), TH.info_of_tok x)
+          in
+          x'::comment_until_defeol xs
       )
 
 let drop_until_defeol xs = 
@@ -726,14 +689,28 @@ let tokens_include (info, includes, filename, inifdef) =
   ]
 
 (*****************************************************************************)
-(* Parsing default define, standard.h *)
+(* Parsing default define macros, usually in a standard.h file *)
 (*****************************************************************************)
 
-let parse_cpp_define_file file = 
-  let toks = tokens file in
+let parse_cpp_define_file2 file = 
+  let toks = tokens ~profile:false file in
   let toks = Parsing_hacks.fix_tokens_define toks in
   Parsing_hacks.extract_cpp_define toks
 
+let parse_cpp_define_file a = 
+  Common.profile_code_exclusif "HACK" (fun () -> parse_cpp_define_file2 a)
+
+(* can not be put in parsing_hack, cos then mutually recursive problem as
+ * we also want to parse the standard.h file.
+ *)
+let init_defs std_h =     
+  if not (Common.lfile_exists std_h)
+  then pr2 ("warning: Can't find default macro file: " ^ std_h)
+  else begin
+    pr2 ("init_defs: " ^ std_h);
+    Parsing_hacks._defs := Common.hash_of_list (parse_cpp_define_file std_h);
+  end
+
 
 (*****************************************************************************)
 (* Main entry point *)
@@ -744,6 +721,18 @@ type info_item =  string * Parser_c.token list
 type program2 = toplevel2 list
      and toplevel2 = Ast_c.toplevel * info_item
 
+let program_of_program2 xs = 
+  xs +> List.map fst
+
+let with_program2 f program2 = 
+  program2 
+  +> Common.unzip 
+  +> (fun (program, infos) -> 
+    f program, infos
+  )
+  +> Common.uncurry Common.zip
+
+
 
 (* The use of local refs (remaining_tokens, passed_tokens, ...) makes
  * possible error recovery. Indeed, they allow to skip some tokens and
@@ -756,7 +745,7 @@ type program2 = toplevel2 list
  * provide enough context information for powerful lex trick.
  * 
  * - passed_tokens_last_ckp stores the passed tokens since last
- *   checkpoint. Used for NotParsedCorrectly and also for build the
+ *   checkpoint. Used for NotParsedCorrectly and also to build the
  *   info_item attached to each program_element.
  * - passed_tokens_clean is used for lookahead, in fact for lookback.
  * - remaining_tokens_clean is used for lookahead. Now remaining_tokens
@@ -779,6 +768,9 @@ type program2 = toplevel2 list
  * At the end of lexer_function call,  cur_tok  overlap  with passed_tok.
  * 
  * convention: I use "tr"  for "tokens refs"
+ * 
+ * I now also need this lexing trick because the lexer return comment
+ * tokens.
  *)
 
 type tokens_state = {
@@ -789,9 +781,46 @@ type tokens_state = {
   mutable passed :       Parser_c.token list;
   mutable passed_clean : Parser_c.token list;
 }
+let clone_tokens_stat tr = 
+  { rest = tr.rest;
+    rest_clean = tr.rest_clean;
+    current = tr.current;
+    passed = tr.passed;
+    passed_clean = tr.passed_clean;
+  }
+let copy_tokens_stat ~src ~dst = 
+  dst.rest <- src.rest;
+  dst.rest_clean <- src.rest_clean;
+  dst.current <- src.current;
+  dst.passed <- src.passed;
+  dst.passed_clean <-  src.passed_clean;
+  ()
+
+let rec filter_noise n xs =
+  match n, xs with
+  | _, [] -> []
+  | 0, xs -> xs
+  | n, x::xs -> 
+      (match x with
+      | Parser_c.TMacroAttr _ -> 
+          filter_noise (n-1) xs
+      | _ -> 
+          x::filter_noise (n-1) xs
+      )
+
+let clean_for_lookahead xs = 
+  match xs with
+  | [] -> []
+  | [x] -> [x]
+  | x::xs -> 
+      x::filter_noise 10 xs
+
 
-(* Hacked lex. This function use refs passed by parse_print_error_heuristic *)
-let rec lexer_function tr = fun lexbuf -> 
+
+(* Hacked lex. This function use refs passed by parse_print_error_heuristic 
+ * tr means token refs.
+ *)
+let rec lexer_function ~pass tr = fun lexbuf -> 
   match tr.rest with
   | [] -> pr2 "ALREADY AT END"; tr.current
   | v::xs -> 
@@ -803,7 +832,7 @@ let rec lexer_function tr = fun lexbuf ->
     if TH.is_comment v
     then begin
       tr.passed <- v::tr.passed;
-      lexer_function tr lexbuf
+      lexer_function ~pass tr lexbuf
     end
     else begin
       let x = List.hd tr.rest_clean  in
@@ -811,16 +840,22 @@ let rec lexer_function tr = fun lexbuf ->
       assert (x = v);
       
       (match v with
+      (* fix_define1. Why not in parsing_hacks lookahead and do passing like
+       * I do for some ifdef directives ? Because here I also need to 
+       * generate some tokens sometimes. 
+       *)
       | Parser_c.TDefine (tok) -> 
-          if not !LP._lexer_hint.LP.toplevel 
+          if not (LP.current_context () = LP.InTopLevel) && 
+            (!Flag_parsing_c.cpp_directive_passing || (pass = 2))
           then begin
+            incr Stat.nDefinePassing;
             pr2_once ("CPP-DEFINE: inside function, I treat it as comment");
             let v' = Parser_c.TCommentCpp (Ast_c.CppDirective,TH.info_of_tok v)
             in
             tr.passed <- v'::tr.passed;
             tr.rest       <- comment_until_defeol tr.rest;
             tr.rest_clean <- drop_until_defeol tr.rest_clean;
-            lexer_function tr lexbuf
+            lexer_function ~pass tr lexbuf
           end
           else begin
             tr.passed <- v::tr.passed;
@@ -829,12 +864,14 @@ let rec lexer_function tr = fun lexbuf ->
           end
             
       | Parser_c.TInclude (includes, filename, inifdef, info) -> 
-          if not !LP._lexer_hint.LP.toplevel 
+          if not (LP.current_context () = LP.InTopLevel)  &&
+            (!Flag_parsing_c.cpp_directive_passing || (pass = 2))
           then begin
+            incr Stat.nIncludePassing;
             pr2_once ("CPP-INCLUDE: inside function, I treat it as comment");
             let v = Parser_c.TCommentCpp(Ast_c.CppDirective, info) in
             tr.passed <- v::tr.passed;
-            lexer_function tr lexbuf
+            lexer_function ~pass tr lexbuf
           end
           else begin
             let (v,new_tokens) = 
@@ -854,21 +891,26 @@ let rec lexer_function tr = fun lexbuf ->
           (* typedef_fix1 *)
           let v = match v with
             | Parser_c.TIdent (s, ii) -> 
-                if LP.is_typedef s 
+                if 
+                  LP.is_typedef s && 
+                    not (!Flag_parsing_c.disable_add_typedef) &&
+                    pass = 1
                 then Parser_c.TypedefIdent (s, ii)
                 else Parser_c.TIdent (s, ii)
             | x -> x
           in
           
-          let v = Parsing_hacks.lookahead (v::tr.rest_clean) tr.passed_clean in
+          let v = Parsing_hacks.lookahead ~pass
+            (clean_for_lookahead (v::tr.rest_clean))
+            tr.passed_clean in
 
           tr.passed <- v::tr.passed;
           
-          (* the lookahead may have change the status of the token and
+          (* the lookahead may have changed the status of the token and
            * consider it as a comment, for instance some #include are
-           * turned into comments hence this code. *)
+           * turned into comments, hence this code. *)
           match v with
-          | Parser_c.TCommentCpp _ -> lexer_function tr lexbuf
+          | Parser_c.TCommentCpp _ -> lexer_function ~pass tr lexbuf
           | v -> 
               tr.passed_clean <- v::tr.passed_clean;
               v
@@ -877,29 +919,97 @@ let rec lexer_function tr = fun lexbuf ->
 
 
 
+let get_one_elem ~pass tr (file, filelines) = 
+
+  if not (LP.is_enabled_typedef()) && !Flag_parsing_c.debug_typedef
+  then pr2 "TYPEDEF:_handle_typedef=false. Not normal if dont come from exn";
+
+  (* normally have to do that only when come from an exception in which
+   * case the dt() may not have been done 
+   * TODO but if was in scoped scope ? have to let only the last scope
+   * so need do a LP.lexer_reset_typedef ();
+   *)
+  LP.enable_typedef();  
+  LP._lexer_hint := (LP.default_hint ());
+  LP.save_typedef_state();
+
+  tr.passed <- [];
+
+  let lexbuf_fake = Lexing.from_function (fun buf n -> raise Impossible) in
+  
+  (try 
+      (* -------------------------------------------------- *)
+      (* Call parser *)
+      (* -------------------------------------------------- *)
+      Common.profile_code_exclusif "YACC" (fun () -> 
+        Left (Parser_c.celem (lexer_function ~pass tr) lexbuf_fake)
+      )
+    with e -> begin
+      if (pass = 1 && !Flag_parsing_c.disable_two_pass)|| (pass = 2) 
+      then begin 
+        (match e with
+        (* Lexical is not anymore launched I think *)
+        | Lexer_c.Lexical s -> 
+            pr2 ("lexical error " ^s^ "\n =" ^ error_msg_tok tr.current)
+        | Parsing.Parse_error -> 
+            pr2 ("parse error \n = " ^ error_msg_tok tr.current)
+        | Semantic_c.Semantic (s, i) -> 
+            pr2 ("semantic error " ^s^ "\n ="^ error_msg_tok tr.current)
+        | e -> raise e
+        )
+      end;
+      LP.restore_typedef_state();
+
+      (* must keep here, before the code that adjusts the tr fields *)
+      let line_error = TH.line_of_tok tr.current in
+        
+        
+      (*  error recovery, go to next synchro point *)
+      let (passed', rest') = find_next_synchro tr.rest tr.passed in
+      tr.rest <- rest';
+      tr.passed <- passed';
+      
+      tr.current <- List.hd passed';
+      tr.passed_clean <- [];           (* enough ? *)
+      (* with error recovery, rest and rest_clean may not be in sync *)
+      tr.rest_clean <- (tr.rest +> List.filter TH.is_not_comment);
+      
+      
+      let info_of_bads = Common.map_eff_rev TH.info_of_tok tr.passed in 
+      Right (info_of_bads,  line_error)
+    end
+  )
+
+
+
+
 (* note: as now we go in 2 passes, there is first all the error message of
- * the lexer, and then the error of the parser. It is no more
+ * the lexer, and then the error of the parser. It is not anymore
  * interwinded.
  * 
  * !!!This function use refs, and is not reentrant !!! so take care.
  * It use globals defined in Lexer_parser and also the _defs global
- * in parsing_hack.ml.
+ * in parsing_hack.ml. 
+ * 
+ * This function uses internally some semi globals in the
+ * tokens_stat record and parsing_stat record.
  *)
 
 let parse_print_error_heuristic2 file = 
 
+  let filelines = (""::Common.cat file) +> Array.of_list in
+  let stat = Parsing_stat.default_stat file in
+
   (* -------------------------------------------------- *)
   (* call lexer and get all the tokens *)
   (* -------------------------------------------------- *)
   LP.lexer_reset_typedef(); 
-  let toks = tokens file in
+  Parsing_hacks.ifdef_paren_cnt := 0;
+  let toks_orig = tokens file in
 
-  let toks = Parsing_hacks.fix_tokens_define toks in
+  let toks = Parsing_hacks.fix_tokens_define toks_orig in
   let toks = Parsing_hacks.fix_tokens_cpp toks in
 
-  let filelines = (""::Common.cat file) +> Array.of_list in
-  let stat = default_stat file in
-
   let tr = { 
     rest       = toks;
     rest_clean = (toks +> List.filter TH.is_not_comment);
@@ -907,114 +1017,126 @@ let parse_print_error_heuristic2 file =
     passed = []; 
     passed_clean = [];
   } in
-  let lexbuf_fake = Lexing.from_function (fun buf n -> raise Impossible) in
 
-  let rec loop () =
 
-    if not (LP.is_enabled_typedef()) && !Flag_parsing_c.debug_typedef
-    then pr2 "TYPEDEF:_handle_typedef=false. Not normal if dont come from exn";
 
-    (* normally have to do that only when come from an exception in which
-     * case the dt() may not have been done 
-     * TODO but if was in scoped scope ? have to let only the last scope
-     * so need do a LP.lexer_reset_typedef ();
-     *)
-    LP.enable_typedef();  
-    LP._lexer_hint := { (LP.default_hint ()) with LP.toplevel = true; };
-    LP.save_typedef_state();
+
+  let rec loop tr =
 
     (* todo?: I am not sure that it represents current_line, cos maybe
      * tr.current partipated in the previous parsing phase, so maybe tr.current
      * is not the first token of the next parsing phase. Same with checkpoint2.
      * It would be better to record when we have a } or ; in parser.mly,
      *  cos we know that they are the last symbols of external_declaration2.
+     *
+     * bugfix: may not be equal to 'file' as after macro expansions we can
+     * start to parse a new entity from the body of a macro, for instance
+     * when parsing a define_machine() body, cf standard.h
      *)
     let checkpoint = TH.line_of_tok tr.current in
+    let checkpoint_file = TH.file_of_tok tr.current in
 
-    tr.passed <- [];
-    let was_define = ref false in
-
+    let tr_save = clone_tokens_stat tr in
+    
+    (* call the parser *)
     let elem = 
-      (try 
-          (* -------------------------------------------------- *)
-          (* Call parser *)
-          (* -------------------------------------------------- *)
-          Parser_c.celem (lexer_function tr) lexbuf_fake
-        with e -> 
-          begin
-            (match e with
-            (* Lexical is no more launched I think *)
-            | Lexer_c.Lexical s -> 
-                pr2 ("lexical error " ^s^ "\n =" ^ error_msg_tok tr.current)
-            | Parsing.Parse_error -> 
-                pr2 ("parse error \n = " ^ error_msg_tok tr.current)
-            | Semantic_c.Semantic (s, i) -> 
-                pr2 ("semantic error " ^s^ "\n ="^ error_msg_tok tr.current)
-            | e -> raise e
-            );
-            LP.restore_typedef_state();
-            let line_error = TH.line_of_tok tr.current in
-
-            (*  error recovery, go to next synchro point *)
-            let (passed', rest') = find_next_synchro tr.rest tr.passed in
-            tr.rest <- rest';
-            tr.passed <- passed';
-
-            tr.current <- List.hd passed';
-            tr.passed_clean <- [];           (* enough ? *)
-            (* with error recovery, rest and rest_clean may not be in sync *)
-            tr.rest_clean <- (tr.rest +> List.filter TH.is_not_comment);
-
-            let checkpoint2 = TH.line_of_tok tr.current in (* <> line_error *)
-
-            (* was a define ? *)
+      let pass1 = get_one_elem ~pass:1 tr (file, filelines) in
+      match pass1 with
+      | Left e -> Left e
+      | Right res -> 
+          if !Flag_parsing_c.disable_two_pass
+          then Right res
+          else begin
+            pr2 "parsing pass2: try again";
+            copy_tokens_stat ~src:tr_save ~dst: tr;
+            let pass2 = get_one_elem ~pass:2 tr (file, filelines) in
+            pass2
+          end
+    in
+
+
+    (* again not sure if checkpoint2 corresponds to end of bad region *)
+    let checkpoint2 = TH.line_of_tok tr.current in (* <> line_error *)
+    let checkpoint2_file = TH.file_of_tok tr.current in
+
+    let was_define = 
+      (match elem with
+      | Left _ -> false
+      | Right (_, line_error) -> 
+          let was_define = 
             let xs = tr.passed +> List.rev +> List.filter TH.is_not_comment in
             if List.length xs >= 2 
             then 
               (match Common.head_middle_tail xs with
               | Parser_c.TDefine _, _, Parser_c.TDefEOL _ -> 
-                  was_define := true
-              | _ -> ()
+                  true
+              | _ -> false
               )
-            else pr2 "WIERD: lenght list of error recovery tokens < 2 ";
-            
-            if !was_define && !Flag_parsing_c.filter_define_error
-            then ()
-            else print_bad line_error (checkpoint, checkpoint2) filelines;
-
+            else begin
+              pr2 "WIERD: length list of error recovery tokens < 2 ";
+              false 
+            end
+          in
+          (if was_define && !Flag_parsing_c.filter_msg_define_error
+          then ()
+          else 
+            (* bugfix: *)
+            if (checkpoint_file = checkpoint2_file) && checkpoint_file = file
+            then print_bad line_error (checkpoint, checkpoint2) filelines
+            else pr2 "PB: bad: but on tokens not from original file"
+          );
+          was_define
+      ) in
+    
 
-            let info_of_bads = Common.map_eff_rev TH.info_of_tok tr.passed in 
-            Ast_c.NotParsedCorrectly info_of_bads
-          end
-      ) 
+    let diffline = 
+      if (checkpoint_file = checkpoint2_file) && (checkpoint_file = file)
+      then (checkpoint2 - checkpoint) 
+      else 0
+        (* TODO? so if error come in middle of something ? where the
+         * start token was from original file but synchro found in body
+         * of macro ? then can have wrong number of lines stat.
+         * Maybe simpler just to look at tr.passed and count
+         * the lines in the token from the correct file ?
+         *)
     in
-
-    (* again not sure if checkpoint2 corresponds to end of bad region *)
-    let checkpoint2 = TH.line_of_tok tr.current in
-    let diffline = (checkpoint2 - checkpoint) in
     let info = mk_info_item file (List.rev tr.passed) in 
 
-    stat.commentized <- stat.commentized + count_lines_commentized (snd info);
+    (* some stat updates *)
+    stat.Stat.commentized <- 
+      stat.Stat.commentized + count_lines_commentized (snd info);
+
+    let elem = 
+      match elem with
+      | Left e -> e
+      | Right (info_of_bads, _line_error) -> 
+          Ast_c.NotParsedCorrectly info_of_bads
+    in
     (match elem with
     | Ast_c.NotParsedCorrectly xs -> 
-        if !was_define && !Flag_parsing_c.filter_define_error
-        then stat.correct <- stat.correct + diffline
-        else stat.bad     <- stat.bad     + diffline
-    | _ -> stat.correct <- stat.correct + diffline
+        if was_define && !Flag_parsing_c.filter_define_error
+        then stat.Stat.correct <- stat.Stat.correct + diffline
+        else stat.Stat.bad     <- stat.Stat.bad     + diffline
+    | _ -> stat.Stat.correct <- stat.Stat.correct + diffline
     );
 
     (match elem with
     | Ast_c.FinalDef x -> [(Ast_c.FinalDef x, info)]
-    | xs -> (xs, info):: loop () (* recurse *)
+    | xs -> (xs, info):: loop tr (* recurse *)
     )
   in
-  let v = loop() in
+  let v = loop tr in
+
   let v = consistency_checking v in
   (v, stat)
 
 
+let time_total_parsing a  = 
+  Common.profile_code "TOTAL" (fun () -> parse_print_error_heuristic2 a)
+
 let parse_print_error_heuristic a  = 
-  Common.profile_code "C parsing" (fun () -> parse_print_error_heuristic2 a)
+  Common.profile_code "C parsing" (fun () -> time_total_parsing a)
+
 
 (* alias *)
 let parse_c_and_cpp a = parse_print_error_heuristic a
@@ -1025,14 +1147,19 @@ let parse_c_and_cpp a = parse_print_error_heuristic a
 let parse_cache file = 
   if not !Flag_parsing_c.use_cache then parse_print_error_heuristic file 
   else 
+  let _ = pr2 "TOFIX" in
   let need_no_changed_files = 
     (* should use Sys.argv.(0), would be safer. *)
-    [Config.path ^ "/parsing_c/c_parser.cma";
-     (* we may also depend now on the semantic patch because 
-        the SP may use macro and so we will disable some of the
-        macro expansions from standard.h. 
-     *)
-     !Config.std_h;
+
+    [
+      (* TOFIX
+      Config.path ^ "/parsing_c/c_parser.cma";
+      (* we may also depend now on the semantic patch because 
+         the SP may use macro and so we will disable some of the
+         macro expansions from standard.h. 
+      *)
+      !Config.std_h;
+      *)
     ] 
   in
   let need_no_changed_variables = 
@@ -1047,14 +1174,27 @@ let parse_cache file =
 
 
 (*****************************************************************************)
+(* Some special cases *)
 (*****************************************************************************)
 
-(* can not be put in parsing_hack, cos then mutually recursive problem as
- * we also want to parse the standard.h file.
- *)
-let init_defs std_h =     
-  if not (Common.lfile_exists std_h)
-  then pr2 ("warning: Can't find default macro file: " ^ std_h)
-  else 
-    Parsing_hacks._defs := Common.hash_of_list (parse_cpp_define_file std_h)
-  ;
+let (cstatement_of_string: string -> Ast_c.statement) = fun s ->
+  Common.write_file ("/tmp/__cocci.c") ("void main() { \n" ^ s ^ "\n}");
+  let program = parse_c_and_cpp ("/tmp/__cocci.c") +> fst in
+  program +> Common.find_some (fun (e,_) -> 
+    match e with
+    | Ast_c.Definition ({Ast_c.f_body = [Ast_c.StmtElem st]},_) -> Some st
+    | _ -> None
+  )
+
+let (cexpression_of_string: string -> Ast_c.expression) = fun s ->
+  Common.write_file ("/tmp/__cocci.c") ("void main() { \n" ^ s ^ ";\n}");
+  let program = parse_c_and_cpp ("/tmp/__cocci.c") +> fst in
+  program +> Common.find_some (fun (e,_) -> 
+    match e with
+    | Ast_c.Definition ({Ast_c.f_body = compound},_) -> 
+        (match compound with
+        | [Ast_c.StmtElem (Ast_c.ExprStatement (Some e),ii)] -> Some e
+        | _ -> None
+        )
+    | _ -> None
+  )
index ef896b5..2287d7a 100644 (file)
@@ -1,14 +1,3 @@
-(* Copyright (C) 2002-2008 Yoann Padioleau
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License (GPL)
- * version 2 as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * file license.txt for more details.
- *)
 open Common
 
 (* The main function is parse_c_and_cpp. It uses globals in Lexer_Parser and 
@@ -16,28 +5,29 @@ open Common
  * from a standard.h macro file. Cf also init_defs below.
  *)
 
-(* the token list contains now also the comment-tokens  *)
-type info_item = (string * Parser_c.token list)
-
+(* ---------------------------------------------------------------------- *)
 type program2 = toplevel2 list
-     and toplevel2 = Ast_c.toplevel * info_item
+   and toplevel2 = Ast_c.toplevel * info_item
 
-type parsing_stat = {
-    filename: filename;
-    mutable have_timeout: bool;
-    mutable correct: int;
-    mutable bad: int;
-    mutable commentized: int;
-  } 
+    (* the token list contains now also the comment-tokens *)
+    and info_item = (string * Parser_c.token list)
 
+(* ---------------------------------------------------------------------- *)
 (* This is the main function *)
 val parse_print_error_heuristic:  
-  filename (*cfile*) -> (program2 * parsing_stat)
-val parse_c_and_cpp : (* alias of previous func *)
-  filename (*cfile*) -> (program2 * parsing_stat)
+  filename (*cfile*) -> (program2 * Parsing_stat.parsing_stat)
+(* alias of previous func *)
+val parse_c_and_cpp : 
+  filename (*cfile*) -> (program2 * Parsing_stat.parsing_stat)
 
+(* use some .ast_raw memoized version, and take care if obsolete *)
+val parse_cache:
+  filename (*cfile*) -> (program2 * Parsing_stat.parsing_stat)
+
+
+(* ---------------------------------------------------------------------- *)
 val parse_cpp_define_file : 
-  filename -> (string, Parsing_hacks.define_body) assoc
+  filename -> (string, Parsing_hacks.define_def) assoc
 
 val init_defs : filename -> unit
 
@@ -45,26 +35,36 @@ val init_defs : filename -> unit
 
 
 
-
-val tokens:      filename -> Parser_c.token list
-val tokens_string: string -> Parser_c.token list
+(* ---------------------------------------------------------------------- *)
+(* used also for the standard.h file *)
+val tokens:      ?profile:bool -> filename -> Parser_c.token list
+val tokens_of_string: string -> Parser_c.token list
 
 val parse:                        filename -> Ast_c.program
 val parse_print_error:            filename -> Ast_c.program
 val parse_gen: 
     ((Lexing.lexbuf -> Parser_c.token) -> Lexing.lexbuf -> 'a) -> string -> 'a
 
-(* easy way to build complex Ast elements from simple strings *)
+
+
+(* ---------------------------------------------------------------------- *)
+(* Easy way to build complex Ast elements from simple strings.
+ * Can also be useful when called from the ocaml toplevel to test. 
+ *)
 val type_of_string      : string -> Ast_c.fullType
 val statement_of_string : string -> Ast_c.statement
+(* similar but use parse_c_and_cpp and a /tmp/__cocci.c and extract the part *)
+val cstatement_of_string  : string -> Ast_c.statement
+val cexpression_of_string : string -> Ast_c.expression
+
 
 
-(* use some .ast_raw memoized version, and take care if obsolete *)
-val parse_cache:
-  filename (*cfile*) -> (program2 * parsing_stat)
 
+(* ---------------------------------------------------------------------- *)
+(* a few helpers *)
+val program_of_program2 : program2 -> Ast_c.program
+val with_program2: (Ast_c.program -> Ast_c.program) -> program2 -> program2
 
-val print_parsing_stat_list: parsing_stat list -> unit
 val print_commentized       : Parser_c.token list -> unit
 
 
index 6153e26..a14d178 100644 (file)
@@ -1,5 +1,5 @@
 %{
-(* Copyright (C) 2002-2008 Yoann Padioleau
+(* Copyright (C) 2002, 2006, 2007, 2008 Yoann Padioleau
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License (GPL)
@@ -19,6 +19,7 @@ open Lexer_parser (* for the fields *)
 
 open Semantic_c (* Semantic exn *)
 
+module Stat = Parsing_stat
 
 (*****************************************************************************)
 (* Wrappers *)
@@ -93,6 +94,7 @@ let addTypeD     = function
   | ((Middle3 Long,ii),   ({typeD = ((a,Some LongLong ,c),ii2)} as v)) -> 
       warning "triplicate 'long'" v
 
+
   | ((Middle3 _,ii),      ({typeD = ((a,Some _,c),ii2)} as _v)) -> 
       raise (Semantic ("both long and short specified", fake_pi))
   | ((Middle3 x,ii),      ({typeD = ((a,None,c),ii2)} as v))  -> 
@@ -227,9 +229,12 @@ let fixFunc = function
   | ((
       (s,iis), 
       (nQ, (FunctionType (fullt, (params,bool)),iifunc)), 
-      (st,iist)
+      (st,iist),
+      attrs
     ), 
-    (cp,iicp)) -> 
+    (cp,iicp)
+    ) 
+    -> 
       let iistart = Ast_c.fakeInfo () in
       assert (nQ =*= nullQualif);
       (match params with
@@ -241,7 +246,12 @@ let fixFunc = function
                 (* failwith "internal errror: fixOldCDecl not good" *)
           ));
       (* it must be nullQualif,cos parser construct only this*)
-      (s, (fullt, (params, bool)), st, cp), 
+      {f_name = s;
+       f_type = (fullt, (params, bool));
+       f_storage = st;
+       f_body = cp;
+       f_attr = attrs;
+      }, 
       ([iis]++iifunc++iicp++[iistart]++iist) 
   | _ -> 
       raise 
@@ -264,7 +274,7 @@ let et s () =
 
 
 let fix_add_params_ident = function
-  | ((s, (nQ, (FunctionType (fullt, (params, bool)),_)), st)) ->  
+  | ((s, (nQ, (FunctionType (fullt, (params, bool)),_)), st, _attrs)) ->  
 
       (match params with
       | [((reg, None, ((_qua, (BaseType Void,_)))),_), _] ->  ()
@@ -287,6 +297,8 @@ let mk_e e ii = ((e, Ast_c.noType()), ii)
 %}
 
 /*(*****************************************************************************)*/
+/*(* Tokens *)*/
+/*(*************************************************************************)*/
 
 /*
 (* 
@@ -300,63 +312,26 @@ let mk_e e ii = ((e, Ast_c.noType()), ii)
 %token <Ast_c.info> TUnknown /*(* unrecognized token *)*/
 
 /*(* coupling: Token_helpers.is_real_comment *)*/
-%token <Ast_c.info> TComment TCommentSpace TCommentNewline
-
-/*(* cppext: extra tokens *)*/
-
-%token <Ast_c.info> TDefine
-%token <(string * Ast_c.info)> TDefParamVariadic
-/*(* disappear after fix_tokens_define *)*/
-%token <Ast_c.info> TCppEscapedNewline 
-/*(* appear    after fix_tokens_define *)*/
-%token <Ast_c.info> TOParDefine        
-%token <(string * Ast_c.info)> TIdentDefine /*(* same *)*/
-%token <Ast_c.info>            TDefEOL      /*(* same *)*/
-
-/*(* used only in lexer_c, then transformed in comment or splitted in tokens *)*/
-%token <(string * string * bool ref * Ast_c.info)> TInclude
-/*(* tokens coming from above, generated in parse_c from TInclude, etc *)*/
-%token <(Ast_c.info * bool ref)> TIncludeStart
-%token <(string * Ast_c.info)> TIncludeFilename
-
-
-/*(* coupling: Token_helpers.is_cpp_instruction *)*/
-%token <Ast_c.info>          TIfdef TIfdefelse TIfdefelif TEndif
-%token <(bool * Ast_c.info)> TIfdefBool TIfdefMisc TIfdefVersion
-
-
-%token <Ast_c.info> TCommentMisc
-%token <(Ast_c.cppcommentkind * Ast_c.info)> TCommentCpp
-
-/*(* appear  after fix_tokens_cpp *)*/
-
-%token <Ast_c.info>            TMacroStmt
-/*(* no need value for the moment *)*/
-%token <Ast_c.info>            TMacroString 
-%token <(string * Ast_c.info)> TMacroDecl
-%token <Ast_c.info>            TMacroDeclConst 
-%token <(string * Ast_c.info)> TMacroIterator
-/*(* %token <(string * Ast_c.info)> TMacroTop *)*/
-/*(* appear after parsing_hack *)*/
-%token <Ast_c.info> TCParEOL   
-
-%token <Ast_c.info> TAction
-
+%token <Ast_c.info> TCommentSpace TCommentNewline   TComment
 
+/*(*-----------------------------------------*)*/
 /*(* the normal tokens *)*/
+/*(*-----------------------------------------*)*/
 
 %token <string * Ast_c.info>                     TInt
 %token <(string * Ast_c.floatType) * Ast_c.info> TFloat
 %token <(string * Ast_c.isWchar) * Ast_c.info>   TChar
 %token <(string * Ast_c.isWchar) * Ast_c.info>   TString
 
-%token <string * Ast_c.info> TIdent TypedefIdent
+%token <string * Ast_c.info> TIdent 
+/*(* appears mostly after some fix_xxx in parsing_hack *)*/
+%token <string * Ast_c.info> TypedefIdent
 
 
 /*
 (* Some tokens like TOPar and TCPar are used as synchronisation stuff, 
  * in parsing_hack.ml. So if define special tokens like TOParDefine and
- * TCParEOL, then take care to also modify in Token_helpers
+ * TCParEOL, then take care to also modify in Token_helpers.
  *)
 */
   
@@ -385,18 +360,115 @@ let mk_e e ii = ((e, Ast_c.noType()), ii)
        Tgoto Tdefault
        Tsizeof  
 
+/*(* C99 *)*/
+%token <Ast_c.info>
+       Trestrict
+
+/*(*-----------------------------------------*)*/
 /*(* gccext: extra tokens *)*/
+/*(*-----------------------------------------*)*/
 %token <Ast_c.info> Tasm
 %token <Ast_c.info> Tattribute
 %token <Ast_c.info> Tinline
 %token <Ast_c.info> Ttypeof
 
+/*(*-----------------------------------------*)*/
+/*(* cppext: extra tokens *)*/
+/*(*-----------------------------------------*)*/
+/*(* coupling with Token_helpers.is_cpp_token *)*/
+
+
+/*(*---------------*)*/
+/*(* define        *)*/
+/*(*---------------*)*/
+
+%token <Ast_c.info> TDefine
+%token <(string * Ast_c.info)> TDefParamVariadic
+
+/*(* disappear after fix_tokens_define *)*/
+%token <Ast_c.info> TCppEscapedNewline 
+
+/*(* appear    after fix_tokens_define *)*/
+%token <Ast_c.info> TOParDefine        
+%token <Ast_c.info> TOBraceDefineInit
+
+%token <(string * Ast_c.info)> TIdentDefine /*(* same *)*/
+%token <Ast_c.info>            TDefEOL      /*(* same *)*/
+
+
+/*(*---------------*)*/
+/*(* include       *)*/
+/*(*---------------*)*/
+
+
+/*(* used only in lexer_c, then transformed in comment or splitted in tokens *)*/
+%token <(string * string * bool ref * Ast_c.info)> TInclude
+
+/*(* tokens coming from above, generated in parse_c from TInclude, etc *)*/
+%token <(Ast_c.info * bool ref)> TIncludeStart
+%token <(string * Ast_c.info)> TIncludeFilename
+
+
+/*(*---------------*)*/
+/*(* ifdef         *)*/
+/*(*---------------*)*/
+
+/*(* coupling: Token_helpers.is_cpp_instruction *)*/
+%token <((int * int) option ref * Ast_c.info)> 
+  TIfdef TIfdefelse TIfdefelif TEndif
+%token <(bool * (int * int) option ref * Ast_c.info)> 
+  TIfdefBool TIfdefMisc TIfdefVersion
+
+/*(*---------------*)*/
+/*(* other         *)*/
+/*(*---------------*)*/
+
+
+%token <string * Ast_c.info> TUndef
+
+%token <Ast_c.info> TCppDirectiveOther
+
+/*(*---------------*)*/
+/*(* macro use     *)*/
+/*(*---------------*)*/
+
+/*(* appear  after fix_tokens_cpp, cf also parsing_hacks#hint *)*/
+
+%token <(string * Ast_c.info)>            TMacroAttr
+%token <(string * Ast_c.info)>            TMacroStmt
+/*(* no need value for the moment *)*/
+%token <(string * Ast_c.info)>            TMacroString 
+%token <(string * Ast_c.info)> TMacroDecl
+%token <Ast_c.info>            TMacroDeclConst 
+%token <(string * Ast_c.info)> TMacroStructDecl
+%token <(string * Ast_c.info)> TMacroIterator
+/*(* %token <(string * Ast_c.info)> TMacroTop *)*/
+
+%token <(string * Ast_c.info)>            TMacroAttrStorage
+
+
+/*(*---------------*)*/
+/*(* other         *)*/
+/*(*---------------*)*/
+
+/*(* appear after parsing_hack *)*/
+%token <Ast_c.info> TCParEOL   
+
+%token <Ast_c.info> TAction
+
+
+%token <Ast_c.info> TCommentMisc
+%token <(Ast_c.cppcommentkind * Ast_c.info)> TCommentCpp
+
 
+/*(*-----------------------------------------*)*/
 %token <Ast_c.info> EOF
 
+/*(*-----------------------------------------*)*/
+
+/*(* must be at the top so that it has the lowest priority *)*/
+%nonassoc SHIFTHERE
 
-/* operator precedence */
-%nonassoc Tif
 %nonassoc Telse
 
 %left TOrLog
@@ -410,6 +482,10 @@ let mk_e e ii = ((e, Ast_c.noType()), ii)
 %left TPlus TMinus
 %left TMul TDiv TMod 
 
+/*(*************************************************************************)*/
+/*(* Rules type declaration *)*/
+/*(*************************************************************************)*/
+
 %start main celem statement expr type_name
 %type <Ast_c.program> main
 %type <Ast_c.toplevel> celem
@@ -422,27 +498,57 @@ let mk_e e ii = ((e, Ast_c.noType()), ii)
 /*(*************************************************************************)*/
 /*
 (* TOC:
+ * toplevel (obsolete)
+ * 
+ * ident
  * expression
  * statement
- * declaration, types, initializers, struct, enum
- * xxx_list, xxx_opt
+ * types with 
+ *   - left part (type_spec, qualif), 
+ *   - right part (declarator, abstract declarator)
+ *   - aux part (parameters)
+ * declaration, storage, initializers
+ * struct
+ * enum
  * cpp directives
  * celem (=~ main)
+ * 
+ * generic workarounds (obrace, cbrace for context setting)
+ * xxx_list, xxx_opt
  *)
 */
 /*(*************************************************************************)*/
 
+/*(*************************************************************************)*/
+/*(* toplevel *)*/
+/*(*************************************************************************)*/
 /*(* no more used; now that use error recovery *)*/
 
 main:  translation_unit EOF     { $1 }
 
 translation_unit: 
  | external_declaration                  
-     { !LP._lexer_hint.toplevel <- true;   [$1] }
+     { !LP._lexer_hint.context_stack <- [LP.InTopLevel];   [$1] }
  | translation_unit external_declaration
-     { !LP._lexer_hint.toplevel <- true; $1 ++ [$2] }
+     { !LP._lexer_hint.context_stack <- [LP.InTopLevel]; $1 ++ [$2] }
+
+
+
+/*(*************************************************************************)*/
+/*(* ident *)*/
+/*(*************************************************************************)*/
+
+/*(* Why this ? Why not s/ident/TIdent ? cos there is multiple namespaces in C, 
+   * so a label can have the same name that a typedef, same for field and tags
+   * hence sometimes the use of ident  instead of TIdent.
+   *)*/
+ident: 
+ | TIdent       { $1 }
+ | TypedefIdent { $1 }
 
 
+identifier:
+ | TIdent       { $1 }
 
 /*(*************************************************************************)*/
 /*(* expr *)*/
@@ -537,14 +643,15 @@ postfix_expr:
      { mk_e(Constructor ($2, List.rev $5)) ([$1;$3;$4;$7] ++ $6) }
 
 primary_expr: 
- | TIdent  { mk_e(Ident  (fst $1)) [snd $1] }
+ | identifier  { mk_e(Ident  (fst $1)) [snd $1] }
  | TInt    { mk_e(Constant (Int    (fst $1))) [snd $1] }
  | TFloat  { mk_e(Constant (Float  (fst $1))) [snd $1] }
  | TString { mk_e(Constant (String (fst $1))) [snd $1] }
  | TChar   { mk_e(Constant (Char   (fst $1))) [snd $1] }
  | TOPar expr TCPar { mk_e(ParenExpr ($2)) [$1;$3] }  /*(* forunparser: *)*/
 
- /*(* gccext: cppext: *)*/
+ /*(* gccext: cppext: TODO better ast ? *)*/
+ | TMacroString { mk_e(Constant (MultiString)) [snd $1] }
  | string_elem string_list { mk_e(Constant (MultiString)) ($1 ++ $2) }
 
  /*(* gccext: allow statement as expressions via ({ statement }) *)*/
@@ -552,16 +659,22 @@ primary_expr:
 
 
 
+/*(*----------------------------*)*/
+/*(* cppext: *)*/
+/*(*----------------------------*)*/
 
 /*(* cppext: *)*/
+/*(* to avoid conflicts have to introduce a _not_empty (ne) version *)*/
 argument_ne: 
  | assign_expr { Left $1 }
  | parameter_decl { Right (ArgType $1)  }
  | action_higherordermacro_ne { Right (ArgAction $1) }
 
+
 argument: 
  | assign_expr { Left $1 }
  | parameter_decl { Right (ArgType $1)  }
+ /*(* had conflicts before, but julia fixed them *)*/
  | action_higherordermacro { Right (ArgAction $1) }
 
 action_higherordermacro_ne: 
@@ -571,6 +684,7 @@ action_higherordermacro_ne:
        else ActMisc $1
      }
 
+
 action_higherordermacro: 
  | taction_list 
      { if null $1
@@ -583,17 +697,6 @@ action_higherordermacro:
 /*(* workarounds *)*/
 /*(*----------------------------*)*/
 
-/*(* Why this ? Why not s/ident/TIdent ? cos there is multiple namespaces in C, 
-   * so a label can have the same name that a typedef, same for field and tags
-   * hence sometimes the use of ident  instead of TIdent.
-   *)*/
-ident: 
- | TIdent       { $1 }
- | TypedefIdent { $1 }
-
-identifier:
- | TIdent       { $1 }
-
 /*(* would like evalInt $1 but require too much info *)*/
 const_expr: cond_expr { $1  }
 
@@ -620,8 +723,7 @@ statement:
  | Tasm Tvolatile TOPar asmbody TCPar TPtVirg   { Asm $4, [$1;$2;$3;$5;$6] }
 
  /*(* cppext: *)*/
- | TMacroStmt { MacroStmt, [$1] }
- | TMacroStmt TPtVirg { MacroStmt, [$1;$2] }
+ | TMacroStmt { MacroStmt, [snd $1] }
 
 
 
@@ -638,8 +740,10 @@ labeled:
 
 end_labeled: 
  /*(* gccext:  allow toto: }
-    * generate each 30 shift/Reduce conflicts,  mais ca va, ca fait ce qu'il
-    * faut
+    * was generating each 30 shift/Reduce conflicts,
+    * mais ca va, ca fait ce qu'il faut.
+    * update: julia fixed the problem by introducing end_labeled 
+    * and modifying below stat_or_decl_list
     *)*/
  | ident            TDotDot 
      { Label (fst $1, (ExprStatement None, [])), [snd $1; $2] }
@@ -652,19 +756,6 @@ end_labeled:
 
 compound: tobrace compound2 tcbrace { $2, [$1; $3]  }
 
-tobrace:  TOBrace                    {  LP.new_scope (); $1 }
-tcbrace:  TCBrace                    {  LP.del_scope (); $1 }
-
-/*(* old:
-compound2: 
- |                            { ([],[]) }
- |  statement_list            { ([], $1) }
- |  decl_list                 { ($1, []) }
- |  decl_list statement_list  { ($1,$2) }
-
-statement_list: stat_or_decl_list { $1 }
-*)*/
-
 
 /*
 (* cppext: because of cpp, some stuff looks like declaration but are in
@@ -678,19 +769,26 @@ compound2:
  |                   { ([]) }
  | stat_or_decl_list { $1 }
 
-stat_or_decl: 
- | decl      { Decl ($1 Ast_c.LocalDecl), [] }
- | statement { $1 }
 
-  /*(* cppext: if -ifdef_to_if is enabled for parsing_hack *)*/
- | TIfdef stat_or_decl_list TIfdefelse stat_or_decl_list TEndif 
-     { Selection (Ifdef ($2, $4)), [$1;$3;$5;fakeInfo()] }
- | TIfdef stat_or_decl_list TEndif 
-     { Selection (Ifdef ($2, [])), [$1;$3;fakeInfo()] }
+stat_or_decl_list: 
+ | stat_or_decl                   { [$1] }                          
+ /*(* gccext: to avoid conflicts, cf end_labeled above *)*/
+ | end_labeled  { [StmtElem (Labeled      (fst $1), snd $1)] }
+ /*(* old: conflicts | stat_or_decl_list stat_or_decl { $1 ++ [$2] } *)*/
+ | stat_or_decl stat_or_decl_list { $1 :: $2 }
+
+stat_or_decl: 
+ | decl      { StmtElem (Decl ($1 Ast_c.LocalDecl), []) }
+ | statement { StmtElem $1 }
 
   /*(* gccext: *)*/
- | function_definition { NestedFunc $1, [] }
+ | function_definition { StmtElem (NestedFunc $1, []) }
 
+ /* (* cppext: *)*/
+ | cpp_directive 
+     { CppDirectiveStmt $1 }
+ | cpp_ifdef_directive/*(* stat_or_decl_list ...*)*/  
+     { IfdefStmt $1 }
 
 
 
@@ -701,7 +799,7 @@ expr_statement:
  | expr TPtVirg { Some $1, [$2] }
 
 selection: 
- | Tif TOPar expr TCPar statement %prec Tif           
+ | Tif TOPar expr TCPar statement              %prec SHIFTHERE
      { If ($3, $5, (ExprStatement None, [])),   [$1;$2;$4] }
  | Tif TOPar expr TCPar statement Telse statement 
      { If ($3, $5, $7),  [$1;$2;$4;$6] }
@@ -717,12 +815,12 @@ iteration:
      { For ($3,$4,(None, []),$6),    [$1;$2;$5]}
  | Tfor TOPar expr_statement expr_statement expr TCPar statement
      { For ($3,$4,(Some $5, []),$7), [$1;$2;$6] }
-/*(* c++ext: for(int i = 0; i < n; i++)
- | Tfor TOPar decl expr_statement expr TCPar statement
-     { pr2 "DECL in for";
-       While ($5, $7), [] (* fake ast *)
+ /*(* c++ext: for(int i = 0; i < n; i++)*)*/
+ | Tfor TOPar decl expr_statement expr_opt TCPar statement
+     { 
+       (* pr2 "DECL in for"; *)
+       MacroIteration ("toto", [], $7),[] (* TODOfake ast, TODO need decl2 ? *)
      }
-*)*/
  /*(* cppext: *)*/
  | TMacroIterator TOPar argument_list_ne TCPar statement
      { MacroIteration (fst $1, $3, $5), [snd $1;$2;$4] }
@@ -746,7 +844,7 @@ jump:
 string_elem:
  | TString { [snd $1] }
  /*(* cppext:  ex= printk (KERN_INFO "xxx" UTS_RELEASE)  *)*/
- | TMacroString { [$1] }
+ | TMacroString { [snd $1] }
 
 
 asmbody: 
@@ -767,74 +865,14 @@ colon_option:
 
 asm_expr: assign_expr { $1 }
 
-       
-
 /*(*************************************************************************)*/
-/*(* declaration, types, initializers *)*/
+/*(* types *)*/
 /*(*************************************************************************)*/
+       
 
-decl2: 
- | decl_spec TPtVirg
-     { function local ->
-       let (returnType,storage) = fixDeclSpecForDecl $1 in 
-       let iistart = Ast_c.fakeInfo () in
-       DeclList ([(None, returnType, unwrap storage, local),[]],  
-                ($2::iistart::snd storage))
-     } 
- | decl_spec init_declarator_list TPtVirg 
-     { function local ->
-       let (returnType,storage) = fixDeclSpecForDecl $1 in
-       let iistart = Ast_c.fakeInfo () in
-       DeclList (
-         ($2 +> List.map (fun ((((s,iis),f), ini), iivirg) -> 
-           let ini, iini = 
-             match ini with
-             | None -> None, []
-             | Some (ini, iini) -> Some ini, [iini]
-           in
-          if fst (unwrap storage) = StoTypedef 
-          then LP.add_typedef s;
-           (Some ((s, ini), iis::iini), f returnType, unwrap storage, local),
-           iivirg 
-         )
-         ),  ($3::iistart::snd storage))
-     } 
- /*(* cppext: *)*/
-
- | TMacroDecl TOPar argument_list TCPar TPtVirg 
-     { function _ ->
-       MacroDecl ((fst $1, $3), [snd $1;$2;$4;$5;fakeInfo()]) }
- | Tstatic TMacroDecl TOPar argument_list TCPar TPtVirg 
-     { function _ ->
-       MacroDecl ((fst $2, $4), [snd $2;$3;$5;$6;fakeInfo();$1]) }
- | Tstatic TMacroDeclConst TMacroDecl TOPar argument_list TCPar TPtVirg 
-     { function _ ->
-       MacroDecl ((fst $3, $5), [snd $3;$4;$6;$7;fakeInfo();$1;$2])}
-
-
-
-decl_spec2: 
- | storage_class_spec      { {nullDecl with storageD = (fst $1, [snd $1]) } }
- | type_spec               { addTypeD ($1,nullDecl) }
- | type_qualif             { {nullDecl with qualifD  = (fst $1, [snd $1]) } }
- | Tinline                 { {nullDecl with inlineD = (true, [$1]) } }
- | storage_class_spec decl_spec2 { addStorageD ($1, $2) }
- | type_spec          decl_spec2 { addTypeD    ($1, $2) }
- | type_qualif        decl_spec2 { addQualifD  ($1, $2) }
- | Tinline            decl_spec2 { addInlineD ((true, $1), $2) }
-
-/*(* can simplify by putting all in _opt ? must have at least one otherwise
-   *  decl_list is ambiguous ? (no cos have ';' between decl) 
-   *)*/
-
-
-storage_class_spec: 
- | Tstatic      { Sto Static,  $1 }
- | Textern      { Sto Extern,  $1 }
- | Tauto        { Sto Auto,    $1 }
- | Tregister    { Sto Register,$1 }
- | Ttypedef     { StoTypedef,  $1 }
-
+/*(*-----------------------------------------------------------------------*)*/
+/*(* Type spec, left part of a type *)*/
+/*(*-----------------------------------------------------------------------*)*/
 type_spec2: 
  | Tvoid                { Right3 (BaseType Void),            [$1] }
  | Tchar                { Right3 (BaseType (IntType CChar)), [$1]}
@@ -866,73 +904,43 @@ type_spec2:
  | Ttypeof TOPar assign_expr TCPar { Right3 (TypeOfExpr ($3)), [$1;$2;$4] }
  | Ttypeof TOPar type_name   TCPar { Right3 (TypeOfType ($3)), [$1;$2;$4] }
 
-
-type_qualif: 
- | Tconst    { {const=true  ; volatile=false}, $1 }
- | Tvolatile { {const=false ; volatile=true},  $1 }
-
-
-
 /*(*----------------------------*)*/
 /*(* workarounds *)*/
 /*(*----------------------------*)*/
 
-decl:      decl2         { et "decl" (); $1 }
-decl_spec: decl_spec2    { dt "declspec" (); $1  }
 type_spec: type_spec2    { dt "type" (); $1   }
 
+/*(*-----------------------------------------------------------------------*)*/
+/*(* Qualifiers *)*/
+/*(*-----------------------------------------------------------------------*)*/
 
-
-
+type_qualif: 
+ | Tconst    { {const=true  ; volatile=false}, $1 }
+ | Tvolatile { {const=false ; volatile=true},  $1 }
+ /*(* C99 *)*/
+ | Trestrict { (* TODO *) {const=false ; volatile=false},  $1 }
 
 
 /*(*-----------------------------------------------------------------------*)*/
-/*(* for struct and also typename *)*/
-/*(* cant put decl_spec cos no storage is allowed for field struct *)*/
-spec_qualif_list2: 
- | type_spec                    { addTypeD ($1, nullDecl) }
- | type_qualif                  { {nullDecl with qualifD = (fst $1,[snd $1])}}
- | type_spec   spec_qualif_list { addTypeD ($1,$2)   }
- | type_qualif spec_qualif_list { addQualifD ($1,$2) }
-
-spec_qualif_list: spec_qualif_list2            {  dt "spec_qualif" (); $1 }
-            
+/*(* gccext: attributes  *)*/
 /*(*-----------------------------------------------------------------------*)*/
-init_declarator: init_declarator2  { dt "init" (); $1 }
-
-init_declarator2:  
- | declaratori                  { ($1, None) }
- | declaratori teq initialize   { ($1, Some ($3, $2)) }
 
+attribute:
+ | Tattribute TOPar /*stuff*/ TCPar { raise Todo }
+ /*(* cppext: *)*/
+ | TMacroAttr { Attribute (fst $1), [snd $1] }
 
 
-/*(*----------------------------*)*/
-/*(* workarounds *)*/
-/*(*----------------------------*)*/
-declaratori: 
- | declarator
-     { LP.add_ident (fst (fst $1)); $1 }
- /*(* gccext: *)*/
- | declarator gcc_asm_decl     
-     { LP.add_ident (fst (fst $1)); $1 }
+attribute_storage:
+ | TMacroAttrStorage { $1 }
 
-teq: TEq  { et "teq" (); $1 }
+type_qualif_attr:
+ | type_qualif { $1 }
+ | TMacroAttr { {const=false  ; volatile=false}, snd $1 (*TODO*)  }
 
-
-
-/*(*----------------------------*)*/
-/*(* gccext: *)*/
-/*(*----------------------------*)*/
-
-gcc_asm_decl: 
- | Tasm TOPar asmbody TCPar              {  }
- | Tasm Tvolatile TOPar asmbody TCPar   {  }
-
-
-
-
-
-/*(*-----------------------------------------------------------------------*)*/
+/*(*-----------------------------------------------------------------------*)*/
+/*(* Declarator, right part of a type + second part of decl (the ident)  *)*/
+/*(*-----------------------------------------------------------------------*)*/
 
 /*
 (* declarator return a couple: 
@@ -953,12 +961,9 @@ pointer:
  | TMul pointer                  { fun x ->(nQ,         (Pointer ($2 x),[$1]))}
  | TMul type_qualif_list pointer { fun x ->($2.qualifD, (Pointer ($3 x),[$1]))}
 
-type_qualif_list: 
- | type_qualif                  { {nullDecl with qualifD = (fst $1,[snd $1])} }
- | type_qualif_list type_qualif { addQualifD ($2,$1) }
 
 direct_d: 
- | identifier                                  
+ | identifier
      { ($1, fun x -> x) }
  | TOPar declarator TCPar      /*(* forunparser: old: $2 *)*/ 
      { (fst $2, fun x -> (nQ, (ParenType ((snd $2) x), [$1;$3]))) }
@@ -975,6 +980,43 @@ direct_d:
      { (fst $1,fun x->(snd $1) (nQ,(FunctionType (x, $3),   [$2;$4]))) }
 
 
+/*(*----------------------------*)*/
+/*(* workarounds *)*/
+/*(*----------------------------*)*/
+
+tocro: TOCro { et "tocro" ();$1 }
+tccro: TCCro { dt "tccro" ();$1 }
+
+/*(*-----------------------------------------------------------------------*)*/
+abstract_declarator: 
+ | pointer                            { $1 }
+ |         direct_abstract_declarator { $1 }
+ | pointer direct_abstract_declarator { fun x -> x +> $2 +> $1 }
+
+direct_abstract_declarator: 
+ | TOPar abstract_declarator TCPar /*(* forunparser: old: $2 *)*/
+     { (fun x -> (nQ, (ParenType ($2 x), [$1;$3]))) }
+
+ | TOCro            TCCro                            
+     { fun x ->   (nQ, (Array (None, x),      [$1;$2]))}
+ | TOCro const_expr TCCro                            
+     { fun x ->   (nQ, (Array (Some $2, x),   [$1;$3]))}
+ | direct_abstract_declarator TOCro            TCCro 
+     { fun x ->$1 (nQ, (Array (None, x),      [$2;$3])) }
+ | direct_abstract_declarator TOCro const_expr TCCro
+     { fun x ->$1 (nQ, (Array (Some $3,x),    [$2;$4])) }
+ | TOPar TCPar                                       
+     { fun x ->   (nQ, (FunctionType (x, ([], (false,  []))),   [$1;$2])) }
+ | TOPar parameter_type_list TCPar
+     { fun x ->   (nQ, (FunctionType (x, $2),           [$1;$3]))}
+ | direct_abstract_declarator TOPar TCPar
+     { fun x ->$1 (nQ, (FunctionType (x, (([], (false, [])))),[$2;$3])) }
+ | direct_abstract_declarator TOPar parameter_type_list TCPar
+     { fun x -> $1 (nQ, (FunctionType (x, $3), [$2;$4])) }
+
+/*(*-----------------------------------------------------------------------*)*/
+/*(* Parameters (use decl_spec not type_spec just for 'register') *)*/
+/*(*-----------------------------------------------------------------------*)*/
 parameter_type_list: 
  | parameter_list                  { ($1, (false, []))}
  | parameter_list TComma TEllipsis { ($1, (true,  [$2;$3])) }
@@ -987,7 +1029,7 @@ parameter_decl2:
        (hasreg, Some (fst (fst $2)), ((snd $2) returnType)),    
         (iihasreg ++ [snd (fst $2)]) 
      }
- | decl_spec abstract_declarator
+ | decl_spec abstract_declaratorp
      { let ((returnType,hasreg), iihasreg) = fixDeclSpecForParam $1 
        in (hasreg, None, ($2 returnType)),      (iihasreg ++ []) 
      }
@@ -1001,65 +1043,193 @@ parameter_decl2:
 /*(* workarounds *)*/
 /*(*----------------------------*)*/
 
-tocro: TOCro { et "tocro" ();$1 }
-tccro: TCCro { dt "tccro" ();$1 }
+parameter_decl: parameter_decl2 { et "param" ();  $1 }
 
-topar: TOPar 
-     { LP.new_scope ();et "topar" (); 
-       !LP._lexer_hint.parameterDeclaration <- true; $1  
-     }
-tcpar: TCPar 
-     { LP.del_scope ();dt "tcpar" (); 
-       !LP._lexer_hint.parameterDeclaration <- false; $1  
-     }
+declaratorp: 
+ | declarator  { LP.add_ident (fst (fst $1)); $1 }
+ /*(* gccext: *)*/
+ | attributes declarator   { LP.add_ident (fst (fst $2)); $2 }
+ | declarator attributes   { LP.add_ident (fst (fst $1)); $1 }
 
-parameter_decl: parameter_decl2 { et "param" ();  $1 }
+abstract_declaratorp:
+ | abstract_declarator { $1 }
+ /*(* gccext: *)*/
+ | attributes abstract_declarator { $2 }
+
+/*(*-----------------------------------------------------------------------*)*/
+/*(* helper type rules *)*/
+/*(*-----------------------------------------------------------------------*)*/
+
+/*(* for struct and also typename *)*/
+/*(* cant put decl_spec cos no storage is allowed for field struct *)*/
+spec_qualif_list2: 
+ | type_spec                    { addTypeD ($1, nullDecl) }
+ | type_qualif                  { {nullDecl with qualifD = (fst $1,[snd $1])}}
+ | type_spec   spec_qualif_list { addTypeD ($1,$2)   }
+ | type_qualif spec_qualif_list { addQualifD ($1,$2) }
+
+spec_qualif_list: spec_qualif_list2            {  dt "spec_qualif" (); $1 }
+
+
+/*(* for pointers in direct_declarator and abstract_declarator *)*/
+type_qualif_list: 
+ | type_qualif_attr                  { {nullDecl with qualifD = (fst $1,[snd $1])} }
+ | type_qualif_list type_qualif_attr { addQualifD ($2,$1) }
 
-declaratorp: declarator 
-     { LP.add_ident (fst (fst $1)); $1 }
 
 
+
+            
+
+/*(*-----------------------------------------------------------------------*)*/
+/*(* xxx_type_id *)*/
 /*(*-----------------------------------------------------------------------*)*/
+
 type_name: 
  | spec_qualif_list                     
      { let (returnType, _) = fixDeclSpecForDecl $1 in  returnType }
- | spec_qualif_list abstract_declarator 
+ | spec_qualif_list abstract_declaratort
      { let (returnType, _) = fixDeclSpecForDecl $1 in $2 returnType }
 
 
-abstract_declarator: 
- | pointer                            { $1 }
- |         direct_abstract_declarator { $1 }
- | pointer direct_abstract_declarator { fun x -> x +> $2 +> $1 }
 
-direct_abstract_declarator: 
- | TOPar abstract_declarator TCPar /*(* forunparser: old: $2 *)*/
-     { (fun x -> (nQ, (ParenType ($2 x), [$1;$3]))) }
+abstract_declaratort: 
+ | abstract_declarator { $1 }
+ /*(* gccext: *)*/
+ | attributes abstract_declarator { $2 }
+
+
+/*(*************************************************************************)*/
+/*(* declaration and initializers *)*/
+/*(*************************************************************************)*/
+
+decl2: 
+ | decl_spec TPtVirg
+     { function local ->
+       let (returnType,storage) = fixDeclSpecForDecl $1 in 
+       let iistart = Ast_c.fakeInfo () in
+       DeclList ([{v_namei = None; v_type = returnType; 
+                   v_storage = unwrap storage; v_local = local;
+                   v_attr = Ast_c.noattr;
+                },[]],  
+                ($2::iistart::snd storage))
+     } 
+ | decl_spec init_declarator_list TPtVirg 
+     { function local ->
+       let (returnType,storage) = fixDeclSpecForDecl $1 in
+       let iistart = Ast_c.fakeInfo () in
+       DeclList (
+         ($2 +> List.map (fun (((((s,iis),f),attrs), ini), iivirg) -> 
+           let ini, iini = 
+             match ini with
+             | None -> None, []
+             | Some (ini, iini) -> Some ini, [iini]
+           in
+          if fst (unwrap storage) = StoTypedef 
+          then LP.add_typedef s;
+           {v_namei = Some ((s, ini), iis::iini);
+            v_type = f returnType;
+            v_storage = unwrap storage;
+            v_local = local;
+            v_attr = attrs;
+           },
+           iivirg 
+         )
+         ),  ($3::iistart::snd storage))
+     } 
+ /*(* cppext: *)*/
+
+ | TMacroDecl TOPar argument_list TCPar TPtVirg 
+     { function _ ->
+       MacroDecl ((fst $1, $3), [snd $1;$2;$4;$5;fakeInfo()]) }
+ | Tstatic TMacroDecl TOPar argument_list TCPar TPtVirg 
+     { function _ ->
+       MacroDecl ((fst $2, $4), [snd $2;$3;$5;$6;fakeInfo();$1]) }
+ | Tstatic TMacroDeclConst TMacroDecl TOPar argument_list TCPar TPtVirg 
+     { function _ ->
+       MacroDecl ((fst $3, $5), [snd $3;$4;$6;$7;fakeInfo();$1;$2])}
+
+
+/*(*-----------------------------------------------------------------------*)*/
+decl_spec2: 
+ | storage_class_spec      { {nullDecl with storageD = (fst $1, [snd $1]) } }
+ | type_spec               { addTypeD ($1,nullDecl) }
+ | type_qualif             { {nullDecl with qualifD  = (fst $1, [snd $1]) } }
+ | Tinline                 { {nullDecl with inlineD = (true, [$1]) } }
+ | storage_class_spec decl_spec2 { addStorageD ($1, $2) }
+ | type_spec          decl_spec2 { addTypeD    ($1, $2) }
+ | type_qualif        decl_spec2 { addQualifD  ($1, $2) }
+ | Tinline            decl_spec2 { addInlineD ((true, $1), $2) }
+
+/*(* can simplify by putting all in _opt ? must have at least one otherwise
+   *  decl_list is ambiguous ? (no cos have ';' between decl) 
+   *)*/
+
+
+storage_class_spec2: 
+ | Tstatic      { Sto Static,  $1 }
+ | Textern      { Sto Extern,  $1 }
+ | Tauto        { Sto Auto,    $1 }
+ | Tregister    { Sto Register,$1 }
+ | Ttypedef     { StoTypedef,  $1 }
+
+storage_class_spec:
+ /*(* gccext: *)*/
+ | storage_class_spec2 { $1 }
+ | storage_class_spec2 attributes_storage { $1 (* TODO *) }
+
+
+
+/*(*----------------------------*)*/
+/*(* workarounds *)*/
+/*(*----------------------------*)*/
+
+decl:      decl2         { et "decl" (); $1 }
+decl_spec: decl_spec2    { dt "declspec" (); $1  }
+
+/*(*-----------------------------------------------------------------------*)*/
+/*(* declarators (right part of type and variable) *)*/
+/*(*-----------------------------------------------------------------------*)*/
+init_declarator2:  
+ | declaratori                  { ($1, None) }
+ | declaratori teq initialize   { ($1, Some ($3, $2)) }
+
+
+
+/*(*----------------------------*)*/
+/*(* workarounds *)*/
+/*(*----------------------------*)*/
+teq: TEq  { et "teq" (); $1 }
+
+init_declarator: init_declarator2  { dt "init" (); $1 }
+
+
+/*(*----------------------------*)*/
+/*(* gccext: *)*/
+/*(*----------------------------*)*/
+
+declaratori: 
+ | declarator              { LP.add_ident (fst (fst $1)); $1, Ast_c.noattr }
+ /*(* gccext: *)*/
+ | declarator gcc_asm_decl { LP.add_ident (fst (fst $1)); $1, Ast_c.noattr }
+ /*(* gccext: *)*/
+ | attributes declarator   { LP.add_ident (fst (fst $2)); $2, $1 }
+ | declarator attributes   { LP.add_ident (fst (fst $1)); $1, Ast_c.noattr (* TODO *) }
+
+
+
+gcc_asm_decl: 
+ | Tasm TOPar asmbody TCPar              {  }
+ | Tasm Tvolatile TOPar asmbody TCPar   {  }
+
 
- | TOCro            TCCro                            
-     { fun x ->   (nQ, (Array (None, x),      [$1;$2]))}
- | TOCro const_expr TCCro                            
-     { fun x ->   (nQ, (Array (Some $2, x),   [$1;$3]))}
- | direct_abstract_declarator TOCro            TCCro 
-     { fun x ->$1 (nQ, (Array (None, x),      [$2;$3])) }
- | direct_abstract_declarator TOCro const_expr TCCro
-     { fun x ->$1 (nQ, (Array (Some $3,x),    [$2;$4])) }
- | TOPar TCPar                                       
-     { fun x ->   (nQ, (FunctionType (x, ([], (false,  []))),   [$1;$2])) }
- | TOPar parameter_type_list TCPar
-     { fun x ->   (nQ, (FunctionType (x, $2),           [$1;$3]))}
- | direct_abstract_declarator TOPar TCPar
-     { fun x ->$1 (nQ, (FunctionType (x, (([], (false, [])))),[$2;$3])) }
- | direct_abstract_declarator TOPar parameter_type_list TCPar
-     { fun x -> $1 (nQ, (FunctionType (x, $3), [$2;$4])) }
-                         
 /*(*-----------------------------------------------------------------------*)*/
 initialize: 
  | assign_expr                                    
      { InitExpr $1,                [] }
- | tobrace_ini initialize_list gcc_comma_opt_struct  TCBrace
+ | tobrace_ini initialize_list gcc_comma_opt_struct  tcbrace_ini
      { InitList (List.rev $2),     [$1;$4]++$3 }
- | tobrace_ini TCBrace
+ | tobrace_ini tcbrace_ini
      { InitList [],       [$1;$2] } /*(* gccext: *)*/
 
 
@@ -1079,9 +1249,9 @@ initialize_list:
 initialize2: 
  | cond_expr 
      { InitExpr $1,   [] } 
- | tobrace_ini initialize_list gcc_comma_opt_struct TCBrace
+ | tobrace_ini initialize_list gcc_comma_opt_struct tcbrace_ini
      { InitList (List.rev $2),   [$1;$4]++$3 }
- | tobrace_ini TCBrace
+ | tobrace_ini tcbrace_ini
      { InitList [],  [$1;$2]  }
 
  /*(* gccext: labeled elements, a.k.a designators *)*/
@@ -1091,8 +1261,12 @@ initialize2:
  /*(* gccext: old format *)*/
  | ident TDotDot initialize2
      { InitFieldOld (fst $1, $3),     [snd $1; $2] } /*(* in old kernel *)*/
+/* conflict 
  | TOCro const_expr TCCro initialize2
      { InitIndexOld ($2, $4),    [$1;$3] }
+*/
+
+
 
 /*(* they can be nested, can have a .x.[3].y *)*/
 designator: 
@@ -1113,14 +1287,16 @@ gcc_comma_opt_struct:
  | /*(* empty *)*/  {  [Ast_c.fakeInfo() +> Ast_c.rewrap_str ","]  }
 
 
-tobrace_ini: TOBrace { !LP._lexer_hint.toplevel <- false; $1 }
 
 
 
 
 
 
-/*(*-----------------------------------------------------------------------*)*/
+/*(*************************************************************************)*/
+/*(* struct *)*/
+/*(*************************************************************************)*/
+
 s_or_u_spec2: 
  | struct_or_union ident tobrace_struct struct_decl_list_gcc tcbrace_struct
      { StructUnion (fst $1, Some (fst $2), $4),  [snd $1;snd $2;$3;$5]  }
@@ -1132,10 +1308,25 @@ s_or_u_spec2:
 struct_or_union2: 
  | Tstruct   { Struct, $1 }
  | Tunion    { Union, $1 }
+ /*(* gccext: *)*/
+ | Tstruct attributes   { Struct, $1 (* TODO *) }
+ | Tunion  attributes   { Union, $1  (* TODO *) }
 
 
 
 struct_decl2: 
+ | field_declaration { DeclarationField $1, noii }
+ | TPtVirg { EmptyField, [$1]  }
+ | TMacroStructDecl { MacroStructDeclTodo, [] }
+
+ /*(* cppext: *)*/
+ | cpp_directive 
+     { CppDirectiveStruct $1, noii }
+ | cpp_ifdef_directive/*(* struct_decl_list ... *)*/ 
+     { IfdefStruct $1, noii }
+
+
+field_declaration:
  | spec_qualif_list struct_declarator_list TPtVirg 
      { 
        let (returnType,storage) = fixDeclSpecForDecl $1 in
@@ -1144,13 +1335,12 @@ struct_decl2:
        
        FieldDeclList ($2 +> (List.map (fun (f, iivirg) ->     
          f returnType, iivirg))
-       ),    [$3]
+                         ,[$3])
          (* dont need to check if typedef or func initialised cos
           * grammar dont allow typedef nor initialiser in struct 
           *)
      }
 
-
  |  spec_qualif_list TPtVirg 
      { 
        (* gccext: allow empty elements if it is a structdef or enumdef *)
@@ -1158,9 +1348,10 @@ struct_decl2:
        if fst (unwrap storage) <> NoSto 
        then internal_error "parsing dont allow this";
        
-       FieldDeclList [(Simple (None, returnType), []) , []], [$2]
+       FieldDeclList ([(Simple (None, returnType), []) , []], [$2])
      }
- | TPtVirg { EmptyField, [$1]  }
+
+
 
 
 
@@ -1180,19 +1371,12 @@ struct_declarator:
 /*(*----------------------------*)*/
 /*(* workarounds *)*/
 /*(*----------------------------*)*/
-tobrace_struct: TOBrace 
-     { !LP._lexer_hint.toplevel <- false; 
-       !LP._lexer_hint.structDefinition <- !LP._lexer_hint.structDefinition +1;
-       $1 
-     }
-tcbrace_struct: TCBrace 
-     {
-       !LP._lexer_hint.structDefinition <- !LP._lexer_hint.structDefinition -1;
-       $1
-     }
+declaratorsd: 
+ | declarator { (*also ? LP.add_ident (fst (fst $1)); *) $1 }
+ /*(* gccext: *)*/
+ | attributes declarator   { $2 }
+ | declarator attributes   { $1 }
 
-declaratorsd: declarator 
-  { (*also ? LP.add_ident (fst (fst $1)); *) $1 }
 
 
 
@@ -1208,11 +1392,13 @@ struct_decl_list_gcc:
  | /*(* empty *)*/       { [] } /*(* gccext: allow empty struct *)*/
 
 
-/*(*-----------------------------------------------------------------------*)*/
+/*(*************************************************************************)*/
+/*(* enum *)*/
+/*(*************************************************************************)*/
 enum_spec: 
- | Tenum        tobrace_enum enumerator_list gcc_comma_opt TCBrace 
+ | Tenum        tobrace_enum enumerator_list gcc_comma_opt tcbrace_enum
      { Enum (None,    $3),           [$1;$2;$5] ++ $4 }
- | Tenum ident  tobrace_enum enumerator_list gcc_comma_opt TCBrace
+ | Tenum ident  tobrace_enum enumerator_list gcc_comma_opt tcbrace_enum
      { Enum (Some (fst $2), $4),     [$1; snd $2; $3;$6] ++ $5 }
  | Tenum ident                                                
      { EnumName (fst $2),       [$1; snd $2] }
@@ -1229,29 +1415,287 @@ enumerator:
 
 idente: ident { LP.add_ident (fst $1); $1 }
 
-tobrace_enum: TOBrace { !LP._lexer_hint.toplevel <- false; $1 }
-
 
 
 /*(*************************************************************************)*/
-/*(* xxx_list, xxx_opt *)*/
+/*(* function *)*/
 /*(*************************************************************************)*/
+function_definition: function_def    { fixFunc $1 }
 
-
-/*(*
 decl_list: 
  | decl           { [$1]   }
  | decl_list decl { $1 ++ [$2] }
 
-statement_list: 
- | statement { [$1] }
- | statement_list statement { $1 ++ [$2] }
-*)*/
+function_def: 
+ | start_fun compound      { LP.del_scope(); ($1, $2) }
+ | start_fun decl_list compound      { 
+     pr2 "OLD STYLE DECL NOT WELL SUPPORTED";
+     (* TODO: undo the typedef added ? *)
+     LP.del_scope(); 
+     ($1, $3) 
+   }
+
+start_fun: start_fun2                        
+  { LP.new_scope(); 
+    fix_add_params_ident $1; 
+    (* toreput? !LP._lexer_hint.toplevel <- false;  *)
+    $1 
+  }
+
+start_fun2: decl_spec declaratorfd  
+     { let (returnType,storage) = fixDeclSpecForFuncDef $1 in
+       let (id, attrs) = $2 in
+       (fst id, fixOldCDecl ((snd id) returnType) , storage, attrs) 
+     }
+
+/*(*----------------------------*)*/
+/*(* workarounds *)*/
+/*(*----------------------------*)*/
+
+declaratorfd: 
+ | declarator { et "declaratorfd" (); $1, Ast_c.noattr }
+ /*(* gccext: *)*/
+ | attributes declarator   { et "declaratorfd" (); $2, $1 }
+ | declarator attributes   { et "declaratorfd" (); $1, Ast_c.noattr }
+
+
+
+/*(*************************************************************************)*/
+/*(* cpp directives *)*/
+/*(*************************************************************************)*/
+
+cpp_directive: 
+ | TIncludeStart TIncludeFilename 
+     { 
+       let (i1, in_ifdef) = $1 in
+       let (s, i2) = $2 in
+
+       (* redo some lexing work :( *)
+       let inc_file = 
+         match () with
+         | _ when s =~ "^\"\\(.*\\)\"$" -> 
+             Local (Common.split "/" (matched1 s))
+         | _ when s =~ "^\\<\\(.*\\)\\>$" -> 
+             NonLocal (Common.split "/" (matched1 s))
+         | _ -> 
+             Wierd s 
+       in
+       Include { i_include = (inc_file, [i1;i2]);
+                 i_rel_pos = Ast_c.noRelPos();
+                 i_is_in_ifdef = !in_ifdef;
+                 i_content = Ast_c.noi_content;
+       }
+     }
+
+ | TDefine TIdentDefine define_val TDefEOL 
+     { Define ((fst $2, [$1; snd $2;$4]), (DefineVar, $3)) }
+
+ /*
+ (* The TOParDefine is introduced to avoid ambiguity with previous rules.
+  * A TOParDefine is a TOPar that was just next to the ident.
+  *)*/
+ | TDefine TIdentDefine TOParDefine param_define_list TCPar define_val TDefEOL
+     { Define 
+         ((fst $2, [$1; snd $2;$7]), 
+           (DefineFunc ($4, [$3;$5]), $6)) 
+     }
+
+ | TUndef { Undef (fst $1, [snd $1]) }
+ | TCppDirectiveOther { PragmaAndCo ([$1]) }
+
+/*(* perhaps better to use assign_expr ? but in that case need 
+   * do a assign_expr_of_string in parse_c
+   *)*/
+define_val: 
+ | expr      { DefineExpr $1 }
+ | statement { DefineStmt $1 }
+ | decl      { DefineStmt (Decl ($1 Ast_c.NotLocalDecl), []) }
+
+/*(*old: | TypedefIdent { DefineType (nQ,(TypeName(fst $1,noTypedefDef()),[snd $1]))}*)*/
+ | spec_qualif_list { DefineTodo }
+ | function_definition { DefineFunction $1 }
+
+ | TOBraceDefineInit initialize_list gcc_comma_opt_struct TCBrace comma_opt 
+    { DefineInit (InitList (List.rev $2), [$1;$4]++$3++$5)  }
+
+ /*(* note: had a conflict before when were putting TInt instead of expr *)*/
+ | Tdo statement Twhile TOPar expr TCPar 
+     {
+       (* TOREPUT 
+       if fst $5 <> "0" 
+       then pr2 "WIERD: in macro and have not a while(0)";
+       *)
+       DefineDoWhileZero (($2,$5),   [$1;$3;$4;$6])
+     }
+
+ /*(* a few special cases *)*/
+ | stat_or_decl stat_or_decl_list { DefineTodo }
+/*
+ | statement statement { DefineTodo }
+ | decl function_definition { DefineTodo }
+*/
+
+ | Tasm TOPar asmbody TCPar              { DefineTodo }
+ | Tasm Tvolatile TOPar asmbody TCPar    { DefineTodo }
+
+
+ /*(* aliases macro *)*/
+ | TMacroAttr { DefineTodo }
+ | storage_class_spec { DefineTodo }
+ | Tinline { DefineTodo }
+
+ | /*(* empty *)*/ { DefineEmpty }
+
+
+param_define:
+ | TIdent               { fst $1, [snd $1] } 
+ | TypedefIdent         { fst $1, [snd $1] } 
+ | TDefParamVariadic    { fst $1, [snd $1] } 
+ | TEllipsis            { "...", [$1] }
+ /*(* they reuse keywords :(  *)*/
+ | Tregister            { "register", [$1] }
+
+
+
+
+cpp_ifdef_directive: 
+ | TIfdef     
+     { let (tag,ii) = $1 in 
+       IfdefDirective ((Ifdef, IfdefTag (Common.some !tag)),  [ii]) }
+ | TIfdefelse 
+     { let (tag,ii) = $1 in  
+       IfdefDirective ((IfdefElse, IfdefTag (Common.some !tag)), [ii]) }
+ | TIfdefelif 
+     { let (tag,ii) = $1 in  
+       IfdefDirective ((IfdefElseif, IfdefTag (Common.some !tag)), [ii]) }
+ | TEndif     
+     { let (tag,ii) = $1 in  
+       IfdefDirective ((IfdefEndif, IfdefTag (Common.some !tag)), [ii]) }
+
+ | TIfdefBool    
+     { let (_b, tag,ii) = $1 in  
+       IfdefDirective ((Ifdef, IfdefTag (Common.some !tag)), [ii]) }
+ | TIfdefMisc    
+     { let (_b, tag,ii) = $1 in  
+       IfdefDirective ((Ifdef, IfdefTag (Common.some !tag)), [ii]) }
+ | TIfdefVersion 
+     { let (_b, tag,ii) = $1 in  
+       IfdefDirective ((Ifdef, IfdefTag (Common.some !tag)), [ii]) }
+
+
+/*(* cppext: *)*/
+cpp_other: 
+ /*(* no conflict ? no need for a TMacroTop ? apparently not as at toplevel
+    * the rule are slightly different, they cant be statement and so expr
+    * at the top, only decl or function definition.
+    *)*/
+ | identifier TOPar argument_list TCPar TPtVirg
+     { MacroTop (fst $1, $3,    [snd $1;$2;$4;$5]) } 
+
+ /*(* TCParEOL to fix the end-of-stream bug of ocamlyacc *)*/
+ | identifier TOPar argument_list TCParEOL
+     { MacroTop (fst $1, $3,    [snd $1;$2;$4;fakeInfo()]) } 
+
+  /*(* ex: EXPORT_NO_SYMBOLS; *)*/
+ | identifier TPtVirg { EmptyDef [snd $1;$2] }
+
+
+
+/*(*************************************************************************)*/
+/*(* celem *)*/
+/*(*************************************************************************)*/
+
+external_declaration: 
+ | function_definition               { Definition $1 }
+ | decl                              { Declaration ($1 Ast_c.NotLocalDecl) }
+
+
+celem: 
+ | external_declaration                         { $1 }
+
+ /*(* cppext: *)*/
+ | cpp_directive                                
+     { CppTop $1 }
+ | cpp_other                                    
+     { $1 }
+ | cpp_ifdef_directive /* (*external_declaration_list ...*)*/
+     { IfdefTop $1 }
+
+ /*(* can have asm declaration at toplevel *)*/
+ | Tasm TOPar asmbody TCPar TPtVirg             { EmptyDef [$1;$2;$4;$5] } 
+
+ /*
+ (* in ~/kernels/src/linux-2.5.2/drivers/isdn/hisax/isdnl3.c sometimes
+  * the function ends with }; instead of just } 
+  * can also remove this rule and report "parse error" pb to morton
+  *)*/
+ | TPtVirg    { EmptyDef [$1] } 
+
+         
+ | EOF        { FinalDef $1 } 
+
+
+
+
+/*(*************************************************************************)*/
+/*(* some generic workarounds *)*/
+/*(*************************************************************************)*/
+
+tobrace: TOBrace  { LP.push_context LP.InFunction; LP.new_scope (); $1 }
+tcbrace: TCBrace  { LP.pop_context();              LP.del_scope (); $1 }
+
+tobrace_enum: TOBrace { LP.push_context LP.InEnum; $1 }
+tcbrace_enum: TCBrace { LP.pop_context (); $1 }
+
+tobrace_ini: TOBrace { LP.push_context LP.InInitializer; $1 }
+tcbrace_ini: TCBrace { LP.pop_context (); $1 }
+
+tobrace_struct: TOBrace { LP.push_context LP.InStruct; $1}
+tcbrace_struct: TCBrace { LP.pop_context (); $1 }
+
+
+
+
+topar: TOPar 
+     { LP.new_scope ();et "topar" (); 
+       LP.push_context LP.InParameter;
+       $1  
+     }
+tcpar: TCPar 
+     { LP.del_scope ();dt "tcpar" (); 
+       LP.pop_context (); 
+       $1  
+     }
+
+
+
+
+/*(*************************************************************************)*/
+/*(* xxx_list, xxx_opt *)*/
+/*(*************************************************************************)*/
+
+
+/*(* old:
+compound2: 
+ |                            { ([],[]) }
+ |  statement_list            { ([], $1) }
+ |  decl_list                 { ($1, []) }
+ |  decl_list statement_list  { ($1,$2) }
+
+statement_list: stat_or_decl_list { $1 }
+*)*/
+
+
+/*(*
+decl_list: 
+ | decl           { [$1]   }
+ | decl_list decl { $1 ++ [$2] }
+
+statement_list: 
+ | statement { [$1] }
+ | statement_list statement { $1 ++ [$2] }
+*)*/
 
-stat_or_decl_list: 
- | stat_or_decl { [$1] }
- | end_labeled  { [Labeled      (fst $1), snd $1] }
- | stat_or_decl stat_or_decl_list { $1 :: $2 }
 
 
 
@@ -1269,7 +1713,6 @@ colon_option_list:
  | colon_option_list TComma colon_option { $1 ++ [$3, [$2]] }
 
 
-
 argument_list_ne: 
  | argument_ne                           { [$1, []] }
  | argument_list_ne TComma argument { $1 ++ [$3,    [$2]] }
@@ -1314,6 +1757,11 @@ taction_list_ne:
  | TAction taction_list_ne { $1 :: $2 }
 
 taction_list: 
+/*old: was generating conflict, hence now taction_list_ne 
+    | (* empty *) { [] }
+ | TAction { [$1] }
+ | taction_list TAction { $1 ++ [$2] }
+*/
  |                      { [] }
  | TAction taction_list { $1 :: $2 }
 
@@ -1326,12 +1774,29 @@ designator_list:
  | designator { [$1] }
  | designator_list designator { $1 ++ [$2] }
 
+attribute_list:
+ | attribute { [$1] }
+ | attribute_list attribute { $1 ++ [$2] }
+
+attribute_storage_list:
+ | attribute_storage { [$1] }
+ | attribute_storage_list attribute_storage { $1 ++ [$2] }
+
+
+attributes: attribute_list { $1 }
+
+attributes_storage: attribute_storage_list { $1 }
+
 
 /*(* gccext:  which allow a trailing ',' in enum, as in perl *)*/
 gcc_comma_opt: 
  | TComma {  [$1] } 
  | /*(* empty *)*/  {  []  }
 
+comma_opt: 
+ | TComma {  [$1] } 
+ | /*(* empty *)*/  {  []  }
+
 /*(*
 gcc_opt_virg:
  | TPtVirg { }
@@ -1349,127 +1814,7 @@ opt_ptvirg:
 *)*/
 
 
-/*(*************************************************************************)*/
-/*(* cpp directives *)*/
-/*(*************************************************************************)*/
-
-/*(* cppext: *)*/
-cpp_directive: 
-
- | identifier TOPar argument_list TCPar TPtVirg
-     { MacroTop (fst $1, $3,    [snd $1;$2;$4;$5]) } 
-
- /*(* TCParEOL to fix the end-of-stream bug of ocamlyacc *)*/
- | identifier TOPar argument_list TCParEOL
-     { MacroTop (fst $1, $3,    [snd $1;$2;$4;fakeInfo()]) } 
-
-  /*(* ex: EXPORT_NO_SYMBOLS; *)*/
- | identifier TPtVirg { EmptyDef [snd $1;$2] }
-
- | TIncludeStart TIncludeFilename 
-     { 
-       let (i1, in_ifdef) = $1 in
-       let (s, i2) = $2 in
-
-       (* redo some lexing work :( *)
-       let inc_file = 
-         match () with
-         | _ when s =~ "^\"\\(.*\\)\"$" -> 
-             Local (Common.split "/" (matched1 s))
-         | _ when s =~ "^\\<\\(.*\\)\\>$" -> 
-             NonLocal (Common.split "/" (matched1 s))
-         | _ -> 
-             Wierd s 
-       in
-       Include ((inc_file, [i1;i2]), (Ast_c.noRelPos(), !in_ifdef)) 
-     }
-
- | TDefine TIdentDefine define_val TDefEOL 
-     { Define ((fst $2, [$1; snd $2;$4]), (DefineVar, $3)) }
-
- /*
- (* The TOParDefine is introduced to avoid ambiguity with previous rules.
-  * A TOParDefine is a TOPar that was just next to the ident.
-  *)*/
- | TDefine TIdentDefine TOParDefine param_define_list TCPar define_val TDefEOL
-     { Define 
-         ((fst $2, [$1; snd $2;$7]), 
-           (DefineFunc ($4, [$3;$5]), $6)) 
-     }
-
-
-/*(* perhaps better to use assign_expr ? but in that case need 
-   * do a assign_expr_of_string in parse_c
-   *)*/
-define_val: 
- | expr      { DefineExpr $1 }
- | statement { DefineStmt $1 }
- | decl      { DefineStmt (Decl ($1 Ast_c.NotLocalDecl), []) }
- | TypedefIdent { DefineType (nQ,(TypeName(fst $1,noTypedefDef()),[snd $1]))}
- | function_definition { DefineFunction $1 }
-
- | Tdo statement Twhile TOPar TInt TCPar 
-     {
-       if fst $5 <> "0" 
-       then pr2 "WIERD: in macro and have not a while(0)";
-       DefineDoWhileZero ($2,  [$1;$3;$4;snd $5;$6])
-     }
- | /*(* empty *)*/ { DefineEmpty }
-
-param_define:
- | identifier           { fst $1, [snd $1] } 
- | TypedefIdent         { fst $1, [snd $1] } 
- | TDefParamVariadic    { fst $1, [snd $1] } 
- | TEllipsis            { "...", [$1] }
- /*(* they reuse keywords :(  *)*/
- | Tregister            { "register", [$1] }
-
-
-/*(*************************************************************************)*/
-/*(* celem *)*/
-/*(*************************************************************************)*/
-
-external_declaration: 
- | function_definition               { Definition $1 }
- | decl                              { Declaration ($1 Ast_c.NotLocalDecl) }
-
-function_definition: function_def    { fixFunc $1 }
-
-function_def: start_fun compound { LP.del_scope(); ($1, $2) }
-
-start_fun: start_fun2                        
-  { LP.new_scope(); 
-    fix_add_params_ident $1; 
-    !LP._lexer_hint.toplevel <- false;  
-    $1 
-  }
-
-start_fun2: decl_spec declaratorfd  
-     { let (returnType,storage) = fixDeclSpecForFuncDef $1 in
-       (fst $2, fixOldCDecl ((snd $2) returnType) , storage) 
-     }
-
-celem: 
- | external_declaration                         { $1 }
- | cpp_directive                                { $1 }
-
- /*(* can have asm declaration at toplevel *)*/
- | Tasm TOPar asmbody TCPar TPtVirg             { EmptyDef [] } 
-
- /*
- (* in ~/kernels/src/linux-2.5.2/drivers/isdn/hisax/isdnl3.c sometimes
-  * the function ends with }; instead of just } 
-  * can also remove this rule and report "parse error" pb to morton
-  *)*/
- | TPtVirg    { EmptyDef [$1] } 
-
-         
- | EOF        { FinalDef $1 } 
-
-
-/*(*----------------------------*)*/
-/*(* workarounds *)*/
-/*(*----------------------------*)*/
-declaratorfd: declarator { et "declaratorfd" (); $1 }
-
+expr_opt: 
+ | expr            { Some $1 }
+ | /*(* empty *)*/ { None }
 
index af59c37..fcca15a 100644 (file)
@@ -1,4 +1,4 @@
-(* Copyright (C) 2002-2008 Yoann Padioleau
+(* Copyright (C) 2007, 2008 Yoann Padioleau
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License (GPL)
@@ -15,13 +15,9 @@ open Common
 module TH = Token_helpers 
 module LP = Lexer_parser
 
-open Parser_c 
+module Stat = Parsing_stat
 
-let acc_map f l =
-  let rec loop acc = function
-    [] -> List.rev acc
-  | x::xs -> loop ((f x)::acc) xs in
-  loop [] l
+open Parser_c 
 
 (*****************************************************************************)
 (* Some debugging functions  *)
@@ -36,15 +32,6 @@ let pr2_cpp s =
   then Common.pr2_once ("CPP-" ^ s)
 
 
-(* In the following, there are some harcoded names of types or macros
- * but they are not used by our heuristics! They are just here to
- * enable to detect false positive by printing only the typedef/macros
- * that we don't know yet. If we print everything, then we can easily
- * get lost with too much verbose tracing information. So those
- * functions "filter" some messages. So our heuristics are still good,
- * there is no more (or not that much) hardcoded linux stuff.
- *)
-
 let msg_gen cond is_known printer s = 
   if cond
   then
@@ -55,15 +42,16 @@ let msg_gen cond is_known printer s =
       then printer s
         
 
-
-
-
-(* note: cant use partial application with let msg_typedef = 
- * because it would compute msg_typedef at compile time when 
- * the flag debug_typedef is always false
+(* In the following, there are some harcoded names of types or macros
+ * but they are not used by our heuristics! They are just here to
+ * enable to detect false positive by printing only the typedef/macros
+ * that we don't know yet. If we print everything, then we can easily
+ * get lost with too much verbose tracing information. So those
+ * functions "filter" some messages. So our heuristics are still good,
+ * there is no more (or not that much) hardcoded linux stuff.
  *)
-let msg_typedef s = 
-  msg_gen (!Flag_parsing_c.debug_typedef)
+
+let is_known_typdef = 
     (fun s -> 
       (match s with
       | "u_char"   | "u_short"  | "u_int"  | "u_long"
@@ -84,15 +72,29 @@ let msg_typedef s =
       | _ -> false 
       )
     )
+
+(* note: cant use partial application with let msg_typedef = 
+ * because it would compute msg_typedef at compile time when 
+ * the flag debug_typedef is always false
+ *)
+let msg_typedef s = 
+  incr Stat.nTypedefInfer;
+  msg_gen (!Flag_parsing_c.debug_typedef)
+    is_known_typdef
     (fun s -> 
       pr2_cpp ("TYPEDEF: promoting: " ^ s)
     )
     s
 
+let msg_maybe_dangereous_typedef s =
+  if not (is_known_typdef s)
+  then 
+    pr2 ("PB MAYBE: dangerous typedef inference, maybe not a typedef: " ^ s)
 
 
 
 let msg_declare_macro s = 
+  incr Stat.nMacroDecl;
   msg_gen (!Flag_parsing_c.debug_cpp)
     (fun s -> 
       (match s with 
@@ -121,25 +123,33 @@ let msg_declare_macro s =
       
 
 let msg_foreach s = 
+  incr Stat.nIteratorHeuristic;
   pr2_cpp ("MACRO: found foreach: " ^ s)
 
 
+(* ?? 
 let msg_debug_macro s = 
   pr2_cpp ("MACRO: found debug-macro: " ^ s)
+*)
 
 
 let msg_macro_noptvirg s = 
+  incr Stat.nMacroStmt;
   pr2_cpp ("MACRO: found macro with param noptvirg: " ^ s)
 
 let msg_macro_toplevel_noptvirg s = 
+  incr Stat.nMacroStmt;
   pr2_cpp ("MACRO: found toplevel macro noptvirg: " ^ s)
 
-
 let msg_macro_noptvirg_single s = 
+  incr Stat.nMacroStmt;
   pr2_cpp ("MACRO: found single-macro noptvirg: " ^ s)
 
 
+
+
 let msg_macro_higher_order s = 
+  incr Stat.nMacroHigherOrder;
   msg_gen (!Flag_parsing_c.debug_cpp)
     (fun s -> 
       (match s with 
@@ -155,6 +165,7 @@ let msg_macro_higher_order s =
 
 
 let msg_stringification s = 
+  incr Stat.nMacroString;
   msg_gen (!Flag_parsing_c.debug_cpp)
     (fun s -> 
       (match s with 
@@ -170,10 +181,51 @@ let msg_stringification s =
     (fun s -> pr2_cpp ("MACRO: found string-macro " ^ s))
     s
 
+let msg_stringification_params s =
+  incr Stat.nMacroString;
+  pr2_cpp ("MACRO: string-macro with params : " ^ s)
+
+
+
+let msg_apply_known_macro s = 
+  incr Stat.nMacroExpand;
+  pr2_cpp ("MACRO: found known macro = " ^ s)
+
+let msg_apply_known_macro_hint s = 
+  incr Stat.nMacroHint;
+  pr2_cpp ("MACRO: found known macro hint = " ^ s)
+
+
   
 
+let msg_ifdef_bool_passing is_ifdef_positif =      
+  incr Stat.nIfdefZero; (* of Version ? *)
+  if is_ifdef_positif
+  then pr2_cpp "commenting parts of a #if 1 or #if LINUX_VERSION"
+  else pr2_cpp "commenting a #if 0 or #if LINUX_VERSION or __cplusplus"
+
+
+let msg_ifdef_mid_something () =
+  incr Stat.nIfdefExprPassing;
+  pr2_cpp "found ifdef-mid-something"
+
+let msg_ifdef_funheaders () =
+  incr Stat.nIfdefFunheader;
+  ()
+
+let msg_ifdef_passing () = 
+  pr2_cpp("IFDEF: or related outside function. I treat it as comment");
+  incr Stat.nIfdefPassing;
+  ()
+
+let msg_attribute s = 
+  incr Stat.nMacroAttribute;
+  pr2_cpp("ATTR:" ^ s)
+  
+
+
 (*****************************************************************************)
-(* CPP handling: macros, ifdefs, macros defs  *)
+(* The regexp and basic view definitions *)
 (*****************************************************************************)
 
 (* opti: better to built then once and for all, especially regexp_foreach *)
@@ -196,14 +248,72 @@ let regexp_foreach = Str.regexp_case_fold
 let regexp_typedef = Str.regexp
   ".*_t$"
 
-
 let false_typedef = [
   "printk";
   ]
 
-type define_body = (unit,string list) either * Parser_c.token list
 
-let (_defs : (string, define_body) Hashtbl.t ref)  = 
+let ok_typedef s = not (List.mem s false_typedef)
+
+let not_annot s = 
+  not (s ==~ regexp_annot)
+
+
+(* ------------------------------------------------------------------------- *)
+(* cpp part 1 for standard.h *)
+(* ------------------------------------------------------------------------- *)
+
+type define_def = string * define_param * define_body 
+ and define_param = 
+   | NoParam
+   | Params of string list
+ and define_body = 
+   | DefineBody of Parser_c.token list
+   | DefineHint of parsinghack_hint
+
+   and parsinghack_hint = 
+     | HintIterator
+     | HintDeclarator
+     | HintMacroString
+     | HintMacroStatement
+     | HintAttribute
+
+
+(* cf also data/test.h *)
+let assoc_hint_string = [
+  "YACFE_ITERATOR"   , HintIterator;
+  "YACFE_DECLARATOR" , HintDeclarator;
+  "YACFE_STRING"     , HintMacroString;
+  "YACFE_STATEMENT"  , HintMacroStatement;
+  "YACFE_ATTRIBUTE"  , HintAttribute;
+  "MACROSTATEMENT"   , HintMacroStatement; (* backward compatibility *)
+]
+
+
+let (parsinghack_hint_of_string: string -> parsinghack_hint option) = fun s -> 
+  Common.assoc_option s assoc_hint_string
+
+let (is_parsinghack_hint: string -> bool) = fun s -> 
+  parsinghack_hint_of_string s <> None
+
+let (token_from_parsinghack_hint: 
+     (string * Ast_c.info) -> parsinghack_hint -> Parser_c.token) = 
+ fun (s,ii) hint ->
+   match hint with
+   | HintIterator -> 
+       Parser_c.TMacroIterator (s, ii)
+   | HintDeclarator -> 
+       Parser_c.TMacroDecl (s, ii)
+   | HintMacroString -> 
+       Parser_c.TMacroString (s, ii)
+   | HintMacroStatement -> 
+       Parser_c.TMacroStmt (s, ii)
+   | HintAttribute -> 
+       Parser_c.TMacroAttr (s, ii)
+  
+
+
+let (_defs : (string, define_def) Hashtbl.t ref)  = 
   ref (Hashtbl.create 101)
 
 
@@ -389,7 +499,7 @@ let rec mk_ifdef xs =
       | TIfdef _ -> 
           let body, extra, xs = mk_ifdef_parameters [x] [] xs in
           Ifdef (body, extra)::mk_ifdef xs
-      | TIfdefBool (b,_) -> 
+      | TIfdefBool (b,_, _) -> 
           let body, extra, xs = mk_ifdef_parameters [x] [] xs in
           
           (* if not passing, then consider a #if 0 as an ordinary #ifdef *)
@@ -397,7 +507,7 @@ let rec mk_ifdef xs =
           then Ifdefbool (b, body, extra)::mk_ifdef xs
           else Ifdef(body, extra)::mk_ifdef xs
 
-      | TIfdefMisc (b,_) | TIfdefVersion (b,_) -> 
+      | TIfdefMisc (b,_,_) | TIfdefVersion (b,_,_) -> 
           let body, extra, xs = mk_ifdef_parameters [x] [] xs in
           Ifdefbool (b, body, extra)::mk_ifdef xs
 
@@ -427,7 +537,7 @@ and mk_ifdef_parameters extras acc_before_sep xs =
           mk_ifdef_parameters 
             extras (Ifdef (body, extrasnest)::acc_before_sep) xs
 
-      | TIfdefBool (b,_) -> 
+      | TIfdefBool (b,_,_) -> 
           let body, extrasnest, xs = mk_ifdef_parameters [x] [] xs in
 
           if !Flag_parsing_c.if0_passing
@@ -439,7 +549,7 @@ and mk_ifdef_parameters extras acc_before_sep xs =
               extras (Ifdef (body, extrasnest)::acc_before_sep) xs
 
 
-      | TIfdefMisc (b,_) | TIfdefVersion (b,_) -> 
+      | TIfdefMisc (b,_,_) | TIfdefVersion (b,_,_) -> 
           let body, extrasnest, xs = mk_ifdef_parameters [x] [] xs in
           mk_ifdef_parameters 
             extras (Ifdefbool (b, body, extrasnest)::acc_before_sep) xs
@@ -669,6 +779,128 @@ let set_context_tag xs =
   end
   
 
+(*****************************************************************************)
+(* Helpers *)
+(*****************************************************************************)
+
+(* To expand the parameter of the macro. The env corresponds to the actual
+ * code that is binded to the parameters of the macro.
+ * TODO? recurse ? fixpoint ? the expansion may also contain macro.
+ * Or to macro expansion in a strict manner, that is process first
+ * the parameters, expands macro in params, and then process enclosing
+ * macro call.
+ *)
+let rec (cpp_engine: (string , Parser_c.token list) assoc -> 
+          Parser_c.token list -> Parser_c.token list) = 
+ fun env xs ->
+  xs +> List.map (fun tok -> 
+    match tok with
+    | TIdent (s,i1) when List.mem_assoc s env -> Common.assoc s env
+    | x -> [x]
+  )
+  +> List.flatten
+
+
+
+
+(* ------------------------------------------------------------------------- *)
+(* the pair is the status of '()' and '{}', ex: (-1,0) 
+ * if too much ')' and good '{}' 
+ * could do for [] too ? 
+ * could do for ','   if encounter ',' at "toplevel", not inside () or {}
+ * then if have ifdef, then certainly can lead to a problem.
+ *)
+let (count_open_close_stuff_ifdef_clause: ifdef_grouped list -> (int * int)) = 
+ fun xs -> 
+   let cnt_paren, cnt_brace = ref 0, ref 0 in
+   xs +> iter_token_ifdef (fun x -> 
+     (match x.tok with
+     | x when TH.is_opar x  -> incr cnt_paren
+     | TOBrace _ -> incr cnt_brace
+     | x when TH.is_cpar x  -> decr cnt_paren
+     | TCBrace _ -> decr cnt_brace
+     | _ -> ()
+     )
+   );
+   !cnt_paren, !cnt_brace
+
+
+(* ------------------------------------------------------------------------- *)
+let forLOOKAHEAD = 30
+
+  
+(* look if there is a '{' just after the closing ')', and handling the
+ * possibility to have nested expressions inside nested parenthesis 
+ * 
+ * todo: use indentation instead of premier(statement) ?
+ *)
+let rec is_really_foreach xs = 
+  let rec is_foreach_aux = function
+    | [] -> false, []
+    | TCPar _::TOBrace _::xs -> true, xs
+      (* the following attempts to handle the cases where there is a
+        single statement in the body of the loop.  undoubtedly more
+        cases are needed. 
+         todo: premier(statement) - suivant(funcall)
+      *)
+    | TCPar _::TIdent _::xs -> true, xs
+    | TCPar _::Tif _::xs -> true, xs
+    | TCPar _::Twhile _::xs -> true, xs
+    | TCPar _::Tfor _::xs -> true, xs
+    | TCPar _::Tswitch _::xs -> true, xs
+    | TCPar _::Treturn _::xs -> true, xs
+
+
+    | TCPar _::xs -> false, xs
+    | TOPar _::xs -> 
+        let (_, xs') = is_foreach_aux xs in
+        is_foreach_aux xs'
+    | x::xs -> is_foreach_aux xs
+  in
+  is_foreach_aux xs +> fst
+
+
+(* ------------------------------------------------------------------------- *)
+let set_ifdef_token_parenthize_info cnt x = 
+    match x with
+    | TIfdef (tag, _)
+    | TIfdefelse (tag, _)
+    | TIfdefelif (tag, _)
+    | TEndif (tag, _)
+
+    | TIfdefBool (_, tag, _)
+    | TIfdefMisc (_, tag, _)   
+    | TIfdefVersion (_, tag, _)
+        -> 
+        tag := Some cnt;
+
+    | _ -> raise Impossible
+  
+
+
+let ifdef_paren_cnt = ref 0 
+
+
+let rec set_ifdef_parenthize_info xs = 
+  xs +> List.iter (function
+  | NotIfdefLine xs -> ()
+  | Ifdefbool (_, xxs, info_ifdef) 
+  | Ifdef (xxs, info_ifdef) -> 
+      
+      incr ifdef_paren_cnt;
+      let total_directives = List.length info_ifdef in
+
+      info_ifdef +> List.iter (fun x -> 
+        set_ifdef_token_parenthize_info (!ifdef_paren_cnt, total_directives)
+          x.tok);
+      xxs +> List.iter set_ifdef_parenthize_info
+  )
+
+
+(*****************************************************************************)
+(* CPP handling: macros, ifdefs, macros defs  *)
+(*****************************************************************************)
+
 (* ------------------------------------------------------------------------- *)
 (* ifdef keeping/passing *)
 (* ------------------------------------------------------------------------- *)
@@ -678,10 +910,8 @@ let rec find_ifdef_bool xs =
   xs +> List.iter (function 
   | NotIfdefLine _ -> ()
   | Ifdefbool (is_ifdef_positif, xxs, info_ifdef_stmt) -> 
-      
-      if is_ifdef_positif
-      then pr2_cpp "commenting parts of a #if 1 or #if LINUX_VERSION"
-      else pr2_cpp "commenting a #if 0 or #if LINUX_VERSION or __cplusplus";
+
+      msg_ifdef_bool_passing is_ifdef_positif;
 
       (match xxs with
       | [] -> raise Impossible
@@ -690,14 +920,14 @@ let rec find_ifdef_bool xs =
             
           if is_ifdef_positif
           then xxs +> List.iter 
-            (iter_token_ifdef (set_as_comment Ast_c.CppOther))
+            (iter_token_ifdef (set_as_comment Ast_c.CppPassingNormal))
           else begin
-            firstclause +> iter_token_ifdef (set_as_comment Ast_c.CppOther);
+            firstclause +> iter_token_ifdef (set_as_comment Ast_c.CppPassingNormal);
             (match List.rev xxs with
             (* keep only last *)
             | last::startxs -> 
                 startxs +> List.iter 
-                  (iter_token_ifdef (set_as_comment Ast_c.CppOther))
+                  (iter_token_ifdef (set_as_comment Ast_c.CppPassingNormal))
             | [] -> (* not #else *) ()
             );
           end
@@ -708,26 +938,6 @@ let rec find_ifdef_bool xs =
 
 
 
-(* the pair is the status of '()' and '{}', ex: (-1,0) 
- * if too much ')' and good '{}' 
- * could do for [] too ? 
- * could do for ','   if encounter ',' at "toplevel", not inside () or {}
- * then if have ifdef, then certainly can lead to a problem.
- *)
-let (count_open_close_stuff_ifdef_clause: ifdef_grouped list -> (int * int)) = 
- fun xs -> 
-   let cnt_paren, cnt_brace = ref 0, ref 0 in
-   xs +> iter_token_ifdef (fun x -> 
-     (match x.tok with
-     | x when TH.is_opar x  -> incr cnt_paren
-     | TOBrace _ -> incr cnt_brace
-     | x when TH.is_cpar x  -> decr cnt_paren
-     | TCBrace _ -> decr cnt_brace
-     | _ -> ()
-     )
-   );
-   !cnt_paren, !cnt_brace
-
 let thresholdIfdefSizeMid = 6
 
 (* infer ifdef involving not-closed expressions/statements *)
@@ -759,11 +969,12 @@ let rec find_ifdef_mid xs =
                 ) 
               *)
             then begin
-              pr2_cpp "found ifdef-mid-something";
+              msg_ifdef_mid_something();
+
               (* keep only first, treat the rest as comment *)
               info_ifdef_stmt +> List.iter (set_as_comment Ast_c.CppDirective);
               (second::rest) +> List.iter 
-                (iter_token_ifdef (set_as_comment Ast_c.CppOther));
+                (iter_token_ifdef (set_as_comment Ast_c.CppPassingCosWouldGetError));
             end
               
       );
@@ -796,10 +1007,12 @@ let rec find_ifdef_funheaders = function
         List.length ifdefblock2 <= thresholdFunheaderLimit
     -> 
       find_ifdef_funheaders xs;
+
+      msg_ifdef_funheaders ();
       info_ifdef_stmt +> List.iter (set_as_comment Ast_c.CppDirective);
       let all_toks = [xline2] @ line2 in
-      all_toks +> List.iter (set_as_comment Ast_c.CppOther) ;
-      ifdefblock2 +> iter_token_ifdef (set_as_comment Ast_c.CppOther);
+      all_toks +> List.iter (set_as_comment Ast_c.CppPassingCosWouldGetError) ;
+      ifdefblock2 +> iter_token_ifdef (set_as_comment Ast_c.CppPassingCosWouldGetError);
 
   (* ifdef with nested ifdef *)
   | Ifdef 
@@ -816,10 +1029,12 @@ let rec find_ifdef_funheaders = function
     ::xs  
     -> 
       find_ifdef_funheaders xs;
+
+      msg_ifdef_funheaders ();
       info_ifdef_stmt  +> List.iter (set_as_comment Ast_c.CppDirective);
       info_ifdef_stmt2 +> List.iter (set_as_comment Ast_c.CppDirective);
       let all_toks = [xline2;xline3] @ line2 @ line3 in
-      all_toks +> List.iter (set_as_comment Ast_c.CppOther);
+      all_toks +> List.iter (set_as_comment Ast_c.CppPassingCosWouldGetError);
 
  (* ifdef with elseif *)
   | Ifdef 
@@ -832,11 +1047,13 @@ let rec find_ifdef_funheaders = function
     ::xs 
     -> 
       find_ifdef_funheaders xs;
+
+      msg_ifdef_funheaders ();
       info_ifdef_stmt +> List.iter (set_as_comment Ast_c.CppDirective);
       let all_toks = [xline2;xline3] @ line2 @ line3 in
-      all_toks +> List.iter (set_as_comment Ast_c.CppOther)
+      all_toks +> List.iter (set_as_comment Ast_c.CppPassingCosWouldGetError)
         
-
+  (* recurse *)
   | Ifdef (xxs,info_ifdef_stmt)::xs 
   | Ifdefbool (_, xxs,info_ifdef_stmt)::xs -> 
       List.iter find_ifdef_funheaders xxs; 
@@ -844,7 +1061,7 @@ let rec find_ifdef_funheaders = function
         
 
 
-
+(* ?? *)
 let rec adjust_inifdef_include xs = 
   xs +> List.iter (function 
   | NotIfdefLine _ -> ()
@@ -860,23 +1077,15 @@ let rec adjust_inifdef_include xs =
 
 
 (* ------------------------------------------------------------------------- *)
-(* cpp-builtin part1, macro, using standard.h or other defs *)
+(* cpp-builtin part2, macro, using standard.h or other defs *)
 (* ------------------------------------------------------------------------- *)
 
 (* Thanks to this function many stuff are not anymore hardcoded in ocaml code
  * (but they are now hardcoded in standard.h ...)
- *)
-
-let rec (cpp_engine: (string , Parser_c.token list) assoc -> 
-          Parser_c.token list -> Parser_c.token list) = fun env xs ->
-  xs +> List.map (fun tok -> 
-    match tok with
-    | TIdent (s,i1) when List.mem_assoc s env -> Common.assoc s env
-    | x -> [x]
-  )
-  +> List.flatten
-  
-(* no need to take care to not substitute the macro name itself
+ *
+ * 
+ * 
+ * No need to take care to not substitute the macro name itself
  * that occurs in the macro definition because the macro name is
  * after fix_token_define a TDefineIdent, no more a TIdent.
  *)
@@ -885,62 +1094,109 @@ let rec apply_macro_defs xs =
   match xs with
   | [] -> ()
 
+  (* old: "but could do more, could reuse same original token
+   * so that have in the Ast a Dbg, not a MACROSTATEMENT"
+   * 
+   *   | PToken ({tok = TIdent (s,i1)} as id)::xs 
+   *     when s = "MACROSTATEMENT" -> 
+   * 
+   *     msg_macro_statement_hint s;
+   *     id.tok <- TMacroStmt(TH.info_of_tok id.tok);
+   *     find_macro_paren xs
+   * 
+   *  let msg_macro_statement_hint s = 
+   *    incr Stat.nMacroHint;
+   *   ()
+   * 
+   *)
+
   (* recognized macro of standard.h (or other) *)
   | PToken ({tok = TIdent (s,i1)} as id)::Parenthised (xxs,info_parens)::xs 
       when Hashtbl.mem !_defs s -> 
-      pr2_cpp ("MACRO: found known macro = " ^ s);
-      (match Hashtbl.find !_defs s with
-      | Left (), bodymacro -> 
-          pr2 ("macro without param used before parenthize, wierd: " ^ s);
-          (* ex: PRINTP("NCR53C400 card%s detected\n" ANDP(((struct ... *)
-          set_as_comment (Ast_c.CppMacro) id;
-          id.new_tokens_before <- bodymacro;
-      | Right params, bodymacro -> 
-          if List.length params = List.length xxs
-          then
-            let xxs' = xxs +> List.map (fun x -> 
-              (tokens_of_paren_ordered x) +> List.map (fun x -> 
-                TH.visitor_info_of_tok Ast_c.make_expanded x.tok
-              )
-            ) in
-            id.new_tokens_before <-
-              cpp_engine (Common.zip params xxs') bodymacro
-
-          else begin
-            pr2 ("macro with wrong number of arguments, wierd: " ^ s);
-            id.new_tokens_before <- bodymacro;
-          end;
-          (* important to do that after have apply the macro, otherwise
-           * will pass as argument to the macro some tokens that
-           * are all TCommentCpp
-           *)
-          [Parenthised (xxs, info_parens)] +> 
-            iter_token_paren (set_as_comment Ast_c.CppMacro);
-          set_as_comment Ast_c.CppMacro id;
+      
+      msg_apply_known_macro s;
+      let (s, params, body) = Hashtbl.find !_defs s in
 
-           
+      (match params with
+      | NoParam -> 
+          pr2 ("WIERD: macro without param used before parenthize: " ^ s);
+          (* ex: PRINTP("NCR53C400 card%s detected\n" ANDP(((struct ... *)
 
+          (match body with
+          | DefineBody bodymacro -> 
+              set_as_comment (Ast_c.CppMacro) id;
+              id.new_tokens_before <- bodymacro;
+          | DefineHint hint -> 
+              msg_apply_known_macro_hint s;
+              id.tok <- token_from_parsinghack_hint (s,i1) hint;
+          )
+      | Params params -> 
+          if List.length params != List.length xxs
+          then begin 
+            pr2 ("WIERD: macro with wrong number of arguments: " ^ s);
+            (* old: id.new_tokens_before <- bodymacro; *)
+            ()
+          end
+          else 
+            (match body with
+            | DefineBody bodymacro -> 
+                let xxs' = xxs +> List.map (fun x -> 
+                  (tokens_of_paren_ordered x) +> List.map (fun x -> 
+                    TH.visitor_info_of_tok Ast_c.make_expanded x.tok
+                  )
+                ) in
+                id.new_tokens_before <-
+                  cpp_engine (Common.zip params xxs') bodymacro;
+
+                (* important to do that after have apply the macro, otherwise
+                 * will pass as argument to the macro some tokens that
+                 * are all TCommentCpp
+                 *)
+                [Parenthised (xxs, info_parens)] +> 
+                  iter_token_paren (set_as_comment Ast_c.CppMacro);
+                set_as_comment Ast_c.CppMacro id;
+
+            | DefineHint (HintMacroStatement as hint) -> 
+                (* important to do that after have apply the macro, otherwise
+                 * will pass as argument to the macro some tokens that
+                 * are all TCommentCpp
+                 *)
+                msg_apply_known_macro_hint s;
+                id.tok <- token_from_parsinghack_hint (s,i1) hint;
+                [Parenthised (xxs, info_parens)] +> 
+                  iter_token_paren (set_as_comment Ast_c.CppMacro);
+                
+
+            | DefineHint hint -> 
+                msg_apply_known_macro_hint s;
+                id.tok <- token_from_parsinghack_hint (s,i1) hint;
+            )
       );
       apply_macro_defs xs
 
   | PToken ({tok = TIdent (s,i1)} as id)::xs 
       when Hashtbl.mem !_defs s -> 
-      pr2_cpp ("MACRO: found known macro = " ^ s);
-      (match Hashtbl.find !_defs s with
-      | Right params, bodymacro -> 
-          pr2 ("macro with params but no parens found, wierd: " ^ s);
+
+      msg_apply_known_macro s;
+      let (_s, params, body) = Hashtbl.find !_defs s in
+
+      (match params with
+      | Params params -> 
+          pr2 ("WIERD: macro with params but no parens found: " ^ s);
           (* dont apply the macro, perhaps a redefinition *)
           ()
-      | Left (), bodymacro -> 
-          (* special case when 1-1 substitution, we reuse the token *)
-          (match bodymacro with
-          | [newtok] -> 
+      | NoParam -> 
+          (match body with
+          | DefineBody [newtok] -> 
+             (* special case when 1-1 substitution, we reuse the token *)
               id.tok <- (newtok +> TH.visitor_info_of_tok (fun _ -> 
                 TH.info_of_tok id.tok))
-
-          | _ -> 
+          | DefineBody bodymacro -> 
               set_as_comment Ast_c.CppMacro id;
               id.new_tokens_before <- bodymacro;
+          | DefineHint hint -> 
+                msg_apply_known_macro_hint s;
+                id.tok <- token_from_parsinghack_hint (s,i1) hint;
           )
       );
       apply_macro_defs xs
@@ -968,16 +1224,16 @@ let rec find_string_macro_paren xs =
   | Parenthised(xxs, info_parens)::xs -> 
       xxs +> List.iter (fun xs -> 
         if xs +> List.exists 
-          (function PToken({tok = TString _}) -> true | _ -> false) &&
+          (function PToken({tok = (TString _| TMacroString _)}) -> true | _ -> false) &&
           xs +> List.for_all 
-          (function PToken({tok = TString _}) | PToken({tok = TIdent _}) -> 
+          (function PToken({tok = (TString _| TMacroString _)}) | PToken({tok = TIdent _}) -> 
             true | _ -> false)
         then
           xs +> List.iter (fun tok -> 
             match tok with
             | PToken({tok = TIdent (s,_)} as id) -> 
                 msg_stringification s;
-                id.tok <- TMacroString (TH.info_of_tok id.tok);
+                id.tok <- TMacroString (s, TH.info_of_tok id.tok);
             | _ -> ()
           )
         else 
@@ -1008,6 +1264,37 @@ let rec find_macro_paren xs =
       set_as_comment Ast_c.CppAttr id;
       find_macro_paren xs
 
+(*
+  (* attribute cpp, __xxx id() *)
+  | PToken ({tok = TIdent (s,i1)} as id)
+    ::PToken ({tok = TIdent (s2, i2)})
+    ::Parenthised(xxs,info_parens)
+    ::xs when s ==~ regexp_annot
+     -> 
+      msg_attribute s;
+      id.tok <- TMacroAttr (s, i1);
+      find_macro_paren (Parenthised(xxs,info_parens)::xs)
+
+  (* attribute cpp, id __xxx =  *)
+  | PToken ({tok = TIdent (s,i1)})
+    ::PToken ({tok = TIdent (s2, i2)} as id)
+    ::xs when s2 ==~ regexp_annot
+     -> 
+      msg_attribute s2;
+      id.tok <- TMacroAttr (s2, i2);
+      find_macro_paren (xs)
+*)
+
+  (* storage attribute *)
+  | PToken ({tok = (Tstatic _ | Textern _)} as tok1)
+    ::PToken ({tok = TMacroAttr (s,i1)} as attr)::xs 
+    -> 
+      pr2_cpp ("storage attribute: " ^ s);
+      attr.tok <- TMacroAttrStorage (s,i1);
+      (* recurse, may have other storage attributes *)
+      find_macro_paren (PToken (tok1)::xs)
+      
+
   (* stringification
    * 
    * the order of the matching clause is important
@@ -1015,11 +1302,12 @@ let rec find_macro_paren xs =
    *)
 
   (* string macro with params, before case *)
-  | PToken ({tok = TString _})::PToken ({tok = TIdent (s,_)} as id)
+  | PToken ({tok = (TString _| TMacroString _)})::PToken ({tok = TIdent (s,_)} as id)
     ::Parenthised (xxs, info_parens)
     ::xs -> 
-      pr2_cpp ("MACRO: string-macro with params : " ^ s);
-      id.tok <- TMacroString (TH.info_of_tok id.tok);
+
+      msg_stringification_params s;
+      id.tok <- TMacroString (s, TH.info_of_tok id.tok);
       [Parenthised (xxs, info_parens)] +> 
         iter_token_paren (set_as_comment Ast_c.CppMacro);
       find_macro_paren xs
@@ -1027,10 +1315,11 @@ let rec find_macro_paren xs =
   (* after case *)
   | PToken ({tok = TIdent (s,_)} as id)
     ::Parenthised (xxs, info_parens)
-    ::PToken ({tok = TString _})
+    ::PToken ({tok = (TString _ | TMacroString _)})
     ::xs -> 
-      pr2_cpp ("MACRO: string-macro with params : " ^ s);
-      id.tok <- TMacroString (TH.info_of_tok id.tok);
+
+      msg_stringification_params s;
+      id.tok <- TMacroString (s, TH.info_of_tok id.tok);
       [Parenthised (xxs, info_parens)] +> 
         iter_token_paren (set_as_comment Ast_c.CppMacro);
       find_macro_paren xs
@@ -1041,27 +1330,24 @@ let rec find_macro_paren xs =
    *)
         
   (* string macro variable, before case *)
-  | PToken ({tok = TString _})::PToken ({tok = TIdent (s,_)} as id)
+  | PToken ({tok = (TString _ | TMacroString _)})::PToken ({tok = TIdent (s,_)} as id)
       ::xs -> 
+
       msg_stringification s;
-      id.tok <- TMacroString (TH.info_of_tok id.tok);
+      id.tok <- TMacroString (s, TH.info_of_tok id.tok);
       find_macro_paren xs
 
   (* after case *)
-  | PToken ({tok = TIdent (s,_)} as id)::PToken ({tok = TString _})
+  | PToken ({tok = TIdent (s,_)} as id)
+      ::PToken ({tok = (TString _ | TMacroString _)})
       ::xs -> 
+
       msg_stringification s;
-      id.tok <- TMacroString (TH.info_of_tok id.tok);
+      id.tok <- TMacroString (s, TH.info_of_tok id.tok);
       find_macro_paren xs
 
 
-
-  (* cooperating with standard.h *)
-  | PToken ({tok = TIdent (s,i1)} as id)::xs 
-      when s = "MACROSTATEMENT" -> 
-      id.tok <- TMacroStmt(TH.info_of_tok id.tok);
-      find_macro_paren xs
-        
+    
 
 
   (* recurse *)
@@ -1090,6 +1376,7 @@ let rec find_macro_lineparen xs =
         ))
     ::xs 
     when (s ==~ regexp_macro) -> 
+
       msg_declare_macro s;
       let info = TH.info_of_tok macro.tok in
       macro.tok <- TMacroDecl (Ast_c.str_of_info info, info);
@@ -1110,6 +1397,7 @@ let rec find_macro_lineparen xs =
         ))
     ::xs 
     when (s ==~ regexp_macro) -> 
+
       msg_declare_macro s;
       let info = TH.info_of_tok macro.tok in
       macro.tok <- TMacroDecl (Ast_c.str_of_info info, info);
@@ -1163,6 +1451,7 @@ let rec find_macro_lineparen xs =
         )
     ::xs 
     when (s ==~ regexp_macro) -> 
+
       msg_declare_macro s;
       let info = TH.info_of_tok macro.tok in
       macro.tok <- TMacroDecl (Ast_c.str_of_info info, info);
@@ -1233,6 +1522,7 @@ let rec find_macro_lineparen xs =
       in
       if condition
       then begin
+
           msg_macro_toplevel_noptvirg s;
           (* just to avoid the end-of-stream pb of ocamlyacc  *)
           let tcpar = Common.last info_parens in
@@ -1293,7 +1583,7 @@ let rec find_macro_lineparen xs =
         if col1 = 0 then ()
         else begin
           msg_macro_noptvirg s;
-          macro.tok <- TMacroStmt (TH.info_of_tok macro.tok);
+          macro.tok <- TMacroStmt (s, TH.info_of_tok macro.tok);
           [Parenthised (xxs, info_parens)] +> 
             iter_token_paren (set_as_comment Ast_c.CppMacro);
         end;
@@ -1339,7 +1629,7 @@ let rec find_macro_lineparen xs =
       if condition
       then begin
         msg_macro_noptvirg_single s;
-        macro.tok <- TMacroStmt (TH.info_of_tok macro.tok);
+        macro.tok <- TMacroStmt (s, TH.info_of_tok macro.tok);
       end;
       find_macro_lineparen (line2::xs)
         
@@ -1347,6 +1637,76 @@ let rec find_macro_lineparen xs =
       find_macro_lineparen xs
 
 
+
+(* ------------------------------------------------------------------------- *)
+(* define tobrace init *)
+(* ------------------------------------------------------------------------- *)
+
+let rec find_define_init_brace_paren xs = 
+ let rec aux xs = 
+  match xs with
+  | [] -> ()
+
+  (* mainly for firefox *)
+  | (PToken {tok = TDefine _})
+    ::(PToken {tok = TIdentDefine (s,_)})
+    ::(PToken ({tok = TOBrace i1} as tokbrace))
+    ::(PToken tok2)
+    ::(PToken tok3)
+    ::xs -> 
+      let is_init =
+        match tok2.tok, tok3.tok with
+        | TInt _, TComma _ -> true
+        | TString _, TComma _ -> true
+        | TIdent _, TComma _ -> true
+        | _ -> false
+            
+      in
+      if is_init
+      then begin 
+        pr2_cpp("found define initializer: " ^s);
+        tokbrace.tok <- TOBraceDefineInit i1;
+      end;
+
+      aux xs
+
+  (* mainly for linux, especially in sound/ *)
+  | (PToken {tok = TDefine _})
+    ::(PToken {tok = TIdentDefine (s,_)})
+    ::(Parenthised(xxx, info_parens))
+    ::(PToken ({tok = TOBrace i1} as tokbrace))
+    ::(PToken tok2)
+    ::(PToken tok3)
+    ::xs -> 
+      let is_init =
+        match tok2.tok, tok3.tok with
+        | TInt _, TComma _ -> true
+        | TDot _, TIdent _ -> true
+        | TIdent _, TComma _ -> true
+        | _ -> false
+            
+      in
+      if is_init
+      then begin 
+        pr2_cpp("found define initializer with param: " ^ s);
+        tokbrace.tok <- TOBraceDefineInit i1;
+      end;
+
+      aux xs
+
+    
+
+  (* recurse *)
+  | (PToken x)::xs -> aux xs 
+  | (Parenthised (xxs, info_parens))::xs -> 
+      (* not need for tobrace init:
+       *  xxs +> List.iter aux; 
+       *)
+      aux xs
+ in
+ aux xs
+
+
 (* ------------------------------------------------------------------------- *)
 (* action *)
 (* ------------------------------------------------------------------------- *)
@@ -1451,6 +1811,7 @@ let insert_virtual_positions l =
        | _ -> x::skip_fake xs in
   skip_fake l
 
+(* ------------------------------------------------------------------------- *)
 let fix_tokens_cpp2 tokens = 
   let tokens2 = ref (tokens +> acc_map mk_token_extended) in
   
@@ -1472,6 +1833,8 @@ let fix_tokens_cpp2 tokens =
       not (TH.is_comment x.tok) (* could filter also #define/#include *)
     ) in
     let ifdef_grouped = mk_ifdef cleaner in
+    set_ifdef_parenthize_info ifdef_grouped;
+
     find_ifdef_funheaders ifdef_grouped;
     find_ifdef_bool       ifdef_grouped;
     find_ifdef_mid        ifdef_grouped;
@@ -1503,6 +1866,7 @@ let fix_tokens_cpp2 tokens =
 
     let paren_grouped      = mk_parenthised  cleaner in
     let line_paren_grouped = mk_line_parenthised paren_grouped in
+    find_define_init_brace_paren paren_grouped;
     find_string_macro_paren paren_grouped;
     find_macro_lineparen    line_paren_grouped;
     find_macro_paren        paren_grouped;
@@ -1517,8 +1881,11 @@ let fix_tokens_cpp2 tokens =
     insert_virtual_positions (!tokens2 +> acc_map (fun x -> x.tok))
   end
 
+let time_hack1 a = 
+  Common.profile_code_exclusif "HACK" (fun () -> fix_tokens_cpp2 a)
+
 let fix_tokens_cpp a = 
-  Common.profile_code "C parsing.fix_cpp" (fun () -> fix_tokens_cpp2 a)
+  Common.profile_code "C parsing.fix_cpp" (fun () -> time_hack1 a)
 
 
 
@@ -1618,7 +1985,7 @@ let rec define_ident acc xs =
          let acc = (TIdentDefine (s,i2)) :: acc in
           define_ident acc xs
       | _ -> 
-          pr2 "wierd #define body"; 
+          pr2 "WIERD: wierd #define body"; 
           define_ident acc xs
       )
   | x::xs ->
@@ -1635,9 +2002,20 @@ let fix_tokens_define a =
       
 
 (*****************************************************************************)
-(* for the cpp-builtin *)
+(* for the cpp-builtin, standard.h, part 0 *)
 (*****************************************************************************)
 
+let macro_body_to_maybe_hint body = 
+  match body with
+  | [] -> DefineBody body
+  | [TIdent (s,i1)] -> 
+      (match parsinghack_hint_of_string s with
+      | Some hint -> DefineHint hint
+      | None -> DefineBody body
+      )
+  | xs -> DefineBody body
+
+
 let rec define_parse xs = 
   match xs with
   | [] -> []
@@ -1654,7 +2032,7 @@ let rec define_parse xs =
         ) in
       let body = body +> List.map 
         (TH.visitor_info_of_tok Ast_c.make_expanded) in
-      let def = (s, (Right params, body)) in
+      let def = (s, (s, Params params, macro_body_to_maybe_hint body)) in
       def::define_parse xs
 
   | TDefine i1::TIdentDefine (s,i2)::xs -> 
@@ -1662,10 +2040,11 @@ let rec define_parse xs =
         xs +> Common.split_when (function TDefEOL _ -> true | _ -> false) in
       let body = body +> List.map 
         (TH.visitor_info_of_tok Ast_c.make_expanded) in
-      let def = (s, (Left (), body)) in
+      let def = (s, (s, NoParam, macro_body_to_maybe_hint body)) in
       def::define_parse xs
 
   | TDefine i1::_ -> 
+      pr2_gen i1;
       raise Impossible
   | x::xs -> define_parse xs 
       
@@ -1693,54 +2072,8 @@ let extract_cpp_define xs =
  * todo?: maybe could try to get rid of this technique. Maybe a better
  * set_context() would make possible to move this code using a fix_xx
  * technique.
- *)
-
-open Lexer_parser (* for the fields of lexer_hint type *)
-
-let not_struct_enum = function
-  | (Parser_c.Tstruct _ | Parser_c.Tunion _ | Parser_c.Tenum _)::_ -> false
-  | _ -> true
-
-
-let not_annot s = 
-  not (s ==~ regexp_annot)
-
-
-let forLOOKAHEAD = 30
-
-  
-(* look if there is a '{' just after the closing ')', and handling the
- * possibility to have nested expressions inside nested parenthesis 
- *)
-let rec is_really_foreach xs = 
-  let rec is_foreach_aux = function
-    | [] -> false, []
-    | TCPar _::TOBrace _::xs -> true, xs
-      (* the following attempts to handle the cases where there is a
-        single statement in the body of the loop.  undoubtedly more
-        cases are needed. 
-         todo: premier(statement) - suivant(funcall)
-      *)
-    | TCPar _::TIdent _::xs -> true, xs
-    | TCPar _::Tif _::xs -> true, xs
-    | TCPar _::Twhile _::xs -> true, xs
-    | TCPar _::Tfor _::xs -> true, xs
-    | TCPar _::Tswitch _::xs -> true, xs
-
-    | TCPar _::xs -> false, xs
-    | TOPar _::xs -> 
-        let (_, xs') = is_foreach_aux xs in
-        is_foreach_aux xs'
-    | x::xs -> is_foreach_aux xs
-  in
-  is_foreach_aux xs +> fst
-
-
-let ok_typedef s = not (List.mem s false_typedef)
-
-
-
-(* LALR(k) trick. We can do stuff by adding cases in lexer_c.mll, but
+ * 
+ * LALR(k) trick. We can do stuff by adding cases in lexer_c.mll, but
  * it is more general to do it via my LALR(k) tech. Because here we can
  * transform some token give some context information. So sometimes it
  * makes sense to transform a token in one context, sometimes not, and
@@ -1752,8 +2085,14 @@ let ok_typedef s = not (List.mem s false_typedef)
  * 
  *)
 
+open Lexer_parser (* for the fields of lexer_hint type *)
+
+let not_struct_enum = function
+  | (Parser_c.Tstruct _ | Parser_c.Tunion _ | Parser_c.Tenum _)::_ -> false
+  | _ -> true
 
-let lookahead2 next before = 
+
+let lookahead2 ~pass next before = 
 
   match (next, before) with
 
@@ -1800,7 +2139,7 @@ let lookahead2 next before =
 
   (* [,(] xx [,)] AND param decl *)
   | (TIdent (s, i1)::(TComma _|TCPar _)::_ , (TComma _ |TOPar _)::_ )
-    when not_struct_enum before && !LP._lexer_hint.parameterDeclaration
+    when not_struct_enum before && (LP.current_context() = LP.InParameter)
       && ok_typedef s
       -> 
       msg_typedef s; LP.add_typedef_root s;
@@ -1830,7 +2169,7 @@ let lookahead2 next before =
 
 
   (* xx const *   USELESS because of next rule ? *)
-  | (TIdent (s, i1)::(Tconst _|Tvolatile _)::TMul _::_ , _ ) 
+  | (TIdent (s, i1)::(Tconst _|Tvolatile _|Trestrict _)::TMul _::_ , _ ) 
       when not_struct_enum before 
       (* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
       && ok_typedef s
@@ -1840,7 +2179,7 @@ let lookahead2 next before =
       TypedefIdent (s, i1)
   
   (* xx const *)
-  | (TIdent (s, i1)::(Tconst _|Tvolatile _)::_ , _ ) 
+  | (TIdent (s, i1)::(Tconst _|Tvolatile _|Trestrict _)::_ , _ ) 
       when not_struct_enum before 
       && ok_typedef s
       (* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
@@ -1851,7 +2190,7 @@ let lookahead2 next before =
 
 
   (* xx * const *)
-  | (TIdent (s, i1)::TMul _::(Tconst _ | Tvolatile _)::_ , _ ) 
+  | (TIdent (s, i1)::TMul _::(Tconst _ | Tvolatile _|Trestrict _)::_ , _ ) 
       when not_struct_enum before 
       && ok_typedef s
       ->
@@ -1862,7 +2201,7 @@ let lookahead2 next before =
 
 
   (* ( const xx)  *)
-  | (TIdent (s, i1)::TCPar _::_,  (Tconst _ | Tvolatile _)::TOPar _::_) when
+  | (TIdent (s, i1)::TCPar _::_,  (Tconst _ | Tvolatile _|Trestrict _)::TOPar _::_) when
       ok_typedef s ->
       msg_typedef s; LP.add_typedef_root s;
       TypedefIdent (s, i1)
@@ -1870,7 +2209,7 @@ let lookahead2 next before =
 
 
   (* ( xx ) [sizeof, ~] *)
-  | (TIdent (s, i1)::TCPar _::(Tsizeof _|TTilde _)::_ , TOPar _::_ )
+  | (TIdent (s, i1)::TCPar _::(Tsizeof _|TTilde _)::_ ,     TOPar _::_ )
     when not_struct_enum before
       && ok_typedef s
     -> 
@@ -1879,7 +2218,7 @@ let lookahead2 next before =
 
   (* [(,] xx [   AND parameterdeclaration *)
   | (TIdent (s, i1)::TOCro _::_, (TComma _ |TOPar _)::_)
-      when !LP._lexer_hint.parameterDeclaration
+      when (LP.current_context() = LP.InParameter)
       && ok_typedef s
      -> 
       msg_typedef s; LP.add_typedef_root s;
@@ -1892,7 +2231,7 @@ let lookahead2 next before =
 
   (* static xx * yy  *)
   | (TIdent (s, i1)::TMul _::TIdent (s2, i2)::_ , 
-     (Tregister _|Tstatic _  |Tvolatile _|Tconst _)::_) when
+     (Tregister _|Tstatic _  |Tvolatile _|Tconst _|Trestrict _)::_) when
       ok_typedef s 
         ->
       msg_typedef s; LP.add_typedef_root s;
@@ -1903,7 +2242,7 @@ let lookahead2 next before =
 
   (*  xx * yy,      AND  in paramdecl *)
   | (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TComma _::_ , _)
-    when not_struct_enum before && !LP._lexer_hint.parameterDeclaration 
+    when not_struct_enum before && (LP.current_context() = LP.InParameter)
       && ok_typedef s 
       -> 
 
@@ -1915,13 +2254,14 @@ let lookahead2 next before =
   | (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TPtVirg _::_ , TEq _::_) ->
       TIdent (s, i1)
   | (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TPtVirg _::_ , _)
-    when not_struct_enum before && !LP._lexer_hint.toplevel  -> 
+    when not_struct_enum before && (LP.is_top_or_struct (LP.current_context ()))
+      -> 
       msg_typedef s; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (*  xx * yy ,     AND in Toplevel  *)
   | (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TComma _::_ , _)
-    when not_struct_enum before && !LP._lexer_hint.toplevel  
+    when not_struct_enum before && (LP.current_context () = LP.InTopLevel)
       && ok_typedef s 
       -> 
 
@@ -1930,7 +2270,8 @@ let lookahead2 next before =
 
   (*  xx * yy (     AND in Toplevel  *)
   | (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TOPar _::_ , _)
-    when not_struct_enum before  && !LP._lexer_hint.toplevel 
+    when not_struct_enum before 
+      && (LP.is_top_or_struct (LP.current_context ()))
       && ok_typedef s 
       ->
       msg_typedef s; LP.add_typedef_root s;
@@ -1940,7 +2281,7 @@ let lookahead2 next before =
   (* todo? enough ? cos in struct def we can have some expression ! *)
   | (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TOCro _::_ , _)
     when not_struct_enum before && 
-      (!LP._lexer_hint.structDefinition > 0 || !LP._lexer_hint.toplevel)
+      (LP.is_top_or_struct (LP.current_context ()))
       && ok_typedef s 
       -> 
       msg_typedef s;  LP.add_typedef_root s;
@@ -1948,7 +2289,7 @@ let lookahead2 next before =
 
   (* u16: 10; in struct *)
   | (TIdent (s, i1)::TDotDot _::_ , (TOBrace _ | TPtVirg _)::_)
-    when (!LP._lexer_hint.structDefinition > 0 || !LP._lexer_hint.toplevel)
+    when       (LP.is_top_or_struct (LP.current_context ()))
       && ok_typedef s 
       -> 
       msg_typedef s;  LP.add_typedef_root s;
@@ -1980,7 +2321,7 @@ let lookahead2 next before =
 
   (*  xx * yy)      AND in paramdecl *)
   | (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TCPar _::_ , _)
-      when not_struct_enum before && !LP._lexer_hint.parameterDeclaration
+      when not_struct_enum before && (LP.current_context () = LP.InParameter)
       && ok_typedef s 
         ->
       msg_typedef s; LP.add_typedef_root s;
@@ -1993,7 +2334,7 @@ let lookahead2 next before =
       && ok_typedef s 
         ->
       msg_typedef s;  LP.add_typedef_root s;
-      pr2 ("PB MAYBE: dangerous typedef inference, maybe not a typedef: " ^ s);
+      msg_maybe_dangereous_typedef s;
       TypedefIdent (s, i1)
 
 
@@ -2045,33 +2386,42 @@ let lookahead2 next before =
 
 
   (* ----------------------------------- *)
+  (* old: why not do like for other rules and start with TIdent ? 
+   * why do TOPar :: TIdent :: ..., _  and not TIdent :: ...,  TOPAr::_ ?
+   * new: prefer now start with TIdent because otherwise the add_typedef_root
+   * may have no effect if in second pass or if have disable the add_typedef.
+   *)
 
   (*  (xx) yy *)
-  | (TOPar info::TIdent (s, i1)::TCPar i2::(TIdent (_,i3)|TInt (_,i3))::_ , 
-    x::_)  
+  | (TIdent (s, i1)::TCPar i2::(TIdent (_,i3)|TInt (_,i3))::_ , 
+    (TOPar info)::x::_)  
     when not (TH.is_stuff_taking_parenthized x) &&
       Ast_c.line_of_info i2 = Ast_c.line_of_info i3
       && ok_typedef s 
       -> 
 
       msg_typedef s; LP.add_typedef_root s;
-      TOPar info
+      (*TOPar info*)
+      TypedefIdent (s, i1)
 
 
   (*  (xx) (    yy) *)
-  | (TOPar info::TIdent (s, i1)::TCPar _::TOPar _::_ , x::_)  
+  | (TIdent (s, i1)::TCPar _::TOPar _::_ , (TOPar info)::x::_)  
     when not (TH.is_stuff_taking_parenthized x)  
       && ok_typedef s 
         ->
       msg_typedef s; LP.add_typedef_root s;
-      TOPar info
+      (* TOPar info *)
+      TypedefIdent (s, i1)
 
   (*  (xx * ) yy *)
-  | (TOPar info::TIdent (s, i1)::TMul _::TCPar _::TIdent (s2, i2)::_ , _) when 
+  | (TIdent (s, i1)::TMul _::TCPar _::TIdent (s2, i2)::_ , (TOPar info)::_) when 
       ok_typedef s 
         -> 
       msg_typedef s; LP.add_typedef_root s;
-      TOPar info
+      (*TOPar info*)
+      TypedefIdent (s,i1)
+
 
   (* (xx){ ... }  constructor *)
   | (TIdent (s, i1)::TCPar _::TOBrace _::_ , TOPar _::x::_)  
@@ -2100,28 +2450,49 @@ let lookahead2 next before =
   (*-------------------------------------------------------------*)
   (* CPP *)
   (*-------------------------------------------------------------*)
-  | ((TIfdef ii |TIfdefelse ii |TIfdefelif ii |TEndif ii |
-      TIfdefBool (_,ii)|TIfdefMisc(_,ii)|TIfdefVersion(_,ii))
+  | ((TIfdef (_,ii) |TIfdefelse (_,ii) |TIfdefelif (_,ii) |TEndif (_,ii) |
+      TIfdefBool (_,_,ii)|TIfdefMisc(_,_,ii)|TIfdefVersion(_,_,ii))
         as x)
     ::_, _ 
       -> 
+      (*
       if not !Flag_parsing_c.ifdef_to_if 
       then TCommentCpp (Ast_c.CppDirective, ii)
       else 
-        if not !LP._lexer_hint.toplevel
-        then x
-        else begin
-          pr2_cpp("IFDEF: or related outside function. I treat it as comment");
+      *)
+         (* not !LP._lexer_hint.toplevel *)
+        if !Flag_parsing_c.ifdef_directive_passing
+            || (pass = 2)
+        then begin
+
+          if (LP.current_context () = LP.InInitializer)
+          then begin 
+            pr2 "In Initializer passing"; (* cheat: dont count in stat *)
+            incr Stat.nIfdefInitializer;
+            
+          end
+          else msg_ifdef_passing ()
+          ;
+
           TCommentCpp (Ast_c.CppDirective, ii)
         end
+        else x
 
+  | (TUndef (id, ii) as x)::_, _ 
+      -> 
+        if (pass = 2)
+        then begin
+          pr2_once ("CPP-UNDEF: I treat it as comment");
+          TCommentCpp (Ast_c.CppDirective, ii)
+        end
+        else x
 
    (* If ident contain a for_each, then certainly a macro. But to be
     * sure should look if there is a '{' after the ')', but it requires
     * to count the '('. Because this can be expensive, we do that only
     * when the token contains "for_each". 
     *)
-  | (TIdent (s, i1)::TOPar _::rest, _) when not !LP._lexer_hint.toplevel  
+  | (TIdent (s, i1)::TOPar _::rest, _) when not (LP.current_context () = LP.InTopLevel)
       (* otherwise a function such as static void loopback_enable(int i) { 
        * will be considered as a loop 
        *)
@@ -2143,7 +2514,7 @@ let lookahead2 next before =
  | v::xs, _ -> v
  | _ -> raise Impossible
 
-let lookahead a b = 
-  Common.profile_code "C parsing.lookahead" (fun () -> lookahead2 a b)
+let lookahead ~pass a b = 
+  Common.profile_code "C parsing.lookahead" (fun () -> lookahead2 ~pass a b)
 
 
index 3897a47..dbf050f 100644 (file)
@@ -1,8 +1,8 @@
 open Common 
 
-(* Try detect some cpp idioms so can parse as is files by adjusting or
+(* Try detect some cpp idioms so can parse as-is files by adjusting or
  * commenting some tokens. Parsing hack style. Sometime use indentation info,
- * Sometimes do some kind of lalr(k) by finding patterns. Often try to
+ * sometimes do some kind of lalr(k) by finding patterns. Often try to
  * work on better token representation, like ifdef-paren-ized, brace-ized,
  * paren-ized, so can do easier pattern matching to more easily match
  * complex cpp idiom pattern. Also try to get context info such as
@@ -32,18 +32,38 @@ open Common
  * end-of-line token.
  *)
 
-(* the either is to differentialte macro-variables from macro-functions *)
-type define_body = (unit,string list) either * Parser_c.token list
+(* corresponds to what is in the yacfe configuration file (e.g. standard.h) *)
+type define_def = string * define_param * define_body 
+ and define_param = 
+   | NoParam
+   | Params of string list
+ and define_body = 
+   | DefineBody of Parser_c.token list
+   | DefineHint of parsinghack_hint
 
-val _defs : (string, define_body) Hashtbl.t ref
+   (* strongly corresponds to the TMacroXxx in the grammar and lexer and the
+    * MacroXxx in the ast.
+    *)
+   and parsinghack_hint = 
+     | HintIterator
+     | HintDeclarator
+     | HintMacroString
+     | HintMacroStatement
+     | HintAttribute
 
+val _defs : (string, define_def) Hashtbl.t ref
+
+(* can reset it *)
+val ifdef_paren_cnt: int ref
 
 val fix_tokens_define : Parser_c.token list -> Parser_c.token list
-val extract_cpp_define : Parser_c.token list -> (string, define_body) assoc
+val extract_cpp_define : Parser_c.token list -> (string, define_def) assoc
 
 
 val fix_tokens_cpp : Parser_c.token list -> Parser_c.token list
 
 (* next stream tokens -> passed stream tokens -> final next token *)
-val lookahead : Parser_c.token list -> Parser_c.token list -> Parser_c.token
+val lookahead : 
+  pass:int -> 
+  Parser_c.token list -> Parser_c.token list -> Parser_c.token
 
diff --git a/parsing_c/parsing_stat.ml b/parsing_c/parsing_stat.ml
new file mode 100644 (file)
index 0000000..a5cb607
--- /dev/null
@@ -0,0 +1,274 @@
+open Common 
+
+(* if do .mli:
+val print_parsing_stat_list: parsing_stat list -> unit
+*)
+
+(*****************************************************************************)
+(* Stat *)
+(*****************************************************************************)
+type parsing_stat = {
+    filename: filename;
+    mutable have_timeout: bool;
+
+    mutable correct: int;  
+    mutable bad: int;
+
+    mutable commentized: int; (* by our cpp commentizer *)
+
+    (* if want to know exactly what was passed through, uncomment:
+     *  
+     * mutable passing_through_lines: int;
+     * 
+     * it differs from bad by starting from the error to
+     * the synchro point instead of starting from start of
+     * function to end of function.
+     *)
+
+  } 
+
+let default_stat file =  { 
+    filename = file;
+    have_timeout = false;
+    correct = 0; bad = 0;
+    commentized = 0;
+  }
+
+(* todo: stat per dir ?  give in terms of func_or_decl numbers:   
+ * nbfunc_or_decl pbs / nbfunc_or_decl total ?/ 
+ *
+ * note: cela dit si y'a des fichiers avec des #ifdef dont on connait pas les 
+ * valeurs alors on parsera correctement tout le fichier et pourtant y'aura 
+ * aucune def  et donc aucune couverture en fait.   
+ * ==> TODO evaluer les parties non parsé ? 
+ *)
+
+let print_parsing_stat_list ?(verbose=false) = fun statxs -> 
+  let total = List.length statxs in
+  let perfect = 
+    statxs 
+      +> List.filter (function 
+          {have_timeout = false; bad = 0} -> true | _ -> false)
+      +> List.length 
+  in
+
+  if verbose then begin
+  pr "\n\n\n---------------------------------------------------------------";
+  pr "pbs with files:";
+  statxs 
+    +> List.filter (function 
+      | {have_timeout = true} -> true 
+      | {bad = n} when n > 0 -> true 
+      | _ -> false)
+    +> List.iter (function 
+        {filename = file; have_timeout = timeout; bad = n} -> 
+          pr (file ^ "  " ^ (if timeout then "TIMEOUT" else i_to_s n));
+        );
+
+  pr "\n\n\n";
+  pr "files with lots of tokens passed/commentized:";
+  let threshold_passed = 100 in
+  statxs 
+    +> List.filter (function 
+      | {commentized = n} when n > threshold_passed -> true
+      | _ -> false)
+    +> List.iter (function 
+        {filename = file; commentized = n} -> 
+          pr (file ^ "  " ^ (i_to_s n));
+        );
+
+  pr "\n\n\n---------------------------------------------------------------";
+  end;
+
+  pr (
+  (sprintf "NB total files = %d; " total) ^
+  (sprintf "perfect = %d; " perfect) ^
+  (sprintf "pbs = %d; "     (statxs +> List.filter (function 
+      {have_timeout = b; bad = n} when n > 0 -> true | _ -> false) 
+                               +> List.length)) ^
+  (sprintf "timeout = %d; " (statxs +> List.filter (function 
+      {have_timeout = true; bad = n} -> true | _ -> false) 
+                               +> List.length)) ^
+  (sprintf "=========> %d" ((100 * perfect) / total)) ^ "%"
+                                                          
+  );
+  let good = statxs +> List.fold_left (fun acc {correct = x} -> acc+x) 0 in
+  let bad  = statxs +> List.fold_left (fun acc {bad = x} -> acc+x) 0  in
+  let passed = statxs +> List.fold_left (fun acc {commentized = x} -> acc+x) 0
+  in
+  let gf, badf = float_of_int good, float_of_int bad in
+  let passedf = float_of_int passed in
+  pr (
+  (sprintf "nb good = %d,  nb passed = %d " good passed) ^
+  (sprintf "=========> %f"  (100.0 *. (passedf /. gf)) ^ "%")
+   );
+  pr (
+  (sprintf "nb good = %d,  nb bad = %d " good bad) ^
+  (sprintf "=========> %f"  (100.0 *. (gf /. (gf +. badf))) ^ "%"
+   )
+  )
+
+(*****************************************************************************)
+(* Stat *)
+(*****************************************************************************)
+
+(* coupling: if you add a new var, modify also assoc_stat_number below *)
+
+let nTypedefInfer = ref 0
+
+let nIncludeGrammar = ref 0
+let nIncludeHack = ref 0
+
+let nIteratorGrammar = ref 0 
+let nIteratorHeuristic = ref 0 
+
+let nMacroTopDecl = ref 0
+let nMacroStructDecl = ref 0
+let nMacroDecl = ref 0
+let nMacroStmt = ref 0
+let nMacroString = ref 0
+let nMacroHigherOrder = ref 0 (* actions *)
+let nMacrohigherTypeGrammar = ref 0
+let nMacroAttribute = ref 0
+
+let nIfdefTop = ref 0
+let nIfdefStmt = ref 0
+let nIfdefStruct = ref 0
+let nIfdefInitializer = ref 0
+(* nIfdefExpr, nIfdefType *)
+
+let nIfdefFunheader = ref 0
+
+let nIfdefExprPassing = ref 0
+let nIfdefPassing = ref 0
+
+let nIncludePassing = ref 0
+let nDefinePassing = ref 0
+
+let nIfdefZero = ref 0
+let nIfdefVersion = ref 0
+
+
+
+let nGccTypeof = ref 0
+let nGccLongLong = ref 0
+let nGccAsm = ref 0
+let nGccInline = ref 0
+let nGccAttribute = ref 0
+let nGccCaseRange = ref 0
+let nGccMixDecl = ref 0
+let nGccDesignator = ref 0
+let nGccStmtExpr = ref 0
+let nGccConstructor = ref 0
+let nGccEmptyStruct = ref 0
+let nGccNestedFunc = ref 0
+
+let nGccMisc = ref 0
+
+
+
+let nDefineHack = ref 0
+
+let nDefineConstant = ref 0
+let nDefineStmt = ref 0
+let nDefineExpr = ref 0
+(* both below require some heuristic support *)
+let nDefineWhile0 = ref 0
+let nDefineInit = ref 0
+
+let nDefineOther = ref 0
+
+let nUndef = ref 0
+let nPragmaAndCo = ref 0
+
+(* let nDirectiveTop = ref 0 *)
+let nDirectiveStmt = ref 0
+let nDirectiveStruct = ref 0
+let nDirectiveInitializer = ref 0
+
+
+(* from standard.h *)
+let nMacroHint = ref 0
+let nMacroExpand = ref 0
+
+let nNotParsedCorrectly = ref 0
+
+let assoc_stat_number = 
+  [
+    "nTypedefInfer", nTypedefInfer;
+
+    "nIteratorHeuristic", nIteratorHeuristic;
+
+    "nMacroTopDecl", nMacroTopDecl;
+    "nMacroStructDecl", nMacroStructDecl;
+    "nMacroDecl", nMacroDecl;
+    "nMacroStmt", nMacroStmt;
+    "nMacroString", nMacroString;
+    "nMacroHigherOrder", nMacroHigherOrder;
+    "nMacroAttribute", nMacroAttribute;
+
+    "nMacrohigherTypeGrammar", nMacrohigherTypeGrammar;
+
+    "nIfdefTop", nIfdefTop;
+    "nIfdefStmt", nIfdefStmt;
+    "nIfdefStruct", nIfdefStruct;
+    "nIfdefInitializer", nIfdefInitializer;
+
+    "nIfdefFunheader", nIfdefFunheader;
+    "nIfdefZero", nIfdefZero;
+    "nIfdefVersion", nIfdefVersion;
+    "nIfdefExprPassing", nIfdefExprPassing;
+    "nIfdefPassing", nIfdefPassing;
+
+    "nIncludePassing", nIncludePassing;
+    "nDefinePassing", nDefinePassing;
+
+    "nMacroExpand", nMacroExpand;
+    "nMacroHint", nMacroHint;
+
+
+    "nGccTypeof", nGccTypeof;
+    "nGccLongLong", nGccLongLong;
+    "nGccAsm", nGccAsm;
+    "nGccInline", nGccInline;
+    "nGccAttribute", nGccAttribute;
+    "nGccCaseRange", nGccCaseRange;
+    "nGccMixDecl", nGccMixDecl;
+    "nGccDesignator", nGccDesignator;
+    "nGccStmtExpr", nGccStmtExpr;
+    "nGccConstructor", nGccConstructor;
+    "nGccEmptyStruct", nGccEmptyStruct;
+    "nGccNestedFunc", nGccNestedFunc;
+
+    "nGccMisc", nGccMisc;
+
+
+    "nDefineHack", nDefineHack;
+
+    "nDefineConstant", nDefineConstant;
+    "nDefineStmt", nDefineStmt;
+    "nDefineExpr", nDefineExpr;
+    "nDefineInit", nDefineInit;
+    "nDefineOther", nDefineOther;
+
+    "nUndef", nUndef;
+    "nPragmaAndCo", nPragmaAndCo;
+
+    "nDirectiveStmt", nDirectiveStmt;
+    "nDirectiveStruct", nDirectiveStruct;
+    "nDirectiveInitializer", nDirectiveInitializer;
+
+    "nNotParsedCorrectly", nNotParsedCorrectly;
+
+
+    (* less *)
+    "nIncludeGrammar", nIncludeGrammar;
+    "nIncludeHack", nIncludeHack;
+
+    "nIteratorGrammar", nIteratorGrammar;
+  ]
+
+let print_stat_numbers () = 
+  assoc_stat_number +> List.iter (fun (k, vref) -> 
+    pr2 (spf "%-30s -> %d" k !vref);
+  )
index be1931b..0c8bef0 100644 (file)
@@ -1,4 +1,4 @@
-(* Copyright (C) 2002-2008 Yoann Padioleau
+(* Copyright (C) 2006, 2007, 2008 Yoann Padioleau
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License (GPL)
@@ -16,6 +16,8 @@ open Ast_c
 type pr_elem_func = Ast_c.info -> unit
 type pr_space_func = unit -> unit
 
+module F = Control_flow_c
+
 (*****************************************************************************)
 
 (* This module is used by unparse_c, but because unparse_c have also
@@ -30,7 +32,8 @@ type pr_space_func = unit -> unit
 let rec pp_expression_gen pr_elem pr_space = 
   (* subtil: dont try to shorten the def of pp_statement by omitting e,
      otherwise get infinite funcall and huge memory consumption *)
-  let pp_statement e = pp_statement_gen pr_elem pr_space e in
+  let _pp_statement e = pp_statement_gen pr_elem pr_space e in
+
   let rec pp_expression = fun ((exp, typ), ii) -> 
     (match exp, ii with
     | Ident (c),         [i]     -> pr_elem i
@@ -79,7 +82,7 @@ let rec pp_expression_gen pr_elem pr_space =
     | StatementExpr (statxs, [ii1;ii2]),  [i1;i2] -> 
         pr_elem i1;
         pr_elem ii1;
-        statxs +> List.iter pp_statement;
+        statxs +> List.iter (pp_statement_seq_gen pr_elem pr_space);
         pr_elem ii2;
         pr_elem i2;
     | Constructor (t, xs), lp::rp::i1::i2::iicommaopt -> 
@@ -109,6 +112,7 @@ let rec pp_expression_gen pr_elem pr_space =
         | ParenExpr (_)
       ),_ -> raise Impossible
     );
+
     if !Flag_parsing_c.pretty_print_type_info
     then begin
       pr_elem (Ast_c.fakeInfo() +> Ast_c.rewrap_str "/*");
@@ -156,7 +160,9 @@ and pp_statement_gen pr_elem pr_space =
         pp_statement st
     | Labeled (Default st), [i1;i2] -> pr_elem i1; pr_elem i2; pp_statement st
     | Compound statxs, [i1;i2] -> 
-        pr_elem i1; statxs +> List.iter pp_statement; pr_elem i2;
+        pr_elem i1; 
+        statxs +> List.iter (pp_statement_seq_gen pr_elem pr_space); 
+        pr_elem i2;
         
     | ExprStatement (None), [i] -> pr_elem i;
     | ExprStatement (None), [] -> ()
@@ -239,19 +245,6 @@ and pp_statement_gen pr_elem pr_space =
     | MacroStmt, ii -> 
         ii +> List.iter pr_elem ;
 
-    | Selection  (Ifdef (st1s, st2s)), i1::i2::is -> 
-        pr_elem i1; 
-        st1s +> List.iter pp_statement; 
-        (match (st2s, is) with
-        | [], [iifakend] -> pr_elem i2; pr_elem iifakend
-        | x::xs, [i3;iifakend] -> 
-            pr_elem i2;
-            st2s +> List.iter pp_statement; 
-            pr_elem i3;
-            pr_elem iifakend
-              
-        | _ -> raise Impossible
-        )
     | ( Labeled (Label (_,_)) | Labeled (Case  (_,_)) 
         | Labeled (CaseRange  (_,_,_)) | Labeled (Default _)
         | Compound _ | ExprStatement _ 
@@ -261,13 +254,41 @@ and pp_statement_gen pr_elem pr_space =
         | Iteration  (MacroIteration (_,_,_))
         | Jump (Goto _) | Jump ((Continue|Break|Return)) | Jump (ReturnExpr _)
         | Jump (GotoComputed _)
-        | Decl _ | Selection (Ifdef (_,_))
+        | Decl _ 
       ), _ -> raise Impossible
 
   in
   pp_statement
 
+and pp_statement_seq_gen pr_elem pr_space stseq = 
+  match stseq with
+  | StmtElem st -> 
+      pp_statement_gen pr_elem pr_space st
+  | IfdefStmt ifdef -> pp_ifdef_gen pr_elem pr_space ifdef
+  | CppDirectiveStmt cpp -> pp_directive_gen pr_elem pr_space cpp
+  | IfdefStmt2 (ifdef, xxs) -> 
+      pp_ifdef_tree_sequence pr_elem pr_space ifdef xxs
+
+(* ifdef XXX elsif YYY elsif ZZZ endif *)
+and pp_ifdef_tree_sequence pr_elem pr_space ifdef xxs = 
+  match ifdef with
+  | if1::ifxs -> 
+      pp_ifdef_gen   pr_elem pr_space    if1;
+      pp_ifdef_tree_sequence_aux    pr_elem pr_space  ifxs xxs
+  | _ -> raise Impossible
+
+(* XXX elsif YYY elsif ZZZ endif *)
+and pp_ifdef_tree_sequence_aux pr_elem pr_space ifdefs xxs = 
+  Common.zip ifdefs xxs +> List.iter (fun (ifdef, xs) -> 
+    xs +> List.iter (pp_statement_seq_gen pr_elem pr_space);
+    pp_ifdef_gen pr_elem pr_space ifdef;
+  )
+
+      
+
 
+
+(* ---------------------- *)
 and pp_asmbody_gen pr_elem pr_space (string_list, colon_list) = 
   string_list +> List.iter pr_elem ;
   colon_list +> List.iter (fun (Colon xs, ii) -> 
@@ -282,20 +303,33 @@ and pp_asmbody_gen pr_elem pr_space (string_list, colon_list) =
           pr_elem iopar;
           pp_expression_gen pr_elem pr_space e;
           pr_elem icpar
-      | _ -> raise Impossible
+      | (ColonExpr _), _ -> raise Impossible
       )
     ))
   
 
 (* ---------------------- *)
+
+(*
+pp_type_with_ident_gen
+pp_base_type_gen
+pp_type_with_ident_rest_gen
+pp_type_left_gen
+pp_type_right_gen
+pp_type_gen
+
+pp_decl_gen
+*)
 and (pp_type_with_ident_gen: 
         pr_elem_func -> pr_space_func -> 
-      (string * info) option -> (storage * il) option -> fullType -> unit) = 
+      (string * info) option -> (storage * il) option -> 
+      fullType -> attribute list ->
+      unit) = 
   fun pr_elem pr_space ->
-    fun ident sto ((qu, iiqu), (ty, iity)) -> 
+    fun ident sto ((qu, iiqu), (ty, iity)) attrs -> 
       pp_base_type_gen pr_elem pr_space ((qu, iiqu), (ty, iity))  sto;
       pp_type_with_ident_rest_gen pr_elem pr_space ident
-       ((qu, iiqu), (ty, iity))
+       ((qu, iiqu), (ty, iity)) attrs
 
 
 and (pp_base_type_gen: 
@@ -352,10 +386,10 @@ and (pp_base_type_gen:
             );
 
             fields +> List.iter 
-              (fun (xfield, iipttvirg) -> 
+              (fun (xfield, iipttvirg_when_emptyfield) -> 
 
                 match xfield with 
-                | FieldDeclList onefield_multivars -> 
+                | DeclarationField (FieldDeclList (onefield_multivars, iiptvirg)) -> 
                  (match onefield_multivars with
                  | x::xs -> 
                   (* handling the first var. Special case, with the
@@ -372,7 +406,7 @@ and (pp_base_type_gen:
                         | x -> raise Impossible) 
                       in
                       pp_type_with_ident_gen pr_elem pr_space
-                       identinfo None typ;
+                       identinfo None typ Ast_c.noattr;
 
                   | (BitField (sopt, typ, expr), ii), iivirg -> 
                       (* first var cant have a preceding ',' *)
@@ -384,13 +418,13 @@ and (pp_base_type_gen:
                           pp_expression expr
                       | (Some s, [is;idot]) -> 
                           pp_type_with_ident_gen 
-                            pr_elem pr_space (Some (s, is)) None typ;
+                            pr_elem pr_space 
+                            (Some (s, is)) None typ Ast_c.noattr;
                           pr_elem idot;
                           pp_expression expr
                       | x -> raise Impossible
                       )
-                        
-                  );
+                  ); (* match x, first onefield_multivars *)
                   
                   (* for other vars *)
                   xs +> List.iter (function
@@ -403,26 +437,36 @@ and (pp_base_type_gen:
                         | x -> raise Impossible) 
                       in
                       pp_type_with_ident_rest_gen pr_elem pr_space
-                       identinfo typ;
+                       identinfo typ Ast_c.noattr;
 
                   | (BitField (sopt, typ, expr), ii), iivirg -> 
                       iivirg +> List.iter pr_elem;
                       (match sopt, ii with
                       | (Some s, [is;idot]) -> 
                           pp_type_with_ident_rest_gen 
-                            pr_elem pr_space (Some (s, is)) typ;
+                            pr_elem pr_space 
+                            (Some (s, is)) typ Ast_c.noattr;
                           pr_elem idot;
                           pp_expression expr
                       | x -> raise Impossible
                       );
                       
-                  );
+                  ); (* iter other vars *)
+
+              | [] -> raise Impossible
+              ); (* onefield_multivars *)
+              assert (List.length iiptvirg = 1);
+              iiptvirg +> List.iter pr_elem;
+
+              
+            | MacroStructDeclTodo -> pr2 "MacroTodo"
+
 
-                  assert (List.length iipttvirg = 1);
-                  iipttvirg +> List.iter pr_elem;
-              | x -> raise Impossible
-              ) 
-            | EmptyField -> ()
+            | EmptyField -> 
+                iipttvirg_when_emptyfield +> List.iter pr_elem
+
+            | CppDirectiveStruct cpp -> pp_directive_gen pr_elem pr_space cpp
+            | IfdefStruct ifdef -> pp_ifdef_gen pr_elem pr_space ifdef
             );
 
             (match sopt,iis with
@@ -503,8 +547,14 @@ and (pp_base_type_gen:
             | _ -> raise Impossible
             )
 
+        | (Pointer _ | (*ParenType _ |*) Array _ | FunctionType _ 
+            (* | StructUnion _ | Enum _ | BaseType _ *)
+            (* | StructUnionName _ | EnumName _ | TypeName _  *)
+            (* | TypeOfExpr _ | TypeOfType _ *)
+          ), _ -> raise Impossible
+            
+
 
-        | x -> raise Impossible
     in
     pp_base_type
 
@@ -513,10 +563,16 @@ and (pp_base_type_gen:
    int before *j *) 
 and (pp_type_with_ident_rest_gen: 
         pr_elem_func -> pr_space_func ->
-         (string * info) option -> fullType -> unit) = 
+         (string * info) option -> 
+      fullType -> attribute list ->
+      unit) = 
   fun pr_elem pr_space -> 
-    fun ident (((qu, iiqu), (ty, iity)) as fullt) -> 
-      let print_ident ident = do_option (fun (s, iis) -> pr_elem iis) ident
+
+    fun ident (((qu, iiqu), (ty, iity)) as fullt) attrs -> 
+      let print_ident ident = Common.do_option (fun (s, iis) -> 
+        (* XXX attrs +> pp_attributes pr_elem pr_space; *)
+        pr_elem iis
+      ) ident
       in
 
       match ty, iity with
@@ -539,7 +595,7 @@ and (pp_type_with_ident_rest_gen:
           (* bug: pp_type_with_ident_rest None t;      print_ident ident *)
           pr_elem i; 
           iiqu +> List.iter pr_elem; (* le const est forcement apres le '*' *)
-          pp_type_with_ident_rest_gen pr_elem pr_space ident t;
+          pp_type_with_ident_rest_gen pr_elem pr_space ident t attrs;
 
       (* ugly special case ... todo? maybe sufficient in practice *)       
       | (ParenType (q1, (Pointer (q2, (FunctionType t, ii3))   , 
@@ -572,7 +628,7 @@ and (pp_type_with_ident_rest_gen:
 
       | (ParenType t, [i1;i2]) ->  
           pr2 "PB PARENTYPE ZARB, I forget about the ()";
-          pp_type_with_ident_rest_gen pr_elem pr_space ident t;
+          pp_type_with_ident_rest_gen pr_elem pr_space ident t attrs;
           
 
       | (Array (eopt, t), [i1;i2]) -> 
@@ -591,8 +647,10 @@ and (pp_type_with_ident_rest_gen:
           print_ident ident;
 
           pp_type_right_gen pr_elem pr_space fullt;
+          
 
-      | x -> raise Impossible
+      | (FunctionType _ | Array _ | ParenType _ | Pointer _ 
+        ), _ -> raise Impossible
           
 
 and (pp_type_left_gen: pr_elem_func -> pr_space_func -> fullType -> unit) = 
@@ -616,7 +674,12 @@ and (pp_type_left_gen: pr_elem_func -> pr_space_func -> fullType -> unit) =
       | (StructUnionName (s, structunion), iis) -> ()    
       | (EnumName  s, iis) -> ()    
       | (TypeName (s,_typ), iis) -> ()
-      | x -> raise Impossible
+
+      | TypeOfType _, _ -> ()
+      | TypeOfExpr _, _ -> ()
+
+      | (FunctionType _ | Array _ | Pointer _ 
+        ), _ -> raise Impossible
     in
     pp_type_left
 
@@ -630,10 +693,12 @@ and pp_param_gen pr_elem pr_space = fun ((b, sopt, t), ii_b_s) ->
       pp_type_gen pr_elem pr_space t
 
   | false, Some s, [i1] -> 
-      pp_type_with_ident_gen pr_elem pr_space (Some (s, i1)) None t;
+      pp_type_with_ident_gen pr_elem pr_space 
+        (Some (s, i1)) None t Ast_c.noattr;
   | true, Some s, [i1;i2] -> 
       pr_elem i1;
-      pp_type_with_ident_gen pr_elem pr_space (Some (s, i2)) None t;
+      pp_type_with_ident_gen pr_elem pr_space 
+        (Some (s, i2)) None t Ast_c.noattr;
   | _ -> raise Impossible                
 
 
@@ -673,16 +738,25 @@ and (pp_type_right_gen: pr_elem_func -> pr_space_func -> fullType -> unit) =
       | (StructUnionName (s, structunion), iis) -> ()    
       | (EnumName  s, iis) -> ()    
       | (TypeName (s,_typ), iis) -> ()
-      | x -> raise Impossible
+
+      | TypeOfType _, _ -> ()
+      | TypeOfExpr _, _ -> ()
+
+      | (FunctionType _ | Array _ | Pointer _ 
+        ), _ -> raise Impossible
+
     in 
     pp_type_right
 
 and pp_type_gen pr_elem pr_space t =
-  pp_type_with_ident_gen pr_elem pr_space None None t
+  pp_type_with_ident_gen pr_elem pr_space 
+    None None t Ast_c.noattr
 
 (* ---------------------- *)
 and pp_decl_gen pr_elem pr_space = function
-  | DeclList ((((var, returnType, storage, _local),[])::xs), 
+  | DeclList ((({v_namei = var; v_type = returnType;
+                 v_storage = storage; v_attr = attrs;
+                },[])::xs), 
              iivirg::ifakestart::iisto) -> 
 
       pr_elem ifakestart;
@@ -695,7 +769,7 @@ and pp_decl_gen pr_elem pr_space = function
       | Some ((s, ini),  iis::iini) -> 
           pp_type_with_ident_gen pr_elem pr_space
            (Some (s, iis)) (Some (storage, iisto))
-            returnType;
+            returnType attrs;
           ini +> do_option (fun init -> 
             List.iter pr_elem iini; pp_init_gen pr_elem pr_space init);
       | None -> pp_type_gen pr_elem pr_space returnType
@@ -704,11 +778,16 @@ and pp_decl_gen pr_elem pr_space = function
 
       (* for other vars, we just call pp_type_with_ident_rest. *)
       xs +> List.iter (function
-      | ((Some ((s, ini), iis::iini), returnType, storage2, _local), iivirg) ->
+      | ({v_namei = Some ((s, ini), iis::iini);
+          v_type = returnType;
+          v_storage = storage2;
+          v_attr = attrs;
+          }, iivirg) ->
+
           assert (storage2 = storage);
           iivirg +> List.iter pr_elem;
           pp_type_with_ident_rest_gen pr_elem pr_space
-           (Some (s, iis)) returnType;
+           (Some (s, iis)) returnType attrs;
           ini +> do_option (fun (init) -> 
             List.iter pr_elem iini; pp_init_gen pr_elem pr_space init);
 
@@ -732,7 +811,7 @@ and pp_decl_gen pr_elem pr_space = function
       pr_elem rp;
       pr_elem iiend;
 
-  | x -> raise Impossible
+  | (DeclList (_, _) | (MacroDecl _)) -> raise Impossible
       
 
 (* ---------------------- *)
@@ -762,7 +841,10 @@ and pp_init_gen = fun pr_elem pr_space ->
     | InitIndexOld (expression, initialiser), [i1;i2] -> (* [1] in oldgcc *)
         pr_elem i1; pp_expression expression; pr_elem i2; 
         pp_init initialiser
-    | x -> raise Impossible
+
+    | (InitIndexOld _ | InitFieldOld _ | InitDesignators _ 
+        | InitList _ | InitExpr _
+      ), _ -> raise Impossible
   in
   pp_init
 
@@ -779,22 +861,40 @@ and pp_designator pr_elem pr_space design =
   | DesignatorRange (e1, e2), [iocro;iellipsis;iccro] -> 
       pr_elem iocro; pp_expression e1; pr_elem iellipsis;
       pp_expression e2; pr_elem iccro; 
-  | x -> raise Impossible
-     
 
+  | (DesignatorField _ | DesignatorIndex _ | DesignatorRange _
+    ), _ -> raise Impossible
+     
 
+(* ---------------------- *)
+and pp_attributes pr_elem pr_space attrs =
+  attrs +> List.iter (fun (attr, ii) -> 
+    ii +> List.iter pr_elem;
+  );
 
 (* ---------------------- *)
 and pp_def_gen pr_elem pr_space def = 
-  match def with 
-  | ((s, (returnt, (paramst, (b, iib))), sto, statxs), 
-                     is::iifunc1::iifunc2::i1::i2::ifakestart::isto) -> 
+  let defbis, ii = def in
+  match ii with 
+  | is::iifunc1::iifunc2::i1::i2::ifakestart::isto -> 
+
+      let {f_name = s;
+           f_type = (returnt, (paramst, (b, iib)));
+           f_storage = sto;
+           f_body = statxs;
+           f_attr = attrs;
+      } = defbis
+      in
 
          pr_elem ifakestart;
                        
          pp_type_with_ident_gen pr_elem pr_space None (Some (sto, isto)) 
-                         returnt;
+                         returnt Ast_c.noattr;
+
+         pp_attributes pr_elem pr_space attrs;
          pr_elem is;
+
+
          pr_elem iifunc1;
 
         (* not anymore, cf tests/optional_name_parameter and 
@@ -849,33 +949,41 @@ and pp_def_gen pr_elem pr_space def =
 
          pr_elem iifunc2;
          pr_elem i1; 
-         statxs +> List.iter (pp_statement_gen pr_elem pr_space);
+         statxs +> List.iter (pp_statement_seq_gen pr_elem pr_space);
          pr_elem i2;
      | _ -> raise Impossible
 
 
 
+(* ---------------------- *)
+
+and pp_ifdef_gen pr_elem pr_space ifdef = 
+  match ifdef with
+  | IfdefDirective (ifdef, ii) -> 
+      List.iter pr_elem ii
 
-let pp_program_gen pr_elem pr_space progelem =
-  match progelem with
-  | Declaration decl -> pp_decl_gen pr_elem pr_space decl
-  | Definition def -> pp_def_gen pr_elem pr_space def
 
-  | Include ((s, [i1;i2]),h_rel_pos) -> 
+and pp_directive_gen pr_elem pr_space directive = 
+  match directive with
+  | Include {i_include = (s, ii);} -> 
+      let (i1,i2) = Common.tuple_of_list2 ii in
       pr_elem i1; pr_elem i2
-  | Define ((s,[idefine;iident;ieol]), (defkind, defval)) -> 
+  | Define ((s,ii), (defkind, defval)) -> 
+      let (idefine,iident,ieol) = Common.tuple_of_list3 ii in
       pr_elem idefine;
       pr_elem iident;
         
       let define_val = function
         | DefineExpr e -> pp_expression_gen pr_elem pr_space e
         | DefineStmt st -> pp_statement_gen pr_elem pr_space st
-        | DefineDoWhileZero (st, ii) -> 
+        | DefineDoWhileZero ((st,e), ii) -> 
             (match ii with
-            | [ido;iwhile;iopar;iint;icpar] -> 
+            | [ido;iwhile;iopar;icpar] -> 
                 pr_elem ido;
                 pp_statement_gen pr_elem pr_space st;
-                pr_elem iwhile; pr_elem iopar; pr_elem iint; pr_elem icpar
+                pr_elem iwhile; pr_elem iopar; 
+                pp_expression_gen pr_elem pr_space e; 
+                pr_elem icpar
             | _ -> raise Impossible
             )
         | DefineFunction def -> pp_def_gen pr_elem pr_space def
@@ -883,6 +991,10 @@ let pp_program_gen pr_elem pr_space progelem =
         | DefineType ty -> pp_type_gen pr_elem pr_space ty
         | DefineText (s, ii) -> List.iter pr_elem ii
         | DefineEmpty -> ()
+        | DefineInit ini -> 
+            pp_init_gen pr_elem pr_space ini
+
+        | DefineTodo -> pr2 "DefineTodo"
       in
       (match defkind with
       | DefineVar -> ()
@@ -899,6 +1011,21 @@ let pp_program_gen pr_elem pr_space progelem =
       define_val defval;
       pr_elem ieol
           
+  | Undef (s, ii) -> 
+      List.iter pr_elem ii
+  | PragmaAndCo (ii) -> 
+      List.iter pr_elem ii
+
+
+
+
+let pp_program_gen pr_elem pr_space progelem =
+  match progelem with
+  | Declaration decl -> pp_decl_gen pr_elem pr_space decl
+  | Definition def -> pp_def_gen pr_elem pr_space def
+
+  | CppTop directive -> pp_directive_gen pr_elem pr_space directive 
+
 
   | MacroTop (s, es,   [i1;i2;i3;i4]) -> 
       pr_elem i1;
@@ -917,9 +1044,188 @@ let pp_program_gen pr_elem pr_space progelem =
       assert (List.length ii >= 1);
       ii +> List.iter pr_elem 
   | FinalDef info -> pr_elem (Ast_c.rewrap_str "" info)
+
+  | IfdefTop ifdefdir -> 
+      pp_ifdef_gen pr_elem pr_space ifdefdir
+
+  | (MacroTop _) 
+    -> raise Impossible
       
-  | _ -> raise Impossible
-     
+      
+
+
+let pp_flow_gen pr_elem pr_space n = 
+  match F.unwrap n  with
+  | F.FunHeader ({f_name =idb;
+                   f_type = (rett, (paramst,(isvaargs,iidotsb)));
+                   f_storage = stob;
+                   f_body = body;
+                   f_attr = attrs},ii) ->
+
+      assert(null body);
+      (*
+      iif ii;
+      iif iidotsb;
+      attrs +> List.iter (vk_attribute bigf);
+      vk_type bigf rett;
+      paramst +> List.iter (fun (param, iicomma) ->
+        vk_param bigf param;
+        iif iicomma;
+      );
+      *)
+      pr2 "Def";
+
+
+    | F.Decl decl -> 
+        (* vk_decl bigf decl *)
+        pr2 "Decl" 
+
+    | F.ExprStatement (st, (eopt, ii)) ->  
+        pp_statement_gen pr_elem pr_space (ExprStatement eopt, ii) 
+
+    | F.IfHeader (_, (e,ii)) 
+    | F.SwitchHeader (_, (e,ii))
+    | F.WhileHeader (_, (e,ii))
+    | F.DoWhileTail (e,ii) -> 
+        (*
+        iif ii;
+        vk_expr bigf e
+        *)
+        pr2 "XXX";
+
+
+    | F.ForHeader (_st, (((e1opt,i1), (e2opt,i2), (e3opt,i3)), ii)) -> 
+        (*
+        iif i1; iif i2; iif i3;
+        iif ii;
+        e1opt +> do_option (vk_expr bigf);
+        e2opt +> do_option (vk_expr bigf);
+        e3opt +> do_option (vk_expr bigf);
+        *)
+        pr2 "XXX";
+
+    | F.MacroIterHeader (_s, ((s,es), ii)) -> 
+        (*
+        iif ii;
+        vk_argument_list bigf es;
+        *)
+        pr2 "XXX";
+
+        
+    | F.ReturnExpr (_st, (e,ii)) -> 
+        (* iif ii; vk_expr bigf e*)
+        pr2 "XXX";
+
+        
+    | F.Case  (_st, (e,ii)) -> 
+        (* iif ii; vk_expr bigf e *)
+        pr2 "XXX";
+        
+    | F.CaseRange (_st, ((e1, e2),ii)) -> 
+        (* iif ii; vk_expr bigf e1; vk_expr bigf e2 *)
+        pr2 "XXX";
+
+
+
+    | F.CaseNode i -> ()
+
+    | F.DefineExpr e  -> 
+        (* vk_expr bigf e *)
+        pr2 "XXX";
+
+    | F.DefineType ft  -> 
+        (* vk_type bigf ft *)
+        pr2 "XXX";
+
+    | F.DefineHeader ((s,ii), (defkind))  -> 
+        (*
+        iif ii;
+        vk_define_kind bigf defkind;
+        *)
+        pr2 "XXX";
+
+
+    | F.DefineDoWhileZeroHeader (((),ii)) -> 
+        (* iif ii *)
+        pr2 "XXX";
+
+
+    | F.Include {i_include = (s, ii);} -> 
+        (* iif ii; *)
+        pr2 "XXX";
+        
+
+    | F.MacroTop (s, args, ii) -> 
+        (* iif ii;
+        vk_argument_list bigf args *)
+        pr2 "XXX";
+
+
+    | F.Break    (st,((),ii)) -> 
+        (* iif ii *)
+        pr2 "XXX";
+    | F.Continue (st,((),ii)) -> 
+        (* iif ii *)
+        pr2 "XXX";
+    | F.Default  (st,((),ii)) -> 
+        (* iif ii *)
+        pr2 "XXX";
+    | F.Return   (st,((),ii)) -> 
+        (* iif ii *)
+        pr2 "XXX";
+    | F.Goto  (st, (s,ii)) -> 
+        (* iif ii *)
+        pr2 "XXX";
+    | F.Label (st, (s,ii)) -> 
+        (* iif ii *)
+        pr2 "XXX";
+    | F.EndStatement iopt -> 
+        (* do_option infof iopt *)
+        pr2 "XXX";
+    | F.DoHeader (st, info) -> 
+        (* infof info *)
+        pr2 "XXX";
+    | F.Else info -> 
+        (* infof info *)
+        pr2 "XXX";
+    | F.SeqEnd (i, info) -> 
+        (* infof info *)
+        pr2 "XXX";
+    | F.SeqStart (st, i, info) -> 
+        (* infof info *)
+        pr2 "XXX";
+
+    | F.MacroStmt (st, ((),ii)) -> 
+        (* iif ii *)
+        pr2 "XXX";
+    | F.Asm (st, (asmbody,ii)) -> 
+        (*
+        iif ii;
+        vk_asmbody bigf asmbody
+        *)
+        pr2 "XXX";
+
+
+    | F.IfdefHeader (info) -> 
+        pp_ifdef_gen pr_elem pr_space  info
+    | F.IfdefElse (info) -> 
+        pp_ifdef_gen pr_elem pr_space info
+    | F.IfdefEndif (info) -> 
+        pp_ifdef_gen pr_elem pr_space info
+
+
+    | (
+        F.TopNode|F.EndNode|
+        F.ErrorExit|F.Exit|F.Enter|
+        F.FallThroughNode|F.AfterNode|F.FalseNode|F.TrueNode|F.InLoopNode|
+        F.Fake
+      ) -> 
+        pr2 "YYY"
+
+
+
+
+
 
 
 
@@ -935,3 +1241,6 @@ let pr_space _ = Format.print_space()
 let pp_expression_simple = pp_expression_gen pr_elem pr_space
 let pp_statement_simple  = pp_statement_gen pr_elem pr_space
 let pp_type_simple  = pp_type_gen pr_elem pr_space
+let pp_toplevel_simple = pp_program_gen pr_elem pr_space
+let pp_flow_simple = pp_flow_gen pr_elem pr_space
+
index 70091fa..c78de1a 100644 (file)
@@ -13,7 +13,8 @@ val pp_type_gen : pr_elem_func -> pr_space_func -> Ast_c.fullType -> unit
 val pp_type_with_ident_gen :
   pr_elem_func -> pr_space_func ->
   (string * Ast_c.info) option ->
-  (Ast_c.storage * Ast_c.il) option -> Ast_c.fullType -> unit
+  (Ast_c.storage * Ast_c.il) option -> Ast_c.fullType -> Ast_c.attribute list ->
+  unit
 
 
 val pp_program_gen : pr_elem_func -> pr_space_func -> Ast_c.toplevel -> unit
@@ -21,3 +22,5 @@ val pp_program_gen : pr_elem_func -> pr_space_func -> Ast_c.toplevel -> unit
 val pp_expression_simple : Ast_c.expression -> unit
 val pp_statement_simple : Ast_c.statement -> unit
 val pp_type_simple : Ast_c.fullType -> unit
+val pp_toplevel_simple : Ast_c.toplevel -> unit
+val pp_flow_simple: Control_flow_c.node -> unit
index d49f7b0..868c537 100644 (file)
@@ -39,12 +39,12 @@ let test_parse_gen xs ext =
      let xs = if !Flag.dir then 
      process_output_to_list ("find " ^ x ^" -name \"*.c\"") else x::xs in
   *)
-  let fullxs = Common.files_of_dir_or_files ext xs in
+  let fullxs = Common.files_of_dir_or_files_no_vcs ext xs in
 
   let stat_list = ref [] in
   let newscore  = Common.empty_score () in
 
-  (*cocci: Common.check_stack_nbfiles (List.length fullxs); *)
+  Common.check_stack_nbfiles (List.length fullxs);
 
   fullxs +> List.iter (fun file -> 
     if not (file =~ (".*\\."^ext))
@@ -62,15 +62,15 @@ let test_parse_gen xs ext =
     Common.push2 stat stat_list;
     let s = 
       sprintf "bad = %d, timeout = %B" 
-        stat.Parse_c.bad stat.Parse_c.have_timeout
+        stat.Parsing_stat.bad stat.Parsing_stat.have_timeout
     in
-    if stat.Parse_c.bad = 0 && not stat.Parse_c.have_timeout
+    if stat.Parsing_stat.bad = 0 && not stat.Parsing_stat.have_timeout
     then Hashtbl.add newscore file (Common.Ok)
     else Hashtbl.add newscore file (Common.Pb s)
   );
   
   if not (null !stat_list) 
-  then Parse_c.print_parsing_stat_list !stat_list;
+  then Parsing_stat.print_parsing_stat_list !stat_list;
   
   dirname_opt +> Common.do_option (fun dirname -> 
     pr2 "--------------------------------";
@@ -106,7 +106,6 @@ let test_parse_ch xs =
 (* ---------------------------------------------------------------------- *)
 (* file can be   "foo.c"  or "foo.c:main" *)
 let test_cfg file = 
-
   let (file, specific_func) = 
     if file =~ "\\(.*\\.c\\):\\(.*\\)"
     then 
@@ -125,8 +124,8 @@ let test_cfg file =
     let toprocess = 
       match specific_func, e with
       | None, _ -> true
-      | Some s, Ast_c.Definition (((funcs, _, _, c),_))  -> 
-          s = funcs
+      | Some s, Ast_c.Definition (defbis,_)  -> 
+          s = defbis.Ast_c.f_name
       | _, _ -> false 
     in
           
@@ -147,7 +146,8 @@ let test_cfg file =
 *)
               flow
             in
-            Ograph_extended.print_ograph_mutable flow' ("/tmp/output.dot") true
+           let filename = Filename.temp_file "output" ".dot" in
+            Ograph_extended.print_ograph_mutable flow' (filename) true
           )
         with Ast_to_flow.Error (x) -> Ast_to_flow.report_error x
       )
@@ -155,23 +155,20 @@ let test_cfg file =
 
 
 
-
 (* ---------------------------------------------------------------------- *)
 let test_parse_unparse infile = 
   if not (infile =~ ".*\\.c") 
   then pr2 "warning: seems not a .c file";
 
-(* for cocci: to remove one day
   let (program2, _stat) = Parse_c.parse_print_error_heuristic infile in
   let program2_with_ppmethod = 
-    program2 +> List.map (fun x -> x, Unparse_c2.PPnormal)
+    program2 +> List.map (fun x -> x, Unparse_c.PPnormal)
   in
-  Unparse_c2.pp_program program2_with_ppmethod tmpfile;
+  Unparse_c.pp_program program2_with_ppmethod tmpfile;
   Common.command2 ("cat " ^ tmpfile);
   (* if want see diff of space => no -b -B *)
   Common.command2 (spf "diff -u -p  %s %s" infile tmpfile);
   (* +> Transformation.test_simple_trans1;*)
-*)
   ()
 
 
@@ -194,11 +191,10 @@ let test_type_c infile =
     )
     +> Common.uncurry Common.zip
   in
-(* for cocci: to remove one day *)
   let program2_with_ppmethod = 
-    program2 +> List.map (fun x -> x, Unparse_c2.PPnormal)
+    program2 +> List.map (fun x -> x, Unparse_c.PPnormal)
   in
-  Unparse_c2.pp_program program2_with_ppmethod tmpfile;
+  Unparse_c.pp_program program2_with_ppmethod tmpfile;
   Common.command2 ("cat " ^ tmpfile);
   ();;
 
index 082c9cc..80f45f7 100644 (file)
@@ -1,6 +1,7 @@
 open Common.BasicType
 
 val test_tokens_c : filename -> unit
+
 (* parse and handle some regression information when called with dirmode *)
 val test_parse_c  : filename list -> unit
 val test_parse_h  : filename list -> unit
index 14aed16..4fdf39c 100644 (file)
@@ -8,33 +8,30 @@ open Parser_c
 
 let is_space = function
   | TCommentSpace _ -> true
+  | TCommentNewline _ -> true
   | _ -> false
 
+let is_whitespace = is_space
+
 let is_comment_or_space = function
   | TComment _ -> true
   | TCommentSpace _ -> true
-
+  | TCommentNewline _ -> true
   | _ -> false
+let is_real_comment = is_comment_or_space
 
 let is_just_comment = function
   | TComment _ -> true
   | _ -> false
 
-
-
-
-
 let is_comment = function
-  | TComment _    | TCommentSpace _ | TCommentNewline _ 
+  | TComment _    
+  | TCommentSpace _ | TCommentNewline _ 
   | TCommentCpp _ 
   | TCommentMisc _ -> true
   | _ -> false
 
 
-let is_real_comment = function
-  | TComment _    | TCommentSpace _ | TCommentNewline _ 
-      -> true
-  | _ -> false
 
 let is_fake_comment = function
   | TCommentCpp _    | TCommentMisc _ 
@@ -45,11 +42,25 @@ let is_not_comment x =
   not (is_comment x)
 
 
+
+
+
 let is_cpp_instruction = function
-  | TInclude _ | TDefine _
-  | TIfdef _   | TIfdefelse _ | TIfdefelif _
-  | TEndif _ 
+  | TInclude _ 
+  | TDefine _
+  | TIfdef _   | TIfdefelse _ | TIfdefelif _ | TEndif _ 
   | TIfdefBool _ | TIfdefMisc _ | TIfdefVersion _
+  | TUndef _ 
+  | TCppDirectiveOther _
+      -> true
+  | _ -> false
+
+
+let is_gcc_token = function
+  | Tasm _ 
+  | Tinline _ 
+  | Tattribute _ 
+  | Ttypeof _ 
       -> true
   | _ -> false
 
@@ -64,10 +75,24 @@ let is_cpar = function
   | TCPar _ | TCParEOL _ -> true
   | _ -> false
 
+
+let is_obrace = function
+  | TOBrace _ | TOBraceDefineInit _ -> true
+  | _ -> false
+
+let is_cbrace = function
+  | TCBrace _ -> true
+  | _ -> false 
+
+
+
+
 let is_eof = function
   | EOF x -> true
   | _ -> false
 
+
+
 let is_statement = function
   | Tfor _ | Tdo _ | Tif _ | Twhile _ | Treturn _ 
   | Tbreak _ | Telse _ | Tswitch _ | Tcase _ | Tcontinue _
@@ -145,6 +170,9 @@ let info_of_tok = function
   | TDefine (ii) -> ii 
   | TInclude (includes, filename, inifdef, i1) ->     i1
 
+  | TUndef (s, ii) -> ii
+  | TCppDirectiveOther (ii) -> ii
+
   | TIncludeStart (i1, inifdef) ->     i1
   | TIncludeFilename (s, i1) ->     i1
 
@@ -154,11 +182,16 @@ let info_of_tok = function
   | TCppEscapedNewline (ii) -> ii
   | TDefParamVariadic (s, i1) ->     i1
 
+  | TOBraceDefineInit (i1) ->     i1
+
   | TUnknown             (i) -> i
 
-  | TMacroStmt             (i) -> i
-  | TMacroString             (i) -> i
+  | TMacroAttr             (s, i) -> i
+  | TMacroAttrStorage             (s, i) -> i
+  | TMacroStmt             (s, i) -> i
+  | TMacroString             (s, i) -> i
   | TMacroDecl             (s, i) -> i
+  | TMacroStructDecl             (s, i) -> i
   | TMacroDeclConst             (i) -> i
   | TMacroIterator             (s,i) -> i
 (*  | TMacroTop             (s,i) -> i *)
@@ -172,13 +205,13 @@ let info_of_tok = function
   | TCommentCpp          (cppkind, i) -> i
   | TCommentMisc         (i) -> i
 
-  | TIfdef               (i) -> i
-  | TIfdefelse           (i) -> i
-  | TIfdefelif           (i) -> i
-  | TEndif               (i) -> i
-  | TIfdefBool           (b, i) -> i
-  | TIfdefMisc           (b, i) -> i
-  | TIfdefVersion           (b, i) -> i
+  | TIfdef               (_, i) -> i
+  | TIfdefelse           (_, i) -> i
+  | TIfdefelif           (_, i) -> i
+  | TEndif               (_, i) -> i
+  | TIfdefBool           (b, _, i) -> i
+  | TIfdefMisc           (b, _, i) -> i
+  | TIfdefVersion           (b, _, i) -> i
 
   | TOPar                (i) -> i
   | TCPar                (i) -> i
@@ -232,6 +265,9 @@ let info_of_tok = function
   | Tstatic              (i) -> i
   | Tconst               (i) -> i
   | Tvolatile            (i) -> i
+
+  | Trestrict            (i) -> i
+
   | Tstruct              (i) -> i
   | Tenum                (i) -> i
   | Ttypedef             (i) -> i
@@ -258,6 +294,7 @@ let info_of_tok = function
   
 
 
+
 (* used by tokens to complete the parse_info with filename, line, col infos *)
 let visitor_info_of_tok f = function
   | TString ((s, isWchar), i)  -> TString ((s, isWchar), f i) 
@@ -271,6 +308,9 @@ let visitor_info_of_tok f = function
 
   | TDefine (i1) -> TDefine(f i1) 
 
+  | TUndef (s,i1) -> TUndef(s, f i1) 
+  | TCppDirectiveOther (i1) -> TCppDirectiveOther(f i1) 
+
   | TInclude (includes, filename, inifdef, i1) -> 
       TInclude (includes, filename, inifdef, f i1)
 
@@ -284,14 +324,19 @@ let visitor_info_of_tok f = function
 
   | TDefParamVariadic (s, i1) -> TDefParamVariadic (s, f i1)
 
+  | TOBraceDefineInit (i1) -> TOBraceDefineInit (f i1)
+
 
   | TUnknown             (i) -> TUnknown                (f i)
 
-  | TMacroStmt           (i)   -> TMacroStmt            (f i)
-  | TMacroString         (i)   -> TMacroString          (f i)
-  | TMacroDecl           (s,i) -> TMacroDecl            (s, f i)
+  | TMacroAttr           (s, i)   -> TMacroAttr            (s, f i)
+  | TMacroAttrStorage           (s, i)   -> TMacroAttrStorage         (s, f i)
+  | TMacroStmt           (s, i)   -> TMacroStmt            (s, f i)
+  | TMacroString         (s, i)   -> TMacroString          (s, f i)
+  | TMacroDecl           (s, i) -> TMacroDecl            (s, f i)
+  | TMacroStructDecl     (s, i) -> TMacroStructDecl      (s, f i)
   | TMacroDeclConst      (i)   -> TMacroDeclConst       (f i)
-  | TMacroIterator       (s,i) -> TMacroIterator        (s,f i)
+  | TMacroIterator       (s, i) -> TMacroIterator        (s, f i)
 (*  | TMacroTop          (s,i) -> TMacroTop             (s,f i) *)
   | TCParEOL (i) ->     TCParEOL (f i)
 
@@ -303,13 +348,14 @@ let visitor_info_of_tok f = function
   | TCommentNewline      (i) -> TCommentNewline      (f i) 
   | TCommentCpp          (cppkind, i) -> TCommentCpp (cppkind, f i) 
   | TCommentMisc         (i) -> TCommentMisc         (f i) 
-  | TIfdef               (i) -> TIfdef               (f i) 
-  | TIfdefelse           (i) -> TIfdefelse           (f i) 
-  | TIfdefelif           (i) -> TIfdefelif           (f i) 
-  | TEndif               (i) -> TEndif               (f i) 
-  | TIfdefBool           (b, i) -> TIfdefBool        (b, f i) 
-  | TIfdefMisc           (b, i) -> TIfdefMisc        (b, f i) 
-  | TIfdefVersion        (b, i) -> TIfdefVersion     (b, f i) 
+
+  | TIfdef               (t, i) -> TIfdef               (t, f i) 
+  | TIfdefelse           (t, i) -> TIfdefelse           (t, f i) 
+  | TIfdefelif           (t, i) -> TIfdefelif           (t, f i) 
+  | TEndif               (t, i) -> TEndif               (t, f i) 
+  | TIfdefBool           (b, t, i) -> TIfdefBool        (b, t, f i) 
+  | TIfdefMisc           (b, t, i) -> TIfdefMisc        (b, t, f i) 
+  | TIfdefVersion        (b, t, i) -> TIfdefVersion     (b, t, f i) 
 
   | TOPar                (i) -> TOPar                (f i) 
   | TCPar                (i) -> TCPar                (f i) 
@@ -362,6 +408,9 @@ let visitor_info_of_tok f = function
   | Tstatic              (i) -> Tstatic              (f i) 
   | Tconst               (i) -> Tconst               (f i) 
   | Tvolatile            (i) -> Tvolatile            (f i) 
+
+  | Trestrict            (i) -> Trestrict            (f i) 
+
   | Tstruct              (i) -> Tstruct              (f i) 
   | Tenum                (i) -> Tenum                (f i) 
   | Ttypedef             (i) -> Ttypedef             (f i) 
index 8c48683..0d7cfd8 100644 (file)
@@ -8,6 +8,8 @@ val is_fake_comment        : Parser_c.token -> bool
 val is_not_comment         : Parser_c.token -> bool
 
 val is_cpp_instruction     : Parser_c.token -> bool
+val is_gcc_token           : Parser_c.token -> bool
+
 val is_eof                 : Parser_c.token -> bool
 val is_statement           : Parser_c.token -> bool
 val is_start_of_something  : Parser_c.token -> bool
@@ -16,6 +18,9 @@ val is_stuff_taking_parenthized : Parser_c.token -> bool
 
 val is_opar : Parser_c.token -> bool
 val is_cpar : Parser_c.token -> bool
+val is_obrace : Parser_c.token -> bool
+val is_cbrace : Parser_c.token -> bool
+
 
 val info_of_tok : Parser_c.token -> Ast_c.info
 
index d35aeba..21547ff 100644 (file)
@@ -1,4 +1,4 @@
-(* Copyright (C) 2002-2008 Yoann Padioleau
+(* Copyright (C) 2007, 2008 Yoann Padioleau
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License (GPL)
@@ -246,7 +246,7 @@ let (type_field:
   fun fld (su, fields) -> 
     fields +> Common.find_some (fun x -> 
       match Ast_c.unwrap x with
-      | FieldDeclList onefield_multivars -> 
+      | DeclarationField (FieldDeclList (onefield_multivars, iiptvirg)) -> 
           Common.optionise (fun () -> 
             onefield_multivars +> Common.find_some (fun fieldkind -> 
 
@@ -257,6 +257,9 @@ let (type_field:
             )
           )
       | EmptyField -> None
+      | MacroStructDeclTodo -> pr2 "DeclTodo"; None
+      | CppDirectiveStruct _
+      | IfdefStruct _ -> pr2 "StructCpp"; None
     )
 
 
@@ -522,7 +525,9 @@ let rec (annotate_program2 :
     Visitor_c.kdecl = (fun (k, bigf) d -> 
       (match d with
       | (DeclList (xs, ii)) -> 
-          xs +> List.iter (fun ((var, t, sto, local), iicomma) -> 
+          xs +> List.iter (fun ({v_namei = var; v_type = t;
+                                 v_storage = sto; v_local = local}, iicomma) -> 
+
            let local =
              match local with
                Ast_c.NotLocalDecl -> Ast_c.NotLocalVar
@@ -566,7 +571,10 @@ let rec (annotate_program2 :
       _notyped_var := Hashtbl.create 100;
       match elem with
       | Definition def -> 
-          let (funcs, ((returnt, (paramst, b)) as ftyp), sto, statxs),ii = def
+          let {f_name = funcs;
+               f_type = ((returnt, (paramst, b)) as ftyp);
+               f_storage = sto;
+               f_body = statxs},ii = def
           in
           let (i1, i2) = 
             match ii with 
similarity index 95%
rename from parsing_c/unparse_c2.ml
rename to parsing_c/unparse_c.ml
index 7fb532e..806ad4f 100644 (file)
@@ -1,4 +1,4 @@
-(* Copyright (C) 2002-2008 Yoann Padioleau
+(* Copyright (C) 2006, 2007, 2008 Yoann Padioleau
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License (GPL)
@@ -8,6 +8,9 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * file license.txt for more details.
+ * 
+ * 
+ * Modifications by Julia Lawall for better newline handling.
  *)
 open Common
 
@@ -122,6 +125,7 @@ let rebuild_tokens_extented toks_ext =
 let mcode_contain_plus = function
   | Ast_cocci.CONTEXT (_,Ast_cocci.NOTHING) -> false
   | Ast_cocci.CONTEXT _ -> true
+(* patch: when need full coccinelle transformation *)
   | Ast_cocci.MINUS (_,[]) -> false
   | Ast_cocci.MINUS (_,x::xs) -> true
   | Ast_cocci.PLUS -> raise Impossible
@@ -214,6 +218,7 @@ let displace_fake_nodes toks =
   let is_fake = function Fake1 _ -> true | _ -> false in
   let is_whitespace = function
       T1(Parser_c.TCommentSpace _)
+      (* patch: cocci    *)
     | T1(Parser_c.TCommentNewline _) -> true
     | _ -> false in
   let rec loop toks =
@@ -238,7 +243,8 @@ let displace_fake_nodes toks =
            bef @ fake :: (loop aft)
        | (Ast_cocci.CONTEXT(_,Ast_cocci.BEFOREAFTER _),_) ->
            failwith "fake node should not be before-after"
-       | _ -> bef @ fake :: (loop aft))
+       | _ -> bef @ fake :: (loop aft) (* old: was removed when have simpler yacfe *)
+        )
     | None -> toks
     | _ -> raise Impossible in
   loop toks
@@ -304,28 +310,32 @@ let expand_mcode toks =
 
     let args_pp = (env, pr_cocci, pr_c, pr_space, indent, unindent) in
 
+    (* old: when for yacfe with partial cocci: 
+     *    add_elem t false; 
+    *)
 
+    (* patch: when need full coccinelle transformation *)
     match mcode with
     | Ast_cocci.MINUS (_,any_xxs) -> 
         (* Why adding ? because I want to have all the information, the whole
          * set of tokens, so I can then process and remove the 
          * is_between_two_minus for instance *)
         add_elem t true;
-        Unparse_cocci2.pp_list_list_any args_pp any_xxs Unparse_cocci2.InPlace
+        Unparse_cocci.pp_list_list_any args_pp any_xxs Unparse_cocci.InPlace
     | Ast_cocci.CONTEXT (_,any_befaft) -> 
         (match any_befaft with
         | Ast_cocci.NOTHING -> 
             add_elem t false
         | Ast_cocci.BEFORE xxs -> 
-            Unparse_cocci2.pp_list_list_any args_pp xxs Unparse_cocci2.Before;
+            Unparse_cocci.pp_list_list_any args_pp xxs Unparse_cocci.Before;
             add_elem t false
         | Ast_cocci.AFTER xxs -> 
             add_elem t false;
-            Unparse_cocci2.pp_list_list_any args_pp xxs Unparse_cocci2.After;
+            Unparse_cocci.pp_list_list_any args_pp xxs Unparse_cocci.After;
         | Ast_cocci.BEFOREAFTER (xxs, yys) -> 
-            Unparse_cocci2.pp_list_list_any args_pp xxs Unparse_cocci2.Before;
+            Unparse_cocci.pp_list_list_any args_pp xxs Unparse_cocci.Before;
             add_elem t false;
-            Unparse_cocci2.pp_list_list_any args_pp yys Unparse_cocci2.After;
+            Unparse_cocci.pp_list_list_any args_pp yys Unparse_cocci.After;
         )
     | Ast_cocci.PLUS -> raise Impossible
 
@@ -343,6 +353,7 @@ let is_minusable_comment = function
   | T2 (t,_b,_i) -> 
       (match t with
       | Parser_c.TCommentSpace _   (* only whitespace *)
+      (* patch: coccinelle *)      
       | Parser_c.TCommentNewline _ (* newline plus whitespace *)
       | Parser_c.TComment _ 
       | Parser_c.TCommentCpp (Ast_c.CppAttr, _) 
@@ -351,7 +362,7 @@ let is_minusable_comment = function
 
       | Parser_c.TCommentMisc _ 
       | Parser_c.TCommentCpp (Ast_c.CppDirective, _)
-      | Parser_c.TCommentCpp (Ast_c.CppOther, _)
+      | Parser_c.TCommentCpp (Ast_c.CppPassingCosWouldGetError, _)
         -> false
 
       | _ -> false
@@ -363,6 +374,7 @@ let all_coccis = function
   | _ -> false
 
 let is_minusable_comment_or_plus = function
+(* patch: coccinelle *)
     T2(Parser_c.TCommentNewline _,_b,_i) -> false
   | x -> is_minusable_comment x or all_coccis x
 
@@ -371,6 +383,7 @@ let set_minus_comment = function
       let str = TH.str_of_tok t in
       (match t with
       | Parser_c.TCommentSpace _
+(* patch: coccinelle *)      
       | Parser_c.TCommentNewline _ -> ()
 
       | Parser_c.TComment _ 
@@ -381,6 +394,7 @@ let set_minus_comment = function
       | _ -> raise Impossible
       );
       T2 (t, true, idx)
+(* patch: coccinelle *)   
   | T2 (Parser_c.TCommentNewline _,true,idx) as x -> x
   | _ -> raise Impossible
 
@@ -403,6 +417,7 @@ let remove_minus_and_between_and_expanded_and_fake xs =
   (*This drops the space before each completely minused block (no plus code).*)
   let rec adjust_before_minus = function
       [] -> []
+(* patch: coccinelle  *)
     | (T2(Parser_c.TCommentNewline c,_b,_i) as x)::((T2(_,true,_)::_) as xs) ->
        let minus_or_comment = function
            T2(_,true,_) -> true
@@ -523,6 +538,7 @@ let rec adjust_indentation xs =
       [] -> ()
     | ((T2 (tok,_,_)) as x)::xs when str_of_token2 x = "{" ->
        find_first_tab true xs
+(* patch: coccinelle *)
     | ((T2 (Parser_c.TCommentNewline s, _, _)) as x)::_
       when started ->
        let s = str_of_token2 x +> new_tabbing in
@@ -533,6 +549,7 @@ let rec adjust_indentation xs =
   let rec aux started xs = 
     match xs with
     | [] ->  []
+(* patch: coccinelle *)
     | ((T2 (tok,_,_)) as x)::(T2 (Parser_c.TCommentNewline s, _, _))::
       (Cocci2 "{")::xs when started && str_of_token2 x = ")" ->
        (* to be done for if, etc, but not for a function header *)
@@ -758,3 +775,7 @@ let pp_program2 xs outfile  =
 let pp_program a b = 
   Common.profile_code "C unparsing" (fun () -> pp_program2 a b)
 
+
+let pp_program_default xs outfile = 
+  let xs' = xs +> List.map (fun x -> x, PPnormal) in
+  pp_program xs' outfile
similarity index 75%
rename from parsing_c/unparse_c2.mli
rename to parsing_c/unparse_c.mli
index b0bcd36..a51534f 100644 (file)
@@ -5,3 +5,5 @@ type ppmethod = PPnormal | PPviastr
 (* program -> output filename (often "/tmp/output.c") -> unit *) 
 val pp_program : 
   (Parse_c.toplevel2 * ppmethod) list -> filename -> unit
+
+val pp_program_default: Parse_c.program2 -> filename -> unit
index a2fcfb6..c7b29f8 100644 (file)
@@ -82,7 +82,8 @@ let print_metavar pr typedefs = function
         il)
   | _ -> failwith "function must have named parameters"
 
-let print_metavariables pr (s, (_, (paramst, (b, iib))), _, _) header_req =
+let print_metavariables pr defn header_req =
+  let {Ast_c.f_name = s; f_type = (_, (paramst, (b, iib))); } = defn in
   (if header_req
   then pr "@depends on header@\n"
   else pr "@@\n");
@@ -114,7 +115,8 @@ let print_param_name pr = function
     ((_,Some param,_),_) -> pr param
   | _ -> failwith "function must have named parameters"
 
-let pp_def_gen pr (s, (_, (paramst, (b, iib))), _, _) isexp =
+let pp_def_gen pr defn isexp =
+  let {Ast_c.f_name = s; f_type = (_, (paramst, (b, iib))); } = defn in
   pr s; pr "(";
   (if b then failwith "not handling variable argument functions");
   (match paramst with
@@ -129,12 +131,12 @@ let pp_def_gen pr (s, (_, (paramst, (b, iib))), _, _) isexp =
 
 let pp_program (e,(str, toks_e)) outdir srcfile isexp =
   match e with
-    Ast_c.Definition(((name,_,_,_) as defn),_) ->
+    Ast_c.Definition(({Ast_c.f_name = name;} as defn),_) ->
       (* generate the - code *)
       drop_header_toks toks_e;
       let toks_e = strip_comments toks_e in
       let tmp_file = Common.new_temp_file "cocci_small_output" ".c" in
-      Unparse_c2.pp_program [((e,(str, toks_e)), Unparse_c2.PPnormal)]
+      Unparse_c.pp_program [((e,(str, toks_e)), Unparse_c.PPnormal)]
        tmp_file;
       let outfile = outdir ^ "/" ^ name in
       let outfile =
index 32f85bc..27840f0 100644 (file)
@@ -1,4 +1,4 @@
-(* Copyright (C) 2002-2008 Yoann Padioleau
+(* Copyright (C) 2006, 2007, 2008 Yoann Padioleau
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License (GPL)
@@ -21,7 +21,8 @@ module F = Control_flow_c
 
 
 (* Visitor based on continuation. Cleaner than the one based on mutable 
- * pointer functions. src: based on a (vague) idea from Remy Douence.
+ * pointer functions that I had before. 
+ * src: based on a (vague) idea from Remy Douence.
  * 
  * 
  * 
@@ -113,6 +114,8 @@ let test =
  * 
  * Note that I don't visit necesserally in the order of the token
  * found in the original file. So don't assume such hypothesis!
+ * 
+ * todo? parameter ? onedecl ?
  *)
 type visitor_c = 
  { 
@@ -124,12 +127,16 @@ type visitor_c =
    kdef:       (definition  -> unit) * visitor_c -> definition  -> unit; 
    kini:       (initialiser  -> unit) * visitor_c -> initialiser  -> unit; 
 
-   kinfo: (info -> unit) * visitor_c -> info -> unit;
+   kcppdirective: (cpp_directive -> unit) * visitor_c -> cpp_directive -> unit;
+   kdefineval : (define_val -> unit) * visitor_c -> define_val -> unit;
+   kstatementseq: (statement_sequencable   -> unit) * visitor_c -> statement_sequencable   -> unit;
 
    (* CFG *)
    knode: (F.node -> unit) * visitor_c -> F.node -> unit;
    (* AST *)
    ktoplevel: (toplevel -> unit) * visitor_c -> toplevel -> unit;
+
+   kinfo: (info -> unit) * visitor_c -> info -> unit;
  } 
 
 let default_visitor_c = 
@@ -142,8 +149,15 @@ let default_visitor_c =
     kinfo      = (fun (k,_) ii  -> k ii);
     knode      = (fun (k,_) n  -> k n);
     ktoplevel  = (fun (k,_) p  -> k p);
+    kcppdirective = (fun (k,_) p  -> k p);
+    kdefineval = (fun (k,_) p  -> k p);
+    kstatementseq    = (fun (k,_) p  -> k p);
   } 
 
+
+(* ------------------------------------------------------------------------ *)
+
+
 let rec vk_expr = fun bigf expr ->
   let iif ii = vk_ii bigf ii in
 
@@ -156,10 +170,7 @@ let rec vk_expr = fun bigf expr ->
     | Constant (c) -> ()
     | FunCall  (e, es)         -> 
         exprf e;  
-        es +> List.iter (fun (e, ii) -> 
-          iif ii;
-          vk_argument bigf e
-          );
+        vk_argument_list bigf es;
     | CondExpr (e1, e2, e3)    -> 
         exprf e1; do_option (exprf) e2; exprf e3
     | Sequence (e1, e2)        -> exprf e1; exprf e2;
@@ -184,7 +195,7 @@ let rec vk_expr = fun bigf expr ->
      *)
     | StatementExpr ((statxs, is)) -> 
         iif is;
-        statxs +> List.iter (vk_statement bigf);
+        statxs +> List.iter (vk_statement_sequencable bigf);
 
     (* TODO, we will certainly have to then do a special visitor for 
      * initializer 
@@ -201,19 +212,11 @@ let rec vk_expr = fun bigf expr ->
 
   in exprf expr
 
-and vk_argument = fun bigf arg -> 
-  let rec do_action = function 
-    | (ActMisc ii) -> vk_ii bigf ii
-  in
-  match arg with
-  | Left e -> (vk_expr bigf) e
-  | Right (ArgType param) -> vk_param bigf param
-  | Right (ArgAction action) -> do_action action
 
 
 
 
-and vk_statement = fun bigf st -> 
+and vk_statement = fun bigf (st: Ast_c.statement) -> 
   let iif ii = vk_ii bigf ii in
 
   let rec statf x = bigf.kstatement (k,bigf) x 
@@ -227,14 +230,12 @@ and vk_statement = fun bigf st ->
         vk_expr bigf e; vk_expr bigf e2; statf st;
     | Labeled (Default st) -> statf st;
 
-    | Compound statxs -> statxs +> List.iter (vk_statement bigf)
+    | Compound statxs -> 
+        statxs +> List.iter (vk_statement_sequencable bigf)
     | ExprStatement (eopt) -> do_option (vk_expr bigf) eopt;
 
     | Selection  (If (e, st1, st2)) -> 
         vk_expr bigf e; statf st1; statf st2;
-    | Selection (Ifdef (st1s, st2s)) -> 
-        st1s +> List.iter (vk_statement bigf);
-        st2s +> List.iter (vk_statement bigf)
     | Selection  (Switch (e, st)) -> 
         vk_expr bigf e; statf st;
     | Iteration  (While (e, st)) -> 
@@ -247,10 +248,7 @@ and vk_statement = fun bigf st ->
         statf st;
 
     | Iteration  (MacroIteration (s, es, st)) -> 
-        es +> List.iter (fun (e, ii) -> 
-          iif ii;
-          vk_argument bigf e
-          );
+        vk_argument_list bigf es;
         statf st;
           
     | Jump (Goto s) -> ()
@@ -265,21 +263,25 @@ and vk_statement = fun bigf st ->
 
   in statf st
 
-and vk_asmbody = fun bigf (string_list, colon_list) -> 
-  let iif ii = vk_ii bigf ii in
+and vk_statement_sequencable = fun bigf stseq -> 
+  let f = bigf.kstatementseq in 
+
+  let rec k stseq = 
+    match stseq with
+    | StmtElem st -> vk_statement bigf st
+    | CppDirectiveStmt directive -> 
+        vk_cpp_directive bigf directive
+    | IfdefStmt ifdef -> 
+        vk_ifdef_directive bigf ifdef
+    | IfdefStmt2 (ifdef, xxs) -> 
+        ifdef +> List.iter (vk_ifdef_directive bigf);
+        xxs +> List.iter (fun xs -> 
+          xs +> List.iter (vk_statement_sequencable bigf)
+        )
+          
+  in f (k, bigf) stseq
+
 
-  iif string_list;
-  colon_list +> List.iter (fun (Colon xs, ii)  -> 
-    iif ii;
-    xs +> List.iter (fun (x,iicomma) -> 
-      iif iicomma;
-      (match x with
-      | ColonMisc, ii -> iif ii 
-      | ColonExpr e, ii -> 
-          vk_expr bigf e;
-          iif ii
-      )
-    ))
 
 and vk_type = fun bigf t -> 
   let iif ii = vk_ii bigf ii in
@@ -302,11 +304,7 @@ and vk_type = fun bigf t ->
         (match paramst with
         | (ts, (b,iihas3dots)) -> 
             iif iihas3dots;
-            ts +> List.iter (fun (param,iicomma) -> 
-              vk_param bigf param;
-              iif iicomma;
-              
-            )
+            vk_param_list bigf ts
         )
 
     | Enum  (sopt, enumt) -> 
@@ -330,6 +328,16 @@ and vk_type = fun bigf t ->
 
   in typef t
 
+
+and vk_attribute = fun bigf attr -> 
+  let iif ii = vk_ii bigf ii in
+  match attr with
+  | Attribute s, ii -> 
+      iif ii
+
+
+(* ------------------------------------------------------------------------ *)
+
 and vk_decl = fun bigf d -> 
   let iif ii = vk_ii bigf ii in
 
@@ -339,15 +347,14 @@ and vk_decl = fun bigf d ->
     | DeclList (xs,ii) -> iif ii; List.iter aux xs 
     | MacroDecl ((s, args),ii) -> 
         iif ii;
-        args +> List.iter (fun (e, ii) -> 
-          iif ii;
-          vk_argument bigf e
-          );
+        vk_argument_list bigf args;
 
         
-  and aux ((var, t, _sto, _local), iicomma) = 
+  and aux ({v_namei = var; v_type = t; 
+            v_storage = _sto; v_attr = attrs}, iicomma) = 
     iif iicomma;
     vk_type bigf t;
+    attrs +> List.iter (vk_attribute bigf);
     var +> do_option (fun ((s, ini), ii_s_ini) -> 
       iif ii_s_ini;
       ini +> do_option (vk_ini bigf)
@@ -375,6 +382,7 @@ and vk_ini = fun bigf ini ->
     | InitIndexOld (e1, e) ->
         vk_expr bigf e1; inif e
 
+
   in inif ini
 
 
@@ -387,18 +395,32 @@ and vk_designator = fun bigf design ->
   | DesignatorIndex e -> vk_expr bigf e
   | DesignatorRange (e1, e2) -> vk_expr bigf e1; vk_expr bigf e2
 
+
+(* ------------------------------------------------------------------------ *)
+
 and vk_struct_fields = fun bigf fields -> 
   let iif ii = vk_ii bigf ii in
 
   fields +> List.iter (fun (xfield, ii) -> 
     iif ii;
     match xfield with 
-    | FieldDeclList onefield_multivars -> 
-        vk_struct_field bigf onefield_multivars
+    | DeclarationField 
+        (FieldDeclList (onefield_multivars, iiptvirg)) -> 
+        vk_struct_fieldkinds bigf onefield_multivars;
+          iif iiptvirg;
     | EmptyField -> ()
+    | MacroStructDeclTodo -> 
+        pr2 "MacroStructDeclTodo";
+        ()
+
+    | CppDirectiveStruct directive -> 
+        vk_cpp_directive bigf directive
+    | IfdefStruct ifdef -> 
+        vk_ifdef_directive bigf ifdef
+
   )
 
-and vk_struct_field = fun bigf onefield_multivars -> 
+and vk_struct_fieldkinds = fun bigf onefield_multivars -> 
   let iif ii = vk_ii bigf ii in
   onefield_multivars +> List.iter (fun (field, iicomma) ->
     iif iicomma;
@@ -410,6 +432,7 @@ and vk_struct_field = fun bigf onefield_multivars ->
         vk_type bigf t 
   )
 
+(* ------------------------------------------------------------------------ *)
 
 
 and vk_def = fun bigf d -> 
@@ -418,15 +441,22 @@ and vk_def = fun bigf d ->
   let f = bigf.kdef in
   let rec k d = 
     match d with
-    | (s, (returnt, (paramst, (b, iib))), sto, statxs), ii -> 
+    | {f_name = s;
+       f_type = (returnt, (paramst, (b, iib)));
+       f_storage = sto;
+       f_body = statxs;
+       f_attr = attrs;
+      }, ii 
+        -> 
         iif ii;
         iif iib;
+        attrs +> List.iter (vk_attribute bigf);
         vk_type bigf returnt;
         paramst +> List.iter (fun (param,iicomma) -> 
           vk_param bigf param;
           iif iicomma;
         );
-        statxs +> List.iter (vk_statement bigf)
+        statxs +> List.iter (vk_statement_sequencable bigf)
   in f (k, bigf) d 
 
 
@@ -441,20 +471,49 @@ and vk_toplevel = fun bigf p ->
     | Definition def -> (vk_def bigf def)
     | EmptyDef ii -> iif ii
     | MacroTop (s, xs, ii) -> 
-          xs +> List.iter (fun (elem, iicomma) -> 
-            vk_argument bigf elem; iif iicomma
-          );
-          iif ii
+        vk_argument_list bigf xs;
+        iif ii
+
+    | CppTop top -> vk_cpp_directive bigf top
+    | IfdefTop ifdefdir -> vk_ifdef_directive bigf ifdefdir
           
-    | Include ((s, ii), h_rel_pos) -> iif ii;
+    | NotParsedCorrectly ii -> iif ii
+    | FinalDef info -> vk_info bigf info
+  in f (k, bigf) p
+
+and vk_program = fun bigf xs -> 
+  xs +> List.iter (vk_toplevel bigf)
+
+and vk_ifdef_directive bigf directive = 
+  let iif ii =  vk_ii bigf ii in
+  match directive with
+  | IfdefDirective (ifkind, ii) -> iif ii
+
+
+and vk_cpp_directive bigf directive =
+  let iif ii =  vk_ii bigf ii in
+  let f = bigf.kcppdirective in
+  let rec k directive = 
+    match directive with
+    | Include {i_include = (s, ii);
+               i_content = copt;
+              }
+      -> 
+        (* go inside ? *)
+        iif ii;
+        copt +> Common.do_option (fun (file, asts) -> 
+          vk_program bigf asts
+        );
     | Define ((s,ii), (defkind, defval)) -> 
         iif ii;
         vk_define_kind bigf defkind;
         vk_define_val bigf defval
+    | Undef (s, ii) -> 
+        iif ii
+    | PragmaAndCo (ii) -> 
+        iif ii
+  in f (k, bigf) directive
 
-    | NotParsedCorrectly ii -> iif ii
-    | FinalDef info -> vk_info bigf info
-  in f (k, bigf) p
 
 and vk_define_kind bigf defkind = 
   match defkind with
@@ -467,17 +526,28 @@ and vk_define_kind bigf defkind =
       )
 
 and vk_define_val bigf defval = 
+  let f = bigf.kdefineval in 
+
+  let rec k defval = 
   match defval with
   | DefineExpr e -> 
       vk_expr bigf e
   | DefineStmt stmt -> vk_statement bigf stmt
-  | DefineDoWhileZero (stmt, ii) -> 
+  | DefineDoWhileZero ((stmt, e), ii) -> 
       vk_statement bigf stmt;
+      vk_expr bigf e;
       vk_ii bigf ii
   | DefineFunction def -> vk_def bigf def
   | DefineType ty -> vk_type bigf ty
   | DefineText (s, ii) -> vk_ii bigf ii
   | DefineEmpty -> ()
+  | DefineInit ini -> vk_ini bigf ini
+
+  | DefineTodo -> 
+      pr2 "DefineTodo";
+      ()
+  in f (k, bigf) defval
+  
 
         
 
@@ -490,7 +560,7 @@ and vk_define_val bigf defval =
  * be deeper, in the then branch). So have to not visit
  * all inside a node anymore.
  * 
- * update: j'ai choisi d'accrocher au noeud du CFG Ã  la
+ * update: j'ai choisi d'accrocher au noeud du CFG a la
  * fois le fullstatement et le partialstatement et appeler le 
  * visiteur que sur le partialstatement.
  *)
@@ -503,7 +573,16 @@ and vk_node = fun bigf node ->
   let rec k n = 
     match F.unwrap n with
 
-    | F.FunHeader ((idb, (rett, (paramst,(isvaargs,iidotsb))), stob),ii) ->
+    | F.FunHeader ({f_name =idb;
+                   f_type = (rett, (paramst,(isvaargs,iidotsb)));
+                   f_storage = stob;
+                   f_body = body;
+                   f_attr = attrs},ii) ->
+
+        assert(null body);
+        iif ii;
+        iif iidotsb;
+        attrs +> List.iter (vk_attribute bigf);
         vk_type bigf rett;
         paramst +> List.iter (fun (param, iicomma) ->
           vk_param bigf param;
@@ -531,10 +610,7 @@ and vk_node = fun bigf node ->
         e3opt +> do_option (vk_expr bigf);
     | F.MacroIterHeader (_s, ((s,es), ii)) -> 
         iif ii;
-        es +> List.iter (fun (e, ii) -> 
-          iif ii;
-          vk_argument bigf e
-        );
+        vk_argument_list bigf es;
         
     | F.ReturnExpr (_st, (e,ii)) -> iif ii; vk_expr bigf e
         
@@ -552,14 +628,20 @@ and vk_node = fun bigf node ->
         vk_define_kind bigf defkind;
 
     | F.DefineDoWhileZeroHeader (((),ii)) -> iif ii
+    | F.DefineTodo -> 
+        pr2 "DefineTodo";
+        ()
+
 
-    | F.Include ((s, ii),h_rel_pos) -> iif ii
+    | F.Include {i_include = (s, ii);} -> iif ii;
 
     | F.MacroTop (s, args, ii) -> 
         iif ii;
-        args +> List.iter (fun (e, ii) -> vk_argument bigf e; iif ii)
+        vk_argument_list bigf args
 
-    | F.Ifdef (st, ((),ii)) -> iif ii
+    | F.IfdefHeader    (info) -> vk_ifdef_directive bigf info 
+    | F.IfdefElse    (info) ->  vk_ifdef_directive bigf info 
+    | F.IfdefEndif    (info) ->  vk_ifdef_directive bigf info 
 
     | F.Break    (st,((),ii)) -> iif ii
     | F.Continue (st,((),ii)) -> iif ii
@@ -567,9 +649,12 @@ and vk_node = fun bigf node ->
     | F.Return   (st,((),ii)) -> iif ii
     | F.Goto  (st, (s,ii)) -> iif ii
     | F.Label (st, (s,ii)) -> iif ii
-    | F.EndStatement iopt -> do_option infof iopt
+
     | F.DoHeader (st, info) -> infof info
+
     | F.Else info -> infof info
+    | F.EndStatement iopt -> do_option infof iopt
+
     | F.SeqEnd (i, info) -> infof info
     | F.SeqStart (st, i, info) -> infof info
 
@@ -601,12 +686,58 @@ and vk_ii = fun bigf ii ->
   List.iter (vk_info bigf) ii
 
 
+(* ------------------------------------------------------------------------ *)
+and vk_argument = fun bigf arg -> 
+  let rec do_action = function 
+    | (ActMisc ii) -> vk_ii bigf ii
+  in
+  match arg with
+  | Left e -> (vk_expr bigf) e
+  | Right (ArgType param) -> vk_param bigf param
+  | Right (ArgAction action) -> do_action action
+
+and vk_argument_list = fun bigf es -> 
+  let iif ii = vk_ii bigf ii in
+  es +> List.iter (fun (e, ii) -> 
+    iif ii;
+    vk_argument bigf e
+  )
+
+
+
 and vk_param = fun bigf (((b, s, t), ii_b_s)) ->  
   let iif ii = vk_ii bigf ii in
   iif ii_b_s;
   vk_type bigf t
 
+and vk_param_list = fun bigf ts -> 
+  let iif ii = vk_ii bigf ii in
+  ts +> List.iter (fun (param,iicomma) -> 
+    vk_param bigf param;
+    iif iicomma;
+  )
+
+
+
+(* ------------------------------------------------------------------------ *)
+and vk_asmbody = fun bigf (string_list, colon_list) -> 
+  let iif ii = vk_ii bigf ii in
+
+  iif string_list;
+  colon_list +> List.iter (fun (Colon xs, ii)  -> 
+    iif ii;
+    xs +> List.iter (fun (x,iicomma) -> 
+      iif iicomma;
+      (match x with
+      | ColonMisc, ii -> iif ii 
+      | ColonExpr e, ii -> 
+          vk_expr bigf e;
+          iif ii
+      )
+    ))
+
 
+(* ------------------------------------------------------------------------ *)
 let vk_args_splitted = fun bigf args_splitted -> 
   let iif ii = vk_ii bigf ii in
   args_splitted +> List.iter (function  
@@ -631,7 +762,7 @@ let vk_params_splitted = fun bigf args_splitted ->
   | Right ii -> iif ii
   )
 
-
+(* ------------------------------------------------------------------------ *)
 let vk_cst = fun bigf (cst, ii) -> 
   let iif ii = vk_ii bigf ii in
   iif ii;
@@ -646,6 +777,9 @@ let vk_cst = fun bigf (cst, ii) ->
 (*****************************************************************************)
 (* "syntetisized attributes" style *)
 (*****************************************************************************)
+
+(* TODO port the xxs_s to new cpp construct too *)
+
 type 'a inout = 'a -> 'a 
 
 (* _s for synthetizized attributes 
@@ -657,16 +791,21 @@ type visitor_c_s = {
   kexpr_s:      (expression inout * visitor_c_s) -> expression inout;
   kstatement_s: (statement  inout * visitor_c_s) -> statement  inout;
   ktype_s:      (fullType   inout * visitor_c_s) -> fullType   inout;
-  kini_s:  (initialiser  inout * visitor_c_s) -> initialiser inout; 
 
   kdecl_s: (declaration  inout * visitor_c_s) -> declaration inout;
   kdef_s:  (definition   inout * visitor_c_s) -> definition  inout; 
 
-  ktoplevel_s: (toplevel inout * visitor_c_s) -> toplevel inout;
-  knode_s: (F.node inout * visitor_c_s) -> F.node inout;
+  kini_s:  (initialiser  inout * visitor_c_s) -> initialiser inout; 
 
+  kcppdirective_s: (cpp_directive inout * visitor_c_s) -> cpp_directive inout;
   kdefineval_s: (define_val inout * visitor_c_s) -> define_val inout;
+  kstatementseq_s: (statement_sequencable inout * visitor_c_s) -> statement_sequencable inout;
+  kstatementseq_list_s: (statement_sequencable list inout * visitor_c_s) -> statement_sequencable list inout;
+
+  knode_s: (F.node inout * visitor_c_s) -> F.node inout;
 
+
+  ktoplevel_s: (toplevel inout * visitor_c_s) -> toplevel inout;
   kinfo_s: (info inout * visitor_c_s) -> info inout;
  } 
 
@@ -681,6 +820,9 @@ let default_visitor_c_s =
     knode_s      = (fun (k,_) n  -> k n);
     kinfo_s      = (fun (k,_) i  -> k i);
     kdefineval_s = (fun (k,_) x  -> k x);
+    kstatementseq_s = (fun (k,_) x  -> k x);
+    kstatementseq_list_s = (fun (k,_) x  -> k x);
+    kcppdirective_s = (fun (k,_) x  -> k x);
   } 
 
 let rec vk_expr_s = fun bigf expr ->
@@ -721,7 +863,7 @@ let rec vk_expr_s = fun bigf expr ->
 
       | StatementExpr (statxs, is) -> 
           StatementExpr (
-            statxs +> List.map (vk_statement_s bigf),
+            vk_statement_sequencable_list_s bigf statxs,
             iif is)
       | Constructor (t, initxs) -> 
           Constructor 
@@ -768,15 +910,11 @@ and vk_statement_s = fun bigf st ->
                               statf st))
       | Labeled (Default st) -> Labeled (Default (statf st))
       | Compound statxs -> 
-          Compound (statxs +> List.map (vk_statement_s bigf))
+          Compound (vk_statement_sequencable_list_s bigf statxs)
       | ExprStatement (None) ->  ExprStatement (None)
       | ExprStatement (Some e) -> ExprStatement (Some ((vk_expr_s bigf) e))
       | Selection (If (e, st1, st2)) -> 
           Selection  (If ((vk_expr_s bigf) e, statf st1, statf st2))
-      | Selection (Ifdef (st1s, st2s)) -> 
-          Selection  (Ifdef 
-                         (st1s +> List.map (vk_statement_s bigf),
-                         st2s +> List.map (vk_statement_s bigf)))
       | Selection (Switch (e, st))   -> 
           Selection  (Switch ((vk_expr_s bigf) e, statf st))
       | Iteration (While (e, st))    -> 
@@ -817,6 +955,36 @@ and vk_statement_s = fun bigf st ->
     st', vk_ii_s bigf ii
   in statf st
 
+
+and vk_statement_sequencable_s = fun bigf stseq -> 
+  let f = bigf.kstatementseq_s in
+  let k stseq = 
+
+    match stseq with
+    | StmtElem st -> 
+        StmtElem (vk_statement_s bigf st)
+    | CppDirectiveStmt directive -> 
+        CppDirectiveStmt (vk_cpp_directive_s bigf directive)
+    | IfdefStmt ifdef -> 
+        IfdefStmt (vk_ifdef_directive_s bigf ifdef)
+    | IfdefStmt2 (ifdef, xxs) -> 
+        let ifdef' = List.map (vk_ifdef_directive_s bigf) ifdef in
+        let xxs' = xxs +> List.map (fun xs -> 
+          xs +> List.map (vk_statement_sequencable_s bigf)
+        )
+        in
+        IfdefStmt2(ifdef', xxs')
+  in f (k, bigf) stseq
+
+and vk_statement_sequencable_list_s = fun bigf statxs -> 
+  let f = bigf.kstatementseq_list_s in
+  let k xs = 
+    xs +> List.map (vk_statement_sequencable_s bigf)
+  in
+  f (k, bigf) statxs
+  
+
+
 and vk_asmbody_s = fun bigf (string_list, colon_list) -> 
   let  iif ii = vk_ii_s bigf ii in
 
@@ -883,6 +1051,14 @@ and vk_type_s = fun bigf t ->
 
   in typef t
 
+and vk_attribute_s = fun bigf attr -> 
+  let iif ii = vk_ii_s bigf ii in
+  match attr with
+  | Attribute s, ii -> 
+      Attribute s, iif ii
+
+
+
 and vk_decl_s = fun bigf d -> 
   let f = bigf.kdecl_s in 
   let iif ii = vk_ii_s bigf ii in
@@ -898,15 +1074,20 @@ and vk_decl_s = fun bigf d ->
           iif ii)
 
 
-  and aux ((var, t, sto, local), iicomma) = 
-    ((var +> map_option (fun ((s, ini), ii_s_ini) -> 
+  and aux ({v_namei = var; v_type = t; 
+            v_storage = sto; v_local= local; v_attr = attrs}, iicomma) = 
+    {v_namei = 
+        (var +> map_option (fun ((s, ini), ii_s_ini) -> 
       (s, ini +> map_option (fun init -> vk_ini_s bigf init)),
       iif ii_s_ini
-    )
-    ),
-    vk_type_s bigf t, 
-    sto, local),
-  iif iicomma
+        )
+        );
+     v_type = vk_type_s bigf t;
+     v_storage = sto;
+     v_local = local;
+     v_attr = attrs +> List.map (vk_attribute_s bigf);
+    },
+    iif iicomma
 
   in f (k, bigf) d 
 
@@ -932,6 +1113,7 @@ and vk_ini_s = fun bigf ini ->
     | InitFieldOld (s, e) -> InitFieldOld (s, inif e)
     | InitIndexOld (e1, e) -> InitIndexOld (vk_expr_s bigf e1, inif e)
 
+
     in ini', vk_ii_s bigf ii
   in inif ini
 
@@ -949,6 +1131,18 @@ and vk_designator_s = fun bigf design ->
 
 
 
+and vk_struct_fieldkinds_s = fun bigf onefield_multivars -> 
+  let iif ii = vk_ii_s bigf ii in
+  
+  onefield_multivars +> List.map (fun (field, iicomma) ->
+    (match field with
+    | Simple (s, t), iis -> Simple (s, vk_type_s bigf t), iif iis
+    | BitField (sopt, t, expr), iis -> 
+        BitField (sopt, vk_type_s bigf t, vk_expr_s bigf expr), 
+        iif iis
+    ), iif iicomma
+  )
+
 and vk_struct_fields_s = fun bigf fields -> 
 
   let iif ii = vk_ii_s bigf ii in
@@ -956,18 +1150,20 @@ and vk_struct_fields_s = fun bigf fields ->
   fields +> List.map (fun (xfield, iiptvirg) -> 
     
     (match xfield with
-    | FieldDeclList onefield_multivars -> 
-        FieldDeclList (
-          onefield_multivars +> List.map (fun (field, iicomma) ->
-            (match field with
-            | Simple (s, t), iis -> Simple (s, vk_type_s bigf t), iif iis
-            | BitField (sopt, t, expr), iis -> 
-                BitField (sopt, vk_type_s bigf t, vk_expr_s bigf expr), 
-                iif iis
-            ), iif iicomma
-          )
-        )
+    | (DeclarationField (FieldDeclList (onefield_multivars, iiptvirg))) -> 
+        DeclarationField
+          (FieldDeclList 
+              (vk_struct_fieldkinds_s bigf onefield_multivars, iif iiptvirg))
     | EmptyField -> EmptyField
+    | MacroStructDeclTodo -> 
+        pr2 "MacroStructDeclTodo";
+        MacroStructDeclTodo
+
+    | CppDirectiveStruct directive -> 
+        CppDirectiveStruct (vk_cpp_directive_s bigf directive)
+    | IfdefStruct ifdef -> 
+        IfdefStruct (vk_ifdef_directive_s bigf ifdef)
+
     ), iif iiptvirg
   )
 
@@ -977,16 +1173,25 @@ and vk_def_s = fun bigf d ->
   let iif ii = vk_ii_s bigf ii in
   let rec k d = 
     match d with
-    | (s, (returnt, (paramst, (b, iib))), sto, statxs), ii  -> 
-        (s, 
-        (vk_type_s bigf returnt, 
-        (paramst +> List.map (fun (param, iicomma) ->
-          (vk_param_s bigf param, iif iicomma)
-        ), 
-        (b, iif iib))), 
-        sto, 
-        statxs +> List.map (vk_statement_s bigf) 
-        ),
+    | {f_name = s;
+       f_type = (returnt, (paramst, (b, iib)));
+       f_storage = sto;
+       f_body = statxs;
+       f_attr = attrs;
+      }, ii  
+        -> 
+        {f_name = s;
+         f_type = 
+            (vk_type_s bigf returnt, 
+            (paramst +> List.map (fun (param, iicomma) ->
+              (vk_param_s bigf param, iif iicomma)
+            ), (b, iif iib)));
+         f_storage = sto;
+         f_body = 
+            vk_statement_sequencable_list_s bigf statxs;
+         f_attr = 
+            attrs +> List.map (vk_attribute_s bigf)
+        },
         iif ii
 
   in f (k, bigf) d 
@@ -1007,15 +1212,50 @@ and vk_toplevel_s = fun bigf p ->
           ),
           iif ii
           )
-    | Include ((s, ii), h_rel_pos) -> Include ((s, iif ii), h_rel_pos)
-    | Define ((s,ii), (defkind, defval)) -> 
-        Define ((s, iif ii), 
-               (vk_define_kind_s bigf defkind, vk_define_val_s bigf defval))
+    | CppTop top -> CppTop (vk_cpp_directive_s bigf top)
+    | IfdefTop ifdefdir -> IfdefTop (vk_ifdef_directive_s bigf ifdefdir)
 
     | NotParsedCorrectly ii -> NotParsedCorrectly (iif ii)
     | FinalDef info -> FinalDef (vk_info_s bigf info)
   in f (k, bigf) p
 
+and vk_program_s = fun bigf xs -> 
+  xs +> List.map (vk_toplevel_s bigf)
+
+
+and vk_cpp_directive_s = fun bigf top ->
+  let iif ii = vk_ii_s bigf ii in
+  let f = bigf.kcppdirective_s in
+  let rec k top = 
+  match top with 
+    (* go inside ? *)
+    | Include {i_include = (s, ii);
+               i_rel_pos = h_rel_pos;
+               i_is_in_ifdef = b;
+               i_content = copt;
+               } 
+      -> Include {i_include = (s, iif ii);
+                  i_rel_pos = h_rel_pos;
+                  i_is_in_ifdef = b;
+                  i_content = copt +> Common.map_option (fun (file, asts) -> 
+                    file, vk_program_s bigf asts
+                  );
+      }
+    | Define ((s,ii), (defkind, defval)) -> 
+        Define ((s, iif ii), 
+               (vk_define_kind_s bigf defkind, vk_define_val_s bigf defval))
+    | Undef (s, ii) -> Undef (s, iif ii)
+    | PragmaAndCo (ii) -> PragmaAndCo (iif ii)
+
+  in f (k, bigf) top
+
+and vk_ifdef_directive_s = fun bigf ifdef -> 
+  let iif ii = vk_ii_s bigf ii in
+  match ifdef with
+  | IfdefDirective (ifkind, ii) -> IfdefDirective (ifkind, iif ii)
+
+
+
 and vk_define_kind_s  = fun bigf defkind -> 
   match defkind with
   | DefineVar -> DefineVar 
@@ -1035,12 +1275,19 @@ and vk_define_val_s = fun bigf x ->
     match x with
     | DefineExpr e  -> DefineExpr (vk_expr_s bigf e)
     | DefineStmt st -> DefineStmt (vk_statement_s bigf st)
-    | DefineDoWhileZero (st,ii) -> 
-        DefineDoWhileZero (vk_statement_s bigf st, iif ii)
+    | DefineDoWhileZero ((st,e),ii) -> 
+        let st' = vk_statement_s bigf st in
+        let e' = vk_expr_s bigf e in
+        DefineDoWhileZero ((st',e'), iif ii)
     | DefineFunction def -> DefineFunction (vk_def_s bigf def)
     | DefineType ty -> DefineType (vk_type_s bigf ty)
     | DefineText (s, ii) -> DefineText (s, iif ii)
     | DefineEmpty -> DefineEmpty
+    | DefineInit ini -> DefineInit (vk_ini_s bigf ini)
+
+    | DefineTodo -> 
+        pr2 "DefineTodo";
+        DefineTodo
   in
   f (k, bigf) x
   
@@ -1063,13 +1310,27 @@ and vk_node_s = fun bigf node ->
   and k node = 
     F.rewrap node (
     match F.unwrap node with
-    | F.FunHeader ((idb, (rett, (paramst,(isvaargs,iidotsb))), stob),ii) ->
+    | F.FunHeader ({f_name = idb;
+                   f_type =(rett, (paramst,(isvaargs,iidotsb)));
+                   f_storage = stob;
+                   f_body = body;
+                   f_attr = attrs;
+      },ii) ->
+        assert(null body);
+
         F.FunHeader 
-          ((idb,
-           (vk_type_s bigf rett,
-           (paramst +> List.map (fun (param, iicomma) ->
-             (vk_param_s bigf param, iif iicomma)
-           ), (isvaargs,iif iidotsb))), stob),iif ii)
+          ({f_name =idb;
+            f_type =
+              (vk_type_s bigf rett,
+              (paramst +> List.map (fun (param, iicomma) ->
+                (vk_param_s bigf param, iif iicomma)
+              ), (isvaargs,iif iidotsb)));
+            f_storage = stob;
+            f_body = body;
+            f_attr = 
+              attrs +> List.map (vk_attribute_s bigf)
+          },
+          iif ii)
           
           
     | F.Decl declb -> F.Decl (vk_decl_s bigf declb)
@@ -1115,9 +1376,21 @@ and vk_node_s = fun bigf node ->
     | F.DefineType ft -> F.DefineType (vk_type_s bigf ft)
     | F.DefineDoWhileZeroHeader ((),ii) -> 
         F.DefineDoWhileZeroHeader ((),iif ii)
+    | F.DefineTodo -> F.DefineTodo
+
+    | F.Include {i_include = (s, ii);
+                 i_rel_pos = h_rel_pos;
+                 i_is_in_ifdef = b;
+                 i_content = copt;
+                 }     
+      -> 
+        assert (copt = None);
+        F.Include {i_include = (s, iif ii);
+                    i_rel_pos = h_rel_pos;
+                    i_is_in_ifdef = b;
+                    i_content = copt;
+                   }
 
-    | F.Include ((s, ii), h_rel_pos) -> F.Include ((s, iif ii), h_rel_pos)
-    | F.Ifdef (st, ((),ii)) -> F.Ifdef (st, ((),iif ii))
     | F.MacroTop (s, args, ii) -> 
         F.MacroTop 
           (s,
@@ -1140,6 +1413,10 @@ and vk_node_s = fun bigf node ->
     | F.SeqEnd (i, info) -> F.SeqEnd (i, infof info)
     | F.SeqStart (st, i, info) -> F.SeqStart (st, i, infof info)
 
+    | F.IfdefHeader (info) -> F.IfdefHeader (vk_ifdef_directive_s bigf info)
+    | F.IfdefElse (info) -> F.IfdefElse (vk_ifdef_directive_s bigf info)
+    | F.IfdefEndif (info) -> F.IfdefEndif (vk_ifdef_directive_s bigf info)
+
     | (
         (
           F.TopNode|F.EndNode|
index 58f0523..197c1d1 100644 (file)
@@ -7,10 +7,13 @@ type visitor_c = {
   kdecl      : (declaration -> unit)  * visitor_c -> declaration -> unit;
   kdef       : (definition  -> unit)  * visitor_c -> definition  -> unit;
   kini       : (initialiser -> unit)  * visitor_c -> initialiser -> unit;
-  kinfo      : (info        -> unit)  * visitor_c -> info        -> unit;
+  kcppdirective: (cpp_directive -> unit) * visitor_c -> cpp_directive -> unit;
+  kdefineval : (define_val -> unit) * visitor_c -> define_val -> unit;
+  kstatementseq: (statement_sequencable   -> unit) * visitor_c -> statement_sequencable   -> unit;
   knode      :      
     (Control_flow_c.node -> unit) * visitor_c -> Control_flow_c.node -> unit;
   ktoplevel: (toplevel -> unit) * visitor_c -> toplevel -> unit;
+  kinfo      : (info        -> unit)  * visitor_c -> info        -> unit;
 }
 
 val default_visitor_c : visitor_c
@@ -23,7 +26,8 @@ val vk_ini       : visitor_c -> initialiser -> unit
 val vk_def       : visitor_c -> definition  -> unit
 val vk_node      : visitor_c -> Control_flow_c.node -> unit
 val vk_info      : visitor_c -> info -> unit
-val vk_toplevel :   visitor_c -> toplevel -> unit
+val vk_toplevel : visitor_c -> toplevel -> unit
+val vk_program  : visitor_c -> program -> unit
 
 val vk_argument : visitor_c -> argument -> unit
 
@@ -32,8 +36,8 @@ val vk_param : visitor_c -> parameterType -> unit
 val vk_params_splitted : 
   visitor_c -> (parameterType, il) Common.either list -> unit
 
-val vk_struct_fields : visitor_c -> field wrap list -> unit
-val vk_struct_field : visitor_c -> fieldkind wrap list -> unit
+val vk_struct_fields : visitor_c -> field list -> unit
+val vk_struct_fieldkinds : visitor_c -> fieldkind wrap list -> unit
 
 val vk_cst : visitor_c -> ((constant, string) Common.either wrap) -> unit
 
@@ -48,13 +52,17 @@ type visitor_c_s = {
   kexpr_s      : expression     inout * visitor_c_s -> expression     inout;
   kstatement_s : statement      inout * visitor_c_s -> statement      inout;
   ktype_s      : fullType       inout * visitor_c_s -> fullType       inout;
-  kini_s       : initialiser    inout * visitor_c_s -> initialiser    inout;
   kdecl_s      : declaration    inout * visitor_c_s -> declaration    inout;
   kdef_s       : definition     inout * visitor_c_s -> definition     inout;
-  ktoplevel_s  : toplevel inout * visitor_c_s -> toplevel inout;
+  kini_s       : initialiser    inout * visitor_c_s -> initialiser    inout;
+  kcppdirective_s : (cpp_directive inout * visitor_c_s) -> cpp_directive inout;
+  kdefineval_s : (define_val inout * visitor_c_s) -> define_val inout;
+  kstatementseq_s: (statement_sequencable inout * visitor_c_s) -> statement_sequencable inout;
+  kstatementseq_list_s: 
+    (statement_sequencable list inout * visitor_c_s) -> statement_sequencable list inout;
   knode_s      : 
     Control_flow_c.node inout * visitor_c_s -> Control_flow_c.node    inout;
-  kdefineval_s : (define_val inout * visitor_c_s) -> define_val inout;
+  ktoplevel_s  : toplevel inout * visitor_c_s -> toplevel inout;
   kinfo_s      : info           inout * visitor_c_s -> info           inout;
   }
 
@@ -63,6 +71,7 @@ val default_visitor_c_s : visitor_c_s
 val vk_expr_s : visitor_c_s -> expression -> expression
 val vk_argument_s : visitor_c_s -> argument -> argument
 val vk_statement_s : visitor_c_s -> statement -> statement
+val vk_statement_sequencable_s : visitor_c_s -> statement_sequencable -> statement_sequencable
 val vk_type_s : visitor_c_s -> fullType -> fullType
 val vk_decl_s : visitor_c_s -> declaration -> declaration
 val vk_ini_s : visitor_c_s -> initialiser -> initialiser
@@ -70,6 +79,7 @@ val vk_def_s : visitor_c_s -> definition -> definition
 val vk_toplevel_s : visitor_c_s -> toplevel -> toplevel
 val vk_info_s : visitor_c_s -> info -> info
 val vk_node_s : visitor_c_s -> Control_flow_c.node -> Control_flow_c.node
+val vk_program_s  : visitor_c_s -> program -> program
 
 val vk_arguments_s : 
   visitor_c_s -> 
@@ -98,7 +108,6 @@ val vk_define_params_splitted_s :
   (string Ast_c.wrap, il) Common.either list -> 
   (string Ast_c.wrap, il) Common.either list
 
-val vk_struct_fields_s : visitor_c_s -> 
-  field wrap list -> field wrap list
+val vk_struct_fields_s : visitor_c_s -> field list -> field list
 
 val vk_cst_s : visitor_c_s -> ((constant, string) Common.either wrap) inout 
diff --git a/parsing_cocci/.#ast0_cocci.ml.1.107 b/parsing_cocci/.#ast0_cocci.ml.1.107
new file mode 100644 (file)
index 0000000..5d9f214
--- /dev/null
@@ -0,0 +1,646 @@
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+* 
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+* 
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
+* 
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+module Ast = Ast_cocci
+
+(* --------------------------------------------------------------------- *)
+(* Modified code *)
+
+type arity = OPT | UNIQUE | NONE
+
+type token_info =
+    { tline_start : int; tline_end : int;
+      left_offset : int; right_offset : int }
+let default_token_info =
+  { tline_start = -1; tline_end = -1; left_offset = -1; right_offset = -1 }
+
+(* MIXED is like CONTEXT, since sometimes MIXED things have to revert to
+CONTEXT - see insert_plus.ml *)
+type mcodekind =
+    MINUS       of (Ast.anything list list * token_info) ref
+  | PLUS
+  | CONTEXT     of (Ast.anything Ast.befaft * token_info * token_info) ref
+  | MIXED       of (Ast.anything Ast.befaft * token_info * token_info) ref
+
+type info = { line_start : int; line_end : int;
+             logical_start : int; logical_end : int;
+             attachable_start : bool; attachable_end : bool;
+             mcode_start : mcodekind list; mcode_end : mcodekind list;
+             column : int; offset : int;
+             (* the following are only for + code *)
+             strings_before : string list; strings_after : string list }
+
+type 'a mcode = 'a * arity * info * mcodekind * meta_pos ref (* pos, - only *)
+(* int ref is an index *)
+and 'a wrap =
+    { node : 'a;
+      info : info;
+      index : int ref;
+      mcodekind : mcodekind ref;
+      exp_ty : Type_cocci.typeC option ref; (* only for expressions *)
+      bef_aft : dots_bef_aft; (* only for statements *)
+      true_if_arg : bool; (* true if "arg_exp", only for exprs *)
+      true_if_test : bool; (* true if "test position", only for exprs *)
+      true_if_test_exp : bool;(* true if "test_exp from iso", only for exprs *)
+      (*nonempty if this represents the use of an iso*)
+      iso_info : (string*anything) list }
+
+and dots_bef_aft =
+    NoDots | AddingBetweenDots of statement | DroppingBetweenDots of statement
+
+(* for iso metavariables, true if they can only match nonmodified terms with
+   all metavariables unitary
+   for SP metavariables, true if the metavariable is unitary (valid up to
+   isomorphism phase only)
+   In SP, the only options are impure and context
+*)
+and pure = Impure | Pure | Context | PureContext (* pure and only context *)
+
+(* --------------------------------------------------------------------- *)
+(* --------------------------------------------------------------------- *)
+(* Dots *)
+
+and 'a base_dots =
+    DOTS of 'a list
+  | CIRCLES of 'a list
+  | STARS of 'a list
+
+and 'a dots = 'a base_dots wrap
+
+(* --------------------------------------------------------------------- *)
+(* Identifier *)
+
+and base_ident =
+    Id of string mcode
+  | MetaId        of Ast.meta_name mcode * ident list * pure
+  | MetaFunc      of Ast.meta_name mcode * ident list * pure
+  | MetaLocalFunc of Ast.meta_name mcode * ident list * pure
+  | OptIdent      of ident
+  | UniqueIdent   of ident
+
+and ident = base_ident wrap
+
+(* --------------------------------------------------------------------- *)
+(* Expression *)
+
+and base_expression = 
+    Ident          of ident
+  | Constant       of Ast.constant mcode
+  | FunCall        of expression * string mcode (* ( *) *
+                      expression dots * string mcode (* ) *)
+  | Assignment     of expression * Ast.assignOp mcode * expression *
+                     bool (* true if it can match an initialization *)
+  | CondExpr       of expression * string mcode (* ? *) * expression option *
+                     string mcode (* : *) * expression
+  | Postfix        of expression * Ast.fixOp mcode
+  | Infix          of expression * Ast.fixOp mcode
+  | Unary          of expression * Ast.unaryOp mcode
+  | Binary         of expression * Ast.binaryOp mcode * expression
+  | Nested         of expression * Ast.binaryOp mcode * expression
+  | Paren          of string mcode (* ( *) * expression *
+                      string mcode (* ) *)
+  | ArrayAccess    of expression * string mcode (* [ *) * expression *
+                     string mcode (* ] *)
+  | RecordAccess   of expression * string mcode (* . *) * ident
+  | RecordPtAccess of expression * string mcode (* -> *) * ident
+  | Cast           of string mcode (* ( *) * typeC * string mcode (* ) *) *
+                      expression
+  | SizeOfExpr     of string mcode (* sizeof *) * expression
+  | SizeOfType     of string mcode (* sizeof *) * string mcode (* ( *) *
+                      typeC * string mcode (* ) *)
+  | TypeExp        of typeC (* type name used as an expression, only in args *)
+  | MetaErr        of Ast.meta_name mcode * expression list * pure
+  | MetaExpr       of Ast.meta_name mcode * expression list *
+                     Type_cocci.typeC list option * Ast.form * pure
+  | MetaExprList   of Ast.meta_name mcode (* only in arg lists *) *
+                     listlen * pure
+  | EComma         of string mcode (* only in arg lists *)
+  | DisjExpr       of string mcode * expression list *
+                     string mcode list (* the |s *) * string mcode
+  | NestExpr       of string mcode * expression dots * string mcode *
+                     expression option * Ast.multi
+  | Edots          of string mcode (* ... *) * expression option
+  | Ecircles       of string mcode (* ooo *) * expression option
+  | Estars         of string mcode (* *** *) * expression option
+  | OptExp         of expression
+  | UniqueExp      of expression
+
+and expression = base_expression wrap
+
+and listlen = Ast.meta_name mcode option
+
+(* --------------------------------------------------------------------- *)
+(* Types *)
+
+and base_typeC = 
+    ConstVol        of Ast.const_vol mcode * typeC
+  | BaseType        of Ast.baseType mcode * Ast.sign mcode option
+  | ImplicitInt     of Ast.sign mcode
+  | Pointer         of typeC * string mcode (* * *)
+  | FunctionPointer of typeC *
+                 string mcode(* ( *)*string mcode(* * *)*string mcode(* ) *)*
+                  string mcode (* ( *)*parameter_list*string mcode(* ) *)
+  | FunctionType    of typeC option *
+                      string mcode (* ( *) * parameter_list *
+                       string mcode (* ) *)
+  | Array           of typeC * string mcode (* [ *) *
+                      expression option * string mcode (* ] *)
+  | StructUnionName of Ast.structUnion mcode * ident option (* name *)
+  | StructUnionDef  of typeC (* either StructUnionName or metavar *) *
+       string mcode (* { *) * declaration dots * string mcode (* } *)
+  | TypeName        of string mcode
+  | MetaType        of Ast.meta_name mcode * pure
+  | DisjType        of string mcode * typeC list * (* only after iso *)
+                       string mcode list (* the |s *)  * string mcode
+  | OptType         of typeC
+  | UniqueType      of typeC
+
+and typeC = base_typeC wrap
+
+(* --------------------------------------------------------------------- *)
+(* Variable declaration *)
+(* Even if the Cocci program specifies a list of declarations, they are
+   split out into multiple declarations of a single variable each. *)
+
+and base_declaration =
+    Init of Ast.storage mcode option * typeC * ident * string mcode (*=*) *
+       initialiser * string mcode (*;*)
+  | UnInit of Ast.storage mcode option * typeC * ident * string mcode (* ; *)
+  | TyDecl of typeC * string mcode (* ; *)
+  | MacroDecl of ident (* name *) * string mcode (* ( *) *
+        expression dots * string mcode (* ) *) * string mcode (* ; *)
+  | Typedef of string mcode (* typedef *) * typeC * typeC * string mcode (*;*)
+  | DisjDecl   of string mcode * declaration list *
+                  string mcode list (* the |s *)  * string mcode
+  (* Ddots is for a structure declaration *)
+  | Ddots      of string mcode (* ... *) * declaration option (* whencode *)
+  | OptDecl    of declaration
+  | UniqueDecl of declaration
+
+and declaration = base_declaration wrap
+
+(* --------------------------------------------------------------------- *)
+(* Initializers *)
+
+and base_initialiser =
+    InitExpr of expression 
+  | InitList of string mcode (*{*) * initialiser_list * string mcode (*}*)
+  | InitGccDotName of
+      string mcode (*.*) * ident (* name *) * string mcode (*=*) *
+       initialiser (* gccext: *)
+  | InitGccName of ident (* name *) * string mcode (*:*) *
+       initialiser
+  | InitGccIndex of
+      string mcode (*[*) * expression * string mcode (*]*) *
+       string mcode (*=*) * initialiser
+  | InitGccRange of
+      string mcode (*[*) * expression * string mcode (*...*) *
+        expression * string mcode (*]*) * string mcode (*=*) * initialiser
+  | IComma of string mcode (* , *)
+  | Idots  of string mcode (* ... *) * initialiser option (* whencode *)
+  | OptIni    of initialiser
+  | UniqueIni of initialiser
+
+and initialiser = base_initialiser wrap
+
+and initialiser_list = initialiser dots
+
+(* --------------------------------------------------------------------- *)
+(* Parameter *)
+
+and base_parameterTypeDef =
+    VoidParam     of typeC
+  | Param         of typeC * ident option
+  | MetaParam     of Ast.meta_name mcode * pure
+  | MetaParamList of Ast.meta_name mcode * listlen * pure
+  | PComma        of string mcode
+  | Pdots         of string mcode (* ... *)
+  | Pcircles      of string mcode (* ooo *)
+  | OptParam      of parameterTypeDef
+  | UniqueParam   of parameterTypeDef
+
+and parameterTypeDef = base_parameterTypeDef wrap
+
+and parameter_list = parameterTypeDef dots
+
+(* --------------------------------------------------------------------- *)
+(* #define Parameters *)
+
+and base_define_param =
+    DParam        of ident
+  | DPComma       of string mcode
+  | DPdots        of string mcode (* ... *)
+  | DPcircles     of string mcode (* ooo *)
+  | OptDParam     of define_param
+  | UniqueDParam  of define_param
+
+and define_param = base_define_param wrap
+
+and base_define_parameters =
+    NoParams
+  | DParams      of string mcode(*( *) * define_param dots * string mcode(* )*)
+
+and define_parameters = base_define_parameters wrap
+
+(* --------------------------------------------------------------------- *)
+(* Statement*)
+
+and base_statement =
+    Decl          of (info * mcodekind) (* before the decl *) * declaration
+  | Seq           of string mcode (* { *) * statement dots *
+                    string mcode (* } *)
+  | ExprStatement of expression * string mcode (*;*)
+  | IfThen        of string mcode (* if *) * string mcode (* ( *) *
+                    expression * string mcode (* ) *) *
+                    statement * (info * mcodekind) (* after info *)
+  | IfThenElse    of string mcode (* if *) * string mcode (* ( *) *
+                    expression * string mcode (* ) *) *
+                    statement * string mcode (* else *) * statement *
+                    (info * mcodekind)
+  | While         of string mcode (* while *) * string mcode (* ( *) *
+                    expression * string mcode (* ) *) *
+                    statement * (info * mcodekind) (* after info *)
+  | Do            of string mcode (* do *) * statement *
+                     string mcode (* while *) * string mcode (* ( *) *
+                    expression * string mcode (* ) *) *
+                     string mcode (* ; *)
+  | For           of string mcode (* for *) * string mcode (* ( *) *
+                     expression option * string mcode (*;*) *
+                    expression option * string mcode (*;*) *
+                     expression option * string mcode (* ) *) * statement *
+                    (info * mcodekind) (* after info *)
+  | Iterator      of ident (* name *) * string mcode (* ( *) *
+                    expression dots * string mcode (* ) *) *
+                    statement * (info * mcodekind) (* after info *)
+  | Switch        of string mcode (* switch *) * string mcode (* ( *) *
+                    expression * string mcode (* ) *) * string mcode (* { *) *
+                    case_line dots * string mcode (* } *)
+  | Break         of string mcode (* break *) * string mcode (* ; *)
+  | Continue      of string mcode (* continue *) * string mcode (* ; *)
+  | Label         of ident * string mcode (* : *)
+  | Goto          of string mcode (* goto *) * ident * string mcode (* ; *)
+  | Return        of string mcode (* return *) * string mcode (* ; *)
+  | ReturnExpr    of string mcode (* return *) * expression *
+                    string mcode (* ; *)
+  | MetaStmt      of Ast.meta_name mcode * pure
+  | MetaStmtList  of Ast.meta_name mcode(*only in statement lists*) * pure
+  | Exp           of expression  (* only in dotted statement lists *)
+  | TopExp        of expression (* for macros body *)
+  | Ty            of typeC (* only at top level *)
+  | TopInit       of initialiser (* only at top level *)
+  | Disj          of string mcode * statement dots list *
+                    string mcode list (* the |s *)  * string mcode
+  | Nest          of string mcode * statement dots * string mcode *
+                    (statement dots,statement) whencode list * Ast.multi
+  | Dots          of string mcode (* ... *) *
+                     (statement dots,statement) whencode list
+  | Circles       of string mcode (* ooo *) *
+                    (statement dots,statement) whencode list
+  | Stars         of string mcode (* *** *) *
+                    (statement dots,statement) whencode list
+  | FunDecl of (info * mcodekind) (* before the function decl *) *
+       fninfo list * ident (* name *) *
+       string mcode (* ( *) * parameter_list * string mcode (* ) *) *
+       string mcode (* { *) * statement dots *
+       string mcode (* } *)
+  | Include of string mcode (* #include *) * Ast.inc_file mcode (* file *)
+  | Define of string mcode (* #define *) * ident (* name *) *
+       define_parameters (*params*) * statement dots
+  | OptStm   of statement
+  | UniqueStm of statement
+
+and fninfo =
+    FStorage of Ast.storage mcode
+  | FType of typeC
+  | FInline of string mcode
+  | FAttr of string mcode
+
+and ('a,'b) whencode =
+    WhenNot of 'a
+  | WhenAlways of 'b
+  | WhenModifier of Ast.when_modifier
+  | WhenNotTrue of expression
+  | WhenNotFalse of expression
+
+and statement = base_statement wrap
+
+and base_case_line =
+    Default of string mcode (* default *) * string mcode (*:*) * statement dots
+  | Case of string mcode (* case *) * expression * string mcode (*:*) *
+       statement dots
+  | OptCase of case_line
+
+and case_line = base_case_line wrap
+
+(* --------------------------------------------------------------------- *)
+(* Positions *)
+
+and meta_pos =
+    MetaPos of Ast.meta_name mcode * Ast.meta_name list * Ast.meta_collect
+  | NoMetaPos
+
+(* --------------------------------------------------------------------- *)
+(* Top-level code *)
+
+and base_top_level =
+    DECL of statement
+  | CODE of statement dots
+  | FILEINFO of string mcode (* old file *) * string mcode (* new file *)
+  | ERRORWORDS of expression list
+  | OTHER of statement (* temporary, disappears after top_level.ml *)
+
+and top_level = base_top_level wrap
+and rule = top_level list
+
+and parsed_rule =
+    CocciRule of
+      (rule * Ast.metavar list *
+        (string list * string list * Ast.dependency * string * Ast.exists)) *
+       (rule * Ast.metavar list)
+  | ScriptRule of
+      string * Ast.dependency * (string * Ast.meta_name) list * string
+
+(* --------------------------------------------------------------------- *)
+
+and anything =
+    DotsExprTag of expression dots
+  | DotsInitTag of initialiser dots
+  | DotsParamTag of parameterTypeDef dots
+  | DotsStmtTag of statement dots
+  | DotsDeclTag of declaration dots
+  | DotsCaseTag of case_line dots
+  | IdentTag of ident
+  | ExprTag of expression
+  | ArgExprTag of expression  (* for isos *)
+  | TestExprTag of expression (* for isos *)
+  | TypeCTag of typeC
+  | ParamTag of parameterTypeDef
+  | InitTag of initialiser
+  | DeclTag of declaration
+  | StmtTag of statement
+  | CaseLineTag of case_line
+  | TopTag of top_level
+  | IsoWhenTag of Ast.when_modifier
+  | IsoWhenTTag of expression
+  | IsoWhenFTag of expression
+  | MetaPosTag of meta_pos
+
+let dotsExpr x = DotsExprTag x
+let dotsParam x = DotsParamTag x
+let dotsInit x = DotsInitTag x
+let dotsStmt x = DotsStmtTag x
+let dotsDecl x = DotsDeclTag x
+let dotsCase x = DotsCaseTag x
+let ident x = IdentTag x
+let expr x = ExprTag x
+let typeC x = TypeCTag x
+let param x = ParamTag x
+let ini x = InitTag x
+let decl x = DeclTag x
+let stmt x = StmtTag x
+let case_line x = CaseLineTag x
+let top x = TopTag x
+
+(* --------------------------------------------------------------------- *)
+(* Avoid cluttering the parser.  Calculated in compute_lines.ml. *)
+
+let default_info _ = (* why is this a function? *)
+  { line_start = -1; line_end = -1;
+    logical_start = -1; logical_end = -1;
+    attachable_start = true; attachable_end = true;
+    mcode_start = []; mcode_end = [];
+    column = -1; offset = -1; strings_before = []; strings_after = [] }
+
+let default_befaft _ =
+  MIXED(ref (Ast.NOTHING,default_token_info,default_token_info))
+let context_befaft _ =
+  CONTEXT(ref (Ast.NOTHING,default_token_info,default_token_info))
+
+let wrap x =
+  { node = x;
+    info = default_info();
+    index = ref (-1);
+    mcodekind = ref (default_befaft());
+    exp_ty = ref None;
+    bef_aft = NoDots;
+    true_if_arg = false;
+    true_if_test = false;
+    true_if_test_exp = false;
+    iso_info = [] }
+let context_wrap x =
+  { node = x;
+    info = default_info();
+    index = ref (-1);
+    mcodekind = ref (context_befaft());
+    exp_ty = ref None;
+    bef_aft = NoDots;
+    true_if_arg = false;
+    true_if_test = false;
+    true_if_test_exp = false;
+    iso_info = [] }
+let unwrap x = x.node
+let unwrap_mcode (x,_,_,_,_) = x
+let rewrap model x = { model with node = x }
+let rewrap_mcode (_,arity,info,mcodekind,pos) x = (x,arity,info,mcodekind,pos)
+let copywrap model x =
+  { model with node = x; index = ref !(model.index);
+    mcodekind = ref !(model.mcodekind); exp_ty = ref !(model.exp_ty)}
+let get_pos (_,_,_,_,x) = !x
+let get_pos_ref (_,_,_,_,x) = x
+let set_pos pos (m,arity,info,mcodekind,_) = (m,arity,info,mcodekind,ref pos)
+let get_info x      = x.info
+let set_info x info = {x with info = info}
+let get_line x      = x.info.line_start
+let get_line_end x  = x.info.line_end
+let get_index x     = !(x.index)
+let set_index x i   = x.index := i
+let get_mcodekind x = !(x.mcodekind)
+let get_mcode_mcodekind (_,_,_,mcodekind,_) = mcodekind
+let get_mcodekind_ref x = x.mcodekind
+let set_mcodekind x mk  = x.mcodekind := mk
+let set_type x t        = x.exp_ty := t
+let get_type x          = !(x.exp_ty)
+let get_dots_bef_aft x  = x.bef_aft
+let set_dots_bef_aft x dots_bef_aft = {x with bef_aft = dots_bef_aft}
+let get_arg_exp x       = x.true_if_arg
+let set_arg_exp x       = {x with true_if_arg = true}
+let get_test_pos x      = x.true_if_test
+let set_test_pos x      = {x with true_if_test = true}
+let get_test_exp x      = x.true_if_test_exp
+let set_test_exp x      = {x with true_if_test_exp = true}
+let get_iso x           = x.iso_info
+let set_iso x i = if !Flag.track_iso_usage then {x with iso_info = i} else x
+let set_mcode_data data (_,ar,info,mc,pos) = (data,ar,info,mc,pos)
+
+(* --------------------------------------------------------------------- *)
+
+(* unique indices, for mcode and tree nodes *)
+let index_counter = ref 0
+let fresh_index _ = let cur = !index_counter in index_counter := cur + 1; cur
+
+(* --------------------------------------------------------------------- *)
+
+let undots d =
+  match unwrap d with
+  | DOTS    e -> e
+  | CIRCLES e -> e
+  | STARS   e -> e
+
+(* --------------------------------------------------------------------- *)
+
+let rec ast0_type_to_type ty =
+  match unwrap ty with
+    ConstVol(cv,ty) -> Type_cocci.ConstVol(const_vol cv,ast0_type_to_type ty)
+  | BaseType(bty,None) ->
+      Type_cocci.BaseType(baseType bty,None)
+  | BaseType(bty,Some sgn) ->
+      Type_cocci.BaseType(baseType bty,Some (sign sgn))
+  | ImplicitInt(sgn) ->
+      let bty = Type_cocci.IntType in
+      Type_cocci.BaseType(bty,Some (sign sgn))
+  | Pointer(ty,_) -> Type_cocci.Pointer(ast0_type_to_type ty)
+  | FunctionPointer(ty,_,_,_,_,params,_) ->
+      Type_cocci.FunctionPointer(ast0_type_to_type ty)
+  | FunctionType _ -> failwith "not supported"
+  | Array(ety,_,_,_) -> Type_cocci.Array(ast0_type_to_type ety)
+  | StructUnionName(su,Some tag) ->
+      (match unwrap tag with
+       Id(tag) ->
+         Type_cocci.StructUnionName(structUnion su,false,unwrap_mcode tag)
+      | MetaId(tag,_,_) ->
+         (Printf.printf
+            "warning: struct/union with a metavariable name detected.\n";
+          Printf.printf
+            "For type checking assuming the name of the metavariable is the name of the type\n";
+          let (rule,tag) = unwrap_mcode tag in
+          Type_cocci.StructUnionName(structUnion su,true,rule^tag))
+      | _ -> failwith "unexpected struct/union type name")
+  | StructUnionName(su,None) -> failwith "nameless structure - what to do???"
+  | StructUnionDef(ty,_,_,_) -> ast0_type_to_type ty
+  | TypeName(name) -> Type_cocci.TypeName(unwrap_mcode name)
+  | MetaType(name,_) ->
+      Type_cocci.MetaType(unwrap_mcode name,Type_cocci.Unitary,false)
+  | DisjType(_,types,_,_) -> failwith "unexpected DisjType"
+  | OptType(ty) | UniqueType(ty) ->
+      ast0_type_to_type ty
+
+and baseType t =
+  match unwrap_mcode t with
+    Ast.VoidType -> Type_cocci.VoidType
+  | Ast.CharType -> Type_cocci.CharType
+  | Ast.ShortType -> Type_cocci.ShortType
+  | Ast.IntType -> Type_cocci.IntType
+  | Ast.DoubleType -> Type_cocci.DoubleType
+  | Ast.FloatType -> Type_cocci.FloatType
+  | Ast.LongType -> Type_cocci.LongType
+
+and structUnion t =
+  match unwrap_mcode t with
+    Ast.Struct -> Type_cocci.Struct
+  | Ast.Union -> Type_cocci.Union
+
+and sign t =
+  match unwrap_mcode t with
+    Ast.Signed -> Type_cocci.Signed
+  | Ast.Unsigned -> Type_cocci.Unsigned
+
+and const_vol t =
+  match unwrap_mcode t with
+    Ast.Const -> Type_cocci.Const
+  | Ast.Volatile -> Type_cocci.Volatile
+
+(* --------------------------------------------------------------------- *)
+(* this function is a rather minimal attempt.  the problem is that information
+has been lost.  but since it is only used for metavariable types in the isos,
+perhaps it doesn't matter *)
+let make_mcode x = (x,NONE,default_info(),context_befaft(),ref NoMetaPos)
+let make_mcode_info x info = (x,NONE,info,context_befaft(),ref NoMetaPos)
+
+exception TyConv
+
+let rec reverse_type ty =
+  match ty with
+    Type_cocci.ConstVol(cv,ty) ->
+      ConstVol(reverse_const_vol cv,wrap(reverse_type ty))
+  | Type_cocci.BaseType(bty,None) ->
+      BaseType(reverse_baseType bty,None)
+  | Type_cocci.BaseType(bty,Some sgn) ->
+      BaseType(reverse_baseType bty,Some (reverse_sign sgn))
+  | Type_cocci.Pointer(ty) ->
+      Pointer(wrap(reverse_type ty),make_mcode "*")
+  | Type_cocci.StructUnionName(su,mv,tag) ->
+      if mv
+      then
+       (* not right... *)
+       StructUnionName(reverse_structUnion su,
+                       Some(wrap(MetaId(make_mcode ("",tag),[],Impure))))
+      else
+       StructUnionName(reverse_structUnion su,
+                       Some (wrap(Id(make_mcode tag))))
+  | Type_cocci.TypeName(name) -> TypeName(make_mcode name)
+  | Type_cocci.MetaType(name,_,_) ->
+      MetaType(make_mcode name,Impure(*not really right*))
+  | _ -> raise TyConv
+
+and reverse_baseType t =
+  make_mcode
+    (match t with
+      Type_cocci.VoidType -> Ast.VoidType
+    | Type_cocci.CharType -> Ast.CharType
+    | Type_cocci.BoolType -> Ast.IntType
+    | Type_cocci.ShortType -> Ast.ShortType
+    | Type_cocci.IntType -> Ast.IntType
+    | Type_cocci.DoubleType -> Ast.DoubleType
+    | Type_cocci.FloatType -> Ast.FloatType
+    | Type_cocci.LongType -> Ast.LongType)
+
+and reverse_structUnion t =
+  make_mcode
+    (match t with
+      Type_cocci.Struct -> Ast.Struct
+    | Type_cocci.Union -> Ast.Union)
+
+and reverse_sign t =
+  make_mcode
+    (match t with
+      Type_cocci.Signed -> Ast.Signed
+    | Type_cocci.Unsigned -> Ast.Unsigned)
+
+and reverse_const_vol t =
+  make_mcode
+    (match t with
+      Type_cocci.Const -> Ast.Const
+    | Type_cocci.Volatile -> Ast.Volatile)
+
+(* --------------------------------------------------------------------- *)
+
+let lub_pure x y =
+  match (x,y) with
+    (Impure,_) | (_,Impure) -> Impure
+  | (Pure,Context) | (Context,Pure) -> Impure
+  | (Pure,_) | (_,Pure) -> Pure
+  | (_,Context) | (Context,_) -> Context
+  | _ -> PureContext
+
+(* --------------------------------------------------------------------- *)
+
+let rule_name = ref "" (* for the convenience of the parser *)
diff --git a/parsing_cocci/.#context_neg.ml.1.97 b/parsing_cocci/.#context_neg.ml.1.97
new file mode 100644 (file)
index 0000000..abc2054
--- /dev/null
@@ -0,0 +1,1003 @@
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+* 
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+* 
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
+* 
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+(* Detects subtrees that are all minus/plus and nodes that are "binding
+context nodes".  The latter is a node whose structure and immediate tokens
+are the same in the minus and plus trees, and such that for every child,
+the set of context nodes in the child subtree is the same in the minus and
+plus subtrees. *)
+
+module Ast = Ast_cocci
+module Ast0 = Ast0_cocci
+module V0 = Visitor_ast0
+module U = Unparse_ast0
+
+(* --------------------------------------------------------------------- *)
+(* Generic access to code *)
+
+let set_mcodekind x mcodekind =
+  match x with
+    Ast0.DotsExprTag(d) -> Ast0.set_mcodekind d mcodekind
+  | Ast0.DotsInitTag(d) -> Ast0.set_mcodekind d mcodekind
+  | Ast0.DotsParamTag(d) -> Ast0.set_mcodekind d mcodekind
+  | Ast0.DotsStmtTag(d) -> Ast0.set_mcodekind d mcodekind
+  | Ast0.DotsDeclTag(d) -> Ast0.set_mcodekind d mcodekind
+  | Ast0.DotsCaseTag(d) -> Ast0.set_mcodekind d mcodekind
+  | Ast0.IdentTag(d) -> Ast0.set_mcodekind d mcodekind
+  | Ast0.ExprTag(d) -> Ast0.set_mcodekind d mcodekind
+  | Ast0.ArgExprTag(d) | Ast0.TestExprTag(d) ->
+      failwith "not possible - iso only"
+  | Ast0.TypeCTag(d) -> Ast0.set_mcodekind d mcodekind
+  | Ast0.ParamTag(d) -> Ast0.set_mcodekind d mcodekind
+  | Ast0.DeclTag(d) -> Ast0.set_mcodekind d mcodekind
+  | Ast0.InitTag(d) -> Ast0.set_mcodekind d mcodekind
+  | Ast0.StmtTag(d) -> Ast0.set_mcodekind d mcodekind
+  | Ast0.CaseLineTag(d) -> Ast0.set_mcodekind d mcodekind
+  | Ast0.TopTag(d) -> Ast0.set_mcodekind d mcodekind
+  | Ast0.IsoWhenTag(_) -> failwith "only within iso phase"
+  | Ast0.IsoWhenTTag(_) -> failwith "only within iso phase"
+  | Ast0.IsoWhenFTag(_) -> failwith "only within iso phase"
+  | Ast0.MetaPosTag(p) -> failwith "metapostag only within iso phase"
+
+let set_index x index =
+  match x with
+    Ast0.DotsExprTag(d) -> Ast0.set_index d index
+  | Ast0.DotsInitTag(d) -> Ast0.set_index d index
+  | Ast0.DotsParamTag(d) -> Ast0.set_index d index
+  | Ast0.DotsStmtTag(d) -> Ast0.set_index d index
+  | Ast0.DotsDeclTag(d) -> Ast0.set_index d index
+  | Ast0.DotsCaseTag(d) -> Ast0.set_index d index
+  | Ast0.IdentTag(d) -> Ast0.set_index d index
+  | Ast0.ExprTag(d) -> Ast0.set_index d index
+  | Ast0.ArgExprTag(d) | Ast0.TestExprTag(d) ->
+      failwith "not possible - iso only"
+  | Ast0.TypeCTag(d) -> Ast0.set_index d index
+  | Ast0.ParamTag(d) -> Ast0.set_index d index
+  | Ast0.InitTag(d) -> Ast0.set_index d index
+  | Ast0.DeclTag(d) -> Ast0.set_index d index
+  | Ast0.StmtTag(d) -> Ast0.set_index d index
+  | Ast0.CaseLineTag(d) -> Ast0.set_index d index
+  | Ast0.TopTag(d) -> Ast0.set_index d index
+  | Ast0.IsoWhenTag(_) -> failwith "only within iso phase"
+  | Ast0.IsoWhenTTag(_) -> failwith "only within iso phase"
+  | Ast0.IsoWhenFTag(_) -> failwith "only within iso phase"
+  | Ast0.MetaPosTag(p) -> failwith "metapostag only within iso phase"
+
+let get_index = function
+    Ast0.DotsExprTag(d) -> Index.expression_dots d
+  | Ast0.DotsInitTag(d) -> Index.initialiser_dots d
+  | Ast0.DotsParamTag(d) -> Index.parameter_dots d
+  | Ast0.DotsStmtTag(d) -> Index.statement_dots d
+  | Ast0.DotsDeclTag(d) -> Index.declaration_dots d
+  | Ast0.DotsCaseTag(d) -> Index.case_line_dots d
+  | Ast0.IdentTag(d) -> Index.ident d
+  | Ast0.ExprTag(d) -> Index.expression d
+  | Ast0.ArgExprTag(d) | Ast0.TestExprTag(d) ->
+      failwith "not possible - iso only"
+  | Ast0.TypeCTag(d) -> Index.typeC d
+  | Ast0.ParamTag(d) -> Index.parameterTypeDef d
+  | Ast0.InitTag(d) -> Index.initialiser d
+  | Ast0.DeclTag(d) -> Index.declaration d
+  | Ast0.StmtTag(d) -> Index.statement d
+  | Ast0.CaseLineTag(d) -> Index.case_line d
+  | Ast0.TopTag(d) -> Index.top_level d
+  | Ast0.IsoWhenTag(_) -> failwith "only within iso phase"
+  | Ast0.IsoWhenTTag(_) -> failwith "only within iso phase"
+  | Ast0.IsoWhenFTag(_) -> failwith "only within iso phase"
+  | Ast0.MetaPosTag(p) -> failwith "metapostag only within iso phase"
+
+(* --------------------------------------------------------------------- *)
+(* Collect the line numbers of the plus code.  This is used for disjunctions.
+It is not completely clear why this is necessary, but it seems like an easy
+fix for whatever is the problem that is discussed in disj_cases *)
+
+let plus_lines = ref ([] : int list)
+
+let insert n =
+  let rec loop = function
+      [] -> [n]
+    | x::xs ->
+       match compare n x with
+         1 -> x::(loop xs)
+       | 0 -> x::xs
+       | -1 -> n::x::xs
+       | _ -> failwith "not possible" in
+  plus_lines := loop !plus_lines
+
+let find n min max =
+  let rec loop = function
+      [] -> (min,max)
+    | [x] -> if n < x then (min,x) else (x,max)
+    | x1::x2::rest ->
+       if n < x1
+       then (min,x1)
+       else if n > x1 && n < x2 then (x1,x2) else loop (x2::rest) in
+  loop !plus_lines
+
+let collect_plus_lines top =
+  plus_lines := [];
+  let bind x y = () in
+  let option_default = () in
+  let donothing r k e = k e in
+  let mcode (_,_,info,mcodekind,_) =
+    match mcodekind with
+      Ast0.PLUS -> insert info.Ast0.line_start
+    | _ -> () in
+  let fn =
+    V0.combiner bind option_default
+      mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+      mcode
+      donothing donothing donothing donothing donothing donothing
+      donothing donothing donothing donothing donothing donothing donothing
+      donothing donothing in
+  fn.V0.combiner_top_level top
+
+(* --------------------------------------------------------------------- *)
+
+type kind = Neutral | AllMarked | NotAllMarked (* marked means + or - *)
+
+(* --------------------------------------------------------------------- *)
+(* The first part analyzes each of the minus tree and the plus tree
+separately *)
+
+(* ints are unique token indices (offset field) *)
+type node =
+    Token (* tokens *) of kind * int (* unique index *) * Ast0.mcodekind *
+       int list (* context tokens *)
+  | Recursor (* children *) of kind *
+       int list (* indices of all tokens at the level below *) *
+       Ast0.mcodekind list (* tokens at the level below *) *
+       int list
+  | Bind (* neighbors *) of kind *
+       int list (* indices of all tokens at current level *) *
+       Ast0.mcodekind list (* tokens at current level *) *
+       int list (* indices of all tokens at the level below *) *
+       Ast0.mcodekind list (* tokens at the level below *)
+       * int list list
+
+let kind2c = function
+    Neutral -> "neutral"
+  | AllMarked -> "allmarked"
+  | NotAllMarked -> "notallmarked"
+
+let node2c = function
+    Token(k,_,_,_) -> Printf.sprintf "token %s\n" (kind2c k)
+  | Recursor(k,_,_,_) -> Printf.sprintf "recursor %s\n" (kind2c k)
+  | Bind(k,_,_,_,_,_) -> Printf.sprintf "bind %s\n" (kind2c k)
+
+(* goal: detect negative in both tokens and recursors, or context only in
+tokens *)
+let bind c1 c2 =
+  let lub = function
+      (k1,k2) when k1 = k2 -> k1
+    | (Neutral,AllMarked) -> AllMarked
+    | (AllMarked,Neutral) -> AllMarked
+    | _ -> NotAllMarked in
+  match (c1,c2) with
+    (* token/token *)
+    (* there are tokens at this level, so ignore the level below *)
+    (Token(k1,i1,t1,l1),Token(k2,i2,t2,l2)) ->
+      Bind(lub(k1,k2),[i1;i2],[t1;t2],[],[],[l1;l2])
+
+    (* token/recursor *)
+    (* there are tokens at this level, so ignore the level below *)
+  | (Token(k1,i1,t1,l1),Recursor(k2,_,_,l2)) ->
+      Bind(lub(k1,k2),[i1],[t1],[],[],[l1;l2])
+  | (Recursor(k1,_,_,l1),Token(k2,i2,t2,l2)) ->
+      Bind(lub(k1,k2),[i2],[t2],[],[],[l1;l2])
+
+    (* token/bind *)
+    (* there are tokens at this level, so ignore the level below *)
+  | (Token(k1,i1,t1,l1),Bind(k2,i2,t2,_,_,l2)) ->
+      Bind(lub(k1,k2),i1::i2,t1::t2,[],[],l1::l2)
+  | (Bind(k1,i1,t1,_,_,l1),Token(k2,i2,t2,l2)) ->
+      Bind(lub(k1,k2),i1@[i2],t1@[t2],[],[],l1@[l2])
+
+    (* recursor/bind *)
+  | (Recursor(k1,bi1,bt1,l1),Bind(k2,i2,t2,bi2,bt2,l2)) ->
+      Bind(lub(k1,k2),i2,t2,bi1@bi2,bt1@bt2,l1::l2)
+  | (Bind(k1,i1,t1,bi1,bt1,l1),Recursor(k2,bi2,bt2,l2)) ->
+      Bind(lub(k1,k2),i1,t1,bi1@bi2,bt1@bt2,l1@[l2])
+
+    (* recursor/recursor and bind/bind - not likely to ever occur *)
+  | (Recursor(k1,bi1,bt1,l1),Recursor(k2,bi2,bt2,l2)) ->
+      Bind(lub(k1,k2),[],[],bi1@bi2,bt1@bt2,[l1;l2])
+  | (Bind(k1,i1,t1,bi1,bt1,l1),Bind(k2,i2,t2,bi2,bt2,l2)) ->
+      Bind(lub(k1,k2),i1@i2,t1@t2,bi1@bi2,bt1@bt2,l1@l2)
+
+
+let option_default = (*Bind(Neutral,[],[],[],[],[])*)
+  Recursor(Neutral,[],[],[])
+
+let mcode (_,_,info,mcodekind,pos) =
+  let offset = info.Ast0.offset in
+  match mcodekind with
+    Ast0.MINUS(_) -> Token(AllMarked,offset,mcodekind,[])
+  | Ast0.PLUS -> Token(AllMarked,offset,mcodekind,[])
+  | Ast0.CONTEXT(_) -> Token(NotAllMarked,offset,mcodekind,[offset])
+  | _ -> failwith "not possible"
+
+let neutral_mcode (_,_,info,mcodekind,pos) =
+  let offset = info.Ast0.offset in
+  match mcodekind with
+    Ast0.MINUS(_) -> Token(Neutral,offset,mcodekind,[])
+  | Ast0.PLUS -> Token(Neutral,offset,mcodekind,[])
+  | Ast0.CONTEXT(_) -> Token(Neutral,offset,mcodekind,[offset])
+  | _ -> failwith "not possible"
+
+let is_context = function Ast0.CONTEXT(_) -> true | _ -> false
+
+let union_all l = List.fold_left Common.union_set [] l
+
+(* is minus is true when we are processing minus code that might be
+intermingled with plus code.  it is used in disj_cases *)
+let classify is_minus all_marked table code =
+  let mkres builder k il tl bil btl l e =
+    (if k = AllMarked
+    then Ast0.set_mcodekind e (all_marked()) (* definitive *)
+    else
+      let check_index il tl =
+       if List.for_all is_context tl
+       then
+         (let e1 = builder e in
+         let index = (get_index e1)@il in
+         try
+           let _ = Hashtbl.find table index in
+           failwith
+             (Printf.sprintf "%d: index %s already used\n"
+                (Ast0.get_info e).Ast0.line_start
+                (String.concat " " (List.map string_of_int index)))
+         with Not_found -> Hashtbl.add table index (e1,l)) in
+      if il = [] then check_index bil btl else check_index il tl);
+    if il = []
+    then Recursor(k, bil, btl, union_all l)
+    else Recursor(k, il, tl, union_all l) in
+
+  let compute_result builder e = function
+      Bind(k,il,tl,bil,btl,l) -> mkres builder k il tl bil btl l e
+    | Token(k,il,tl,l) -> mkres builder k [il] [tl] [] [] [l] e
+    | Recursor(k,bil,btl,l) -> mkres builder k [] [] bil btl [l] e in
+
+  let make_not_marked = function
+      Bind(k,il,tl,bil,btl,l) -> Bind(NotAllMarked,il,tl,bil,btl,l)
+    | Token(k,il,tl,l) -> Token(NotAllMarked,il,tl,l)
+    | Recursor(k,bil,btl,l) -> Recursor(NotAllMarked,bil,btl,l) in
+
+  let do_nothing builder r k e = compute_result builder e (k e) in
+
+  let disj_cases disj starter code fn ender =
+    (* neutral_mcode used so starter and ender don't have an affect on
+       whether the code is considered all plus/minus, but so that they are
+       consider in the index list, which is needed to make a disj with
+       something in one branch and nothing in the other different from code
+       that just has the something (starter/ender enough, mids not needed
+       for this).  Cannot agglomerate + code over | boundaries, because two -
+       cases might have different + code, and don't want to put the + code
+       together into one unit. *)
+    let make_not_marked =
+      if is_minus
+      then
+       (let min = Ast0.get_line disj in
+       let max = Ast0.get_line_end disj in
+       let (plus_min,plus_max) = find min (min-1) (max+1) in
+       if max > plus_max then make_not_marked else (function x -> x))
+      else make_not_marked in
+    bind (neutral_mcode starter)
+      (bind (List.fold_right bind
+              (List.map make_not_marked (List.map fn code))
+              option_default)
+        (neutral_mcode ender)) in
+
+  (* no whencode in plus tree so have to drop it *)
+  (* need special cases for dots, nests, and disjs *)
+  let expression r k e =
+    compute_result Ast0.expr e
+      (match Ast0.unwrap e with
+       Ast0.NestExpr(starter,exp,ender,whencode,multi) ->
+         k (Ast0.rewrap e (Ast0.NestExpr(starter,exp,ender,None,multi)))
+      | Ast0.Edots(dots,whencode) ->
+         k (Ast0.rewrap e (Ast0.Edots(dots,None)))
+      | Ast0.Ecircles(dots,whencode) ->
+         k (Ast0.rewrap e (Ast0.Ecircles(dots,None)))
+      | Ast0.Estars(dots,whencode) ->
+         k (Ast0.rewrap e (Ast0.Estars(dots,None)))
+      | Ast0.DisjExpr(starter,expr_list,_,ender) -> 
+         disj_cases e starter expr_list r.V0.combiner_expression ender
+      |        _ -> k e) in
+
+  (* not clear why we have the next two cases, since DisjDecl and
+  DisjType shouldn't have been constructed yet, as they only come from isos *)
+  let declaration r k e =
+    compute_result Ast0.decl e
+      (match Ast0.unwrap e with
+       Ast0.DisjDecl(starter,decls,_,ender) ->
+         disj_cases e starter decls r.V0.combiner_declaration ender
+      | Ast0.Ddots(dots,whencode) ->
+         k (Ast0.rewrap e (Ast0.Ddots(dots,None)))
+       (* Need special cases for the following so that the type will be
+          considered as a unit, rather than distributed around the
+          declared variable.  This needs to be done because of the call to
+          compute_result, ie the processing of each term should make a
+          side-effect on the complete term structure as well as collecting
+          some information about it.  So we have to visit each complete
+          term structure.  In (all?) other such cases, we visit the terms
+          using rebuilder, which just visits the subterms, rather than
+          reordering their components. *)
+      |        Ast0.Init(stg,ty,id,eq,ini,sem) ->
+         bind (match stg with Some stg -> mcode stg | _ -> option_default)
+           (bind (r.V0.combiner_typeC ty)
+              (bind (r.V0.combiner_ident id)
+                 (bind (mcode eq)
+                    (bind (r.V0.combiner_initialiser ini) (mcode sem)))))
+      | Ast0.UnInit(stg,ty,id,sem) ->
+         bind (match stg with Some stg -> mcode stg | _ -> option_default)
+           (bind (r.V0.combiner_typeC ty)
+              (bind (r.V0.combiner_ident id) (mcode sem)))
+      |        _ -> k e) in
+
+  let param r k e =
+    compute_result Ast0.param e
+      (match Ast0.unwrap e with
+       Ast0.Param(ty,Some id) ->
+         (* needed for the same reason as in the Init and UnInit cases *)
+         bind (r.V0.combiner_typeC ty) (r.V0.combiner_ident id)
+      |        _ -> k e) in
+
+  let typeC r k e =
+    compute_result Ast0.typeC e
+      (match Ast0.unwrap e with
+       Ast0.DisjType(starter,types,_,ender) ->
+         disj_cases e starter types r.V0.combiner_typeC ender
+      |        _ -> k e) in
+
+  let initialiser r k i =
+    compute_result Ast0.ini i
+      (match Ast0.unwrap i with
+       Ast0.Idots(dots,whencode) ->
+         k (Ast0.rewrap i (Ast0.Idots(dots,None)))
+      |        _ -> k i) in
+
+  let statement r k s =
+    compute_result Ast0.stmt s
+      (match Ast0.unwrap s with
+       Ast0.Nest(started,stm_dots,ender,whencode,multi) ->
+         k (Ast0.rewrap s (Ast0.Nest(started,stm_dots,ender,[],multi)))
+      | Ast0.Dots(dots,whencode) ->
+         k (Ast0.rewrap s (Ast0.Dots(dots,[])))
+      | Ast0.Circles(dots,whencode) ->
+         k (Ast0.rewrap s (Ast0.Circles(dots,[])))
+      | Ast0.Stars(dots,whencode) ->
+         k (Ast0.rewrap s (Ast0.Stars(dots,[])))
+      | Ast0.Disj(starter,statement_dots_list,_,ender) ->
+         disj_cases s starter statement_dots_list r.V0.combiner_statement_dots
+           ender
+(*  Why? There is nothing there
+       (* cases for everything with extra mcode *)
+      |        Ast0.FunDecl((info,bef),_,_,_,_,_,_,_,_)
+      | Ast0.Decl((info,bef),_) ->
+         bind (mcode ((),(),info,bef)) (k s)
+      | Ast0.IfThen(_,_,_,_,_,(info,aft))
+      | Ast0.IfThenElse(_,_,_,_,_,_,_,(info,aft))
+      | Ast0.While(_,_,_,_,_,(info,aft)) ->
+      | Ast0.For(_,_,_,_,_,_,_,_,_,(info,aft)) ->
+         bind (k s) (mcode ((),(),info,aft))
+      | Ast0.Iterator(_,_,_,_,_,(info,aft))
+*)
+      |        _ -> k s
+
+) in
+
+  let do_top builder r k e = compute_result builder e (k e) in
+
+  let combiner = 
+    V0.combiner bind option_default
+      mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+      mcode
+      (do_nothing Ast0.dotsExpr) (do_nothing Ast0.dotsInit)
+      (do_nothing Ast0.dotsParam) (do_nothing Ast0.dotsStmt)
+      (do_nothing Ast0.dotsDecl) (do_nothing Ast0.dotsCase)
+      (do_nothing Ast0.ident) expression typeC initialiser param declaration
+      statement (do_nothing Ast0.case_line) (do_top Ast0.top) in
+  combiner.V0.combiner_top_level code
+
+(* --------------------------------------------------------------------- *)
+(* Traverse the hash tables and find corresponding context nodes that have
+the same context children *)
+
+(* this is just a sanity check - really only need to look at the top-level
+   structure *)
+let equal_mcode (_,_,info1,_,_) (_,_,info2,_,_) =
+  info1.Ast0.offset = info2.Ast0.offset
+
+let equal_option e1 e2 =
+  match (e1,e2) with
+    (Some x, Some y) -> equal_mcode x y
+  | (None, None) -> true
+  | _ -> false
+
+let dots fn d1 d2 =
+  match (Ast0.unwrap d1,Ast0.unwrap d2) with
+    (Ast0.DOTS(l1),Ast0.DOTS(l2)) -> List.length l1 = List.length l2
+  | (Ast0.CIRCLES(l1),Ast0.CIRCLES(l2)) -> List.length l1 = List.length l2
+  | (Ast0.STARS(l1),Ast0.STARS(l2)) -> List.length l1 = List.length l2
+  | _ -> false
+
+let rec equal_ident i1 i2 =
+  match (Ast0.unwrap i1,Ast0.unwrap i2) with
+    (Ast0.Id(name1),Ast0.Id(name2)) -> equal_mcode name1 name2
+  | (Ast0.MetaId(name1,_,_),Ast0.MetaId(name2,_,_)) ->
+      equal_mcode name1 name2
+  | (Ast0.MetaFunc(name1,_,_),Ast0.MetaFunc(name2,_,_)) ->
+      equal_mcode name1 name2
+  | (Ast0.MetaLocalFunc(name1,_,_),Ast0.MetaLocalFunc(name2,_,_)) ->
+      equal_mcode name1 name2
+  | (Ast0.OptIdent(_),Ast0.OptIdent(_)) -> true
+  | (Ast0.UniqueIdent(_),Ast0.UniqueIdent(_)) -> true
+  | _ -> false
+
+let rec equal_expression e1 e2 =
+  match (Ast0.unwrap e1,Ast0.unwrap e2) with
+    (Ast0.Ident(_),Ast0.Ident(_)) -> true
+  | (Ast0.Constant(const1),Ast0.Constant(const2)) -> equal_mcode const1 const2
+  | (Ast0.FunCall(_,lp1,_,rp1),Ast0.FunCall(_,lp2,_,rp2)) ->
+      equal_mcode lp1 lp2 && equal_mcode rp1 rp2
+  | (Ast0.Assignment(_,op1,_,_),Ast0.Assignment(_,op2,_,_)) ->
+      equal_mcode op1 op2
+  | (Ast0.CondExpr(_,why1,_,colon1,_),Ast0.CondExpr(_,why2,_,colon2,_)) ->
+      equal_mcode why1 why2 && equal_mcode colon1 colon2
+  | (Ast0.Postfix(_,op1),Ast0.Postfix(_,op2)) -> equal_mcode op1 op2
+  | (Ast0.Infix(_,op1),Ast0.Infix(_,op2)) -> equal_mcode op1 op2
+  | (Ast0.Unary(_,op1),Ast0.Unary(_,op2)) -> equal_mcode op1 op2
+  | (Ast0.Binary(_,op1,_),Ast0.Binary(_,op2,_)) -> equal_mcode op1 op2
+  | (Ast0.Paren(lp1,_,rp1),Ast0.Paren(lp2,_,rp2)) ->
+      equal_mcode lp1 lp2 && equal_mcode rp1 rp2
+  | (Ast0.ArrayAccess(_,lb1,_,rb1),Ast0.ArrayAccess(_,lb2,_,rb2)) ->
+      equal_mcode lb1 lb2 && equal_mcode rb1 rb2
+  | (Ast0.RecordAccess(_,pt1,_),Ast0.RecordAccess(_,pt2,_)) ->
+      equal_mcode pt1 pt2
+  | (Ast0.RecordPtAccess(_,ar1,_),Ast0.RecordPtAccess(_,ar2,_)) ->
+      equal_mcode ar1 ar2
+  | (Ast0.Cast(lp1,_,rp1,_),Ast0.Cast(lp2,_,rp2,_)) ->
+      equal_mcode lp1 lp2 && equal_mcode rp1 rp2
+  | (Ast0.SizeOfExpr(szf1,_),Ast0.SizeOfExpr(szf2,_)) ->
+      equal_mcode szf1 szf2
+  | (Ast0.SizeOfType(szf1,lp1,_,rp1),Ast0.SizeOfType(szf2,lp2,_,rp2)) ->
+      equal_mcode szf1 szf2 && equal_mcode lp1 lp2 && equal_mcode rp1 rp2
+  | (Ast0.TypeExp(_),Ast0.TypeExp(_)) -> true
+  | (Ast0.MetaErr(name1,_,_),Ast0.MetaErr(name2,_,_))
+  | (Ast0.MetaExpr(name1,_,_,_,_),Ast0.MetaExpr(name2,_,_,_,_))
+  | (Ast0.MetaExprList(name1,_,_),Ast0.MetaExprList(name2,_,_)) ->
+      equal_mcode name1 name2
+  | (Ast0.EComma(cm1),Ast0.EComma(cm2)) -> equal_mcode cm1 cm2
+  | (Ast0.DisjExpr(starter1,_,mids1,ender1),
+     Ast0.DisjExpr(starter2,_,mids2,ender2)) ->
+       equal_mcode starter1 starter2 && 
+       List.for_all2 equal_mcode mids1 mids2 &&
+       equal_mcode ender1 ender2
+  | (Ast0.NestExpr(starter1,_,ender1,_,m1),
+     Ast0.NestExpr(starter2,_,ender2,_,m2)) ->
+      equal_mcode starter1 starter2 && equal_mcode ender1 ender2 && m1 = m2
+  | (Ast0.Edots(dots1,_),Ast0.Edots(dots2,_))
+  | (Ast0.Ecircles(dots1,_),Ast0.Ecircles(dots2,_))
+  | (Ast0.Estars(dots1,_),Ast0.Estars(dots2,_)) -> equal_mcode dots1 dots2
+  | (Ast0.OptExp(_),Ast0.OptExp(_)) -> true
+  | (Ast0.UniqueExp(_),Ast0.UniqueExp(_)) -> true
+  | _ -> false
+
+let rec equal_typeC t1 t2 =
+  match (Ast0.unwrap t1,Ast0.unwrap t2) with
+    (Ast0.ConstVol(cv1,_),Ast0.ConstVol(cv2,_)) -> equal_mcode cv1 cv2
+  | (Ast0.BaseType(ty1,sign1),Ast0.BaseType(ty2,sign2)) ->
+      equal_mcode ty1 ty2 && equal_option sign1 sign2
+  | (Ast0.ImplicitInt(sign1),Ast0.ImplicitInt(sign2)) ->
+      equal_mcode sign1 sign2
+  | (Ast0.Pointer(_,star1),Ast0.Pointer(_,star2)) ->
+      equal_mcode star1 star2
+  | (Ast0.Array(_,lb1,_,rb1),Ast0.Array(_,lb2,_,rb2)) ->
+      equal_mcode lb1 lb2 && equal_mcode rb1 rb2
+  | (Ast0.StructUnionName(kind1,_),Ast0.StructUnionName(kind2,_)) ->
+      equal_mcode kind1 kind2
+  | (Ast0.FunctionType(ty1,lp1,p1,rp1),Ast0.FunctionType(ty2,lp2,p2,rp2)) ->
+      equal_mcode lp1 lp2 && equal_mcode rp1 rp2
+  | (Ast0.StructUnionDef(_,lb1,_,rb1),
+     Ast0.StructUnionDef(_,lb2,_,rb2)) ->
+       equal_mcode lb1 lb2 && equal_mcode rb1 rb2
+  | (Ast0.TypeName(name1),Ast0.TypeName(name2)) -> equal_mcode name1 name2
+  | (Ast0.MetaType(name1,_),Ast0.MetaType(name2,_)) ->
+      equal_mcode name1 name2
+  | (Ast0.DisjType(starter1,_,mids1,ender1),
+     Ast0.DisjType(starter2,_,mids2,ender2)) ->
+       equal_mcode starter1 starter2 && 
+       List.for_all2 equal_mcode mids1 mids2 &&
+       equal_mcode ender1 ender2
+  | (Ast0.OptType(_),Ast0.OptType(_)) -> true
+  | (Ast0.UniqueType(_),Ast0.UniqueType(_)) -> true
+  | _ -> false
+
+let equal_declaration d1 d2 =
+  match (Ast0.unwrap d1,Ast0.unwrap d2) with
+    (Ast0.Init(stg1,_,_,eq1,_,sem1),Ast0.Init(stg2,_,_,eq2,_,sem2)) ->
+      equal_option stg1 stg2 && equal_mcode eq1 eq2 && equal_mcode sem1 sem2
+  | (Ast0.UnInit(stg1,_,_,sem1),Ast0.UnInit(stg2,_,_,sem2)) ->
+      equal_option stg1 stg2 && equal_mcode sem1 sem2
+  | (Ast0.MacroDecl(nm1,lp1,_,rp1,sem1),Ast0.MacroDecl(nm2,lp2,_,rp2,sem2)) ->
+      equal_mcode lp1 lp2 && equal_mcode rp1 rp2 && equal_mcode sem1 sem2
+  | (Ast0.TyDecl(_,sem1),Ast0.TyDecl(_,sem2)) -> equal_mcode sem1 sem2
+  | (Ast0.Ddots(dots1,_),Ast0.Ddots(dots2,_)) -> equal_mcode dots1 dots2
+  | (Ast0.OptDecl(_),Ast0.OptDecl(_)) -> true
+  | (Ast0.UniqueDecl(_),Ast0.UniqueDecl(_)) -> true
+  | (Ast0.DisjDecl _,_) | (_,Ast0.DisjDecl _) ->
+      failwith "DisjDecl not expected here"
+  | _ -> false
+
+let equal_initialiser i1 i2 =
+  match (Ast0.unwrap i1,Ast0.unwrap i2) with
+    (Ast0.InitExpr(_),Ast0.InitExpr(_)) -> true
+  | (Ast0.InitList(lb1,_,rb1),Ast0.InitList(lb2,_,rb2)) ->
+      (equal_mcode lb1 lb2) && (equal_mcode rb1 rb2)
+  | (Ast0.InitGccDotName(dot1,_,eq1,_),Ast0.InitGccDotName(dot2,_,eq2,_)) ->
+      (equal_mcode dot1 dot2) && (equal_mcode eq1 eq2)
+  | (Ast0.InitGccName(_,eq1,_),Ast0.InitGccName(_,eq2,_)) ->
+      equal_mcode eq1 eq2
+  | (Ast0.InitGccIndex(lb1,_,rb1,eq1,_),Ast0.InitGccIndex(lb2,_,rb2,eq2,_)) ->
+      (equal_mcode lb1 lb2) && (equal_mcode rb1 rb2) && (equal_mcode eq1 eq2)
+  | (Ast0.InitGccRange(lb1,_,dots1,_,rb1,eq1,_),
+     Ast0.InitGccRange(lb2,_,dots2,_,rb2,eq2,_)) ->
+      (equal_mcode lb1 lb2) && (equal_mcode dots1 dots2) &&
+       (equal_mcode rb1 rb2) && (equal_mcode eq1 eq2)
+ | (Ast0.IComma(cm1),Ast0.IComma(cm2)) -> equal_mcode cm1 cm2
+  | (Ast0.Idots(d1,_),Ast0.Idots(d2,_)) -> equal_mcode d1 d2
+  | (Ast0.OptIni(_),Ast0.OptIni(_)) -> true
+  | (Ast0.UniqueIni(_),Ast0.UniqueIni(_)) -> true
+  | _ -> false
+       
+let equal_parameterTypeDef p1 p2 =
+  match (Ast0.unwrap p1,Ast0.unwrap p2) with
+    (Ast0.VoidParam(_),Ast0.VoidParam(_)) -> true
+  | (Ast0.Param(_,_),Ast0.Param(_,_)) -> true
+  | (Ast0.MetaParam(name1,_),Ast0.MetaParam(name2,_))
+  | (Ast0.MetaParamList(name1,_,_),Ast0.MetaParamList(name2,_,_)) ->
+      equal_mcode name1 name2
+  | (Ast0.PComma(cm1),Ast0.PComma(cm2)) -> equal_mcode cm1 cm2
+  | (Ast0.Pdots(dots1),Ast0.Pdots(dots2))
+  | (Ast0.Pcircles(dots1),Ast0.Pcircles(dots2)) -> equal_mcode dots1 dots2
+  | (Ast0.OptParam(_),Ast0.OptParam(_)) -> true
+  | (Ast0.UniqueParam(_),Ast0.UniqueParam(_)) -> true
+  | _ -> false
+
+let rec equal_statement s1 s2 =
+  match (Ast0.unwrap s1,Ast0.unwrap s2) with
+    (Ast0.FunDecl(_,fninfo1,_,lp1,_,rp1,lbrace1,_,rbrace1),
+     Ast0.FunDecl(_,fninfo2,_,lp2,_,rp2,lbrace2,_,rbrace2)) ->
+       (List.length fninfo1) = (List.length fninfo2) &&
+       List.for_all2 equal_fninfo fninfo1 fninfo2 &&
+       equal_mcode lp1 lp2 && equal_mcode rp1 rp2 &&
+       equal_mcode lbrace1 lbrace2 && equal_mcode rbrace1 rbrace2
+  | (Ast0.Decl(_,_),Ast0.Decl(_,_)) -> true
+  | (Ast0.Seq(lbrace1,_,rbrace1),Ast0.Seq(lbrace2,_,rbrace2)) ->
+      equal_mcode lbrace1 lbrace2 && equal_mcode rbrace1 rbrace2
+  | (Ast0.ExprStatement(_,sem1),Ast0.ExprStatement(_,sem2)) ->
+      equal_mcode sem1 sem2
+  | (Ast0.IfThen(iff1,lp1,_,rp1,_,_),Ast0.IfThen(iff2,lp2,_,rp2,_,_)) ->
+      equal_mcode iff1 iff2 && equal_mcode lp1 lp2 && equal_mcode rp1 rp2
+  | (Ast0.IfThenElse(iff1,lp1,_,rp1,_,els1,_,_),
+     Ast0.IfThenElse(iff2,lp2,_,rp2,_,els2,_,_)) ->
+       equal_mcode iff1 iff2 &&
+        equal_mcode lp1 lp2 && equal_mcode rp1 rp2 && equal_mcode els1 els2
+  | (Ast0.While(whl1,lp1,_,rp1,_,_),Ast0.While(whl2,lp2,_,rp2,_,_)) ->
+      equal_mcode whl1 whl2 && equal_mcode lp1 lp2 && equal_mcode rp1 rp2
+  | (Ast0.Do(d1,_,whl1,lp1,_,rp1,sem1),Ast0.Do(d2,_,whl2,lp2,_,rp2,sem2)) ->
+      equal_mcode whl1 whl2 && equal_mcode d1 d2 &&
+      equal_mcode lp1 lp2 && equal_mcode rp1 rp2 && equal_mcode sem1 sem2
+  | (Ast0.For(fr1,lp1,_,sem11,_,sem21,_,rp1,_,_),
+     Ast0.For(fr2,lp2,_,sem12,_,sem22,_,rp2,_,_)) ->
+       equal_mcode fr1 fr2 && equal_mcode lp1 lp2 &&
+       equal_mcode sem11 sem12 && equal_mcode sem21 sem22 &&
+       equal_mcode rp1 rp2
+  | (Ast0.Iterator(nm1,lp1,_,rp1,_,_),Ast0.Iterator(nm2,lp2,_,rp2,_,_)) ->
+      equal_mcode lp1 lp2 && equal_mcode rp1 rp2
+  | (Ast0.Switch(switch1,lp1,_,rp1,lb1,case1,rb1),
+     Ast0.Switch(switch2,lp2,_,rp2,lb2,case2,rb2)) ->
+       equal_mcode switch1 switch2 && equal_mcode lp1 lp2 &&
+       equal_mcode rp1 rp2 && equal_mcode lb1 lb2 &&
+       equal_mcode rb1 rb2
+  | (Ast0.Break(br1,sem1),Ast0.Break(br2,sem2)) ->
+      equal_mcode br1 br2 && equal_mcode sem1 sem2
+  | (Ast0.Continue(cont1,sem1),Ast0.Continue(cont2,sem2)) ->
+      equal_mcode cont1 cont2 && equal_mcode sem1 sem2
+  | (Ast0.Label(_,dd1),Ast0.Label(_,dd2)) ->
+      equal_mcode dd1 dd2
+  | (Ast0.Goto(g1,_,sem1),Ast0.Goto(g2,_,sem2)) ->
+      equal_mcode g1 g2 && equal_mcode sem1 sem2
+  | (Ast0.Return(ret1,sem1),Ast0.Return(ret2,sem2)) ->
+      equal_mcode ret1 ret2 && equal_mcode sem1 sem2
+  | (Ast0.ReturnExpr(ret1,_,sem1),Ast0.ReturnExpr(ret2,_,sem2)) ->
+      equal_mcode ret1 ret2 && equal_mcode sem1 sem2
+  | (Ast0.MetaStmt(name1,_),Ast0.MetaStmt(name2,_))
+  | (Ast0.MetaStmtList(name1,_),Ast0.MetaStmtList(name2,_)) ->
+      equal_mcode name1 name2
+  | (Ast0.Disj(starter1,_,mids1,ender1),Ast0.Disj(starter2,_,mids2,ender2)) ->
+      equal_mcode starter1 starter2 && 
+      List.for_all2 equal_mcode mids1 mids2 &&
+      equal_mcode ender1 ender2
+  | (Ast0.Nest(starter1,_,ender1,_,m1),Ast0.Nest(starter2,_,ender2,_,m2)) ->
+      equal_mcode starter1 starter2 && equal_mcode ender1 ender2 && m1 = m2
+  | (Ast0.Exp(_),Ast0.Exp(_)) -> true
+  | (Ast0.TopExp(_),Ast0.TopExp(_)) -> true
+  | (Ast0.Ty(_),Ast0.Ty(_)) -> true
+  | (Ast0.TopInit(_),Ast0.TopInit(_)) -> true
+  | (Ast0.Dots(d1,_),Ast0.Dots(d2,_))
+  | (Ast0.Circles(d1,_),Ast0.Circles(d2,_))
+  | (Ast0.Stars(d1,_),Ast0.Stars(d2,_)) -> equal_mcode d1 d2
+  | (Ast0.Include(inc1,name1),Ast0.Include(inc2,name2)) ->
+      equal_mcode inc1 inc2 && equal_mcode name1 name2
+  | (Ast0.Define(def1,_,_,_),Ast0.Define(def2,_,_,_)) ->
+      equal_mcode def1 def2
+  | (Ast0.OptStm(_),Ast0.OptStm(_)) -> true
+  | (Ast0.UniqueStm(_),Ast0.UniqueStm(_)) -> true
+  | _ -> false
+
+and equal_fninfo x y =
+  match (x,y) with
+    (Ast0.FStorage(s1),Ast0.FStorage(s2)) -> equal_mcode s1 s2
+  | (Ast0.FType(_),Ast0.FType(_)) -> true
+  | (Ast0.FInline(i1),Ast0.FInline(i2)) -> equal_mcode i1 i2
+  | (Ast0.FAttr(i1),Ast0.FAttr(i2)) -> equal_mcode i1 i2
+  | _ -> false
+
+let equal_case_line c1 c2 =
+  match (Ast0.unwrap c1,Ast0.unwrap c2) with
+    (Ast0.Default(def1,colon1,_),Ast0.Default(def2,colon2,_)) ->
+      equal_mcode def1 def2 && equal_mcode colon1 colon2
+  | (Ast0.Case(case1,_,colon1,_),Ast0.Case(case2,_,colon2,_)) ->
+      equal_mcode case1 case2 && equal_mcode colon1 colon2
+  | (Ast0.OptCase(_),Ast0.OptCase(_)) -> true
+  | _ -> false
+
+let rec equal_top_level t1 t2 =
+  match (Ast0.unwrap t1,Ast0.unwrap t2) with
+    (Ast0.DECL(_),Ast0.DECL(_)) -> true
+  | (Ast0.FILEINFO(old_file1,new_file1),Ast0.FILEINFO(old_file2,new_file2)) ->
+      equal_mcode old_file1 old_file2 && equal_mcode new_file1 new_file2
+  | (Ast0.CODE(_),Ast0.CODE(_)) -> true
+  | (Ast0.ERRORWORDS(_),Ast0.ERRORWORDS(_)) -> true
+  | _ -> false
+
+let root_equal e1 e2 =
+  match (e1,e2) with
+    (Ast0.DotsExprTag(d1),Ast0.DotsExprTag(d2)) -> dots equal_expression d1 d2
+  | (Ast0.DotsParamTag(d1),Ast0.DotsParamTag(d2)) ->
+      dots equal_parameterTypeDef d1 d2
+  | (Ast0.DotsStmtTag(d1),Ast0.DotsStmtTag(d2)) -> dots equal_statement d1 d2
+  | (Ast0.DotsDeclTag(d1),Ast0.DotsDeclTag(d2)) -> dots equal_declaration d1 d2
+  | (Ast0.DotsCaseTag(d1),Ast0.DotsCaseTag(d2)) -> dots equal_case_line d1 d2
+  | (Ast0.IdentTag(i1),Ast0.IdentTag(i2)) -> equal_ident i1 i2
+  | (Ast0.ExprTag(e1),Ast0.ExprTag(e2)) -> equal_expression e1 e2
+  | (Ast0.ArgExprTag(d),_) -> failwith "not possible - iso only"
+  | (Ast0.TypeCTag(t1),Ast0.TypeCTag(t2)) -> equal_typeC t1 t2
+  | (Ast0.ParamTag(p1),Ast0.ParamTag(p2)) -> equal_parameterTypeDef p1 p2
+  | (Ast0.InitTag(d1),Ast0.InitTag(d2)) -> equal_initialiser d1 d2
+  | (Ast0.DeclTag(d1),Ast0.DeclTag(d2)) -> equal_declaration d1 d2
+  | (Ast0.StmtTag(s1),Ast0.StmtTag(s2)) -> equal_statement s1 s2
+  | (Ast0.TopTag(t1),Ast0.TopTag(t2)) -> equal_top_level t1 t2
+  | (Ast0.IsoWhenTag(_),_) | (_,Ast0.IsoWhenTag(_))
+  | (Ast0.IsoWhenTTag(_),_) | (_,Ast0.IsoWhenTTag(_))
+  | (Ast0.IsoWhenFTag(_),_) | (_,Ast0.IsoWhenFTag(_)) ->
+      failwith "only within iso phase"
+  | _ -> false
+
+let default_context _ =
+  Ast0.CONTEXT(ref(Ast.NOTHING,
+                  Ast0.default_token_info,Ast0.default_token_info))
+
+let traverse minus_table plus_table =
+  Hashtbl.iter
+    (function key ->
+      function (e,l) ->
+       try
+         let (plus_e,plus_l) = Hashtbl.find plus_table key in
+         if root_equal e plus_e &&
+           List.for_all (function x -> x)
+             (List.map2 Common.equal_set l plus_l)
+         then
+           let i = Ast0.fresh_index() in
+           (set_index e i; set_index plus_e i;
+            set_mcodekind e (default_context());
+            set_mcodekind plus_e (default_context()))
+       with Not_found -> ())
+    minus_table
+
+(* --------------------------------------------------------------------- *)
+(* contextify the whencode *)
+
+let contextify_all =
+  let bind x y = () in
+  let option_default = () in
+  let mcode x = () in
+  let do_nothing r k e = Ast0.set_mcodekind e (default_context()); k e in
+
+  V0.combiner bind option_default
+    mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+    mcode
+    do_nothing do_nothing do_nothing do_nothing do_nothing do_nothing
+    do_nothing do_nothing do_nothing do_nothing do_nothing do_nothing
+    do_nothing do_nothing do_nothing
+
+let contextify_whencode =
+  let bind x y = () in
+  let option_default = () in
+  let mcode x = () in
+  let do_nothing r k e = k e in
+
+  let expression r k e =
+    k e;
+    match Ast0.unwrap e with
+      Ast0.NestExpr(_,_,_,Some whencode,_)
+    | Ast0.Edots(_,Some whencode)
+    | Ast0.Ecircles(_,Some whencode)
+    | Ast0.Estars(_,Some whencode) ->
+       contextify_all.V0.combiner_expression whencode
+    | _ -> () in
+
+  let initialiser r k i =
+    match Ast0.unwrap i with
+      Ast0.Idots(dots,Some whencode) ->
+       contextify_all.V0.combiner_initialiser whencode
+    | _ -> k i in
+
+  let whencode = function
+      Ast0.WhenNot sd -> contextify_all.V0.combiner_statement_dots sd
+    | Ast0.WhenAlways s -> contextify_all.V0.combiner_statement s
+    | Ast0.WhenModifier(_) -> ()
+    | Ast0.WhenNotTrue(e) -> contextify_all.V0.combiner_expression e
+    | Ast0.WhenNotFalse(e) -> contextify_all.V0.combiner_expression e in
+
+  let statement r k (s : Ast0.statement) =
+    k s;
+    match Ast0.unwrap s with
+      Ast0.Nest(_,_,_,whn,_)
+    | Ast0.Dots(_,whn) | Ast0.Circles(_,whn) | Ast0.Stars(_,whn) ->
+       List.iter whencode whn
+    | _ -> () in
+
+  let combiner = 
+    V0.combiner bind option_default
+      mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+      mcode
+      do_nothing do_nothing do_nothing do_nothing do_nothing do_nothing
+      do_nothing
+      expression
+      do_nothing initialiser do_nothing do_nothing statement do_nothing
+      do_nothing in
+  combiner.V0.combiner_top_level
+
+(* --------------------------------------------------------------------- *)
+
+(* the first int list is the tokens in the node, the second is the tokens
+in the descendents *)
+let minus_table =
+  (Hashtbl.create(50) : (int list, Ast0.anything * int list list) Hashtbl.t)
+let plus_table =
+  (Hashtbl.create(50) : (int list, Ast0.anything * int list list) Hashtbl.t)
+
+let iscode t =
+  match Ast0.unwrap t with
+    Ast0.DECL(_) -> true
+  | Ast0.FILEINFO(_) -> true
+  | Ast0.ERRORWORDS(_) -> false
+  | Ast0.CODE(_) -> true
+  | Ast0.OTHER(_) -> failwith "unexpected top level code"
+
+(* ------------------------------------------------------------------- *)
+(* alignment of minus and plus *)
+
+let concat = function
+    [] -> []
+  | [s] -> [s]
+  | l ->
+      let rec loop = function
+         [] -> []
+       | x::rest ->
+           (match Ast0.unwrap x with
+             Ast0.DECL(s) -> let stms = loop rest in s::stms
+           | Ast0.CODE(ss) ->
+               let stms = loop rest in
+               (match Ast0.unwrap ss with
+                 Ast0.DOTS(d) -> d@stms
+               | _ -> failwith "no dots allowed in pure plus code")
+           | _ -> failwith "plus code is being discarded") in
+      let res =
+       Compute_lines.statement_dots
+         (Ast0.rewrap (List.hd l) (Ast0.DOTS (loop l))) in
+      [Ast0.rewrap res (Ast0.CODE res)]
+
+let collect_up_to m plus =
+  let minfo = Ast0.get_info m in
+  let mend = minfo.Ast0.logical_end in
+  let rec loop = function
+      [] -> ([],[])
+    | p::plus -> 
+       let pinfo = Ast0.get_info p in
+       let pstart = pinfo.Ast0.logical_start in
+       if pstart > mend
+       then ([],p::plus)
+       else let (plus,rest) = loop plus in (p::plus,rest) in
+  let (plus,rest) = loop plus in
+  (concat plus,rest)
+
+let realign minus plus =
+  let rec loop = function
+      ([],_) -> failwith "not possible, some context required"
+    | ([m],p) -> ([m],concat p)
+    | (m::minus,plus) ->
+       let (p,plus) = collect_up_to m plus in
+       let (minus,plus) = loop (minus,plus) in
+       (m::minus,p@plus) in
+  loop (minus,plus)
+
+(* ------------------------------------------------------------------- *)
+(* check compatible: check that at the top level the minus and plus code is
+of the same kind.  Could go further and make the correspondence between the
+code between ...s. *)
+
+let isonly f l = match Ast0.undots l with [s] -> f s | _ -> false
+
+let isall f l = List.for_all (isonly f) l
+
+let rec is_exp s =
+  match Ast0.unwrap s with
+    Ast0.Exp(e) -> true
+  | Ast0.Disj(_,stmts,_,_) -> isall is_exp stmts
+  | _ -> false
+
+let rec is_ty s =
+  match Ast0.unwrap s with
+    Ast0.Ty(e) -> true
+  | Ast0.Disj(_,stmts,_,_) -> isall is_ty stmts
+  | _ -> false
+
+let rec is_decl s =
+  match Ast0.unwrap s with
+    Ast0.Decl(_,e) -> true
+  | Ast0.FunDecl(_,_,_,_,_,_,_,_,_) -> true
+  | Ast0.Disj(_,stmts,_,_) -> isall is_decl stmts
+  | _ -> false
+
+let rec is_fndecl s =
+  match Ast0.unwrap s with
+    Ast0.FunDecl(_,_,_,_,_,_,_,_,_) -> true
+  | Ast0.Disj(_,stmts,_,_) -> isall is_fndecl stmts
+  | _ -> false
+
+let rec is_toplevel s =
+  match Ast0.unwrap s with
+    Ast0.Decl(_,e) -> true
+  | Ast0.FunDecl(_,_,_,_,_,_,_,_,_) -> true
+  | Ast0.Disj(_,stmts,_,_) -> isall is_toplevel stmts
+  | Ast0.ExprStatement(fc,_) ->
+      (match Ast0.unwrap fc with
+       Ast0.FunCall(_,_,_,_) -> true
+      |        _ -> false)
+  | Ast0.Include(_,_) -> true
+  | Ast0.Define(_,_,_,_) -> true
+  | _ -> false
+
+let check_compatible m p =
+  let fail _ =
+    failwith
+      (Printf.sprintf
+        "incompatible minus and plus code starting on lines %d and %d"
+        (Ast0.get_line m) (Ast0.get_line p)) in
+  match (Ast0.unwrap m, Ast0.unwrap p) with
+    (Ast0.DECL(decl1),Ast0.DECL(decl2)) ->
+      if not (is_decl decl1 && is_decl decl2)
+      then fail()
+  | (Ast0.DECL(decl1),Ast0.CODE(code2)) ->
+      let v1 = is_decl decl1 in
+      let v2 = List.for_all is_toplevel (Ast0.undots code2) in
+      if !Flag.make_hrule = None && v1 && not v2 then fail()
+  | (Ast0.CODE(code1),Ast0.DECL(decl2)) ->
+      let v1 = List.for_all is_toplevel (Ast0.undots code1) in
+      let v2 = is_decl decl2 in
+      if v1 && not v2 then fail()
+  | (Ast0.CODE(code1),Ast0.CODE(code2)) ->
+      let testers = [is_exp;is_ty] in
+      List.iter
+       (function tester ->
+         let v1 = isonly tester code1 in
+         let v2 = isonly tester code2 in
+         if (v1 && not v2) or (!Flag.make_hrule = None && v2 && not v1)
+         then fail())
+       testers;
+      let v1 = isonly is_fndecl code1 in
+      let v2 = List.for_all is_toplevel (Ast0.undots code2) in
+      if !Flag.make_hrule = None && v1 && not v2 then fail()
+  | (Ast0.FILEINFO(_,_),Ast0.FILEINFO(_,_)) -> ()
+  | (Ast0.OTHER(_),Ast0.OTHER(_)) -> ()
+  | _ -> fail()
+
+(* ------------------------------------------------------------------- *)
+
+(* returns a list of corresponding minus and plus trees *)
+let context_neg minus plus =
+  Hashtbl.clear minus_table;
+  Hashtbl.clear plus_table;
+  List.iter contextify_whencode minus;
+  let (minus,plus) = realign minus plus in
+  let rec loop = function
+      ([],[]) -> []
+    | ([],l) ->
+       failwith (Printf.sprintf "%d plus things remaining" (List.length l))
+    | (minus,[]) ->
+       plus_lines := [];
+       let _ =
+         List.map
+           (function m ->
+             classify true
+               (function _ -> Ast0.MINUS(ref([],Ast0.default_token_info)))
+               minus_table m)
+           minus in
+       []
+    | (((m::minus) as mall),((p::plus) as pall)) ->
+       let minfo = Ast0.get_info m in
+       let pinfo = Ast0.get_info p in
+       let mstart = minfo.Ast0.logical_start in
+       let mend = minfo.Ast0.logical_end in
+       let pstart = pinfo.Ast0.logical_start in
+       let pend = pinfo.Ast0.logical_end in
+       if (iscode m or iscode p) &&
+         (mend + 1 = pstart or pend + 1 = mstart or (* adjacent *)
+          (mstart <= pstart && mend >= pstart) or
+          (pstart <= mstart && pend >= mstart)) (* overlapping or nested *)
+       then
+         begin
+           (* ensure that the root of each tree has a unique index,
+              although it might get overwritten if the node is a context
+              node *)
+           let i = Ast0.fresh_index() in
+           Ast0.set_index m i; Ast0.set_index p i;
+           check_compatible m p;
+           collect_plus_lines p;
+           let _ =
+             classify true
+               (function _ -> Ast0.MINUS(ref([],Ast0.default_token_info)))
+               minus_table m in
+           let _ = classify false (function _ -> Ast0.PLUS) plus_table p in
+           traverse minus_table plus_table;
+           (m,p)::loop(minus,plus)
+         end
+       else
+         if not(iscode m or iscode p)
+         then loop(minus,plus)
+         else
+           if mstart < pstart
+           then
+             begin
+               plus_lines := [];
+               let _ =
+                 classify true
+                   (function _ -> Ast0.MINUS(ref([],Ast0.default_token_info)))
+                   minus_table m in
+               loop(minus,pall)
+             end
+           else loop(mall,plus) in
+  loop(minus,plus)
diff --git a/parsing_cocci/.#iso_pattern.ml.1.138 b/parsing_cocci/.#iso_pattern.ml.1.138
new file mode 100644 (file)
index 0000000..f7975b8
--- /dev/null
@@ -0,0 +1,2311 @@
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+* 
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+* 
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
+* 
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+(* Potential problem: offset of mcode is not updated when an iso is
+instantiated, implying that a term may end up with many mcodes with the
+same offset.  On the other hand, at the moment offset only seems to be used
+before this phase.  Furthermore add_dot_binding relies on the offset to
+remain the same between matching an iso and instantiating it with bindings. *)
+
+(* --------------------------------------------------------------------- *)
+(* match a SmPL expression against a SmPL abstract syntax tree,
+either - or + *)
+
+module Ast = Ast_cocci
+module Ast0 = Ast0_cocci
+module V0 = Visitor_ast0
+
+let current_rule = ref ""
+
+(* --------------------------------------------------------------------- *)
+
+type isomorphism =
+    Ast_cocci.metavar list * Ast0_cocci.anything list list * string (* name *)
+
+let strip_info =
+  let mcode (term,_,_,_,_) =
+    (term,Ast0.NONE,Ast0.default_info(),Ast0.PLUS,ref Ast0.NoMetaPos) in
+  let donothing r k e =
+    let x = k e in
+    {(Ast0.wrap (Ast0.unwrap x)) with
+      Ast0.mcodekind = ref Ast0.PLUS;
+      Ast0.true_if_test = x.Ast0.true_if_test} in
+  V0.rebuilder
+    mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+    mcode
+    donothing donothing donothing donothing donothing donothing
+    donothing donothing donothing donothing donothing donothing donothing
+    donothing donothing
+
+let anything_equal = function
+    (Ast0.DotsExprTag(d1),Ast0.DotsExprTag(d2)) ->
+      failwith "not a possible variable binding" (*not sure why these are pbs*)
+  | (Ast0.DotsInitTag(d1),Ast0.DotsInitTag(d2)) ->
+      failwith "not a possible variable binding"
+  | (Ast0.DotsParamTag(d1),Ast0.DotsParamTag(d2)) ->
+      failwith "not a possible variable binding"
+  | (Ast0.DotsStmtTag(d1),Ast0.DotsStmtTag(d2)) ->
+      (strip_info.V0.rebuilder_statement_dots d1) =
+      (strip_info.V0.rebuilder_statement_dots d2)
+  | (Ast0.DotsDeclTag(d1),Ast0.DotsDeclTag(d2)) ->
+      failwith "not a possible variable binding"
+  | (Ast0.DotsCaseTag(d1),Ast0.DotsCaseTag(d2)) ->
+      failwith "not a possible variable binding"
+  | (Ast0.IdentTag(d1),Ast0.IdentTag(d2)) ->
+      (strip_info.V0.rebuilder_ident d1) = (strip_info.V0.rebuilder_ident d2)
+  | (Ast0.ExprTag(d1),Ast0.ExprTag(d2)) ->
+      (strip_info.V0.rebuilder_expression d1) =
+      (strip_info.V0.rebuilder_expression d2)
+  | (Ast0.ArgExprTag(_),_) | (_,Ast0.ArgExprTag(_)) ->
+      failwith "not possible - only in isos1"
+  | (Ast0.TestExprTag(_),_) | (_,Ast0.TestExprTag(_)) ->
+      failwith "not possible - only in isos1"
+  | (Ast0.TypeCTag(d1),Ast0.TypeCTag(d2)) ->
+      (strip_info.V0.rebuilder_typeC d1) =
+      (strip_info.V0.rebuilder_typeC d2)
+  | (Ast0.InitTag(d1),Ast0.InitTag(d2)) ->
+      (strip_info.V0.rebuilder_initialiser d1) =
+      (strip_info.V0.rebuilder_initialiser d2)
+  | (Ast0.ParamTag(d1),Ast0.ParamTag(d2)) ->
+      (strip_info.V0.rebuilder_parameter d1) =
+      (strip_info.V0.rebuilder_parameter d2)
+  | (Ast0.DeclTag(d1),Ast0.DeclTag(d2)) ->
+      (strip_info.V0.rebuilder_declaration d1) =
+      (strip_info.V0.rebuilder_declaration d2)
+  | (Ast0.StmtTag(d1),Ast0.StmtTag(d2)) ->
+      (strip_info.V0.rebuilder_statement d1) =
+      (strip_info.V0.rebuilder_statement d2)
+  | (Ast0.CaseLineTag(d1),Ast0.CaseLineTag(d2)) ->
+      (strip_info.V0.rebuilder_case_line d1) =
+      (strip_info.V0.rebuilder_case_line d2)
+  | (Ast0.TopTag(d1),Ast0.TopTag(d2)) ->
+      (strip_info.V0.rebuilder_top_level d1) =
+      (strip_info.V0.rebuilder_top_level d2)
+  | (Ast0.IsoWhenTTag(_),_) | (_,Ast0.IsoWhenTTag(_)) ->
+      failwith "only for isos within iso phase"
+  | (Ast0.IsoWhenFTag(_),_) | (_,Ast0.IsoWhenFTag(_)) ->
+      failwith "only for isos within iso phase"
+  | (Ast0.IsoWhenTag(_),_) | (_,Ast0.IsoWhenTag(_)) ->
+      failwith "only for isos within iso phase"
+  | _ -> false
+
+let term (var1,_,_,_,_) = var1
+let dot_term (var1,_,info,_,_) = ("", var1 ^ (string_of_int info.Ast0.offset))
+
+
+type reason =
+    NotPure of Ast0.pure * (string * string) * Ast0.anything
+  | NotPureLength of (string * string)
+  | ContextRequired of Ast0.anything
+  | NonMatch
+  | Braces of Ast0.statement
+  | Position of string * string
+
+let interpret_reason name line reason printer =
+  Printf.printf
+    "warning: iso %s does not match the code below on line %d\n" name line;
+  printer(); Format.print_newline();
+  match reason with
+    NotPure(Ast0.Pure,(_,var),nonpure) ->
+      Printf.printf
+       "pure metavariable %s is matched against the following nonpure code:\n"
+       var;
+      Unparse_ast0.unparse_anything nonpure
+  | NotPure(Ast0.Context,(_,var),nonpure) ->
+      Printf.printf
+       "context metavariable %s is matched against the following\nnoncontext code:\n"
+       var;
+      Unparse_ast0.unparse_anything nonpure
+  | NotPure(Ast0.PureContext,(_,var),nonpure) ->
+      Printf.printf
+       "pure context metavariable %s is matched against the following\nnonpure or noncontext code:\n"
+       var;
+      Unparse_ast0.unparse_anything nonpure
+  | NotPureLength((_,var)) ->
+      Printf.printf
+       "pure metavariable %s is matched against too much or too little code\n"
+       var;
+  | ContextRequired(term) ->
+      Printf.printf
+       "the following code matched is not uniformly minus or context,\nor contains a disjunction:\n";
+      Unparse_ast0.unparse_anything term
+  | Braces(s) ->
+      Printf.printf "braces must be all minus (plus code allowed) or all\ncontext (plus code not allowed in the body) to match:\n";
+      Unparse_ast0.statement "" s;
+      Format.print_newline()
+  | Position(rule,name) ->
+      Printf.printf "position variable %s.%s conflicts with an isomorphism\n"
+       rule name;
+  | _ -> failwith "not possible"
+
+type 'a either = OK of 'a | Fail of reason
+
+let add_binding var exp bindings =
+  let var = term var in
+  let attempt bindings =
+    try
+      let cur = List.assoc var bindings in
+      if anything_equal(exp,cur) then [bindings] else []
+    with Not_found -> [((var,exp)::bindings)] in
+  match List.concat(List.map attempt bindings) with
+    [] -> Fail NonMatch
+  | x -> OK x
+
+let add_dot_binding var exp bindings =
+  let var = dot_term var in
+  let attempt bindings =
+    try
+      let cur = List.assoc var bindings in
+      if anything_equal(exp,cur) then [bindings] else []
+    with Not_found -> [((var,exp)::bindings)] in
+  match List.concat(List.map attempt bindings) with
+    [] -> Fail NonMatch
+  | x -> OK x
+
+(* multi-valued *)
+let add_multi_dot_binding var exp bindings =
+  let var = dot_term var in
+  let attempt bindings = [((var,exp)::bindings)] in
+  match List.concat(List.map attempt bindings) with
+    [] -> Fail NonMatch
+  | x -> OK x
+
+let rec nub ls =
+  match ls with
+    [] -> []
+  | (x::xs) when (List.mem x xs) -> nub xs
+  | (x::xs) -> x::(nub xs)
+
+(* --------------------------------------------------------------------- *)
+
+let init_env = [[]]
+
+let debug str m binding =
+  let res = m binding in
+  (match res with
+    None -> Printf.printf "%s: failed\n" str
+  | Some binding ->
+      List.iter
+       (function binding ->
+         Printf.printf "%s: %s\n" str
+           (String.concat " " (List.map (function (x,_) -> x) binding)))
+       binding);
+  res
+
+let conjunct_bindings
+    (m1 : 'binding -> 'binding either)
+    (m2 : 'binding -> 'binding either)
+    (binding : 'binding) : 'binding either =
+  match m1 binding with Fail(reason) -> Fail(reason) | OK binding -> m2 binding
+
+let rec conjunct_many_bindings = function
+    [] -> failwith "not possible"
+  | [x] -> x
+  | x::xs -> conjunct_bindings x (conjunct_many_bindings xs)
+
+let mcode_equal (x,_,_,_,_) (y,_,_,_,_) = x = y
+
+let return b binding = if b then OK binding else Fail NonMatch
+let return_false reason binding = Fail reason
+
+let match_option f t1 t2 =
+  match (t1,t2) with
+    (Some t1, Some t2) -> f t1 t2
+  | (None, None) -> return true
+  | _ -> return false
+
+let bool_match_option f t1 t2 =
+  match (t1,t2) with
+    (Some t1, Some t2) -> f t1 t2
+  | (None, None) -> true
+  | _ -> false
+
+(* context_required is for the example
+   if (
++      (int * )
+       x == NULL)
+  where we can't change x == NULL to eg NULL == x.  So there can either be
+  nothing attached to the root or the term has to be all removed.
+  if would be nice if we knew more about the relationship between the - and +
+  code, because in the case where the + code is a separate statement in a
+  sequence, this is not a problem.  Perhaps something could be done in
+  insert_plus
+
+   The example seems strange.  Why isn't the cast attached to x?
+ *)
+let is_context e =
+  !Flag.sgrep_mode2 or (* everything is context for sgrep *)
+  (match Ast0.get_mcodekind e with
+    Ast0.CONTEXT(cell) -> true
+  | _ -> false)
+
+(* needs a special case when there is a Disj or an empty DOTS
+   the following stops at the statement level, and gives true if one
+   statement is replaced by another *)
+let rec is_pure_context s =
+  !Flag.sgrep_mode2 or (* everything is context for sgrep *)
+  (match Ast0.unwrap s with
+    Ast0.Disj(starter,statement_dots_list,mids,ender) ->
+      List.for_all
+       (function x ->
+         match Ast0.undots x with
+           [s] -> is_pure_context s
+         | _ -> false (* could we do better? *))
+       statement_dots_list
+  | _ ->
+      (match Ast0.get_mcodekind s with
+       Ast0.CONTEXT(mc) ->
+         (match !mc with
+           (Ast.NOTHING,_,_) -> true
+         | _ -> false)
+      | Ast0.MINUS(mc) ->
+         (match !mc with
+       (* do better for the common case of replacing a stmt by another one *)
+           ([[Ast.StatementTag(s)]],_) ->
+             (match Ast.unwrap s with
+               Ast.IfThen(_,_,_) -> false (* potentially dangerous *)
+             | _ -> true)
+         |     (_,_) -> false)
+      | _ -> false))
+
+let is_minus e =
+  match Ast0.get_mcodekind e with Ast0.MINUS(cell) -> true | _ -> false
+
+let match_list matcher is_list_matcher do_list_match la lb =
+  let rec loop = function
+      ([],[]) -> return true
+    | ([x],lb) when is_list_matcher x -> do_list_match x lb
+    | (x::xs,y::ys) -> conjunct_bindings (matcher x y) (loop (xs,ys))
+    | _ -> return false in
+  loop (la,lb)
+
+let match_maker checks_needed context_required whencode_allowed =
+
+  let check_mcode pmc cmc binding =
+    if checks_needed
+    then
+      match Ast0.get_pos cmc with
+       (Ast0.MetaPos (name,_,_)) as x ->
+         (match Ast0.get_pos pmc with
+           Ast0.MetaPos (name1,_,_) ->
+             add_binding name1 (Ast0.MetaPosTag x) binding
+         | Ast0.NoMetaPos ->
+             let (rule,name) = Ast0.unwrap_mcode name in
+             Fail (Position(rule,name)))
+      | Ast0.NoMetaPos -> OK binding
+    else OK binding in
+
+  let match_dots matcher is_list_matcher do_list_match d1 d2 =
+    match (Ast0.unwrap d1, Ast0.unwrap d2) with
+      (Ast0.DOTS(la),Ast0.DOTS(lb))
+    | (Ast0.CIRCLES(la),Ast0.CIRCLES(lb))
+    | (Ast0.STARS(la),Ast0.STARS(lb)) ->
+       match_list matcher is_list_matcher (do_list_match d2) la lb
+    | _ -> return false in
+
+  let is_elist_matcher el =
+    match Ast0.unwrap el with Ast0.MetaExprList(_,_,_) -> true | _ -> false in
+
+  let is_plist_matcher pl =
+    match Ast0.unwrap pl with Ast0.MetaParamList(_,_,_) -> true | _ -> false in
+
+  let is_slist_matcher pl =
+    match Ast0.unwrap pl with Ast0.MetaStmtList(_,_) -> true | _ -> false in
+
+  let no_list _ = false in
+
+  let build_dots pattern data =
+    match Ast0.unwrap pattern with
+      Ast0.DOTS(_) -> Ast0.rewrap pattern (Ast0.DOTS(data))
+    | Ast0.CIRCLES(_) -> Ast0.rewrap pattern (Ast0.CIRCLES(data))
+    | Ast0.STARS(_) -> Ast0.rewrap pattern (Ast0.STARS(data)) in
+
+  let pure_sp_code =
+    let bind = Ast0.lub_pure in
+    let option_default = Ast0.Context in
+    let pure_mcodekind = function
+       Ast0.CONTEXT(mc) ->
+         (match !mc with
+           (Ast.NOTHING,_,_) -> Ast0.PureContext
+         | _ -> Ast0.Context)
+      | Ast0.MINUS(mc) ->
+         (match !mc with ([],_) -> Ast0.Pure | _ ->  Ast0.Impure)
+      | _ -> Ast0.Impure in
+    let donothing r k e =
+      bind (pure_mcodekind (Ast0.get_mcodekind e)) (k e) in
+
+    let mcode m = pure_mcodekind (Ast0.get_mcode_mcodekind m) in
+
+    (* a case for everything that has a metavariable *)
+    (* pure is supposed to match only unitary metavars, not anything that
+       contains only unitary metavars *)
+    let ident r k i =
+      bind (bind (pure_mcodekind (Ast0.get_mcodekind i)) (k i))
+       (match Ast0.unwrap i with
+         Ast0.MetaId(name,_,pure) | Ast0.MetaFunc(name,_,pure)
+       | Ast0.MetaLocalFunc(name,_,pure) -> pure
+       | _ -> Ast0.Impure) in
+
+    let expression r k e =
+      bind (bind (pure_mcodekind (Ast0.get_mcodekind e)) (k e))
+       (match Ast0.unwrap e with
+         Ast0.MetaErr(name,_,pure)
+       | Ast0.MetaExpr(name,_,_,_,pure) | Ast0.MetaExprList(name,_,pure) ->
+           pure
+       | _ -> Ast0.Impure) in
+
+    let typeC r k t =
+      bind (bind (pure_mcodekind (Ast0.get_mcodekind t)) (k t))
+       (match Ast0.unwrap t with
+         Ast0.MetaType(name,pure) -> pure
+       | _ -> Ast0.Impure) in
+
+    let param r k p =
+      bind (bind (pure_mcodekind (Ast0.get_mcodekind p)) (k p))
+       (match Ast0.unwrap p with
+         Ast0.MetaParam(name,pure) | Ast0.MetaParamList(name,_,pure) -> pure
+       | _ -> Ast0.Impure) in
+
+    let stmt r k s =
+      bind (bind (pure_mcodekind (Ast0.get_mcodekind s)) (k s))
+       (match Ast0.unwrap s with
+         Ast0.MetaStmt(name,pure) | Ast0.MetaStmtList(name,pure) -> pure
+       | _ -> Ast0.Impure) in
+
+    V0.combiner bind option_default 
+      mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+      mcode
+      donothing donothing donothing donothing donothing donothing
+      ident expression typeC donothing param donothing stmt donothing
+      donothing in
+
+  let add_pure_list_binding name pure is_pure builder1 builder2 lst =
+    match (checks_needed,pure) with
+      (true,Ast0.Pure) | (true,Ast0.Context) | (true,Ast0.PureContext) ->
+       (match lst with
+         [x] ->
+           if (Ast0.lub_pure (is_pure x) pure) = pure
+           then add_binding name (builder1 lst)
+           else return_false (NotPure (pure,term name,builder1 lst))
+       | _ -> return_false (NotPureLength (term name)))
+    | (false,_) | (_,Ast0.Impure) -> add_binding name (builder2 lst) in
+
+  let add_pure_binding name pure is_pure builder x =
+    match (checks_needed,pure) with
+      (true,Ast0.Pure) | (true,Ast0.Context) | (true,Ast0.PureContext) ->
+       if (Ast0.lub_pure (is_pure x) pure) = pure
+       then add_binding name (builder x)
+       else return_false (NotPure (pure,term name, builder x))
+    | (false,_) | (_,Ast0.Impure) ->  add_binding name (builder x) in
+
+  let do_elist_match builder el lst =
+    match Ast0.unwrap el with
+      Ast0.MetaExprList(name,lenname,pure) ->
+        (*how to handle lenname? should it be an option type and always None?*)
+       failwith "expr list pattern not supported in iso"
+       (*add_pure_list_binding name pure
+         pure_sp_code.V0.combiner_expression
+         (function lst -> Ast0.ExprTag(List.hd lst))
+         (function lst -> Ast0.DotsExprTag(build_dots builder lst))
+         lst*)
+    | _ -> failwith "not possible" in
+
+  let do_plist_match builder pl lst =
+    match Ast0.unwrap pl with
+      Ast0.MetaParamList(name,lename,pure) ->
+       failwith "param list pattern not supported in iso"
+       (*add_pure_list_binding name pure
+         pure_sp_code.V0.combiner_parameter
+         (function lst -> Ast0.ParamTag(List.hd lst))
+         (function lst -> Ast0.DotsParamTag(build_dots builder lst))
+         lst*)
+    | _ -> failwith "not possible" in
+
+  let do_slist_match builder sl lst =
+    match Ast0.unwrap sl with
+      Ast0.MetaStmtList(name,pure) ->
+       add_pure_list_binding name pure
+         pure_sp_code.V0.combiner_statement
+         (function lst -> Ast0.StmtTag(List.hd lst))
+         (function lst -> Ast0.DotsStmtTag(build_dots builder lst))
+         lst
+    | _ -> failwith "not possible" in
+
+  let do_nolist_match _ _ = failwith "not possible" in
+
+  let rec match_ident pattern id =
+    match Ast0.unwrap pattern with
+      Ast0.MetaId(name,_,pure) ->
+       (add_pure_binding name pure pure_sp_code.V0.combiner_ident
+         (function id -> Ast0.IdentTag id) id)
+    | Ast0.MetaFunc(name,_,pure) -> failwith "metafunc not supported"
+    | Ast0.MetaLocalFunc(name,_,pure) -> failwith "metalocalfunc not supported"
+    | up ->
+       if not(checks_needed) or not(context_required) or is_context id
+       then
+         match (up,Ast0.unwrap id) with
+           (Ast0.Id(namea),Ast0.Id(nameb)) ->
+             if mcode_equal namea nameb
+             then check_mcode namea nameb
+             else return false
+         | (Ast0.OptIdent(ida),Ast0.OptIdent(idb))
+         | (Ast0.UniqueIdent(ida),Ast0.UniqueIdent(idb)) ->
+             match_ident ida idb
+         | (_,Ast0.OptIdent(idb))
+         | (_,Ast0.UniqueIdent(idb)) -> match_ident pattern idb
+         | _ -> return false
+       else return_false (ContextRequired (Ast0.IdentTag id)) in
+
+  (* should we do something about matching metavars against ...? *)
+  let rec match_expr pattern expr =
+    match Ast0.unwrap pattern with
+      Ast0.MetaExpr(name,_,ty,form,pure) ->
+       let form_ok =
+         match (form,expr) with
+           (Ast.ANY,_) -> true
+         | (Ast.CONST,e) ->
+             let rec matches e =
+               match Ast0.unwrap e with
+                 Ast0.Constant(c) -> true
+               | Ast0.Cast(lp,ty,rp,e) -> matches e
+               | Ast0.SizeOfExpr(se,exp) -> true
+               | Ast0.SizeOfType(se,lp,ty,rp) -> true
+               | Ast0.MetaExpr(nm,_,_,Ast.CONST,p) ->
+                   (Ast0.lub_pure p pure) = pure
+               | _ -> false in
+             matches e
+         | (Ast.ID,e) | (Ast.LocalID,e) ->
+             let rec matches e =
+               match Ast0.unwrap e with
+                 Ast0.Ident(c) -> true
+               | Ast0.Cast(lp,ty,rp,e) -> matches e
+               | Ast0.MetaExpr(nm,_,_,Ast.ID,p) ->
+                   (Ast0.lub_pure p pure) = pure
+               | _ -> false in
+             matches e in
+       if form_ok
+       then
+         match ty with
+           Some ts ->
+             if List.exists
+                 (function Type_cocci.MetaType(_,_,_) -> true | _ -> false)
+                 ts
+             then
+               (match ts with
+                 [Type_cocci.MetaType(tyname,_,_)] ->
+                   let expty =
+                     match (Ast0.unwrap expr,Ast0.get_type expr) with
+                 (* easier than updating type inferencer to manage multiple
+                    types *)
+                       (Ast0.MetaExpr(_,_,Some tts,_,_),_) -> Some tts
+                     | (_,Some ty) -> Some [ty]
+                     | _ -> None in
+                   (match expty with
+                     Some expty ->
+                       let tyname = Ast0.rewrap_mcode name tyname in
+                       (function bindings ->
+                         let attempts =
+                           List.map
+                             (function expty ->
+                               (try
+                                 conjunct_bindings
+                                   (add_pure_binding tyname Ast0.Impure
+                                      (function _ -> Ast0.Impure)
+                                      (function ty -> Ast0.TypeCTag ty)
+                                      (Ast0.rewrap expr
+                                         (Ast0.reverse_type expty)))
+                                   (add_pure_binding name pure
+                                      pure_sp_code.V0.combiner_expression
+                                      (function expr -> Ast0.ExprTag expr)
+                                      expr)
+                                   bindings
+                               with Ast0.TyConv ->
+                                 Printf.printf "warning: unconvertible type";
+                                 return false bindings))
+                             expty in
+                         match
+                           List.concat
+                             (List.map (function Fail _ -> [] | OK x -> x)
+                                attempts)
+                         with
+                           [] -> Fail NonMatch
+                         | x -> OK x)
+                   |   _ ->
+                 (*Printf.printf
+                    "warning: type metavar can only match one type";*)
+                       return false)
+               | _ ->
+                   failwith
+                     "mixture of metatype and other types not supported")
+             else
+               let expty = Ast0.get_type expr in
+               if List.exists (function t -> Type_cocci.compatible t expty) ts
+               then
+                 add_pure_binding name pure
+                   pure_sp_code.V0.combiner_expression
+                   (function expr -> Ast0.ExprTag expr)
+                   expr
+               else return false
+         | None ->
+             add_pure_binding name pure pure_sp_code.V0.combiner_expression
+               (function expr -> Ast0.ExprTag expr)
+               expr
+       else return false
+    | Ast0.MetaErr(namea,_,pure) -> failwith "metaerr not supported"
+    | Ast0.MetaExprList(_,_,_) -> failwith "metaexprlist not supported"
+    | up ->
+       if not(checks_needed) or not(context_required) or is_context expr
+       then
+         match (up,Ast0.unwrap expr) with
+           (Ast0.Ident(ida),Ast0.Ident(idb)) ->
+             match_ident ida idb
+         | (Ast0.Constant(consta),Ast0.Constant(constb)) ->
+             if mcode_equal consta constb
+             then check_mcode consta constb
+             else return false
+         | (Ast0.FunCall(fna,lp1,argsa,rp1),Ast0.FunCall(fnb,lp,argsb,rp)) ->
+             conjunct_many_bindings
+               [check_mcode lp1 lp; check_mcode rp1 rp; match_expr fna fnb;
+                 match_dots match_expr is_elist_matcher do_elist_match
+                   argsa argsb]
+         | (Ast0.Assignment(lefta,opa,righta,_),
+            Ast0.Assignment(leftb,opb,rightb,_)) ->
+              if mcode_equal opa opb
+              then
+                conjunct_many_bindings
+                  [check_mcode opa opb; match_expr lefta leftb;
+                    match_expr righta rightb]
+              else return false
+         | (Ast0.CondExpr(exp1a,lp1,exp2a,rp1,exp3a),
+            Ast0.CondExpr(exp1b,lp,exp2b,rp,exp3b)) ->
+              conjunct_many_bindings
+                [check_mcode lp1 lp; check_mcode rp1 rp;
+                  match_expr exp1a exp1b; match_option match_expr exp2a exp2b;
+                  match_expr exp3a exp3b]
+         | (Ast0.Postfix(expa,opa),Ast0.Postfix(expb,opb)) ->
+             if mcode_equal opa opb
+             then
+               conjunct_bindings (check_mcode opa opb) (match_expr expa expb)
+             else return false
+         | (Ast0.Infix(expa,opa),Ast0.Infix(expb,opb)) ->
+             if mcode_equal opa opb
+             then
+               conjunct_bindings (check_mcode opa opb) (match_expr expa expb)
+             else return false
+         | (Ast0.Unary(expa,opa),Ast0.Unary(expb,opb)) ->
+             if mcode_equal opa opb
+             then
+               conjunct_bindings (check_mcode opa opb) (match_expr expa expb)
+             else return false
+         | (Ast0.Binary(lefta,opa,righta),Ast0.Binary(leftb,opb,rightb)) ->
+             if mcode_equal opa opb
+             then
+               conjunct_many_bindings
+                 [check_mcode opa opb; match_expr lefta leftb;
+                   match_expr righta rightb]
+             else return false
+         | (Ast0.Paren(lp1,expa,rp1),Ast0.Paren(lp,expb,rp)) ->
+             conjunct_many_bindings
+               [check_mcode lp1 lp; check_mcode rp1 rp; match_expr expa expb]
+         | (Ast0.ArrayAccess(exp1a,lb1,exp2a,rb1),
+            Ast0.ArrayAccess(exp1b,lb,exp2b,rb)) ->
+              conjunct_many_bindings
+                [check_mcode lb1 lb; check_mcode rb1 rb;
+                  match_expr exp1a exp1b; match_expr exp2a exp2b]
+         | (Ast0.RecordAccess(expa,opa,fielda),
+            Ast0.RecordAccess(expb,op,fieldb))
+         | (Ast0.RecordPtAccess(expa,opa,fielda),
+            Ast0.RecordPtAccess(expb,op,fieldb)) ->
+              conjunct_many_bindings
+                [check_mcode opa op; match_expr expa expb;
+                  match_ident fielda fieldb]
+         | (Ast0.Cast(lp1,tya,rp1,expa),Ast0.Cast(lp,tyb,rp,expb)) ->
+             conjunct_many_bindings
+               [check_mcode lp1 lp; check_mcode rp1 rp;
+                 match_typeC tya tyb; match_expr expa expb]
+         | (Ast0.SizeOfExpr(szf1,expa),Ast0.SizeOfExpr(szf,expb)) ->
+             conjunct_bindings (check_mcode szf1 szf) (match_expr expa expb)
+         | (Ast0.SizeOfType(szf1,lp1,tya,rp1),
+            Ast0.SizeOfType(szf,lp,tyb,rp)) ->
+              conjunct_many_bindings
+                [check_mcode lp1 lp; check_mcode rp1 rp;
+                  check_mcode szf1 szf; match_typeC tya tyb]
+         | (Ast0.TypeExp(tya),Ast0.TypeExp(tyb)) ->
+             match_typeC tya tyb
+         | (Ast0.EComma(cm1),Ast0.EComma(cm)) -> check_mcode cm1 cm
+         | (Ast0.DisjExpr(_,expsa,_,_),_) ->
+             failwith "not allowed in the pattern of an isomorphism"
+         | (Ast0.NestExpr(_,exp_dotsa,_,_,_),_) ->
+             failwith "not allowed in the pattern of an isomorphism"
+         | (Ast0.Edots(d,None),Ast0.Edots(d1,None))
+         | (Ast0.Ecircles(d,None),Ast0.Ecircles(d1,None))
+         | (Ast0.Estars(d,None),Ast0.Estars(d1,None)) -> check_mcode d d1
+         | (Ast0.Edots(ed,None),Ast0.Edots(ed1,Some wc))
+         | (Ast0.Ecircles(ed,None),Ast0.Ecircles(ed1,Some wc))
+         | (Ast0.Estars(ed,None),Ast0.Estars(ed1,Some wc)) ->
+           (* hope that mcode of edots is unique somehow *)
+             conjunct_bindings (check_mcode ed ed1)
+               (let (edots_whencode_allowed,_,_) = whencode_allowed in
+               if edots_whencode_allowed
+               then add_dot_binding ed (Ast0.ExprTag wc)
+               else
+                 (Printf.printf
+                    "warning: not applying iso because of whencode";
+                  return false))
+         | (Ast0.Edots(_,Some _),_) | (Ast0.Ecircles(_,Some _),_)
+         | (Ast0.Estars(_,Some _),_) ->
+             failwith "whencode not allowed in a pattern1"
+         | (Ast0.OptExp(expa),Ast0.OptExp(expb))
+         | (Ast0.UniqueExp(expa),Ast0.UniqueExp(expb)) -> match_expr expa expb
+         | (_,Ast0.OptExp(expb))
+         | (_,Ast0.UniqueExp(expb)) -> match_expr pattern expb
+         | _ -> return false
+       else return_false (ContextRequired (Ast0.ExprTag expr))
+           
+(* the special case for function types prevents the eg T X; -> T X = E; iso
+   from applying, which doesn't seem very relevant, but it also avoids a
+   mysterious bug that is obtained with eg int attach(...); *)
+  and match_typeC pattern t =
+    match Ast0.unwrap pattern with
+      Ast0.MetaType(name,pure) ->
+       (match Ast0.unwrap t with
+         Ast0.FunctionType(tya,lp1a,paramsa,rp1a) -> return false
+       | _ ->
+           add_pure_binding name pure pure_sp_code.V0.combiner_typeC
+             (function ty -> Ast0.TypeCTag ty)
+             t)
+    | up ->
+       if not(checks_needed) or not(context_required) or is_context t
+       then
+         match (up,Ast0.unwrap t) with
+           (Ast0.ConstVol(cva,tya),Ast0.ConstVol(cvb,tyb)) ->
+             if mcode_equal cva cvb
+             then
+               conjunct_bindings (check_mcode cva cvb) (match_typeC tya tyb)
+             else return false
+         | (Ast0.BaseType(tya,signa),Ast0.BaseType(tyb,signb)) ->
+             if (mcode_equal tya tyb &&
+                 bool_match_option mcode_equal signa signb)
+             then
+               conjunct_bindings (check_mcode tya tyb)
+                 (match_option check_mcode signa signb)
+             else return false
+         | (Ast0.ImplicitInt(signa),Ast0.ImplicitInt(signb)) ->
+             if mcode_equal signa signb
+             then check_mcode signa signb
+             else return false
+         | (Ast0.Pointer(tya,star1),Ast0.Pointer(tyb,star)) ->
+             conjunct_bindings (check_mcode star1 star) (match_typeC tya tyb)
+         | (Ast0.FunctionPointer(tya,lp1a,stara,rp1a,lp2a,paramsa,rp2a),
+            Ast0.FunctionPointer(tyb,lp1b,starb,rp1b,lp2b,paramsb,rp2b)) ->
+              conjunct_many_bindings
+                [check_mcode stara starb; check_mcode lp1a lp1b;
+                  check_mcode rp1a rp1b; check_mcode lp2a lp2b;
+                  check_mcode rp2a rp2b; match_typeC tya tyb;
+                  match_dots match_param is_plist_matcher
+                    do_plist_match paramsa paramsb]
+         | (Ast0.FunctionType(tya,lp1a,paramsa,rp1a),
+            Ast0.FunctionType(tyb,lp1b,paramsb,rp1b)) ->
+              conjunct_many_bindings
+                [check_mcode lp1a lp1b; check_mcode rp1a rp1b;
+                  match_option match_typeC tya tyb;
+                  match_dots match_param is_plist_matcher do_plist_match
+                    paramsa paramsb]
+         | (Ast0.Array(tya,lb1,sizea,rb1),Ast0.Array(tyb,lb,sizeb,rb)) ->
+             conjunct_many_bindings
+               [check_mcode lb1 lb; check_mcode rb1 rb;
+                 match_typeC tya tyb; match_option match_expr sizea sizeb]
+         | (Ast0.StructUnionName(kinda,Some namea),
+            Ast0.StructUnionName(kindb,Some nameb)) ->
+              if mcode_equal kinda kindb
+              then
+                conjunct_bindings (check_mcode kinda kindb)
+                  (match_ident namea nameb)
+              else return false
+         | (Ast0.StructUnionDef(tya,lb1,declsa,rb1),
+            Ast0.StructUnionDef(tyb,lb,declsb,rb)) ->
+              conjunct_many_bindings
+                [check_mcode lb1 lb; check_mcode rb1 rb;
+                  match_typeC tya tyb;
+                  match_dots match_decl no_list do_nolist_match declsa declsb]
+         | (Ast0.TypeName(namea),Ast0.TypeName(nameb)) ->
+             if mcode_equal namea nameb
+             then check_mcode namea nameb
+             else return false
+         | (Ast0.DisjType(_,typesa,_,_),Ast0.DisjType(_,typesb,_,_)) ->
+             failwith "not allowed in the pattern of an isomorphism"
+         | (Ast0.OptType(tya),Ast0.OptType(tyb))
+         | (Ast0.UniqueType(tya),Ast0.UniqueType(tyb)) -> match_typeC tya tyb
+         | (_,Ast0.OptType(tyb))
+         | (_,Ast0.UniqueType(tyb)) -> match_typeC pattern tyb
+         | _ -> return false
+       else return_false (ContextRequired (Ast0.TypeCTag t))
+           
+  and match_decl pattern d =
+    if not(checks_needed) or not(context_required) or is_context d
+    then
+      match (Ast0.unwrap pattern,Ast0.unwrap d) with
+       (Ast0.Init(stga,tya,ida,eq1,inia,sc1),
+        Ast0.Init(stgb,tyb,idb,eq,inib,sc)) ->
+         if bool_match_option mcode_equal stga stgb
+         then
+           conjunct_many_bindings
+             [check_mcode eq1 eq; check_mcode sc1 sc;
+               match_option check_mcode stga stgb;
+               match_typeC tya tyb; match_ident ida idb;
+               match_init inia inib]
+         else return false
+      | (Ast0.UnInit(stga,tya,ida,sc1),Ast0.UnInit(stgb,tyb,idb,sc)) ->
+         if bool_match_option mcode_equal stga stgb
+         then
+           conjunct_many_bindings
+             [check_mcode sc1 sc; match_option check_mcode stga stgb;
+               match_typeC tya tyb; match_ident ida idb]
+         else return false
+      | (Ast0.MacroDecl(namea,lp1,argsa,rp1,sc1),
+        Ast0.MacroDecl(nameb,lp,argsb,rp,sc)) ->
+          conjunct_many_bindings
+            [match_ident namea nameb;
+              check_mcode lp1 lp; check_mcode rp1 rp;
+              check_mcode sc1 sc;
+              match_dots match_expr is_elist_matcher do_elist_match
+                argsa argsb]
+      | (Ast0.TyDecl(tya,sc1),Ast0.TyDecl(tyb,sc)) ->
+         conjunct_bindings (check_mcode sc1 sc) (match_typeC tya tyb)
+      | (Ast0.Typedef(stga,tya,ida,sc1),Ast0.Typedef(stgb,tyb,idb,sc)) ->
+         conjunct_bindings (check_mcode sc1 sc)
+           (conjunct_bindings (match_typeC tya tyb) (match_typeC ida idb))
+      | (Ast0.DisjDecl(_,declsa,_,_),Ast0.DisjDecl(_,declsb,_,_)) ->
+         failwith "not allowed in the pattern of an isomorphism"
+      | (Ast0.Ddots(d1,None),Ast0.Ddots(d,None)) -> check_mcode d1 d
+      |        (Ast0.Ddots(dd,None),Ast0.Ddots(d,Some wc)) ->
+         conjunct_bindings (check_mcode dd d)
+           (* hope that mcode of ddots is unique somehow *)
+           (let (ddots_whencode_allowed,_,_) = whencode_allowed in
+           if ddots_whencode_allowed
+           then add_dot_binding dd (Ast0.DeclTag wc)
+           else
+             (Printf.printf "warning: not applying iso because of whencode";
+              return false))
+      | (Ast0.Ddots(_,Some _),_) ->
+         failwith "whencode not allowed in a pattern1"
+           
+      | (Ast0.OptDecl(decla),Ast0.OptDecl(declb))
+      | (Ast0.UniqueDecl(decla),Ast0.UniqueDecl(declb)) ->
+         match_decl decla declb
+      | (_,Ast0.OptDecl(declb))
+      | (_,Ast0.UniqueDecl(declb)) ->
+         match_decl pattern declb
+      | _ -> return false
+    else return_false (ContextRequired (Ast0.DeclTag d))
+       
+  and match_init pattern i =
+    if not(checks_needed) or not(context_required) or is_context i
+    then
+      match (Ast0.unwrap pattern,Ast0.unwrap i) with
+       (Ast0.InitExpr(expa),Ast0.InitExpr(expb)) ->
+         match_expr expa expb
+      | (Ast0.InitList(lb1,initlista,rb1),Ast0.InitList(lb,initlistb,rb)) ->
+         conjunct_many_bindings
+           [check_mcode lb1 lb; check_mcode rb1 rb;
+             match_dots match_init no_list do_nolist_match
+               initlista initlistb]
+      | (Ast0.InitGccDotName(d1,namea,e1,inia),
+        Ast0.InitGccDotName(d,nameb,e,inib)) ->
+          conjunct_many_bindings
+            [check_mcode d1 d; check_mcode e1 e;
+              match_ident namea nameb; match_init inia inib]
+      | (Ast0.InitGccName(namea,c1,inia),Ast0.InitGccName(nameb,c,inib)) ->
+         conjunct_many_bindings
+           [check_mcode c1 c; match_ident namea nameb;
+             match_init inia inib]
+      | (Ast0.InitGccIndex(lb1,expa,rb1,e1,inia),
+        Ast0.InitGccIndex(lb2,expb,rb2,e2,inib)) ->
+         conjunct_many_bindings
+            [check_mcode lb1 lb2; check_mcode rb1 rb2; check_mcode e1 e2;
+              match_expr expa expb; match_init inia inib]
+      | (Ast0.InitGccRange(lb1,exp1a,d1,exp2a,rb1,e1,inia),
+        Ast0.InitGccRange(lb2,exp1b,d2,exp2b,rb2,e2,inib)) ->
+         conjunct_many_bindings
+            [check_mcode lb1 lb2; check_mcode d1 d2;
+              check_mcode rb1 rb2; check_mcode e1 e2;
+              match_expr exp1a exp1b; match_expr exp2a exp2b;
+              match_init inia inib]
+      | (Ast0.IComma(c1),Ast0.IComma(c)) -> check_mcode c1 c
+      | (Ast0.Idots(d1,None),Ast0.Idots(d,None)) -> check_mcode d1 d
+      | (Ast0.Idots(id,None),Ast0.Idots(d,Some wc)) ->
+         conjunct_bindings (check_mcode id d)
+         (* hope that mcode of edots is unique somehow *)
+           (let (_,idots_whencode_allowed,_) = whencode_allowed in
+           if idots_whencode_allowed
+           then add_dot_binding id (Ast0.InitTag wc)
+           else
+             (Printf.printf "warning: not applying iso because of whencode";
+              return false))
+      | (Ast0.Idots(_,Some _),_) ->
+         failwith "whencode not allowed in a pattern2"
+      | (Ast0.OptIni(ia),Ast0.OptIni(ib))
+      | (Ast0.UniqueIni(ia),Ast0.UniqueIni(ib)) -> match_init ia ib
+      | (_,Ast0.OptIni(ib))
+      | (_,Ast0.UniqueIni(ib)) -> match_init pattern ib
+      | _ -> return false
+    else return_false (ContextRequired (Ast0.InitTag i))
+       
+  and match_param pattern p =
+    match Ast0.unwrap pattern with
+      Ast0.MetaParam(name,pure) ->
+       add_pure_binding name pure pure_sp_code.V0.combiner_parameter
+         (function p -> Ast0.ParamTag p)
+         p
+    | Ast0.MetaParamList(name,_,pure) -> failwith "metaparamlist not supported"
+    | up ->
+       if not(checks_needed) or not(context_required) or is_context p
+       then
+         match (up,Ast0.unwrap p) with
+           (Ast0.VoidParam(tya),Ast0.VoidParam(tyb)) -> match_typeC tya tyb
+         | (Ast0.Param(tya,ida),Ast0.Param(tyb,idb)) ->
+             conjunct_bindings (match_typeC tya tyb)
+               (match_option match_ident ida idb)
+         | (Ast0.PComma(c1),Ast0.PComma(c)) -> check_mcode c1 c
+         | (Ast0.Pdots(d1),Ast0.Pdots(d))
+         | (Ast0.Pcircles(d1),Ast0.Pcircles(d)) -> check_mcode d1 d
+         | (Ast0.OptParam(parama),Ast0.OptParam(paramb))
+         | (Ast0.UniqueParam(parama),Ast0.UniqueParam(paramb)) ->
+             match_param parama paramb
+         | (_,Ast0.OptParam(paramb))
+         | (_,Ast0.UniqueParam(paramb)) -> match_param pattern paramb
+         | _ -> return false
+       else return_false (ContextRequired (Ast0.ParamTag p))
+           
+  and match_statement pattern s =
+    match Ast0.unwrap pattern with
+      Ast0.MetaStmt(name,pure) ->
+       (match Ast0.unwrap s with
+         Ast0.Dots(_,_) | Ast0.Circles(_,_) | Ast0.Stars(_,_) ->
+           return false (* ... is not a single statement *)
+       | _ ->
+           add_pure_binding name pure pure_sp_code.V0.combiner_statement
+             (function ty -> Ast0.StmtTag ty)
+             s)
+    | Ast0.MetaStmtList(name,pure) -> failwith "metastmtlist not supported"
+    | up ->
+       if not(checks_needed) or not(context_required) or is_context s
+       then
+         match (up,Ast0.unwrap s) with
+           (Ast0.FunDecl(_,fninfoa,namea,lp1,paramsa,rp1,lb1,bodya,rb1),
+            Ast0.FunDecl(_,fninfob,nameb,lp,paramsb,rp,lb,bodyb,rb)) ->
+              conjunct_many_bindings
+                [check_mcode lp1 lp; check_mcode rp1 rp;
+                  check_mcode lb1 lb; check_mcode rb1 rb;
+                  match_fninfo fninfoa fninfob; match_ident namea nameb;
+                  match_dots match_param is_plist_matcher do_plist_match
+                    paramsa paramsb;
+                  match_dots match_statement is_slist_matcher do_slist_match
+                    bodya bodyb]
+         | (Ast0.Decl(_,decla),Ast0.Decl(_,declb)) ->
+             match_decl decla declb
+         | (Ast0.Seq(lb1,bodya,rb1),Ast0.Seq(lb,bodyb,rb)) ->
+             (* seqs can only match if they are all minus (plus code
+                allowed) or all context (plus code not allowed in the body).
+                we could be more permissive if the expansions of the isos are
+                also all seqs, but this would be hard to check except at top
+                level, and perhaps not worth checking even in that case.
+                Overall, the issue is that braces are used where single
+                statements are required, and something not satisfying these
+                conditions can cause a single statement to become a
+                non-single statement after the transformation.
+
+                example: if { ... -foo(); ... }
+                if we let the sequence convert to just -foo();
+                then we produce invalid code.  For some reason,
+                single_statement can't deal with this case, perhaps because
+                it starts introducing too many braces?  don't remember the
+                exact problem...
+             *)
+             conjunct_bindings (check_mcode lb1 lb)
+               (conjunct_bindings (check_mcode rb1 rb)
+                  (if not(checks_needed) or is_minus s or
+                    (is_context s &&
+                     List.for_all is_pure_context (Ast0.undots bodyb))
+                  then
+                    match_dots match_statement is_slist_matcher do_slist_match
+                      bodya bodyb
+                  else return_false (Braces(s))))
+         | (Ast0.ExprStatement(expa,sc1),Ast0.ExprStatement(expb,sc)) ->
+             conjunct_bindings (check_mcode sc1 sc) (match_expr expa expb)
+         | (Ast0.IfThen(if1,lp1,expa,rp1,branch1a,_),
+            Ast0.IfThen(if2,lp2,expb,rp2,branch1b,_)) ->
+              conjunct_many_bindings
+                [check_mcode if1 if2; check_mcode lp1 lp2;
+                  check_mcode rp1 rp2;
+                  match_expr expa expb;
+                  match_statement branch1a branch1b]
+         | (Ast0.IfThenElse(if1,lp1,expa,rp1,branch1a,e1,branch2a,_),
+            Ast0.IfThenElse(if2,lp2,expb,rp2,branch1b,e2,branch2b,_)) ->
+              conjunct_many_bindings
+                [check_mcode if1 if2; check_mcode lp1 lp2;
+                  check_mcode rp1 rp2; check_mcode e1 e2;
+                  match_expr expa expb;
+                  match_statement branch1a branch1b;
+                  match_statement branch2a branch2b]
+         | (Ast0.While(w1,lp1,expa,rp1,bodya,_),
+            Ast0.While(w,lp,expb,rp,bodyb,_)) ->
+              conjunct_many_bindings
+                [check_mcode w1 w; check_mcode lp1 lp;
+                  check_mcode rp1 rp; match_expr expa expb;
+                  match_statement bodya bodyb]
+         | (Ast0.Do(d1,bodya,w1,lp1,expa,rp1,_),
+            Ast0.Do(d,bodyb,w,lp,expb,rp,_)) ->
+              conjunct_many_bindings
+                [check_mcode d1 d; check_mcode w1 w; check_mcode lp1 lp;
+                  check_mcode rp1 rp; match_statement bodya bodyb;
+                  match_expr expa expb]
+         | (Ast0.For(f1,lp1,e1a,sc1a,e2a,sc2a,e3a,rp1,bodya,_),
+            Ast0.For(f,lp,e1b,sc1b,e2b,sc2b,e3b,rp,bodyb,_)) ->
+              conjunct_many_bindings
+                [check_mcode f1 f; check_mcode lp1 lp; check_mcode sc1a sc1b;
+                  check_mcode sc2a sc2b; check_mcode rp1 rp;
+                  match_option match_expr e1a e1b;
+                  match_option match_expr e2a e2b;
+                  match_option match_expr e3a e3b;
+                  match_statement bodya bodyb]
+         | (Ast0.Iterator(nma,lp1,argsa,rp1,bodya,_),
+            Ast0.Iterator(nmb,lp,argsb,rp,bodyb,_)) ->
+              conjunct_many_bindings
+                [match_ident nma nmb;
+                  check_mcode lp1 lp; check_mcode rp1 rp;
+                  match_dots match_expr is_elist_matcher do_elist_match
+                    argsa argsb;
+                  match_statement bodya bodyb]
+         | (Ast0.Switch(s1,lp1,expa,rp1,lb1,casesa,rb1),
+            Ast0.Switch(s,lp,expb,rp,lb,casesb,rb)) ->
+              conjunct_many_bindings
+                [check_mcode s1 s; check_mcode lp1 lp; check_mcode rp1 rp;
+                  check_mcode lb1 lb; check_mcode rb1 rb;
+                  match_expr expa expb;
+                  match_dots match_case_line no_list do_nolist_match
+                    casesa casesb]
+         | (Ast0.Break(b1,sc1),Ast0.Break(b,sc))
+         | (Ast0.Continue(b1,sc1),Ast0.Continue(b,sc)) ->
+             conjunct_bindings (check_mcode b1 b) (check_mcode sc1 sc)
+         | (Ast0.Label(l1,c1),Ast0.Label(l2,c)) ->
+             conjunct_bindings (match_ident l1 l2) (check_mcode c1 c)
+         | (Ast0.Goto(g1,l1,sc1),Ast0.Goto(g,l2,sc)) ->
+             conjunct_many_bindings
+               [check_mcode g1 g; check_mcode sc1 sc; match_ident l1 l2]
+         | (Ast0.Return(r1,sc1),Ast0.Return(r,sc)) ->
+             conjunct_bindings (check_mcode r1 r) (check_mcode sc1 sc)
+         | (Ast0.ReturnExpr(r1,expa,sc1),Ast0.ReturnExpr(r,expb,sc)) ->
+             conjunct_many_bindings
+               [check_mcode r1 r; check_mcode sc1 sc; match_expr expa expb]
+         | (Ast0.Disj(_,statement_dots_lista,_,_),_) ->
+             failwith "disj not supported in patterns"
+         | (Ast0.Nest(_,stmt_dotsa,_,_,_),_) ->
+             failwith "nest not supported in patterns"
+         | (Ast0.Exp(expa),Ast0.Exp(expb)) -> match_expr expa expb
+         | (Ast0.TopExp(expa),Ast0.TopExp(expb)) -> match_expr expa expb
+         | (Ast0.Exp(expa),Ast0.TopExp(expb)) -> match_expr expa expb
+         | (Ast0.TopInit(inita),Ast0.TopInit(initb)) -> match_init inita initb
+         | (Ast0.Ty(tya),Ast0.Ty(tyb)) -> match_typeC tya tyb
+         | (Ast0.Dots(d,[]),Ast0.Dots(d1,wc))
+         | (Ast0.Circles(d,[]),Ast0.Circles(d1,wc))
+         | (Ast0.Stars(d,[]),Ast0.Stars(d1,wc)) ->
+             (match wc with
+               [] -> check_mcode d d1
+             | _ ->
+                 let (_,_,dots_whencode_allowed) = whencode_allowed in
+                 if dots_whencode_allowed
+                 then
+                   conjunct_bindings (check_mcode d d1)
+                     (List.fold_left
+                        (function prev ->
+                          function
+                            | Ast0.WhenNot wc ->
+                                conjunct_bindings prev
+                                  (add_multi_dot_binding d
+                                     (Ast0.DotsStmtTag wc))
+                            | Ast0.WhenAlways wc ->
+                                conjunct_bindings prev
+                                  (add_multi_dot_binding d (Ast0.StmtTag wc))
+                            | Ast0.WhenNotTrue wc ->
+                                conjunct_bindings prev
+                                  (add_multi_dot_binding d
+                                     (Ast0.IsoWhenTTag wc))
+                            | Ast0.WhenNotFalse wc ->
+                                conjunct_bindings prev
+                                  (add_multi_dot_binding d
+                                     (Ast0.IsoWhenFTag wc))
+                            | Ast0.WhenModifier(x) ->
+                                conjunct_bindings prev
+                                  (add_multi_dot_binding d
+                                     (Ast0.IsoWhenTag x)))
+                        (return true) wc)
+                 else
+                   (Printf.printf
+                      "warning: not applying iso because of whencode";
+                    return false))
+         | (Ast0.Dots(_,_::_),_) | (Ast0.Circles(_,_::_),_)
+         | (Ast0.Stars(_,_::_),_) ->
+             failwith "whencode not allowed in a pattern3"
+         | (Ast0.OptStm(rea),Ast0.OptStm(reb))
+         | (Ast0.UniqueStm(rea),Ast0.UniqueStm(reb)) ->
+             match_statement rea reb
+         | (_,Ast0.OptStm(reb))
+         | (_,Ast0.UniqueStm(reb)) -> match_statement pattern reb
+         |     _ -> return false
+       else return_false (ContextRequired (Ast0.StmtTag s))
+           
+  (* first should provide a subset of the information in the second *)
+  and match_fninfo patterninfo cinfo =
+    let patterninfo = List.sort compare patterninfo in
+    let cinfo = List.sort compare cinfo in
+    let rec loop = function
+       (Ast0.FStorage(sta)::resta,Ast0.FStorage(stb)::restb) ->
+         if mcode_equal sta stb
+         then conjunct_bindings (check_mcode sta stb) (loop (resta,restb))
+         else return false
+      |        (Ast0.FType(tya)::resta,Ast0.FType(tyb)::restb) ->
+         conjunct_bindings (match_typeC tya tyb) (loop (resta,restb))
+      |        (Ast0.FInline(ia)::resta,Ast0.FInline(ib)::restb) ->
+         if mcode_equal ia ib
+         then conjunct_bindings (check_mcode ia ib) (loop (resta,restb))
+         else return false
+      |        (Ast0.FAttr(ia)::resta,Ast0.FAttr(ib)::restb) ->
+         if mcode_equal ia ib
+         then conjunct_bindings (check_mcode ia ib) (loop (resta,restb))
+         else return false
+      |        (x::resta,((y::_) as restb)) ->
+         (match compare x y with
+           -1 -> return false
+         | 1 -> loop (resta,restb)
+         | _ -> failwith "not possible")
+      |        _ -> return false in
+    loop (patterninfo,cinfo)
+      
+  and match_case_line pattern c =
+    if not(checks_needed) or not(context_required) or is_context c
+    then
+      match (Ast0.unwrap pattern,Ast0.unwrap c) with
+       (Ast0.Default(d1,c1,codea),Ast0.Default(d,c,codeb)) ->
+         conjunct_many_bindings
+           [check_mcode d1 d; check_mcode c1 c;
+             match_dots match_statement is_slist_matcher do_slist_match
+               codea codeb]
+      | (Ast0.Case(ca1,expa,c1,codea),Ast0.Case(ca,expb,c,codeb)) ->
+         conjunct_many_bindings
+           [check_mcode ca1 ca; check_mcode c1 c; match_expr expa expb;
+             match_dots match_statement is_slist_matcher do_slist_match
+               codea codeb]
+      |        (Ast0.OptCase(ca),Ast0.OptCase(cb)) -> match_case_line ca cb
+      |        (_,Ast0.OptCase(cb)) -> match_case_line pattern cb
+      |        _ -> return false
+    else return_false (ContextRequired (Ast0.CaseLineTag c)) in
+  
+  let match_statement_dots x y =
+    match_dots match_statement is_slist_matcher do_slist_match x y in
+  
+  (match_expr, match_decl, match_statement, match_typeC,
+   match_statement_dots)
+    
+let match_expr dochecks context_required whencode_allowed =
+  let (fn,_,_,_,_) = match_maker dochecks context_required whencode_allowed in
+  fn
+    
+let match_decl dochecks context_required whencode_allowed =
+  let (_,fn,_,_,_) = match_maker dochecks context_required whencode_allowed in
+  fn
+    
+let match_statement dochecks context_required whencode_allowed =
+  let (_,_,fn,_,_) = match_maker dochecks context_required whencode_allowed in
+  fn
+    
+let match_typeC dochecks context_required whencode_allowed =
+  let (_,_,_,fn,_) = match_maker dochecks context_required whencode_allowed in
+  fn
+    
+let match_statement_dots dochecks context_required whencode_allowed =
+  let (_,_,_,_,fn) = match_maker dochecks context_required whencode_allowed in
+  fn
+    
+(* --------------------------------------------------------------------- *)
+(* make an entire tree MINUS *)
+    
+let make_minus =
+  let mcode (term,arity,info,mcodekind,pos) =
+    let new_mcodekind =
+     match mcodekind with
+       Ast0.CONTEXT(mc) ->
+        (match !mc with
+          (Ast.NOTHING,_,_) -> Ast0.MINUS(ref([],Ast0.default_token_info))
+        | _ -> failwith "make_minus: unexpected befaft")
+     | Ast0.MINUS(mc) -> mcodekind (* in the part copied from the src term *)
+     | _ -> failwith "make_minus mcode: unexpected mcodekind" in
+    (term,arity,info,new_mcodekind,pos) in
+  
+  let update_mc mcodekind e =
+    match !mcodekind with
+      Ast0.CONTEXT(mc) ->
+       (match !mc with
+         (Ast.NOTHING,_,_) ->
+           mcodekind := Ast0.MINUS(ref([],Ast0.default_token_info))
+       | _ -> failwith "make_minus: unexpected befaft")
+    | Ast0.MINUS(_mc) -> () (* in the part copied from the src term *)
+    | Ast0.PLUS -> failwith "make_minus donothing: unexpected plus mcodekind"
+    | _ -> failwith "make_minus donothing: unexpected mcodekind" in
+  
+  let donothing r k e =
+    let mcodekind = Ast0.get_mcodekind_ref e in
+    let e = k e in update_mc mcodekind e; e in
+  
+  (* special case for whencode, because it isn't processed by contextneg,
+     since it doesn't appear in the + code *)
+  (* cases for dots and nests *)
+  let expression r k e =
+    let mcodekind = Ast0.get_mcodekind_ref e in
+    match Ast0.unwrap e with
+      Ast0.Edots(d,whencode) ->
+       (*don't recurse because whencode hasn't been processed by context_neg*)
+       update_mc mcodekind e; Ast0.rewrap e (Ast0.Edots(mcode d,whencode))
+    | Ast0.Ecircles(d,whencode) ->
+       (*don't recurse because whencode hasn't been processed by context_neg*)
+       update_mc mcodekind e; Ast0.rewrap e (Ast0.Ecircles(mcode d,whencode))
+    | Ast0.Estars(d,whencode) ->
+       (*don't recurse because whencode hasn't been processed by context_neg*)
+       update_mc mcodekind e; Ast0.rewrap e (Ast0.Estars(mcode d,whencode))
+    | Ast0.NestExpr(starter,expr_dots,ender,whencode,multi) ->
+       update_mc mcodekind e;
+       Ast0.rewrap e
+         (Ast0.NestExpr(mcode starter,
+                        r.V0.rebuilder_expression_dots expr_dots,
+                        mcode ender,whencode,multi))
+    | _ -> donothing r k e in
+  
+  let declaration r k e =
+    let mcodekind = Ast0.get_mcodekind_ref e in
+    match Ast0.unwrap e with
+      Ast0.Ddots(d,whencode) ->
+       (*don't recurse because whencode hasn't been processed by context_neg*)
+       update_mc mcodekind e; Ast0.rewrap e (Ast0.Ddots(mcode d,whencode))
+    | _ -> donothing r k e in
+  
+  let statement r k e =
+    let mcodekind = Ast0.get_mcodekind_ref e in
+    match Ast0.unwrap e with
+      Ast0.Dots(d,whencode) ->
+       (*don't recurse because whencode hasn't been processed by context_neg*)
+       update_mc mcodekind e; Ast0.rewrap e (Ast0.Dots(mcode d,whencode))
+    | Ast0.Circles(d,whencode) ->
+       update_mc mcodekind e; Ast0.rewrap e (Ast0.Circles(mcode d,whencode))
+    | Ast0.Stars(d,whencode) ->
+       update_mc mcodekind e; Ast0.rewrap e (Ast0.Stars(mcode d,whencode))
+    | Ast0.Nest(starter,stmt_dots,ender,whencode,multi) ->
+       update_mc mcodekind e;
+       Ast0.rewrap e
+         (Ast0.Nest(mcode starter,r.V0.rebuilder_statement_dots stmt_dots,
+                    mcode ender,whencode,multi))
+    | _ -> donothing r k e in
+  
+  let initialiser r k e =
+    let mcodekind = Ast0.get_mcodekind_ref e in
+    match Ast0.unwrap e with
+      Ast0.Idots(d,whencode) ->
+       (*don't recurse because whencode hasn't been processed by context_neg*)
+       update_mc mcodekind e; Ast0.rewrap e (Ast0.Idots(mcode d,whencode))
+    | _ -> donothing r k e in
+  
+  let dots r k e =
+    let info = Ast0.get_info e in
+    let mcodekind = Ast0.get_mcodekind_ref e in
+    match Ast0.unwrap e with
+      Ast0.DOTS([]) ->
+       (* if context is - this should be - as well.  There are no tokens
+          here though, so the bottom-up minusifier in context_neg leaves it
+          as mixed.  It would be better to fix context_neg, but that would
+          require a special case for each term with a dots subterm. *)
+       (match !mcodekind with
+         Ast0.MIXED(mc) ->
+           (match !mc with
+             (Ast.NOTHING,_,_) ->
+               mcodekind := Ast0.MINUS(ref([],Ast0.default_token_info));
+               e
+           | _ -> failwith "make_minus: unexpected befaft")
+         (* code already processed by an enclosing iso *)
+       | Ast0.MINUS(mc) -> e
+       | _ ->
+           failwith
+             (Printf.sprintf
+                "%d: make_minus donothingxxx: unexpected mcodekind"
+                info.Ast0.line_start))
+    | _ -> donothing r k e in
+  
+  V0.rebuilder
+    mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+    mcode
+    dots dots dots dots dots dots
+    donothing expression donothing initialiser donothing declaration
+    statement donothing donothing
+    
+(* --------------------------------------------------------------------- *)
+(* rebuild mcode cells in an instantiated alt *)
+    
+(* mcodes will be side effected later with plus code, so we have to copy
+   them on instantiating an isomorphism.  One could wonder whether it would
+   be better not to use side-effects, but they are convenient for insert_plus
+   where is it useful to manipulate a list of the mcodes but side-effect a
+   tree *)
+(* hmm... Insert_plus is called before Iso_pattern... *)
+let rebuild_mcode start_line =
+  let copy_mcodekind = function
+      Ast0.CONTEXT(mc) -> Ast0.CONTEXT(ref (!mc))
+    | Ast0.MINUS(mc) -> Ast0.MINUS(ref (!mc))
+    | Ast0.MIXED(mc) -> Ast0.MIXED(ref (!mc))
+    | Ast0.PLUS ->
+       (* this function is used elsewhere where we need to rebuild the
+          indices, and so we allow PLUS code as well *)
+        Ast0.PLUS in
+  
+  let mcode (term,arity,info,mcodekind,pos) =
+    let info =
+      match start_line with
+       Some x -> {info with Ast0.line_start = x; Ast0.line_end = x}
+      |        None -> info in
+    (term,arity,info,copy_mcodekind mcodekind,pos) in
+  
+  let copy_one x =
+    let old_info = Ast0.get_info x in
+    let info =
+      match start_line with
+       Some x -> {old_info with Ast0.line_start = x; Ast0.line_end = x}
+      |        None -> old_info in
+    {x with Ast0.info = info; Ast0.index = ref(Ast0.get_index x);
+      Ast0.mcodekind = ref (copy_mcodekind (Ast0.get_mcodekind x))} in
+  
+  let donothing r k e = copy_one (k e) in
+  
+  (* case for control operators (if, etc) *)
+  let statement r k e =
+    let s = k e in
+    let res =
+      copy_one
+       (Ast0.rewrap s
+          (match Ast0.unwrap s with
+            Ast0.Decl((info,mc),decl) ->
+              Ast0.Decl((info,copy_mcodekind mc),decl)
+          | Ast0.IfThen(iff,lp,tst,rp,branch,(info,mc)) ->
+              Ast0.IfThen(iff,lp,tst,rp,branch,(info,copy_mcodekind mc))
+          | Ast0.IfThenElse(iff,lp,tst,rp,branch1,els,branch2,(info,mc)) ->
+              Ast0.IfThenElse(iff,lp,tst,rp,branch1,els,branch2,
+                (info,copy_mcodekind mc))
+          | Ast0.While(whl,lp,exp,rp,body,(info,mc)) ->
+              Ast0.While(whl,lp,exp,rp,body,(info,copy_mcodekind mc))
+          | Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,(info,mc)) ->
+              Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,
+                       (info,copy_mcodekind mc))
+          | Ast0.Iterator(nm,lp,args,rp,body,(info,mc)) ->
+              Ast0.Iterator(nm,lp,args,rp,body,(info,copy_mcodekind mc))
+          | Ast0.FunDecl
+              ((info,mc),fninfo,name,lp,params,rp,lbrace,body,rbrace) ->
+                Ast0.FunDecl
+                  ((info,copy_mcodekind mc),
+                   fninfo,name,lp,params,rp,lbrace,body,rbrace)
+          | s -> s)) in
+    Ast0.set_dots_bef_aft res
+      (match Ast0.get_dots_bef_aft res with
+       Ast0.NoDots -> Ast0.NoDots
+      | Ast0.AddingBetweenDots s ->
+         Ast0.AddingBetweenDots(r.V0.rebuilder_statement s)
+      | Ast0.DroppingBetweenDots s ->
+         Ast0.DroppingBetweenDots(r.V0.rebuilder_statement s)) in
+  
+  V0.rebuilder
+    mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+    mcode
+    donothing donothing donothing donothing donothing donothing
+    donothing donothing donothing donothing donothing
+    donothing statement donothing donothing
+    
+(* --------------------------------------------------------------------- *)
+(* The problem of whencode.  If an isomorphism contains dots in multiple
+   rules, then the code that is matched cannot contain whencode, because we
+   won't know which dots it goes with. Should worry about nests, but they
+   aren't allowed in isomorphisms for the moment. *)
+    
+let count_edots =
+  let mcode x = 0 in
+  let option_default = 0 in
+  let bind x y = x + y in
+  let donothing r k e = k e in
+  let exprfn r k e =
+    match Ast0.unwrap e with
+      Ast0.Edots(_,_) | Ast0.Ecircles(_,_) | Ast0.Estars(_,_) -> 1
+    | _ -> 0 in
+  
+  V0.combiner bind option_default
+    mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+    mcode
+    donothing donothing donothing donothing donothing donothing
+    donothing exprfn donothing donothing donothing donothing donothing
+    donothing donothing
+    
+let count_idots =
+  let mcode x = 0 in
+  let option_default = 0 in
+  let bind x y = x + y in
+  let donothing r k e = k e in
+  let initfn r k e =
+    match Ast0.unwrap e with Ast0.Idots(_,_) -> 1 | _ -> 0 in
+  
+  V0.combiner bind option_default
+    mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+    mcode
+    donothing donothing donothing donothing donothing donothing
+    donothing donothing donothing initfn donothing donothing donothing
+    donothing donothing
+    
+let count_dots =
+  let mcode x = 0 in
+  let option_default = 0 in
+  let bind x y = x + y in
+  let donothing r k e = k e in
+  let stmtfn r k e =
+    match Ast0.unwrap e with
+      Ast0.Dots(_,_) | Ast0.Circles(_,_) | Ast0.Stars(_,_) -> 1
+    | _ -> 0 in
+  
+  V0.combiner bind option_default
+    mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+    mcode
+    donothing donothing donothing donothing donothing donothing
+    donothing donothing donothing donothing donothing donothing stmtfn
+    donothing donothing
+    
+(* --------------------------------------------------------------------- *)
+    
+let lookup name bindings mv_bindings =
+  try Common.Left (List.assoc (term name) bindings)
+  with
+    Not_found ->
+      (* failure is not possible anymore *)
+      Common.Right (List.assoc (term name) mv_bindings)
+
+(* mv_bindings is for the fresh metavariables that are introduced by the
+isomorphism *)
+let instantiate bindings mv_bindings =
+  let mcode x =
+    match Ast0.get_pos x with
+      Ast0.MetaPos(name,_,_) ->
+       (try
+         match lookup name bindings mv_bindings with
+           Common.Left(Ast0.MetaPosTag(id)) -> Ast0.set_pos id x
+         | _ -> failwith "not possible"
+       with Not_found -> Ast0.set_pos Ast0.NoMetaPos x)
+    | _ -> x in
+  let donothing r k e = k e in
+
+  (* cases where metavariables can occur *)
+  let identfn r k e =
+    let e = k e in
+    match Ast0.unwrap e with
+      Ast0.MetaId(name,constraints,pure) ->
+       (rebuild_mcode None).V0.rebuilder_ident
+         (match lookup name bindings mv_bindings with
+           Common.Left(Ast0.IdentTag(id)) -> id
+         | Common.Left(_) -> failwith "not possible 1"
+         | Common.Right(new_mv) ->
+             Ast0.rewrap e
+               (Ast0.MetaId
+                  (Ast0.set_mcode_data new_mv name,constraints,pure)))
+    | Ast0.MetaFunc(name,_,pure) -> failwith "metafunc not supported"
+    | Ast0.MetaLocalFunc(name,_,pure) -> failwith "metalocalfunc not supported"
+    | _ -> e in
+
+  (* case for list metavariables *)
+  let rec elist r same_dots = function
+      [] -> []
+    | [x] ->
+       (match Ast0.unwrap x with
+         Ast0.MetaExprList(name,lenname,pure) ->
+           failwith "meta_expr_list in iso not supported"
+           (*match lookup name bindings mv_bindings with
+             Common.Left(Ast0.DotsExprTag(exp)) ->
+               (match same_dots exp with
+                 Some l -> l
+               | None -> failwith "dots put in incompatible context")
+           | Common.Left(Ast0.ExprTag(exp)) -> [exp]
+           | Common.Left(_) -> failwith "not possible 1"
+           | Common.Right(new_mv) ->
+               failwith "MetaExprList in SP not supported"*)
+       | _ -> [r.V0.rebuilder_expression x])
+    | x::xs -> (r.V0.rebuilder_expression x)::(elist r same_dots xs) in
+
+  let rec plist r same_dots = function
+      [] -> []
+    | [x] ->
+       (match Ast0.unwrap x with
+         Ast0.MetaParamList(name,lenname,pure) ->
+           failwith "meta_param_list in iso not supported"
+           (*match lookup name bindings mv_bindings with
+             Common.Left(Ast0.DotsParamTag(param)) ->
+               (match same_dots param with
+                 Some l -> l
+               | None -> failwith "dots put in incompatible context")
+           | Common.Left(Ast0.ParamTag(param)) -> [param]
+           | Common.Left(_) -> failwith "not possible 1"
+           | Common.Right(new_mv) ->
+               failwith "MetaExprList in SP not supported"*)
+       | _ -> [r.V0.rebuilder_parameter x])
+    | x::xs -> (r.V0.rebuilder_parameter x)::(plist r same_dots xs) in
+
+  let rec slist r same_dots = function
+      [] -> []
+    | [x] ->
+       (match Ast0.unwrap x with
+         Ast0.MetaStmtList(name,pure) ->
+           (match lookup name bindings mv_bindings with
+             Common.Left(Ast0.DotsStmtTag(stm)) ->
+               (match same_dots stm with
+                 Some l -> l
+               | None -> failwith "dots put in incompatible context")
+           | Common.Left(Ast0.StmtTag(stm)) -> [stm]
+           | Common.Left(_) -> failwith "not possible 1"
+           | Common.Right(new_mv) ->
+               failwith "MetaExprList in SP not supported")
+       | _ -> [r.V0.rebuilder_statement x])
+    | x::xs -> (r.V0.rebuilder_statement x)::(slist r same_dots xs) in
+
+  let same_dots d =
+    match Ast0.unwrap d with Ast0.DOTS(l) -> Some l |_ -> None in
+  let same_circles d =
+    match Ast0.unwrap d with Ast0.CIRCLES(l) -> Some l |_ -> None in
+  let same_stars d =
+    match Ast0.unwrap d with Ast0.STARS(l) -> Some l |_ -> None in
+
+  let dots list_fn r k d =
+    Ast0.rewrap d
+      (match Ast0.unwrap d with
+       Ast0.DOTS(l) -> Ast0.DOTS(list_fn r same_dots l)
+      | Ast0.CIRCLES(l) -> Ast0.CIRCLES(list_fn r same_circles l)
+      | Ast0.STARS(l) -> Ast0.STARS(list_fn r same_stars l)) in
+
+  let exprfn r k old_e = (* need to keep the original code for ! optim *)
+    let e = k old_e in
+    let e1 =
+    match Ast0.unwrap e with
+      Ast0.MetaExpr(name,constraints,x,form,pure) ->
+       (rebuild_mcode None).V0.rebuilder_expression
+         (match lookup name bindings mv_bindings with
+           Common.Left(Ast0.ExprTag(exp)) -> exp
+         | Common.Left(_) -> failwith "not possible 1"
+         | Common.Right(new_mv) ->
+             let new_types =
+               match x with
+                 None -> None
+               | Some types ->
+                   let rec renamer = function
+                       Type_cocci.MetaType(name,keep,inherited) ->
+                         (match
+                           lookup (name,(),(),(),None) bindings mv_bindings
+                         with
+                           Common.Left(Ast0.TypeCTag(t)) ->
+                             Ast0.ast0_type_to_type t
+                         | Common.Left(_) ->
+                             failwith "iso pattern: unexpected type"
+                         | Common.Right(new_mv) ->
+                             Type_cocci.MetaType(new_mv,keep,inherited))
+                     | Type_cocci.ConstVol(cv,ty) ->
+                         Type_cocci.ConstVol(cv,renamer ty)
+                     | Type_cocci.Pointer(ty) ->
+                         Type_cocci.Pointer(renamer ty)
+                     | Type_cocci.FunctionPointer(ty) ->
+                         Type_cocci.FunctionPointer(renamer ty)
+                     | Type_cocci.Array(ty) ->
+                         Type_cocci.Array(renamer ty)
+                     | t -> t in
+                   Some(List.map renamer types) in
+             Ast0.rewrap e
+               (Ast0.MetaExpr
+                  (Ast0.set_mcode_data new_mv name,constraints,
+                   new_types,form,pure)))
+    | Ast0.MetaErr(namea,_,pure) -> failwith "metaerr not supported"
+    | Ast0.MetaExprList(namea,lenname,pure) ->
+       failwith "metaexprlist not supported"
+    | Ast0.Unary(exp,unop) ->
+       (match Ast0.unwrap_mcode unop with
+         Ast.Not ->
+           let was_meta =
+             (* k e doesn't change the outer structure of the term,
+                only the metavars *)
+             match Ast0.unwrap old_e with
+               Ast0.Unary(exp,_) ->
+                 (match Ast0.unwrap exp with
+                   Ast0.MetaExpr(name,constraints,x,form,pure) -> true
+                 | _ -> false)
+             | _ -> failwith "not possible" in
+           let nomodif e =
+             let mc = Ast0.get_mcodekind exp in
+             match mc with
+               Ast0.MINUS(x) ->
+                 (match !x with
+                   ([],_) -> true
+                 | _ -> false)
+             | Ast0.CONTEXT(x) | Ast0.MIXED(x) ->
+                 (match !x with
+                   (Ast.NOTHING,_,_) -> true
+                 | _ -> false)
+             | _ -> failwith "plus not possible" in
+           if was_meta && nomodif exp && nomodif e
+           then
+             let rec negate e (*for rewrapping*) res (*code to process*) =
+               match Ast0.unwrap res with
+                 Ast0.Unary(e1,op) when Ast0.unwrap_mcode op = Ast.Not ->
+                   Ast0.rewrap e (Ast0.unwrap e1)
+               | Ast0.Edots(_,_) -> Ast0.rewrap e (Ast0.unwrap res)
+               | Ast0.Paren(lp,e,rp) ->
+                   Ast0.rewrap res (Ast0.Paren(lp,negate e e,rp))
+               | Ast0.Binary(e1,op,e2) ->
+                   let reb nop = Ast0.rewrap_mcode op (Ast.Logical(nop)) in
+                   let invop =
+                     match Ast0.unwrap_mcode op with
+                       Ast.Logical(Ast.Inf) ->
+                         Ast0.Binary(e1,reb Ast.SupEq,e2)
+                     | Ast.Logical(Ast.Sup) ->
+                         Ast0.Binary(e1,reb Ast.InfEq,e2)
+                     | Ast.Logical(Ast.InfEq) ->
+                         Ast0.Binary(e1,reb Ast.Sup,e2)
+                     | Ast.Logical(Ast.SupEq) ->
+                         Ast0.Binary(e1,reb Ast.Inf,e2)
+                     | Ast.Logical(Ast.Eq) ->
+                         Ast0.Binary(e1,reb Ast.NotEq,e2)
+                     | Ast.Logical(Ast.NotEq) ->
+                         Ast0.Binary(e1,reb Ast.Eq,e2)
+                     | Ast.Logical(Ast.AndLog) ->
+                         Ast0.Binary(negate e1 e1,reb Ast.OrLog,
+                                     negate e2 e2)
+                     | Ast.Logical(Ast.OrLog) ->
+                         Ast0.Binary(negate e1 e1,reb Ast.AndLog,
+                                     negate e2 e2)
+                     | _ -> Ast0.Unary(res,Ast0.rewrap_mcode op Ast.Not) in
+                   Ast0.rewrap e invop
+               | Ast0.DisjExpr(lp,exps,mids,rp) ->
+                     (* use res because it is the transformed argument *)
+                   let exps = List.map (function e -> negate e e) exps in
+                   Ast0.rewrap res (Ast0.DisjExpr(lp,exps,mids,rp))
+               | _ ->
+                     (*use e, because this might be the toplevel expression*)
+                   Ast0.rewrap e
+                     (Ast0.Unary(res,Ast0.rewrap_mcode unop Ast.Not)) in
+             negate e exp
+           else e
+       | _ -> e)
+    | Ast0.Edots(d,_) ->
+       (try
+         (match List.assoc (dot_term d) bindings with
+           Ast0.ExprTag(exp) -> Ast0.rewrap e (Ast0.Edots(d,Some exp))
+         | _ -> failwith "unexpected binding")
+       with Not_found -> e)
+    | Ast0.Ecircles(d,_) ->
+       (try
+         (match List.assoc (dot_term d) bindings with
+           Ast0.ExprTag(exp) -> Ast0.rewrap e (Ast0.Ecircles(d,Some exp))
+         | _ -> failwith "unexpected binding")
+       with Not_found -> e)
+    | Ast0.Estars(d,_) ->
+       (try
+         (match List.assoc (dot_term d) bindings with
+           Ast0.ExprTag(exp) -> Ast0.rewrap e (Ast0.Estars(d,Some exp))
+         | _ -> failwith "unexpected binding")
+       with Not_found -> e)
+    | _ -> e in
+    if Ast0.get_test_exp old_e then Ast0.set_test_exp e1 else e1 in
+
+  let tyfn r k e =
+    let e = k e in
+    match Ast0.unwrap e with
+      Ast0.MetaType(name,pure) ->
+       (rebuild_mcode None).V0.rebuilder_typeC
+         (match lookup name bindings mv_bindings with
+           Common.Left(Ast0.TypeCTag(ty)) -> ty
+         | Common.Left(_) -> failwith "not possible 1"
+         | Common.Right(new_mv) ->
+             Ast0.rewrap e
+               (Ast0.MetaType(Ast0.set_mcode_data new_mv name,pure)))
+    | _ -> e in
+
+  let declfn r k e =
+    let e = k e in
+    match Ast0.unwrap e with
+      Ast0.Ddots(d,_) ->
+       (try
+         (match List.assoc (dot_term d) bindings with
+           Ast0.DeclTag(exp) -> Ast0.rewrap e (Ast0.Ddots(d,Some exp))
+         | _ -> failwith "unexpected binding")
+       with Not_found -> e)
+    | _ -> e in
+
+  let paramfn r k e =
+    let e = k e in
+    match Ast0.unwrap e with
+      Ast0.MetaParam(name,pure) ->
+       (rebuild_mcode None).V0.rebuilder_parameter
+         (match lookup name bindings mv_bindings with
+           Common.Left(Ast0.ParamTag(param)) -> param
+         | Common.Left(_) -> failwith "not possible 1"
+         | Common.Right(new_mv) ->
+             Ast0.rewrap e
+               (Ast0.MetaParam(Ast0.set_mcode_data new_mv name, pure)))
+    | Ast0.MetaParamList(name,lenname,pure) ->
+       failwith "metaparamlist not supported"
+    | _ -> e in
+
+  let whenfn (_,v) =
+    match v with
+      Ast0.DotsStmtTag(stms) -> Ast0.WhenNot stms
+    | Ast0.StmtTag(stm) -> Ast0.WhenAlways stm
+    | Ast0.IsoWhenTTag(stm) -> Ast0.WhenNotTrue stm
+    | Ast0.IsoWhenFTag(stm) -> Ast0.WhenNotFalse stm
+    | Ast0.IsoWhenTag(x) -> Ast0.WhenModifier(x)
+    | _ -> failwith "unexpected binding" in
+
+  let stmtfn r k e =
+    let e = k e in
+    match Ast0.unwrap e with
+    Ast0.MetaStmt(name,pure) ->
+       (rebuild_mcode None).V0.rebuilder_statement
+         (match lookup name bindings mv_bindings with
+           Common.Left(Ast0.StmtTag(stm)) -> stm
+         | Common.Left(_) -> failwith "not possible 1"
+         | Common.Right(new_mv) ->
+             Ast0.rewrap e
+               (Ast0.MetaStmt(Ast0.set_mcode_data new_mv name,pure)))
+    | Ast0.MetaStmtList(name,pure) -> failwith "metastmtlist not supported"
+    | Ast0.Dots(d,_) ->
+       Ast0.rewrap e
+         (Ast0.Dots
+            (d,
+             List.map whenfn
+               (List.filter (function (x,v) -> x = (dot_term d)) bindings)))
+    | Ast0.Circles(d,_) ->
+       Ast0.rewrap e
+         (Ast0.Circles
+            (d,
+             List.map whenfn
+               (List.filter (function (x,v) -> x = (dot_term d)) bindings)))
+    | Ast0.Stars(d,_) ->
+       Ast0.rewrap e
+         (Ast0.Stars
+            (d,
+             List.map whenfn
+               (List.filter (function (x,v) -> x = (dot_term d)) bindings)))
+    | _ -> e in
+
+  V0.rebuilder
+    mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+    mcode
+    (dots elist) donothing (dots plist) (dots slist) donothing donothing
+    identfn exprfn tyfn donothing paramfn declfn stmtfn donothing donothing
+
+(* --------------------------------------------------------------------- *)
+
+let is_minus e =
+  match Ast0.get_mcodekind e with Ast0.MINUS(cell) -> true | _ -> false
+
+let context_required e = not(is_minus e) && not !Flag.sgrep_mode2
+
+let disj_fail bindings e =
+  match bindings with
+    Some x -> Printf.fprintf stderr "no disj available at this type"; e
+  | None -> e
+
+(* isomorphism code is by default CONTEXT *)
+let merge_plus model_mcode e_mcode =
+  match model_mcode with
+    Ast0.MINUS(mc) ->
+      (* add the replacement information at the root *)
+      (match e_mcode with
+       Ast0.MINUS(emc) ->
+         emc :=
+           (match (!mc,!emc) with
+             (([],_),(x,t)) | ((x,_),([],t)) -> (x,t)
+           | _ -> failwith "how can we combine minuses?")
+      |        _ -> failwith "not possible 6")
+  | Ast0.CONTEXT(mc) ->
+      (match e_mcode with
+       Ast0.CONTEXT(emc) ->
+         (* keep the logical line info as in the model *)
+         let (mba,tb,ta) = !mc in
+         let (eba,_,_) = !emc in
+         (* merging may be required when a term is replaced by a subterm *)
+         let merged =
+           match (mba,eba) with
+             (x,Ast.NOTHING) | (Ast.NOTHING,x) -> x
+           | (Ast.BEFORE(b1),Ast.BEFORE(b2)) -> Ast.BEFORE(b1@b2)
+           | (Ast.BEFORE(b),Ast.AFTER(a)) -> Ast.BEFOREAFTER(b,a)
+           | (Ast.BEFORE(b1),Ast.BEFOREAFTER(b2,a)) ->
+               Ast.BEFOREAFTER(b1@b2,a)
+           | (Ast.AFTER(a),Ast.BEFORE(b)) -> Ast.BEFOREAFTER(b,a)
+           | (Ast.AFTER(a1),Ast.AFTER(a2)) ->Ast.AFTER(a2@a1)
+           | (Ast.AFTER(a1),Ast.BEFOREAFTER(b,a2)) -> Ast.BEFOREAFTER(b,a2@a1)
+           | (Ast.BEFOREAFTER(b1,a),Ast.BEFORE(b2)) ->
+               Ast.BEFOREAFTER(b1@b2,a)
+           | (Ast.BEFOREAFTER(b,a1),Ast.AFTER(a2)) ->
+               Ast.BEFOREAFTER(b,a2@a1)
+           | (Ast.BEFOREAFTER(b1,a1),Ast.BEFOREAFTER(b2,a2)) ->
+                Ast.BEFOREAFTER(b1@b2,a2@a1) in
+         emc := (merged,tb,ta)
+      |        Ast0.MINUS(emc) ->
+         let (anything_bef_aft,_,_) = !mc in
+         let (anythings,t) = !emc in
+         emc :=
+           (match anything_bef_aft with
+             Ast.BEFORE(b) -> (b@anythings,t)
+           | Ast.AFTER(a) -> (anythings@a,t)
+           | Ast.BEFOREAFTER(b,a) -> (b@anythings@a,t)
+           | Ast.NOTHING -> (anythings,t))
+      |        _ -> failwith "not possible 7")
+  | Ast0.MIXED(_) -> failwith "not possible 8"
+  | Ast0.PLUS -> failwith "not possible 9"
+
+let copy_plus printer minusify model e =
+  if !Flag.sgrep_mode2
+  then e (* no plus code, can cause a "not possible" error, so just avoid it *)
+  else
+    let e =
+      match Ast0.get_mcodekind model with
+       Ast0.MINUS(mc) -> minusify e
+      | Ast0.CONTEXT(mc) -> e
+      | _ -> failwith "not possible: copy_plus\n" in
+    merge_plus (Ast0.get_mcodekind model) (Ast0.get_mcodekind e);
+    e
+
+let copy_minus printer minusify model e =
+  match Ast0.get_mcodekind model with
+    Ast0.MINUS(mc) -> minusify e
+  | Ast0.CONTEXT(mc) -> e
+  | Ast0.MIXED(_) ->
+      if !Flag.sgrep_mode2
+      then e
+      else failwith "not possible 8"
+  | Ast0.PLUS -> failwith "not possible 9"
+
+let whencode_allowed prev_ecount prev_icount prev_dcount
+    ecount icount dcount rest =
+  (* actually, if ecount or dcount is 0, the flag doesn't matter, because it
+     won't be tested *)
+  let other_ecount = (* number of edots *)
+    List.fold_left (function rest -> function (_,ec,ic,dc) -> ec + rest)
+      prev_ecount rest in
+  let other_icount = (* number of dots *)
+    List.fold_left (function rest -> function (_,ec,ic,dc) -> ic + rest)
+      prev_icount rest in
+  let other_dcount = (* number of dots *)
+    List.fold_left (function rest -> function (_,ec,ic,dc) -> dc + rest)
+      prev_dcount rest in
+  (ecount = 0 or other_ecount = 0, icount = 0 or other_icount = 0,
+   dcount = 0 or other_dcount = 0)
+
+(* copy the befores and afters to the instantiated code *)
+let extra_copy_stmt_plus model e =
+  (if not !Flag.sgrep_mode2 (* sgrep has no plus code, so nothing to do *)
+  then
+    (match Ast0.unwrap model with
+      Ast0.FunDecl((info,bef),_,_,_,_,_,_,_,_)
+    | Ast0.Decl((info,bef),_) ->
+       (match Ast0.unwrap e with
+         Ast0.FunDecl((info,bef1),_,_,_,_,_,_,_,_)
+       | Ast0.Decl((info,bef1),_) ->
+           merge_plus bef bef1
+       | _ ->  merge_plus bef (Ast0.get_mcodekind e))
+    | Ast0.IfThen(_,_,_,_,_,(info,aft))
+    | Ast0.IfThenElse(_,_,_,_,_,_,_,(info,aft))
+    | Ast0.While(_,_,_,_,_,(info,aft))
+    | Ast0.For(_,_,_,_,_,_,_,_,_,(info,aft))
+    | Ast0.Iterator(_,_,_,_,_,(info,aft)) ->
+       (match Ast0.unwrap e with
+         Ast0.IfThen(_,_,_,_,_,(info,aft1))
+       | Ast0.IfThenElse(_,_,_,_,_,_,_,(info,aft1))
+       | Ast0.While(_,_,_,_,_,(info,aft1))
+       | Ast0.For(_,_,_,_,_,_,_,_,_,(info,aft1))
+       | Ast0.Iterator(_,_,_,_,_,(info,aft1)) ->
+           merge_plus aft aft1
+       | _ -> merge_plus aft (Ast0.get_mcodekind e))
+    | _ -> ()));
+  e
+
+let extra_copy_other_plus model e = e
+
+(* --------------------------------------------------------------------- *)
+
+let mv_count = ref 0
+let new_mv (_,s) =
+  let ct = !mv_count in
+  mv_count := !mv_count + 1;
+  "_"^s^"_"^(string_of_int ct)
+
+let get_name = function
+    Ast.MetaIdDecl(ar,nm) ->
+      (nm,function nm -> Ast.MetaIdDecl(ar,nm))
+  | Ast.MetaFreshIdDecl(ar,nm) ->
+      (nm,function nm -> Ast.MetaFreshIdDecl(ar,nm))
+  | Ast.MetaTypeDecl(ar,nm) ->
+      (nm,function nm -> Ast.MetaTypeDecl(ar,nm))
+  | Ast.MetaListlenDecl(nm) ->
+      failwith "should not be rebuilt"
+  | Ast.MetaParamDecl(ar,nm) ->
+      (nm,function nm -> Ast.MetaParamDecl(ar,nm))
+  | Ast.MetaParamListDecl(ar,nm,nm1) ->
+      (nm,function nm -> Ast.MetaParamListDecl(ar,nm,nm1))
+  | Ast.MetaConstDecl(ar,nm,ty) ->
+      (nm,function nm -> Ast.MetaConstDecl(ar,nm,ty))
+  | Ast.MetaErrDecl(ar,nm) ->
+      (nm,function nm -> Ast.MetaErrDecl(ar,nm))
+  | Ast.MetaExpDecl(ar,nm,ty) ->
+      (nm,function nm -> Ast.MetaExpDecl(ar,nm,ty))
+  | Ast.MetaIdExpDecl(ar,nm,ty) ->
+      (nm,function nm -> Ast.MetaIdExpDecl(ar,nm,ty))
+  | Ast.MetaLocalIdExpDecl(ar,nm,ty) ->
+      (nm,function nm -> Ast.MetaLocalIdExpDecl(ar,nm,ty))
+  | Ast.MetaExpListDecl(ar,nm,nm1) ->
+      (nm,function nm -> Ast.MetaExpListDecl(ar,nm,nm1))
+  | Ast.MetaStmDecl(ar,nm) ->
+      (nm,function nm -> Ast.MetaStmDecl(ar,nm))
+  | Ast.MetaStmListDecl(ar,nm) ->
+      (nm,function nm -> Ast.MetaStmListDecl(ar,nm))
+  | Ast.MetaFuncDecl(ar,nm) ->
+      (nm,function nm -> Ast.MetaFuncDecl(ar,nm))
+  | Ast.MetaLocalFuncDecl(ar,nm) ->
+      (nm,function nm -> Ast.MetaLocalFuncDecl(ar,nm))
+  | Ast.MetaPosDecl(ar,nm) ->
+      (nm,function nm -> Ast.MetaPosDecl(ar,nm))
+  | Ast.MetaDeclarerDecl(ar,nm) ->
+      (nm,function nm -> Ast.MetaDeclarerDecl(ar,nm))
+  | Ast.MetaIteratorDecl(ar,nm) ->
+      (nm,function nm -> Ast.MetaIteratorDecl(ar,nm))
+
+let make_new_metavars metavars bindings =
+  let new_metavars =
+    List.filter
+      (function mv ->
+       let (s,_) = get_name mv in
+       try let _ = List.assoc s bindings in false with Not_found -> true)
+      metavars in
+  List.split
+    (List.map
+       (function mv ->
+        let (s,rebuild) = get_name mv in
+        let new_s = (!current_rule,new_mv s) in
+        (rebuild new_s, (s,new_s)))
+       new_metavars)
+
+(* --------------------------------------------------------------------- *)
+
+let do_nothing x = x
+
+let mkdisj matcher metavars alts e instantiater mkiso disj_maker minusify
+    rebuild_mcodes name printer extra_plus update_others =
+  let call_instantiate bindings mv_bindings alts =
+    List.concat
+      (List.map
+        (function (a,_,_,_) ->
+          nub
+          (* no need to create duplicates when the bindings have no effect *)
+            (List.map
+               (function bindings ->
+                 Ast0.set_iso
+                   (copy_plus printer minusify e
+                      (extra_plus e
+                         (instantiater bindings mv_bindings
+                            (rebuild_mcodes a))))
+                   (Common.union_set [(name,mkiso a)] (Ast0.get_iso e)))
+               bindings))
+        alts) in
+  let rec inner_loop all_alts prev_ecount prev_icount prev_dcount = function
+      [] -> Common.Left (prev_ecount, prev_icount, prev_dcount)
+    | ((pattern,ecount,icount,dcount)::rest) ->
+       let wc =
+         whencode_allowed prev_ecount prev_icount prev_dcount
+           ecount dcount icount rest in
+       (match matcher true (context_required e) wc pattern e init_env with
+         Fail(reason) ->
+           if reason = NonMatch || not !Flag_parsing_cocci.show_iso_failures
+           then ()
+           else
+             (match matcher false false wc pattern e init_env with
+               OK _ ->
+                 interpret_reason name (Ast0.get_line e) reason
+                   (function () -> printer e)
+             | _ -> ());
+           inner_loop all_alts (prev_ecount + ecount) (prev_icount + icount)
+             (prev_dcount + dcount) rest
+       | OK (bindings : (((string * string) * 'a) list list)) ->
+           let all_alts =
+             (* apply update_others to all patterns other than the matched
+                one.  This is used to desigate the others as test
+                expressions in the TestExpression case *)
+             (List.map
+                (function (x,e,i,d) as all ->
+                  if x = pattern
+                  then all
+                  else (update_others x,e,i,d))
+                (List.hd all_alts)) ::
+             (List.map
+                (List.map (function (x,e,i,d) -> (update_others x,e,i,d)))
+                (List.tl all_alts)) in
+           (match List.concat all_alts with
+             [x] -> Common.Left (prev_ecount, prev_icount, prev_dcount)
+           | all_alts ->
+               let (new_metavars,mv_bindings) =
+                 make_new_metavars metavars (nub(List.concat bindings)) in
+               Common.Right
+                 (new_metavars,
+                  call_instantiate bindings mv_bindings all_alts))) in
+  let rec outer_loop prev_ecount prev_icount prev_dcount = function
+      [] | [[_]] (*only one alternative*)  -> ([],e) (* nothing matched *)
+    | (alts::rest) as all_alts ->
+       match inner_loop all_alts prev_ecount prev_icount prev_dcount alts with
+         Common.Left(prev_ecount, prev_icount, prev_dcount) ->
+           outer_loop prev_ecount prev_icount prev_dcount rest
+       | Common.Right (new_metavars,res) ->
+           (new_metavars,
+            copy_minus printer minusify e (disj_maker res)) in
+  outer_loop 0 0 0 alts
+
+(* no one should ever look at the information stored in these mcodes *)
+let disj_starter lst =
+  let old_info = Ast0.get_info(List.hd lst) in
+  let info =
+    { old_info with
+      Ast0.line_end = old_info.Ast0.line_start;
+      Ast0.logical_end = old_info.Ast0.logical_start;
+      Ast0.attachable_start = false; Ast0.attachable_end = false;
+      Ast0.mcode_start = []; Ast0.mcode_end = [];
+      Ast0.strings_before = []; Ast0.strings_after = [] } in
+  Ast0.make_mcode_info "(" info
+
+let disj_ender lst =
+  let old_info = Ast0.get_info(List.hd lst) in
+  let info =
+    { old_info with
+      Ast0.line_start = old_info.Ast0.line_end;
+      Ast0.logical_start = old_info.Ast0.logical_end;
+      Ast0.attachable_start = false; Ast0.attachable_end = false;
+      Ast0.mcode_start = []; Ast0.mcode_end = [];
+      Ast0.strings_before = []; Ast0.strings_after = [] } in
+  Ast0.make_mcode_info ")" info
+
+let disj_mid _ = Ast0.make_mcode "|"
+
+let make_disj_type tl =
+  let mids =
+    match tl with
+      [] -> failwith "bad disjunction"
+    | x::xs -> List.map disj_mid xs in
+  Ast0.context_wrap (Ast0.DisjType(disj_starter tl,tl,mids,disj_ender tl))
+let make_disj_stmt_list tl =
+  let mids =
+    match tl with
+      [] -> failwith "bad disjunction"
+    | x::xs -> List.map disj_mid xs in
+  Ast0.context_wrap (Ast0.Disj(disj_starter tl,tl,mids,disj_ender tl))
+let make_disj_expr model el =
+  let mids =
+    match el with
+      [] -> failwith "bad disjunction"
+    | x::xs -> List.map disj_mid xs in
+  let update_arg x =
+    if Ast0.get_arg_exp model then Ast0.set_arg_exp x else x in
+  let update_test x =
+    let x = if Ast0.get_test_pos model then Ast0.set_test_pos x else x in
+    if Ast0.get_test_exp model then Ast0.set_test_exp x else x in
+  let el = List.map update_arg (List.map update_test el) in
+  Ast0.context_wrap (Ast0.DisjExpr(disj_starter el,el,mids,disj_ender el))
+let make_disj_decl dl =
+  let mids =
+    match dl with
+      [] -> failwith "bad disjunction"
+    | x::xs -> List.map disj_mid xs in
+  Ast0.context_wrap (Ast0.DisjDecl(disj_starter dl,dl,mids,disj_ender dl))
+let make_disj_stmt sl =
+  let dotify x = Ast0.context_wrap (Ast0.DOTS[x]) in
+  let mids =
+    match sl with
+      [] -> failwith "bad disjunction"
+    | x::xs -> List.map disj_mid xs in
+  Ast0.context_wrap
+    (Ast0.Disj(disj_starter sl,List.map dotify sl,mids,disj_ender sl))
+
+let transform_type (metavars,alts,name) e =
+  match alts with
+    (Ast0.TypeCTag(_)::_)::_ ->
+      (* start line is given to any leaves in the iso code *)
+      let start_line = Some ((Ast0.get_info e).Ast0.line_start) in
+      let alts =
+       List.map
+         (List.map
+            (function
+                Ast0.TypeCTag(p) ->
+                  (p,count_edots.V0.combiner_typeC p,
+                   count_idots.V0.combiner_typeC p,
+                   count_dots.V0.combiner_typeC p)
+              | _ -> failwith "invalid alt"))
+         alts in
+      mkdisj match_typeC metavars alts e
+       (function b -> function mv_b ->
+         (instantiate b mv_b).V0.rebuilder_typeC)
+       (function t -> Ast0.TypeCTag t)
+       make_disj_type make_minus.V0.rebuilder_typeC
+       (rebuild_mcode start_line).V0.rebuilder_typeC
+       name Unparse_ast0.typeC extra_copy_other_plus do_nothing
+  | _ -> ([],e)
+
+
+let transform_expr (metavars,alts,name) e =
+  let process update_others =
+      (* start line is given to any leaves in the iso code *)
+    let start_line = Some ((Ast0.get_info e).Ast0.line_start) in
+    let alts =
+      List.map
+       (List.map
+          (function
+              Ast0.ExprTag(p) | Ast0.ArgExprTag(p) | Ast0.TestExprTag(p) ->
+                (p,count_edots.V0.combiner_expression p,
+                 count_idots.V0.combiner_expression p,
+                 count_dots.V0.combiner_expression p)
+            | _ -> failwith "invalid alt"))
+       alts in
+    mkdisj match_expr metavars alts e
+      (function b -> function mv_b ->
+       (instantiate b mv_b).V0.rebuilder_expression)
+      (function e -> Ast0.ExprTag e)
+      (make_disj_expr e) make_minus.V0.rebuilder_expression
+      (rebuild_mcode start_line).V0.rebuilder_expression
+      name Unparse_ast0.expression extra_copy_other_plus update_others in
+  match alts with
+    (Ast0.ExprTag(_)::_)::_ -> process do_nothing
+  | (Ast0.ArgExprTag(_)::_)::_ when Ast0.get_arg_exp e -> process do_nothing
+  | (Ast0.TestExprTag(_)::_)::_ when Ast0.get_test_pos e ->
+      process Ast0.set_test_exp
+  | _ -> ([],e)
+
+let transform_decl (metavars,alts,name) e =
+  match alts with
+    (Ast0.DeclTag(_)::_)::_ ->
+      (* start line is given to any leaves in the iso code *)
+      let start_line = Some (Ast0.get_info e).Ast0.line_start in
+      let alts =
+       List.map
+         (List.map
+            (function
+                Ast0.DeclTag(p) ->
+                  (p,count_edots.V0.combiner_declaration p,
+                   count_idots.V0.combiner_declaration p,
+                   count_dots.V0.combiner_declaration p)
+              | _ -> failwith "invalid alt"))
+         alts in
+      mkdisj match_decl metavars alts e
+       (function b -> function mv_b ->
+         (instantiate b mv_b).V0.rebuilder_declaration)
+       (function d -> Ast0.DeclTag d)
+       make_disj_decl
+       make_minus.V0.rebuilder_declaration
+       (rebuild_mcode start_line).V0.rebuilder_declaration
+       name Unparse_ast0.declaration extra_copy_other_plus do_nothing
+  | _ -> ([],e)
+
+let transform_stmt (metavars,alts,name) e =
+  match alts with
+    (Ast0.StmtTag(_)::_)::_ ->
+      (* start line is given to any leaves in the iso code *)
+      let start_line = Some (Ast0.get_info e).Ast0.line_start in
+      let alts =
+       List.map
+         (List.map
+            (function
+                Ast0.StmtTag(p) ->
+                  (p,count_edots.V0.combiner_statement p,
+                   count_idots.V0.combiner_statement p,
+                   count_dots.V0.combiner_statement p)
+              | _ -> failwith "invalid alt"))
+         alts in
+      mkdisj match_statement metavars alts e
+       (function b -> function mv_b ->
+         (instantiate b mv_b).V0.rebuilder_statement)
+       (function s -> Ast0.StmtTag s)
+       make_disj_stmt make_minus.V0.rebuilder_statement
+       (rebuild_mcode start_line).V0.rebuilder_statement
+       name (Unparse_ast0.statement "") extra_copy_stmt_plus do_nothing
+  | _ -> ([],e)
+
+(* sort of a hack, because there is no disj at top level *)
+let transform_top (metavars,alts,name) e =
+  match Ast0.unwrap e with
+    Ast0.DECL(declstm) ->
+      (try
+       let strip alts =
+         List.map
+           (List.map
+              (function
+                  Ast0.DotsStmtTag(d) ->
+                    (match Ast0.unwrap d with
+                      Ast0.DOTS([s]) -> Ast0.StmtTag(s)
+                    | _ -> raise (Failure ""))
+                | _ -> raise (Failure "")))
+           alts in
+       let (mv,s) = transform_stmt (metavars,strip alts,name) declstm in
+       (mv,Ast0.rewrap e (Ast0.DECL(s)))
+      with Failure _ -> ([],e))
+  | Ast0.CODE(stmts) ->
+      let (mv,res) =
+       match alts with
+         (Ast0.DotsStmtTag(_)::_)::_ ->
+              (* start line is given to any leaves in the iso code *)
+           let start_line = Some ((Ast0.get_info e).Ast0.line_start) in
+           let alts =
+             List.map
+               (List.map
+                  (function
+                      Ast0.DotsStmtTag(p) ->
+                        (p,count_edots.V0.combiner_statement_dots p,
+                         count_idots.V0.combiner_statement_dots p,
+                         count_dots.V0.combiner_statement_dots p)
+                    | _ -> failwith "invalid alt"))
+               alts in
+           mkdisj match_statement_dots metavars alts stmts
+             (function b -> function mv_b ->
+               (instantiate b mv_b).V0.rebuilder_statement_dots)
+             (function s -> Ast0.DotsStmtTag s)
+             (function x ->
+               Ast0.rewrap e (Ast0.DOTS([make_disj_stmt_list x])))
+             make_minus.V0.rebuilder_statement_dots
+             (rebuild_mcode start_line).V0.rebuilder_statement_dots
+             name Unparse_ast0.statement_dots extra_copy_other_plus do_nothing
+       | _ -> ([],stmts) in
+      (mv,Ast0.rewrap e (Ast0.CODE res))
+  | _ -> ([],e)
+
+(* --------------------------------------------------------------------- *)
+
+let transform (alts : isomorphism) t =
+  (* the following ugliness is because rebuilder only returns a new term *)
+  let extra_meta_decls = ref ([] : Ast_cocci.metavar list) in
+  let mcode x = x in
+  let donothing r k e = k e in
+  let exprfn r k e =
+    let (extra_meta,exp) = transform_expr alts (k e) in
+    extra_meta_decls := extra_meta @ !extra_meta_decls;
+    exp in
+
+  let declfn r k e =
+    let (extra_meta,dec) = transform_decl alts (k e) in
+    extra_meta_decls := extra_meta @ !extra_meta_decls;
+    dec in
+
+  let stmtfn r k e =
+    let (extra_meta,stm) = transform_stmt alts (k e) in
+    extra_meta_decls := extra_meta @ !extra_meta_decls;
+    stm in
+  
+  let typefn r k e =
+    let (extra_meta,ty) = transform_type alts (k e) in
+    extra_meta_decls := extra_meta @ !extra_meta_decls;
+    ty in
+  
+  let topfn r k e =
+    let (extra_meta,ty) = transform_top alts (k e) in
+    extra_meta_decls := extra_meta @ !extra_meta_decls;
+    ty in
+  
+  let res =
+    V0.rebuilder
+      mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+      mcode
+      donothing donothing donothing donothing donothing donothing
+      donothing exprfn typefn donothing donothing declfn stmtfn
+      donothing topfn in
+  let res = res.V0.rebuilder_top_level t in
+  (!extra_meta_decls,res)
+
+(* --------------------------------------------------------------------- *)
+
+(* should be done by functorizing the parser to use wrap or context_wrap *)
+let rewrap =
+  let mcode (x,a,i,mc,pos) = (x,a,i,Ast0.context_befaft(),pos) in
+  let donothing r k e = Ast0.context_wrap(Ast0.unwrap(k e)) in
+  V0.rebuilder
+    mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+    mcode
+    donothing donothing donothing donothing donothing donothing
+    donothing donothing donothing donothing donothing donothing donothing
+    donothing donothing
+
+let rewrap_anything = function
+    Ast0.DotsExprTag(d) ->
+      Ast0.DotsExprTag(rewrap.V0.rebuilder_expression_dots d)
+  | Ast0.DotsInitTag(d) ->
+      Ast0.DotsInitTag(rewrap.V0.rebuilder_initialiser_list d)
+  | Ast0.DotsParamTag(d) ->
+      Ast0.DotsParamTag(rewrap.V0.rebuilder_parameter_list d)
+  | Ast0.DotsStmtTag(d) ->
+      Ast0.DotsStmtTag(rewrap.V0.rebuilder_statement_dots d)
+  | Ast0.DotsDeclTag(d) ->
+      Ast0.DotsDeclTag(rewrap.V0.rebuilder_declaration_dots d)
+  | Ast0.DotsCaseTag(d) ->
+      Ast0.DotsCaseTag(rewrap.V0.rebuilder_case_line_dots d)
+  | Ast0.IdentTag(d) -> Ast0.IdentTag(rewrap.V0.rebuilder_ident d)
+  | Ast0.ExprTag(d) -> Ast0.ExprTag(rewrap.V0.rebuilder_expression d)
+  | Ast0.ArgExprTag(d) -> Ast0.ArgExprTag(rewrap.V0.rebuilder_expression d)
+  | Ast0.TestExprTag(d) -> Ast0.TestExprTag(rewrap.V0.rebuilder_expression d)
+  | Ast0.TypeCTag(d) -> Ast0.TypeCTag(rewrap.V0.rebuilder_typeC d)
+  | Ast0.InitTag(d) -> Ast0.InitTag(rewrap.V0.rebuilder_initialiser d)
+  | Ast0.ParamTag(d) -> Ast0.ParamTag(rewrap.V0.rebuilder_parameter d)
+  | Ast0.DeclTag(d) -> Ast0.DeclTag(rewrap.V0.rebuilder_declaration d)
+  | Ast0.StmtTag(d) -> Ast0.StmtTag(rewrap.V0.rebuilder_statement d)
+  | Ast0.CaseLineTag(d) -> Ast0.CaseLineTag(rewrap.V0.rebuilder_case_line d)
+  | Ast0.TopTag(d) -> Ast0.TopTag(rewrap.V0.rebuilder_top_level d)
+  | Ast0.IsoWhenTag(_) | Ast0.IsoWhenTTag(_) | Ast0.IsoWhenFTag(_) ->
+      failwith "only for isos within iso phase"
+  | Ast0.MetaPosTag(p) -> Ast0.MetaPosTag(p)
+
+(* --------------------------------------------------------------------- *)
+
+let apply_isos isos rule rule_name =
+  if isos = []
+  then ([],rule)
+  else
+    begin
+      current_rule := rule_name;
+      let isos =
+       List.map
+         (function (metavars,iso,name) ->
+           (metavars,List.map (List.map rewrap_anything) iso,name))
+         isos in
+      let (extra_meta,rule) =
+       List.split
+         (List.map
+            (function t ->
+              List.fold_left
+                (function (extra_meta,t) -> function iso ->
+                  let (new_extra_meta,t) = transform iso t in
+                  (new_extra_meta@extra_meta,t))
+                ([],t) isos)
+            rule) in
+      (List.concat extra_meta, Compute_lines.compute_lines rule)
+    end
diff --git a/parsing_cocci/.#parser_cocci_menhir.mly.1.156 b/parsing_cocci/.#parser_cocci_menhir.mly.1.156
new file mode 100644 (file)
index 0000000..1e71638
--- /dev/null
@@ -0,0 +1,1769 @@
+/*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+* 
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+* 
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
+* 
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*/
+
+
+%{
+
+(* Not clear how to allow function declarations to specify a return type
+and how to allow both to be specified as static, because they are in
+different rules.  The rules seem to have to be combined, which would allow
+functions to be declared as local variables *)
+
+(* Not clear how to let a function have a parameter of type void.  At the
+moment, void is allowed to be the type of a variable, which is wrong, and a
+parameter needs both a type and an identifier *)
+module Ast0 = Ast0_cocci
+module Ast = Ast_cocci
+module P = Parse_aux
+%}
+
+%token EOF
+
+%token TIdentifier TExpression TStatement TFunction TLocal TType TParameter
+%token TIdExpression
+%token Tlist TFresh TConstant TError TWords TWhy0 TPlus0 TBang0
+%token TPure TContext
+%token TTypedef TDeclarer TIterator TName TPosition TPosAny
+%token TUsing TDisable TExtends TDepends TOn TEver TNever TExists TForall TScript
+%token TReverse TNothing
+%token<string> TRuleName
+
+%token<Data.clt> Tchar Tshort Tint Tdouble Tfloat Tlong
+%token<Data.clt> Tvoid Tstruct Tunion
+%token<Data.clt> Tunsigned Tsigned
+
+%token<Data.clt> Tstatic Tauto Tregister Textern Tinline Ttypedef
+%token<Data.clt> Tconst Tvolatile
+%token<string * Data.clt> Tattr
+
+%token <Data.clt> TIf TElse TWhile TFor TDo TSwitch TCase TDefault TReturn
+%token <Data.clt> TBreak TContinue TGoto TSizeof TFunDecl
+%token <string * Data.clt> TIdent TTypeId TDeclarerId TIteratorId
+
+%token <Parse_aux.idinfo>     TMetaId TMetaFunc TMetaLocalFunc
+%token <Parse_aux.idinfo>     TMetaIterator TMetaDeclarer
+%token <Parse_aux.expinfo>    TMetaErr 
+%token <Parse_aux.info>       TMetaParam TMetaStm TMetaStmList TMetaType
+%token <Parse_aux.list_info>  TMetaParamList TMetaExpList
+%token <Parse_aux.typed_info> TMetaExp TMetaIdExp TMetaLocalIdExp TMetaConst
+%token <Parse_aux.pos_info>   TMetaPos
+
+%token TArob TArobArob TPArob
+%token <string> TScriptData
+
+%token <Data.clt> TEllipsis TOEllipsis TCEllipsis TPOEllipsis TPCEllipsis
+%token <Data.clt> TWhen TWhenTrue TWhenFalse TAny TStrict TLineEnd
+
+%token <Data.clt> TWhy TDotDot TBang TOPar TOPar0
+%token <Data.clt> TMid0 TCPar TCPar0
+
+%token <string>  TPragma TPathIsoFile
+%token <string * Data.clt> TIncludeL TIncludeNL
+%token <Data.clt * token> TDefine
+%token <Data.clt * token * int> TDefineParam
+%token <string * Data.clt> TMinusFile TPlusFile
+
+%token <Data.clt> TInc TDec
+
+%token <string * Data.clt> TString TChar TFloat TInt
+
+%token <Data.clt> TOrLog
+%token <Data.clt> TAndLog
+%token <Data.clt> TOr
+%token <Data.clt> TXor
+%token <Data.clt> TAnd 
+%token <Data.clt> TEqEq TNotEq
+%token <Ast_cocci.logicalOp * Data.clt> TLogOp /* TInf TSup TInfEq TSupEq */
+%token <Ast_cocci.arithOp * Data.clt>   TShOp  /* TShl TShr */
+%token <Ast_cocci.arithOp * Data.clt>   TDmOp  /* TDiv TMod */
+%token <Data.clt> TPlus TMinus
+%token <Data.clt> TMul TTilde
+
+%token <Data.clt> TOBrace TCBrace TOInit
+%token <Data.clt> TOCro TCCro
+
+%token <Data.clt> TPtrOp
+
+%token TMPtVirg
+%token <Data.clt> TEq TDot TComma TPtVirg
+%token <Ast_cocci.assignOp * Data.clt> TAssign
+
+%token TIso TRightIso TIsoExpression TIsoStatement TIsoDeclaration TIsoType
+%token TIsoTopLevel TIsoArgExpression TIsoTestExpression
+
+%token TInvalid
+
+/* operator precedence */
+%nonassoc TIf
+%nonassoc TElse
+
+%left TOrLog
+%left TAndLog
+%left TOr
+%left TXor
+%left TAnd 
+%left TEqEq TNotEq
+%left TLogOp /* TInf TSup TInfEq TSupEq */
+%left TShOp /* TShl TShr */
+%left TPlus TMinus
+%left TMul TDmOp /* TDiv TMod */
+
+%start reinit
+%type <unit> reinit
+
+%start minus_main
+%type <Ast0_cocci.rule> minus_main
+
+%start minus_exp_main
+%type <Ast0_cocci.rule> minus_exp_main
+
+%start plus_main
+%type <Ast0_cocci.rule> plus_main
+
+%start plus_exp_main
+%type <Ast0_cocci.rule> plus_exp_main
+
+%start include_main
+%type <(string,string) Common.either list> include_main
+
+%start iso_rule_name
+%type <Ast_cocci.rulename>
+iso_rule_name
+
+%start rule_name
+%type <Ast_cocci.rulename>
+rule_name
+
+%start meta_main
+%type <(Ast_cocci.metavar,Ast_cocci.metavar) Common.either list> meta_main
+
+%start <string * (string * string)> script_meta_main
+
+%start iso_main
+%type <Ast0_cocci.anything list list> iso_main
+
+%start iso_meta_main
+%type <(Ast_cocci.metavar,Ast_cocci.metavar) Common.either list> iso_meta_main
+
+%start never_used
+%type <unit> never_used
+
+%%
+
+reinit: { }
+minus_main: minus_body EOF { $1 } | m=minus_body TArobArob { m }
+| m=minus_body TArob { m }
+plus_main: plus_body EOF { $1 } | p=plus_body TArobArob { p }
+| p=plus_body TArob { p }
+minus_exp_main: minus_exp_body EOF { $1 } | m=minus_exp_body TArobArob { m }
+| m=minus_exp_body TArob { m }
+plus_exp_main: plus_exp_body EOF { $1 } | p=plus_exp_body TArobArob { p }
+| p=plus_exp_body TArob { p }
+meta_main: m=metadec   { m (!Ast0.rule_name) }
+iso_meta_main: m=metadec { m "" }
+
+/*****************************************************************************
+*
+*
+*****************************************************************************/
+
+pure:
+  TPure          { Ast0.Pure }
+| TContext       { Ast0.Context }
+| TPure TContext { Ast0.PureContext }
+| TContext TPure { Ast0.PureContext }
+| /* empty */    { Ast0.Impure }
+
+iso_rule_name:
+  nm=pure_ident TArob { P.make_iso_rule_name_result (P.id2name nm) }
+
+rule_name:
+  nm=ioption(pure_ident) extends d=depends i=loption(choose_iso)
+    a=loption(disable) e=exists ee=is_expression TArob
+      { P.make_cocci_rule_name_result nm d i a e ee }
+  | TScript TDotDot lang=pure_ident d=depends TArob
+      { P.make_script_rule_name_result lang d }
+
+extends:
+  /* empty */                                     { () }
+| TExtends parent=TRuleName
+    { !Data.install_bindings (parent) }
+
+depends:
+  /* empty */              { Ast.NoDep }
+| TDepends TOn parents=dep { parents }
+
+dep:
+  pnrule           { $1 }
+| dep TAndLog dep  { Ast.AndDep($1, $3) }
+| dep TOrLog  dep  { Ast.OrDep ($1, $3) }
+
+pnrule:
+  TRuleName        { Ast.Dep      $1 }
+| TBang TRuleName  { Ast.AntiDep  $2 }
+| TEver TRuleName  { Ast.EverDep  $2 }
+| TNever TRuleName { Ast.NeverDep $2 }
+| TOPar dep TCPar  { $2 }
+
+choose_iso:
+  TUsing separated_nonempty_list(TComma,TString) { List.map P.id2name $2 }
+
+disable:
+  TDisable separated_nonempty_list(TComma,pure_ident) { List.map P.id2name $2 }
+
+exists:
+  TExists { Ast.Exists }
+| TForall { Ast.Forall }
+| TReverse TForall { Ast.ReverseForall }
+|         { Ast.Undetermined }
+
+is_expression: // for more flexible parsing of top level expressions
+              { false }
+| TExpression { true }
+
+include_main:
+  list(incl) TArob     { $1 }
+| list(incl) TArobArob { $1 }
+
+incl:
+  TUsing TString      { Common.Left(P.id2name $2) }
+| TUsing TPathIsoFile { Common.Right $2 }
+
+metadec:
+  ar=arity ispure=pure
+  kindfn=metakind ids=comma_list(pure_ident_or_meta_ident) TMPtVirg
+    { P.create_metadec ar ispure kindfn ids }
+| ar=arity ispure=pure
+  kindfn=metakind_atomic
+  ids=comma_list(pure_ident_or_meta_ident_with_not_eq(not_eq)) TMPtVirg
+    { P.create_metadec_ne ar ispure kindfn ids }
+| ar=arity ispure=pure
+  kindfn=metakind_atomic_expi
+  ids=comma_list(pure_ident_or_meta_ident_with_not_eq(not_eqe)) TMPtVirg
+    { P.create_metadec_ne ar ispure kindfn ids }
+| ar=arity ispure=pure
+  kindfn=metakind_atomic_expe
+  ids=comma_list(pure_ident_or_meta_ident_with_not_eq(not_ceq)) TMPtVirg
+    { P.create_metadec_ne ar ispure kindfn ids }
+| ar=arity TPosition a=option(TPosAny)
+    ids=comma_list(pure_ident_or_meta_ident_with_not_eq(not_pos)) TMPtVirg
+    { let kindfn arity name pure check_meta constraints =
+      let tok = check_meta(Ast.MetaPosDecl(arity,name)) in
+      let any = match a with None -> Ast.PER | Some _ -> Ast.ALL in
+      !Data.add_pos_meta name constraints any; tok in
+    P.create_metadec_ne ar false kindfn ids }
+| ar=arity ispure=pure
+    TParameter Tlist TOCro id=pure_ident_or_meta_ident TCCro
+    ids=comma_list(pure_ident_or_meta_ident) TMPtVirg
+    { P.create_len_metadec ar ispure
+       (fun lenname arity name pure check_meta ->
+         let tok =
+           check_meta(Ast.MetaParamListDecl(arity,name,Some lenname)) in
+         !Data.add_paramlist_meta name (Some lenname) pure; tok)
+       id ids }
+| ar=arity ispure=pure
+    TExpression Tlist TOCro id=pure_ident_or_meta_ident TCCro
+    ids=comma_list(pure_ident_or_meta_ident) TMPtVirg
+    { P.create_len_metadec ar ispure
+       (fun lenname arity name pure check_meta ->
+         let tok =
+           check_meta(Ast.MetaExpListDecl(arity,name,Some lenname)) in
+         !Data.add_explist_meta name (Some lenname) pure; tok)
+       id ids }
+
+%inline metakind:
+  TFresh TIdentifier
+    { (fun arity name pure check_meta ->
+      let tok = check_meta(Ast.MetaFreshIdDecl(arity,name)) in
+      !Data.add_id_meta name [] pure; tok) }
+| TParameter
+    { (fun arity name pure check_meta ->
+      let tok = check_meta(Ast.MetaParamDecl(arity,name)) in
+      !Data.add_param_meta name pure; tok) }
+| TParameter Tlist
+    { (fun arity name pure check_meta ->
+      let tok = check_meta(Ast.MetaParamListDecl(arity,name,None)) in
+      !Data.add_paramlist_meta name None pure; tok) }
+| TExpression Tlist
+    { (fun arity name pure check_meta ->
+      let tok = check_meta(Ast.MetaExpListDecl(arity,name,None)) in
+      !Data.add_explist_meta name None pure; tok) }
+| TType
+    { (fun arity name pure check_meta ->
+      let tok = check_meta(Ast.MetaTypeDecl(arity,name)) in
+      !Data.add_type_meta name pure; tok) } 
+| TStatement
+    { (fun arity name pure check_meta ->
+      let tok = check_meta(Ast.MetaStmDecl(arity,name)) in
+      !Data.add_stm_meta name pure; tok) }
+| TStatement Tlist
+    { (fun arity name pure check_meta ->
+      let tok = check_meta(Ast.MetaStmListDecl(arity,name)) in
+      !Data.add_stmlist_meta name pure; tok) }
+| TTypedef
+    { (fun arity (_,name) pure check_meta ->
+      if arity = Ast.NONE && pure = Ast0.Impure
+      then (!Data.add_type_name name; [])
+      else raise (Semantic_cocci.Semantic "bad typedef")) }
+| TDeclarer TName
+    { (fun arity (_,name) pure check_meta ->
+      if arity = Ast.NONE && pure = Ast0.Impure
+      then (!Data.add_declarer_name name; [])
+      else raise (Semantic_cocci.Semantic "bad declarer")) }
+| TIterator TName
+    { (fun arity (_,name) pure check_meta ->
+      if arity = Ast.NONE && pure = Ast0.Impure
+      then (!Data.add_iterator_name name; [])
+      else raise (Semantic_cocci.Semantic "bad iterator")) }
+
+
+%inline metakind_atomic:
+  TIdentifier
+    { (fun arity name pure check_meta constraints ->
+      let tok = check_meta(Ast.MetaIdDecl(arity,name)) in
+      !Data.add_id_meta name constraints pure; tok) }
+| TFunction
+    { (fun arity name pure check_meta constraints ->
+      let tok = check_meta(Ast.MetaFuncDecl(arity,name)) in
+      !Data.add_func_meta name constraints pure; tok) }
+| TLocal TFunction
+    { (fun arity name pure check_meta constraints ->
+      let tok = check_meta(Ast.MetaLocalFuncDecl(arity,name)) in
+      !Data.add_local_func_meta name constraints pure;
+      tok) }
+| TDeclarer
+    { (fun arity name pure check_meta constraints ->
+      let tok = check_meta(Ast.MetaDeclarerDecl(arity,name)) in
+      !Data.add_declarer_meta name constraints pure; tok) }
+| TIterator
+    { (fun arity name pure check_meta constraints ->
+      let tok = check_meta(Ast.MetaIteratorDecl(arity,name)) in
+      !Data.add_iterator_meta name constraints pure; tok) }
+
+%inline metakind_atomic_expi:
+  TError
+    { (fun arity name pure check_meta constraints ->
+      let tok = check_meta(Ast.MetaErrDecl(arity,name)) in
+      !Data.add_err_meta name constraints pure; tok) }
+| l=option(TLocal) TIdExpression ty=ioption(meta_exp_type)
+    { (fun arity name pure check_meta constraints ->
+      match l with
+       None ->
+         !Data.add_idexp_meta ty name constraints pure;
+         check_meta(Ast.MetaIdExpDecl(arity,name,ty))
+      | Some _ ->
+         !Data.add_local_idexp_meta ty name constraints pure;
+         check_meta(Ast.MetaLocalIdExpDecl(arity,name,ty))) }
+| l=option(TLocal) TIdExpression m=nonempty_list(TMul)
+    { (fun arity name pure check_meta constraints ->
+      let ty = Some [P.ty_pointerify Type_cocci.Unknown m] in
+      match l with
+       None ->
+         !Data.add_idexp_meta ty name constraints pure;
+         check_meta(Ast.MetaIdExpDecl(arity,name,ty))
+      | Some _ ->
+         !Data.add_local_idexp_meta ty name constraints pure;
+         check_meta(Ast.MetaLocalIdExpDecl(arity,name,ty))) }
+| TExpression m=nonempty_list(TMul)
+    { (fun arity name pure check_meta constraints ->
+      let ty = Some [P.ty_pointerify Type_cocci.Unknown m] in
+      let tok = check_meta(Ast.MetaExpDecl(arity,name,ty)) in
+      !Data.add_exp_meta ty name constraints pure; tok) }
+| vl=meta_exp_type TOCro TCCro
+    { (fun arity name pure check_meta constraints ->
+      let ty = Some (List.map (function x -> Type_cocci.Array x) vl) in
+      let tok = check_meta(Ast.MetaExpDecl(arity,name,ty)) in
+      !Data.add_exp_meta ty name constraints pure; tok) }
+| TConstant ty=ioption(meta_exp_type)
+    { (fun arity name pure check_meta constraints ->
+      let tok = check_meta(Ast.MetaConstDecl(arity,name,ty)) in
+      !Data.add_const_meta ty name constraints pure; tok) }
+
+%inline metakind_atomic_expe:
+  TExpression
+    { (fun arity name pure check_meta constraints ->
+      let tok = check_meta(Ast.MetaExpDecl(arity,name,None)) in
+      !Data.add_exp_meta None name constraints pure; tok) }
+| vl=meta_exp_type // no error if use $1 but doesn't type check
+    { (fun arity name pure check_meta constraints ->
+      let ty = Some vl in
+      List.iter
+       (function c ->
+         match Ast0.unwrap c with
+           Ast0.Constant(_) ->
+             if not
+                 (List.exists
+                    (function
+                        Type_cocci.BaseType(Type_cocci.IntType,_) -> true
+                      | Type_cocci.BaseType(Type_cocci.ShortType,_) -> true
+                      | Type_cocci.BaseType(Type_cocci.LongType,_) -> true
+                      | _ -> false)
+                    vl)
+             then failwith "metavariable with int constraint must be an int"
+         | _ -> ())
+       constraints;
+      let tok = check_meta(Ast.MetaExpDecl(arity,name,ty)) in
+      !Data.add_exp_meta ty name constraints pure; tok) }
+
+
+meta_exp_type:
+  t=ctype
+    { [Ast0_cocci.ast0_type_to_type t] }
+| TOBrace t=comma_list(ctype) TCBrace m=list(TMul)
+    { List.map
+       (function x -> P.ty_pointerify (Ast0_cocci.ast0_type_to_type x) m)
+       t }
+
+arity: TBang0 { Ast.UNIQUE }
+     | TWhy0  { Ast.OPT }
+     | TPlus0 { Ast.MULTI }
+     | /* empty */ { Ast.NONE }
+
+generic_ctype:
+       q=ctype_qualif
+         { Ast0.wrap(Ast0.ImplicitInt(q)) }
+     | q=ioption(ctype_qualif) ty=Tchar
+         { Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.CharType ty, q)) }
+     | q=ioption(ctype_qualif) ty=Tshort
+         { Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.ShortType ty, q)) }
+     | q=ioption(ctype_qualif) ty=Tint
+         { Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.IntType ty, q)) }
+     | t=Tdouble
+         { Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.DoubleType t, None)) }
+     | t=Tfloat
+         { Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.FloatType t, None)) }
+     | q=ioption(ctype_qualif) ty=Tlong
+         { Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.LongType ty, q)) }
+     | s=struct_or_union i=ident
+        { Ast0.wrap(Ast0.StructUnionName(s, Some i)) }
+     | s=struct_or_union i=ioption(ident)
+       l=TOBrace d=struct_decl_list r=TCBrace
+        { (if i = None && !Data.in_iso
+          then failwith "structures must be named in the iso file");
+           Ast0.wrap(Ast0.StructUnionDef(Ast0.wrap(Ast0.StructUnionName(s, i)),
+                                        P.clt2mcode "{" l,
+                                        d, P.clt2mcode "}" r)) }
+     | s=TMetaType l=TOBrace d=struct_decl_list r=TCBrace
+        { let (nm,pure,clt) = s in
+        let ty =
+          Ast0.wrap(Ast0.MetaType(P.clt2mcode nm clt,pure)) in
+        Ast0.wrap
+          (Ast0.StructUnionDef(ty,P.clt2mcode "{" l,d,P.clt2mcode "}" r)) }
+     | r=TRuleName TDot p=TIdent
+        { let nm = (r,P.id2name p) in
+        (* this is only possible when we are in a metavar decl.  Otherwise,
+           it will be represented already as a MetaType *)
+        let _ = P.check_meta(Ast.MetaTypeDecl(Ast.NONE,nm)) in
+        Ast0.wrap(Ast0.MetaType(P.clt2mcode nm (P.id2clt p),
+                                Ast0.Impure (*will be ignored*))) }
+     | p=TTypeId
+        { Ast0.wrap(Ast0.TypeName(P.id2mcode p)) }
+     | p=TMetaType
+        { let (nm,pure,clt) = p in
+        Ast0.wrap(Ast0.MetaType(P.clt2mcode nm clt,pure)) }
+
+struct_or_union:
+       s=Tstruct { P.clt2mcode Ast.Struct s }
+     | u=Tunion  { P.clt2mcode Ast.Union u }
+
+struct_decl:
+      TNothing { [] }
+    | t=ctype d=d_ident pv=TPtVirg
+        { let (id,fn) = d in
+        [Ast0.wrap(Ast0.UnInit(None,fn t,id,P.clt2mcode ";" pv))] }
+    | t=fn_ctype lp1=TOPar st=TMul d=d_ident rp1=TCPar
+       lp2=TOPar p=decl_list(name_opt_decl) rp2=TCPar pv=TPtVirg
+        { let (id,fn) = d in
+        let t =
+         Ast0.wrap
+           (Ast0.FunctionPointer
+              (t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
+               P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
+        [Ast0.wrap(Ast0.UnInit(None,fn t,id,P.clt2mcode ";" pv))] }
+     | cv=ioption(const_vol) i=pure_ident d=d_ident pv=TPtVirg
+        { let (id,fn) = d in
+        let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
+        [Ast0.wrap(Ast0.UnInit(None,fn idtype,id,P.clt2mcode ";" pv))] }
+
+struct_decl_list:
+   struct_decl_list_start { Ast0.wrap(Ast0.DOTS($1)) }
+
+struct_decl_list_start:
+  struct_decl                        { $1 }
+| struct_decl struct_decl_list_start { $1@$2 }
+| d=edots_when(TEllipsis,struct_decl) r=continue_struct_decl_list
+    { (P.mkddots "..." d)::r }
+
+continue_struct_decl_list:
+  /* empty */                        { [] }
+| struct_decl struct_decl_list_start { $1@$2 }
+| struct_decl                        { $1 }
+
+ctype:
+       cv=ioption(const_vol) ty=generic_ctype m=list(TMul)
+        { P.pointerify (P.make_cv cv ty) m }
+     | cv=ioption(const_vol) t=Tvoid m=nonempty_list(TMul)
+         { let ty =
+            Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.VoidType t, None)) in
+          P.pointerify (P.make_cv cv ty) m }
+   | lp=TOPar0 t=midzero_list(ctype,ctype) rp=TCPar0
+      /* more hacks */
+    { let (mids,code) = t in
+      Ast0.wrap
+       (Ast0.DisjType(P.clt2mcode "(" lp,code,mids, P.clt2mcode ")" rp)) }
+
+
+fn_ctype: // allows metavariables
+       ty=generic_ctype m=list(TMul) { P.pointerify ty m }
+     | t=Tvoid m=list(TMul)
+         { P.pointerify
+            (Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.VoidType t, None)))
+            m }
+
+ctype_qualif:
+       Tunsigned   { P.clt2mcode Ast.Unsigned $1 }
+     | Tsigned     { P.clt2mcode Ast.Signed $1 }
+
+/*****************************************************************************/
+
+/* have to inline everything to avoid conflicts? switch to proper
+declarations, statements, and expressions for the subterms */
+
+minus_body: 
+    f=loption(filespec)
+    b=loption(minus_start)
+    ew=loption(error_words)
+    { match f@b@ew with
+      [] -> raise (Semantic_cocci.Semantic "minus slice can't be empty")
+    | code -> Top_level.top_level code }
+
+plus_body: 
+    f=loption(filespec)
+    b=loption(plus_start)
+    ew=loption(error_words)
+    { Top_level.top_level (f@b@ew) }
+
+minus_exp_body:
+    f=loption(filespec)
+    b=top_eexpr
+    ew=loption(error_words)
+    { match f@[b]@ew with
+      [] -> raise (Semantic_cocci.Semantic "minus slice can't be empty")
+    | code -> Top_level.top_level code }
+
+plus_exp_body:
+    f=loption(filespec)
+    b=top_eexpr
+    ew=loption(error_words)
+    { Top_level.top_level (f@[b]@ew) }
+
+filespec:
+  TMinusFile TPlusFile
+    { [Ast0.wrap
+         (Ast0.FILEINFO(P.id2mcode $1,
+                        P.id2mcode $2))] }
+
+includes:
+  TIncludeL
+    { Ast0.wrap
+             (Ast0.Include(P.clt2mcode "#include" (P.drop_aft (P.id2clt $1)),
+                           let (arity,ln,lln,offset,col,strbef,straft,pos) =
+                             P.id2clt $1 in
+                           let clt =
+                             (arity,ln,lln,offset,0,strbef,straft,pos) in
+                           P.clt2mcode
+                             (Ast.Local (Parse_aux.str2inc (P.id2name $1)))
+                             (P.drop_bef clt))) }
+| TIncludeNL
+    { Ast0.wrap
+             (Ast0.Include(P.clt2mcode "#include" (P.drop_aft (P.id2clt $1)),
+                           let (arity,ln,lln,offset,col,strbef,straft,pos) =
+                             P.id2clt $1 in
+                           let clt =
+                             (arity,ln,lln,offset,0,strbef,straft,pos) in
+                           P.clt2mcode
+                             (Ast.NonLocal (Parse_aux.str2inc (P.id2name $1)))
+                             (P.drop_bef clt))) }
+| d=defineop t=ctype TLineEnd
+    { let ty = Ast0.wrap(Ast0.TopExp(Ast0.wrap(Ast0.TypeExp(t)))) in
+      d (Ast0.wrap(Ast0.DOTS([ty]))) }
+| defineop b=toplevel_seq_start(toplevel_after_dots) TLineEnd
+    { let body =
+       match b with
+         [e] ->
+           (match Ast0.unwrap e with
+             Ast0.Exp(e1) ->
+               [Ast0.rewrap e (Ast0.TopExp(Ast0.set_arg_exp (e1)))]
+           | _ -> b)
+       | _ -> b in
+      $1 (Ast0.wrap(Ast0.DOTS(body))) }
+
+defineop:
+  TDefine
+    { let (clt,ident) = $1 in
+      function body ->
+       Ast0.wrap
+         (Ast0.Define
+            (P.clt2mcode "#define" clt,
+             (match ident with
+               TMetaId((nm,constraints,pure,clt)) ->
+                 Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure))
+             | TIdent(nm_pure) ->
+                 Ast0.wrap(Ast0.Id(P.id2mcode nm_pure))
+             | _ ->
+                 raise
+                   (Semantic_cocci.Semantic
+                      "unexpected name for a #define")),
+             Ast0.wrap Ast0.NoParams,
+             body)) }
+| TDefineParam define_param_list_option TCPar
+    { let (clt,ident,parenoff) = $1 in
+      let (arity,line,lline,offset,col,strbef,straft,pos) = clt in
+      let lp =
+       P.clt2mcode "(" (arity,line,lline,parenoff,0,[],[],Ast0.NoMetaPos) in
+      function body ->
+       Ast0.wrap
+         (Ast0.Define
+            (P.clt2mcode "#define" clt,
+             (match ident with
+               TMetaId((nm,constraints,pure,clt)) ->
+                 Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure))
+             | TIdent(nm_pure) ->
+                 Ast0.wrap(Ast0.Id(P.id2mcode nm_pure))
+             | _ ->
+                 raise
+                   (Semantic_cocci.Semantic
+                      "unexpected name for a #define")),
+             Ast0.wrap (Ast0.DParams (lp,$2,P.clt2mcode ")" $3)),body)) }
+
+/* ---------------------------------------------------------------------- */
+
+define_param_list: define_param_list_start
+     {let circle x =
+       match Ast0.unwrap x with Ast0.DPcircles(_) -> true | _ -> false in
+     if List.exists circle $1
+     then Ast0.wrap(Ast0.CIRCLES($1))
+     else Ast0.wrap(Ast0.DOTS($1)) }
+
+define_param_list_start:
+    ident { [Ast0.wrap(Ast0.DParam $1)] }
+  | ident TComma define_param_list_start
+      { Ast0.wrap(Ast0.DParam $1)::
+       Ast0.wrap(Ast0.DPComma(P.clt2mcode "," $2))::$3 }
+  | d=TEllipsis r=list(dp_comma_args(TEllipsis))
+      { (P.mkdpdots "..." d)::
+       (List.concat (List.map (function x -> x (P.mkdpdots "...")) r)) }
+
+dp_comma_args(dotter):
+  c=TComma d=dotter
+    { function dot_builder ->
+      [Ast0.wrap(Ast0.DPComma(P.clt2mcode "," c)); dot_builder d] }
+| TComma ident
+    { function dot_builder ->
+      [Ast0.wrap(Ast0.DPComma(P.clt2mcode "," $1));
+       Ast0.wrap(Ast0.DParam $2)] }
+
+define_param_list_option: define_param_list { $1 }
+         | /* empty */     { Ast0.wrap(Ast0.DOTS([])) }
+
+/*****************************************************************************/
+
+funproto:
+  s=ioption(storage) t=ctype
+  id=func_ident lp=TOPar d=decl_list(name_opt_decl) rp=TCPar pt=TPtVirg
+      { Ast0.wrap
+         (Ast0.UnInit
+            (s,
+             Ast0.wrap
+               (Ast0.FunctionType(Some t,
+                                  P.clt2mcode "(" lp, d, P.clt2mcode ")" rp)),
+             id, P.clt2mcode ";" pt)) }
+| s=ioption(storage) t=Tvoid
+  id=func_ident lp=TOPar d=decl_list(name_opt_decl) rp=TCPar pt=TPtVirg
+    { let t = Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.VoidType t, None)) in
+      Ast0.wrap
+        (Ast0.UnInit
+          (s,
+           Ast0.wrap
+             (Ast0.FunctionType(Some t,
+                                P.clt2mcode "(" lp, d, P.clt2mcode ")" rp)),
+           id, P.clt2mcode ";" pt)) }
+
+
+fundecl:
+  f=fninfo
+  TFunDecl i=func_ident lp=TOPar d=decl_list(decl) rp=TCPar
+  lb=TOBrace b=fun_start rb=TCBrace
+      { Ast0.wrap(Ast0.FunDecl((Ast0.default_info(),Ast0.context_befaft()),
+                              f, i,
+                              P.clt2mcode "(" lp, d,
+                              P.clt2mcode ")" rp,
+                              P.clt2mcode "{" lb, b,
+                              P.clt2mcode "}" rb)) }
+
+fninfo:
+    /* empty */ { [] }
+  | storage  fninfo
+      { try
+       let _ =
+         List.find (function Ast0.FStorage(_) -> true | _ -> false) $2 in
+       raise (Semantic_cocci.Semantic "duplicate storage")
+      with Not_found -> (Ast0.FStorage($1))::$2 }
+  | t=fn_ctype r=fninfo_nt { (Ast0.FType(t))::r }
+  | Tinline  fninfo
+      { try
+       let _ = List.find (function Ast0.FInline(_) -> true | _ -> false) $2 in
+       raise (Semantic_cocci.Semantic "duplicate inline")
+      with Not_found -> (Ast0.FInline(P.clt2mcode "inline" $1))::$2 }
+  | Tattr    fninfo
+      { try
+       let _ = List.find (function Ast0.FAttr(_) -> true | _ -> false) $2 in
+       raise (Semantic_cocci.Semantic "multiple attributes")
+      with Not_found -> (Ast0.FAttr(P.id2mcode $1))::$2 }
+
+fninfo_nt:
+    /* empty */ { [] }
+  | storage  fninfo_nt
+      { try
+       let _ =
+         List.find (function Ast0.FStorage(_) -> true | _ -> false) $2 in
+       raise (Semantic_cocci.Semantic "duplicate storage")
+      with Not_found -> (Ast0.FStorage($1))::$2 }
+  | Tinline  fninfo_nt
+      { try
+       let _ = List.find (function Ast0.FInline(_) -> true | _ -> false) $2 in
+       raise (Semantic_cocci.Semantic "duplicate inline")
+      with Not_found -> (Ast0.FInline(P.clt2mcode "inline" $1))::$2 }
+  | Tattr    fninfo_nt
+      { try
+       let _ = List.find (function Ast0.FAttr(_) -> true | _ -> false) $2 in
+       raise (Semantic_cocci.Semantic "duplicate init")
+      with Not_found -> (Ast0.FAttr(P.id2mcode $1))::$2 }
+
+storage:
+         s=Tstatic      { P.clt2mcode Ast.Static s }
+       | s=Tauto        { P.clt2mcode Ast.Auto s }
+       | s=Tregister    { P.clt2mcode Ast.Register s }
+       | s=Textern      { P.clt2mcode Ast.Extern s }
+
+decl: t=ctype i=ident
+       { Ast0.wrap(Ast0.Param(t, Some i)) }
+    | t=fn_ctype lp=TOPar s=TMul i=ident rp=TCPar
+       lp1=TOPar d=decl_list(name_opt_decl) rp1=TCPar
+        { let fnptr =
+         Ast0.wrap
+           (Ast0.FunctionPointer
+              (t,P.clt2mcode "(" lp,P.clt2mcode "*" s,P.clt2mcode ")" rp,
+               P.clt2mcode "(" lp1,d,P.clt2mcode ")" rp1)) in
+       Ast0.wrap(Ast0.Param(fnptr, Some i)) }
+    | t=Tvoid
+       { let ty = Ast0.wrap(Ast0.BaseType(P.clt2mcode Ast.VoidType t, None)) in
+          Ast0.wrap(Ast0.VoidParam(ty)) }
+    | TMetaParam
+       { let (nm,pure,clt) = $1 in
+       Ast0.wrap(Ast0.MetaParam(P.clt2mcode nm clt,pure)) }
+
+name_opt_decl:
+      decl  { $1 }
+    | t=ctype { Ast0.wrap(Ast0.Param(t, None)) }
+    | t=fn_ctype lp=TOPar s=TMul rp=TCPar
+       lp1=TOPar d=decl_list(name_opt_decl) rp1=TCPar
+        { let fnptr =
+         Ast0.wrap
+           (Ast0.FunctionPointer
+              (t,P.clt2mcode "(" lp,P.clt2mcode "*" s,P.clt2mcode ")" rp,
+               P.clt2mcode "(" lp1,d,P.clt2mcode ")" rp1)) in
+       Ast0.wrap(Ast0.Param(fnptr, None)) }
+
+const_vol:
+      Tconst       { P.clt2mcode Ast.Const $1 }
+    | Tvolatile    { P.clt2mcode Ast.Volatile $1 }
+
+/*****************************************************************************/
+
+statement:
+  includes { $1 } /* shouldn't be allowed to be a single_statement... */
+| TMetaStm
+    { P.meta_stm $1 }
+| expr TPtVirg
+    { P.exp_stm $1 $2 }
+| TIf TOPar eexpr TCPar single_statement %prec TIf
+    { P.ifthen $1 $2 $3 $4 $5 }
+| TIf TOPar eexpr TCPar single_statement TElse single_statement
+    { P.ifthenelse $1 $2 $3 $4 $5 $6 $7 }
+| TFor TOPar option(eexpr) TPtVirg option(eexpr) TPtVirg
+    option(eexpr) TCPar single_statement
+    { P.forloop $1 $2 $3 $4 $5 $6 $7 $8 $9 }
+| TWhile TOPar eexpr TCPar single_statement
+    { P.whileloop $1 $2 $3 $4 $5 }
+| TDo single_statement TWhile TOPar eexpr TCPar TPtVirg
+    { P.doloop $1 $2 $3 $4 $5 $6 $7 }
+| iter_ident TOPar eexpr_list_option TCPar single_statement
+    { P.iterator $1 $2 $3 $4 $5 }
+| TSwitch TOPar eexpr TCPar TOBrace list(case_line) TCBrace
+    { P.switch $1 $2 $3 $4 $5 $6 $7 }
+| TReturn eexpr TPtVirg { P.ret_exp $1 $2 $3 }
+| TReturn TPtVirg { P.ret $1 $2 }
+| TBreak TPtVirg { P.break $1 $2 }
+| TContinue TPtVirg { P.cont $1 $2 }
+| ident TDotDot { P.label $1 $2 }
+| TGoto ident TPtVirg { P.goto $1 $2 $3 }
+| TOBrace fun_start TCBrace
+    { P.seq $1 $2 $3 }
+
+stm_dots:
+  TEllipsis w=list(whenppdecs)
+    { Ast0.wrap(Ast0.Dots(P.clt2mcode "..." $1, List.concat w)) }
+| TOEllipsis w=list(whenppdecs) b=nest_start c=TCEllipsis
+    { Ast0.wrap(Ast0.Nest(P.clt2mcode "<..." $1, b,
+                         P.clt2mcode "...>" c, List.concat w, false)) }
+| TPOEllipsis w=list(whenppdecs) b=nest_start c=TPCEllipsis
+    { Ast0.wrap(Ast0.Nest(P.clt2mcode "<+..." $1, b,
+                         P.clt2mcode "...+>" c, List.concat w, true)) }
+
+whenppdecs: w=whens(when_start,rule_elem_statement)
+    { w }
+
+/* a statement that fits into a single rule_elem.  should nests be included?
+what about statement metavariables? */
+rule_elem_statement:
+  one_decl_var
+    { Ast0.wrap(Ast0.Decl((Ast0.default_info(),Ast0.context_befaft()),$1)) }
+| expr TPtVirg { P.exp_stm $1 $2 }
+| TReturn eexpr TPtVirg { P.ret_exp $1 $2 $3 }
+| TReturn TPtVirg { P.ret $1 $2 }
+| TBreak TPtVirg { P.break $1 $2 }
+| TContinue TPtVirg { P.cont $1 $2 }
+| TOPar0 midzero_list(rule_elem_statement,rule_elem_statement) TCPar0
+    { let (mids,code) = $2 in
+    Ast0.wrap
+      (Ast0.Disj(P.clt2mcode "(" $1,
+                List.map (function x -> Ast0.wrap(Ast0.DOTS([x]))) code,
+                mids, P.clt2mcode ")" $3)) }
+
+/* a statement on its own */
+single_statement:
+    statement                         { $1 }
+  | TOPar0 midzero_list(statement,statement) TCPar0
+      /* degenerate case, elements are single statements and thus don't
+       contain dots */
+      { let (mids,code) = $2 in
+        Ast0.wrap
+         (Ast0.Disj(P.clt2mcode "(" $1,
+                    List.map (function x -> Ast0.wrap(Ast0.DOTS([x]))) code,
+                    mids, P.clt2mcode ")" $3)) }
+
+case_line:
+    TDefault TDotDot fun_start
+      { Ast0.wrap(Ast0.Default(P.clt2mcode "default" $1,P.clt2mcode ":" $2,$3)) }
+  | TCase eexpr TDotDot fun_start
+      { Ast0.wrap(Ast0.Case(P.clt2mcode "case" $1,$2,P.clt2mcode ":" $3,$4)) }
+
+/* In the following, an identifier as a type is not fully supported.  Indeed,
+the language is ambiguous: what is foo * bar; */
+/* The AST DisjDecl cannot be generated because it would be ambiguous with
+a disjunction on a statement with a declaration in each branch */
+decl_var:
+    t=ctype pv=TPtVirg
+      { [Ast0.wrap(Ast0.TyDecl(t,P.clt2mcode ";" pv))] }
+  | s=ioption(storage) t=ctype d=comma_list(d_ident) pv=TPtVirg
+      { List.map
+         (function (id,fn) ->
+           Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv)))
+         d }
+  | f=funproto { [f] }
+  | s=ioption(storage) t=ctype d=d_ident q=TEq e=initialize pv=TPtVirg
+      {let (id,fn) = d in
+      [Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv))]}
+  /* type is a typedef name */
+  | s=ioption(storage) cv=ioption(const_vol) i=pure_ident
+      d=comma_list(d_ident) pv=TPtVirg
+      { List.map
+         (function (id,fn) ->
+           let idtype =
+             P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
+           Ast0.wrap(Ast0.UnInit(s,fn idtype,id,P.clt2mcode ";" pv)))
+         d }
+  | s=ioption(storage) cv=ioption(const_vol) i=pure_ident d=d_ident q=TEq
+      e=initialize pv=TPtVirg
+      { let (id,fn) = d in
+      !Data.add_type_name (P.id2name i);
+      let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
+      [Ast0.wrap(Ast0.Init(s,fn idtype,id,P.clt2mcode "=" q,e,
+                          P.clt2mcode ";" pv))] }
+  /* function pointer type */
+  | s=ioption(storage)
+    t=fn_ctype lp1=TOPar st=TMul d=d_ident rp1=TCPar
+    lp2=TOPar p=decl_list(name_opt_decl) rp2=TCPar
+    pv=TPtVirg
+      { let (id,fn) = d in
+        let t =
+         Ast0.wrap
+           (Ast0.FunctionPointer
+              (t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
+               P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
+        [Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv))] }
+  | decl_ident TOPar eexpr_list_option TCPar TPtVirg
+      { [Ast0.wrap(Ast0.MacroDecl($1,P.clt2mcode "(" $2,$3,
+                                 P.clt2mcode ")" $4,P.clt2mcode ";" $5))] } 
+  | s=ioption(storage)
+    t=fn_ctype lp1=TOPar st=TMul d=d_ident rp1=TCPar
+    lp2=TOPar p=decl_list(name_opt_decl) rp2=TCPar
+    q=TEq e=initialize pv=TPtVirg
+      { let (id,fn) = d in
+        let t =
+         Ast0.wrap
+           (Ast0.FunctionPointer
+              (t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
+               P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
+      [Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv))]}
+  | s=Ttypedef t=ctype id=typedef_ident pv=TPtVirg
+      { let s = P.clt2mcode "typedef" s in
+        [Ast0.wrap(Ast0.Typedef(s,t,id,P.clt2mcode ";" pv))] }
+
+one_decl_var:
+    t=ctype pv=TPtVirg
+      { Ast0.wrap(Ast0.TyDecl(t,P.clt2mcode ";" pv)) }
+  | s=ioption(storage) t=ctype d=d_ident pv=TPtVirg
+      { let (id,fn) = d in
+        Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv)) }
+  | f=funproto { f }
+  | s=ioption(storage) t=ctype d=d_ident q=TEq e=initialize pv=TPtVirg
+      { let (id,fn) = d in
+      Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv)) }
+  /* type is a typedef name */
+  | s=ioption(storage) cv=ioption(const_vol) i=pure_ident
+      d=d_ident pv=TPtVirg
+      { let (id,fn) = d in
+        let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
+       Ast0.wrap(Ast0.UnInit(s,fn idtype,id,P.clt2mcode ";" pv)) }
+  | s=ioption(storage) cv=ioption(const_vol) i=pure_ident d=d_ident q=TEq
+      e=initialize pv=TPtVirg
+      { let (id,fn) = d in
+      !Data.add_type_name (P.id2name i);
+      let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
+      Ast0.wrap(Ast0.Init(s,fn idtype,id,P.clt2mcode "=" q,e,
+                          P.clt2mcode ";" pv)) }
+  /* function pointer type */
+  | s=ioption(storage)
+    t=fn_ctype lp1=TOPar st=TMul d=d_ident rp1=TCPar
+    lp2=TOPar p=decl_list(name_opt_decl) rp2=TCPar
+    pv=TPtVirg
+      { let (id,fn) = d in
+        let t =
+         Ast0.wrap
+           (Ast0.FunctionPointer
+              (t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
+               P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
+        Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv)) }
+  | decl_ident TOPar eexpr_list_option TCPar TPtVirg
+      { Ast0.wrap(Ast0.MacroDecl($1,P.clt2mcode "(" $2,$3,
+                                 P.clt2mcode ")" $4,P.clt2mcode ";" $5)) } 
+  | s=ioption(storage)
+    t=fn_ctype lp1=TOPar st=TMul d=d_ident rp1=TCPar
+    lp2=TOPar p=decl_list(name_opt_decl) rp2=TCPar
+    q=TEq e=initialize pv=TPtVirg
+      { let (id,fn) = d in
+        let t =
+         Ast0.wrap
+           (Ast0.FunctionPointer
+              (t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
+               P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
+      Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv))}
+
+
+d_ident:
+    ident list(array_dec)
+      { ($1,
+        function t ->
+          List.fold_right
+            (function (l,i,r) ->
+              function rest ->
+                Ast0.wrap
+                  (Ast0.Array(rest,P.clt2mcode "[" l,i,P.clt2mcode "]" r)))
+            $2 t) }
+
+array_dec: l=TOCro i=option(eexpr) r=TCCro { (l,i,r) }
+
+initialize:
+    eexpr
+      { Ast0.wrap(Ast0.InitExpr($1)) }
+  | TOBrace initialize_list TCBrace
+      { Ast0.wrap(Ast0.InitList(P.clt2mcode "{" $1,$2,P.clt2mcode "}" $3)) }
+  | TOBrace TCBrace
+      { Ast0.wrap
+         (Ast0.InitList(P.clt2mcode "{" $1,Ast0.wrap(Ast0.DOTS []),
+                        P.clt2mcode "}" $2)) }
+
+initialize2:
+  /*arithexpr and not eexpr because can have ambiguity with comma*/
+  /*dots and nests probably not allowed at top level, haven't looked into why*/
+  arith_expr(eexpr,invalid) { Ast0.wrap(Ast0.InitExpr($1)) }
+| TOBrace initialize_list TCBrace
+    { Ast0.wrap(Ast0.InitList(P.clt2mcode "{" $1,$2,P.clt2mcode "}" $3)) }
+| TOBrace TCBrace
+    { Ast0.wrap
+       (Ast0.InitList(P.clt2mcode "{" $1,Ast0.wrap(Ast0.DOTS []),
+                      P.clt2mcode "}" $2)) }
+           /* gccext:, labeled elements */
+| TDot ident TEq initialize2
+    { Ast0.wrap(Ast0.InitGccDotName(P.clt2mcode "." $1,$2,P.clt2mcode "=" $3,$4)) }
+| ident TDotDot initialize2
+    { Ast0.wrap(Ast0.InitGccName($1,P.clt2mcode ":" $2,$3)) } /* in old kernel */
+| TOCro eexpr TCCro TEq initialize2
+    { Ast0.wrap(Ast0.InitGccIndex(P.clt2mcode "[" $1,$2,P.clt2mcode "]" $3,
+                                 P.clt2mcode "=" $4,$5)) }
+| TOCro eexpr TEllipsis eexpr TCCro TEq initialize2
+    { Ast0.wrap(Ast0.InitGccRange(P.clt2mcode "[" $1,$2,P.clt2mcode "..." $3,
+                                 $4,P.clt2mcode "]" $5,P.clt2mcode "=" $6,$7)) }
+
+initialize_list:
+   initialize_list_start { Ast0.wrap(Ast0.DOTS($1)) }
+
+initialize_list_start:
+  initialize2 TComma { [$1;Ast0.wrap(Ast0.IComma(P.clt2mcode "," $2))] }
+| initialize2 TComma initialize_list_start
+    { $1::Ast0.wrap(Ast0.IComma(P.clt2mcode "," $2))::$3 }
+| d=edots_when(TEllipsis,initialize)
+      r=comma_initializers(edots_when(TEllipsis,initialize))
+    { (P.mkidots "..." d)::
+      (List.concat(List.map (function x -> x (P.mkidots "...")) r)) }
+
+comma_initializers(dotter):
+  /* empty */ { [] }
+| d=dotter r=comma_initializers2(dotter)
+      { (function dot_builder -> [dot_builder d])::r }
+| i=initialize2 c=TComma r=comma_initializers(dotter)
+    { (function dot_builder -> [i; Ast0.wrap(Ast0.IComma(P.clt2mcode "," c))])::
+      r }
+
+comma_initializers2(dotter):
+  /* empty */ { [] }
+| i=initialize2 c=TComma r=comma_initializers(dotter)
+    { (function dot_builder -> [i; Ast0.wrap(Ast0.IComma(P.clt2mcode "," c))])::
+      r }
+
+/* a statement that is part of a list */
+decl_statement:
+    TMetaStmList
+      { let (nm,pure,clt) = $1 in
+      [Ast0.wrap(Ast0.MetaStmt(P.clt2mcode nm clt,pure))] }
+  | decl_var
+      { List.map
+         (function x ->
+           Ast0.wrap
+             (Ast0.Decl((Ast0.default_info(),Ast0.context_befaft()),x)))
+         $1 }
+  | statement { [$1] }
+  /* this doesn't allow expressions at top level, because the parser doesn't
+       know whether there is one.  If there is one, this is not sequencible.
+       If there is not one, then it is.  It seems complicated to get around
+    this at the parser level.  We would have to have a check afterwards to
+    allow this.  One case where this would be useful is for a when.  Now
+       we allow a sequence of whens, so one can be on only statements and
+    one can be on only expressions. */
+  | TOPar0 t=midzero_list(fun_start,fun_start) TCPar0
+      { let (mids,code) = t in
+       if List.for_all
+           (function x ->
+             match Ast0.unwrap x with Ast0.DOTS([]) -> true | _ -> false)
+           code
+      then []
+      else
+         [Ast0.wrap(Ast0.Disj(P.clt2mcode "(" $1, code, mids,
+                              P.clt2mcode ")" $3))] }
+
+/* a statement that is part of a list */
+decl_statement_expr:
+    TMetaStmList
+      { let (nm,pure,clt) = $1 in
+      [Ast0.wrap(Ast0.MetaStmt(P.clt2mcode nm clt,pure))] }
+  | decl_var
+      { List.map
+         (function x ->
+           Ast0.wrap
+             (Ast0.Decl((Ast0.default_info(),Ast0.context_befaft()),x)))
+         $1 }
+  | statement { [$1] }
+  /* this doesn't allow expressions at top level, because the parser doesn't
+       know whether there is one.  If there is one, this is not sequencible.
+       If there is not one, then it is.  It seems complicated to get around
+    this at the parser level.  We would have to have a check afterwards to
+    allow this.  One case where this would be useful is for a when.  Now
+       we allow a sequence of whens, so one can be on only statements and
+    one can be on only expressions. */
+  | TOPar0 t=midzero_list(fun_after_stm,fun_after_dots_or) TCPar0
+      { let (mids,code) = t in
+       if List.for_all (function [] -> true | _ -> false) code
+      then []
+      else
+         let dot_code =
+           List.map (function x -> Ast0.wrap(Ast0.DOTS x)) code in
+         [Ast0.wrap(Ast0.Disj(P.clt2mcode "(" $1, dot_code, mids,
+                              P.clt2mcode ")" $3))] }
+
+/*****************************************************************************/
+
+/* The following cannot contain <... ...> at the top level.  This can only
+be allowed as an expression when the expression is delimited on both sides
+by expression-specific markers.  In that case, the rule eexpr is used, which
+allows <... ...> anywhere.  Hopefully, this will not be too much of a problem
+in practice. */
+expr:  basic_expr(expr,invalid) { $1 }
+/* allows ... and nests */
+eexpr: basic_expr(eexpr,dot_expressions) { $1 }
+/* allows nests but not .... */
+dexpr: basic_expr(eexpr,nest_expressions) { $1 }
+
+top_eexpr:
+  eexpr { Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Exp($1)))) }
+
+invalid:
+  TInvalid { raise (Semantic_cocci.Semantic "not matchable") }
+
+dot_expressions:
+  TEllipsis { Ast0.wrap(Ast0.Edots(P.clt2mcode "..." $1,None)) }
+| nest_expressions { $1 }
+
+nest_expressions:
+  TOEllipsis w=option(whenexp) e=expr_dots(TEllipsis) c=TCEllipsis
+    { Ast0.wrap(Ast0.NestExpr(P.clt2mcode "<..." $1,
+                             Ast0.wrap(Ast0.DOTS(e (P.mkedots "..."))),
+                             P.clt2mcode "...>" c, w, false)) }
+| TPOEllipsis w=option(whenexp) e=expr_dots(TEllipsis) c=TPCEllipsis
+    { Ast0.wrap(Ast0.NestExpr(P.clt2mcode "<+..." $1,
+                             Ast0.wrap(Ast0.DOTS(e (P.mkedots "..."))),
+                             P.clt2mcode "...+>" c, w, true)) }
+
+whenexp: TWhen TNotEq w=eexpr TLineEnd { w }
+
+basic_expr(recurser,primary_extra):
+  assign_expr(recurser,primary_extra)                        { $1 }
+
+assign_expr(r,pe):
+    cond_expr(r,pe)                        { $1 }
+  | unary_expr(r,pe) TAssign assign_expr_bis
+      { let (op,clt) = $2 in
+      Ast0.wrap(Ast0.Assignment($1,P.clt2mcode op clt,
+                               Ast0.set_arg_exp $3,false)) }
+  | unary_expr(r,pe) TEq assign_expr_bis
+      { Ast0.wrap
+         (Ast0.Assignment
+            ($1,P.clt2mcode Ast.SimpleAssign $2,Ast0.set_arg_exp $3,false)) }
+
+assign_expr_bis:
+    cond_expr(eexpr,dot_expressions)                        { $1 }
+  | unary_expr(eexpr,dot_expressions) TAssign assign_expr_bis
+      { let (op,clt) = $2 in
+      Ast0.wrap(Ast0.Assignment($1,P.clt2mcode op clt,
+                               Ast0.set_arg_exp $3,false)) }
+  | unary_expr(eexpr,dot_expressions) TEq assign_expr_bis
+      { Ast0.wrap
+         (Ast0.Assignment
+            ($1,P.clt2mcode Ast.SimpleAssign $2,Ast0.set_arg_exp $3,false)) }
+
+cond_expr(r,pe):
+    arith_expr(r,pe)                         { $1 }
+  | l=arith_expr(r,pe) w=TWhy t=option(eexpr) dd=TDotDot r=cond_expr(r,pe)
+      { Ast0.wrap(Ast0.CondExpr (l, P.clt2mcode "?" w, t,
+                                P.clt2mcode ":" dd, r)) }
+
+arith_expr(r,pe):
+    cast_expr(r,pe)                         { $1 }
+  | arith_expr(r,pe) TMul    arith_expr(r,pe)
+      { P.arith_op Ast.Mul $1 $2 $3 }
+  | arith_expr(r,pe) TDmOp    arith_expr(r,pe)
+      { let (op,clt) = $2 in P.arith_op op $1 clt $3 }
+  | arith_expr(r,pe) TPlus   arith_expr(r,pe)
+      { P.arith_op Ast.Plus $1 $2 $3 }
+  | arith_expr(r,pe) TMinus  arith_expr(r,pe)
+      { P.arith_op Ast.Minus $1 $2 $3 }
+  | arith_expr(r,pe) TShOp    arith_expr(r,pe)
+      { let (op,clt) = $2 in P.arith_op op $1 clt $3 }
+  | arith_expr(r,pe) TLogOp    arith_expr(r,pe)
+      { let (op,clt) = $2 in P.logic_op op $1 clt $3 }
+  | arith_expr(r,pe) TEqEq   arith_expr(r,pe)
+      { P.logic_op Ast.Eq $1 $2 $3 }
+  | arith_expr(r,pe) TNotEq  arith_expr(r,pe)
+      { P.logic_op Ast.NotEq $1 $2 $3 }
+  | arith_expr(r,pe) TAnd    arith_expr(r,pe)
+      { P.arith_op Ast.And $1 $2 $3 }
+  | arith_expr(r,pe) TOr     arith_expr(r,pe)
+      { P.arith_op Ast.Or $1 $2 $3 }
+  | arith_expr(r,pe) TXor    arith_expr(r,pe)
+      { P.arith_op Ast.Xor $1 $2 $3 }
+  | arith_expr(r,pe) TAndLog arith_expr(r,pe)
+      { P.logic_op Ast.AndLog $1 $2 $3 }
+  | arith_expr(r,pe) TOrLog  arith_expr(r,pe)
+      { P.logic_op Ast.OrLog $1 $2 $3 }
+
+cast_expr(r,pe):
+    unary_expr(r,pe)                      { $1 }
+  | lp=TOPar t=ctype rp=TCPar e=cast_expr(r,pe)
+      { Ast0.wrap(Ast0.Cast (P.clt2mcode "(" lp, t,
+                            P.clt2mcode ")" rp, e)) }
+
+unary_expr(r,pe):
+    postfix_expr(r,pe)                   { $1 }
+  | TInc unary_expr(r,pe)
+      { Ast0.wrap(Ast0.Infix ($2, P.clt2mcode Ast.Inc $1)) }
+  | TDec unary_expr(r,pe)
+      { Ast0.wrap(Ast0.Infix ($2, P.clt2mcode Ast.Dec $1)) }
+  | unary_op unary_expr(r,pe)
+      { let mcode = $1 in Ast0.wrap(Ast0.Unary($2, mcode)) }
+  | TBang unary_expr(r,pe)
+      { let mcode = P.clt2mcode Ast.Not $1 in
+      Ast0.wrap(Ast0.Unary($2, mcode)) }
+  | TSizeof unary_expr(r,pe)
+      { Ast0.wrap(Ast0.SizeOfExpr (P.clt2mcode "sizeof" $1, $2)) }
+  | s=TSizeof lp=TOPar t=ctype rp=TCPar
+      { Ast0.wrap(Ast0.SizeOfType (P.clt2mcode "sizeof" s,
+                                   P.clt2mcode "(" lp,t,
+                                   P.clt2mcode ")" rp)) }
+
+unary_op: TAnd    { P.clt2mcode Ast.GetRef $1 }
+       | TMul    { P.clt2mcode Ast.DeRef $1 }
+       | TPlus   { P.clt2mcode Ast.UnPlus $1 }
+       | TMinus  { P.clt2mcode Ast.UnMinus $1 }
+       | TTilde  { P.clt2mcode Ast.Tilde $1 }
+
+postfix_expr(r,pe):
+   primary_expr(r,pe)                            { $1 }
+ | postfix_expr(r,pe) TOCro eexpr TCCro
+     { Ast0.wrap(Ast0.ArrayAccess ($1,P.clt2mcode "[" $2,$3,
+                                      P.clt2mcode "]" $4)) }
+ | postfix_expr(r,pe) TDot   ident
+     { Ast0.wrap(Ast0.RecordAccess($1, P.clt2mcode "." $2, $3)) }
+ | postfix_expr(r,pe) TPtrOp ident
+     { Ast0.wrap(Ast0.RecordPtAccess($1, P.clt2mcode "->" $2,
+                                    $3)) }
+ | postfix_expr(r,pe) TInc
+     { Ast0.wrap(Ast0.Postfix ($1, P.clt2mcode Ast.Inc $2)) }
+ | postfix_expr(r,pe) TDec
+     { Ast0.wrap(Ast0.Postfix ($1, P.clt2mcode Ast.Dec $2)) }
+ | postfix_expr(r,pe) TOPar eexpr_list_option TCPar
+     { Ast0.wrap(Ast0.FunCall($1,P.clt2mcode "(" $2,
+                             $3,
+                             P.clt2mcode ")" $4)) }
+
+primary_expr(recurser,primary_extra):
+   func_ident   { Ast0.wrap(Ast0.Ident($1)) }
+ | TInt
+     { let (x,clt) = $1 in
+     Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) }
+ | TFloat
+     { let (x,clt) = $1 in
+     Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Float x) clt)) }
+ | TString
+     { let (x,clt) = $1 in
+     Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.String x) clt)) }
+ | TChar
+     { let (x,clt) = $1 in
+     Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Char x) clt)) }
+ | TMetaConst
+     { let (nm,constraints,pure,ty,clt) = $1 in
+     Ast0.wrap
+       (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.CONST,pure)) }
+ | TMetaErr
+     { let (nm,constraints,pure,clt) = $1 in
+     Ast0.wrap(Ast0.MetaErr(P.clt2mcode nm clt,constraints,pure)) }
+ | TMetaExp
+     { let (nm,constraints,pure,ty,clt) = $1 in
+     Ast0.wrap
+       (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ANY,pure)) }
+ | TMetaIdExp
+     { let (nm,constraints,pure,ty,clt) = $1 in
+     Ast0.wrap
+       (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ID,pure)) }
+ | TMetaLocalIdExp
+     { let (nm,constraints,pure,ty,clt) = $1 in
+     Ast0.wrap
+       (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.LocalID,pure)) }
+ | TOPar eexpr TCPar
+     { Ast0.wrap(Ast0.Paren(P.clt2mcode "(" $1,$2,
+                           P.clt2mcode ")" $3)) }
+ | TOPar0 midzero_list(recurser,eexpr) TCPar0
+     { let (mids,code) = $2 in
+       Ast0.wrap(Ast0.DisjExpr(P.clt2mcode "(" $1,
+                              code, mids,
+                              P.clt2mcode ")" $3)) }
+ | primary_extra { $1 }
+
+expr_dots(dotter):
+    r=no_dot_start_end(dexpr,edots_when(dotter,eexpr)) { r }
+
+// used in NEST
+no_dot_start_end(grammar,dotter):
+  g=grammar dg=list(pair(dotter,grammar))
+  { function dot_builder ->
+      g :: (List.concat(List.map (function (d,g) -> [dot_builder d;g]) dg)) }
+
+/*****************************************************************************/
+
+pure_ident:
+     TIdent { $1 }
+
+meta_ident:
+       TRuleName TDot pure_ident { (Some $1,P.id2name $3) }
+
+pure_ident_or_meta_ident:
+       pure_ident                { (None,P.id2name $1) }
+     | meta_ident                { $1 }
+     | Tlist                     { (None,"list") }
+     | TError                    { (None,"error") }
+     | TType                     { (None,"type") }
+
+pure_ident_or_meta_ident_with_not_eq(not_eq):
+       i=pure_ident_or_meta_ident l=loption(not_eq) { (i,l) }
+
+not_eq:
+       TNotEq i=pure_ident
+         { (if !Data.in_iso
+          then failwith "constraints not allowed in iso file");
+          [Ast0.wrap(Ast0.Id(P.id2mcode i))] }
+     | TNotEq TOBrace l=comma_list(pure_ident) TCBrace
+        { (if !Data.in_iso
+          then failwith "constraints not allowed in iso file");
+          List.map (function i -> Ast0.wrap(Ast0.Id(P.id2mcode i))) l }
+
+not_eqe:
+       TNotEq i=pure_ident
+         { (if !Data.in_iso
+          then failwith "constraints not allowed in iso file");
+          [Ast0.wrap(Ast0.Ident(Ast0.wrap(Ast0.Id(P.id2mcode i))))] }
+     | TNotEq TOBrace l=comma_list(pure_ident) TCBrace
+        { (if !Data.in_iso
+          then failwith "constraints not allowed in iso file");
+          List.map
+            (function i ->
+              Ast0.wrap(Ast0.Ident(Ast0.wrap(Ast0.Id(P.id2mcode i)))))
+            l }
+
+not_ceq:
+       TNotEq i=ident_or_const
+         { (if !Data.in_iso
+          then failwith "constraints not allowed in iso file");
+          [i] }
+     | TNotEq TOBrace l=comma_list(ident_or_const) TCBrace
+        { (if !Data.in_iso
+          then failwith "constraints not allowed in iso file");
+          l }
+
+ident_or_const:
+       i=pure_ident { Ast0.wrap(Ast0.Ident(Ast0.wrap(Ast0.Id(P.id2mcode i)))) }
+     | TInt
+        { let (x,clt) = $1 in
+        Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) }
+
+not_pos:
+       TNotEq i=meta_ident
+         { (if !Data.in_iso
+          then failwith "constraints not allowed in iso file");
+          match i with
+            (None,_) -> failwith "constraint must be an inherited variable"
+          | (Some rule,name) ->
+              let i = (rule,name) in
+              P.check_meta(Ast.MetaPosDecl(Ast.NONE,i));
+              [i] }
+     | TNotEq TOBrace l=comma_list(meta_ident) TCBrace
+        { (if !Data.in_iso
+          then failwith "constraints not allowed in iso file");
+          List.map
+            (function
+                (None,_) ->
+                  failwith "constraint must be an inherited variable"
+              | (Some rule,name) ->
+                  let i = (rule,name) in
+                  P.check_meta(Ast.MetaPosDecl(Ast.NONE,i));
+                  i)
+            l }
+
+func_ident: pure_ident
+         { Ast0.wrap(Ast0.Id(P.id2mcode $1)) }
+     | TMetaId
+         { let (nm,constraints,pure,clt) = $1 in
+        Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) }
+     | TMetaFunc
+         { let (nm,constraints,pure,clt) = $1 in
+        Ast0.wrap(Ast0.MetaFunc(P.clt2mcode nm clt,constraints,pure)) }
+     | TMetaLocalFunc
+        { let (nm,constraints,pure,clt) = $1 in
+        Ast0.wrap
+          (Ast0.MetaLocalFunc(P.clt2mcode nm clt,constraints,pure)) }
+
+ident: pure_ident
+         { Ast0.wrap(Ast0.Id(P.id2mcode $1)) }
+     | TMetaId
+         { let (nm,constraints,pure,clt) = $1 in
+         Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) }
+
+decl_ident:
+       TDeclarerId
+         { Ast0.wrap(Ast0.Id(P.id2mcode $1)) }
+     | TMetaDeclarer
+         { let (nm,constraints,pure,clt) = $1 in
+         Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) }
+
+iter_ident:
+       TIteratorId
+         { Ast0.wrap(Ast0.Id(P.id2mcode $1)) }
+     | TMetaIterator
+         { let (nm,constraints,pure,clt) = $1 in
+         Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) }
+
+typedef_ident:
+       pure_ident
+         { Ast0.wrap(Ast0.TypeName(P.id2mcode $1)) }
+     | TMetaType
+         { let (nm,pure,clt) = $1 in
+        Ast0.wrap(Ast0.MetaType(P.clt2mcode nm clt,pure)) }
+
+/*****************************************************************************/
+
+decl_list(decl):
+   decl_list_start(decl)
+     {let circle x =
+       match Ast0.unwrap x with Ast0.Pcircles(_) -> true | _ -> false in
+     if List.exists circle $1
+     then Ast0.wrap(Ast0.CIRCLES($1))
+     else Ast0.wrap(Ast0.DOTS($1)) }
+
+decl_list_start(decl):
+  one_dec(decl)  { [$1] }
+| one_dec(decl) TComma decl_list_start(decl)
+    { $1::Ast0.wrap(Ast0.PComma(P.clt2mcode "," $2))::$3 }
+| TEllipsis list(comma_decls(TEllipsis,decl))
+    { Ast0.wrap(Ast0.Pdots(P.clt2mcode "..." $1))::
+      (List.concat(List.map (function x -> x (P.mkpdots "...")) $2)) }
+
+one_dec(decl):
+  decl  { $1 }
+| TMetaParamList
+    { let (nm,lenname,pure,clt) = $1 in
+    let nm = P.clt2mcode nm clt in
+    let lenname =
+      match lenname with
+       Some nm -> Some(P.clt2mcode nm clt)
+      | None -> None in
+    Ast0.wrap(Ast0.MetaParamList(nm,lenname,pure)) }
+comma_decls(dotter,decl):
+  TComma dotter
+    { function dot_builder ->
+      [Ast0.wrap(Ast0.PComma(P.clt2mcode "," $1));
+       dot_builder $2] }
+| TComma one_dec(decl)
+    { function dot_builder ->
+      [Ast0.wrap(Ast0.PComma(P.clt2mcode "," $1)); $2] }
+
+/* ---------------------------------------------------------------------- */
+
+error_words:
+    TError TWords TEq TOCro cl=comma_list(dexpr) TCCro
+      { [Ast0.wrap(Ast0.ERRORWORDS(cl))] }
+
+/* ---------------------------------------------------------------------- */
+/* sequences of statements and expressions */
+
+/* There are number of cases that must be considered:
+
+1. Top level:
+   Dots and nests allowed at the beginning or end
+   Expressions allowed at the beginning or end
+   One function allowed, by itself
+2. A function body:
+   Dots and nests allowed at the beginning or end
+   Expressions not allowed at the beginning or end
+   Functions not allowed
+3. The body of a nest:
+   Dots and nests not allowed at the beginning or end
+   Expressions allowed at the beginning or end
+   Functions not allowed
+4. Whencode:
+   Dots and nests not allowed at the beginning but allowed at the end
+   Expressions allowed at the beginning or end
+   Functions not allowed
+
+These are implemented by the rules minus_toplevel_sequence,
+plus_toplevel_sequence, function_body_sequence, nest_body_sequence, and
+when_body_sequence.
+*/
+/* ------------------------------------------------------------------------ */
+/* Minus top level */
+
+/* doesn't allow only ... */
+minus_start:
+  fundecl                { [Ast0.wrap(Ast0.DECL($1))] }
+| ctype                  { [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Ty($1))))] }
+| top_init          { [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.TopInit($1))))] }
+| toplevel_seq_start(toplevel_after_dots_init)
+    { List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) $1 }
+
+toplevel_seq_start(after_dots_init):
+  stm_dots after_dots_init           { $1::$2 }
+| expr toplevel_after_exp            { (Ast0.wrap(Ast0.Exp($1)))::$2 }
+| decl_statement_expr toplevel_after_stm  { $1@$2 }
+
+toplevel_after_dots_init:
+  TNothing toplevel_after_exp        {$2}
+| expr toplevel_after_exp            {(Ast0.wrap(Ast0.Exp($1)))::$2}
+| decl_statement_expr toplevel_after_stm  {$1@$2}
+
+toplevel_after_exp:
+  /* empty */                        {[]}
+| stm_dots toplevel_after_dots       {$1::$2}
+
+toplevel_after_dots:
+  /* empty */                        {[]}
+| TNothing toplevel_after_exp        {$2}
+| expr toplevel_after_exp            {(Ast0.wrap(Ast0.Exp($1)))::$2}
+| decl_statement_expr toplevel_after_stm  {$1@$2}
+
+toplevel_after_stm:
+  /* empty */                        {[]}
+| stm_dots toplevel_after_dots       {$1::$2}
+| decl_statement toplevel_after_stm  {$1@$2}
+
+top_init:
+  TOInit initialize_list TCBrace
+    { Ast0.wrap(Ast0.InitList(P.clt2mcode "{" $1,$2,P.clt2mcode "}" $3)) }
+
+/* ------------------------------------------------------------------------ */
+/* Plus top level */
+
+/* does allow only ... also allows multiple top-level functions */
+plus_start:
+  ctype                   { [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Ty($1))))] }
+| top_init           { [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.TopInit($1))))] }
+| stm_dots plus_after_dots
+                                          { (Ast0.wrap(Ast0.OTHER($1)))::$2 }
+| expr plus_after_exp
+                     { (Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Exp($1)))))::$2 }
+| fundecl plus_after_stm                     { Ast0.wrap(Ast0.DECL($1))::$2 }
+| decl_statement_expr plus_after_stm
+                { (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) $1)@$2 }
+
+plus_after_exp:
+  /* empty */                                                            {[]}
+| stm_dots plus_after_dots                { (Ast0.wrap(Ast0.OTHER($1)))::$2 }
+
+plus_after_dots:
+  /* empty */                                                            {[]}
+| TNothing plus_after_exp                                                {$2}
+| expr plus_after_exp
+                     { (Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Exp($1)))))::$2 }
+| fundecl plus_after_stm                     { Ast0.wrap(Ast0.DECL($1))::$2 }
+| decl_statement_expr plus_after_stm
+                { (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) $1)@$2 }
+
+plus_after_stm:
+  /* empty */                                                            {[]}
+| stm_dots plus_after_dots                { (Ast0.wrap(Ast0.OTHER($1)))::$2 }
+| fundecl plus_after_stm                     { Ast0.wrap(Ast0.DECL($1))::$2 }
+| decl_statement plus_after_stm
+                { (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) $1)@$2 }
+
+/* ------------------------------------------------------------------------ */
+/* Function body */
+
+fun_start:
+  fun_after_stm  { Ast0.wrap(Ast0.DOTS($1)) }
+
+fun_after_stm:
+  /* empty */                  {[]}
+| stm_dots fun_after_dots      {$1::$2}
+| decl_statement fun_after_stm {$1@$2}
+
+fun_after_dots:
+  /* empty */                  {[]}
+| TNothing fun_after_exp       {$2}
+| expr fun_after_exp           {Ast0.wrap(Ast0.Exp($1))::$2}
+| decl_statement_expr fun_after_stm {$1@$2}
+
+fun_after_exp:
+  stm_dots fun_after_dots      {$1::$2}
+
+/* hack to allow mixing statements and expressions in an or */
+fun_after_dots_or:
+  /* empty */                  {[]}
+| TNothing fun_after_exp_or    {$2}
+| expr fun_after_exp_or        {Ast0.wrap(Ast0.Exp($1))::$2}
+| decl_statement_expr fun_after_stm {$1@$2}
+
+fun_after_exp_or:
+  /* empty */                  {[]}
+| stm_dots fun_after_dots      {$1::$2}
+
+/* ------------------------------------------------------------------------ */
+/* Nest body */
+
+nest_start:
+  nest_after_dots  { Ast0.wrap(Ast0.DOTS($1)) }
+
+nest_after_dots:
+  decl_statement_expr nest_after_stm {$1@$2}
+| TNothing nest_after_exp       {$2}
+| expr nest_after_exp           {(Ast0.wrap(Ast0.Exp($1)))::$2}
+
+nest_after_stm:
+  /* empty */                   {[]}
+| stm_dots nest_after_dots      {$1::$2}
+| decl_statement nest_after_stm {$1@$2}
+
+nest_after_exp:
+  /* empty */                   {[]}
+| stm_dots nest_after_dots      {$1::$2}
+
+/* ------------------------------------------------------------------------ */
+/*Whencode*/
+
+when_start:
+  expr toplevel_after_exp
+    { Ast0.wrap(Ast0.DOTS((Ast0.wrap(Ast0.Exp($1)))::$2)) }
+| decl_statement toplevel_after_stm
+    { Ast0.wrap(Ast0.DOTS($1@$2)) }
+
+/* ---------------------------------------------------------------------- */
+
+eexpr_list:
+  eexpr_list_start
+     {let circle x =
+       match Ast0.unwrap x with Ast0.Ecircles(_) -> true | _ -> false in
+     let star x =
+       match Ast0.unwrap x with Ast0.Estars(_) -> true | _ -> false in
+     if List.exists circle $1
+     then Ast0.wrap(Ast0.CIRCLES($1))
+     else
+       if List.exists star $1
+       then Ast0.wrap(Ast0.STARS($1))
+       else Ast0.wrap(Ast0.DOTS($1)) }
+
+/* arg expr.  may contain a type or a explist metavariable */
+aexpr:
+    eexpr
+      { Ast0.set_arg_exp $1 }
+  | TMetaExpList
+      { let (nm,lenname,pure,clt) = $1 in
+      let nm = P.clt2mcode nm clt in
+      let lenname =
+       match lenname with
+         Some nm -> Some(P.clt2mcode nm clt)
+       | None -> None in
+      Ast0.wrap(Ast0.MetaExprList(nm,lenname,pure)) }
+  | ctype
+      { Ast0.set_arg_exp(Ast0.wrap(Ast0.TypeExp($1))) }
+
+eexpr_list_start:
+    aexpr { [$1] }
+  | aexpr TComma eexpr_list_start
+      { $1::Ast0.wrap(Ast0.EComma(P.clt2mcode "," $2))::$3 }
+
+comma_args(dotter):
+  c=TComma d=dotter
+    { function dot_builder ->
+      [Ast0.wrap(Ast0.EComma(P.clt2mcode "," c)); dot_builder d] }
+| TComma aexpr
+    { function dot_builder ->
+      [Ast0.wrap(Ast0.EComma(P.clt2mcode "," $1)); $2] }
+
+eexpr_list_option: eexpr_list { $1 }
+         | /* empty */     { Ast0.wrap(Ast0.DOTS([])) }
+
+/****************************************************************************/
+
+// non-empty lists - drop separator
+comma_list(elem):
+  separated_nonempty_list(TComma,elem) { $1 }
+
+midzero_list(elem,aft):
+  a=elem b=list(mzl(aft))
+     { let (mids,code) = List.split b in (mids,(a::code)) }
+
+mzl(elem):
+  a=TMid0 b=elem { (P.clt2mcode "|" a, b) }
+
+edots_when(dotter,when_grammar):
+    d=dotter                                      { (d,None) }
+  | d=dotter TWhen TNotEq w=when_grammar TLineEnd { (d,Some w) }
+
+whens(when_grammar,simple_when_grammar):
+    TWhen TNotEq w=when_grammar TLineEnd { [Ast0.WhenNot w] }
+  | TWhen TEq w=simple_when_grammar TLineEnd { [Ast0.WhenAlways w] }
+  | TWhen comma_list(any_strict) TLineEnd
+      { List.map (function x -> Ast0.WhenModifier(x)) $2 }
+  | TWhenTrue TNotEq e = eexpr TLineEnd { [Ast0.WhenNotTrue e] }
+  | TWhenFalse TNotEq e = eexpr TLineEnd { [Ast0.WhenNotFalse e] }
+
+any_strict:
+    TAny    { Ast.WhenAny }
+  | TStrict { Ast.WhenStrict }
+  | TForall { Ast.WhenForall }
+  | TExists { Ast.WhenExists }
+
+/*****************************************************************************
+*
+*
+*****************************************************************************/
+
+iso_main:
+  TIsoExpression e1=dexpr el=list(iso(dexpr)) EOF
+    { P.iso_adjust (function x -> Ast0.ExprTag x) e1 el }
+| TIsoArgExpression e1=dexpr el=list(iso(dexpr)) EOF
+    { P.iso_adjust (function x -> Ast0.ArgExprTag x) e1 el }
+| TIsoTestExpression e1=dexpr el=list(iso(dexpr)) EOF
+    { P.iso_adjust (function x -> Ast0.TestExprTag x) e1 el }
+| TIsoStatement s1=single_statement sl=list(iso(single_statement)) EOF
+    { P.iso_adjust (function x -> Ast0.StmtTag x) s1 sl }
+| TIsoType t1=ctype tl=list(iso(ctype)) EOF
+    { P.iso_adjust (function x -> Ast0.TypeCTag x) t1 tl }
+| TIsoTopLevel e1=nest_start el=list(iso(nest_start)) EOF
+    { P.iso_adjust (function x -> Ast0.DotsStmtTag x) e1 el }
+| TIsoDeclaration d1=decl_var dl=list(iso(decl_var)) EOF
+    { let check_one = function
+       [x] -> x
+      | _ ->
+         raise
+           (Semantic_cocci.Semantic
+              "only one variable per declaration in an isomorphism rule") in
+    let d1 = check_one d1 in
+    let dl =
+      List.map
+       (function
+           Common.Left x -> Common.Left(check_one x)
+         | Common.Right x -> Common.Right(check_one x))
+       dl in
+    P.iso_adjust (function x -> Ast0.DeclTag x) d1 dl }
+
+iso(term):
+    TIso t=term { Common.Left t }
+  | TRightIso t=term { Common.Right t }
+
+/*****************************************************************************
+*
+*
+*****************************************************************************/
+
+never_used: TPragma { () }
+  | TPArob TMetaPos { () }
+  | TScriptData     { () }
+
+script_meta_main: py=pure_ident TShOp TRuleName TDot cocci=pure_ident TMPtVirg
+  { (P.id2name py, ($3, P.id2name cocci)) }
diff --git a/parsing_cocci/.#unitary_ast0.ml.1.29 b/parsing_cocci/.#unitary_ast0.ml.1.29
new file mode 100644 (file)
index 0000000..31ad2c0
--- /dev/null
@@ -0,0 +1,288 @@
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+* 
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+* 
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
+* 
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+(* find unitary metavariables *)
+module Ast0 = Ast0_cocci
+module Ast = Ast_cocci
+module V0 = Visitor_ast0
+
+let set_minus s minus = List.filter (function n -> not (List.mem n minus)) s
+
+let rec nub = function
+    [] -> []
+  | (x::xs) when (List.mem x xs) -> nub xs
+  | (x::xs) -> x::(nub xs)
+
+(* ----------------------------------------------------------------------- *)
+(* Find the variables that occur free and occur free in a unitary way *)
+
+(* take everything *)
+let minus_checker name = let id = Ast0.unwrap_mcode name in [id]
+
+(* take only what is in the plus code *)
+let plus_checker (nm,_,_,mc,_) =
+  match mc with Ast0.PLUS -> [nm] | _ -> []  
+      
+let get_free checker t =
+  let bind x y = x @ y in
+  let option_default = [] in
+  let donothing r k e = k e in
+  let mcode _ = option_default in
+  
+  (* considers a single list *)
+  let collect_unitary_nonunitary free_usage =
+    let free_usage = List.sort compare free_usage in
+    let rec loop1 todrop = function
+       [] -> []
+      | (x::xs) as all -> if x = todrop then loop1 todrop xs else all in
+    let rec loop2 = function
+       [] -> ([],[])
+      | [x] -> ([x],[])
+      | x::y::xs ->
+         if x = y
+         then
+           let (unitary,non_unitary) = loop2(loop1 x xs) in
+           (unitary,x::non_unitary)
+         else
+           let (unitary,non_unitary) = loop2 (y::xs) in
+           (x::unitary,non_unitary) in
+    loop2 free_usage in
+  
+  (* considers a list of lists *)
+  let detect_unitary_frees l =
+    let (unitary,nonunitary) =
+      List.split (List.map collect_unitary_nonunitary l) in
+    let unitary = nub (List.concat unitary) in
+    let nonunitary = nub (List.concat nonunitary) in
+    let unitary =
+      List.filter (function x -> not (List.mem x nonunitary)) unitary in
+    unitary@nonunitary@nonunitary in
+
+  let whencode afn bfn expression = function
+      Ast0.WhenNot(a) -> afn a
+    | Ast0.WhenAlways(b) -> bfn b
+    | Ast0.WhenModifier(_) -> option_default
+    | Ast0.WhenNotTrue(a) -> expression a
+    | Ast0.WhenNotFalse(a) -> expression a in
+  
+  let ident r k i =
+    match Ast0.unwrap i with
+      Ast0.MetaId(name,_,_) | Ast0.MetaFunc(name,_,_)
+    | Ast0.MetaLocalFunc(name,_,_) -> checker name
+    | _ -> k i in
+  
+  let expression r k e =
+    match Ast0.unwrap e with
+      Ast0.MetaErr(name,_,_) | Ast0.MetaExpr(name,_,_,_,_)
+    | Ast0.MetaExprList(name,_,_) -> checker name
+    | Ast0.DisjExpr(starter,expr_list,mids,ender) ->
+       detect_unitary_frees(List.map r.V0.combiner_expression expr_list)
+    | _ -> k e in
+  
+  let typeC r k t =
+    match Ast0.unwrap t with
+      Ast0.MetaType(name,_) -> checker name
+    | Ast0.DisjType(starter,types,mids,ender) ->
+       detect_unitary_frees(List.map r.V0.combiner_typeC types)
+    | _ -> k t in
+  
+  let parameter r k p =
+    match Ast0.unwrap p with
+      Ast0.MetaParam(name,_) | Ast0.MetaParamList(name,_,_) -> checker name
+    | _ -> k p in
+  
+  let declaration r k d =
+    match Ast0.unwrap d with
+      Ast0.DisjDecl(starter,decls,mids,ender) ->
+       detect_unitary_frees(List.map r.V0.combiner_declaration decls)
+    | _ -> k d in
+
+  let statement r k s =
+    match Ast0.unwrap s with
+      Ast0.MetaStmt(name,_) | Ast0.MetaStmtList(name,_) -> checker name
+    | Ast0.Disj(starter,stmt_list,mids,ender) ->
+       detect_unitary_frees(List.map r.V0.combiner_statement_dots stmt_list)
+    | Ast0.Nest(starter,stmt_dots,ender,whn,multi) ->
+       bind (r.V0.combiner_statement_dots stmt_dots)
+         (detect_unitary_frees 
+            (List.map
+               (whencode r.V0.combiner_statement_dots r.V0.combiner_statement
+                   r.V0.combiner_expression)
+               whn))
+    | Ast0.Dots(d,whn) | Ast0.Circles(d,whn) | Ast0.Stars(d,whn) ->
+       detect_unitary_frees
+         (List.map
+            (whencode r.V0.combiner_statement_dots r.V0.combiner_statement
+               r.V0.combiner_expression)
+            whn)
+    | _ -> k s in
+  
+  let res = V0.combiner bind option_default 
+      mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+      mcode
+      donothing donothing donothing donothing donothing donothing
+      ident expression typeC donothing parameter declaration statement
+      donothing donothing in
+  
+  collect_unitary_nonunitary
+    (List.concat (List.map res.V0.combiner_top_level t))
+    
+(* ----------------------------------------------------------------------- *)
+(* update the variables that are unitary *)
+    
+let update_unitary unitary =
+  let donothing r k e = k e in
+  let mcode x = x in
+  
+  let is_unitary name =
+    match (List.mem (Ast0.unwrap_mcode name) unitary,
+          Ast0.get_mcode_mcodekind name) with
+      (true,Ast0.CONTEXT(mc)) -> Ast0.PureContext
+    | (true,_) -> Ast0.Pure
+    | (false,Ast0.CONTEXT(mc)) -> Ast0.Context
+    | (false,_) -> Ast0.Impure in
+
+  let ident r k i =
+    match Ast0.unwrap i with
+      Ast0.MetaId(name,constraints,_) ->
+       Ast0.rewrap i (Ast0.MetaId(name,constraints,is_unitary name))
+    | Ast0.MetaFunc(name,constraints,_) ->
+       Ast0.rewrap i (Ast0.MetaFunc(name,constraints,is_unitary name))
+    | Ast0.MetaLocalFunc(name,constraints,_) ->
+       Ast0.rewrap i (Ast0.MetaLocalFunc(name,constraints,is_unitary name))
+    | _ -> k i in
+
+  let expression r k e =
+    match Ast0.unwrap e with
+      Ast0.MetaErr(name,constraints,_) ->
+       Ast0.rewrap e (Ast0.MetaErr(name,constraints,is_unitary name))
+    | Ast0.MetaExpr(name,constraints,ty,form,_) ->
+       Ast0.rewrap e (Ast0.MetaExpr(name,constraints,ty,form,is_unitary name))
+    | Ast0.MetaExprList(name,lenname,_) ->
+       Ast0.rewrap e (Ast0.MetaExprList(name,lenname,is_unitary name))
+    | _ -> k e in
+  
+  let typeC r k t =
+    match Ast0.unwrap t with
+      Ast0.MetaType(name,_) ->
+       Ast0.rewrap t (Ast0.MetaType(name,is_unitary name))
+    | _ -> k t in
+  
+  let parameter r k p =
+    match Ast0.unwrap p with
+      Ast0.MetaParam(name,_) ->
+       Ast0.rewrap p (Ast0.MetaParam(name,is_unitary name))
+    | Ast0.MetaParamList(name,lenname,_) ->
+       Ast0.rewrap p (Ast0.MetaParamList(name,lenname,is_unitary name))
+    | _ -> k p in
+  
+  let statement r k s =
+    match Ast0.unwrap s with
+      Ast0.MetaStmt(name,_) ->
+       Ast0.rewrap s (Ast0.MetaStmt(name,is_unitary name))
+    | Ast0.MetaStmtList(name,_) ->
+       Ast0.rewrap s (Ast0.MetaStmtList(name,is_unitary name))
+    | _ -> k s in
+  
+  let res = V0.rebuilder
+      mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+      mcode
+      donothing donothing donothing donothing donothing donothing
+      ident expression typeC donothing parameter donothing statement
+      donothing donothing in
+
+  List.map res.V0.rebuilder_top_level
+
+(* ----------------------------------------------------------------------- *)
+
+let rec split3 = function
+    [] -> ([],[],[])
+  | (a,b,c)::xs -> let (l1,l2,l3) = split3 xs in (a::l1,b::l2,c::l3)
+
+let rec combine3 = function
+    ([],[],[]) -> []
+  | (a::l1,b::l2,c::l3) -> (a,b,c) :: combine3 (l1,l2,l3)
+  | _ -> failwith "not possible"
+
+(* ----------------------------------------------------------------------- *)
+(* process all rules *)
+
+let do_unitary rules =
+  let rec loop = function
+      [] -> ([],[])
+    | (r::rules) ->
+      match r with
+        Ast0.ScriptRule (a,b,c,d) ->
+          let (x,rules) = loop rules in
+          (x, r::rules)
+      | Ast0.CocciRule ((minus,metavars,chosen_isos),((plus,_) as plusz)) ->
+          let mm1 = List.map Ast.get_meta_name metavars in
+          let (used_after, rest) = loop rules in
+          let (m_unitary, m_nonunitary) = get_free minus_checker minus in
+          let (p_unitary, p_nonunitary) = get_free plus_checker plus in
+          let p_free = 
+            if !Flag.sgrep_mode2 then []
+            else p_unitary @ p_nonunitary in
+          let (in_p, m_unitary) =
+            List.partition (function x -> List.mem x p_free) m_unitary in
+          let m_nonunitary = in_p @ m_nonunitary in
+          let (m_unitary, not_local) =
+            List.partition (function x -> List.mem x mm1) m_unitary in
+          let m_unitary =
+            List.filter (function x -> not (List.mem x used_after))
+             m_unitary in
+          let rebuilt = update_unitary m_unitary minus in
+          (set_minus (m_nonunitary @ used_after) mm1,
+             (Ast0.CocciRule
+               ((rebuilt, metavars, chosen_isos),plusz))::rest) in
+  let (_,rules) = loop rules in
+  rules
+
+(*
+let do_unitary minus plus =
+  let (minus,metavars,chosen_isos) = split3 minus in
+  let (plus,_) = List.split plus in
+  let rec loop = function
+      ([],[],[]) -> ([],[])
+    | (mm1::metavars,m1::minus,p1::plus) ->
+       let mm1 = List.map Ast.get_meta_name mm1 in
+       let (used_after,rest) = loop (metavars,minus,plus) in
+       let (m_unitary,m_nonunitary) = get_free minus_checker m1 in
+       let (p_unitary,p_nonunitary) = get_free plus_checker p1 in
+       let p_free =
+         if !Flag.sgrep_mode2
+         then []
+         else p_unitary @ p_nonunitary in
+       let (in_p,m_unitary) =
+         List.partition (function x -> List.mem x p_free) m_unitary in
+       let m_nonunitary = in_p@m_nonunitary in
+       let (m_unitary,not_local) =
+         List.partition (function x -> List.mem x mm1) m_unitary in
+       let m_unitary =
+         List.filter (function x -> not(List.mem x used_after)) m_unitary in
+       let rebuilt = update_unitary m_unitary m1 in
+       (set_minus (m_nonunitary @ used_after) mm1,
+        rebuilt::rest)
+    | _ -> failwith "not possible" in
+  let (_,rules) = loop (metavars,minus,plus) in
+  combine3 (rules,metavars,chosen_isos)
+*)
diff --git a/parsing_cocci/.#unparse_ast0.ml.1.109 b/parsing_cocci/.#unparse_ast0.ml.1.109
new file mode 100644 (file)
index 0000000..7fb2c75
--- /dev/null
@@ -0,0 +1,658 @@
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+* 
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+* 
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
+* 
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+open Format
+module Ast0 = Ast0_cocci
+module U = Pretty_print_cocci
+
+let quiet = ref true (* true = no decoration on - context, etc *)
+
+let start_block str =
+  force_newline(); print_string "  "; open_box 0
+
+let end_block str =
+  close_box(); force_newline ()
+
+let print_option = Common.do_option
+let print_between = Common.print_between
+
+(* --------------------------------------------------------------------- *)
+(* Positions *)
+
+let meta_pos = function
+    Ast0.MetaPos(name,_,_) ->
+      print_string "@";
+      let (_,name) = Ast0.unwrap_mcode name in
+      print_string name
+  | Ast0.NoMetaPos -> ()
+
+(* --------------------------------------------------------------------- *)
+(* Modified code *)
+
+let mcodekind brackets fn x info = function
+    Ast0.MINUS(plus_stream) ->
+      let (lb,rb) =
+       if !quiet
+       then ("","")
+       else
+         match brackets with
+           Some x -> ("[","]^"^(string_of_int x))
+         | None -> ("","") in
+      let (plus_stream,_) = !plus_stream in
+      if !quiet
+      then fn x
+      else (print_string "-";
+           print_string lb; fn x; print_string rb);
+      U.print_anything ">>> " plus_stream
+  | Ast0.CONTEXT(plus_streams) ->
+      let (lb,rb) =
+       if !quiet
+       then ("","")
+       else
+         match brackets with
+           Some x -> ("[",("]^"^(string_of_int x))) | None -> ("","") in
+      let (plus_streams,t1,t2) = !plus_streams in
+      U.print_around
+       (function x ->
+         print_string lb; fn x; print_string rb)
+       x plus_streams
+  | Ast0.PLUS ->
+      List.iter (function s -> print_string s; force_newline())
+       info.Ast0.strings_before;
+      fn x;
+      List.iter (function s -> force_newline(); print_string s)
+       info.Ast0.strings_after
+  | Ast0.MIXED(plus_streams) ->
+      let (lb,rb) =
+       if !quiet
+       then ("","")
+       else
+         let n = 
+           match brackets with Some x -> "^"^(string_of_int x) | None -> "" in
+         ("§","½"^n) in
+      let (plus_streams,_,_) = !plus_streams in
+      U.print_around (function x -> print_string lb; fn x; print_string rb)
+       x plus_streams
+
+let mcode fn (x,_,info,mc,pos) =
+  let fn x = fn x; meta_pos !pos in
+  mcodekind (Some info.Ast0.line_start)(*None*) fn x info mc
+
+let print_context x fn =
+  mcodekind (Some (Ast0.get_line x)) fn () (Ast0.get_info x)
+    (Ast0.get_mcodekind x)
+
+let print_meta (_,name) = print_string name
+
+(* --------------------------------------------------------------------- *)
+(* --------------------------------------------------------------------- *)
+(* Dots *)
+
+let dots between fn d =
+  print_context d
+    (function _ ->
+      match Ast0.unwrap d with
+       Ast0.DOTS(l) -> print_between between fn l
+      | Ast0.CIRCLES(l) -> print_between between fn l
+      | Ast0.STARS(l) -> print_between between fn l)
+
+(* --------------------------------------------------------------------- *)
+
+let print_types = function
+    None -> ()
+  | Some ty ->
+      print_string "/* ";
+      Format.print_flush();
+      print_between (function _ -> print_string ", ") Type_cocci.typeC ty;
+      Format.print_flush();
+      print_string " */"
+
+(* --------------------------------------------------------------------- *)
+(* Identifier *)
+
+let rec ident i =
+  print_context i
+    (function _ ->
+      match Ast0.unwrap i with
+       Ast0.Id(name) -> mcode print_string name
+      | Ast0.MetaId(name,_,_) -> mcode print_meta name
+      | Ast0.MetaFunc(name,_,_) -> mcode print_meta name
+      | Ast0.MetaLocalFunc(name,_,_) -> mcode print_meta name
+      | Ast0.OptIdent(id) -> print_string "?"; ident id
+      | Ast0.UniqueIdent(id) -> print_string "!"; ident id)
+
+(* --------------------------------------------------------------------- *)
+(* Expression *)
+
+let print_string_box s = print_string s; open_box 0
+
+let rec expression e =
+  print_option Type_cocci.typeC (Ast0.get_type e);
+  print_context e
+    (function _ ->
+      match Ast0.unwrap e with
+       Ast0.Ident(id) -> ident id
+      | Ast0.Constant(const) -> mcode U.constant const
+      | Ast0.FunCall(fn,lp,args,rp) ->
+         expression fn; mcode print_string_box lp;
+         let _ = dots (function _ -> ()) expression args in
+         close_box(); mcode print_string rp
+      | Ast0.Assignment(left,op,right,_) ->
+         expression left; print_string " "; mcode U.assignOp op;
+         print_string " "; expression right
+      | Ast0.CondExpr(exp1,why,exp2,colon,exp3) ->
+         expression exp1; print_string " "; mcode print_string why;
+         print_option (function e -> print_string " "; expression e) exp2;
+         print_string " "; mcode print_string colon; expression exp3
+      | Ast0.Postfix(exp,op) -> expression exp; mcode U.fixOp op
+      | Ast0.Infix(exp,op) -> mcode U.fixOp op; expression exp
+      | Ast0.Unary(exp,op) -> mcode U.unaryOp op; expression exp
+      | Ast0.Binary(left,op,right) ->
+         print_string "(";
+         expression left; print_string " "; mcode U.binaryOp op;
+         print_string " "; expression right;
+         print_string ")"
+      | Ast0.Nested(left,op,right) ->
+         print_string "(";
+         expression left; print_string " "; mcode U.binaryOp op;
+         print_string " "; expression right;
+         print_string ")"
+      | Ast0.Paren(lp,exp,rp) ->
+         mcode print_string_box lp; expression exp; close_box();
+         mcode print_string rp
+      | Ast0.ArrayAccess(exp1,lb,exp2,rb) ->
+         expression exp1; mcode print_string_box lb; expression exp2;
+         close_box(); mcode print_string rb
+      | Ast0.RecordAccess(exp,pt,field) ->
+         expression exp; mcode print_string pt; ident field
+      | Ast0.RecordPtAccess(exp,ar,field) ->
+         expression exp; mcode print_string ar; ident field
+      | Ast0.Cast(lp,ty,rp,exp) ->
+         mcode print_string_box lp; typeC ty; close_box();
+         mcode print_string rp; expression exp
+      | Ast0.SizeOfExpr(szf,exp) ->
+         mcode print_string szf; expression exp
+      | Ast0.SizeOfType(szf,lp,ty,rp) ->
+          mcode print_string szf;
+         mcode print_string_box lp; typeC ty; close_box();
+         mcode print_string rp
+      | Ast0.TypeExp(ty) -> typeC ty
+      | Ast0.MetaErr(name,_,_) -> mcode print_meta name
+      | Ast0.MetaExpr(name,_,ty,_,_) ->
+         mcode print_meta name; print_types ty
+      | Ast0.MetaExprList(name,_,_) -> mcode print_meta name
+      | Ast0.EComma(cm) -> mcode print_string cm; print_space()
+      | Ast0.DisjExpr(_,exp_list,_,_) ->
+         print_string "\n("; force_newline();
+         print_between
+           (function _ -> print_string "\n|"; force_newline())
+           expression exp_list;
+         print_string "\n)"
+      | Ast0.NestExpr(starter,expr_dots,ender,None,multi) ->
+         mcode print_string starter;
+         start_block(); dots force_newline expression expr_dots; end_block();
+         mcode print_string ender
+      | Ast0.NestExpr(starter,expr_dots,ender,Some whencode,multi) ->
+         mcode print_string starter; print_string "   WHEN != ";
+         expression whencode;
+         start_block(); dots force_newline expression expr_dots; end_block();
+         mcode print_string ender
+      | Ast0.Edots(dots,Some whencode)
+      | Ast0.Ecircles(dots,Some whencode)
+      | Ast0.Estars(dots,Some whencode) ->
+         mcode print_string dots; print_string "   WHEN != ";
+         expression whencode
+      | Ast0.Edots(dots,None)
+      | Ast0.Ecircles(dots,None)
+      | Ast0.Estars(dots,None) -> mcode print_string dots
+      | Ast0.OptExp(exp) -> print_string "?"; expression exp
+      | Ast0.UniqueExp(exp) -> print_string "!"; expression exp)
+
+and expression_dots x = dots (function _ -> ()) expression x
+
+(* --------------------------------------------------------------------- *)
+(* Types *)
+
+and print_function_pointer (ty,lp1,star,rp1,lp2,params,rp2) fn =
+  typeC ty; mcode print_string lp1; mcode print_string star; fn();
+  mcode print_string rp1; mcode print_string lp2;
+  parameter_list params; mcode print_string rp2
+
+and print_function_type (ty,lp1,params,rp1) fn =
+  print_option typeC ty; fn(); mcode print_string lp1;
+  parameter_list params; mcode print_string rp1
+
+and typeC t =
+  print_context t
+    (function _ ->
+      match Ast0.unwrap t with
+       Ast0.ConstVol(cv,ty) ->
+         mcode U.const_vol cv; print_string " "; typeC ty
+      |        Ast0.BaseType(ty,sgn) ->
+         print_option (mcode U.sign) sgn; mcode U.baseType ty
+      |        Ast0.ImplicitInt(sgn) -> mcode U.sign sgn
+      | Ast0.Pointer(ty,star) -> typeC ty; mcode print_string star
+      | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
+         print_function_pointer (ty,lp1,star,rp1,lp2,params,rp2)
+           (function _ -> ())
+      | Ast0.FunctionType(ty,lp1,params,rp1) ->
+         print_function_type (ty,lp1,params,rp1) (function _ -> ())
+      | Ast0.Array(ty,lb,size,rb) ->
+         typeC ty; mcode print_string lb; print_option expression size;
+         mcode print_string rb
+      | Ast0.StructUnionName(kind,name) ->
+         mcode U.structUnion kind;
+         print_option (function x -> ident x; print_string " ") name
+      | Ast0.StructUnionDef(ty,lb,decls,rb) ->
+         typeC ty; mcode print_string lb;
+         dots force_newline declaration decls;
+         mcode print_string rb
+      | Ast0.TypeName(name)-> mcode print_string name; print_string " "
+      | Ast0.MetaType(name,_)-> mcode print_meta name; print_string " "
+      | Ast0.DisjType(lp,types,mids,rp) ->
+         print_string "\n"; mcode print_string lp; force_newline();
+         print_between
+           (function _ -> print_string "\n|"; force_newline())
+           typeC types;
+         print_string "\n"; mcode print_string rp
+      | Ast0.OptType(ty) -> print_string "?"; typeC ty
+      | Ast0.UniqueType(ty) -> print_string "!"; typeC ty)
+
+(* --------------------------------------------------------------------- *)
+(* Variable declaration *)
+(* Even if the Cocci program specifies a list of declarations, they are
+   split out into multiple declarations of a single variable each. *)
+
+and print_named_type ty id =
+  match Ast0.unwrap ty with
+    Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
+      print_function_pointer (ty,lp1,star,rp1,lp2,params,rp2)
+       (function _ -> print_string " "; ident id)
+  | Ast0.FunctionType(ty,lp1,params,rp1) ->
+      print_function_type (ty,lp1,params,rp1)
+       (function _ -> print_string " "; ident id)
+  | Ast0.Array(ty,lb,size,rb) ->
+      let rec loop ty k =
+       match Ast0.unwrap ty with
+         Ast0.Array(ty,lb,size,rb) ->
+           loop ty
+             (function _ ->
+               k ();
+               mcode print_string lb;
+               print_option expression size;
+               mcode print_string rb)
+       | _ -> typeC ty; ident id; k () in
+      loop ty (function _ -> ())
+  | _ -> typeC ty; ident id
+
+and declaration d =
+  print_context d
+    (function _ ->
+      match Ast0.unwrap d with
+       Ast0.Init(stg,ty,id,eq,ini,sem) ->
+         print_option (mcode U.storage) stg;
+         print_named_type ty id;
+         print_string " ";
+         mcode print_string eq; print_string " "; initialiser ini;
+         mcode print_string sem
+      | Ast0.UnInit(stg,ty,id,sem) ->
+         print_option (mcode U.storage) stg; print_named_type ty id;
+         mcode print_string sem
+      | Ast0.MacroDecl(name,lp,args,rp,sem) ->
+         ident name; mcode print_string_box lp;
+         let _ = dots (function _ -> ()) expression args in
+         close_box(); mcode print_string rp; mcode print_string sem
+      | Ast0.TyDecl(ty,sem) -> typeC ty; mcode print_string sem
+      | Ast0.Typedef(stg,ty,id,sem) ->
+         mcode print_string stg; typeC ty; typeC id;
+         mcode print_string sem
+      | Ast0.DisjDecl(_,decls,_,_) ->
+         print_string "\n("; force_newline();
+         print_between
+           (function _ -> print_string "\n|"; force_newline())
+           declaration decls;
+         print_string "\n)"
+      | Ast0.Ddots(dots,Some whencode) -> 
+         mcode print_string dots; print_string "   when != ";
+         declaration whencode
+      | Ast0.Ddots(dots,None) -> mcode print_string dots
+      | Ast0.OptDecl(decl) -> print_string "?"; declaration decl
+      | Ast0.UniqueDecl(decl) -> print_string "!"; declaration decl)
+
+and declaration_dots l = dots (function _ -> ()) declaration l
+
+(* --------------------------------------------------------------------- *)
+(* Initialiser *)
+
+and initialiser i =
+  print_context i
+    (function _ ->
+      match Ast0.unwrap i with
+       Ast0.InitExpr(exp) -> expression exp
+      | Ast0.InitList(lb,initlist,rb) ->
+         mcode print_string lb; open_box 0;
+         let _ = dots (function _ -> ()) initialiser initlist in
+         close_box(); mcode print_string rb
+      | Ast0.InitGccDotName(dot,name,eq,ini) ->
+         mcode print_string dot; ident name; print_string " ";
+         mcode print_string eq; print_string " "; initialiser ini
+      | Ast0.InitGccName(name,eq,ini) ->
+         ident name; mcode print_string eq; initialiser ini
+      | Ast0.InitGccIndex(lb,exp,rb,eq,ini) ->
+         mcode print_string lb; expression exp; mcode print_string rb;
+         print_string " "; mcode print_string eq; print_string " ";
+         initialiser ini
+      | Ast0.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini) ->
+         mcode print_string lb; expression exp1; mcode print_string dots;
+         expression exp2; mcode print_string rb;
+         print_string " "; mcode print_string eq; print_string " ";
+         initialiser ini
+      | Ast0.IComma(cm) -> mcode print_string cm; force_newline()
+      | Ast0.Idots(d,Some whencode) ->
+         mcode print_string d; print_string "   WHEN != ";
+         initialiser whencode
+      | Ast0.Idots(d,None) -> mcode print_string d
+      | Ast0.OptIni(ini) -> print_string "?"; initialiser ini
+      | Ast0.UniqueIni(ini) -> print_string "!"; initialiser ini)
+
+and initialiser_list l = dots (function _ -> ()) initialiser l
+
+(* --------------------------------------------------------------------- *)
+(* Parameter *)
+
+and parameterTypeDef p =
+  print_context p
+    (function _ ->
+      match Ast0.unwrap p with
+       Ast0.VoidParam(ty) -> typeC ty
+      | Ast0.Param(ty,Some id) -> print_named_type ty id
+      |        Ast0.Param(ty,None) -> typeC ty
+      | Ast0.MetaParam(name,_) -> mcode print_meta name
+      | Ast0.MetaParamList(name,_,_) -> mcode print_meta name
+      | Ast0.PComma(cm) -> mcode print_string cm; print_space()
+      | Ast0.Pdots(dots) -> mcode print_string dots
+      | Ast0.Pcircles(dots) -> mcode print_string dots
+      | Ast0.OptParam(param) -> print_string "?"; parameterTypeDef param
+      | Ast0.UniqueParam(param) -> print_string "!"; parameterTypeDef param)
+
+and parameter_list l = dots (function _ -> ()) parameterTypeDef l
+
+(* --------------------------------------------------------------------- *)
+(* Top-level code *)
+
+and statement arity s =
+  print_context s
+    (function _ ->
+      match Ast0.unwrap s with
+       Ast0.FunDecl(_,fninfo,name,lp,params,rp,lbrace,body,rbrace) ->
+         print_string arity;
+         List.iter print_fninfo fninfo;
+         ident name; mcode print_string_box lp;
+         parameter_list params; close_box(); mcode print_string rp;
+         print_string " ";
+         print_string arity; mcode print_string lbrace; start_block();
+         dots force_newline (statement arity) body;
+         end_block(); print_string arity; mcode print_string rbrace
+      | Ast0.Decl(_,decl) -> print_string arity; declaration decl
+      | Ast0.Seq(lbrace,body,rbrace) ->
+         print_string arity; mcode print_string lbrace; start_block();
+         dots force_newline (statement arity) body;
+         end_block(); print_string arity; mcode print_string rbrace
+      | Ast0.ExprStatement(exp,sem) ->
+         print_string arity; expression exp; mcode print_string sem
+      | Ast0.IfThen(iff,lp,exp,rp,branch1,(info,aft)) ->
+         print_string arity;
+         mcode print_string iff; print_string " "; mcode print_string_box lp;
+         expression exp; close_box(); mcode print_string rp; print_string " ";
+         statement arity branch1;
+         mcode (function _ -> ()) ((),(),info,aft,ref Ast0.NoMetaPos)
+      | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,(info,aft)) ->
+         print_string arity;
+         mcode print_string iff; print_string " "; mcode print_string_box lp;
+         expression exp; close_box(); mcode print_string rp; print_string " ";
+         statement arity branch1;
+         print_string arity; mcode print_string els; print_string " ";
+         statement arity branch2;
+         mcode (function _ -> ()) ((),(),info,aft,ref Ast0.NoMetaPos)
+      | Ast0.While(whl,lp,exp,rp,body,(info,aft)) ->
+         print_string arity;
+         mcode print_string whl; print_string " "; mcode print_string_box lp;
+         expression exp; close_box(); mcode print_string rp; print_string " ";
+         statement arity body;
+         mcode (function _ -> ()) ((),(),info,aft,ref Ast0.NoMetaPos)
+      | Ast0.Do(d,body,whl,lp,exp,rp,sem) ->
+         print_string arity; mcode print_string d; print_string " ";
+         statement arity body;
+         print_string arity;
+         mcode print_string whl; print_string " "; mcode print_string_box lp;
+         expression exp; close_box(); mcode print_string rp;
+         mcode print_string sem
+      | Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,(info,aft)) ->
+         print_string arity;
+         mcode print_string fr; mcode print_string_box lp;
+         print_option expression e1; mcode print_string sem1;
+         print_option expression e2; mcode print_string sem2;
+         print_option expression e3; close_box();
+         mcode print_string rp; print_string " "; statement arity body;
+         mcode (function _ -> ()) ((),(),info,aft,ref Ast0.NoMetaPos)
+      | Ast0.Iterator(nm,lp,args,rp,body,(info,aft)) ->
+         print_string arity;
+         ident nm; print_string " "; mcode print_string_box lp;
+         let _ = dots (function _ -> ()) expression args in
+         close_box(); mcode print_string rp; print_string " ";
+         statement arity body;
+         mcode (function _ -> ()) ((),(),info,aft,ref Ast0.NoMetaPos)
+      |        Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) ->
+         print_string arity;
+         mcode print_string switch; print_string " ";
+         mcode print_string_box lp; expression exp; close_box();
+         mcode print_string rp; print_string " "; mcode print_string lb;
+         dots force_newline (case_line arity) cases;
+         mcode print_string rb
+      | Ast0.Break(br,sem) ->
+         print_string arity; mcode print_string br; mcode print_string sem
+      | Ast0.Continue(cont,sem) ->
+         print_string arity; mcode print_string cont; mcode print_string sem
+      |        Ast0.Label(l,dd) -> ident l; print_string ":"
+      | Ast0.Goto(goto,l,sem) ->
+         mcode print_string goto; ident l; mcode print_string sem
+      | Ast0.Return(ret,sem) ->
+         print_string arity; mcode print_string ret; mcode print_string sem
+      | Ast0.ReturnExpr(ret,exp,sem) ->
+         print_string arity; mcode print_string ret; print_string " ";
+         expression exp; mcode print_string sem
+      | Ast0.MetaStmt(name,pure) ->
+         print_string arity; mcode print_meta name;(*
+         print_string "^";
+         (match pure with
+           Ast0.Pure -> print_string "pure"
+         | Ast0.Impure -> print_string "impure"
+         | Ast0.Context -> print_string "context"
+         | Ast0.PureContext -> print_string "pure_context")*)
+      | Ast0.MetaStmtList(name,_) ->
+         print_string arity;  mcode print_meta name
+      | Ast0.Disj(_,statement_dots_list,_,_) ->
+         print_string arity;
+         print_string "\n("; force_newline();
+         print_between
+           (function _ -> print_string "\n|"; force_newline())
+           (dots force_newline (statement arity))
+           statement_dots_list;
+         print_string "\n)"
+      | Ast0.Nest(starter,stmt_dots,ender,whn,multi) ->
+         print_string arity;
+         mcode print_string starter;
+         open_box 0;
+         List.iter
+           (whencode (dots force_newline (statement "")) (statement ""))
+           whn;
+         close_box();
+         start_block();
+         dots force_newline (statement arity) stmt_dots;
+         end_block();
+         mcode print_string ender
+      | Ast0.Exp(exp) -> print_string arity; expression exp
+      | Ast0.TopExp(exp) -> print_string arity; expression exp
+      | Ast0.Ty(ty) -> print_string arity; typeC ty
+      |        Ast0.TopInit(init) -> initialiser init
+      | Ast0.Dots(d,whn) | Ast0.Circles(d,whn) | Ast0.Stars(d,whn) ->
+         print_string arity; mcode print_string d;
+         List.iter
+           (whencode (dots force_newline (statement "")) (statement ""))
+           whn
+      | Ast0.Include(inc,s) ->
+         mcode print_string inc; print_string " "; mcode U.inc_file s
+      | Ast0.Define(def,id,params,body) ->
+         mcode print_string def; print_string " "; ident id;
+         print_define_parameters params;
+         print_string " ";
+         dots force_newline (statement arity) body
+      | Ast0.OptStm(re) -> statement "?" re
+      | Ast0.UniqueStm(re) -> statement "!" re)
+
+and print_define_parameters params =
+  match Ast0.unwrap params with
+    Ast0.NoParams -> ()
+  | Ast0.DParams(lp,params,rp) ->
+      mcode print_string lp;
+      dots (function _ -> ()) print_define_param params; mcode print_string rp
+
+and print_define_param param =
+  match Ast0.unwrap param with
+    Ast0.DParam(id) -> ident id
+  | Ast0.DPComma(comma) -> mcode print_string comma
+  | Ast0.DPdots(dots) -> mcode print_string dots
+  | Ast0.DPcircles(circles) -> mcode print_string circles
+  | Ast0.OptDParam(dp) -> print_string "?"; print_define_param dp
+  | Ast0.UniqueDParam(dp) -> print_string "!"; print_define_param dp
+
+and print_fninfo = function
+    Ast0.FStorage(stg) -> mcode U.storage stg
+  | Ast0.FType(ty) -> typeC ty
+  | Ast0.FInline(inline) -> mcode print_string inline
+  | Ast0.FAttr(attr) -> mcode print_string attr
+
+and whencode notfn alwaysfn = function
+    Ast0.WhenNot a ->
+      print_string "   WHEN != "; open_box 0; notfn a; close_box()
+  | Ast0.WhenAlways a ->
+      print_string "   WHEN = "; open_box 0; alwaysfn a; close_box()
+  | Ast0.WhenModifier x -> print_string "   WHEN "; U.print_when_modif x
+  | Ast0.WhenNotTrue a ->
+      print_string "   WHEN != TRUE "; open_box 0; expression a; close_box()
+  | Ast0.WhenNotFalse a ->
+      print_string "   WHEN != FALSE "; open_box 0; expression a; close_box()
+
+and case_line arity c =
+  print_context c
+    (function _ ->
+      match Ast0.unwrap c with
+       Ast0.Default(def,colon,code) ->
+         print_string arity;
+         mcode print_string def; mcode print_string colon; print_string " ";
+         dots force_newline (statement arity) code
+      | Ast0.Case(case,exp,colon,code) ->
+         print_string arity;
+         mcode print_string case; print_string " "; expression exp;
+         mcode print_string colon; print_string " ";
+         dots force_newline (statement arity) code
+      | Ast0.OptCase(case) -> case_line "?" case)
+
+and statement_dots l = dots (function _ -> ()) (statement "") l
+and case_dots l = dots (function _ -> ()) (case_line "") l
+
+(* --------------------------------------------------------------------- *)
+(* Top level code *)
+
+let top_level t =
+  print_context t
+    (function _ ->
+      match Ast0.unwrap t with
+       Ast0.FILEINFO(old_file,new_file) ->
+         print_string "--- "; mcode print_string old_file; force_newline();
+         print_string "+++ "; mcode print_string new_file
+      | Ast0.DECL(stmt) -> statement "" stmt
+      | Ast0.CODE(stmt_dots) ->
+         dots force_newline (statement "") stmt_dots
+      | Ast0.ERRORWORDS(exps) ->
+         print_string "error words = [";
+         print_between (function _ -> print_string ", ") expression exps;
+         print_string "]"
+      | Ast0.OTHER(s) ->
+         print_string "OTHER("; statement "" s; print_string ")")
+
+let rule =
+  print_between (function _ -> force_newline(); force_newline()) top_level
+
+let unparse_anything x =
+  let q = !quiet in
+  quiet := true;
+  (match x with
+    Ast0.DotsExprTag(d) ->
+      print_string "ExpDots:"; force_newline();
+      expression_dots d
+  | Ast0.DotsParamTag(d) ->
+      parameter_list d
+  | Ast0.DotsInitTag(d) ->
+      initialiser_list d
+  | Ast0.DotsStmtTag(d) ->
+      print_string "StmDots:"; force_newline();
+      statement_dots d
+  | Ast0.DotsDeclTag(d) ->
+      declaration_dots d
+  | Ast0.DotsCaseTag(d) ->
+      case_dots d
+  | Ast0.IdentTag(d) ->
+      ident d
+  | Ast0.ExprTag(d) | Ast0.ArgExprTag(d) | Ast0.TestExprTag(d) ->
+      print_string "Exp:"; force_newline();
+      expression d
+  | Ast0.TypeCTag(d) ->
+      typeC d
+  | Ast0.ParamTag(d) ->
+      parameterTypeDef d
+  | Ast0.InitTag(d) ->
+      initialiser d
+  | Ast0.DeclTag(d) ->
+      declaration d
+  | Ast0.StmtTag(d) ->
+      print_string "Stm:"; force_newline();
+      statement "" d
+  | Ast0.CaseLineTag(d) ->
+      case_line "" d
+  | Ast0.TopTag(d) ->
+      top_level d
+  | Ast0.IsoWhenTag(x) -> U.print_when_modif x
+  | Ast0.IsoWhenTTag(e) -> expression e
+  | Ast0.IsoWhenFTag(e) -> expression e
+  | Ast0.MetaPosTag(var) -> meta_pos var);
+  quiet := q;
+  print_newline()
+
+let unparse x =
+  print_string "\n@@\n@@";
+  force_newline();
+  force_newline();
+  rule x;
+  print_newline()
+
+let unparse_to_string x = Common.format_to_string (function _ -> unparse x)
diff --git a/parsing_cocci/.#visitor_ast0.ml.1.81 b/parsing_cocci/.#visitor_ast0.ml.1.81
new file mode 100644 (file)
index 0000000..2e258a9
--- /dev/null
@@ -0,0 +1,1038 @@
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+* 
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+* 
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
+* 
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+module Ast = Ast_cocci
+module Ast0 = Ast0_cocci
+
+(* --------------------------------------------------------------------- *)
+(* Generic traversal: combiner *)
+(* parameters:
+   combining function
+   treatment of: mcode, identifiers, expressions, typeCs, types,
+   declarations, statements, toplevels
+   default value for options *)
+
+type 'a combiner =
+    {combiner_ident : Ast0.ident -> 'a;
+      combiner_expression : Ast0.expression -> 'a;
+      combiner_typeC : Ast0.typeC -> 'a;
+      combiner_declaration : Ast0.declaration -> 'a;
+      combiner_initialiser : Ast0.initialiser -> 'a;
+      combiner_initialiser_list : Ast0.initialiser_list -> 'a;
+      combiner_parameter : Ast0.parameterTypeDef -> 'a;
+      combiner_parameter_list : Ast0.parameter_list -> 'a;
+      combiner_statement : Ast0.statement -> 'a;
+      combiner_case_line : Ast0.case_line -> 'a;
+      combiner_top_level : Ast0.top_level -> 'a;
+      combiner_expression_dots :
+         Ast0.expression Ast0.dots -> 'a;
+      combiner_statement_dots :
+             Ast0.statement Ast0.dots -> 'a;
+      combiner_declaration_dots :
+                 Ast0.declaration Ast0.dots -> 'a;
+      combiner_case_line_dots :
+                 Ast0.case_line Ast0.dots -> 'a;
+      combiner_anything : Ast0.anything -> 'a}
+
+
+type ('mc,'a) cmcode = 'mc Ast0.mcode -> 'a
+type ('cd,'a) ccode = 'a combiner -> ('cd -> 'a) -> 'cd -> 'a
+
+let combiner bind option_default 
+    meta_mcode string_mcode const_mcode assign_mcode fix_mcode unary_mcode
+    binary_mcode cv_mcode base_mcode sign_mcode struct_mcode storage_mcode
+    inc_mcode
+    dotsexprfn dotsinitfn dotsparamfn dotsstmtfn dotsdeclfn dotscasefn
+    identfn exprfn
+    tyfn initfn paramfn declfn stmtfn casefn topfn =
+  let multibind l =
+    let rec loop = function
+       [] -> option_default
+      |        [x] -> x
+      |        x::xs -> bind x (loop xs) in
+    loop l in
+  let get_option f = function
+      Some x -> f x
+    | None -> option_default in
+  let rec expression_dots d =
+    let k d =
+      match Ast0.unwrap d with
+       Ast0.DOTS(l) | Ast0.CIRCLES(l) | Ast0.STARS(l) ->
+         multibind (List.map expression l) in
+    dotsexprfn all_functions k d
+  and initialiser_dots d =
+    let k d =
+      match Ast0.unwrap d with
+       Ast0.DOTS(l) | Ast0.CIRCLES(l) | Ast0.STARS(l) ->
+         multibind (List.map initialiser l) in
+    dotsinitfn all_functions k d
+  and parameter_dots d =
+    let k d =
+      match Ast0.unwrap d with
+       Ast0.DOTS(l) | Ast0.CIRCLES(l) | Ast0.STARS(l) ->
+         multibind (List.map parameterTypeDef l) in
+    dotsparamfn all_functions k d
+  and statement_dots d =
+    let k d =
+      match Ast0.unwrap d with
+       Ast0.DOTS(l) | Ast0.CIRCLES(l) | Ast0.STARS(l) ->
+         multibind (List.map statement l) in
+    dotsstmtfn all_functions k d
+  and declaration_dots d =
+    let k d =
+      match Ast0.unwrap d with
+       Ast0.DOTS(l) | Ast0.CIRCLES(l) | Ast0.STARS(l) ->
+         multibind (List.map declaration l) in
+    dotsdeclfn all_functions k d
+  and case_line_dots d =
+    let k d =
+      match Ast0.unwrap d with
+       Ast0.DOTS(l) | Ast0.CIRCLES(l) | Ast0.STARS(l) ->
+         multibind (List.map case_line l) in
+    dotscasefn all_functions k d
+  and ident i =
+    let k i =
+      match Ast0.unwrap i with
+       Ast0.Id(name) -> string_mcode name
+      | Ast0.MetaId(name,_,_) -> meta_mcode name
+      | Ast0.MetaFunc(name,_,_) -> meta_mcode name
+      | Ast0.MetaLocalFunc(name,_,_) -> meta_mcode name
+      | Ast0.OptIdent(id) -> ident id
+      | Ast0.UniqueIdent(id) -> ident id in
+  identfn all_functions k i
+  and expression e =
+    let k e =
+      match Ast0.unwrap e with
+       Ast0.Ident(id) -> ident id
+      | Ast0.Constant(const) -> const_mcode const
+      | Ast0.FunCall(fn,lp,args,rp) ->
+         multibind
+           [expression fn; string_mcode lp; expression_dots args;
+             string_mcode rp]
+      | Ast0.Assignment(left,op,right,_) ->
+         multibind [expression left; assign_mcode op; expression right]
+      | Ast0.CondExpr(exp1,why,exp2,colon,exp3) ->
+         multibind
+           [expression exp1; string_mcode why; get_option expression exp2;
+             string_mcode colon; expression exp3]
+      | Ast0.Postfix(exp,op) -> bind (expression exp) (fix_mcode op)
+      | Ast0.Infix(exp,op) -> bind (fix_mcode op) (expression exp)
+      | Ast0.Unary(exp,op) -> bind (unary_mcode op) (expression exp)
+      | Ast0.Binary(left,op,right) ->
+         multibind [expression left; binary_mcode op; expression right]
+      | Ast0.Nested(left,op,right) ->
+         multibind [expression left; binary_mcode op; expression right]
+      | Ast0.Paren(lp,exp,rp) ->
+         multibind [string_mcode lp; expression exp; string_mcode rp]
+      | Ast0.ArrayAccess(exp1,lb,exp2,rb) ->
+         multibind
+           [expression exp1; string_mcode lb; expression exp2;
+             string_mcode rb]
+      | Ast0.RecordAccess(exp,pt,field) ->
+         multibind [expression exp; string_mcode pt; ident field]
+      | Ast0.RecordPtAccess(exp,ar,field) ->
+         multibind [expression exp; string_mcode ar; ident field]
+      | Ast0.Cast(lp,ty,rp,exp) ->
+         multibind
+           [string_mcode lp; typeC ty; string_mcode rp; expression exp]
+      | Ast0.SizeOfExpr(szf,exp) ->
+         multibind [string_mcode szf; expression exp]
+      | Ast0.SizeOfType(szf,lp,ty,rp) ->
+         multibind
+           [string_mcode szf; string_mcode lp; typeC ty; string_mcode rp]
+      | Ast0.TypeExp(ty) -> typeC ty
+      | Ast0.MetaErr(name,_,_)
+      | Ast0.MetaExpr(name,_,_,_,_)
+      | Ast0.MetaExprList(name,_,_) -> meta_mcode name
+      | Ast0.EComma(cm) -> string_mcode cm
+      | Ast0.DisjExpr(starter,expr_list,mids,ender) ->
+         (match expr_list with
+           [] -> failwith "bad disjunction"
+         | x::xs ->
+             bind (string_mcode starter)
+               (bind (expression x)
+                  (bind
+                     (multibind
+                        (List.map2
+                           (function mid ->
+                             function x ->
+                               bind (string_mcode mid) (expression x))
+                           mids xs))
+                     (string_mcode ender))))
+      | Ast0.NestExpr(starter,expr_dots,ender,whencode,multi) ->
+         bind (string_mcode starter)
+           (bind (expression_dots expr_dots)
+              (bind (string_mcode ender) (get_option expression whencode)))
+      | Ast0.Edots(dots,whencode) | Ast0.Ecircles(dots,whencode)
+      | Ast0.Estars(dots,whencode) ->
+         bind (string_mcode dots) (get_option expression whencode)
+      | Ast0.OptExp(exp) -> expression exp
+      | Ast0.UniqueExp(exp) -> expression exp in
+    exprfn all_functions k e
+  and function_pointer (ty,lp1,star,rp1,lp2,params,rp2) extra =
+    (* have to put the treatment of the identifier into the right position *)
+    multibind
+      ([typeC ty; string_mcode lp1; string_mcode star] @ extra @
+       [string_mcode rp1;
+        string_mcode lp2; parameter_dots params; string_mcode rp2])
+  and function_type (ty,lp1,params,rp1) extra =
+    (* have to put the treatment of the identifier into the right position *)
+    multibind ([get_option typeC ty] @ extra @
+              [string_mcode lp1; parameter_dots params; string_mcode rp1])
+  and array_type (ty,lb,size,rb) extra =
+    multibind
+      ([typeC ty] @ extra @
+       [string_mcode lb; get_option expression size; string_mcode rb])
+  and typeC t =
+    let k t =
+      match Ast0.unwrap t with
+       Ast0.ConstVol(cv,ty) -> bind (cv_mcode cv) (typeC ty)
+      |        Ast0.BaseType(ty,sign) ->
+         bind (get_option sign_mcode sign) (base_mcode ty)
+      |        Ast0.ImplicitInt(sign) -> (sign_mcode sign)
+      | Ast0.Pointer(ty,star) -> bind (typeC ty) (string_mcode star)
+      | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
+         function_pointer (ty,lp1,star,rp1,lp2,params,rp2) []
+      | Ast0.FunctionType(ty,lp1,params,rp1) ->
+         function_type (ty,lp1,params,rp1) []
+      | Ast0.Array(ty,lb,size,rb) ->
+         array_type (ty,lb,size,rb) []
+      | Ast0.StructUnionName(kind,name) ->
+         bind (struct_mcode kind) (get_option ident name)
+      | Ast0.StructUnionDef(ty,lb,decls,rb) ->
+         multibind
+           [typeC ty;string_mcode lb;declaration_dots decls;string_mcode rb]
+      | Ast0.TypeName(name) -> string_mcode name
+      | Ast0.MetaType(name,_) -> meta_mcode name
+      |        Ast0.DisjType(starter,types,mids,ender) ->
+         (match types with
+           [] -> failwith "bad disjunction"
+         | x::xs ->
+             bind (string_mcode starter)
+               (bind (typeC x)
+                  (bind
+                     (multibind
+                        (List.map2
+                           (function mid ->
+                             function x ->
+                               bind (string_mcode mid) (typeC x))
+                           mids xs))
+                     (string_mcode ender))))
+      | Ast0.OptType(ty) -> typeC ty
+      | Ast0.UniqueType(ty) -> typeC ty in
+    tyfn all_functions k t
+  and named_type ty id =
+    match Ast0.unwrap ty with
+      Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
+       function_pointer (ty,lp1,star,rp1,lp2,params,rp2) [ident id]
+    | Ast0.FunctionType(ty,lp1,params,rp1) ->
+       function_type (ty,lp1,params,rp1) [ident id]
+    | Ast0.Array(ty,lb,size,rb) ->
+       array_type (ty,lb,size,rb) [ident id]
+    | _ -> bind (typeC ty) (ident id)
+  and declaration d =
+    let k d =
+      match Ast0.unwrap d with
+       Ast0.Init(stg,ty,id,eq,ini,sem) ->
+         bind (get_option storage_mcode stg)
+           (bind (named_type ty id)
+              (multibind
+                 [string_mcode eq; initialiser ini; string_mcode sem]))
+      | Ast0.UnInit(stg,ty,id,sem) ->
+         bind (get_option storage_mcode stg)
+           (bind (named_type ty id) (string_mcode sem))
+      | Ast0.MacroDecl(name,lp,args,rp,sem) ->
+         multibind
+           [ident name; string_mcode lp; expression_dots args;
+             string_mcode rp; string_mcode sem]
+      | Ast0.TyDecl(ty,sem) -> bind (typeC ty) (string_mcode sem)
+      | Ast0.Typedef(stg,ty,id,sem) ->
+         bind (string_mcode stg)
+           (bind (typeC ty) (bind (typeC id) (string_mcode sem)))
+      |        Ast0.DisjDecl(starter,decls,mids,ender) ->
+         (match decls with
+           [] -> failwith "bad disjunction"
+         | x::xs ->
+             bind (string_mcode starter)
+               (bind (declaration x)
+                  (bind
+                     (multibind
+                        (List.map2
+                           (function mid ->
+                             function x ->
+                               bind (string_mcode mid) (declaration x))
+                           mids xs))
+                     (string_mcode ender))))
+      |        Ast0.Ddots(dots,whencode) ->
+         bind (string_mcode dots) (get_option declaration whencode)
+      | Ast0.OptDecl(decl) -> declaration decl
+      | Ast0.UniqueDecl(decl) -> declaration decl in
+    declfn all_functions k d
+  and initialiser i =
+    let k i =
+      match Ast0.unwrap i with
+       Ast0.InitExpr(exp) -> expression exp
+      | Ast0.InitList(lb,initlist,rb) ->
+         multibind
+           [string_mcode lb; initialiser_dots initlist; string_mcode rb]
+      | Ast0.InitGccDotName(dot,name,eq,ini) ->
+         multibind
+           [string_mcode dot; ident name; string_mcode eq; initialiser ini]
+      | Ast0.InitGccName(name,eq,ini) ->
+         multibind [ident name; string_mcode eq; initialiser ini]
+      | Ast0.InitGccIndex(lb,exp,rb,eq,ini) ->
+         multibind
+           [string_mcode lb; expression exp; string_mcode rb;
+             string_mcode eq; initialiser ini]
+      | Ast0.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini) ->
+         multibind
+           [string_mcode lb; expression exp1; string_mcode dots;
+             expression exp2; string_mcode rb; string_mcode eq;
+             initialiser ini]
+      | Ast0.IComma(cm) -> string_mcode cm
+      | Ast0.Idots(dots,whencode) ->
+         bind (string_mcode dots) (get_option initialiser whencode)
+      | Ast0.OptIni(i) -> initialiser i
+      | Ast0.UniqueIni(i) -> initialiser i in
+    initfn all_functions k i
+  and parameterTypeDef p =
+    let k p =
+      match Ast0.unwrap p with
+       Ast0.VoidParam(ty) -> typeC ty
+      | Ast0.Param(ty,Some id) -> named_type ty id
+      | Ast0.Param(ty,None) -> typeC ty
+      | Ast0.MetaParam(name,_) -> meta_mcode name
+      | Ast0.MetaParamList(name,_,_) -> meta_mcode name
+      | Ast0.PComma(cm) -> string_mcode cm
+      | Ast0.Pdots(dots) -> string_mcode dots
+      | Ast0.Pcircles(dots) -> string_mcode dots
+      | Ast0.OptParam(param) -> parameterTypeDef param
+      | Ast0.UniqueParam(param) -> parameterTypeDef param in
+    paramfn all_functions k p
+
+  (* discard the result, because the statement is assumed to be already
+     represented elsewhere in the code *)
+  and process_bef_aft s =
+    match Ast0.get_dots_bef_aft s with
+      Ast0.NoDots -> ()
+    | Ast0.DroppingBetweenDots(stm) -> let _ = statement stm in ()
+    | Ast0.AddingBetweenDots(stm) -> let _ = statement stm in ()
+
+  and statement s =
+    process_bef_aft s;
+    let k s =
+      match Ast0.unwrap s with
+       Ast0.FunDecl(_,fi,name,lp,params,rp,lbrace,body,rbrace) ->
+         multibind
+           ((List.map fninfo fi) @
+            [ident name; string_mcode lp;
+              parameter_dots params; string_mcode rp; string_mcode lbrace;
+              statement_dots body; string_mcode rbrace])
+      | Ast0.Decl(_,decl) -> declaration decl
+      | Ast0.Seq(lbrace,body,rbrace) ->
+         multibind
+           [string_mcode lbrace; statement_dots body; string_mcode rbrace]
+      | Ast0.ExprStatement(exp,sem) ->
+         bind (expression exp) (string_mcode sem)
+      | Ast0.IfThen(iff,lp,exp,rp,branch1,_) ->
+         multibind
+           [string_mcode iff; string_mcode lp; expression exp;
+             string_mcode rp; statement branch1]
+      | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,_) ->
+         multibind
+           [string_mcode iff; string_mcode lp; expression exp;
+             string_mcode rp; statement branch1; string_mcode els;
+             statement branch2]
+      | Ast0.While(whl,lp,exp,rp,body,_) ->
+         multibind
+           [string_mcode whl; string_mcode lp; expression exp;
+             string_mcode rp; statement body]
+      | Ast0.Do(d,body,whl,lp,exp,rp,sem) ->
+         multibind
+           [string_mcode d; statement body; string_mcode whl;
+             string_mcode lp; expression exp; string_mcode rp;
+             string_mcode sem]
+      | Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,_) ->
+         multibind
+           [string_mcode fr; string_mcode lp; get_option expression e1;
+             string_mcode sem1; get_option expression e2; string_mcode sem2;
+             get_option expression e3;
+             string_mcode rp; statement body]
+      | Ast0.Iterator(nm,lp,args,rp,body,_) ->
+         multibind
+           [ident nm; string_mcode lp; expression_dots args;
+             string_mcode rp; statement body]
+      |        Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) ->
+         multibind
+           [string_mcode switch; string_mcode lp; expression exp;
+             string_mcode rp; string_mcode lb; case_line_dots cases;
+             string_mcode rb]
+      | Ast0.Break(br,sem) -> bind (string_mcode br) (string_mcode sem)
+      | Ast0.Continue(cont,sem) -> bind (string_mcode cont) (string_mcode sem)
+      |        Ast0.Label(l,dd) -> bind (ident l) (string_mcode dd)
+      |        Ast0.Goto(goto,l,sem) ->
+         bind (string_mcode goto) (bind (ident l) (string_mcode sem))
+      | Ast0.Return(ret,sem) -> bind (string_mcode ret) (string_mcode sem)
+      | Ast0.ReturnExpr(ret,exp,sem) ->
+         multibind [string_mcode ret; expression exp; string_mcode sem]
+      | Ast0.MetaStmt(name,_) -> meta_mcode name
+      | Ast0.MetaStmtList(name,_) -> meta_mcode name
+      | Ast0.Disj(starter,statement_dots_list,mids,ender) ->
+         (match statement_dots_list with
+           [] -> failwith "bad disjunction"
+         | x::xs ->
+             bind (string_mcode starter)
+               (bind (statement_dots x)
+                  (bind
+                     (multibind
+                        (List.map2
+                           (function mid ->
+                             function x ->
+                               bind (string_mcode mid) (statement_dots x))
+                           mids xs))
+                     (string_mcode ender))))
+      | Ast0.Nest(starter,stmt_dots,ender,whn,multi) ->
+         bind (string_mcode starter)
+           (bind (statement_dots stmt_dots)
+              (bind (string_mcode ender)
+                 (multibind
+                    (List.map (whencode statement_dots statement) whn))))
+      | Ast0.Exp(exp) -> expression exp
+      | Ast0.TopExp(exp) -> expression exp
+      | Ast0.Ty(ty) -> typeC ty
+      | Ast0.TopInit(init) -> initialiser init
+      | Ast0.Dots(d,whn) | Ast0.Circles(d,whn) | Ast0.Stars(d,whn) ->
+         bind (string_mcode d)
+           (multibind (List.map (whencode statement_dots statement) whn))
+      | Ast0.Include(inc,name) -> bind (string_mcode inc) (inc_mcode name)
+      | Ast0.Define(def,id,params,body) ->
+         multibind [string_mcode def; ident id; define_parameters params;
+                     statement_dots body]
+      | Ast0.OptStm(re) -> statement re
+      | Ast0.UniqueStm(re) -> statement re in
+    stmtfn all_functions k s
+
+  (* not parameterizable for now... *)
+  and define_parameters p =
+    let k p =
+      match Ast0.unwrap p with
+       Ast0.NoParams -> option_default
+      | Ast0.DParams(lp,params,rp) ->
+         multibind
+           [string_mcode lp; define_param_dots params; string_mcode rp] in
+    k p
+
+  and define_param_dots d =
+    let k d =
+      match Ast0.unwrap d with
+       Ast0.DOTS(l) | Ast0.CIRCLES(l) | Ast0.STARS(l) ->
+         multibind (List.map define_param l) in
+    k d
+
+  and define_param p =
+    let k p =
+      match Ast0.unwrap p with
+       Ast0.DParam(id) -> ident id
+      | Ast0.DPComma(comma) -> string_mcode comma
+      | Ast0.DPdots(d) -> string_mcode d
+      | Ast0.DPcircles(c) -> string_mcode c
+      | Ast0.OptDParam(dp) -> define_param dp
+      | Ast0.UniqueDParam(dp) -> define_param dp in
+    k p 
+
+  and fninfo = function
+      Ast0.FStorage(stg) -> storage_mcode stg
+    | Ast0.FType(ty) -> typeC ty
+    | Ast0.FInline(inline) -> string_mcode inline
+    | Ast0.FAttr(init) -> string_mcode init
+
+  and whencode notfn alwaysfn = function
+      Ast0.WhenNot a -> notfn a
+    | Ast0.WhenAlways a -> alwaysfn a
+    | Ast0.WhenModifier(_) -> option_default
+    | Ast0.WhenNotTrue(e) -> expression e
+    | Ast0.WhenNotFalse(e) -> expression e
+
+  and case_line c =
+    let k c =
+      match Ast0.unwrap c with
+       Ast0.Default(def,colon,code) ->
+         multibind [string_mcode def;string_mcode colon;statement_dots code]
+      | Ast0.Case(case,exp,colon,code) ->
+         multibind [string_mcode case;expression exp;string_mcode colon;
+                     statement_dots code]
+      |        Ast0.OptCase(case) -> case_line case in
+    casefn all_functions k c
+
+  and anything a = (* for compile_iso, not parameterisable *)
+    let k = function
+       Ast0.DotsExprTag(exprs) -> expression_dots exprs
+      | Ast0.DotsInitTag(inits) -> initialiser_dots inits
+      | Ast0.DotsParamTag(params) -> parameter_dots params
+      | Ast0.DotsStmtTag(stmts) -> statement_dots stmts
+      | Ast0.DotsDeclTag(decls) -> declaration_dots decls
+      | Ast0.DotsCaseTag(cases) -> case_line_dots cases
+      | Ast0.IdentTag(id) -> ident id
+      | Ast0.ExprTag(exp) -> expression exp
+      | Ast0.ArgExprTag(exp) -> expression exp
+      | Ast0.TestExprTag(exp) -> expression exp
+      | Ast0.TypeCTag(ty) -> typeC ty
+      | Ast0.ParamTag(param) -> parameterTypeDef param
+      | Ast0.InitTag(init) -> initialiser init
+      | Ast0.DeclTag(decl) -> declaration decl
+      | Ast0.StmtTag(stmt) -> statement stmt
+      | Ast0.CaseLineTag(c) -> case_line c
+      | Ast0.TopTag(top) -> top_level top
+      | Ast0.IsoWhenTag(_) -> option_default
+      | Ast0.IsoWhenTTag(e) -> expression e
+      | Ast0.IsoWhenFTag(e) -> expression e
+      |        Ast0.MetaPosTag(var) -> failwith "not supported" in
+    k a
+
+  and top_level t =
+    let k t =
+      match Ast0.unwrap t with
+       Ast0.FILEINFO(old_file,new_file) ->
+         bind (string_mcode old_file) (string_mcode new_file)
+      | Ast0.DECL(stmt_dots) -> statement stmt_dots
+      | Ast0.CODE(stmt_dots) -> statement_dots stmt_dots
+      | Ast0.ERRORWORDS(exps) -> multibind (List.map expression exps)
+      | Ast0.OTHER(_) -> failwith "unexpected code" in
+    topfn all_functions k t
+  and all_functions =
+    {combiner_ident = ident;
+      combiner_expression = expression;
+      combiner_typeC = typeC;
+      combiner_declaration = declaration;
+      combiner_initialiser = initialiser;
+      combiner_initialiser_list = initialiser_dots;
+      combiner_parameter = parameterTypeDef;
+      combiner_parameter_list = parameter_dots;
+      combiner_statement = statement;
+      combiner_case_line = case_line;
+      combiner_top_level = top_level;
+      combiner_expression_dots = expression_dots;
+      combiner_statement_dots = statement_dots;
+      combiner_declaration_dots = declaration_dots;
+      combiner_case_line_dots = case_line_dots;
+      combiner_anything = anything} in
+  all_functions
+
+(* --------------------------------------------------------------------- *)
+(* Generic traversal: rebuilder *)
+
+type 'a inout = 'a -> 'a (* for specifying the type of rebuilder *)
+
+type rebuilder =
+    {rebuilder_ident : Ast0.ident inout;
+      rebuilder_expression : Ast0.expression inout;
+      rebuilder_typeC : Ast0.typeC inout;
+      rebuilder_declaration : Ast0.declaration inout;
+      rebuilder_initialiser : Ast0.initialiser inout;
+      rebuilder_initialiser_list : Ast0.initialiser_list inout;
+      rebuilder_parameter : Ast0.parameterTypeDef inout;
+      rebuilder_parameter_list : Ast0.parameter_list inout;
+      rebuilder_statement : Ast0.statement inout;
+      rebuilder_case_line : Ast0.case_line inout;
+      rebuilder_top_level : Ast0.top_level inout;
+      rebuilder_expression_dots :
+       Ast0.expression Ast0.dots ->
+         Ast0.expression Ast0.dots;
+         rebuilder_statement_dots :
+           Ast0.statement Ast0.dots ->
+             Ast0.statement Ast0.dots;
+         rebuilder_declaration_dots :
+           Ast0.declaration Ast0.dots ->
+             Ast0.declaration Ast0.dots;
+         rebuilder_case_line_dots :
+           Ast0.case_line Ast0.dots ->
+             Ast0.case_line Ast0.dots;
+         rebuilder_anything :
+           Ast0.anything -> Ast0.anything}
+
+type 'mc rmcode = 'mc Ast0.mcode inout
+type 'cd rcode = rebuilder -> ('cd inout) -> 'cd inout
+
+let rebuilder = fun
+    meta_mcode string_mcode const_mcode assign_mcode fix_mcode unary_mcode
+    binary_mcode cv_mcode base_mcode sign_mcode struct_mcode storage_mcode
+    inc_mcode
+    dotsexprfn dotsinitfn dotsparamfn dotsstmtfn dotsdeclfn dotscasefn
+    identfn exprfn tyfn initfn paramfn declfn stmtfn casefn topfn ->
+  let get_option f = function
+      Some x -> Some (f x)
+    | None -> None in
+  let rec expression_dots d =
+    let k d =
+      Ast0.rewrap d
+       (match Ast0.unwrap d with
+         Ast0.DOTS(l) -> Ast0.DOTS(List.map expression l)
+       | Ast0.CIRCLES(l) -> Ast0.CIRCLES(List.map expression l)
+       | Ast0.STARS(l) -> Ast0.STARS(List.map expression l)) in
+    dotsexprfn all_functions k d
+  and initialiser_list i =
+    let k i =
+      Ast0.rewrap i
+       (match Ast0.unwrap i with
+         Ast0.DOTS(l) -> Ast0.DOTS(List.map initialiser l)
+       | Ast0.CIRCLES(l) -> Ast0.CIRCLES(List.map initialiser l)
+       | Ast0.STARS(l) -> Ast0.STARS(List.map initialiser l)) in
+    dotsinitfn all_functions k i
+  and parameter_list d =
+    let k d =
+      Ast0.rewrap d
+       (match Ast0.unwrap d with
+         Ast0.DOTS(l) -> Ast0.DOTS(List.map parameterTypeDef l)
+       | Ast0.CIRCLES(l) -> Ast0.CIRCLES(List.map parameterTypeDef l)
+       | Ast0.STARS(l) -> Ast0.STARS(List.map parameterTypeDef l)) in
+    dotsparamfn all_functions k d
+  and statement_dots d =
+    let k d =
+      Ast0.rewrap d
+       (match Ast0.unwrap d with
+         Ast0.DOTS(l) -> Ast0.DOTS(List.map statement l)
+       | Ast0.CIRCLES(l) -> Ast0.CIRCLES(List.map statement l)
+       | Ast0.STARS(l) -> Ast0.STARS(List.map statement l)) in
+    dotsstmtfn all_functions k d
+  and declaration_dots d =
+    let k d =
+      Ast0.rewrap d
+       (match Ast0.unwrap d with
+         Ast0.DOTS(l) -> Ast0.DOTS(List.map declaration l)
+       | Ast0.CIRCLES(l) -> Ast0.CIRCLES(List.map declaration l)
+       | Ast0.STARS(l) -> Ast0.STARS(List.map declaration l)) in
+    dotsdeclfn all_functions k d
+  and case_line_dots d =
+    let k d =
+      Ast0.rewrap d
+       (match Ast0.unwrap d with
+         Ast0.DOTS(l) -> Ast0.DOTS(List.map case_line l)
+       | Ast0.CIRCLES(l) -> Ast0.CIRCLES(List.map case_line l)
+       | Ast0.STARS(l) -> Ast0.STARS(List.map case_line l)) in
+    dotscasefn all_functions k d
+  and ident i =
+    let k i =
+      Ast0.rewrap i
+       (match Ast0.unwrap i with
+         Ast0.Id(name) -> Ast0.Id(string_mcode name)
+       | Ast0.MetaId(name,constraints,pure) ->
+           Ast0.MetaId(meta_mcode name,constraints,pure)
+       | Ast0.MetaFunc(name,constraints,pure) ->
+           Ast0.MetaFunc(meta_mcode name,constraints,pure)
+       | Ast0.MetaLocalFunc(name,constraints,pure) ->
+           Ast0.MetaLocalFunc(meta_mcode name,constraints,pure)
+       | Ast0.OptIdent(id) -> Ast0.OptIdent(ident id)
+       | Ast0.UniqueIdent(id) -> Ast0.UniqueIdent(ident id)) in
+    identfn all_functions k i
+  and expression e =
+    let k e =
+      Ast0.rewrap e
+       (match Ast0.unwrap e with
+         Ast0.Ident(id) -> Ast0.Ident(ident id)
+       | Ast0.Constant(const) -> Ast0.Constant(const_mcode const)
+       | Ast0.FunCall(fn,lp,args,rp) ->
+           Ast0.FunCall(expression fn,string_mcode lp,expression_dots args,
+                        string_mcode rp)
+       | Ast0.Assignment(left,op,right,simple) ->
+           Ast0.Assignment(expression left,assign_mcode op,expression right,
+                           simple)
+       | Ast0.CondExpr(exp1,why,exp2,colon,exp3) ->
+           Ast0.CondExpr(expression exp1, string_mcode why,
+                         get_option expression exp2, string_mcode colon,
+                         expression exp3)
+       | Ast0.Postfix(exp,op) -> Ast0.Postfix(expression exp, fix_mcode op)
+       | Ast0.Infix(exp,op) -> Ast0.Infix(expression exp, fix_mcode op)
+       | Ast0.Unary(exp,op) -> Ast0.Unary(expression exp, unary_mcode op)
+       | Ast0.Binary(left,op,right) ->
+           Ast0.Binary(expression left, binary_mcode op, expression right)
+       | Ast0.Nested(left,op,right) ->
+           Ast0.Nested(expression left, binary_mcode op, expression right)
+       | Ast0.Paren(lp,exp,rp) ->
+           Ast0.Paren(string_mcode lp, expression exp, string_mcode rp)
+       | Ast0.ArrayAccess(exp1,lb,exp2,rb) ->
+           Ast0.ArrayAccess(expression exp1,string_mcode lb,expression exp2,
+                            string_mcode rb)
+       | Ast0.RecordAccess(exp,pt,field) ->
+           Ast0.RecordAccess(expression exp, string_mcode pt, ident field)
+       | Ast0.RecordPtAccess(exp,ar,field) ->
+           Ast0.RecordPtAccess(expression exp, string_mcode ar, ident field)
+       | Ast0.Cast(lp,ty,rp,exp) ->
+           Ast0.Cast(string_mcode lp, typeC ty, string_mcode rp,
+                     expression exp)
+       | Ast0.SizeOfExpr(szf,exp) ->
+           Ast0.SizeOfExpr(string_mcode szf, expression exp)
+       | Ast0.SizeOfType(szf,lp,ty,rp) ->
+           Ast0.SizeOfType(string_mcode szf,string_mcode lp, typeC ty, 
+                            string_mcode rp)
+       | Ast0.TypeExp(ty) -> Ast0.TypeExp(typeC ty)
+       | Ast0.MetaErr(name,constraints,pure) ->
+           Ast0.MetaErr(meta_mcode name,constraints,pure)
+       | Ast0.MetaExpr(name,constraints,ty,form,pure) ->
+           Ast0.MetaExpr(meta_mcode name,constraints,ty,form,pure)
+       | Ast0.MetaExprList(name,lenname,pure) ->
+           Ast0.MetaExprList(meta_mcode name,lenname,pure)
+       | Ast0.EComma(cm) -> Ast0.EComma(string_mcode cm)
+       | Ast0.DisjExpr(starter,expr_list,mids,ender) ->
+           Ast0.DisjExpr(string_mcode starter,List.map expression expr_list,
+                         List.map string_mcode mids,string_mcode ender)
+       | Ast0.NestExpr(starter,expr_dots,ender,whencode,multi) ->
+           Ast0.NestExpr(string_mcode starter,expression_dots expr_dots,
+                         string_mcode ender, get_option expression whencode,
+                         multi)
+       | Ast0.Edots(dots,whencode) ->
+           Ast0.Edots(string_mcode dots, get_option expression whencode)
+       | Ast0.Ecircles(dots,whencode) ->
+           Ast0.Ecircles(string_mcode dots, get_option expression whencode)
+       | Ast0.Estars(dots,whencode) ->
+           Ast0.Estars(string_mcode dots, get_option expression whencode)
+       | Ast0.OptExp(exp) -> Ast0.OptExp(expression exp)
+       | Ast0.UniqueExp(exp) -> Ast0.UniqueExp(expression exp)) in
+    exprfn all_functions k e
+  and typeC t =
+    let k t =
+      Ast0.rewrap t
+       (match Ast0.unwrap t with
+         Ast0.ConstVol(cv,ty) -> Ast0.ConstVol(cv_mcode cv,typeC ty)
+       | Ast0.BaseType(ty,sign) ->
+           Ast0.BaseType(base_mcode ty, get_option sign_mcode sign)
+       | Ast0.ImplicitInt(sign) -> Ast0.ImplicitInt(sign_mcode sign)
+       | Ast0.Pointer(ty,star) ->
+           Ast0.Pointer(typeC ty, string_mcode star)
+       | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
+           Ast0.FunctionPointer(typeC ty,string_mcode lp1,string_mcode star,
+                                string_mcode rp1,string_mcode lp2,
+                                parameter_list params,
+                                string_mcode rp2)
+       | Ast0.FunctionType(ty,lp1,params,rp1) ->
+           Ast0.FunctionType(get_option typeC ty,
+                             string_mcode lp1,parameter_list params,
+                             string_mcode rp1)
+       | Ast0.Array(ty,lb,size,rb) ->
+           Ast0.Array(typeC ty, string_mcode lb,
+                      get_option expression size, string_mcode rb)
+       | Ast0.StructUnionName(kind,name) ->
+           Ast0.StructUnionName (struct_mcode kind, get_option ident name)
+       | Ast0.StructUnionDef(ty,lb,decls,rb) ->
+           Ast0.StructUnionDef (typeC ty,
+                                string_mcode lb, declaration_dots decls,
+                                string_mcode rb)
+       | Ast0.TypeName(name) -> Ast0.TypeName(string_mcode name)
+       | Ast0.MetaType(name,pure) ->
+           Ast0.MetaType(meta_mcode name,pure)
+       | Ast0.DisjType(starter,types,mids,ender) ->
+           Ast0.DisjType(string_mcode starter,List.map typeC types,
+                         List.map string_mcode mids,string_mcode ender)
+       | Ast0.OptType(ty) -> Ast0.OptType(typeC ty)
+       | Ast0.UniqueType(ty) -> Ast0.UniqueType(typeC ty)) in
+    tyfn all_functions k t
+  and declaration d =
+    let k d =
+      Ast0.rewrap d
+       (match Ast0.unwrap d with
+         Ast0.Init(stg,ty,id,eq,ini,sem) ->
+           Ast0.Init(get_option storage_mcode stg,
+                     typeC ty, ident id, string_mcode eq, initialiser ini,
+                     string_mcode sem)
+       | Ast0.UnInit(stg,ty,id,sem) ->
+           Ast0.UnInit(get_option storage_mcode stg,
+                       typeC ty, ident id, string_mcode sem)
+       | Ast0.MacroDecl(name,lp,args,rp,sem) ->
+           Ast0.MacroDecl(ident name,string_mcode lp,
+                          expression_dots args,
+                          string_mcode rp,string_mcode sem)
+       | Ast0.TyDecl(ty,sem) -> Ast0.TyDecl(typeC ty, string_mcode sem)
+       | Ast0.Typedef(stg,ty,id,sem) ->
+           Ast0.Typedef(string_mcode stg, typeC ty, typeC id,
+                        string_mcode sem)
+       | Ast0.DisjDecl(starter,decls,mids,ender) ->
+           Ast0.DisjDecl(string_mcode starter,List.map declaration decls,
+                         List.map string_mcode mids,string_mcode ender)
+       | Ast0.Ddots(dots,whencode) ->
+           Ast0.Ddots(string_mcode dots, get_option declaration whencode)
+       | Ast0.OptDecl(decl) -> Ast0.OptDecl(declaration decl)
+       | Ast0.UniqueDecl(decl) -> Ast0.UniqueDecl(declaration decl)) in
+    declfn all_functions k d
+  and initialiser i =
+    let k i =
+      Ast0.rewrap i
+       (match Ast0.unwrap i with
+         Ast0.InitExpr(exp) -> Ast0.InitExpr(expression exp)
+       | Ast0.InitList(lb,initlist,rb) ->
+           Ast0.InitList(string_mcode lb, initialiser_list initlist,
+                         string_mcode rb)
+       | Ast0.InitGccDotName(dot,name,eq,ini) ->
+           Ast0.InitGccDotName
+             (string_mcode dot, ident name, string_mcode eq, initialiser ini)
+       | Ast0.InitGccName(name,eq,ini) ->
+           Ast0.InitGccName(ident name, string_mcode eq, initialiser ini)
+       | Ast0.InitGccIndex(lb,exp,rb,eq,ini) ->
+           Ast0.InitGccIndex
+             (string_mcode lb, expression exp, string_mcode rb,
+              string_mcode eq, initialiser ini)
+       | Ast0.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini) ->
+           Ast0.InitGccRange
+             (string_mcode lb, expression exp1, string_mcode dots,
+              expression exp2, string_mcode rb, string_mcode eq,
+              initialiser ini)
+       | Ast0.IComma(cm) -> Ast0.IComma(string_mcode cm)
+       | Ast0.Idots(d,whencode) ->
+           Ast0.Idots(string_mcode d, get_option initialiser whencode)
+       | Ast0.OptIni(i) -> Ast0.OptIni(initialiser i)
+       | Ast0.UniqueIni(i) -> Ast0.UniqueIni(initialiser i)) in
+    initfn all_functions k i
+  and parameterTypeDef p =
+    let k p =
+      Ast0.rewrap p
+       (match Ast0.unwrap p with
+         Ast0.VoidParam(ty) -> Ast0.VoidParam(typeC ty)
+       | Ast0.Param(ty,id) -> Ast0.Param(typeC ty, get_option ident id)
+       | Ast0.MetaParam(name,pure) ->
+           Ast0.MetaParam(meta_mcode name,pure)
+       | Ast0.MetaParamList(name,lenname,pure) ->
+           Ast0.MetaParamList(meta_mcode name,lenname,pure)
+       | Ast0.PComma(cm) -> Ast0.PComma(string_mcode cm)
+       | Ast0.Pdots(dots) -> Ast0.Pdots(string_mcode dots)
+       | Ast0.Pcircles(dots) -> Ast0.Pcircles(string_mcode dots)
+       | Ast0.OptParam(param) -> Ast0.OptParam(parameterTypeDef param)
+       | Ast0.UniqueParam(param) ->
+           Ast0.UniqueParam(parameterTypeDef param)) in
+    paramfn all_functions k p
+  (* not done for combiner, because the statement is assumed to be already
+     represented elsewhere in the code *)
+  and process_bef_aft s =
+    Ast0.set_dots_bef_aft s
+      (match Ast0.get_dots_bef_aft s with
+       Ast0.NoDots -> Ast0.NoDots
+      | Ast0.DroppingBetweenDots(stm) ->
+         Ast0.DroppingBetweenDots(statement stm)
+      | Ast0.AddingBetweenDots(stm) ->
+         Ast0.AddingBetweenDots(statement stm))
+
+  and statement s =
+    let k s =
+      Ast0.rewrap s
+       (match Ast0.unwrap s with
+         Ast0.FunDecl(bef,fi,name,lp,params,rp,lbrace,body,rbrace) ->
+           Ast0.FunDecl(bef,List.map fninfo fi, ident name,
+                        string_mcode lp, parameter_list params,
+                        string_mcode rp, string_mcode lbrace,
+                        statement_dots body, string_mcode rbrace)
+       | Ast0.Decl(bef,decl) -> Ast0.Decl(bef,declaration decl)
+       | Ast0.Seq(lbrace,body,rbrace) ->
+           Ast0.Seq(string_mcode lbrace, statement_dots body,
+                    string_mcode rbrace)
+       | Ast0.ExprStatement(exp,sem) ->
+           Ast0.ExprStatement(expression exp, string_mcode sem)
+       | Ast0.IfThen(iff,lp,exp,rp,branch1,aft) ->
+           Ast0.IfThen(string_mcode iff, string_mcode lp, expression exp,
+             string_mcode rp, statement branch1,aft)
+       | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,aft) ->
+           Ast0.IfThenElse(string_mcode iff,string_mcode lp,expression exp,
+             string_mcode rp, statement branch1, string_mcode els,
+             statement branch2,aft)
+       | Ast0.While(whl,lp,exp,rp,body,aft) ->
+           Ast0.While(string_mcode whl, string_mcode lp, expression exp,
+                      string_mcode rp, statement body, aft)
+       | Ast0.Do(d,body,whl,lp,exp,rp,sem) ->
+           Ast0.Do(string_mcode d, statement body, string_mcode whl,
+                   string_mcode lp, expression exp, string_mcode rp,
+                   string_mcode sem)
+       | Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,aft) ->
+           Ast0.For(string_mcode fr, string_mcode lp,
+                    get_option expression e1, string_mcode sem1,
+                    get_option expression e2, string_mcode sem2,
+                    get_option expression e3,
+                    string_mcode rp, statement body, aft)
+       | Ast0.Iterator(nm,lp,args,rp,body,aft) ->
+           Ast0.Iterator(ident nm, string_mcode lp,
+                         expression_dots args,
+                         string_mcode rp, statement body, aft)
+       | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) ->
+           Ast0.Switch(string_mcode switch,string_mcode lp,expression exp,
+                       string_mcode rp,string_mcode lb,
+                       case_line_dots cases, string_mcode rb)
+       | Ast0.Break(br,sem) ->
+           Ast0.Break(string_mcode br,string_mcode sem)
+       | Ast0.Continue(cont,sem) ->
+           Ast0.Continue(string_mcode cont,string_mcode sem)
+       | Ast0.Label(l,dd) -> Ast0.Label(ident l,string_mcode dd)
+       | Ast0.Goto(goto,l,sem) ->
+           Ast0.Goto(string_mcode goto,ident l,string_mcode sem)
+       | Ast0.Return(ret,sem) ->
+           Ast0.Return(string_mcode ret,string_mcode sem)
+       | Ast0.ReturnExpr(ret,exp,sem) ->
+           Ast0.ReturnExpr(string_mcode ret,expression exp,string_mcode sem)
+       | Ast0.MetaStmt(name,pure) ->
+           Ast0.MetaStmt(meta_mcode name,pure)
+       | Ast0.MetaStmtList(name,pure) ->
+           Ast0.MetaStmtList(meta_mcode name,pure)
+       | Ast0.Disj(starter,statement_dots_list,mids,ender) ->
+           Ast0.Disj(string_mcode starter,
+                     List.map statement_dots statement_dots_list,
+                     List.map string_mcode mids,
+                     string_mcode ender)
+       | Ast0.Nest(starter,stmt_dots,ender,whn,multi) ->
+           Ast0.Nest(string_mcode starter,statement_dots stmt_dots,
+                     string_mcode ender,
+                     List.map (whencode statement_dots statement) whn,
+                     multi)
+       | Ast0.Exp(exp) -> Ast0.Exp(expression exp)
+       | Ast0.TopExp(exp) -> Ast0.TopExp(expression exp)
+       | Ast0.Ty(ty) -> Ast0.Ty(typeC ty)
+       | Ast0.TopInit(init) -> Ast0.TopInit(initialiser init)
+       | Ast0.Dots(d,whn) ->
+           Ast0.Dots(string_mcode d,
+                     List.map (whencode statement_dots statement) whn)
+       | Ast0.Circles(d,whn) ->
+           Ast0.Circles(string_mcode d,
+                        List.map (whencode statement_dots statement) whn)
+       | Ast0.Stars(d,whn) ->
+           Ast0.Stars(string_mcode d,
+                      List.map (whencode statement_dots statement) whn)
+       | Ast0.Include(inc,name) ->
+           Ast0.Include(string_mcode inc,inc_mcode name)
+       | Ast0.Define(def,id,params,body) ->
+           Ast0.Define(string_mcode def,ident id,
+                       define_parameters params,
+                       statement_dots body)
+       | Ast0.OptStm(re) -> Ast0.OptStm(statement re)
+       | Ast0.UniqueStm(re) -> Ast0.UniqueStm(statement re)) in
+    let s = stmtfn all_functions k s in
+    process_bef_aft s
+
+  (* not parameterizable for now... *)
+  and define_parameters p =
+    let k p =
+      Ast0.rewrap p
+       (match Ast0.unwrap p with
+         Ast0.NoParams -> Ast0.NoParams
+       | Ast0.DParams(lp,params,rp) ->
+           Ast0.DParams(string_mcode lp,define_param_dots params,
+                        string_mcode rp))in
+    k p
+
+  and define_param_dots d =
+    let k d =
+      Ast0.rewrap d
+       (match Ast0.unwrap d with
+         Ast0.DOTS(l) -> Ast0.DOTS(List.map define_param l)
+       | Ast0.CIRCLES(l) -> Ast0.CIRCLES(List.map define_param l)
+       | Ast0.STARS(l) -> Ast0.STARS(List.map define_param l)) in
+    k d
+
+  and define_param p =
+    let k p =
+      Ast0.rewrap p
+       (match Ast0.unwrap p with
+         Ast0.DParam(id) -> Ast0.DParam(ident id)
+       | Ast0.DPComma(comma) -> Ast0.DPComma(string_mcode comma)
+       | Ast0.DPdots(d) -> Ast0.DPdots(string_mcode d)
+       | Ast0.DPcircles(c) -> Ast0.DPcircles(string_mcode c)
+       | Ast0.OptDParam(dp) -> Ast0.OptDParam(define_param dp)
+       | Ast0.UniqueDParam(dp) -> Ast0.UniqueDParam(define_param dp)) in
+    k p
+
+  and fninfo = function
+      Ast0.FStorage(stg) -> Ast0.FStorage(storage_mcode stg)
+    | Ast0.FType(ty) -> Ast0.FType(typeC ty)
+    | Ast0.FInline(inline) -> Ast0.FInline(string_mcode inline)
+    | Ast0.FAttr(init) -> Ast0.FAttr(string_mcode init)
+
+  and whencode notfn alwaysfn = function
+      Ast0.WhenNot a -> Ast0.WhenNot (notfn a)
+    | Ast0.WhenAlways a -> Ast0.WhenAlways (alwaysfn a)
+    | Ast0.WhenModifier(x) -> Ast0.WhenModifier(x)
+    | Ast0.WhenNotTrue(e) -> Ast0.WhenNotTrue(expression e)
+    | Ast0.WhenNotFalse(e) -> Ast0.WhenNotFalse(expression e)
+
+  and case_line c =
+    let k c =
+      Ast0.rewrap c
+       (match Ast0.unwrap c with
+         Ast0.Default(def,colon,code) ->
+           Ast0.Default(string_mcode def,string_mcode colon,
+                        statement_dots code)
+       | Ast0.Case(case,exp,colon,code) ->
+           Ast0.Case(string_mcode case,expression exp,string_mcode colon,
+                     statement_dots code)
+       | Ast0.OptCase(case) -> Ast0.OptCase(case_line case)) in
+    casefn all_functions k c
+
+  and top_level t =
+    let k t =
+      Ast0.rewrap t
+       (match Ast0.unwrap t with
+         Ast0.FILEINFO(old_file,new_file) ->
+           Ast0.FILEINFO(string_mcode old_file, string_mcode new_file)
+       | Ast0.DECL(statement_dots) ->
+           Ast0.DECL(statement statement_dots)
+       | Ast0.CODE(stmt_dots) -> Ast0.CODE(statement_dots stmt_dots)
+       | Ast0.ERRORWORDS(exps) -> Ast0.ERRORWORDS(List.map expression exps)
+       | Ast0.OTHER(_) -> failwith "unexpected code") in
+    topfn all_functions k t
+
+  and anything a = (* for compile_iso, not parameterisable *)
+    let k = function
+       Ast0.DotsExprTag(exprs) -> Ast0.DotsExprTag(expression_dots exprs)
+      | Ast0.DotsInitTag(inits) -> Ast0.DotsInitTag(initialiser_list inits)
+      | Ast0.DotsParamTag(params) -> Ast0.DotsParamTag(parameter_list params)
+      | Ast0.DotsStmtTag(stmts) -> Ast0.DotsStmtTag(statement_dots stmts)
+      | Ast0.DotsDeclTag(decls) -> Ast0.DotsDeclTag(declaration_dots decls)
+      | Ast0.DotsCaseTag(cases) -> Ast0.DotsCaseTag(case_line_dots cases)
+      | Ast0.IdentTag(id) -> Ast0.IdentTag(ident id)
+      | Ast0.ExprTag(exp) -> Ast0.ExprTag(expression exp)
+      | Ast0.ArgExprTag(exp) -> Ast0.ArgExprTag(expression exp)
+      | Ast0.TestExprTag(exp) -> Ast0.TestExprTag(expression exp)
+      | Ast0.TypeCTag(ty) -> Ast0.TypeCTag(typeC ty)
+      | Ast0.ParamTag(param) -> Ast0.ParamTag(parameterTypeDef param)
+      | Ast0.InitTag(init) -> Ast0.InitTag(initialiser init)
+      | Ast0.DeclTag(decl) -> Ast0.DeclTag(declaration decl)
+      | Ast0.StmtTag(stmt) -> Ast0.StmtTag(statement stmt)
+      | Ast0.CaseLineTag(c) -> Ast0.CaseLineTag(case_line c)
+      | Ast0.TopTag(top) -> Ast0.TopTag(top_level top)
+      | Ast0.IsoWhenTag(x) -> Ast0.IsoWhenTag(x)
+      | Ast0.IsoWhenTTag(e) -> Ast0.IsoWhenTTag(expression e)
+      | Ast0.IsoWhenFTag(e) -> Ast0.IsoWhenFTag(expression e)
+      |        Ast0.MetaPosTag(var) -> failwith "not supported" in
+    k a
+
+  (* not done for combiner, because the statement is assumed to be already
+     represented elsewhere in the code *)
+
+  and all_functions =
+    {rebuilder_ident = ident;
+      rebuilder_expression = expression;
+      rebuilder_typeC = typeC;
+      rebuilder_declaration = declaration;
+      rebuilder_initialiser = initialiser;
+      rebuilder_initialiser_list = initialiser_list;
+      rebuilder_parameter = parameterTypeDef;
+      rebuilder_parameter_list = parameter_list;
+      rebuilder_statement = statement;
+      rebuilder_case_line = case_line;
+      rebuilder_top_level = top_level;
+      rebuilder_expression_dots = expression_dots;
+      rebuilder_statement_dots = statement_dots;
+      rebuilder_declaration_dots = declaration_dots;
+      rebuilder_case_line_dots = case_line_dots;
+      rebuilder_anything = anything} in
+  all_functions
index 5d9f214..02cb0f9 100644 (file)
@@ -580,22 +580,24 @@ exception TyConv
 let rec reverse_type ty =
   match ty with
     Type_cocci.ConstVol(cv,ty) ->
-      ConstVol(reverse_const_vol cv,wrap(reverse_type ty))
+      ConstVol(reverse_const_vol cv,context_wrap(reverse_type ty))
   | Type_cocci.BaseType(bty,None) ->
       BaseType(reverse_baseType bty,None)
   | Type_cocci.BaseType(bty,Some sgn) ->
       BaseType(reverse_baseType bty,Some (reverse_sign sgn))
   | Type_cocci.Pointer(ty) ->
-      Pointer(wrap(reverse_type ty),make_mcode "*")
+      Pointer(context_wrap(reverse_type ty),make_mcode "*")
   | Type_cocci.StructUnionName(su,mv,tag) ->
       if mv
       then
        (* not right... *)
-       StructUnionName(reverse_structUnion su,
-                       Some(wrap(MetaId(make_mcode ("",tag),[],Impure))))
+       StructUnionName
+         (reverse_structUnion su,
+          Some(context_wrap(MetaId(make_mcode ("",tag),[],Impure))))
       else
-       StructUnionName(reverse_structUnion su,
-                       Some (wrap(Id(make_mcode tag))))
+       StructUnionName
+         (reverse_structUnion su,
+          Some (context_wrap(Id(make_mcode tag))))
   | Type_cocci.TypeName(name) -> TypeName(make_mcode name)
   | Type_cocci.MetaType(name,_,_) ->
       MetaType(make_mcode name,Impure(*not really right*))
index abc2054..86d6a8f 100644 (file)
@@ -875,6 +875,12 @@ let rec is_ty s =
   | Ast0.Disj(_,stmts,_,_) -> isall is_ty stmts
   | _ -> false
 
+let rec is_init s =
+  match Ast0.unwrap s with
+    Ast0.TopInit(e) -> true
+  | Ast0.Disj(_,stmts,_,_) -> isall is_init stmts
+  | _ -> false
+
 let rec is_decl s =
   match Ast0.unwrap s with
     Ast0.Decl(_,e) -> true
@@ -920,17 +926,23 @@ let check_compatible m p =
       let v2 = is_decl decl2 in
       if v1 && not v2 then fail()
   | (Ast0.CODE(code1),Ast0.CODE(code2)) ->
-      let testers = [is_exp;is_ty] in
-      List.iter
-       (function tester ->
-         let v1 = isonly tester code1 in
-         let v2 = isonly tester code2 in
-         if (v1 && not v2) or (!Flag.make_hrule = None && v2 && not v1)
-         then fail())
-       testers;
-      let v1 = isonly is_fndecl code1 in
-      let v2 = List.for_all is_toplevel (Ast0.undots code2) in
-      if !Flag.make_hrule = None && v1 && not v2 then fail()
+      let v1 = isonly is_init code1 in
+      let v2a = isonly is_init code2 in
+      let v2b = isonly is_exp code2 in
+      if v1
+      then (if not (v2a || v2b) then fail())
+      else
+       let testers = [is_exp;is_ty] in
+       List.iter
+         (function tester ->
+           let v1 = isonly tester code1 in
+           let v2 = isonly tester code2 in
+           if (v1 && not v2) or (!Flag.make_hrule = None && v2 && not v1)
+           then fail())
+         testers;
+       let v1 = isonly is_fndecl code1 in
+       let v2 = List.for_all is_toplevel (Ast0.undots code2) in
+       if !Flag.make_hrule = None && v1 && not v2 then fail()
   | (Ast0.FILEINFO(_,_),Ast0.FILEINFO(_,_)) -> ()
   | (Ast0.OTHER(_),Ast0.OTHER(_)) -> ()
   | _ -> fail()
index f7975b8..6b6875d 100644 (file)
@@ -119,8 +119,9 @@ type reason =
   | NonMatch
   | Braces of Ast0.statement
   | Position of string * string
+  | TypeMatch of reason list
 
-let interpret_reason name line reason printer =
+let rec interpret_reason name line reason printer =
   Printf.printf
     "warning: iso %s does not match the code below on line %d\n" name line;
   printer(); Format.print_newline();
@@ -155,6 +156,9 @@ let interpret_reason name line reason printer =
   | Position(rule,name) ->
       Printf.printf "position variable %s.%s conflicts with an isomorphism\n"
        rule name;
+  | TypeMatch reason_list ->
+      List.iter (function r -> interpret_reason name line r printer)
+       reason_list
   | _ -> failwith "not possible"
 
 type 'a either = OK of 'a | Fail of reason
@@ -342,14 +346,18 @@ let match_maker checks_needed context_required whencode_allowed =
   let pure_sp_code =
     let bind = Ast0.lub_pure in
     let option_default = Ast0.Context in
-    let pure_mcodekind = function
-       Ast0.CONTEXT(mc) ->
-         (match !mc with
-           (Ast.NOTHING,_,_) -> Ast0.PureContext
-         | _ -> Ast0.Context)
-      | Ast0.MINUS(mc) ->
-         (match !mc with ([],_) -> Ast0.Pure | _ ->  Ast0.Impure)
-      | _ -> Ast0.Impure in
+    let pure_mcodekind mc =
+      if !Flag.sgrep_mode2
+      then Ast0.PureContext
+      else
+       match mc with
+         Ast0.CONTEXT(mc) ->
+           (match !mc with
+             (Ast.NOTHING,_,_) -> Ast0.PureContext
+           | _ -> Ast0.Context)
+       | Ast0.MINUS(mc) ->
+           (match !mc with ([],_) -> Ast0.Pure | _ ->  Ast0.Impure)
+       | _ -> Ast0.Impure in
     let donothing r k e =
       bind (pure_mcodekind (Ast0.get_mcodekind e)) (k e) in
 
@@ -522,34 +530,46 @@ let match_maker checks_needed context_required whencode_allowed =
                    (match expty with
                      Some expty ->
                        let tyname = Ast0.rewrap_mcode name tyname in
-                       (function bindings ->
-                         let attempts =
-                           List.map
-                             (function expty ->
-                               (try
-                                 conjunct_bindings
-                                   (add_pure_binding tyname Ast0.Impure
-                                      (function _ -> Ast0.Impure)
-                                      (function ty -> Ast0.TypeCTag ty)
-                                      (Ast0.rewrap expr
-                                         (Ast0.reverse_type expty)))
-                                   (add_pure_binding name pure
-                                      pure_sp_code.V0.combiner_expression
-                                      (function expr -> Ast0.ExprTag expr)
-                                      expr)
-                                   bindings
-                               with Ast0.TyConv ->
-                                 Printf.printf "warning: unconvertible type";
-                                 return false bindings))
-                             expty in
-                         match
-                           List.concat
-                             (List.map (function Fail _ -> [] | OK x -> x)
-                                attempts)
-                         with
-                           [] -> Fail NonMatch
-                         | x -> OK x)
-                   |   _ ->
+                       conjunct_bindings
+                         (add_pure_binding name pure
+                            pure_sp_code.V0.combiner_expression
+                            (function expr -> Ast0.ExprTag expr)
+                            expr)
+                         (function bindings ->
+                           let attempts =
+                             List.map
+                               (function expty ->
+                                 (try
+                                   add_pure_binding tyname Ast0.Impure
+                                     (function _ -> Ast0.Impure)
+                                     (function ty -> Ast0.TypeCTag ty)
+                                     (Ast0.rewrap expr
+                                        (Ast0.reverse_type expty))
+                                     bindings
+                                 with Ast0.TyConv ->
+                                   Printf.printf
+                                     "warning: unconvertible type";
+                                   return false bindings))
+                               expty in
+                           if List.exists
+                               (function Fail _ -> false | OK x -> true)
+                               attempts
+                           then
+                               (* not sure why this is ok. can there be more
+                                than one OK? *)
+                             OK (List.concat
+                                   (List.map
+                                      (function Fail _ -> [] | OK x -> x)
+                                      attempts))
+                           else
+                             Fail
+                               (TypeMatch
+                                  (List.map
+                                     (function
+                                         Fail r -> r
+                                       | OK x -> failwith "not possible")
+                                     attempts)))
+                   | _ ->
                  (*Printf.printf
                     "warning: type metavar can only match one type";*)
                        return false)
@@ -1239,10 +1259,11 @@ let make_minus =
       Ast0.DOTS([]) ->
        (* if context is - this should be - as well.  There are no tokens
           here though, so the bottom-up minusifier in context_neg leaves it
-          as mixed.  It would be better to fix context_neg, but that would
+          as mixed (or context for sgrep2).  It would be better to fix
+          context_neg, but that would
           require a special case for each term with a dots subterm. *)
        (match !mcodekind with
-         Ast0.MIXED(mc) ->
+         Ast0.MIXED(mc) | Ast0.CONTEXT(mc) ->
            (match !mc with
              (Ast.NOTHING,_,_) ->
                mcodekind := Ast0.MINUS(ref([],Ast0.default_token_info));
@@ -1253,8 +1274,8 @@ let make_minus =
        | _ ->
            failwith
              (Printf.sprintf
-                "%d: make_minus donothingxxx: unexpected mcodekind"
-                info.Ast0.line_start))
+                "%d: make_minus donothingxxx: unexpected mcodekind: %s"
+                info.Ast0.line_start (Dumper.dump e)))
     | _ -> donothing r k e in
   
   V0.rebuilder
@@ -2095,7 +2116,8 @@ let transform_expr (metavars,alts,name) e =
       (function b -> function mv_b ->
        (instantiate b mv_b).V0.rebuilder_expression)
       (function e -> Ast0.ExprTag e)
-      (make_disj_expr e) make_minus.V0.rebuilder_expression
+      (make_disj_expr e)
+      make_minus.V0.rebuilder_expression
       (rebuild_mcode start_line).V0.rebuilder_expression
       name Unparse_ast0.expression extra_copy_other_plus update_others in
   match alts with
@@ -2194,7 +2216,8 @@ let transform_top (metavars,alts,name) e =
              (function s -> Ast0.DotsStmtTag s)
              (function x ->
                Ast0.rewrap e (Ast0.DOTS([make_disj_stmt_list x])))
-             make_minus.V0.rebuilder_statement_dots
+             (function x ->
+               make_minus.V0.rebuilder_statement_dots x)
              (rebuild_mcode start_line).V0.rebuilder_statement_dots
              name Unparse_ast0.statement_dots extra_copy_other_plus do_nothing
        | _ -> ([],stmts) in
index e798752..2abc53a 100644 (file)
@@ -1332,19 +1332,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           Obj.repr _v
   
   let default_reduction =
-    (16, "\000\000\000\000\001 \001!\000\000\001#\001\"\000\001\000\000\001[\000\000\000\000\000\136\000\000\000\000\001\214\000\142\000\145\002\197\002\196\000\146\001\013\001\019\001\015\001\018\001\017\000\135\001\011\001\026\000\000\000\000\001\025\000\000\000\000\000\000\000\000\000\000\001O\000\232\002\187\002q\000\000\000\000\000\000\000\000\000\000\002\192\000\000\001\022\000\000\002\194\000\000\001\029\001\028\000\000\000\000\002\252\002;\000\000\002\250\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\253\000\000\002U\000\000\000\000\002\249\002\251\002A\001\004\002@\001\002\001\003\002?\002>\002=\0029\000\000\000\000\002:\000\205\000\000\002<\000\000\002\248\000\000\002\223\001\001\002\028\000\000\000\000\002\031\000\000\000\015\000\000\000\000\000\000\000\000\000\206\0028\002D\000[\000\021\000]\000\000\000\000\000c\000\000\000\000\000\000\000\000\000\000\000\000\000\022\000\000\000\023\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\130\001\251\000R\000\215\000^\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\\\000T\000\000\000S\000\000\000\000\000\140\000\216\000\000\002\"\000\217\000\014\000\000\001\014\001\020\001\016\001\012\000\016\000\000\000\000\000\143\000\000\000\141\000\000\000\000\000\220\000\000\000\000\002\029\002 \000\000\002\030\002!\002\224\002\222\000\000\002B\002\221\000\000\002]\000\000\000\000\001\190\000\000\001i\001\171\000\000\000\000\002\\\000\000\002\240\002[\002Z\002Y\002X\002W\002S\000\000\000\000\002T\000\000\002V\000\000\000\000\002\237\002*\000\000\000\000\002-\000\000\000\000\0020\000\000\000\000\002+\002.\000\000\002,\002/\002^\002R\002\238\002\236\002\235\002\239\000\000\000\000\000\000\000g\000h\000\000\000\000\000W\000\000\000V\000\227\000\000\001\206\000\000\000\000\000\000\000\000\000\000\000\210\001\212\000\000\000\000\001s\000U\0001\000\203\000_\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\000\000\0003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002C\000\000\000\144\000\000\000\000\001\189\000\000\001g\001\170\000\000\000\000\000d\000\000\002\255\000\000\000\000\001\207\000\000\000\000\002\226\002\225\000\000\000Q\000\147\000\000\001Q\000\000\002\190\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\226\000\151\000\000\000\000\000n\000o\001\225\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\160\001\195\000\000\000\148\000\155\000\000\001\197\000\000\000\000\000\000\000\000\000\149\000\161\000\000\001W\000\000\000\000\002\189\000\000\000\000\000\138\000\000\000\000\002\188\000\000\000\000\000\000\002\191\002\195\000\000\000\000\000\000\001\023\000\000\000\214\000\000\001\024\000\000\000\000\001:\000\000\0019\000\000\001G\000\000\001]\000\000\000\000\000\000\000\000\000\000\000\000\001\008\000\000\000\000\002\219\000\000\000\189\002\218\002\183\002\185\002\186\002\184\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002b\000\000\000\000\000\000\000\000\002i\000\000\000\000\002h\002g\002f\002e\002d\0016\002`\000\000\000\000\002a\000\000\002c\000\000\000\000\002\244\0021\000\000\000\000\0024\000\000\000\000\0027\000\000\000\000\0022\0025\000\000\0023\0026\002k\002_\002\245\002\243\002\242\000i\000j\000\000\000\000\000Z\000\000\000Y\000\000\002j\000\000\001\172\000X\000?\000\226\000`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\134\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\247\002\246\000\000\002\174\000\000\002\173\000\000\000\000\000\000\000\000\003\004\000\000\000\000\000\000\003\005\000\000\000\018\000\000\000\000\000\000\003\000\000\000\001u\000\000\000\000\000\000\000\162\002\164\001M\000\000\000\153\001L\001%\001$\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\178\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\207\000\208\000\195\000\000\001Y\000\000\000\000\000\194\000\190\000\000\000\197\000\191\000\196\000\000\002\176\000\000\002\175\002\161\000\000\000\000\000\000\000\000\000\000\002\170\000\000\000\000\000\000\000\000\000\000\002\171\002\163\000\000\002\177\000\000\002\165\000\000\000\166\000\000\002\180\000\152\000\000\001'\000\000\000\000\000\000\000\000\000\000\000\000\001\t\000\000\000w\000\000\000\000\000\000\002H\000\000\000\000\000\000\002P\000\000\000\000\002O\000\000\002\233\002N\002M\002L\002K\002J\002F\000\000\000\000\002G\000\000\002I\000\000\000\000\002\230\002#\000\000\000\000\002&\000\000\000\000\002)\000\000\000\000\002$\002'\000\000\002%\002(\002Q\002E\002\231\002\229\002\228\002\232\000\000\000\000\000\000\000e\000f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\212\001(\000\000\000\000\000\000\001.\000\000\000\000\001/\000#\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000$\000\000\000%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001-\0012\000\000\001,\000\000\000\000\0014\000\000\000\000\000\000\000\000\000\000\000\000\000t\000q\000r\0015\0011\000\000\000\000\0010\001*\000\000\001)\000\000\000\182\000\000\002\142\000\000\000\000\000\178\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\185\000\000\000\000\000\188\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\007\000\000\000\000\000\000\000\175\000\000\000\172\000\000\000\000\000\000\000\000\000\000\000\183\000\000\000\179\000\000\000\000\002\201\000\000\002\208\000\168\000\000\000\000\000\000\000\000\000\180\000\000\000\176\000\173\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\184\000\000\000\000\000\187\000\000\002\202\000\167\000\000\002\203\000\000\002\210\000\000\000\000\000\000\000\000\000\186\000\000\000\170\000\000\000\000\000\000\000\000\001\006\000\000\000\000\000\000\000\174\000\000\000\171\000\000\000\000\000\000\000\000\000\000\000\181\000\000\000\177\000\164\000\163\000\000\002\211\002\212\000\000\002\213\000\000\002\214\000\000\001&\002\168\000\000\000\000\001\194\000\000\001q\001\176\000\000\002\162\000\000\000\000\000\000\002\167\000\000\000\000\000\000\000\250\000\000\000\244\000\000\000\245\000\000\000\255\000\243\000\254\000\000\002\179\001\000\000\000\000\169\000\000\000\000\000\000\000\000\000\252\000\247\001\191\000\000\000\248\000\000\000\249\000\000\001k\001\173\000\000\000\000\000\000\001\202\000\000\001\200\000\000\000\000\001\204\001\198\000\000\001\205\001\199\000\000\002\181\001\208\000\000\000\165\000\000\000\000\001\192\000\000\001m\001\174\000\000\003\001\000\000\002\253\000\000\002\254\000\019\000\020\000\000\000\000\002\127\000\000\002~\000\000\000\000\002\129\000\000\002\128\000\000\000\000\000\000\001\235\000\000\000\000\001\239\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\242\000\000\000\000\001\245\000\000\000\000\001\229\000\000\000\000\001\232\000\000\000\000\000\000\001\236\000\000\000\000\001\240\000\000\000\000\001\193\000\000\000\000\001\233\000\000\000\000\001\237\002|\001\230\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\241\000\000\000\000\001\244\000\000\002}\000\000\000\000\000\000\000\000\001\243\000\000\001\227\000\000\001\228\000\000\000\000\001\231\000\000\000\000\000\000\001\234\000\000\000\000\001\238\000\000\001o\001\175\000\000\002\130\000\000\000\000\000\000\003\002\000\017\000u\000\000\003\003\000\000\000\000\002\138\000\000\000\000\002\182\000a\000\000\000\000\000\000\000b\000\000\002\172\000\000\001S\002\169\000\000\000\000\001@\000\000\001?\000\000\001H\000\000\001c\000\000\000\000\000\000\001>\000\000\001=\000\000\001E\000\000\001a\000\000\000\000\000\000\001B\000\000\001A\000\000\001F\000\000\001e\000\000\000\000\000\000\001C\000\000\000\000\000\000\000\000\001<\000\000\001;\000\000\001I\000\000\001_\000\000\000\000\000\000\001D\000\002\000\000\000N\000O\000M\001J\000\003\000\000\000\000\002n\000\000\001\249\000\000\002t\002v\000\000\000\000\001\140\002u\000\128\000\000\000\000\002\160\000\000\000\000\000\000\000z\000\000\000\000\002\148\000\000\001\222\001\221\001\135\002z\002r\002s\000\000\001\167\000\000\002o\000\000\000\000\000|\000\000\000\000\002\152\000\000\001\149\000\000\000\000\001\146\000\000\000\000\000\000\001\148\000\000\001\147\000\000\000\000\000\000\000\000\000\000\000\000\001\168\000\000\001\144\000\000\001\143\000\000\000v\000\000\000\000\002\140\000\000\000\000\001\139\000\000\000\000\000~\000\000\000\000\002\156\000\000\000\000\000\000\000{\000\000\000\000\002\150\000\000\001\218\001\217\001\131\002x\000\000\001\154\000\000\000\000\000\000\001\151\000\000\001\156\000\000\000\000\001\152\000\000\000\000\001\153\000\000\000\000\000\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\001\169\000\000\001\145\000}\000\000\000\000\002\154\000\000\000\000\000\000\001\031\000y\001\030\000\000\000\000\002\146\000\000\001\216\001\215\001\129\002w\000\000\000\127\000\000\000\000\002\158\000\000\000\000\000\000\000\000\001\220\001\219\001\133\002y\000\000\001\161\000\000\001\165\000\000\000\000\001\157\000\000\000\000\000\000\001\150\000\000\001\155\000\000\000\000\000\000\000\000\000\000\000\000\001\164\001\138\000\000\001\163\000\000\000\000\000\000\000\000\001\160\000\000\000\000\001\159\000\000\001\158\000\000\000\000\000\000\000\000\001\162\000\000\001\166\000\000\000\000\001K\000\004\000\000\001\141\000\005\000\000\000\000\000\230\000\006\000\000\001\180\001\181\001\179\000\000\000\000\000\000\000\000\000\000\000\000\000x\000\000\000\000\002\144\000\000\000\221\001\178\001{\002\198\001}\000\000\000\007\000\000\001\183\001\184\001\182\000\000\000\000\000\000\000\000\000\000\000\000\000\231\000\234\000\000\000\000\000\000\000\000\000\239\000\241\000\240\000\235\000\237\000\236\000\000\000\000\002\199\001\188\001\187\000\000\000\000\000\000\000\000\002\204\002\215\000\000\002\205\000\000\002\206\001\127\000\000\001\177\001\185\000\000\000\000\000\000\000\000\001\224\000\000\000\000\000l\000m\000\000\000\000\000\000\001\223\000\000\000\158\000\000\001U\000\000\000\000\000\157\000\154\000\000\000\000\000\000\000\000\001\005\000\000\000\000\002\216\000\000\002\217\000\000\000\000\001\211\001\209\000\000\001\210\000\008\000\000\000\t\000\000\002\012\002\013\002\011\000\000\000\000\002\n\000\000\000\n\000\000\002\015\002\016\002\014\000\000\002\018\000\000\000\000\000\000\002\004\000\000\000\000\002\006\000\000\002\000\000\000\002\002\000\000\002\007\000\000\002\008\002\001\001\255\002\019\001\137\000\000\002\t\000\000\002\021\000\000\002\020\000\000\002\022\000\000\002{\000\011\000\000\000\000\000\000\000\000\000\000\000\000\002\023\000\000\000\000\002\026\000\000\002\025\000\000\002\024\000\198\000\000\000\000\000\000\000\000\000\199\002\027\000\000\000\000\002\133\000\000\000\229\000\012\000\000\000\000\000\000\000\000\000\000\000\000\002\136\000k\000\000\000\000\000\204\000\000\000\000\000\224\000\223\000\222\000\000\0018\000\000\002\132\001y\001w\000\000\000\000\000\000\000\000\000\000\000\000\002\131\000\000\000\013\000\000\000\000\000\000\000\000\000\000\002\134")
+    (16, "\000\000\000\000\001 \001!\000\000\001#\001\"\000\001\000\000\001[\000\000\000\000\000\136\000\000\000\000\001\214\000\142\000\145\002\195\002\194\000\146\001\013\001\019\001\015\001\018\001\017\000\135\001\011\001\026\000\000\000\000\001\025\000\000\000\000\000\000\000\000\000\000\001O\000\232\002\185\002o\000\000\000\000\000\000\000\000\000\000\002\190\000\000\001\022\000\000\002\192\000\000\001\029\001\028\000\000\000\000\002\250\0029\000\000\002\248\000\000\002S\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\247\002\249\002?\001\004\002>\001\002\001\003\002=\002<\002;\0027\000\000\000\000\0028\000\205\000\000\002:\000\000\002\246\000\000\002\221\001\001\002\026\000\000\000\000\002\029\000\000\000\015\000\000\000\000\000\000\000\000\000\206\0026\002B\000[\000\021\000]\000\000\000\000\000c\000\000\000\000\000\000\000\000\000\000\000\000\000\022\000\000\000\023\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\130\001\251\000R\000\215\000^\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\\\000T\000\000\000S\000\000\000\000\000\140\000\216\000\000\002 \000\217\000\014\000\000\001\014\001\020\001\016\001\012\000\016\000\000\000\000\000\143\000\000\000\141\000\000\000\000\000\220\000\000\000\000\002\027\002\030\000\000\002\028\002\031\002\222\002\220\000\000\002@\002\219\000\000\002Z\000\000\000\000\002Y\002X\002W\002V\002U\002Q\000\000\000\000\002R\000\000\002T\000\000\000\000\002\235\002(\000\000\000\000\002+\000\000\000\000\002.\000\000\000\000\002)\002,\000\000\002*\002-\002\\\002P\002\236\002\234\002\233\000g\000h\000\000\000\000\000W\000\000\000V\000\227\000\000\001\206\000\000\000\000\000\000\000\000\000\000\000\210\001\212\000\000\000\000\001s\000U\0001\000\203\000_\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\000\000\0003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002A\000\000\000\144\000\000\000\000\001\190\000\000\001i\001\171\000\000\000\000\001\189\000\000\001g\001\170\000\000\000\000\000d\000\000\002[\000\000\000\000\002\238\002\237\000\000\001\207\000\000\000\000\002\224\002\223\000\000\000Q\000\147\000\000\001Q\000\000\002\188\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\226\000\151\000\000\000\000\000n\000o\001\225\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\160\001\195\000\000\000\148\000\155\000\000\001\197\000\000\000\000\000\000\000\000\000\149\000\161\000\000\001W\000\000\000\000\002\187\000\000\000\000\000\138\000\000\000\000\002\186\000\000\000\000\000\000\002\189\002\193\000\000\000\000\000\000\001\023\000\000\000\214\000\000\001\024\000\000\000\000\001:\000\000\0019\000\000\001G\000\000\001]\000\000\000\000\000\000\000\000\000\000\000\000\001\008\000\000\000\000\002\217\000\000\000\189\002\216\002\181\002\183\002\184\002\182\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002`\000\000\000\000\000\000\000\000\002g\000\000\000\000\002f\002e\002d\002c\002b\0016\002^\000\000\000\000\002_\000\000\002a\000\000\000\000\002\242\002/\000\000\000\000\0022\000\000\000\000\0025\000\000\000\000\0020\0023\000\000\0021\0024\002i\002]\002\243\002\241\002\240\000i\000j\000\000\000\000\000Z\000\000\000Y\000\000\002h\000\000\001\172\000X\000?\000\226\000`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\134\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\245\002\244\000\000\002\172\000\000\002\171\000\000\000\000\000\000\000\000\003\001\000\000\000\000\000\000\003\002\000\000\000\018\000\000\000\000\000\000\002\253\000\000\001u\000\000\000\000\000\000\000\162\002\162\001M\000\000\000\153\001L\001%\001$\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\207\000\208\000\195\000\000\001Y\000\000\000\000\000\194\000\190\000\000\000\197\000\191\000\196\000\000\002\174\000\000\002\173\002\159\000\000\000\000\000\000\000\000\000\000\002\168\000\000\000\000\000\000\000\000\000\000\002\169\002\161\000\000\002\175\000\000\002\163\000\000\000\166\000\000\002\178\000\152\000\000\001'\000\000\000\000\000\000\000\000\000\000\000\000\001\t\000\000\000w\000\000\000\000\000\000\002F\000\000\000\000\000\000\002N\000\000\000\000\002M\000\000\002\231\002L\002K\002J\002I\002H\002D\000\000\000\000\002E\000\000\002G\000\000\000\000\002\228\002!\000\000\000\000\002$\000\000\000\000\002'\000\000\000\000\002\"\002%\000\000\002#\002&\002O\002C\002\229\002\227\002\226\002\230\000\000\000\000\000\000\000e\000f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\212\001(\000\000\000\000\000\000\001.\000\000\000\000\001/\000#\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000$\000\000\000%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001-\0012\000\000\001,\000\000\000\000\0014\000\000\000\000\000\000\000\000\000\000\000\000\000t\000q\000r\0015\0011\000\000\000\000\0010\001*\000\000\001)\000\000\000\182\000\000\002\140\000\000\000\000\000\178\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\185\000\000\000\000\000\188\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\007\000\000\000\000\000\000\000\175\000\000\000\172\000\000\000\000\000\000\000\000\000\000\000\183\000\000\000\179\000\000\000\000\002\199\000\000\002\206\000\168\000\000\000\000\000\000\000\000\000\180\000\000\000\176\000\173\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\184\000\000\000\000\000\187\000\000\002\200\000\167\000\000\002\201\000\000\002\208\000\000\000\000\000\000\000\000\000\186\000\000\000\170\000\000\000\000\000\000\000\000\001\006\000\000\000\000\000\000\000\174\000\000\000\171\000\000\000\000\000\000\000\000\000\000\000\181\000\000\000\177\000\164\000\163\000\000\002\209\002\210\000\000\002\211\000\000\002\212\000\000\001&\002\166\000\000\000\000\001\194\000\000\001q\001\176\000\000\002\160\000\000\000\000\000\000\002\165\000\000\000\000\000\000\000\250\000\000\000\244\000\000\000\245\000\000\000\255\000\243\000\254\000\000\002\177\001\000\000\000\000\169\000\000\000\000\000\000\000\000\000\252\000\247\001\191\000\000\000\248\000\000\000\249\000\000\001k\001\173\000\000\000\000\000\000\001\202\000\000\001\200\000\000\000\000\001\204\001\198\000\000\001\205\001\199\000\000\002\179\001\208\000\000\000\165\000\000\000\000\001\192\000\000\001m\001\174\000\000\002\254\000\000\002\251\000\000\002\252\000\019\000\020\000\000\000\000\002}\000\000\002|\000\000\000\000\002\127\000\000\002~\000\000\000\000\000\000\001\235\000\000\000\000\001\239\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\242\000\000\000\000\001\245\000\000\000\000\001\229\000\000\000\000\001\232\000\000\000\000\000\000\001\236\000\000\000\000\001\240\000\000\000\000\001\193\000\000\000\000\001\233\000\000\000\000\001\237\002z\001\230\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\241\000\000\000\000\001\244\000\000\002{\000\000\000\000\000\000\000\000\001\243\000\000\001\227\000\000\001\228\000\000\000\000\001\231\000\000\000\000\000\000\001\234\000\000\000\000\001\238\000\000\001o\001\175\000\000\002\128\000\000\000\000\000\000\002\255\000\017\000u\000\000\003\000\000\000\000\000\002\136\000\000\000\000\002\180\000a\000\000\000\000\000\000\000b\000\000\002\170\000\000\001S\002\167\000\000\000\000\001@\000\000\001?\000\000\001H\000\000\001c\000\000\000\000\000\000\001>\000\000\001=\000\000\001E\000\000\001a\000\000\000\000\000\000\001B\000\000\001A\000\000\001F\000\000\001e\000\000\000\000\000\000\001C\000\000\000\000\000\000\000\000\001<\000\000\001;\000\000\001I\000\000\001_\000\000\000\000\000\000\001D\000\002\000\000\000N\000O\000M\001J\000\003\000\000\000\000\002l\000\000\001\249\000\000\002r\002t\000\000\000\000\001\140\002s\000\128\000\000\000\000\002\158\000\000\000\000\000\000\000z\000\000\000\000\002\146\000\000\001\222\001\221\001\135\002x\002p\002q\000\000\001\167\000\000\002m\000\000\000\000\000|\000\000\000\000\002\150\000\000\001\149\000\000\000\000\001\146\000\000\000\000\000\000\001\148\000\000\001\147\000\000\000\000\000\000\000\000\000\000\000\000\001\168\000\000\001\144\000\000\001\143\000\000\000v\000\000\000\000\002\138\000\000\000\000\001\139\000\000\000\000\000~\000\000\000\000\002\154\000\000\000\000\000\000\000{\000\000\000\000\002\148\000\000\001\218\001\217\001\131\002v\000\000\001\154\000\000\000\000\000\000\001\151\000\000\001\156\000\000\000\000\001\152\000\000\000\000\001\153\000\000\000\000\000\000\001\142\000\000\000\000\000\000\000\000\000\000\000\000\001\169\000\000\001\145\000}\000\000\000\000\002\152\000\000\000\000\000\000\001\031\000y\001\030\000\000\000\000\002\144\000\000\001\216\001\215\001\129\002u\000\000\000\127\000\000\000\000\002\156\000\000\000\000\000\000\000\000\001\220\001\219\001\133\002w\000\000\001\161\000\000\001\165\000\000\000\000\001\157\000\000\000\000\000\000\001\150\000\000\001\155\000\000\000\000\000\000\000\000\000\000\000\000\001\164\001\138\000\000\001\163\000\000\000\000\000\000\000\000\001\160\000\000\000\000\001\159\000\000\001\158\000\000\000\000\000\000\000\000\001\162\000\000\001\166\000\000\000\000\001K\000\004\000\000\001\141\000\005\000\000\000\000\000\230\000\006\000\000\001\180\001\181\001\179\000\000\000\000\000\000\000\000\000\000\000\000\000x\000\000\000\000\002\142\000\000\000\221\001\178\001{\002\196\001}\000\000\000\007\000\000\001\183\001\184\001\182\000\000\000\000\000\000\000\000\000\000\000\000\000\231\000\234\000\000\000\000\000\000\000\000\000\239\000\241\000\240\000\235\000\237\000\236\000\000\000\000\002\197\001\188\001\187\000\000\000\000\000\000\000\000\002\202\002\213\000\000\002\203\000\000\002\204\001\127\000\000\001\177\001\185\000\000\000\000\000\000\000\000\001\224\000\000\000\000\000l\000m\000\000\000\000\000\000\001\223\000\000\000\158\000\000\001U\000\000\000\000\000\157\000\154\000\000\000\000\000\000\000\000\001\005\000\000\000\000\002\214\000\000\002\215\000\000\000\000\001\211\001\209\000\000\001\210\000\008\000\000\000\t\000\000\002\n\002\011\002\t\000\000\000\000\002\008\000\000\000\n\000\000\002\013\002\014\002\012\000\000\002\016\000\000\000\000\000\000\002\002\000\000\000\000\002\004\000\000\001\254\000\000\002\000\000\000\002\005\000\000\002\006\001\255\001\253\002\017\001\137\000\000\002\007\000\000\002\019\000\000\002\018\000\000\002\020\000\000\002y\000\011\000\000\000\000\000\000\000\000\000\000\000\000\002\021\000\000\000\000\002\024\000\000\002\023\000\000\002\022\000\198\000\000\000\000\000\000\000\000\000\199\002\025\000\000\000\000\002\131\000\000\000\229\000\012\000\000\000\000\000\000\000\000\000\000\000\000\002\134\000k\000\000\000\000\000\204\000\000\000\000\000\224\000\223\000\222\000\000\0018\000\000\002\130\001y\001w\000\000\000\000\000\000\000\000\000\000\000\000\002\129\000\000\000\013\000\000\000\000\000\000\000\000\000\000\002\132")
   
   let error =
-    (167, "\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000`\000\000\000\000\016\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\192\000\000\000\000\000\000\003\214\171\128\004\000\128\000\004\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\016\006\016\000\002\t\1290\008\002\002\000\016\000\0012\024\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000z\213p\000\128\016\000\000\128\002\000\000\000\000\000\000\000\000\000\000\000\002U\024\000\1280\128\000\152L\t\128@\016\017\000\128\000\t\144\197\235U\192\002\000@\000\002\008\008\000\000\000\000 \000\016\000\000\000\000\000\000\000\000\000\000\000\002\001\000\000\000\000\000\000\000\000\000\000\000\000\018(\192\000\000\004\000\004\002@L\002\000\000\136\004\000\000L\006 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\245\170\224\t\000 \000\001\004\004\000\000\000\000\016\000\000\000\000\016\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\004\000\128\000\004\016\016\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\008\000\000\000\128\000\000\000\000\000\015Z\174\000\016\002\000\000\016@@\000\000\000\001\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\245\170\224\001\000 \000\001\004\004\000\000\000\000\016\000\008\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\002\000\000\000\000\000\000\000\004\000\001\016\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\008\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t  \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000B\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130z\213p\000\169\016\001 \208*\013\218\000\002H\008\004\000B\001\004\245\170\224\001R \002A\160T\027\180\000\004\144\016\008\000\132\002\008\000\000\000\016\164\000\004\131@\1607h\000\t  \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\129@n\208\000\018@@ \002\016\008 \000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\129@n\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001 \000D`\155,\150\000\000P\004 \000;\160\"xw\000\000\000\000\000\000\000\000\000\000\000\128\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\235U\192\002\164@\004\131@\1687\232\000\t  \016\001\t\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000$\000\008\004\016`\018\192\000\n\000\000\000\007d\000M\014\224\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\144\000\"\016M\132K\000\000(\002\000\000\029\144\001<;\128\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\144\000\"\016M\132K\000\000(\002\000\000\025\144\001<\027\128\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\128\001\016\130l\"X\000\001@\016\000\000\204\128\t\224\220\000\000\000\000\164\000\004\131@\1607h\000\t  \016\001\008\004\016\000\000\018\000\004B\t\176\137`\000\005\000@\000\0032\000'\131p\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000H\000\017\008&\194%\128\000\020\001\000\000\012\200\000\158\013\192\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t  \016\001\008\004\016\000\000\018\000\004B\t\176\137`\000\005\000@\000\0032\000'\131p\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000H\000\017\008&\194%\128\000\020\001\000\000\012\200\000\158\013\192\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\001 \000D \155\008\150\000\000P\004\000\0003 \002x7\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\004\128\001\016\130l\"X\000\001@\016\000\000\204\128\t\224\220\000\000\000\000\164\000\004\131@\1607h\000\t  \016\001\008\004\016\000\000\018\000\004B\t\176\137`\000\005\000@\000\0032\000'\131p\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128`\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000H\000\017\008&\194%\128\000\020\001\000\000\012\200\000\158\013\192\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\001 \000D \155\008\150\000\000P\004\000\0003 \002x7\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\004\128\001\016\130l\"X\000\001@\016\000\000\204\128\t\224\220\000\000\000\000\164\000\004\131@\1607h\000\t  \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000 \012\000\000\004\019\000\000\000\004\004\000 \000\002d\001\001*\140\000@\024@\000H&\004\192 \008\008\128@\000\004\200b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\191N\000 \012 \000$\019\002`\016\004\004@ \000\002d1\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007Z\170\000\016\002\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000@\024@\000\008&\004\192 \008\008\000@\000\004\200b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\017\000\003\214\171\128\005H\128\t\006\129Po\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\004\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\245\170\224\001R \002A\160T\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\000\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\000\000\132\002\008\000\000\000\000\164\000\004\131@\1607h\000\t  \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000H\000\017\016\"\201%\000\000\016\001\008\000\006\168\008\134\017\192\000\000\000\000\000\000\000\000\000\000 \000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000z\213p\000\169\016\001 \208*\013\250\000\002H\008\004\000BA\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\129@n\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000z\213p\000\169\016\001 \208*\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\164\000\004\131@\1607h\000\t  \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000H\000\017\000\"\192%\000\000\016\001\000\000\006\136\000\134\017\192\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\128\000\004\000\000\000\000\001\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\128\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018\000\004@\008\176\t@\000\004\000@\000\001\"\000!\128p\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000H\000\017\000\"\192%\000\000\016\001\000\000\004\136\000\134\001\192\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\001 \000D\000\139\000\148\000\000@\004\000\000\018 \002\024\007\000\000\000\000)\000\001 \208(\013\218\000\002H\008\000\000B\001\004\000\000\004\128\001\016\002,\002P\000\001\000\016\000\000H\128\008`\028\000\000\000\000\164\000\004\131@\1607h\000\t  \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\001 \000D\000\139\000\148\000\000@\004\000\000\018 \002\024\007\000\000\000\000)\000\001 \208(\013\218\000\002H\008\000\000B\001\004\000\000\004\128\001\016\002,\002P\000\001\000\016\000\000H\128\008`\028\000\000\000\000\164\000\004\131@\1607h\000\t  \000\001\008\004\016\000\000\018\000\004@\008\176\t@\000\004\000@\000\001\"\000!\128p\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000H\000\017\000\"\192%\000\000\016\001\000\000\004\136\000\134\001\192\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\001 \000D\000\139\000\148\000\000@\004\000\000\018 \002\024\007\000\000\000\000)\000\001 \208(\013\218\000\002H\008\006\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t  \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000H\000\017\000\"\192%\000\000\016\001\000\000\004\136\000\134\001\192\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\001 \000D\000\139\000\148\000\000@\004\000\000\018 \002\024\007\000\000\000\000)\000\001 \208(\013\218\000\002H\008\000\000B\001\004\000\000\004\128\001\016\002,\002P\000\001\000\016\000\000H\128\008`\028\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000 \000=j\184\000@\008\000\000@\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\000\000\132\002\008\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\n\145\000\018\013\002\160\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000@\000\000\000\000\000\000\000\128\000\"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\145F\000\000\000 \000 \018\002`\016\000\004@ \000\002`1\001\"\140\000\000\000@\000@\004\004\192 \000\008\128@\000\004\192b\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\030\181\\\000 \004\000\000 \000\140\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000 \016\000\000\000\000\000\000\000\000\002 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\017\000\003\214\171\128\004\000\128\000\004\000\017\128\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\128\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\004\000\128\000\004\000\017\128\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000D\000\015Z\174\000\016\002\000\000\016\000F\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\008\000\000\000\004@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000=j\184\000@\008\000\000@\001\024\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000z\213p\000\128\016\000\000\130\002\000\000\000\000\008\000\000\000\000\008\000\245\170\224\001\000 \000\001\004\004\000\000\000\000\016\000\008\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\014\181T\000 \004\000\000\000\000\128\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\tT`\002\000\194\000\002a0&\001\000@D\002\000\000&C\023\173W\000\008\001\000\000\008  \000\000\000\000\128\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000@\000\000\000\000\000\000\023\173W\000\008\001\000\000\008\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\030\181\\\000 \004\000\000 \000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000 \000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255_\130\011\145 \016\012b\184\253\225\000~\161\128\008\214 P@$Q\128\000\000\000\000\008\004\000\152\000\000\001\016\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000=j\184\000@\008\000\000@\001\024\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\004\000\128\000\004\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000 9\002\001\000\196(\143\218\016\007\234\024\000\140b\005\004\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t  \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@!\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000?\250\252\016\\\137\000\144j\021\199\239\008\003\245\012\002G\177\134\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002\001\128P\027\180\000\012\144\016\000\000\132\002\008\000\000\000\000\164\000\004\003\000\1607h\000\025  \000\001\008\004\019\214\171\128\005H\128\t\006\129Pn\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\020\128\000\128`\020\006\237\000\003$\004\000\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\128`\020\006\237\000\003$\004\000\000!\000\130\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\003\000\1607h\000\025  \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\016\012\002\128\221\160\000d\128\128\000\004 \016@\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002@\000\136\1936Y,\000\000\160\008@\000u@@\160\238\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\005H\128\t\006\129Po\208\000\018@@ \002\018\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000$\000\008\132\019a\018\192\000\n\000\128\000\007D\000\n\014\224\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\128\001\016\130l\"X\000\001@\016\000\000\200\128\001@\220\000\000\000\000\164\000\004\003\000\1607h\000\025  \000\001\008\004\016\000\000\018\000\004B\t\176\137`\000\005\000@\000\003\"\000\005\003p\000\000\000\002\144\000\016\012\002\128\221\160\000d\128\128\000\004 \016@\000\000H\000\017\008&\194%\128\000\020\001\000\000\012\136\000\020\013\192\000\000\000\n@\000@0\n\003v\128\001\146\002\000\000\016\128A\000\000\001 \000D \155\008\150\000\000P\004\000\0002 \000P7\000\000\000\000)\000\001\000\192(\013\218\000\006H\008\000\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\003\000\1607h\000\025  \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\016\012\002\128\221\160\000d\128\128\000\004 \016@\000\000H\000\017\008&\194%\128\000\020\001\000\000\012\136\000\020\013\192\000\000\000\n@\000@0\n\003v\128\001\146\002\000\000\016\128A\000\000\001 \000D \155\008\150\000\000P\004\000\0002 \000P7\000\000\000\000)\000\001\000\192(\013\218\000\006H\008\000\000B\001\004\000\000\004\128\001\016\130l\"X\000\001@\016\000\000\200\128\001@\220\000\000\000\000\164\000\004\003\000\1607h\000\025  \000\001\008\004\016\000\000\018\000\004B\t\176\137`\000\005\000@\000\003\"\000\005\003p\000\000\000\002\144\000\016\012\002\128\221\160\000d\128\128\000\004 \016@\000\000H\000\017\008&\194%\128\000\020\001\000\000\012\136\000\020\013\192\000\000\000\n@\000H4\n\003v\128\000\146\002\001\128\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000)\000\001\000\192(\013\218\000\006H\008\000\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\003\000\1607h\000\025  \000\001\008\004\016\000\000\018\000\004B\t\176\137`\000\005\000@\000\003\"\000\005\003p\000\000\000\002\144\000\016\012\002\128\221\160\000d\128\128\000\004 \016@\000\000H\000\017\008&\194%\128\000\020\001\000\000\012\136\000\020\013\192\000\000\000\n@\000@0\n\003v\128\001\146\002\000\000\016\128A\000\000\001 \000D \155\008\150\000\000P\004\000\0002 \000P7z\213p\000\169\016\001 \208*\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\004\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\245\248<\185\018\001\000\198+\143\222\016\007\234\024\000\141b\005\004\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t  \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\002\000\000\000\000\000\000B \000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\175\193\005\200\144\008\006!\\~\240\128?P\192\004k\016('\255_\130\011\145 \018\013B\248\253\225\000~\161\128H\214(PO\254\191\007\151\"@ \024\197q\251\194\000\253C\000\017\172@\160\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000?\251\254\030\\\137\000\128c\023\199\239\024\003\245L G\177\198\179\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\255\235\240Ar$\002\001\140W\031\188 \015\2120\001\026\196\n\t\255\215\224\130\228H\004\131P\190?x@\031\168`\0185\138\020\019\255\175\193\005\200\144\t\006\161\\~\240\128?P\192$k\016h \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001 \000D`\155,\150\000\000P\004 \000;\160\"Pw\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\016\028\129\000\128b\020G\237\008\003\245\012\000F1\002\130\000\000\000 9\002\001\000\196(\143\218\016\007\234\024\000\140b\005\004\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \008$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128 \144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\008\000\132\130\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\001\001\200\016\008\006!D~\208\128?P\192\004c\016( \000\000\002\003\144 \016\012B\136\253\161\000~\161\128\008\198 P@\000\000\000\000\000\000\000\000\000\000\016\000\000\001\000\000\128\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\016\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\004\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\136\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\002\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002@\000\128\193\006I,\000\000\128\000@\0003@D\128\140\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\001\235U\192\002\164@\004\131@\1687\232\000\t  \016\001\t\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\002\003\144 \016\012B\136\253\161\000~\161\128\008\198 P@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\175\193\005\200\144\t\006\161\\~\240\128?P\192$k\016( \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\254\255\135\151\"@ \024\197\241\251\198\000\253S\008\017\236q\172\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\235U\192\002\000@\000\002\000\008\000\000\000\000 \000\000\000\000\000\000\t\020`\000\000\000\000\002\001\000&\000\000\000D\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\015Z\174\000\016\002\000\000\016\000F\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\128\000 \000\000\000\000\000\002\144\000\018\013B\128\221\160\000$\128\128@\004 \016@\000\000\000\005 \000 \025\133\001\187@\000\201\001\000\160\008A \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\128`\020\006\237\000\003$\004\000\000!\000\130\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\005H\128\t\006\129Pn\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000@0\n\003v\128\001\146\002\000\000\016\128A\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002\001\128P\027\180\000\012\144\016\000\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\008\006\001@n\208\0002@@\000\002\016\008 \000\000\000\002\144\000\016\012\002\128\221\160\000d\128\128\000\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000@@\131$\148\000\000@\000 \000\016\160\"\000\006\000\000\000\000\000\000\000\000\000\000\000\128\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\235U\192\002\164@\004\131@\1687\232\000\t  \016\001\t\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\235U\192\002\164@\004\131@\1687h\000\t  \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\002\144\000\016\012\002\128\221\160\000d\128\128\000\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\016\000\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\002\144\000\016\012\194\128\221\160\000d\128\128\016\004 \016@\000\000\000\005 \000 \025\133\001\187@\000\201\001\000\160\008A \128\000\000\001\n@\000@3\n\003v\128\001\146\002\001@\016\130A\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \212(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\n@\000@3\n\003v\128\001\146\002\000@\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000R\000\002\001\152P\027\180\000\012\144\016\002\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\008\000\016`\018\128\000\008\000\000\000\002\004\000@\000\192\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\128\000 \000A\128J\000\000 \000\000\000\008\016\001\000\003\000\000\000\000\020\128\000\128`\020\006\237\000\003$\004\000\000!\000\130\000\000\002\000\000\128\001\006\001(\000\000\128\000\000\000 @\004\000\012\000\000\000\000R\000\002\001\128P\027\180\000\012\144\016\000\000\132\002\008\000\000\008\000\002\000\004\024\004\160\000\002\000\000\000\000\129\000\016\0000\000\000\000\001H\000\008\006\001@n\208\0002@@\000\002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\128`\020\006\237\000\003$\004\000\000!\000\130\000\000\002\000\000\128\001\006\001(\000\000\128\000\000\000 @\004\000\012\000\000\000\000R\000\002\001\128P\027\180\000\012\144\016\000\000\132\002\008\000\000\008\000\002\000\004\024\004\160\000\002\000\000\000\000\129\000\016\0000\000\000\000\001H\000\008\006\001@n\208\0002@@\000\002\016\008 \000\000 \000\008\000\016`\018\128\000\008\000\000\000\002\004\000@\000\192\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\128\000 \000A\128J\000\000 \000\000\000\008\016\001\000\003\000\000\000\000\020\128\000\128`\020\006\237\000\003$\004\000\000!\000\130\000\000\002\000\000\128\001\006\001(\000\000\128\000\000\000 @\004\000\012\000\000\000\000R\000\002\001\128P\027\180\000\012\144\016\000\000\132\002\008\000\000\008\000\002\000\004\024\004\160\000\002\000\000\000\000\129\000\016\0000\000\000\000\001H\000\008\006\001@n\208\0002@@\000\002\016\008 \000\000 \000\008\000\016`\018\128\000\008\000\000\000\002\004\000@\000\192\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\128\000 \000A\128J\000\000 \000\000\000\008\016\001\000\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\002\144\000\016\012\194\128\221\160\000d\128\128P\004 \144@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000@3\n\003v\128\001\146\002\001@\016\130A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000)\000\001\000\204(\013\218\000\006H\008\005\000B\t\004\000\000\000\000R\000\002\001\152P\027\180\000\012\144\016\002\000\132\018\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\001H\000\008\006a@n\208\0002@@(\002\016H \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\164\000\004\0030\1607h\000\025  \004\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\004\000\128\000\004\000\017\128\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144j\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\019\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\002\000\002@\000\000\000\000\000\000\000\128\000 \000\000\000\000\000\000\000\004\000\004\128\000\000\000\000\000\000\001\000\000@\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\030\181\\\000 \004\000\000 \000\140\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000@\000\016\000\000\000\000\000\001H\000\t\006\161@n\208\000\018@@ \002\016\008 \000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000:\213P\000\128\016\000\000\000\002\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000@\000\016\000\000\000\000\000\001H\000\t\006\161@n\208\000\018@@ \002\016\008 \000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\245\248 \185\018\001\000\198+\143\2220\007\234\024\000\141b\005\004\000\000\000\000\000\000\000@ \000\000\000@\000\000\000\136\000\000\000\196\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\175\193\005\200\144\008\0061\\~\241\128?P\194\004k\016+0\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\144\000\"0M\150K\000 (\002\018\000\029\208\016(;\128\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\008\000\002\000\000\000\000\000\000)\000\001 \212(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\004\000\128\000\004\000\017\128\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144j\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\128@\000\000\000\128\000\000\001\016\000\000\001\136\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\254\191\004\023\"@$\026\133q\251\198\000\253C\008\145\172@\172\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000?\250\252\016\\\137\000\128c\021\199\239\024\003\245\012 F\177\002\179\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\001\235U\192\002\164@\004\131@\1687\232\000\t  \016\001\t\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\0010\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\245\170\224\001\000 \000\001\000\004`\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\002\000\000\128\000\000\000\000\000\n@\000H5\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\214\170\128\004\000\128\000\000\000\016\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\002\000\000\128\000\000\000\000\000\n@\000H5\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\254\191\004\023\"@$\026\133q\251\198\000\253C\008\145\172@\172\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@ \016\000\000\000 \000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\255\215\224\130\228H\004\131P\174?x\192\031\168`\0185\136\020\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000L\002\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000@\000\000\000\000 9\002\001\000\196(\143\218\016\007\234\024\000\140b\005\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\002\000\000\000\000\000\000\000\000\000@\000\127\247\252 \185\026\0010\212/\143\2220\015\234\152L\143c\173f\000\000\000@r\004\002\001\136Q\031\180 \015\2120\001\024\196\n\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\175\193\005\200\144\008\0061|~\240\128?P\192\004{\028h \000\000\000\000\000\000\002\001\000\000\000\000\000\000\000\000@\000\000\000\015\254\191\004\023\"@ \024\197\241\251\194\000\253C\000\017\236q\160\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \016\008\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\255\235\240Ar$\002A\168_\031\188 \015\2120\t\030\199\026\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\175\193\005\200\144\t\006\161|~\240\128?P\192${\028h \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\008\000\015\254\191\004\023\"@ \024\197\241\251\194\000\253C\000\017\172P\160\128\000\000\000\000\000\000\008\004\001\000\000\000\000\000\000\001\000\000 \000?\250\252\016\\\137\000\128c\023\199\239\008\003\245\012\000F\177B\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\001\000\128 \000\000\000\000\000\000 \000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\254\191\004\023\"@$\026\133\241\251\194\000\253C\000\145\172P\160\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\019\000\000\000 \000\000\000\002\000\000\000\000\000\000\000@\001\128\128\000\000\000\000@\000\000 \000\001\000\023\255_\130\011\145 \016\012b\184\253\225\000~\161\128\008\214 P@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\016\012\004\000\000\000\000\002\000\000\001\000\000\008\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\245\248 \185\026\0010\212+\143\222\016\015\234\024\004\141b%\006\255\235\240Ar$\002\001\140W\031\188 \015\2120\001\026\196\n\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255_\130\011\145\160\019\013B\184\253\225\000\254\161\128H\214\"P`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\008\000\015\254\191\004\023\"@$\026\133\241\251\194\000\253C\000\145\172P\160\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\002\001\000\000\000\002\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253~\008.D\128H5\n\227\247\140\001\250\134\001#X\129A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\239\215\224\002\164H\004\003\000\1687x\000\025  \000\005\136\020\016\000\000\000\001H\002\t\006\129@n\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000=\250\252\000T\137\000\128`\021\006\239\000\003$\004\000\000\177\002\130\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\008\001\000\000\008\000 \000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \212(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000z\213p\000\128\016\000\000\128\0020\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013B\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002`\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131P\1607h\000\t  \016\001\008\004\016\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007Z\170\000\016\002\000\000\000\000@\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\002\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002A\168P\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\008\000\015~\191\000\021\"@ \024\005A\187\192\000\201\001\000\000,@\160\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001 \000@`\131$\150\000@@\000$\000\024\160 @F\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131P\1607h\000\t  \016\001\008\004\016\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\008\001\000\000\008\000#\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \212(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\030\181\\\000*D\000H4\n\131~\128\000\146\002\001\000\016\144A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\019\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H5\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000u\170\160\001\000 \000\000\000\004\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\133\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\128\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\016\000\000\001\0010\000\000\002\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\128\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\008@\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\245\248 \185\018\001\000\198+\143\222\016\007\234\024\000\141b\005\004\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\031\253~\008.D\128H5\n\227\247\132\001\250\134\001#\216\195A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\004 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000_\253~\008.D\128@1\138\227\247\132\001\250\134\000#X\129A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\245\248 \185\018\001\000\198+\143\222\016\007\234\024\000\141b\005\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\128\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\000\000\000\004\000\000\000\000\000\000\000\004\000\000\000\000\000\000\001\000\000\000\000)\000\001 \208(\013\218\000\002H\008\000\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t  \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 9\002\001\000\196(\143\218\016\007\234\024\000\140b\005\004\000\000\000\000\000\016\000\000\000\000\000\000\000\016\000\000\000\000\000\000\004\000\000\000\128\228\008\004\003\016\162?h@\031\168`\0021\136\020\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\003\144 \016\012B\136\253\161\000~\161\128\008\198 P@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\008\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t  \000\001\008\004\016\000\000\000\000\000@\000\000\000\000\000\000\000@\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253~\000 \004\000\000 \000\128\001\000\000\002\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\004\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\008\000\000\000\000\000\000\002\255\235\240\001\000 \000\001\000\004\000\008\000\000\016\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\175\192\004\000\128\000\004\000\016\000 \000\000@\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\004\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\000\000\132\002\008\000\000\000\000\000 \000\000\000\000\000\000\000 \000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\030\181\\ p\132D\144!\000\128\000\018\000\005P\144\000&\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\028!\017\004\008@ \000\004\128\001T$\000\t\128\000\015Z\174\0008B\000\008\016\128@\000\t\000\002\168H\000\019\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000 \008\004\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\128 \000\000\000\000\000\000\000\000\016\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\008\000\000\000 \000\001\000@\000\000\000\000\000\000\000\000 \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\016\000\000\000\000\000\000@\000\000\000\000\000\000\002\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\008\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\028!\016\004\008@ \000\004\128\001T$\000\008\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\030\181\\\000p\132\000\016!\000\128\000\018\000\005P\144\000\"\000\000\000\004\000\000 \008\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\008\000\000\000 \000\001\000@\000\000\000\000\000\000\000\000 \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\016\004\000\000\000\000\000\000\000\000\002\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\128 \000\000\000\000\000\000\000\000\016\000\128\000\000\000\000\000 \000\001\000@\000\000\000\000\000\004\000\000 \001\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000 \008\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\008\000\000@\016\000\000\008\000\000\001\000\000\008\000@\000\004\000\000\000\016\000\000\128 \000\000\000\000\000\000\000\000\016\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000@\000\002\000\128\000\000\000\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\235U\192\002\000@\000\002\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\128\015Z\174\000\016\002\000\000\016\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\008\000\000@\016\000\000\008 \000\000\000\000\008\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000@\000\002\000\128\000\000\000\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\128\000\000\002\000\000\016\004\000\000\000\000\000\000\000\000\002\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\001\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\0020\000\000@\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\016\004\000\000\000\016\000\000\000\000\002\000\016\000\000\000\000\000\004\000\000 \008\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\004\001\000\000\000\000\000\000\000\000\000\128\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000 \008\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000@\000\002\000\128\000\000\000\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\016\004\000\000\000\008\000\000\000\000\002\000\016\000\000\000\000\000\004\000\000 \008\000\000\004\128\000\000\128\000\004\000 \000\002\000\000\000\008\000\000@\016\000\000\000\000\000\000\000\000\008\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000 \000\001\000@\000\000\000\000\000\000\000\000 \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\004\000\000\000\016\000\000\128 \000\000\000\000\000\000\000\000\016\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\008\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000@\000\000\000\000 \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\128 \000\000\000\000\000\000\000\000\016\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000 \000\000\000\128\000\004\001\000\000\000\000\000\000\000\000\000\128\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000@\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\001\000@\000\000\000\000\000\000\000\000 \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\008\002\000\000\000\008\000\000\000\000\001\000\008\000\000\000\000\000\002\000\000\016\004\000\000\000\000\000\000\000\000\002\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\214\235\128\006\000\128\000\004 \016\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\002\000\000\016\004\000\000\000H\000\000@\000\002\000\016\000\001\000\000\000\004\000\000 \008\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\030\183\\\0000\004\000\000!\008\128\000\000\000\002\000\016\000\000\000\000\000\004\000\000 \008\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\001\000@\000\000\000\000\000\000\000\000 \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000 \008\000\000\004\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\016\000\000\128 \000\000\000\000\000\000\000\000\016\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\235U\194\007\008DI\002\016\008\000\001 \000U\t\000\002`\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\007\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\024\128\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t  \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000A\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\000\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\254\255\132\023\"@$\030\135q\251\194\000\253S\008\145\172@\172\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\191\225\005\200\144\t\007\161\\~\240\128?T\194$k\016+3\191}\192\008\001\000\000\000\000 \000\000\000\000\008\000\000\000\000\000\000$Q\128\000\000\000\000\000\004\000\000\000\000\000\016\000\000\000\000\000\014\253\247\000 \004\000\000\000\000\128\000\000\000\000 \000\000\000\000\000\029\251\238\000@\008\000\000\000\001\000\000\000\000\000@\000\000\000\000\000\001\"\140\000\000\000\000\000\000 \000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\020`\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\018(\192\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000$Q\128\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000H\163\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000 \025\133\001\187@\000\201\001\000\160\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\239\223\240\002\000@\000\002\000\008\000\000\000\000\"\000\000\000\000\000\000\t\020`\000\000\000\000\002\000\000\000\000\000\000\004\000\000\000\000\000\007\255_\130\011\145 \016\012b\184\253\225\000~\161\128\008\214 P@\000\000\000\000\000\000\004\002\000\000\000\000\000\000\000\008\128\000\000\012@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@ \016\000\000\000\000\000\000\000D\000\000\000b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\255\215\224\130\228H\004\131P\174?x@\031\168a\0185\136\021\152\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\012@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\128\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\004\000\128\000\004\000\017\128\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\136\000\030\181\\\000 \004\000\000 \000\140\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\128\001\235U\192\002\000@\000\002\000\008\192\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000?\250\252\016\\\137\000\144j\021\199\239\008\003\245\012\002F\177\006\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\1380\000\000\000\000\001\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\002\001\000\128\000\000\000\000\000\000\002 \000\000\003\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\254\191\004\023\"@$\026\133q\251\194\000\253C\008\145\172@\172\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\002`\000\000\004\000 \000\000\0001\000\000\000\000\000@ \008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\014\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\012@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000?\251\254\016\\\137\000\144z\029\199\239\008\003\245L\"F\177\002\179\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\254\255\132\023\"@$\030\133q\251\194\000\253S\008\145\172@\172\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000?\251\254\016\\\137\000\128c\021\199\239\008\003\245L F\177\002\179\000\000\000\000\000\000\000 \016\000\000\000\000\000\000\000D\000\000\000b\255\239\248Ar$\002\001\140W\031\188 \015\2130\129\026\196\n\204\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\191\225\005\200\144\t\006\161\\~\240\128?T\194$k\016+7\255\127\194\011\145 \016\012b\184\253\225\000~\169\132\008\214 V`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\008\004\000\000\000\000\000\000\000\017\000\000\000\024\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\247\252 \185\018\001 \212+\143\222\016\007\234\152D\141b\005f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\255\223\240\130\228H\004\131P\174?x@\031\170a\0185\136\021\152\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255\127\194\011\145 \018\013B\184\253\225\000~\169\132H\214 V`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\001\136\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255\127\194\011\145 \018\013B\184\253\225\000~\169\132H\214 V`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\008\004\000\000\000\000\000\000\000\017\000\000\000\024\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\247\252 \185\018\001 \212+\143\222\016\007\234\152D\141b\005f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\019\000\000\000 \001\000\000\000\001\136\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\004\128\000\000\000\000\000\000\000\001\004\224\006\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000 \000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\001\002\000\000\000\000\000\000\002\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\004\008\000\000\000\000\000\000\008\000\000\000\016\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\004\000\128\000\000\000\000\002\000\000\008\016\000\000\000\000\000\000\016\000\000\000 \000\000\000\000\128\001\000\001\000\000\000\000\000\000\000\008\192\008\000\016\n\000\000\000\000\000\008\000\000 @\000\000\000\000\000\000@\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\016\000\016\000\000\000\000\000\000\000\140\000\128\000\000\160\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\004\000\000\000\000\000\000\000\000\000'\0000\000\000 \000\000\000\004\000\008\000\000\000\000\000\000\000\000\000F\000`\000\000@\000\000\000\008\000\016\000\000\000\000\000\000\000\000\000\140\000\128\000\000\128\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\0020\002\000@\002\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000#\000 \000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\001\024\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\001\000\000\000\000\000\000\000\000\000\008\192\012\000\000\008\000\000\000\001\000\002\000\000\000\000\000\000\000\000\000\017\128\016\000\000\016\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000#\000 \000\000 \000\000\000\000\000\008\000\000\000\000\000\000\000\000\000F\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")
+    (167, "\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000`\000\000\000\000\016\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\192\000\000\000\000\000\000\003\214\171\128\004\000\128\000\004\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\016\006\016\000\002\t\1290\008\002\002\000\016\000\0012\024\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000z\213p\000\128\016\000\000\128\002\000\000\000\000\000\000\000\000\000\000\000\002U\024\000\1280\128\000\152L\t\128@\016\017\000\128\000\t\144\197\235U\192\002\000@\000\002\008\008\000\000\000\000 \000\016\000\000\000\000\000\000\000\000\000\000\000\002\001\000\000\000\000\000\000\000\000\000\000\000\000\018(\192\000\000\004\000\004\002@L\002\000\000\136\004\000\000L\006 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\245\170\224\t\000 \000\001\004\004\000\000\000\000\016\000\000\000\000\016\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\004\000\128\000\004\016\016\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\008\000\000\000\128\000\000\000\000\000\015Z\174\000\016\002\000\000\016@@\000\000\000\001\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\245\170\224\001\000 \000\001\004\004\000\000\000\000\016\000\008\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\002\000\000\000\000\000\000\000\004\000\001\016\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\008\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t  \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\245\170\224\001R \002A\160T\027\180\000\004\144\016\008\000\132\002\t\235U\192\002\164@\004\131@\1687h\000\t  \016\001\008\004\016\000\000\000\001H\000\t\006\129@n\208\000\018@@\000\002\016\008'\173W\000\n\145\000\018\013\002\160\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000$\000\008\140\019e\146\192\000\n\000\132\000\007t\004O\014\224\000\000\000\000\000\000\000\000\000\000\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000=j\184\000T\136\000\144h\021\006\253\000\001$\004\002\000! \130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\128\001\000\130\012\002X\000\001@\000\000\000\236\128\t\161\220\000\000\000\000\164\000\004\131@\1607h\000\t  \016\001\008\004\016\000\000\018\000\004B\t\176\137`\000\005\000@\000\003\178\000'\135p\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018\000\004B\t\176\137`\000\005\000@\000\0032\000'\131p\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\144\000\"\016M\132K\000\000(\002\000\000\025\144\001<\027\128\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\002@\000\136A6\017,\000\000\160\008\000\000f@\004\240n\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\008\000\132\002\008\000\000\t\000\002!\004\216D\176\000\002\128 \000\001\153\000\019\193\184\000\000\000\001H\000\t\006\129@n\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\002@\000\136A6\017,\000\000\160\008\000\000f@\004\240n\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\008\000\132\002\008\000\000\t\000\002!\004\216D\176\000\002\128 \000\001\153\000\019\193\184\000\000\000\001H\000\t\006\129@n\208\000\018@@ \002\016\008 \000\000$\000\008\132\019a\018\192\000\n\000\128\000\006d\000O\006\224\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\144\000\"\016M\132K\000\000(\002\000\000\025\144\001<\027\128\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\002@\000\136A6\017,\000\000\160\008\000\000f@\004\240n\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\012\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\001H\000\t\006\129@n\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\008\000\132\002\008\000\000\t\000\002!\004\216D\176\000\002\128 \000\001\153\000\019\193\184\000\000\000\001H\000\t\006\129@n\208\000\018@@ \002\016\008 \000\000$\000\008\132\019a\018\192\000\n\000\128\000\006d\000O\006\224\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\144\000\"\016M\132K\000\000(\002\000\000\025\144\001<\027\128\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t  \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\004\001\128\000\000\130`\000\000\000\128\128\004\000\000L\128 %Q\128\008\003\008\000\t\004\192\152\004\001\001\016\008\000\000\153\012@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\023\233\192\004\001\132\000\004\130`L\002\000\128\136\004\000\000L\134 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\235U@\002\000@\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\008\003\008\000\001\004\192\152\004\001\001\000\008\000\000\153\012@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002 \000z\213p\000\169\016\001 \208*\013\250\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t  \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\000\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \208(\013\218\000\002H\008\000\000B\001\004\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\129@n\208\000\018@@\000\002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\000\008@ \128\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\128\001\017\002,\146P\000\001\000\016\128\000j\128\136a\028\000\000\000\000\000\000\000\000\000\000\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\n\145\000\018\013\002\160\223\160\000$\128\128@\004$\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000H\000\017\000\"\192%\000\000\016\001\000\000\006\136\000\134\017\192\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\128\000\004\000\000\000\000\001\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\128\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018\000\004@\008\176\t@\000\004\000@\000\001\"\000!\128p\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000H\000\017\000\"\192%\000\000\016\001\000\000\004\136\000\134\001\192\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\001 \000D\000\139\000\148\000\000@\004\000\000\018 \002\024\007\000\000\000\000)\000\001 \208(\013\218\000\002H\008\000\000B\001\004\000\000\004\128\001\016\002,\002P\000\001\000\016\000\000H\128\008`\028\000\000\000\000\164\000\004\131@\1607h\000\t  \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\001 \000D\000\139\000\148\000\000@\004\000\000\018 \002\024\007\000\000\000\000)\000\001 \208(\013\218\000\002H\008\000\000B\001\004\000\000\004\128\001\016\002,\002P\000\001\000\016\000\000H\128\008`\028\000\000\000\000\164\000\004\131@\1607h\000\t  \000\001\008\004\016\000\000\018\000\004@\008\176\t@\000\004\000@\000\001\"\000!\128p\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000H\000\017\000\"\192%\000\000\016\001\000\000\004\136\000\134\001\192\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\001 \000D\000\139\000\148\000\000@\004\000\000\018 \002\024\007\000\000\000\000)\000\001 \208(\013\218\000\002H\008\006\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t  \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\221\160\000$\128\128\000\004 \016@\000\000H\000\017\000\"\192%\000\000\016\001\000\000\004\136\000\134\001\192\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\001 \000D\000\139\000\148\000\000@\004\000\000\018 \002\024\007\000\000\000\000)\000\001 \208(\013\218\000\002H\008\000\000B\001\004\000\000\004\128\001\016\002,\002P\000\001\000\016\000\000H\128\008`\028\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\008\000\015Z\174\000\016\002\000\000\016\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\001H\000\t\006\129@n\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000=j\184\000T\136\000\144h\021\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015Z\174\000\021\"\000$\026\005A\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\128\000\000\000\000\000\000\001\000\000D\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\"\140\000\000\000@\000@$\004\192 \000\008\128@\000\004\192b\002E\024\000\000\000\128\000\128\008\t\128@\000\017\000\128\000\t\128\196\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000=j\184\000@\008\000\000@\001\024\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000@ \000\000\000\000\000\000\000\000\004@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\"\000\007\173W\000\008\001\000\000\008\000#\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000 \000\000\000\001\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\008\001\000\000\008\000#\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\136\000\030\181\\\000 \004\000\000 \000\140\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\008\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000z\213p\000\128\016\000\000\128\0020\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000D\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\245\170\224\001\000 \000\001\004\004\000\000\000\000\016\000\000\000\000\016\001\235U\192\002\000@\000\002\008\008\000\000\000\000 \000\016\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\029j\168\000@\008\000\000\000\001\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018\168\192\004\001\132\000\004\194`L\002\000\128\136\004\000\000L\134/Z\174\000\016\002\000\000\016@@\000\000\000\001\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\128\000\000\000\000\000\000/Z\174\000\016\002\000\000\016\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000=j\184\000@\008\000\000@\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000@\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\254\191\004\023\"@ \024\197q\251\194\000\253C\000\017\172@\160\128H\163\000\000\000\000\000\016\008\0010\000\000\002 \000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000z\213p\000\128\016\000\000\128\0020\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\008\001\000\000\008\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000@r\004\002\001\136Q\031\180 \015\2120\001\024\196\n\008\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\129@n\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128B\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\127\245\248 \185\018\001 \212+\143\222\016\007\234\024\004\143c\013\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\003\000\1607h\000\025  \000\001\008\004\016\000\000\000\001H\000\008\006\001@n\208\0002@@\000\002\016\008'\173W\000\n\145\000\018\013\002\160\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000)\000\001\000\192(\013\218\000\006H\008\000\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001\000\192(\013\218\000\006H\008\000\000B\001\004\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\008\006\001@n\208\0002@@\000\002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\000\n@\000@0\n\003v\128\001\146\002\000\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\128\001\017\130l\178X\000\001@\016\128\000\234\128\129A\220\000\000\000\000\000\000\000\000\000\000\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\n\145\000\018\013\002\160\223\160\000$\128\128@\004$\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000H\000\017\008&\194%\128\000\020\001\000\000\014\136\000\020\029\192\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\000\002!\004\216D\176\000\002\128 \000\001\145\000\002\129\184\000\000\000\001H\000\008\006\001@n\208\0002@@\000\002\016\008 \000\000$\000\008\132\019a\018\192\000\n\000\128\000\006D\000\n\006\224\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\144\000\"\016M\132K\000\000(\002\000\000\025\016\000(\027\128\000\000\000\020\128\000\128`\020\006\237\000\003$\004\000\000!\000\130\000\000\002@\000\136A6\017,\000\000\160\008\000\000d@\000\160n\000\000\000\000R\000\002\001\128P\027\180\000\012\144\016\000\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\008\006\001@n\208\0002@@\000\002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\144\000\"\016M\132K\000\000(\002\000\000\025\016\000(\027\128\000\000\000\020\128\000\128`\020\006\237\000\003$\004\000\000!\000\130\000\000\002@\000\136A6\017,\000\000\160\008\000\000d@\000\160n\000\000\000\000R\000\002\001\128P\027\180\000\012\144\016\000\000\132\002\008\000\000\t\000\002!\004\216D\176\000\002\128 \000\001\145\000\002\129\184\000\000\000\001H\000\008\006\001@n\208\0002@@\000\002\016\008 \000\000$\000\008\132\019a\018\192\000\n\000\128\000\006D\000\n\006\224\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\144\000\"\016M\132K\000\000(\002\000\000\025\016\000(\027\128\000\000\000\020\128\000\144h\020\006\237\000\001$\004\003\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000R\000\002\001\128P\027\180\000\012\144\016\000\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\008\006\001@n\208\0002@@\000\002\016\008 \000\000$\000\008\132\019a\018\192\000\n\000\128\000\006D\000\n\006\224\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\144\000\"\016M\132K\000\000(\002\000\000\025\016\000(\027\128\000\000\000\020\128\000\128`\020\006\237\000\003$\004\000\000!\000\130\000\000\002@\000\136A6\017,\000\000\160\008\000\000d@\000\160n\245\170\224\001R \002A\160T\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \008$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\255\235\240yr$\002\001\140W\031\188 \015\2120\001\026\196\n\008\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\129@n\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\004\000\000\000\000\000\000\132@\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255_\130\011\145 \016\012B\184\253\225\000~\161\128\008\214 PO\254\191\004\023\"@$\026\133\241\251\194\000\253C\000\145\172P\160\159\253~\015.D\128@1\138\227\247\132\001\250\134\000#X\129A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\247\252<\185\018\001\000\198/\143\2220\007\234\152@\143c\141f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\255\215\224\130\228H\004\003\024\174?x@\031\168`\0025\136\020\019\255\175\193\005\200\144\t\006\161|~\240\128?P\192$k\020('\255_\130\011\145 \018\013B\184\253\225\000~\161\128H\214 \208@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002@\000\136\1936Y,\000\000\160\008@\000w@D\160\238\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000 9\002\001\000\196(\143\218\016\007\234\024\000\140b\005\004\000\000\000@r\004\002\001\136Q\031\180 \015\2120\001\024\196\n\008\000\000\000\000\000\000\000\000\000\000\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\016H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000A \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t  \016\001\t\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\002\003\144 \016\012B\136\253\161\000~\161\128\008\198 P@\000\000\004\007 @ \024\133\017\251B\000\253C\000\017\140@\160\128\000\000\000\000\000\000\000\000\000\000 \000\000\002\000\001\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002 \000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\008\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000D\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\016\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\004\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\128\001\001\130\012\146X\000\001\000\000\128\000f\128\137\001\024\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\005H\128\t\006\129Po\208\000\018@@ \002\018\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\004\007 @ \024\133\017\251B\000\253C\000\017\140@\160\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255_\130\011\145 \018\013B\184\253\225\000~\161\128H\214 P@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253\255\015.D\128@1\139\227\247\140\001\250\166\016#\216\227Y\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\004\000\128\000\004\000\016\000\000\000\000@\000\000\000\000\000\000\018(\192\000\000\000\000\004\002\000L\000\000\000\136\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\030\181\\\000 \004\000\000 \000\140\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\001\000\000@\000\000\000\000\000\005 \000$\026\133\001\187@\000I\001\000\128\008@ \128\000\000\000\n@\000@3\n\003v\128\001\146\002\001@\016\130A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001\000\192(\013\218\000\006H\008\000\000B\001\004\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\n\145\000\018\013\002\160\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\128`\020\006\237\000\003$\004\000\000!\000\130\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\003\000\1607h\000\025  \000\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\016\012\002\128\221\160\000d\128\128\000\004 \016@\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\128\129\006I(\000\000\128\000@\000!@D\000\012\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\005H\128\t\006\129Po\208\000\018@@ \002\018\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\005H\128\t\006\129Pn\208\000\018@@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\005 \000 \024\005\001\187@\000\201\001\000\000\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \208(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000 \000\000\000\000\000\164\000\004\131@\1607h\000\t  \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\005 \000 \025\133\001\187@\000\201\001\000 \008@ \128\000\000\000\n@\000@3\n\003v\128\001\146\002\001@\016\130A\000\000\000\002\020\128\000\128f\020\006\237\000\003$\004\002\128!\004\130\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002A\168P\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\020\128\000\128f\020\006\237\000\003$\004\000\128!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\164\000\004\0030\1607h\000\025  \004\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\016\000 \192%\000\000\016\000\000\000\004\008\000\128\001\128\000\000\000\n@\000@0\n\003v\128\001\146\002\000\000\016\128A\000\000\001\000\000@\000\131\000\148\000\000@\000\000\000\016 \002\000\006\000\000\000\000)\000\001\000\192(\013\218\000\006H\008\000\000B\001\004\000\000\004\000\001\000\002\012\002P\000\001\000\000\000\000@\128\008\000\024\000\000\000\000\164\000\004\003\000\1607h\000\025  \000\001\008\004\016\000\000\016\000\004\000\0080\t@\000\004\000\000\000\001\002\000 \000`\000\000\000\002\144\000\016\012\002\128\221\160\000d\128\128\000\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000@0\n\003v\128\001\146\002\000\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001\000\192(\013\218\000\006H\008\000\000B\001\004\000\000\004\000\001\000\002\012\002P\000\001\000\000\000\000@\128\008\000\024\000\000\000\000\164\000\004\003\000\1607h\000\025  \000\001\008\004\016\000\000\016\000\004\000\0080\t@\000\004\000\000\000\001\002\000 \000`\000\000\000\002\144\000\016\012\002\128\221\160\000d\128\128\000\004 \016@\000\000@\000\016\000 \192%\000\000\016\000\000\000\004\008\000\128\001\128\000\000\000\n@\000@0\n\003v\128\001\146\002\000\000\016\128A\000\000\001\000\000@\000\131\000\148\000\000@\000\000\000\016 \002\000\006\000\000\000\000)\000\001\000\192(\013\218\000\006H\008\000\000B\001\004\000\000\004\000\001\000\002\012\002P\000\001\000\000\000\000@\128\008\000\024\000\000\000\000\164\000\004\003\000\1607h\000\025  \000\001\008\004\016\000\000\016\000\004\000\0080\t@\000\004\000\000\000\001\002\000 \000`\000\000\000\002\144\000\016\012\002\128\221\160\000d\128\128\000\004 \016@\000\000@\000\016\000 \192%\000\000\016\000\000\000\004\008\000\128\001\128\000\000\000\n@\000@0\n\003v\128\001\146\002\000\000\016\128A\000\000\001\000\000@\000\131\000\148\000\000@\000\000\000\016 \002\000\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\005 \000 \025\133\001\187@\000\201\001\000\160\008A \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\128f\020\006\237\000\003$\004\002\128!\004\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000R\000\002\001\152P\027\180\000\012\144\016\n\000\132\018\008\000\000\000\000\164\000\004\0030\1607h\000\025  \004\001\008$\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\002\144\000\016\012\194\128\221\160\000d\128\128P\004 \144@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\001H\000\008\006a@n\208\0002@@\008\002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\008\001\000\000\008\000#\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \212(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000&\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\004\000\004\128\000\000\000\000\000\000\001\000\000@\000\000\000\000\000\000\000\008\000\t\000\000\000\000\000\000\000\002\000\000\128\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000=j\184\000@\008\000\000@\001\024\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\128\000 \000\000\000\000\000\002\144\000\018\013B\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000u\170\160\001\000 \000\000\000\004\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\128\000 \000\000\000\000\000\002\144\000\018\013B\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\255\235\240Ar$\002\001\140W\031\188`\015\2120\001\026\196\n\008\000\000\000\000\000\000\000\128@\000\000\000\128\000\000\001\016\000\000\001\136\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255_\130\011\145 \016\012b\184\253\227\000~\161\132\008\214 V`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001 \000D`\155,\150\000@P\004$\000;\160 Pw\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\016\000\004\000\000\000\000\000\000R\000\002A\168P\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\008\001\000\000\008\000#\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\000\001 \212(\013\218\000\002H\008\004\000B\001\004\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\001\000\128\000\000\001\000\000\000\002 \000\000\003\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253~\008.D\128H5\n\227\247\140\001\250\134\017#X\129Y\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\245\248 \185\018\001\000\198+\143\2220\007\234\024@\141b\005f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\005H\128\t\006\129Po\208\000\018@@ \002\018\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\002`\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\001\235U\192\002\000@\000\002\000\008\192\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\004\000\001\000\000\000\000\000\000\020\128\000\144j\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\173U\000\008\001\000\000\000\000 \000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\004\000\001\000\000\000\000\000\000\020\128\000\144j\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253~\008.D\128H5\n\227\247\140\001\250\134\017#X\129Y\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128@ \000\000\000@\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\175\193\005\200\144\t\006\161\\~\241\128?P\192$k\016( \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\152\004\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\128\000\000\000\000@r\004\002\001\136Q\031\180 \015\2120\001\024\196\n\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\004\000\000\000\000\000\000\000\000\000\128\000\255\239\248Ar4\002a\168_\031\188`\031\2130\153\030\199Z\204\000\000\000\128\228\008\004\003\016\162?h@\031\168`\0021\136\020\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255_\130\011\145 \016\012b\248\253\225\000~\161\128\008\2468\208@\000\000\000\000\000\000\004\002\000\000\000\000\000\000\000\000\128\000\000\000\031\253~\008.D\128@1\139\227\247\132\001\250\134\000#\216\227A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@ \016\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\255\215\224\130\228H\004\131P\190?x@\031\168`\018=\1424\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255_\130\011\145 \018\013B\248\253\225\000~\161\128H\2468\208@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\016\000\031\253~\008.D\128@1\139\227\247\132\001\250\134\000#X\161A\000\000\000\000\000\000\000\016\008\002\000\000\000\000\000\000\002\000\000@\000\127\245\248 \185\018\001\000\198/\143\222\016\007\234\024\000\141b\133\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\002\001\000@\000\000\000\000\000\000@\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253~\008.D\128H5\011\227\247\132\001\250\134\001#X\161A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000 &\000\000\000@\000\000\000\004\000\000\000\000\000\000\000\128\003\001\000\000\000\000\000\128\000\000@\000\002\000/\254\191\004\023\"@ \024\197q\251\194\000\253C\000\017\172@\160\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004 \024\008\000\000\000\000\004\000\000\002\000\000\016\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\255\235\240Ar4\002a\168W\031\188 \031\2120\t\026\196J\013\255\215\224\130\228H\004\003\024\174?x@\031\168`\0025\136\020\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\254\191\004\023#@&\026\133q\251\194\001\253C\000\145\172D\160\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\016\000\031\253~\008.D\128H5\011\227\247\132\001\250\134\001#X\161A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\004\002\000\000\000\004\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000?\250\252\016\\\137\000\144j\021\199\239\024\003\245\012\002F\177\002\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\223\175\192\005H\144\008\006\001Pn\240\0002@@\000\011\016( \000\000\000\002\144\004\018\013\002\128\221\160\000$\128\128@\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000{\245\248\000\169\018\001\000\192*\013\222\000\006H\008\000\001b\005\004\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015Z\174\000\016\002\000\000\016\000@\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\002\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002A\168P\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\245\170\224\001\000 \000\001\000\004`\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\133\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\192\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\161@n\208\000\018@@ \002\016\008 \000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\014\181T\000 \004\000\000\000\000\128\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131P\1607h\000\t  \016\001\008\004\016\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\016\000\030\253~\000*D\128@0\n\131w\128\001\146\002\000\000X\129A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002@\000\128\193\006I,\000\128\128\000H\0001@@\128\140\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\161@n\208\000\018@@ \002\016\008 \000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\015Z\174\000\016\002\000\000\016\000F\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002A\168P\027\180\000\004\144\016\008\000\132\002\008\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000=j\184\000T\136\000\144h\021\006\253\000\001$\004\002\000! \130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000&\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144j\020\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\235U@\002\000@\000\000\000\008\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H5\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\001\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000 \000\000\002\002`\000\000\004\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\001\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\016\128\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\255\235\240Ar$\002\001\140W\031\188 \015\2120\001\026\196\n\008\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000?\250\252\016\\\137\000\144j\021\199\239\008\003\245\012\002G\177\134\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\008@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\191\250\252\016\\\137\000\128c\021\199\239\008\003\245\012\000F\177\002\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\255\235\240Ar$\002\001\140W\031\188 \015\2120\001\026\196\n\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\020\006\237\000\001$\004\000\000!\000\130\000\000\000\000\000\008\000\000\000\000\000\000\000\008\000\000\000\000\000\000\002\000\000\000\000R\000\002A\160P\027\180\000\004\144\016\000\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\129@n\208\000\018@@\000\002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\004\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@r\004\002\001\136Q\031\180 \015\2120\001\024\196\n\008\000\000\000\000\000 \000\000\000\000\000\000\000 \000\000\000\000\000\000\008\000\000\001\001\200\016\008\006!D~\208\128?P\192\004c\016( \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\007 @ \024\133\017\251B\000\253C\000\017\140@\160\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\016\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\129@n\208\000\018@@\000\002\016\008 \000\000\000\000\000\128\000\000\000\000\000\000\000\128\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000?\250\252\000@\008\000\000@\001\000\002\000\000\004\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\008\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\016\000\000\000\000\000\000\005\255\215\224\002\000@\000\002\000\008\000\016\000\000 \000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255_\128\008\001\000\000\008\000 \000@\000\000\128\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\008\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\000\004\131@\1607h\000\t  \000\001\008\004\016\000\000\000\000\000@\000\000\000\000\000\000\000@\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000=j\184@\225\008\137 B\001\000\000$\000\n\161 \000L\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015Z\174\0008B\"\008\016\128@\000\t\000\002\168H\000\019\000\000\030\181\\\000p\132\000\016!\000\128\000\018\000\005P\144\000&\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000@\016\008\000\000\000\000\000\000\000\008\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\001\000@\000\000\000\000\000\000\000\000 \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\016\000\000\000@\000\002\000\128\000\000\000\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000 \000\000\000\000\000\000\128\000\000\000\000\000\000\004\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\016\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015Z\174\0008B \008\016\128@\000\t\000\002\168H\000\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000=j\184\000\225\008\000 B\001\000\000$\000\n\161 \000D\000\000\000\008\000\000@\016\000\000\000\000\000\000\000\000\008\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\016\000\000\000@\000\002\000\128\000\000\000\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000 \008\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\001\000@\000\000\000\000\000\000\000\000 \001\000\000\000\000\000\000@\000\002\000\128\000\000\000\000\000\008\000\000@\002\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000@\016\000\000\000\000\000\000\000\000\008\000@\000\000\000\000\000\016\000\000\128 \000\000\016\000\000\002\000\000\016\000\128\000\008\000\000\000 \000\001\000@\000\000\000\000\000\000\000\000 \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\128\000\004\001\000\000\000\000\000\000\000\000\000\128\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\128\004\000\128\000\004\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\129\000\030\181\\\000 \004\000\000 \000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\016\000\000\128 \000\000\016@\000\000\000\000\016\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000(\000\000\000\000\000\000\000\128\000\004\001\000\000\000\000\000\000\000\000\000\128\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\001\000\000\000\004\000\000 \008\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\002\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\004`\000\000\129\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000 \008\000\000\000 \000\000\000\000\004\000 \000\000\000\000\000\008\000\000@\016\000\000\000\000\000\000\000\000\008\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\008\002\000\000\000\000\000\000\000\000\001\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000@\016\000\000\000\000\000\000\000\000\008\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\128\000\004\001\000\000\000\000\000\000\000\000\000\128\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000 \008\000\000\000\016\000\000\000\000\004\000 \000\000\000\000\000\008\000\000@\016\000\000\t\000\000\001\000\000\008\000@\000\004\000\000\000\016\000\000\128 \000\000\000\000\000\000\000\000\016\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000@\000\002\000\128\000\000\000\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\008\000\000\000 \000\001\000@\000\000\000\000\000\000\000\000 \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\016\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\001\000@\000\000\000\000\000\000\000\000 \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000@\000\000\001\000\000\008\002\000\000\000\000\000\000\000\000\001\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\128\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\002\000\128\000\000\000\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\016\004\000\000\000\016\000\000\000\000\002\000\016\000\000\000\000\000\004\000\000 \008\000\000\000\000\000\000\000\000\004\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\173\215\000\012\001\000\000\008@ \000\000\000\000\128\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\004\000\000 \008\000\000\000\144\000\000\128\000\004\000 \000\002\000\000\000\008\000\000@\016\000\000\000\000\000\000\000\000\008\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000=n\184\000`\008\000\000B\017\000\000\000\000\004\000 \000\000\000\000\000\008\000\000@\016\000\000\000\000\000\000\000\000\008\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\002\000\128\000\000\000\000\000\000\000\000@\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000@\016\000\000\008\000\000\000\000\000\008\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000 \000\001\000@\000\000\000\000\000\000\000\000 \001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\132\014\016\136\146\004 \016\000\002@\000\170\018\000\004\192\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\014\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\136\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\001\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\0001\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\129@n\208\000\018@@\000\002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\130\000\000\000\000\000\n@\000H4\n\003v\128\000\146\002\000\000\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253\255\008.D\128H=\014\227\247\132\001\250\166\017#X\129Y\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255\127\194\011\145 \018\015B\184\253\225\000~\169\132H\214 Vg~\251\128\016\002\000\000\000\000@\000\000\000\000\016\000\000\000\000\000\000H\163\000\000\000\000\000\000\008\000\000\000\000\000 \000\000\000\000\000\029\251\238\000@\008\000\000\000\001\000\000\000\000\000@\000\000\000\000\000;\247\220\000\128\016\000\000\000\002\000\000\000\000\000\128\000\000\000\000\000\002E\024\000\000\000\000\000\000@\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018(\192\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000$Q\128\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000H\163\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\145F\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000@3\n\003v\128\001\146\002\001@\016\128A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\223\191\224\004\000\128\000\004\000\016\000\000\000\000D\000\000\000\000\000\000\018(\192\000\000\000\000\004\000\000\000\000\000\000\008\000\000\000\000\000\015\254\191\004\023\"@ \024\197q\251\194\000\253C\000\017\172@\160\128\000\000\000\000\000\000\008\004\000\000\000\000\000\000\000\017\000\000\000\024\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128@ \000\000\000\000\000\000\000\136\000\000\000\196\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\175\193\005\200\144\t\006\161\\~\240\128?P\194$k\016+0\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\024\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\019\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\000\008\001\000\000\008\000#\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\016\000=j\184\000@\008\000\000@\001\024\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\017\000\003\214\171\128\004\000\128\000\004\000\017\128\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\127\245\248 \185\018\001 \212+\143\222\016\007\234\024\004\141b\013\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\020`\000\000\000\000\002\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\004\002\001\000\000\000\000\000\000\000\004@\000\000\006 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253~\008.D\128H5\n\227\247\132\001\250\134\017#X\129Y\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\004\192\000\000\008\000@\000\000\000b\000\000\000\000\000\128@\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\028\006\237\000\001$\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\196\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005 \000$\026\005\001\187@\000I\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\024\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\247\252 \185\018\001 \244;\143\222\016\007\234\152D\141b\005f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\136\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253\255\008.D\128H=\n\227\247\132\001\250\166\017#X\129Y\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\247\252 \185\018\001\000\198+\143\222\016\007\234\152@\141b\005f\000\000\000\000\000\000\000@ \000\000\000\000\000\000\000\136\000\000\000\197\255\223\240\130\228H\004\003\024\174?x@\031\170a\0025\136\021\152\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255\127\194\011\145 \018\013B\184\253\225\000~\169\132H\214 Vo\254\255\132\023\"@ \024\197q\251\194\000\253S\008\017\172@\172\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \016\008\000\000\000\000\000\000\000\"\000\000\0001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\255\239\248Ar$\002A\168W\031\188 \015\2130\137\026\196\n\204\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\191\225\005\200\144\t\006\161\\~\240\128?T\194$k\016+0\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\254\255\132\023\"@$\026\133q\251\194\000\253S\008\145\172@\172\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\003\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015\254\255\132\023\"@$\026\133q\251\194\000\253S\008\145\172@\172\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \016\008\000\000\000\000\000\000\000\"\000\000\0001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\255\239\248Ar$\002A\168W\031\188 \015\2130\137\026\196\n\204\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000&\000\000\000@\002\000\000\000\003\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\t\000\000\000\000\000\000\000\000\002\t\192\012\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000@\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\002\004\000\000\000\000\000\000\004\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\008\016\000\000\000\000\000\000\016\000\000\000 \000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\008\001\000\000\000\000\000\004\000\000\016 \000\000\000\000\000\000 \000\000\000@\000\000\000\001\000\002\000\002\000\000\000\000\000\000\000\017\128\016\000 \020\000\000\000\000\000\016\000\000@\128\000\000\000\000\000\000\128\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000 \000 \000\000\000\000\000\000\001\024\001\000\000\001@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\008\000\000\000\000\000\000\000\000\000N\000`\000\000@\000\000\000\008\000\016\000\000\000\000\000\000\000\000\000\140\000\192\000\000\128\000\000\000\016\000 \000\000\000\000\000\000\000\000\001\024\001\000\000\001\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\004`\004\000\128\004\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000F\000@\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\0020\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\002\000\000\000\000\000\000\000\000\000\017\128\024\000\000\016\000\000\000\002\000\004\000\000\000\000\000\000\000\000\000#\000 \000\000 \000\000\000\000\000\008\000\000\000\000\000\000\000\000\000F\000@\000\000@\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\140\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")
   
   let action =
-    ((16, "\001\128\000X\000\000\000\000\001\015\000\000\000\000\000\000\001\128\000\000\002,%\"\000\000\000\127;\208\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\191\000y\000\000%\"#\"C\146\000C<2\000\000\000\000\000\000\000\000B\244\000\005C\146\001 C\146\000\000\000U\000\000C\146\000\000\000\133\000\000\000\000\000\0032\202\000\000\000\0004\156\000\0005\028\000\1822\2022\202\016j\016j5\028\000\0006L\000\0006\2042\202\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0005t2\202\000\000\000\0005t\000\0005t\000\0005t\000\000\000\000\000\000\018\208\000\133\000\000\016j\000\000*\2202\202\02302\202\000\000\000\000\000\000\000\000\000\000\000\000\025`2\202\000\000\026N2\202\026\1742\202\027\1562\202\000\0002\202\000\0002\202\027\2522\202\028\2342\202\029J2\202\03082\202\030\1522\202\000\1462\202\000\000\000\000\000\000\000\000\000\0002\202\031\1342\202\031\2302\202 \2122\202\000\000\000\0002\202\000\000\015\254%\164\000\000\000\000\000\140\000\000\000\000\000\000\023\252\000\000\000\000\000\000\000\000\000\000\014\024\000\127\000\000%\164\000\000\000\251\016j\000\0002\202\000\222\000\000\000\000\000\133\000\000\000\000\000\000\000\000\001\028\000\000\000\000\001@\000\000\00052\202\000\000\0005\000\000\000\000\016j\001B\000\000\002\"\000\000\000\000\000\000\000\000\000\000\000\000\000\0007$2\202\000\0007$\000\0007$7$\000\000\000\000'\164\000\133\000\000\016j\002N\000\0002\202\002T\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016j\002^6L\000\000\000\000;\1602\202\000\0002\202\000\000\000\000\002f\000\000\000=5\244\003N2\202\003V\000\000\000\0006L\000=\000\000\000\000\000\000\000\000\000\000<\2166L=,6L=<6L>26L\000\0006L\000\0006L>`6L>\1806L?\1506L?\1966L@\0242\202\003\0206L\000\0006L@\2506LA(6LA|\003$\000\000\003\160\000\000\000\132%\"\000\000\000\132\000\000\000\000\003\1802\202\000\000\004$\000\0006L\004\140\000\000\016j\003\214\000\000\000\000\003\232\000\000\000\000\000\003\000\000\004\198\000\000%>B:\004\196\004\198\000\133\004P\005$D0\000C\000\000\000\000\001\006D\136\000\000\000\000\000\000\005(\005\024\001\"\005>D0\001\222D0\000\000\000\000\001 \000\000\000\000\004\146\000\000\004\162\005`D0\004\186\000\000\000\000\001\006\000\000\004\202\005\156\000\000D\222C\232\000\000\000\133\005\182\000\000\014\024\000\133\005\186\000\000\000\000#\214C\146\004\234\000\000\005j\000\000\005\002\000\000\000\162%\"\000\000%\"\000\000\004\240\000\000\000\162\000\000\012\246\018\240\005\192D0\005\018\005\232\000\000%\"\000\158\000\000\005\236\000\000\000\000\000\000\000\000\000\000\000\000\005\2102\202\005$\017\"\005\2142\202\0050\005\218\001\006\005^\006z\000\0007\1648$\016j\005<\000\000\005D8$\000\000\000\000\000\000\000\000\000\000\000\000\000\0008\1642\202\000\0008\164\000\0008\1648\164\000\000\000\000\022B\000\133\000\000\016j\005`\000\0002\202\005r\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000&.2\202\000\0002\202\000\000\005z\000\000\0005\000\000\000\000\000\000\000\000\000\000+@8$,.8$,b8$-P8$\000\0008$\000\0008$-\1328$.r8$.\1668$/\1488$/\2002\202\005\1668$\000\0008$0\1828$0\2348$1\216\016j\005\130\000\000\000\0002\202\000\000\006T\000\000\001J\006.2\202\006\000\000\000\006<2\202\006\008\000\000\003>\000\000\006z\006z\001J\000\000\001J\000\000\012\246\006z\006z\000\000\000\000\000\000\020\172\000\000\000\000\000\000\000\000\006L2\202\005\162\017\"\017\240\000\133\006v\000\000\006X3\132\006|3\132\006\1302\202\005\180\017\"\017\"\000g\0026\000Y\000\000\000\000\000\000\0026\000\000\002j\000g\000\000\000\000\005\184\000\000\000\000\000\000\006\142\000\000\006\144\000\000\000\000\006\192\006v2\202\005\204\006\160\000\000\019\190\006\136\016j\005\218\017\"\000\000\000\000\006\004\000\000\0009\000\000\003\226\000\000\001J\000\000\000\000\006X\000\000.(\018\240\006\156D0\005\252\006\214\000\000\000\133\000\000\000\0272\202(J\000\0009$2\202\006\n\000\000\016j\006\n\000\000\006\016\000\000\000\000\000\000\000\000\000\000\000\000\000\0009\1642\202\000\0009\164\000\0009\1649\164\000\000\000\000D\174\000\133\000\000\016j\006\018\000\0002\202\006\016\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016j\006\024:$\000\000\000\0002\202\000w2\202\006\022\006J(J(\242'\014\006\1962\202\006\156\000\000\000\000\000\133\006^(J\000\000\006\\(J\000\000\000\000\020X:$\021F:$\025p:$!\188:$\000\000:$\000\000:$$~:$(&:$E\216:$E\238:$F8:$Ff:$F\196:$F\218\000\000\000\000\0064\000\000\006D)\154\000\000*B\006J*B1\252\006L*B\000\000\000\000\000\000\000\000\000\000\006t(J\000\000\000\000\006F\000\000\007\030\000\000\000\133\000\000\000\027\007$\000\000\000N\006\250\000\133\006^\007\024D0\006n\000@\000\0002\202\007B\000\000\001\022\001\026\003\178\007,D0\006~\007T\000\000\000\0052\202\007X\000\000\007`\000\000\014\024\000\133\002\1722\202\007|\000\000\007\128\000\000\011\170\0009\000\000\011\170\000\000\000\000\019\190\002\2442\202\007\144\000\000\007\148\000\000\000\000\001\154\007h\000\133\006\206\007\128D0\006\210\000\210\000\0002\202\007\166\000\000\0009\000\000\000\000\007\198\000\000\011\170\000\000\007\142\016j\006\228\007\182\000\000\001\022\000\000\007\158D0\006\242\007\196\000\000\00302\202\007\200\000\000\007\202\000\000\014\024\000\133\003@2\202\007\206\000\000\007\208\000\000\000\000\000\000\007\198\000\000\000\000\0009\000\000\006z\000\000\001\022\000\000\000\000\001\024\017\240\000\000\001\024\000\000\000\000\007\006\000\000\0005\000\003\017\"\000\000\003\226\0009\003\226\000\000\0009\000\000\006z\000\000\006z\000\000\000\000\000\000\007\004\000\000\000\000\007\014\000\000\001\162\005.\000\013\003\226\000\000\000\000\000\000\003\"\000\000\006z\000\000\001\162\000\000\000\000\001\022\003\214\012\246\000\000\014\242\000\000\t\018\012\246\000\000\000\000\t\018\000\000\000\000\007\012\000\000\000\000\007\018\000\000\001\248\006z\000\000\001\248\000\000\000\000\007\128\000\000\0009\000\000\006z\000\000\000\000\000\000\015\1283\226\000\000\007\232\000\000\015\128\007\236\000\000\007\244\000\000.(\000\133\002\028\000\0002\202\007\246\000\000\007\218\007\212\000\133\007H\008\002D0\007T\002d\000\0002\202\008&\000\000\001\022\002\176\000\0002\202\008,\000\000\014\024\000\133\002\196\000\0002\202\008.\000\000\002\158\015\128\000\000\019\190\003<\000\0002\202\0080\000\000\000\000\000\000\008\022\008\006\000\133\007j\008\028D0\007~\004$\000\0002\202\008V\000\000\002.\000\000\0088\016j\007\144\008b\000\000\002\188\000\000\004j\000\0002\202\008d\000\000\014\024\000\133\004\140\000\0002\202\008h\000\000\002\158\000\000\000\000\007\162\000\000\002.\003\174\008\016\000\000\000\000\000\000\008\020\000\000\002\016\002d\000\000\012\246\008f\000\000\000\0002\202\007\214\006z\000\000\007\174\000\000\001\006\000\000\000\000\003h\012\246\000\000\012\246\000\000\007\160\000\000\003h\000\0006L\003\2046L\000\0006L\000\000\007\164\000\000\003\204\000\000\017\"\004\028\017\"\000\000\017\"\000\000\007\168\000\000\004\028\000\0006L\003\204\007\174\000\000;\028\000\133\004 ;\028\000\000;\028\000\000\007\178\000\000\004 \000\0006L\003\204\007\186\000\000\000\000\021\248\000\000\000\000\000\000\000\000\000\000\025H!x\000\000\006\160\000\000\005\222\000\000\000\000\007\254\000\133\000\000\000\000\000\000\000\164\005\222\000\000\002\238\002\130\002\130\000\000\002\018\002\130\000\000\007\242\000\000\000\000\000\000\000\000\000\000\000\000\008p\000\000\"\160\000\000%\"\005\222\000\000\003^\005\222\000\000\008~\000\000\005\222\008\130\000\000\005\234\006\030\008\132\000\000\008\134\000\000\0076\007\216\005\222\008\018\005\222\008\140\000\000\008\142\000\000\008\146\000\000%\"\000\000\002\154%\"\000\000\008\028\011\188\000\000\001\002\005\222\000\000\004\166\005\222\000\000\004\208\003\136\000\133\000\000\t\004\000\133\000\000\008$\000\000\000\000\000\000\000\000\008\164\000\000\006\030\005\222\008\166\000\000\008\178\000\000\005\222\008\180\000\000\005\222\008\182\000\000\008\144\005\222\008\186\000\000\015\180\006\030\005\222\008D\005\222\008\190\000\000\008\192\000\000\000\000\004\168\005\222\000\000\004\220\001\130\001\130\000\000\000\000\000\000\003\158\001\130\000\000\008J\000\000\000\000\000\000\000\000\005\222\000\000\004\200\005\222\000\000\004\234\003\196\000\133\008L\000\000\000\000\000\000\000\000\008\204\000\000\008\206\000\000\005\222\008\208\000\000\007\216\005\222\008\210\000\000\008\216\000\000-\006\008\140\008\182\007j\005\222\008\226\000\000\000\000\008\228\000\000\008\186-\006\005\222\008\234\000\000\005\222\008\238\000\000\008\246\000\000\005\222\008\128\005\222\008\250\000\000\t\008\000\000\000\133\008\140\000\000\000\000\021\248\000\000\000\000\0028\th\000\000\000\000\003^\000\000\000\000\000\0002\202\000\135\t\166\008\208\tR6L\000\000\003\1926L\000\000\008\166\000\000\000\000\000\000\000\000\000\000\002\150\000\000\003n\000\000\000\000\000\000\003\226C2\005lC2C2\005l\000\000\000\000\000N\000N\000N\000N\000\000\000\000\000\000\000\000\000\000\000\000(J\008\166\000\000\000\000\000\000;\160\000N\014@\0009\000\000\000\000\0009\000\000\007\198\000\000\000\000\000\135\000\000\000\000\008\240\001h\t`E\146\000\000\004nE\250\000\000\000\000\tb\tR\000\133\000\000\000\133\000\000\004n\000\000\004\140E\146\000\000\000\000\008\182\tr\006z\008\204\000\000\001\154\0009\000\000\007\198\000\000\014\196\005,\000\000\000\000\tp\000\000\000\000\0028\000\000\004\172\000\000\000\000\000\0002\202\000\135\000\000\002\150\000\000\004\230\000\000\000\000\000\000\005.\000\000\n^\001\020\n^\000\000\006z\n^\000\000\001\020\000\000\006z\000\000\006z\000\000\006z\000\000\000\000\000\000\000\000\000\000\000\135\000\000\006z\000\000\001\020\000\000\006z\000\000\017H\000\000\000\000\t\018\t\008\000\133\003\144\t\152\004`\000\000\004`\t\194\000\000\t\196\000\000\t\200\000\000\000\000\001*\004`\012\244\004`\000\000\000\000\000\152\008\220\000\000\t\206\000\000\000\000\t\018\007\184\002\202\t\234\n\248\t\234\000\000\000\000\007\250\000\133\000\000\004\024\tD\000\000\000\000\000\000\004\192\000\000\008\246\000\000\000\000\000\000\007\184\002\202\007\250\004\024\004\192\008\252\000\000\000\133\000\000\t\242\t\238\t<\000\133\t\144\000\000"), (16, "\n\149\n\149\n\149\n\149\n\149\n\149\n\149\n\149\n\149\n\149\n\149\000:\n\149\n\149\n\149\n\149\n\149\n\149\n\149\n\149\n\149\tJ\000\210\tJ\002\174\n\149\000\023\000\027\003i\005\197\008\002\n\149\0055\n\149\n\149\n\149\n1\000\210\n\149\0086\000z\000\146\n\149\n\149\000\210\n\149\006F\n1\005=\006J\000\162\002\242\008\002\020\178\n\149\006N\000~\n\149\n\149\006R\020\182\0086\020>\n\149\n\149\000\162\n\149\000\222\n\149\000\174\0119\003\233\000\162\n\149\nf\n\149\n\149\n\149\n\149\n\149\000\n\011\186\008\186\n\149\n\149\n\149\n\149\n\149\n\149\008\194\n\149\n\149\n\149\n\149\005\229\005\229\011f\n\149\n\149\005\229\000\014\0119\002\253\003\218\011\158\tV\003%\n\149\n\149\n\149\n\149\n\149\n\149\n\149\000\194\n\149\002U\n\149\t\146\n\149\002U\003%\n\149\n\149\005\197\005\242\005\157\tV\n\149\011\238\005=\013f\n\149\0119\0119\n\149\011\134\022\182\0119\n\149\n\149\n\149\n\149\004\158\n\149\n\149\003\233\011\134\005=\n\149\n\149\n\149\005=\n\149\012z\n\149\n\149\0066\n\149\003\181\n\149\n\149\000\250\011\190\n\149\n\149\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\ny\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\tJ\012\190\005\250\004q\005\205\008\006\008\022\008&\000\162\008\002\005\205\003%\005\205\005\205\005\205\003%\003%\005\205\0086\004\005\002\026\005\205\004q\022\182\005\205\006F\000\182\003%\006J\004\158\013B\005\149\020\178\005\205\006N\000\006\002r\001.\006R\020\182\011\206\001:\005\205\005\205\017J\000\210\000\210\005\205\005\205\012~\0136\003%\005\205\022\190\005\205\005\205\005\205\005\205\005\205\007\217\005m\018.\005\205\005\205\005\205\005\205\005\205\005\205\000\162\005\205\005\205\005\205\005\205\000\162\000\162\018\246\005\205\005\205\001.\002\190\008\t\0016\001:\012^\tV\004q\006z\005\205\005\205\005\205\005\205\005\205\005\205\005.\005\205\016\018\005\205\005U\005\205\013\182\005E\005\205\005\205\004q\005\149\005\189\007\013\005\205\002\222\000\162\007\013\005J\008\t\008\t\005\205\022\198\018\250\008\t\005\205\005\205\005\205\005\205\000\162\005\205\005\205\002\234\022\190\003\014\005\205\005\205\005\205\005\237\014\158\005\237\005\205\005\205\005\237\005\205\003\181\005\205\005\205\015r\0146\005\205\005\205\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\008*\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005e\005e\014\206\002\242\005\237\005\237\020\026\005\237\005\165\n!\005\237\0172\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\000.\006\018\016Z\016\130\016\170\016\186\016\230\005\237\022\238\005V\005\237\017Z\n1\002y\014\230\005\237\005\237\005\237\005\237\005\237\015\142\005\237\014\162\005\213\015\002\005\173\005\237\020\026\005\237\005\237\005\237\005\237\005\237\015\022\015\250\017f\005\237\005\237\005\237\005\237\005\237\005\237\nI\005\237\005\237\005\237\005\237\003\022\n1\014b\005\237\005\237\005\157\008\190\014f\005\237\001.\005]\014\210\011\206\001:\005\237\005\237\005\237\005\237\005\237\005\237\017V\005\237\003j\005\237\tJ\005\237\008*\003v\005\237\005\237\003\170\n1\008\218\008\002\005\237\003\210\003\001\015&\005\237\n1\000\162\005\237\0086\015\230\006\021\005\237\005\237\012\014\005\237\014\234\005\237\005\237\003\233\005\213\016:\005\237\018\022\005\213\005\213\015\006\008.\005\181\005\237\n)\005\237\011\134\005\237\005\237\003\226\005\213\005\237\005\237\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\012B\000^\020\146\000b\006N\000f\000j\000n\006R\020\154\005\213\015\142\018J\004m\006V\006\021\003\234\nY\011\134\004j\000r\016b\000\226\006f\006\130\tV\007!\006\134\014b\004\001\012\218\000v\004m\014f\007\242\016B\015*\014j\012\250\004\158\008\002\007!\019B\000\238\003\233\004\142\008\002\001.\011\134\0086\011\206\001:\008J\006\142\020\214\0086\011\134\008N\013r\000\162\023\018\016\138\001\"\016\198\001&\003\197\000\134\tR\008V\015\230\015^\017\170\006\162\001.\008Z\006\166\008^\001:\000\162\006\170\006\174\008b\006\178\020+\020/\016j\022\134\008f\0203\000\162\007!\020\131\020\135\005\133\022\142\004m\020\139\006\182\006\186\008j\008n\006\190\008r\019\n\000\162\015\150\008\134\004\150\003\161\003!\nA\008\146\006\198\004m\005\149\tV\022\146\005\245\004\182\004\194\020V\tV\015\178\022\150\008\178\016\146\n9\016\206\008\182\008\242\003\197\t^\004\206\006\202\008\246\004\218\007!\023\026\006\206\003\197\003\197\003\129\023\030\005}\003\197\008\254\004\230\006\210\007!\005\245\005\245\004\250\015b\001j\005\245\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\005\n\000^\020\146\000b\006N\000f\000j\000n\006R\020\154\005\014\003\129\018F\022\158\006V\ni\na\005\141\018\242\005u\000r\015\154\000\226\006f\006\130\019>\0055\006\134\021\167\0055\005\022\000v\nq\0055\007\242\0055\006\005\021\171\015\182\0055\0055\021:\005\253\000\238\022\166\005M\008\002\021\174\005\026\006\013\005B\005F\008J\006\142\020\214\0086\021j\008N\013\186\023&\002m\005N\001\"\005r\001&\003\213\000\134\tR\008V\018:\018\230\005z\006\162\001.\008Z\006\166\008^\001:\005~\006\170\006\174\008b\006\178\005\134\021\199\021\203\0192\008f\017*\021\207\006\005\005\154\005\158\002b\017\202\004\217\005\253\006\182\006\186\008j\008n\006\190\008r\006\013\000\162\005\182\008\134\005\198\003\161\017.\005\218\008\146\006\198\021\235\021\239\017.\005\226\006\029\021\243\0172\017*\tV\005\234\006\007\008\178\0172\006\030\006&\008\182\008\242\006*\t^\006>\006\202\008\246\006Z\006b\006j\006\206\0055\003\213\017.\006r\006v\019\226\008\254\006~\006\210\006\150\006\029\006\029\0172\006\158\001j\006\029\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\006\246\000^\020\146\000b\006N\000f\000j\000n\006R\020\154\018\194\007\002\007J\t\205\006V\018~\007\194\007\234\007\254\007\221\000r\008\n\000\226\006f\006\130\008\018\000\162\006\134\008\026\008\"\008v\000v\000\162\008~\007\242\008\142\008\150\t\205\008\158\017>\007\221\008\166\008\174\000\238\008\234\017>\008\002\008\250\t\002\t\014\007\221\t\018\0082\006\142\t\026\0086\t\030\008N\000\162\017\"\t*\t2\001\"\tB\001&\003\241\000\134\008R\008V\tf\tv\017>\006\162\001.\008Z\006\166\008^\001:\t~\006\170\006\174\008b\006\178\t\130\t\170\t\182\011A\008f\t\190\n\018\n\030\t\205\nR\nn\017\226\nr\n\130\006\182\006\186\008j\008n\006\190\008r\n\138\000\162\n\154\008\134\n\166\003\161\011*\0112\008\146\006\198\011B\011N\017.\011j\008\017\011z\011\130\004a\tV\011\150\007\221\008\178\0172\011\162\011\170\008\182\008\242\003\241\t^\011\174\006\202\008\246\011\182\007\221\011\198\006\206\003\241\003\241\004a\011\218\011\226\003\241\008\254\011\230\006\210\011\246\008\017\008\017\004a\011\254\001j\008\017\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\012\022\000^\012\030\000b\006N\000f\000j\000n\006R\017*\012J\003!\012R\t\193\006V\012b\004a\012j\012n\012v\000r\012\134\000\226\006f\006\130\012\170\003!\006\134\012\178\012\182\017.\000v\000\162\012\198\007\242\012\206\012\210\t\193\012\226\012\234\0172\013\002\013\n\000\238\013Z\017>\008\002\013\162\013\174\014\"\014.\014N\0082\006\142\014z\0086\014\134\008N\004a\005\221\014\142\014\170\001\"\014\178\001&\017\230\000\134\008R\008V\014\182\019z\004a\006\162\001.\008Z\006\166\008^\001:\014\190\006\170\006\174\008b\006\178\014\194\014\202\014\218\011A\008f\014\242\015\014\0152\t\193\t\205\015B\015F\015N\015R\006\182\006\186\008j\008n\006\190\008r\003!\000\162\015Z\008\134\003!\003!\015j\015z\008\146\006\198\000\162\015\130\015\134\015\162\011A\015\190\003!\022\134\tV\015\210\015\226\008\178\015\242\017>\016\n\008\182\008\242\016\026\t^\016&\006\202\008\246\016O\005\221\016w\006\206\016\159\005\221\005\221\016\183\003!\016\219\008\254\t\205\006\210\016\243\011A\011A\0176\023\006\001j\011A\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\017r\000^\017\143\000b\006N\000f\000j\000n\006R\017\183\005\221\017\195\017\211\017\219\006V\017\238\017\247\017\255\003\141\018\007\000r\018\"\000\226\006f\006\130\018b\nQ\006\134\018w\018\135\022z\000v\007)\003\141\007\242\018\143\018\155\018\167\018\174\018\183\018\202\018\211\018\219\000\238\019\022\019J\008\002\007)\019_\019g\019s\019\131\0082\006\142\019\139\0086\019\150\008N\019\154\019\167\019\179\019\186\001\"\019\199\001&\019\211\000\134\008R\008V\019\219\019\230\019\239\006\162\001.\008Z\006\166\008^\001:\019\247\006\170\006\174\008b\006\178\020\003\020\030\020B\020F\008f\020J\020b\020\222\021&\021.\021J\021N\021z\007)\006\182\006\186\008j\008n\006\190\008r\nQ\000\162\021~\008\134\nQ\nQ\021\134\003\141\008\146\006\198\022\214\003\141\003\141\021\179\022~\022\138\022\154\022\162\tV\022\170\022\211\008\178\022\218\003\141\003\141\008\182\008\242\018V\t^\022\242\006\202\008\246\023\022\023/\nQ\006\206\023S\023b\023f\007)\nQ\023j\008\254\023s\006\210\000\000\000\000\003\141\000\000\000\000\001j\007)\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\000\000\000^\020\146\000b\006N\000f\000j\000n\006R\020\154\000\000\000\000\000\000\000\000\006V\000\000\000\000\000\000\000\000\000\000\000r\000\000\000\226\006f\006\130\000\000\000\000\006\134\000\000\000\000\000\000\000v\000\000\000\000\007\242\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008J\006\142\000\000\000\000\000\000\008N\022\002\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\134\tR\008V\000\000\000\000\000\000\006\162\001.\008Z\006\166\008^\001:\000\000\006\170\006\174\008b\006\178\000\000\000\000\000\000\000\000\008f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\182\006\186\008j\008n\006\190\008r\000\000\000\162\000\000\008\134\000\000\003\161\000\000\n\025\008\146\006\198\000\000\000\000\000\000\000\000\007\245\000\000\000\000\000\000\000\000\000\000\000\000\008\178\000\000\000\000\000\000\008\182\008\242\000\000\t^\000\000\006\202\008\246\000\000\000\000\000\000\006\206\000\000\000\000\000\000\000\000\000\000\000\000\008\254\000\000\006\210\000\000\007\245\007\245\000\000\000\000\001j\007\245\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\000\000\000^\000\000\000b\006N\000f\000j\000n\006R\0055\000\000\000\000\000\000\000\000\006V\000\000\000\000\000\000\000\000\000\000\000r\n\025\000\226\006f\006\130\n\025\n\025\006\134\000\000\000\000\0055\000v\000\000\000\000\007\242\000\000\000\000\n\025\000\000\000\000\0055\000\000\000\000\000\238\000\000\000\000\000\000\000\000\022\246\000\000\000\000\000\000\008J\006\142\000\000\000\000\000\000\008N\012&\000\000\000\000\n\025\001\"\000\000\001&\0055\000\134\tR\008V\000\000\000\000\002b\006\162\001.\008Z\006\166\008^\001:\000\000\006\170\006\174\008b\006\178\000\000\000\000\000\000\011\029\008f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\182\006\186\008j\008n\006\190\008r\000\000\000\162\000\000\008\134\000\000\000\000\000\000\000\000\008\146\006\198\0055\000\000\000\000\000\000\011\029\000\000\000\000\000\000\000\000\000\000\000\000\008\178\000\000\0055\000\000\008\182\008\242\000\000\t^\000\000\006\202\008\246\000\000\000\000\000\000\006\206\000\000\000\000\000\000\000\000\000\000\000\000\008\254\000\000\006\210\000\000\011\029\011\029\000\000\000\000\001j\011\029\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\000\000\000^\000\000\000b\006N\000f\000j\000n\006R\000\000\000\000\000\000\000\000\000\000\006V\000\000\000\000\003\029\000\000\000\000\000r\000\000\000\226\006f\006\130\000\000\000\000\006\134\000\000\000\000\000\000\000v\003\029\000\000\007\242\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\000\000\000\003\029\000\000\000\000\000\000\008J\006\142\000\000\000\000\000\000\008N\013\238\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\134\tR\008V\000\000\000\000\000\000\006\162\001.\008Z\006\166\008^\001:\000\000\006\170\006\174\008b\006\178\000\000\000\000\000\000\000\000\008f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\182\006\186\008j\008n\006\190\008r\000\000\000\162\000\000\008\134\000\000\000\000\003\029\000\000\008\146\006\198\003\029\003\029\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\178\003\029\000\000\000\000\008\182\008\242\000\000\t^\000\000\006\202\008\246\002\154\000F\000J\006\206\000N\003\029\000R\000V\000\000\000Z\008\254\000^\006\210\000b\003\029\000f\022\190\000n\001j\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\000r\000^\000\000\000b\006N\000f\000j\000n\006R\000\000\000\000\000v\000\000\000\000\006V\000\000\000\000\000\000\000\000\000\000\000r\000\000\000\226\006f\006\130\000\000\000\000\006\134\000\000\000\000\000\000\000v\000\000\000\000\007\242\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\134\000\000\000\000\000\000\000\000\000\000\008J\006\142\000\000\000\000\000\000\008N\020\246\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\134\tR\008V\000\000\000\000\000\000\006\162\001.\008Z\006\166\008^\001:\000\000\006\170\006\174\008b\006\178\000\000\000\162\000\000\000\000\008f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\182\006\186\008j\008n\006\190\008r\012\190\000\162\000\000\008\134\000\000\000\000\000\000\000\000\008\146\006\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007!\000\000\000\000\008\178\000\000\tJ\000\000\008\182\008\242\000\000\t^\000\000\006\202\008\246\008\002\007!\000\000\006\206\001.\000\000\000\000\011\206\001:\0086\008\254\000\000\006\210\000\000\0002\006\022\000F\000J\001j\000N\006F\000R\000V\006J\000Z\000\000\000^\000\000\000b\006N\000f\000j\000n\006R\000\000\000\162\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000r\000\000\000\226\006\229\006\130\007!\018\190\006\134\000\000\000\000\000\000\000v\000\000\000\000\014n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\000\017.\000\000\000\000\tV\000\000\014~\006\142\000\000\006\229\006\229\0172\000\000\000\000\006\229\000\000\001\"\0055\001&\000\000\000\134\000\000\000\000\000\000\000\000\007!\006\162\001.\000\000\006\166\0016\001:\000\000\006\170\006\174\008b\006\178\007!\0055\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\000\0055\0055\000\000\006\182\006\186\000\000\000\000\006\190\000\000\000\000\000\162\000\000\0002\0006\000F\000J\000\000\000N\006\198\000R\000V\000\000\000Z\000\000\000^\0055\000b\000\000\000f\000j\000n\002b\000\000\000\000\0055\0055\000\162\t^\000\000\006\202\014\130\000\000\000\000\000r\006\206\000\226\000\000\000\230\000\000\017>\000\234\014\138\000\000\006\210\000v\000\000\000\000\000\000\000\000\001j\000\000\000\000\000\000\000\000\000\000\0055\000\238\000\000\000\000\000\242\000\000\000\000\000\000\0055\000\000\001\006\001\002\000\000\001\n\000\000\000\000\000\000\000\000\000\000\000\000\001\"\0055\001&\000\000\000\134\000\000\000\000\000\000\000\000\000\000\001*\001.\000\000\0012\0016\001:\001\142\001>\001B\000\000\001F\0055\000\000\000\000\0055\0055\000\000\000\000\0055\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001J\000\000\0055\001N\000\000\000\000\000\162\000\000\006V\000\000\000\000\000\000\000\000\000\000\001V\000\000\000\226\006f\006\130\000\000\000\000\006\134\000\000\001Z\000\000\000\000\000\000\000\000\007\242\000\000\000\000\000\000\000\000\000\000\000\000\001^\000\000\000\238\000\000\000\000\001b\000\000\000\000\003e\000\000\000\000\008\130\006\142\000\000\001f\012\190\008N\000\000\000\000\000\000\001j\001\"\000\000\001&\000\000\000\000\000\000\008V\000\000\000\000\000\000\006\162\001.\008Z\006\166\008^\001:\000\000\006\170\006\174\000\000\006\178\000\000\000\000\000\000\000\000\008f\000\000\000\000\000\000\000\000\001.\000\000\000\000\011\206\001:\006\182\006\186\008j\008n\006\190\008r\000\000\000\162\000\000\008\134\000\000\000\000\000\000\000\000\008\146\006\198\000\000\000\000\000\000\000\000\006V\000\000\000\000\000\000\000\000\000\000\000\162\008\178\000\226\006f\006\130\008\182\008\242\006\134\000\000\000\000\006\202\008\246\000\000\008A\007\242\006\206\000\000\000\000\000\000\000\000\000\000\000\000\008\254\000\238\006\210\000\000\000\000\000\000\000\000\000\000\001j\000\000\006\138\006\142\000\000\000\000\000\000\008N\000\000\000\000\000\000\000\000\001\"\000\000\001&\008A\008A\000\000\008V\000\000\008A\000\000\006\162\001.\008Z\006\166\008^\001:\000\000\006\170\006\174\000\000\006\178\000\000\000\000\000\000\000\000\008f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\182\006\186\008j\008n\006\190\008r\000\000\000\162\000\000\008\134\000\000\000\000\000\000\000\000\008\146\006\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011m\0055\008\178\011m\0055\000\000\008\182\008\242\0055\000\000\0055\006\202\008\246\000\000\0055\0055\006\206\000\000\011m\000\000\000\000\000\000\011m\008\254\000\000\006\210\001\130\011m\000\000\000\000\000\000\001j\000\000\011m\000\000\000\000\011m\011m\000\000\011m\011m\000\000\000\000\001\138\000\000\011m\002\182\000\000\000\000\011m\000\000\000\000\011m\000\000\011m\011m\000\000\000\000\000\000\0055\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\146\000\000\000\000\000\000\000\000\000\000\011m\000\000\011m\000\000\000\000\001.\000\000\000\000\0016\001:\000\000\000\000\011m\000\000\000\000\000\000\000\000\002\194\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011m\011m\011m\000\162\011m\011m\002\198\0055\011m\000\000\000\000\000\000\004\001\000\000\000\000\004\001\002\206\000\000\000\000\000\000\011m\000\000\000\000\011m\011m\011m\011m\000\000\000\000\000\000\004\001\011m\011m\011m\004\001\011m\011m\011m\004\001\004\001\000\000\000\000\000\000\000\000\000\000\004\001\000\000\000\000\004\001\004\001\000\000\004\001\004\001\000\000\000\000\004\001\000\000\004\001\004\001\000\000\000\000\004\001\000\000\000\000\004\001\000\000\004\001\004\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\210\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\001\000\000\004\001\n\182\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\001\000\000\000\000\000\000\000\000\004\001\000\000\000\000\000\162\n\190\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\001\004\001\004\001\n\198\004\001\004m\004\001\000\000\004\001\011\006\011\014\000\000\004\005\000\000\000\000\004\005\004\001\000\000\000\000\n\230\004\001\000\000\n\206\004\001\n\222\004\001\000\000\000\000\000\000\000\000\004\005\004\001\004\001\004\001\004\005\004\001\004\001\004\001\004\005\004\005\000\000\000\000\000\000\000\000\n\238\004\005\000\000\000\000\004\005\004\005\000\000\004\005\004\005\000\000\000\000\004\005\000\000\004\005\004\005\000\000\000\000\004\005\000\000\000\000\004\005\000\000\004\005\004\005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\246\000\000\000\000\000\000\000\000\000\000\000\000\n\214\004\005\000\000\004\005\000\181\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\169\004\005\000\000\000\000\000\000\000\000\004\005\000\000\000\000\000\000\n\190\000\000\000\000\000\000\000\000\011\022\n\254\000\000\000\000\000\000\000\000\000\000\004\005\004\005\004\005\n\198\004\005\004q\004\005\000\000\004\005\000\181\000\181\000\000\000\000\000\000\000\000\000\000\004\005\000\000\000\000\n\230\004\005\000\000\n\206\004\005\n\222\004\005\000\000\000\000\000\000\000\000\000\000\004\005\004\005\004\005\000\000\004\005\004\005\004\005\001=\001=\001=\001=\000\000\001=\n\238\001=\001=\000\000\001=\000\000\001=\000\000\001=\000\000\001=\001=\001=\000\000\000\000\000\000\000\000\016\254\000\000\000\000\000\000\000\000\000\000\000\000\001=\001=\001=\000\000\000\000\000\000\000\000\001=\000\000\000\000\n\246\000\000\001=\000\000\000\000\000\000\001=\n\214\000\000\000\000\001=\000\000\000\000\017\002\000\000\000\000\001=\000\000\011\193\000\181\000\000\011\193\000\000\001=\000\000\000\000\000\000\000\000\001=\000\000\000\000\000\000\000\000\000\000\000\181\n\254\011\193\001=\000\000\000\000\011\193\000\000\000\000\000\000\006\230\011\193\000\000\000\000\000\000\000\000\000\000\011\193\000\000\000\000\011\193\011\193\001=\011\193\011\193\001=\000\000\006\238\000\000\011\193\006\250\000\000\000\000\011\193\000\000\000\000\011\193\000\000\011\193\011\193\001=\000\000\001=\000\000\001=\000\000\001=\000\000\000\000\000\000\000\000\001=\000\000\000\000\001=\000\000\000\000\000\000\011\193\000\000\011\193\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001=\011\193\000\000\001=\001=\000\000\007\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\017\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\193\011\193\011\193\000\000\011\193\000\000\007\n\000\000\011\193\000\000\000\000\000\000\001\137\000\000\000\000\001\137\007\018\000\000\000\000\000\000\000\000\000\000\000\000\011\193\000\000\011\193\000\000\000\000\000\000\000\000\001\137\011\193\011\193\011\193\001\137\011\193\011\193\011\193\000\000\001\137\000\000\000\000\000\000\000\000\000\000\001\137\000\000\000\000\001\137\001\137\000\000\001\137\001\137\000\000\000\000\000\000\000\000\001\137\000\000\000\000\000\000\001\137\000\000\000\000\001\137\000\000\001\137\001\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\137\000\000\001\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\137\004%\000\000\002\130\004%\002\134\004%\002\138\004%\000\000\004%\000\000\000\000\002\142\004%\004%\000\000\000\000\000\000\000\000\000\000\001\137\001\137\001\158\000\000\001\137\001\137\004%\000\000\001\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\004%\000\000\000\000\001\137\000\000\004%\001\137\001\137\001\137\001\137\000\000\000\000\000\000\000\000\002J\001\137\001\137\000\000\001\137\001\137\001\137\004%\000\000\000\000\004%\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\004%\004%\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\004%\004%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\000\000\004%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\004%\004%\000\000\000\000\004%\000\000\000\000\000\000\000\000\004%\004%\000\000\000\000\000\000\004%\t\189\t\189\t\189\t\189\000\000\t\189\000\000\t\189\t\189\000\000\t\189\000\000\t\189\000\000\t\189\000\000\t\189\t\189\t\189\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\189\t\189\t\189\001\190\000\000\000\000\002\018\t\189\000\000\000\000\000\000\000\157\t\189\000\000\000\000\000\000\017\022\000\000\000\000\000\000\017\030\001\202\000\000\000\000\000\000\002\001\t\189\000\000\000\000\000\157\002\001\000\000\000\000\t\189\000\000\000\000\001\210\000\000\t\189\002\001\002\001\000\000\0022\002:\n\198\000\000\000\000\t\189\002\001\000\000\000\157\000\157\001\242\000\000\000\000\001\218\000\000\001\234\002\001\000\000\000\157\000\000\000\000\n\206\000\000\n\222\t\189\000\000\000\000\t\189\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\250\000\000\002\001\000\000\000\000\000\000\000\000\t\189\000\157\t\189\000\000\t\189\002\001\t\189\000\000\000\000\000\000\000\000\t\189\000\000\000\000\t\189\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\001\002\002\000\000\t\189\002\001\002\001\017\146\t\189\001\226\000\157\000\000\000\000\000}\000\000\000\000\000}\n\214\000\000\000\000\000\000\002\001\000\000\000\000\002\001\002\001\002\001\002\001\000\000\000\157\000\000\001\202\000\000\002\001\002\001\000}\002B\002\n\002\001\000\000\000}\000\000\000\000\000\000\000\157\000\157\001\210\000\000\000\000\000}\000}\000\000\000}\000}\000\000\000\000\000\000\000\000\000}\000\000\000\000\000e\001\242\000\000\000e\001\218\000\000\001\234\000}\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000e\000\000\000\000\000\000\000e\000\000\000\000\000\000\001\250\000e\000}\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000e\000e\000}\000e\000e\000\000\000\000\000\000\000\000\000e\000\000\000\000\000\000\000e\000\000\000\000\001\218\000\000\001\234\000e\000\000\000\000\000\000\000}\002\002\000\000\000\000\000}\000}\000\000\000\000\001\226\000\000\000\000\000\000\000\000\000\000\000\000\000e\000\000\000e\000\000\000\000\000}\000\000\000\000\000}\000}\000}\000}\000e\000\000\000\000\000\000\000\000\000}\000}\000\000\000}\002\n\000}\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000e\000e\000\000\000\000\000e\000e\000\000\000\000\001\226\000\000\000\000\000\000\000]\000\000\000\000\000]\000\000\000\000\000\000\000\000\000e\000\000\000\000\000e\000e\000e\000e\000\000\000\000\000\000\000]\000\000\000e\000e\000]\000e\000e\000e\000\000\000]\000\000\000\000\000\000\000\000\000\000\000]\000\000\000\000\000]\000]\000\000\000]\000]\000\000\000\000\000\000\000\000\000]\000\000\000\000\000a\000]\000\000\000a\001\218\000\000\000]\000]\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000a\000\000\000\000\000\000\000a\000\000\000\000\000\000\000]\000a\000]\000\000\000\000\000\000\000\000\000a\000\000\000\000\000a\000a\000]\000a\000a\000\000\000\000\000\000\000\000\000a\000\000\000\000\000\000\000a\000\000\000\000\001\218\000\000\000a\000a\000\000\000\000\000\000\000]\000]\000\000\000\000\000]\000]\000\000\000\000\001\226\000\000\000\000\000\000\000\000\000\000\000\000\000a\000\000\000a\000\000\000\000\000]\000\000\000\000\000]\000]\000]\000]\000a\000\000\000\000\000\000\000\000\000]\000]\000\000\000]\000]\000]\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000a\000a\000\000\000\000\000a\000a\000\000\000\000\001\226\000\000\000\000\000\000\000q\000\000\000\000\000q\000\000\000\000\000\000\000\000\000a\000\000\000\000\000a\000a\000a\000a\000\000\000\000\000\000\001\202\000\000\000a\000a\000q\000a\000a\000a\000\000\000q\000\000\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000q\000q\000\000\000q\000q\000\000\000\000\000\000\000\000\000q\000\000\000\000\000i\000q\000\000\000i\001\218\000\000\001\234\000q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\202\000\000\000\000\000\000\000i\000\000\000\000\000\000\001\250\000i\000q\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000i\000i\000q\000i\000i\000\000\000\000\000\000\000\000\000i\000\000\000\000\000\000\000i\000\000\000\000\001\218\000\000\001\234\000i\000\000\000\000\000\000\000q\000q\000\000\000\000\000q\000q\000\000\000\000\001\226\000\000\000\000\000\000\000\000\000\000\000\000\000i\000\000\000i\000\000\000\000\000q\000\000\000\000\000q\000q\000q\000q\000i\000\000\000\000\000\000\000\000\000q\000q\000\000\000q\000q\000q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000i\000i\000\000\000\000\000i\000i\000\000\000\000\001\226\000\000\000\000\000\000\000m\000\000\000\000\000m\000\000\000\000\000\000\000\000\000i\000\000\000\000\000i\000i\000i\000i\000\000\000\000\000\000\001\202\000\000\000i\000i\000m\000i\000i\000i\000\000\000m\000\000\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000m\000m\000\000\000m\000m\000\000\000\000\000\000\000\000\000m\000\000\000\000\000u\000m\000\000\000u\001\218\000\000\001\234\000m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\202\000\000\000\000\000\000\000u\000\000\000\000\000\000\001\250\000u\000m\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000u\000u\000m\000u\000u\000\000\000\000\000\000\000\000\000u\000\000\000\000\000\000\001\242\000\000\000\000\001\218\000\000\001\234\000u\000\000\000\000\000\000\000m\000m\000\000\000\000\000m\000m\000\000\000\000\001\226\000\000\000\000\000\000\000\000\000\000\000\000\001\250\000\000\000u\000\000\000\000\000m\000\000\000\000\000m\000m\000m\000m\000u\000\000\000\000\000\000\000\000\000m\000m\000\000\000m\000m\000m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000u\002\002\000\000\000\000\000u\000u\000\000\000\000\001\226\000\000\000\000\000\000\001\190\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000u\000\000\000\000\000u\000u\000u\000u\000\000\000\000\000\000\001\202\000\000\000u\000u\000\133\000u\000u\000u\000\000\000\133\000\000\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000\133\000\133\000\000\000\133\002:\000\000\000\000\000\000\000\000\000\133\000\000\000\000\001\190\001\242\000\000\000y\001\218\000\000\001\234\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\202\000\000\000\000\000\000\000y\000\000\000\000\000\000\001\250\000y\000\133\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000y\000y\000\133\000y\000y\000\000\000\000\000\000\000\000\000y\000\000\000\000\000\000\001\242\000\000\000\000\001\218\000\000\001\234\000y\000\000\000\000\000\000\000\133\002\002\000\000\000\000\000\133\000\133\000\000\000\000\001\226\000\000\000\000\000\000\000\000\000\000\000\000\001\250\000\000\000y\000\000\000\000\000\133\000\000\000\000\000\133\000\133\000\133\000\133\000y\000\000\000\000\000\000\000\000\000\133\000\133\000\000\002B\002\n\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000y\002\002\000\000\000\000\000y\000y\000\000\000\000\001\226\000\000\000\000\000\000\001\190\000\000\000\000\000\129\000\000\000\000\000\000\000\000\000y\000\000\000\000\000y\000y\000y\000y\000\000\000\000\000\000\001\202\000\000\000y\000y\000\129\000y\002\n\000y\000\000\000\129\000\000\000\000\000\000\000\000\000\000\001\210\000\000\000\000\000\129\000\129\000\000\000\129\002:\000\000\000\000\000\000\000\000\000\129\000\000\000\000\000\000\001\242\000\000\000\000\001\218\000\000\001\234\000\129\000\000\000\000\000\000\000\000\000\000\t\173\t\173\t\173\t\173\000\000\t\173\000\000\t\173\t\173\000\000\t\173\000\000\t\173\001\250\t\173\000\129\t\173\t\173\t\173\000\000\000\000\000\000\000\000\000\000\000\000\000\129\000\000\000\000\000\000\000\000\t\173\t\173\t\173\000\000\000\000\000\000\000\000\t\173\000\000\000\000\000\000\000\000\t\173\000\000\000\000\000\000\000\129\002\002\000\000\000\000\000\129\000\129\000\000\000\000\001\226\000\149\t\173\000\000\000\000\000\000\000\000\000\000\000\000\t\173\000\000\000\000\000\129\000\000\t\173\000\129\000\129\000\129\000\129\000\149\000\000\000\000\000\000\t\173\000\129\000\129\000\000\000\129\002\n\000\129\000\000\000\000\000\000\000\000\000\149\000\000\000\000\000\000\000\000\000\000\000\149\000\149\t\173\000\000\000\000\t\173\000\000\000\000\000\000\000\000\000\149\000\000\000\000\n\206\000\000\000\149\000\000\000\000\000\000\000\000\t\173\000\000\t\173\000\000\t\173\000\000\t\173\000\000\000\000\000\000\000\000\t\173\000\000\000\000\t\173\000\149\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\173\000\000\000\000\017\026\t\173\t\177\t\177\t\177\t\177\000\000\t\177\000\000\t\177\t\177\000\000\t\177\000\000\t\177\000\000\t\177\000\149\t\177\t\177\t\177\000\000\000\000\000\000\n\214\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\177\t\177\t\177\000\000\000\149\000\000\000\000\t\177\000\000\000\000\000\000\000\000\t\177\000\000\000\000\000\000\017\150\000\000\000\000\000\149\000\149\000\000\000\000\000\000\000\000\000\000\t\177\000\000\000\000\000\000\000\000\000\000\000\000\t\177\000\000\000\000\000\000\000\000\t\177\000\000\000\000\004i\000\000\000\000\004i\000\000\004i\t\177\004i\000\000\004i\000\000\000\000\000\000\004i\004i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\177\004i\000\000\t\177\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004i\004i\000\000\000\000\000\000\000\000\004i\t\177\000\000\t\177\000\000\t\177\000\000\t\177\000\000\000\000\000\000\000\000\t\177\000\000\000\000\t\177\004i\000\000\000\000\004i\000\138\000\000\000\000\000\000\000\000\004i\000\000\000\000\004i\004i\t\177\000\000\000\000\000\000\t\177\000\000\004i\000\000\000\000\004i\004i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004Q\004i\000\000\004Q\000\000\004Q\000\000\004Q\000\000\004Q\000\000\004i\000\000\004Q\004Q\000\000\000\000\000\000\000\000\004i\000\000\000\000\000\000\004i\000\000\000\000\004Q\000\000\000\000\000\000\000\000\000\000\004i\000\000\000\000\000\000\004Q\004Q\000\000\000\000\000\000\000\000\004Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004i\000\000\000\000\004i\004i\000\000\004Q\004i\000\000\004Q\005\210\000\000\004i\004i\000\000\004Q\000\000\004i\004Q\004Q\000\000\000\000\000\000\000\000\000\000\000\000\004Q\000\000\000\000\004Q\004Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\153\000\000\004Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004Q\000\000\000\000\000\000\004Q\000\000\000\000\000\000\000\153\000\000\000\000\000\000\000\000\004Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\153\000\000\000\000\000\000\000\000\000\000\000\153\000\153\000\000\000\000\004Q\000\000\000\000\004Q\004Q\000\000\000\153\004Q\000\000\n\206\000\000\000\153\004Q\004Q\000\000\000\000\000\000\004Q\0002\0006\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\000\000\000^\000\153\000b\000\000\000f\000j\000n\000\000\0055\000\000\000\000\0055\000\000\000\000\000\000\0055\000\000\0055\017\158\000r\017\186\0055\0055\000\000\000\000\017\198\000\000\000\000\000\000\000\000\000v\000\000\000\000\000\000\000\000\000\153\000\000\000\000\000\000\000\000\000\000\000\000\n\214\000\000\017\222\000\000\000\000\000\000\000\000\000\000\0055\000\130\000\000\000\000\000\153\000\000\018\n\000\000\000\000\0055\000\000\000\000\0055\000\000\0055\000\134\0055\000\000\0055\000\153\000\153\000\000\0055\0055\000\000\002b\000\000\000\000\0055\000\000\000\000\000\000\000\000\000\000\018*\0055\0055\018z\000\000\0055\0055\000\000\000\000\000\000\000\000\0055\0055\000\000\000\000\0055\000\000\0055\018\146\000\000\007\213\000\000\018\158\000\000\018\170\000\000\000\000\000\000\000\000\018\186\000\000\000\000\019j\0055\000\000\000\000\0055\0055\000\000\000\000\000\000\000\000\002b\000\000\000\000\0055\0055\019v\000\000\000\000\000\000\019\142\000\000\0055\000\000\000\000\0055\0055\000\000\001\161\000\000\000\000\001\161\000\000\000\000\000\000\0055\000\000\000\000\0055\0055\000\000\000\000\000\000\000\000\000\000\0055\001\161\0055\0055\000\000\001\161\000\000\0055\0055\000\000\001\161\000\000\0055\000\000\000\000\000\000\001\161\000\000\000\000\001\161\001\161\0055\001\161\001\161\000\000\000\000\000\000\000\000\001\161\000\000\000\000\000\000\001\161\000\000\000\000\001\161\000\000\001\161\001\161\000\000\000\000\0055\000\000\000\000\0055\0055\000\000\000\000\0055\000\000\000\000\000\000\000\000\0055\0055\000\000\000\000\001\161\0055\001\161\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\161\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\161\001\161\0076\000\000\001\161\000\000\000\000\000\000\001\161\000\000\000\000\000\000\n~\000\000\000\000\000\000\000\000\003I\000\000\003I\000\000\000\000\003I\001\161\000\000\001\161\000\000\000\000\000\000\000\000\000\000\007>\001\161\001\161\000\000\001\161\001\161\001\161\003I\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003I\003I\000\000\000\000\003I\003I\000\000\000\000\000\000\000\000\003I\000\000\003I\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003I\003I\000\000\003I\003I\003I\000\000\003I\003I\000\000\003I\000\000\000\000\011\165\000\000\000\000\011\165\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003I\003I\000\000\000\000\003I\000\000\011\165\003I\000\000\000\000\011\165\000\000\000\000\000\000\003Z\003I\000\000\000\000\000\000\000\000\000\000\011\165\000\000\000\000\003I\011\165\003I\011\165\011\165\000\000\000\000\003b\000\000\000\000\003n\000\000\003I\011\165\000\000\000\000\011\165\003I\011\165\000\000\000\000\000\000\000\000\003I\000\000\000\000\003I\000\000\000\000\000\169\000\000\000\000\003I\000\000\000\000\000\000\000\000\000\000\011\165\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\190\000\000\000\000\011\165\000\000\000\000\000\000\000\000\003z\000\000\000\000\000\000\000\226\000\000\t\154\n\198\000\000\t\158\000\000\000\000\000\000\000\169\000\169\000\000\000\000\011\165\011\165\000\000\011\165\000\000\003~\000\169\011\165\000\238\n\206\000\000\n\222\000\000\000\000\000\000\003\134\000\000\t\162\nJ\011\165\000\000\n^\nv\000\000\011\165\011\165\000\000\001\"\000\000\001&\011\165\n\238\000\000\000\000\011\165\011\165\011\165\t\194\001.\000\000\t\198\008^\001:\000\000\t\202\t\206\000\000\t\210\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\182\t\214\000\000\000\169\t\218\000\000\000\000\000\162\000\000\000\226\n\214\t\154\000\000\000\000\t\158\t\226\000\000\000\000\000\000\000\000\000\000\000\000\000\169\000\000\nz\000\000\n\146\000\000\000\000\000\000\000\238\000\000\000\000\000\000\000\000\000\000\t\230\000\169\000\169\t\162\nJ\t\234\000\000\n^\nv\000\000\000\000\011r\000\000\001\"\t\238\001&\000\000\000\000\000\000\000\000\001j\000\000\000\000\t\194\001.\000\000\t\198\008^\001:\000\000\t\202\t\206\000\000\t\210\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\182\t\214\000\000\000\000\t\218\000\000\000\000\000\162\000\000\000\226\000\000\t\154\000\000\000\000\t\158\t\226\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\nz\000\000\n\146\000\000\000\000\000\000\000\238\000\000\000\000\000\000\000\000\000\000\t\230\000\000\000\000\t\162\nJ\t\234\000\000\n^\nv\000\000\000\000\011\030\000\000\001\"\t\238\001&\000\000\000\000\000\000\000\000\001j\000\000\000\000\t\194\001.\000\000\t\198\008^\001:\000\000\t\202\t\206\000\000\t\210\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\182\t\214\000\000\000\000\t\218\000\000\000\000\000\162\000\000\000\226\000\000\t\154\000\000\000\000\t\158\t\226\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\nz\000\000\n\146\000\000\000\000\000\000\000\238\000\000\000\000\000\000\000\000\000\000\t\230\000\000\000\000\t\162\nJ\t\234\000\000\n^\nv\000\000\000\000\004\201\000\000\001\"\t\238\001&\000\000\000\000\000\000\000\000\001j\000\000\000\000\t\194\001.\000\000\t\198\008^\001:\000\000\t\202\t\206\000\000\t\210\000\000\000\000\000\000\000\000\001\137\000\000\000\000\001\137\000\000\000\000\000\000\000\000\000\000\000\000\006\182\t\214\000\000\000\000\t\218\000\000\000\000\000\162\001\137\000\000\000\000\000\000\000\000\000\000\000\000\t\226\000\000\001\137\000\000\000\000\000\000\000\000\000\000\001\137\nz\000\000\n\146\000\000\000\000\001\137\001\137\000\000\000\000\000\000\000\000\000\000\t\230\000\000\000\000\001\137\007j\t\234\001\137\007\186\001\137\001\137\000\000\001\189\000\000\000\000\t\238\000\000\000\000\000\000\000\000\000\000\001j\000\000\007r\000\000\000\000\000\000\002\017\000\000\001\137\000\000\001\137\002\017\000\000\000\000\000\000\000\000\000\000\007z\000\000\000\000\002\017\002\017\000\000\007\202\007\210\000\000\000\000\000\000\000\000\002\017\000\000\000\000\000\000\007\154\000\000\000\000\007\130\000\000\007\146\002\017\000\000\001\137\001\137\001\150\000\000\001\137\001\137\000\000\000\000\001\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\162\000\000\002\017\001\137\000\000\000\000\001\137\001\137\000\000\001\137\000\000\000\000\002\017\000\000\002V\001\137\001\137\000\000\001\137\001\137\001\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\017\007\170\000\000\000\000\002\017\000\000\000\000\000\000\007\138\000\000\000\000\000\000\001%\000\000\000\000\001%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\017\000\000\002\017\000\000\000\000\000\000\000\000\007r\000\000\002\017\002\017\001%\007\218\007\178\002\017\001\013\001%\000\000\001\013\000\000\000\000\000\000\007z\000\000\000\000\001%\001%\000\000\001%\001%\000\000\000\000\000\000\001\013\001%\000\000\000\000\001\013\007\154\000\000\000\000\007\130\001\013\007\146\001%\000\000\000\000\000\000\007z\000\000\000\000\001\013\001\013\000\000\001\013\001\013\000\000\000\000\000\000\000\000\001\013\000\000\000\000\007\162\001\013\001%\000\000\007\130\000\000\007\146\001\013\000\000\000\000\000\000\000\000\001%\0002\0006\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\017*\000^\001\013\000b\001\013\000f\000j\000n\000\000\001%\007\170\000\000\000\000\001%\001\013\000\000\000\000\007\138\000\000\000\000\000r\017.\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\019\146\001%\000\000\001%\001\013\001\013\000\000\000\000\001\013\000\000\001%\001%\007\138\001%\007\178\001%\001\005\000\000\000\000\001\005\000\000\000\130\000\000\000\000\000\000\000\000\018\n\001\013\000\000\001\013\000\000\000:\000\000\000\000\001\005\000\134\001\013\001\013\001\005\001\013\001\013\001\013\001\t\001\005\000\000\001\t\000\000\000\000\000\000\001\005\000\000\000\000\001\005\001\005\000\000\001\005\001\005\000\000\000\000\000\000\001\t\001\005\000\000\000\000\001\t\001\005\000\000\000\000\007\130\001\t\001\005\001\005\000\000\000\162\000\000\001\t\000\000\000\000\001\t\001\t\000\000\001\t\001\t\000\000\000\000\000\000\017>\001\t\000\000\000\000\001\005\001\t\001\005\000\000\007\130\000\000\001\t\001\t\000\000\000\000\000\000\000\000\001\005\0002\tn\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\000\000\000^\001\t\000b\001\t\000f\000j\000n\000\000\001\005\001\005\000\000\000\000\001\005\001\t\000\000\000\000\007\138\000\000\000\000\000r\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000v\001\005\000\000\001\005\001\t\001\t\000\000\000\000\001\t\000\000\001\005\001\005\007\138\001\005\001\005\001\005\001\025\000\000\000\000\001\025\000\000\000\130\000\000\000\000\000\000\000\000\000\000\001\t\000\000\001\t\000\000\000\000\000\000\000\000\007r\000\134\001\t\001\t\001\025\001\t\001\t\001\t\001\017\001\025\000\000\001\017\000\000\000\000\000\000\007z\000\000\000\000\001\025\001\025\000\000\001\025\001\025\000\000\000\000\000\000\007r\001\025\000\000\000\000\001\017\001\025\000\000\000\000\007\130\001\017\007\146\001\025\000\000\000\162\000\000\007z\000\000\000\000\001\017\001\017\000\000\001\017\001\017\000\000\000\000\000\000\000\000\001\017\000\000\000\000\007\162\001\017\001\025\000\000\007\130\000\000\007\146\001\017\000\000\000\000\000\000\000\000\001\025\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\017\000\000\001\017\000\000\000\000\000\000\000\000\001\025\001\025\000\000\000\000\001\025\001\017\000\000\000\000\007\138\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\025\000\000\001\025\001\017\001\017\000\000\000\000\001\017\000\000\001\025\001\025\007\138\001\025\001\025\001\025\001\021\000\000\000\000\001\021\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\017\000\000\001\017\000\000\000\000\000\000\000\000\007r\000\000\001\017\001\017\001\021\001\017\001\017\001\017\001\029\001\021\000\000\001\029\000\000\000\000\000\000\007z\000\000\000\000\001\021\001\021\000\000\001\021\001\021\000\000\000\000\000\000\007r\001\021\000\000\000\000\001\029\001\021\000\000\000\000\007\130\001\029\007\146\001\021\000\000\000\000\000\000\007z\000\000\000\000\001\029\001\029\000\000\001\029\001\029\000\000\000\000\000\000\000\000\001\029\000\000\000\000\007\162\007\154\001\021\000\000\007\130\000\000\007\146\001\029\000\000\000\000\000\000\000\000\001\021\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\162\000\000\001\029\000\000\000\000\000\000\000\000\001\021\001\021\000\000\000\000\001\021\001\029\000\000\000\000\007\138\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\021\000\000\001\021\001\029\007\170\000\000\000\000\001\029\000\000\001\021\001\021\007\138\001\021\001\021\001\021\007j\000\000\000\000\001-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\029\000\000\001\029\000\000\000\000\000\000\000\000\007r\000\000\001\029\001\029\001-\001\029\001\029\001\029\007j\001-\000\000\001!\000\000\000\000\000\000\007z\000\000\000\000\001-\001-\000\000\001-\007\210\000\000\000\000\000\000\007r\001-\000\000\000\000\001!\007\154\000\000\000\000\007\130\001!\007\146\001-\000\000\000\000\000\000\007z\000\000\000\000\001!\001!\000\000\001!\001!\000\000\000\000\000\000\000\000\001!\000\000\000\000\007\162\007\154\001-\000\000\007\130\000\000\007\146\001!\000\000\000\000\000\000\000\000\001-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\162\000\000\001!\000\000\000\000\000\000\000\000\001-\007\170\000\000\000\000\001-\001!\000\000\000\000\007\138\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001-\000\000\001-\001!\007\170\000\000\000\000\001!\000\000\001-\001-\007\138\007\218\007\178\001-\007j\000\000\000\000\001)\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001!\000\000\001!\000\000\000\000\000\000\000\000\007r\000\000\001!\001!\001)\001!\007\178\001!\000\000\001)\000\000\000\000\000\226\000\000\t\154\007z\000\000\t\158\001)\001)\000\000\001)\007\210\000\000\000\000\000\000\000\000\001)\000\000\000\000\000\000\007\154\000\000\000\238\007\130\000\000\007\146\001)\000\000\000\000\000\000\000\000\t\162\nJ\000\000\000\000\n^\nv\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\000\007\162\000\000\001)\000\000\000\000\000\000\t\194\001.\000\000\t\198\008^\001:\001)\t\202\t\206\000\000\t\210\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\182\t\214\001)\007\170\t\218\000\000\001)\000\162\000\000\000\000\007\138\000\000\000\000\000\000\000\000\t\226\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001)\n\146\001)\000\226\000\000\000\230\000\000\000\000\000\234\001)\001)\t\230\001)\007\178\001)\000\000\t\234\000\000\007\246\000\000\000\000\000\000\001\201\000\000\000\238\t\238\000\000\000\242\000\000\000\000\000\000\001j\000\000\000\254\001\002\000\000\001\n\000\000\t\150\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001*\001.\000\000\0012\0016\001:\000\000\001>\001B\000\000\001F\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001J\000\000\000\000\001N\000\000\000\000\000\162\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001V\000\000\000\000\000\226\000\000\000\230\000\000\000\000\000\234\001Z\007\229\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\229\000\000\000\000\001^\000\000\000\000\000\238\000\000\001b\000\242\000\000\007\229\000\000\007\229\000\000\000\254\001\002\001f\001\n\000\000\000\000\000\000\000\000\001j\000\000\001\"\000\000\001&\000\000\000\000\000\000\000\000\000\226\000\000\000\230\001*\001.\000\234\0012\0016\001:\000\000\001>\001B\000\000\001F\000\000\014r\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\242\000\000\000\000\000\000\000\000\001J\000\254\001\002\001N\001\n\000\000\000\162\000\000\000\000\000\000\000\000\001\"\000\000\001&\001V\000\000\000\000\000\000\000\000\000\000\000\000\001*\001.\001Z\0012\0016\001:\000\000\001>\001B\000\000\001F\000\000\000\000\000\000\001^\000\000\000\000\000\000\000\000\001b\000\000\000\000\000\000\000\000\000\000\000\000\001J\000\000\001f\001N\000\000\000\000\000\162\000\000\001j\000\000\000\000\000\000\000\000\000\000\001V\000\000\000\000\000\226\000\000\000\230\000\000\000\000\000\234\001Z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001^\000\000\000\000\000\238\000\000\001b\000\242\000\000\000\000\000\000\000\000\000\000\000\254\004\210\001f\001\n\000\000\000\000\000\000\000\000\001j\000\000\001\"\000\000\001&\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001*\001.\000\000\0012\0016\001:\000\000\001>\001B\000\246\001F\000\000\000\000\000\000\007\237\000\000\007\237\000\000\000\000\007\237\000\000\000\000\000\000\000\000\000\000\000\000\001J\000\000\000\000\001N\000\000\000\000\000\162\000\000\000\000\007\237\000\000\000\000\007\237\000\000\001V\000\000\000\000\000\000\007\237\007\237\000\000\007\237\000\000\001Z\000\000\000\000\000\000\000\000\007\237\000\000\007\237\000\000\000\226\000\000\000\230\001^\000\000\000\234\007\237\007\237\001b\007\237\007\237\007\237\000\000\007\237\007\237\000\000\007\237\001f\000\000\000\000\000\000\000\238\000\000\001j\000\242\000\000\000\000\000\000\000\000\000\000\000\254\001R\007\237\001\n\000\000\007\237\000\000\000\000\007\237\000\000\001\"\000\000\001&\000\000\000\000\000\000\007\237\000\000\000\000\000\000\001*\001.\000\000\0012\0016\001:\000\000\001>\001B\003\222\001F\000\000\000\000\000\000\003A\000\000\003A\007\237\000\000\003A\000\000\000\000\007\237\000\000\000\000\000\000\001J\000\000\000\000\001N\000\000\007\237\000\162\000\000\000\000\003A\000\000\007\237\003A\000\000\001V\000\000\000\000\000\000\003A\003A\000\000\003A\000\000\001Z\000\000\000\000\000\000\000\000\003A\000\000\003A\000\000\000\226\000\000\001\022\001^\000\000\001\026\003A\003A\001b\003A\003A\003A\000\000\003A\003A\000\000\003A\001f\000\000\000\000\000\000\000\238\000\000\001j\000\242\000\000\000\000\000\000\000\000\000\000\001\030\003\162\003A\001\n\000\000\003A\000\000\000\000\003A\000\000\001\"\000\000\001&\000\000\000\000\000\000\003A\000\000\000\000\000\000\003\026\001.\000\000\003\030\0016\001:\000\000\003\"\003&\000\000\003*\000\000\000\000\000\000\000\226\000\000\001\022\003A\000\000\001\026\000\000\000\000\003A\000\000\000\000\000\000\003.\000\000\000\000\0032\000\000\003A\000\162\000\000\000\000\000\238\000\000\003A\000\242\000\000\003:\000\000\000\000\000\000\001\030\003\006\000\000\001\n\000\000\000\000\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\226\000\000\001\022\003>\000\000\001\026\003\026\001.\003B\003\030\0016\001:\000\000\003\"\003&\000\000\003*\003F\000\000\000\000\000\000\000\238\000\000\001j\000\242\000\000\000\000\000\000\000\000\000\000\001\030\0036\003.\001\n\000\000\0032\000\000\000\000\000\162\000\000\001\"\000\000\001&\000\000\000\000\000\000\003:\000\000\000\000\000\000\003\026\001.\000\000\003\030\0016\001:\000\000\003\"\003&\000\000\003*\000\000\000\000\000\000\000\226\000\000\006\130\003>\000\000\006\134\000\000\000\000\003B\000\000\000\000\000\000\003.\000\000\000\000\0032\000\000\003F\000\162\000\000\000\000\000\238\000\000\001j\000\000\000\000\003:\000\000\000\000\000\000\006\138\007\226\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\000\000\000\000\000\003>\000\000\000\000\006\162\001.\003B\006\166\0016\001:\000\000\006\170\006\174\000\000\006\178\003F\000\000\000\000\000\226\000\000\006\130\001j\000\000\006\134\000\000\000\000\000\000\000\000\000\000\006\182\006\186\000\000\000\000\006\190\000\000\000\000\000\162\000\000\000\000\000\238\000\000\000\000\000\000\000\000\006\198\000\000\000\000\000\000\006\138\006\142\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\000\000\000\000\000\006\202\000\000\000\000\006\162\001.\006\206\006\166\0016\001:\000\000\006\170\006\174\000\000\006\178\006\210\000\000\000\000\000\226\000\000\006\130\001j\000\000\006\134\000\000\000\000\000\000\000\000\000\000\006\182\006\186\000\000\000\000\006\190\000\000\000\000\000\162\000\000\000\000\000\238\000\000\000\000\000\000\000\000\006\198\000\000\000\000\000\000\006\138\006\194\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\000\000\000\000\000\006\202\000\000\000\000\006\162\001.\006\206\006\166\0016\001:\000\000\006\170\006\174\000\000\006\178\006\210\000\000\000\000\000\226\000\000\t\154\001j\000\000\t\158\000\000\000\000\000\000\000\000\000\000\006\182\006\186\000\000\000\000\006\190\000\000\000\000\000\162\000\000\000\000\000\238\000\000\000\000\000\000\000\000\006\198\000\000\000\000\000\000\t\162\t\174\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\000\000\000\000\000\006\202\000\000\000\000\t\194\001.\006\206\t\198\0016\001:\000\000\t\202\t\206\000\000\t\210\006\210\000\000\000\000\000\226\000\000\t\154\001j\000\000\t\158\000\000\000\000\000\000\000\000\000\000\006\182\t\214\000\000\000\000\t\218\000\000\000\000\000\162\000\000\000\000\000\238\000\000\000\000\000\000\000\000\t\226\000\000\000\000\000\000\t\162\t\222\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\000\000\000\000\000\t\230\000\000\000\000\t\194\001.\t\234\t\198\0016\001:\000\000\t\202\t\206\000\000\t\210\t\238\000\000\000\000\000\226\000\000\t\154\001j\000\000\t\158\000\000\000\000\000\000\000\000\000\000\006\182\t\214\000\000\000\000\t\218\000\000\000\000\000\162\000\000\000\000\000\238\000\000\000\000\000\000\000\000\t\226\000\000\000\000\000\000\t\162\nJ\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\"\000\000\001&\000\000\000\000\000\000\000\000\t\230\000\000\000\000\t\194\001.\t\234\t\198\0016\001:\000\000\t\202\t\206\000\000\t\210\t\238\000\000\000\000\000\000\000\000\000\000\001j\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\182\t\214\000\000\000\000\t\218\000\000\000\000\000\162\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\226\0002\006\022\000F\000J\006.\000N\006F\000R\000V\006J\000Z\000\000\000^\000\000\000b\006N\000f\000j\000n\006R\t\230\000\000\000\000\000\000\000\000\t\234\000\000\000\000\000\000\000\000\000\000\000r\000\000\000\000\t\238\000\000\000\000\000\000\000\000\000\000\001j\000\000\000v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\130\000\000\000\000\0002\tn\000F\000J\000\000\000N\006F\000R\000V\006J\000Z\000\134\000^\020\146\000b\006N\000f\000j\000n\006R\020\154\001\153\000\000\000\000\001\153\000\000\008b\000\000\000\000\000\000\000\000\000r\000\000\000\000\000\000\007Q\000\000\000\000\000\000\001\153\000\000\000\000\000v\001\153\000\000\000\000\000\000\000\000\000\000\000\162\000\000\000\000\000\000\000\000\001\153\000\000\007Q\000\000\001\153\000\000\001\153\001\153\000\000\000\130\000\000\000\000\007Q\007Q\000\000\000\000\001\153\000\000\007Q\001\153\000\000\001\153\t^\000\134\000\000\0055\000\000\000\000\0055\000\000\000\000\000\000\0055\000\000\0055\000\000\000\000\007Q\0055\0055\000\000\001\153\000\000\000:\000\000\000\000\007Q\007Q\000\000\000\000\000\000\000\000\000\000\001\153\007Q\000\000\000\000\007Q\007Q\000\000\000\000\000\162\000\000\000\000\000\000\003\161\000\000\007Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\153\003\186\007Q\001\153\000\000\000\000\000\000\001\153\0055\000\000\007Q\000\000\000\000\000\000\000\000\000\000\000\000\000\146\000\000\001\153\007Q\000\000\000\000\007Q\001\153\001\153\000\000\000\000\007Q\000\000\003\194\007Q\007Q\000\000\001\153\001\153\001\153\000\000\000\000\000\000\000\000\007Q\000\000\007Q\000\000\000\000\007Q\007Q\004\018\000\000\007Q\004b\000\000\000\000\000\000\007Q\007Q\000\000\000\000\007Q\007Q\000\000\000\000\0055\000\000\000\000\004\026\000\000\000\000\000\000\002\t\000\000\007Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\"\000\000\000\000\000\000\002\t\000\000\004r\004z\000\000\000\237\000\000\007Q\000\237\000\000\007Q\007Q\004B\000\213\000\000\004*\000\213\004:\000\000\007Q\007Q\000\000\000\000\004\026\007Q\000\000\000\000\000\237\000\000\000\000\000\000\000\213\000\000\000\000\000\000\000\213\000\000\004J\004\"\000\000\000\000\000\000\000\237\000\000\000\237\000\237\004\"\000\000\000\000\002\t\000\213\000\000\000\213\000\213\004B\000\000\000\000\004*\000\000\004:\000\000\000\000\000\213\000\000\000\000\004*\000\000\004:\000\000\000\000\000\000\004R\000\000\000\000\002\t\000\000\000\000\000\000\0042\004J\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\213\000\000\000\000\002\t\000\237\000\000\000\000\000\000\002\t\002\t\000\000\000\000\000\213\000\000\000\000\000\000\000\000\000\000\004\130\004Z\002\t\000\000\000\000\000\000\000\000\000\000\004R\000\000\000\000\000\237\000\000\000\000\000\000\0042\000\213\000\000\000\000\000\213\000\000\000\000\000\000\0042\000\000\000\000\000\000\000\237\000\000\000\000\000\000\000\205\000\237\000\237\000\205\000\213\000\000\000\000\000\000\000\000\000\213\000\213\000\237\004Z\000\237\000\000\000\000\000\000\000\000\000\205\000\213\000\213\000\213\000\205\000\209\000\000\000\000\000\209\000\000\000\000\000\000\000\000\000\000\000\000\000\205\000\000\000\000\000\000\000\205\000\000\000\205\000\205\000\209\000\000\000\000\000\000\000\209\000\000\000\000\000\000\000\205\000\000\000\000\004*\000\000\000\205\000\000\000\209\000\000\000\000\000\000\000\209\000\000\000\209\000\209\000\000\000\225\000\000\000\000\000\225\000\000\000\000\000\000\000\209\000\000\000\205\004*\000\000\000\209\000\000\000\000\000\000\000\000\000\000\004\026\000\000\000\000\000\205\000\225\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\209\004\"\000\000\000\000\000\000\000\225\000\000\000\225\000\225\000\000\000\000\000\205\000\209\000\000\000\205\000\000\000\000\000\225\0042\000\000\004*\000\000\004:\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\205\000\000\000\000\000\000\000\209\000\205\000\205\000\209\000\000\000\000\000\000\0042\004J\000\000\000\000\000\205\000\205\000\205\000\000\000\000\000\000\000\000\000\000\000\209\000\225\000\000\000\000\000\000\000\209\000\209\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\209\000\209\000\209\000\000\000\000\000\000\000\000\000\000\000\225\000\000\000\000\000\225\000\000\000\217\000\000\0042\000\217\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\225\000\000\000\000\000\000\004\026\000\225\000\225\000\000\000\217\000\221\000\000\000\000\000\221\000\000\000\000\000\225\000\225\000\225\000\000\004\"\000\000\000\000\000\000\000\217\000\000\000\217\000\217\004\026\000\000\000\000\000\000\000\221\000\000\000\000\000\000\000\217\000\000\000\000\004*\000\000\004:\000\000\004\"\000\000\000\000\000\000\000\221\000\000\000\221\000\221\000\000\000\229\000\000\000\000\000\229\000\000\000\000\000\000\000\221\000\000\000\217\004*\000\000\004:\000\000\000\000\000\000\000\000\000\000\004\026\000\000\000\000\000\217\000\229\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004J\004\"\000\000\000\000\000\000\000\229\000\000\000\229\000\229\000\000\000\000\000\217\000\221\000\000\000\217\000\000\000\000\004B\0042\000\000\004*\000\000\004:\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\217\000\000\000\000\000\000\000\221\000\217\000\217\000\221\000\000\000\000\000\000\0042\004J\000\000\000\000\000\217\000\217\000\217\000\000\000\000\000\000\000\000\000\000\000\221\000\229\000\000\000\000\000\000\000\221\000\221\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\221\000\221\000\221\000\000\000\000\000\000\000\000\000\000\004R\000\000\000\000\000\229\000\000\004\018\000\000\0042\000\245\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\229\000\000\000\000\000\000\004\026\000\229\000\229\000\000\000\245\004\018\000\000\000\000\000\233\000\000\000\000\000\229\000\229\000\229\000\000\004\"\000\000\000\000\000\000\000\245\000\000\000\245\004z\004\026\000\000\000\000\000\000\000\233\000\000\000\000\000\000\004B\000\000\000\000\004*\000\000\004:\000\000\004\"\000\000\000\000\000\000\000\233\000\000\000\233\000\233\000\000\004\018\000\000\000\000\000\241\000\000\000\000\000\000\004B\000\000\004J\004*\000\000\004:\000\000\000\000\000\000\000\000\000\000\004\026\000\000\000\000\000\245\000\241\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004J\004\"\000\000\000\000\000\000\000\241\000\000\000\241\004z\000\000\000\000\004R\000\233\000\000\000\245\000\000\000\000\004B\0042\000\000\004*\000\000\004:\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\245\000\000\000\000\000\000\004R\000\245\000\245\000\233\000\000\000\000\000\000\0042\004J\000\000\000\000\004\130\004Z\000\245\003\153\000\000\000\000\003\153\000\000\000\233\000\241\003\153\000\000\003\153\000\233\000\233\000\000\003\153\003\153\000\000\000\000\000\000\000\000\000\000\000\233\004Z\000\233\000\000\000\000\000\000\000\000\000\000\004R\000\000\000\000\000\241\000\000\000\000\000\000\0042\000\000\000\000\000\000\000\000\000\000\000\000\002-\000\000\000\000\000\000\000\000\000\241\000\000\000\000\000\000\000\000\000\241\000\241\000\000\000\000\000\000\000\000\003\153\000\000\000\000\000\000\000\241\004Z\000\241\000\000\000\000\000\000\000\000\000\000\002-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002-\000\000\000\000\002-\002-\000\000\000\000\000\000\000\000\003Q\003Q\003Q\003Q\002-\003Q\000\000\003Q\003Q\000\000\003Q\000\000\003Q\000\000\003Q\000\000\003Q\003Q\003Q\000\000\000\000\000\000\002-\000\000\000\000\000\000\003\153\000\000\000\170\000\000\000\000\003Q\020\150\000F\000J\002-\000N\006F\000R\000V\006J\000Z\003Q\000^\020\146\000b\006N\000f\000\000\000n\006R\020\154\000\000\000\000\000\000\002-\000\000\000\000\002-\002-\000\000\000\000\000r\003Q\000\000\000\000\000\000\002-\002-\003Q\000\000\000\000\002-\000v\000\000\000\000\000\000\003Q\000\000\0002\000\142\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\000\000\000^\000\000\000b\000\000\000f\000j\000n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\134\000\000\000r\000\000\000\000\000\000\000\000\003Q\000\000\000\000\000\000\000\000\000\000\000v\0002\000\142\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\000\000\000^\000\000\000b\000\000\000f\000j\000n\000\000\000\130\000\000\000\000\000\000\000\000\000\000\000\158\000\000\003\161\000\000\000\000\000r\000\000\003Q\000\134\000\000\0002\005\030\000F\000J\000\000\000N\000v\000R\000V\000\000\000Z\000\000\000^\000\000\000b\000\000\000f\000j\000n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\130\000\000\000\000\000\000\000r\000\000\000\158\000\000\000\000\000\162\000\000\000\000\000\000\000\000\000\134\000v\000\000\0002\005\030\000F\000J\000\000\000N\000\000\000R\000V\000\166\000Z\000\000\000^\000\000\000b\000\000\000f\000j\000n\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000r\011\001\000\134\000\000\000\162\000\000\005\"\005&\000\000\011\137\000\000\000v\0002\000\142\000F\000J\000\000\000N\000\000\000R\000V\000\166\000Z\000\000\000^\000\000\000b\011\137\000f\000j\000n\000\000\000\130\000\000\000\000\n\002\000\000\000\000\000\000\000\000\000\000\000\000\011\137\000r\002)\000\000\000\134\000\000\011\137\011\137\005\"\005&\n\n\000\000\000v\n\022\000\000\005*\011\137\000\000\000\000\011\137\000\000\011\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\130\000\000\000\000\000\000\000\000\000\000\000\158\000\000\011\137\000\000\000\000\000\000\000\000\000\000\000\134\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\"\0052\0002\005\030\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\000\000\000^\000\000\000b\011\137\000f\000j\000n\000\000\n&\000\000\011\137\000\000\000\000\000\162\000\000\000\000\000\000\000\000\n.\000r\000\000\000\000\011\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000v\000\000\000\000\000\000\000\000\000\000\000\000\011\137\011\137\000\000\0002\005\030\000F\000J\000\161\000N\000\000\000R\000V\000\000\000Z\000\130\000^\002!\000b\000\165\000f\000j\000n\000\000\000\000\000\000\n\190\000\000\000\000\000\134\000\000\000\000\000\000\0212\005&\000r\000\000\n\190\000\000\000\000\000\000\n\198\000\000\000\000\000\000\000\000\000v\000\161\000\161\000\000\000\000\000\000\n\198\000\000\000\000\000\000\000\173\000\161\000\165\000\165\n\206\000\000\n\222\000\000\000\000\000\000\000\000\000\130\000\165\000\000\000\000\n\206\000\000\n\222\n\190\000\000\000\000\000\000\000\000\n\182\000\000\000\134\000\161\000\000\0216\0212\005&\000\000\000\000\n\198\000\000\000\000\000\000\n\238\000\000\000\173\000\173\n\190\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\230\000\000\000\000\n\206\000\000\n\222\000\000\n\198\000\000\000\000\000\000\000\161\000\000\000\189\011\014\000\000\000\000\000\000\n\214\000\000\000\000\n\182\000\165\n\230\000\000\n\238\n\206\000\000\n\222\n\214\000\161\021>\n\182\000\000\000\000\000\000\000\000\000\000\000\000\n\190\000\000\000\165\000\000\000\000\000\000\000\161\000\161\000\000\n\238\000\000\n\190\000\000\000\000\000\000\n\198\000\000\000\165\000\165\000\000\n\246\000\177\000\177\000\000\000\000\000\000\n\198\n\214\000\000\000\000\000\000\n\230\000\185\011\014\n\206\000\000\n\222\000\000\000\000\000\173\000\000\000\000\n\230\n\246\000\000\n\206\000\000\n\222\000\000\000\000\n\214\000\000\000\000\000\000\000\173\000\173\n\238\000\000\000\000\000\000\000\000\000\000\000\189\000\000\000\000\000\000\000\000\n\238\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\022\n\254\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\246\000\000\000\000\000\000\000\000\000\000\000\000\n\214\000\000\000\000\000\000\n\246\000\000\000\000\000\000\000\000\000\000\000\000\n\214\000\177\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\185\000\000\000\000\000\000\000\177\n\254\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\185\n\254"))
+    ((16, "\001\128\000X\000\000\000\000\001\015\000\000\000\000\000\000\001\128\000\000\002,%\"\000\000\000\127;\144\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\191\000y\000\000%\"#\"CR\000C;\242\000\000\000\000\000\000\000\000B\180\000\005CR\001 CR\000\000\000U\000\000CR\000\000\000\133\000\000\000\000\000\0032\202\000\000\000\0004\156\000\0006\012\000\0006\1402\2022\202\016j\016j6\012\016j\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0004\2502\202\000\000\000\0004\250\000\0004\250\000\0004\250\000\000\000\000\000\000\018\208\000\133\000\000\016j\000\000*\2202\202\02302\202\000\000\000\000\000\000\000\000\000\000\000\000\025`2\202\000\000\026N2\202\026\1742\202\027\1562\202\000\0002\202\000\0002\202\027\2522\202\028\2342\202\029J2\202\03082\202\030\1522\202\00082\202\000\000\000\000\000\000\000\000\000\0002\202\031\1342\202\031\2302\202 \2122\202\000\000\000\0002\202\000\000\015\254%\164\000\000\000\000\000l\000\000\000\000\000\000\023\252\000\000\000\000\000\000\000\000\000\000\014\024\000\127\000\000%\164\000\000\000\251\016j\000\0002\202\000\136\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000\226\000\000\000\000\001\028\000\000\001>6\012\000\000\000\000\000\000\000\000\000\000\000\0006\2282\202\000\0006\228\000\0006\2286\228\000\000\000\000'\164\000\133\000\000\016j\001B\000\0002\202\002\030\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000;`2\202\000\0002\202\000\000\000\000\002L\000\000\000=5\180\002\2522\202\002\204\000\000\000\0006\012\000=\000\000\000\000\000\000\000\000\000\000<\1526\012<\2366\012<\2526\012=\2426\012\000\0006\012\000\0006\012> 6\012>t6\012?V6\012?\1326\012?\2162\202\002\1426\012\000\0006\012@\1866\012@\2326\012A<\002\172\000\000\002\234\000\000\00052\202\000\000\0005\000\000\000\000\000\132%\"\000\000\000\132\000\000\000\000\002\2382\202\000\000\003$\000\000\016j\003\158\000\000\000\000\004p\000\000\016j\003\182\000\000\000\000\003\204\000\000\000\000\000\003\000\000\004\166\000\000%>A\250\004\156\004\148\000\133\004\020\004\216C\240\000C\000\000\000\000\001\006DH\000\000\000\000\000\000\005\000\005\018\001\"\005(C\240\001\222C\240\000\000\000\000\001 \000\000\000\000\004z\000\000\004\142\005BC\240\004\162\000\000\000\000\001\006\000\000\004\176\005\138\000\000D\158C\168\000\000\000\133\005\154\000\000\014\024\000\133\005\156\000\000\000\000#\214CR\004\224\000\000\005X\000\000\004\234\000\000\000\162%\"\000\000%\"\000\000\004\226\000\000\000\162\000\000\012\246\018\240\005\184C\240\005\n\005\224\000\000%\"\000\158\000\000\005\226\000\000\000\000\000\000\000\000\000\000\000\000\005\2002\202\005\028\017\"\005\2102\202\005$\005\206\001\006\005V\006z\000\0007d7\228\016j\0052\000\000\00587\228\000\000\000\000\000\000\000\000\000\000\000\000\000\0008d2\202\000\0008d\000\0008d8d\000\000\000\000\022B\000\133\000\000\016j\005<\000\0002\202\005@\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000&.2\202\000\0002\202\000\000\005b\000\000\0005\000\000\000\000\000\000\000\000\000\000+@7\228,.7\228,b7\228-P7\228\000\0007\228\000\0007\228-\1327\228.r7\228.\1667\228/\1487\228/\2002\202\005\1567\228\000\0007\2280\1827\2280\2347\2281\216\016j\005x\000\000\000\0002\202\000\000\006P\000\000\001J\006&2\202\005\242\000\000\006.2\202\006\000\000\000\003>\000\000\006z\006z\001J\000\000\001J\000\000\012\246\006z\006z\000\000\000\000\000\000\020\172\000\000\000\000\000\000\000\000\006H2\202\005\154\017\"\017\240\000\133\006l\000\000\006R3\132\006v3\132\006x2\202\005\172\017\"\017\"\000g\0026\000Y\000\000\000\000\000\000\0026\000\000\002j\000g\000\000\000\000\005\178\000\000\000\000\000\000\006\132\000\000\006\136\000\000\000\000\006\188\006p2\202\005\194\006\150\000\000\019\190\006|\016j\005\208\017\"\000\000\000\000\005\254\000\000\0009\000\000\003\226\000\000\001J\000\000\000\000\006H\000\000.(\018\240\006\142C\240\005\234\006\188\000\000\000\133\000\000\000\0272\202(J\000\0008\2282\202\005\254\000\000\016j\006\006\000\000\006\008\000\000\000\000\000\000\000\000\000\000\000\000\000\0009d2\202\000\0009d\000\0009d9d\000\000\000\000Dn\000\133\000\000\016j\006\n\000\0002\202\006\012\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016j\006\0189\228\000\000\000\0002\202\000w2\202\006\016\006D(J(\242'\014\006\1902\202\006\140\000\000\000\000\000\133\006L(J\000\000\006T(J\000\000\000\000\020X9\228\021F9\228\025p9\228!\1889\228\000\0009\228\000\0009\228$~9\228(&9\228E\1529\228E\1749\228E\2489\228F&9\228F\1329\228F\154\000\000\000\000\006,\000\000\006>)\154\000\000*B\006B*B1\252\006D*B\000\000\000\000\000\000\000\000\000\000\006n(J\000\000\000\000\006>\000\000\007\024\000\000\000\133\000\000\000\027\007\028\000\000\000N\006\236\000\133\006T\007\012C\240\006^\000@\000\0002\202\0078\000\000\001\022\001\026\003\178\007\030C\240\006r\007L\000\000\000\0052\202\007N\000\000\007T\000\000\014\024\000\133\002\1722\202\007X\000\000\007`\000\000\011\170\0009\000\000\011\170\000\000\000\000\019\190\002\2442\202\007|\000\000\007\128\000\000\000\000\001\154\007^\000\133\006\196\007zC\240\006\206\000\210\000\0002\202\007\160\000\000\0009\000\000\000\000\007\198\000\000\011\170\000\000\007\130\016j\006\214\007\174\000\000\001\022\000\000\007\148C\240\006\230\007\190\000\000\00302\202\007\194\000\000\007\196\000\000\014\024\000\133\003@2\202\007\200\000\000\007\202\000\000\000\000\000\000\007\198\000\000\000\000\0009\000\000\006z\000\000\001\022\000\000\000\000\001\024\017\240\000\000\001\024\000\000\000\000\007\000\000\000\0005\000\003\017\"\000\000\003\226\0009\003\226\000\000\0009\000\000\006z\000\000\006z\000\000\000\000\000\000\006\250\000\000\000\000\007\006\000\000\001\162\005.\000\013\003\226\000\000\000\000\000\000\003\"\000\000\006z\000\000\001\162\000\000\000\000\001\022\003\214\012\246\000\000\014\242\000\000\t\018\012\246\000\000\000\000\t\018\000\000\000\000\007\008\000\000\000\000\007\014\000\000\001\248\006z\000\000\001\248\000\000\000\000\007|\000\000\0009\000\000\006z\000\000\000\000\000\000\015\1283\226\000\000\007\224\000\000\015\128\007\226\000\000\007\232\000\000.(\000\133\002\028\000\0002\202\007\236\000\000\007\212\007\196\000\133\007*\007\230C\240\007H\002d\000\0002\202\008\"\000\000\001\022\002\176\000\0002\202\008$\000\000\014\024\000\133\002\196\000\0002\202\008&\000\000\002\158\015\128\000\000\019\190\003<\000\0002\202\008,\000\000\000\000\000\000\008\014\007\254\000\133\007f\008\024C\240\007j\004$\000\0002\202\008<\000\000\002.\000\000\008.\016j\007\134\008X\000\000\002\188\000\000\004j\000\0002\202\008`\000\000\014\024\000\133\004\140\000\0002\202\008b\000\000\002\158\000\000\000\000\007\150\000\000\002.\003\174\008\006\000\000\000\000\000\000\008\014\000\000\002\016\002d\000\000\012\246\008^\000\000\000\0002\202\007\204\006z\000\000\007\164\000\000\001\006\000\000\000\000\003h\012\246\000\000\012\246\000\000\007\150\000\000\003h\000\0006\012\003\2046\012\000\0006\012\000\000\007\154\000\000\003\204\000\000\017\"\004\028\017\"\000\000\017\"\000\000\007\160\000\000\004\028\000\0006\012\003\204\007\164\000\000:\220\000\133\004 :\220\000\000:\220\000\000\007\168\000\000\004 \000\0006\012\003\204\007\174\000\000\000\000\021\248\000\000\000\000\000\000\000\000\000\000\025H!x\000\000\006\160\000\000\005\222\000\000\000\000\007\240\000\133\000\000\000\000\000\000\000\164\005\222\000\000\002\238\002\130\002\130\000\000\002\018\002\130\000\000\007\206\000\000\000\000\000\000\000\000\000\000\000\000\008N\000\000\"\160\000\000%\"\005\222\000\000\003^\005\222\000\000\008l\000\000\005\222\008p\000\000\005\234\006\030\008~\000\000\008\130\000\000\0076\007\216\005\222\008\012\005\222\008\134\000\000\008\138\000\000\008\140\000\000%\"\000\000\002\154%\"\000\000\008\020\011\188\000\000\001\002\005\222\000\000\004\166\005\222\000\000\004\208\003\136\000\133\000\000\t\004\000\133\000\000\008\024\000\000\000\000\000\000\000\000\008\150\000\000\006\030\005\222\008\158\000\000\008\164\000\000\005\222\008\166\000\000\005\222\008\178\000\000\008\140\005\222\008\182\000\000\015\180\006\030\005\222\008@\005\222\008\186\000\000\008\188\000\000\000\000\004\168\005\222\000\000\004\220\001\130\001\130\000\000\000\000\000\000\003\158\001\130\000\000\008D\000\000\000\000\000\000\000\000\005\222\000\000\004\200\005\222\000\000\004\234\003\196\000\133\008F\000\000\000\000\000\000\000\000\008\196\000\000\008\198\000\000\005\222\008\204\000\000\007\216\005\222\008\206\000\000\008\208\000\000-\006\008\130\008\174\007j\005\222\008\220\000\000\000\000\008\224\000\000\008\182-\006\005\222\008\228\000\000\005\222\008\230\000\000\008\234\000\000\005\222\008v\005\222\008\246\000\000\008\248\000\000\000\133\008t\000\000\000\000\021\248\000\000\000\000\0028\t\\\000\000\000\000\003^\000\000\000\000\000\0002\202\000\135\t\162\008\204\tL6\012\000\000\003\1926\012\000\000\008\160\000\000\000\000\000\000\000\000\000\000\002\150\000\000\003n\000\000\000\000\000\000\003\226B\242\005lB\242B\242\005l\000\000\000\000\000N\000N\000N\000N\000\000\000\000\000\000\000\000\000\000\000\000(J\008\162\000\000\000\000\000\000;`\000N\014@\0009\000\000\000\000\0009\000\000\007\198\000\000\000\000\000\135\000\000\000\000\008\236\001h\t\\ER\000\000\004nE\186\000\000\000\000\t^\tN\000\133\000\000\000\133\000\000\004n\000\000\004\140ER\000\000\000\000\008\178\t\\\006z\008\176\000\000\001\154\0009\000\000\007\198\000\000\014\196\005,\000\000\000\000\tZ\000\000\000\000\0028\000\000\004\172\000\000\000\000\000\0002\202\000\135\000\000\002\150\000\000\004\230\000\000\000\000\000\000\005.\000\000\n^\001\020\n^\000\000\006z\n^\000\000\001\020\000\000\006z\000\000\006z\000\000\006z\000\000\000\000\000\000\000\000\000\000\000\135\000\000\006z\000\000\001\020\000\000\006z\000\000\017H\000\000\000\000\t\018\008\248\000\133\003\144\t\148\004`\000\000\004`\t\190\000\000\t\192\000\000\t\194\000\000\000\000\001*\004`\012\244\004`\000\000\000\000\000\152\008\214\000\000\t\200\000\000\000\000\t\018\007\184\002\202\t\216\n\248\t\216\000\000\000\000\007\250\000\133\000\000\004\024\t0\000\000\000\000\000\000\004\192\000\000\008\238\000\000\000\000\000\000\007\184\002\202\007\250\004\024\004\192\008\244\000\000\000\133\000\000\t\234\t\234\t4\000\133\t\134\000\000"), (16, "\n\141\n\141\n\141\n\141\n\141\n\141\n\141\n\141\n\141\n\141\n\141\000:\n\141\n\141\n\141\n\141\n\141\n\141\n\141\n\141\n\141\t.\000\210\t.\002\162\n\141\000\023\000\027\003i\005\197\007\230\n\141\0055\n\141\n\141\n\141\n)\000\210\n\141\008\026\000z\000\146\n\141\n\141\000\210\n\141\006*\n)\005=\006.\000\162\004^\007\230\020\150\n\141\0062\000~\n\141\n\141\0066\020\154\008\026\020\"\n\141\n\141\000\162\n\141\000\222\n\141\000\174\0111\003\233\000\162\n\141\nJ\n\141\n\141\n\141\n\141\n\141\000\n\011\158\008\158\n\141\n\141\n\141\n\141\n\141\n\141\008\166\n\141\n\141\n\141\n\141\005\229\005\229\011J\n\141\n\141\005\229\000\014\0111\002\253\003\154\011\130\t:\003%\n\141\n\141\n\141\n\141\n\141\n\141\n\141\000\194\n\141\002U\n\141\tv\n\141\002U\003%\n\141\n\141\005\197\005\214\005\157\t:\n\141\011\210\005=\013J\n\141\0111\0111\n\141\011j\022\154\0111\n\141\n\141\n\141\n\141\004v\n\141\n\141\003\233\011j\005=\n\141\n\141\n\141\005=\n\141\012^\n\141\n\141\006\026\n\141\003\181\n\141\n\141\002\014\011\162\n\141\n\141\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\nq\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\005\205\t.\012\162\005\222\004q\005\205\007\234\007\250\008\n\000\162\007\230\005\205\003%\005\205\005\205\005\205\003%\003%\005\205\008\026\004\005\002f\005\205\004q\022\154\005\205\006*\000\182\003%\006.\004v\013&\005\149\020\150\005\205\0062\000\006\002\178\001\"\0066\020\154\011\178\001.\005\205\005\205\017.\000\210\000\210\005\205\005\205\012b\013\026\003%\005\205\022\162\005\205\005\205\005\205\005\205\005\205\007\217\005m\018\018\005\205\005\205\005\205\005\205\005\205\005\205\000\162\005\205\005\205\005\205\005\205\000\162\000\162\018\218\005\205\005\205\001\"\002\210\008\001\001*\001.\012B\t:\004q\006^\005\205\005\205\005\205\005\205\005\205\005\205\005\018\005\205\015\246\005\205\005U\005\205\013\154\005E\005\205\005\205\004q\005\149\005\189\007\013\005\205\002\222\000\162\007\013\005.\008\001\008\001\005\205\022\170\018\222\008\001\005\205\005\205\005\205\005\205\000\162\005\205\005\205\002\230\022\162\003:\005\205\005\205\005\205\005\237\014\130\005\237\005\205\005\205\005\237\005\205\003\181\005\205\005\205\015V\014\026\005\205\005\205\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\008\014\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005e\005e\014\178\004^\005\237\005\237\019\254\005\237\005\165\n\025\005\237\017\022\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\005\237\000.\005\246\016>\016f\016\142\016\158\016\202\005\237\022\210\005:\005\237\017>\n)\002y\014\202\005\237\005\237\005\237\005\237\005\237\015r\005\237\014\134\005\213\014\230\005\173\005\237\019\254\005\237\005\237\005\237\005\237\005\237\014\250\015\222\017J\005\237\005\237\005\237\005\237\005\237\005\237\nA\005\237\005\237\005\237\005\237\003F\n)\014F\005\237\005\237\005\157\008\162\014J\005\237\001\"\005]\014\182\011\178\001.\005\237\005\237\005\237\005\237\005\237\005\237\017:\005\237\003\146\005\237\t.\005\237\008\014\003\162\005\237\005\237\003\170\n)\008\190\007\230\005\237\004*\003\001\015\n\005\237\n)\000\162\005\237\008\026\015\202\006\021\005\237\005\237\011\242\005\237\014\206\005\237\005\237\003\233\005\213\016\030\005\237\017\250\005\213\005\213\014\234\008\018\005\181\005\237\n!\005\237\011j\005\237\005\237\004N\005\213\005\237\005\237\0002\005\250\000F\000J\006\018\000N\006*\000R\000V\006.\000Z\012&\000^\020v\000b\0062\000f\000j\000n\0066\020~\005\213\015r\018.\004m\006:\006\021\004V\nQ\011j\004\142\000r\016F\000\226\006J\006f\t:\007!\006j\014F\004\001\012\190\000v\004m\014J\007\214\016&\015\014\014N\012\222\004v\007\230\007!\019&\000\238\003\233\004\154\007\230\001\"\011j\008\026\011\178\001.\008.\006r\020\186\008\026\011j\0082\013V\000\162\022\246\016n\001\022\016\170\001\026\003\197\000\134\t6\008:\015\202\015B\017\142\006\134\001\"\008>\006\138\008B\001.\000\162\006\142\006\146\008F\006\150\020\015\020\019\016N\022j\008J\020\023\000\162\007!\020g\020k\005\133\022r\004m\020o\006\154\006\158\008N\008R\006\162\008V\018\238\000\162\015z\008j\004\166\003\161\003!\n9\008v\006\170\004m\005\149\t:\022v\005\245\004\178\004\190\020:\t:\015\150\022z\008\150\016v\n1\016\178\008\154\008\214\003\197\tB\004\202\006\174\008\218\004\222\007!\022\254\006\178\003\197\003\197\003\129\023\002\005}\003\197\008\226\004\238\006\182\007!\005\245\005\245\004\242\015F\001^\005\245\0002\005\250\000F\000J\006\018\000N\006*\000R\000V\006.\000Z\004\250\000^\020v\000b\0062\000f\000j\000n\0066\020~\004\254\003\129\018*\022\130\006:\na\nY\005\141\018\214\005u\000r\015~\000\226\006J\006f\019\"\0055\006j\021\139\0055\005&\000v\ni\0055\007\214\0055\006\005\021\143\015\154\0055\0055\021\030\005\253\000\238\022\138\005M\007\230\021\146\005*\006\013\0052\005V\008.\006r\020\186\008\026\021N\0082\013\158\023\n\002m\005^\001\022\005b\001\026\003\213\000\134\t6\008:\018\030\018\202\005j\006\134\001\"\008>\006\138\008B\001.\005~\006\142\006\146\008F\006\150\005\130\021\171\021\175\019\022\008J\017\014\021\179\006\005\005\154\005\170\002V\017\174\004\217\005\253\006\154\006\158\008N\008R\006\162\008V\006\013\000\162\005\190\008j\005\198\003\161\017\018\005\206\008v\006\170\021\207\021\211\017\018\005\235\006\029\021\215\017\022\017\014\t:\006\002\006\n\008\150\017\022\006\014\006\"\008\154\008\214\006>\tB\006F\006\174\008\218\006N\006V\006Z\006\178\0055\003\213\017\018\006b\006z\019\198\008\226\006\130\006\182\006\218\006\029\006\029\017\022\006\230\001^\006\029\0002\005\250\000F\000J\006\018\000N\006*\000R\000V\006.\000Z\007.\000^\020v\000b\0062\000f\000j\000n\0066\020~\018\166\007\166\007\206\t\197\006:\018b\007\226\007\238\007\246\007\221\000r\007\254\000\226\006J\006f\008\006\000\162\006j\008Z\008b\008r\000v\000\162\008z\007\214\008\130\008\138\t\197\008\146\017\"\007\221\008\206\008\222\000\238\008\230\017\"\007\230\008\242\008\246\008\254\007\221\t\002\008\022\006r\t\014\008\026\t\022\0082\000\162\017\006\t&\tJ\001\022\tZ\001\026\003\241\000\134\0086\008:\tb\tf\017\"\006\134\001\"\008>\006\138\008B\001.\t\142\006\142\006\146\008F\006\150\t\154\t\162\t\246\0119\008J\n\002\n6\nR\t\197\nV\nf\017\198\nn\n~\006\154\006\158\008N\008R\006\162\008V\n\138\000\162\011\014\008j\011\022\003\161\011&\0112\008v\006\170\011N\011^\017\018\011f\008\t\011z\011\134\004a\t:\011\142\007\221\008\150\017\022\011\146\011\154\008\154\008\214\003\241\tB\011\170\006\174\008\218\011\190\007\221\011\198\006\178\003\241\003\241\004a\011\202\011\218\003\241\008\226\011\226\006\182\011\250\008\t\008\t\004a\012\002\001^\008\t\0002\005\250\000F\000J\006\018\000N\006*\000R\000V\006.\000Z\012.\000^\0126\000b\0062\000f\000j\000n\0066\017\014\012F\003!\012N\t\185\006:\012R\004a\012Z\012j\012\142\000r\012\150\000\226\006J\006f\012\154\003!\006j\012\170\012\178\017\018\000v\000\162\012\182\007\214\012\198\012\206\t\185\012\230\012\238\017\022\013>\013\134\000\238\013\146\017\"\007\230\014\006\014\018\0142\014^\014j\008\022\006r\014r\008\026\014\142\0082\004a\005\221\014\150\014\154\001\022\014\162\001\026\017\202\000\134\0086\008:\014\166\019^\004a\006\134\001\"\008>\006\138\008B\001.\014\174\006\142\006\146\008F\006\150\014\190\014\214\014\242\0119\008J\015\022\015&\015*\t\185\t\197\0152\0156\015>\015N\006\154\006\158\008N\008R\006\162\008V\003!\000\162\015^\008j\003!\003!\015f\015j\008v\006\170\000\162\015\134\015\162\015\182\0119\015\198\003!\022j\t:\015\214\015\238\008\150\015\254\017\"\016\n\008\154\008\214\0163\tB\016[\006\174\008\218\016\131\005\221\016\155\006\178\016\191\005\221\005\221\016\215\003!\017\026\008\226\t\197\006\182\017V\0119\0119\017s\022\234\001^\0119\0002\005\250\000F\000J\006\018\000N\006*\000R\000V\006.\000Z\017\155\000^\017\167\000b\0062\000f\000j\000n\0066\017\183\005\221\017\191\017\210\017\219\006:\017\227\017\235\018\006\003\141\018F\000r\018[\000\226\006J\006f\018k\nI\006j\018s\018\127\022^\000v\007)\003\141\007\214\018\139\018\146\018\155\018\174\018\183\018\191\018\250\019.\000\238\019C\019K\007\230\007)\019W\019g\019o\019z\008\022\006r\019~\008\026\019\139\0082\019\151\019\158\019\171\019\183\001\022\019\191\001\026\019\202\000\134\0086\008:\019\211\019\219\019\231\006\134\001\"\008>\006\138\008B\001.\020\002\006\142\006\146\008F\006\150\020&\020*\020.\020F\008J\020\194\021\n\021\018\021.\0212\021^\021b\021j\007)\006\154\006\158\008N\008R\006\162\008V\nI\000\162\021\151\008j\nI\nI\022b\003\141\008v\006\170\022\186\003\141\003\141\022n\022~\022\134\022\142\022\183\t:\022\190\022\214\008\150\022\250\003\141\003\141\008\154\008\214\018:\tB\023\019\006\174\008\218\0237\023F\nI\006\178\023J\023N\023W\007)\nI\000\000\008\226\000\000\006\182\000\000\000\000\003\141\000\000\000\000\001^\007)\0002\005\250\000F\000J\006\018\000N\006*\000R\000V\006.\000Z\000\000\000^\020v\000b\0062\000f\000j\000n\0066\020~\000\000\000\000\000\000\000\000\006:\000\000\000\000\000\000\000\000\000\000\000r\000\000\000\226\006J\006f\000\000\000\000\006j\000\000\000\000\000\000\000v\000\000\000\000\007\214\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008.\006r\000\000\000\000\000\000\0082\021\230\000\000\000\000\000\000\001\022\000\000\001\026\000\000\000\134\t6\008:\000\000\000\000\000\000\006\134\001\"\008>\006\138\008B\001.\000\000\006\142\006\146\008F\006\150\000\000\000\000\000\000\000\000\008J\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\154\006\158\008N\008R\006\162\008V\000\000\000\162\000\000\008j\000\000\003\161\000\000\n\017\008v\006\170\000\000\000\000\000\000\000\000\007\237\000\000\000\000\000\000\000\000\000\000\000\000\008\150\000\000\000\000\000\000\008\154\008\214\000\000\tB\000\000\006\174\008\218\000\000\000\000\000\000\006\178\000\000\000\000\000\000\000\000\000\000\000\000\008\226\000\000\006\182\000\000\007\237\007\237\000\000\000\000\001^\007\237\0002\005\250\000F\000J\006\018\000N\006*\000R\000V\006.\000Z\000\000\000^\000\000\000b\0062\000f\000j\000n\0066\0055\000\000\000\000\000\000\000\000\006:\000\000\000\000\000\000\000\000\000\000\000r\n\017\000\226\006J\006f\n\017\n\017\006j\000\000\000\000\0055\000v\000\000\000\000\007\214\000\000\000\000\n\017\000\000\000\000\0055\000\000\000\000\000\238\000\000\000\000\000\000\000\000\022\218\000\000\000\000\000\000\008.\006r\000\000\000\000\000\000\0082\012\n\000\000\000\000\n\017\001\022\000\000\001\026\0055\000\134\t6\008:\000\000\000\000\002V\006\134\001\"\008>\006\138\008B\001.\000\000\006\142\006\146\008F\006\150\000\000\000\000\000\000\011\021\008J\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\154\006\158\008N\008R\006\162\008V\000\000\000\162\000\000\008j\000\000\000\000\000\000\000\000\008v\006\170\0055\000\000\000\000\000\000\011\021\000\000\000\000\000\000\000\000\000\000\000\000\008\150\000\000\0055\000\000\008\154\008\214\000\000\tB\000\000\006\174\008\218\000\000\000\000\000\000\006\178\000\000\000\000\000\000\000\000\000\000\000\000\008\226\000\000\006\182\000\000\011\021\011\021\000\000\000\000\001^\011\021\0002\005\250\000F\000J\006\018\000N\006*\000R\000V\006.\000Z\000\000\000^\000\000\000b\0062\000f\000j\000n\0066\000\000\000\000\000\000\000\000\000\000\006:\000\000\000\000\003\029\000\000\000\000\000r\000\000\000\226\006J\006f\000\000\000\000\006j\000\000\000\000\000\000\000v\003\029\000\000\007\214\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\000\000\000\003\029\000\000\000\000\000\000\008.\006r\000\000\000\000\000\000\0082\013\210\000\000\000\000\000\000\001\022\000\000\001\026\000\000\000\134\t6\008:\000\000\000\000\000\000\006\134\001\"\008>\006\138\008B\001.\000\000\006\142\006\146\008F\006\150\000\000\000\000\000\000\000\000\008J\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\154\006\158\008N\008R\006\162\008V\000\000\000\162\000\000\008j\000\000\000\000\003\029\000\000\008v\006\170\003\029\003\029\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\150\003\029\000\000\000\000\008\154\008\214\000\000\tB\000\000\006\174\008\218\002\142\000F\000J\006\178\000N\003\029\000R\000V\000\000\000Z\008\226\000^\006\182\000b\003\029\000f\022\162\000n\001^\0002\005\250\000F\000J\006\018\000N\006*\000R\000V\006.\000Z\000r\000^\000\000\000b\0062\000f\000j\000n\0066\000\000\000\000\000v\000\000\000\000\006:\000\000\000\000\000\000\000\000\000\000\000r\000\000\000\226\006J\006f\000\000\000\000\006j\000\000\000\000\000\000\000v\000\000\000\000\007\214\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\134\000\000\000\000\000\000\000\000\000\000\008.\006r\000\000\000\000\000\000\0082\020\218\000\000\000\000\000\000\001\022\000\000\001\026\000\000\000\134\t6\008:\000\000\000\000\000\000\006\134\001\"\008>\006\138\008B\001.\000\000\006\142\006\146\008F\006\150\000\000\000\162\000\000\000\000\008J\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\154\006\158\008N\008R\006\162\008V\012\162\000\162\000\000\008j\000\000\000\000\000\000\000\000\008v\006\170\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007!\000\000\000\000\008\150\000\000\t.\000\000\008\154\008\214\000\000\tB\000\000\006\174\008\218\007\230\007!\000\000\006\178\001\"\000\000\000\000\011\178\001.\008\026\008\226\000\000\006\182\000\000\0002\005\250\000F\000J\001^\000N\006*\000R\000V\006.\000Z\000\000\000^\000\000\000b\0062\000f\000j\000n\0066\000\000\000\162\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000r\000\000\000\226\006\229\006f\007!\018\162\006j\000\000\000\000\000\000\000v\000\000\000\000\014R\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\000\017\018\000\000\000\000\t:\000\000\014b\006r\000\000\006\229\006\229\017\022\000\000\000\000\006\229\000\000\001\022\0055\001\026\000\000\000\134\000\000\000\000\000\000\000\000\007!\006\134\001\"\000\000\006\138\001*\001.\000\000\006\142\006\146\008F\006\150\007!\0055\000\000\000\000\000\000\000:\000\000\000\000\000\000\000\000\000\000\0055\0055\000\000\006\154\006\158\000\000\000\000\006\162\000\000\000\000\000\162\000\000\0002\0006\000F\000J\000\000\000N\006\170\000R\000V\000\000\000Z\000\000\000^\0055\000b\000\000\000f\000j\000n\002V\000\000\000\000\0055\0055\000\162\tB\000\000\006\174\014f\000\000\000\000\000r\006\178\000\226\000\000\000\230\000\000\017\"\000\234\014n\000\000\006\182\000v\000\000\000\000\000\000\000\000\001^\000\000\000\000\000\000\000\000\000\000\0055\000\238\000\000\000\000\000\242\000\000\000\000\000\000\0055\000\000\001\n\001\006\000\000\001\014\000\000\000\000\000\000\000\000\000\000\000\000\001\022\0055\001\026\000\000\000\134\000\000\000\000\000\000\000\000\000\000\001\030\001\"\000\000\001&\001*\001.\001\130\0012\0016\000\000\001:\0055\000\000\000\000\0055\0055\000\000\000\000\0055\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001>\000\000\0055\001B\000\000\000\000\000\162\000\000\006:\000\000\000\000\000\000\000\000\000\000\001J\000\000\000\226\006J\006f\000\000\000\000\006j\000\000\001N\000\000\000\000\000\000\000\000\007\214\000\000\000\000\000\000\000\000\000\000\000\000\001R\000\000\000\238\000\000\000\000\001V\000\000\000\000\003e\000\000\000\000\008f\006r\000\000\001Z\012\162\0082\000\000\000\000\000\000\001^\001\022\000\000\001\026\000\000\000\000\000\000\008:\000\000\000\000\000\000\006\134\001\"\008>\006\138\008B\001.\000\000\006\142\006\146\000\000\006\150\000\000\000\000\000\000\000\000\008J\000\000\000\000\000\000\000\000\001\"\000\000\000\000\011\178\001.\006\154\006\158\008N\008R\006\162\008V\000\000\000\162\000\000\008j\000\000\000\000\000\000\000\000\008v\006\170\000\000\000\000\000\000\000\000\006:\000\000\000\000\000\000\000\000\000\000\000\162\008\150\000\226\006J\006f\008\154\008\214\006j\000\000\000\000\006\174\008\218\000\000\0089\007\214\006\178\000\000\000\000\000\000\000\000\000\000\000\000\008\226\000\238\006\182\000\000\000\000\000\000\000\000\000\000\001^\000\000\006n\006r\000\000\000\000\000\000\0082\000\000\000\000\000\000\000\000\001\022\000\000\001\026\0089\0089\000\000\008:\000\000\0089\000\000\006\134\001\"\008>\006\138\008B\001.\000\000\006\142\006\146\000\000\006\150\000\000\000\000\000\000\000\000\008J\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\154\006\158\008N\008R\006\162\008V\000\000\000\162\000\000\008j\000\000\000\000\000\000\000\000\008v\006\170\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011e\0055\008\150\011e\0055\000\000\008\154\008\214\0055\000\000\0055\006\174\008\218\000\000\0055\0055\006\178\000\000\011e\000\000\000\000\000\000\011e\008\226\000\000\006\182\001v\011e\000\000\000\000\000\000\001^\000\000\011e\000\000\000\000\011e\011e\000\000\011e\011e\000\000\000\000\001~\000\000\011e\002\170\000\000\000\000\011e\000\000\000\000\011e\000\000\011e\011e\000\000\000\000\000\000\0055\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\146\000\000\000\000\000\000\000\000\000\000\011e\000\000\011e\000\000\000\000\001\"\000\000\000\000\001*\001.\000\000\000\000\011e\000\000\000\000\000\000\000\000\002\182\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011e\011e\011e\000\162\011e\011e\002\186\0055\011e\000\000\000\000\000\000\004\001\000\000\000\000\004\001\002\194\000\000\000\000\000\000\011e\000\000\000\000\011e\011e\011e\011e\000\000\000\000\000\000\004\001\011e\011e\011e\004\001\011e\011e\011e\004\001\004\001\000\000\000\000\000\000\000\000\000\000\004\001\000\000\000\000\004\001\004\001\000\000\004\001\004\001\000\000\000\000\004\001\000\000\004\001\004\001\000\000\000\000\004\001\000\000\000\000\004\001\000\000\004\001\004\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\210\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\001\000\000\004\001\n\154\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\001\000\000\000\000\000\000\000\000\004\001\000\000\000\000\000\162\n\162\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\001\004\001\004\001\n\170\004\001\004m\004\001\000\000\004\001\n\234\n\242\000\000\004\005\000\000\000\000\004\005\004\001\000\000\000\000\n\202\004\001\000\000\n\178\004\001\n\194\004\001\000\000\000\000\000\000\000\000\004\005\004\001\004\001\004\001\004\005\004\001\004\001\004\001\004\005\004\005\000\000\000\000\000\000\000\000\n\210\004\005\000\000\000\000\004\005\004\005\000\000\004\005\004\005\000\000\000\000\004\005\000\000\004\005\004\005\000\000\000\000\004\005\000\000\000\000\004\005\000\000\004\005\004\005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\218\000\000\000\000\000\000\000\000\000\000\000\000\n\186\004\005\000\000\004\005\000\181\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\169\004\005\000\000\000\000\000\000\000\000\004\005\000\000\000\000\000\000\n\162\000\000\000\000\000\000\000\000\n\250\n\226\000\000\000\000\000\000\000\000\000\000\004\005\004\005\004\005\n\170\004\005\004q\004\005\000\000\004\005\000\181\000\181\000\000\000\000\000\000\000\000\000\000\004\005\000\000\000\000\n\202\004\005\000\000\n\178\004\005\n\194\004\005\000\000\000\000\000\000\000\000\000\000\004\005\004\005\004\005\000\000\004\005\004\005\004\005\001=\001=\001=\001=\000\000\001=\n\210\001=\001=\000\000\001=\000\000\001=\000\000\001=\000\000\001=\001=\001=\000\000\000\000\000\000\000\000\016\226\000\000\000\000\000\000\000\000\000\000\000\000\001=\001=\001=\000\000\000\000\000\000\000\000\001=\000\000\000\000\n\218\000\000\001=\000\000\000\000\000\000\001=\n\186\000\000\000\000\001=\000\000\000\000\016\230\000\000\000\000\001=\000\000\011\185\000\181\000\000\011\185\000\000\001=\000\000\000\000\000\000\000\000\001=\000\000\000\000\000\000\000\000\000\000\000\181\n\226\011\185\001=\000\000\000\000\011\185\000\000\000\000\000\000\006\202\011\185\000\000\000\000\000\000\000\000\000\000\011\185\000\000\000\000\011\185\011\185\001=\011\185\011\185\001=\000\000\006\210\000\000\011\185\006\222\000\000\000\000\011\185\000\000\000\000\011\185\000\000\011\185\011\185\001=\000\000\001=\000\000\001=\000\000\001=\000\000\000\000\000\000\000\000\001=\000\000\000\000\001=\000\000\000\000\000\000\011\185\000\000\011\185\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001=\011\185\000\000\001=\001=\000\000\006\234\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\234\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\185\011\185\011\185\000\000\011\185\000\000\006\238\000\000\011\185\000\000\000\000\000\000\001\137\000\000\000\000\001\137\006\246\000\000\000\000\000\000\000\000\000\000\000\000\011\185\000\000\011\185\000\000\000\000\000\000\000\000\001\137\011\185\011\185\011\185\001\137\011\185\011\185\011\185\000\000\001\137\000\000\000\000\000\000\000\000\000\000\001\137\000\000\000\000\001\137\001\137\000\000\001\137\001\137\000\000\000\000\000\000\000\000\001\137\000\000\000\000\000\000\001\137\000\000\000\000\001\137\000\000\001\137\001\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\137\000\000\001\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\137\004%\000\000\002v\004%\002z\004%\002~\004%\000\000\004%\000\000\000\000\002\130\004%\004%\000\000\000\000\000\000\000\000\000\000\001\137\001\137\001\146\000\000\001\137\001\137\004%\000\000\001\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\004%\000\000\000\000\001\137\000\000\004%\001\137\001\137\001\137\001\137\000\000\000\000\000\000\000\000\002>\001\137\001\137\000\000\001\137\001\137\001\137\004%\000\000\000\000\004%\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\004%\004%\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\004%\004%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\000\000\004%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004%\000\000\000\000\004%\004%\000\000\000\000\004%\000\000\000\000\000\000\000\000\004%\004%\000\000\000\000\000\000\004%\t\181\t\181\t\181\t\181\000\000\t\181\000\000\t\181\t\181\000\000\t\181\000\000\t\181\000\000\t\181\000\000\t\181\t\181\t\181\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\181\t\181\t\181\001\178\000\000\000\000\002\006\t\181\000\000\000\000\000\000\000\157\t\181\000\000\000\000\000\000\016\250\000\000\000\000\000\000\017\002\001\190\000\000\000\000\000\000\002\001\t\181\000\000\000\000\000\157\002\001\000\000\000\000\t\181\000\000\000\000\001\198\000\000\t\181\002\001\002\001\000\000\002&\002.\n\170\000\000\000\000\t\181\002\001\000\000\000\157\000\157\001\230\000\000\000\000\001\206\000\000\001\222\002\001\000\000\000\157\000\000\000\000\n\178\000\000\n\194\t\181\000\000\000\000\t\181\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\238\000\000\002\001\000\000\000\000\000\000\000\000\t\181\000\157\t\181\000\000\t\181\002\001\t\181\000\000\000\000\000\000\000\000\t\181\000\000\000\000\t\181\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\001\001\246\000\000\t\181\002\001\002\001\017v\t\181\001\214\000\157\000\000\000\000\000}\000\000\000\000\000}\n\186\000\000\000\000\000\000\002\001\000\000\000\000\002\001\002\001\002\001\002\001\000\000\000\157\000\000\001\190\000\000\002\001\002\001\000}\0026\001\254\002\001\000\000\000}\000\000\000\000\000\000\000\157\000\157\001\198\000\000\000\000\000}\000}\000\000\000}\000}\000\000\000\000\000\000\000\000\000}\000\000\000\000\000e\001\230\000\000\000e\001\206\000\000\001\222\000}\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000e\000\000\000\000\000\000\000e\000\000\000\000\000\000\001\238\000e\000}\000\000\000\000\000\000\000\000\001\198\000\000\000\000\000e\000e\000}\000e\000e\000\000\000\000\000\000\000\000\000e\000\000\000\000\000\000\000e\000\000\000\000\001\206\000\000\001\222\000e\000\000\000\000\000\000\000}\001\246\000\000\000\000\000}\000}\000\000\000\000\001\214\000\000\000\000\000\000\000\000\000\000\000\000\000e\000\000\000e\000\000\000\000\000}\000\000\000\000\000}\000}\000}\000}\000e\000\000\000\000\000\000\000\000\000}\000}\000\000\000}\001\254\000}\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000e\000e\000\000\000\000\000e\000e\000\000\000\000\001\214\000\000\000\000\000\000\000]\000\000\000\000\000]\000\000\000\000\000\000\000\000\000e\000\000\000\000\000e\000e\000e\000e\000\000\000\000\000\000\000]\000\000\000e\000e\000]\000e\000e\000e\000\000\000]\000\000\000\000\000\000\000\000\000\000\000]\000\000\000\000\000]\000]\000\000\000]\000]\000\000\000\000\000\000\000\000\000]\000\000\000\000\000a\000]\000\000\000a\001\206\000\000\000]\000]\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000a\000\000\000\000\000\000\000a\000\000\000\000\000\000\000]\000a\000]\000\000\000\000\000\000\000\000\000a\000\000\000\000\000a\000a\000]\000a\000a\000\000\000\000\000\000\000\000\000a\000\000\000\000\000\000\000a\000\000\000\000\001\206\000\000\000a\000a\000\000\000\000\000\000\000]\000]\000\000\000\000\000]\000]\000\000\000\000\001\214\000\000\000\000\000\000\000\000\000\000\000\000\000a\000\000\000a\000\000\000\000\000]\000\000\000\000\000]\000]\000]\000]\000a\000\000\000\000\000\000\000\000\000]\000]\000\000\000]\000]\000]\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000a\000a\000\000\000\000\000a\000a\000\000\000\000\001\214\000\000\000\000\000\000\000q\000\000\000\000\000q\000\000\000\000\000\000\000\000\000a\000\000\000\000\000a\000a\000a\000a\000\000\000\000\000\000\001\190\000\000\000a\000a\000q\000a\000a\000a\000\000\000q\000\000\000\000\000\000\000\000\000\000\001\198\000\000\000\000\000q\000q\000\000\000q\000q\000\000\000\000\000\000\000\000\000q\000\000\000\000\000i\000q\000\000\000i\001\206\000\000\001\222\000q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\190\000\000\000\000\000\000\000i\000\000\000\000\000\000\001\238\000i\000q\000\000\000\000\000\000\000\000\001\198\000\000\000\000\000i\000i\000q\000i\000i\000\000\000\000\000\000\000\000\000i\000\000\000\000\000\000\000i\000\000\000\000\001\206\000\000\001\222\000i\000\000\000\000\000\000\000q\000q\000\000\000\000\000q\000q\000\000\000\000\001\214\000\000\000\000\000\000\000\000\000\000\000\000\000i\000\000\000i\000\000\000\000\000q\000\000\000\000\000q\000q\000q\000q\000i\000\000\000\000\000\000\000\000\000q\000q\000\000\000q\000q\000q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000i\000i\000\000\000\000\000i\000i\000\000\000\000\001\214\000\000\000\000\000\000\000m\000\000\000\000\000m\000\000\000\000\000\000\000\000\000i\000\000\000\000\000i\000i\000i\000i\000\000\000\000\000\000\001\190\000\000\000i\000i\000m\000i\000i\000i\000\000\000m\000\000\000\000\000\000\000\000\000\000\001\198\000\000\000\000\000m\000m\000\000\000m\000m\000\000\000\000\000\000\000\000\000m\000\000\000\000\000u\000m\000\000\000u\001\206\000\000\001\222\000m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\190\000\000\000\000\000\000\000u\000\000\000\000\000\000\001\238\000u\000m\000\000\000\000\000\000\000\000\001\198\000\000\000\000\000u\000u\000m\000u\000u\000\000\000\000\000\000\000\000\000u\000\000\000\000\000\000\001\230\000\000\000\000\001\206\000\000\001\222\000u\000\000\000\000\000\000\000m\000m\000\000\000\000\000m\000m\000\000\000\000\001\214\000\000\000\000\000\000\000\000\000\000\000\000\001\238\000\000\000u\000\000\000\000\000m\000\000\000\000\000m\000m\000m\000m\000u\000\000\000\000\000\000\000\000\000m\000m\000\000\000m\000m\000m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000u\001\246\000\000\000\000\000u\000u\000\000\000\000\001\214\000\000\000\000\000\000\001\178\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000u\000\000\000\000\000u\000u\000u\000u\000\000\000\000\000\000\001\190\000\000\000u\000u\000\133\000u\000u\000u\000\000\000\133\000\000\000\000\000\000\000\000\000\000\001\198\000\000\000\000\000\133\000\133\000\000\000\133\002.\000\000\000\000\000\000\000\000\000\133\000\000\000\000\001\178\001\230\000\000\000y\001\206\000\000\001\222\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\190\000\000\000\000\000\000\000y\000\000\000\000\000\000\001\238\000y\000\133\000\000\000\000\000\000\000\000\001\198\000\000\000\000\000y\000y\000\133\000y\000y\000\000\000\000\000\000\000\000\000y\000\000\000\000\000\000\001\230\000\000\000\000\001\206\000\000\001\222\000y\000\000\000\000\000\000\000\133\001\246\000\000\000\000\000\133\000\133\000\000\000\000\001\214\000\000\000\000\000\000\000\000\000\000\000\000\001\238\000\000\000y\000\000\000\000\000\133\000\000\000\000\000\133\000\133\000\133\000\133\000y\000\000\000\000\000\000\000\000\000\133\000\133\000\000\0026\001\254\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000y\001\246\000\000\000\000\000y\000y\000\000\000\000\001\214\000\000\000\000\000\000\001\178\000\000\000\000\000\129\000\000\000\000\000\000\000\000\000y\000\000\000\000\000y\000y\000y\000y\000\000\000\000\000\000\001\190\000\000\000y\000y\000\129\000y\001\254\000y\000\000\000\129\000\000\000\000\000\000\000\000\000\000\001\198\000\000\000\000\000\129\000\129\000\000\000\129\002.\000\000\000\000\000\000\000\000\000\129\000\000\000\000\000\000\001\230\000\000\000\000\001\206\000\000\001\222\000\129\000\000\000\000\000\000\000\000\000\000\t\165\t\165\t\165\t\165\000\000\t\165\000\000\t\165\t\165\000\000\t\165\000\000\t\165\001\238\t\165\000\129\t\165\t\165\t\165\000\000\000\000\000\000\000\000\000\000\000\000\000\129\000\000\000\000\000\000\000\000\t\165\t\165\t\165\000\000\000\000\000\000\000\000\t\165\000\000\000\000\000\000\000\000\t\165\000\000\000\000\000\000\000\129\001\246\000\000\000\000\000\129\000\129\000\000\000\000\001\214\000\149\t\165\000\000\000\000\000\000\000\000\000\000\000\000\t\165\000\000\000\000\000\129\000\000\t\165\000\129\000\129\000\129\000\129\000\149\000\000\000\000\000\000\t\165\000\129\000\129\000\000\000\129\001\254\000\129\000\000\000\000\000\000\000\000\000\149\000\000\000\000\000\000\000\000\000\000\000\149\000\149\t\165\000\000\000\000\t\165\000\000\000\000\000\000\000\000\000\149\000\000\000\000\n\178\000\000\000\149\000\000\000\000\000\000\000\000\t\165\000\000\t\165\000\000\t\165\000\000\t\165\000\000\000\000\000\000\000\000\t\165\000\000\000\000\t\165\000\149\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\165\000\000\000\000\016\254\t\165\t\169\t\169\t\169\t\169\000\000\t\169\000\000\t\169\t\169\000\000\t\169\000\000\t\169\000\000\t\169\000\149\t\169\t\169\t\169\000\000\000\000\000\000\n\186\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\169\t\169\t\169\000\000\000\149\000\000\000\000\t\169\000\000\000\000\000\000\000\000\t\169\000\000\000\000\000\000\017z\000\000\000\000\000\149\000\149\000\000\000\000\000\000\000\000\000\000\t\169\000\000\000\000\000\000\000\000\000\000\000\000\t\169\000\000\000\000\000\000\000\000\t\169\000\000\000\000\004i\000\000\000\000\004i\000\000\004i\t\169\004i\000\000\004i\000\000\000\000\000\000\004i\004i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\169\004i\000\000\t\169\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004i\004i\000\000\000\000\000\000\000\000\004i\t\169\000\000\t\169\000\000\t\169\000\000\t\169\000\000\000\000\000\000\000\000\t\169\000\000\000\000\t\169\004i\000\000\000\000\004i\000\138\000\000\000\000\000\000\000\000\004i\000\000\000\000\004i\004i\t\169\000\000\000\000\000\000\t\169\000\000\004i\000\000\000\000\004i\004i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004Q\004i\000\000\004Q\000\000\004Q\000\000\004Q\000\000\004Q\000\000\004i\000\000\004Q\004Q\000\000\000\000\000\000\000\000\004i\000\000\000\000\000\000\004i\000\000\000\000\004Q\000\000\000\000\000\000\000\000\000\000\004i\000\000\000\000\000\000\004Q\004Q\000\000\000\000\000\000\000\000\004Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004i\000\000\000\000\004i\004i\000\000\004Q\004i\000\000\004Q\005\182\000\000\004i\004i\000\000\004Q\000\000\004i\004Q\004Q\000\000\000\000\000\000\000\000\000\000\000\000\004Q\000\000\000\000\004Q\004Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\153\000\000\004Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004Q\000\000\000\000\000\000\004Q\000\000\000\000\000\000\000\153\000\000\000\000\000\000\000\000\004Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\153\000\000\000\000\000\000\000\000\000\000\000\153\000\153\000\000\000\000\004Q\000\000\000\000\004Q\004Q\000\000\000\153\004Q\000\000\n\178\000\000\000\153\004Q\004Q\000\000\000\000\000\000\004Q\0002\0006\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\000\000\000^\000\153\000b\000\000\000f\000j\000n\000\000\0055\000\000\000\000\0055\000\000\000\000\000\000\0055\000\000\0055\017\130\000r\017\158\0055\0055\000\000\000\000\017\170\000\000\000\000\000\000\000\000\000v\000\000\000\000\000\000\000\000\000\153\000\000\000\000\000\000\000\000\000\000\000\000\n\186\000\000\017\194\000\000\000\000\000\000\000\000\000\000\0055\000\130\000\000\000\000\000\153\000\000\017\238\000\000\000\000\0055\000\000\000\000\0055\000\000\0055\000\134\0055\000\000\0055\000\153\000\153\000\000\0055\0055\000\000\002V\000\000\000\000\0055\000\000\000\000\000\000\000\000\000\000\018\014\0055\0055\018^\000\000\0055\0055\000\000\000\000\000\000\000\000\0055\0055\000\000\000\000\0055\000\000\0055\018v\000\000\007\213\000\000\018\130\000\000\018\142\000\000\000\000\000\000\000\000\018\158\000\000\000\000\019N\0055\000\000\000\000\0055\0055\000\000\000\000\000\000\000\000\002V\000\000\000\000\0055\0055\019Z\000\000\000\000\000\000\019r\000\000\0055\000\000\000\000\0055\0055\000\000\001\161\000\000\000\000\001\161\000\000\000\000\000\000\0055\000\000\000\000\0055\0055\000\000\000\000\000\000\000\000\000\000\0055\001\161\0055\0055\000\000\001\161\000\000\0055\0055\000\000\001\161\000\000\0055\000\000\000\000\000\000\001\161\000\000\000\000\001\161\001\161\0055\001\161\001\161\000\000\000\000\000\000\000\000\001\161\000\000\000\000\000\000\001\161\000\000\000\000\001\161\000\000\001\161\001\161\000\000\000\000\0055\000\000\000\000\0055\0055\000\000\000\000\0055\000\000\000\000\000\000\000\000\0055\0055\000\000\000\000\001\161\0055\001\161\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\161\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\161\001\161\007\026\000\000\001\161\000\000\000\000\000\000\001\161\000\000\000\000\000\000\nb\000\000\000\000\000\000\000\000\003I\000\000\003I\000\000\000\000\003I\001\161\000\000\001\161\000\000\000\000\000\000\000\000\000\000\007\"\001\161\001\161\000\000\001\161\001\161\001\161\003I\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003I\003I\000\000\000\000\003I\003I\000\000\000\000\000\000\000\000\003I\000\000\003I\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003I\003I\000\000\003I\003I\003I\000\000\003I\003I\000\000\003I\000\000\000\000\011\157\000\000\000\000\011\157\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003I\003I\000\000\000\000\003I\000\000\011\157\003I\000\000\000\000\011\157\000\000\000\000\000\000\003*\003I\000\000\000\000\000\000\000\000\000\000\011\157\000\000\000\000\003I\011\157\003I\011\157\011\157\000\000\000\000\0032\000\000\000\000\003>\000\000\003I\011\157\000\000\000\000\011\157\003I\011\157\000\000\000\000\000\000\000\000\003I\000\000\000\000\003I\000\000\000\000\000\169\000\000\000\000\003I\000\000\000\000\000\000\000\000\000\000\011\157\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\162\000\000\000\000\011\157\000\000\000\000\000\000\000\000\003J\000\000\000\000\000\000\000\226\000\000\t~\n\170\000\000\t\130\000\000\000\000\000\000\000\169\000\169\000\000\000\000\011\157\011\157\000\000\011\157\000\000\003N\000\169\011\157\000\238\n\178\000\000\n\194\000\000\000\000\000\000\003V\000\000\t\134\n.\011\157\000\000\nB\nZ\000\000\011\157\011\157\000\000\001\022\000\000\001\026\011\157\n\210\000\000\000\000\011\157\011\157\011\157\t\166\001\"\000\000\t\170\008B\001.\000\000\t\174\t\178\000\000\t\182\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\154\t\186\000\000\000\169\t\190\000\000\000\000\000\162\000\000\000\226\n\186\t~\000\000\000\000\t\130\t\198\000\000\000\000\000\000\000\000\000\000\000\000\000\169\000\000\n^\000\000\nv\000\000\000\000\000\000\000\238\000\000\000\000\000\000\000\000\000\000\t\202\000\169\000\169\t\134\n.\t\206\000\000\nB\nZ\000\000\000\000\011V\000\000\001\022\t\210\001\026\000\000\000\000\000\000\000\000\001^\000\000\000\000\t\166\001\"\000\000\t\170\008B\001.\000\000\t\174\t\178\000\000\t\182\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\154\t\186\000\000\000\000\t\190\000\000\000\000\000\162\000\000\000\226\000\000\t~\000\000\000\000\t\130\t\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n^\000\000\nv\000\000\000\000\000\000\000\238\000\000\000\000\000\000\000\000\000\000\t\202\000\000\000\000\t\134\n.\t\206\000\000\nB\nZ\000\000\000\000\011\002\000\000\001\022\t\210\001\026\000\000\000\000\000\000\000\000\001^\000\000\000\000\t\166\001\"\000\000\t\170\008B\001.\000\000\t\174\t\178\000\000\t\182\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\154\t\186\000\000\000\000\t\190\000\000\000\000\000\162\000\000\000\226\000\000\t~\000\000\000\000\t\130\t\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n^\000\000\nv\000\000\000\000\000\000\000\238\000\000\000\000\000\000\000\000\000\000\t\202\000\000\000\000\t\134\n.\t\206\000\000\nB\nZ\000\000\000\000\004\201\000\000\001\022\t\210\001\026\000\000\000\000\000\000\000\000\001^\000\000\000\000\t\166\001\"\000\000\t\170\008B\001.\000\000\t\174\t\178\000\000\t\182\000\000\000\000\000\000\000\000\001\137\000\000\000\000\001\137\000\000\000\000\000\000\000\000\000\000\000\000\006\154\t\186\000\000\000\000\t\190\000\000\000\000\000\162\001\137\000\000\000\000\000\000\000\000\000\000\000\000\t\198\000\000\001\137\000\000\000\000\000\000\000\000\000\000\001\137\n^\000\000\nv\000\000\000\000\001\137\001\137\000\000\000\000\000\000\000\000\000\000\t\202\000\000\000\000\001\137\007N\t\206\001\137\007\158\001\137\001\137\000\000\001\189\000\000\000\000\t\210\000\000\000\000\000\000\000\000\000\000\001^\000\000\007V\000\000\000\000\000\000\002\017\000\000\001\137\000\000\001\137\002\017\000\000\000\000\000\000\000\000\000\000\007^\000\000\000\000\002\017\002\017\000\000\007\174\007\182\000\000\000\000\000\000\000\000\002\017\000\000\000\000\000\000\007~\000\000\000\000\007f\000\000\007v\002\017\000\000\001\137\001\137\001\138\000\000\001\137\001\137\000\000\000\000\001\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\134\000\000\002\017\001\137\000\000\000\000\001\137\001\137\000\000\001\137\000\000\000\000\002\017\000\000\002J\001\137\001\137\000\000\001\137\001\137\001\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\017\007\142\000\000\000\000\002\017\000\000\000\000\000\000\007n\000\000\000\000\000\000\001%\000\000\000\000\001%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\017\000\000\002\017\000\000\000\000\000\000\000\000\007V\000\000\002\017\002\017\001%\007\190\007\150\002\017\001\013\001%\000\000\001\013\000\000\000\000\000\000\007^\000\000\000\000\001%\001%\000\000\001%\001%\000\000\000\000\000\000\001\013\001%\000\000\000\000\001\013\007~\000\000\000\000\007f\001\013\007v\001%\000\000\000\000\000\000\007^\000\000\000\000\001\013\001\013\000\000\001\013\001\013\000\000\000\000\000\000\000\000\001\013\000\000\000\000\007\134\001\013\001%\000\000\007f\000\000\007v\001\013\000\000\000\000\000\000\000\000\001%\0002\0006\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\017\014\000^\001\013\000b\001\013\000f\000j\000n\000\000\001%\007\142\000\000\000\000\001%\001\013\000\000\000\000\007n\000\000\000\000\000r\017\018\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\019v\001%\000\000\001%\001\013\001\013\000\000\000\000\001\013\000\000\001%\001%\007n\001%\007\150\001%\001\005\000\000\000\000\001\005\000\000\000\130\000\000\000\000\000\000\000\000\017\238\001\013\000\000\001\013\000\000\000:\000\000\000\000\001\005\000\134\001\013\001\013\001\005\001\013\001\013\001\013\001\t\001\005\000\000\001\t\000\000\000\000\000\000\001\005\000\000\000\000\001\005\001\005\000\000\001\005\001\005\000\000\000\000\000\000\001\t\001\005\000\000\000\000\001\t\001\005\000\000\000\000\007f\001\t\001\005\001\005\000\000\000\162\000\000\001\t\000\000\000\000\001\t\001\t\000\000\001\t\001\t\000\000\000\000\000\000\017\"\001\t\000\000\000\000\001\005\001\t\001\005\000\000\007f\000\000\001\t\001\t\000\000\000\000\000\000\000\000\001\005\0002\tR\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\000\000\000^\001\t\000b\001\t\000f\000j\000n\000\000\001\005\001\005\000\000\000\000\001\005\001\t\000\000\000\000\007n\000\000\000\000\000r\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000v\001\005\000\000\001\005\001\t\001\t\000\000\000\000\001\t\000\000\001\005\001\005\007n\001\005\001\005\001\005\001\025\000\000\000\000\001\025\000\000\000\130\000\000\000\000\000\000\000\000\000\000\001\t\000\000\001\t\000\000\000\000\000\000\000\000\007V\000\134\001\t\001\t\001\025\001\t\001\t\001\t\001\017\001\025\000\000\001\017\000\000\000\000\000\000\007^\000\000\000\000\001\025\001\025\000\000\001\025\001\025\000\000\000\000\000\000\007V\001\025\000\000\000\000\001\017\001\025\000\000\000\000\007f\001\017\007v\001\025\000\000\000\162\000\000\007^\000\000\000\000\001\017\001\017\000\000\001\017\001\017\000\000\000\000\000\000\000\000\001\017\000\000\000\000\007\134\001\017\001\025\000\000\007f\000\000\007v\001\017\000\000\000\000\000\000\000\000\001\025\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\017\000\000\001\017\000\000\000\000\000\000\000\000\001\025\001\025\000\000\000\000\001\025\001\017\000\000\000\000\007n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\025\000\000\001\025\001\017\001\017\000\000\000\000\001\017\000\000\001\025\001\025\007n\001\025\001\025\001\025\001\021\000\000\000\000\001\021\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\017\000\000\001\017\000\000\000\000\000\000\000\000\007V\000\000\001\017\001\017\001\021\001\017\001\017\001\017\001\029\001\021\000\000\001\029\000\000\000\000\000\000\007^\000\000\000\000\001\021\001\021\000\000\001\021\001\021\000\000\000\000\000\000\007V\001\021\000\000\000\000\001\029\001\021\000\000\000\000\007f\001\029\007v\001\021\000\000\000\000\000\000\007^\000\000\000\000\001\029\001\029\000\000\001\029\001\029\000\000\000\000\000\000\000\000\001\029\000\000\000\000\007\134\007~\001\021\000\000\007f\000\000\007v\001\029\000\000\000\000\000\000\000\000\001\021\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\134\000\000\001\029\000\000\000\000\000\000\000\000\001\021\001\021\000\000\000\000\001\021\001\029\000\000\000\000\007n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\021\000\000\001\021\001\029\007\142\000\000\000\000\001\029\000\000\001\021\001\021\007n\001\021\001\021\001\021\007N\000\000\000\000\001-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\029\000\000\001\029\000\000\000\000\000\000\000\000\007V\000\000\001\029\001\029\001-\001\029\001\029\001\029\007N\001-\000\000\001!\000\000\000\000\000\000\007^\000\000\000\000\001-\001-\000\000\001-\007\182\000\000\000\000\000\000\007V\001-\000\000\000\000\001!\007~\000\000\000\000\007f\001!\007v\001-\000\000\000\000\000\000\007^\000\000\000\000\001!\001!\000\000\001!\001!\000\000\000\000\000\000\000\000\001!\000\000\000\000\007\134\007~\001-\000\000\007f\000\000\007v\001!\000\000\000\000\000\000\000\000\001-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\134\000\000\001!\000\000\000\000\000\000\000\000\001-\007\142\000\000\000\000\001-\001!\000\000\000\000\007n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001-\000\000\001-\001!\007\142\000\000\000\000\001!\000\000\001-\001-\007n\007\190\007\150\001-\007N\000\000\000\000\001)\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001!\000\000\001!\000\000\000\000\000\000\000\000\007V\000\000\001!\001!\001)\001!\007\150\001!\000\000\001)\000\000\000\000\000\226\000\000\t~\007^\000\000\t\130\001)\001)\000\000\001)\007\182\000\000\000\000\000\000\000\000\001)\000\000\000\000\000\000\007~\000\000\000\238\007f\000\000\007v\001)\000\000\000\000\000\000\000\000\t\134\n.\000\000\000\000\nB\nZ\000\000\000\000\000\000\000\000\001\022\000\000\001\026\000\000\007\134\000\000\001)\000\000\000\000\000\000\t\166\001\"\000\000\t\170\008B\001.\001)\t\174\t\178\000\000\t\182\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\154\t\186\001)\007\142\t\190\000\000\001)\000\162\000\000\000\000\007n\000\000\000\000\000\000\000\000\t\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001)\nv\001)\000\226\000\000\000\230\000\000\000\000\000\234\001)\001)\t\202\001)\007\150\001)\000\000\t\206\000\000\007\218\000\000\000\000\000\000\001\201\000\000\000\238\t\210\000\000\000\242\000\000\000\000\000\000\001^\000\000\001\002\001\006\000\000\001\014\000\000\tz\000\000\000\000\000\000\000\000\001\022\000\000\001\026\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\030\001\"\000\000\001&\001*\001.\000\000\0012\0016\000\000\001:\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001>\000\000\000\000\001B\000\000\000\000\000\162\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001J\000\000\000\000\000\226\000\000\000\230\000\000\000\000\000\234\001N\007\229\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\229\000\000\000\000\001R\000\000\000\000\000\238\000\000\001V\000\242\000\000\007\229\000\000\007\229\000\000\001\002\001\006\001Z\001\014\000\000\000\000\000\000\000\000\001^\000\000\001\022\000\000\001\026\000\000\000\000\000\000\000\000\000\226\000\000\000\230\001\030\001\"\000\234\001&\001*\001.\000\000\0012\0016\000\000\001:\000\000\014V\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\242\000\000\000\000\000\000\000\000\001>\001\002\001\006\001B\001\014\000\000\000\162\000\000\000\000\000\000\000\000\001\022\000\000\001\026\001J\000\000\000\000\000\000\000\000\000\000\000\000\001\030\001\"\001N\001&\001*\001.\000\000\0012\0016\000\000\001:\000\000\000\000\000\000\001R\000\000\000\000\000\000\000\000\001V\000\000\000\000\000\000\000\000\000\000\000\000\001>\000\000\001Z\001B\000\000\000\000\000\162\000\000\001^\000\000\000\000\000\000\000\000\000\000\001J\000\000\000\000\000\226\000\000\000\230\000\000\000\000\000\234\001N\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001R\000\000\000\000\000\238\000\000\001V\000\242\000\000\000\000\000\000\000\000\000\000\001\002\004\182\001Z\001\014\000\000\000\000\000\000\000\000\001^\000\000\001\022\000\000\001\026\000\000\000\000\000\000\000\000\000\226\000\000\000\230\001\030\001\"\000\234\001&\001*\001.\000\000\0012\0016\000\000\001:\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\242\000\000\000\000\000\000\000\000\001>\001\002\001F\001B\001\014\000\000\000\162\000\000\000\000\000\000\000\000\001\022\000\000\001\026\001J\000\000\000\000\000\000\000\000\000\000\000\000\001\030\001\"\001N\001&\001*\001.\000\000\0012\0016\000\000\001:\000\000\000\000\000\000\001R\000\000\000\000\000\000\000\000\001V\000\000\000\000\000\000\000\000\000\000\000\000\001>\000\000\001Z\001B\000\000\000\000\000\162\000\000\001^\000\000\000\000\000\000\003\158\000\000\001J\000\000\000\000\003A\000\000\003A\000\000\000\000\003A\001N\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001R\000\000\000\000\003A\000\000\001V\003A\000\000\000\000\000\000\000\000\000\000\003A\003A\001Z\003A\000\000\000\000\000\000\000\000\001^\000\000\003A\000\000\003A\000\000\000\226\000\000\000\246\000\000\000\000\000\250\003A\003A\000\000\003A\003A\003A\000\000\003A\003A\000\000\003A\000\000\000\000\000\000\000\000\000\238\000\000\000\000\000\242\000\000\000\000\000\000\000\000\000\000\000\254\001\018\003A\001\014\000\000\003A\000\000\000\000\003A\000\000\001\022\000\000\001\026\000\000\000\000\000\000\003A\000\000\000\000\000\000\002\234\001\"\000\000\002\238\001*\001.\000\000\002\242\002\246\000\000\002\250\000\000\000\000\000\000\000\226\000\000\000\246\003A\000\000\000\250\000\000\000\000\003A\000\000\000\000\000\000\002\254\000\000\000\000\003\002\000\000\003A\000\162\000\000\000\000\000\238\000\000\003A\000\242\000\000\003\n\000\000\000\000\000\000\000\254\004\158\000\000\001\014\000\000\000\000\000\000\000\000\000\000\000\000\001\022\000\000\001\026\000\000\000\226\000\000\000\246\003\014\000\000\000\250\002\234\001\"\003\018\002\238\001*\001.\000\000\002\242\002\246\000\000\002\250\003\022\000\000\000\000\000\000\000\238\000\000\001^\000\242\000\000\000\000\000\000\000\000\000\000\000\254\003\006\002\254\001\014\000\000\003\002\000\000\000\000\000\162\000\000\001\022\000\000\001\026\000\000\000\000\000\000\003\n\000\000\000\000\000\000\002\234\001\"\000\000\002\238\001*\001.\000\000\002\242\002\246\000\000\002\250\000\000\000\000\000\000\000\226\000\000\006f\003\014\000\000\006j\000\000\000\000\003\018\000\000\000\000\000\000\002\254\000\000\000\000\003\002\000\000\003\022\000\162\000\000\000\000\000\238\000\000\001^\000\000\000\000\003\n\000\000\000\000\000\000\006n\007\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\022\000\000\001\026\000\000\000\000\000\000\000\000\003\014\000\000\000\000\006\134\001\"\003\018\006\138\001*\001.\000\000\006\142\006\146\000\000\006\150\003\022\000\000\000\000\000\226\000\000\006f\001^\000\000\006j\000\000\000\000\000\000\000\000\000\000\006\154\006\158\000\000\000\000\006\162\000\000\000\000\000\162\000\000\000\000\000\238\000\000\000\000\000\000\000\000\006\170\000\000\000\000\000\000\006n\006r\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\022\000\000\001\026\000\000\000\000\000\000\000\000\006\174\000\000\000\000\006\134\001\"\006\178\006\138\001*\001.\000\000\006\142\006\146\000\000\006\150\006\182\000\000\000\000\000\226\000\000\006f\001^\000\000\006j\000\000\000\000\000\000\000\000\000\000\006\154\006\158\000\000\000\000\006\162\000\000\000\000\000\162\000\000\000\000\000\238\000\000\000\000\000\000\000\000\006\170\000\000\000\000\000\000\006n\006\166\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\022\000\000\001\026\000\000\000\000\000\000\000\000\006\174\000\000\000\000\006\134\001\"\006\178\006\138\001*\001.\000\000\006\142\006\146\000\000\006\150\006\182\000\000\000\000\000\226\000\000\t~\001^\000\000\t\130\000\000\000\000\000\000\000\000\000\000\006\154\006\158\000\000\000\000\006\162\000\000\000\000\000\162\000\000\000\000\000\238\000\000\000\000\000\000\000\000\006\170\000\000\000\000\000\000\t\134\t\146\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\022\000\000\001\026\000\000\000\000\000\000\000\000\006\174\000\000\000\000\t\166\001\"\006\178\t\170\001*\001.\000\000\t\174\t\178\000\000\t\182\006\182\000\000\000\000\000\226\000\000\t~\001^\000\000\t\130\000\000\000\000\000\000\000\000\000\000\006\154\t\186\000\000\000\000\t\190\000\000\000\000\000\162\000\000\000\000\000\238\000\000\000\000\000\000\000\000\t\198\000\000\000\000\000\000\t\134\t\194\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\022\000\000\001\026\000\000\000\000\000\000\000\000\t\202\000\000\000\000\t\166\001\"\t\206\t\170\001*\001.\000\000\t\174\t\178\000\000\t\182\t\210\000\000\000\000\000\226\000\000\t~\001^\000\000\t\130\000\000\000\000\000\000\000\000\000\000\006\154\t\186\000\000\000\000\t\190\000\000\000\000\000\162\000\000\000\000\000\238\000\000\000\000\000\000\000\000\t\198\000\000\000\000\000\000\t\134\n.\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\022\000\000\001\026\000\000\000\000\000\000\000\000\t\202\000\000\000\000\t\166\001\"\t\206\t\170\001*\001.\000\000\t\174\t\178\000\000\t\182\t\210\000\000\000\000\000\000\000\000\000\000\001^\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\154\t\186\000\000\000\000\t\190\000\000\000\000\000\162\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\198\0002\005\250\000F\000J\006\018\000N\006*\000R\000V\006.\000Z\000\000\000^\000\000\000b\0062\000f\000j\000n\0066\t\202\000\000\000\000\000\000\000\000\t\206\000\000\000\000\000\000\000\000\000\000\000r\000\000\000\000\t\210\000\000\000\000\000\000\000\000\000\000\001^\000\000\000v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\130\000\000\000\000\0002\tR\000F\000J\000\000\000N\006*\000R\000V\006.\000Z\000\134\000^\020v\000b\0062\000f\000j\000n\0066\020~\001\153\000\000\000\000\001\153\000\000\008F\000\000\000\000\000\000\000\000\000r\000\000\000\000\000\000\007Q\000\000\000\000\000\000\001\153\000\000\000\000\000v\001\153\000\000\000\000\000\000\000\000\000\000\000\162\000\000\000\000\000\000\000\000\001\153\000\000\007Q\000\000\001\153\000\000\001\153\001\153\000\000\000\130\000\000\000\000\007Q\007Q\000\000\000\000\001\153\000\000\007Q\001\153\000\000\001\153\tB\000\134\000\000\0055\000\000\000\000\0055\000\000\000\000\000\000\0055\000\000\0055\000\000\000\000\007Q\0055\0055\000\000\001\153\000\000\000:\000\000\000\000\007Q\007Q\000\000\000\000\000\000\000\000\000\000\001\153\007Q\000\000\000\000\007Q\007Q\000\000\000\000\000\162\000\000\000\000\000\000\003\161\000\000\007Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\153\003z\007Q\001\153\000\000\000\000\000\000\001\153\0055\000\000\007Q\000\000\000\000\000\000\000\000\000\000\000\000\000\146\000\000\001\153\007Q\000\000\000\000\007Q\001\153\001\153\000\000\000\000\007Q\000\000\003\130\007Q\007Q\000\000\001\153\001\153\001\153\000\000\000\000\000\000\000\000\007Q\000\000\007Q\000\000\000\000\007Q\007Q\003\210\000\000\007Q\004\"\000\000\000\000\000\000\007Q\007Q\000\000\000\000\007Q\007Q\000\000\000\000\0055\000\000\000\000\003\218\000\000\000\000\000\000\002\t\000\000\007Q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\226\000\000\000\000\000\000\002\t\000\000\0042\004:\000\000\000\237\000\000\007Q\000\237\000\000\007Q\007Q\004\002\000\213\000\000\003\234\000\213\003\250\000\000\007Q\007Q\000\000\000\000\003\218\007Q\000\000\000\000\000\237\000\000\000\000\000\000\000\213\000\000\000\000\000\000\000\213\000\000\004\n\003\226\000\000\000\000\000\000\000\237\000\000\000\237\000\237\003\226\000\000\000\000\002\t\000\213\000\000\000\213\000\213\004\002\000\000\000\000\003\234\000\000\003\250\000\000\000\000\000\213\000\000\000\000\003\234\000\000\003\250\000\000\000\000\000\000\004\018\000\000\000\000\002\t\000\000\000\000\000\000\003\242\004\n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\213\000\000\000\000\002\t\000\237\000\000\000\000\000\000\002\t\002\t\000\000\000\000\000\213\000\000\000\000\000\000\000\000\000\000\004B\004\026\002\t\000\000\000\000\000\000\000\000\000\000\004\018\000\000\000\000\000\237\000\000\000\000\000\000\003\242\000\213\000\000\000\000\000\213\000\000\000\000\000\000\003\242\000\000\000\000\000\000\000\237\000\000\000\000\000\000\000\205\000\237\000\237\000\205\000\213\000\000\000\000\000\000\000\000\000\213\000\213\000\237\004\026\000\237\000\000\000\000\000\000\000\000\000\205\000\213\000\213\000\213\000\205\000\209\000\000\000\000\000\209\000\000\000\000\000\000\000\000\000\000\000\000\000\205\000\000\000\000\000\000\000\205\000\000\000\205\000\205\000\209\000\000\000\000\000\000\000\209\000\000\000\000\000\000\000\205\000\000\000\000\003\234\000\000\000\205\000\000\000\209\000\000\000\000\000\000\000\209\000\000\000\209\000\209\000\000\000\225\000\000\000\000\000\225\000\000\000\000\000\000\000\209\000\000\000\205\003\234\000\000\000\209\000\000\000\000\000\000\000\000\000\000\003\218\000\000\000\000\000\205\000\225\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\209\003\226\000\000\000\000\000\000\000\225\000\000\000\225\000\225\000\000\000\000\000\205\000\209\000\000\000\205\000\000\000\000\000\225\003\242\000\000\003\234\000\000\003\250\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\205\000\000\000\000\000\000\000\209\000\205\000\205\000\209\000\000\000\000\000\000\003\242\004\n\000\000\000\000\000\205\000\205\000\205\000\000\000\000\000\000\000\000\000\000\000\209\000\225\000\000\000\000\000\000\000\209\000\209\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\209\000\209\000\209\000\000\000\000\000\000\000\000\000\000\000\225\000\000\000\000\000\225\000\000\000\217\000\000\003\242\000\217\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\225\000\000\000\000\000\000\003\218\000\225\000\225\000\000\000\217\000\221\000\000\000\000\000\221\000\000\000\000\000\225\000\225\000\225\000\000\003\226\000\000\000\000\000\000\000\217\000\000\000\217\000\217\003\218\000\000\000\000\000\000\000\221\000\000\000\000\000\000\000\217\000\000\000\000\003\234\000\000\003\250\000\000\003\226\000\000\000\000\000\000\000\221\000\000\000\221\000\221\000\000\000\229\000\000\000\000\000\229\000\000\000\000\000\000\000\221\000\000\000\217\003\234\000\000\003\250\000\000\000\000\000\000\000\000\000\000\003\218\000\000\000\000\000\217\000\229\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\n\003\226\000\000\000\000\000\000\000\229\000\000\000\229\000\229\000\000\000\000\000\217\000\221\000\000\000\217\000\000\000\000\004\002\003\242\000\000\003\234\000\000\003\250\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\217\000\000\000\000\000\000\000\221\000\217\000\217\000\221\000\000\000\000\000\000\003\242\004\n\000\000\000\000\000\217\000\217\000\217\000\000\000\000\000\000\000\000\000\000\000\221\000\229\000\000\000\000\000\000\000\221\000\221\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\221\000\221\000\221\000\000\000\000\000\000\000\000\000\000\004\018\000\000\000\000\000\229\000\000\003\210\000\000\003\242\000\245\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\229\000\000\000\000\000\000\003\218\000\229\000\229\000\000\000\245\003\210\000\000\000\000\000\233\000\000\000\000\000\229\000\229\000\229\000\000\003\226\000\000\000\000\000\000\000\245\000\000\000\245\004:\003\218\000\000\000\000\000\000\000\233\000\000\000\000\000\000\004\002\000\000\000\000\003\234\000\000\003\250\000\000\003\226\000\000\000\000\000\000\000\233\000\000\000\233\000\233\000\000\003\210\000\000\000\000\000\241\000\000\000\000\000\000\004\002\000\000\004\n\003\234\000\000\003\250\000\000\000\000\000\000\000\000\000\000\003\218\000\000\000\000\000\245\000\241\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\n\003\226\000\000\000\000\000\000\000\241\000\000\000\241\004:\000\000\000\000\004\018\000\233\000\000\000\245\000\000\000\000\004\002\003\242\000\000\003\234\000\000\003\250\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\245\000\000\000\000\000\000\004\018\000\245\000\245\000\233\000\000\000\000\000\000\003\242\004\n\000\000\000\000\004B\004\026\000\245\003\153\000\000\000\000\003\153\000\000\000\233\000\241\003\153\000\000\003\153\000\233\000\233\000\000\003\153\003\153\000\000\000\000\000\000\000\000\000\000\000\233\004\026\000\233\000\000\000\000\000\000\000\000\000\000\004\018\000\000\000\000\000\241\000\000\000\000\000\000\003\242\000\000\000\000\000\000\000\000\000\000\000\000\002-\000\000\000\000\000\000\000\000\000\241\000\000\000\000\000\000\000\000\000\241\000\241\000\000\000\000\000\000\000\000\003\153\000\000\000\000\000\000\000\241\004\026\000\241\000\000\000\000\000\000\000\000\000\000\002-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002-\000\000\000\000\002-\002-\000\000\000\000\000\000\000\000\003Q\003Q\003Q\003Q\002-\003Q\000\000\003Q\003Q\000\000\003Q\000\000\003Q\000\000\003Q\000\000\003Q\003Q\003Q\000\000\000\000\000\000\002-\000\000\000\000\000\000\003\153\000\000\000\170\000\000\000\000\003Q\020z\000F\000J\002-\000N\006*\000R\000V\006.\000Z\003Q\000^\020v\000b\0062\000f\000\000\000n\0066\020~\000\000\000\000\000\000\002-\000\000\000\000\002-\002-\000\000\000\000\000r\003Q\000\000\000\000\000\000\002-\002-\003Q\000\000\000\000\002-\000v\000\000\000\000\000\000\003Q\000\000\0002\000\142\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\000\000\000^\000\000\000b\000\000\000f\000j\000n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\134\000\000\000r\000\000\000\000\000\000\000\000\003Q\000\000\000\000\000\000\000\000\000\000\000v\0002\000\142\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\000\000\000^\000\000\000b\000\000\000f\000j\000n\000\000\000\130\000\000\000\000\000\000\000\000\000\000\000\158\000\000\003\161\000\000\000\000\000r\000\000\003Q\000\134\000\000\0002\005\002\000F\000J\000\000\000N\000v\000R\000V\000\000\000Z\000\000\000^\000\000\000b\000\000\000f\000j\000n\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\130\000\000\000\000\000\000\000r\000\000\000\158\000\000\000\000\000\162\000\000\000\000\000\000\000\000\000\134\000v\000\000\0002\005\002\000F\000J\000\000\000N\000\000\000R\000V\000\166\000Z\000\000\000^\000\000\000b\000\000\000f\000j\000n\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000r\n\249\000\134\000\000\000\162\000\000\005\006\005\n\000\000\011\129\000\000\000v\0002\000\142\000F\000J\000\000\000N\000\000\000R\000V\000\166\000Z\000\000\000^\000\000\000b\011\129\000f\000j\000n\000\000\000\130\000\000\000\000\t\230\000\000\000\000\000\000\000\000\000\000\000\000\011\129\000r\002)\000\000\000\134\000\000\011\129\011\129\005\006\005\n\t\238\000\000\000v\t\250\000\000\005\014\011\129\000\000\000\000\011\129\000\000\011\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\130\000\000\000\000\000\000\000\000\000\000\000\158\000\000\011\129\000\000\000\000\000\000\000\000\000\000\000\134\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\006\005\022\0002\005\002\000F\000J\000\000\000N\000\000\000R\000V\000\000\000Z\000\000\000^\000\000\000b\011\129\000f\000j\000n\000\000\n\n\000\000\011\129\000\000\000\000\000\162\000\000\000\000\000\000\000\000\n\018\000r\000\000\000\000\011\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000v\000\000\000\000\000\000\000\000\000\000\000\000\011\129\011\129\000\000\0002\005\002\000F\000J\000\161\000N\000\000\000R\000V\000\000\000Z\000\130\000^\002!\000b\000\165\000f\000j\000n\000\000\000\000\000\000\n\162\000\000\000\000\000\134\000\000\000\000\000\000\021\022\005\n\000r\000\000\n\162\000\000\000\000\000\000\n\170\000\000\000\000\000\000\000\000\000v\000\161\000\161\000\000\000\000\000\000\n\170\000\000\000\000\000\000\000\173\000\161\000\165\000\165\n\178\000\000\n\194\000\000\000\000\000\000\000\000\000\130\000\165\000\000\000\000\n\178\000\000\n\194\n\162\000\000\000\000\000\000\000\000\n\154\000\000\000\134\000\161\000\000\021\026\021\022\005\n\000\000\000\000\n\170\000\000\000\000\000\000\n\210\000\000\000\173\000\173\n\162\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\202\000\000\000\000\n\178\000\000\n\194\000\000\n\170\000\000\000\000\000\000\000\161\000\000\000\189\n\242\000\000\000\000\000\000\n\186\000\000\000\000\n\154\000\165\n\202\000\000\n\210\n\178\000\000\n\194\n\186\000\161\021\"\n\154\000\000\000\000\000\000\000\000\000\000\000\000\n\162\000\000\000\165\000\000\000\000\000\000\000\161\000\161\000\000\n\210\000\000\n\162\000\000\000\000\000\000\n\170\000\000\000\165\000\165\000\000\n\218\000\177\000\177\000\000\000\000\000\000\n\170\n\186\000\000\000\000\000\000\n\202\000\185\n\242\n\178\000\000\n\194\000\000\000\000\000\173\000\000\000\000\n\202\n\218\000\000\n\178\000\000\n\194\000\000\000\000\n\186\000\000\000\000\000\000\000\173\000\173\n\210\000\000\000\000\000\000\000\000\000\000\000\189\000\000\000\000\000\000\000\000\n\210\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\250\n\226\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\218\000\000\000\000\000\000\000\000\000\000\000\000\n\186\000\000\000\000\000\000\n\218\000\000\000\000\000\000\000\000\000\000\000\000\n\186\000\177\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\185\000\000\000\000\000\000\000\177\n\226\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\185\n\226"))
   
   let lhs =
-    (16, "\000\012\000\011\000\n\000\t\000\008\000\007\000\006\000\005\000\004\000\003\000\002\000\001\000\000\001\005\001\005\001\005\001\004\001\004\001\004\001\004\001\003\001\003\001\003\001\003\001\003\001\003\001\003\001\003\001\003\001\003\001\003\001\003\001\003\001\003\001\002\001\002\001\002\001\002\001\002\001\002\001\002\001\002\001\002\001\002\001\002\001\002\001\002\001\002\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\000\255\000\255\000\255\000\255\000\254\000\253\000\253\000\253\000\252\000\252\000\252\000\251\000\251\000\251\000\250\000\250\000\250\000\249\000\248\000\247\000\246\000\246\000\245\000\245\000\244\000\244\000\243\000\243\000\242\000\242\000\241\000\240\000\240\000\239\000\239\000\238\000\238\000\238\000\237\000\237\000\236\000\235\000\234\000\233\000\232\000\231\000\230\000\229\000\228\000\227\000\226\000\225\000\224\000\224\000\223\000\223\000\222\000\222\000\221\000\221\000\220\000\220\000\220\000\219\000\219\000\219\000\219\000\219\000\218\000\218\000\217\000\216\000\216\000\216\000\216\000\215\000\215\000\214\000\213\000\212\000\212\000\212\000\211\000\211\000\211\000\210\000\210\000\210\000\210\000\209\000\209\000\209\000\209\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\208\000\207\000\206\000\206\000\205\000\205\000\205\000\204\000\204\000\203\000\203\000\203\000\202\000\202\000\201\000\200\000\199\000\199\000\198\000\198\000\197\000\197\000\196\000\196\000\195\000\195\000\194\000\193\000\192\000\192\000\191\000\191\000\190\000\189\000\189\000\189\000\189\000\188\000\187\000\186\000\186\000\185\000\184\000\184\000\183\000\183\000\183\000\183\000\183\000\182\000\182\000\182\000\182\000\181\000\181\000\181\000\181\000\180\000\180\000\180\000\180\000\179\000\178\000\178\000\177\000\177\000\177\000\176\000\175\000\175\000\175\000\175\000\174\000\173\000\173\000\173\000\173\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\172\000\171\000\171\000\170\000\170\000\169\000\169\000\168\000\168\000\167\000\167\000\167\000\167\000\166\000\166\000\166\000\165\000\165\000\165\000\165\000\165\000\165\000\165\000\164\000\163\000\163\000\163\000\162\000\161\000\161\000\160\000\160\000\159\000\159\000\158\000\158\000\157\000\157\000\156\000\156\000\155\000\155\000\155\000\155\000\155\000\155\000\155\000\154\000\153\000\152\000\152\000\151\000\151\000\150\000\150\000\149\000\149\000\148\000\148\000\147\000\147\000\146\000\146\000\145\000\145\000\144\000\144\000\143\000\143\000\142\000\142\000\141\000\141\000\140\000\140\000\139\000\139\000\138\000\138\000\137\000\137\000\136\000\136\000\135\000\135\000\134\000\134\000\133\000\133\000\132\000\132\000\131\000\131\000\130\000\130\000\129\000\129\000\128\000\128\000\127\000\127\000~\000~\000}\000}\000|\000|\000{\000{\000z\000z\000y\000y\000x\000w\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000v\000u\000t\000s\000r\000q\000p\000o\000n\000m\000l\000l\000l\000k\000k\000k\000j\000j\000j\000j\000i\000h\000g\000f\000e\000d\000c\000c\000c\000b\000b\000b\000a\000a\000`\000`\000`\000_\000_\000^\000]\000]\000]\000\\\000[\000[\000Z\000Z\000Y\000Y\000X\000X\000W\000W\000V\000V\000U\000U\000T\000T\000T\000T\000T\000T\000T\000T\000T\000T\000T\000T\000T\000T\000T\000T\000T\000T\000T\000S\000S\000R\000R\000Q\000Q\000P\000P\000O\000O\000O\000O\000O\000N\000N\000M\000M\000M\000M\000L\000K\000J\000J\000J\000I\000I\000I\000H\000H\000H\000H\000H\000H\000G\000G\000G\000G\000G\000F\000F\000F\000F\000F\000F\000F\000E\000E\000E\000E\000E\000E\000E\000D\000D\000D\000D\000D\000D\000D\000C\000C\000C\000C\000C\000C\000C\000B\000B\000B\000B\000B\000B\000B\000B\000B\000B\000B\000B\000B\000A\000A\000A\000A\000A\000A\000A\000A\000A\000A\000A\000A\000A\000@\000@\000@\000@\000@\000@\000@\000@\000@\000@\000@\000@\000@\000?\000?\000?\000?\000?\000?\000?\000?\000?\000?\000?\000?\000?\000>\000>\000>\000>\000>\000=\000<\000<\000<\000<\000<\000;\000:\0009\0008\0007\0006\0006\0006\0006\0006\0006\0006\0005\0005\0005\0004\0003\0003\0002\0002\0001\0001\0000\0000\000/\000/\000.\000.\000-\000-\000,\000,\000+\000+\000*\000*\000)\000)\000(\000(\000'\000'\000&\000&\000%\000%\000%\000%\000%\000%\000%\000%\000%\000%\000%\000%\000%\000%\000%\000%\000%\000$\000$\000$\000#\000#\000#\000#\000\"\000\"\000\"\000\"\000\"\000!\000 \000 \000 \000\031\000\031\000\030\000\029\000\028\000\028\000\028\000\028\000\027\000\027\000\027\000\026\000\026\000\025\000\025\000\025\000\024\000\024\000\024\000\023\000\023\000\023\000\022\000\022\000\021\000\021\000\021\000\021\000\021\000\021\000\021\000\020\000\020\000\020\000\020\000\020\000\020\000\020\000\019\000\019\000\019\000\019\000\019\000\019\000\019\000\018\000\018\000\018\000\018\000\018\000\018\000\018\000\017\000\017\000\017\000\017\000\017\000\016\000\016\000\015\000\014\000\013\000\013\000\013\000\013\000\013")
+    (16, "\000\012\000\011\000\n\000\t\000\008\000\007\000\006\000\005\000\004\000\003\000\002\000\001\000\000\001\003\001\003\001\003\001\002\001\002\001\002\001\002\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\001\000\000\255\000\255\000\255\000\255\000\255\000\255\000\255\000\255\000\255\000\255\000\255\000\255\000\255\000\255\000\254\000\254\000\254\000\254\000\254\000\254\000\254\000\254\000\254\000\254\000\254\000\254\000\254\000\254\000\253\000\253\000\253\000\253\000\252\000\251\000\251\000\251\000\250\000\250\000\250\000\249\000\249\000\249\000\248\000\248\000\248\000\247\000\246\000\245\000\244\000\244\000\243\000\243\000\242\000\242\000\241\000\241\000\240\000\240\000\239\000\238\000\238\000\237\000\237\000\236\000\236\000\236\000\235\000\235\000\234\000\233\000\232\000\231\000\230\000\229\000\228\000\227\000\226\000\225\000\224\000\223\000\222\000\222\000\221\000\221\000\220\000\220\000\219\000\219\000\218\000\218\000\218\000\217\000\217\000\217\000\217\000\217\000\216\000\216\000\215\000\214\000\214\000\214\000\214\000\213\000\213\000\212\000\211\000\210\000\210\000\210\000\209\000\209\000\209\000\208\000\208\000\208\000\208\000\207\000\207\000\207\000\207\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\206\000\205\000\204\000\204\000\203\000\203\000\203\000\202\000\202\000\201\000\201\000\201\000\200\000\200\000\199\000\198\000\197\000\197\000\196\000\196\000\195\000\195\000\194\000\194\000\193\000\193\000\192\000\191\000\190\000\190\000\189\000\189\000\188\000\187\000\187\000\187\000\187\000\186\000\185\000\184\000\184\000\183\000\182\000\182\000\181\000\181\000\181\000\181\000\181\000\180\000\180\000\180\000\180\000\179\000\179\000\179\000\179\000\178\000\178\000\178\000\178\000\177\000\176\000\176\000\175\000\175\000\175\000\174\000\173\000\173\000\173\000\173\000\172\000\171\000\171\000\171\000\171\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\170\000\169\000\169\000\168\000\168\000\167\000\167\000\166\000\166\000\165\000\165\000\165\000\165\000\164\000\164\000\164\000\163\000\163\000\163\000\163\000\163\000\163\000\163\000\162\000\161\000\161\000\161\000\160\000\159\000\159\000\158\000\158\000\157\000\157\000\156\000\156\000\155\000\155\000\154\000\154\000\153\000\153\000\153\000\153\000\153\000\153\000\153\000\152\000\151\000\150\000\150\000\149\000\149\000\148\000\148\000\147\000\147\000\146\000\146\000\145\000\145\000\144\000\144\000\143\000\143\000\142\000\142\000\141\000\141\000\140\000\140\000\139\000\139\000\138\000\138\000\137\000\137\000\136\000\136\000\135\000\135\000\134\000\134\000\133\000\133\000\132\000\132\000\131\000\131\000\130\000\130\000\129\000\129\000\128\000\128\000\127\000\127\000~\000~\000}\000}\000|\000|\000{\000{\000z\000z\000y\000y\000x\000x\000w\000w\000v\000u\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000t\000s\000r\000q\000p\000o\000n\000m\000l\000k\000j\000j\000j\000i\000i\000i\000h\000h\000h\000h\000g\000f\000e\000d\000c\000b\000a\000a\000a\000`\000`\000`\000_\000_\000^\000^\000^\000]\000]\000\\\000[\000[\000[\000Z\000Y\000Y\000X\000X\000W\000W\000V\000V\000U\000U\000T\000T\000S\000S\000R\000R\000R\000R\000R\000R\000R\000R\000R\000R\000R\000R\000R\000R\000R\000R\000R\000R\000R\000Q\000Q\000P\000P\000O\000O\000N\000N\000N\000N\000N\000M\000M\000L\000L\000L\000L\000K\000J\000I\000I\000I\000H\000H\000H\000G\000G\000G\000G\000G\000G\000F\000F\000F\000F\000F\000E\000E\000E\000E\000E\000E\000E\000D\000D\000D\000D\000D\000D\000D\000C\000C\000C\000C\000C\000C\000C\000B\000B\000B\000B\000B\000B\000B\000A\000A\000A\000A\000A\000A\000A\000A\000A\000A\000A\000A\000A\000@\000@\000@\000@\000@\000@\000@\000@\000@\000@\000@\000@\000@\000?\000?\000?\000?\000?\000?\000?\000?\000?\000?\000?\000?\000?\000>\000>\000>\000>\000>\000>\000>\000>\000>\000>\000>\000>\000>\000=\000=\000=\000=\000=\000<\000;\000;\000;\000;\000;\000:\0009\0008\0007\0006\0005\0005\0005\0005\0005\0005\0005\0004\0004\0004\0003\0002\0002\0001\0001\0000\0000\000/\000/\000.\000.\000-\000-\000,\000,\000+\000+\000*\000*\000)\000)\000(\000(\000'\000'\000&\000&\000%\000%\000$\000$\000$\000$\000$\000$\000$\000$\000$\000$\000$\000$\000$\000$\000$\000$\000$\000#\000#\000#\000\"\000\"\000\"\000\"\000!\000!\000!\000!\000!\000 \000\031\000\031\000\031\000\030\000\030\000\029\000\028\000\027\000\027\000\027\000\027\000\026\000\026\000\026\000\025\000\025\000\024\000\024\000\024\000\023\000\023\000\023\000\022\000\022\000\022\000\021\000\021\000\020\000\020\000\020\000\020\000\020\000\020\000\020\000\019\000\019\000\019\000\019\000\019\000\019\000\019\000\018\000\018\000\018\000\018\000\018\000\018\000\018\000\017\000\017\000\017\000\017\000\017\000\017\000\017\000\016\000\016\000\016\000\016\000\016\000\015\000\015\000\014\000\013\000\013\000\013\000\013\000\013")
   
   let goto =
-    ((16, "\000\209\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\249\000\000\001/\008\000\000\000\000g\000a\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\188\000\000\002J\000g\000a\000\000\000\000\000\000\000\000\000\000\000\000\001t\000$\006B\000\000\000\000\000\000\t\216\000\000\000\017\000\000\000\000\001\027\002\208\000\000\000\000\000\029\000\000\000\184\000\0001\020\004p\018\252$`\000\188\000\000\000\012\000\000\000\150\t\212\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003`\018\252\000\000\000\000\017t\000\000\019n\000\000\0210\000\000\000\000\000\000\000\000\000\202\000\000\031\238\000\000\000\000\020\222\000\000\027\232\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018$\000\000\000\000\022\232\000\0006v\000\0007\008\000\0007>\000\0007V\000\0007|\000\0007\158\000\0007\252\000\0008\026\000\000)\178\000\000)\180\000\000\000\000\000\000\000\000\000\0008\030\000\00088\000\0008\\\000\000$\228\000\000\000\0005\176\000\000\000I\000a\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\184\000\194\000\000\001\162\000\000\000\000$v\000\0001f\000\000\000\000\000\000\0010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000k2\008\000\000\001N\000\000\000\000%8\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003,%8\000\000\004\172\000\000\n\196\021\178\000\000\000\000\000\000\001\152\000\000 |\000\000\000\0002 \000\000\000\000\000\000\001\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000%R\000\000\000\130\000\000\000\000\000\0005\208\000\00060\000\000\000\000\000\000\000\000\000;\000\000\000\0002\136\000\000\000\000\000\000\nx\0018\000\000\000\000\000\000\000\000\000\000\000\000\000&\000\000\012\018\000\000\",\000\000%.\000\000'r\000\000*\000\000\000,v\000\0003,\000\0003\174\000\0007\234\000\000+^\000\000\0166\000\0007\250\000\0008\n\000\0008~\000\000\000\000\000\000\000\000\000\000\000K\t*\000\000\003\028\000\000\000\000\000\000\014\244\000\000\000\000\000\000\013\138\000\000\000\000%\232\000\000\000\000\000\000\000\000\000\000\000\000\000\191\000\000\000\000\000\000\001\206\000\000\000\000\000\000\001\014\000\000\000\000\005|\000g\000\000\000\000\000\240\002\206\000\000\000\000\000\000\000\000\000\000\002\238\000\000\005\226\000\000\001\134\000\000\000\000\003\136\000\000\000\000\000\000\000\000\000\000\000\000\007\238\000\000\000\000\000\000\002\238\000\000\000\000\000\000\000\000\019\184(H\000\000\001F\000\000\000\000\004\192\004\136\000\000\000\000\000\000\000\000\012t\000\000\000\000\000\000\000\000\000\000\000\000\001\007\012\138\000\000\014\240\000\000\000\000\000\000\000\169\000\000\012\152\000g\000\000\023\190\000\000\000\000\000\000\017x\001\214\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\158\000\000&\220\000\0002\182\000\000\000\000\000\194\000\000\006\246\000\000\006\028\018\234&\170\000\000\000\000\000\000\018\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\nR&\170\000\000\023\180\000\000%\000*\160\000\000\000\000\000\000\003\242\000\000!\020\000\000\000\0003\030\000\000\000\000\000\000\005<\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0006J\000\0006N\000\000\000\000\000\000\003f\000\000\000\000\000\000\000\000\000\000\000\000\012\030\000\000\020\024\000\000 \128\000\000!\206\000\000$4\000\000'\194\000\0008L\000\0008\138\000\0008\204\000\0008\240\000\000+\180\000\000\002\220\000\0009\000\000\0009\020\000\0009>\000\000'H\000\000\000\000\000\0003@\000\000\000\000\000\000\003\216\000\0003`\000\000\000\000\000\0003\222\000\000\000\000\000\031\000\000\023p\000x\003\254\000\000\004\248\000\000\013\026\001\192\007\194\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0004>\000\000'\148% \005\186\000\000\000\000\000\000+\252\000\000,\028\000\000,>\000\000(\004(n\000w\002,\006*\000\000\000\000\000\000\003$\000\000\000\000\002(\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0004\\\000\000\000\000\000\000\000\000\000\000!\240\000\000)\000\000\000\000\000\000\000\000\000\000\000\000\000\013\220\000\000\005r\000\000\000\000\000\000\000\000\004N\001l\000\000\029\188\000\000\000\000\000\000\007d\000\000\000\000\030j\007\140\000\000\002& ~\000\000\000\000)2\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012b)2\000\000\016\202\000\000\020\178\026\148\000\000\000\000\000\000\006d\000\000\"~\000\000\000\0004\144\000\000\000\000\000\000\006\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000)\174\000\000\028\224\000\000\000\0004\178\000\00052\000\000\000\000\013V\tB\000\000\000\000!\204\000\000\000\000\000\000\006\204\000\000\014\204\000\000\000\000\028\178\000\000\000\000\000\000\008<\000\000\nt\000\000\014\136\000\000\018\216\000\000\021\002\000\000\021$\000\000\026 \000\000\0306\000\000 Z\000\000#\244\000\000$\130\000\000-j\000\000-\144\000\000\000\000\000\000\000\000\000\000\000\000\003^\000\000\011\130\000\000\022\162\003\238\000\000\"8\000\000\000\000\000\000\000\000\000\000\000\000\030V\000\000\000\000\000\000\000\000\000\000\000\000\003\230\000\000\000\000\000\000\000\000\000\000\000\000\005(\000\000\000\000 \006\000\000\000\000\000\000,\208\000\000\000\000\000?\000\000\000\000\000\000#\134\000\000\000\000\000\000\000\000,\242\000\000\000\000\000\000\000\000\004\224\008\024\000\000-\166\000\000\000\000\000\000\000\000\024<\000F\000\000\024\184\000\000\000\000\013\214\000\000-\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\146\000\000\000\000%\240\000\000\000\000\000\000-\230\000\000\000\000\002\158\000\000\000\000\014^\000\000\025\132\000\000\000\000\"\198\000\000\000\000\000\000\000K\000\000\000\000&\178\000\000\000\000\000\000\000\000.$\000\000\000\000\000\000\000\000\005p\015D\000\000.p\000\000\000\000\000\000\000\000\000\000\000\000\015 \000\000\000\000\003\154\000\000\015\162\000\000\000K\000\000\000\000\003\238\0254\000\000\004\012\000\000\000\000\000\000\000\000\003f\000\000)\210\000\000\026\000\0022\026|\000\000\002\252\000\000\016\"\000\000\016\230\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\022\027J\004\232\027\198\000\000\000\000\000\000\006*\000\000\017f\000\000\004\130\000\000\000\000\000K\004\014\028\146\000\000\005\130\000\000\017\230\029J\000\000\000\000\018\170\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\030\008z\000\000\006\166\000\000\000\000\000\000\000\000\003\194\000\000\019\154\000\000\000\000\000\000\031j5P\000\000\000\000\000\000\030\216\000\000\000\000\000\000\000\000\015.\005\170\000\000\000\000.\164\000\000\000\000\000\000\000\000\006\210\000\000\000\0000T\000\000\000\000\000\000.\188\000\000\000\000\000-\000\000\000\000/:\000\000\000\000\n\022\006\244\000\000\000\000/x\000\000\000\000\006\174\031\208\000\000\006\252\000\000\000\000/\152\000\000\000\000\000\000\000\000\000\000\000\000\007\022\000\000\000\0006>\000\000\000\000\000\000/\192\000\000\000\000\000\000\000\000\000\000#\014\000\000\000\000\000\000\000\162\000\000\000\000\000\000/\196\000\000\000\000\n\174\007*\000\000\000\0000V\000\000\000\000\006\180\000\000\000\000\000\000\000\000\003f\005\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\134\000\000\020J\000\000\000\000\000\0005h\000\000\t\012\000\000\000\000\000\000\004t\000\000\000\000\000g\020\250\000\000\021\170\000\000\000\000\000\000\004\194\000\000\014>\005<\016\n\000\000\023Z\000\000\000\000\000\000\005\224\000\000*~\006\018+,\000\000+r\000\000\000\000\000\000\007J\000\000\026\200\007X\000\000\000\000\022l\013\214\007j\029T\000\000\030,\000\000\000\000\000\000\007\234\000\0003\176\008 \000\000\000\000\000\000\000c\000\000\000\000\000\000\000\000\000\000\002\208\000\000\000\000\002\186\000\000\003\024\000\000\000\000\000\000\003\018\000\000\000\000\000\000\000\000\000E\000\000\006\242\002\166\002\184\000\000\000\000\006\184\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\246\002B\000\000\000\000\000\025\000\000\000\000\000\000\004&\000\000\000\000\006j\006x\000\000\000\000\000\000\000\000\008\146\011&\000\024\000\000\012\172\000\000\000\000\000\000\000\000\000\000\000\000\007H\000\000\000\000\005\022\000\000\000\000\002\164\000\000\000\000\000\140\000\000\000\000\005\154\000\000\007\030\004J\005\140\000\000\000\000\0060\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\206\017\254\000\000\000\000\000\000\000\000\006^\000\000\000\000\007\138\000\000\000\000\000\000\019\252\000\000\000\000\t\130\021\144\0044\000\000\021\188\000\000\000\000\000\000\000\000\000\000\000\000\0007\000\000\007\166\007h\001\224\000\000\000\000\000\000\000\000\006\002\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000v\000\000\008\026\004r\006\020\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\142\000\000\000\000\014r\022@\000\000\000\000\000\000\000\000\001\230\000\000\003\018\000\000\n0\000\000\000\000\000\000\000\000\000\000\000\000\000\007\0114\000\000\000\000\011\222\000\000\000\000\000\000\000\000\007x\000\000\013B\000\000\000\000\000\000\000\000\003\198\000\000\000\000\000\000\000B\000\000\000\000\003\128\000\000\000\000\000\000\000\000\000\000\000\000\000\0000~\005\188\000\000\000\000\000\0000\142\000\000\000\000\016\140\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003f\000\000\000\000\000\000\000\000\000\000\000#\007\128\000g\007\212\013\136\003\214\000\000\000\000\000\204\001\150\003*\004\170\000\000\000\000\000\000\000\000\000\000\000\000\028\\\000\000\000\000\000\000\000\000\016\248\000\204\029\220\005\234\000\000\000\000\008(\000\000\022Z\000\000\000\000\007\204\000\000\000\000\000\000\007\128\000\000\004\012\000\000\004h!l\000\000\000\000\000\000\000\000\002\238\000\000\003\136\000\000\007\164\000\000\000\000\006\214\000\000\000\000\000\000\000\000\t\196\000\000\000\000\000\204\008\178\000\000\022\244\000\000\000K\004\164\000\000\000\000\000\000\000\000\000\000\000\250\000\000\000\000\000\000\000\000\000\0000\182\008$\000\000\001\178\000\000\000\000\000\000\000\000\000\000\001&\000\000\n\144\t$\011R\000\000\002n\011\212\000\000\t*\000\000\003\178\000\000\004,\000\000\004\248\000\000\000\000\000\000\000\000\000\000\008x\000\000\005\176\000\000\tD\000\000\006|\000\000\000K\005\006\000\000\000[\000\000\006<\005p\000\000\008\156\000\000\008\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\192\000\000\t \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\238\005\246\008\150\007<\000\000\007R\000\000\000\000\006\128\tT\000\000\006T\000\000\000\000\000\000\000\000\0074\000\000\000\000\000\000\000\000\000\000\007L\008\172\008\146\007\138\007\204\000\000\000\000\000\028\000\000\000\000\000\000\000\000\008\188\000\000\000\000"), (16, "\001\182\001\205\0006\000\\\004>\004T\0059\0018\005\184\001;\000^\002c\005:\001\129\000-\004\187\005\185\002c\005;\005=\003\014\000\n\004R\000\211\002\245\000\238\004U\004a\000-\001\131\002\245\004l\004\185\004\188\004a\003\251\000\211\004\203\000\236\002\245\000\017\000\005\004\203\000\016\003\015\000\t\001\184\000^\004j\004a\001\185\000\191\000_\0006\004\204\001=\000`\004\207\004a\004\204\001\132\003\011\004\207\004a\000\008\000\t\005\215\000^\001*\004C\000\213\003\012\004{\004a\000\214\005\216\001\131\001\182\001\205\0006\000^\000i\000\211\000\213\000\236\000\193\004b\000\214\004\240\005E\004\019\000-\000\211\004b\000\232\002[\003\\\003D\000\243\004\206\000'\000\227\001,\000&\000\252\004D\004\021\000D\004b\000D\005F\004\141\0026\001<\000\227\000\154\004\204\004b\004\243\004\207\004a\003\015\004b\001\184\001\135\000-\000^\001\185\004\142\000\213\004\145\004a\004b\000\214\0007\002J\000^\005/\0031\000\213\0007\005\207\002\245\000\214\002\246\001\198\0029\002:\002<\0007\002O\005\004\005\005\002\246\002P\001@\003\022\005H\001\199\001<\000\227\000j\0006\0007\001\182\001\205\005I\005c\000\253\000\152\000\227\005d\0012\003\139\000E\001\210\005\127\001%\000-\004b\0036\000\228\005;\005\128\003\014\000k\002\251\002T\000\168\001t\004b\003%\005f\000\244\000\228\003\185\0006\003:\003*\005p\005q\000\160\005h\002\255\003<\001\214\004E\000\246\003\015\001>\001\184\001%\002J\0006\001\185\000\160\004\235\000-\000\166\005\146\001x\003\252\001\198\004\246\0006\001\215\000-\002O\004\215\001\000\001\216\002P\001@\003\022\001\217\001\199\003\141\003j\005/\001\218\000\228\001\182\001\205\000^\003\023\003\254\004\t\0004\003X\001\001\000\228\000-\0007\005u\001\002\000-\0031\001\143\001\003\002[\003\\\003D\001\001\001\004\002T\0006\000\152\001c\003E\005\147\003d\000\191\000b\000\017\000-\003*\001\006\0006\000\160\003{\001U\003<\001\214\004\203\0053\003\015\004\192\001\184\004E\000\255\005y\001\185\002}\005z\001O\002\146\001\145\004\157\003\229\002J\004\204\004\193\001\215\004\207\004a\000\192\0007\001\216\000\237\001\198\005\029\001\217\000\160\001'\002O\000\166\001\218\003^\002P\001@\003\022\005\149\001\199\000\179\000-\000/\001z\0002\001\182\001\205\005I\005c\004i\000'\0007\005\151\000^\0006\003k\001\210\002\127\001%\000-\004\011\002\128\005~\005;\005\133\003D\004j\004a\002T\001E\000\253\0004\003%\005\153\002]\001@\001d\000\170\003$\003*\004b\004\232\000\160\005\155\001@\003<\001\214\001B\003\012\003\015\004\000\001\184\000\216\002J\000\\\001\185\001P\001m\000e\001A\001\182\001\203\0052\001\198\000\225\005\143\001\215\000-\002O\000\169\004X\001\216\002P\001@\003\022\001\217\001\199\004\141\003m\005\029\001\218\000\160\001l\001W\001o\003\023\004b\004\194\001X\003X\000\160\001Y\000\152\000\166\004\142\003^\004\145\004a\000^\004g\000\211\0023\000\231\000_\000^\002T\001\184\000`\004J\003E\001\185\003d\004Q\0006\002\141\000\160\003*\005/\0019\000\160\003{\001N\003<\001\214\0026\002}\000\\\002\142\002\150\004R\000\185\004O\000i\004U\004a\001O\004^\003f\000\160\004\235\002J\000\166\001@\001\215\000^\004Y\004\236\000\213\001\216\004\197\001\198\000\214\001\217\0024\001B\002O\004b\001\218\0028\002P\001@\003\022\005\139\001\199\003J\001i\004\138\001\182\001\205\002I\000^\005I\005c\002\127\003\012\000_\002R\002\128\000\227\000`\001*\000-\002\015\002\016\003\150\005;\005\133\003D\000\160\001l\0006\001o\002T\004b\003\012\004m\003E\002}\005\141\001e\002\150\002\015\002\016\003*\000i\001\198\000\160\003/\001@\003<\001\214\003\015\000j\001\184\001+\000-\000\191\001\185\001\199\005\031\001P\005\000\005 \001^\002\227\0025\000-\005\138\001\182\001\205\001\215\000\137\003}\005\t\005\n\001\216\000k\0006\003a\001\217\005$\002I\000-\0006\001\218\002\127\005;\005\133\003D\002\128\001\213\004i\001X\005\014\000\160\001Y\004\\\000\166\000\228\000-\003\254\000\138\000\\\004\163\0051\001\242\000e\004\238\004j\004a\002\141\002\206\003\015\002\204\001\184\004\178\004a\0024\001\185\002\169\003S\005Z\000m\002\142\000j\001\215\000\139\004\154\005\140\002b\000\140\001d\000\211\003\135\000\230\003S\000o\005\029\004c\001\218\001Z\004\001\002J\003x\002\207\004\248\000^\004\212\000k\005/\005\029\000_\001\198\005\002\003U\000`\000-\002O\0006\005*\002\018\002P\001@\003\022\005\139\001\199\002\015\002\016\004b\003T\001\182\001\205\000-\005I\005c\004b\000^\003z\002R\000\213\000i\003p\002\141\000\214\000-\002\211\001p\0007\005;\005\133\003D\002\169\002\172\001\187\002T\002\142\000\152\003x\003E\000-\005\141\001#\003\002\002J\005n\003*\002\173\001@\000\160\003/\000\227\003<\001\214\001\198\003\015\005\157\001\184\004\135\002O\005R\001\185\002\245\002P\001@\003\022\005\139\001\199\002\015\002\016\005W\005\142\003y\001\215\002\228\005I\005c\004\012\001\216\0006\002R\001@\001\217\000\160\004\235\000-\000\166\001\218\005]\0006\005^\000-\005U\002\231\000\160\005V\002T\000\166\002\214\003}\003E\000j\005\141\001\182\001\205\002\172\001*\003*\004\022\0007\000\160\003/\004\148\003<\001\214\003=\004\144\000-\004p\002\173\000\188\005;\005\133\003D\004\021\000k\002\017\000\160\002\243\004\149\003\001\000\228\0006\004\142\001\215\004\145\004a\0050\000\169\001\216\001,\005?\000-\001\217\0006\001U\002J\003\015\001\218\001\184\000\138\003\012\0006\001\185\000\169\001q\001\198\001\182\001\252\001O\003\128\002O\005X\005\150\003r\002P\001@\003\022\005\139\001\199\004\029\000m\0007\004\196\004\011\000\139\0031\005I\005c\000\140\004\148\000\152\002R\003p\000\160\000o\004\031\002W\004\193\0007\000-\000/\0000\0002\004\151\004b\001U\004\149\002T\001\196\000\160\000^\003E\001\184\005\141\001\182\001\205\001\185\0006\003*\001O\004\149\000\160\003/\004\141\003<\001\214\005\161\003\229\000-\0004\005\026\004i\005;\005\133\003D\000\169\000\160\004\133\004i\000\166\004\142\001@\004\145\004a\002\234\001\215\0006\002J\004j\004a\001\216\0007\003\144\001P\001\217\004j\004a\001\198\003\015\001\218\001\184\004 \002O\0007\001\185\005\180\002P\001@\003\022\005\139\001\199\002#\004[\000-\005\154\001\182\001\205\004\031\005I\005c\001[\000\160\001f\002R\004'\001X\003\146\000\160\001Y\000-\000\166\005\027\001@\002[\003\\\003D\0006\003\026\0006\002T\004)\0006\004b\003E\001P\005\141\004\194\004\152\004b\003\167\003*\001\198\005\186\000\160\003/\004b\003<\001\214\0006\003\015\003\144\001\184\0006\003\241\001\199\001\185\003\241\0022\005Z\005\196\000-\001[\005\187\001\\\003u\0006\001X\001\215\000\160\001Y\001@\000\166\001\216\004_\005\192\0006\001\217\004Y\004\132\002J\002}\001\218\001B\002\150\003\145\005\191\002\130\003\243\000-\001\198\003\242\002c\005(\001i\002O\004\184\005\201\004\155\002P\001@\003\022\005\139\001\199\004\141\0006\004\210\004\193\001\182\001\205\004`\005I\005c\004\185\004\188\004a\002R\000\160\001l\000^\001o\004\142\000-\004\145\004a\002I\002[\003\\\003D\002\127\005\205\000-\002T\002\128\004\156\005(\003E\002\139\005\141\002\166\004\166\002J\0007\003*\000-\001@\000\160\003/\004v\003<\001\214\001\198\003\015\000-\001\184\004t\002O\005R\001\185\0007\002P\001@\003\022\0007\001\199\004\004\003j\004\200\005B\002}\001\215\004*\002\150\003\023\004b\001\216\0007\002R\003\012\001\217\004-\005\203\002c\004b\001\218\005\\\0007\004)\003\175\005U\0046\000\160\005V\002T\000\166\0006\004\031\003E\001U\003d\001\182\001\205\000\152\004\201\003*\003\192\0048\000\160\003/\003\201\003<\001\214\001O\000^\000-\0007\004\199\002\127\002[\003\\\003D\002\128\003\211\004\213\005Y\005G\002\141\002\201\002\222\002\204\005)\001\215\003\236\005K\005\208\002\169\001\216\005e\004i\002\142\001\217\0055\005,\002J\003\015\001\218\001\184\003\012\000\160\004\133\001\185\000\166\005\211\001\198\0049\004j\004a\005\212\002O\004\214\002\207\002d\002P\001@\003\022\004\136\001\199\003h\003j\005w\0048\005\172\005)\001\182\001\205\003\023\000\160\005\220\002\229\002R\004<\005\172\004\253\0054\005,\001@\005\027\000-\000\000\005\172\004\169\002[\003\\\003D\000\152\002T\004\031\001P\000\000\003E\002}\003d\000-\002\150\005\130\0007\003*\005\130\002\172\000\160\003/\005\148\003<\001\214\002\141\004b\005X\003\015\000\160\001\184\005\130\000\000\002\173\001\185\001[\005\210\001a\002\142\005\193\001X\005\027\000\160\001Y\001\215\000\166\002J\005\195\005\172\001\216\005\209\000\160\001|\001\217\000\166\002I\001\198\005\144\001\218\002\127\005\136\002O\003\003\002\128\004\149\002P\001@\003\022\004\184\001\199\003\143\003j\004\203\005\152\000\000\000\000\001\182\001\205\003\023\003\007\000\000\000\000\002R\005\027\000\\\004\185\004\188\004a\000e\004\204\000-\000\000\004\207\004a\002[\003\\\003D\000\000\002T\000\000\000-\0003\003E\0002\003d\000\000\005\205\002\172\000\000\003*\000\000\000\000\000\160\003/\005\179\003<\001\214\004\202\000\000\002J\003\015\002\175\001\184\000\000\005\173\000\000\001\185\000\000\000^\001\198\0004\000-\005\175\000_\002O\004\129\001\215\000`\002P\001@\003\022\001\216\001\199\004\008\003j\001\217\004b\001\182\001\202\005\206\001\218\003\023\004b\004\203\000\152\002R\002\141\002\201\002\202\002\204\005\206\003\191\000i\000\000\002}\002\169\000\211\002\150\000\238\002\142\004\204\002T\000\000\004\207\004a\003E\000\000\003d\001\182\001\205\005\177\000\000\003*\000\186\000\000\000\160\003/\000\000\003<\001\214\002\207\000^\000-\001\184\000\000\000\000\005;\001\185\003\014\000\000\000\160\001)\000\000\000\166\000\211\000\000\000\229\000-\000^\001\215\000^\002J\002\127\000\213\001\216\000\000\002\128\000\214\001\217\000\000\000\000\001\198\003\015\001\218\001\184\000\000\002O\000\000\001\185\000\000\002P\001@\003\022\004b\001\199\005a\003j\003\235\002\172\000\000\005\145\001@\000j\003\023\000\227\000\000\000\000\002R\000^\000\000\000\000\000\213\002\173\001B\004\217\000\214\000\000\000\000\004\220\000\000\000\000\000\188\000\000\002T\001i\000\000\000k\003E\000\000\003d\000\000\000\000\000\169\000\000\003*\001\182\001\205\000\160\003/\004i\003<\001\214\000\227\004\203\000\000\000\000\000\000\000\160\001l\000-\001o\000\138\001\198\005;\000\000\003\014\004j\004a\000\000\002}\004\204\001\215\002\150\004\207\004a\001\199\001\216\000\000\000\000\002\141\001\217\000\000\000m\002J\000\000\001\218\000\139\000\000\000\160\003\015\000\140\001\184\002\142\001\198\000\228\001\185\000o\000\000\002O\000\000\000\000\000\000\002P\001@\003\022\005\132\001\199\005\131\000\000\004\233\001\182\001\205\000\000\002I\005I\005c\000\000\002\127\000\169\005\135\000\254\002\128\000\000\000\000\000-\000\000\004b\000\000\005;\000\000\003\014\000\000\000\228\004b\000\000\002T\000\000\000\000\004\203\003%\005\137\000\211\001\000\000\236\000\000\000\000\003*\001\182\001\203\000\160\003/\000\000\003<\001\214\003\015\004\204\001\184\000\000\004\207\004a\001\185\002\172\001\001\000\000\000\160\000\000\000\000\001\002\000\000\000\000\000\000\001\003\005\134\001\215\000\000\002\177\001\004\000\000\001\216\000\000\002J\002}\001\217\000\000\002\145\000^\000\000\001\218\000\213\000\000\001\198\000^\000\214\001\184\000\000\002O\000\000\001\185\000\000\002P\001@\003\022\005\132\001\199\000-\000/\001v\0002\001\182\001\205\000\000\005I\005c\000\000\002\141\000-\005\135\002\208\004b\000\227\000\000\000\000\000-\002\169\000\000\000^\002[\002\142\003\014\002\127\000\000\000\000\002T\002\128\0004\004\127\003%\005\137\000\000\004\241\000\000\000\000\000\000\003*\004i\002J\000\160\003/\002\210\003<\001\214\000\000\003\015\000\000\001\184\001\198\000\000\000\000\001\185\000\000\002O\004j\004a\000\000\002P\001@\003\022\005\132\001\199\000\000\001\215\000\000\000\000\001\182\001\205\001\216\005I\005c\000\000\001\217\000\000\005\135\000\000\000\000\001\218\004\014\000\000\000-\000\000\003\138\002\216\002[\001\198\003\014\000\000\000\000\002\172\002T\000\000\000\228\000\000\003%\005\137\002}\000\000\001\199\002\150\000\000\003*\000\000\002\173\000\160\003/\000\000\003<\001\214\004\203\003\015\000\000\001\184\000\000\004b\000\000\001\185\004\244\000\000\002\141\000\000\000\000\000\211\000\000\000\238\000\000\004\204\000\000\001\215\004\207\004a\000\000\002\142\001\216\000\000\000-\002J\001\217\001@\005(\002I\000\000\001\218\003\136\002\127\000\000\001\198\003\138\002\128\000\152\001B\002O\000\000\000\000\000\000\002P\001@\003\022\000\000\001\199\001\001\001i\000\000\001\182\001\205\001\215\000^\000\000\003\023\000\213\002Y\000\000\003\127\000\214\001\008\000\000\000\000\000-\000\000\001\220\000\000\002[\003\t\003\014\000\160\001l\000\000\001o\002T\004b\000\000\002c\003%\003\129\000\000\000\160\001~\000\243\000\166\003*\000\227\002J\000\160\003/\0006\003<\001\214\003\015\000\000\001\184\000\000\001\198\000\211\001\185\000\238\000\000\002O\000\000\000\000\000\000\002P\001@\003\022\004}\001\199\000\000\001\215\000\000\001\182\001\205\000\000\001\216\000\000\003\023\000\000\001\217\003'\003\127\000\000\000\000\001\218\002\141\000-\000\000\002\217\000\000\002[\003(\003D\002}\002\169\000\000\002\150\002T\002\142\000\000\000^\003%\003\129\000\213\000\000\000\000\004\141\000\214\003*\000\000\000\000\000\160\003/\000\000\003<\001\214\003\015\000\000\001\184\000\000\005)\000\000\001\185\004\142\000\228\004\145\004a\002}\000\000\000\000\002\150\005+\005,\000\000\000\227\001\215\0013\000^\000\000\004\251\001\216\002\127\002J\000\000\001\217\002\128\000\000\000\\\000\000\001\218\000\246\000q\001\198\000\000\000\000\000\000\000\000\002O\0007\000-\000\000\002P\001@\003\022\000\000\001\199\000\160\002\172\000\000\001\182\001\205\002I\001\000\000\000\003\023\002\127\000\000\003G\003I\002\128\000\000\002\173\000\000\000-\000\000\004b\000\000\002[\003(\003D\000-\000^\001\001\000\000\002T\000\000\000_\001\002\003%\003K\000`\001\003\000\000\000\000\003\016\003*\001\004\002J\000\160\003M\000\000\003<\001\214\003\015\000\228\001\184\000\000\001\198\002c\001\185\003\166\003\020\002O\000\000\000\000\000i\002P\001@\003\022\000\000\001\199\0006\001\215\000\000\001\182\001\205\000\000\001\216\002\141\003\023\004\024\001\217\003L\002R\000\000\000\000\001\218\000\000\000-\000\000\000\000\002\142\002[\003(\003D\000\000\000\000\000\000\000\000\002T\000\000\000\000\001\000\003E\000\000\003F\000\000\000\000\000\000\000\000\003*\000\000\002\141\000\160\003/\002\168\003<\001\214\003\015\000\000\001\184\002\169\001\001\000\000\001\185\002\142\000\211\001\002\000\238\000\000\000\000\001\003\004\226\000\000\000\000\000\000\001\004\001\215\001\182\001\205\000\152\000\000\001\216\000\000\002J\000j\001\217\000\000\000\211\000\000\000\236\001\218\000-\000\000\001\198\000\000\002[\003\\\003D\002O\002\172\000\000\000\000\002P\001@\003\022\000\000\001\199\000\000\000k\000^\001@\000\000\000\213\002\179\000\000\003\023\000\214\000\000\000\000\002R\0007\003\015\003\172\001\184\000\000\000\160\001\128\001\185\000\166\000\000\000\211\000^\000\238\002\172\000\213\002T\000\000\000\000\000\214\003E\000\000\003F\000\000\000\227\000\000\000\000\003*\002\173\002J\000\160\003/\000\000\003<\001\214\001/\000\000\000\160\003\184\001\198\003\190\005\023\002}\000\000\002O\002\144\000\227\003>\002P\001@\003\022\000\000\001\199\000\000\001\215\000^\001\182\001\205\000\213\001\216\000\000\003\023\000\214\001\217\003B\002R\000\000\000\000\001\218\000\000\000-\000\000\000\000\000\000\002[\003\\\003D\000\000\000\000\000-\000\000\002T\000\000\005(\000\000\003E\000^\003F\000\000\000\227\002\127\000\000\003*\002J\002\128\000\160\003/\000\000\003<\001\214\003\015\000\000\001\184\001\198\000\228\000\000\001\185\000\000\002O\002b\000\000\000\000\002P\001@\003\022\000\000\001\199\000\000\003c\001\215\001\182\001\205\000\000\000\000\001\216\003\023\000\228\000\\\001\217\002R\004\026\000\182\000\000\001\218\000-\000\000\000\000\000\000\002[\003\\\003D\000\000\000\000\000-\000\000\002T\000\000\000\000\000\000\003E\000\000\003d\001\000\000\000\000\000\000\000\003*\000\000\000\000\000\160\003/\000\000\003<\001\214\003\015\000\000\001\184\000\000\000\000\000\228\001\185\000^\001\001\000\000\001\028\000\000\000_\001\002\000\000\000\000\000`\001\003\000\000\001\215\001\182\001\205\001\004\002\141\001\216\000\000\000\000\002J\001\217\000\000\001\001\005\021\000\000\001\218\000-\000\000\002\142\001\198\002[\003\130\003D\000i\002O\000\000\001\004\000\000\002P\001@\003\022\000\000\001\199\000\\\003e\001\000\000\000\000q\001@\000\000\004i\003\023\000\000\000\000\000\000\002R\003\015\000\000\001\184\005+\005<\000\000\001\185\000\000\000\000\001\001\000\000\004j\004a\000\000\001\002\002T\000\000\000\000\001\003\003E\000\000\003d\000\000\001\004\000\000\000\000\003*\002J\000\000\000\160\003/\000^\003<\001\214\000\000\003\132\000_\001\198\000\160\002\243\000`\003\001\002O\000\000\000\000\000\000\002P\001@\003\022\000\000\001\199\000\000\003w\001\215\001\182\001\205\000\152\000j\001\216\003\023\000\000\000\000\001\217\002R\000\000\000i\000\000\001\218\000-\001\182\001\203\004b\002[\003\130\003D\000\000\000\000\002}\000\000\002T\002\150\000k\000\000\003E\000\000\003d\001\182\001\205\000\000\000\000\003*\002J\000\000\000\160\003/\000\\\003<\001\214\003\015\000e\001\184\001\198\000\160\001\141\001\185\000\166\002O\000\000\000\000\000-\002P\001@\003\022\000^\001\199\001\184\000\000\001\215\000\000\001\185\000\000\000^\001\216\003\023\000\000\002\127\001\217\002R\000\000\002\128\000^\001\218\001\184\003\134\000\000\000\000\001\185\000\000\000\000\000^\000\000\000\000\000\000\002T\000_\000j\000\000\003E\000`\003\133\000\000\000\000\000\\\000\000\003*\000\000\000\181\000\160\003/\000\000\003<\001\214\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000k\000\000\000\000\000\000\000i\001\182\001\205\000\000\000\000\000\000\000\000\004\161\001\215\003\152\000\000\001\210\000\000\001\216\000\000\000-\002J\001\217\000\000\002[\003(\003D\001\218\000^\000\000\000\000\001\198\000\000\000_\000\000\000-\002O\000`\001j\000\000\002P\001@\003\022\000\000\001\199\000\000\001\198\000m\000\000\000\000\003\015\000\000\001\184\003\023\002\141\000\000\001\185\002R\000\000\001\199\000\000\000r\000i\001\198\000\000\0004\000\000\002\142\000\000\001\182\001\203\000\000\000\000\002T\000\000\000\000\001\199\003E\000\000\003\133\000\000\004i\000\152\000\000\003*\000j\000\000\000\160\003/\001\212\003<\001\214\000\000\000\000\001\182\001\205\000\000\000\000\004j\004a\000\000\000\000\000\000\000\000\000\183\000\000\000\000\000\000\000-\000k\000\000\001\215\002[\000^\003\014\001\184\001\216\000\000\000\000\001\185\001\217\000\000\000\000\001\214\000\000\001\218\001\204\000\000\000\160\001-\000\000\000\166\000\000\000\000\000\138\000\000\002\172\000\000\003\015\000\000\001\184\002J\000j\001\215\001\185\000\000\002}\000\000\001\216\002\143\002\181\001\198\001\217\000\000\000\000\000m\002O\001\218\004b\000\139\002P\001@\003\022\000\140\001\199\000\000\000k\000\000\000\\\000o\000\000\004\002\000g\003\023\000\000\003\138\001@\002R\000\000\000\000\000\000\000\000\001\182\001\205\000\000\000\000\002}\000\000\001B\002\150\000^\000\000\000\000\002T\002\127\000\000\000-\003E\002\128\003F\002[\000\000\003\014\002}\003*\000\000\002\150\000\160\003/\000\\\003<\001\214\000^\000]\001\198\000\000\000\000\000_\000\000\000\000\000\000\000`\000\160\001l\001s\001o\003\015\001\199\001\184\002J\000^\001\215\001\185\000\000\002\127\000\000\001\216\000\000\002\128\001\198\001\217\000\000\000\000\000\000\002O\001\218\000i\000^\002P\001@\003\022\002\127\001\199\000^\000\000\002\128\000\000\000\000\000_\004\016\000\000\003\023\000`\003\138\000\000\003\127\000\000\004\173\000\000\000\000\001\182\001\205\000\000\000\000\000\211\000\000\000\212\000\000\000\000\000\000\000\000\002T\000\000\004i\000-\003%\003\129\000i\002[\000\000\003\014\002\141\003*\000\000\001\215\000\160\003/\000\000\003<\001\214\004j\004a\000\000\000\000\002\142\004i\000\000\000\000\001\222\000\000\000\000\000\000\000\000\000\000\003\015\000\000\001\184\002J\000^\001\215\001\185\000\213\004j\004a\001\216\000\214\000j\001\198\001\217\000\000\000\000\002\141\002O\001\218\000\000\000\000\002P\001@\003\022\000\000\001\199\000\000\000\000\000\000\002\142\000\000\000\000\004\018\002\141\003\023\000k\003\138\000\227\003\127\000\000\000\000\000\000\000\000\001\182\001\205\004b\002\142\000\000\000\000\000\000\000\000\005D\000j\000\000\002T\000\000\004i\000-\003%\003\129\000l\002[\003(\003D\000\000\003*\000-\004b\000\160\003/\002[\003<\001\214\004j\004a\000\000\000k\000\000\000\000\002}\000\000\000m\002\150\000\000\000\000\000\000\000\149\003\015\000\000\001\184\002J\000\000\001\215\001\185\000\000\000o\0040\001\216\002\172\000\000\001\198\001\217\000\000\000\000\000\000\002O\001\218\000\000\000\000\002P\001@\003\022\002\183\001\199\000\\\002\172\000\000\000\228\000q\000\000\001\182\001\205\003\023\002I\000\000\000\000\003\127\002\127\005g\002\185\000\000\002\128\000\000\004b\000-\000\000\000\000\000\000\002[\003(\003D\000\000\002T\000\000\000\000\000\000\003%\003\129\000\000\000\000\000\000\000\000\000\000\003*\004\182\000\000\000\160\003/\000^\003<\001\214\000\000\000\000\000_\003\015\000\000\001\184\000`\000\000\000\000\001\185\000\211\000\000\000\238\000\000\000\000\004\180\000\000\002J\000\000\001\215\003\147\001\182\001\205\000\000\001\216\000\000\000\000\001\198\001\217\000\000\000\000\000i\002O\001\218\000\000\000-\002P\001@\003\022\002[\001\199\003D\000\000\000\000\000\000\000\000\001@\003\022\000\000\003\023\000\000\000\000\000\000\002R\000^\001\182\001\201\000\213\003\023\000\000\000\000\000\214\000\000\002\141\000\000\003\015\002\208\001\184\000\000\002T\000\000\001\185\002\169\003E\000-\003F\002\142\000\000\000\000\000\000\003*\004\224\0041\000\160\003/\000\000\003<\001\214\000\227\003*\000\000\000\000\000\160\003/\002J\003<\000\000\002\210\000\000\000^\000\000\001\184\000\000\000\000\001\198\001\185\000\000\001\215\000\000\002O\000\000\000j\001\216\002P\001@\003\022\001\217\001\199\000\000\000\000\000\000\001\218\000\000\001\182\001\205\000\000\003\023\000\000\001U\000\000\002R\000\000\000\000\000\000\003H\000k\000\000\000-\000\000\002\215\000\000\002[\001O\003\014\000\000\002\172\002T\000\000\000\000\000\000\003E\000\000\003F\000\000\000\000\000\000\002J\003*\000\000\002\173\000\160\003/\000\000\003<\001\214\000\000\001\198\003\015\000\228\001\184\000\000\002O\000\000\001\185\000\000\002P\001@\003\022\000\000\001\199\000\000\000m\000\000\000\000\001\215\001\182\001\205\000\000\003\023\001\216\000\000\000\000\003\149\001\217\004\028\000t\003\013\000\000\001\218\000-\001\198\000\000\000\000\002[\000\000\003\014\000\000\000\000\002T\000\000\000\000\000\000\003E\001\199\003\151\001@\001\000\000\000\000\000\003*\000\000\000\000\000\160\003/\000\000\003<\001\214\001P\000\000\003\015\000\000\001\184\000\000\000\000\000\000\001\185\001\001\000\000\000\000\000\000\000\000\001\002\000\000\000\000\000\000\001\003\001\215\001\182\001\205\000\000\001\004\001\216\000\000\000\000\001[\001\217\001\137\000\000\002J\001X\001\218\000\160\001Y\000\000\000\166\000\000\000\000\003R\001\198\000\000\000\000\000\000\000\000\002O\000\000\000\000\000\000\002P\001@\003\022\000\000\001\199\000\000\000\000\000\000\000\000\000\000\001\182\001\205\000\000\003\023\002I\000\000\001\184\003#\000\000\000\000\001\185\003)\000\000\000\000\000-\000\000\000\000\000\000\002[\000\000\003\014\000\000\000\000\002T\000\000\000\000\000\000\003%\003&\000\000\000\000\000\000\000\000\002J\003*\000\000\000\000\000\160\003/\000\000\003<\001\214\000\000\001\198\003\015\000\000\001\184\000\000\002O\000\000\001\185\000\000\002P\001@\003\022\000\000\001\199\000\000\000\000\000\000\000\000\001\215\001\182\001\205\000\000\003\023\001\216\000\000\000\000\003#\001\217\000\000\000\000\000\000\000\000\001\218\000-\000\000\002}\000\000\002[\002\150\003\014\000\000\000\000\002T\000\000\000\000\000\000\003%\003&\000\000\000\000\000\000\000\000\002J\003*\000\000\000\000\000\160\003/\000\000\003<\001\214\000\000\001\198\003\015\000\000\001\184\000\000\002O\000\000\001\185\000\000\002P\000\000\000\000\000\000\001\199\000\000\000\000\000\000\000^\001\215\001\182\001\205\002\127\000\000\001\216\000\000\002\128\002R\001\217\000\000\000\000\002J\002}\001\218\000-\002~\000\000\000\000\002[\000\000\003\014\001\198\000\000\002T\000\000\000\000\002O\000\000\000\000\000\000\002P\001@\003\022\000\000\001\199\000\000\000\000\000\000\000\211\000\000\000\238\001\214\000\000\003\023\003\015\000\000\001\184\003#\000\000\000\000\001\185\000\000\000\000\000\000\000\000\000\000\000^\000\000\000\000\000\000\002\127\001\215\000\000\002T\002\128\000\000\001\216\003%\003&\000\000\001\217\000\000\000\000\002J\003*\001\218\000\000\000\160\003/\000\000\003<\001\214\000^\001\198\000\000\000\213\000\000\000\000\002O\000\214\000\000\000\000\002P\001@\003\022\000\000\001\199\000\000\000\000\002\141\000\000\001\215\003g\001\182\001\205\003\023\001\216\000\000\000\000\003`\001\217\000\000\002\142\000\000\000\000\001\218\000\227\000-\000\000\000\000\000\000\002[\000\000\003\014\000\000\002T\000\000\000\000\000\000\003%\003b\000\000\000\000\000\000\000\000\002J\003*\000\000\000\000\000\160\003/\000\000\003<\001\214\000\000\001\198\000\000\003\015\000\000\001\184\002O\000\000\000\000\001\185\002P\001@\003\022\002\141\001\199\000\000\000\000\000\000\000\000\001\215\003_\001\182\001\205\003\023\001\216\000\000\002\142\003`\001\217\000\000\000\000\000\000\000\000\001\218\000\000\000-\000\000\002\172\000\\\002[\000\000\003\014\000g\002T\000\000\000\000\000\000\003%\003b\000\000\000\000\002\187\000\228\000\000\003*\000\000\000\000\000\160\003/\000\000\003<\001\214\000\000\000\000\000\000\003\015\000\000\001\184\000\000\000\000\000\000\001\185\000\000\000\000\000\000\000\000\000\000\000\000\004,\000\000\000\000\001\215\000^\000\000\000\000\000\000\001\216\000_\000\000\000\000\001\217\000`\000\000\000\000\002J\001\218\002}\000\000\000\000\002\150\001\000\000\000\000\000\000\000\001\198\000\000\000\000\000\000\000\000\002O\000\000\000\000\000\000\002P\001@\003\022\000i\001\199\000\000\000\000\001\001\000\000\003s\001\182\001\205\001\002\003\023\000\000\000\000\001\003\003t\000\000\000\000\000\000\001\004\000\000\000\000\000-\000\000\002}\002I\002[\002\150\003\014\002\127\000\000\002T\000\000\002\128\000\000\003%\003v\000\000\000\000\000\000\000\000\002J\003*\000\000\000\000\000\160\003/\002}\003<\001\214\002\150\001\198\003\015\000\000\001\184\000\000\002O\000\000\001\185\000\000\002P\001@\003\022\000\000\001\199\000\000\000\000\000\000\002I\001\215\003q\000\000\002\127\003\023\001\216\000\000\002\128\003`\001\217\000\000\000\000\000j\000\000\001\218\000\000\000\000\000\000\000\000\000\000\003~\000\000\000^\000\000\002T\000\000\002\127\000\000\003%\003b\002\128\001\182\001\205\000\000\000\000\003*\000k\000\000\000\160\003/\000\000\003<\001\214\000\000\000\000\000-\000\000\000\000\000\000\002[\000-\003\014\000\000\000\000\002[\000\000\000\000\002\141\002\201\0057\002\204\000l\001\215\000\000\000\000\000\000\002\169\001\216\000\000\000\000\002\142\001\217\000\000\000\000\002J\003\015\001\218\001\184\000\000\000\000\0040\001\185\000m\000\000\001\198\000\000\000\000\000n\000\000\002O\000\000\002\207\000\000\002P\001@\003\022\000o\001\199\000\000\000\000\002\141\000\000\000-\002\171\001\182\001\205\003\023\000\000\000\000\002\169\003\127\000\000\003\131\002\142\005@\000\000\000\000\000\000\000-\000\000\000\000\000\000\002[\002\141\003\014\000\000\002T\000\000\000\000\000\000\003%\003\129\000\000\000\000\000\000\000\000\002\142\003*\000\000\002\172\000\160\003/\000\000\003<\001\214\000\000\000\000\000\000\003\015\002}\001\184\000\000\002\150\002\173\001\185\000\000\001U\000\000\000-\000\000\000\000\000\000\002[\000\000\001\215\002}\002J\000\000\002\150\001\216\001O\000\000\000\000\001\217\000\000\000\\\001\198\000\000\001\218\000e\000\000\002O\002\172\000\000\000\000\002P\001@\003\022\0040\001\199\000\000\001@\003\022\000^\000\000\000\000\002\173\002\127\003\023\000\000\000\000\002\128\003\127\003\023\000\000\002\151\000\000\000\000\000\000\002I\000\000\000\000\000\000\002\127\000\000\000\000\000\000\002\128\002T\000^\000\000\000\000\003%\003\129\000_\000\000\000\000\0043\000`\003*\001\182\001\205\000\160\003/\003*\003<\001\214\000\160\003/\002J\003<\000\000\000\000\001@\000-\000\000\000\000\000\000\003\165\001\198\000\000\000\000\000\000\000i\002O\001P\001\215\000\000\002P\001@\003\022\001\216\001\199\000\000\000\000\001\217\000\000\003\197\000\000\000\000\001\218\003\023\000\000\000\000\003\200\005A\001\184\000\000\000\000\000\000\001\185\000\000\001[\000\000\002_\000\000\000\000\001X\000\000\000\160\001Y\002T\000\166\000\000\002\141\003%\005C\003\206\000\000\001@\003\022\000\000\003*\001\182\001\205\000\160\003/\002\142\003<\001\214\002\141\003\023\000\000\002\220\000\000\000\000\000\000\000-\000\000\002\169\000\000\003\165\000\000\002\142\002\224\003\244\000\000\000\000\001\210\001\215\001%\000\000\000\000\000j\001\216\0045\000\000\000\000\001\217\000\000\003\248\000\000\003*\001\218\000\000\000\160\003/\003\200\003<\001\184\000\000\000\000\002\164\001\185\001\182\001\205\000\000\000k\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000-\000\\\003\206\000\000\003\165\000e\000\000\001\198\002\172\000\000\000\000\000\000\000\000\000\000\000\138\000-\000\000\001@\003\207\000\000\001\199\000\000\002\189\003\199\002\172\000\000\000\000\000-\000\000\003\208\003\200\000\000\001\184\003\246\000\000\000m\001\185\000\000\002\173\000\139\000\000\000\000\000\000\000\140\000\000\000^\000\000\000\000\000\000\000o\000_\000\000\000\000\003\206\000`\002}\000\000\000\000\002\150\000\000\003\222\000\000\000\000\000\160\003\247\000\000\003\234\001\214\000\000\000\000\000\000\000\000\000\\\000\\\001\182\001\203\000e\000e\000\000\000i\001\198\001U\000\000\000\000\000\000\000\000\000-\001\215\000\000\000\000\001@\003\207\001\216\001\199\000\000\001O\001\217\000\000\000\000\000^\000\000\001\218\003\208\002\127\000\000\000\000\003\220\002\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000^\000^\000^\000\000\001\184\000_\000_\000\000\001\185\000`\000`\000\000\000\000\000\000\000\000\001\198\000\000\003\222\000\000\000\000\000\160\003\227\000\000\003\234\001\214\001@\003\207\000\000\001\199\000\000\000\000\000\000\000\\\000\000\000i\000i\000e\003\208\000\000\000\000\000\152\003\220\000\000\000j\001\215\000\000\000-\000\000\000\000\001\216\000\000\000\000\001@\001\217\000\000\000\000\002j\000\000\001\218\000\155\000\156\000\158\000\159\000\000\001P\000\000\000\000\000k\003\222\000\000\000\000\000\160\003\227\000\000\003\234\001\214\000^\000\000\000\000\000\000\000\000\000_\000\000\000\000\002\141\000`\000\160\000\165\000\000\000\166\000-\001[\000\138\002\237\000\000\001\215\001X\002\142\000\160\001Y\001\216\000\166\000\000\001\198\001\217\000\000\000\000\000\000\000\000\001\218\000i\000\152\000\000\000m\000j\000j\001\199\000\139\000\000\000\000\000\000\000\140\000\000\000\000\000\\\001\182\001\203\000o\000e\000\171\000\155\000\218\000\158\000\159\000\188\000\000\000\000\000\000\000k\000k\000\000\000\000\000\\\000\000\000\000\005Q\000e\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000-\000\160\000\165\000\000\000\166\000\000\000\000\000\138\000\138\000\000\002\172\000\000\000^\000^\000\000\001\184\000\211\000_\000\236\001\185\000\000\000`\002}\000\000\002\191\002\150\000\000\001\215\000m\000m\000^\000\152\000\139\000\139\000j\000_\000\140\000\140\000\000\000`\000\000\001\224\000o\000o\000\171\000\000\000i\000\000\000\000\000\000\000\155\001\189\000\158\000\159\000\000\000\000\000\000\000\\\000k\000\000\000^\000e\000\000\000\213\000i\000\000\002I\000\214\000\000\000\000\002\127\000-\000\000\000\000\002\128\001@\000\000\000\160\000\165\000\000\000\166\000\000\000\000\000\138\000\000\000\000\000\000\005R\000\000\000\000\000\000\000\000\000\000\000\\\000\227\000\000\000\000\000e\000\000\000\000\000\000\000^\000\000\000\000\000m\000\000\000_\000-\000\139\000\000\000`\000\000\000\140\000\000\001\198\000\000\000\000\002\162\000o\005U\000\171\000\160\005V\000\000\000\166\000\000\000j\001\199\000\000\000\\\000\000\000\000\000\000\000e\000\000\000i\000\000\000^\000\000\000\000\000\000\000\152\000_\000-\000j\002\164\000`\000\000\000\000\000\000\000k\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\155\002L\000\158\000\159\000\000\000\000\000\000\002\141\000k\000\000\002\208\000i\000\000\000^\000\228\000\138\002\169\000\000\000_\000\000\002\142\000\000\000`\000\000\000\000\000\000\000\000\000\160\000\165\000\000\000\166\000\000\000\000\000\138\001\215\000\000\000m\000\000\000\000\000\000\000\139\002\210\000\000\000-\000\140\000\000\000\000\000i\001\226\000\000\000o\000\000\000\152\000\000\000m\000j\000\000\000\000\000\139\000\000\000\000\000\000\000\140\000\000\000\000\000\000\000\000\000\000\000o\000\000\000\171\000\155\002\132\000\158\000\159\000\000\000\000\000\000\000\000\000k\000\000\000\000\001\001\002\213\002}\000\000\000\000\002\150\000\152\002\172\000\000\000j\000\000\000\000\000\000\000\000\001\n\001U\000\160\000\165\000\000\000\166\000\000\002\173\000\138\000\000\000\000\000\155\003,\000\158\000\159\001O\000\000\000\000\000\000\000k\001\182\001\203\000\000\000\000\000\000\000\000\000\000\000\000\000\152\000m\000\000\000j\000^\000\139\000\000\000\000\002\127\000\140\000\160\000\165\002\128\000\166\000\\\000o\000\138\000\171\000e\000\155\003\224\000\158\000\159\000\000\000\000\000\\\000\000\000k\000-\000e\000\000\002}\000\000\000\000\002\150\000\000\000^\000m\001\184\000-\000\000\000\139\001\185\000\000\000\000\000\140\000\160\000\165\000\000\000\166\000\000\000o\000\138\000\171\000\000\000\000\000\000\000\000\000^\000\000\001@\000\000\000\000\000_\000\000\000\000\000\000\000`\000\000\000^\000\000\000\000\001P\000m\000_\000^\000\000\000\139\000`\002\127\000\\\000\140\000\000\002\128\000g\000\000\000\000\000o\000\000\000\171\000\000\000\000\000i\000\000\001\182\001\200\000\000\000\000\000\000\001[\000\000\002\248\000\000\000i\001X\002\141\000\160\001Y\000\000\000\166\001\182\001\205\000\000\001#\001%\000\000\000\000\000\211\002\142\000\236\000\000\000\000\000\\\000\000\000^\000\000\000e\000\000\000\000\000_\003P\000\000\000\000\000`\000\000\000\\\000-\001\198\000^\000e\001\184\000\000\000\000\000\000\001\185\000\000\000\000\000\000\000\000\000-\001\199\000\000\000\000\000\000\002I\000\000\001\184\000\000\000i\000\000\001\185\000^\000\000\000\000\000\213\000\000\000^\000\000\000\214\000\152\000\000\000_\000j\000\000\000\000\000`\002\141\000\000\000\000\000^\000\152\000\000\000\000\000j\000_\000\000\000\000\002\172\000`\002\142\000\000\000\188\000\000\000\000\000\000\000\227\000k\000\000\000\000\000\173\000i\002\193\000\159\000\000\003V\000\000\000\000\000k\001\210\000\000\000\\\000\000\000\000\000i\000e\000\160\001'\001\215\000\166\000\000\000\000\000\138\000\000\000\000\000-\000\000\000\160\000\165\000-\000\166\000\000\001\228\000\138\000\000\000\000\000\000\000\000\000\000\000j\001\198\000\000\000\000\000m\000\000\000\000\002J\000\139\000\000\000\000\000\000\000\140\000\000\001\199\000m\000^\001\198\000o\000\139\002\172\000_\002O\000\140\000k\000`\002P\000\000\000\000\000o\001\199\000\171\000\000\000\000\002\195\000\000\000\000\000\228\000\000\000\152\000\000\000\000\000j\003X\001U\000\000\000\000\000\000\000\000\000l\000i\000\000\000\152\000\000\000\000\000j\000\000\000\000\001O\002T\000\000\000\195\000\000\000\000\000\000\000\000\000k\000\000\000\000\000\\\000m\000\000\000\000\000e\000\195\000\148\000\000\001\214\000\000\000k\000\000\000\000\000\000\000-\000o\000\160\000\197\000-\000\166\000\000\000\000\000\138\000\000\000\000\001\182\001\205\000\000\001\215\000\160\000\234\000\000\000\166\001\216\000\000\000\138\001\001\001\217\000\000\000\000\000\000\000\000\001\218\000m\000^\002B\004\013\000\139\000\000\000_\001\012\000\140\000\000\000`\000\000\000\000\000m\000o\000\152\000\000\000\139\000j\001@\000\000\000\140\000\000\000\000\000\000\000\000\002I\000o\001\184\001U\000\000\001P\001\185\000\000\000\000\000i\000\\\000\183\000\000\000\000\000e\000\000\000k\001O\000\000\000\000\000\000\000\000\000\000\000\000\000-\000\000\000\000\000\000\000\000\000\000\000\000\000\211\001[\000\236\003\029\000\160\0016\001X\000\166\000\160\001Y\000\138\000\166\000\000\000\000\000\000\000\000\000\000\001\182\001\205\000\000\000\000\000\000\000\000\000^\000\000\000\000\000\000\000\000\000_\000\000\000\000\000m\000`\000\000\000\000\000\139\000\000\002B\003Y\000\140\001\182\001\203\000\000\000\000\000^\000o\000\000\000\213\000\000\000\000\000\000\000\214\000\000\000\000\000\000\000\152\000\000\000i\000j\001@\002J\002I\000\000\001\184\000\000\000\000\000\000\001\185\000\000\000\000\001\198\001P\000\000\001\182\001\205\002O\000\000\001\165\000\227\002P\000\000\000\000\000k\001\199\000^\000\000\001\184\000\000\000\000\000\000\001\185\000\000\000\000\002B\003O\000\000\002R\000\000\001[\000\000\0033\000\160\001\167\001X\000\166\000\160\001Y\000\138\000\166\000\000\000\000\000\000\002T\000\000\000\000\000\000\000\000\002I\000\000\001\184\000\000\000-\001k\001\185\0002\000\000\001\182\001\205\000m\000\000\001\214\000\000\000\139\000\000\000\152\000\000\000\140\000j\000\000\000\000\000\000\000\000\000o\000\000\000\000\000\000\002B\002C\000\000\000\000\001\215\0004\002J\000\000\000\000\001\216\001\165\000\000\000\228\001\217\000\000\000k\001\198\000\000\001\218\000\000\000\000\002O\000\000\000\000\002I\002P\001\184\000\000\000\000\001\199\001\185\000\000\000\000\000\000\000\160\001\250\000\000\000\166\000\000\001\198\000\138\000\000\002R\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\199\001\182\001\205\000\000\000\000\000\000\002T\000\000\000\000\000m\002J\000\000\000\000\000\139\000\000\000\000\000\000\000\140\000\000\000\000\001\198\002B\002N\000o\001\214\002O\000\\\000\000\001\001\002P\000e\000\000\000\000\001\199\000\000\000\000\000\000\000\000\000\000\000\000\000-\000\000\001\014\000\000\001\215\002I\002R\001\184\000\000\001\216\000\000\001\185\000\000\001\217\000\000\000\000\000\000\000\000\001\218\000\000\000\000\000\000\002T\002J\001@\000\000\000\000\001\215\000\000\000\000\000^\000\000\000\000\001\198\000\000\000_\001B\000\000\002O\000`\001\214\001\230\002P\000\000\000\000\000\000\001\199\001i\000\\\000\000\000\\\000\\\000e\000\000\000e\000q\000\000\000\000\000\000\002R\001\215\000\000\000-\000\000\000i\001\216\001\182\001\205\000\000\001\217\000\160\001l\000\000\001o\001\218\002T\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002B\003[\000\000\000\211\000\000\000\236\000^\001\214\000^\000^\002J\000_\000\000\000_\000_\000`\000\000\000`\000`\000\000\001\198\000\000\000\000\000\000\002I\002O\001\184\001\215\000\134\002P\001\185\000\000\001\216\001\199\000\000\000\000\001\217\000\000\000\000\000\000\000i\001\218\000i\000i\000\000\000\000\002R\000^\000\000\000\000\000\213\000\000\000\000\000\000\000\214\000\152\000\000\000\000\000j\000\000\000\000\000\000\002T\000\000\000\000\000\000\001\182\001\205\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002m\000\000\000\000\001\214\000\227\000k\001\182\001\183\000\000\002B\004\"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\215\000\160\002o\000\000\000\166\001\216\000\000\000\138\000\000\001\217\002I\000\000\001\184\000\000\001\218\002J\001\185\000\152\000\000\000\000\000j\000\000\000j\000j\000\000\001\198\000\000\000^\000m\001\184\002O\000\000\000\139\001\185\002P\000\000\000\140\000\000\001\199\002m\000\000\000\137\000o\000\000\000k\000\000\000k\000k\000\000\000\000\000\000\002R\000\000\001\182\001\205\000\000\000\000\000\000\000\000\000\000\000\000\000\228\000\000\000\160\002\148\000\000\000\166\002T\000\000\000\138\000\000\000\138\000\136\002B\004$\000\000\000\000\000\000\000\\\000\000\000\000\000\000\000e\000\000\000\000\001\214\000\000\000\000\001\182\001\205\000m\000\000\000m\000m\000\139\000\000\000\139\002I\000\140\001\184\000\140\002J\000\000\001\185\000o\001\215\000o\000o\002B\004&\001\216\001\198\000\000\000\000\001\217\000\000\002O\000\000\000\000\001\218\002P\000\\\000^\000\000\001\199\000e\000\000\000_\001\198\001\001\000\000\000`\002I\000\000\001\184\000\000\000\000\002R\001\185\000\000\000\000\001\199\001\026\001\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002T\000\000\000\000\000i\000\\\000\000\000\000\000\000\000e\000\000\000\000\000\000\000^\000\000\000\000\000\000\000\000\000_\001\214\000\000\000\\\000`\000\000\000\000\000e\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\240\000\000\000\000\002J\000\000\000\\\001\215\000\000\000\000\000e\000\000\001\216\000\000\001\198\000i\001\217\000^\000\000\002O\000\000\001\218\000_\002P\000\000\000\000\000`\001\199\000\000\000\000\000\000\000\000\000\000\000^\000\211\000\000\000\236\002'\000_\002J\002R\000\000\000`\000\000\000\000\000\000\000\000\000\000\000\000\001\198\000^\000i\000j\002)\002O\000_\002T\000\000\002P\000`\000\000\000\000\001\199\000\000\000\000\000\000\000\000\000i\000\000\000\000\002+\000\137\000\000\000\000\001\214\002R\000k\000\000\000^\000\\\000\000\000\213\000\000\000e\000i\000\214\000\000\000\000\000\000\000\000\000\000\002T\000\000\000\000\001\215\000j\000\\\000\000\000\000\001\216\000e\000\138\000\000\001\217\000\000\000\000\000\000\000\000\001\218\001\214\000\000\000\000\000\227\000\000\000\137\000\000\000\000\000\000\000\000\000k\000\000\000\000\000m\000^\000\000\000\000\000\139\000\000\000_\001\215\000\140\000j\000`\000\000\001\216\000\000\000o\000\000\001\217\000\000\000^\000\000\000\000\001\218\000\138\000_\000\000\000j\000\000\000`\000\137\000\000\000\000\000\000\000\000\000k\002}\000i\000\000\002\150\000\000\000\000\000\000\000\000\000j\000m\000\137\000\000\000\000\000\139\000\000\000k\000\000\000\140\000i\002}\000\000\000\000\002\150\000o\000\138\000\000\000\000\000\137\000\000\000\000\000\\\000\000\000k\000\000\000e\000\000\000\228\000\000\000\000\000\000\000\138\000\000\000\000\000\000\000^\000m\000\\\000\000\002\127\000\139\000e\000\000\002\128\000\140\000\000\000\000\000\000\000\138\000\000\000o\000\000\000m\000\\\000^\000\000\000\139\000e\002\127\000\000\000\140\000\000\002\128\002\241\000\000\000^\000o\000\000\000\000\000m\000_\000\000\000j\000\139\000`\000\000\000\000\000\140\000\000\000\000\002\253\000^\000\000\000o\000\\\000\000\000_\000\000\000e\000j\000`\002\164\000\000\000\000\000\000\001\001\000k\000^\000\000\000i\000\000\000\000\000_\000\000\000\000\000\000\000`\000\000\002\164\001\018\000\000\000\000\000\000\000k\000\000\000i\000\000\000\000\000\000\000\000\000\000\000\138\000\\\000\000\000\000\000\000\000e\000\000\000^\000\000\000\000\000i\000\000\000_\000\000\000\000\002\141\000`\000\138\000\000\000\000\000\000\000m\000\000\000\000\000\000\000\139\000\000\000\\\002\142\000\140\000\000\000e\000\000\000\000\002\141\000o\000\000\000\000\000m\000\\\000\000\000i\000\139\000e\000\000\000^\000\140\002\142\000\000\003\005\000_\000\000\000o\000\000\000`\000\000\000\000\000\000\000j\000\000\000\000\000\000\000\000\000\000\000\000\003\018\000\000\000\000\000\000\000\000\000\000\000^\000\000\000\000\000j\000\000\000_\002\164\000\000\000i\000`\003!\000k\000^\000\000\000\000\000\000\000\000\000_\000\000\000j\000\000\000`\002\164\000\000\000\000\000\000\002\172\000k\000\000\000\000\000\000\000\\\000\000\000\000\000i\000e\000\138\000\000\002\164\000\000\002\197\0038\000\000\000k\000\000\002\172\000i\000\000\000\000\000\000\000j\000\000\000\138\000\000\000\000\000\000\000\000\000m\000\000\002\199\000\000\000\139\000\\\000\000\000\000\000\140\000e\000\000\000\138\002\164\000\000\000o\000\000\000m\000k\000^\000\000\000\139\000\\\003@\000_\000\140\000e\000\000\000`\000\000\000\000\000o\000j\000m\000\000\000\000\000\000\000\139\000\000\000\000\000\000\000\140\000\\\000\138\000\\\000\000\000e\000o\000e\003\170\000^\002\164\000\000\000i\000\000\000_\000k\000\000\000j\000`\000\000\003\182\000\000\000\000\000m\000\000\000^\000\000\000\139\000\000\000j\000_\000\140\000\000\000\000\000`\000\000\002\164\000o\000\000\000\000\000\138\000k\000\000\000i\000\000\000^\000\000\000^\002\164\000\000\000_\000\000\000_\000k\000`\000\000\000`\000\000\000\000\000i\000\000\000m\000\000\000\000\000\000\000\139\000\138\000\000\000\000\000\140\000\000\000\000\000\000\000\000\000\000\000o\000\\\000\000\000\138\000i\000e\000i\000\000\003\188\000\000\000\000\000\000\000m\000\000\000-\000\000\000\139\000j\000\000\000\000\000\140\000\\\000\000\000\000\000m\000e\000o\000\000\000\139\000\211\000\000\000\238\000\140\000\000\005\015\000\000\002\164\000\000\000o\003\195\000\000\000k\000\000\000\000\000\000\000^\000\000\000\000\000j\000\\\000_\000\000\000\000\000e\000`\003\204\000\000\000\000\000\000\005\020\000\000\000\000\005v\000\000\000j\000^\000\138\002\164\001U\000\000\000_\000\000\000k\000^\000`\003\218\000\213\003\232\000\000\000i\000\214\000\000\001O\002\164\000j\000\000\000j\000m\000k\000\000\000\000\000\139\000\000\000^\000\000\000\140\000\\\000\138\000_\000i\000e\000o\000`\002\164\000\000\002\164\000\000\000\227\000k\000\000\000k\000\000\000\000\000\138\000\000\000\000\000\000\000\000\000m\000\000\000\000\000\000\000\139\000\000\000\000\000\000\000\140\000i\000\000\000\000\000\000\000\000\000o\000\138\000m\000\138\000\000\000\\\000\139\000\000\000^\000e\000\140\000\000\000\000\000_\000\000\000\000\000o\000`\003\239\000\000\000\000\000\000\000m\001@\000m\000\000\000\139\000j\000\139\000\000\000\140\000\000\000\140\000\000\000\000\001P\000o\000\000\000o\000\000\000\000\000\000\000i\000\000\000\000\000\000\002\164\000j\000\000\000^\000\000\000k\000\000\000\000\000_\000\228\000\000\000\000\000`\000\000\000\000\000\000\001[\000\000\003\178\000\000\005\028\001X\000\000\000\160\001Y\000k\000\166\000\000\000\000\000j\000\138\000\000\000\000\000\000\000\000\005\021\000\000\000i\000\000\000\000\000\\\000\000\000\000\000\000\000e\000\000\000\000\000\000\005\028\000\000\000\138\000m\000\\\000k\000\000\000\139\000e\001\000\000\000\000\140\000\000\000\000\000\000\000\000\000\000\000o\000\000\005\024\000\000\000\000\000\000\000m\000\000\000\000\000\000\000\139\000j\001\001\000\138\000\140\000\000\000\000\001\002\000\000\000^\000o\001\003\000\000\000\000\000_\000\000\001\004\000\000\000`\000\000\0010\000^\000\000\000\000\000m\000k\000_\000\000\000\139\000\\\000`\000\000\000\140\000e\000\000\000\000\000\000\000\000\000o\000\000\000\\\000\000\000j\000i\000e\000\000\000\000\000\000\000\000\000\000\000\138\000\000\000\\\000\000\000\000\000i\000e\000\000\000\000\000\000\000\000\000\175\000\000\000\000\000\000\000\000\000k\000\000\000\000\000\000\000\000\000m\000\000\000^\000\000\000\139\000\000\000\000\000_\000\140\000\000\000\000\000`\000\000\000^\000o\000\000\000\000\000\000\000_\000\000\000\138\000\000\000`\000\000\000\000\000^\000\000\000\000\000\000\000\000\000_\000\000\000\000\000\\\000`\000\000\000i\000e\000\000\000\000\000\211\000m\000\236\000\000\000\000\000\139\000\000\000i\000\000\000\140\000\\\000\000\000j\000\000\000e\000o\000\000\000\000\000\000\000i\000\000\000\000\000\000\000\000\000j\000\000\000\\\000\000\000\000\000\000\000e\000\190\000\000\000\000\000\000\000\000\000k\000^\000\000\000\000\000\000\000\000\000_\000\221\000^\000\000\000`\000\213\000k\000\000\000\000\000\214\000\000\000\000\000^\000\000\000\000\000\000\000\000\000_\000\000\000\138\000\000\000`\000\000\000\211\000\211\000\236\000\238\000\000\000^\000i\000\000\000\138\000\000\000_\000j\000\000\000\227\000`\000\000\000\000\000m\000\000\000\000\000\000\000\139\000j\000i\000\\\000\140\000\000\000\000\000e\000m\000\250\000o\000\000\000\139\000j\000k\000\000\000\140\000\000\000i\000\000\001\152\000\000\000o\000^\000^\000k\000\213\000\213\000\000\000\000\000\214\000\214\001\156\000\000\000\000\000\000\000\000\000k\000\000\000\138\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000^\000\000\000\000\000\138\000\\\000_\000\000\000\000\000e\000`\000\227\000\227\000\000\000m\000\000\000\138\000\000\000\139\000j\000\\\000\000\000\140\000\000\000e\000m\000\228\000\000\000o\000\139\000\000\000\000\000\000\000\140\000\000\000i\000j\000m\001\192\000o\000\000\000\139\000\000\000k\000\000\000\140\000\\\000\000\000\000\000^\000e\000o\000j\000\000\000_\001\255\000\000\000\000\000`\000\000\000k\000\000\000\000\000\\\000^\000\000\000\000\000e\000\138\000_\000\000\002\004\000\000\000`\000\000\000\000\000k\000\000\000\000\000\000\000\000\000\000\000\000\000i\000\000\000\138\000\000\000\000\000\000\000m\000^\000\228\000\228\000\139\001\001\000_\000\000\000\140\000i\000`\000\000\000\138\000\000\000o\000\000\000\000\000m\000^\001\020\000\000\000\139\000\000\000_\000\000\000\140\000j\000`\000\000\004;\000\000\000o\000\000\000m\000\000\000i\000\000\000\139\000\\\000\000\000\000\000\140\000e\000\000\000\000\002\008\000\000\000o\000\000\000\000\000k\001\000\000i\000\\\000\000\000\000\000\000\000e\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\\\000\000\000\000\000\000\000e\001\001\001\001\000\000\000\000\000j\000\138\001\002\000\000\000\000\000\000\001\003\000\000\000^\000\000\001\022\001\004\000\000\000_\000\000\000j\000\000\000`\000\000\002\031\000\000\000\000\000m\000^\000k\000\000\000\139\000\\\000_\000\000\000\140\000g\000`\000\000\002F\000^\000o\000\000\000\000\000k\000_\000j\000i\000\\\000`\000\000\000\000\000g\000\000\000\138\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000i\000j\000\000\002\135\000\000\000\000\000\000\000\138\000k\000\000\000\000\000\000\000i\000m\000^\000\000\000\000\000\139\000\000\000_\002\153\000\140\000\000\000`\000\000\000k\000\000\000o\000m\000\000\000^\000\000\000\139\000\138\000\\\000_\000\140\000\000\000g\000`\000\000\000\000\000o\000\000\000\000\000\000\000\000\000\\\000i\000\\\000\138\000g\000\000\000g\000m\000-\000\000\000\000\000\139\000\000\000\000\000\000\000\140\000\000\000i\000j\000\000\000\000\000o\000\\\000\000\000m\000\000\000q\000\000\000\139\000\000\000\000\000^\000\140\000j\000\000\000\000\000_\002\155\000o\000\000\000`\000\000\000k\000\000\000^\000j\000^\000\000\000\000\000_\000\000\000_\003\158\000`\000\000\000`\000\000\000k\000\000\000\000\000\000\000\000\001U\000\000\004\006\000i\000^\000\138\000\000\000k\000\000\000_\000\000\000\000\000\000\000`\001O\000\000\000i\000\000\000i\000j\000\138\000\000\000\000\000\000\000\000\000\000\000m\000\000\000\000\000\000\000\139\000\000\000\138\000\\\000\140\000j\000\000\000q\000i\000\000\000o\000m\000\000\000k\000\000\000\139\000\000\000\000\000\000\000\140\000\000\000\000\000\000\000m\000\000\000o\000\000\000\139\000\000\000k\000\\\000\140\000\000\000\000\000q\000\000\000\000\000o\000l\000\000\000\000\000\000\000\\\000\000\000\000\000\000\000q\000^\000\000\000\000\000\000\000\000\000_\000j\000l\000\000\000`\001@\000\000\000m\000\000\000\\\000\000\000\000\000\151\000q\000j\000\000\000j\001P\000\000\000\000\000\000\000o\000^\000m\000\000\000k\000\\\000_\000\240\000i\000q\000`\000\000\000\000\000^\000\000\000j\000o\000k\000_\000k\000\000\000\000\000`\001[\000\000\003\214\000\000\000\000\001X\000l\000\160\001Y\000^\000\166\000\000\000i\000\000\000_\000\000\000k\000\000\000`\000l\000\211\000l\000\236\000\000\000i\000\000\000^\000m\000\211\000\\\000\236\000_\000\242\000q\000\000\000`\000\211\000\000\000\236\000\000\000m\000o\000m\000i\000\\\001\207\000\\\001\209\000q\000\000\000q\000\000\000\000\000\000\000o\000\000\000o\000\000\000\000\000\\\000i\000\000\000m\000q\000^\000j\000\000\000\213\000\000\001\182\001\203\000\214\000^\000^\000\000\000\213\000v\000\\\000_\000\214\000^\000q\000`\000\213\000\000\000\000\000\000\000\214\000^\000k\000^\000\000\000j\000_\000\211\000_\000\236\000`\000\227\000`\001\182\001\203\000\000\000^\000j\000\000\000\227\000i\000_\000\000\000\000\000\000\000`\000^\000\227\001\184\000k\000\000\000\000\001\185\000\000\000^\000i\000j\000i\000\000\000_\000\000\000k\000\000\000`\000\000\000\000\001\182\001\203\000m\000\000\000i\000^\000\000\000j\000\213\000\000\000\000\000^\000\214\001\184\000k\000\000\000x\001\185\001\182\001\203\000\000\000\000\000i\000\000\000\000\000\000\001\182\001\203\000\000\000m\000\000\000k\000\000\000\000\000\000\000\000\001\182\001\203\000\000\000\227\000\000\000m\000\000\000z\000^\000\228\001\184\000\000\000\000\000\000\001\185\000\000\000\000\000\228\000j\000|\000\000\001\182\001\203\000\000\000m\000\228\000^\000\000\001\184\000\000\000\000\000\000\001\185\000j\000^\000j\001\184\000\000\000~\000\000\001\185\000m\000k\000\000\000^\001\198\001\184\000\000\000j\000\000\001\185\000\000\000\000\000\000\000\000\000\128\000\000\000k\001\199\000k\000\000\000\000\000\000\000\000\000\000\000^\000j\001\184\000\000\000\000\000\000\001\185\000k\000\000\000\000\000\000\001\198\001\001\000\000\000\000\000\000\000\000\000\000\000\228\000\000\001\001\000\000\000\000\000m\001\199\000k\001\024\000\000\001\001\000\000\000\000\000\000\000\000\000\000\001\030\000\000\000\000\000\130\000m\000\000\000m\000\000\001 \000\000\001\198\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\132\000m\000\142\000\000\000\000\001\199\000\000\000\000\001\215\000\000\001\198\000\000\000\000\000\000\000\000\000\144\000\000\000\000\001\198\000m\000\000\000\000\001\232\001\199\000\000\000\000\000\000\000\000\001\198\000\000\000\000\001\199\000\000\000\146\001\001\000\000\000\000\000\000\000\000\001\215\000\000\001\199\000\000\000\000\000\000\000\000\000\000\000\000\001\"\001\198\000\000\000\000\000\000\001\234\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\199\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\215\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\236\000\000\000\000\000\000\001\215\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\215\000\000\000\000\000\000\000\000\000\000\001\238\000\000\000\000\000\000\001\215\000\000\000\000\000\000\001\244\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\246\000\000\000\000\000\000\000\000\000\000\000\000\001\215\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\248"))
+    ((16, "\000\183\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\021\000\000\000\135\001\148\000\000\000\137\000Y\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004v\000\000\005z\000\137\000Y\000\000\000\000\000\000\000\000\000\000\000\000\t*\000\023\006B\000\000\000\000\000\000\0014\000\000\000_\000\000\000\000\000K\016\164\000\000\000\000\000L\000\000\000\014\000\000\011\168\021\006$\250%\222$\250\006\160&\152\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011Z%\222\000\000\000\000\013P\000\000\016\216\000\000\017\226\000\000\000\000\000\000\000\000\000\166\000\000\000\218\000\000\000\000\002\136\000\000\015\202\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\132\000\000\000\000\027t\000\000&\158\000\000/J\000\0001\192\000\0007\130\000\0007\142\000\0007\154\000\0008\030\000\0008>\000\000+\206\000\000(8\000\000\000\000\000\000\000\000\000\0008J\000\0008t\000\0008\132\000\000\019\144\000\000\000\000\0312\000\000\000[\000Y\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000N\0004\000\000\000\003\000\000\000\000%~\000\0002j\000\000\000\000\000\000\000\246\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\192\000\000\000\000\000\000\000\000\000\000\000\000\014\248&\152\000\000\020\004\000\000\0234\024\020\000\000\000\000\000\000\001,\000\000!\138\000\000\000\0002\136\000\000\000\000\000\000\001\194\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0006\222\000\0007T\000\000\000\000\000\000\000\000\000\209\000\000\000\0003\024\000\000\000\000\000\000\008\190\000\015\000\000\000\000\000\000\000\000\000\000\000\000\012\224\000\000\013f\000\000\023\230\000\000\028\210\000\000 \192\000\000!P\000\000!\196\000\000#|\000\000&X\000\000-d\000\000+\210\000\000\002\182\000\0002\206\000\0004(\000\0008\130\000\000\000\000\000\000\000\000\000\000\000#3d\000\000\001\194\000\000\000\000\000W\003\178\000\000\0038\000\000\000\000\000\000\000\016\000\000\000\000\000\000'\030\000\000\000\000\000\000\000\000\000\000'~\000\000\000\000\000\000\000\000\000\000\000\000\003\178\000\000\000\000\000\000\000,\000\000\000\000\000\000\000\234\000\000\000\000\007\212\000\137\000\000\000\000\002\004\004\220\000\000\000\000\000\000\000\000\000\000\003<\000\000\013`\000\000\014,\000\000\000\000\004.\000\000\000\000\000\000\000\000\000\000\000\000\015\190\000\000\000\000\000\000\003.\000\000\000\000\000\000\000\000\006l\024\180\000\000\002\228\000\000\000\000\000T\004\252\000\000\000\000\000\000\000\000\014\252\000\000\000\000\000\000\000\000\000\000\000\000\002\138\005N\000\000\008\210\000\000\000\000\000\000\003J\000\000\012z\0005\000\000\020\210\000\000\000\000\000\000\014\148\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0003\238\000\000\030\170\000\0004\016\000\000\000\000\0004\000\000\007b\000\000\003\208$6'\162\000\000\000\000\000\000\000\019\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\000'\162\000\000\011\198\000\000\012.\017\150\000\000\000\000\000\000\004\132\000\000\".\000\000\000\00042\000\000\000\000\000\000\005\190\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0007`\000\0007d\000\000\000\000\000\000\004\022\000\000\000\000\000\000\000\000\000\000\000\000\008\\\000\000\020\188\000\000%L\000\000*\004\000\000*\154\000\000,d\000\000,\238\000\000-N\000\000.\128\000\0000d\000\000,\154\000\000\000\152\000\0002\176\000\0008\176\000\0009\022\000\000(2\000\000\000\000\000\0004\154\000\000\000\000\000\000\000\007\000\0004\178\000\000\000\000\000\0005$\000\000\000\000\003\200\000\000\024\160\000`\000\132\000\000\002Z\000\000\013:\002\"\007\244\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0005H\000\000 \230%\194\005\202\000\000\000\000\000\000,\198\000\000,\222\000\000-^\000\000( )\006\002`\000\213\006`\000\000\000\000\000\000\000\157\000\000\000\000\004\012\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0005\140\000\000\000\000\000\000\000\000\000\000\"\250\000\000)\030\000\000\000\000\000\000\000\000\000\000\000\000\014\006\000\000\004\142\000\000\000\000\000\000\000\000\006v\003\024\000\000\029T\000\000\000\000\000\000\001\014\000\000\000\000-\130\003\168\000\000\0082-\128\000\000\000\000)\152\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016j)\152\000\000\018\022\000\000\018Z\023\240\000\000\000\000\000\000\006\138\000\000#B\000\000\000\0005\194\000\000\000\000\000\000\006\240\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000* \000\000\007\222\000\000\000\0005\216\000\0006@\000\000\000\000\003\018\t\178\000\000\000\000.,\000\000\000\000\000\000\006\242\000\000\020\020\000\000\000\000\025\178\000\000\000\000\000\000\008\128\000\000\011\132\000\000\019>\000\000\0252\000\000\031\018\000\000!n\000\0008\002\000\0008\138\000\00092\000\0009>\000\0009b\000\0009\128\000\0009\178\000\000\000\000\000\000\000\000\000\000\000\000\024\002\000\000\004\020\000\000\025x\"\004\000\000\025\142\000\000\000\000\000\000\000\000\000\000\000\000\"\236\000\000\000\000\000\000\000\000\000\000\000\000\002\\\000\000\000\000\000\000\000\000\000\000\000\000\004\254\000\000\000\000#,\000\000\000\000\000\000.N\000\000\000\000\000\180\000\000\000\000\000\000$l\000\000\000\000\000\000\000\000.l\000\000\000\000\000\000\000\000\000\204\002\178\000\000/\016\000\000\000\000\000\000\000\000\025X\002\234\000\000\026,\000\000\000\000\003^\000\000/(\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\150\000\000\000\000&\202\000\000\000\000\000\000/\210\000\000\000\000\005&\000\000\000\000\014\128\000\000\026\166\000\000\000\000#\208\000\000\000\000\000\000\000W\000\000\000\000)\138\000\000\000\000\000\000\000\000/\212\000\000\000\000\000\000\000\000\003t\008r\000\000/\244\000\000\000\000\000\000\000\000\000\000\000\000\015L\000\000\000\000\006X\000\000\015\222\000\000\000W\000\000\000\000\005,+P\000\000\006v\000\000\000\000\000\000\000\000\004\022\000\000*L\000\000\027&\004\128\027\232\000\000\004\252\000\000\016\148\000\000\017`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\150\028h\001j\028\232\000\000\000\000\000\000\006\240\000\000\017\218\000\000\006\194\000\000\000\000\000W\000\196\030*\000\000\001\240\000\000\018\164\030\164\000\000\000\000\019f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\216\008\170\000\000\007\140\000\000\000\000\000\000\000\000\006j\000\000\0200\000\000\000\000\000\000 \2246v\000\000\000\000\000\000 f\000\000\000\000\000\000\000\000\013\008\005\206\000\000\000\0000 \000\000\000\000\000\000\000\000\005\244\000\000\000\000)\176\000\000\000\000\000\0000\176\000\000\000\000\001\246\000\000\000\0000\216\000\000\000\000\005\228\006\236\000\000\000\0001z\000\000\000\000\007\154!F\000\000\007\022\000\000\000\0001\156\000\000\000\000\000\000\000\000\000\000\000\000\007>\000\000\000\0003|\000\000\000\000\000\0001\190\000\000\000\000\000\000\000\000\000\000#\230\000\000\000\000\000\000\004\200\000\000\000\000\000\0001\196\000\000\000\000\006\024\008\146\000\000\000\0002>\000\000\000\000\007\190\000\000\000\000\000\000\000\000\004\022\004\216\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\198\000\000\020\172\000\000\000\000\000\0006\150\000\000\tv\000\000\000\000\000\000\004\174\000\000\000\000\005\172\021v\000\000\022.\000\000\000\000\000\000\006\132\000\000\018J\0072\023>\000\000\025\166\000\000\000\000\000\000\007\194\000\000*d\007\200+8\000\000+\162\000\000\000\000\000\000\007\208\000\000\028|\007\248\000\000\000\000\021f\003^\008 \021\224\000\000'\198\000\000\000\000\000\000\008B\000\000\030\184\008V\000\000\000\000\000\000\001\132\000\000\000\000\000\000\000\000\000\000\001\178\000\000\000\000\002\154\000\000\000;\000\000\000\000\000\000\002\246\000\000\000\000\000\000\000\000\000/\000\000\006l\002\216\001\176\000\000\000\000\002\204\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002|\001\214\000\000\000\000\004\008\000\000\000\000\000\000\006F\000\000\000\000\012B\012\164\000\000\000\000\000\000\000\000\014\170\014\214\000\025\000\000\015\196\000\000\000\000\000\000\000\000\000\000\000\000\004L\000\000\000\000\002f\000\000\000\000\003\198\000\000\000\000\tX\000\000\000\000\000\004\000\000\007\220\004\194\000\170\000\000\000\000\0007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\226\018\240\000\000\000\000\000\000\000\000\013\222\000\000\000\000\018\150\000\000\000\000\000\000\018\252\000\000\000\000\002z\019(\000\162\000\000\020\180\000\000\000\000\000\000\000\000\000\000\000\000\006R\000\000\008l\002\236\000\022\000\000\000\000\000\000\000\000\006\202\000\000\000\000\000\000\000\000\000\000\000\000\0088\000\000\000\000\005\144\000\000\008\128\004\196\000\184\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\250\000\000\000\000\018\226\020\204\000\000\000\000\000\000\000\000\0024\000\000\002\246\000\000\011\128\000\000\000\000\000\000\000\000\000\000\000\000\000r\012P\000\000\000\000\012Z\000\000\000\000\000\000\000\000\000'\000\000\013\198\000\000\000\000\000\000\000\000\004\198\000\000\000\000\000\000\003\216\000\000\000\000\001\024\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\222\005\214\000\000\000\000\000\000\012\184\000\000\000\000\021\178\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003n\000\000\000\000\000\000\000\000\000\000\000!\005\156\000\137\006\014\t&\004\028\000\000\000\000\003|\005\008\007\240\008*\000\000\000\000\000\000\000\000\000\000\000\000\023\132\000\000\000\000\000\000\000\000\018\178\003|\031$\007f\000\000\000\000\008\228\000\000\023\002\000\000\000\000\008\156\000\000\000\000\000\000\007\172\000\000\004\194\000\000\007\162\014`\000\000\000\000\000\000\000\000\003<\000\000\004.\000\000\007\196\000\000\000\000\012L\000\000\000\000\000\000\000\000\t\240\000\000\000\000\003|\t\130\000\000\023\186\000\000\000W\004\186\000\000\000\000\000\000\000\000\000\000\000\143\000\000\000\000\000\000\000\000\000\0002T\008\176\000\000\003x\000\000\000\000\000\000\000\000\000\000\001\162\000\000\nl\007n\0118\000\000\003d\011\248\000\000\tr\000\000\003\222\000\000\004Z\000\000\005\160\000\000\000\000\000\000\000\000\000\000\008\222\000\000\006\028\000\000\t\128\000\000\006\150\000\000\000W\005\252\000\000\000#\000\000\006\002\005\022\000\000\001,\000\000\008\228\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\\\000\000\t~\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005`\005F\002p\006\136\000\000\006\190\000\000\000\000\008V\t\138\000\000\005\178\000\000\000\000\000\000\000\000\006\184\000\000\000\000\000\000\000\000\000\000\006\204\0080\t\"\006\236\007&\000\000\000\000\002L\000\000\000\000\000\000\000\000\007\250\000\000\000\000"), (16, "\001\175\001\198\005i\005j\002\\\000\n\0052\001\175\001\196\004J\002\008\002\t\0053\0006\000-\004M\004\144\002\238\0054\0056\003\007\000\017\004\177\000\199\000Y\000\222\004K\000\236\000n\000\t\004N\004Z\004K\004\142\000[\005\177\004N\004Z\002,\004\178\004\181\004Z\004\137\005\178\003\008\000\016\001\177\004t\004Z\0006\001\178\000[\000\005\001\177\000Y\005n\004\185\001\178\0011\004\135\001 \004\138\004Z\000\017\001\175\001\198\002.\000[\000[\000-\000\201\004\186\000-\000\\\000\202\000\008\000\t\000]\000-\002\008\002\t\000'\002T\003U\003=\001\026\0047\000-\005>\004[\002-\000\237\001\175\001\196\001\"\004[\004\196\000\227\000[\004[\000\215\000f\001i\000\\\000\151\000&\004[\000]\003\008\005?\001\177\0014\005\022\004\197\001\178\000\165\004\200\004Z\002-\001\028\004[\001\136\0007\000'\000\239\000Y\0007\003\250\004\141\000b\003*\000f\000-\003v\002C\004\141\000[\002\\\001\177\000-\004\171\004Z\001\178\0006\001\191\004\142\004\233\001\128\000\167\002H\002\238\001\191\004\142\002I\0019\003\015\005A\001\192\001m\003\132\001\138\001\203\002\251\001\021\001\192\005B\005\\\005\200\0017\000[\005]\001:\003/\004\002\000\\\004[\004\236\0006\000]\004\187\000\216\000g\002\\\0006\000-\0003\002M\0002\000\237\0033\003\030\005_\001,\003\128\004\\\0006\002\011\003#\002C\004[\000\157\005a\000f\0035\001\207\000h\000\230\004\246\001\191\000\166\0006\000g\000\166\002H\0004\0015\003i\002I\0019\003\015\005\165\001\192\003\134\003c\001\208\001\175\001\198\000\149\000\240\001\209\003\016\001\197\000-\001\210\003Q\000h\001\191\005x\001\211\000-\000\199\004\190\000\220\0054\005y\003\007\005\002\005\003\000\241\001\192\002M\001%\000_\000\242\003>\000\157\003]\000\243\000\157\0007\004Q\003#\000\244\002\239\000\157\003t\005\007\0035\001\207\003\008\004\004\001\177\000\166\000\157\004\228\001\178\000\163\004b\004`\000\149\005\139\004\239\000g\003v\000[\0006\0007\000\201\001\208\001\175\001\198\000\202\000\176\001\209\004c\004Z\001\235\001\210\000\152\000\153\000\155\000\156\001\211\000-\0007\002\244\000h\002T\003U\003=\004<\002\238\000-\004\145\002\008\002\t\001\208\000\215\000\157\000\204\004\203\004\196\002\248\005\022\0019\000\157\000\162\001\026\000\163\005\140\001\211\000\135\001>\003\008\004R\001\177\001;\000-\004\197\001\178\000Y\004\200\004Z\003y\000d\005\208\004=\001b\000-\002\220\002]\005\172\000j\004[\005\209\004\128\000\136\003k\004\177\002C\000\137\001\027\0006\000\199\0006\000\220\000l\002\222\000\168\001\191\000\157\001e\000\149\001h\002H\004\178\004\181\004Z\002I\0019\003\015\005\142\001\192\000Y\000[\003d\001\203\000b\001\021\000\\\005B\005\\\002\\\000]\000\213\005\144\005\008\000\216\003\004\004\231\004[\004\225\004T\001\\\003\249\0006\004\195\000[\003\005\002v\000\201\002M\002\143\004C\000\202\003\030\005\146\000f\000\157\001u\0007\000\163\003#\002C\002\239\000\157\005\148\000[\0035\001\207\0006\002\n\000\\\001\191\004\186\004[\000]\004\241\002H\004H\000\215\005\186\002I\0019\003\015\004U\001\192\004>\003f\001\208\001\175\001\198\000\149\002B\001\209\003\016\000[\002x\001\210\003Q\000f\002y\004f\001\211\000-\000\221\003\178\001z\0054\005~\003=\0007\000-\002/\0006\002M\004R\000\149\002\\\003>\005(\003]\004W\001|\002v\000\017\003#\002\143\000\149\000\157\003t\0006\0035\001\207\003\008\001]\001\177\000g\000\157\004\228\001\178\000\163\0036\000-\001\175\001\245\004\229\0022\0023\0025\005\136\001\175\001\198\001\208\0007\001 \005r\002\221\001\209\005s\000\216\000h\001\210\000\157\004~\000-\000\163\001\211\002B\0054\005~\003=\002x\003\244\000\157\004\228\002y\000\163\002v\0007\000g\002\143\004\192\004\210\005\024\000'\000i\005\025\000[\001!\001\177\005\199\001^\002\134\001\178\003\008\002\210\001\177\004e\005\021\002\252\001\178\002\162\001}\000h\005\029\002\135\000j\001\012\002V\005w\005\131\000\146\001\175\001\198\004c\004Z\003\000\0006\001|\000-\000l\002B\001W\002C\001f\002x\000-\000\241\000\135\002y\0054\005~\003=\001\191\0006\002\008\002\t\004}\002H\0007\000-\000\244\002I\0019\003\015\005\132\001\192\004\253\004\254\000j\003W\000\166\003\247\000\136\005B\005\\\003\008\000\137\001\177\002K\0016\005\022\001\178\000l\001\026\005,\005\022\002\134\002\194\002\215\002\197\004\131\005\133\004[\002\165\002M\002\162\0006\000-\003>\002\135\005\134\000\149\001]\002C\003\t\003#\001\191\002\166\000\157\003(\000-\0035\001\207\001\191\001\175\001\195\000\157\001\206\002H\001\192\002\200\003\013\002I\0019\003\015\005\132\001\192\004\147\004\205\004\249\002\238\003W\001\208\005#\005B\005\\\005(\001\209\002\238\002K\002\134\001\210\003\029\002\201\001\021\002/\001\211\000\157\001\031\002\162\000\163\005S\003\005\002\135\005g\002M\0006\0006\000[\003>\001\177\005\134\001S\001G\001\178\002C\003#\000-\002\165\000\157\003(\002P\0035\001\207\002\203\001\191\003\245\001H\000\149\0021\002H\001 \002\166\0015\002I\0019\003\015\005\132\001\192\000-\000/\001s\0002\001\208\001\175\001\198\005B\005\\\001\209\000\149\003\247\002K\001\210\004>\004\005\001\180\000-\001\211\000-\004\199\005!\003_\0054\005~\003=\001\"\002\209\002M\003L\0004\004\251\003>\002\165\005\134\000\157\004~\004\197\000\163\003#\004\200\004Z\000\157\003(\0006\0035\001\207\002\166\0019\003\008\0007\001\177\004\129\000-\003*\001\178\000\157\001\029\0007\000\163\005K\0019\003*\003N\0006\005\135\001\208\001\175\001\198\001\191\0006\001\209\0006\001I\000-\001\210\0007\0007\005!\000-\001\211\000-\001\192\003\184\003Z\0054\005~\003=\005V\005\150\005W\0006\005N\005+\000\157\005O\003\222\000\163\005\154\004[\000-\000/\0000\0002\003\222\001Q\003C\000\157\001R\003\228\000\163\003\008\004\004\001\177\004b\003\143\003\005\001\178\000\149\004\180\005\173\000-\001j\002\227\001c\003\005\000-\005\143\001\175\001\198\0004\004c\004Z\000\199\004\012\000\222\004\178\004\181\004Z\002C\0019\005\179\000-\005\019\005\180\0006\0054\005~\003=\001\191\004\014\0004\001;\0007\002H\005\185\002[\005\"\002I\0019\003\015\005\132\001\192\001b\000\157\001w\0006\000\163\005.\005%\005B\005\\\003\008\001\189\001\177\002K\004X\000[\001\178\002\028\000\201\0007\005\184\004\189\000\202\005\194\000\157\001e\005\147\001h\004[\002M\003i\000\166\003L\003>\004[\005\134\004\186\003\019\0007\002C\003#\000\157\005\020\000\157\003(\000\227\0035\001\207\000\215\001\191\004Y\003q\005\"\0006\002H\0006\0006\000\166\002I\0019\003\015\005\132\001\192\005-\005%\003\160\003M\001\208\001\175\001\198\005B\005\\\001\209\003q\0006\002K\001\210\000\157\0019\0058\004\015\001\211\000-\003\137\003\168\003s\002T\003U\003=\003\005\001;\002M\002+\005{\0006\003>\004\014\005\134\000\157\0019\002C\001b\003#\000\157\0019\000\157\003(\003r\0035\001\207\001\191\001;\003\008\002{\001\177\002H\002\224\003\139\001\178\002I\0019\003\015\005\132\001\192\000\157\001e\005\196\001h\000\216\001\208\002v\005B\005\\\002\143\001\209\005\137\002K\004i\001\210\000-\000\228\001\175\001\198\001\211\004\187\000\157\001e\001l\001h\000[\000\157\002\236\002M\002\250\000\230\000-\003>\005(\005\134\002T\003U\003=\0007\003#\002\132\002\159\000\157\003(\004\022\0035\001\207\003n\002v\003\137\000[\002\139\000\240\005\201\002x\003\234\005\204\005\205\002y\0007\004\024\003\008\005(\001\177\005\213\000\000\001\208\001\178\001N\001\175\001\196\001\209\000\241\003\234\004\196\001\210\004\148\000\242\002C\0007\001\211\000\243\001H\003\138\003\185\000\000\000\244\002v\001\191\003\236\002\143\004\197\000[\002H\004\200\004Z\002x\002I\0019\003\015\002y\001\192\003\253\003c\000\000\003\194\005P\003\235\001\175\001\198\003\016\002\\\004\149\000[\002K\001\177\004\025\004 \000\199\001\178\000\222\004#\000-\005R\0006\003\204\002T\003U\003=\000\000\002M\000[\004\024\004\"\003>\002x\003]\004\"\005D\002y\0006\003#\000-\004&\000\157\003(\005;\0035\001\207\004\193\002\134\002C\003\008\004[\001\177\0019\003\005\004\206\001\178\004\024\005\202\001\191\000[\002\135\004/\000\201\002H\001I\001\208\000\202\002I\0019\003\015\001\209\001\192\003a\003c\001\210\005\189\005*\0041\0042\001\211\003\016\000-\004\194\000-\002K\005!\001q\0045\005\165\002\134\004\207\001T\000\215\001_\0041\005Q\001Q\000\000\000\157\001R\002M\000\163\002\135\004\024\003>\005)\003]\001\175\001\198\005@\001\191\003#\005Q\0004\000\157\003(\004\134\0035\001\207\005p\000\000\000-\005^\001\192\005{\002T\003U\003=\002\134\002\144\0007\005{\003\005\004\135\000\000\004\138\004Z\002v\001\208\002C\002\143\002\135\005\141\001\209\005\188\005\198\0007\001\210\005\165\001\191\000\000\003\008\001\211\001\177\002H\000\000\004\208\001\178\002I\0019\003\015\004\142\001\192\003\136\003c\005\165\005\129\005\199\001\175\001\198\005\020\003\016\000\216\005\145\000\000\002K\0037\005\203\000\000\000\149\005\020\002B\000-\000\000\000\000\002x\002T\003U\003=\002y\001\208\002M\003\229\003;\004[\003>\004\196\003]\000\238\000\000\000\000\000\000\003#\005\020\001\213\000\157\003(\000\000\0035\001\207\002\165\000\000\003\008\004\197\001\177\000\000\004\200\004Z\001\178\005\166\000\240\005\"\000\000\0019\002\168\000\157\001y\000\000\000\163\001\208\001\175\001\198\005$\005%\001\209\001;\000\000\000\000\001\210\000\000\000\241\002C\000Y\001\211\000-\000\242\000n\005\198\0054\000\243\003\007\001\191\000\000\000\000\000\244\000\000\002H\000\000\000\000\000\000\002I\0019\003\015\000\000\001\192\004\001\003c\000\157\000\000\000\157\001e\000\000\001h\003\016\003\008\004[\001\177\002K\000\000\005\168\001\178\002\134\002\194\002\195\002\197\000\000\000[\000\000\000\000\000\000\002\162\000\\\005\138\002M\002\135\000]\005\170\003>\000\000\003]\000\000\004\150\002C\000\000\003#\000\000\000\000\000\157\003(\000\000\0035\001\207\001\191\000\000\000\000\002\200\000\000\002H\000\000\000f\000\000\002I\0019\003\015\000\000\001\192\005Z\003c\000\000\000\000\000\000\001\208\001\175\001\198\003\016\000\000\001\209\000\000\002K\000\000\001\210\000\000\000\000\000\000\000\000\001\211\000-\000\000\000\000\000Y\0054\000\000\003\007\000\182\002M\000\000\000\000\000\000\003>\000\000\003]\000\000\000\000\002\165\002C\003#\000\000\000\000\000\157\003(\002v\0035\001\207\002\143\001\191\000\000\003\008\002\166\001\177\002H\000\000\004\213\001\178\002I\0019\003\015\005}\001\192\000\199\000\000\001+\004\196\001\208\000[\005|\005B\005\\\001\209\000\\\000g\005\128\001\210\000]\001\175\001\194\000\000\001\211\000\000\004\197\000\000\000\000\004\200\004Z\000\000\000[\000\000\002M\000\000\002x\000\000\003\030\005\130\002y\000h\000\000\000\000\000f\003#\001\175\001\198\000\157\003(\000[\0035\001\207\000\201\000\000\000\000\000\000\000\202\000\000\004\134\000-\000\000\000\000\000\000\0054\000[\003\007\001\177\000\000\000\000\000\000\001\178\001\208\001\175\001\193\000\000\004\135\001\209\004\138\004Z\000\000\001\210\000\000\000\215\002C\000\000\001\211\000j\004[\000\000\003\008\000\000\001\177\000\000\001\191\000\000\001\178\000\000\000\000\002H\000\000\000o\000-\002I\0019\003\015\005}\001\192\005\127\004b\000\000\001\175\001\198\004\196\000\000\005B\005\\\000[\004\196\001\177\005\128\000\000\000\000\001\178\000g\000-\004c\004Z\000\000\002T\004\197\003\007\002\134\004\200\004Z\004\197\002M\004[\004\200\004Z\003\030\005\130\000\199\000\000\000\222\002\135\000\000\003#\000h\000\000\000\157\003(\000\000\0035\001\207\003\008\005S\001\177\004b\000\000\000\000\001\178\000\199\000\216\000\220\001\191\000\000\000\000\000\000\000\000\000\000\000\000\005\013\000\000\001\208\004c\004Z\000\000\001\192\001\209\002C\000\000\000\000\001\210\000\000\004[\000[\004\007\001\211\000\201\001\191\003\131\004[\000\202\004\226\002H\000-\004[\000\000\002I\0019\003\015\005}\001\192\000\000\000\000\000[\001\175\001\198\000\201\000\000\005B\005\\\000\202\002\165\000\000\005\128\001\191\000Y\000\215\000\000\000-\000\179\000\000\000\000\002T\003\159\003\007\002\170\000\199\001\192\000\220\002M\000\000\004[\000\000\003\030\005\130\000\000\000\215\000-\000\000\0019\003#\004\156\002C\000\157\003(\000\000\0035\001\207\003\008\000\000\001\177\005K\001\191\000\000\001\178\000\000\000\000\002H\000\000\000[\000\000\002I\0019\003\015\000\\\001\192\000\000\001\208\000]\000\000\000[\000\000\001\209\000\201\003\016\000\000\001\210\000\202\003x\005U\003\129\001\211\000\000\005N\003\131\000\157\005O\000\000\000\163\000\000\001N\004o\000f\000\000\002M\004\234\000\216\004\196\003\030\003z\004\237\000\000\000\000\000\215\001H\003#\001\175\001\198\000\157\003(\004\134\0035\001\207\002R\004\197\000\000\000\216\004\200\004Z\000\000\000-\000\000\005\014\000\000\002T\003\002\003\007\004\135\000\000\004\138\004Z\000\000\001\208\0019\000\000\000\000\000\000\001\209\002C\000-\004m\001\210\000\000\000\000\000\240\003\165\001\211\000\000\001\191\000\000\003\008\000\000\001\177\002H\005\017\000\000\001\178\002I\0019\003\015\000\000\001\192\000\000\000\000\000\241\000-\000\000\001\175\001\198\000\242\003\016\000\000\000g\000\243\003x\003 \004[\0019\000\244\000\157\003\177\000-\003\183\000\216\000\241\002T\003!\003=\004[\001I\002M\000-\001N\000\000\003\030\003z\000h\000\000\000\246\000\000\000\000\003#\000\000\000\000\000\157\003(\001H\0035\001\207\000\000\000\000\003\008\000\000\001\177\004b\000\000\001T\001\178\001U\005J\000\000\001Q\000\000\000\157\001R\000\000\000\163\000\199\001\208\000\219\000\000\004c\004Z\001\209\000\000\000\000\004b\001\210\000\000\000\000\002C\000\000\001\211\000-\000/\001o\0002\000\000\000\000\000\000\001\191\000\241\000\000\004c\004Z\002H\000\000\000\000\000\000\002I\0019\003\015\000\000\001\192\000\000\000\248\000\000\000\000\000\000\001\175\001\198\000[\003\016\0004\000\201\000\000\003B\003@\000\202\0019\000\000\000\000\004\244\000-\000\000\000\000\000\000\002T\003!\003=\004[\001I\002M\000\000\000\000\004\159\003\030\003D\000\000\000\000\000\000\002C\000\000\003#\000\215\0019\000\157\003F\000\000\0035\001\207\001\191\004[\003\008\000\000\001\177\002H\005K\001P\001\178\002I\0019\003\015\001Q\001\192\000\157\001R\000\000\000\163\000\000\001\208\000\149\000Y\003\016\000\000\001\209\000d\002K\000\000\001\210\000-\000\000\001\175\001\198\001\211\000\000\000\000\000\000\000\000\005N\003E\000\157\005O\002M\000\163\004b\000-\003>\000\000\003?\002T\003!\003=\000\000\003#\000\000\000\000\000\157\003(\000\000\0035\001\207\004c\004Z\000\000\000\000\000[\000\157\001\134\000\000\000\163\000\\\000\000\0019\000\216\000]\003\008\000\000\001\177\000\000\000\000\001\208\001\178\001N\000\000\001;\001\209\000\000\000\000\004z\001\210\000\000\000\000\002C\000\000\001\211\001b\001H\000\000\000f\000\000\000\000\002v\001\191\000\000\002\138\000\000\000\000\002H\000\000\000\000\004x\002I\0019\003\015\000\000\001\192\000\000\000\000\000\157\001e\004[\001h\001\175\001\198\003\016\000\000\000\000\000\000\002K\000\000\000Y\000\000\000\000\000\000\000b\000\000\000-\000\000\000\000\000\000\002T\003U\003=\000\000\002M\000[\000\000\000\000\003>\002x\003?\000\000\000\000\002y\000\000\003#\000Y\000\000\000\157\003(\000\178\0035\001\207\000\000\000\000\002C\003\008\000\000\001\177\0019\000\000\000\000\001\178\000\000\000[\001\191\000\000\000\000\000g\000\\\002H\001I\001\208\000]\002I\0019\003\015\001\209\001\192\000\000\000\000\001\210\000\000\0012\000\000\000\000\001\211\003\016\000\000\000\000\000[\002K\000h\000\000\000\000\000\\\000\000\000f\001T\000]\001Z\000\000\000\000\001Q\000\000\000\157\001R\002M\000\163\000\000\000\000\003>\000\000\003?\001\175\001\198\000\000\000i\003#\004v\000\000\000\157\003(\000f\0035\001\207\000\000\000\000\000-\000\000\000\000\000\000\002T\003U\003=\002\134\000\000\000\000\000j\000\000\000\000\001\175\001\176\000k\000\000\001\208\002C\000\000\002\135\000\000\001\209\000\000\000l\000\000\001\210\000\000\001\191\000\000\003\008\001\211\001\177\002H\000\000\000\000\001\178\002I\0019\003\015\000\000\001\192\000\000\003\\\000\000\000\000\000\000\001\175\001\198\000g\003\016\000Y\000\000\000\000\002K\000Z\000\000\000[\000\000\001\177\000\000\000-\000\000\001\178\000\000\002T\003U\003=\000\134\000\000\002M\000\000\000\000\000h\003>\000g\003]\002v\000\000\000\000\002\137\003#\000\000\000\000\000\157\003(\000\000\0035\001\207\000\000\000\000\003\008\000\000\001\177\000\000\000[\000\000\001\178\000\135\000h\000\\\000\000\000\000\000\199\000]\000\222\000\000\000\000\001\208\000\000\000\000\002v\000\000\001\209\002\136\000\000\000\000\001\210\000\000\000j\002C\000[\001\211\000\136\000\000\002x\000\000\000\137\000f\002y\001\191\000\000\000\000\000l\000\000\002H\000\000\000\000\000\000\002I\0019\003\015\000\000\001\192\000\000\003^\000\000\000[\001\175\001\198\000\201\000\000\003\016\000\000\000\202\000[\002K\001\191\000\000\002x\000\000\000\000\000-\002y\000\000\004\134\002T\003{\003=\000-\001\192\000\000\002M\005!\000\000\000\000\003>\000\000\003]\000\000\000\215\002C\004\135\003#\004\138\004Z\000\157\003(\000\000\0035\001\207\001\191\003\008\000\000\001\177\000\000\002H\000\000\001\178\002[\002I\0019\003\015\004\134\001\192\000\000\003p\000\000\000g\000\000\001\208\000\000\004b\003\016\000\000\001\209\000\000\002K\004b\001\210\004\135\002\134\004\138\004Z\001\211\002v\003}\000\000\002\143\004c\004Z\000\000\000h\002M\002\135\004c\004Z\003>\000\000\003]\004b\000\000\000\000\004[\003#\001\175\001\198\000\157\003(\000\000\0035\001\207\000\000\000\000\000\000\002\134\000\000\004c\004Z\000-\000\216\000\000\000\000\002T\003{\003=\000Y\000\000\002\135\000[\000d\001\208\000\000\002x\000\000\000\000\001\209\002y\000\000\000\000\001\210\004[\002C\000\000\000\000\001\211\004\017\000\000\004[\003\008\000\000\001\177\001\191\000\000\004[\001\178\000\000\002H\000\000\000\000\000\000\002I\0019\003\015\000\000\001\192\000\000\000\000\000\240\0019\000[\000\000\000\000\000\000\003\016\000\\\004[\000\000\002K\000]\005$\0055\000\000\003\127\000\199\000\000\000\218\000\000\000\241\000\000\000\000\000\000\002v\000\242\002M\002\143\000\000\000\243\003>\000\000\003~\000\000\000\244\000f\000\000\003#\001\175\001\198\000\157\003(\004\162\0035\001\207\000\000\003\145\000\157\002\236\000\000\002\250\000\000\000-\000\000\000\000\000\000\002T\003!\003=\000\000\000[\002\134\000\000\000\201\001\208\000\000\000\000\000\202\002B\001\209\000\000\002C\002x\001\210\002\135\000\000\002y\000\000\001\211\000\000\004\219\001\191\003\008\000\000\001\177\000\000\002H\000\000\001\178\004\154\002I\0019\003\015\000\215\001\192\004\166\000\000\000\000\000\000\000\000\001\175\001\198\000\000\003\016\000\000\000\000\000\000\002K\001\175\001\196\000\000\000\000\000\000\000\000\000-\000g\000\000\004\175\002T\000\000\003\007\000\000\000\000\002M\000\000\000\000\000\000\003>\000\000\003~\004b\000\000\000\000\000-\003#\000\000\000\000\000\157\003(\000h\0035\001\207\004b\002\165\003\008\000Y\001\177\004c\004Z\000b\001\178\000\000\000[\000\000\001\177\000\000\000\000\002\172\001\178\004c\004Z\001\208\000\000\000\000\000i\000\000\001\209\000\000\002\134\000\000\001\210\002\161\002C\000\216\000\000\001\211\003\251\002\162\000\000\000\000\003\131\002\135\001\191\000\000\000\000\000j\001N\002H\000\000\000[\000\145\002I\0019\003\015\000\\\001\192\000\000\000\000\000]\000l\001H\001\175\001\198\000\000\003\016\000\000\004[\000-\002K\000\000\000\000\002T\000\000\000\000\000\000\000-\000\000\000\000\004[\002T\000\000\003\007\000f\000\000\002M\000\000\000\000\000\000\003>\000\000\003?\000\199\000\000\000\222\002C\003#\000\000\004)\000\157\003(\000\000\0035\001\207\001&\001\191\003\008\000\000\001\177\000\000\002H\002\165\001\178\001\191\002I\0019\003\015\000\000\001\192\000\000\000\000\000\000\005\016\001\208\000\000\002\166\001\192\003\016\001\209\000-\000\000\003x\001\210\002T\0019\000\000\000[\001\211\004\t\000\201\000\000\000\000\003\131\000\202\000\000\000\000\001I\002M\000\000\000\000\000\000\003\030\003z\000\000\001\175\001\198\000\000\000\000\003#\004)\000\000\000\157\003(\000g\0035\001\207\000\000\000\000\000-\000\215\000\000\000\000\002T\001T\003\007\001\130\004\173\000\000\001Q\000\000\000\157\001R\001\023\000\163\000\000\001\208\000\000\000h\004\217\000\000\001\209\000\000\000\000\001\208\001\210\000\000\002C\000\000\003\008\001\211\001\177\000\000\000\000\000\000\001\178\000\000\001\191\001\215\0019\003\015\000\000\002H\000\135\000\000\000\000\002I\0019\003\015\000\000\001\192\003\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\016\000\000\004\011\000\000\003x\000j\003\131\000\000\000\000\000\136\000\000\000\000\000\000\000\137\000\000\000\000\004*\000\000\000\000\000l\002M\000\216\000\000\003#\003\030\003z\000\157\003(\000\000\0035\000\000\003#\001\175\001\198\000\157\003(\000\000\0035\001\207\000\000\005=\0019\003\015\000\000\000\000\000\000\000-\005\014\000\000\000\000\002T\003!\003=\003\016\000\000\000\000\000\000\000\199\001\208\000\217\002C\000\000\000\199\001\209\000\222\000\000\000\000\001\210\000\000\000\240\001\191\000\000\001\211\000\000\000\000\002H\003\008\004,\001\177\002I\0019\003\015\001\178\001\192\003#\000\000\000\000\000\157\003(\000\241\0035\000\000\003\016\000\000\000\242\000\000\003x\002v\000\243\000\000\002\143\000[\000\000\000\244\000\201\000\000\000[\000\000\000\202\000\201\000\000\000\000\002M\000\202\000\000\000\000\003\030\003z\000\000\000\000\000\000\000\000\000\000\003#\001\175\001\198\000\157\003(\000\000\0035\001\207\000\000\005`\000\000\000\215\000\000\000\000\000\000\000-\000\215\000\000\002B\002T\003!\003=\002x\000\199\000\000\000\220\002y\001\208\002v\000\000\000\000\002w\001\209\000\000\000\000\000\000\001\210\002v\000\000\000\000\002\143\001\211\000\000\002C\000\000\003\008\000\199\001\177\000\200\000\000\000\000\001\178\000\000\001\191\000\000\000\000\000\000\000\000\002H\000\000\000\000\000\000\002I\0019\003\015\000\000\001\192\000[\000\000\000\000\000\201\000\000\000[\000\000\000\202\003\016\002x\000\000\000\000\002K\002y\002B\000\000\000\000\000\000\002x\000\000\000\000\000\000\002y\000[\000\216\000\000\000\201\000\000\002M\000\216\000\202\000\000\003>\000\215\003?\000\000\000\000\000\000\000\000\003#\000\000\000\000\000\157\003(\000\000\0035\001\207\000\000\003\140\001\175\001\198\002\134\002\194\0050\002\197\004\019\000\215\000\000\000\000\000\000\002\162\000\000\000\000\000-\002\135\000\000\001\208\002T\002C\003=\000\000\001\209\000\000\000-\001d\001\210\0002\000\240\001\191\000\000\001\211\000\000\000\000\002H\000\000\002\200\000\000\002I\0019\003\015\000\000\001\192\000\000\003\008\000\000\001\177\000\000\000\241\000\000\001\178\003\016\000\000\000\242\0004\002K\002\134\000\243\000\000\000\000\000\000\000\000\000\244\000\000\000\216\002\134\002\199\000\000\002\197\002\135\000\000\002M\000\000\002v\002\162\003>\002\143\003?\002\135\000\000\000\000\000\000\003#\000\000\002\165\000\157\003(\000\216\0035\001\207\000\000\000\000\001\175\001\198\000\000\000\000\000\000\000\000\002\166\002\200\000\000\000\000\000\000\003A\000\000\000\000\000-\000\000\002v\001\208\002T\002\143\003\007\000\000\001\209\000\000\000\000\000[\001\210\002v\000\000\002x\002\143\001\211\000\000\002y\000\000\000\000\000\000\000\000\000\000\000\199\000\241\000\222\002C\000\000\003\008\002v\001\177\000\000\002\143\000\000\001\178\000\000\001\191\000\000\000\250\002\165\000\000\002H\000\000\000\000\002B\002I\0019\003\015\002x\001\192\000\000\000\000\002y\002\166\000\000\002B\0019\000\000\003\016\002x\000\000\000\000\003\142\002y\000\000\000\000\000\000\000[\001;\000\000\000\201\000\000\000\000\002B\000\202\000\000\000\000\002x\002M\001b\000\000\002y\003>\000\000\003\144\000\000\000\000\000\000\000\000\003#\001\175\001\198\000\157\003(\000\000\0035\001\207\000\000\000\000\000\000\000\215\003\006\000\157\001e\000-\001h\000\000\000\000\002T\002\134\003\007\000\000\000\000\000\000\000\000\000\000\001\208\000\000\002C\000\000\000\000\001\209\002\135\000\000\000\000\001\210\000\000\000\000\001\191\000\000\001\211\000\000\000\000\002H\003\008\000\000\001\177\002I\0019\003\015\001\178\001\192\000\000\000\000\002\134\000\000\000\000\002\201\000\000\000\000\003\016\001\175\001\198\002\162\003\028\002\134\000\000\002\135\002\201\000\000\000\000\000\000\003\"\000\000\002\162\000-\000\000\000\000\002\135\002T\002M\003\007\000\000\002\134\003\030\003\031\002\164\000\000\002\203\000\000\000\216\003#\002\162\000\000\000\157\003(\002\135\0035\001\207\002\203\000\000\002\165\000\000\000\000\000\000\003\008\000\000\001\177\000\000\000\000\000\000\001\178\000\000\000\000\000\000\002\174\004\021\000\000\001\208\000\000\000\000\000\000\000\000\001\209\000\000\001\175\001\198\001\210\000\000\000\000\002\208\000\000\001\211\000\000\002C\000\000\002\165\000\000\000\240\000-\000\000\002\206\000\000\002T\001\191\003\007\000\000\002\165\000\000\002H\002\166\000\000\000\000\002I\0019\003\015\000\000\001\192\000\241\000\000\000\000\002\166\000\000\000\242\000Y\002\165\003\016\000\243\000n\003\008\003\028\001\177\000\244\000\000\000\000\001\178\000\000\000\000\000\000\002\166\000\000\000\000\000\000\000\000\000\000\000\000\002M\000\000\000\000\000\000\003\030\003\031\000\000\000\000\000\000\002C\000\000\003#\000\000\000\000\000\157\003(\000\000\0035\001\207\001\191\000\000\000\000\000[\000\000\002H\000\000\000\000\000\\\002I\0019\003\015\000]\001\192\000\000\000\000\000\000\001\175\001\198\001\208\000\000\000\000\003\016\000\000\001\209\000\000\003\028\000\000\001\210\000\000\000\000\000-\000\000\001\211\000\000\002T\000f\003\007\000\000\000\000\000\000\000\000\002M\000\000\000\000\000\000\003\030\003\031\000\000\000\000\000\000\000\000\000\000\003#\002C\000\000\000\157\003(\000\000\0035\001\207\003\008\000\000\001\177\001\191\000\000\000\000\001\178\000\000\002H\000\000\000\000\000\000\002I\0019\003\015\000\000\001\192\000\000\000\000\001\208\001\175\001\198\003`\000\000\001\209\003\016\000\000\000\000\001\210\003Y\000\199\000\000\000\222\001\211\000-\000\000\000\000\000\000\002T\000\000\003\007\000\000\000\000\000\000\000\000\002M\000\000\000\000\000\000\003\030\003[\000\000\000\000\000\000\000\000\000g\003#\000\000\000\000\000\157\003(\000\000\0035\001\207\003\008\000\000\001\177\000\000\000\000\000\000\001\178\000\000\000\000\000\199\000[\000\220\000\000\000\201\000\000\000h\000\000\000\202\000\000\001\208\001\175\001\198\000\000\000\000\001\209\000\000\002C\000\000\001\210\000\000\000\000\000\000\000\000\001\211\000-\000\000\001\191\000\000\002T\000\000\003\007\002H\000\000\000\215\000\000\002I\0019\003\015\000\000\001\192\000\000\000\000\000\000\000[\000\000\003X\000\201\000\000\003\016\000\000\000\202\000j\003Y\000\000\003\008\000\000\001\177\000\000\000\000\000\000\001\178\000\000\000\000\000\000\000\000\000q\000\000\000\000\002M\000\000\000\000\000\000\003\030\003[\000\000\000\000\000\215\000\000\000-\003#\002C\000\000\000\157\003(\000\000\0035\001\207\000\000\000\000\000\000\001\191\000\000\000\000\000\000\000\000\002H\000\000\000\000\000\000\002I\0019\003\015\000\000\001\192\000\000\000\000\001\208\000\000\003l\000\000\000\000\001\209\003\016\000\216\000\000\001\210\003m\000\000\000\000\000\000\001\211\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001N\002M\000\000\000\000\000\000\003\030\003o\000\000\004%\000\000\000\000\000\000\003#\002C\001H\000\157\003(\000\000\0035\001\207\000\000\000\000\000\000\001\191\000\000\000\216\000\000\000\000\002H\000\000\000\240\000\000\002I\0019\003\015\000\000\001\192\000\000\000\000\001\208\001\175\001\198\003j\000\000\001\209\003\016\000\000\000\000\001\210\003Y\000\241\000\000\000\000\001\211\000-\000\242\000\000\000\000\002T\000\243\003\007\000\000\000\000\000\000\000\244\002M\000\000\000\000\000\000\003\030\003[\000\000\000\000\000\000\000\000\000\000\003#\000\000\000\000\000\157\003(\000\000\0035\001\207\003\008\000\000\001\177\0019\000\000\000\000\001\178\000\000\000\000\000\241\000\000\000\000\000\000\000\000\000\000\001I\000\000\001\175\001\198\001\208\001\175\001\198\000\000\000\252\001\209\000\000\000\000\000\199\001\210\000\222\000\000\000-\000\000\001\211\000\000\002T\003w\003\007\000\000\000\000\002;\004\006\001T\000\000\002X\000\000\000\000\001Q\000\000\000\157\001R\000\000\000\163\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\008\000\000\001\177\002B\000\000\001\177\001\178\000\000\000\000\001\178\000[\002v\000\000\000\201\002\143\000\000\000\000\000\202\000\000\000\000\001\175\001\198\000\000\000\000\000\000\000\000\000\000\000Y\000\000\002C\0059\000d\000\000\000\000\000-\000\000\003|\000\000\002T\001\191\003\007\000\000\000\000\000\215\002H\000\000\000\000\000\000\002I\0019\003\015\000\000\001\192\000\000\000\000\000[\000\000\000\000\000\000\002x\000\000\003\016\000\000\002y\003\008\003x\001\177\000\000\000\000\000\000\001\178\000[\000\000\000\000\000\000\000\000\000\\\000\000\000\000\000\000\000]\002M\000\000\000\000\000\000\003\030\003z\000\000\000\000\000\000\002C\000\000\003#\002C\000\000\000\157\003(\000\000\0035\001\207\001\191\000\000\000\000\001\191\000f\002H\000\000\000\000\002H\002I\0019\003\015\002I\001\192\000\000\000\000\001\192\000\000\000\000\001\208\000\000\000\000\003\016\000\216\001\209\000\000\003x\000\000\001\210\002K\000\000\000\000\000\000\001\211\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002M\000\000\000\000\002M\003\030\003z\000\000\0044\000\000\000\000\000\000\003#\002C\002\134\000\157\003(\000\000\0035\001\207\000\000\000\000\001\207\001\191\000\000\000\000\000\000\002\135\002H\000\000\000\240\000\000\002I\0019\003\015\000\000\001\192\000\000\000\000\001\208\001\175\001\198\001\208\000g\001\209\003\016\000\000\001\209\001\210\005:\000\241\001\210\000\000\001\211\000-\000\242\001\211\000\000\003\158\000\243\000\000\000\000\000\000\000\000\000\244\002M\000\000\000h\000\000\003\030\005<\000\000\000\000\000\000\000\000\000\000\003#\003\190\000\000\000\157\003(\000\000\0035\001\207\003\193\000\199\001\177\000\220\000\000\000\000\001\178\000\000\000i\000\000\000\000\000\000\002\165\000\000\000\000\000\000\000\000\001\175\001\198\001\208\001\175\001\198\003\199\000\000\001\209\000\000\002\176\000\000\001\210\000j\000\000\000-\000\000\001\211\000\148\003\158\000\000\000\000\000\000\000\000\002;\003R\000\000\000l\000\000\000[\000\000\000\000\000\201\000\000\003\237\000\000\000\202\001\203\003\241\001\021\000\000\000\000\000\000\000\000\000\000\003\193\000\000\001\177\002B\000\000\001\177\001\178\001\175\001\198\001\178\000\000\000\000\000\199\000\000\000\220\000\000\000\000\000\215\000\000\000\000\000\000\000-\003\199\000\000\000\000\003\158\000\000\002v\000\000\000\000\002\143\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\191\000\000\000Y\000\000\000\000\003\192\000b\000\000\000\000\000\000\0019\003\200\003\193\001\192\001\177\000\000\000-\000[\001\178\000\000\000\201\000\000\003\201\000\000\000\202\000\000\003\239\000\000\000\000\000\000\000\000\000\199\000[\000\220\003\199\000\000\002x\000\000\000\000\000\000\002y\000\000\000\000\000\000\000\000\000\000\000[\000\000\000\000\000\000\000\215\000\\\000\000\003\215\002C\000]\000\157\003\240\000\216\003\227\001\207\001\191\000\000\002v\001\191\000\000\002\143\000\000\000\000\002H\000\000\0019\003\200\002I\001\192\000[\000\000\001\192\000\201\000f\001\208\000\000\000\202\003\201\000Y\001\209\000\000\003\213\000b\001\210\002K\000\000\000\000\000\000\001\211\000\000\000\000\000\000\000-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002M\002B\000\215\000\000\000\000\002x\001\191\000\000\003\215\002y\000\000\000\157\003\220\000\000\003\227\001\207\0019\003\200\001\207\001\192\000\241\000\000\000[\000\000\000\216\000\000\002\134\000\\\003\201\000\000\000\000\000]\003\213\000\000\000\254\001\208\000\000\000\000\001\208\002\135\001\209\000\000\000\000\001\209\001\210\000\000\000\000\001\210\000\000\001\211\000\149\000\000\001\211\000g\000\000\000f\000\000\000\000\000\000\003\215\000\000\000\000\000\157\003\220\000\000\003\227\001\207\000\000\000\000\000\152\000\206\000\155\000\156\002v\000\000\000\000\002\143\000h\000\000\000\000\000Y\000\000\000\216\000\000\000b\000\000\001\208\000\000\000\000\000\000\000\000\001\209\000\241\000\000\000-\001\210\000\157\000\162\000\000\000\163\001\211\002\134\000\135\000\000\002\204\000\000\001\000\000\000\002\165\000\000\002\162\000\000\000\000\000\000\002\135\000\000\000Y\002B\000\000\000-\000b\002x\002\178\000j\000[\002y\000\000\000\136\000\000\000\\\000-\000\137\000\149\000]\000\000\000g\000\000\000l\000\000\000\168\000\000\000\000\000\000\000\000\000\000\000\199\000\000\000\220\000\000\000\000\000\241\000\152\001\182\000\155\000\156\000\000\000\000\000f\000\000\000h\000[\000\000\000\000\000\000\001\002\000\\\000\000\000\000\000\000\000]\000\000\000\000\001N\000\000\000\000\000\000\002\207\000\000\000\157\000\162\000\000\000\163\000\000\002\165\000\135\000\000\001H\000Y\000\000\000[\000\000\000b\000\201\000f\000\000\000\000\000\202\002\166\000Y\000\000\000\000\000-\000b\000\000\000\000\000j\000\000\000\000\000\000\000\136\000\000\000\000\000-\000\137\000\000\000\000\000\000\002\134\000\000\000l\002\213\000\168\000\215\000\000\000\000\000\000\002\162\000\000\000\000\000\000\002\135\000[\000\000\000\000\000\149\000\000\000\\\000g\001\175\001\198\000]\000\000\000[\000\000\000\000\000\000\000\000\000\\\000\000\000\000\000\000\000]\000\000\000\152\002E\000\155\000\156\000\000\000\000\0019\000\000\000h\000\000\000\000\000f\000\000\000\000\000\000\000\000\000\000\000\149\001I\000\000\000g\000\000\000f\000\000\000\000\000\000\000-\000\157\000\162\000[\000\163\001\177\000\000\000\135\000\000\001\178\000\152\002}\000\155\000\156\000\000\000\000\000\000\000\000\000h\001T\002\165\002\230\000\000\000\216\001Q\000\000\000\157\001R\000j\000\163\000\000\000\000\000\136\000\000\002\166\000\000\000\137\000\157\000\162\000\000\000\163\000\000\000l\000\135\000\168\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001N\000\000\000\000\001\203\000Y\000\000\000\000\000\000\000b\000\149\000\000\000j\000g\000\000\001H\000\136\000\000\000\000\000-\000\137\000\149\000\000\000\000\000g\000\000\000l\000\000\000\168\000\152\003%\000\155\000\156\000\000\000\000\000\000\000\000\000h\000\000\000\241\000\152\003\217\000\155\000\156\000\000\000\000\001\175\001\196\000h\000[\000\000\001\191\000\000\001\004\000\\\000\000\000\157\000\162\000]\000\163\000\000\000\000\000\135\000\000\001\192\000\000\000\000\000\157\000\162\000\000\000\163\000Y\000\000\000\135\000\000\000b\000\000\001\205\000\000\000\000\000\000\000\000\000f\000j\000\000\000-\000\000\000\136\0019\000\000\000[\000\137\001\177\000\000\000j\000\000\001\178\000l\000\136\000\168\001I\000\000\000\137\001\019\001\021\001\175\001\198\000\000\000l\000\000\000\168\001\207\000\000\000\000\000\000\000[\000\000\000\000\000\000\000Y\000\\\000\000\000\000\000b\000]\003I\000\000\001T\000\000\002\241\000\000\001\208\001Q\000-\000\157\001R\001\209\000\163\000\000\000\000\001\210\000\000\000\000\000\000\000\000\001\211\000\000\000\000\000f\002B\000\000\001\177\000\000\000\000\000\000\001\178\000\000\000\000\000\000\000\149\000\000\000\000\000g\000[\000\000\000\000\000\000\000\000\000\\\000\000\000\000\000\000\000]\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\199\001\023\000\220\000\000\000\000\000\000\000h\000\000\000\000\000\000\001\191\000\000\000\000\000\000\000\000\000\000\000f\000\000\003O\000\000\000\000\000\000\001\203\001\192\000\000\000\157\001\029\000\000\000\163\000\000\000\000\000\135\000Y\000\000\000\000\000Y\000b\000\000\000\000\000n\000\000\000\000\000\000\000\000\000[\000\149\000-\000\201\000g\000\000\000\000\000\202\000j\000\000\000\000\000\000\000\136\000\000\000\000\002C\000\137\000\000\000\000\000\000\000\170\000\000\000l\000\156\000\000\001\191\000\000\000-\000h\000\000\002H\000\000\000[\000\215\002I\000[\000\000\000\\\001\192\000\000\000\\\000]\000\000\000\000\000]\000\000\001\208\000\157\000\162\000\149\000\163\003Q\000g\000\135\000\000\000Y\000\000\000\000\000\000\000b\001\217\000\000\000\000\000\000\000\000\000f\000\000\002M\000f\000-\000\000\000\180\000\000\000\000\000j\000\000\000h\000\000\000\136\000\000\001N\000\000\000\137\000\000\000\000\001\207\000\000\000\000\000l\000\000\000\168\000\000\000\000\000\000\001H\000\157\001#\000\000\000\163\000[\000\000\000\135\000\000\000Y\000\\\001\208\000\000\000b\000]\000\000\001\209\000\000\000\000\000\216\001\210\000\000\000\000\000-\000\000\001\211\000\000\000Y\000j\000\000\000\000\000b\000\136\000\000\000\000\000\000\000\137\000\000\000f\000\000\000\000\000-\000l\000\000\000\000\000\000\000\000\000\000\000\149\000\000\000\000\000g\000\000\000[\000g\000\000\000\000\000\000\000\\\000-\000\000\000\000\000]\002T\000\000\000\000\000\000\000\000\000\000\000\000\000\183\000[\000\000\0019\000\000\000h\000\\\000\000\000h\000\000\000]\000\000\000\000\000\000\000\000\001I\000f\000\241\000\000\004)\001\175\001\198\000\000\000\000\000\157\000\185\000\000\000\163\000\000\000Y\000\135\001\006\000Y\000b\000f\000\000\000n\000\000\000\000\000\000\002;\003H\001T\000-\003\022\000\149\000\000\001Q\000g\000\157\001R\000j\000\163\000\000\000j\000\136\000\000\000\000\000\000\000\137\000\000\000\000\000\000\000\000\002B\000l\001\177\000\183\000s\000\000\001\178\000\000\000h\000[\000\000\000\000\000[\000\000\000\\\000\000\000\000\000\\\000]\000\000\000\000\000]\000\000\000\000\000\000\000\000\000\000\000\157\001)\000\149\000\163\000\000\000g\000\135\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000f\000\000\000\000\000f\000\000\000\149\000\000\000\000\000g\000\180\000\000\000\000\000j\000\000\000h\000\000\000\136\000\000\000\000\000\000\000\137\000\000\000\000\0019\003\015\000\000\000l\001\158\000\000\001\175\001\198\000\000\000h\000\157\001/\003\016\000\163\000\000\000\000\000\135\000\000\001\175\001\198\000\000\000\000\000\000\000\000\000\000\002C\002;\002<\000\157\001\160\000\000\000\163\000\000\000\000\000\135\001\191\004.\000j\002;\002G\002H\000\136\000\000\003#\002I\000\137\000\157\003(\001\192\0035\002B\000l\001\177\000\000\000\149\000j\001\178\000g\000\000\000\136\000g\002K\002B\000\137\001\177\000\000\000\000\000\000\001\178\000l\000\000\000\000\000\000\000\000\000\000\000\000\001\158\002M\000\000\000Y\000\000\000h\000\000\000b\000h\000\000\000-\000\000\000\000\000\000\000\000\000\000\000\000\000-\000\000\001\207\000\000\000\000\000\000\000\000\000\157\001\243\000\000\000\163\000\000\000-\000\135\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000\000\001\208\000\000\000\000\000\000\000\000\001\209\000\000\000\000\000[\001\210\000\000\000\000\000j\000\\\001\211\000j\000\136\000]\001\175\001\196\000\137\000\000\000\000\000\000\001N\002C\000l\000\000\000\000\000l\000\000\000\000\000Y\000\000\000\000\001\191\000b\002C\001H\000\000\002H\000f\000\000\001N\002I\000\000\000-\001\191\001\192\000\000\000\000\000\000\002H\000\000\001\175\001\198\002I\001H\000\000\000\000\001\192\002K\000[\000\000\001\177\000\000\001\175\001\198\001\178\000\000\000\000\000\000\000\000\002K\002;\003T\000[\002M\000\000\000\000\000\000\000\\\000\000\000\000\000\000\000]\002;\004\027\000\000\002M\000\000\000\000\000\000\001\175\001\196\001\207\000\000\000\000\002B\000\000\001\177\000\000\000\000\000\000\001\178\000\000\000\000\001\207\000\000\000f\002B\0019\001\177\000\000\000\000\001\208\001\178\000\000\000\149\000\000\001\209\000g\000\000\001I\001\210\000\000\000\000\001\208\000\000\001\211\0019\000\000\001\209\000\000\000\000\000\000\001\210\000[\000\000\001\177\002f\001\211\001I\001\178\000\000\000h\000\000\000\000\000\000\000\000\001T\000\000\003,\000\000\000\000\001Q\000\000\000\157\001R\000\000\000\163\000\000\001\191\000\000\000\157\002h\000\000\000\163\000\000\001T\000\135\003\171\001\175\001\198\001Q\001\192\000\157\001R\000\000\000\163\000\000\000\000\000\000\000\000\001\175\001\198\000\149\000\000\002C\000g\000\000\000j\002;\004\029\000\000\000\136\000\000\000\000\001\191\000\137\002C\000\000\000\000\002H\003K\000l\000\000\002I\002f\000\000\001\191\001\192\000\000\000h\000\000\002H\002B\000\000\001\177\002I\000\000\000\000\001\178\001\192\002K\001\175\001\198\000\000\002B\000\000\001\177\000\000\000\157\002\141\001\178\000\163\002K\001\191\000\135\000\000\002M\000\000\001\208\000\000\000\000\002;\004\031\000Y\000\000\000Y\001\192\000b\002M\000b\000\000\000\000\001\219\000\000\001\207\000j\000\000\000\000\000\000\000\136\000\000\000\000\000\000\000\137\000\000\002B\001\207\001\177\000\000\000l\000\000\001\178\000\000\000\000\001\208\000\000\000\000\000\000\000\000\001\209\000\000\000\000\000\000\001\210\000\000\000\000\001\208\000[\001\211\000[\000\000\001\209\000\\\000\000\000\\\001\210\000]\000\000\000]\000\000\001\211\000\000\002C\000\000\000\000\000\000\000\131\000\000\001\n\000\000\000\000\000\000\001\191\001\208\002C\000\000\000\000\002H\001\175\001\196\000f\002I\000f\000\000\001\191\001\192\000\000\001\221\000\000\002H\000\000\000\000\000\000\002I\000\000\000\000\000\000\001\192\002K\000\000\000\000\000\000\000\000\000\000\000\000\000Y\000\000\000\000\000\000\000b\002K\000\000\000\000\000\000\002M\002C\000\000\000\000\000\000\000\000\000\000\000\000\000[\000\000\001\177\001\191\002M\000Y\001\178\000\000\002H\000b\001\207\000\000\002I\000\000\000\000\000\000\001\192\000Y\000\000\000\000\000\000\000b\001\207\000\000\000\000\001\175\001\196\000[\000\000\002K\001\208\000\000\000\\\000\000\000\000\001\209\000]\000\000\000g\001\210\000g\000\000\001\208\000\000\001\211\002M\001\233\001\209\000\000\000[\000\000\001\210\000\000\000\000\000\\\000\000\001\211\000\134\000]\000\134\000f\000[\000h\001\207\000h\000\000\000\\\000\000\002 \000[\000]\001\177\000\000\001\175\001\196\001\178\000\000\000\000\000\000\000\000\002\"\000Y\000f\001\208\000\199\000b\000\220\000\135\001\209\000\135\000\000\000\000\001\210\000\000\000f\000\000\000\000\001\211\000Y\000Y\001\191\000\000\000b\000b\000\000\000\000\000\000\000\000\000j\000\000\000j\000\000\000\136\001\192\000\136\000\000\000\137\000[\000\137\001\177\000\000\000\000\000l\001\178\000l\000[\000\000\000\000\000[\000\000\000\\\000\201\000\000\000\000\000]\000\202\000\000\000\000\000\000\000\000\000g\000\000\000[\000[\002$\000\000\000\000\000\\\000\\\000\000\000\000\000]\000]\000\000\000\000\000\000\000\000\000\000\000f\000\134\000\000\000\215\000g\000\000\000h\000\000\000\000\000\000\000\000\001\191\000\000\000\000\000\000\000\000\000g\000f\000f\000\000\000\000\000\000\001\208\000\134\001\192\000\000\000Y\000\000\000h\000\000\000b\000\135\000\000\000\000\000\000\000\134\001\223\000\000\002c\000\000\000h\000\000\000\000\000Y\000\000\000\000\000\000\000b\000\000\000\000\000\000\000\000\000j\000\135\000\000\000\000\000\136\000\000\000Y\001\191\000\137\000\000\000b\000\000\000\000\000\135\000l\000\000\001\175\001\196\000[\000\000\001\192\000\000\000j\000\\\000\000\000\000\000\136\000]\000g\000\000\000\137\000\216\000\000\000\000\000j\000[\000l\002\217\000\136\001\208\000\\\000\000\000\137\000\000\000]\000g\000g\000\134\000l\000\000\000[\000f\000h\001\225\000\000\000\\\000\000\000\000\000\000\000]\000[\000\000\001\177\000\000\001\023\002\157\001\178\000\000\000f\000h\000h\000\000\000\000\000\000\000\000\000\000\000\000\000\135\000\000\000\000\000\000\000\000\000\000\000f\000\000\000\000\000\000\001\208\000Y\000\000\000\000\000\000\000b\000\000\000\135\000\135\000\000\000\000\000j\000\241\000Y\001\227\000\136\000\000\000b\000\000\000\137\000\000\000\000\000\000\000\000\000\000\000l\001\008\000\000\000j\000j\000Y\000\000\000\136\000\136\000n\002\155\000\137\000\137\000\000\000\000\000\000\000\000\000l\000l\000g\000[\000\000\000\000\000\000\000\000\000\\\000\000\002\234\000\000\000]\000\000\000\000\000[\000\000\000\000\000\000\000g\000\\\002\157\000\000\000\000\000]\002\246\000h\000\000\000\000\000\000\000\000\001\191\000[\000\000\000g\000\000\000f\000\\\002\157\000\000\000\000\000]\000\000\000h\001\192\000\000\000\000\000\000\000f\000\000\000\000\000\135\000\000\002\157\000\000\000\000\000Y\000Y\000h\000\000\000b\000b\000\000\000\000\000\000\000f\000\000\000\000\000\135\000\000\000\000\000\000\000j\000Y\000\000\000\000\000\136\000b\000\000\000\000\000\137\000\000\000\000\000\135\000\000\000\000\000l\000\000\000\000\000j\000\000\000\000\000\000\000\136\000\000\000Y\000\000\000\137\000\000\000b\000[\000[\000\000\000l\000j\000\\\000\\\002\254\000\136\000]\000]\001\208\000\137\000\000\000\000\000\000\000g\000[\000l\003\011\000\000\000\000\000\\\000\000\000\000\001\229\000]\000\000\000g\001\175\001\196\000\000\000\000\000f\000f\002\157\000\000\000\000\000\000\000[\000h\000\000\000\000\000\000\000\\\000g\000\000\002\157\000]\000\000\000f\000\000\000h\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\135\000\000\000Y\000\000\000h\000\000\000b\000f\000[\000\000\001\177\000\000\000\135\000\000\001\178\000\000\000\000\000\000\000\000\000\000\000\000\000j\000Y\000\000\000\000\000\136\000b\000\000\000\000\000\137\000\000\000\000\000\000\000j\000\000\000l\000\000\000\136\000\000\003\026\0031\000\137\000\000\000\000\000\000\000\000\000[\000l\000g\000g\000j\000\\\000\000\000\000\000\000\000]\0039\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000u\000g\000[\002\157\002\157\000\000\000\000\000\\\000h\000h\000\000\000]\000\000\000\000\003\163\000f\000\000\000\000\000\000\000\000\002\157\000\000\000\000\000g\000\000\000h\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\135\000\135\000f\000\000\000\000\000\000\000Y\000\000\000\000\002\157\000b\001\191\000\000\000\000\000h\000\000\000\000\000\135\000\000\000\000\000\000\000j\000j\000Y\001\192\000\136\000\136\000b\000\000\000\137\000\137\000\000\000\000\000\000\000\000\000l\000l\000\000\000j\000\135\000Y\000Y\000\136\000Y\000b\000n\000\137\000b\000\000\000\000\000[\000\000\000l\003\175\000\000\000\\\000\000\000\000\000\000\000]\000j\000\000\000g\000\000\000\136\000\000\000\000\000[\000\137\000\000\000\000\000\000\000\\\003\181\000l\000\000\000]\000\000\000\000\000\000\000\000\002\157\000g\000f\000[\000[\000h\000[\000\000\000\\\000\\\001\208\000\\\000]\000]\000\000\000]\000\000\000\000\000\000\000f\002\157\000\000\000\000\000Y\001\231\000h\000\000\000b\000\000\000\000\000\135\000\000\000\000\000\000\000Y\000\000\000f\000f\000b\000f\000\000\000\000\000\000\000\000\000\000\000Y\000\000\005o\000\000\000b\000\135\000j\000\000\000\000\000\000\000\136\000\000\000\000\000\000\000\137\000Y\000\000\000\000\000\000\000b\000l\000\000\000[\000\000\000\000\000\000\000j\000\\\003\188\000\000\000\136\000]\000\000\000[\000\137\001\175\001\196\000g\000\\\000\000\000l\000\000\000]\000\000\000[\003\197\000\000\000\000\000\000\000\\\000\199\000\000\000\220\000]\000g\000f\002\157\000\000\000\000\000[\000\000\000h\003\211\000\000\000\\\003\225\000f\000\000\000]\000\000\000\000\000g\000g\002\157\000g\000\000\000\000\000f\000h\000[\000\000\001\177\000\000\000\000\000\000\001\178\000\135\000Y\000\000\000\000\002\157\000b\000f\002\157\000[\000h\000h\000\201\000h\000\000\000\000\000\202\000\000\000\135\000\000\000\000\000\000\000j\000\000\000\000\000\000\000\136\000\000\000\000\000\000\000\137\000\000\000\000\000\000\000\000\000\135\000l\000\000\000\135\000j\000Y\003\232\000\215\000\136\000b\000\000\000[\000\137\000\000\000\000\000g\000\\\000\000\000l\000\000\000]\000j\000j\000\000\000j\000\136\000g\000\000\000\136\000\137\000\000\000-\000\137\000\000\002\157\000l\000w\000g\000l\000h\000\000\000\000\000\000\000\000\000f\005\021\000\000\000\000\000\000\000[\000h\000\000\000g\000\000\000\\\000\000\000\172\000\000\000]\001\191\000\000\000h\000\000\000\000\000\135\000\000\000\000\000\000\000\000\000\000\000\000\000\209\001\192\000\000\000Y\000\135\000h\000\000\000b\000\000\000\000\000\000\000f\000\000\001N\000j\000\135\000\216\000\000\000\136\000\000\000Y\000\000\000\137\000\000\000b\000j\000\000\001H\000l\000\136\000\135\000\000\000\199\000\137\000\220\000\000\000j\000Y\000\000\000l\000\136\000b\000\000\000\000\000\137\000\000\000\000\000[\000\000\000\000\000l\000j\000\\\000g\000\000\000\136\000]\000\000\000\000\000\137\000\000\000\000\000\000\000\000\000[\000l\000\000\000\000\001\208\000\\\000\000\000\000\000\234\000]\000\000\000\000\000[\000h\000\000\000\201\000f\000[\001\237\000\202\000\241\000\000\000\\\000\000\000\000\000Y\000]\000g\000\000\000b\000\000\000\000\000\000\000f\001\014\000\000\0019\000Y\000\135\000\000\000\000\000b\000\000\000\000\000\000\000\215\001\025\000\000\001I\000\000\000f\000h\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000j\000\000\000\000\000\000\000\136\000\000\000\000\000\000\000\137\000\000\000[\000\000\000\000\000\000\000l\000\\\001T\000\135\003\207\000]\000\000\001Q\000[\000\157\001R\000\000\000\163\000\\\000\000\000\000\000\000\000]\000\000\000\000\000\000\000Y\000\000\000g\000j\000b\000\000\000\000\000\136\000f\000\000\000\000\000\137\000\000\000\000\000\000\000\000\000\000\000l\000Y\000g\000f\001\145\000b\000\000\000\000\000\000\000h\000\000\000\000\000\000\000\000\000\216\000\000\000\000\000\000\000\000\000g\000\000\001\149\000\000\000\000\000\000\000\000\000h\000[\000\000\000\000\000\000\000\000\000\\\000\000\000\135\000Y\000]\000\000\001\185\000b\000\000\000\000\000\000\000h\000\000\000[\000\000\000\000\000\000\000\000\000\\\000\135\000\000\000\000\000]\000j\000\000\000\000\000\000\000\136\000f\000\000\000Y\000\137\000\000\000\000\000b\000\000\000\135\000l\000\000\000g\000j\000Y\000\000\000\000\000\136\000b\000f\000[\000\137\000\000\000\241\000g\000\\\000\000\000l\000\000\000]\000j\001\248\000\000\000\000\000\136\000\000\000h\001\016\000\137\000\000\000\000\000\000\000\000\001\253\000l\000\000\000\000\000[\000h\000\000\000\000\000\000\000\\\000f\000\000\000\000\000]\000\000\000[\000\000\000\000\000\135\000\000\000\\\000\000\000\000\000Y\000]\000\000\000\000\000b\000\000\000\000\000\135\000\000\000\000\000\000\000\000\000\000\000\000\000f\000g\000j\000\000\000\000\000\000\000\136\000\000\000\000\000\000\000\137\000f\000\000\000Y\000j\000\000\000l\000b\000\136\000g\002\001\000\000\000\137\000\000\000\000\000h\000\000\000\000\000l\000Y\000[\000\000\000\000\000b\000\000\000\\\000\000\000\000\002\024\000]\000\000\000\000\000\000\000h\000\000\000\000\000\000\000\000\000\000\000\000\000\135\000\000\000\000\000g\000\000\000\000\000\000\000[\000\000\000\000\000\000\000\000\000\\\000f\000\000\000Y\000]\000\000\000\135\000d\000\000\000j\002?\000[\000\000\000\136\000\000\000h\000\\\000\137\000g\000\000\000]\000\000\000\000\000l\000\000\000\000\000\000\000j\000f\000g\000\000\000\136\000\000\000\000\000\000\000\137\000\000\002\128\000\000\000\000\000\135\000l\000h\000\000\000f\000\000\000\000\000[\002\146\000\000\000\000\000\000\000\\\000h\000\000\000\000\000]\000\000\000\000\000\000\000\000\000j\000Y\000\000\000\000\000\136\000d\000\135\000Y\000\137\000Y\000\000\000d\000\000\000d\000l\000\000\000\000\000\135\000\000\000f\000g\000\000\000\000\000\000\000Y\000\000\000\000\000j\000n\000\000\000Y\000\136\000\000\000\000\000n\000\137\000Y\000\000\000j\002\148\000n\000l\000\136\000\000\000h\000[\000\137\000g\000\000\000\000\000\\\000[\000l\000[\000]\000\000\000\\\000\000\000\\\000\000\000]\000\000\000]\000g\000\000\000\000\003\151\000\000\000[\000\135\000\000\000h\000\000\000\\\000[\000\000\000\000\000]\000f\000\\\000[\000\000\003\255\000]\000f\000\\\000f\000h\002v\000]\000j\002\143\000\000\000\000\000\136\000\000\000\135\000\000\000\137\000g\000\000\000f\000Y\000\000\000l\000\000\000n\000f\000\000\000\000\000\000\000\000\000\135\000f\000\000\000\000\000\000\000j\000Y\000\000\000\000\000\136\000n\000h\000Y\000\137\000\000\000\000\000n\000\000\000\000\000l\000[\000j\000\000\000\000\002x\000\136\000\000\000\000\002y\000\137\000\000\000\000\000\000\000Y\000[\000l\000i\000n\000\000\000\\\000\199\000Y\000\220\000]\002v\000n\000g\002\143\000\000\000\000\000[\000\000\000g\000\000\000g\000\\\000[\000j\000\000\000]\000\000\000\\\000\224\001\175\001\196\000]\000\000\000f\000\000\000g\000h\000l\000\000\000\000\000\000\000g\000h\000[\000h\000\000\000\000\000g\000\\\000f\000[\000[\000]\000\201\000[\000f\000\\\000\202\002x\000h\000]\000i\002y\000\000\000\000\000h\000\000\000i\000\000\000i\000\000\000h\000\000\000[\000\000\001\177\000f\000\000\000\000\001\178\001\175\001\196\000j\000\215\000f\000\000\002\134\000\226\000j\000\000\000j\000\000\000\000\001\200\002v\001\202\000l\002\143\000\000\002\135\002v\000\000\000l\002\143\000l\000j\000\000\000\000\000\000\000\000\000\000\000j\000\000\000g\000\000\000\000\000\000\000j\002v\000y\000\000\002\143\000\000\000\000\000[\000{\001\177\000\000\000\000\000g\001\178\000}\000\000\002v\000\000\000g\002\143\000h\000[\000\000\000\000\000\000\002x\000\000\000[\000\000\002y\000\000\002x\000\000\000\000\000\000\002y\000h\002\134\000\000\000g\000\000\002v\000h\000\000\002\143\000[\000\216\000g\000\000\002x\002\135\002\165\000\000\002y\000\000\000\000\001\191\000\000\000\000\000\000\000[\000\000\000\000\000h\002x\002\180\000j\000\000\002y\001\192\000\000\000h\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\000\000\000j\000\000\000\000\000[\000\000\000\000\000j\002x\000\000\000\000\000\000\002y\000\000\000\000\000\129\000\000\000\000\000\000\000\000\000\000\000\139\000\000\000\000\000\000\000\000\001\191\000\000\000j\000\000\000\000\000\000\000\000\000\241\000\000\000\000\000j\000\000\002\165\001\192\002\134\000\000\000\141\000\000\000\000\000\000\002\134\001\018\000\000\000\000\000\143\000\000\002\182\002\135\000\000\001\208\000\000\000\000\000\000\002\135\000\000\000\000\000\000\000\000\002\134\000\000\000\000\000\000\000\000\001\239\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\135\000\000\002\134\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\135\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\134\000\000\001\208\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\135\000\000\000\000\001\241\000\000\002\165\000\000\000\000\000\000\000\000\000\000\002\165\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\184\000\000\000\000\000\000\000\000\000\000\002\186\000\000\000\000\000\000\002\165\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\188\002\165\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\190\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\165\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\192"))
   
   let semantic_action =
     [|
@@ -1491,7 +1491,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_aexpr = 
-# 1662 "parser_cocci_menhir.mly"
+# 1663 "parser_cocci_menhir.mly"
       ( Ast0.set_arg_exp _1 )
 # 1497 "parser_cocci_menhir.ml"
          in
@@ -1519,7 +1519,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_aexpr = 
-# 1664 "parser_cocci_menhir.mly"
+# 1665 "parser_cocci_menhir.mly"
       ( let (nm,lenname,pure,clt) = _1 in
       let nm = P.clt2mcode nm clt in
       let lenname =
@@ -1549,7 +1549,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_aexpr = 
-# 1672 "parser_cocci_menhir.mly"
+# 1673 "parser_cocci_menhir.mly"
       ( Ast0.set_arg_exp(Ast0.wrap(Ast0.TypeExp(_1))) )
 # 1555 "parser_cocci_menhir.ml"
          in
@@ -1571,7 +1571,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_any_strict = 
-# 1716 "parser_cocci_menhir.mly"
+# 1717 "parser_cocci_menhir.mly"
             ( Ast.WhenAny )
 # 1577 "parser_cocci_menhir.ml"
          in
@@ -1593,7 +1593,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_any_strict = 
-# 1717 "parser_cocci_menhir.mly"
+# 1718 "parser_cocci_menhir.mly"
             ( Ast.WhenStrict )
 # 1599 "parser_cocci_menhir.ml"
          in
@@ -1615,7 +1615,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_any_strict = 
-# 1718 "parser_cocci_menhir.mly"
+# 1719 "parser_cocci_menhir.mly"
             ( Ast.WhenForall )
 # 1621 "parser_cocci_menhir.ml"
          in
@@ -1637,7 +1637,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_any_strict = 
-# 1719 "parser_cocci_menhir.mly"
+# 1720 "parser_cocci_menhir.mly"
             ( Ast.WhenExists )
 # 1643 "parser_cocci_menhir.ml"
          in
@@ -1661,7 +1661,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_arith_expr_eexpr_dot_expressions_ = 
-# 1190 "parser_cocci_menhir.mly"
+# 1191 "parser_cocci_menhir.mly"
                                             ( _1 )
 # 1667 "parser_cocci_menhir.ml"
          in
@@ -1701,7 +1701,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_dot_expressions_ = 
-# 1192 "parser_cocci_menhir.mly"
+# 1193 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Mul _1 _2 _3 )
 # 1707 "parser_cocci_menhir.ml"
          in
@@ -1741,7 +1741,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_dot_expressions_ = 
-# 1194 "parser_cocci_menhir.mly"
+# 1195 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
 # 1747 "parser_cocci_menhir.ml"
          in
@@ -1781,7 +1781,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_dot_expressions_ = 
-# 1196 "parser_cocci_menhir.mly"
+# 1197 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Plus _1 _2 _3 )
 # 1787 "parser_cocci_menhir.ml"
          in
@@ -1821,7 +1821,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_dot_expressions_ = 
-# 1198 "parser_cocci_menhir.mly"
+# 1199 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Minus _1 _2 _3 )
 # 1827 "parser_cocci_menhir.ml"
          in
@@ -1861,7 +1861,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_dot_expressions_ = 
-# 1200 "parser_cocci_menhir.mly"
+# 1201 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
 # 1867 "parser_cocci_menhir.ml"
          in
@@ -1901,7 +1901,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_dot_expressions_ = 
-# 1202 "parser_cocci_menhir.mly"
+# 1203 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.logic_op op _1 clt _3 )
 # 1907 "parser_cocci_menhir.ml"
          in
@@ -1941,7 +1941,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_dot_expressions_ = 
-# 1204 "parser_cocci_menhir.mly"
+# 1205 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.Eq _1 _2 _3 )
 # 1947 "parser_cocci_menhir.ml"
          in
@@ -1981,7 +1981,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_dot_expressions_ = 
-# 1206 "parser_cocci_menhir.mly"
+# 1207 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.NotEq _1 _2 _3 )
 # 1987 "parser_cocci_menhir.ml"
          in
@@ -2021,7 +2021,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_dot_expressions_ = 
-# 1208 "parser_cocci_menhir.mly"
+# 1209 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.And _1 _2 _3 )
 # 2027 "parser_cocci_menhir.ml"
          in
@@ -2061,7 +2061,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_dot_expressions_ = 
-# 1210 "parser_cocci_menhir.mly"
+# 1211 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Or _1 _2 _3 )
 # 2067 "parser_cocci_menhir.ml"
          in
@@ -2101,7 +2101,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_dot_expressions_ = 
-# 1212 "parser_cocci_menhir.mly"
+# 1213 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Xor _1 _2 _3 )
 # 2107 "parser_cocci_menhir.ml"
          in
@@ -2141,7 +2141,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_dot_expressions_ = 
-# 1214 "parser_cocci_menhir.mly"
+# 1215 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.AndLog _1 _2 _3 )
 # 2147 "parser_cocci_menhir.ml"
          in
@@ -2181,7 +2181,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_dot_expressions_ = 
-# 1216 "parser_cocci_menhir.mly"
+# 1217 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.OrLog _1 _2 _3 )
 # 2187 "parser_cocci_menhir.ml"
          in
@@ -2205,7 +2205,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1190 "parser_cocci_menhir.mly"
+# 1191 "parser_cocci_menhir.mly"
                                             ( _1 )
 # 2211 "parser_cocci_menhir.ml"
          in
@@ -2245,7 +2245,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1192 "parser_cocci_menhir.mly"
+# 1193 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Mul _1 _2 _3 )
 # 2251 "parser_cocci_menhir.ml"
          in
@@ -2285,7 +2285,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1194 "parser_cocci_menhir.mly"
+# 1195 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
 # 2291 "parser_cocci_menhir.ml"
          in
@@ -2325,7 +2325,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1196 "parser_cocci_menhir.mly"
+# 1197 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Plus _1 _2 _3 )
 # 2331 "parser_cocci_menhir.ml"
          in
@@ -2365,7 +2365,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1198 "parser_cocci_menhir.mly"
+# 1199 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Minus _1 _2 _3 )
 # 2371 "parser_cocci_menhir.ml"
          in
@@ -2405,7 +2405,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1200 "parser_cocci_menhir.mly"
+# 1201 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
 # 2411 "parser_cocci_menhir.ml"
          in
@@ -2445,7 +2445,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1202 "parser_cocci_menhir.mly"
+# 1203 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.logic_op op _1 clt _3 )
 # 2451 "parser_cocci_menhir.ml"
          in
@@ -2485,7 +2485,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1204 "parser_cocci_menhir.mly"
+# 1205 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.Eq _1 _2 _3 )
 # 2491 "parser_cocci_menhir.ml"
          in
@@ -2525,7 +2525,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1206 "parser_cocci_menhir.mly"
+# 1207 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.NotEq _1 _2 _3 )
 # 2531 "parser_cocci_menhir.ml"
          in
@@ -2565,7 +2565,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1208 "parser_cocci_menhir.mly"
+# 1209 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.And _1 _2 _3 )
 # 2571 "parser_cocci_menhir.ml"
          in
@@ -2605,7 +2605,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1210 "parser_cocci_menhir.mly"
+# 1211 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Or _1 _2 _3 )
 # 2611 "parser_cocci_menhir.ml"
          in
@@ -2645,7 +2645,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1212 "parser_cocci_menhir.mly"
+# 1213 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Xor _1 _2 _3 )
 # 2651 "parser_cocci_menhir.ml"
          in
@@ -2685,7 +2685,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1214 "parser_cocci_menhir.mly"
+# 1215 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.AndLog _1 _2 _3 )
 # 2691 "parser_cocci_menhir.ml"
          in
@@ -2725,7 +2725,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1216 "parser_cocci_menhir.mly"
+# 1217 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.OrLog _1 _2 _3 )
 # 2731 "parser_cocci_menhir.ml"
          in
@@ -2749,7 +2749,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_arith_expr_eexpr_nest_expressions_ = 
-# 1190 "parser_cocci_menhir.mly"
+# 1191 "parser_cocci_menhir.mly"
                                             ( _1 )
 # 2755 "parser_cocci_menhir.ml"
          in
@@ -2789,7 +2789,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_nest_expressions_ = 
-# 1192 "parser_cocci_menhir.mly"
+# 1193 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Mul _1 _2 _3 )
 # 2795 "parser_cocci_menhir.ml"
          in
@@ -2829,7 +2829,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_nest_expressions_ = 
-# 1194 "parser_cocci_menhir.mly"
+# 1195 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
 # 2835 "parser_cocci_menhir.ml"
          in
@@ -2869,7 +2869,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_nest_expressions_ = 
-# 1196 "parser_cocci_menhir.mly"
+# 1197 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Plus _1 _2 _3 )
 # 2875 "parser_cocci_menhir.ml"
          in
@@ -2909,7 +2909,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_nest_expressions_ = 
-# 1198 "parser_cocci_menhir.mly"
+# 1199 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Minus _1 _2 _3 )
 # 2915 "parser_cocci_menhir.ml"
          in
@@ -2949,7 +2949,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_nest_expressions_ = 
-# 1200 "parser_cocci_menhir.mly"
+# 1201 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
 # 2955 "parser_cocci_menhir.ml"
          in
@@ -2989,7 +2989,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_nest_expressions_ = 
-# 1202 "parser_cocci_menhir.mly"
+# 1203 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.logic_op op _1 clt _3 )
 # 2995 "parser_cocci_menhir.ml"
          in
@@ -3029,7 +3029,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_nest_expressions_ = 
-# 1204 "parser_cocci_menhir.mly"
+# 1205 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.Eq _1 _2 _3 )
 # 3035 "parser_cocci_menhir.ml"
          in
@@ -3069,7 +3069,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_nest_expressions_ = 
-# 1206 "parser_cocci_menhir.mly"
+# 1207 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.NotEq _1 _2 _3 )
 # 3075 "parser_cocci_menhir.ml"
          in
@@ -3109,7 +3109,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_nest_expressions_ = 
-# 1208 "parser_cocci_menhir.mly"
+# 1209 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.And _1 _2 _3 )
 # 3115 "parser_cocci_menhir.ml"
          in
@@ -3149,7 +3149,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_nest_expressions_ = 
-# 1210 "parser_cocci_menhir.mly"
+# 1211 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Or _1 _2 _3 )
 # 3155 "parser_cocci_menhir.ml"
          in
@@ -3189,7 +3189,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_nest_expressions_ = 
-# 1212 "parser_cocci_menhir.mly"
+# 1213 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Xor _1 _2 _3 )
 # 3195 "parser_cocci_menhir.ml"
          in
@@ -3229,7 +3229,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_nest_expressions_ = 
-# 1214 "parser_cocci_menhir.mly"
+# 1215 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.AndLog _1 _2 _3 )
 # 3235 "parser_cocci_menhir.ml"
          in
@@ -3269,7 +3269,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_nest_expressions_ = 
-# 1216 "parser_cocci_menhir.mly"
+# 1217 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.OrLog _1 _2 _3 )
 # 3275 "parser_cocci_menhir.ml"
          in
@@ -3293,7 +3293,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1190 "parser_cocci_menhir.mly"
+# 1191 "parser_cocci_menhir.mly"
                                             ( _1 )
 # 3299 "parser_cocci_menhir.ml"
          in
@@ -3333,7 +3333,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1192 "parser_cocci_menhir.mly"
+# 1193 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Mul _1 _2 _3 )
 # 3339 "parser_cocci_menhir.ml"
          in
@@ -3373,7 +3373,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1194 "parser_cocci_menhir.mly"
+# 1195 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
 # 3379 "parser_cocci_menhir.ml"
          in
@@ -3413,7 +3413,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1196 "parser_cocci_menhir.mly"
+# 1197 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Plus _1 _2 _3 )
 # 3419 "parser_cocci_menhir.ml"
          in
@@ -3453,7 +3453,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1198 "parser_cocci_menhir.mly"
+# 1199 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Minus _1 _2 _3 )
 # 3459 "parser_cocci_menhir.ml"
          in
@@ -3493,7 +3493,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1200 "parser_cocci_menhir.mly"
+# 1201 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
 # 3499 "parser_cocci_menhir.ml"
          in
@@ -3533,7 +3533,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1202 "parser_cocci_menhir.mly"
+# 1203 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.logic_op op _1 clt _3 )
 # 3539 "parser_cocci_menhir.ml"
          in
@@ -3573,7 +3573,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1204 "parser_cocci_menhir.mly"
+# 1205 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.Eq _1 _2 _3 )
 # 3579 "parser_cocci_menhir.ml"
          in
@@ -3613,7 +3613,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1206 "parser_cocci_menhir.mly"
+# 1207 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.NotEq _1 _2 _3 )
 # 3619 "parser_cocci_menhir.ml"
          in
@@ -3653,7 +3653,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1208 "parser_cocci_menhir.mly"
+# 1209 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.And _1 _2 _3 )
 # 3659 "parser_cocci_menhir.ml"
          in
@@ -3693,7 +3693,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1210 "parser_cocci_menhir.mly"
+# 1211 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Or _1 _2 _3 )
 # 3699 "parser_cocci_menhir.ml"
          in
@@ -3733,7 +3733,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1212 "parser_cocci_menhir.mly"
+# 1213 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Xor _1 _2 _3 )
 # 3739 "parser_cocci_menhir.ml"
          in
@@ -3773,7 +3773,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1214 "parser_cocci_menhir.mly"
+# 1215 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.AndLog _1 _2 _3 )
 # 3779 "parser_cocci_menhir.ml"
          in
@@ -3813,7 +3813,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1216 "parser_cocci_menhir.mly"
+# 1217 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.OrLog _1 _2 _3 )
 # 3819 "parser_cocci_menhir.ml"
          in
@@ -3964,7 +3964,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_assign_expr_eexpr_dot_expressions_ = 
-# 1162 "parser_cocci_menhir.mly"
+# 1163 "parser_cocci_menhir.mly"
                                            ( _1 )
 # 3970 "parser_cocci_menhir.ml"
          in
@@ -4004,7 +4004,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_assign_expr_eexpr_dot_expressions_ = 
-# 1164 "parser_cocci_menhir.mly"
+# 1165 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in
       Ast0.wrap(Ast0.Assignment(_1,P.clt2mcode op clt,
                                Ast0.set_arg_exp _3,false)) )
@@ -4046,7 +4046,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_assign_expr_eexpr_dot_expressions_ = 
-# 1168 "parser_cocci_menhir.mly"
+# 1169 "parser_cocci_menhir.mly"
       ( Ast0.wrap
          (Ast0.Assignment
             (_1,P.clt2mcode Ast.SimpleAssign _2,Ast0.set_arg_exp _3,false)) )
@@ -4072,7 +4072,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_assign_expr_eexpr_nest_expressions_ = 
-# 1162 "parser_cocci_menhir.mly"
+# 1163 "parser_cocci_menhir.mly"
                                            ( _1 )
 # 4078 "parser_cocci_menhir.ml"
          in
@@ -4112,7 +4112,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_assign_expr_eexpr_nest_expressions_ = 
-# 1164 "parser_cocci_menhir.mly"
+# 1165 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in
       Ast0.wrap(Ast0.Assignment(_1,P.clt2mcode op clt,
                                Ast0.set_arg_exp _3,false)) )
@@ -4154,7 +4154,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_assign_expr_eexpr_nest_expressions_ = 
-# 1168 "parser_cocci_menhir.mly"
+# 1169 "parser_cocci_menhir.mly"
       ( Ast0.wrap
          (Ast0.Assignment
             (_1,P.clt2mcode Ast.SimpleAssign _2,Ast0.set_arg_exp _3,false)) )
@@ -4180,7 +4180,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_assign_expr_expr_invalid_ = 
-# 1162 "parser_cocci_menhir.mly"
+# 1163 "parser_cocci_menhir.mly"
                                            ( _1 )
 # 4186 "parser_cocci_menhir.ml"
          in
@@ -4220,7 +4220,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_assign_expr_expr_invalid_ = 
-# 1164 "parser_cocci_menhir.mly"
+# 1165 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in
       Ast0.wrap(Ast0.Assignment(_1,P.clt2mcode op clt,
                                Ast0.set_arg_exp _3,false)) )
@@ -4262,7 +4262,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_assign_expr_expr_invalid_ = 
-# 1168 "parser_cocci_menhir.mly"
+# 1169 "parser_cocci_menhir.mly"
       ( Ast0.wrap
          (Ast0.Assignment
             (_1,P.clt2mcode Ast.SimpleAssign _2,Ast0.set_arg_exp _3,false)) )
@@ -4288,7 +4288,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_assign_expr_bis = 
-# 1173 "parser_cocci_menhir.mly"
+# 1174 "parser_cocci_menhir.mly"
                                                             ( _1 )
 # 4294 "parser_cocci_menhir.ml"
          in
@@ -4328,7 +4328,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_assign_expr_bis = 
-# 1175 "parser_cocci_menhir.mly"
+# 1176 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in
       Ast0.wrap(Ast0.Assignment(_1,P.clt2mcode op clt,
                                Ast0.set_arg_exp _3,false)) )
@@ -4370,7 +4370,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_assign_expr_bis = 
-# 1179 "parser_cocci_menhir.mly"
+# 1180 "parser_cocci_menhir.mly"
       ( Ast0.wrap
          (Ast0.Assignment
             (_1,P.clt2mcode Ast.SimpleAssign _2,Ast0.set_arg_exp _3,false)) )
@@ -4396,7 +4396,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_basic_expr_eexpr_dot_expressions_ = 
-# 1159 "parser_cocci_menhir.mly"
+# 1160 "parser_cocci_menhir.mly"
                                                              ( _1 )
 # 4402 "parser_cocci_menhir.ml"
          in
@@ -4420,7 +4420,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_basic_expr_eexpr_nest_expressions_ = 
-# 1159 "parser_cocci_menhir.mly"
+# 1160 "parser_cocci_menhir.mly"
                                                              ( _1 )
 # 4426 "parser_cocci_menhir.ml"
          in
@@ -4444,7 +4444,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_basic_expr_expr_invalid_ = 
-# 1159 "parser_cocci_menhir.mly"
+# 1160 "parser_cocci_menhir.mly"
                                                              ( _1 )
 # 4450 "parser_cocci_menhir.ml"
          in
@@ -4562,7 +4562,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_cast_expr_eexpr_dot_expressions_ = 
-# 1219 "parser_cocci_menhir.mly"
+# 1220 "parser_cocci_menhir.mly"
                                           ( _1 )
 # 4568 "parser_cocci_menhir.ml"
          in
@@ -4612,7 +4612,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_lp_ in
         let _endpos = _endpos_e_ in
         let _v : 'tv_cast_expr_eexpr_dot_expressions_ = 
-# 1221 "parser_cocci_menhir.mly"
+# 1222 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Cast (P.clt2mcode "(" lp, t,
                             P.clt2mcode ")" rp, e)) )
 # 4619 "parser_cocci_menhir.ml"
@@ -4637,7 +4637,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_cast_expr_eexpr_invalid_ = 
-# 1219 "parser_cocci_menhir.mly"
+# 1220 "parser_cocci_menhir.mly"
                                           ( _1 )
 # 4643 "parser_cocci_menhir.ml"
          in
@@ -4687,7 +4687,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_lp_ in
         let _endpos = _endpos_e_ in
         let _v : 'tv_cast_expr_eexpr_invalid_ = 
-# 1221 "parser_cocci_menhir.mly"
+# 1222 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Cast (P.clt2mcode "(" lp, t,
                             P.clt2mcode ")" rp, e)) )
 # 4694 "parser_cocci_menhir.ml"
@@ -4712,7 +4712,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_cast_expr_eexpr_nest_expressions_ = 
-# 1219 "parser_cocci_menhir.mly"
+# 1220 "parser_cocci_menhir.mly"
                                           ( _1 )
 # 4718 "parser_cocci_menhir.ml"
          in
@@ -4762,7 +4762,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_lp_ in
         let _endpos = _endpos_e_ in
         let _v : 'tv_cast_expr_eexpr_nest_expressions_ = 
-# 1221 "parser_cocci_menhir.mly"
+# 1222 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Cast (P.clt2mcode "(" lp, t,
                             P.clt2mcode ")" rp, e)) )
 # 4769 "parser_cocci_menhir.ml"
@@ -4787,7 +4787,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_cast_expr_expr_invalid_ = 
-# 1219 "parser_cocci_menhir.mly"
+# 1220 "parser_cocci_menhir.mly"
                                           ( _1 )
 # 4793 "parser_cocci_menhir.ml"
          in
@@ -4837,7 +4837,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_lp_ in
         let _endpos = _endpos_e_ in
         let _v : 'tv_cast_expr_expr_invalid_ = 
-# 1221 "parser_cocci_menhir.mly"
+# 1222 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Cast (P.clt2mcode "(" lp, t,
                             P.clt2mcode ")" rp, e)) )
 # 4844 "parser_cocci_menhir.ml"
@@ -4904,7 +4904,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_comma_decls_TEllipsis_decl_ = 
-# 1470 "parser_cocci_menhir.mly"
+# 1471 "parser_cocci_menhir.mly"
     ( function dot_builder ->
       [Ast0.wrap(Ast0.PComma(P.clt2mcode "," _1));
        dot_builder _2] )
@@ -4940,7 +4940,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_comma_decls_TEllipsis_decl_ = 
-# 1474 "parser_cocci_menhir.mly"
+# 1475 "parser_cocci_menhir.mly"
     ( function dot_builder ->
       [Ast0.wrap(Ast0.PComma(P.clt2mcode "," _1)); _2] )
 # 4947 "parser_cocci_menhir.ml"
@@ -4979,7 +4979,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_comma_decls_TEllipsis_name_opt_decl_ = 
-# 1470 "parser_cocci_menhir.mly"
+# 1471 "parser_cocci_menhir.mly"
     ( function dot_builder ->
       [Ast0.wrap(Ast0.PComma(P.clt2mcode "," _1));
        dot_builder _2] )
@@ -5015,7 +5015,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_comma_decls_TEllipsis_name_opt_decl_ = 
-# 1474 "parser_cocci_menhir.mly"
+# 1475 "parser_cocci_menhir.mly"
     ( function dot_builder ->
       [Ast0.wrap(Ast0.PComma(P.clt2mcode "," _1)); _2] )
 # 5022 "parser_cocci_menhir.ml"
@@ -5186,7 +5186,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_comma_list_any_strict_ = 
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5192 "parser_cocci_menhir.ml"
          in
@@ -5210,7 +5210,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_comma_list_ctype_ = 
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5216 "parser_cocci_menhir.ml"
          in
@@ -5234,7 +5234,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_comma_list_d_ident_ = 
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5240 "parser_cocci_menhir.ml"
          in
@@ -5258,7 +5258,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_comma_list_dexpr_ = 
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5264 "parser_cocci_menhir.ml"
          in
@@ -5282,7 +5282,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_comma_list_ident_or_const_ = 
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5288 "parser_cocci_menhir.ml"
          in
@@ -5306,7 +5306,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_comma_list_meta_ident_ = 
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5312 "parser_cocci_menhir.ml"
          in
@@ -5330,7 +5330,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_comma_list_pure_ident_ = 
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5336 "parser_cocci_menhir.ml"
          in
@@ -5354,7 +5354,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_comma_list_pure_ident_or_meta_ident_ = 
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5360 "parser_cocci_menhir.ml"
          in
@@ -5378,7 +5378,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_comma_list_pure_ident_or_meta_ident_with_not_eq_not_ceq__ = 
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5384 "parser_cocci_menhir.ml"
          in
@@ -5402,7 +5402,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_comma_list_pure_ident_or_meta_ident_with_not_eq_not_eq__ = 
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5408 "parser_cocci_menhir.ml"
          in
@@ -5426,7 +5426,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_comma_list_pure_ident_or_meta_ident_with_not_eq_not_eqe__ = 
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5432 "parser_cocci_menhir.ml"
          in
@@ -5450,7 +5450,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_comma_list_pure_ident_or_meta_ident_with_not_eq_not_pos__ = 
-# 1694 "parser_cocci_menhir.mly"
+# 1695 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5456 "parser_cocci_menhir.ml"
          in
@@ -5474,7 +5474,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_cond_expr_eexpr_dot_expressions_ = 
-# 1184 "parser_cocci_menhir.mly"
+# 1185 "parser_cocci_menhir.mly"
                                              ( _1 )
 # 5480 "parser_cocci_menhir.ml"
          in
@@ -5530,7 +5530,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_l_ in
         let _endpos = _endpos_r_ in
         let _v : 'tv_cond_expr_eexpr_dot_expressions_ = 
-# 1186 "parser_cocci_menhir.mly"
+# 1187 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.CondExpr (l, P.clt2mcode "?" w, t,
                                 P.clt2mcode ":" dd, r)) )
 # 5537 "parser_cocci_menhir.ml"
@@ -5555,7 +5555,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_cond_expr_eexpr_nest_expressions_ = 
-# 1184 "parser_cocci_menhir.mly"
+# 1185 "parser_cocci_menhir.mly"
                                              ( _1 )
 # 5561 "parser_cocci_menhir.ml"
          in
@@ -5611,7 +5611,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_l_ in
         let _endpos = _endpos_r_ in
         let _v : 'tv_cond_expr_eexpr_nest_expressions_ = 
-# 1186 "parser_cocci_menhir.mly"
+# 1187 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.CondExpr (l, P.clt2mcode "?" w, t,
                                 P.clt2mcode ":" dd, r)) )
 # 5618 "parser_cocci_menhir.ml"
@@ -5636,7 +5636,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_cond_expr_expr_invalid_ = 
-# 1184 "parser_cocci_menhir.mly"
+# 1185 "parser_cocci_menhir.mly"
                                              ( _1 )
 # 5642 "parser_cocci_menhir.ml"
          in
@@ -5692,7 +5692,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_l_ in
         let _endpos = _endpos_r_ in
         let _v : 'tv_cond_expr_expr_invalid_ = 
-# 1186 "parser_cocci_menhir.mly"
+# 1187 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.CondExpr (l, P.clt2mcode "?" w, t,
                                 P.clt2mcode ":" dd, r)) )
 # 5699 "parser_cocci_menhir.ml"
@@ -6340,7 +6340,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_decl_ident = 
-# 1420 "parser_cocci_menhir.mly"
+# 1421 "parser_cocci_menhir.mly"
          ( Ast0.wrap(Ast0.Id(P.id2mcode _1)) )
 # 6346 "parser_cocci_menhir.ml"
          in
@@ -6368,7 +6368,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_decl_ident = 
-# 1422 "parser_cocci_menhir.mly"
+# 1423 "parser_cocci_menhir.mly"
          ( let (nm,constraints,pure,clt) = _1 in
          Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) )
 # 6375 "parser_cocci_menhir.ml"
@@ -6393,7 +6393,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_decl_list_decl_ = 
-# 1443 "parser_cocci_menhir.mly"
+# 1444 "parser_cocci_menhir.mly"
      (let circle x =
        match Ast0.unwrap x with Ast0.Pcircles(_) -> true | _ -> false in
      if List.exists circle _1
@@ -6421,7 +6421,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_decl_list_name_opt_decl_ = 
-# 1443 "parser_cocci_menhir.mly"
+# 1444 "parser_cocci_menhir.mly"
      (let circle x =
        match Ast0.unwrap x with Ast0.Pcircles(_) -> true | _ -> false in
      if List.exists circle _1
@@ -6449,7 +6449,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_decl_list_start_decl_ = 
-# 1450 "parser_cocci_menhir.mly"
+# 1451 "parser_cocci_menhir.mly"
                  ( [_1] )
 # 6455 "parser_cocci_menhir.ml"
          in
@@ -6489,7 +6489,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_decl_list_start_decl_ = 
-# 1452 "parser_cocci_menhir.mly"
+# 1453 "parser_cocci_menhir.mly"
     ( _1::Ast0.wrap(Ast0.PComma(P.clt2mcode "," _2))::_3 )
 # 6495 "parser_cocci_menhir.ml"
          in
@@ -6523,7 +6523,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_decl_list_start_decl_ = 
-# 1454 "parser_cocci_menhir.mly"
+# 1455 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.Pdots(P.clt2mcode "..." _1))::
       (List.concat(List.map (function x -> x (P.mkpdots "...")) _2)) )
 # 6530 "parser_cocci_menhir.ml"
@@ -6548,7 +6548,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_decl_list_start_name_opt_decl_ = 
-# 1450 "parser_cocci_menhir.mly"
+# 1451 "parser_cocci_menhir.mly"
                  ( [_1] )
 # 6554 "parser_cocci_menhir.ml"
          in
@@ -6588,7 +6588,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_decl_list_start_name_opt_decl_ = 
-# 1452 "parser_cocci_menhir.mly"
+# 1453 "parser_cocci_menhir.mly"
     ( _1::Ast0.wrap(Ast0.PComma(P.clt2mcode "," _2))::_3 )
 # 6594 "parser_cocci_menhir.ml"
          in
@@ -6622,7 +6622,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_decl_list_start_name_opt_decl_ = 
-# 1454 "parser_cocci_menhir.mly"
+# 1455 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.Pdots(P.clt2mcode "..." _1))::
       (List.concat(List.map (function x -> x (P.mkpdots "...")) _2)) )
 # 6629 "parser_cocci_menhir.ml"
@@ -8991,7 +8991,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_d_ in
         let _endpos = _endpos_d_ in
         let _v : 'tv_edots_when_TEllipsis_eexpr_ = 
-# 1704 "parser_cocci_menhir.mly"
+# 1705 "parser_cocci_menhir.mly"
                                                   ( (d,None) )
 # 8997 "parser_cocci_menhir.ml"
          in
@@ -9037,7 +9037,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_d_ in
         let _endpos = _endpos__5_ in
         let _v : 'tv_edots_when_TEllipsis_eexpr_ = 
-# 1705 "parser_cocci_menhir.mly"
+# 1706 "parser_cocci_menhir.mly"
                                                   ( (d,Some w) )
 # 9043 "parser_cocci_menhir.ml"
          in
@@ -9065,7 +9065,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_d_ in
         let _endpos = _endpos_d_ in
         let _v : 'tv_edots_when_TEllipsis_initialize_ = 
-# 1704 "parser_cocci_menhir.mly"
+# 1705 "parser_cocci_menhir.mly"
                                                   ( (d,None) )
 # 9071 "parser_cocci_menhir.ml"
          in
@@ -9111,7 +9111,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_d_ in
         let _endpos = _endpos__5_ in
         let _v : 'tv_edots_when_TEllipsis_initialize_ = 
-# 1705 "parser_cocci_menhir.mly"
+# 1706 "parser_cocci_menhir.mly"
                                                   ( (d,Some w) )
 # 9117 "parser_cocci_menhir.ml"
          in
@@ -9139,7 +9139,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_d_ in
         let _endpos = _endpos_d_ in
         let _v : 'tv_edots_when_TEllipsis_struct_decl_ = 
-# 1704 "parser_cocci_menhir.mly"
+# 1705 "parser_cocci_menhir.mly"
                                                   ( (d,None) )
 # 9145 "parser_cocci_menhir.ml"
          in
@@ -9185,7 +9185,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_d_ in
         let _endpos = _endpos__5_ in
         let _v : 'tv_edots_when_TEllipsis_struct_decl_ = 
-# 1705 "parser_cocci_menhir.mly"
+# 1706 "parser_cocci_menhir.mly"
                                                   ( (d,Some w) )
 # 9191 "parser_cocci_menhir.ml"
          in
@@ -9233,7 +9233,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_eexpr_list = 
-# 1648 "parser_cocci_menhir.mly"
+# 1649 "parser_cocci_menhir.mly"
      (let circle x =
        match Ast0.unwrap x with Ast0.Ecircles(_) -> true | _ -> false in
      let star x =
@@ -9266,7 +9266,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_eexpr_list_option = 
-# 1687 "parser_cocci_menhir.mly"
+# 1688 "parser_cocci_menhir.mly"
                               ( _1 )
 # 9272 "parser_cocci_menhir.ml"
          in
@@ -9283,7 +9283,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
         let _endpos = _startpos in
         let _v : 'tv_eexpr_list_option = 
-# 1688 "parser_cocci_menhir.mly"
+# 1689 "parser_cocci_menhir.mly"
                            ( Ast0.wrap(Ast0.DOTS([])) )
 # 9289 "parser_cocci_menhir.ml"
          in
@@ -9307,7 +9307,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_eexpr_list_start = 
-# 1675 "parser_cocci_menhir.mly"
+# 1676 "parser_cocci_menhir.mly"
           ( [_1] )
 # 9313 "parser_cocci_menhir.ml"
          in
@@ -9347,7 +9347,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_eexpr_list_start = 
-# 1677 "parser_cocci_menhir.mly"
+# 1678 "parser_cocci_menhir.mly"
       ( _1::Ast0.wrap(Ast0.EComma(P.clt2mcode "," _2))::_3 )
 # 9353 "parser_cocci_menhir.ml"
          in
@@ -9391,7 +9391,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__6_ in
         let _v : 'tv_error_words = 
-# 1481 "parser_cocci_menhir.mly"
+# 1482 "parser_cocci_menhir.mly"
       ( [Ast0.wrap(Ast0.ERRORWORDS(cl))] )
 # 9397 "parser_cocci_menhir.ml"
          in
@@ -9526,7 +9526,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_r_ in
         let _endpos = _endpos_r_ in
         let _v : 'tv_expr_dots_TEllipsis_ = 
-# 1311 "parser_cocci_menhir.mly"
+# 1312 "parser_cocci_menhir.mly"
                                                        ( r )
 # 9532 "parser_cocci_menhir.ml"
          in
@@ -9978,7 +9978,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
         let _endpos = _startpos in
         let _v : 'tv_fun_after_dots = 
-# 1596 "parser_cocci_menhir.mly"
+# 1597 "parser_cocci_menhir.mly"
                                ([])
 # 9984 "parser_cocci_menhir.ml"
          in
@@ -10006,7 +10006,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fun_after_dots = 
-# 1597 "parser_cocci_menhir.mly"
+# 1598 "parser_cocci_menhir.mly"
                                (_2)
 # 10012 "parser_cocci_menhir.ml"
          in
@@ -10036,7 +10036,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fun_after_dots = 
-# 1598 "parser_cocci_menhir.mly"
+# 1599 "parser_cocci_menhir.mly"
                                (Ast0.wrap(Ast0.Exp(_1))::_2)
 # 10042 "parser_cocci_menhir.ml"
          in
@@ -10066,7 +10066,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fun_after_dots = 
-# 1599 "parser_cocci_menhir.mly"
+# 1600 "parser_cocci_menhir.mly"
                                     (_1@_2)
 # 10072 "parser_cocci_menhir.ml"
          in
@@ -10083,7 +10083,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
         let _endpos = _startpos in
         let _v : 'tv_fun_after_dots_or = 
-# 1606 "parser_cocci_menhir.mly"
+# 1607 "parser_cocci_menhir.mly"
                                ([])
 # 10089 "parser_cocci_menhir.ml"
          in
@@ -10111,7 +10111,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fun_after_dots_or = 
-# 1607 "parser_cocci_menhir.mly"
+# 1608 "parser_cocci_menhir.mly"
                                (_2)
 # 10117 "parser_cocci_menhir.ml"
          in
@@ -10141,7 +10141,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fun_after_dots_or = 
-# 1608 "parser_cocci_menhir.mly"
+# 1609 "parser_cocci_menhir.mly"
                                (Ast0.wrap(Ast0.Exp(_1))::_2)
 # 10147 "parser_cocci_menhir.ml"
          in
@@ -10171,7 +10171,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fun_after_dots_or = 
-# 1609 "parser_cocci_menhir.mly"
+# 1610 "parser_cocci_menhir.mly"
                                     (_1@_2)
 # 10177 "parser_cocci_menhir.ml"
          in
@@ -10201,7 +10201,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fun_after_exp = 
-# 1602 "parser_cocci_menhir.mly"
+# 1603 "parser_cocci_menhir.mly"
                                (_1::_2)
 # 10207 "parser_cocci_menhir.ml"
          in
@@ -10218,7 +10218,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
         let _endpos = _startpos in
         let _v : 'tv_fun_after_exp_or = 
-# 1612 "parser_cocci_menhir.mly"
+# 1613 "parser_cocci_menhir.mly"
                                ([])
 # 10224 "parser_cocci_menhir.ml"
          in
@@ -10248,7 +10248,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fun_after_exp_or = 
-# 1613 "parser_cocci_menhir.mly"
+# 1614 "parser_cocci_menhir.mly"
                                (_1::_2)
 # 10254 "parser_cocci_menhir.ml"
          in
@@ -10265,7 +10265,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
         let _endpos = _startpos in
         let _v : 'tv_fun_after_stm = 
-# 1591 "parser_cocci_menhir.mly"
+# 1592 "parser_cocci_menhir.mly"
                                ([])
 # 10271 "parser_cocci_menhir.ml"
          in
@@ -10295,7 +10295,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fun_after_stm = 
-# 1592 "parser_cocci_menhir.mly"
+# 1593 "parser_cocci_menhir.mly"
                                (_1::_2)
 # 10301 "parser_cocci_menhir.ml"
          in
@@ -10325,7 +10325,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fun_after_stm = 
-# 1593 "parser_cocci_menhir.mly"
+# 1594 "parser_cocci_menhir.mly"
                                (_1@_2)
 # 10331 "parser_cocci_menhir.ml"
          in
@@ -10349,7 +10349,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_fun_start = 
-# 1588 "parser_cocci_menhir.mly"
+# 1589 "parser_cocci_menhir.mly"
                  ( Ast0.wrap(Ast0.DOTS(_1)) )
 # 10355 "parser_cocci_menhir.ml"
          in
@@ -10373,7 +10373,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_func_ident = 
-# 1400 "parser_cocci_menhir.mly"
+# 1401 "parser_cocci_menhir.mly"
          ( Ast0.wrap(Ast0.Id(P.id2mcode _1)) )
 # 10379 "parser_cocci_menhir.ml"
          in
@@ -10401,7 +10401,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_func_ident = 
-# 1402 "parser_cocci_menhir.mly"
+# 1403 "parser_cocci_menhir.mly"
          ( let (nm,constraints,pure,clt) = _1 in
         Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) )
 # 10408 "parser_cocci_menhir.ml"
@@ -10430,7 +10430,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_func_ident = 
-# 1405 "parser_cocci_menhir.mly"
+# 1406 "parser_cocci_menhir.mly"
          ( let (nm,constraints,pure,clt) = _1 in
         Ast0.wrap(Ast0.MetaFunc(P.clt2mcode nm clt,constraints,pure)) )
 # 10437 "parser_cocci_menhir.ml"
@@ -10459,7 +10459,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_func_ident = 
-# 1408 "parser_cocci_menhir.mly"
+# 1409 "parser_cocci_menhir.mly"
   ( let (nm,constraints,pure,clt) = _1 in
         Ast0.wrap
           (Ast0.MetaLocalFunc(P.clt2mcode nm clt,constraints,pure)) )
@@ -11625,7 +11625,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_ident = 
-# 1413 "parser_cocci_menhir.mly"
+# 1414 "parser_cocci_menhir.mly"
          ( Ast0.wrap(Ast0.Id(P.id2mcode _1)) )
 # 11631 "parser_cocci_menhir.ml"
          in
@@ -11653,7 +11653,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_ident = 
-# 1415 "parser_cocci_menhir.mly"
+# 1416 "parser_cocci_menhir.mly"
          ( let (nm,constraints,pure,clt) = _1 in
          Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) )
 # 11660 "parser_cocci_menhir.ml"
@@ -11678,7 +11678,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_i_ in
         let _endpos = _endpos_i_ in
         let _v : 'tv_ident_or_const = 
-# 1371 "parser_cocci_menhir.mly"
+# 1372 "parser_cocci_menhir.mly"
                     ( Ast0.wrap(Ast0.Ident(Ast0.wrap(Ast0.Id(P.id2mcode i)))) )
 # 11684 "parser_cocci_menhir.ml"
          in
@@ -11706,7 +11706,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_ident_or_const = 
-# 1373 "parser_cocci_menhir.mly"
+# 1374 "parser_cocci_menhir.mly"
   ( let (x,clt) = _1 in
         Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) )
 # 11713 "parser_cocci_menhir.ml"
@@ -12646,7 +12646,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_iso_ctype_ = 
-# 1756 "parser_cocci_menhir.mly"
+# 1757 "parser_cocci_menhir.mly"
                 ( Common.Left t )
 # 12652 "parser_cocci_menhir.ml"
          in
@@ -12674,7 +12674,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_iso_ctype_ = 
-# 1757 "parser_cocci_menhir.mly"
+# 1758 "parser_cocci_menhir.mly"
                      ( Common.Right t )
 # 12680 "parser_cocci_menhir.ml"
          in
@@ -12702,7 +12702,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_iso_decl_var_ = 
-# 1756 "parser_cocci_menhir.mly"
+# 1757 "parser_cocci_menhir.mly"
                 ( Common.Left t )
 # 12708 "parser_cocci_menhir.ml"
          in
@@ -12730,7 +12730,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_iso_decl_var_ = 
-# 1757 "parser_cocci_menhir.mly"
+# 1758 "parser_cocci_menhir.mly"
                      ( Common.Right t )
 # 12736 "parser_cocci_menhir.ml"
          in
@@ -12758,7 +12758,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_iso_dexpr_ = 
-# 1756 "parser_cocci_menhir.mly"
+# 1757 "parser_cocci_menhir.mly"
                 ( Common.Left t )
 # 12764 "parser_cocci_menhir.ml"
          in
@@ -12786,7 +12786,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_iso_dexpr_ = 
-# 1757 "parser_cocci_menhir.mly"
+# 1758 "parser_cocci_menhir.mly"
                      ( Common.Right t )
 # 12792 "parser_cocci_menhir.ml"
          in
@@ -12814,7 +12814,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_iso_nest_start_ = 
-# 1756 "parser_cocci_menhir.mly"
+# 1757 "parser_cocci_menhir.mly"
                 ( Common.Left t )
 # 12820 "parser_cocci_menhir.ml"
          in
@@ -12842,7 +12842,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_iso_nest_start_ = 
-# 1757 "parser_cocci_menhir.mly"
+# 1758 "parser_cocci_menhir.mly"
                      ( Common.Right t )
 # 12848 "parser_cocci_menhir.ml"
          in
@@ -12870,7 +12870,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_iso_single_statement_ = 
-# 1756 "parser_cocci_menhir.mly"
+# 1757 "parser_cocci_menhir.mly"
                 ( Common.Left t )
 # 12876 "parser_cocci_menhir.ml"
          in
@@ -12898,7 +12898,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_iso_single_statement_ = 
-# 1757 "parser_cocci_menhir.mly"
+# 1758 "parser_cocci_menhir.mly"
                      ( Common.Right t )
 # 12904 "parser_cocci_menhir.ml"
          in
@@ -12940,7 +12940,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       (Ast0_cocci.anything list list)
 # 12942 "parser_cocci_menhir.ml"
         ) = 
-# 1728 "parser_cocci_menhir.mly"
+# 1729 "parser_cocci_menhir.mly"
     ( P.iso_adjust (function x -> Ast0.ExprTag x) e1 el )
 # 12946 "parser_cocci_menhir.ml"
          in
@@ -12982,7 +12982,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       (Ast0_cocci.anything list list)
 # 12984 "parser_cocci_menhir.ml"
         ) = 
-# 1730 "parser_cocci_menhir.mly"
+# 1731 "parser_cocci_menhir.mly"
     ( P.iso_adjust (function x -> Ast0.ArgExprTag x) e1 el )
 # 12988 "parser_cocci_menhir.ml"
          in
@@ -13024,7 +13024,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       (Ast0_cocci.anything list list)
 # 13026 "parser_cocci_menhir.ml"
         ) = 
-# 1732 "parser_cocci_menhir.mly"
+# 1733 "parser_cocci_menhir.mly"
     ( P.iso_adjust (function x -> Ast0.TestExprTag x) e1 el )
 # 13030 "parser_cocci_menhir.ml"
          in
@@ -13066,7 +13066,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       (Ast0_cocci.anything list list)
 # 13068 "parser_cocci_menhir.ml"
         ) = 
-# 1734 "parser_cocci_menhir.mly"
+# 1735 "parser_cocci_menhir.mly"
     ( P.iso_adjust (function x -> Ast0.StmtTag x) s1 sl )
 # 13072 "parser_cocci_menhir.ml"
          in
@@ -13108,7 +13108,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       (Ast0_cocci.anything list list)
 # 13110 "parser_cocci_menhir.ml"
         ) = 
-# 1736 "parser_cocci_menhir.mly"
+# 1737 "parser_cocci_menhir.mly"
     ( P.iso_adjust (function x -> Ast0.TypeCTag x) t1 tl )
 # 13114 "parser_cocci_menhir.ml"
          in
@@ -13150,7 +13150,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       (Ast0_cocci.anything list list)
 # 13152 "parser_cocci_menhir.ml"
         ) = 
-# 1738 "parser_cocci_menhir.mly"
+# 1739 "parser_cocci_menhir.mly"
     ( P.iso_adjust (function x -> Ast0.DotsStmtTag x) e1 el )
 # 13156 "parser_cocci_menhir.ml"
          in
@@ -13192,7 +13192,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       (Ast0_cocci.anything list list)
 # 13194 "parser_cocci_menhir.ml"
         ) = 
-# 1740 "parser_cocci_menhir.mly"
+# 1741 "parser_cocci_menhir.mly"
     ( let check_one = function
        [x] -> x
       | _ ->
@@ -13293,7 +13293,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_iter_ident = 
-# 1427 "parser_cocci_menhir.mly"
+# 1428 "parser_cocci_menhir.mly"
          ( Ast0.wrap(Ast0.Id(P.id2mcode _1)) )
 # 13299 "parser_cocci_menhir.ml"
          in
@@ -13321,7 +13321,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_iter_ident = 
-# 1429 "parser_cocci_menhir.mly"
+# 1430 "parser_cocci_menhir.mly"
          ( let (nm,constraints,pure,clt) = _1 in
          Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) )
 # 13328 "parser_cocci_menhir.ml"
@@ -14793,7 +14793,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_meta_ident = 
-# 1325 "parser_cocci_menhir.mly"
+# 1326 "parser_cocci_menhir.mly"
                                  ( (Some _1,P.id2name _3) )
 # 14799 "parser_cocci_menhir.ml"
          in
@@ -16517,7 +16517,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_midzero_list_ctype_ctype_ = 
-# 1698 "parser_cocci_menhir.mly"
+# 1699 "parser_cocci_menhir.mly"
      ( let (mids,code) = List.split b in (mids,(a::code)) )
 # 16523 "parser_cocci_menhir.ml"
          in
@@ -16547,7 +16547,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_midzero_list_eexpr_eexpr_ = 
-# 1698 "parser_cocci_menhir.mly"
+# 1699 "parser_cocci_menhir.mly"
      ( let (mids,code) = List.split b in (mids,(a::code)) )
 # 16553 "parser_cocci_menhir.ml"
          in
@@ -16577,7 +16577,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_midzero_list_expr_eexpr_ = 
-# 1698 "parser_cocci_menhir.mly"
+# 1699 "parser_cocci_menhir.mly"
      ( let (mids,code) = List.split b in (mids,(a::code)) )
 # 16583 "parser_cocci_menhir.ml"
          in
@@ -16607,7 +16607,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_midzero_list_fun_after_stm_fun_after_dots_or_ = 
-# 1698 "parser_cocci_menhir.mly"
+# 1699 "parser_cocci_menhir.mly"
      ( let (mids,code) = List.split b in (mids,(a::code)) )
 # 16613 "parser_cocci_menhir.ml"
          in
@@ -16637,7 +16637,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_midzero_list_fun_start_fun_start_ = 
-# 1698 "parser_cocci_menhir.mly"
+# 1699 "parser_cocci_menhir.mly"
      ( let (mids,code) = List.split b in (mids,(a::code)) )
 # 16643 "parser_cocci_menhir.ml"
          in
@@ -16667,7 +16667,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_midzero_list_rule_elem_statement_rule_elem_statement_ = 
-# 1698 "parser_cocci_menhir.mly"
+# 1699 "parser_cocci_menhir.mly"
      ( let (mids,code) = List.split b in (mids,(a::code)) )
 # 16673 "parser_cocci_menhir.ml"
          in
@@ -16697,7 +16697,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_midzero_list_statement_statement_ = 
-# 1698 "parser_cocci_menhir.mly"
+# 1699 "parser_cocci_menhir.mly"
      ( let (mids,code) = List.split b in (mids,(a::code)) )
 # 16703 "parser_cocci_menhir.ml"
          in
@@ -16989,7 +16989,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_minus_start = 
-# 1514 "parser_cocci_menhir.mly"
+# 1515 "parser_cocci_menhir.mly"
                          ( [Ast0.wrap(Ast0.DECL(_1))] )
 # 16995 "parser_cocci_menhir.ml"
          in
@@ -17013,7 +17013,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_minus_start = 
-# 1515 "parser_cocci_menhir.mly"
+# 1516 "parser_cocci_menhir.mly"
                          ( [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Ty(_1))))] )
 # 17019 "parser_cocci_menhir.ml"
          in
@@ -17037,7 +17037,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_minus_start = 
-# 1516 "parser_cocci_menhir.mly"
+# 1517 "parser_cocci_menhir.mly"
                     ( [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.TopInit(_1))))] )
 # 17043 "parser_cocci_menhir.ml"
          in
@@ -17061,7 +17061,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_minus_start = 
-# 1518 "parser_cocci_menhir.mly"
+# 1519 "parser_cocci_menhir.mly"
     ( List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) _1 )
 # 17067 "parser_cocci_menhir.ml"
          in
@@ -17095,7 +17095,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_mzl_ctype_ = 
-# 1701 "parser_cocci_menhir.mly"
+# 1702 "parser_cocci_menhir.mly"
                  ( (P.clt2mcode "|" a, b) )
 # 17101 "parser_cocci_menhir.ml"
          in
@@ -17129,7 +17129,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_mzl_eexpr_ = 
-# 1701 "parser_cocci_menhir.mly"
+# 1702 "parser_cocci_menhir.mly"
                  ( (P.clt2mcode "|" a, b) )
 # 17135 "parser_cocci_menhir.ml"
          in
@@ -17163,7 +17163,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_mzl_fun_after_dots_or_ = 
-# 1701 "parser_cocci_menhir.mly"
+# 1702 "parser_cocci_menhir.mly"
                  ( (P.clt2mcode "|" a, b) )
 # 17169 "parser_cocci_menhir.ml"
          in
@@ -17197,7 +17197,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_mzl_fun_start_ = 
-# 1701 "parser_cocci_menhir.mly"
+# 1702 "parser_cocci_menhir.mly"
                  ( (P.clt2mcode "|" a, b) )
 # 17203 "parser_cocci_menhir.ml"
          in
@@ -17231,7 +17231,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_mzl_rule_elem_statement_ = 
-# 1701 "parser_cocci_menhir.mly"
+# 1702 "parser_cocci_menhir.mly"
                  ( (P.clt2mcode "|" a, b) )
 # 17237 "parser_cocci_menhir.ml"
          in
@@ -17265,7 +17265,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_mzl_statement_ = 
-# 1701 "parser_cocci_menhir.mly"
+# 1702 "parser_cocci_menhir.mly"
                  ( (P.clt2mcode "|" a, b) )
 # 17271 "parser_cocci_menhir.ml"
          in
@@ -17428,7 +17428,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_nest_after_dots = 
-# 1622 "parser_cocci_menhir.mly"
+# 1623 "parser_cocci_menhir.mly"
                                      (_1@_2)
 # 17434 "parser_cocci_menhir.ml"
          in
@@ -17456,7 +17456,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_nest_after_dots = 
-# 1623 "parser_cocci_menhir.mly"
+# 1624 "parser_cocci_menhir.mly"
                                 (_2)
 # 17462 "parser_cocci_menhir.ml"
          in
@@ -17486,7 +17486,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_nest_after_dots = 
-# 1624 "parser_cocci_menhir.mly"
+# 1625 "parser_cocci_menhir.mly"
                                 ((Ast0.wrap(Ast0.Exp(_1)))::_2)
 # 17492 "parser_cocci_menhir.ml"
          in
@@ -17503,7 +17503,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
         let _endpos = _startpos in
         let _v : 'tv_nest_after_exp = 
-# 1632 "parser_cocci_menhir.mly"
+# 1633 "parser_cocci_menhir.mly"
                                 ([])
 # 17509 "parser_cocci_menhir.ml"
          in
@@ -17533,7 +17533,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_nest_after_exp = 
-# 1633 "parser_cocci_menhir.mly"
+# 1634 "parser_cocci_menhir.mly"
                                 (_1::_2)
 # 17539 "parser_cocci_menhir.ml"
          in
@@ -17550,7 +17550,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
         let _endpos = _startpos in
         let _v : 'tv_nest_after_stm = 
-# 1627 "parser_cocci_menhir.mly"
+# 1628 "parser_cocci_menhir.mly"
                                 ([])
 # 17556 "parser_cocci_menhir.ml"
          in
@@ -17580,7 +17580,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_nest_after_stm = 
-# 1628 "parser_cocci_menhir.mly"
+# 1629 "parser_cocci_menhir.mly"
                                 (_1::_2)
 # 17586 "parser_cocci_menhir.ml"
          in
@@ -17610,7 +17610,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_nest_after_stm = 
-# 1629 "parser_cocci_menhir.mly"
+# 1630 "parser_cocci_menhir.mly"
                                 (_1@_2)
 # 17616 "parser_cocci_menhir.ml"
          in
@@ -17632,39 +17632,33 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             MenhirLib.EngineTypes.startp = _startpos_e_;
             MenhirLib.EngineTypes.endp = _endpos_e_;
             MenhirLib.EngineTypes.next = {
-              MenhirLib.EngineTypes.semv = w;
-              MenhirLib.EngineTypes.startp = _startpos_w_;
-              MenhirLib.EngineTypes.endp = _endpos_w_;
-              MenhirLib.EngineTypes.next = {
-                MenhirLib.EngineTypes.state = _menhir_s;
-                MenhirLib.EngineTypes.semv = _1;
-                MenhirLib.EngineTypes.startp = _startpos__1_;
-                MenhirLib.EngineTypes.endp = _endpos__1_;
-                MenhirLib.EngineTypes.next = _menhir_stack;
-                };
+              MenhirLib.EngineTypes.state = _menhir_s;
+              MenhirLib.EngineTypes.semv = _1;
+              MenhirLib.EngineTypes.startp = _startpos__1_;
+              MenhirLib.EngineTypes.endp = _endpos__1_;
+              MenhirLib.EngineTypes.next = _menhir_stack;
               };
             };
           } = _menhir_stack in
         let c : (
 # 72 "parser_cocci_menhir.mly"
        (Data.clt)
-# 17652 "parser_cocci_menhir.ml"
+# 17647 "parser_cocci_menhir.ml"
         ) = Obj.magic c in
         let e : 'tv_expr_dots_TEllipsis_ = Obj.magic e in
-        let w : 'tv_option_whenexp_ = Obj.magic w in
         let _1 : (
 # 72 "parser_cocci_menhir.mly"
        (Data.clt)
-# 17659 "parser_cocci_menhir.ml"
+# 17653 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_c_ in
         let _v : 'tv_nest_expressions = 
-# 1148 "parser_cocci_menhir.mly"
+# 1149 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.NestExpr(P.clt2mcode "<..." _1,
                              Ast0.wrap(Ast0.DOTS(e (P.mkedots "..."))),
-                             P.clt2mcode "...>" c, w, false)) )
-# 17668 "parser_cocci_menhir.ml"
+                             P.clt2mcode "...>" c, None, false)) )
+# 17662 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17684,39 +17678,33 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             MenhirLib.EngineTypes.startp = _startpos_e_;
             MenhirLib.EngineTypes.endp = _endpos_e_;
             MenhirLib.EngineTypes.next = {
-              MenhirLib.EngineTypes.semv = w;
-              MenhirLib.EngineTypes.startp = _startpos_w_;
-              MenhirLib.EngineTypes.endp = _endpos_w_;
-              MenhirLib.EngineTypes.next = {
-                MenhirLib.EngineTypes.state = _menhir_s;
-                MenhirLib.EngineTypes.semv = _1;
-                MenhirLib.EngineTypes.startp = _startpos__1_;
-                MenhirLib.EngineTypes.endp = _endpos__1_;
-                MenhirLib.EngineTypes.next = _menhir_stack;
-                };
+              MenhirLib.EngineTypes.state = _menhir_s;
+              MenhirLib.EngineTypes.semv = _1;
+              MenhirLib.EngineTypes.startp = _startpos__1_;
+              MenhirLib.EngineTypes.endp = _endpos__1_;
+              MenhirLib.EngineTypes.next = _menhir_stack;
               };
             };
           } = _menhir_stack in
         let c : (
 # 72 "parser_cocci_menhir.mly"
        (Data.clt)
-# 17704 "parser_cocci_menhir.ml"
+# 17693 "parser_cocci_menhir.ml"
         ) = Obj.magic c in
         let e : 'tv_expr_dots_TEllipsis_ = Obj.magic e in
-        let w : 'tv_option_whenexp_ = Obj.magic w in
         let _1 : (
 # 72 "parser_cocci_menhir.mly"
        (Data.clt)
-# 17711 "parser_cocci_menhir.ml"
+# 17699 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_c_ in
         let _v : 'tv_nest_expressions = 
-# 1152 "parser_cocci_menhir.mly"
+# 1153 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.NestExpr(P.clt2mcode "<+..." _1,
                              Ast0.wrap(Ast0.DOTS(e (P.mkedots "..."))),
-                             P.clt2mcode "...+>" c, w, true)) )
-# 17720 "parser_cocci_menhir.ml"
+                             P.clt2mcode "...+>" c, None, true)) )
+# 17708 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17738,9 +17726,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_nest_start = 
-# 1619 "parser_cocci_menhir.mly"
+# 1620 "parser_cocci_menhir.mly"
                    ( Ast0.wrap(Ast0.DOTS(_1)) )
-# 17744 "parser_cocci_menhir.ml"
+# 17732 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17762,11 +17750,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 167 "parser_cocci_menhir.mly"
       (unit)
-# 17766 "parser_cocci_menhir.ml"
+# 17754 "parser_cocci_menhir.ml"
         ) = 
-# 1764 "parser_cocci_menhir.mly"
+# 1765 "parser_cocci_menhir.mly"
                     ( () )
-# 17770 "parser_cocci_menhir.ml"
+# 17758 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17792,11 +17780,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 167 "parser_cocci_menhir.mly"
       (unit)
-# 17796 "parser_cocci_menhir.ml"
+# 17784 "parser_cocci_menhir.ml"
         ) = 
-# 1765 "parser_cocci_menhir.mly"
+# 1766 "parser_cocci_menhir.mly"
                     ( () )
-# 17800 "parser_cocci_menhir.ml"
+# 17788 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17818,11 +17806,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 167 "parser_cocci_menhir.mly"
       (unit)
-# 17822 "parser_cocci_menhir.ml"
+# 17810 "parser_cocci_menhir.ml"
         ) = 
-# 1766 "parser_cocci_menhir.mly"
+# 1767 "parser_cocci_menhir.mly"
                     ( () )
-# 17826 "parser_cocci_menhir.ml"
+# 17814 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17850,10 +17838,10 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_g_ in
         let _endpos = _endpos_dg_ in
         let _v : 'tv_no_dot_start_end_dexpr_edots_when_TEllipsis_eexpr__ = 
-# 1316 "parser_cocci_menhir.mly"
+# 1317 "parser_cocci_menhir.mly"
   ( function dot_builder ->
       g :: (List.concat(List.map (function (d,g) -> [dot_builder d;g]) dg)) )
-# 17857 "parser_cocci_menhir.ml"
+# 17845 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17874,14 +17862,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let x : (
 # 98 "parser_cocci_menhir.mly"
        (Data.clt)
-# 17878 "parser_cocci_menhir.ml"
+# 17866 "parser_cocci_menhir.ml"
         ) = Obj.magic x in
         let _startpos = _startpos_x_ in
         let _endpos = _endpos_x_ in
         let _v : 'tv_nonempty_list_TMul_ = 
 # 124 "standard.mly"
     ( [ x ] )
-# 17885 "parser_cocci_menhir.ml"
+# 17873 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17908,14 +17896,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let x : (
 # 98 "parser_cocci_menhir.mly"
        (Data.clt)
-# 17912 "parser_cocci_menhir.ml"
+# 17900 "parser_cocci_menhir.ml"
         ) = Obj.magic x in
         let _startpos = _startpos_x_ in
         let _endpos = _endpos_xs_ in
         let _v : 'tv_nonempty_list_TMul_ = 
 # 126 "standard.mly"
     ( x :: xs )
-# 17919 "parser_cocci_menhir.ml"
+# 17907 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17941,11 +17929,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_i_ in
         let _v : 'tv_not_ceq = 
-# 1362 "parser_cocci_menhir.mly"
+# 1363 "parser_cocci_menhir.mly"
          ( (if !Data.in_iso
           then failwith "constraints not allowed in iso file");
           [i] )
-# 17949 "parser_cocci_menhir.ml"
+# 17937 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17979,11 +17967,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__4_ in
         let _v : 'tv_not_ceq = 
-# 1366 "parser_cocci_menhir.mly"
+# 1367 "parser_cocci_menhir.mly"
   ( (if !Data.in_iso
           then failwith "constraints not allowed in iso file");
           l )
-# 17987 "parser_cocci_menhir.ml"
+# 17975 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18009,11 +17997,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_i_ in
         let _v : 'tv_not_eq = 
-# 1339 "parser_cocci_menhir.mly"
+# 1340 "parser_cocci_menhir.mly"
          ( (if !Data.in_iso
           then failwith "constraints not allowed in iso file");
           [Ast0.wrap(Ast0.Id(P.id2mcode i))] )
-# 18017 "parser_cocci_menhir.ml"
+# 18005 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18047,11 +18035,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__4_ in
         let _v : 'tv_not_eq = 
-# 1343 "parser_cocci_menhir.mly"
+# 1344 "parser_cocci_menhir.mly"
   ( (if !Data.in_iso
           then failwith "constraints not allowed in iso file");
           List.map (function i -> Ast0.wrap(Ast0.Id(P.id2mcode i))) l )
-# 18055 "parser_cocci_menhir.ml"
+# 18043 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18077,11 +18065,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_i_ in
         let _v : 'tv_not_eqe = 
-# 1349 "parser_cocci_menhir.mly"
+# 1350 "parser_cocci_menhir.mly"
          ( (if !Data.in_iso
           then failwith "constraints not allowed in iso file");
           [Ast0.wrap(Ast0.Ident(Ast0.wrap(Ast0.Id(P.id2mcode i))))] )
-# 18085 "parser_cocci_menhir.ml"
+# 18073 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18115,14 +18103,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__4_ in
         let _v : 'tv_not_eqe = 
-# 1353 "parser_cocci_menhir.mly"
+# 1354 "parser_cocci_menhir.mly"
   ( (if !Data.in_iso
           then failwith "constraints not allowed in iso file");
           List.map
             (function i ->
               Ast0.wrap(Ast0.Ident(Ast0.wrap(Ast0.Id(P.id2mcode i)))))
             l )
-# 18126 "parser_cocci_menhir.ml"
+# 18114 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18148,7 +18136,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_i_ in
         let _v : 'tv_not_pos = 
-# 1378 "parser_cocci_menhir.mly"
+# 1379 "parser_cocci_menhir.mly"
          ( (if !Data.in_iso
           then failwith "constraints not allowed in iso file");
           match i with
@@ -18157,7 +18145,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
               let i = (rule,name) in
               P.check_meta(Ast.MetaPosDecl(Ast.NONE,i));
               [i] )
-# 18161 "parser_cocci_menhir.ml"
+# 18149 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18191,7 +18179,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__4_ in
         let _v : 'tv_not_pos = 
-# 1387 "parser_cocci_menhir.mly"
+# 1388 "parser_cocci_menhir.mly"
   ( (if !Data.in_iso
           then failwith "constraints not allowed in iso file");
           List.map
@@ -18203,7 +18191,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
                   P.check_meta(Ast.MetaPosDecl(Ast.NONE,i));
                   i)
             l )
-# 18207 "parser_cocci_menhir.ml"
+# 18195 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18225,9 +18213,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_one_dec_decl_ = 
-# 1458 "parser_cocci_menhir.mly"
+# 1459 "parser_cocci_menhir.mly"
         ( _1 )
-# 18231 "parser_cocci_menhir.ml"
+# 18219 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18248,12 +18236,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 65 "parser_cocci_menhir.mly"
        (Parse_aux.list_info)
-# 18252 "parser_cocci_menhir.ml"
+# 18240 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_one_dec_decl_ = 
-# 1460 "parser_cocci_menhir.mly"
+# 1461 "parser_cocci_menhir.mly"
     ( let (nm,lenname,pure,clt) = _1 in
     let nm = P.clt2mcode nm clt in
     let lenname =
@@ -18261,7 +18249,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
        Some nm -> Some(P.clt2mcode nm clt)
       | None -> None in
     Ast0.wrap(Ast0.MetaParamList(nm,lenname,pure)) )
-# 18265 "parser_cocci_menhir.ml"
+# 18253 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18283,9 +18271,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_one_dec_name_opt_decl_ = 
-# 1458 "parser_cocci_menhir.mly"
+# 1459 "parser_cocci_menhir.mly"
         ( _1 )
-# 18289 "parser_cocci_menhir.ml"
+# 18277 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18306,12 +18294,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 65 "parser_cocci_menhir.mly"
        (Parse_aux.list_info)
-# 18310 "parser_cocci_menhir.ml"
+# 18298 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_one_dec_name_opt_decl_ = 
-# 1460 "parser_cocci_menhir.mly"
+# 1461 "parser_cocci_menhir.mly"
     ( let (nm,lenname,pure,clt) = _1 in
     let nm = P.clt2mcode nm clt in
     let lenname =
@@ -18319,7 +18307,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
        Some nm -> Some(P.clt2mcode nm clt)
       | None -> None in
     Ast0.wrap(Ast0.MetaParamList(nm,lenname,pure)) )
-# 18323 "parser_cocci_menhir.ml"
+# 18311 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18345,7 +18333,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18349 "parser_cocci_menhir.ml"
+# 18337 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let t : 'tv_ctype = Obj.magic t in
         let _startpos = _startpos_t_ in
@@ -18353,7 +18341,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_one_decl_var = 
 # 944 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.TyDecl(t,P.clt2mcode ";" pv)) )
-# 18357 "parser_cocci_menhir.ml"
+# 18345 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18384,7 +18372,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18388 "parser_cocci_menhir.ml"
+# 18376 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let d : 'tv_d_ident = Obj.magic d in
         let t : 'tv_ctype = Obj.magic t in
@@ -18394,14 +18382,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 39 "standard.mly"
     ( None )
-# 18398 "parser_cocci_menhir.ml"
+# 18386 "parser_cocci_menhir.ml"
           
         in
         
 # 946 "parser_cocci_menhir.mly"
       ( let (id,fn) = d in
         Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv)) )
-# 18405 "parser_cocci_menhir.ml"
+# 18393 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18437,7 +18425,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18441 "parser_cocci_menhir.ml"
+# 18429 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let d : 'tv_d_ident = Obj.magic d in
         let t : 'tv_ctype = Obj.magic t in
@@ -18449,14 +18437,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 18453 "parser_cocci_menhir.ml"
+# 18441 "parser_cocci_menhir.ml"
           
         in
         
 # 946 "parser_cocci_menhir.mly"
       ( let (id,fn) = d in
         Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv)) )
-# 18460 "parser_cocci_menhir.ml"
+# 18448 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18480,7 +18468,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_one_decl_var = 
 # 948 "parser_cocci_menhir.mly"
                ( f )
-# 18484 "parser_cocci_menhir.ml"
+# 18472 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18521,13 +18509,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18525 "parser_cocci_menhir.ml"
+# 18513 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let e : 'tv_initialize = Obj.magic e in
         let q : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18531 "parser_cocci_menhir.ml"
+# 18519 "parser_cocci_menhir.ml"
         ) = Obj.magic q in
         let d : 'tv_d_ident = Obj.magic d in
         let t : 'tv_ctype = Obj.magic t in
@@ -18537,14 +18525,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 39 "standard.mly"
     ( None )
-# 18541 "parser_cocci_menhir.ml"
+# 18529 "parser_cocci_menhir.ml"
           
         in
         
 # 950 "parser_cocci_menhir.mly"
       ( let (id,fn) = d in
       Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv)) )
-# 18548 "parser_cocci_menhir.ml"
+# 18536 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18590,13 +18578,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18594 "parser_cocci_menhir.ml"
+# 18582 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let e : 'tv_initialize = Obj.magic e in
         let q : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18600 "parser_cocci_menhir.ml"
+# 18588 "parser_cocci_menhir.ml"
         ) = Obj.magic q in
         let d : 'tv_d_ident = Obj.magic d in
         let t : 'tv_ctype = Obj.magic t in
@@ -18608,14 +18596,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 18612 "parser_cocci_menhir.ml"
+# 18600 "parser_cocci_menhir.ml"
           
         in
         
 # 950 "parser_cocci_menhir.mly"
       ( let (id,fn) = d in
       Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv)) )
-# 18619 "parser_cocci_menhir.ml"
+# 18607 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18646,7 +18634,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18650 "parser_cocci_menhir.ml"
+# 18638 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let d : 'tv_d_ident = Obj.magic d in
         let i : 'tv_pure_ident = Obj.magic i in
@@ -18656,14 +18644,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 39 "standard.mly"
     ( None )
-# 18660 "parser_cocci_menhir.ml"
+# 18648 "parser_cocci_menhir.ml"
           
         in
         let s =
           
 # 39 "standard.mly"
     ( None )
-# 18667 "parser_cocci_menhir.ml"
+# 18655 "parser_cocci_menhir.ml"
           
         in
         
@@ -18671,7 +18659,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       ( let (id,fn) = d in
         let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
        Ast0.wrap(Ast0.UnInit(s,fn idtype,id,P.clt2mcode ";" pv)) )
-# 18675 "parser_cocci_menhir.ml"
+# 18663 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18707,7 +18695,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18711 "parser_cocci_menhir.ml"
+# 18699 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let d : 'tv_d_ident = Obj.magic d in
         let i : 'tv_pure_ident = Obj.magic i in
@@ -18719,14 +18707,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 18723 "parser_cocci_menhir.ml"
+# 18711 "parser_cocci_menhir.ml"
           
         in
         let s =
           
 # 39 "standard.mly"
     ( None )
-# 18730 "parser_cocci_menhir.ml"
+# 18718 "parser_cocci_menhir.ml"
           
         in
         
@@ -18734,7 +18722,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       ( let (id,fn) = d in
         let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
        Ast0.wrap(Ast0.UnInit(s,fn idtype,id,P.clt2mcode ";" pv)) )
-# 18738 "parser_cocci_menhir.ml"
+# 18726 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18770,7 +18758,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18774 "parser_cocci_menhir.ml"
+# 18762 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let d : 'tv_d_ident = Obj.magic d in
         let i : 'tv_pure_ident = Obj.magic i in
@@ -18781,7 +18769,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 39 "standard.mly"
     ( None )
-# 18785 "parser_cocci_menhir.ml"
+# 18773 "parser_cocci_menhir.ml"
           
         in
         let s =
@@ -18789,7 +18777,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 18793 "parser_cocci_menhir.ml"
+# 18781 "parser_cocci_menhir.ml"
           
         in
         
@@ -18797,7 +18785,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       ( let (id,fn) = d in
         let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
        Ast0.wrap(Ast0.UnInit(s,fn idtype,id,P.clt2mcode ";" pv)) )
-# 18801 "parser_cocci_menhir.ml"
+# 18789 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18838,7 +18826,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18842 "parser_cocci_menhir.ml"
+# 18830 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let d : 'tv_d_ident = Obj.magic d in
         let i : 'tv_pure_ident = Obj.magic i in
@@ -18851,7 +18839,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 18855 "parser_cocci_menhir.ml"
+# 18843 "parser_cocci_menhir.ml"
           
         in
         let s =
@@ -18859,7 +18847,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 18863 "parser_cocci_menhir.ml"
+# 18851 "parser_cocci_menhir.ml"
           
         in
         
@@ -18867,7 +18855,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       ( let (id,fn) = d in
         let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
        Ast0.wrap(Ast0.UnInit(s,fn idtype,id,P.clt2mcode ";" pv)) )
-# 18871 "parser_cocci_menhir.ml"
+# 18859 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18908,13 +18896,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18912 "parser_cocci_menhir.ml"
+# 18900 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let e : 'tv_initialize = Obj.magic e in
         let q : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18918 "parser_cocci_menhir.ml"
+# 18906 "parser_cocci_menhir.ml"
         ) = Obj.magic q in
         let d : 'tv_d_ident = Obj.magic d in
         let i : 'tv_pure_ident = Obj.magic i in
@@ -18924,14 +18912,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 39 "standard.mly"
     ( None )
-# 18928 "parser_cocci_menhir.ml"
+# 18916 "parser_cocci_menhir.ml"
           
         in
         let s =
           
 # 39 "standard.mly"
     ( None )
-# 18935 "parser_cocci_menhir.ml"
+# 18923 "parser_cocci_menhir.ml"
           
         in
         
@@ -18941,7 +18929,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
       Ast0.wrap(Ast0.Init(s,fn idtype,id,P.clt2mcode "=" q,e,
                           P.clt2mcode ";" pv)) )
-# 18945 "parser_cocci_menhir.ml"
+# 18933 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18987,13 +18975,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18991 "parser_cocci_menhir.ml"
+# 18979 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let e : 'tv_initialize = Obj.magic e in
         let q : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18997 "parser_cocci_menhir.ml"
+# 18985 "parser_cocci_menhir.ml"
         ) = Obj.magic q in
         let d : 'tv_d_ident = Obj.magic d in
         let i : 'tv_pure_ident = Obj.magic i in
@@ -19005,14 +18993,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 19009 "parser_cocci_menhir.ml"
+# 18997 "parser_cocci_menhir.ml"
           
         in
         let s =
           
 # 39 "standard.mly"
     ( None )
-# 19016 "parser_cocci_menhir.ml"
+# 19004 "parser_cocci_menhir.ml"
           
         in
         
@@ -19022,7 +19010,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
       Ast0.wrap(Ast0.Init(s,fn idtype,id,P.clt2mcode "=" q,e,
                           P.clt2mcode ";" pv)) )
-# 19026 "parser_cocci_menhir.ml"
+# 19014 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19068,13 +19056,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19072 "parser_cocci_menhir.ml"
+# 19060 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let e : 'tv_initialize = Obj.magic e in
         let q : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19078 "parser_cocci_menhir.ml"
+# 19066 "parser_cocci_menhir.ml"
         ) = Obj.magic q in
         let d : 'tv_d_ident = Obj.magic d in
         let i : 'tv_pure_ident = Obj.magic i in
@@ -19085,7 +19073,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 39 "standard.mly"
     ( None )
-# 19089 "parser_cocci_menhir.ml"
+# 19077 "parser_cocci_menhir.ml"
           
         in
         let s =
@@ -19093,7 +19081,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 19097 "parser_cocci_menhir.ml"
+# 19085 "parser_cocci_menhir.ml"
           
         in
         
@@ -19103,7 +19091,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
       Ast0.wrap(Ast0.Init(s,fn idtype,id,P.clt2mcode "=" q,e,
                           P.clt2mcode ";" pv)) )
-# 19107 "parser_cocci_menhir.ml"
+# 19095 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19154,13 +19142,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19158 "parser_cocci_menhir.ml"
+# 19146 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let e : 'tv_initialize = Obj.magic e in
         let q : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19164 "parser_cocci_menhir.ml"
+# 19152 "parser_cocci_menhir.ml"
         ) = Obj.magic q in
         let d : 'tv_d_ident = Obj.magic d in
         let i : 'tv_pure_ident = Obj.magic i in
@@ -19173,7 +19161,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 19177 "parser_cocci_menhir.ml"
+# 19165 "parser_cocci_menhir.ml"
           
         in
         let s =
@@ -19181,7 +19169,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 19185 "parser_cocci_menhir.ml"
+# 19173 "parser_cocci_menhir.ml"
           
         in
         
@@ -19191,7 +19179,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
       Ast0.wrap(Ast0.Init(s,fn idtype,id,P.clt2mcode "=" q,e,
                           P.clt2mcode ";" pv)) )
-# 19195 "parser_cocci_menhir.ml"
+# 19183 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19252,34 +19240,34 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19256 "parser_cocci_menhir.ml"
+# 19244 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let rp2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19261 "parser_cocci_menhir.ml"
+# 19249 "parser_cocci_menhir.ml"
         ) = Obj.magic rp2 in
         let p : 'tv_decl_list_name_opt_decl_ = Obj.magic p in
         let lp2 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19267 "parser_cocci_menhir.ml"
+# 19255 "parser_cocci_menhir.ml"
         ) = Obj.magic lp2 in
         let rp1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19272 "parser_cocci_menhir.ml"
+# 19260 "parser_cocci_menhir.ml"
         ) = Obj.magic rp1 in
         let d : 'tv_d_ident = Obj.magic d in
         let st : (
 # 98 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19278 "parser_cocci_menhir.ml"
+# 19266 "parser_cocci_menhir.ml"
         ) = Obj.magic st in
         let lp1 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19283 "parser_cocci_menhir.ml"
+# 19271 "parser_cocci_menhir.ml"
         ) = Obj.magic lp1 in
         let t : 'tv_fn_ctype = Obj.magic t in
         let _startpos = _startpos_t_ in
@@ -19288,7 +19276,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 39 "standard.mly"
     ( None )
-# 19292 "parser_cocci_menhir.ml"
+# 19280 "parser_cocci_menhir.ml"
           
         in
         
@@ -19300,7 +19288,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
               (t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
                P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
         Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv)) )
-# 19304 "parser_cocci_menhir.ml"
+# 19292 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19366,34 +19354,34 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19370 "parser_cocci_menhir.ml"
+# 19358 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let rp2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19375 "parser_cocci_menhir.ml"
+# 19363 "parser_cocci_menhir.ml"
         ) = Obj.magic rp2 in
         let p : 'tv_decl_list_name_opt_decl_ = Obj.magic p in
         let lp2 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19381 "parser_cocci_menhir.ml"
+# 19369 "parser_cocci_menhir.ml"
         ) = Obj.magic lp2 in
         let rp1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19386 "parser_cocci_menhir.ml"
+# 19374 "parser_cocci_menhir.ml"
         ) = Obj.magic rp1 in
         let d : 'tv_d_ident = Obj.magic d in
         let st : (
 # 98 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19392 "parser_cocci_menhir.ml"
+# 19380 "parser_cocci_menhir.ml"
         ) = Obj.magic st in
         let lp1 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19397 "parser_cocci_menhir.ml"
+# 19385 "parser_cocci_menhir.ml"
         ) = Obj.magic lp1 in
         let t : 'tv_fn_ctype = Obj.magic t in
         let x0 : 'tv_storage = Obj.magic x0 in
@@ -19404,7 +19392,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 19408 "parser_cocci_menhir.ml"
+# 19396 "parser_cocci_menhir.ml"
           
         in
         
@@ -19416,7 +19404,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
               (t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
                P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
         Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv)) )
-# 19420 "parser_cocci_menhir.ml"
+# 19408 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19457,18 +19445,18 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _5 : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19461 "parser_cocci_menhir.ml"
+# 19449 "parser_cocci_menhir.ml"
         ) = Obj.magic _5 in
         let _4 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19466 "parser_cocci_menhir.ml"
+# 19454 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr_list_option = Obj.magic _3 in
         let _2 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19472 "parser_cocci_menhir.ml"
+# 19460 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_decl_ident = Obj.magic _1 in
         let _startpos = _startpos__1_ in
@@ -19477,7 +19465,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
 # 978 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.MacroDecl(_1,P.clt2mcode "(" _2,_3,
                                  P.clt2mcode ")" _4,P.clt2mcode ";" _5)) )
-# 19481 "parser_cocci_menhir.ml"
+# 19469 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19548,40 +19536,40 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19552 "parser_cocci_menhir.ml"
+# 19540 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let e : 'tv_initialize = Obj.magic e in
         let q : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19558 "parser_cocci_menhir.ml"
+# 19546 "parser_cocci_menhir.ml"
         ) = Obj.magic q in
         let rp2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19563 "parser_cocci_menhir.ml"
+# 19551 "parser_cocci_menhir.ml"
         ) = Obj.magic rp2 in
         let p : 'tv_decl_list_name_opt_decl_ = Obj.magic p in
         let lp2 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19569 "parser_cocci_menhir.ml"
+# 19557 "parser_cocci_menhir.ml"
         ) = Obj.magic lp2 in
         let rp1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19574 "parser_cocci_menhir.ml"
+# 19562 "parser_cocci_menhir.ml"
         ) = Obj.magic rp1 in
         let d : 'tv_d_ident = Obj.magic d in
         let st : (
 # 98 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19580 "parser_cocci_menhir.ml"
+# 19568 "parser_cocci_menhir.ml"
         ) = Obj.magic st in
         let lp1 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19585 "parser_cocci_menhir.ml"
+# 19573 "parser_cocci_menhir.ml"
         ) = Obj.magic lp1 in
         let t : 'tv_fn_ctype = Obj.magic t in
         let _startpos = _startpos_t_ in
@@ -19590,7 +19578,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 39 "standard.mly"
     ( None )
-# 19594 "parser_cocci_menhir.ml"
+# 19582 "parser_cocci_menhir.ml"
           
         in
         
@@ -19602,7 +19590,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
               (t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
                P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
       Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv)))
-# 19606 "parser_cocci_menhir.ml"
+# 19594 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19678,40 +19666,40 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19682 "parser_cocci_menhir.ml"
+# 19670 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let e : 'tv_initialize = Obj.magic e in
         let q : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19688 "parser_cocci_menhir.ml"
+# 19676 "parser_cocci_menhir.ml"
         ) = Obj.magic q in
         let rp2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19693 "parser_cocci_menhir.ml"
+# 19681 "parser_cocci_menhir.ml"
         ) = Obj.magic rp2 in
         let p : 'tv_decl_list_name_opt_decl_ = Obj.magic p in
         let lp2 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19699 "parser_cocci_menhir.ml"
+# 19687 "parser_cocci_menhir.ml"
         ) = Obj.magic lp2 in
         let rp1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19704 "parser_cocci_menhir.ml"
+# 19692 "parser_cocci_menhir.ml"
         ) = Obj.magic rp1 in
         let d : 'tv_d_ident = Obj.magic d in
         let st : (
 # 98 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19710 "parser_cocci_menhir.ml"
+# 19698 "parser_cocci_menhir.ml"
         ) = Obj.magic st in
         let lp1 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19715 "parser_cocci_menhir.ml"
+# 19703 "parser_cocci_menhir.ml"
         ) = Obj.magic lp1 in
         let t : 'tv_fn_ctype = Obj.magic t in
         let x0 : 'tv_storage = Obj.magic x0 in
@@ -19722,7 +19710,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 19726 "parser_cocci_menhir.ml"
+# 19714 "parser_cocci_menhir.ml"
           
         in
         
@@ -19734,7 +19722,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
               (t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
                P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
       Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv)))
-# 19738 "parser_cocci_menhir.ml"
+# 19726 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19751,7 +19739,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_option_TLocal_ = 
 # 29 "standard.mly"
     ( None )
-# 19755 "parser_cocci_menhir.ml"
+# 19743 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19775,7 +19763,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_option_TLocal_ = 
 # 31 "standard.mly"
     ( Some x )
-# 19779 "parser_cocci_menhir.ml"
+# 19767 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19792,7 +19780,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_option_TPosAny_ = 
 # 29 "standard.mly"
     ( None )
-# 19796 "parser_cocci_menhir.ml"
+# 19784 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19816,7 +19804,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_option_TPosAny_ = 
 # 31 "standard.mly"
     ( Some x )
-# 19820 "parser_cocci_menhir.ml"
+# 19808 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19833,7 +19821,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_option_eexpr_ = 
 # 29 "standard.mly"
     ( None )
-# 19837 "parser_cocci_menhir.ml"
+# 19825 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19857,48 +19845,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_option_eexpr_ = 
 # 31 "standard.mly"
     ( Some x )
-# 19861 "parser_cocci_menhir.ml"
-         in
-        _menhir_env.MenhirLib.EngineTypes.stack <- {
-          MenhirLib.EngineTypes.state = _menhir_s;
-          MenhirLib.EngineTypes.semv = Obj.repr _v;
-          MenhirLib.EngineTypes.startp = _startpos;
-          MenhirLib.EngineTypes.endp = _endpos;
-          MenhirLib.EngineTypes.next = _menhir_stack;
-          });
-      (fun _menhir_env ->
-        let _menhir_stack = _menhir_env.MenhirLib.EngineTypes.stack in
-        let _menhir_s = _menhir_env.MenhirLib.EngineTypes.current in
-        let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
-        let _endpos = _startpos in
-        let _v : 'tv_option_whenexp_ = 
-# 29 "standard.mly"
-    ( None )
-# 19878 "parser_cocci_menhir.ml"
-         in
-        _menhir_env.MenhirLib.EngineTypes.stack <- {
-          MenhirLib.EngineTypes.state = _menhir_s;
-          MenhirLib.EngineTypes.semv = Obj.repr _v;
-          MenhirLib.EngineTypes.startp = _startpos;
-          MenhirLib.EngineTypes.endp = _endpos;
-          MenhirLib.EngineTypes.next = _menhir_stack;
-          });
-      (fun _menhir_env ->
-        let _menhir_stack = _menhir_env.MenhirLib.EngineTypes.stack in
-        let {
-          MenhirLib.EngineTypes.state = _menhir_s;
-          MenhirLib.EngineTypes.semv = x;
-          MenhirLib.EngineTypes.startp = _startpos_x_;
-          MenhirLib.EngineTypes.endp = _endpos_x_;
-          MenhirLib.EngineTypes.next = _menhir_stack;
-          } = _menhir_stack in
-        let x : 'tv_whenexp = Obj.magic x in
-        let _startpos = _startpos_x_ in
-        let _endpos = _endpos_x_ in
-        let _v : 'tv_option_whenexp_ = 
-# 31 "standard.mly"
-    ( Some x )
-# 19902 "parser_cocci_menhir.ml"
+# 19849 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19913,9 +19860,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
         let _endpos = _startpos in
         let _v : 'tv_plus_after_dots = 
-# 1569 "parser_cocci_menhir.mly"
+# 1570 "parser_cocci_menhir.mly"
                                                                          ([])
-# 19919 "parser_cocci_menhir.ml"
+# 19866 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19941,9 +19888,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_after_dots = 
-# 1570 "parser_cocci_menhir.mly"
+# 1571 "parser_cocci_menhir.mly"
                                                                          (_2)
-# 19947 "parser_cocci_menhir.ml"
+# 19894 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19971,9 +19918,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_after_dots = 
-# 1572 "parser_cocci_menhir.mly"
+# 1573 "parser_cocci_menhir.mly"
                      ( (Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Exp(_1)))))::_2 )
-# 19977 "parser_cocci_menhir.ml"
+# 19924 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20001,9 +19948,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_after_dots = 
-# 1573 "parser_cocci_menhir.mly"
+# 1574 "parser_cocci_menhir.mly"
                                              ( Ast0.wrap(Ast0.DECL(_1))::_2 )
-# 20007 "parser_cocci_menhir.ml"
+# 19954 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20031,9 +19978,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_after_dots = 
-# 1575 "parser_cocci_menhir.mly"
+# 1576 "parser_cocci_menhir.mly"
                 ( (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) _1)@_2 )
-# 20037 "parser_cocci_menhir.ml"
+# 19984 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20048,9 +19995,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
         let _endpos = _startpos in
         let _v : 'tv_plus_after_exp = 
-# 1565 "parser_cocci_menhir.mly"
+# 1566 "parser_cocci_menhir.mly"
                                                                          ([])
-# 20054 "parser_cocci_menhir.ml"
+# 20001 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20078,9 +20025,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_after_exp = 
-# 1566 "parser_cocci_menhir.mly"
+# 1567 "parser_cocci_menhir.mly"
                                           ( (Ast0.wrap(Ast0.OTHER(_1)))::_2 )
-# 20084 "parser_cocci_menhir.ml"
+# 20031 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20095,9 +20042,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
         let _endpos = _startpos in
         let _v : 'tv_plus_after_stm = 
-# 1578 "parser_cocci_menhir.mly"
+# 1579 "parser_cocci_menhir.mly"
                                                                          ([])
-# 20101 "parser_cocci_menhir.ml"
+# 20048 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20125,9 +20072,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_after_stm = 
-# 1579 "parser_cocci_menhir.mly"
+# 1580 "parser_cocci_menhir.mly"
                                           ( (Ast0.wrap(Ast0.OTHER(_1)))::_2 )
-# 20131 "parser_cocci_menhir.ml"
+# 20078 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20155,9 +20102,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_after_stm = 
-# 1580 "parser_cocci_menhir.mly"
+# 1581 "parser_cocci_menhir.mly"
                                              ( Ast0.wrap(Ast0.DECL(_1))::_2 )
-# 20161 "parser_cocci_menhir.ml"
+# 20108 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20185,9 +20132,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_after_stm = 
-# 1582 "parser_cocci_menhir.mly"
+# 1583 "parser_cocci_menhir.mly"
                 ( (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) _1)@_2 )
-# 20191 "parser_cocci_menhir.ml"
+# 20138 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20223,7 +20170,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_plus_body = 
 # 562 "parser_cocci_menhir.mly"
     ( Top_level.top_level (f@b@ew) )
-# 20227 "parser_cocci_menhir.ml"
+# 20174 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20259,7 +20206,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_plus_exp_body = 
 # 576 "parser_cocci_menhir.mly"
     ( Top_level.top_level (f@[b]@ew) )
-# 20263 "parser_cocci_menhir.ml"
+# 20210 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20287,11 +20234,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 142 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 20291 "parser_cocci_menhir.ml"
+# 20238 "parser_cocci_menhir.ml"
         ) = 
 # 178 "parser_cocci_menhir.mly"
                                  ( _1 )
-# 20295 "parser_cocci_menhir.ml"
+# 20242 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20319,11 +20266,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 142 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 20323 "parser_cocci_menhir.ml"
+# 20270 "parser_cocci_menhir.ml"
         ) = 
 # 178 "parser_cocci_menhir.mly"
                                                                     ( p )
-# 20327 "parser_cocci_menhir.ml"
+# 20274 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20351,11 +20298,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 142 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 20355 "parser_cocci_menhir.ml"
+# 20302 "parser_cocci_menhir.ml"
         ) = 
 # 179 "parser_cocci_menhir.mly"
                         ( p )
-# 20359 "parser_cocci_menhir.ml"
+# 20306 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20383,11 +20330,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 139 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 20387 "parser_cocci_menhir.ml"
+# 20334 "parser_cocci_menhir.ml"
         ) = 
 # 174 "parser_cocci_menhir.mly"
                          ( _1 )
-# 20391 "parser_cocci_menhir.ml"
+# 20338 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20415,11 +20362,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 139 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 20419 "parser_cocci_menhir.ml"
+# 20366 "parser_cocci_menhir.ml"
         ) = 
 # 174 "parser_cocci_menhir.mly"
                                                         ( p )
-# 20423 "parser_cocci_menhir.ml"
+# 20370 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20447,11 +20394,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 139 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 20451 "parser_cocci_menhir.ml"
+# 20398 "parser_cocci_menhir.ml"
         ) = 
 # 175 "parser_cocci_menhir.mly"
                     ( p )
-# 20455 "parser_cocci_menhir.ml"
+# 20402 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20473,9 +20420,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_plus_start = 
-# 1554 "parser_cocci_menhir.mly"
+# 1555 "parser_cocci_menhir.mly"
                           ( [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Ty(_1))))] )
-# 20479 "parser_cocci_menhir.ml"
+# 20426 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20497,9 +20444,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_plus_start = 
-# 1555 "parser_cocci_menhir.mly"
+# 1556 "parser_cocci_menhir.mly"
                      ( [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.TopInit(_1))))] )
-# 20503 "parser_cocci_menhir.ml"
+# 20450 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20527,9 +20474,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_start = 
-# 1557 "parser_cocci_menhir.mly"
+# 1558 "parser_cocci_menhir.mly"
                                           ( (Ast0.wrap(Ast0.OTHER(_1)))::_2 )
-# 20533 "parser_cocci_menhir.ml"
+# 20480 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20557,9 +20504,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_start = 
-# 1559 "parser_cocci_menhir.mly"
+# 1560 "parser_cocci_menhir.mly"
                      ( (Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Exp(_1)))))::_2 )
-# 20563 "parser_cocci_menhir.ml"
+# 20510 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20587,9 +20534,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_start = 
-# 1560 "parser_cocci_menhir.mly"
+# 1561 "parser_cocci_menhir.mly"
                                              ( Ast0.wrap(Ast0.DECL(_1))::_2 )
-# 20593 "parser_cocci_menhir.ml"
+# 20540 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20617,9 +20564,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_start = 
-# 1562 "parser_cocci_menhir.mly"
+# 1563 "parser_cocci_menhir.mly"
                 ( (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) _1)@_2 )
-# 20623 "parser_cocci_menhir.ml"
+# 20570 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20640,14 +20587,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 47 "parser_cocci_menhir.mly"
       (string)
-# 20644 "parser_cocci_menhir.ml"
+# 20591 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_pnrule = 
 # 220 "parser_cocci_menhir.mly"
                    ( Ast.Dep      _1 )
-# 20651 "parser_cocci_menhir.ml"
+# 20598 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20672,14 +20619,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 47 "parser_cocci_menhir.mly"
       (string)
-# 20676 "parser_cocci_menhir.ml"
+# 20623 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_pnrule = 
 # 221 "parser_cocci_menhir.mly"
                    ( Ast.AntiDep  _2 )
-# 20683 "parser_cocci_menhir.ml"
+# 20630 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20704,14 +20651,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 47 "parser_cocci_menhir.mly"
       (string)
-# 20708 "parser_cocci_menhir.ml"
+# 20655 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_pnrule = 
 # 222 "parser_cocci_menhir.mly"
                    ( Ast.EverDep  _2 )
-# 20715 "parser_cocci_menhir.ml"
+# 20662 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20736,14 +20683,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 47 "parser_cocci_menhir.mly"
       (string)
-# 20740 "parser_cocci_menhir.ml"
+# 20687 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_pnrule = 
 # 223 "parser_cocci_menhir.mly"
                    ( Ast.NeverDep _2 )
-# 20747 "parser_cocci_menhir.ml"
+# 20694 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20775,7 +20722,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_pnrule = 
 # 224 "parser_cocci_menhir.mly"
                    ( _2 )
-# 20779 "parser_cocci_menhir.ml"
+# 20726 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20797,9 +20744,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_postfix_expr_eexpr_dot_expressions_ = 
-# 1249 "parser_cocci_menhir.mly"
+# 1250 "parser_cocci_menhir.mly"
                                                  ( _1 )
-# 20803 "parser_cocci_menhir.ml"
+# 20750 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20835,22 +20782,22 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _4 : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20839 "parser_cocci_menhir.ml"
+# 20786 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr = Obj.magic _3 in
         let _2 : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20845 "parser_cocci_menhir.ml"
+# 20792 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_eexpr_dot_expressions_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__4_ in
         let _v : 'tv_postfix_expr_eexpr_dot_expressions_ = 
-# 1251 "parser_cocci_menhir.mly"
+# 1252 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.ArrayAccess (_1,P.clt2mcode "[" _2,_3,
                                       P.clt2mcode "]" _4)) )
-# 20854 "parser_cocci_menhir.ml"
+# 20801 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20882,15 +20829,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20886 "parser_cocci_menhir.ml"
+# 20833 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_eexpr_dot_expressions_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_postfix_expr_eexpr_dot_expressions_ = 
-# 1254 "parser_cocci_menhir.mly"
+# 1255 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.RecordAccess(_1, P.clt2mcode "." _2, _3)) )
-# 20894 "parser_cocci_menhir.ml"
+# 20841 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20922,16 +20869,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 103 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20926 "parser_cocci_menhir.ml"
+# 20873 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_eexpr_dot_expressions_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_postfix_expr_eexpr_dot_expressions_ = 
-# 1256 "parser_cocci_menhir.mly"
+# 1257 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.RecordPtAccess(_1, P.clt2mcode "->" _2,
                                     _3)) )
-# 20935 "parser_cocci_menhir.ml"
+# 20882 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20957,15 +20904,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 84 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20961 "parser_cocci_menhir.ml"
+# 20908 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_eexpr_dot_expressions_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_postfix_expr_eexpr_dot_expressions_ = 
-# 1259 "parser_cocci_menhir.mly"
+# 1260 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Inc _2)) )
-# 20969 "parser_cocci_menhir.ml"
+# 20916 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20991,15 +20938,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 84 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20995 "parser_cocci_menhir.ml"
+# 20942 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_eexpr_dot_expressions_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_postfix_expr_eexpr_dot_expressions_ = 
-# 1261 "parser_cocci_menhir.mly"
+# 1262 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Dec _2)) )
-# 21003 "parser_cocci_menhir.ml"
+# 20950 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21035,23 +20982,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _4 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21039 "parser_cocci_menhir.ml"
+# 20986 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr_list_option = Obj.magic _3 in
         let _2 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21045 "parser_cocci_menhir.ml"
+# 20992 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_eexpr_dot_expressions_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__4_ in
         let _v : 'tv_postfix_expr_eexpr_dot_expressions_ = 
-# 1263 "parser_cocci_menhir.mly"
+# 1264 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.FunCall(_1,P.clt2mcode "(" _2,
                              _3,
                              P.clt2mcode ")" _4)) )
-# 21055 "parser_cocci_menhir.ml"
+# 21002 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21073,9 +21020,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_postfix_expr_eexpr_invalid_ = 
-# 1249 "parser_cocci_menhir.mly"
+# 1250 "parser_cocci_menhir.mly"
                                                  ( _1 )
-# 21079 "parser_cocci_menhir.ml"
+# 21026 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21111,22 +21058,22 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _4 : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21115 "parser_cocci_menhir.ml"
+# 21062 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr = Obj.magic _3 in
         let _2 : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21121 "parser_cocci_menhir.ml"
+# 21068 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_eexpr_invalid_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__4_ in
         let _v : 'tv_postfix_expr_eexpr_invalid_ = 
-# 1251 "parser_cocci_menhir.mly"
+# 1252 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.ArrayAccess (_1,P.clt2mcode "[" _2,_3,
                                       P.clt2mcode "]" _4)) )
-# 21130 "parser_cocci_menhir.ml"
+# 21077 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21158,15 +21105,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21162 "parser_cocci_menhir.ml"
+# 21109 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_eexpr_invalid_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_postfix_expr_eexpr_invalid_ = 
-# 1254 "parser_cocci_menhir.mly"
+# 1255 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.RecordAccess(_1, P.clt2mcode "." _2, _3)) )
-# 21170 "parser_cocci_menhir.ml"
+# 21117 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21198,16 +21145,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 103 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21202 "parser_cocci_menhir.ml"
+# 21149 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_eexpr_invalid_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_postfix_expr_eexpr_invalid_ = 
-# 1256 "parser_cocci_menhir.mly"
+# 1257 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.RecordPtAccess(_1, P.clt2mcode "->" _2,
                                     _3)) )
-# 21211 "parser_cocci_menhir.ml"
+# 21158 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21233,15 +21180,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 84 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21237 "parser_cocci_menhir.ml"
+# 21184 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_eexpr_invalid_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_postfix_expr_eexpr_invalid_ = 
-# 1259 "parser_cocci_menhir.mly"
+# 1260 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Inc _2)) )
-# 21245 "parser_cocci_menhir.ml"
+# 21192 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21267,15 +21214,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 84 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21271 "parser_cocci_menhir.ml"
+# 21218 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_eexpr_invalid_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_postfix_expr_eexpr_invalid_ = 
-# 1261 "parser_cocci_menhir.mly"
+# 1262 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Dec _2)) )
-# 21279 "parser_cocci_menhir.ml"
+# 21226 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21311,23 +21258,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _4 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21315 "parser_cocci_menhir.ml"
+# 21262 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr_list_option = Obj.magic _3 in
         let _2 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21321 "parser_cocci_menhir.ml"
+# 21268 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_eexpr_invalid_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__4_ in
         let _v : 'tv_postfix_expr_eexpr_invalid_ = 
-# 1263 "parser_cocci_menhir.mly"
+# 1264 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.FunCall(_1,P.clt2mcode "(" _2,
                              _3,
                              P.clt2mcode ")" _4)) )
-# 21331 "parser_cocci_menhir.ml"
+# 21278 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21349,9 +21296,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_postfix_expr_eexpr_nest_expressions_ = 
-# 1249 "parser_cocci_menhir.mly"
+# 1250 "parser_cocci_menhir.mly"
                                                  ( _1 )
-# 21355 "parser_cocci_menhir.ml"
+# 21302 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21387,22 +21334,22 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _4 : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21391 "parser_cocci_menhir.ml"
+# 21338 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr = Obj.magic _3 in
         let _2 : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21397 "parser_cocci_menhir.ml"
+# 21344 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_eexpr_nest_expressions_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__4_ in
         let _v : 'tv_postfix_expr_eexpr_nest_expressions_ = 
-# 1251 "parser_cocci_menhir.mly"
+# 1252 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.ArrayAccess (_1,P.clt2mcode "[" _2,_3,
                                       P.clt2mcode "]" _4)) )
-# 21406 "parser_cocci_menhir.ml"
+# 21353 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21434,15 +21381,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21438 "parser_cocci_menhir.ml"
+# 21385 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_eexpr_nest_expressions_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_postfix_expr_eexpr_nest_expressions_ = 
-# 1254 "parser_cocci_menhir.mly"
+# 1255 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.RecordAccess(_1, P.clt2mcode "." _2, _3)) )
-# 21446 "parser_cocci_menhir.ml"
+# 21393 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21474,16 +21421,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 103 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21478 "parser_cocci_menhir.ml"
+# 21425 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_eexpr_nest_expressions_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_postfix_expr_eexpr_nest_expressions_ = 
-# 1256 "parser_cocci_menhir.mly"
+# 1257 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.RecordPtAccess(_1, P.clt2mcode "->" _2,
                                     _3)) )
-# 21487 "parser_cocci_menhir.ml"
+# 21434 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21509,15 +21456,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 84 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21513 "parser_cocci_menhir.ml"
+# 21460 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_eexpr_nest_expressions_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_postfix_expr_eexpr_nest_expressions_ = 
-# 1259 "parser_cocci_menhir.mly"
+# 1260 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Inc _2)) )
-# 21521 "parser_cocci_menhir.ml"
+# 21468 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21543,15 +21490,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 84 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21547 "parser_cocci_menhir.ml"
+# 21494 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_eexpr_nest_expressions_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_postfix_expr_eexpr_nest_expressions_ = 
-# 1261 "parser_cocci_menhir.mly"
+# 1262 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Dec _2)) )
-# 21555 "parser_cocci_menhir.ml"
+# 21502 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21587,23 +21534,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _4 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21591 "parser_cocci_menhir.ml"
+# 21538 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr_list_option = Obj.magic _3 in
         let _2 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21597 "parser_cocci_menhir.ml"
+# 21544 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_eexpr_nest_expressions_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__4_ in
         let _v : 'tv_postfix_expr_eexpr_nest_expressions_ = 
-# 1263 "parser_cocci_menhir.mly"
+# 1264 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.FunCall(_1,P.clt2mcode "(" _2,
                              _3,
                              P.clt2mcode ")" _4)) )
-# 21607 "parser_cocci_menhir.ml"
+# 21554 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21625,9 +21572,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_postfix_expr_expr_invalid_ = 
-# 1249 "parser_cocci_menhir.mly"
+# 1250 "parser_cocci_menhir.mly"
                                                  ( _1 )
-# 21631 "parser_cocci_menhir.ml"
+# 21578 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21663,22 +21610,22 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _4 : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21667 "parser_cocci_menhir.ml"
+# 21614 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr = Obj.magic _3 in
         let _2 : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21673 "parser_cocci_menhir.ml"
+# 21620 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_expr_invalid_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__4_ in
         let _v : 'tv_postfix_expr_expr_invalid_ = 
-# 1251 "parser_cocci_menhir.mly"
+# 1252 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.ArrayAccess (_1,P.clt2mcode "[" _2,_3,
                                       P.clt2mcode "]" _4)) )
-# 21682 "parser_cocci_menhir.ml"
+# 21629 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21710,15 +21657,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21714 "parser_cocci_menhir.ml"
+# 21661 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_expr_invalid_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_postfix_expr_expr_invalid_ = 
-# 1254 "parser_cocci_menhir.mly"
+# 1255 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.RecordAccess(_1, P.clt2mcode "." _2, _3)) )
-# 21722 "parser_cocci_menhir.ml"
+# 21669 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21750,16 +21697,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 103 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21754 "parser_cocci_menhir.ml"
+# 21701 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_expr_invalid_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_postfix_expr_expr_invalid_ = 
-# 1256 "parser_cocci_menhir.mly"
+# 1257 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.RecordPtAccess(_1, P.clt2mcode "->" _2,
                                     _3)) )
-# 21763 "parser_cocci_menhir.ml"
+# 21710 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21785,15 +21732,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 84 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21789 "parser_cocci_menhir.ml"
+# 21736 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_expr_invalid_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_postfix_expr_expr_invalid_ = 
-# 1259 "parser_cocci_menhir.mly"
+# 1260 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Inc _2)) )
-# 21797 "parser_cocci_menhir.ml"
+# 21744 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21819,15 +21766,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 84 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21823 "parser_cocci_menhir.ml"
+# 21770 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_expr_invalid_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_postfix_expr_expr_invalid_ = 
-# 1261 "parser_cocci_menhir.mly"
+# 1262 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Dec _2)) )
-# 21831 "parser_cocci_menhir.ml"
+# 21778 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21863,23 +21810,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _4 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21867 "parser_cocci_menhir.ml"
+# 21814 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr_list_option = Obj.magic _3 in
         let _2 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21873 "parser_cocci_menhir.ml"
+# 21820 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_postfix_expr_expr_invalid_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__4_ in
         let _v : 'tv_postfix_expr_expr_invalid_ = 
-# 1263 "parser_cocci_menhir.mly"
+# 1264 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.FunCall(_1,P.clt2mcode "(" _2,
                              _3,
                              P.clt2mcode ")" _4)) )
-# 21883 "parser_cocci_menhir.ml"
+# 21830 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21901,9 +21848,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_dot_expressions_ = 
-# 1268 "parser_cocci_menhir.mly"
+# 1269 "parser_cocci_menhir.mly"
                 ( Ast0.wrap(Ast0.Ident(_1)) )
-# 21907 "parser_cocci_menhir.ml"
+# 21854 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21924,15 +21871,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 86 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 21928 "parser_cocci_menhir.ml"
+# 21875 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_dot_expressions_ = 
-# 1270 "parser_cocci_menhir.mly"
+# 1271 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) )
-# 21936 "parser_cocci_menhir.ml"
+# 21883 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21953,15 +21900,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 86 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 21957 "parser_cocci_menhir.ml"
+# 21904 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_dot_expressions_ = 
-# 1273 "parser_cocci_menhir.mly"
+# 1274 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Float x) clt)) )
-# 21965 "parser_cocci_menhir.ml"
+# 21912 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21982,15 +21929,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 86 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 21986 "parser_cocci_menhir.ml"
+# 21933 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_dot_expressions_ = 
-# 1276 "parser_cocci_menhir.mly"
+# 1277 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.String x) clt)) )
-# 21994 "parser_cocci_menhir.ml"
+# 21941 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22011,15 +21958,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 86 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 22015 "parser_cocci_menhir.ml"
+# 21962 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_dot_expressions_ = 
-# 1279 "parser_cocci_menhir.mly"
+# 1280 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Char x) clt)) )
-# 22023 "parser_cocci_menhir.ml"
+# 21970 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22040,16 +21987,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 66 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 22044 "parser_cocci_menhir.ml"
+# 21991 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_dot_expressions_ = 
-# 1282 "parser_cocci_menhir.mly"
+# 1283 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,ty,clt) = _1 in
      Ast0.wrap
        (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.CONST,pure)) )
-# 22053 "parser_cocci_menhir.ml"
+# 22000 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22070,15 +22017,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 63 "parser_cocci_menhir.mly"
        (Parse_aux.expinfo)
-# 22074 "parser_cocci_menhir.ml"
+# 22021 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_dot_expressions_ = 
-# 1286 "parser_cocci_menhir.mly"
+# 1287 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,clt) = _1 in
      Ast0.wrap(Ast0.MetaErr(P.clt2mcode nm clt,constraints,pure)) )
-# 22082 "parser_cocci_menhir.ml"
+# 22029 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22099,16 +22046,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 66 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 22103 "parser_cocci_menhir.ml"
+# 22050 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_dot_expressions_ = 
-# 1289 "parser_cocci_menhir.mly"
+# 1290 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,ty,clt) = _1 in
      Ast0.wrap
        (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ANY,pure)) )
-# 22112 "parser_cocci_menhir.ml"
+# 22059 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22129,16 +22076,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 66 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 22133 "parser_cocci_menhir.ml"
+# 22080 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_dot_expressions_ = 
-# 1293 "parser_cocci_menhir.mly"
+# 1294 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,ty,clt) = _1 in
      Ast0.wrap
        (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ID,pure)) )
-# 22142 "parser_cocci_menhir.ml"
+# 22089 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22159,16 +22106,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 66 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 22163 "parser_cocci_menhir.ml"
+# 22110 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_dot_expressions_ = 
-# 1297 "parser_cocci_menhir.mly"
+# 1298 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,ty,clt) = _1 in
      Ast0.wrap
        (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.LocalID,pure)) )
-# 22172 "parser_cocci_menhir.ml"
+# 22119 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22199,21 +22146,21 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22203 "parser_cocci_menhir.ml"
+# 22150 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_eexpr = Obj.magic _2 in
         let _1 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22209 "parser_cocci_menhir.ml"
+# 22156 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_primary_expr_eexpr_dot_expressions_ = 
-# 1301 "parser_cocci_menhir.mly"
+# 1302 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Paren(P.clt2mcode "(" _1,_2,
                            P.clt2mcode ")" _3)) )
-# 22217 "parser_cocci_menhir.ml"
+# 22164 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22244,23 +22191,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22248 "parser_cocci_menhir.ml"
+# 22195 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_midzero_list_eexpr_eexpr_ = Obj.magic _2 in
         let _1 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22254 "parser_cocci_menhir.ml"
+# 22201 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_primary_expr_eexpr_dot_expressions_ = 
-# 1304 "parser_cocci_menhir.mly"
+# 1305 "parser_cocci_menhir.mly"
      ( let (mids,code) = _2 in
        Ast0.wrap(Ast0.DisjExpr(P.clt2mcode "(" _1,
                               code, mids,
                               P.clt2mcode ")" _3)) )
-# 22264 "parser_cocci_menhir.ml"
+# 22211 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22282,9 +22229,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_dot_expressions_ = 
-# 1308 "parser_cocci_menhir.mly"
+# 1309 "parser_cocci_menhir.mly"
                  ( _1 )
-# 22288 "parser_cocci_menhir.ml"
+# 22235 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22306,9 +22253,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_invalid_ = 
-# 1268 "parser_cocci_menhir.mly"
+# 1269 "parser_cocci_menhir.mly"
                 ( Ast0.wrap(Ast0.Ident(_1)) )
-# 22312 "parser_cocci_menhir.ml"
+# 22259 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22329,15 +22276,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 86 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 22333 "parser_cocci_menhir.ml"
+# 22280 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_invalid_ = 
-# 1270 "parser_cocci_menhir.mly"
+# 1271 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) )
-# 22341 "parser_cocci_menhir.ml"
+# 22288 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22358,15 +22305,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 86 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 22362 "parser_cocci_menhir.ml"
+# 22309 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_invalid_ = 
-# 1273 "parser_cocci_menhir.mly"
+# 1274 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Float x) clt)) )
-# 22370 "parser_cocci_menhir.ml"
+# 22317 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22387,15 +22334,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 86 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 22391 "parser_cocci_menhir.ml"
+# 22338 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_invalid_ = 
-# 1276 "parser_cocci_menhir.mly"
+# 1277 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.String x) clt)) )
-# 22399 "parser_cocci_menhir.ml"
+# 22346 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22416,15 +22363,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 86 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 22420 "parser_cocci_menhir.ml"
+# 22367 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_invalid_ = 
-# 1279 "parser_cocci_menhir.mly"
+# 1280 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Char x) clt)) )
-# 22428 "parser_cocci_menhir.ml"
+# 22375 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22445,16 +22392,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 66 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 22449 "parser_cocci_menhir.ml"
+# 22396 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_invalid_ = 
-# 1282 "parser_cocci_menhir.mly"
+# 1283 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,ty,clt) = _1 in
      Ast0.wrap
        (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.CONST,pure)) )
-# 22458 "parser_cocci_menhir.ml"
+# 22405 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22475,15 +22422,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 63 "parser_cocci_menhir.mly"
        (Parse_aux.expinfo)
-# 22479 "parser_cocci_menhir.ml"
+# 22426 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_invalid_ = 
-# 1286 "parser_cocci_menhir.mly"
+# 1287 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,clt) = _1 in
      Ast0.wrap(Ast0.MetaErr(P.clt2mcode nm clt,constraints,pure)) )
-# 22487 "parser_cocci_menhir.ml"
+# 22434 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22504,16 +22451,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 66 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 22508 "parser_cocci_menhir.ml"
+# 22455 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_invalid_ = 
-# 1289 "parser_cocci_menhir.mly"
+# 1290 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,ty,clt) = _1 in
      Ast0.wrap
        (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ANY,pure)) )
-# 22517 "parser_cocci_menhir.ml"
+# 22464 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22534,16 +22481,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 66 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 22538 "parser_cocci_menhir.ml"
+# 22485 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_invalid_ = 
-# 1293 "parser_cocci_menhir.mly"
+# 1294 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,ty,clt) = _1 in
      Ast0.wrap
        (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ID,pure)) )
-# 22547 "parser_cocci_menhir.ml"
+# 22494 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22564,16 +22511,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 66 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 22568 "parser_cocci_menhir.ml"
+# 22515 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_invalid_ = 
-# 1297 "parser_cocci_menhir.mly"
+# 1298 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,ty,clt) = _1 in
      Ast0.wrap
        (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.LocalID,pure)) )
-# 22577 "parser_cocci_menhir.ml"
+# 22524 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22604,21 +22551,21 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22608 "parser_cocci_menhir.ml"
+# 22555 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_eexpr = Obj.magic _2 in
         let _1 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22614 "parser_cocci_menhir.ml"
+# 22561 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_primary_expr_eexpr_invalid_ = 
-# 1301 "parser_cocci_menhir.mly"
+# 1302 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Paren(P.clt2mcode "(" _1,_2,
                            P.clt2mcode ")" _3)) )
-# 22622 "parser_cocci_menhir.ml"
+# 22569 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22649,23 +22596,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22653 "parser_cocci_menhir.ml"
+# 22600 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_midzero_list_eexpr_eexpr_ = Obj.magic _2 in
         let _1 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22659 "parser_cocci_menhir.ml"
+# 22606 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_primary_expr_eexpr_invalid_ = 
-# 1304 "parser_cocci_menhir.mly"
+# 1305 "parser_cocci_menhir.mly"
      ( let (mids,code) = _2 in
        Ast0.wrap(Ast0.DisjExpr(P.clt2mcode "(" _1,
                               code, mids,
                               P.clt2mcode ")" _3)) )
-# 22669 "parser_cocci_menhir.ml"
+# 22616 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22687,9 +22634,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_invalid_ = 
-# 1308 "parser_cocci_menhir.mly"
+# 1309 "parser_cocci_menhir.mly"
                  ( _1 )
-# 22693 "parser_cocci_menhir.ml"
+# 22640 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22711,9 +22658,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_nest_expressions_ = 
-# 1268 "parser_cocci_menhir.mly"
+# 1269 "parser_cocci_menhir.mly"
                 ( Ast0.wrap(Ast0.Ident(_1)) )
-# 22717 "parser_cocci_menhir.ml"
+# 22664 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22734,15 +22681,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 86 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 22738 "parser_cocci_menhir.ml"
+# 22685 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_nest_expressions_ = 
-# 1270 "parser_cocci_menhir.mly"
+# 1271 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) )
-# 22746 "parser_cocci_menhir.ml"
+# 22693 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22763,15 +22710,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 86 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 22767 "parser_cocci_menhir.ml"
+# 22714 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_nest_expressions_ = 
-# 1273 "parser_cocci_menhir.mly"
+# 1274 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Float x) clt)) )
-# 22775 "parser_cocci_menhir.ml"
+# 22722 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22792,15 +22739,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 86 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 22796 "parser_cocci_menhir.ml"
+# 22743 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_nest_expressions_ = 
-# 1276 "parser_cocci_menhir.mly"
+# 1277 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.String x) clt)) )
-# 22804 "parser_cocci_menhir.ml"
+# 22751 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22821,15 +22768,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 86 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 22825 "parser_cocci_menhir.ml"
+# 22772 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_nest_expressions_ = 
-# 1279 "parser_cocci_menhir.mly"
+# 1280 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Char x) clt)) )
-# 22833 "parser_cocci_menhir.ml"
+# 22780 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22850,16 +22797,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 66 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 22854 "parser_cocci_menhir.ml"
+# 22801 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_nest_expressions_ = 
-# 1282 "parser_cocci_menhir.mly"
+# 1283 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,ty,clt) = _1 in
      Ast0.wrap
        (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.CONST,pure)) )
-# 22863 "parser_cocci_menhir.ml"
+# 22810 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22880,15 +22827,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 63 "parser_cocci_menhir.mly"
        (Parse_aux.expinfo)
-# 22884 "parser_cocci_menhir.ml"
+# 22831 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_nest_expressions_ = 
-# 1286 "parser_cocci_menhir.mly"
+# 1287 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,clt) = _1 in
      Ast0.wrap(Ast0.MetaErr(P.clt2mcode nm clt,constraints,pure)) )
-# 22892 "parser_cocci_menhir.ml"
+# 22839 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22909,16 +22856,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 66 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 22913 "parser_cocci_menhir.ml"
+# 22860 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_nest_expressions_ = 
-# 1289 "parser_cocci_menhir.mly"
+# 1290 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,ty,clt) = _1 in
      Ast0.wrap
        (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ANY,pure)) )
-# 22922 "parser_cocci_menhir.ml"
+# 22869 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22939,16 +22886,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 66 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 22943 "parser_cocci_menhir.ml"
+# 22890 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_nest_expressions_ = 
-# 1293 "parser_cocci_menhir.mly"
+# 1294 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,ty,clt) = _1 in
      Ast0.wrap
        (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ID,pure)) )
-# 22952 "parser_cocci_menhir.ml"
+# 22899 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22969,16 +22916,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 66 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 22973 "parser_cocci_menhir.ml"
+# 22920 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_nest_expressions_ = 
-# 1297 "parser_cocci_menhir.mly"
+# 1298 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,ty,clt) = _1 in
      Ast0.wrap
        (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.LocalID,pure)) )
-# 22982 "parser_cocci_menhir.ml"
+# 22929 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23009,21 +22956,21 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 23013 "parser_cocci_menhir.ml"
+# 22960 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_eexpr = Obj.magic _2 in
         let _1 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 23019 "parser_cocci_menhir.ml"
+# 22966 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_primary_expr_eexpr_nest_expressions_ = 
-# 1301 "parser_cocci_menhir.mly"
+# 1302 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Paren(P.clt2mcode "(" _1,_2,
                            P.clt2mcode ")" _3)) )
-# 23027 "parser_cocci_menhir.ml"
+# 22974 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23054,23 +23001,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 23058 "parser_cocci_menhir.ml"
+# 23005 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_midzero_list_eexpr_eexpr_ = Obj.magic _2 in
         let _1 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 23064 "parser_cocci_menhir.ml"
+# 23011 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_primary_expr_eexpr_nest_expressions_ = 
-# 1304 "parser_cocci_menhir.mly"
+# 1305 "parser_cocci_menhir.mly"
      ( let (mids,code) = _2 in
        Ast0.wrap(Ast0.DisjExpr(P.clt2mcode "(" _1,
                               code, mids,
                               P.clt2mcode ")" _3)) )
-# 23074 "parser_cocci_menhir.ml"
+# 23021 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23092,9 +23039,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_nest_expressions_ = 
-# 1308 "parser_cocci_menhir.mly"
+# 1309 "parser_cocci_menhir.mly"
                  ( _1 )
-# 23098 "parser_cocci_menhir.ml"
+# 23045 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23116,9 +23063,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_expr_invalid_ = 
-# 1268 "parser_cocci_menhir.mly"
+# 1269 "parser_cocci_menhir.mly"
                 ( Ast0.wrap(Ast0.Ident(_1)) )
-# 23122 "parser_cocci_menhir.ml"
+# 23069 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23139,15 +23086,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 86 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 23143 "parser_cocci_menhir.ml"
+# 23090 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_expr_invalid_ = 
-# 1270 "parser_cocci_menhir.mly"
+# 1271 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) )
-# 23151 "parser_cocci_menhir.ml"
+# 23098 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23168,15 +23115,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 86 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 23172 "parser_cocci_menhir.ml"
+# 23119 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_expr_invalid_ = 
-# 1273 "parser_cocci_menhir.mly"
+# 1274 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Float x) clt)) )
-# 23180 "parser_cocci_menhir.ml"
+# 23127 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23197,15 +23144,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 86 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 23201 "parser_cocci_menhir.ml"
+# 23148 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_expr_invalid_ = 
-# 1276 "parser_cocci_menhir.mly"
+# 1277 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.String x) clt)) )
-# 23209 "parser_cocci_menhir.ml"
+# 23156 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23226,15 +23173,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 86 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 23230 "parser_cocci_menhir.ml"
+# 23177 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_expr_invalid_ = 
-# 1279 "parser_cocci_menhir.mly"
+# 1280 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Char x) clt)) )
-# 23238 "parser_cocci_menhir.ml"
+# 23185 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23255,16 +23202,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 66 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 23259 "parser_cocci_menhir.ml"
+# 23206 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_expr_invalid_ = 
-# 1282 "parser_cocci_menhir.mly"
+# 1283 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,ty,clt) = _1 in
      Ast0.wrap
        (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.CONST,pure)) )
-# 23268 "parser_cocci_menhir.ml"
+# 23215 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23285,15 +23232,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 63 "parser_cocci_menhir.mly"
        (Parse_aux.expinfo)
-# 23289 "parser_cocci_menhir.ml"
+# 23236 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_expr_invalid_ = 
-# 1286 "parser_cocci_menhir.mly"
+# 1287 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,clt) = _1 in
      Ast0.wrap(Ast0.MetaErr(P.clt2mcode nm clt,constraints,pure)) )
-# 23297 "parser_cocci_menhir.ml"
+# 23244 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23314,16 +23261,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 66 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 23318 "parser_cocci_menhir.ml"
+# 23265 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_expr_invalid_ = 
-# 1289 "parser_cocci_menhir.mly"
+# 1290 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,ty,clt) = _1 in
      Ast0.wrap
        (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ANY,pure)) )
-# 23327 "parser_cocci_menhir.ml"
+# 23274 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23344,16 +23291,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 66 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 23348 "parser_cocci_menhir.ml"
+# 23295 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_expr_invalid_ = 
-# 1293 "parser_cocci_menhir.mly"
+# 1294 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,ty,clt) = _1 in
      Ast0.wrap
        (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.ID,pure)) )
-# 23357 "parser_cocci_menhir.ml"
+# 23304 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23374,16 +23321,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 66 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 23378 "parser_cocci_menhir.ml"
+# 23325 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_expr_invalid_ = 
-# 1297 "parser_cocci_menhir.mly"
+# 1298 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,ty,clt) = _1 in
      Ast0.wrap
        (Ast0.MetaExpr(P.clt2mcode nm clt,constraints,ty,Ast.LocalID,pure)) )
-# 23387 "parser_cocci_menhir.ml"
+# 23334 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23414,21 +23361,21 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 23418 "parser_cocci_menhir.ml"
+# 23365 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_eexpr = Obj.magic _2 in
         let _1 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 23424 "parser_cocci_menhir.ml"
+# 23371 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_primary_expr_expr_invalid_ = 
-# 1301 "parser_cocci_menhir.mly"
+# 1302 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Paren(P.clt2mcode "(" _1,_2,
                            P.clt2mcode ")" _3)) )
-# 23432 "parser_cocci_menhir.ml"
+# 23379 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23459,23 +23406,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 23463 "parser_cocci_menhir.ml"
+# 23410 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_midzero_list_expr_eexpr_ = Obj.magic _2 in
         let _1 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 23469 "parser_cocci_menhir.ml"
+# 23416 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_primary_expr_expr_invalid_ = 
-# 1304 "parser_cocci_menhir.mly"
+# 1305 "parser_cocci_menhir.mly"
      ( let (mids,code) = _2 in
        Ast0.wrap(Ast0.DisjExpr(P.clt2mcode "(" _1,
                               code, mids,
                               P.clt2mcode ")" _3)) )
-# 23479 "parser_cocci_menhir.ml"
+# 23426 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23497,9 +23444,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_expr_invalid_ = 
-# 1308 "parser_cocci_menhir.mly"
+# 1309 "parser_cocci_menhir.mly"
                  ( _1 )
-# 23503 "parser_cocci_menhir.ml"
+# 23450 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23521,7 +23468,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_pure = 
 # 189 "parser_cocci_menhir.mly"
                  ( Ast0.Pure )
-# 23525 "parser_cocci_menhir.ml"
+# 23472 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23543,7 +23490,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_pure = 
 # 190 "parser_cocci_menhir.mly"
                  ( Ast0.Context )
-# 23547 "parser_cocci_menhir.ml"
+# 23494 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23569,7 +23516,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_pure = 
 # 191 "parser_cocci_menhir.mly"
                  ( Ast0.PureContext )
-# 23573 "parser_cocci_menhir.ml"
+# 23520 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23595,7 +23542,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_pure = 
 # 192 "parser_cocci_menhir.mly"
                  ( Ast0.PureContext )
-# 23599 "parser_cocci_menhir.ml"
+# 23546 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23612,7 +23559,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_pure = 
 # 193 "parser_cocci_menhir.mly"
                  ( Ast0.Impure )
-# 23616 "parser_cocci_menhir.ml"
+# 23563 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23633,14 +23580,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 59 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 23637 "parser_cocci_menhir.ml"
+# 23584 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_pure_ident = 
-# 1322 "parser_cocci_menhir.mly"
+# 1323 "parser_cocci_menhir.mly"
             ( _1 )
-# 23644 "parser_cocci_menhir.ml"
+# 23591 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23662,9 +23609,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_pure_ident_or_meta_ident = 
-# 1328 "parser_cocci_menhir.mly"
+# 1329 "parser_cocci_menhir.mly"
                                  ( (None,P.id2name _1) )
-# 23668 "parser_cocci_menhir.ml"
+# 23615 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23686,9 +23633,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_pure_ident_or_meta_ident = 
-# 1329 "parser_cocci_menhir.mly"
+# 1330 "parser_cocci_menhir.mly"
                                  ( _1 )
-# 23692 "parser_cocci_menhir.ml"
+# 23639 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23708,9 +23655,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_pure_ident_or_meta_ident = 
-# 1330 "parser_cocci_menhir.mly"
+# 1331 "parser_cocci_menhir.mly"
                                  ( (None,"list") )
-# 23714 "parser_cocci_menhir.ml"
+# 23661 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23730,9 +23677,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_pure_ident_or_meta_ident = 
-# 1331 "parser_cocci_menhir.mly"
+# 1332 "parser_cocci_menhir.mly"
                                  ( (None,"error") )
-# 23736 "parser_cocci_menhir.ml"
+# 23683 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23752,9 +23699,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_pure_ident_or_meta_ident = 
-# 1332 "parser_cocci_menhir.mly"
+# 1333 "parser_cocci_menhir.mly"
                                  ( (None,"type") )
-# 23758 "parser_cocci_menhir.ml"
+# 23705 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23782,9 +23729,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_i_ in
         let _endpos = _endpos_l_ in
         let _v : 'tv_pure_ident_or_meta_ident_with_not_eq_not_ceq_ = 
-# 1335 "parser_cocci_menhir.mly"
+# 1336 "parser_cocci_menhir.mly"
                                                     ( (i,l) )
-# 23788 "parser_cocci_menhir.ml"
+# 23735 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23812,9 +23759,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_i_ in
         let _endpos = _endpos_l_ in
         let _v : 'tv_pure_ident_or_meta_ident_with_not_eq_not_eq_ = 
-# 1335 "parser_cocci_menhir.mly"
+# 1336 "parser_cocci_menhir.mly"
                                                     ( (i,l) )
-# 23818 "parser_cocci_menhir.ml"
+# 23765 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23842,9 +23789,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_i_ in
         let _endpos = _endpos_l_ in
         let _v : 'tv_pure_ident_or_meta_ident_with_not_eq_not_eqe_ = 
-# 1335 "parser_cocci_menhir.mly"
+# 1336 "parser_cocci_menhir.mly"
                                                     ( (i,l) )
-# 23848 "parser_cocci_menhir.ml"
+# 23795 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23872,9 +23819,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_i_ in
         let _endpos = _endpos_l_ in
         let _v : 'tv_pure_ident_or_meta_ident_with_not_eq_not_pos_ = 
-# 1335 "parser_cocci_menhir.mly"
+# 1336 "parser_cocci_menhir.mly"
                                                     ( (i,l) )
-# 23878 "parser_cocci_menhir.ml"
+# 23825 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23891,11 +23838,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 130 "parser_cocci_menhir.mly"
       (unit)
-# 23895 "parser_cocci_menhir.ml"
+# 23842 "parser_cocci_menhir.ml"
         ) = 
 # 171 "parser_cocci_menhir.mly"
         ( )
-# 23899 "parser_cocci_menhir.ml"
+# 23846 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23919,7 +23866,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_rule_elem_statement = 
 # 849 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.Decl((Ast0.default_info(),Ast0.context_befaft()),_1)) )
-# 23923 "parser_cocci_menhir.ml"
+# 23870 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23945,7 +23892,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 23949 "parser_cocci_menhir.ml"
+# 23896 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_expr = Obj.magic _1 in
         let _startpos = _startpos__1_ in
@@ -23953,7 +23900,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_rule_elem_statement = 
 # 850 "parser_cocci_menhir.mly"
                ( P.exp_stm _1 _2 )
-# 23957 "parser_cocci_menhir.ml"
+# 23904 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23984,20 +23931,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 23988 "parser_cocci_menhir.ml"
+# 23935 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_eexpr = Obj.magic _2 in
         let _1 : (
 # 57 "parser_cocci_menhir.mly"
        (Data.clt)
-# 23994 "parser_cocci_menhir.ml"
+# 23941 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_rule_elem_statement = 
 # 851 "parser_cocci_menhir.mly"
                         ( P.ret_exp _1 _2 _3 )
-# 24001 "parser_cocci_menhir.ml"
+# 23948 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24023,19 +23970,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 24027 "parser_cocci_menhir.ml"
+# 23974 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 57 "parser_cocci_menhir.mly"
        (Data.clt)
-# 24032 "parser_cocci_menhir.ml"
+# 23979 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_rule_elem_statement = 
 # 852 "parser_cocci_menhir.mly"
                   ( P.ret _1 _2 )
-# 24039 "parser_cocci_menhir.ml"
+# 23986 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24061,19 +24008,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 24065 "parser_cocci_menhir.ml"
+# 24012 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 24070 "parser_cocci_menhir.ml"
+# 24017 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_rule_elem_statement = 
 # 853 "parser_cocci_menhir.mly"
                  ( P.break _1 _2 )
-# 24077 "parser_cocci_menhir.ml"
+# 24024 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24099,19 +24046,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 24103 "parser_cocci_menhir.ml"
+# 24050 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 24108 "parser_cocci_menhir.ml"
+# 24055 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_rule_elem_statement = 
 # 854 "parser_cocci_menhir.mly"
                     ( P.cont _1 _2 )
-# 24115 "parser_cocci_menhir.ml"
+# 24062 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24142,13 +24089,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 24146 "parser_cocci_menhir.ml"
+# 24093 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_midzero_list_rule_elem_statement_rule_elem_statement_ = Obj.magic _2 in
         let _1 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 24152 "parser_cocci_menhir.ml"
+# 24099 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
@@ -24159,7 +24106,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       (Ast0.Disj(P.clt2mcode "(" _1,
                 List.map (function x -> Ast0.wrap(Ast0.DOTS([x]))) code,
                 mids, P.clt2mcode ")" _3)) )
-# 24163 "parser_cocci_menhir.ml"
+# 24110 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24215,18 +24162,18 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 152 "parser_cocci_menhir.mly"
       (Ast_cocci.rulename)
-# 24219 "parser_cocci_menhir.ml"
+# 24166 "parser_cocci_menhir.ml"
         ) = let nm =
           
 # 39 "standard.mly"
     ( None )
-# 24224 "parser_cocci_menhir.ml"
+# 24171 "parser_cocci_menhir.ml"
           
         in
         
 # 201 "parser_cocci_menhir.mly"
       ( P.make_cocci_rule_name_result nm d i a e ee )
-# 24230 "parser_cocci_menhir.ml"
+# 24177 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24288,19 +24235,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 152 "parser_cocci_menhir.mly"
       (Ast_cocci.rulename)
-# 24292 "parser_cocci_menhir.ml"
+# 24239 "parser_cocci_menhir.ml"
         ) = let nm =
           let x = x0 in
           
 # 41 "standard.mly"
     ( Some x )
-# 24298 "parser_cocci_menhir.ml"
+# 24245 "parser_cocci_menhir.ml"
           
         in
         
 # 201 "parser_cocci_menhir.mly"
       ( P.make_cocci_rule_name_result nm d i a e ee )
-# 24304 "parser_cocci_menhir.ml"
+# 24251 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24342,11 +24289,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 152 "parser_cocci_menhir.mly"
       (Ast_cocci.rulename)
-# 24346 "parser_cocci_menhir.ml"
+# 24293 "parser_cocci_menhir.ml"
         ) = 
 # 203 "parser_cocci_menhir.mly"
       ( P.make_script_rule_name_result lang d )
-# 24350 "parser_cocci_menhir.ml"
+# 24297 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24390,7 +24337,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 47 "parser_cocci_menhir.mly"
       (string)
-# 24394 "parser_cocci_menhir.ml"
+# 24341 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let py : 'tv_pure_ident = Obj.magic py in
         let _startpos = _startpos_py_ in
@@ -24398,11 +24345,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 158 "parser_cocci_menhir.mly"
        (string * (string * string))
-# 24402 "parser_cocci_menhir.ml"
+# 24349 "parser_cocci_menhir.ml"
         ) = 
-# 1769 "parser_cocci_menhir.mly"
+# 1770 "parser_cocci_menhir.mly"
   ( (P.id2name py, (_3, P.id2name cocci)) )
-# 24406 "parser_cocci_menhir.ml"
+# 24353 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24423,14 +24370,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let x : (
 # 86 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 24427 "parser_cocci_menhir.ml"
+# 24374 "parser_cocci_menhir.ml"
         ) = Obj.magic x in
         let _startpos = _startpos_x_ in
         let _endpos = _endpos_x_ in
         let _v : 'tv_separated_nonempty_list_TComma_TString_ = 
 # 144 "standard.mly"
     ( [ x ] )
-# 24434 "parser_cocci_menhir.ml"
+# 24381 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24461,14 +24408,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let x : (
 # 86 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 24465 "parser_cocci_menhir.ml"
+# 24412 "parser_cocci_menhir.ml"
         ) = Obj.magic x in
         let _startpos = _startpos_x_ in
         let _endpos = _endpos_xs_ in
         let _v : 'tv_separated_nonempty_list_TComma_TString_ = 
 # 146 "standard.mly"
     ( x :: xs )
-# 24472 "parser_cocci_menhir.ml"
+# 24419 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24492,7 +24439,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_any_strict_ = 
 # 144 "standard.mly"
     ( [ x ] )
-# 24496 "parser_cocci_menhir.ml"
+# 24443 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24526,7 +24473,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_any_strict_ = 
 # 146 "standard.mly"
     ( x :: xs )
-# 24530 "parser_cocci_menhir.ml"
+# 24477 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24550,7 +24497,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_ctype_ = 
 # 144 "standard.mly"
     ( [ x ] )
-# 24554 "parser_cocci_menhir.ml"
+# 24501 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24584,7 +24531,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_ctype_ = 
 # 146 "standard.mly"
     ( x :: xs )
-# 24588 "parser_cocci_menhir.ml"
+# 24535 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24608,7 +24555,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_d_ident_ = 
 # 144 "standard.mly"
     ( [ x ] )
-# 24612 "parser_cocci_menhir.ml"
+# 24559 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24642,7 +24589,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_d_ident_ = 
 # 146 "standard.mly"
     ( x :: xs )
-# 24646 "parser_cocci_menhir.ml"
+# 24593 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24666,7 +24613,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_dexpr_ = 
 # 144 "standard.mly"
     ( [ x ] )
-# 24670 "parser_cocci_menhir.ml"
+# 24617 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24700,7 +24647,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_dexpr_ = 
 # 146 "standard.mly"
     ( x :: xs )
-# 24704 "parser_cocci_menhir.ml"
+# 24651 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24724,7 +24671,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_ident_or_const_ = 
 # 144 "standard.mly"
     ( [ x ] )
-# 24728 "parser_cocci_menhir.ml"
+# 24675 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24758,7 +24705,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_ident_or_const_ = 
 # 146 "standard.mly"
     ( x :: xs )
-# 24762 "parser_cocci_menhir.ml"
+# 24709 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24782,7 +24729,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_meta_ident_ = 
 # 144 "standard.mly"
     ( [ x ] )
-# 24786 "parser_cocci_menhir.ml"
+# 24733 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24816,7 +24763,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_meta_ident_ = 
 # 146 "standard.mly"
     ( x :: xs )
-# 24820 "parser_cocci_menhir.ml"
+# 24767 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24840,7 +24787,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_pure_ident_ = 
 # 144 "standard.mly"
     ( [ x ] )
-# 24844 "parser_cocci_menhir.ml"
+# 24791 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24874,7 +24821,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_pure_ident_ = 
 # 146 "standard.mly"
     ( x :: xs )
-# 24878 "parser_cocci_menhir.ml"
+# 24825 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24898,7 +24845,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_ = 
 # 144 "standard.mly"
     ( [ x ] )
-# 24902 "parser_cocci_menhir.ml"
+# 24849 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24932,7 +24879,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_ = 
 # 146 "standard.mly"
     ( x :: xs )
-# 24936 "parser_cocci_menhir.ml"
+# 24883 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24956,7 +24903,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_with_not_eq_not_ceq__ = 
 # 144 "standard.mly"
     ( [ x ] )
-# 24960 "parser_cocci_menhir.ml"
+# 24907 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24990,7 +24937,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_with_not_eq_not_ceq__ = 
 # 146 "standard.mly"
     ( x :: xs )
-# 24994 "parser_cocci_menhir.ml"
+# 24941 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25014,7 +24961,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_with_not_eq_not_eq__ = 
 # 144 "standard.mly"
     ( [ x ] )
-# 25018 "parser_cocci_menhir.ml"
+# 24965 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25048,7 +24995,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_with_not_eq_not_eq__ = 
 # 146 "standard.mly"
     ( x :: xs )
-# 25052 "parser_cocci_menhir.ml"
+# 24999 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25072,7 +25019,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_with_not_eq_not_eqe__ = 
 # 144 "standard.mly"
     ( [ x ] )
-# 25076 "parser_cocci_menhir.ml"
+# 25023 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25106,7 +25053,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_with_not_eq_not_eqe__ = 
 # 146 "standard.mly"
     ( x :: xs )
-# 25110 "parser_cocci_menhir.ml"
+# 25057 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25130,7 +25077,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_with_not_eq_not_pos__ = 
 # 144 "standard.mly"
     ( [ x ] )
-# 25134 "parser_cocci_menhir.ml"
+# 25081 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25164,7 +25111,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_with_not_eq_not_pos__ = 
 # 146 "standard.mly"
     ( x :: xs )
-# 25168 "parser_cocci_menhir.ml"
+# 25115 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25188,7 +25135,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_single_statement = 
 # 864 "parser_cocci_menhir.mly"
                                       ( _1 )
-# 25192 "parser_cocci_menhir.ml"
+# 25139 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25219,13 +25166,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25223 "parser_cocci_menhir.ml"
+# 25170 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_midzero_list_statement_statement_ = Obj.magic _2 in
         let _1 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25229 "parser_cocci_menhir.ml"
+# 25176 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
@@ -25236,7 +25183,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
          (Ast0.Disj(P.clt2mcode "(" _1,
                     List.map (function x -> Ast0.wrap(Ast0.DOTS([x]))) code,
                     mids, P.clt2mcode ")" _3)) )
-# 25240 "parser_cocci_menhir.ml"
+# 25187 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25260,7 +25207,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_statement = 
 # 803 "parser_cocci_menhir.mly"
            ( _1 )
-# 25264 "parser_cocci_menhir.ml"
+# 25211 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25281,14 +25228,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 64 "parser_cocci_menhir.mly"
        (Parse_aux.info)
-# 25285 "parser_cocci_menhir.ml"
+# 25232 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_statement = 
 # 805 "parser_cocci_menhir.mly"
     ( P.meta_stm _1 )
-# 25292 "parser_cocci_menhir.ml"
+# 25239 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25314,7 +25261,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25318 "parser_cocci_menhir.ml"
+# 25265 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_expr = Obj.magic _1 in
         let _startpos = _startpos__1_ in
@@ -25322,7 +25269,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_statement = 
 # 807 "parser_cocci_menhir.mly"
     ( P.exp_stm _1 _2 )
-# 25326 "parser_cocci_menhir.ml"
+# 25273 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25364,25 +25311,25 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _4 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25368 "parser_cocci_menhir.ml"
+# 25315 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr = Obj.magic _3 in
         let _2 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25374 "parser_cocci_menhir.ml"
+# 25321 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 57 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25379 "parser_cocci_menhir.ml"
+# 25326 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__5_ in
         let _v : 'tv_statement = 
 # 809 "parser_cocci_menhir.mly"
     ( P.ifthen _1 _2 _3 _4 _5 )
-# 25386 "parser_cocci_menhir.ml"
+# 25333 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25434,31 +25381,31 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _6 : (
 # 57 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25438 "parser_cocci_menhir.ml"
+# 25385 "parser_cocci_menhir.ml"
         ) = Obj.magic _6 in
         let _5 : 'tv_single_statement = Obj.magic _5 in
         let _4 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25444 "parser_cocci_menhir.ml"
+# 25391 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr = Obj.magic _3 in
         let _2 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25450 "parser_cocci_menhir.ml"
+# 25397 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 57 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25455 "parser_cocci_menhir.ml"
+# 25402 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__7_ in
         let _v : 'tv_statement = 
 # 811 "parser_cocci_menhir.mly"
     ( P.ifthenelse _1 _2 _3 _4 _5 _6 _7 )
-# 25462 "parser_cocci_menhir.ml"
+# 25409 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25520,37 +25467,37 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _8 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25524 "parser_cocci_menhir.ml"
+# 25471 "parser_cocci_menhir.ml"
         ) = Obj.magic _8 in
         let _7 : 'tv_option_eexpr_ = Obj.magic _7 in
         let _6 : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25530 "parser_cocci_menhir.ml"
+# 25477 "parser_cocci_menhir.ml"
         ) = Obj.magic _6 in
         let _5 : 'tv_option_eexpr_ = Obj.magic _5 in
         let _4 : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25536 "parser_cocci_menhir.ml"
+# 25483 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_option_eexpr_ = Obj.magic _3 in
         let _2 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25542 "parser_cocci_menhir.ml"
+# 25489 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 57 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25547 "parser_cocci_menhir.ml"
+# 25494 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__9_ in
         let _v : 'tv_statement = 
 # 814 "parser_cocci_menhir.mly"
     ( P.forloop _1 _2 _3 _4 _5 _6 _7 _8 _9 )
-# 25554 "parser_cocci_menhir.ml"
+# 25501 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25592,25 +25539,25 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _4 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25596 "parser_cocci_menhir.ml"
+# 25543 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr = Obj.magic _3 in
         let _2 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25602 "parser_cocci_menhir.ml"
+# 25549 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 57 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25607 "parser_cocci_menhir.ml"
+# 25554 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__5_ in
         let _v : 'tv_statement = 
 # 816 "parser_cocci_menhir.mly"
     ( P.whileloop _1 _2 _3 _4 _5 )
-# 25614 "parser_cocci_menhir.ml"
+# 25561 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25661,36 +25608,36 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _7 : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25665 "parser_cocci_menhir.ml"
+# 25612 "parser_cocci_menhir.ml"
         ) = Obj.magic _7 in
         let _6 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25670 "parser_cocci_menhir.ml"
+# 25617 "parser_cocci_menhir.ml"
         ) = Obj.magic _6 in
         let _5 : 'tv_eexpr = Obj.magic _5 in
         let _4 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25676 "parser_cocci_menhir.ml"
+# 25623 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : (
 # 57 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25681 "parser_cocci_menhir.ml"
+# 25628 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_single_statement = Obj.magic _2 in
         let _1 : (
 # 57 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25687 "parser_cocci_menhir.ml"
+# 25634 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__7_ in
         let _v : 'tv_statement = 
 # 818 "parser_cocci_menhir.mly"
     ( P.doloop _1 _2 _3 _4 _5 _6 _7 )
-# 25694 "parser_cocci_menhir.ml"
+# 25641 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25732,13 +25679,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _4 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25736 "parser_cocci_menhir.ml"
+# 25683 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr_list_option = Obj.magic _3 in
         let _2 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25742 "parser_cocci_menhir.ml"
+# 25689 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_iter_ident = Obj.magic _1 in
         let _startpos = _startpos__1_ in
@@ -25746,7 +25693,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_statement = 
 # 820 "parser_cocci_menhir.mly"
     ( P.iterator _1 _2 _3 _4 _5 )
-# 25750 "parser_cocci_menhir.ml"
+# 25697 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25797,36 +25744,36 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _7 : (
 # 100 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25801 "parser_cocci_menhir.ml"
+# 25748 "parser_cocci_menhir.ml"
         ) = Obj.magic _7 in
         let _6 : 'tv_list_case_line_ = Obj.magic _6 in
         let _5 : (
 # 100 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25807 "parser_cocci_menhir.ml"
+# 25754 "parser_cocci_menhir.ml"
         ) = Obj.magic _5 in
         let _4 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25812 "parser_cocci_menhir.ml"
+# 25759 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr = Obj.magic _3 in
         let _2 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25818 "parser_cocci_menhir.ml"
+# 25765 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 57 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25823 "parser_cocci_menhir.ml"
+# 25770 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__7_ in
         let _v : 'tv_statement = 
 # 822 "parser_cocci_menhir.mly"
     ( P.switch _1 _2 _3 _4 _5 _6 _7 )
-# 25830 "parser_cocci_menhir.ml"
+# 25777 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25857,20 +25804,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25861 "parser_cocci_menhir.ml"
+# 25808 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_eexpr = Obj.magic _2 in
         let _1 : (
 # 57 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25867 "parser_cocci_menhir.ml"
+# 25814 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_statement = 
 # 823 "parser_cocci_menhir.mly"
                         ( P.ret_exp _1 _2 _3 )
-# 25874 "parser_cocci_menhir.ml"
+# 25821 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25896,19 +25843,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25900 "parser_cocci_menhir.ml"
+# 25847 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 57 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25905 "parser_cocci_menhir.ml"
+# 25852 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_statement = 
 # 824 "parser_cocci_menhir.mly"
                   ( P.ret _1 _2 )
-# 25912 "parser_cocci_menhir.ml"
+# 25859 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25934,19 +25881,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25938 "parser_cocci_menhir.ml"
+# 25885 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25943 "parser_cocci_menhir.ml"
+# 25890 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_statement = 
 # 825 "parser_cocci_menhir.mly"
                  ( P.break _1 _2 )
-# 25950 "parser_cocci_menhir.ml"
+# 25897 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25972,19 +25919,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25976 "parser_cocci_menhir.ml"
+# 25923 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25981 "parser_cocci_menhir.ml"
+# 25928 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_statement = 
 # 826 "parser_cocci_menhir.mly"
                     ( P.cont _1 _2 )
-# 25988 "parser_cocci_menhir.ml"
+# 25935 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26010,7 +25957,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26014 "parser_cocci_menhir.ml"
+# 25961 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_ident = Obj.magic _1 in
         let _startpos = _startpos__1_ in
@@ -26018,7 +25965,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_statement = 
 # 827 "parser_cocci_menhir.mly"
                 ( P.label _1 _2 )
-# 26022 "parser_cocci_menhir.ml"
+# 25969 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26049,20 +25996,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26053 "parser_cocci_menhir.ml"
+# 26000 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_ident = Obj.magic _2 in
         let _1 : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26059 "parser_cocci_menhir.ml"
+# 26006 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_statement = 
 # 828 "parser_cocci_menhir.mly"
                       ( P.goto _1 _2 _3 )
-# 26066 "parser_cocci_menhir.ml"
+# 26013 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26093,20 +26040,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 100 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26097 "parser_cocci_menhir.ml"
+# 26044 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_fun_start = Obj.magic _2 in
         let _1 : (
 # 100 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26103 "parser_cocci_menhir.ml"
+# 26050 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_statement = 
 # 830 "parser_cocci_menhir.mly"
     ( P.seq _1 _2 _3 )
-# 26110 "parser_cocci_menhir.ml"
+# 26057 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26133,14 +26080,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 72 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26137 "parser_cocci_menhir.ml"
+# 26084 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_w_ in
         let _v : 'tv_stm_dots = 
 # 834 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.Dots(P.clt2mcode "..." _1, List.concat w)) )
-# 26144 "parser_cocci_menhir.ml"
+# 26091 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26176,14 +26123,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let c : (
 # 72 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26180 "parser_cocci_menhir.ml"
+# 26127 "parser_cocci_menhir.ml"
         ) = Obj.magic c in
         let b : 'tv_nest_start = Obj.magic b in
         let w : 'tv_list_whenppdecs_ = Obj.magic w in
         let _1 : (
 # 72 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26187 "parser_cocci_menhir.ml"
+# 26134 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_c_ in
@@ -26191,7 +26138,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
 # 836 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.Nest(P.clt2mcode "<..." _1, b,
                          P.clt2mcode "...>" c, List.concat w, false)) )
-# 26195 "parser_cocci_menhir.ml"
+# 26142 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26227,14 +26174,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let c : (
 # 72 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26231 "parser_cocci_menhir.ml"
+# 26178 "parser_cocci_menhir.ml"
         ) = Obj.magic c in
         let b : 'tv_nest_start = Obj.magic b in
         let w : 'tv_list_whenppdecs_ = Obj.magic w in
         let _1 : (
 # 72 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26238 "parser_cocci_menhir.ml"
+# 26185 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_c_ in
@@ -26242,7 +26189,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
 # 839 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.Nest(P.clt2mcode "<+..." _1, b,
                          P.clt2mcode "...+>" c, List.concat w, true)) )
-# 26246 "parser_cocci_menhir.ml"
+# 26193 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26263,14 +26210,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let s : (
 # 53 "parser_cocci_menhir.mly"
       (Data.clt)
-# 26267 "parser_cocci_menhir.ml"
+# 26214 "parser_cocci_menhir.ml"
         ) = Obj.magic s in
         let _startpos = _startpos_s_ in
         let _endpos = _endpos_s_ in
         let _v : 'tv_storage = 
 # 762 "parser_cocci_menhir.mly"
                         ( P.clt2mcode Ast.Static s )
-# 26274 "parser_cocci_menhir.ml"
+# 26221 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26291,14 +26238,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let s : (
 # 53 "parser_cocci_menhir.mly"
       (Data.clt)
-# 26295 "parser_cocci_menhir.ml"
+# 26242 "parser_cocci_menhir.ml"
         ) = Obj.magic s in
         let _startpos = _startpos_s_ in
         let _endpos = _endpos_s_ in
         let _v : 'tv_storage = 
 # 763 "parser_cocci_menhir.mly"
                         ( P.clt2mcode Ast.Auto s )
-# 26302 "parser_cocci_menhir.ml"
+# 26249 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26319,14 +26266,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let s : (
 # 53 "parser_cocci_menhir.mly"
       (Data.clt)
-# 26323 "parser_cocci_menhir.ml"
+# 26270 "parser_cocci_menhir.ml"
         ) = Obj.magic s in
         let _startpos = _startpos_s_ in
         let _endpos = _endpos_s_ in
         let _v : 'tv_storage = 
 # 764 "parser_cocci_menhir.mly"
                         ( P.clt2mcode Ast.Register s )
-# 26330 "parser_cocci_menhir.ml"
+# 26277 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26347,14 +26294,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let s : (
 # 53 "parser_cocci_menhir.mly"
       (Data.clt)
-# 26351 "parser_cocci_menhir.ml"
+# 26298 "parser_cocci_menhir.ml"
         ) = Obj.magic s in
         let _startpos = _startpos_s_ in
         let _endpos = _endpos_s_ in
         let _v : 'tv_storage = 
 # 765 "parser_cocci_menhir.mly"
                         ( P.clt2mcode Ast.Extern s )
-# 26358 "parser_cocci_menhir.ml"
+# 26305 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26376,7 +26323,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_struct_decl = 
 # 488 "parser_cocci_menhir.mly"
                ( [] )
-# 26380 "parser_cocci_menhir.ml"
+# 26327 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26407,7 +26354,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26411 "parser_cocci_menhir.ml"
+# 26358 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let d : 'tv_d_ident = Obj.magic d in
         let t : 'tv_ctype = Obj.magic t in
@@ -26417,7 +26364,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
 # 490 "parser_cocci_menhir.mly"
   ( let (id,fn) = d in
         [Ast0.wrap(Ast0.UnInit(None,fn t,id,P.clt2mcode ";" pv))] )
-# 26421 "parser_cocci_menhir.ml"
+# 26368 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26478,34 +26425,34 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26482 "parser_cocci_menhir.ml"
+# 26429 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let rp2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26487 "parser_cocci_menhir.ml"
+# 26434 "parser_cocci_menhir.ml"
         ) = Obj.magic rp2 in
         let p : 'tv_decl_list_name_opt_decl_ = Obj.magic p in
         let lp2 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26493 "parser_cocci_menhir.ml"
+# 26440 "parser_cocci_menhir.ml"
         ) = Obj.magic lp2 in
         let rp1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26498 "parser_cocci_menhir.ml"
+# 26445 "parser_cocci_menhir.ml"
         ) = Obj.magic rp1 in
         let d : 'tv_d_ident = Obj.magic d in
         let st : (
 # 98 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26504 "parser_cocci_menhir.ml"
+# 26451 "parser_cocci_menhir.ml"
         ) = Obj.magic st in
         let lp1 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26509 "parser_cocci_menhir.ml"
+# 26456 "parser_cocci_menhir.ml"
         ) = Obj.magic lp1 in
         let t : 'tv_fn_ctype = Obj.magic t in
         let _startpos = _startpos_t_ in
@@ -26519,7 +26466,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
               (t,P.clt2mcode "(" lp1,P.clt2mcode "*" st,P.clt2mcode ")" rp1,
                P.clt2mcode "(" lp2,p,P.clt2mcode ")" rp2)) in
         [Ast0.wrap(Ast0.UnInit(None,fn t,id,P.clt2mcode ";" pv))] )
-# 26523 "parser_cocci_menhir.ml"
+# 26470 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26550,7 +26497,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26554 "parser_cocci_menhir.ml"
+# 26501 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let d : 'tv_d_ident = Obj.magic d in
         let i : 'tv_pure_ident = Obj.magic i in
@@ -26560,7 +26507,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 39 "standard.mly"
     ( None )
-# 26564 "parser_cocci_menhir.ml"
+# 26511 "parser_cocci_menhir.ml"
           
         in
         
@@ -26568,7 +26515,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
   ( let (id,fn) = d in
         let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
         [Ast0.wrap(Ast0.UnInit(None,fn idtype,id,P.clt2mcode ";" pv))] )
-# 26572 "parser_cocci_menhir.ml"
+# 26519 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26604,7 +26551,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 106 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26608 "parser_cocci_menhir.ml"
+# 26555 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let d : 'tv_d_ident = Obj.magic d in
         let i : 'tv_pure_ident = Obj.magic i in
@@ -26616,7 +26563,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 26620 "parser_cocci_menhir.ml"
+# 26567 "parser_cocci_menhir.ml"
           
         in
         
@@ -26624,7 +26571,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
   ( let (id,fn) = d in
         let idtype = P.make_cv cv (Ast0.wrap (Ast0.TypeName(P.id2mcode i))) in
         [Ast0.wrap(Ast0.UnInit(None,fn idtype,id,P.clt2mcode ";" pv))] )
-# 26628 "parser_cocci_menhir.ml"
+# 26575 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26648,7 +26595,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_struct_decl_list = 
 # 507 "parser_cocci_menhir.mly"
                           ( Ast0.wrap(Ast0.DOTS(_1)) )
-# 26652 "parser_cocci_menhir.ml"
+# 26599 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26672,7 +26619,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_struct_decl_list_start = 
 # 510 "parser_cocci_menhir.mly"
                                      ( _1 )
-# 26676 "parser_cocci_menhir.ml"
+# 26623 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26702,7 +26649,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_struct_decl_list_start = 
 # 511 "parser_cocci_menhir.mly"
                                      ( _1@_2 )
-# 26706 "parser_cocci_menhir.ml"
+# 26653 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26732,7 +26679,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_struct_decl_list_start = 
 # 513 "parser_cocci_menhir.mly"
     ( (P.mkddots "..." d)::r )
-# 26736 "parser_cocci_menhir.ml"
+# 26683 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26753,14 +26700,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let s : (
 # 50 "parser_cocci_menhir.mly"
       (Data.clt)
-# 26757 "parser_cocci_menhir.ml"
+# 26704 "parser_cocci_menhir.ml"
         ) = Obj.magic s in
         let _startpos = _startpos_s_ in
         let _endpos = _endpos_s_ in
         let _v : 'tv_struct_or_union = 
 # 484 "parser_cocci_menhir.mly"
                  ( P.clt2mcode Ast.Struct s )
-# 26764 "parser_cocci_menhir.ml"
+# 26711 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26781,14 +26728,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let u : (
 # 50 "parser_cocci_menhir.mly"
       (Data.clt)
-# 26785 "parser_cocci_menhir.ml"
+# 26732 "parser_cocci_menhir.ml"
         ) = Obj.magic u in
         let _startpos = _startpos_u_ in
         let _endpos = _endpos_u_ in
         let _v : 'tv_struct_or_union = 
 # 485 "parser_cocci_menhir.mly"
                  ( P.clt2mcode Ast.Union u )
-# 26792 "parser_cocci_menhir.ml"
+# 26739 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26812,7 +26759,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_top_eexpr = 
 # 1137 "parser_cocci_menhir.mly"
         ( Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Exp(_1)))) )
-# 26816 "parser_cocci_menhir.ml"
+# 26763 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26843,20 +26790,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 100 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26847 "parser_cocci_menhir.ml"
+# 26794 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_initialize_list = Obj.magic _2 in
         let _1 : (
 # 100 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26853 "parser_cocci_menhir.ml"
+# 26800 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_top_init = 
-# 1547 "parser_cocci_menhir.mly"
+# 1548 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.InitList(P.clt2mcode "{" _1,_2,P.clt2mcode "}" _3)) )
-# 26860 "parser_cocci_menhir.ml"
+# 26807 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26871,9 +26818,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
         let _endpos = _startpos in
         let _v : 'tv_toplevel_after_dots = 
-# 1535 "parser_cocci_menhir.mly"
+# 1536 "parser_cocci_menhir.mly"
                                      ([])
-# 26877 "parser_cocci_menhir.ml"
+# 26824 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26899,9 +26846,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_after_dots = 
-# 1536 "parser_cocci_menhir.mly"
+# 1537 "parser_cocci_menhir.mly"
                                      (_2)
-# 26905 "parser_cocci_menhir.ml"
+# 26852 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26929,9 +26876,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_after_dots = 
-# 1537 "parser_cocci_menhir.mly"
+# 1538 "parser_cocci_menhir.mly"
                                      ((Ast0.wrap(Ast0.Exp(_1)))::_2)
-# 26935 "parser_cocci_menhir.ml"
+# 26882 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26959,9 +26906,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_after_dots = 
-# 1538 "parser_cocci_menhir.mly"
+# 1539 "parser_cocci_menhir.mly"
                                           (_1@_2)
-# 26965 "parser_cocci_menhir.ml"
+# 26912 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26987,9 +26934,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_after_dots_init = 
-# 1526 "parser_cocci_menhir.mly"
+# 1527 "parser_cocci_menhir.mly"
                                      (_2)
-# 26993 "parser_cocci_menhir.ml"
+# 26940 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27017,9 +26964,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_after_dots_init = 
-# 1527 "parser_cocci_menhir.mly"
+# 1528 "parser_cocci_menhir.mly"
                                      ((Ast0.wrap(Ast0.Exp(_1)))::_2)
-# 27023 "parser_cocci_menhir.ml"
+# 26970 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27047,9 +26994,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_after_dots_init = 
-# 1528 "parser_cocci_menhir.mly"
+# 1529 "parser_cocci_menhir.mly"
                                           (_1@_2)
-# 27053 "parser_cocci_menhir.ml"
+# 27000 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27064,9 +27011,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
         let _endpos = _startpos in
         let _v : 'tv_toplevel_after_exp = 
-# 1531 "parser_cocci_menhir.mly"
+# 1532 "parser_cocci_menhir.mly"
                                      ([])
-# 27070 "parser_cocci_menhir.ml"
+# 27017 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27094,9 +27041,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_after_exp = 
-# 1532 "parser_cocci_menhir.mly"
+# 1533 "parser_cocci_menhir.mly"
                                      (_1::_2)
-# 27100 "parser_cocci_menhir.ml"
+# 27047 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27111,9 +27058,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
         let _endpos = _startpos in
         let _v : 'tv_toplevel_after_stm = 
-# 1541 "parser_cocci_menhir.mly"
+# 1542 "parser_cocci_menhir.mly"
                                      ([])
-# 27117 "parser_cocci_menhir.ml"
+# 27064 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27141,9 +27088,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_after_stm = 
-# 1542 "parser_cocci_menhir.mly"
+# 1543 "parser_cocci_menhir.mly"
                                      (_1::_2)
-# 27147 "parser_cocci_menhir.ml"
+# 27094 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27171,9 +27118,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_after_stm = 
-# 1543 "parser_cocci_menhir.mly"
+# 1544 "parser_cocci_menhir.mly"
                                      (_1@_2)
-# 27177 "parser_cocci_menhir.ml"
+# 27124 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27201,9 +27148,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_seq_start_toplevel_after_dots_ = 
-# 1521 "parser_cocci_menhir.mly"
+# 1522 "parser_cocci_menhir.mly"
                                      ( _1::_2 )
-# 27207 "parser_cocci_menhir.ml"
+# 27154 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27231,9 +27178,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_seq_start_toplevel_after_dots_ = 
-# 1522 "parser_cocci_menhir.mly"
+# 1523 "parser_cocci_menhir.mly"
                                      ( (Ast0.wrap(Ast0.Exp(_1)))::_2 )
-# 27237 "parser_cocci_menhir.ml"
+# 27184 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27261,9 +27208,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_seq_start_toplevel_after_dots_ = 
-# 1523 "parser_cocci_menhir.mly"
+# 1524 "parser_cocci_menhir.mly"
                                           ( _1@_2 )
-# 27267 "parser_cocci_menhir.ml"
+# 27214 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27291,9 +27238,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_seq_start_toplevel_after_dots_init_ = 
-# 1521 "parser_cocci_menhir.mly"
+# 1522 "parser_cocci_menhir.mly"
                                      ( _1::_2 )
-# 27297 "parser_cocci_menhir.ml"
+# 27244 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27321,9 +27268,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_seq_start_toplevel_after_dots_init_ = 
-# 1522 "parser_cocci_menhir.mly"
+# 1523 "parser_cocci_menhir.mly"
                                      ( (Ast0.wrap(Ast0.Exp(_1)))::_2 )
-# 27327 "parser_cocci_menhir.ml"
+# 27274 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27351,9 +27298,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_seq_start_toplevel_after_dots_init_ = 
-# 1523 "parser_cocci_menhir.mly"
+# 1524 "parser_cocci_menhir.mly"
                                           ( _1@_2 )
-# 27357 "parser_cocci_menhir.ml"
+# 27304 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27375,9 +27322,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_typedef_ident = 
-# 1434 "parser_cocci_menhir.mly"
+# 1435 "parser_cocci_menhir.mly"
          ( Ast0.wrap(Ast0.TypeName(P.id2mcode _1)) )
-# 27381 "parser_cocci_menhir.ml"
+# 27328 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27398,15 +27345,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 64 "parser_cocci_menhir.mly"
        (Parse_aux.info)
-# 27402 "parser_cocci_menhir.ml"
+# 27349 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_typedef_ident = 
-# 1436 "parser_cocci_menhir.mly"
+# 1437 "parser_cocci_menhir.mly"
          ( let (nm,pure,clt) = _1 in
         Ast0.wrap(Ast0.MetaType(P.clt2mcode nm clt,pure)) )
-# 27410 "parser_cocci_menhir.ml"
+# 27357 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27428,9 +27375,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_unary_expr_eexpr_dot_expressions_ = 
-# 1225 "parser_cocci_menhir.mly"
+# 1226 "parser_cocci_menhir.mly"
                                          ( _1 )
-# 27434 "parser_cocci_menhir.ml"
+# 27381 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27457,14 +27404,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 84 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27461 "parser_cocci_menhir.ml"
+# 27408 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_eexpr_dot_expressions_ = 
-# 1227 "parser_cocci_menhir.mly"
+# 1228 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Inc _1)) )
-# 27468 "parser_cocci_menhir.ml"
+# 27415 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27491,14 +27438,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 84 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27495 "parser_cocci_menhir.ml"
+# 27442 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_eexpr_dot_expressions_ = 
-# 1229 "parser_cocci_menhir.mly"
+# 1230 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Dec _1)) )
-# 27502 "parser_cocci_menhir.ml"
+# 27449 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27526,9 +27473,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_eexpr_dot_expressions_ = 
-# 1231 "parser_cocci_menhir.mly"
+# 1232 "parser_cocci_menhir.mly"
       ( let mcode = _1 in Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 27532 "parser_cocci_menhir.ml"
+# 27479 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27555,15 +27502,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27559 "parser_cocci_menhir.ml"
+# 27506 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_eexpr_dot_expressions_ = 
-# 1233 "parser_cocci_menhir.mly"
+# 1234 "parser_cocci_menhir.mly"
       ( let mcode = P.clt2mcode Ast.Not _1 in
       Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 27567 "parser_cocci_menhir.ml"
+# 27514 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27590,14 +27537,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27594 "parser_cocci_menhir.ml"
+# 27541 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_eexpr_dot_expressions_ = 
-# 1236 "parser_cocci_menhir.mly"
+# 1237 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.SizeOfExpr (P.clt2mcode "sizeof" _1, _2)) )
-# 27601 "parser_cocci_menhir.ml"
+# 27548 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27633,27 +27580,27 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let rp : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27637 "parser_cocci_menhir.ml"
+# 27584 "parser_cocci_menhir.ml"
         ) = Obj.magic rp in
         let t : 'tv_ctype = Obj.magic t in
         let lp : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27643 "parser_cocci_menhir.ml"
+# 27590 "parser_cocci_menhir.ml"
         ) = Obj.magic lp in
         let s : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27648 "parser_cocci_menhir.ml"
+# 27595 "parser_cocci_menhir.ml"
         ) = Obj.magic s in
         let _startpos = _startpos_s_ in
         let _endpos = _endpos_rp_ in
         let _v : 'tv_unary_expr_eexpr_dot_expressions_ = 
-# 1238 "parser_cocci_menhir.mly"
+# 1239 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.SizeOfType (P.clt2mcode "sizeof" s,
                                    P.clt2mcode "(" lp,t,
                                    P.clt2mcode ")" rp)) )
-# 27657 "parser_cocci_menhir.ml"
+# 27604 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27675,9 +27622,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_unary_expr_eexpr_invalid_ = 
-# 1225 "parser_cocci_menhir.mly"
+# 1226 "parser_cocci_menhir.mly"
                                          ( _1 )
-# 27681 "parser_cocci_menhir.ml"
+# 27628 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27704,14 +27651,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 84 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27708 "parser_cocci_menhir.ml"
+# 27655 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_eexpr_invalid_ = 
-# 1227 "parser_cocci_menhir.mly"
+# 1228 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Inc _1)) )
-# 27715 "parser_cocci_menhir.ml"
+# 27662 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27738,14 +27685,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 84 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27742 "parser_cocci_menhir.ml"
+# 27689 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_eexpr_invalid_ = 
-# 1229 "parser_cocci_menhir.mly"
+# 1230 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Dec _1)) )
-# 27749 "parser_cocci_menhir.ml"
+# 27696 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27773,9 +27720,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_eexpr_invalid_ = 
-# 1231 "parser_cocci_menhir.mly"
+# 1232 "parser_cocci_menhir.mly"
       ( let mcode = _1 in Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 27779 "parser_cocci_menhir.ml"
+# 27726 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27802,15 +27749,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27806 "parser_cocci_menhir.ml"
+# 27753 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_eexpr_invalid_ = 
-# 1233 "parser_cocci_menhir.mly"
+# 1234 "parser_cocci_menhir.mly"
       ( let mcode = P.clt2mcode Ast.Not _1 in
       Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 27814 "parser_cocci_menhir.ml"
+# 27761 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27837,14 +27784,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27841 "parser_cocci_menhir.ml"
+# 27788 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_eexpr_invalid_ = 
-# 1236 "parser_cocci_menhir.mly"
+# 1237 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.SizeOfExpr (P.clt2mcode "sizeof" _1, _2)) )
-# 27848 "parser_cocci_menhir.ml"
+# 27795 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27880,27 +27827,27 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let rp : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27884 "parser_cocci_menhir.ml"
+# 27831 "parser_cocci_menhir.ml"
         ) = Obj.magic rp in
         let t : 'tv_ctype = Obj.magic t in
         let lp : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27890 "parser_cocci_menhir.ml"
+# 27837 "parser_cocci_menhir.ml"
         ) = Obj.magic lp in
         let s : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27895 "parser_cocci_menhir.ml"
+# 27842 "parser_cocci_menhir.ml"
         ) = Obj.magic s in
         let _startpos = _startpos_s_ in
         let _endpos = _endpos_rp_ in
         let _v : 'tv_unary_expr_eexpr_invalid_ = 
-# 1238 "parser_cocci_menhir.mly"
+# 1239 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.SizeOfType (P.clt2mcode "sizeof" s,
                                    P.clt2mcode "(" lp,t,
                                    P.clt2mcode ")" rp)) )
-# 27904 "parser_cocci_menhir.ml"
+# 27851 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27922,9 +27869,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_unary_expr_eexpr_nest_expressions_ = 
-# 1225 "parser_cocci_menhir.mly"
+# 1226 "parser_cocci_menhir.mly"
                                          ( _1 )
-# 27928 "parser_cocci_menhir.ml"
+# 27875 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27951,14 +27898,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 84 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27955 "parser_cocci_menhir.ml"
+# 27902 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_eexpr_nest_expressions_ = 
-# 1227 "parser_cocci_menhir.mly"
+# 1228 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Inc _1)) )
-# 27962 "parser_cocci_menhir.ml"
+# 27909 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27985,14 +27932,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 84 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27989 "parser_cocci_menhir.ml"
+# 27936 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_eexpr_nest_expressions_ = 
-# 1229 "parser_cocci_menhir.mly"
+# 1230 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Dec _1)) )
-# 27996 "parser_cocci_menhir.ml"
+# 27943 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28020,9 +27967,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_eexpr_nest_expressions_ = 
-# 1231 "parser_cocci_menhir.mly"
+# 1232 "parser_cocci_menhir.mly"
       ( let mcode = _1 in Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 28026 "parser_cocci_menhir.ml"
+# 27973 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28049,15 +27996,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28053 "parser_cocci_menhir.ml"
+# 28000 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_eexpr_nest_expressions_ = 
-# 1233 "parser_cocci_menhir.mly"
+# 1234 "parser_cocci_menhir.mly"
       ( let mcode = P.clt2mcode Ast.Not _1 in
       Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 28061 "parser_cocci_menhir.ml"
+# 28008 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28084,14 +28031,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28088 "parser_cocci_menhir.ml"
+# 28035 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_eexpr_nest_expressions_ = 
-# 1236 "parser_cocci_menhir.mly"
+# 1237 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.SizeOfExpr (P.clt2mcode "sizeof" _1, _2)) )
-# 28095 "parser_cocci_menhir.ml"
+# 28042 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28127,27 +28074,27 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let rp : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28131 "parser_cocci_menhir.ml"
+# 28078 "parser_cocci_menhir.ml"
         ) = Obj.magic rp in
         let t : 'tv_ctype = Obj.magic t in
         let lp : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28137 "parser_cocci_menhir.ml"
+# 28084 "parser_cocci_menhir.ml"
         ) = Obj.magic lp in
         let s : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28142 "parser_cocci_menhir.ml"
+# 28089 "parser_cocci_menhir.ml"
         ) = Obj.magic s in
         let _startpos = _startpos_s_ in
         let _endpos = _endpos_rp_ in
         let _v : 'tv_unary_expr_eexpr_nest_expressions_ = 
-# 1238 "parser_cocci_menhir.mly"
+# 1239 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.SizeOfType (P.clt2mcode "sizeof" s,
                                    P.clt2mcode "(" lp,t,
                                    P.clt2mcode ")" rp)) )
-# 28151 "parser_cocci_menhir.ml"
+# 28098 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28169,9 +28116,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_unary_expr_expr_invalid_ = 
-# 1225 "parser_cocci_menhir.mly"
+# 1226 "parser_cocci_menhir.mly"
                                          ( _1 )
-# 28175 "parser_cocci_menhir.ml"
+# 28122 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28198,14 +28145,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 84 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28202 "parser_cocci_menhir.ml"
+# 28149 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_expr_invalid_ = 
-# 1227 "parser_cocci_menhir.mly"
+# 1228 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Inc _1)) )
-# 28209 "parser_cocci_menhir.ml"
+# 28156 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28232,14 +28179,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 84 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28236 "parser_cocci_menhir.ml"
+# 28183 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_expr_invalid_ = 
-# 1229 "parser_cocci_menhir.mly"
+# 1230 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Dec _1)) )
-# 28243 "parser_cocci_menhir.ml"
+# 28190 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28267,9 +28214,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_expr_invalid_ = 
-# 1231 "parser_cocci_menhir.mly"
+# 1232 "parser_cocci_menhir.mly"
       ( let mcode = _1 in Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 28273 "parser_cocci_menhir.ml"
+# 28220 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28296,15 +28243,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28300 "parser_cocci_menhir.ml"
+# 28247 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_expr_invalid_ = 
-# 1233 "parser_cocci_menhir.mly"
+# 1234 "parser_cocci_menhir.mly"
       ( let mcode = P.clt2mcode Ast.Not _1 in
       Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 28308 "parser_cocci_menhir.ml"
+# 28255 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28331,14 +28278,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28335 "parser_cocci_menhir.ml"
+# 28282 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_expr_invalid_ = 
-# 1236 "parser_cocci_menhir.mly"
+# 1237 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.SizeOfExpr (P.clt2mcode "sizeof" _1, _2)) )
-# 28342 "parser_cocci_menhir.ml"
+# 28289 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28374,27 +28321,27 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let rp : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28378 "parser_cocci_menhir.ml"
+# 28325 "parser_cocci_menhir.ml"
         ) = Obj.magic rp in
         let t : 'tv_ctype = Obj.magic t in
         let lp : (
 # 75 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28384 "parser_cocci_menhir.ml"
+# 28331 "parser_cocci_menhir.ml"
         ) = Obj.magic lp in
         let s : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28389 "parser_cocci_menhir.ml"
+# 28336 "parser_cocci_menhir.ml"
         ) = Obj.magic s in
         let _startpos = _startpos_s_ in
         let _endpos = _endpos_rp_ in
         let _v : 'tv_unary_expr_expr_invalid_ = 
-# 1238 "parser_cocci_menhir.mly"
+# 1239 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.SizeOfType (P.clt2mcode "sizeof" s,
                                    P.clt2mcode "(" lp,t,
                                    P.clt2mcode ")" rp)) )
-# 28398 "parser_cocci_menhir.ml"
+# 28345 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28415,14 +28362,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 92 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28419 "parser_cocci_menhir.ml"
+# 28366 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_unary_op = 
-# 1242 "parser_cocci_menhir.mly"
+# 1243 "parser_cocci_menhir.mly"
                   ( P.clt2mcode Ast.GetRef _1 )
-# 28426 "parser_cocci_menhir.ml"
+# 28373 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28443,14 +28390,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 98 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28447 "parser_cocci_menhir.ml"
+# 28394 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_unary_op = 
-# 1243 "parser_cocci_menhir.mly"
+# 1244 "parser_cocci_menhir.mly"
            ( P.clt2mcode Ast.DeRef _1 )
-# 28454 "parser_cocci_menhir.ml"
+# 28401 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28471,14 +28418,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 97 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28475 "parser_cocci_menhir.ml"
+# 28422 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_unary_op = 
-# 1244 "parser_cocci_menhir.mly"
+# 1245 "parser_cocci_menhir.mly"
            ( P.clt2mcode Ast.UnPlus _1 )
-# 28482 "parser_cocci_menhir.ml"
+# 28429 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28499,14 +28446,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 97 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28503 "parser_cocci_menhir.ml"
+# 28450 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_unary_op = 
-# 1245 "parser_cocci_menhir.mly"
+# 1246 "parser_cocci_menhir.mly"
            ( P.clt2mcode Ast.UnMinus _1 )
-# 28510 "parser_cocci_menhir.ml"
+# 28457 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28527,14 +28474,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 98 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28531 "parser_cocci_menhir.ml"
+# 28478 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_unary_op = 
-# 1246 "parser_cocci_menhir.mly"
+# 1247 "parser_cocci_menhir.mly"
            ( P.clt2mcode Ast.Tilde _1 )
-# 28538 "parser_cocci_menhir.ml"
+# 28485 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28562,9 +28509,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_when_start = 
-# 1640 "parser_cocci_menhir.mly"
+# 1641 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.DOTS((Ast0.wrap(Ast0.Exp(_1)))::_2)) )
-# 28568 "parser_cocci_menhir.ml"
+# 28515 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28592,45 +28539,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_when_start = 
-# 1642 "parser_cocci_menhir.mly"
+# 1643 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.DOTS(_1@_2)) )
-# 28598 "parser_cocci_menhir.ml"
-         in
-        _menhir_env.MenhirLib.EngineTypes.stack <- {
-          MenhirLib.EngineTypes.state = _menhir_s;
-          MenhirLib.EngineTypes.semv = Obj.repr _v;
-          MenhirLib.EngineTypes.startp = _startpos;
-          MenhirLib.EngineTypes.endp = _endpos;
-          MenhirLib.EngineTypes.next = _menhir_stack;
-          });
-      (fun _menhir_env ->
-        let _menhir_stack = _menhir_env.MenhirLib.EngineTypes.stack in
-        let {
-          MenhirLib.EngineTypes.startp = _startpos__4_;
-          MenhirLib.EngineTypes.endp = _endpos__4_;
-          MenhirLib.EngineTypes.next = {
-            MenhirLib.EngineTypes.semv = w;
-            MenhirLib.EngineTypes.startp = _startpos_w_;
-            MenhirLib.EngineTypes.endp = _endpos_w_;
-            MenhirLib.EngineTypes.next = {
-              MenhirLib.EngineTypes.startp = _startpos__2_;
-              MenhirLib.EngineTypes.endp = _endpos__2_;
-              MenhirLib.EngineTypes.next = {
-                MenhirLib.EngineTypes.state = _menhir_s;
-                MenhirLib.EngineTypes.startp = _startpos__1_;
-                MenhirLib.EngineTypes.endp = _endpos__1_;
-                MenhirLib.EngineTypes.next = _menhir_stack;
-                };
-              };
-            };
-          } = _menhir_stack in
-        let w : 'tv_eexpr = Obj.magic w in
-        let _startpos = _startpos__1_ in
-        let _endpos = _endpos__4_ in
-        let _v : 'tv_whenexp = 
-# 1156 "parser_cocci_menhir.mly"
-                                       ( w )
-# 28634 "parser_cocci_menhir.ml"
+# 28545 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28654,7 +28565,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_whenppdecs = 
 # 843 "parser_cocci_menhir.mly"
     ( w )
-# 28658 "parser_cocci_menhir.ml"
+# 28569 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28688,9 +28599,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__4_ in
         let _v : 'tv_whens_when_start_rule_elem_statement_ = 
-# 1708 "parser_cocci_menhir.mly"
+# 1709 "parser_cocci_menhir.mly"
                                          ( [Ast0.WhenNot w] )
-# 28694 "parser_cocci_menhir.ml"
+# 28605 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28724,9 +28635,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__4_ in
         let _v : 'tv_whens_when_start_rule_elem_statement_ = 
-# 1709 "parser_cocci_menhir.mly"
+# 1710 "parser_cocci_menhir.mly"
                                              ( [Ast0.WhenAlways w] )
-# 28730 "parser_cocci_menhir.ml"
+# 28641 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28756,9 +28667,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_whens_when_start_rule_elem_statement_ = 
-# 1711 "parser_cocci_menhir.mly"
+# 1712 "parser_cocci_menhir.mly"
       ( List.map (function x -> Ast0.WhenModifier(x)) _2 )
-# 28762 "parser_cocci_menhir.ml"
+# 28673 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28792,9 +28703,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__4_ in
         let _v : 'tv_whens_when_start_rule_elem_statement_ = 
-# 1712 "parser_cocci_menhir.mly"
+# 1713 "parser_cocci_menhir.mly"
                                         ( [Ast0.WhenNotTrue e] )
-# 28798 "parser_cocci_menhir.ml"
+# 28709 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28828,9 +28739,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__4_ in
         let _v : 'tv_whens_when_start_rule_elem_statement_ = 
-# 1713 "parser_cocci_menhir.mly"
+# 1714 "parser_cocci_menhir.mly"
                                          ( [Ast0.WhenNotFalse e] )
-# 28834 "parser_cocci_menhir.ml"
+# 28745 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28851,90 +28762,90 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
 
 let rec script_meta_main =
   fun lexer lexbuf ->
-    (Obj.magic (MenhirInterpreter.entry 1493 lexer lexbuf) : (
+    (Obj.magic (MenhirInterpreter.entry 1486 lexer lexbuf) : (
 # 158 "parser_cocci_menhir.mly"
        (string * (string * string))
-# 28858 "parser_cocci_menhir.ml"
+# 28769 "parser_cocci_menhir.ml"
     ))
 
 and rule_name =
   fun lexer lexbuf ->
-    (Obj.magic (MenhirInterpreter.entry 1437 lexer lexbuf) : (
+    (Obj.magic (MenhirInterpreter.entry 1430 lexer lexbuf) : (
 # 152 "parser_cocci_menhir.mly"
       (Ast_cocci.rulename)
-# 28866 "parser_cocci_menhir.ml"
+# 28777 "parser_cocci_menhir.ml"
     ))
 
 and reinit =
   fun lexer lexbuf ->
-    (Obj.magic (MenhirInterpreter.entry 1435 lexer lexbuf) : (
+    (Obj.magic (MenhirInterpreter.entry 1428 lexer lexbuf) : (
 # 130 "parser_cocci_menhir.mly"
       (unit)
-# 28874 "parser_cocci_menhir.ml"
+# 28785 "parser_cocci_menhir.ml"
     ))
 
 and plus_main =
   fun lexer lexbuf ->
-    (Obj.magic (MenhirInterpreter.entry 1399 lexer lexbuf) : (
+    (Obj.magic (MenhirInterpreter.entry 1392 lexer lexbuf) : (
 # 139 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 28882 "parser_cocci_menhir.ml"
+# 28793 "parser_cocci_menhir.ml"
     ))
 
 and plus_exp_main =
   fun lexer lexbuf ->
-    (Obj.magic (MenhirInterpreter.entry 1390 lexer lexbuf) : (
+    (Obj.magic (MenhirInterpreter.entry 1383 lexer lexbuf) : (
 # 142 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 28890 "parser_cocci_menhir.ml"
+# 28801 "parser_cocci_menhir.ml"
     ))
 
 and never_used =
   fun lexer lexbuf ->
-    (Obj.magic (MenhirInterpreter.entry 1384 lexer lexbuf) : (
+    (Obj.magic (MenhirInterpreter.entry 1377 lexer lexbuf) : (
 # 167 "parser_cocci_menhir.mly"
       (unit)
-# 28898 "parser_cocci_menhir.ml"
+# 28809 "parser_cocci_menhir.ml"
     ))
 
 and minus_main =
   fun lexer lexbuf ->
-    (Obj.magic (MenhirInterpreter.entry 1309 lexer lexbuf) : (
+    (Obj.magic (MenhirInterpreter.entry 1302 lexer lexbuf) : (
 # 133 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 28906 "parser_cocci_menhir.ml"
+# 28817 "parser_cocci_menhir.ml"
     ))
 
 and minus_exp_main =
   fun lexer lexbuf ->
-    (Obj.magic (MenhirInterpreter.entry 1285 lexer lexbuf) : (
+    (Obj.magic (MenhirInterpreter.entry 1278 lexer lexbuf) : (
 # 136 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 28914 "parser_cocci_menhir.ml"
+# 28825 "parser_cocci_menhir.ml"
     ))
 
 and meta_main =
   fun lexer lexbuf ->
-    (Obj.magic (MenhirInterpreter.entry 1282 lexer lexbuf) : (
+    (Obj.magic (MenhirInterpreter.entry 1275 lexer lexbuf) : (
 # 156 "parser_cocci_menhir.mly"
       ((Ast_cocci.metavar,Ast_cocci.metavar) Common.either list)
-# 28922 "parser_cocci_menhir.ml"
+# 28833 "parser_cocci_menhir.ml"
     ))
 
 and iso_rule_name =
   fun lexer lexbuf ->
-    (Obj.magic (MenhirInterpreter.entry 1278 lexer lexbuf) : (
+    (Obj.magic (MenhirInterpreter.entry 1271 lexer lexbuf) : (
 # 148 "parser_cocci_menhir.mly"
       (Ast_cocci.rulename)
-# 28930 "parser_cocci_menhir.ml"
+# 28841 "parser_cocci_menhir.ml"
     ))
 
 and iso_meta_main =
   fun lexer lexbuf ->
-    (Obj.magic (MenhirInterpreter.entry 1086 lexer lexbuf) : (
+    (Obj.magic (MenhirInterpreter.entry 1079 lexer lexbuf) : (
 # 164 "parser_cocci_menhir.mly"
       ((Ast_cocci.metavar,Ast_cocci.metavar) Common.either list)
-# 28938 "parser_cocci_menhir.ml"
+# 28849 "parser_cocci_menhir.ml"
     ))
 
 and iso_main =
@@ -28942,7 +28853,7 @@ and iso_main =
     (Obj.magic (MenhirInterpreter.entry 10 lexer lexbuf) : (
 # 161 "parser_cocci_menhir.mly"
       (Ast0_cocci.anything list list)
-# 28946 "parser_cocci_menhir.ml"
+# 28857 "parser_cocci_menhir.ml"
     ))
 
 and include_main =
@@ -28950,7 +28861,7 @@ and include_main =
     (Obj.magic (MenhirInterpreter.entry 0 lexer lexbuf) : (
 # 145 "parser_cocci_menhir.mly"
       ((string,string) Common.either list)
-# 28954 "parser_cocci_menhir.ml"
+# 28865 "parser_cocci_menhir.ml"
     ))
 
 
index 1e71638..76942f4 100644 (file)
@@ -1143,17 +1143,18 @@ dot_expressions:
   TEllipsis { Ast0.wrap(Ast0.Edots(P.clt2mcode "..." $1,None)) }
 | nest_expressions { $1 }
 
+/* not clear what whencode would mean, so just drop it */
 nest_expressions:
-  TOEllipsis w=option(whenexp) e=expr_dots(TEllipsis) c=TCEllipsis
+  TOEllipsis e=expr_dots(TEllipsis) c=TCEllipsis
     { Ast0.wrap(Ast0.NestExpr(P.clt2mcode "<..." $1,
                              Ast0.wrap(Ast0.DOTS(e (P.mkedots "..."))),
-                             P.clt2mcode "...>" c, w, false)) }
-| TPOEllipsis w=option(whenexp) e=expr_dots(TEllipsis) c=TPCEllipsis
+                             P.clt2mcode "...>" c, None, false)) }
+| TPOEllipsis e=expr_dots(TEllipsis) c=TPCEllipsis
     { Ast0.wrap(Ast0.NestExpr(P.clt2mcode "<+..." $1,
                              Ast0.wrap(Ast0.DOTS(e (P.mkedots "..."))),
-                             P.clt2mcode "...+>" c, w, true)) }
+                             P.clt2mcode "...+>" c, None, true)) }
 
-whenexp: TWhen TNotEq w=eexpr TLineEnd { w }
+//whenexp: TWhen TNotEq w=eexpr TLineEnd { w }
 
 basic_expr(recurser,primary_extra):
   assign_expr(recurser,primary_extra)                        { $1 }
index 31ad2c0..a557b0e 100644 (file)
@@ -155,11 +155,11 @@ let update_unitary unitary =
   
   let is_unitary name =
     match (List.mem (Ast0.unwrap_mcode name) unitary,
-          Ast0.get_mcode_mcodekind name) with
-      (true,Ast0.CONTEXT(mc)) -> Ast0.PureContext
-    | (true,_) -> Ast0.Pure
-    | (false,Ast0.CONTEXT(mc)) -> Ast0.Context
-    | (false,_) -> Ast0.Impure in
+          !Flag.sgrep_mode2, Ast0.get_mcode_mcodekind name) with
+      (true,true,_) | (true,_,Ast0.CONTEXT(_)) -> Ast0.PureContext
+    | (true,_,_) -> Ast0.Pure
+    | (false,true,_) | (false,_,Ast0.CONTEXT(_)) -> Ast0.Context
+    | (false,_,_) -> Ast0.Impure in
 
   let ident r k i =
     match Ast0.unwrap i with
index 7fb2c75..c77a39b 100644 (file)
@@ -197,8 +197,14 @@ let rec expression e =
          mcode print_string rp
       | Ast0.TypeExp(ty) -> typeC ty
       | Ast0.MetaErr(name,_,_) -> mcode print_meta name
-      | Ast0.MetaExpr(name,_,ty,_,_) ->
-         mcode print_meta name; print_types ty
+      | Ast0.MetaExpr(name,_,ty,_,pure) ->
+         mcode print_meta name; print_types ty(*;
+         print_string "^";
+         (match pure with
+           Ast0.Pure -> print_string "pure"
+         | Ast0.Impure -> print_string "impure"
+         | Ast0.Context -> print_string "context"
+         | Ast0.PureContext -> print_string "pure_context")*)
       | Ast0.MetaExprList(name,_,_) -> mcode print_meta name
       | Ast0.EComma(cm) -> mcode print_string cm; print_space()
       | Ast0.DisjExpr(_,exp_list,_,_) ->
diff --git a/popl09/.#Makefile.1.3 b/popl09/.#Makefile.1.3
new file mode 100644 (file)
index 0000000..96ec617
--- /dev/null
@@ -0,0 +1,101 @@
+# Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+# Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+# This file is part of Coccinelle.
+# 
+# Coccinelle is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, according to version 2 of the License.
+# 
+# Coccinelle is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
+# 
+# The authors reserve the right to distribute this or future versions of
+# Coccinelle under other licenses.
+
+
+#note: if you add a file (a .mli or .ml), dont forget to do a   make depend
+
+TARGET = popl
+
+SRC = ast_popl.ml asttopopl.ml insert_quantifiers.ml \
+pretty_print_popl.ml flag_popl.ml popltoctl.ml popl.ml
+
+SYSLIBS=str.cma unix.cma
+LIBS=../commons/commons.cma ../globals/globals.cma
+
+INCLUDES = -I ../commons -I ../globals \
+              -I ../ctl -I ../parsing_c -I ../parsing_cocci -I ../engine
+
+#The Caml compilers.
+#for warning:  -w A 
+#for profiling:  -p -inline 0   with OCAMLOPT
+OCAMLCFLAGS ?= -g -dtypes
+OCAMLC =ocamlc$(OPTBIN) $(OCAMLCFLAGS) $(INCLUDES)
+OCAMLOPT = ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
+OCAMLDEP = ocamldep$(OPTBIN) $(INCLUDES)
+OCAMLMKTOP=ocamlmktop -g -custom
+
+
+
+LIB=$(TARGET).cma
+OPTLIB=$(LIB:.cma=.cmxa)
+
+OBJS = $(SRC:.ml=.cmo)
+OPTOBJS = $(SRC:.ml=.cmx)
+
+all: $(LIB)
+all.opt: $(OPTLIB)
+
+$(TARGET).top: $(LIB)
+       $(OCAMLMKTOP) -o $(TARGET).top $(SYSLIBS) $(LIBS) $(OBJS)
+
+$(LIB):  $(OBJS)
+       $(OCAMLC) -a -o $(LIB) $(OBJS)
+
+clean::
+       rm -f $(LIB) $(TARGET).top
+
+
+$(OPTLIB): $(OPTOBJS)
+       $(OCAMLOPT) -a -o $(OPTLIB) $(OPTOBJS)
+
+# clean rule for LIB.opt
+clean::
+       rm -f $(OPTLIB) $(LIB:.cma=.a)  
+
+
+.SUFFIXES:
+.SUFFIXES: .ml .mli .cmo .cmi .cmx
+
+.ml.cmo:
+       $(OCAMLC) -c $<
+
+.mli.cmi:
+       $(OCAMLC) -c $<
+
+.ml.cmx:
+       $(OCAMLOPT) -c $<
+
+
+
+
+# clean rule for others files
+clean::
+       rm -f *.cm[iox] *.o *.annot
+       rm -f *~ .*~ #*# 
+
+depend: 
+       $(OCAMLDEP) *.mli *.ml > .depend
+
+#clean::
+#      rm -f .depend
+
+.depend:
+       $(OCAMLDEP) $(INCLUDE_PATH) *.mli *.ml > .depend
+
+-include .depend
index 96ec617..36a6c27 100644 (file)
@@ -29,7 +29,7 @@ SYSLIBS=str.cma unix.cma
 LIBS=../commons/commons.cma ../globals/globals.cma
 
 INCLUDES = -I ../commons -I ../globals \
-              -I ../ctl -I ../parsing_c -I ../parsing_cocci -I ../engine
+              -I ../ctl -I ../parsing_cocci -I ../parsing_c  -I ../engine
 
 #The Caml compilers.
 #for warning:  -w A 
index 5d5ff99..1db1ae1 100644 (file)
@@ -523,6 +523,8 @@ external pytuple4 : (pyobject * pyobject * pyobject * pyobject) ->
   pyobject = "pytuple_fromarray"
 external pytuple5 : (pyobject * pyobject * pyobject * pyobject * pyobject) ->
   pyobject = "pytuple_fromarray"
+external pytuple6 : (pyobject * pyobject * pyobject * pyobject * pyobject * pyobject) ->
+  pyobject = "pytuple_fromarray"
 
 let pyint_fromint i = pyint_fromlong (Int64.of_int i)
 let pyint_asint obj = Int64.to_int (pyint_aslong obj)
diff --git a/python/.#yes_pycocci.ml.1.1 b/python/.#yes_pycocci.ml.1.1
new file mode 100644 (file)
index 0000000..c252439
--- /dev/null
@@ -0,0 +1,241 @@
+(*
+* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
+* This file is part of Coccinelle.
+* 
+* Coccinelle is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, according to version 2 of the License.
+* 
+* Coccinelle is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
+* 
+* The authors reserve the right to distribute this or future versions of
+* Coccinelle under other licenses.
+*)
+
+
+open Ast_c
+open Common
+open Pycaml
+open Pycocci_aux
+module StringMap = Map.Make (String)
+
+exception Pycocciexception
+
+let check_return_value v =
+  if v = (pynull ()) then 
+         (pyerr_print ();
+         raise Pycocciexception)
+  else ()
+let check_int_return_value v =
+  if v = -1 then
+         (pyerr_print ();
+         raise Pycocciexception)
+  else ()
+
+let initialised = ref false
+
+let coccinelle_module = ref (pynone ())
+let cocci_file_name = ref ""
+
+(* dealing with python modules loaded *)
+let module_map = ref (StringMap.add "__main__" (pynone ()) StringMap.empty)
+
+let get_module module_name =
+  StringMap.find module_name (!module_map)
+
+let is_module_loaded module_name =
+  try
+    let _ = get_module module_name in
+    true
+  with Not_found -> false
+
+let load_module module_name =
+  if not (is_module_loaded module_name) then
+    let m = pyimport_importmodule module_name in
+    check_return_value m;
+    (module_map := (StringMap.add module_name m (!module_map));
+    m)
+  else get_module module_name
+(* end python module handling part *)
+
+(* initialisation routines *)
+let pycocci_init () =
+  (* initialize *)
+  if not !initialised then (
+  initialised := true;
+  Unix.putenv "PYTHONPATH"
+      (Printf.sprintf "%s/coccinelle" (Unix.getenv "HOME"));
+  let _ = if not (py_isinitialized () != 0) then 
+       (if !Flag.show_misc then Common.pr2 "Initializing python\n%!"; 
+       py_initialize()) in
+
+  (* set argv *)
+  let argv0 = Printf.sprintf "%s%sspatch" (Sys.getcwd ()) (match Sys.os_type with "Win32" -> "\\" | _ -> "/") in
+  let _ = pycaml_setargs argv0 in
+
+  coccinelle_module := (pymodule_new "coccinelle");
+  module_map := StringMap.add "coccinelle" !coccinelle_module !module_map;
+  let _ = load_module "coccilib.elems" in
+  let _ = load_module "coccilib.output" in
+  ()) else
+
+  ()
+
+(*let _ = pycocci_init ()*)
+(* end initialisation routines *)
+
+(* python interaction *)
+let split_fqn fqn =
+  let last_period = String.rindex fqn '.' in
+  let module_name = String.sub fqn 0 last_period in
+  let class_name = String.sub fqn (last_period + 1) (String.length fqn - last_period - 1) in
+  (module_name, class_name)
+
+let pycocci_get_class_type fqn =
+  let (module_name, class_name) = split_fqn fqn in
+  let m = get_module module_name in
+  let attr = pyobject_getattrstring(m, class_name) in
+  check_return_value attr;
+  attr
+
+let pycocci_instantiate_class fqn args =
+  let class_type = pycocci_get_class_type fqn in
+  let obj = pyobject_callobject(class_type, args) in
+  check_return_value obj;
+  obj
+
+(* end python interaction *)
+
+let inc_match = ref true
+
+let include_match v =
+  let truth = pyobject_istrue (pytuple_getitem (v, 1)) in
+  check_int_return_value truth;
+  inc_match := truth != 0;
+  pynone ()
+
+let build_method (mname, camlfunc, args) pymodule classx classdict =
+  let cmx = pymethod_new(pywrap_closure camlfunc, args, classx) in
+  let v = pydict_setitemstring(classdict, mname, cmx) in
+  check_int_return_value v;
+  ()
+
+let build_class cname parent methods pymodule =
+  let cd = pydict_new() in
+  check_return_value cd;
+  let cx = pyclass_new(pytuple_fromsingle (pycocci_get_class_type parent), cd, pystring_fromstring cname) in
+  check_return_value cx;
+  List.iter (function meth -> build_method meth pymodule cx cd) methods;
+  let v = pydict_setitemstring(pymodule_getdict pymodule, cname, cx) in
+  check_int_return_value v;
+  (cd, cx)
+
+let has_environment_binding env name =
+  let a = pytuple_toarray name in
+  let (rule, name) = (Array.get a 1, Array.get a 2) in
+  let orule = pystring_asstring rule in
+  let oname = pystring_asstring name in
+  let e = List.exists (function (x,y) -> orule = x && oname = y) env in
+  if e then pytrue () else pyfalse ()
+
+let pyoutputinstance = ref (pynone ())
+let pyoutputdict = ref (pynone ())
+
+let get_cocci_file args =
+       pystring_fromstring (!cocci_file_name)
+
+let build_classes env =
+       let _ = pycocci_init () in
+       let module_dictionary = pyimport_getmoduledict() in
+        coccinelle_module := pymodule_new "coccinelle";
+       let mx = !coccinelle_module in
+       inc_match := true;
+        let (cd, cx) = build_class "Cocci" (!Flag.pyoutput) 
+               [("include_match", include_match, (pynull()));
+                ("has_env_binding", has_environment_binding env, (pynull()))] mx in
+       pyoutputinstance := cx;
+       pyoutputdict := cd;
+       let v1 = pydict_setitemstring(module_dictionary, "coccinelle", mx) in
+       check_int_return_value v1;
+        let mypystring = pystring_fromstring !cocci_file_name in
+        let v2 = pydict_setitemstring(cd, "cocci_file", mypystring) in
+       check_int_return_value v2;
+        ()
+
+let build_variable name value =
+  let mx = !coccinelle_module in
+  check_int_return_value (pydict_setitemstring(pymodule_getdict mx, name, value))
+
+let contains_binding e (_,(r,m)) =
+  try
+    let _ = List.find (function ((re, rm), _) -> r = re && m = rm) e in true
+  with Not_found -> false
+
+let construct_variables mv e =
+  let find_binding (r,m) =
+    try
+      let elem = List.find (function ((re,rm),_) -> r = re && m = rm) e in
+      Some elem
+    with Not_found -> None
+  in
+
+  let instantiate_Expression(x) =
+    let str = pystring_fromstring (Pycocci_aux.exprrep x) in
+    pycocci_instantiate_class "coccilib.elems.Expression" (pytuple_fromsingle (str))
+  in
+
+  let instantiate_Identifier(x) =
+    let str = pystring_fromstring x in
+    pycocci_instantiate_class "coccilib.elems.Identifier" (pytuple_fromsingle (str))
+  in
+
+  List.iter (function (py,(r,m)) ->
+    match find_binding (r,m) with
+      None -> ()
+    | Some (_, Ast_c.MetaExprVal ((expr, _), info_list)) ->
+       let expr_repr = instantiate_Expression(expr) in
+       let _ = build_variable py expr_repr in
+       ()
+    | Some (_, Ast_c.MetaIdVal id) ->
+       let id_repr = instantiate_Identifier(id) in
+       let _ = build_variable py id_repr in
+       ()
+    | Some (_, Ast_c.MetaPosValList l) ->
+       let locs = List.map (function (fname,(line,col),(line_end,col_end)) ->
+               pycocci_instantiate_class "coccilib.elems.Location" (pytuple5
+               (pystring_fromstring fname,
+               pystring_fromstring (Printf.sprintf "%d" line),
+               pystring_fromstring (Printf.sprintf "%d" col),
+               pystring_fromstring (Printf.sprintf "%d" line_end),
+               pystring_fromstring (Printf.sprintf "%d" col_end)))) l in
+       let pylocs = pytuple_fromarray (Array.of_list locs) in
+       let _ = build_variable py pylocs in
+       ()
+    | Some (_,binding) ->
+       let _ = build_variable py (pystring_fromstring (Pycocci_aux.stringrep binding))
+       in ()
+    ) mv;
+
+  ()
+
+let set_coccifile cocci_file =
+       cocci_file_name := cocci_file;
+       ()
+
+
+let pyrun_simplestring s = 
+  Pycaml.pyrun_simplestring s
+
+let py_isinitialized () = 
+  Pycaml.py_isinitialized ()
+
+
+let py_finalize () =
+  Pycaml.py_finalize ()
index 325c8b0..0e794c9 100644 (file)
@@ -1,6 +1,7 @@
 class Location:
-       def __init__(self, file, line, column, line_end, column_end):
+       def __init__(self, file, current_element, line, column, line_end, column_end):
                self.file = file
+               self.current_element = current_element
                self.line = line
                self.column = column
                self.line_end = line_end
index c252439..a0a6a22 100644 (file)
@@ -208,9 +208,11 @@ let construct_variables mv e =
        let _ = build_variable py id_repr in
        ()
     | Some (_, Ast_c.MetaPosValList l) ->
-       let locs = List.map (function (fname,(line,col),(line_end,col_end)) ->
-               pycocci_instantiate_class "coccilib.elems.Location" (pytuple5
-               (pystring_fromstring fname,
+       let locs =
+        List.map
+          (function (fname,current_element,(line,col),(line_end,col_end)) ->
+               pycocci_instantiate_class "coccilib.elems.Location" (pytuple6
+               (pystring_fromstring fname,pystring_fromstring current_element,
                pystring_fromstring (Printf.sprintf "%d" line),
                pystring_fromstring (Printf.sprintf "%d" col),
                pystring_fromstring (Printf.sprintf "%d" line_end),
index a2e4503..d029e9b 100644 (file)
@@ -631,6 +631,14 @@ T E;
 
 sizeof(T) => sizeof(E)
 
+// Expression
+// @ fld_func_call @
+// expression list ES;
+// identifier fld;
+// expression E;
+// @@
+//  E.fld(ES) <=> (*E.fld)(ES)
+
 
 // ****************************************************************************
 // Linux specific isomorphisms 
index 57518d9..a2a3d29 100644 (file)
@@ -400,22 +400,6 @@ let test_parse_cocci file =
 let sp_of_file file iso    = Parse_cocci.process file iso false
 
 (* TODO: Remove
-let (rule_elem_of_string: string -> filename option -> Ast_cocci.rule_elem) =
- fun s iso -> 
-  begin
-    Common.write_file ("/tmp/__cocci.cocci") (s);
-    let (astcocci, _,_,_,_,_) = sp_of_file ("/tmp/__cocci.cocci") iso in
-    let stmt =
-      astcocci +>
-      List.hd +> (function (_,_,x) -> List.hd x) +> (function x ->
-       match Ast_cocci.unwrap x with
-       | Ast_cocci.CODE stmt_dots -> Ast_cocci.undots stmt_dots +> List.hd
-       | _ -> raise Not_found)
-    in
-    match Ast_cocci.unwrap stmt with
-    | Ast_cocci.Atomic(re) -> re
-    | _ -> failwith "only atomic patterns allowed"
-  end
 *)
 
 (*
diff --git a/tests/error.c b/tests/error.c
new file mode 100644 (file)
index 0000000..1e46dbb
--- /dev/null
@@ -0,0 +1,11 @@
+// for seeing when errorexit nodes are created
+
+int main () {
+  int bad = -1;
+  if (x < 100) return -ENOMEM;
+  if (x < 100) return bad;
+  if (x < 100) goto out;
+  return 0;
+out:
+  return bad;
+}
diff --git a/tests/sys.cocci b/tests/sys.cocci
new file mode 100644 (file)
index 0000000..c01ef25
--- /dev/null
@@ -0,0 +1,14 @@
+@r@
+struct sys_timer E;
+expression E2;
+@@
+
+* E.suspend = E2;
+
+@s@
+struct sys_timer E;
+expression E2;
+@@
+
+E.suspend = E2;
+
diff --git a/tests/sys.iso b/tests/sys.iso
new file mode 100644 (file)
index 0000000..7b33eb4
--- /dev/null
@@ -0,0 +1,10 @@
+TopLevel
+@ mkinit @
+type T;
+pure context T E;
+identifier I;
+identifier fld;
+expression E1;
+@@
+
+E.fld = E1; => T I = { .fld = E1, };
diff --git a/tests/testprint.c b/tests/testprint.c
new file mode 100644 (file)
index 0000000..bb15614
--- /dev/null
@@ -0,0 +1,16 @@
+void main(int foo) {
+
+  f(1);
+  x();
+  g(2);
+  x();
+  if(1) {
+    //    h(3);
+    h(3);
+  } else {
+    h(4);
+  }
+
+  
+}
+
diff --git a/tests/testprint.cocci b/tests/testprint.cocci
new file mode 100644 (file)
index 0000000..ed1846f
--- /dev/null
@@ -0,0 +1,9 @@
+@ rule1 @
+expression X,Y,Z;
+@@
+   f(X);
+   ... when any, strict
+   g(Z);
+   ... when any, strict
+-  h(Y);
++  h(X,Y,Z); 
diff --git a/tests/warnon.cocci b/tests/warnon.cocci
new file mode 100644 (file)
index 0000000..c0fca69
--- /dev/null
@@ -0,0 +1,6 @@
+@@
+//identifier f;
+expression E;
+@@
+
+* WARN_ON(E && !irqs_disabled())
index 227e415..615238d 100644 (file)
@@ -1,4 +1,4 @@
-PROGS=gitgrep split_patch extract_c_and_res meta_files generate_dependencies
+PROGS=gitgrep split_patch extract_c_and_res #generate_dependencies
 
 all: $(PROGS)
 
@@ -29,7 +29,7 @@ SYSLIBS = str.cma unix.cma
 
 INCLUDE=-I ../commons -I ../extra -I  ../parsing_c
 LIBS=../commons/commons.cma ../globals/globals.cma \
-     ../parsing_c/c_parser.cma ../extra/extra.cma 
+     ../parsing_c/parsing_c.cma ../extra/extra.cma 
 
 OCAMLC=ocamlc$(OPTBIN) -g -dtypes   $(INCLUDE) 
 OCAMLOPT=ocamlopt$(OPTBIN)   $(INCLUDE) $(OPTFLAGS)
@@ -45,9 +45,6 @@ split_patch: split_patch.cmo
 extract_c_and_res: extract_c_and_res.cmo
        $(OCAMLC) -o $@ $(SYSLIBS) $(INCLUDE) $(LIBS)  $+
 
-meta_files: meta_files.cmo
-       $(OCAMLC) -o $@ $(SYSLIBS) $(INCLUDE) $(LIBS)  $+
-
 generate_dependencies: generate_dependencies.cmo
        $(OCAMLC) -o $@ $(SYSLIBS) $(INCLUDE) $(LIBS)  $+
 
index aea394c..7124cd4 100755 (executable)
@@ -6,6 +6,6 @@ setenv COCCINELLE_HOME ${HOME}/coccinelle
 
 #  -allow_inconsistent_paths
 
-(~/coccinelle/spatch.opt -quiet -timeout 120 \
+(spatch.opt -quiet -timeout 120 \
 -dir /home/julia/linux-2.6 -use_glimpse -cocci_file $* > ${1:r}.${3}.out) \
 >& tmp.${1:r}.${3}.out
index 41f7712..1eb3804 100644 (file)
@@ -1,4 +1,4 @@
-open Common open Commonop
+open Common
 
 (*****************************************************************************)
 (*  *)
index 7dd22de..4cf056c 100644 (file)
@@ -1,4 +1,4 @@
-open Common open Commonop
+open Common
 
 (*****************************************************************************)
 (* Flags *)
index f77e026..059ba55 100644 (file)
@@ -1,4 +1,4 @@
-open Common open Commonop
+open Common
 
 module CP = Classic_patch