Release coccinelle-0.1.6
authorCoccinelle <cocci@diku.dk>
Sun, 3 Oct 2010 11:57:41 +0000 (13:57 +0200)
committerRene Rydhof Hansen <rrh@cs.aau.dk>
Sun, 3 Oct 2010 11:57:41 +0000 (13:57 +0200)
** Language:
   - the ability to add comments

** Features:
   - grouping of generated rules with -hrule option
   - handling of special coccinelle comments
     /* {{coccinelle:skip_start}} */ and
     /* {{coccinelle:skip_end}} */
     allowing to give more hints to the C parser.
     Thanks to Flavien@lebarbe.net for the idea.
   - the ability to print the values of more (but not all) kinds of
     metavariables from python
   - new vim SmPL mode.
     Thanks to Alexander Faroy.

** Bugfix:
   - consider the ident tokens also in the 2 lines before the error line for the
     10-most-problematic-parsing-errors diagnostic.
   - SmPL parser allows cast as the argument of a pointer
   - SmPL type checker allows enum as an array index
   - Better generation of fresh metavariables names in hrule
   - no more warnings about things that should be metavariables when there is
     a disjunction in a function position
   - bugfix in parser, better error message.
     Thanks to Ali-Erdem OZCAN <ali-erdem.ozcan@st.com> for the bug report.

191 files changed:
.#Makefile.1.122 [new file with mode: 0644]
.#Makefile.1.123 [new file with mode: 0644]
.#Makefile.1.125 [new file with mode: 0644]
.#Makefile.1.127 [new file with mode: 0644]
.#cocci.ml.1.295 [new file with mode: 0644]
.#main.ml.1.248 [new file with mode: 0644]
.#testing.ml.1.67 [new file with mode: 0644]
.depend
Makefile
Makefile.config
changes.txt
cocci.ml
commitmsg
commons/.depend
commons/Makefile
commons/common.ml
commons/common.mli
commons/ocollection/oassoc_buffer.ml
commons/ocollection/oassoc_cache.ml [new file with mode: 0644]
commons/ocollection/oassoc_cache.mli [new file with mode: 0644]
commons/ocollection/oassocbdb.ml
commons/ocollection/oassocbdb_string.ml
commons/ocollection/oassocdbm.ml
configure
credits.txt
ctl/.#Makefile.1.21 [new file with mode: 0644]
ctl/.#Makefile.1.22 [new file with mode: 0644]
ctl/.depend
ctl/Makefile
demos/ifdef_skip_tag.c [new file with mode: 0644]
demos/macro_fix_standard.h [new file with mode: 0644]
demos/macro_parsing_problem.c [new file with mode: 0644]
demos/platform_ifdef.c [new file with mode: 0644]
demos/platform_ifdef.cocci [new file with mode: 0644]
docs/grammar/Makefile
docs/grammar/cocci_syntax.tex
docs/grammar/examples.tex
docs/grammar/tips.tex [new file with mode: 0644]
docs/spatch.1
editors/emacs/cocci-ediff.el [moved from emacs/cocci-ediff.el with 100% similarity]
editors/emacs/cocci.el [moved from emacs/cocci.el with 100% similarity]
editors/vim/README [new file with mode: 0644]
editors/vim/ftdetect/cocci.vim [new file with mode: 0644]
editors/vim/syntax/cocci.vim [new file with mode: 0644]
engine/.#Makefile.1.52 [new file with mode: 0644]
engine/.#Makefile.1.53 [new file with mode: 0644]
engine/.#Makefile.1.54 [new file with mode: 0644]
engine/.#asttoctl.ml.1.81 [new file with mode: 0644]
engine/.#asttoctl2.ml.1.152 [new file with mode: 0644]
engine/.#cocci_vs_c.ml.1.28 [new file with mode: 0644]
engine/.#cocci_vs_c.ml.1.29 [new file with mode: 0644]
engine/.#lib_matcher_c.ml.1.1 [copied from engine/lib_matcher_c.ml with 100% similarity]
engine/.#transformation_c.ml.1.3 [new file with mode: 0644]
engine/.depend
engine/Makefile
engine/asttoctl.ml
engine/asttoctl2.ml
engine/cocci_vs_c.ml
engine/lib_matcher_c.ml
engine/lib_matcher_c.mli
engine/transformation_c.ml
env.sh
extra/.depend
extra/Makefile
globals/Makefile
globals/config.ml
globals/flag.ml
main.ml
menhirlib/Makefile
parsing_c/.depend
parsing_c/Makefile
parsing_c/ast_c.ml
parsing_c/ast_to_flow.ml
parsing_c/comment_annotater_c.ml [new file with mode: 0644]
parsing_c/comment_annotater_c.mli [new file with mode: 0644]
parsing_c/compare_c.ml
parsing_c/control_flow_c.ml
parsing_c/cpp_ast_c.ml
parsing_c/flag_parsing_c.ml
parsing_c/lexer_c.mll
parsing_c/lexer_parser.ml
parsing_c/lib_parsing_c.ml
parsing_c/parse_c.ml
parsing_c/parser_c.mly
parsing_c/parsing_hacks.ml
parsing_c/parsing_stat.ml
parsing_c/pretty_print_c.ml
parsing_c/test_parsing_c.ml
parsing_c/test_parsing_c.mli
parsing_c/token_c.ml [new file with mode: 0644]
parsing_c/token_helpers.ml
parsing_c/token_helpers.mli
parsing_c/type_annoter_c.ml
parsing_c/type_annoter_c.mli
parsing_c/type_c.ml
parsing_c/type_c.mli
parsing_c/unparse_c.ml
parsing_c/unparse_cocci.ml
parsing_c/unparse_hrule.ml
parsing_c/visitor_c.ml
parsing_c/visitor_c.mli
parsing_cocci/.#Makefile.1.50 [new file with mode: 0644]
parsing_cocci/.#Makefile.1.51 [new file with mode: 0644]
parsing_cocci/.#arity.ml.1.88 [new file with mode: 0644]
parsing_cocci/.#ast0_cocci.ml.1.115 [new file with mode: 0644]
parsing_cocci/.#ast0toast.ml.1.140 [new file with mode: 0644]
parsing_cocci/.#ast_cocci.ml.1.151 [new file with mode: 0644]
parsing_cocci/.#check_meta.ml.1.88 [new file with mode: 0644]
parsing_cocci/.#compute_lines.ml.1.92 [new file with mode: 0644]
parsing_cocci/.#context_neg.ml.1.104 [new file with mode: 0644]
parsing_cocci/.#data.ml.1.38 [new file with mode: 0644]
parsing_cocci/.#index.ml.1.60 [new file with mode: 0644]
parsing_cocci/.#insert_plus.ml.1.74 [new file with mode: 0644]
parsing_cocci/.#iso_pattern.ml.1.152 [new file with mode: 0644]
parsing_cocci/.#lexer_cocci.mll.1.86 [new file with mode: 0644]
parsing_cocci/.#parse_aux.ml.1.27 [new file with mode: 0644]
parsing_cocci/.#parse_cocci.ml.1.180 [new file with mode: 0644]
parsing_cocci/.#parser_cocci_menhir.mly.1.168 [new file with mode: 0644]
parsing_cocci/.#parser_cocci_menhir.mly.1.169 [new file with mode: 0644]
parsing_cocci/.#pretty_print_cocci.ml.1.135 [new file with mode: 0644]
parsing_cocci/.#type_infer.ml.1.60 [new file with mode: 0644]
parsing_cocci/.#unparse_ast0.ml.1.118 [new file with mode: 0644]
parsing_cocci/.#visitor_ast.ml.1.97 [new file with mode: 0644]
parsing_cocci/.depend
parsing_cocci/Makefile
parsing_cocci/adjust_pragmas.ml [new file with mode: 0644]
parsing_cocci/adjust_pragmas.mli [new file with mode: 0644]
parsing_cocci/arity.ml
parsing_cocci/ast0_cocci.ml
parsing_cocci/ast0_cocci.mli
parsing_cocci/ast0toast.ml
parsing_cocci/ast_cocci.ml
parsing_cocci/ast_cocci.mli
parsing_cocci/check_meta.ml
parsing_cocci/compute_lines.ml
parsing_cocci/context_neg.ml
parsing_cocci/data.ml
parsing_cocci/data.mli
parsing_cocci/index.ml
parsing_cocci/insert_plus.ml
parsing_cocci/iso_pattern.ml
parsing_cocci/lexer_cocci.mll
parsing_cocci/parse_aux.ml
parsing_cocci/parse_cocci.ml
parsing_cocci/parser_cocci_menhir.ml
parsing_cocci/parser_cocci_menhir.mli
parsing_cocci/parser_cocci_menhir.mly
parsing_cocci/pretty_print_cocci.ml
parsing_cocci/type_infer.ml
parsing_cocci/unparse_ast0.ml
parsing_cocci/visitor_ast.ml
popl/.#Makefile.1.5 [new file with mode: 0644]
popl/Makefile
popl09/.#Makefile.1.5 [new file with mode: 0644]
popl09/.#Makefile.1.6 [new file with mode: 0644]
popl09/.depend
popl09/Makefile
pycaml/pycaml.ml
pycaml/pycaml_ml.c
python/.#Makefile.1.5 [new file with mode: 0644]
python/.#no_pycocci_aux.ml.1.2 [new file with mode: 0644]
python/.#yes_pycocci.ml.1.2 [new file with mode: 0644]
python/.#yes_pycocci_aux.ml.1.2 [new file with mode: 0644]
python/.#yes_pycocci_aux.ml.1.3 [new file with mode: 0644]
python/.depend
python/Makefile
python/coccilib/output.py [changed from file to symlink]
python/coccilib/output_base.py [copied from python/coccilib/output.py with 96% similarity]
python/coccilib/output_trac.py [new file with mode: 0644]
python/no_pycocci_aux.ml
python/yes_pycocci.ml
python/yes_pycocci_aux.ml
scripts/spatch.sh [new file with mode: 0644]
testing.ml
tests/addif.c [new file with mode: 0644]
tests/addif.cocci [new file with mode: 0644]
tests/addif.res [new file with mode: 0644]
tests/addif1.c [new file with mode: 0644]
tests/addif1.cocci [new file with mode: 0644]
tests/addif1.res [new file with mode: 0644]
tests/addif2.c [new file with mode: 0644]
tests/addif2.cocci [new file with mode: 0644]
tests/addif2.res [new file with mode: 0644]
tests/ifdef6a.c [new file with mode: 0644]
tests/ifdef6a.cocci [new file with mode: 0644]
tests/ifdef6a.res [new file with mode: 0644]
tools/Makefile
tools/distributed/Makefile
tools/distributed/cleanup.ml
tools/distributed/cleanup_script [deleted file]
tools/distributed/spatch_linux.c

diff --git a/.#Makefile.1.122 b/.#Makefile.1.122
new file mode 100644 (file)
index 0000000..1168f58
--- /dev/null
@@ -0,0 +1,462 @@
+# Copyright 2005-2009, 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.
+
+
+#############################################################################
+# Configuration section
+#############################################################################
+
+-include Makefile.config
+
+VERSION=$(shell cat globals/config.ml |grep version |perl -p -e 's/.*"(.*)".*/$$1/;')
+
+##############################################################################
+# Variables
+##############################################################################
+TARGET=spatch
+
+SRC=flag_cocci.ml cocci.ml testing.ml test.ml main.ml
+
+
+ifeq ($(FEATURE_PYTHON),1)
+PYCMA=pycaml/pycaml.cma
+PYDIR=pycaml
+PYLIB=dllpycaml_stubs.so
+# the following is essential for Coccinelle to compile under gentoo (wierd)
+OPTLIBFLAGS=-cclib dllpycaml_stubs.so
+else
+PYCMA=
+PYDIR=
+PYLIB=
+OPTLIBFLAGS=
+endif
+
+
+SYSLIBS=str.cma unix.cma
+LIBS=commons/commons.cma globals/globals.cma\
+     ctl/ctl.cma \
+     parsing_cocci/cocci_parser.cma parsing_c/parsing_c.cma \
+     engine/cocciengine.cma popl09/popl.cma \
+     extra/extra.cma $(PYCMA) python/coccipython.cma
+
+MAKESUBDIRS=commons globals menhirlib $(PYDIR) ctl parsing_cocci parsing_c \
+ engine popl09 extra python
+INCLUDEDIRS=commons commons/ocamlextra globals menhirlib $(PYDIR) ctl \
+ parsing_cocci parsing_c engine popl09 extra python
+
+##############################################################################
+# Generic variables
+##############################################################################
+
+INCLUDES=$(INCLUDEDIRS:%=-I %)
+
+OBJS=    $(SRC:.ml=.cmo)
+OPTOBJS= $(SRC:.ml=.cmx)
+
+EXEC=$(TARGET)
+
+##############################################################################
+# Generic ocaml variables
+##############################################################################
+
+OCAMLCFLAGS= #-g -dtypes # -w A
+
+# for profiling add  -p -inline 0
+# but 'make forprofiling' below does that for you.
+# This flag is also used in subdirectories so don't change its name here.
+OPTFLAGS=
+# the following is essential for Coccinelle to compile under gentoo
+# but is now defined above in this file
+#OPTLIBFLAGS=-cclib dllpycaml_stubs.so
+
+# the OPTBIN variable is here to allow to use ocamlc.opt instead of
+# ocaml, when it is available, which speeds up compilation. So
+# if you want the fast version of the ocaml chain tools, set this var
+# or setenv it to ".opt" in your startup script.
+OPTBIN= #.opt
+
+OCAMLC=ocamlc$(OPTBIN) $(OCAMLCFLAGS)  $(INCLUDES)
+OCAMLOPT=ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
+OCAMLLEX=ocamllex #-ml # -ml for debugging lexer, but slightly slower
+OCAMLYACC=ocamlyacc -v
+OCAMLDEP=ocamldep #$(INCLUDES)
+OCAMLMKTOP=ocamlmktop -g -custom $(INCLUDES)
+
+# can also be set via 'make static'
+STATIC= #-ccopt -static
+
+# can also be unset via 'make purebytecode'
+BYTECODE_STATIC=-custom
+
+##############################################################################
+# Top rules
+##############################################################################
+.PHONY: all all.opt opt top clean configure
+.PHONY: $(MAKESUBDIRS) $(MAKESUBDIRS:%=%.opt)
+
+all:
+       $(MAKE) subdirs
+       $(MAKE) $(EXEC)
+
+opt:
+       $(MAKE) subdirs.opt
+       $(MAKE) $(EXEC).opt
+
+all.opt: opt
+top: $(EXEC).top
+
+subdirs: $(MAKESUBDIRS)
+subdirs.opt: $(MAKESUBDIRS:%=%.opt)
+
+$(MAKESUBDIRS):
+       $(MAKE) -C $@ OCAMLCFLAGS="$(OCAMLCFLAGS)" all
+
+$(MAKESUBDIRS:%=%.opt):
+       $(MAKE) -C $(@:%.opt=%) OCAMLCFLAGS="$(OCAMLCFLAGS)" all.opt
+
+commons:
+globals:
+menhirlib:
+parsing_cocci:globals menhirlib
+parsing_c:parsing_cocci
+ctl:globals commons
+engine: parsing_cocci parsing_c ctl
+popl09:engine
+extra: parsing_cocci parsing_c ctl
+pycaml:
+python:pycaml parsing_cocci parsing_c
+
+commons.opt:
+globals.opt:
+menhirlib.opt:
+parsing_cocci.opt:globals.opt menhirlib.opt
+parsing_c.opt:parsing_cocci.opt
+ctl.opt:globals.opt commons.opt
+engine.opt: parsing_cocci.opt parsing_c.opt ctl.opt
+popl09.opt:engine.opt
+extra.opt: parsing_cocci.opt parsing_c.opt ctl.opt
+pycaml.opt:
+python.opt:pycaml.opt parsing_cocci.opt parsing_c.opt
+
+clean::
+       set -e; for i in $(MAKESUBDIRS); do $(MAKE) -C $$i clean; done
+
+configure:
+       ./configure
+
+$(LIBS): #$(MAKESUBDIRS)
+$(LIBS:.cma=.cmxa): #$(MAKESUBDIRS:%=%.opt)
+
+$(OBJS):$(LIBS)
+$(OPTOBJS):$(LIBS:.cma=.cmxa)
+
+$(EXEC): $(LIBS) $(OBJS)
+       $(OCAMLC) $(BYTECODE_STATIC) -o $@ $(SYSLIBS)  $^
+
+$(EXEC).opt: $(LIBS:.cma=.cmxa) $(OPTOBJS)
+       $(OCAMLOPT) $(STATIC) -o $@ $(SYSLIBS:.cma=.cmxa) $(OPTLIBFLAGS)  $^
+
+$(EXEC).top: $(LIBS) $(OBJS)
+       $(OCAMLMKTOP) -custom -o $@ $(SYSLIBS) $^
+
+clean::
+       rm -f $(TARGET) $(TARGET).opt $(TARGET).top
+
+clean::
+       rm -f dllpycaml_stubs.so
+
+
+.PHONY: tools all configure
+
+tools:
+       $(MAKE) -C tools
+clean::
+       $(MAKE) -C tools clean
+
+
+static:
+       rm -f spatch.opt spatch
+       $(MAKE) STATIC="-ccopt -static" spatch.opt
+       cp spatch.opt spatch
+
+purebytecode:
+       rm -f spatch.opt spatch
+       $(MAKE) BYTECODE_STATIC="" spatch
+
+
+##############################################################################
+# Install
+##############################################################################
+
+# don't remove DESTDIR, it can be set by package build system like ebuild
+install: all
+       mkdir -p $(DESTDIR)$(BINDIR)
+       mkdir -p $(DESTDIR)$(LIBDIR)
+       mkdir -p $(DESTDIR)$(SHAREDIR)
+       mkdir -p $(DESTDIR)$(MANDIR)/man1
+       cp spatch $(DESTDIR)$(BINDIR)
+       cp standard.h $(DESTDIR)$(SHAREDIR)
+       cp standard.iso $(DESTDIR)$(SHAREDIR)
+       cp docs/spatch.1 $(DESTDIR)$(MANDIR)/man1/
+       mkdir -p $(DESTDIR)$(SHAREDIR)/python
+       cp -a python/coccilib $(DESTDIR)$(SHAREDIR)/python
+       cp -f dllpycaml_stubs.so $(DESTDIR)$(LIBDIR)
+       @echo ""
+       @echo "You can also install spatch by copying the program spatch"
+       @echo "(available in this directory) anywhere you want and"
+       @echo "give it the right options to find its configuration files."
+
+uninstall:
+       rm -f $(DESTDIR)$(BINDIR)/spatch
+       rm -f $(DESTDIR)$(LIBDIR)/dllpycaml_stubs.so
+       rm -f $(DESTDIR)$(SHAREDIR)/standard.h
+       rm -f $(DESTDIR)$(SHAREDIR)/standard.iso
+       rm -rf $(DESTDIR)$(SHAREDIR)/python/coccilib
+       rm -f $(DESTDIR)$(MANDIR)/man1/spatch.1
+
+
+
+version:
+       @echo $(VERSION)
+
+
+##############################################################################
+# Package rules
+##############################################################################
+
+PACKAGE=coccinelle-$(VERSION)
+
+BINSRC=spatch env.sh env.csh standard.h standard.iso \
+       *.txt docs/* \
+       demos/foo.* demos/simple.*
+#      $(PYLIB) python/coccilib/ demos/printloc.*
+BINSRC2=$(BINSRC:%=$(PACKAGE)/%)
+
+TMP=/tmp
+OCAMLVERSION=$(shell ocaml -version |perl -p -e 's/.*version (.*)/$$1/;')
+
+# Procedure to do first time:
+#  cd ~/release
+#  cvs checkout coccinelle
+#  cd coccinelle
+#  cvs update -d -P
+#  touch **/*
+#  make licensify
+#  remember to comment the -g -dtypes in this Makefile
+
+# Procedure to do each time:
+#  cvs update
+#  make sure that ocaml is the distribution ocaml of /usr/bin, not ~pad/...
+#  modify globals/config.ml
+#  cd globals/; cvs commit -m"new version"  (do not commit from the root!)
+#  ./configure --without-python
+#  make package
+#  make website
+# Check that run an ocaml in /usr/bin
+
+# To test you can try compile and run spatch from different instances
+# like my ~/coccinelle, ~/release/coccinelle, and the /tmp/coccinelle-0.X
+# downloaded from the website.
+
+# For 'make srctar' it must done from a clean
+# repo such as ~/release/coccinelle. It must also be a repo where
+# the scripts/licensify has been run at least once.
+# For the 'make bintar' I can do it from my original repo.
+
+
+package:
+       make srctar
+       make bintar
+       make staticbintar
+       make bytecodetar
+
+# I currently pre-generate the parser so the user does not have to
+# install menhir on his machine. I also do a few cleanups like 'rm todo_pos'.
+# You may have first to do a 'make licensify'.
+srctar:
+       make clean
+       cp -a .  $(TMP)/$(PACKAGE)
+       cd $(TMP)/$(PACKAGE); cd parsing_cocci/; make parser_cocci_menhir.ml
+       cd $(TMP)/$(PACKAGE); rm todo_pos
+       cd $(TMP); tar cvfz $(PACKAGE).tgz --exclude-vcs $(PACKAGE)
+       rm -rf  $(TMP)/$(PACKAGE)
+
+
+bintar: all
+       rm -f $(TMP)/$(PACKAGE)
+       ln -s `pwd` $(TMP)/$(PACKAGE)
+       cd $(TMP); tar cvfz $(PACKAGE)-bin-x86.tgz --exclude-vcs $(BINSRC2)
+       rm -f $(TMP)/$(PACKAGE)
+
+staticbintar: all.opt
+       rm -f $(TMP)/$(PACKAGE)
+       ln -s `pwd` $(TMP)/$(PACKAGE)
+       make static
+       cd $(TMP); tar cvfz $(PACKAGE)-bin-x86-static.tgz --exclude-vcs $(BINSRC2)
+       rm -f $(TMP)/$(PACKAGE)
+
+# add ocaml version in name ?
+bytecodetar: all
+       rm -f $(TMP)/$(PACKAGE)
+       ln -s `pwd` $(TMP)/$(PACKAGE)
+       make purebytecode
+       cd $(TMP); tar cvfz $(PACKAGE)-bin-bytecode-$(OCAMLVERSION).tgz --exclude-vcs $(BINSRC2)
+       rm -f $(TMP)/$(PACKAGE)
+
+clean::
+       rm -f $(PACKAGE)
+       rm -f $(PACKAGE)-bin-x86.tgz
+       rm -f $(PACKAGE)-bin-x86-static.tgz
+       rm -f $(PACKAGE)-bin-bytecode-$(OCAMLVERSION).tgz
+
+
+
+TOLICENSIFY=ctl engine parsing_cocci popl popl09 python
+licensify:
+       ocaml tools/licensify.ml
+       set -e; for i in $(TOLICENSIFY); do cd $$i; ocaml ../tools/licensify.ml; cd ..; done
+
+# When checking out the source from diku sometimes I have some "X in the future"
+# error messages.
+fixdates:
+       echo do 'touch **/*.*'
+
+#fixCVS:
+#      cvs update -d -P
+#      echo do 'rm -rf **/CVS'
+
+ocamlversion:
+       @echo $(OCAMLVERSION)
+
+
+##############################################################################
+# Pad specific rules
+##############################################################################
+
+#TOP=/home/pad/mobile/project-coccinelle
+WEBSITE=/home/pad/mobile/homepage/software/project-coccinelle
+
+website:
+       cp $(TMP)/$(PACKAGE).tgz                $(WEBSITE)
+       cp $(TMP)/$(PACKAGE)-bin-x86.tgz        $(WEBSITE)
+       cp $(TMP)/$(PACKAGE)-bin-x86-static.tgz $(WEBSITE)
+       cp $(TMP)/$(PACKAGE)-bin-bytecode-$(OCAMLVERSION).tgz   $(WEBSITE)
+
+
+#TXT=$(wildcard *.txt)
+syncwiki:
+#      unison ~/public_html/wiki/wiki-LFS/data/pages/ docs/wiki/
+#      set -e; for i in $(TXT); do unison $$i docs/wiki/$$i; done
+
+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
+##############################################################################
+
+test: $(TARGET)
+       ./$(TARGET) -testall
+
+testparsing:
+       ./$(TARGET) -D standard.h -parse_c -dir tests/
+
+
+
+# -inline 0  to see all the functions in the profile.
+# Can also use the profile framework in commons/ and run your program
+# with -profile.
+forprofiling:
+       $(MAKE) OPTFLAGS="-p -inline 0 " opt
+
+clean::
+       rm -f gmon.out
+
+tags:
+       otags -no-mli-tags -r  .
+
+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 -lr /tmp/dependfull.depend > /tmp/dependfull.dot
+       dot -Tps /tmp/dependfull.dot > /tmp/dependfull.ps
+       ps2pdf /tmp/dependfull.ps /tmp/dependfull.pdf
+
+##############################################################################
+# Misc rules
+##############################################################################
+
+# each member of the project can have its own test.ml. this file is
+# not under CVS.
+test.ml:
+       echo "let foo_ctl () = failwith \"there is no foo_ctl formula\"" \
+         > test.ml
+
+beforedepend:: test.ml
+
+
+#INC=$(dir $(shell which ocaml))
+#INCX=$(INC:/=)
+#INCY=$(dir $(INCX))
+#INCZ=$(INCY:/=)/lib/ocaml
+#
+#prim.o: prim.c
+#      gcc -c -o prim.o -I $(INCZ) prim.c
+
+
+##############################################################################
+# Generic ocaml 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[iox] *.o *.annot
+
+clean::
+       rm -f *~ .*~ *.exe #*#
+
+beforedepend::
+
+depend:: beforedepend
+       $(OCAMLDEP) *.mli *.ml > .depend
+       set -e; for i in $(MAKESUBDIRS); do $(MAKE) -C $$i depend; done
+
+-include .depend
diff --git a/.#Makefile.1.123 b/.#Makefile.1.123
new file mode 100644 (file)
index 0000000..dcef57f
--- /dev/null
@@ -0,0 +1,464 @@
+# Copyright 2005-2009, 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.
+
+
+#############################################################################
+# Configuration section
+#############################################################################
+
+-include Makefile.config
+
+VERSION=$(shell cat globals/config.ml |grep version |perl -p -e 's/.*"(.*)".*/$$1/;')
+
+##############################################################################
+# Variables
+##############################################################################
+TARGET=spatch
+
+SRC=flag_cocci.ml cocci.ml testing.ml test.ml main.ml
+
+
+ifeq ($(FEATURE_PYTHON),1)
+PYCMA=pycaml/pycaml.cma
+PYDIR=pycaml
+PYLIB=dllpycaml_stubs.so
+# the following is essential for Coccinelle to compile under gentoo (wierd)
+OPTLIBFLAGS=-cclib dllpycaml_stubs.so
+else
+PYCMA=
+PYDIR=
+PYLIB=
+OPTLIBFLAGS=
+endif
+
+
+SYSLIBS=str.cma unix.cma
+LIBS=commons/commons.cma globals/globals.cma\
+     ctl/ctl.cma \
+     parsing_cocci/cocci_parser.cma parsing_c/parsing_c.cma \
+     engine/cocciengine.cma popl09/popl.cma \
+     extra/extra.cma $(PYCMA) python/coccipython.cma
+
+MAKESUBDIRS=commons globals menhirlib $(PYDIR) ctl parsing_cocci parsing_c \
+ engine popl09 extra python
+INCLUDEDIRS=commons commons/ocamlextra globals menhirlib $(PYDIR) ctl \
+ parsing_cocci parsing_c engine popl09 extra python
+
+##############################################################################
+# Generic variables
+##############################################################################
+
+INCLUDES=$(INCLUDEDIRS:%=-I %)
+
+OBJS=    $(SRC:.ml=.cmo)
+OPTOBJS= $(SRC:.ml=.cmx)
+
+EXEC=$(TARGET)
+
+##############################################################################
+# Generic ocaml variables
+##############################################################################
+
+OCAMLCFLAGS= #-g -dtypes # -w A
+
+# for profiling add  -p -inline 0
+# but 'make forprofiling' below does that for you.
+# This flag is also used in subdirectories so don't change its name here.
+OPTFLAGS=
+# the following is essential for Coccinelle to compile under gentoo
+# but is now defined above in this file
+#OPTLIBFLAGS=-cclib dllpycaml_stubs.so
+
+# the OPTBIN variable is here to allow to use ocamlc.opt instead of
+# ocaml, when it is available, which speeds up compilation. So
+# if you want the fast version of the ocaml chain tools, set this var
+# or setenv it to ".opt" in your startup script.
+OPTBIN= #.opt
+
+OCAMLC=ocamlc$(OPTBIN) $(OCAMLCFLAGS)  $(INCLUDES)
+OCAMLOPT=ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
+OCAMLLEX=ocamllex #-ml # -ml for debugging lexer, but slightly slower
+OCAMLYACC=ocamlyacc -v
+OCAMLDEP=ocamldep #$(INCLUDES)
+OCAMLMKTOP=ocamlmktop -g -custom $(INCLUDES)
+
+# can also be set via 'make static'
+STATIC= #-ccopt -static
+
+# can also be unset via 'make purebytecode'
+BYTECODE_STATIC=-custom
+
+##############################################################################
+# Top rules
+##############################################################################
+.PHONY: all all.opt opt top clean configure
+.PHONY: $(MAKESUBDIRS) $(MAKESUBDIRS:%=%.opt)
+
+all:
+       $(MAKE) subdirs
+       $(MAKE) $(EXEC)
+
+opt:
+       $(MAKE) subdirs.opt
+       $(MAKE) $(EXEC).opt
+
+all.opt: opt
+top: $(EXEC).top
+
+subdirs: $(MAKESUBDIRS)
+subdirs.opt: $(MAKESUBDIRS:%=%.opt)
+
+$(MAKESUBDIRS):
+       $(MAKE) -C $@ OCAMLCFLAGS="$(OCAMLCFLAGS)" all
+
+$(MAKESUBDIRS:%=%.opt):
+       $(MAKE) -C $(@:%.opt=%) OCAMLCFLAGS="$(OCAMLCFLAGS)" all.opt
+
+commons:
+globals:
+menhirlib:
+parsing_cocci:globals menhirlib
+parsing_c:parsing_cocci
+ctl:globals commons
+engine: parsing_cocci parsing_c ctl
+popl09:engine
+extra: parsing_cocci parsing_c ctl
+pycaml:
+python:pycaml parsing_cocci parsing_c
+
+commons.opt:
+globals.opt:
+menhirlib.opt:
+parsing_cocci.opt:globals.opt menhirlib.opt
+parsing_c.opt:parsing_cocci.opt
+ctl.opt:globals.opt commons.opt
+engine.opt: parsing_cocci.opt parsing_c.opt ctl.opt
+popl09.opt:engine.opt
+extra.opt: parsing_cocci.opt parsing_c.opt ctl.opt
+pycaml.opt:
+python.opt:pycaml.opt parsing_cocci.opt parsing_c.opt
+
+clean::
+       set -e; for i in $(MAKESUBDIRS); do $(MAKE) -C $$i clean; done
+
+configure:
+       ./configure
+
+$(LIBS): #$(MAKESUBDIRS)
+$(LIBS:.cma=.cmxa): #$(MAKESUBDIRS:%=%.opt)
+
+$(OBJS):$(LIBS)
+$(OPTOBJS):$(LIBS:.cma=.cmxa)
+
+$(EXEC): $(LIBS) $(OBJS)
+       $(OCAMLC) $(BYTECODE_STATIC) -o $@ $(SYSLIBS)  $^
+
+$(EXEC).opt: $(LIBS:.cma=.cmxa) $(OPTOBJS)
+       $(OCAMLOPT) $(STATIC) -o $@ $(SYSLIBS:.cma=.cmxa) $(OPTLIBFLAGS)  $^
+
+$(EXEC).top: $(LIBS) $(OBJS)
+       $(OCAMLMKTOP) -custom -o $@ $(SYSLIBS) $^
+
+clean::
+       rm -f $(TARGET) $(TARGET).opt $(TARGET).top
+
+clean::
+       rm -f dllpycaml_stubs.so
+
+
+.PHONY: tools all configure
+
+tools:
+       $(MAKE) -C tools
+clean::
+       $(MAKE) -C tools clean
+
+
+static:
+       rm -f spatch.opt spatch
+       $(MAKE) STATIC="-ccopt -static" spatch.opt
+       cp spatch.opt spatch
+
+purebytecode:
+       rm -f spatch.opt spatch
+       $(MAKE) BYTECODE_STATIC="" spatch
+
+
+##############################################################################
+# Install
+##############################################################################
+
+# don't remove DESTDIR, it can be set by package build system like ebuild
+install: all
+       mkdir -p $(DESTDIR)$(BINDIR)
+       mkdir -p $(DESTDIR)$(LIBDIR)
+       mkdir -p $(DESTDIR)$(SHAREDIR)
+       mkdir -p $(DESTDIR)$(MANDIR)/man1
+       cp spatch $(DESTDIR)$(BINDIR)
+       cp standard.h $(DESTDIR)$(SHAREDIR)
+       cp standard.iso $(DESTDIR)$(SHAREDIR)
+       cp docs/spatch.1 $(DESTDIR)$(MANDIR)/man1/
+       mkdir -p $(DESTDIR)$(SHAREDIR)/python
+       cp -a python/coccilib $(DESTDIR)$(SHAREDIR)/python
+       cp -f dllpycaml_stubs.so $(DESTDIR)$(LIBDIR)
+       @echo ""
+       @echo "You can also install spatch by copying the program spatch"
+       @echo "(available in this directory) anywhere you want and"
+       @echo "give it the right options to find its configuration files."
+
+uninstall:
+       rm -f $(DESTDIR)$(BINDIR)/spatch
+       rm -f $(DESTDIR)$(LIBDIR)/dllpycaml_stubs.so
+       rm -f $(DESTDIR)$(SHAREDIR)/standard.h
+       rm -f $(DESTDIR)$(SHAREDIR)/standard.iso
+       rm -rf $(DESTDIR)$(SHAREDIR)/python/coccilib
+       rm -f $(DESTDIR)$(MANDIR)/man1/spatch.1
+
+
+
+version:
+       @echo $(VERSION)
+
+
+##############################################################################
+# Package rules
+##############################################################################
+
+PACKAGE=coccinelle-$(VERSION)
+
+BINSRC=spatch env.sh env.csh standard.h standard.iso \
+       *.txt docs/* \
+       demos/foo.* demos/simple.*
+#      $(PYLIB) python/coccilib/ demos/printloc.*
+BINSRC2=$(BINSRC:%=$(PACKAGE)/%)
+
+TMP=/tmp
+OCAMLVERSION=$(shell ocaml -version |perl -p -e 's/.*version (.*)/$$1/;')
+
+# Procedure to do first time:
+#  cd ~/release
+#  cvs checkout coccinelle
+#  cd coccinelle
+#  cvs update -d -P
+#  touch **/*
+#  make licensify
+#  remember to comment the -g -dtypes in this Makefile
+
+# Procedure to do each time:
+#  cvs update
+#  make sure that ocaml is the distribution ocaml of /usr/bin, not ~pad/...
+#  modify globals/config.ml
+#  cd globals/; cvs commit -m"new version"  (do not commit from the root!)
+#  ./configure --without-python
+#  make package
+#  make website
+# Check that run an ocaml in /usr/bin
+
+# To test you can try compile and run spatch from different instances
+# like my ~/coccinelle, ~/release/coccinelle, and the /tmp/coccinelle-0.X
+# downloaded from the website.
+
+# For 'make srctar' it must done from a clean
+# repo such as ~/release/coccinelle. It must also be a repo where
+# the scripts/licensify has been run at least once.
+# For the 'make bintar' I can do it from my original repo.
+
+
+package:
+       make srctar
+       make bintar
+       make staticbintar
+       make bytecodetar
+
+# I currently pre-generate the parser so the user does not have to
+# install menhir on his machine. I also do a few cleanups like 'rm todo_pos'.
+# You may have first to do a 'make licensify'.
+srctar:
+       make clean
+       cp -a .  $(TMP)/$(PACKAGE)
+       cd $(TMP)/$(PACKAGE); cd parsing_cocci/; make parser_cocci_menhir.ml
+       cd $(TMP)/$(PACKAGE); rm todo_pos
+       cd $(TMP); tar cvfz $(PACKAGE).tgz --exclude-vcs $(PACKAGE)
+       rm -rf  $(TMP)/$(PACKAGE)
+
+
+bintar: all
+       rm -f $(TMP)/$(PACKAGE)
+       ln -s `pwd` $(TMP)/$(PACKAGE)
+       cd $(TMP); tar cvfz $(PACKAGE)-bin-x86.tgz --exclude-vcs $(BINSRC2)
+       rm -f $(TMP)/$(PACKAGE)
+
+staticbintar: all.opt
+       rm -f $(TMP)/$(PACKAGE)
+       ln -s `pwd` $(TMP)/$(PACKAGE)
+       make static
+       cd $(TMP); tar cvfz $(PACKAGE)-bin-x86-static.tgz --exclude-vcs $(BINSRC2)
+       rm -f $(TMP)/$(PACKAGE)
+
+# add ocaml version in name ?
+bytecodetar: all
+       rm -f $(TMP)/$(PACKAGE)
+       ln -s `pwd` $(TMP)/$(PACKAGE)
+       make purebytecode
+       cd $(TMP); tar cvfz $(PACKAGE)-bin-bytecode-$(OCAMLVERSION).tgz --exclude-vcs $(BINSRC2)
+       rm -f $(TMP)/$(PACKAGE)
+
+clean::
+       rm -f $(PACKAGE)
+       rm -f $(PACKAGE)-bin-x86.tgz
+       rm -f $(PACKAGE)-bin-x86-static.tgz
+       rm -f $(PACKAGE)-bin-bytecode-$(OCAMLVERSION).tgz
+
+
+
+TOLICENSIFY=ctl engine parsing_cocci popl popl09 python
+licensify:
+       ocaml tools/licensify.ml
+       set -e; for i in $(TOLICENSIFY); do cd $$i; ocaml ../tools/licensify.ml; cd ..; done
+
+# When checking out the source from diku sometimes I have some "X in the future"
+# error messages.
+fixdates:
+       echo do 'touch **/*.*'
+
+#fixCVS:
+#      cvs update -d -P
+#      echo do 'rm -rf **/CVS'
+
+ocamlversion:
+       @echo $(OCAMLVERSION)
+
+
+##############################################################################
+# Pad specific rules
+##############################################################################
+
+#TOP=/home/pad/mobile/project-coccinelle
+WEBSITE=/home/pad/mobile/homepage/software/project-coccinelle
+
+website:
+       cp $(TMP)/$(PACKAGE).tgz                $(WEBSITE)
+       cp $(TMP)/$(PACKAGE)-bin-x86.tgz        $(WEBSITE)
+       cp $(TMP)/$(PACKAGE)-bin-x86-static.tgz $(WEBSITE)
+       cp $(TMP)/$(PACKAGE)-bin-bytecode-$(OCAMLVERSION).tgz   $(WEBSITE)
+       rm -f $(WEBSITE)/LATEST* $(WEBSITE)/coccinelle-latest.tgz
+       cd $(WEBSITE); touch LATEST_IS_$(VERSION); ln -s $(PACKAGE).tgz coccinelle-latest.tgz
+
+
+#TXT=$(wildcard *.txt)
+syncwiki:
+#      unison ~/public_html/wiki/wiki-LFS/data/pages/ docs/wiki/
+#      set -e; for i in $(TXT); do unison $$i docs/wiki/$$i; done
+
+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
+##############################################################################
+
+test: $(TARGET)
+       ./$(TARGET) -testall
+
+testparsing:
+       ./$(TARGET) -D standard.h -parse_c -dir tests/
+
+
+
+# -inline 0  to see all the functions in the profile.
+# Can also use the profile framework in commons/ and run your program
+# with -profile.
+forprofiling:
+       $(MAKE) OPTFLAGS="-p -inline 0 " opt
+
+clean::
+       rm -f gmon.out
+
+tags:
+       otags -no-mli-tags -r  .
+
+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 -lr /tmp/dependfull.depend > /tmp/dependfull.dot
+       dot -Tps /tmp/dependfull.dot > /tmp/dependfull.ps
+       ps2pdf /tmp/dependfull.ps /tmp/dependfull.pdf
+
+##############################################################################
+# Misc rules
+##############################################################################
+
+# each member of the project can have its own test.ml. this file is
+# not under CVS.
+test.ml:
+       echo "let foo_ctl () = failwith \"there is no foo_ctl formula\"" \
+         > test.ml
+
+beforedepend:: test.ml
+
+
+#INC=$(dir $(shell which ocaml))
+#INCX=$(INC:/=)
+#INCY=$(dir $(INCX))
+#INCZ=$(INCY:/=)/lib/ocaml
+#
+#prim.o: prim.c
+#      gcc -c -o prim.o -I $(INCZ) prim.c
+
+
+##############################################################################
+# Generic ocaml 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[iox] *.o *.annot
+
+clean::
+       rm -f *~ .*~ *.exe #*#
+
+beforedepend::
+
+depend:: beforedepend
+       $(OCAMLDEP) *.mli *.ml > .depend
+       set -e; for i in $(MAKESUBDIRS); do $(MAKE) -C $$i depend; done
+
+-include .depend
diff --git a/.#Makefile.1.125 b/.#Makefile.1.125
new file mode 100644 (file)
index 0000000..6909149
--- /dev/null
@@ -0,0 +1,467 @@
+# Copyright 2005-2009, 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.
+
+
+#############################################################################
+# Configuration section
+#############################################################################
+
+-include Makefile.config
+
+VERSION=$(shell cat globals/config.ml |grep version |perl -p -e 's/.*"(.*)".*/$$1/;')
+
+##############################################################################
+# Variables
+##############################################################################
+TARGET=spatch
+
+SRC=flag_cocci.ml cocci.ml testing.ml test.ml main.ml
+
+
+ifeq ($(FEATURE_PYTHON),1)
+PYCMA=pycaml/pycaml.cma
+PYDIR=pycaml
+PYLIB=dllpycaml_stubs.so
+# the following is essential for Coccinelle to compile under gentoo (wierd)
+OPTLIBFLAGS=-cclib dllpycaml_stubs.so
+else
+PYCMA=
+PYDIR=
+PYLIB=
+OPTLIBFLAGS=
+endif
+
+
+SYSLIBS=str.cma unix.cma
+LIBS=commons/commons.cma globals/globals.cma\
+     ctl/ctl.cma \
+     parsing_cocci/cocci_parser.cma parsing_c/parsing_c.cma \
+     engine/cocciengine.cma popl09/popl.cma \
+     extra/extra.cma $(PYCMA) python/coccipython.cma
+
+MAKESUBDIRS=commons globals menhirlib $(PYDIR) ctl parsing_cocci parsing_c \
+ engine popl09 extra python
+INCLUDEDIRS=commons commons/ocamlextra globals menhirlib $(PYDIR) ctl \
+ parsing_cocci parsing_c engine popl09 extra python
+
+##############################################################################
+# Generic variables
+##############################################################################
+
+INCLUDES=$(INCLUDEDIRS:%=-I %)
+
+OBJS=    $(SRC:.ml=.cmo)
+OPTOBJS= $(SRC:.ml=.cmx)
+
+EXEC=$(TARGET)
+
+##############################################################################
+# Generic ocaml variables
+##############################################################################
+
+OCAMLCFLAGS= #-g -dtypes # -w A
+
+# for profiling add  -p -inline 0
+# but 'make forprofiling' below does that for you.
+# This flag is also used in subdirectories so don't change its name here.
+OPTFLAGS=
+# the following is essential for Coccinelle to compile under gentoo
+# but is now defined above in this file
+#OPTLIBFLAGS=-cclib dllpycaml_stubs.so
+
+# the OPTBIN variable is here to allow to use ocamlc.opt instead of
+# ocaml, when it is available, which speeds up compilation. So
+# if you want the fast version of the ocaml chain tools, set this var
+# or setenv it to ".opt" in your startup script.
+OPTBIN= #.opt
+
+OCAMLC=ocamlc$(OPTBIN) $(OCAMLCFLAGS)  $(INCLUDES)
+OCAMLOPT=ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
+OCAMLLEX=ocamllex #-ml # -ml for debugging lexer, but slightly slower
+OCAMLYACC=ocamlyacc -v
+OCAMLDEP=ocamldep $(INCLUDES)
+OCAMLMKTOP=ocamlmktop -g -custom $(INCLUDES)
+
+# can also be set via 'make static'
+STATIC= #-ccopt -static
+
+# can also be unset via 'make purebytecode'
+BYTECODE_STATIC=-custom
+
+##############################################################################
+# Top rules
+##############################################################################
+.PHONY: all all.opt opt top clean configure
+.PHONY: $(MAKESUBDIRS) $(MAKESUBDIRS:%=%.opt) subdirs subdirs.opt
+
+all:
+       $(MAKE) subdirs
+       $(MAKE) $(EXEC)
+
+opt:
+       $(MAKE) subdirs.opt
+       $(MAKE) $(EXEC).opt
+
+all.opt: opt
+top: $(EXEC).top
+
+subdirs:
+       +for D in $(MAKESUBDIRS); do make $$D ; done
+
+subdirs.opt:
+       +for D in $(MAKESUBDIRS); do make $$D.opt ; done
+
+$(MAKESUBDIRS):
+       $(MAKE) -C $@ OCAMLCFLAGS="$(OCAMLCFLAGS)" all
+
+$(MAKESUBDIRS:%=%.opt):
+       $(MAKE) -C $(@:%.opt=%) OCAMLCFLAGS="$(OCAMLCFLAGS)" all.opt
+
+# commons:
+# globals:
+# menhirlib:
+# parsing_cocci:globals menhirlib
+# parsing_c:parsing_cocci
+# ctl:globals commons
+# engine: parsing_cocci parsing_c ctl
+# popl09:engine
+# extra: parsing_cocci parsing_c ctl
+# pycaml:
+# python:pycaml parsing_cocci parsing_c
+#
+# commons.opt:
+# globals.opt:
+# menhirlib.opt:
+# parsing_cocci.opt:globals.opt menhirlib.opt
+# parsing_c.opt:parsing_cocci.opt
+# ctl.opt:globals.opt commons.opt
+# engine.opt: parsing_cocci.opt parsing_c.opt ctl.opt
+# popl09.opt:engine.opt
+# extra.opt: parsing_cocci.opt parsing_c.opt ctl.opt
+# pycaml.opt:
+# python.opt:pycaml.opt parsing_cocci.opt parsing_c.opt
+
+clean::
+       set -e; for i in $(MAKESUBDIRS); do $(MAKE) -C $$i clean; done
+
+configure:
+       ./configure
+
+$(LIBS): #$(MAKESUBDIRS)
+$(LIBS:.cma=.cmxa): #$(MAKESUBDIRS:%=%.opt)
+
+$(OBJS):$(LIBS)
+$(OPTOBJS):$(LIBS:.cma=.cmxa)
+
+$(EXEC): $(LIBS) $(OBJS)
+       $(OCAMLC) $(BYTECODE_STATIC) -o $@ $(SYSLIBS)  $^
+
+$(EXEC).opt: $(LIBS:.cma=.cmxa) $(OPTOBJS)
+       $(OCAMLOPT) $(STATIC) -o $@ $(SYSLIBS:.cma=.cmxa) $(OPTLIBFLAGS)  $^
+
+$(EXEC).top: $(LIBS) $(OBJS)
+       $(OCAMLMKTOP) -custom -o $@ $(SYSLIBS) $^
+
+clean::
+       rm -f $(TARGET) $(TARGET).opt $(TARGET).top
+
+clean::
+       rm -f dllpycaml_stubs.so
+
+
+.PHONY: tools all configure
+
+tools:
+       $(MAKE) -C tools
+clean::
+       $(MAKE) -C tools clean
+
+
+static:
+       rm -f spatch.opt spatch
+       $(MAKE) STATIC="-ccopt -static" spatch.opt
+       cp spatch.opt spatch
+
+purebytecode:
+       rm -f spatch.opt spatch
+       $(MAKE) BYTECODE_STATIC="" spatch
+
+
+##############################################################################
+# Install
+##############################################################################
+
+# don't remove DESTDIR, it can be set by package build system like ebuild
+install: all
+       mkdir -p $(DESTDIR)$(BINDIR)
+       mkdir -p $(DESTDIR)$(LIBDIR)
+       mkdir -p $(DESTDIR)$(SHAREDIR)
+       mkdir -p $(DESTDIR)$(MANDIR)/man1
+       cp spatch $(DESTDIR)$(BINDIR)
+       cp standard.h $(DESTDIR)$(SHAREDIR)
+       cp standard.iso $(DESTDIR)$(SHAREDIR)
+       cp docs/spatch.1 $(DESTDIR)$(MANDIR)/man1/
+       mkdir -p $(DESTDIR)$(SHAREDIR)/python
+       cp -a python/coccilib $(DESTDIR)$(SHAREDIR)/python
+       cp -f dllpycaml_stubs.so $(DESTDIR)$(LIBDIR)
+       @echo ""
+       @echo "You can also install spatch by copying the program spatch"
+       @echo "(available in this directory) anywhere you want and"
+       @echo "give it the right options to find its configuration files."
+
+uninstall:
+       rm -f $(DESTDIR)$(BINDIR)/spatch
+       rm -f $(DESTDIR)$(LIBDIR)/dllpycaml_stubs.so
+       rm -f $(DESTDIR)$(SHAREDIR)/standard.h
+       rm -f $(DESTDIR)$(SHAREDIR)/standard.iso
+       rm -rf $(DESTDIR)$(SHAREDIR)/python/coccilib
+       rm -f $(DESTDIR)$(MANDIR)/man1/spatch.1
+
+
+
+version:
+       @echo $(VERSION)
+
+
+##############################################################################
+# Package rules
+##############################################################################
+
+PACKAGE=coccinelle-$(VERSION)
+
+BINSRC=spatch env.sh env.csh standard.h standard.iso \
+       *.txt docs/* \
+       demos/foo.* demos/simple.*
+#      $(PYLIB) python/coccilib/ demos/printloc.*
+BINSRC2=$(BINSRC:%=$(PACKAGE)/%)
+
+TMP=/tmp
+OCAMLVERSION=$(shell ocaml -version |perl -p -e 's/.*version (.*)/$$1/;')
+
+# Procedure to do first time:
+#  cd ~/release
+#  cvs checkout coccinelle
+#  cd coccinelle
+#  cvs update -d -P
+#  touch **/*
+#  make licensify
+#  remember to comment the -g -dtypes in this Makefile
+
+# Procedure to do each time:
+#  cvs update
+#  make sure that ocaml is the distribution ocaml of /usr/bin, not ~pad/...
+#  modify globals/config.ml
+#  cd globals/; cvs commit -m"new version"  (do not commit from the root!)
+#  ./configure --without-python
+#  make package
+#  make website
+# Check that run an ocaml in /usr/bin
+
+# To test you can try compile and run spatch from different instances
+# like my ~/coccinelle, ~/release/coccinelle, and the /tmp/coccinelle-0.X
+# downloaded from the website.
+
+# For 'make srctar' it must done from a clean
+# repo such as ~/release/coccinelle. It must also be a repo where
+# the scripts/licensify has been run at least once.
+# For the 'make bintar' I can do it from my original repo.
+
+
+package:
+       make srctar
+       make bintar
+       make staticbintar
+       make bytecodetar
+
+# I currently pre-generate the parser so the user does not have to
+# install menhir on his machine. I also do a few cleanups like 'rm todo_pos'.
+# You may have first to do a 'make licensify'.
+srctar:
+       make clean
+       cp -a .  $(TMP)/$(PACKAGE)
+       cd $(TMP)/$(PACKAGE); cd parsing_cocci/; make parser_cocci_menhir.ml
+       cd $(TMP)/$(PACKAGE); rm todo_pos
+       cd $(TMP); tar cvfz $(PACKAGE).tgz --exclude-vcs $(PACKAGE)
+       rm -rf  $(TMP)/$(PACKAGE)
+
+
+bintar: all
+       rm -f $(TMP)/$(PACKAGE)
+       ln -s `pwd` $(TMP)/$(PACKAGE)
+       cd $(TMP); tar cvfz $(PACKAGE)-bin-x86.tgz --exclude-vcs $(BINSRC2)
+       rm -f $(TMP)/$(PACKAGE)
+
+staticbintar: all.opt
+       rm -f $(TMP)/$(PACKAGE)
+       ln -s `pwd` $(TMP)/$(PACKAGE)
+       make static
+       cd $(TMP); tar cvfz $(PACKAGE)-bin-x86-static.tgz --exclude-vcs $(BINSRC2)
+       rm -f $(TMP)/$(PACKAGE)
+
+# add ocaml version in name ?
+bytecodetar: all
+       rm -f $(TMP)/$(PACKAGE)
+       ln -s `pwd` $(TMP)/$(PACKAGE)
+       make purebytecode
+       cd $(TMP); tar cvfz $(PACKAGE)-bin-bytecode-$(OCAMLVERSION).tgz --exclude-vcs $(BINSRC2)
+       rm -f $(TMP)/$(PACKAGE)
+
+clean::
+       rm -f $(PACKAGE)
+       rm -f $(PACKAGE)-bin-x86.tgz
+       rm -f $(PACKAGE)-bin-x86-static.tgz
+       rm -f $(PACKAGE)-bin-bytecode-$(OCAMLVERSION).tgz
+
+
+
+TOLICENSIFY=ctl engine parsing_cocci popl popl09 python
+licensify:
+       ocaml tools/licensify.ml
+       set -e; for i in $(TOLICENSIFY); do cd $$i; ocaml ../tools/licensify.ml; cd ..; done
+
+# When checking out the source from diku sometimes I have some "X in the future"
+# error messages.
+fixdates:
+       echo do 'touch **/*.*'
+
+#fixCVS:
+#      cvs update -d -P
+#      echo do 'rm -rf **/CVS'
+
+ocamlversion:
+       @echo $(OCAMLVERSION)
+
+
+##############################################################################
+# Pad specific rules
+##############################################################################
+
+#TOP=/home/pad/mobile/project-coccinelle
+WEBSITE=/home/pad/mobile/homepage/software/project-coccinelle
+
+website:
+       cp $(TMP)/$(PACKAGE).tgz                $(WEBSITE)
+       cp $(TMP)/$(PACKAGE)-bin-x86.tgz        $(WEBSITE)
+       cp $(TMP)/$(PACKAGE)-bin-x86-static.tgz $(WEBSITE)
+       cp $(TMP)/$(PACKAGE)-bin-bytecode-$(OCAMLVERSION).tgz   $(WEBSITE)
+       rm -f $(WEBSITE)/LATEST* $(WEBSITE)/coccinelle-latest.tgz
+       cd $(WEBSITE); touch LATEST_IS_$(VERSION); ln -s $(PACKAGE).tgz coccinelle-latest.tgz
+
+
+#TXT=$(wildcard *.txt)
+syncwiki:
+#      unison ~/public_html/wiki/wiki-LFS/data/pages/ docs/wiki/
+#      set -e; for i in $(TXT); do unison $$i docs/wiki/$$i; done
+
+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
+##############################################################################
+
+test: $(TARGET)
+       ./$(TARGET) -testall
+
+testparsing:
+       ./$(TARGET) -D standard.h -parse_c -dir tests/
+
+
+
+# -inline 0  to see all the functions in the profile.
+# Can also use the profile framework in commons/ and run your program
+# with -profile.
+forprofiling:
+       $(MAKE) OPTFLAGS="-p -inline 0 " opt
+
+clean::
+       rm -f gmon.out
+
+tags:
+       otags -no-mli-tags -r  .
+
+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 -lr /tmp/dependfull.depend > /tmp/dependfull.dot
+       dot -Tps /tmp/dependfull.dot > /tmp/dependfull.ps
+       ps2pdf /tmp/dependfull.ps /tmp/dependfull.pdf
+
+##############################################################################
+# Misc rules
+##############################################################################
+
+# each member of the project can have its own test.ml. this file is
+# not under CVS.
+test.ml:
+       echo "let foo_ctl () = failwith \"there is no foo_ctl formula\"" \
+         > test.ml
+
+beforedepend:: test.ml
+
+
+#INC=$(dir $(shell which ocaml))
+#INCX=$(INC:/=)
+#INCY=$(dir $(INCX))
+#INCZ=$(INCY:/=)/lib/ocaml
+#
+#prim.o: prim.c
+#      gcc -c -o prim.o -I $(INCZ) prim.c
+
+
+##############################################################################
+# Generic ocaml 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[iox] *.o *.annot
+
+clean::
+       rm -f *~ .*~ *.exe #*#
+
+beforedepend::
+
+depend:: beforedepend
+       $(OCAMLDEP) *.mli *.ml > .depend
+       set -e; for i in $(MAKESUBDIRS); do $(MAKE) -C $$i depend; done
+
+-include .depend
diff --git a/.#Makefile.1.127 b/.#Makefile.1.127
new file mode 100644 (file)
index 0000000..59a8518
--- /dev/null
@@ -0,0 +1,467 @@
+# Copyright 2005-2009, 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.
+
+
+#############################################################################
+# Configuration section
+#############################################################################
+
+-include Makefile.config
+
+VERSION=$(shell cat globals/config.ml |grep version |perl -p -e 's/.*"(.*)".*/$$1/;')
+
+##############################################################################
+# Variables
+##############################################################################
+TARGET=spatch
+
+SRC=flag_cocci.ml cocci.ml testing.ml test.ml main.ml
+
+
+ifeq ($(FEATURE_PYTHON),1)
+PYCMA=pycaml/pycaml.cma
+PYDIR=pycaml
+PYLIB=dllpycaml_stubs.so
+# the following is essential for Coccinelle to compile under gentoo (wierd)
+OPTLIBFLAGS=-cclib dllpycaml_stubs.so
+else
+PYCMA=
+PYDIR=
+PYLIB=
+OPTLIBFLAGS=
+endif
+
+
+SYSLIBS=str.cma unix.cma
+LIBS=commons/commons.cma globals/globals.cma\
+     ctl/ctl.cma \
+     parsing_cocci/cocci_parser.cma parsing_c/parsing_c.cma \
+     engine/cocciengine.cma popl09/popl.cma \
+     extra/extra.cma $(PYCMA) python/coccipython.cma
+
+MAKESUBDIRS=commons globals menhirlib $(PYDIR) ctl parsing_cocci parsing_c \
+ engine popl09 extra python
+INCLUDEDIRS=commons commons/ocamlextra globals menhirlib $(PYDIR) ctl \
+ parsing_cocci parsing_c engine popl09 extra python
+
+##############################################################################
+# Generic variables
+##############################################################################
+
+INCLUDES=$(INCLUDEDIRS:%=-I %)
+
+OBJS=    $(SRC:.ml=.cmo)
+OPTOBJS= $(SRC:.ml=.cmx)
+
+EXEC=$(TARGET)
+
+##############################################################################
+# Generic ocaml variables
+##############################################################################
+
+OCAMLCFLAGS= #-g -dtypes # -w A
+
+# for profiling add  -p -inline 0
+# but 'make forprofiling' below does that for you.
+# This flag is also used in subdirectories so don't change its name here.
+OPTFLAGS=
+# the following is essential for Coccinelle to compile under gentoo
+# but is now defined above in this file
+#OPTLIBFLAGS=-cclib dllpycaml_stubs.so
+
+# the OPTBIN variable is here to allow to use ocamlc.opt instead of
+# ocaml, when it is available, which speeds up compilation. So
+# if you want the fast version of the ocaml chain tools, set this var
+# or setenv it to ".opt" in your startup script.
+OPTBIN= #.opt
+
+OCAMLC=ocamlc$(OPTBIN) $(OCAMLCFLAGS)  $(INCLUDES)
+OCAMLOPT=ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
+OCAMLLEX=ocamllex #-ml # -ml for debugging lexer, but slightly slower
+OCAMLYACC=ocamlyacc -v
+OCAMLDEP=ocamldep $(INCLUDES)
+OCAMLMKTOP=ocamlmktop -g -custom $(INCLUDES)
+
+# can also be set via 'make static'
+STATIC= #-ccopt -static
+
+# can also be unset via 'make purebytecode'
+BYTECODE_STATIC=-custom
+
+##############################################################################
+# Top rules
+##############################################################################
+.PHONY: all all.opt opt top clean configure
+.PHONY: $(MAKESUBDIRS) $(MAKESUBDIRS:%=%.opt) subdirs subdirs.opt
+
+all:
+       $(MAKE) subdirs
+       $(MAKE) $(EXEC)
+
+opt:
+       $(MAKE) subdirs.opt
+       $(MAKE) $(EXEC).opt
+
+all.opt: opt
+top: $(EXEC).top
+
+subdirs:
+       +for D in $(MAKESUBDIRS); do $(MAKE) $$D ; done
+
+subdirs.opt:
+       +for D in $(MAKESUBDIRS); do $(MAKE) $$D.opt ; done
+
+$(MAKESUBDIRS):
+       $(MAKE) -C $@ OCAMLCFLAGS="$(OCAMLCFLAGS)" all
+
+$(MAKESUBDIRS:%=%.opt):
+       $(MAKE) -C $(@:%.opt=%) OCAMLCFLAGS="$(OCAMLCFLAGS)" all.opt
+
+# commons:
+# globals:
+# menhirlib:
+# parsing_cocci:globals menhirlib
+# parsing_c:parsing_cocci
+# ctl:globals commons
+# engine: parsing_cocci parsing_c ctl
+# popl09:engine
+# extra: parsing_cocci parsing_c ctl
+# pycaml:
+# python:pycaml parsing_cocci parsing_c
+#
+# commons.opt:
+# globals.opt:
+# menhirlib.opt:
+# parsing_cocci.opt:globals.opt menhirlib.opt
+# parsing_c.opt:parsing_cocci.opt
+# ctl.opt:globals.opt commons.opt
+# engine.opt: parsing_cocci.opt parsing_c.opt ctl.opt
+# popl09.opt:engine.opt
+# extra.opt: parsing_cocci.opt parsing_c.opt ctl.opt
+# pycaml.opt:
+# python.opt:pycaml.opt parsing_cocci.opt parsing_c.opt
+
+clean::
+       set -e; for i in $(MAKESUBDIRS); do $(MAKE) -C $$i clean; done
+
+configure:
+       ./configure
+
+$(LIBS): $(MAKESUBDIRS)
+$(LIBS:.cma=.cmxa): $(MAKESUBDIRS:%=%.opt)
+
+$(OBJS):$(LIBS)
+$(OPTOBJS):$(LIBS:.cma=.cmxa)
+
+$(EXEC): $(LIBS) $(OBJS)
+       $(OCAMLC) $(BYTECODE_STATIC) -o $@ $(SYSLIBS)  $^
+
+$(EXEC).opt: $(LIBS:.cma=.cmxa) $(OPTOBJS)
+       $(OCAMLOPT) $(STATIC) -o $@ $(SYSLIBS:.cma=.cmxa) $(OPTLIBFLAGS)  $^
+
+$(EXEC).top: $(LIBS) $(OBJS)
+       $(OCAMLMKTOP) -custom -o $@ $(SYSLIBS) $^
+
+clean::
+       rm -f $(TARGET) $(TARGET).opt $(TARGET).top
+
+clean::
+       rm -f dllpycaml_stubs.so
+
+
+.PHONY: tools all configure
+
+tools:
+       $(MAKE) -C tools
+clean::
+       $(MAKE) -C tools clean
+
+
+static:
+       rm -f spatch.opt spatch
+       $(MAKE) STATIC="-ccopt -static" spatch.opt
+       cp spatch.opt spatch
+
+purebytecode:
+       rm -f spatch.opt spatch
+       $(MAKE) BYTECODE_STATIC="" spatch
+
+
+##############################################################################
+# Install
+##############################################################################
+
+# don't remove DESTDIR, it can be set by package build system like ebuild
+install: all
+       mkdir -p $(DESTDIR)$(BINDIR)
+       mkdir -p $(DESTDIR)$(LIBDIR)
+       mkdir -p $(DESTDIR)$(SHAREDIR)
+       mkdir -p $(DESTDIR)$(MANDIR)/man1
+       cp spatch $(DESTDIR)$(BINDIR)
+       cp standard.h $(DESTDIR)$(SHAREDIR)
+       cp standard.iso $(DESTDIR)$(SHAREDIR)
+       cp docs/spatch.1 $(DESTDIR)$(MANDIR)/man1/
+       mkdir -p $(DESTDIR)$(SHAREDIR)/python
+       cp -a python/coccilib $(DESTDIR)$(SHAREDIR)/python
+       cp -f dllpycaml_stubs.so $(DESTDIR)$(LIBDIR)
+       @echo ""
+       @echo "You can also install spatch by copying the program spatch"
+       @echo "(available in this directory) anywhere you want and"
+       @echo "give it the right options to find its configuration files."
+
+uninstall:
+       rm -f $(DESTDIR)$(BINDIR)/spatch
+       rm -f $(DESTDIR)$(LIBDIR)/dllpycaml_stubs.so
+       rm -f $(DESTDIR)$(SHAREDIR)/standard.h
+       rm -f $(DESTDIR)$(SHAREDIR)/standard.iso
+       rm -rf $(DESTDIR)$(SHAREDIR)/python/coccilib
+       rm -f $(DESTDIR)$(MANDIR)/man1/spatch.1
+
+
+
+version:
+       @echo $(VERSION)
+
+
+##############################################################################
+# Package rules
+##############################################################################
+
+PACKAGE=coccinelle-$(VERSION)
+
+BINSRC=spatch env.sh env.csh standard.h standard.iso \
+       *.txt docs/* \
+       demos/foo.* demos/simple.*
+#      $(PYLIB) python/coccilib/ demos/printloc.*
+BINSRC2=$(BINSRC:%=$(PACKAGE)/%)
+
+TMP=/tmp
+OCAMLVERSION=$(shell ocaml -version |perl -p -e 's/.*version (.*)/$$1/;')
+
+# Procedure to do first time:
+#  cd ~/release
+#  cvs checkout coccinelle
+#  cd coccinelle
+#  cvs update -d -P
+#  touch **/*
+#  make licensify
+#  remember to comment the -g -dtypes in this Makefile
+
+# Procedure to do each time:
+#  cvs update
+#  make sure that ocaml is the distribution ocaml of /usr/bin, not ~pad/...
+#  modify globals/config.ml
+#  cd globals/; cvs commit -m"new version"  (do not commit from the root!)
+#  ./configure --without-python
+#  make package
+#  make website
+# Check that run an ocaml in /usr/bin
+
+# To test you can try compile and run spatch from different instances
+# like my ~/coccinelle, ~/release/coccinelle, and the /tmp/coccinelle-0.X
+# downloaded from the website.
+
+# For 'make srctar' it must done from a clean
+# repo such as ~/release/coccinelle. It must also be a repo where
+# the scripts/licensify has been run at least once.
+# For the 'make bintar' I can do it from my original repo.
+
+
+package:
+       make srctar
+       make bintar
+       make staticbintar
+       make bytecodetar
+
+# I currently pre-generate the parser so the user does not have to
+# install menhir on his machine. I also do a few cleanups like 'rm todo_pos'.
+# You may have first to do a 'make licensify'.
+srctar:
+       make clean
+       cp -a .  $(TMP)/$(PACKAGE)
+       cd $(TMP)/$(PACKAGE); cd parsing_cocci/; make parser_cocci_menhir.ml
+       cd $(TMP)/$(PACKAGE); rm todo_pos
+       cd $(TMP); tar cvfz $(PACKAGE).tgz --exclude-vcs $(PACKAGE)
+       rm -rf  $(TMP)/$(PACKAGE)
+
+
+bintar: all
+       rm -f $(TMP)/$(PACKAGE)
+       ln -s `pwd` $(TMP)/$(PACKAGE)
+       cd $(TMP); tar cvfz $(PACKAGE)-bin-x86.tgz --exclude-vcs $(BINSRC2)
+       rm -f $(TMP)/$(PACKAGE)
+
+staticbintar: all.opt
+       rm -f $(TMP)/$(PACKAGE)
+       ln -s `pwd` $(TMP)/$(PACKAGE)
+       make static
+       cd $(TMP); tar cvfz $(PACKAGE)-bin-x86-static.tgz --exclude-vcs $(BINSRC2)
+       rm -f $(TMP)/$(PACKAGE)
+
+# add ocaml version in name ?
+bytecodetar: all
+       rm -f $(TMP)/$(PACKAGE)
+       ln -s `pwd` $(TMP)/$(PACKAGE)
+       make purebytecode
+       cd $(TMP); tar cvfz $(PACKAGE)-bin-bytecode-$(OCAMLVERSION).tgz --exclude-vcs $(BINSRC2)
+       rm -f $(TMP)/$(PACKAGE)
+
+clean::
+       rm -f $(PACKAGE)
+       rm -f $(PACKAGE)-bin-x86.tgz
+       rm -f $(PACKAGE)-bin-x86-static.tgz
+       rm -f $(PACKAGE)-bin-bytecode-$(OCAMLVERSION).tgz
+
+
+
+TOLICENSIFY=ctl engine parsing_cocci popl popl09 python
+licensify:
+       ocaml tools/licensify.ml
+       set -e; for i in $(TOLICENSIFY); do cd $$i; ocaml ../tools/licensify.ml; cd ..; done
+
+# When checking out the source from diku sometimes I have some "X in the future"
+# error messages.
+fixdates:
+       echo do 'touch **/*.*'
+
+#fixCVS:
+#      cvs update -d -P
+#      echo do 'rm -rf **/CVS'
+
+ocamlversion:
+       @echo $(OCAMLVERSION)
+
+
+##############################################################################
+# Pad specific rules
+##############################################################################
+
+#TOP=/home/pad/mobile/project-coccinelle
+WEBSITE=/home/pad/mobile/homepage/software/project-coccinelle
+
+website:
+       cp $(TMP)/$(PACKAGE).tgz                $(WEBSITE)
+       cp $(TMP)/$(PACKAGE)-bin-x86.tgz        $(WEBSITE)
+       cp $(TMP)/$(PACKAGE)-bin-x86-static.tgz $(WEBSITE)
+       cp $(TMP)/$(PACKAGE)-bin-bytecode-$(OCAMLVERSION).tgz   $(WEBSITE)
+       rm -f $(WEBSITE)/LATEST* $(WEBSITE)/coccinelle-latest.tgz
+       cd $(WEBSITE); touch LATEST_IS_$(VERSION); ln -s $(PACKAGE).tgz coccinelle-latest.tgz
+
+
+#TXT=$(wildcard *.txt)
+syncwiki:
+#      unison ~/public_html/wiki/wiki-LFS/data/pages/ docs/wiki/
+#      set -e; for i in $(TXT); do unison $$i docs/wiki/$$i; done
+
+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
+##############################################################################
+
+test: $(TARGET)
+       ./$(TARGET) -testall
+
+testparsing:
+       ./$(TARGET) -D standard.h -parse_c -dir tests/
+
+
+
+# -inline 0  to see all the functions in the profile.
+# Can also use the profile framework in commons/ and run your program
+# with -profile.
+forprofiling:
+       $(MAKE) OPTFLAGS="-p -inline 0 " opt
+
+clean::
+       rm -f gmon.out
+
+tags:
+       otags -no-mli-tags -r  .
+
+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 -lr /tmp/dependfull.depend > /tmp/dependfull.dot
+       dot -Tps /tmp/dependfull.dot > /tmp/dependfull.ps
+       ps2pdf /tmp/dependfull.ps /tmp/dependfull.pdf
+
+##############################################################################
+# Misc rules
+##############################################################################
+
+# each member of the project can have its own test.ml. this file is
+# not under CVS.
+test.ml:
+       echo "let foo_ctl () = failwith \"there is no foo_ctl formula\"" \
+         > test.ml
+
+beforedepend:: test.ml
+
+
+#INC=$(dir $(shell which ocaml))
+#INCX=$(INC:/=)
+#INCY=$(dir $(INCX))
+#INCZ=$(INCY:/=)/lib/ocaml
+#
+#prim.o: prim.c
+#      gcc -c -o prim.o -I $(INCZ) prim.c
+
+
+##############################################################################
+# Generic ocaml 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[iox] *.o *.annot
+
+clean::
+       rm -f *~ .*~ *.exe #*#
+
+beforedepend::
+
+depend:: beforedepend
+       $(OCAMLDEP) *.mli *.ml > .depend
+       set -e; for i in $(MAKESUBDIRS); do $(MAKE) -C $$i depend; done
+
+-include .depend
diff --git a/.#cocci.ml.1.295 b/.#cocci.ml.1.295
new file mode 100644 (file)
index 0000000..1c1c45a
--- /dev/null
@@ -0,0 +1,1512 @@
+(*
+* Copyright 2005-2009, 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 CCI = Ctlcocci_integration
+module TAC = Type_annoter_c
+
+(*****************************************************************************)
+(* This file is a kind of driver. It gathers all the important functions 
+ * from coccinelle in one place. The different entities in coccinelle are:
+ *  - files
+ *  - astc
+ *  - astcocci
+ *  - flow (contain nodes)
+ *  - ctl  (contain rule_elems)
+ * This file contains functions to transform one in another.
+ *)
+(*****************************************************************************)
+
+(* --------------------------------------------------------------------- *)
+(* C related *)
+(* --------------------------------------------------------------------- *)
+let cprogram_of_file file = 
+  let (program2, _stat) = Parse_c.parse_print_error_heuristic file in
+  program2 
+
+let cprogram_of_file_cached file = 
+  let (program2, _stat) = Parse_c.parse_cache file in
+  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_c.pp_program program2_with_ppmethod outf
+
+(* for memoization, contains only one entry, the one for the SP *)
+let _hparse = Hashtbl.create 101
+let _hctl = Hashtbl.create 101
+
+(* --------------------------------------------------------------------- *)
+(* Cocci related *)
+(* --------------------------------------------------------------------- *)
+let sp_of_file2 file iso   =
+  Common.memoized _hparse (file, iso) (fun () ->
+    Parse_cocci.process file iso false)
+let sp_of_file file iso    = 
+  Common.profile_code "parse cocci" (fun () -> sp_of_file2 file iso)
+
+
+(* --------------------------------------------------------------------- *)
+(* Flow related *)
+(* --------------------------------------------------------------------- *)
+let print_flow flow = 
+  Ograph_extended.print_ograph_mutable flow "/tmp/test.dot" true
+
+
+let ast_to_flow_with_error_messages2 x =
+  let flowopt = 
+    try Ast_to_flow.ast_to_control_flow x
+    with Ast_to_flow.Error x -> 
+      Ast_to_flow.report_error x;
+      None
+  in
+  flowopt +> do_option (fun flow -> 
+    (* This time even if there is a deadcode, we still have a
+     * flow graph, so I can try the transformation and hope the
+     * deadcode will not bother us. 
+     *)
+    try Ast_to_flow.deadcode_detection flow
+    with Ast_to_flow.Error (Ast_to_flow.DeadCode x) -> 
+      Ast_to_flow.report_error (Ast_to_flow.DeadCode x);
+  );
+  flowopt
+let ast_to_flow_with_error_messages a = 
+  Common.profile_code "flow" (fun () -> ast_to_flow_with_error_messages2 a)
+
+
+(* --------------------------------------------------------------------- *)
+(* Ctl related *)
+(* --------------------------------------------------------------------- *)
+let ctls_of_ast2 ast ua pos =
+  List.map2
+    (function ast -> function (ua,pos) ->
+      List.combine
+       (if !Flag_cocci.popl
+       then Popl.popl ast
+       else Asttoctl2.asttoctl ast ua pos)
+       (Asttomember.asttomember ast ua))
+    ast (List.combine ua pos)
+
+let ctls_of_ast ast ua =
+  Common.profile_code "asttoctl2" (fun () -> ctls_of_ast2 ast ua)
+
+(*****************************************************************************)
+(* Some  debugging functions *)
+(*****************************************************************************)
+
+(* the inputs *)
+
+let show_or_not_cfile2 cfile =
+  if !Flag_cocci.show_c then begin
+    Common.pr2_xxxxxxxxxxxxxxxxx ();
+    pr2 ("processing C file: " ^ cfile);
+    Common.pr2_xxxxxxxxxxxxxxxxx ();
+    Common.command2 ("cat " ^ cfile);
+  end
+let show_or_not_cfile a = 
+  Common.profile_code "show_xxx" (fun () -> show_or_not_cfile2 a)
+
+let show_or_not_cfiles cfiles = List.iter show_or_not_cfile cfiles
+
+
+let show_or_not_cocci2 coccifile isofile = 
+  if !Flag_cocci.show_cocci then begin
+    Common.pr2_xxxxxxxxxxxxxxxxx ();
+    pr2 ("processing semantic patch file: " ^ coccifile);
+    isofile +> (fun s -> pr2 ("with isos from: " ^ s));
+    Common.pr2_xxxxxxxxxxxxxxxxx ();
+    Common.command2 ("cat " ^ coccifile);
+    pr2 "";
+  end
+let show_or_not_cocci a b = 
+  Common.profile_code "show_xxx" (fun () -> show_or_not_cocci2 a b)
+
+
+(* the output *)
+
+let show_or_not_diff2 cfile outfile show_only_minus = 
+  if !Flag_cocci.show_diff then begin
+    match Common.fst(Compare_c.compare_default cfile outfile) with
+      Compare_c.Correct -> () (* diff only in spacing, etc *)
+    | _ ->
+        (* may need --strip-trailing-cr under windows *)
+       pr2 "diff = ";
+
+       let line =
+         match !Flag_parsing_c.diff_lines with
+         | None ->   "diff -u -p " ^ cfile ^ " " ^ outfile
+         | Some n -> "diff -U "^n^" -p "^cfile^" "^outfile in
+       let xs =
+         let res = Common.cmd_to_list line in
+         match (!Flag.patch,res) with
+       (* create something that looks like the output of patch *)
+           (Some prefix,minus_file::plus_file::rest) ->
+             let drop_prefix file =
+               if prefix = ""
+               then "/"^file
+               else
+                 (match Str.split (Str.regexp prefix) file with
+                   [base_file] -> base_file
+                 | _ -> failwith "prefix not found in the old file name") in
+             let diff_line =
+               match List.rev(Str.split (Str.regexp " ") line) with
+                 new_file::old_file::cmdrev ->
+                   if !Flag.sgrep_mode2
+                   then
+                     String.concat " "
+                       (List.rev ("/tmp/nothing" :: old_file :: cmdrev))
+                   else
+                     let old_base_file = drop_prefix old_file in
+                     String.concat " "
+                       (List.rev
+                          (("b"^old_base_file)::("a"^old_base_file)::cmdrev))
+               | _ -> failwith "bad command" in
+             let (minus_line,plus_line) =
+               if !Flag.sgrep_mode2
+               then (minus_file,plus_file)
+               else
+                 match (Str.split (Str.regexp "[ \t]") minus_file,
+                        Str.split (Str.regexp "[ \t]") plus_file) with
+                   ("---"::old_file::old_rest,"+++"::new_file::new_rest) ->
+                     let old_base_file = drop_prefix old_file in
+                     (String.concat " "
+                        ("---"::("a"^old_base_file)::old_rest),
+                      String.concat " "
+                        ("+++"::("b"^old_base_file)::new_rest))
+                 | (l1,l2) ->
+                     failwith
+                       (Printf.sprintf "bad diff header lines: %s %s"
+                          (String.concat ":" l1) (String.concat ":" l2)) in
+             diff_line::minus_line::plus_line::rest
+         |     _ -> res in
+       xs +> List.iter (fun s -> 
+         if s =~ "^\\+" && show_only_minus
+         then ()
+         else pr s)
+  end
+let show_or_not_diff a b c  = 
+  Common.profile_code "show_xxx" (fun () -> show_or_not_diff2 a b c)
+    
+    
+(* the derived input *)
+    
+let show_or_not_ctl_tex2 astcocci ctls =
+  if !Flag_cocci.show_ctl_tex then begin
+    Ctltotex.totex ("/tmp/__cocci_ctl.tex") astcocci ctls;
+    Common.command2 ("cd /tmp; latex __cocci_ctl.tex; " ^
+                    "dvips __cocci_ctl.dvi -o __cocci_ctl.ps;" ^
+                    "gv __cocci_ctl.ps &");
+  end
+let show_or_not_ctl_tex a b  = 
+  Common.profile_code "show_xxx" (fun () -> show_or_not_ctl_tex2 a b)
+    
+    
+    
+let show_or_not_rule_name ast rulenb =
+  if !Flag_cocci.show_ctl_text or !Flag.show_trying or
+    !Flag.show_transinfo or !Flag_cocci.show_binding_in_out
+  then
+    begin
+      let name =
+       match ast with
+         Ast_cocci.CocciRule (nm, (deps, drops, exists), x, _, _) -> nm
+       | _ -> i_to_s rulenb in
+      Common.pr_xxxxxxxxxxxxxxxxx ();
+      pr (name ^ " = ");
+      Common.pr_xxxxxxxxxxxxxxxxx ()
+    end
+
+let show_or_not_scr_rule_name rulenb =
+  if !Flag_cocci.show_ctl_text or !Flag.show_trying or
+    !Flag.show_transinfo or !Flag_cocci.show_binding_in_out
+  then
+    begin
+      let name = i_to_s rulenb in
+      Common.pr_xxxxxxxxxxxxxxxxx ();
+      pr ("script rule " ^ name ^ " = ");
+      Common.pr_xxxxxxxxxxxxxxxxx ()
+    end
+
+let show_or_not_ctl_text2 ctl ast rulenb =
+  if !Flag_cocci.show_ctl_text then begin
+    
+    adjust_pp_with_indent (fun () -> 
+      Format.force_newline();
+      Pretty_print_cocci.print_plus_flag := true;
+      Pretty_print_cocci.print_minus_flag := true;
+      Pretty_print_cocci.unparse ast;
+      );
+    
+    pr "CTL = ";
+    let (ctl,_) = ctl in
+    adjust_pp_with_indent (fun () -> 
+      Format.force_newline();
+      Pretty_print_engine.pp_ctlcocci 
+        !Flag_cocci.show_mcodekind_in_ctl !Flag_cocci.inline_let_ctl ctl;
+      );
+    pr "";
+  end
+let show_or_not_ctl_text a b c =
+      Common.profile_code "show_xxx" (fun () -> show_or_not_ctl_text2 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 = 
+  let (tag,trying) =
+  (match celem with 
+  | Ast_c.Definition ({Ast_c.f_name = funcs;},_) -> 
+      Flag.current_element := funcs;
+      (" function: ",funcs)
+  | Ast_c.Declaration
+      (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)
+
+
+let show_or_not_trans_info2 trans_info = 
+  if !Flag.show_transinfo then begin
+    if null trans_info then pr2 "transformation info is empty"
+    else begin
+      pr2 "transformation info returned:";
+      let trans_info =
+        List.sort (function (i1,_,_) -> function (i2,_,_) -> compare i1 i2)
+          trans_info 
+      in
+      indent_do (fun () -> 
+        trans_info +> List.iter (fun (i, subst, re) -> 
+          pr2 ("transform state: " ^ (Common.i_to_s i));
+          indent_do (fun () -> 
+            adjust_pp_with_indent_and_header "with rule_elem: " (fun () -> 
+              Pretty_print_cocci.print_plus_flag := true;
+              Pretty_print_cocci.print_minus_flag := true;
+              Pretty_print_cocci.rule_elem "" re;
+            );
+            adjust_pp_with_indent_and_header "with binding: " (fun () -> 
+              Pretty_print_engine.pp_binding subst;
+            );
+          )
+        );
+      )
+    end
+  end
+let show_or_not_trans_info a  = 
+  Common.profile_code "show_xxx" (fun () -> show_or_not_trans_info2 a)
+
+
+
+let show_or_not_binding2 s binding =
+  if !Flag_cocci.show_binding_in_out then begin
+    adjust_pp_with_indent_and_header ("binding " ^ s ^ " = ") (fun () -> 
+      Pretty_print_engine.pp_binding binding
+    )
+  end
+let show_or_not_binding a b  = 
+  Common.profile_code "show_xxx" (fun () -> show_or_not_binding2 a b)
+
+
+
+(*****************************************************************************)
+(* Some  helper functions *)
+(*****************************************************************************)
+
+let worth_trying cfiles tokens = 
+  (* drop the following line for a list of list by rules.  since we don't
+     allow multiple minirules, all the tokens within a rule should be in
+     a single CFG entity *)
+  let tokens = Common.union_all tokens in
+  if not !Flag_cocci.windows && not (null tokens)
+  then
+   (* could also modify the code in get_constants.ml *)
+    let tokens = tokens +> List.map (fun s -> 
+      match () with 
+      | _ when s =~ "^[A-Za-z_][A-Za-z_0-9]*$" -> 
+          "\\b" ^ s ^ "\\b"
+
+      | _ when s =~ "^[A-Za-z_]" -> 
+          "\\b" ^ s
+
+      | _ when s =~ ".*[A-Za-z_]$" -> 
+          s ^ "\\b"
+      | _ -> s
+
+    ) in
+    let com = sprintf "egrep -q '(%s)' %s" (join "|" tokens) (join " " cfiles)
+    in
+    (match Sys.command com with
+    | 0 (* success *) -> true
+    | _ (* failure *) ->
+       (if !Flag.show_misc
+       then Printf.printf "grep failed: %s\n" com);
+       false (* no match, so not worth trying *)
+    )
+  else true
+
+let check_macro_in_sp_and_adjust tokens = 
+  let tokens = Common.union_all tokens in
+  tokens +> List.iter (fun s -> 
+    if Hashtbl.mem !Parsing_hacks._defs s
+    then begin
+      pr2 "warning: macro in semantic patch was in macro definitions";
+      pr2 ("disabling macro expansion for " ^ s);
+      Hashtbl.remove !Parsing_hacks._defs s
+    end
+  )
+
+
+let contain_loop gopt = 
+  match gopt with
+  | Some g -> 
+      g#nodes#tolist +> List.exists (fun (xi, node) -> 
+        Control_flow_c.extract_is_loop node
+      )
+  | None -> true (* means nothing, if no g then will not model check *)
+
+
+
+let sp_contain_typed_metavar_z toplevel_list_list = 
+  let bind x y = x or y in
+  let option_default = false in
+  let mcode _ _ = option_default in
+  let donothing r k e = k e in
+
+  let expression r k e =
+    match Ast_cocci.unwrap e with
+    | Ast_cocci.MetaExpr (_,_,_,Some t,_,_) -> true
+    | Ast_cocci.MetaExpr (_,_,_,_,Ast_cocci.LocalID,_) -> true
+    | _ -> k e 
+  in
+
+  let combiner = 
+    Visitor_ast.combiner bind option_default
+      mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+      donothing donothing donothing donothing
+      donothing expression donothing donothing donothing donothing donothing
+      donothing donothing donothing donothing donothing 
+  in
+  toplevel_list_list +> 
+    List.exists
+    (function (nm,_,rule) ->
+      (List.exists combiner.Visitor_ast.combiner_top_level rule))
+    
+
+let sp_contain_typed_metavar rules =
+  sp_contain_typed_metavar_z 
+    (List.map
+       (function x ->
+        match x with
+          Ast_cocci.CocciRule (a,b,c,d,_) -> (a,b,c)
+        | _ -> failwith "error in filter")
+    (List.filter
+       (function x ->
+        match x with
+          Ast_cocci.CocciRule (a,b,c,d,Ast_cocci.Normal) -> true
+        | _ -> false)
+       rules))
+
+
+
+(* finding among the #include the one that we need to parse
+ * because they may contain useful type definition or because
+ * we may have to modify them
+ * 
+ * For the moment we base in part our heuristic on the name of the file, e.g.
+ * serio.c is related we think to #include <linux/serio.h> 
+ *)
+
+let (includes_to_parse:
+       (Common.filename * Parse_c.program2) list ->
+        Flag_cocci.include_options -> 'a) = fun xs choose_includes ->
+  match choose_includes with
+    Flag_cocci.I_UNSPECIFIED -> failwith "not possible"
+  | Flag_cocci.I_NO_INCLUDES -> []
+  | x ->
+      let all_includes = x = Flag_cocci.I_ALL_INCLUDES in
+      xs +> List.map (fun (file, cs) -> 
+       let dir = Common.dirname file in
+       
+       cs +> Common.map_filter (fun (c,_info_item) -> 
+         match c with
+         | 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
+             (* for our tests, all the files are flat in the current dir *)
+               if not (Sys.file_exists f) && !Flag_cocci.relax_include_path
+               then
+                 let attempt2 = Filename.concat dir (Common.last xs) in
+                 if not (Sys.file_exists f) && all_includes
+                 then Some (Filename.concat !Flag_cocci.include_path 
+                               (Common.join "/" xs))
+                 else Some attempt2
+               else Some f
+
+            | Ast_c.NonLocal xs -> 
+               if all_includes ||
+               Common.fileprefix (Common.last xs) = Common.fileprefix file
+               then 
+                  Some (Filename.concat !Flag_cocci.include_path 
+                          (Common.join "/" xs))
+               else None
+            | Ast_c.Wierd _ -> None
+                 )
+         | _ -> None))
+       +> List.concat
+       +> Common.uniq
+      
+let rec interpret_dependencies local global = function
+    Ast_cocci.Dep s      -> List.mem s local
+  | Ast_cocci.AntiDep s  ->
+      (if !Flag_ctl.steps != None
+      then failwith "steps and ! dependency incompatible");
+      not (List.mem s local)
+  | Ast_cocci.EverDep s  -> List.mem s global
+  | Ast_cocci.NeverDep s ->
+      (if !Flag_ctl.steps != None
+      then failwith "steps and ! dependency incompatible");
+      not (List.mem s global)
+  | Ast_cocci.AndDep(s1,s2) ->
+      (interpret_dependencies local global s1) &&
+      (interpret_dependencies local global s2)
+  | Ast_cocci.OrDep(s1,s2)  ->
+      (interpret_dependencies local global s1) or
+      (interpret_dependencies local global s2)
+  | Ast_cocci.NoDep -> true
+       
+let rec print_dependencies str local global dep =
+  if !Flag_cocci.show_dependencies
+  then
+    begin
+      pr2 str;
+      let seen = ref [] in
+      let rec loop = function
+         Ast_cocci.Dep s | Ast_cocci.AntiDep s ->
+           if not (List.mem s !seen)
+           then
+             begin
+               if List.mem s local
+               then pr2 (s^" satisfied")
+               else pr2 (s^" not satisfied");
+               seen := s :: !seen
+             end 
+       | Ast_cocci.EverDep s | Ast_cocci.NeverDep s ->
+           if not (List.mem s !seen)
+           then
+             begin
+               if List.mem s global
+               then pr2 (s^" satisfied")
+               else pr2 (s^" not satisfied");
+               seen := s :: !seen
+             end
+       | Ast_cocci.AndDep(s1,s2) ->
+           loop s1;
+           loop s2
+       | Ast_cocci.OrDep(s1,s2)  ->
+           loop s1;
+           loop s2
+       | Ast_cocci.NoDep -> () in
+      loop dep
+    end
+    
+    
+    
+(* --------------------------------------------------------------------- *)
+(* #include relative position in the file *)
+(* --------------------------------------------------------------------- *)
+    
+(* compute the set of new prefixes
+ * on 
+ *  "a/b/x"; (* in fact it is now a list of string so  ["a";"b";"x"] *)
+ *  "a/b/c/x";
+ *  "a/x";
+ *  "b/x";
+ * it would give for the first element 
+ *   ""; "a"; "a/b"; "a/b/x"
+ * for the second
+ *   "a/b/c/x"
+ * 
+ * update: if the include is inside a ifdef a put nothing. cf -test incl.
+ * this is because we dont want code added inside ifdef.
+ *)
+
+let compute_new_prefixes xs = 
+  xs +> Common.map_withenv (fun already xs -> 
+    let subdirs_prefixes = Common.inits xs in
+    let new_first = subdirs_prefixes +> List.filter (fun x -> 
+      not (List.mem x already)
+    )
+    in
+    new_first, 
+    new_first @ already
+  ) []
+  +> fst
+
+
+(* does via side effect on the ref in the Include in Ast_c *)
+let rec update_include_rel_pos cs =
+  let only_include = cs +> Common.map_filter (fun c -> 
+    match c with 
+    | 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
+        | _ -> 
+            if inifdef 
+            then None
+            else Some (x, aref)
+        )
+    | _ -> None
+  )
+  in
+  let (locals, nonlocals) = 
+    only_include +> Common.partition_either (fun (c, aref)  -> 
+      match c with
+      | Ast_c.Local x -> Left (x, aref)
+      | Ast_c.NonLocal x -> Right (x, aref)
+      | Ast_c.Wierd x -> raise Impossible
+    ) in
+
+  update_rel_pos_bis locals;
+  update_rel_pos_bis nonlocals;
+  cs
+and update_rel_pos_bis xs = 
+  let xs' = List.map fst xs in
+  let the_first = compute_new_prefixes xs' in
+  let the_last  = List.rev (compute_new_prefixes (List.rev xs')) in
+  let merged = Common.zip xs (Common.zip the_first the_last) in
+  merged +> List.iter (fun ((x, aref), (the_first, the_last)) -> 
+    aref := Some 
+      { 
+        Ast_c.first_of = the_first;
+        Ast_c.last_of = the_last;
+      }
+  )
+        
+
+
+
+
+
+(*****************************************************************************)
+(* All the information needed around the C elements and Cocci rules *)
+(*****************************************************************************)
+
+type toplevel_c_info = { 
+  ast_c: Ast_c.toplevel; (* contain refs so can be modified *)
+  tokens_c: Parser_c.token list;
+  fullstring: string;
+
+  flow: Control_flow_c.cflow option; (* it's the "fixed" flow *)
+  contain_loop: bool;
+  
+  env_typing_before: TAC.environment;
+  env_typing_after:  TAC.environment;
+
+  was_modified: bool ref;
+
+  (* id: int *)
+}
+
+type toplevel_cocci_info_script_rule = {
+  scr_ast_rule: string * (string * (string * string)) list * string;
+  language: string;
+  scr_dependencies: Ast_cocci.dependency;
+  scr_ruleid: int;
+  script_code: string;
+}
+
+type toplevel_cocci_info_cocci_rule = {
+  ctl: Lib_engine.ctlcocci * (CCI.pred list list);
+  metavars: Ast_cocci.metavar list;
+  ast_rule: Ast_cocci.rule;
+  isexp: bool; (* true if + code is an exp, only for Flag.make_hrule *)
+
+  rulename: string;
+  dependencies: Ast_cocci.dependency;
+  (* There are also some hardcoded rule names in parse_cocci.ml:
+   *  let reserved_names = ["all";"optional_storage";"optional_qualifier"] 
+   *)
+  dropped_isos: string list;
+  free_vars:  Ast_cocci.meta_name list;
+  negated_pos_vars:  Ast_cocci.meta_name list;
+  used_after: Ast_cocci.meta_name list;
+  positions: Ast_cocci.meta_name list;
+
+  ruleid: int;
+  ruletype: Ast_cocci.ruletype;
+
+  was_matched: bool ref;
+}
+
+type toplevel_cocci_info = 
+    ScriptRuleCocciInfo of toplevel_cocci_info_script_rule
+  | CocciRuleCocciInfo of toplevel_cocci_info_cocci_rule
+
+type kind_file = Header | Source 
+type file_info = { 
+  fname : string;
+  full_fname : string;
+  was_modified_once: bool ref;
+  asts: toplevel_c_info list;
+  fpath : string;
+  fkind : kind_file;
+}
+
+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: 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_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 metavars astcocci = 
+
+  let gathered = Common.index_list_1
+      (zip (zip (zip (zip (zip (zip ctls metavars) astcocci) free_var_lists)
+                  negated_pos_lists) used_after_lists) positions_list)
+  in
+  gathered +> List.map 
+    (fun (((((((ctl_toplevel_list,metavars),ast),free_var_list),
+            negated_pos_list),used_after_list),positions_list),rulenb) -> 
+      
+      let is_script_rule r =
+        match r with Ast_cocci.ScriptRule _ -> true | _ -> false in
+
+      if not (List.length ctl_toplevel_list = 1) && not (is_script_rule ast)
+      then failwith "not handling multiple minirules";
+
+      match ast with
+        Ast_cocci.ScriptRule (lang,deps,mv,code) ->
+          let r = 
+          {
+            scr_ast_rule = (lang, mv, code);
+            language = lang;
+            scr_dependencies = deps;
+            scr_ruleid = rulenb;
+            script_code = code;
+          }
+          in ScriptRuleCocciInfo r
+      | Ast_cocci.CocciRule
+         (rulename,(dependencies,dropped_isos,z),restast,isexp,ruletype) ->
+          CocciRuleCocciInfo (
+          {
+            ctl = List.hd ctl_toplevel_list;
+            metavars = metavars;
+            ast_rule = ast;
+           isexp = List.hd isexp;
+            rulename = rulename;
+            dependencies = dependencies;
+            dropped_isos = dropped_isos;
+            free_vars = List.hd free_var_list;
+            negated_pos_vars = List.hd negated_pos_list;
+            used_after = List.hd used_after_list;
+            positions = List.hd positions_list;
+            ruleid = rulenb;
+           ruletype = ruletype;
+            was_matched = ref false;
+          })
+    )
+
+
+(* --------------------------------------------------------------------- *)
+
+let build_info_program cprogram env = 
+  let (cs, parseinfos) = Common.unzip cprogram in
+  let (cs, envs) =
+    Common.unzip (TAC.annotate_program env (*!g_contain_typedmetavar*) cs) in
+
+  zip (zip cs parseinfos) envs +> List.map (fun ((c, parseinfo), (enva,envb))->
+    let (fullstr, tokens) = parseinfo in
+
+    let flow = 
+      ast_to_flow_with_error_messages c +> Common.map_option (fun flow -> 
+        let flow = Ast_to_flow.annotate_loop_nodes flow in
+
+        (* remove the fake nodes for julia *)
+        let fixed_flow = CCI.fix_flow_ctl flow in
+
+        if !Flag_cocci.show_flow then print_flow fixed_flow;
+        if !Flag_cocci.show_before_fixed_flow then print_flow flow;
+
+        fixed_flow
+      )
+    in
+
+    {
+      ast_c = c; (* contain refs so can be modified *)
+      tokens_c =  tokens;
+      fullstring = fullstr;
+
+      flow = flow;
+
+      contain_loop = contain_loop flow;
+  
+      env_typing_before = enva;
+      env_typing_after = envb;
+
+      was_modified = ref false;
+    }
+  )
+
+
+
+(* Optimisation. Try not unparse/reparse the whole file when have modifs  *)
+let rebuild_info_program cs file isexp = 
+  cs +> List.map (fun c ->
+    if !(c.was_modified)
+    then
+      let file = Common.new_temp_file "cocci_small_output" ".c" in
+      cfile_of_program 
+        [(c.ast_c, (c.fullstring, c.tokens_c)), Unparse_c.PPnormal] 
+        file;
+         
+      (* Common.command2 ("cat " ^ file); *)
+      let cprogram = cprogram_of_file file in
+      let xs = build_info_program cprogram c.env_typing_before in
+         
+      (* TODO: assert env has not changed,
+      * if yes then must also reparse what follows even if not modified.
+      * Do that only if contain_typedmetavar of course, so good opti.
+      *)
+      (* Common.list_init xs *) (* get rid of the FinalDef *)
+      xs
+    else [c]
+  ) +> List.concat
+
+
+let rebuild_info_c_and_headers ccs isexp =
+  ccs +> List.iter (fun c_or_h -> 
+    if c_or_h.asts +> List.exists (fun c -> !(c.was_modified))
+    then c_or_h.was_modified_once := true;
+  );
+  ccs +> List.map (fun c_or_h -> 
+    { c_or_h with
+      asts = rebuild_info_program c_or_h.asts c_or_h.full_fname isexp }
+  )
+
+
+
+
+
+
+
+let prepare_c files choose_includes : file_info list = 
+  let cprograms = List.map cprogram_of_file_cached files in
+  let includes = includes_to_parse (zip files cprograms) choose_includes in
+
+  (* todo?: may not be good to first have all the headers and then all the c *)
+  let all = 
+    (includes +> List.map (fun hpath -> Right hpath))
+    ++
+    ((zip files cprograms) +> List.map (fun (file, asts) -> Left (file, asts)))
+  in
+
+  let env = ref !TAC.initial_env in
+
+  let ccs = all +> Common.map_filter (fun x -> 
+    match x with 
+    | Right hpath -> 
+        if not (Common.lfile_exists hpath) 
+        then begin 
+          pr2 ("TYPE: header " ^ hpath ^ " not found"); 
+          None 
+        end
+        else 
+          let h_cs = cprogram_of_file_cached hpath in
+          let info_h_cs = build_info_program h_cs !env in
+          env := 
+            if null info_h_cs
+            then !env
+            else last_env_toplevel_c_info info_h_cs
+          ;
+          Some { 
+            fname = Common.basename hpath;
+            full_fname = hpath;
+            asts = info_h_cs;
+            was_modified_once = ref false;
+            fpath = hpath;
+            fkind = Header;
+          }
+    | Left (file, cprogram) -> 
+        (* todo?: don't update env ? *)
+        let cs = build_info_program cprogram !env in
+        (* we do that only for the c, not for the h *)
+        ignore(update_include_rel_pos (cs +> List.map (fun x -> x.ast_c)));
+        Some { 
+          fname = Common.basename file;
+          full_fname = file;
+          asts = cs;
+          was_modified_once = ref false;
+          fpath = file;
+          fkind = Source;
+        }
+  ) 
+  in
+  ccs        
+
+
+(*****************************************************************************)
+(* Processing the ctls and toplevel C elements *)
+(*****************************************************************************)
+
+(* The main algorithm =~
+ * The algorithm is roughly: 
+ *  for_all ctl rules in SP
+ *   for_all minirule in rule (no more)
+ *    for_all binding (computed during previous phase)
+ *      for_all C elements
+ *         match control flow of function vs minirule 
+ *         with the binding and update the set of possible 
+ *         bindings, and returned the possibly modified function.
+ *   pretty print modified C elements and reparse it.
+ *
+ * 
+ * On ne prends que les newbinding ou returned_any_state est vrai.
+ * Si ca ne donne rien, on prends ce qu'il y avait au depart.
+ * Mais au nouveau depart de quoi ?  
+ * - si ca donne rien apres avoir traité toutes les fonctions avec ce binding ?
+ * - ou alors si ca donne rien, apres avoir traité toutes les fonctions 
+ *   avec tous les bindings du round d'avant ?
+ * 
+ * Julia pense qu'il faut prendre la premiere solution.
+ * Example: on a deux environnements candidats, E1 et E2 apres avoir traité
+ * la regle ctl 1. On arrive sur la regle ctl 2.
+ * E1 ne donne rien pour la regle 2, on garde quand meme E1 pour la regle 3.
+ * E2 donne un match a un endroit et rend E2' alors on utilise ca pour
+ * la regle 3.
+ * 
+ * I have not to look at used_after_list to decide to restart from
+ * scratch. I just need to look if the binding list is empty.
+ * Indeed, let's suppose that a SP have 3 regions/rules. If we
+ * don't find a match for the first region, then if this first
+ * region does not bind metavariable used after, that is if
+ * used_after_list is empty, then mysat(), even if does not find a
+ * match, will return a Left, with an empty transformation_info,
+ * and so current_binding will grow. On the contrary if the first
+ * region must bind some metavariables used after, and that we
+ * dont find any such region, then mysat() will returns lots of
+ * Right, and current_binding will not grow, and so we will have
+ * an empty list of binding, and we will catch such a case. 
+ *
+ * opti: julia says that because the binding is
+ * determined by the used_after_list, the items in the list
+ * are kind of sorted, so could optimise the insert_set operations.
+ *)
+
+
+(* r(ule), c(element in C code), e(nvironment) *)
+
+let rec apply_python_rule r cache newes e rules_that_have_matched
+    rules_that_have_ever_matched =
+  show_or_not_scr_rule_name r.scr_ruleid;
+  if not(interpret_dependencies rules_that_have_matched
+          !rules_that_have_ever_matched r.scr_dependencies)
+  then
+    begin
+      print_dependencies "dependencies for script not satisfied:"
+       rules_that_have_matched
+       !rules_that_have_ever_matched r.scr_dependencies;
+      show_or_not_binding "in environment" e;
+      (cache, (e, rules_that_have_matched)::newes)
+    end
+  else
+    begin
+      let (_, mv, _) = r.scr_ast_rule in
+      if List.for_all (Pycocci.contains_binding e) mv
+      then
+       begin
+         let relevant_bindings =
+           List.filter
+             (function ((re,rm),_) ->
+               List.exists (function (_,(r,m)) -> r = re && m = rm) mv)
+             e in
+         let new_cache =
+           if List.mem relevant_bindings cache
+           then cache
+           else
+             begin
+               print_dependencies "dependencies for script satisfied:"
+                 rules_that_have_matched
+                 !rules_that_have_ever_matched r.scr_dependencies;
+               show_or_not_binding "in" e;
+               Pycocci.build_classes (List.map (function (x,y) -> x) e);
+               Pycocci.construct_variables mv e;
+               let _ = Pycocci.pyrun_simplestring
+                 ("import coccinelle\nfrom coccinelle "^
+                  "import *\ncocci = Cocci()\n" ^
+                  r.script_code) in
+               relevant_bindings :: cache
+             end in
+         if !Pycocci.inc_match
+         then (new_cache, merge_env [(e, rules_that_have_matched)] newes)
+         else (new_cache, newes)
+       end
+      else (cache, merge_env [(e, rules_that_have_matched)] newes)
+    end
+
+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;
+
+    let reorganized_env =
+      reassociate_positions r.free_vars r.negated_pos_vars !es in
+
+    (* looping over the environments *)
+    let (_,newes (* envs for next round/rule *)) =
+      List.fold_left
+       (function (cache,newes) ->
+         function ((e,rules_that_have_matched),relevant_bindings) ->
+           if not(interpret_dependencies rules_that_have_matched
+                    !rules_that_have_ever_matched r.dependencies)
+           then
+             begin
+               print_dependencies
+                 ("dependencies for rule "^r.rulename^" not satisfied:")
+                 rules_that_have_matched
+                 !rules_that_have_ever_matched r.dependencies;
+               show_or_not_binding "in environment" e;
+               (cache,
+                merge_env
+                  [(e +> List.filter (fun (s,v) -> List.mem s r.used_after),
+                    rules_that_have_matched)]
+                  newes)
+             end
+           else
+             let new_bindings =
+               try List.assoc relevant_bindings cache
+               with
+                 Not_found ->
+                   print_dependencies
+                     ("dependencies for rule "^r.rulename^" satisfied:")
+                     rules_that_have_matched
+                     !rules_that_have_ever_matched r.dependencies;
+                   show_or_not_binding "in" e;
+                   show_or_not_binding "relevant in" relevant_bindings;
+
+                   (* applying the rule *)
+                   (match r.ruletype with
+                     Ast_cocci.Normal ->
+                       let children_e = ref [] in
+      
+                      (* looping over the functions and toplevel elements in
+                        .c and .h *)
+                       concat_headers_and_c !ccs +> List.iter (fun (c,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 f in
+                           match processed with
+                           | None -> ()
+                           | Some newbindings -> 
+                               newbindings +> List.iter (fun newbinding -> 
+                                 children_e :=
+                                   Common.insert_set newbinding !children_e)
+                                 ); (* end iter cs *)
+
+                       !children_e
+                   | Ast_cocci.Generated ->
+                       process_a_generated_a_env_a_toplevel r
+                         relevant_bindings !ccs;
+                       []) in
+
+             let old_bindings_to_keep =
+               Common.nub
+                 (e +> List.filter (fun (s,v) -> List.mem s r.used_after)) in
+             let new_e =
+               if null new_bindings
+               then
+                 begin
+                 (*use the old bindings, specialized to the used_after_list*)
+                   if !Flag_ctl.partial_match
+                   then
+                     printf
+                       "Empty list of bindings, I will restart from old env";
+                   [(old_bindings_to_keep,rules_that_have_matched)]
+                 end
+               else
+               (* combine the new bindings with the old ones, and
+                  specialize to the used_after_list *)
+                 let old_variables = List.map fst old_bindings_to_keep in
+                 (* have to explicitly discard the inherited variables
+                    because we want the inherited value of the positions
+                    variables not the extended one created by
+                    reassociate_positions. want to reassociate freshly
+                    according to the free variables of each rule. *)
+                 let new_bindings_to_add =
+                   Common.nub
+                     (new_bindings +>
+                      List.map
+                        (List.filter
+                           (fun (s,v) ->
+                             List.mem s r.used_after &&
+                             not (List.mem s old_variables)))) in
+                 List.map
+                   (function new_binding_to_add ->
+                     (List.sort compare
+                        (Common.union_set
+                           old_bindings_to_keep new_binding_to_add),
+                      r.rulename::rules_that_have_matched))
+                   new_bindings_to_add in
+             ((relevant_bindings,new_bindings)::cache,
+              merge_env new_e newes))
+       ([],[]) reorganized_env in (* end iter es *)
+    if !(r.was_matched)
+    then Common.push2 r.rulename rules_that_have_ever_matched;
+
+    es := newes;
+
+    (* apply the tagged modifs and reparse *)
+    if not !Flag.sgrep_mode2
+    then ccs := rebuild_info_c_and_headers !ccs r.isexp
+  )
+
+and merge_env new_e old_e =
+  List.fold_left
+    (function old_e ->
+      function (e,rules) as elem ->
+       let (same,diff) = List.partition (function (e1,_) -> e = e1) old_e in
+       match same with
+         [] -> elem :: old_e
+       | [(_,old_rules)] -> (e,Common.union_set rules old_rules) :: diff
+       | _ -> failwith "duplicate environment entries")
+    old_e new_e
+
+and bigloop2 rs (ccs: file_info list) = 
+  let es = ref [(Ast_c.emptyMetavarsBinding,[])] in
+  let ccs = ref ccs in
+  let rules_that_have_ever_matched = ref [] in
+
+  (* looping over the rules *)
+  rs +> List.iter (fun r -> 
+    match r with
+      ScriptRuleCocciInfo r -> 
+       if !Flag_cocci.show_ctl_text then begin
+          Common.pr_xxxxxxxxxxxxxxxxx ();
+          pr ("script: " ^ r.language);
+          Common.pr_xxxxxxxxxxxxxxxxx ();
+         
+          adjust_pp_with_indent (fun () -> 
+            Format.force_newline();
+            let (l,mv,code) = r.scr_ast_rule in
+           let deps = r.scr_dependencies in
+            Pretty_print_cocci.unparse
+             (Ast_cocci.ScriptRule (l,deps,mv,code)));
+       end;
+
+       if !Flag.show_misc then print_endline "RESULT =";
+
+        let (_, newes) =
+          List.fold_left
+            (function (cache, newes) ->
+              function (e, rules_that_have_matched) ->
+               match r.language with
+                  "python" ->
+                   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,_) -> 
+                     if c.flow <> None 
+                     then
+                       Printf.printf "Flow: %s\r\nFlow!\r\n%!" c.fullstring);
+                   (cache, newes)
+               | _ ->
+                    Printf.printf "Unknown language: %s\n" r.language;
+                    (cache, newes)
+                     )
+            ([],[]) !es in
+
+        es := newes;
+    | CocciRuleCocciInfo r ->
+       apply_cocci_rule r rules_that_have_ever_matched es ccs);
+
+  if !Flag.sgrep_mode2
+  then begin
+    (* sgrep can lead to code that is not parsable, but we must
+     * still call rebuild_info_c_and_headers to pretty print the 
+     * action (MINUS), so that later the diff will show what was
+     * matched by sgrep. But we don't want the parsing error message
+     * hence the following flag setting. So this code propably
+     * will generate a NotParsedCorrectly for the matched parts
+     * and the very final pretty print and diff will work
+     *)
+    Flag_parsing_c.verbose_parsing := false;
+    ccs := rebuild_info_c_and_headers !ccs false
+  end;
+  !ccs (* return final C asts *)
+
+and reassociate_positions free_vars negated_pos_vars envs =
+  (* issues: isolate the bindings that are relevant to a given rule.
+     separate out the position variables
+     associate all of the position variables for a given set of relevant
+     normal variable bindings with each set of relevant normal variable
+     bindings.  Goal: if eg if@p (E) matches in two places, then both inherited
+     occurrences of E should see both bindings of p, not just its own.
+     Otherwise, a position constraint for something that matches in two
+     places will never be useful, because the position can always be
+     different from the other one. *)
+   let relevant =
+     List.map
+       (function (e,_) ->
+        List.filter (function (x,_) -> List.mem x free_vars) e)
+       envs in
+   let splitted_relevant =
+     (* separate the relevant variables into the non-position ones and the
+       position ones *)
+     List.map
+       (function r ->
+        List.fold_left
+          (function (non_pos,pos) ->
+            function (v,_) as x ->
+              if List.mem v negated_pos_vars
+              then (non_pos,x::pos)
+              else (x::non_pos,pos))
+          ([],[]) r)
+       relevant in
+   let splitted_relevant =
+     List.map
+       (function (non_pos,pos) ->
+        (List.sort compare non_pos,List.sort compare pos))
+       splitted_relevant in
+   let non_poss =
+     List.fold_left
+       (function non_pos ->
+        function (np,_) ->
+          if List.mem np non_pos then non_pos else np::non_pos)
+       [] splitted_relevant in
+   let extended_relevant =
+     (* extend the position variables with the values found at other identical
+       variable bindings *)
+     List.map
+       (function non_pos ->
+        let others =
+          List.filter
+            (function (other_non_pos,other_pos) ->
+               (* do we want equal? or just somehow compatible? eg non_pos
+              binds only E, but other_non_pos binds both E and E1 *)
+              non_pos = other_non_pos)
+            splitted_relevant in
+        (non_pos,
+         List.sort compare
+           (non_pos @
+            (combine_pos negated_pos_vars
+               (List.map (function (_,x) -> x) others)))))
+       non_poss in
+   List.combine envs
+     (List.map (function (non_pos,_) -> List.assoc non_pos extended_relevant)
+       splitted_relevant)
+
+and combine_pos negated_pos_vars others =
+  List.map
+    (function posvar ->
+      (posvar,
+       Ast_c.MetaPosValList
+        (List.sort compare
+           (List.fold_left
+              (function positions ->
+                function other_list ->
+                  try
+                    match List.assoc posvar other_list with
+                      Ast_c.MetaPosValList l1 ->
+                        Common.union_set l1 positions
+                    | _ -> failwith "bad value for a position variable"
+                  with Not_found -> positions)
+              [] others))))
+    negated_pos_vars
+
+and bigloop a b = 
+  Common.profile_code "bigloop" (fun () -> bigloop2 a b)
+
+
+
+
+
+(* does side effects on C ast and on Cocci info rule *)
+and process_a_ctl_a_env_a_toplevel2 r e c f = 
+ indent_do (fun () -> 
+  show_or_not_celem "trying" c.ast_c;
+  Flag.currentfile := Some (f ^ ":" ^get_celem c.ast_c);
+  let (trans_info, returned_any_states, inherited_bindings, newbindings) = 
+    Common.save_excursion Flag_ctl.loop_in_src_code (fun () -> 
+      Flag_ctl.loop_in_src_code := !Flag_ctl.loop_in_src_code||c.contain_loop;
+      
+      (***************************************)
+      (* !Main point! The call to the engine *)
+      (***************************************)
+      let model_ctl  = CCI.model_for_ctl r.dropped_isos (Common.some c.flow) e
+      in CCI.mysat model_ctl r.ctl (r.used_after, e)
+    ) 
+  in
+  if not returned_any_states 
+  then None
+  else begin
+    show_or_not_celem "found match in" c.ast_c;
+    show_or_not_trans_info trans_info;
+    List.iter (show_or_not_binding "out") newbindings;    
+
+    r.was_matched := true;
+
+    if not (null trans_info)
+    then begin
+      c.was_modified := true;
+      try 
+        (* les "more than one var in a decl" et "already tagged token"
+         * font crasher coccinelle. Si on a 5 fichiers, donc on a 5
+         * failed. Le try limite le scope des crashes pendant la
+         * trasformation au fichier concerne. *)
+
+        (* modify ast via side effect *)
+        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;
+
+    Some (List.map (function x -> x@inherited_bindings) newbindings)
+  end
+ )
+   
+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 f)
+
+and process_a_generated_a_env_a_toplevel2 r env = function
+    [cfile] ->
+      let free_vars =
+       List.filter
+         (function
+             (rule,_) when rule = r.rulename -> false
+           | (_,"ARGS") -> false
+           | _ -> true)
+         r.free_vars in
+      let env_domain = List.map (function (nm,vl) -> nm) env in
+      let metavars =
+       List.filter
+         (function md ->
+           let (rl,_) = Ast_cocci.get_meta_name md in
+           rl = r.rulename)
+         r.metavars in
+      if Common.include_set free_vars env_domain
+      then Unparse_hrule.pp_rule metavars r.ast_rule env cfile.full_fname
+  | _ -> failwith "multiple files not supported"
+   
+and process_a_generated_a_env_a_toplevel rule env ccs = 
+  Common.profile_code "process_a_ctl_a_env_a_toplevel" 
+    (fun () -> process_a_generated_a_env_a_toplevel2 rule env ccs)
+   
+
+
+(*****************************************************************************)
+(* The main function *)
+(*****************************************************************************)
+
+let full_engine2 (coccifile, isofile) cfiles = 
+
+  show_or_not_cfiles  cfiles;
+  show_or_not_cocci   coccifile isofile;
+  Pycocci.set_coccifile coccifile;
+
+  let isofile = 
+    if not (Common.lfile_exists isofile)
+    then begin 
+      pr2 ("warning: Can't find default iso file: " ^ isofile);
+      None
+    end
+    else Some isofile
+  in
+
+  (* useful opti when use -dir *)
+  let (metavars,astcocci,free_var_lists,negated_pos_lists,used_after_lists,
+       positions_lists,toks,_) = 
+      sp_of_file coccifile isofile
+  in
+  let ctls = 
+    Common.memoized _hctl (coccifile, isofile) (fun () -> 
+      ctls_of_ast astcocci used_after_lists positions_lists)
+  in
+
+  let contain_typedmetavar = sp_contain_typed_metavar astcocci in
+
+  (* optimisation allowing to launch coccinelle on all the drivers *)
+  if !Flag_cocci.worth_trying_opt && not (worth_trying cfiles toks)
+  then begin 
+    pr2 ("not worth trying:" ^ Common.join " " cfiles);
+    cfiles +> List.map (fun s -> s, None)
+  end
+  else begin
+
+    if !Flag.show_misc then Common.pr_xxxxxxxxxxxxxxxxx();
+    if !Flag.show_misc then pr "let's go";
+    if !Flag.show_misc then Common.pr_xxxxxxxxxxxxxxxxx();
+
+    g_contain_typedmetavar := contain_typedmetavar;
+
+    check_macro_in_sp_and_adjust toks;
+
+    
+
+    let cocci_infos =
+      prepare_cocci ctls free_var_lists negated_pos_lists
+       used_after_lists positions_lists metavars astcocci in
+    let choose_includes =
+      match !Flag_cocci.include_options with
+       Flag_cocci.I_UNSPECIFIED ->
+         if contain_typedmetavar
+         then Flag_cocci.I_NORMAL_INCLUDES
+         else Flag_cocci.I_NO_INCLUDES
+      |        x -> x in
+    let c_infos  = prepare_c cfiles choose_includes in
+
+    show_or_not_ctl_tex astcocci ctls;
+
+    (* ! the big loop ! *)
+    let c_infos' = bigloop cocci_infos c_infos in
+
+    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 -> 
+      if !(c_or_h.was_modified_once)
+      then begin
+        let outfile = Common.new_temp_file "cocci-output" ("-" ^ c_or_h.fname) 
+        in
+
+        if c_or_h.fkind = Header 
+        then pr2 ("a header file was modified: " ^ c_or_h.fname);
+
+        (* and now unparse everything *)
+        cfile_of_program (for_unparser c_or_h.asts) outfile;
+
+        let show_only_minus = !Flag.sgrep_mode2 in
+        show_or_not_diff c_or_h.fpath outfile show_only_minus;
+
+        (c_or_h.fpath, 
+        if !Flag.sgrep_mode2 then None else Some outfile
+        )
+      end
+      else 
+        (c_or_h.fpath, None)
+    );
+  end
+
+let full_engine a b = 
+  Common.profile_code "full_engine" (fun () -> full_engine2 a b)
+
+
+(*****************************************************************************)
+(* check duplicate from result of full_engine *)
+(*****************************************************************************)
+
+let check_duplicate_modif2 xs = 
+  (* opti: let groups = Common.groupBy (fun (a,resa) (b,resb) -> a =$= b) xs *)
+  pr2 ("Check duplication for " ^ i_to_s (List.length xs) ^ " files");
+  let groups = Common.group_assoc_bykey_eff xs in
+  groups +> Common.map_filter (fun (file, xs) -> 
+    match xs with
+    | [] -> raise Impossible
+    | [res] -> Some (file, res)
+    | res::xs -> 
+        match res with 
+        | None -> 
+            if not (List.for_all (fun res2 -> res2 = None) xs)
+            then begin
+              pr2 ("different modification result for " ^ file);
+              None
+            end
+            else Some (file, None)
+        | Some res -> 
+            if not(List.for_all (fun res2 -> 
+              match res2 with
+              | None -> false
+              | Some res2 -> 
+                  let diff = Common.cmd_to_list ("diff -u -b -B "^res^" "^res2)
+                  in
+                  null diff
+            ) xs) then begin
+              pr2 ("different modification result for " ^ file);
+              None
+            end
+            else Some (file, Some res)
+            
+        
+  )
+let check_duplicate_modif a = 
+  Common.profile_code "check_duplicate" (fun () -> check_duplicate_modif2 a)
+
diff --git a/.#main.ml.1.248 b/.#main.ml.1.248
new file mode 100644 (file)
index 0000000..992b6ae
--- /dev/null
@@ -0,0 +1,847 @@
+(*
+* Copyright 2005-2009, 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 FC = Flag_cocci
+
+(*****************************************************************************)
+(* Flags *)
+(*****************************************************************************)
+
+(* In addition to flags that can be tweaked via -xxx options (cf the
+ * full list of options in "the spatch options" section below), the
+ * spatch program also depends on external files, described in
+ * globals/config.ml, mainly a standard.h and standard.iso file *)
+
+let cocci_file = ref ""
+
+let output_file = ref ""
+let inplace_modif = ref false  (* but keeps a .cocci_orig *)
+let outplace_modif = ref false (* generates a .cocci_res  *)
+
+(* could be avoided by using Common.files_of_dir_or_files instead *)
+let dir = ref false 
+
+let include_headers = ref false
+let kbuild_info = ref ""
+
+(* test mode *)
+let test_mode = ref false
+let test_all = ref false
+let test_okfailed = ref false
+let test_regression_okfailed = ref false
+
+
+(* action mode *)
+let action = ref ""
+
+(* works with -test but also in "normal" spatch mode *)
+let compare_with_expected = ref false
+
+
+let distrib_index = ref (None : int option)
+let distrib_max   = ref (None : int option)
+let mod_distrib   = ref false
+
+
+(*****************************************************************************)
+(* Profiles *)
+(*****************************************************************************)
+
+(* pair of  (list of flags to set true, list of flags to set false *)
+let quiet_profile = (
+  [
+  ],
+  [
+    (* FC.show_diff;   just leave this as it is *)
+
+    Flag.show_misc;
+    Flag.show_trying;
+    Flag.show_transinfo;
+
+    FC.show_c;
+    FC.show_cocci;
+    FC.show_flow;
+    FC.show_before_fixed_flow;
+    FC.show_ctl_tex;
+    FC.show_ctl_text;
+    FC.show_binding_in_out;
+
+    Flag_parsing_cocci.show_SP;
+    Flag_parsing_cocci.show_iso_failures;
+    Flag_ctl.verbose_ctl_engine;
+    Flag_ctl.verbose_match;
+    Flag_matcher.debug_engine;
+    Flag_parsing_c.debug_unparsing;
+    Flag_parsing_c.verbose_type;
+    Flag_parsing_c.verbose_parsing;
+  ])
+
+(* some information that is useful in seeing why a semantic patch doesn't
+work properly *)
+let debug_profile = (
+  [
+    Flag.show_misc;
+    FC.show_diff;
+    FC.show_cocci;
+    FC.show_binding_in_out;
+    FC.show_dependencies;
+    Flag.show_transinfo;
+    Flag_parsing_cocci.show_iso_failures;
+  ],
+  [
+
+    Flag.show_misc;
+
+    FC.show_c;
+    FC.show_flow;
+    FC.show_before_fixed_flow;
+    FC.show_ctl_tex;
+    FC.show_ctl_text;
+
+    Flag_parsing_cocci.show_SP;
+    Flag_ctl.verbose_ctl_engine;
+    Flag_ctl.verbose_match;
+    Flag_matcher.debug_engine;
+    Flag_parsing_c.debug_unparsing;
+    Flag_parsing_c.verbose_type;
+    Flag_parsing_c.verbose_parsing;
+  ])
+
+let pad_profile = (
+  [
+    FC.show_diff;
+  ],
+  [
+
+    Flag.show_misc;
+    Flag.show_transinfo;
+
+    FC.show_c;
+    FC.show_cocci;
+    FC.show_flow;
+    FC.show_before_fixed_flow;
+    FC.show_ctl_tex;
+    FC.show_ctl_text;
+    FC.show_binding_in_out;
+
+    Flag_parsing_cocci.show_SP;
+    Flag_parsing_cocci.show_iso_failures;
+    Flag_ctl.verbose_ctl_engine;
+    Flag_ctl.verbose_match;
+    Flag_matcher.debug_engine;
+    Flag_parsing_c.debug_unparsing;
+    Flag_parsing_c.verbose_type;
+    Flag_parsing_c.verbose_parsing;
+  ])
+
+let run_profile p =
+  let (set_to_true, set_to_false) = p in
+  List.iter (fun x -> x := false) set_to_false;
+  List.iter (fun x -> x := true) set_to_true
+
+(*****************************************************************************)
+(* The spatch options *)
+(*****************************************************************************)
+
+let usage_msg = 
+  "Usage: " ^ basename Sys.argv.(0) ^ 
+    " -sp_file <SP> <infile> [-o <outfile>] [-iso_file <iso>] [options]" ^ 
+    "\n" ^ "Options are:"
+
+(* forward reference trick *)
+let short_usage_func = ref (fun () -> ())
+let long_usage_func  = ref (fun () -> ())
+
+
+(* The short_options are user-oriented. The other options are for
+ * the developers of coccinelle or advanced-users that know
+ * quite well the underlying semantics of coccinelle.
+ *)
+  
+
+(* will be printed when use only ./spatch. For the rest you have to
+ * use -longhelp to see them. 
+ *)
+let short_options = [ 
+  "-sp_file",  Arg.Set_string cocci_file, 
+  " <file> the semantic patch file";
+
+  "-o", Arg.Set_string output_file,
+  "   <file> the output file";
+  "-inplace", Arg.Set inplace_modif,
+  "   do the modification on the file directly";
+  "-outplace", Arg.Set outplace_modif,
+  "   store modifications in a .cocci_res file";
+
+  "-U", Arg.Int (fun n -> Flag_parsing_c.diff_lines := Some (i_to_s n)), 
+  "  set number of diff context lines";
+  "-partial_match",        Arg.Set Flag_ctl.partial_match, 
+  "    report partial matches of the SP on the C file";
+
+  "-iso_file", Arg.Set_string Config.std_iso,   
+  " <file> (default=" ^ !Config.std_iso ^")";
+  "-macro_file", Arg.Set_string Config.std_h,
+  " <file> (default=" ^ !Config.std_h ^ ")";
+
+  "-all_includes",
+  Arg.Unit (function _ -> FC.include_options := FC.I_ALL_INCLUDES),
+  "  causes all available include files to be used";
+  "-no_includes",
+  Arg.Unit (function _ -> FC.include_options := FC.I_NO_INCLUDES),
+  "  causes not even local include files to be used";
+  "-local_includes",
+  Arg.Unit (function _ -> FC.include_options := FC.I_NORMAL_INCLUDES),
+  "  causes local include files to be used";
+  "-include_headers", Arg.Set include_headers,
+  "    process header files independently";
+  "-I",   Arg.Set_string FC.include_path,
+  "  <dir> containing the Linux headers (optional)";
+
+
+  "-dir", Arg.Set dir,
+  "    <dir> process all files in directory recursively";
+
+  "-use_glimpse", Arg.Set Flag.use_glimpse,
+  "    works with -dir, use info generated by glimpseindex";
+  "-patch", Arg.String (function s -> Flag.patch := Some s),
+  ("    <dir> path name with respect to which a patch should be created\n"^
+   "    \"\" for a file in the current directory");
+  "-kbuild_info", Arg.Set_string kbuild_info, 
+  "    <file> improve -dir by grouping related c files";
+  "-pyoutput", Arg.Set_string Flag.pyoutput,
+  "    Sets output routine: Standard values: <coccilib.output.Gtk|coccilib.output.Console>";
+
+
+  "-version",   Arg.Unit (fun () -> 
+    pr2 (spf "spatch version: %s" Config.version);
+    exit 0;
+  ), 
+    "  guess what";
+
+  "-date",   Arg.Unit (fun () -> 
+    pr2 "version: $Date: 2009/02/03 17:17:04 $";
+    raise (Common.UnixExit 0)
+    ), 
+  "   guess what";
+
+  "-shorthelp", Arg.Unit (fun () -> 
+    !short_usage_func();
+    raise (Common.UnixExit 0)
+  ), 
+  "    see short list of options";
+  "-longhelp", Arg.Unit (fun () -> 
+    !long_usage_func();
+    raise (Common.UnixExit 0)
+    ), 
+  "    see all the available options in different categories";
+  "-help", Arg.Unit (fun () -> 
+    !long_usage_func();
+    raise (Common.UnixExit 0)
+  ),
+  " ";
+  "--help", Arg.Unit (fun () -> 
+    !long_usage_func();
+    raise (Common.UnixExit 0)
+  ),
+  " ";
+    
+]
+
+(* the format is a list of triples:
+ *  (title of section * (optional) explanation of sections * option list)
+ *)
+let other_options = [
+  "aliases and obsolete options", 
+  "",
+  [ 
+    "-cocci_file", Arg.Set_string cocci_file, 
+    "   <file> the semantic patch file";
+    "-c", Arg.Set_string cocci_file,     " short option of -cocci_file";
+    "-iso", Arg.Set_string Config.std_iso,   " short option of -iso_file";
+    "-D",   Arg.Set_string Config.std_h,     " short option of -macro_file";
+  ];
+
+  "most useful show options", 
+  "",
+  [
+    "-show_diff"           , Arg.Set FC.show_diff, " ";
+    "-no_show_diff"           , Arg.Clear FC.show_diff, " ";
+    "-show_flow"              , Arg.Set FC.show_flow,        " ";
+    (* works in conjunction with -show_ctl_text *)
+    "-ctl_inline_let",   
+    Arg.Unit
+    (function _ -> FC.show_ctl_text := true; FC.inline_let_ctl := true), " ";
+    "-ctl_show_mcodekind",
+    Arg.Unit
+    (function _ -> FC.show_ctl_text := true; FC.show_mcodekind_in_ctl := true),
+    " ";
+    "-show_bindings",        Arg.Set FC.show_binding_in_out, " ";
+    "-show_transinfo",    Arg.Set Flag.show_transinfo, " ";
+    "-show_misc",         Arg.Set Flag.show_misc, " ";
+    "-show_trying",          Arg.Set Flag.show_trying,
+    " show the name of each function being processed";
+    "-show_dependencies",
+    Arg.Unit (function _ -> FC.show_dependencies := true;
+      FC.show_binding_in_out := true),
+    " show the dependencies related to each rule";
+  ];
+
+  "verbose subsystems options",  
+  "",
+  [
+    "-verbose_ctl_engine",
+    Arg.Unit (function _ ->
+      Flag_ctl.verbose_ctl_engine := true; FC.show_ctl_text := true) , " ";
+    "-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.Unit (function _ ->
+       Flag_ctl.graphical_trace := true; Flag_ctl.gt_without_label := true),
+       "  remove graph label (requires option -graphical_trace)";
+
+    "-parse_error_msg", Arg.Set Flag_parsing_c.verbose_parsing, " ";
+    "-type_error_msg",  Arg.Set Flag_parsing_c.verbose_type, " ";
+    (* could also use Flag_parsing_c.options_verbose *)
+  ];
+
+  "other show options",
+  "",
+  [
+    "-show_c"                 , Arg.Set FC.show_c,           " ";
+    "-show_cocci"             , Arg.Set FC.show_cocci,       " ";
+    "-show_before_fixed_flow" , Arg.Set FC.show_before_fixed_flow,  " ";
+    "-show_ctl_tex"           , Arg.Set FC.show_ctl_tex,     " ";
+    "-show_ctl_text"          , Arg.Set FC.show_ctl_text,     " ";
+    "-show_SP"             ,    Arg.Set Flag_parsing_cocci.show_SP,  " ";
+  ];
+
+
+  "debug C parsing/unparsing",
+  "",
+  [
+    "-debug_cpp",          Arg.Set  Flag_parsing_c.debug_cpp, " ";
+    "-debug_lexer",        Arg.Set  Flag_parsing_c.debug_lexer , " ";
+    "-debug_etdt",         Arg.Set  Flag_parsing_c.debug_etdt , "  ";
+    "-debug_typedef",      Arg.Set  Flag_parsing_c.debug_typedef, "  ";
+
+    "-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_passed_level", Arg.Set_int Flag_parsing_c.filter_passed_level,"  ";
+(*  debug cfg doesn't seem to have any effect, so drop it as an option *)
+(*  "-debug_cfg",          Arg.Set Flag_parsing_c.debug_cfg , "  "; *)
+    "-debug_unparsing",      Arg.Set  Flag_parsing_c.debug_unparsing, "  ";
+
+  ];
+  (* could use Flag_parsing_c.options_debug_with_title instead *)
+
+
+  "shortcut for enabling/disabling a set of debugging options at once",
+  "",
+  [
+    (* todo: other profile ? *)
+    "-quiet",   Arg.Unit (fun () -> run_profile quiet_profile), " ";
+    "-debug",   Arg.Unit (fun () -> run_profile debug_profile), " ";
+    "-pad",     Arg.Unit (fun () -> run_profile pad_profile),   " ";
+
+  ];
+
+  "bench options",
+  "",
+  [
+    "-profile", Arg.Unit (function () -> Common.profile := Common.PALL) , 
+    "   gather timing information about the main coccinelle functions";
+    "-bench", Arg.Int (function x -> Flag_ctl.bench := x), 
+    "   <level> for profiling the CTL engine";
+    "-timeout", Arg.Int (fun x -> FC.timeout := Some x), 
+    "   <sec> timeout in seconds";
+    "-steps", Arg.Int (fun x -> Flag_ctl.steps := Some x), 
+    "   max number of model checking steps per code unit";
+    "-track_iso", Arg.Set Flag.track_iso_usage,
+    "   gather information about isomorphism usage";
+    "-profile_iso",
+    Arg.Unit
+    (function () ->
+      Common.profile:=PSOME ["parse cocci";"mysat";"asttoctl2";"full_engine"]),
+    "   gather information about the cost of isomorphism usage"
+  ];
+
+
+
+  "change of algorithm options",
+  "", 
+  [  
+    "-popl", Arg.Set FC.popl, 
+    "    simplified SmPL, for the popl paper";
+
+    "-popl_mark_all",
+    Arg.Unit
+    (function _ -> FC.popl := true; Flag_popl.mark_all := true), 
+    "    simplified SmPL, for the popl paper";
+
+    "-popl_keep_all_wits",
+    Arg.Unit
+    (function _ -> FC.popl := true; Flag_popl.keep_all_wits := true), 
+    "    simplified SmPL, for the popl paper";
+
+    "-hrule", Arg.String
+    (function s ->
+      Flag.make_hrule := Some s; FC.include_options := FC.I_NO_INCLUDES),
+    "    semantic patch generation";
+
+    "-loop",              Arg.Set Flag_ctl.loop_in_src_code,    " ";
+
+    "-l1",                Arg.Clear Flag_parsing_c.label_strategy_2, " ";
+    "-ifdef_to_if",              Arg.Set FC.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_matcher.disallow_nested_exps,
+       "disallow an expresion pattern from matching a term and its subterm";
+    "-disable_worth_trying_opt", Arg.Clear FC.worth_trying_opt,
+    "  ";
+    "-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_matcher.allow_inconsistent_paths,
+    "if this flag is set don't check for inconsistent paths; dangerous";    
+  ];
+
+  "misc options",
+  "",
+  [
+    "-debugger",         Arg.Set Common.debugger , 
+    "   option to set if launch spatch in ocamldebug";
+    "-disable_once",     Arg.Set Common.disable_pr2_once, 
+    "   to print more messages";
+    "-save_tmp_files",   Arg.Set Common.save_tmp_files,   " ";
+  ];
+
+  "concurrency",
+  "",
+  [
+    "-index",       Arg.Int (function x -> distrib_index := Some x) , 
+    "   the processor to use for this run of spatch";
+    "-max",         Arg.Int (function x -> distrib_max := Some x) , 
+    "   the number of processors available";
+    "-mod_distrib", Arg.Set mod_distrib,
+    "   use mod to distribute files among the processors";
+  ];
+
+  "pad options",
+  "",
+  [
+    "-use_cache", Arg.Set Flag_parsing_c.use_cache, 
+    "   use .ast_raw pre-parsed cached C file";
+    (* could use Flag_parsing_c.options_pad instead *)
+  ];
+
+
+
+  "test mode and test options (works with tests/ or .ok files)",
+  "The test options don't work with the -sp_file and so on.",
+  [
+    "-test",    Arg.Set test_mode, 
+    "   <file> launch spatch on tests/file.[c,cocci]";
+    "-testall", Arg.Set test_all, 
+    "   launch spatch on all files in tests/ having a .res";
+    "-test_okfailed", Arg.Set test_okfailed,
+    "    generates .{ok,failed,spatch_ok} files using .res files";
+    "-test_regression_okfailed", Arg.Set test_regression_okfailed,
+    "    process the .{ok,failed,spatch_ok} files in current dir";
+
+    "-compare_with_expected", Arg.Set compare_with_expected, 
+    "   use also file.res"; 
+    "-relax_include_path", Arg.Set FC.relax_include_path,
+    " ";
+    
+  ];
+
+  "action mode",
+  ("The action options don't work with the -sp_file and so on." ^ "\n" ^
+   "It's for the other (internal) uses of the spatch program."
+  ),
+
+    (* -token_c, -parse_c, etc  *)
+  ((Common.options_of_actions action (Test_parsing_c.actions())) ++
+    [
+    (let s = "-parse_cocci"  in s, Arg.Unit (fun () -> action := s),
+    "   <file>");
+    (let s = "-compare_c"  in s, Arg.Unit (fun () -> action := s),
+    "   <file1> <file2>");
+    ]);
+]
+
+
+let all_options = 
+  short_options ++ List.concat (List.map Common.thd3 other_options)
+
+  
+(* I don't want the -help and --help that are appended by Arg.align *)
+let arg_align2 xs =
+  Arg.align xs +> List.rev +> Common.drop 2 +> List.rev
+
+(* copy paste of Arg.parse. Don't want the default -help msg *)
+let arg_parse2 l f msg =
+  (try
+    Arg.parse_argv Sys.argv l f msg;
+  with
+  | Arg.Bad msg -> (* eprintf "%s" msg; exit 2; *)
+      let xs = Common.lines msg in
+      (* take only head, it's where the error msg is *)
+      pr2 (List.hd xs);
+      !short_usage_func();
+      raise (Common.UnixExit (2))
+  | Arg.Help msg -> (* printf "%s" msg; exit 0; *)
+      raise Impossible  (* -help is specified in speclist *)
+  )
+
+
+let short_usage () =
+ begin
+  Common.short_usage usage_msg short_options; 
+  pr2 "";
+  pr2 "Example of use:";
+  pr2 "  ./spatch -sp_file foo.cocci foo.c -o /tmp/newfoo.c";
+  pr2 "";
+ end
+
+
+let long_usage () = 
+  Common.long_usage usage_msg short_options other_options
+
+let _ = short_usage_func := short_usage
+let _ = long_usage_func := long_usage
+
+(*****************************************************************************)
+(* Helpers *)
+(*****************************************************************************)
+
+let adjust_stdin cfile k =
+  if !dir
+  then k()
+  else
+    let newin = 
+      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 = 
+  let (_metavars,astcocci,_free_var_lists,_negated_positions,
+       _used_after_lists,_positions_lists,_,query) =
+    Cocci.sp_of_file coccifile (Some isofile) in
+  match query with
+    None -> pr2 "no glimpse keyword inferred from snippet"; None
+  | Some query ->
+      let suffixes = if !include_headers then ["c";"h"] else ["c"] in
+      pr2 ("glimpse request = " ^ query);
+      let command = spf "glimpse -y -H %s -N -W -w '%s'" dir query in
+      let (glimpse_res,stat) = Common.cmd_to_list_and_status command in
+      match stat with
+       Unix.WEXITED(0) | Unix.WEXITED(1) ->
+         Some
+           (glimpse_res +>
+            List.filter
+              (fun file -> List.mem (Common.filesuffix file) suffixes))
+      |        _ -> None (* error, eg due to pattern too big *)
+       
+       
+
+
+(*****************************************************************************)
+(* The coccinelle main entry point *)
+(*****************************************************************************)
+let main () = 
+  begin
+    let arglist = Array.to_list Sys.argv in
+
+    if not (null (Common.inter_set arglist
+                    ["-cocci_file";"-sp_file";"-test";"-testall";
+                      "-test_okfailed";"-test_regression_okfailed"]))
+    then run_profile quiet_profile;
+
+    let args = ref [] in
+
+    (* this call can set up many global flag variables via the cmd line *)
+    arg_parse2 (Arg.align all_options) (fun x -> args := x::!args) usage_msg;
+
+    (if !dir && List.length !args > 1
+    then
+      begin
+       let chosen = List.hd !args in
+       pr2 ("ignoring all but the last specified directory: "^chosen);
+       args := [chosen]
+      end);
+    args := List.rev !args;
+
+    if !cocci_file <> "" && (not (!cocci_file =~ ".*\\.\\(sgrep\\|spatch\\)$"))
+    then cocci_file := Common.adjust_ext_if_needed !cocci_file ".cocci";
+
+    if !Config.std_iso <> "" 
+    then Config.std_iso := Common.adjust_ext_if_needed !Config.std_iso ".iso";
+    if !Config.std_h <> "" 
+    then Config.std_h := Common.adjust_ext_if_needed !Config.std_h ".h";
+
+    if !Config.std_h <> "" 
+    then Parse_c.init_defs !Config.std_h;
+
+
+    (* must be done after Arg.parse, because Common.profile is set by it *)
+    Common.profile_code "Main total" (fun () -> 
+
+
+    let all_actions = Test_parsing_c.actions() in
+
+    (match (!args) with
+
+    (* --------------------------------------------------------- *)
+    (* The test framework. Works with tests/ or .ok and .failed  *)
+    (* --------------------------------------------------------- *)
+    | [x] when !test_mode    -> 
+        FC.include_path := "tests/include";
+        Testing.testone x !compare_with_expected
+
+    | []  when !test_all -> 
+        FC.include_path := "tests/include";
+        Testing.testall ()
+
+    | [] when !test_regression_okfailed -> 
+        Testing.test_regression_okfailed ()
+
+    | x::xs when !test_okfailed -> 
+        (* do its own timeout on FC.timeout internally *)
+        FC.relax_include_path := true;
+       adjust_stdin x (fun () -> 
+          Testing.test_okfailed !cocci_file (x::xs)
+        )
+
+    (* --------------------------------------------------------- *)
+    (* Actions, useful to debug subpart of coccinelle *)
+    (* --------------------------------------------------------- *)
+
+    | xs when List.mem !action (Common.action_list all_actions) ->
+        Common.do_action !action xs all_actions
+
+    | [file] when !action = "-parse_cocci" -> 
+        Testing.test_parse_cocci file
+
+     (* I think this is used by some scripts in some Makefile for our
+      * big-tests. So dont remove.
+      *)
+    | [file1;file2] when !action = "-compare_c" -> 
+       Test_parsing_c.test_compare_c file1 file2 (* result = unix code *)
+
+    (* could add the Test_parsing_c.test_actions such as -parse_c & co *)
+
+
+    (* --------------------------------------------------------- *)
+    (* This is the main entry *)
+    (* --------------------------------------------------------- *)
+    | x::xs -> 
+        
+       adjust_stdin x (fun () ->
+          if !cocci_file = ""
+          then failwith "I need a cocci file,  use -sp_file <file>";
+
+         if !dir && !Flag.patch = None
+         then
+           (match xs with
+           | [] -> Flag.patch := Some x
+           | _ ->
+               pr2
+                 ("warning: patch output can only be created when only one\n"^
+                  "directory is specified or when the -patch flag is used")
+            );
+
+          let infiles = 
+            Common.profile_code "Main.infiles computation" (fun () -> 
+             match !dir, !kbuild_info, !Flag.use_glimpse with
+              (* glimpse *)
+              | false, _, true -> 
+                  failwith "-use_glimpse works only with -dir"
+              | true, s, true when s <> "" -> 
+                  failwith "-use_glimpse does not work with -kbuild"
+              | true, "", true -> 
+                  if not (null xs)
+                  then failwith "-use_glimpse can accept only one dir";
+                  
+                  let files =
+                   match glimpse_filter (!cocci_file, !Config.std_iso) x with
+                     None ->
+                       Common.cmd_to_list (* same as "true, "", _" case *)
+                         (if !include_headers
+                         then ("find "^(join " " (x::xs))^" -name \"*.[ch]\"")
+                         else ("find "^(join " " (x::xs))^" -name \"*.c\""))
+                   | Some files -> files in
+                  files +> List.map (fun x -> [x])
+              (* normal *)
+             | false, _, _ -> [x::xs]
+             | true, "", _ -> 
+                 Common.cmd_to_list
+                   (if !include_headers
+                   then ("find "^(join " " (x::xs))^" -name \"*.[ch]\"")
+                   else ("find "^(join " " (x::xs))^" -name \"*.c\""))
+                 +> List.map (fun x -> [x])
+
+              (* kbuild *)
+             | true, kbuild_info_file,_ -> 
+                 let dirs = 
+                    Common.cmd_to_list ("find "^(join " " (x::xs))^" -type d") 
+                  in
+                 let info = Kbuild.parse_kbuild_info kbuild_info_file in
+                 let groups = Kbuild.files_in_dirs dirs info in
+                 
+                 groups +> List.map (function Kbuild.Group xs -> xs)
+           )
+          in
+
+         let infiles =
+           match (!distrib_index,!distrib_max) with
+             (None,None) -> infiles
+           | (Some index,Some max) ->
+               (if index >= max
+               then
+                 failwith "index starts at 0, and so must be less than max");
+               if !mod_distrib
+               then
+                 let rec loop ct = function
+                     [] -> []
+                   | x::xs ->
+                       if (ct mod max) = index
+                       then x::(loop (ct+1) xs)
+                       else loop (ct+1) xs in
+                 loop 0 infiles
+               else
+                 begin
+                   let all_files = List.length infiles in
+                   let regions = (all_files + (max - 1)) / max in
+                   let this_min = index * regions in
+                   let this_max = (index+1) * regions in
+                   let rec loop ct = function
+                       [] -> []
+                     | x::xs ->
+                         if this_min <= ct && ct < this_max
+                         then x::(loop (ct+1) xs)
+                         else loop (ct+1) xs in
+                   loop 0 infiles
+                 end
+           | _ -> failwith "inconsistent distribution information" in
+           
+          let outfiles = 
+            Common.profile_code "Main.outfiles computation" (fun () -> 
+             infiles +> List.map (fun cfiles -> 
+               pr2 ("HANDLING: " ^ (join " " cfiles));
+               Common.timeout_function_opt !FC.timeout (fun () -> 
+               Common.report_if_take_time 10 (join " " cfiles) (fun () -> 
+                    (* Unix.sleep 1; *)
+                  try 
+                    (* this is the main call *)
+                    Cocci.full_engine (!cocci_file, !Config.std_iso) cfiles
+                 with 
+                 | Common.UnixExit x -> raise (Common.UnixExit x)
+                 | e -> 
+                     if !dir
+                     then begin
+                       pr2 ("EXN:" ^ Printexc.to_string e); 
+                       [] (* *)
+                     end
+                     else raise e)))
+            ) +> List.concat 
+          in
+
+          Common.profile_code "Main.result analysis" (fun () -> 
+             
+           Ctlcocci_integration.print_bench();
+             
+            let outfiles = Cocci.check_duplicate_modif outfiles in
+              
+            outfiles +> List.iter (fun (infile, outopt) -> 
+             outopt +> Common.do_option (fun outfile -> 
+               if !inplace_modif
+               then begin
+                  Common.command2 ("cp "^infile^" "^infile^".cocci_orig");
+                  Common.command2 ("cp "^outfile^" "^infile);
+               end;
+
+               if !outplace_modif
+               then Common.command2 ("cp "^outfile^" "^infile^".cocci_res");
+                 
+               if !output_file = "" 
+               then begin
+                  let tmpfile = "/tmp/"^Common.basename infile in
+                  pr2 (spf "One file modified. Result is here: %s" tmpfile);
+                  Common.command2 ("cp "^outfile^" "^tmpfile);
+               end
+             ));
+            if !output_file <> "" then
+             (match outfiles with 
+             | [infile, Some outfile] when infile = x && null xs -> 
+                  Common.command2 ("cp " ^outfile^ " " ^ !output_file);
+             | [infile, None] when infile = x && null xs -> 
+                  Common.command2 ("cp " ^infile^ " " ^ !output_file);
+             | _ -> 
+                  failwith 
+                    ("-o can not be applied because there is multiple " ^
+                        "modified files");
+             );
+            
+            if !compare_with_expected
+            then Testing.compare_with_expected outfiles))
+          
+    (* --------------------------------------------------------- *)
+    (* empty entry *)
+    (* --------------------------------------------------------- *)
+    | [] -> short_usage()
+        
+  ));
+    if !Pycocci.initialised && (Pycocci.py_isinitialized ()) != 0 then begin
+      ignore(Pycocci.pyrun_simplestring "cocci.finalise()");
+      if !Flag.show_misc 
+      then Common.pr2 "Finalizing python\n";
+      Pycocci.py_finalize ();
+    end
+  end
+
+(*****************************************************************************)
+let _ =
+  Common.main_boilerplate (fun () -> 
+    main ();
+    Ctlcocci_integration.print_bench();
+  )
diff --git a/.#testing.ml.1.67 b/.#testing.ml.1.67
new file mode 100644 (file)
index 0000000..c1087eb
--- /dev/null
@@ -0,0 +1,414 @@
+(*
+* Copyright 2005-2009, 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
+
+(*****************************************************************************)
+(* Test framework *)
+(*****************************************************************************)
+
+(* There can be multiple .c for the same cocci file. The convention
+ * is to have one base.cocci and a base.c and some optional
+ * base_vernn.[c,res].
+ * 
+ * If want to test without iso, use -iso_file empty.iso option.
+ *)
+let testone x compare_with_expected_flag = 
+  let x    = if x =~ "\\(.*\\)_ver0$" then matched1 x else x in
+  let base = if x =~ "\\(.*\\)_ver[0-9]+$" then matched1 x else x in
+
+  let cfile      = "tests/" ^ x ^ ".c" in 
+  let cocci_file = "tests/" ^ base ^ ".cocci" in
+
+  let expected_res   = "tests/" ^ x ^ ".res" in
+  begin
+    let res = Cocci.full_engine (cocci_file, !Config.std_iso) [cfile] in
+    let generated = 
+      match Common.optionise (fun () -> List.assoc cfile res) with
+      | Some (Some outfile) -> 
+          if List.length res > 1 
+          then pr2 ("note that not just " ^ cfile ^ " was involved");
+
+          let tmpfile = "/tmp/"^Common.basename cfile in
+          pr2 (sprintf "One file modified. Result is here: %s" tmpfile);
+          Common.command2 ("mv "^outfile^" "^tmpfile);
+          tmpfile
+      | Some None -> 
+          pr2 "no modification on the input file";
+          cfile
+      | None -> raise Impossible
+    in
+    if compare_with_expected_flag
+    then 
+      Compare_c.compare_default generated expected_res 
+      +> Compare_c.compare_result_to_string 
+      +> pr2;
+  end
+          
+
+(* ------------------------------------------------------------------------ *)
+let testall () =
+
+  let newscore  = empty_score () in
+
+  let expected_result_files = 
+    Common.glob "tests/*.res" 
+    +> List.filter (fun f -> Common.filesize f > 0)
+    +> List.map Filename.basename
+    +> List.sort compare
+  in
+
+  begin
+    expected_result_files +> List.iter (fun res -> 
+      let x = if res =~ "\\(.*\\).res" then matched1 res else raise Impossible 
+      in
+      let base = if x =~ "\\(.*\\)_ver[0-9]+" then matched1 x else x in 
+      let cfile      = "tests/" ^ x ^ ".c" in
+      let cocci_file = "tests/" ^ base ^ ".cocci" in
+      let expected = "tests/" ^ res in
+
+      let timeout_testall = 30 in
+
+      try (
+        Common.timeout_function timeout_testall  (fun () -> 
+          
+          let xs = Cocci.full_engine (cocci_file, !Config.std_iso) [cfile] in
+          let generated = 
+            match List.assoc cfile xs with
+            | Some generated -> generated
+            | None -> cfile
+          in
+
+          let (correct, diffxs) = Compare_c.compare_default generated expected
+          in
+
+         pr2 res;
+          (* I don't use Compare_c.compare_result_to_string because
+           * I want to indent a little more the messages.
+           *)
+          (match correct with
+          | Compare_c.Correct -> Hashtbl.add newscore res Common.Ok;
+          | Compare_c.Pb s -> 
+              let s = Str.global_replace 
+                (Str.regexp "\"/tmp/cocci-output.*\"") "<COCCIOUTPUTFILE>" s
+              in
+              let s = 
+                "INCORRECT:" ^ s ^ "\n" ^ 
+                "    diff (result(<) vs expected_result(>)) = \n" ^
+                (diffxs +> List.map(fun s -> "    "^s^"\n") +> Common.join "")
+              in
+              Hashtbl.add newscore res (Common.Pb s)
+          | Compare_c.PbOnlyInNotParsedCorrectly s -> 
+              let s = 
+                "seems incorrect, but only because of code that " ^
+                "was not parsable" ^ s
+              in
+              Hashtbl.add newscore res (Common.Pb s)
+          )
+        )
+      )
+      with exn -> 
+        Common.reset_pr_indent();
+        let s = "PROBLEM\n" ^ ("   exn = " ^ Printexc.to_string exn ^ "\n") in
+        Hashtbl.add newscore res (Common.Pb s)
+    );
+
+
+    pr2 "--------------------------------";
+    pr2 "statistics";
+    pr2 "--------------------------------";
+
+    Common.hash_to_list newscore +> List.iter (fun (s, v) -> 
+      pr_no_nl (Printf.sprintf "%-30s: " s);
+      pr_no_nl (
+        match v with
+        | Common.Ok ->  "CORRECT\n" 
+        | Common.Pb s -> s
+      )
+    );
+    flush stdout; flush stderr;
+
+    pr2 "--------------------------------";
+    pr2 "regression testing  information";
+    pr2 "--------------------------------";
+    Common.regression_testing newscore 
+      (Filename.concat Config.path "tests/score_cocci_best.marshalled");
+
+
+    pr2 "--------------------------------";
+    pr2 "total score";
+    pr2 "--------------------------------";
+    let total = Common.hash_to_list newscore +> List.length in
+    let good  = Common.hash_to_list newscore +> List.filter 
+      (fun (s, v) -> v = Ok) +> List.length 
+    in
+    
+    pr2 (sprintf "good = %d/%d" good total);
+
+  end
+
+(* ------------------------------------------------------------------------ *)
+
+type okfailed = Ok | SpatchOK | Failed
+
+(* test_to_string *)
+let t_to_s = function
+  | Ok -> ".ok"
+  | SpatchOK -> ".spatch_ok"
+  | Failed -> ".failed"
+
+let delete_previous_result_files infile = 
+  [Ok;SpatchOK;Failed] +> List.iter (fun kind -> 
+    Common.command2 ("rm -f " ^ infile ^ t_to_s kind)
+  )
+
+(* quite similar to compare_with_expected  below *)
+let test_okfailed cocci_file cfiles = 
+  cfiles +> List.iter delete_previous_result_files;
+
+  (* final_files contain the name of an output file (a .ok or .failed
+   * or .spatch_ok), and also some additionnal strings to be printed in
+   * this output file in addition to the general error message of
+   * full_engine. *)
+  let final_files = ref [] in 
+
+
+  let newout = 
+    Common.new_temp_file "cocci" ".stdout" 
+  in
+
+  let t = Unix.gettimeofday () in
+  let time_per_file_str () = 
+    let t' = Unix.gettimeofday () in
+    let tdiff = t' -. t in
+    let tperfile = tdiff /. (float_of_int (List.length cfiles)) in
+    spf "time: %f" tperfile
+  in
+  
+  Common.redirect_stdout_stderr newout (fun () -> 
+    try (
+      Common.timeout_function_opt !Flag_cocci.timeout (fun () ->
+
+        
+        let outfiles = Cocci.full_engine (cocci_file, !Config.std_iso) cfiles
+        in
+
+        let time_str = time_per_file_str () in
+          
+        outfiles +> List.iter (fun (infile, outopt) -> 
+          let (dir, base, ext) = Common.dbe_of_filename infile in
+          let expected_suffix   = 
+            match ext with
+            | "c" -> "res"
+            | "h" -> "h.res"
+            | s -> pr2 ("WIERD: not a .c or .h :" ^ base ^ "." ^ s);
+                "" (* no extension, will compare to same file *)
+          in
+          let expected_res =  
+            Common.filename_of_dbe  (dir, base, expected_suffix) in
+          let expected_res2 = 
+            Common.filename_of_dbe (dir,"corrected_"^ base,expected_suffix) 
+          in
+         
+            (* can delete more than the first delete_previous_result_files
+               * because here we can have more files than in cfiles, for instance
+               * the header files
+            *)
+          delete_previous_result_files infile;
+          
+          match outopt, Common.lfile_exists expected_res with
+          | None, false -> 
+              ()
+          | Some outfile, false -> 
+              let s =("PB: input file " ^ infile ^ " modified but no .res") in
+              push2 (infile^t_to_s Failed, [s;time_str]) final_files
+               
+          | x, true -> 
+              let outfile = 
+                match x with 
+                | Some outfile -> outfile 
+                | None -> infile 
+              in
+              
+              let diff = Compare_c.compare_default outfile expected_res in
+              let s1 = (Compare_c.compare_result_to_string diff) in
+              if fst diff = Compare_c.Correct
+              then push2 (infile ^ (t_to_s Ok), [s1;time_str]) final_files
+              else 
+                if Common.lfile_exists expected_res2
+                then begin
+                  let diff = Compare_c.compare_default outfile expected_res2 in
+                  let s2 = Compare_c.compare_result_to_string diff in
+                  if fst diff = Compare_c.Correct
+                  then push2 (infile ^ (t_to_s SpatchOK),[s2;s1;time_str]) 
+                      final_files
+                  else push2 (infile ^ (t_to_s Failed), [s2;s1;time_str]) 
+                      final_files
+                end
+               else push2 (infile ^ (t_to_s Failed), [s1;time_str]) final_files
+                   )
+         );
+      )
+    with exn -> 
+      let clean s =
+       Str.global_replace (Str.regexp "\\\\n") "\n"
+         (Str.global_replace (Str.regexp ("\\\\\"")) "\""
+            (Str.global_replace (Str.regexp "\\\\t") "\t" s)) in
+      let s = "PROBLEM\n"^("   exn = " ^ clean(Printexc.to_string exn) ^ "\n")
+      in
+      let time_str = time_per_file_str () 
+      in
+      (* we may miss some file because cfiles is shorter than outfiles.
+        * For instance the detected local headers are not in cfiles, so
+        * may have less failed. But at least have some failed.
+      *)
+      cfiles +> List.iter (fun infile -> 
+        push2 (infile ^ (t_to_s Failed), [s;time_str]) final_files;
+       );
+      );
+  !final_files +> List.iter (fun (file, additional_strs) -> 
+    Common.command2 ("cp " ^ newout ^ " " ^ file);
+    with_open_outfile file (fun (pr, chan) -> 
+      additional_strs +> List.iter (fun s -> pr (s ^ "\n"))
+       );
+    
+    )
+
+
+let test_regression_okfailed () = 
+
+  (* it's  xxx.c.ok *)
+  let chop_ext f = f +> Filename.chop_extension in
+
+  let newscore  = Common.empty_score () in
+  let oks = 
+    Common.cmd_to_list ("find -name \"*.ok\"") 
+    ++
+    Common.cmd_to_list ("find -name \"*.spatch_ok\"")
+  in
+  let failed = Common.cmd_to_list ("find -name \"*.failed\"") in
+
+  if null (oks ++ failed) 
+  then failwith "no ok/failed file, you certainly did a make clean"
+  else begin
+    oks +> List.iter (fun s -> 
+      Hashtbl.add newscore (chop_ext s)  Common.Ok
+    );
+    failed +> List.iter (fun s -> 
+      Hashtbl.add newscore (chop_ext s) (Common.Pb "fail")
+    );
+    pr2 "--------------------------------";
+    pr2 "regression testing  information";
+    pr2 "--------------------------------";
+    Common.regression_testing newscore ("score_failed.marshalled")
+  end
+    
+
+(* ------------------------------------------------------------------------ *)
+(* quite similar to test_ok_failed. Maybe could factorize code *)
+let compare_with_expected outfiles =
+  pr2 "";
+  outfiles +> List.iter (fun (infile, outopt) -> 
+    let (dir, base, ext) = Common.dbe_of_filename infile in
+    let expected_suffix   = 
+      match ext with
+      | "c" -> "res"
+      | "h" -> "h.res"
+      | s -> failwith ("wierd C file, not a .c or .h :" ^ s)
+    in
+    let expected_res =  
+      Common.filename_of_dbe  (dir, base, expected_suffix) in
+    let expected_res2 = 
+      Common.filename_of_dbe (dir,"corrected_"^ base,expected_suffix) 
+    in
+    
+    match outopt, Common.lfile_exists expected_res with
+    | None, false -> ()
+    | Some outfile, false -> 
+        let s =("PB: input file " ^ infile ^ " modified but no .res") in
+        pr2 s
+    | x, true -> 
+        let outfile = 
+          match x with 
+          | Some outfile -> outfile 
+          | None -> infile 
+        in
+        let diff = Compare_c.compare_default outfile expected_res in
+        let s1 = (Compare_c.compare_result_to_string diff) in
+        if fst diff = Compare_c.Correct
+        then pr2_no_nl (infile ^ " " ^ s1)
+        else 
+          if Common.lfile_exists expected_res2
+          then begin
+            let diff = Compare_c.compare_default outfile expected_res2 in
+            let s2 = Compare_c.compare_result_to_string diff in
+            if fst diff = Compare_c.Correct
+            then pr2 (infile ^ " is spatchOK " ^ s2)
+            else pr2 (infile ^ " is failed " ^ s2)
+          end
+        else pr2 (infile ^ " is failed " ^ s1)
+  )
+
+(*****************************************************************************)
+(* Subsystem testing *)
+(*****************************************************************************)
+
+let test_parse_cocci file = 
+  if not (file =~ ".*\\.cocci") 
+  then pr2 "warning: seems not a .cocci file";
+
+  let (_,xs,_,_,_,_,grep_tokens,query) =
+    Parse_cocci.process file (Some !Config.std_iso) false in
+  xs +> List.iter Pretty_print_cocci.unparse;
+  Printf.printf "grep tokens\n";
+  List.iter (function x -> Printf.printf "%s\n" (String.concat " " x))
+    grep_tokens;
+  if !Flag.use_glimpse
+  then match query with None -> pr "No query" | Some x -> pr x
+
+
+
+
+
+
+
+
+(*****************************************************************************)
+(* to be called by ocaml toplevel, to test. *)
+(*****************************************************************************)
+
+(* no point to memoize this one *)
+let sp_of_file file iso    = Parse_cocci.process file iso false
+
+(* TODO: Remove
+*)
+
+(*
+let flows_of_ast astc = 
+  astc +> Common.map_filter (fun e -> ast_to_flow_with_error_messages e)
+
+let one_flow flows = 
+  List.hd flows
+
+let one_ctl ctls = List.hd (List.hd ctls)
+*)
+
diff --git a/.depend b/.depend
dissimilarity index 100%
index b3f20b0..9fe1035 100644 (file)
--- a/.depend
+++ b/.depend
@@ -1,6 +1,48 @@
-cocci.cmo: flag_cocci.cmo cocci.cmi 
-cocci.cmx: flag_cocci.cmx cocci.cmi 
-main.cmo: testing.cmi flag_cocci.cmo cocci.cmi 
-main.cmx: testing.cmx flag_cocci.cmx cocci.cmx 
-testing.cmo: flag_cocci.cmo cocci.cmi testing.cmi 
-testing.cmx: flag_cocci.cmx cocci.cmx testing.cmi 
+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_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 \
+    ctl/ctl_engine.cmi parsing_c/cpp_ast_c.cmi parsing_c/control_flow_c.cmi \
+    parsing_c/compare_c.cmi commons/common.cmi \
+    parsing_c/comment_annotater_c.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_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 \
+    ctl/ctl_engine.cmx parsing_c/cpp_ast_c.cmx parsing_c/control_flow_c.cmx \
+    parsing_c/compare_c.cmx commons/common.cmx \
+    parsing_c/comment_annotater_c.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_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_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 \
+    parsing_cocci/parse_cocci.cmi flag_cocci.cmo globals/flag.cmo \
+    globals/config.cmo parsing_c/compare_c.cmi commons/common.cmi cocci.cmi \
+    testing.cmi 
+testing.cmx: parsing_cocci/pretty_print_cocci.cmx \
+    parsing_cocci/parse_cocci.cmx flag_cocci.cmx globals/flag.cmx \
+    globals/config.cmx parsing_c/compare_c.cmx commons/common.cmx cocci.cmx \
+    testing.cmi 
index 1168f58..fd8a9c5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -85,17 +85,11 @@ OPTFLAGS=
 # but is now defined above in this file
 #OPTLIBFLAGS=-cclib dllpycaml_stubs.so
 
-# the OPTBIN variable is here to allow to use ocamlc.opt instead of
-# ocaml, when it is available, which speeds up compilation. So
-# if you want the fast version of the ocaml chain tools, set this var
-# or setenv it to ".opt" in your startup script.
-OPTBIN= #.opt
-
 OCAMLC=ocamlc$(OPTBIN) $(OCAMLCFLAGS)  $(INCLUDES)
 OCAMLOPT=ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
 OCAMLLEX=ocamllex #-ml # -ml for debugging lexer, but slightly slower
 OCAMLYACC=ocamlyacc -v
-OCAMLDEP=ocamldep #$(INCLUDES)
+OCAMLDEP=ocamldep $(INCLUDES)
 OCAMLMKTOP=ocamlmktop -g -custom $(INCLUDES)
 
 # can also be set via 'make static'
@@ -108,7 +102,7 @@ BYTECODE_STATIC=-custom
 # Top rules
 ##############################################################################
 .PHONY: all all.opt opt top clean configure
-.PHONY: $(MAKESUBDIRS) $(MAKESUBDIRS:%=%.opt)
+.PHONY: $(MAKESUBDIRS) $(MAKESUBDIRS:%=%.opt) subdirs subdirs.opt
 
 all:
        $(MAKE) subdirs
@@ -121,8 +115,11 @@ opt:
 all.opt: opt
 top: $(EXEC).top
 
-subdirs: $(MAKESUBDIRS)
-subdirs.opt: $(MAKESUBDIRS:%=%.opt)
+subdirs:
+       +for D in $(MAKESUBDIRS); do $(MAKE) $$D ; done
+
+subdirs.opt:
+       +for D in $(MAKESUBDIRS); do $(MAKE) $$D.opt ; done
 
 $(MAKESUBDIRS):
        $(MAKE) -C $@ OCAMLCFLAGS="$(OCAMLCFLAGS)" all
@@ -130,29 +127,29 @@ $(MAKESUBDIRS):
 $(MAKESUBDIRS:%=%.opt):
        $(MAKE) -C $(@:%.opt=%) OCAMLCFLAGS="$(OCAMLCFLAGS)" all.opt
 
-commons:
-globals:
-menhirlib:
-parsing_cocci:globals menhirlib
-parsing_c:parsing_cocci
-ctl:globals commons
-engine: parsing_cocci parsing_c ctl
-popl09:engine
-extra: parsing_cocci parsing_c ctl
-pycaml:
-python:pycaml parsing_cocci parsing_c
-
-commons.opt:
-globals.opt:
-menhirlib.opt:
-parsing_cocci.opt:globals.opt menhirlib.opt
-parsing_c.opt:parsing_cocci.opt
-ctl.opt:globals.opt commons.opt
-engine.opt: parsing_cocci.opt parsing_c.opt ctl.opt
-popl09.opt:engine.opt
-extra.opt: parsing_cocci.opt parsing_c.opt ctl.opt
-pycaml.opt:
-python.opt:pycaml.opt parsing_cocci.opt parsing_c.opt
+commons:
+globals:
+menhirlib:
+# parsing_cocci: commons globals menhirlib
+parsing_c:parsing_cocci
+ctl:globals commons
+engine: parsing_cocci parsing_c ctl
+popl09:engine
+extra: parsing_cocci parsing_c ctl
+pycaml:
+python:pycaml parsing_cocci parsing_c
+#
+commons.opt:
+globals.opt:
+menhirlib.opt:
+# parsing_cocci.opt: commons.opt globals.opt menhirlib.opt
+parsing_c.opt:parsing_cocci.opt
+ctl.opt:globals.opt commons.opt
+engine.opt: parsing_cocci.opt parsing_c.opt ctl.opt
+popl09.opt:engine.opt
+extra.opt: parsing_cocci.opt parsing_c.opt ctl.opt
+pycaml.opt:
+python.opt:pycaml.opt parsing_cocci.opt parsing_c.opt
 
 clean::
        set -e; for i in $(MAKESUBDIRS); do $(MAKE) -C $$i clean; done
@@ -160,8 +157,8 @@ clean::
 configure:
        ./configure
 
-$(LIBS): #$(MAKESUBDIRS)
-$(LIBS:.cma=.cmxa): #$(MAKESUBDIRS:%=%.opt)
+$(LIBS): $(MAKESUBDIRS)
+$(LIBS:.cma=.cmxa): $(MAKESUBDIRS:%=%.opt)
 
 $(OBJS):$(LIBS)
 $(OPTOBJS):$(LIBS:.cma=.cmxa)
@@ -205,12 +202,11 @@ purebytecode:
 ##############################################################################
 
 # don't remove DESTDIR, it can be set by package build system like ebuild
-install: all
+install-common:
        mkdir -p $(DESTDIR)$(BINDIR)
        mkdir -p $(DESTDIR)$(LIBDIR)
        mkdir -p $(DESTDIR)$(SHAREDIR)
        mkdir -p $(DESTDIR)$(MANDIR)/man1
-       cp spatch $(DESTDIR)$(BINDIR)
        cp standard.h $(DESTDIR)$(SHAREDIR)
        cp standard.iso $(DESTDIR)$(SHAREDIR)
        cp docs/spatch.1 $(DESTDIR)$(MANDIR)/man1/
@@ -221,6 +217,22 @@ install: all
        @echo "You can also install spatch by copying the program spatch"
        @echo "(available in this directory) anywhere you want and"
        @echo "give it the right options to find its configuration files."
+       @echo ""
+
+# user will use spatch to run spatch.opt (native)
+install: all.opt install-common
+       cp spatch.opt $(DESTDIR)$(SHAREDIR)
+       cat scripts/spatch.sh | sed "s|SHAREDIR|$(DESTDIR)$(SHAREDIR)|g" > $(DESTDIR)$(BINDIR)/spatch
+
+# user will use spatch to run spatch (bytecode)
+install-byte: all install-common
+       cp spatch $(DESTDIR)$(SHAREDIR)
+       cat scripts/spatch.sh | sed "s|\.opt||" | sed "s|SHAREDIR|$(DESTDIR)$(SHAREDIR)|g" > $(DESTDIR)$(BINDIR)/spatch
+
+# user will use spatch.opt to run spatch.opt (native)
+install-opt: all.opt install-common
+       cp spatch.opt $(DESTDIR)$(SHAREDIR)
+       cat scripts/spatch.sh | sed "s|SHAREDIR|$(DESTDIR)$(SHAREDIR)|g" > $(DESTDIR)$(BINDIR)/spatch.opt
 
 uninstall:
        rm -f $(DESTDIR)$(BINDIR)/spatch
@@ -357,6 +369,8 @@ website:
        cp $(TMP)/$(PACKAGE)-bin-x86.tgz        $(WEBSITE)
        cp $(TMP)/$(PACKAGE)-bin-x86-static.tgz $(WEBSITE)
        cp $(TMP)/$(PACKAGE)-bin-bytecode-$(OCAMLVERSION).tgz   $(WEBSITE)
+       rm -f $(WEBSITE)/LATEST* $(WEBSITE)/coccinelle-latest.tgz
+       cd $(WEBSITE); touch LATEST_IS_$(VERSION); ln -s $(PACKAGE).tgz coccinelle-latest.tgz
 
 
 #TXT=$(wildcard *.txt)
index c05b87e..dd601ee 100644 (file)
@@ -14,3 +14,9 @@ SHAREDIR=/usr/local/share/coccinelle
 
 # Features
 FEATURE_PYTHON=0
+
+# The OPTBIN variable is here to allow to use ocamlc.opt instead of
+# ocaml, when it is available, which speeds up compilation. So
+# if you want the fast version of the ocaml chain tools, set this var
+# or setenv it to ".opt" in your startup script.
+OPTBIN=.opt
index 9364c31..88141ff 100644 (file)
@@ -1,10 +1,40 @@
 -*- org -*-
 
-* 0.1.5
+* 0.1.6
 
 ** Features: 
+- grouping of generated rules with -hrule option
+- handling of special coccinelle comments 
+  /* {{coccinelle:skip_start}} */ and
+  /* {{coccinelle:skip_end}} */
+  allowing to give more hints to the C parser.
+  Thanks to Flavien@lebarbe.net for the idea.
+- the ability to add comments
+- the ability to print the values of more (but not all) kinds of
+  metavariables from python
+- new vim SmPL mode.
+  Thanks to Alexander Faroy.
+
+** Bugfix:
+- consider the ident tokens also in the 2 lines before the error line for the 
+  10-most-problematic-parsing-errors diagnostic.
+- SmPL parser allows cast as the argument of a pointer
+- SmPL type checker allows enum as an array index
+- Better generation of fresh metavariables names in hrule
+- no more warnings about things that should be metavariables when there is
+  a disjunction in a function position
+- bugfix in parser, better error message.
+  Thanks to Ali-Erdem OZCAN <ali-erdem.ozcan@st.com> for the bug report.
+
+** Internals: 
+
+* 0.1.5
+
+** Language: 
 - added initialiser metavariable
 - added sequences of designators in structures
+
+** Features: 
 - improved printing of the C code corresponding to metavariables
 - improved printing when code (eg declarations) is removed at the beginning
   of a block, and then is followed by a blank line
 
 * 0.1.4
 
+** Language: 
+- long long added to SmPL
+
 ** Features: 
 - can match patterns of the form unsigned T or signed T, where T is a
   metavariable
 - dropped the sizeof_parens isomorphism, which was made redundant by the
   paren isomorphism
 - simple rule generation
-- long long added to SmPL
 
 ** Bugfix:
 - trailing , ; and ) no longer left on a line by themselves
 
 * 0.1.1
 
-** Langage: 
+** Language: 
  - support for initializer at toplevel, cf -test substruct
 
 * 0.1
 
 ** first public release of the source code:
 
-** Features
+** Language: 
  - embeded python scripting
  - position
 
+** Features
+
 * beta 
 
 ** first public release of the binary
index 1c1c45a..32bb774 100644 (file)
--- a/cocci.ml
+++ b/cocci.ml
@@ -489,7 +489,7 @@ let (includes_to_parse:
                   Some (Filename.concat !Flag_cocci.include_path 
                           (Common.join "/" xs))
                else None
-            | Ast_c.Wierd _ -> None
+            | Ast_c.Weird _ -> None
                  )
          | _ -> None))
        +> List.concat
@@ -591,7 +591,7 @@ let rec update_include_rel_pos cs =
                      i_rel_pos = aref;
                      i_is_in_ifdef = inifdef}) ->
         (match x with
-        | Ast_c.Wierd _ -> None
+        | Ast_c.Weird _ -> None
         | _ -> 
             if inifdef 
             then None
@@ -605,7 +605,7 @@ let rec update_include_rel_pos cs =
       match c with
       | Ast_c.Local x -> Left (x, aref)
       | Ast_c.NonLocal x -> Right (x, aref)
-      | Ast_c.Wierd x -> raise Impossible
+      | Ast_c.Weird x -> raise Impossible
     ) in
 
   update_rel_pos_bis locals;
@@ -785,11 +785,21 @@ let prepare_cocci ctls free_var_lists negated_pos_lists
 (* --------------------------------------------------------------------- *)
 
 let build_info_program cprogram env = 
-  let (cs, parseinfos) = Common.unzip cprogram in
-  let (cs, envs) =
-    Common.unzip (TAC.annotate_program env (*!g_contain_typedmetavar*) cs) in
+  
+  let (cs, parseinfos) = 
+    Common.unzip cprogram in
+
+  let alltoks = 
+    parseinfos +> List.map (fun (s,toks) -> toks) +> List.flatten in
 
-  zip (zip cs parseinfos) envs +> List.map (fun ((c, parseinfo), (enva,envb))->
+  (* I use cs' but really annotate_xxx work by doing side effects on cs *)
+  let cs' = 
+    Comment_annotater_c.annotate_program alltoks cs in
+  let cs_with_envs = 
+    Type_annoter_c.annotate_program env (*!g_contain_typedmetavar*) cs'
+  in
+  
+  zip cs_with_envs parseinfos +> List.map (fun ((c, (enva,envb)), parseinfo)->
     let (fullstr, tokens) = parseinfo in
 
     let flow = 
dissimilarity index 93%
index c7d1f4f..6f7c7cc 100644 (file)
--- a/commitmsg
+++ b/commitmsg
@@ -1,17 +1,27 @@
-Release coccinelle-0.1.5
-
-** Language:
-   - added initialiser metavariable
-   - added sequences of designators in structures
-
-** Features:
-   - improved printing of the C code corresponding to metavariables
-   - improved printing when code (eg declarations) is removed at the beginning
-     of a block, and then is followed by a blank line
-   - slightly less verbose error reporting in parsing_hacks
-
-** Bugfix:
-   - fixed some problems with parsing SmPL code where a nest appears after a |
-   - better treatment of { }, form in macros wrt unparse_c
-   - less quiet for -parse_c
-   - improve parsing heuristics regarding macro statement
+Release coccinelle-0.1.6
+
+** Language:
+   - the ability to add comments
+
+** Features:
+   - grouping of generated rules with -hrule option
+   - handling of special coccinelle comments
+     /* {{coccinelle:skip_start}} */ and
+     /* {{coccinelle:skip_end}} */
+     allowing to give more hints to the C parser.
+     Thanks to Flavien@lebarbe.net for the idea.
+   - the ability to print the values of more (but not all) kinds of
+     metavariables from python
+   - new vim SmPL mode.
+     Thanks to Alexander Faroy.
+
+** Bugfix:
+   - consider the ident tokens also in the 2 lines before the error line for the
+     10-most-problematic-parsing-errors diagnostic.
+   - SmPL parser allows cast as the argument of a pointer
+   - SmPL type checker allows enum as an array index
+   - Better generation of fresh metavariables names in hrule
+   - no more warnings about things that should be metavariables when there is
+     a disjunction in a function position
+   - bugfix in parser, better error message.
+     Thanks to Ali-Erdem OZCAN <ali-erdem.ozcan@st.com> for the bug report.
index 7abe8f8..5fbb959 100644 (file)
@@ -72,6 +72,12 @@ ocollection/oassoc_buffer.cmo: ocamlextra/setb.cmi ocollection/osetb.cmo \
 ocollection/oassoc_buffer.cmx: ocamlextra/setb.cmx ocollection/osetb.cmx \
     ocollection/oassocb.cmx oassoc.cmx common.cmx \
     ocollection/oassoc_buffer.cmi 
+ocollection/oassoc_cache.cmo: ocamlextra/setb.cmi ocollection/osetb.cmo \
+    ocollection/oassocb.cmo oassoc.cmi common.cmi \
+    ocollection/oassoc_cache.cmi 
+ocollection/oassoc_cache.cmx: ocamlextra/setb.cmx ocollection/osetb.cmx \
+    ocollection/oassocb.cmx oassoc.cmx common.cmx \
+    ocollection/oassoc_cache.cmi 
 ocollection/oassocb.cmo: oassoc.cmi ocamlextra/mapb.cmo common.cmi 
 ocollection/oassocb.cmx: oassoc.cmx ocamlextra/mapb.cmx common.cmx 
 ocollection/oassocbdb.cmo: ocollection/oassoc_buffer.cmi oassoc.cmi \
@@ -101,6 +107,7 @@ ocollection/oseti.cmx: seti.cmx oset.cmx ocollection.cmx
 ocollection/osetpt.cmo: ocamlextra/setPt.cmo oset.cmi ocollection.cmi 
 ocollection/osetpt.cmx: ocamlextra/setPt.cmx oset.cmx ocollection.cmx 
 ocollection/oassoc_buffer.cmi: ocollection.cmi oassoc.cmi 
+ocollection/oassoc_cache.cmi: ocollection.cmi oassoc.cmi 
 ocollection/oassocbdb.cmi: ocollection.cmi ocollection/oassoc_buffer.cmi \
     oassoc.cmi 
 ocollection/oassocbdb_string.cmi: ocollection.cmi \
index e30d1af..baba40d 100644 (file)
@@ -1,6 +1,8 @@
 ##############################################################################
 # Variables
 ##############################################################################
+-include ../Makefile.config
+
 TARGET=commons
 
 # note: if you add a file (a .mli or .ml), dont forget to redo a 'make depend'
@@ -10,7 +12,7 @@ MYSRC=common.ml common_extra.ml \
       seti.ml \
       oset.ml oassoc.ml osequence.ml ograph.ml \
       ocollection/oseti.ml ocollection/oseth.ml ocollection/osetb.ml ocollection/osetpt.ml \
-      ocollection/oassocb.ml ocollection/oassoch.ml ocollection/oassoc_buffer.ml ocollection/oassocid.ml \
+      ocollection/oassocb.ml ocollection/oassoch.ml ocollection/oassoc_buffer.ml ocollection/oassoc_cache.ml ocollection/oassocid.ml \
       oarray.ml \
       ocollection/ograph2way.ml ograph_extended.ml \
       ofullcommon.ml \
@@ -89,12 +91,6 @@ INCLUDES=$(INCLUDEDIRS:%=-I %) $(INCLUDESEXTRA)
 OPTFLAGS= 
 #-thread
 
-# The OPTBIN variable is here to allow to use ocamlc.opt instead of 
-# ocaml, when it is available, which speeds up compilation. So
-# if you want the fast version of the ocaml chain tools, set this var 
-# or setenv it to ".opt" in your startup script.
-OPTBIN= #.opt
-
 OCAMLCFLAGS ?= -g -dtypes
 
 # The OCaml tools.
index 36d29b1..d080f35 100644 (file)
@@ -51,6 +51,7 @@
  *   - List.fold*, List.concat, ... 
  *   - Str.global_replace
  *   - Filename.is_relative
+ *   - String.uppercase, String.lowercase
  * 
  * 
  * The Format library allows to hide passing an indent_level variable.
@@ -580,6 +581,9 @@ let profile_end category = failwith "todo"
 
 (* subtil: don't forget to give all argumens to f, otherwise partial app
  * and will profile nothing.
+ * 
+ * todo: try also detect when complexity augment each time, so can
+ * detect the situation for a function gets worse and worse ? 
  *)  
 let profile_code category f = 
   if not (check_profile category)
@@ -937,6 +941,18 @@ let write_back func filename =
 let read_value f = get_value f
 
 
+let marshal__to_string2 v flags = 
+  Marshal.to_string v flags
+let marshal__to_string a b = 
+  profile_code "Marshalling" (fun () -> marshal__to_string2 a b)
+
+let marshal__from_string2 v flags = 
+  Marshal.from_string v flags
+let marshal__from_string a b = 
+  profile_code "Marshalling" (fun () -> marshal__from_string2 a b)
+
+
+
 (*****************************************************************************)
 (* Counter *)
 (*****************************************************************************)
@@ -1053,6 +1069,17 @@ let format_to_string f =
 
 
 
+let mk_str_func_of_assoc_conv xs = 
+  let swap (x,y) = (y,x) in
+
+  (fun s -> 
+    let xs' = List.map swap xs in
+    List.assoc s xs'
+  ),
+  (fun a -> 
+    List.assoc a xs
+  )
+
 (*****************************************************************************)
 (* Macro *)
 (*****************************************************************************)
@@ -1286,7 +1313,7 @@ exception Impossible
 exception Here
 exception ReturnExn
 
-exception MultiFound
+exception Multi_found (* to be consistent with Not_found *)
 
 exception WrongFormat of string
 
@@ -1989,6 +2016,20 @@ let map_find f xs =
 *)
 
 
+let list_to_single_or_exn xs =
+  match xs with
+  | [] -> raise Not_found
+  | x::y::zs -> raise Multi_found
+  | [x] -> x
+
+(*****************************************************************************)
+(* TriBool *)
+(*****************************************************************************)
+
+type bool3 = True3 | False3 | TrueFalsePb3 of string
+
+
+
 (*****************************************************************************)
 (* Regexp, can also use PCRE *)
 (*****************************************************************************)
@@ -2823,6 +2864,9 @@ let unixtime_to_dmy tm =
 let unixtime_to_floattime tm = 
   Unix.mktime tm +> fst
 
+let floattime_to_unixtime sec = 
+  Unix.localtime sec
+
 
 let sec_to_days sec = 
   let minfactor = 60 in
@@ -3050,6 +3094,12 @@ let command2_y_or_no cmd =
     | _ -> failwith "answer by yes or no"
   end
 
+let command2_y_or_no_exit_if_no cmd = 
+  let res = command2_y_or_no cmd in
+  if res
+  then ()
+  else raise (UnixExit (1))
+
   
 
 
@@ -3493,6 +3543,17 @@ let rec groupBy eq l =
       let (xs1,xs2) = List.partition (fun x' -> eq x x') xs in
       (x::xs1)::(groupBy eq xs2)
 
+let rec group_by_mapped_key fkey l =
+  match l with
+  | [] -> []
+  | x::xs -> 
+      let k = fkey x in 
+      let (xs1,xs2) = List.partition (fun x' -> let k2 = fkey x' in k=k2) xs in
+      (k, (x::xs1))::(group_by_mapped_key fkey xs2)
+
+
+
+
 let (exclude_but_keep_attached: ('a -> bool) -> 'a list -> ('a * 'a list) list)=
  fun f xs -> 
    let rec aux_filter acc = function
@@ -4045,6 +4106,12 @@ let sort_by_key_lowfirst xs =
 let _ = example (sort_by_key_lowfirst [4, (); 7,()] = [4,(); 7,()])
 let _ = example (sort_by_key_highfirst [4,(); 7,()] = [7,(); 4,()])
 
+
+let sortgen_by_key_highfirst xs = 
+  sort_prof (fun (k1,v1) (k2,v2) -> compare k2 k1) xs
+let sortgen_by_key_lowfirst xs = 
+  sort_prof (fun (k1,v1) (k2,v2) -> compare k1 k2) xs
+
 (*----------------------------------*)
 
 (* sur surEnsemble [p1;p2] [[p1;p2;p3] [p1;p2] ....] -> [[p1;p2;p3] ...      *)
@@ -4725,7 +4792,7 @@ let find_treeref f tree =
   match !res with
   | [n,xs] -> NodeRef (n, xs)
   | [] -> raise Not_found
-  | x::y::zs -> raise MultiFound
+  | x::y::zs -> raise Multi_found
 
 
 let find_treeref_with_parents_some f tree = 
@@ -4739,7 +4806,7 @@ let find_treeref_with_parents_some f tree =
   match !res with
   | [v] -> v
   | [] -> raise Not_found
-  | x::y::zs -> raise MultiFound
+  | x::y::zs -> raise Multi_found
 
 let find_multi_treeref_with_parents_some f tree = 
   let res = ref [] in
index 21a05da..d6d9b63 100644 (file)
@@ -280,12 +280,16 @@ val laws2 :
 (* Persistence *)
 (*****************************************************************************)
 
-(* just wrappers around Marshall *)
+(* just wrappers around Marshal *)
 val get_value : filename -> 'a
 val read_value : filename -> 'a (* alias *)
 val write_value : 'a -> filename -> unit
 val write_back : ('a -> 'b) -> filename -> unit
 
+(* wrappers that also use profile_code *)
+val marshal__to_string:   'a -> Marshal.extern_flags list -> string
+val marshal__from_string:   string -> int -> 'a
+
 (*****************************************************************************)
 (* Counter *)
 (*****************************************************************************)
@@ -330,6 +334,10 @@ val format_to_string : (unit -> unit) (* printer *) -> string
 val adjust_pp_with_indent : (unit -> unit) -> unit
 val adjust_pp_with_indent_and_header : string -> (unit -> unit) -> unit
 
+
+val mk_str_func_of_assoc_conv: 
+  ('a * string) list -> (string -> 'a) * ('a -> string)
+
 (*****************************************************************************)
 (* Macro *)
 (*****************************************************************************)
@@ -441,7 +449,7 @@ exception Impossible
 exception Here
 exception ReturnExn
 
-exception MultiFound
+exception Multi_found
 
 exception WrongFormat of string
 
@@ -578,6 +586,7 @@ val ( ==> ) : bool -> bool -> bool
 val xor : 'a -> 'a -> bool
 
 
+
 (*****************************************************************************)
 (* Char *)
 (*****************************************************************************)
@@ -760,6 +769,14 @@ val filter_some : 'a option list -> 'a list
 val map_filter : ('a -> 'b option) -> 'a list -> 'b list
 val find_some : ('a -> 'b option) -> 'a list -> 'b
 
+val list_to_single_or_exn: 'a list -> 'a
+
+(*****************************************************************************)
+(* TriBool *)
+(*****************************************************************************)
+type bool3 = True3 | False3 | TrueFalsePb3 of string
+
+
 (*****************************************************************************)
 (* Strings *)
 (*****************************************************************************)
@@ -951,6 +968,7 @@ val floattime_of_string: string -> float_time
 val dmy_to_unixtime: date_dmy -> float_time * Unix.tm
 val unixtime_to_dmy: Unix.tm -> date_dmy
 val unixtime_to_floattime: Unix.tm -> float_time
+val floattime_to_unixtime: float_time -> Unix.tm
 
 val sec_to_days : int -> string
 val sec_to_hours : int -> string
@@ -1024,6 +1042,7 @@ val cmd_to_list_and_status : string -> string list * Unix.process_status
 val command2 : string -> unit
 val _batch_mode: bool ref
 val command2_y_or_no : string -> bool
+val command2_y_or_no_exit_if_no : string -> unit
 
 val do_in_fork : (unit -> unit) -> int
 
@@ -1157,6 +1176,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
+val group_by_mapped_key: ('a -> 'b) -> 'a list -> ('b * 'a list) list
 
 (* Use hash internally to not be in O(n2). If you want to use it on a
  * simple list, then first do a List.map to generate a key, for instance the
@@ -1463,6 +1483,9 @@ val sort_by_val_highfirst: ('a,'b) assoc -> ('a * 'b) list
 val sort_by_key_lowfirst: (int,'b) assoc -> (int * 'b) list
 val sort_by_key_highfirst: (int,'b) assoc -> (int * 'b) list
 
+val sortgen_by_key_lowfirst: ('a,'b) assoc -> ('a * 'b) list
+val sortgen_by_key_highfirst: ('a,'b) assoc -> ('a * 'b) list
+
 (*****************************************************************************)
 (* Assoc, specialized. *)
 (*****************************************************************************)
index 345f051..85f430c 100644 (file)
@@ -5,13 +5,7 @@ open Oassoc
 open Oassocb
 open Osetb
 
-(* todo: limit number of entries, and erase all (then better do a ltu) 
- * todo: another cache that behave as in lfs1, 
- * every 100 operation do a flush 
- * 
- * todo: choose between oassocb and oassoch ? 
- * 
- * Also take care that must often redefine all function in the original
+(* Take care that must often redefine all function in the original
  * oassoc.ml because if some methods are not redefined, for instance 
  * #clear, then if do wrapper over a oassocdbm, then even if oassocdbm
  * redefine #clear, it will not be called, but instead the default
@@ -19,7 +13,7 @@ open Osetb
  * So better delegate all the methods and override even the method
  * with a default definition.
  * 
- * In the same way sometimes an exn can occur at wierd time. When
+ * In the same way sometimes an exn can occur at weird time. When
  * we add an element, sometimes this may raise an exn such as Out_of_memory,
  * but as we dont add directly but only at flush time, the exn
  * may happen far later the user added something in this oassoc.
@@ -28,6 +22,8 @@ open Osetb
  * and so the next flush will still generate an exn that again
  * may not be cached. So for the moment if Out_of_memory then
  * do something special and erase the entry in the cache.
+ * 
+ * Cf also oassoc_cache.ml which can be even more efficient.
  *)
 
 (* !!take care!!: this class has side effect, not a pure oassoc *)
@@ -136,31 +132,3 @@ object(o)
 end     
 
 
-(*
-class ['a,'b] oassoc_cache cache cached max =  
-  object(o) 
-    inherit ['a,'b] oassoc 
-    val full = ref 0 
-    val max = max 
-    val cache = cache 
-    val cached = cached 
-    val lru = TODO 
-       
-    val data = Hashtbl.create 100 
-    method empty = raise Todo 
-    method add (k,v) = (Hashtbl.add data k v; o) 
-    method iter f = cached#iter f 
-    method view = raise Todo 
-    method del (k,v) = (cache#del (k,v); cached#del (k,v); o) 
-    method mem e = raise Todo 
-    method null = raise Todo 
-    method assoc k = Hashtbl.find data k 
-    method delkey k = (cache#delkey (k,v); cached#del (k,v); o) 
-end    
-*)
-
-
diff --git a/commons/ocollection/oassoc_cache.ml b/commons/ocollection/oassoc_cache.ml
new file mode 100644 (file)
index 0000000..e62936f
--- /dev/null
@@ -0,0 +1,171 @@
+open Common
+
+open Oassoc
+
+open Oassocb
+open Osetb
+
+(* todo: gather stat of use per key, so when flush, try keep
+ * entries that are used above a certain threshold, and if after
+ * this step, there is still too much, then erase also those keys.
+ * 
+ * todo: limit number of entries, and erase all (then better do a ltu) 
+ * 
+ * todo: another cache that behave as in lfs1, 
+ * every 100 operation do a flush 
+ * 
+ * todo: choose between oassocb and oassoch ? 
+ * 
+ * Also take care that must often redefine all function in the original
+ * oassoc.ml because if some methods are not redefined, for instance 
+ * #clear, then if do wrapper over a oassocdbm, then even if oassocdbm
+ * redefine #clear, it will not be called, but instead the default
+ * method will be called that internally will call another method.
+ * So better delegate all the methods and override even the method
+ * with a default definition.
+ * 
+ * In the same way sometimes an exn can occur at weird time. When
+ * we add an element, sometimes this may raise an exn such as Out_of_memory,
+ * but as we dont add directly but only at flush time, the exn
+ * may happen far later the user added something in this oassoc.
+ * Also in the case of Out_of_memory, even if the entry is not 
+ * added in the wrapped, it will still be present in the cache
+ * and so the next flush will still generate an exn that again
+ * may not be cached. So for the moment if Out_of_memory then
+ * do something special and erase the entry in the cache.
+ *)
+
+(* !!take care!!: this class has side effect, not a pure oassoc *)
+(* can not make it pure, cos the assoc have side effect on the cache *)
+class ['a,'b] oassoc_buffer   max cached = 
+object(o)
+  inherit ['a,'b] oassoc
+
+  val counter = ref 0
+  val cache = ref (new oassocb []) 
+  val dirty = ref (new osetb Setb.empty)
+  val wrapped = ref cached
+
+  method private myflush = 
+
+    let has_a_raised = ref false in 
+
+    !dirty#iter (fun k -> 
+      try 
+        wrapped := !wrapped#add (k, !cache#assoc k)
+      with Out_of_memory -> 
+        pr2 "PBBBBBB: Out_of_memory in oassoc_buffer, but still empty cache";
+        has_a_raised := true;
+    );
+    dirty := (new osetb Setb.empty);
+    cache := (new oassocb []);
+    counter := 0;
+    if !has_a_raised then raise Out_of_memory
+
+      
+  method misc_op_hook2 = o#myflush
+        
+  method empty = 
+    raise Todo
+      
+  (* what happens in k is already present ? or if add multiple times
+   * the same k ? cache is a oassocb and so the previous binding is
+   * still there, but dirty is a set, and in myflush we iter based 
+   * on dirty so we will flush only the last 'k' in the cache.
+   *)
+  method add (k,v) = 
+    cache := !cache#add (k,v);
+    dirty := !dirty#add k;
+    incr counter;
+    if !counter > max then o#myflush;
+    o
+
+  method iter f = 
+    o#myflush; (* bugfix: have to flush !!! *)
+    !wrapped#iter f
+
+
+  method keys = 
+    o#myflush; (* bugfix: have to flush !!! *)
+    !wrapped#keys
+
+  method clear = 
+    o#myflush; (* bugfix: have to flush !!! *)
+    !wrapped#clear
+
+
+  method length = 
+    o#myflush;
+    !wrapped#length
+
+  method view = 
+    raise Todo
+
+  method del (k,v) = 
+    cache := !cache#del (k,v); 
+    (* TODO as for delkey, do a try over wrapped *)
+    wrapped := !wrapped#del (k,v); 
+    dirty := !dirty#del k;
+    o
+  method mem e = raise Todo
+  method null = raise Todo
+
+  method assoc k = 
+    try !cache#assoc k 
+    with Not_found -> 
+      (* may launch Not_found, but this time, dont catch it *)
+      let v = !wrapped#assoc k in 
+      begin
+        cache := !cache#add (k,v);
+        (* otherwise can use too much mem *)
+        incr counter;
+        if !counter > max then o#myflush;
+        v
+      end
+          
+  method delkey k = 
+    cache := !cache#delkey k; 
+    (* sometimes have not yet flushed, so may not be yet in, (could
+     * also flush in place of doing try).
+     * 
+     * TODO would be better to see if was in cache (in case mean that
+     * perhaps not flushed and do try and in other case just cos del
+     * (without try) cos forcement flushed ou was an error *)
+    begin 
+      try wrapped := !wrapped#delkey k 
+      with Not_found -> ()
+    end;
+    dirty := !dirty#del k;
+    o
+
+end     
+
+
+(*
+class ['a,'b] oassoc_cache cache cached max =  
+  object(o) 
+    inherit ['a,'b] oassoc 
+    val full = ref 0 
+    val max = max 
+    val cache = cache 
+    val cached = cached 
+    val lru = TODO 
+       
+    val data = Hashtbl.create 100 
+    method empty = raise Todo 
+    method add (k,v) = (Hashtbl.add data k v; o) 
+    method iter f = cached#iter f 
+    method view = raise Todo 
+    method del (k,v) = (cache#del (k,v); cached#del (k,v); o) 
+    method mem e = raise Todo 
+    method null = raise Todo 
+    method assoc k = Hashtbl.find data k 
+    method delkey k = (cache#delkey (k,v); cached#del (k,v); o) 
+end    
+*)
+
+
diff --git a/commons/ocollection/oassoc_cache.mli b/commons/ocollection/oassoc_cache.mli
new file mode 100644 (file)
index 0000000..9cff0d7
--- /dev/null
@@ -0,0 +1,34 @@
+(* !!take care!!: this classe have side effect, not a pure oassoc *)
+class ['a, 'b] oassoc_buffer :
+  int ->
+  (< add : 'a * 'b -> 'd; assoc : 'a -> 'b; del : 'a * 'b -> 'd;
+   delkey : 'a -> 'd; iter : ('a * 'b -> unit) -> unit; length : int; 
+   keys: 'a list; clear: unit;
+   .. >
+     as 'd) ->
+object ('o)
+  inherit ['a,'b] Oassoc.oassoc
+
+  (* ocollection concrete instantiation of virtual methods *)
+  method empty : 'o
+  method add : 'a * 'b -> 'o
+
+  method iter : ('a * 'b -> unit) -> unit
+  method view : ('a * 'b, 'o) Ocollection.view
+
+  method del : 'a * 'b -> 'o
+  method mem : 'a * 'b -> bool
+  method null : bool
+
+  (* oassoc concrete instantiation of virtual methods *)
+  method assoc : 'a -> 'b
+  method delkey : 'a -> 'o
+
+  method keys: 'a list
+
+  (* ugly, from objet class, extension trick *)
+  method private myflush : unit
+  method misc_op_hook2 : unit
+
+
+end
index 6d09410..a395131 100644 (file)
@@ -10,6 +10,10 @@ open Oassoc
  * the dbm, before marshalling. Cf oassocdbm.mli for more about this.
  * 
  * Quite similar to oassocdbm.ml. New: Take transact argument.
+ * 
+ * How to optimize when using this oassoc is slow ?
+ *   - use oassoc_buffer as a front-end of this oassoc
+ *   - reduce the size of the key or value
  *)
 class ['a,'b] oassoc_btree db namedb transact (*fkey unkey*) fv unv = 
 let namedb = if namedb = "" then "" else "(" ^ namedb ^ ")" in
@@ -29,10 +33,10 @@ object(o)
        (Marshal.to_string k []) [] 
        with Not_found -> ());
     *)
-    let k' = Marshal.to_string k [] in
+    let k' = Common.marshal__to_string k [] in
     let v' = 
       try
-        Marshal.to_string (fv v) [(*Marshal.Closures*)] 
+        Common.marshal__to_string (fv v) [(*Marshal.Closures*)] 
       with Out_of_memory -> 
         pr2 ("PBBBBBBB Out_of_memory in: " ^ namedb);
         raise Out_of_memory
@@ -55,8 +59,8 @@ object(o)
        (try 
            let a = Cursor.dbc_get dbc [Cursor.DB_NEXT] in
             (* minsky ? Cursor.get dbc Cursor.NEXT [] *)
-           let key  = (* unkey *) Marshal.from_string (fst a) 0 in 
-           let valu = unv (Marshal.from_string (snd a) 0) in
+           let key  = (* unkey *) Common.marshal__from_string (fst a) 0 in 
+           let valu = unv (Common.marshal__from_string (snd a) 0) in
            f (key, valu);
             true
         with Failure "ending" -> false
@@ -106,10 +110,10 @@ object(o)
 
   method private assoc2 k = 
     try 
-      let k' = Marshal.to_string k [] in
+      let k' = Common.marshal__to_string k [] in
       let vget = Db.get data (transact()) k' [] in
       (* minsky ? Db.get data ~txn:(transact() *)
-      unv (Marshal.from_string vget  0)
+      unv (Common.marshal__from_string vget  0)
     with Not_found -> 
       log3 ("pb assoc with k = " ^ (Dumper.dump k)); 
       raise Not_found
@@ -117,7 +121,7 @@ object(o)
     Common.profile_code ("Btree.assoc" ^ namedb) (fun () -> o#assoc2 x)
 
   method private delkey2 k = 
-    let k' = Marshal.to_string k [] in
+    let k' = Common.marshal__to_string k [] in
     Db.del data (transact()) k'  []; 
     o
   method delkey x = 
@@ -132,9 +136,9 @@ object(o)
        (try 
            let a = Cursor.dbc_get dbc [Cursor.DB_NEXT] in
             (* minsky ? Cursor.get dbc Cursor.NEXT [] *)
-           let key  = (* unkey *) Marshal.from_string (fst a) 0 in 
+           let key  = (* unkey *) Common.marshal__from_string (fst a) 0 in 
            (* 
-               let valu = unv (Marshal.from_string (snd a) 0) in
+               let valu = unv (Common.marshal__from_string (snd a) 0) in
               f (key, valu);
             *)
             Common.push2 key res;
index 8682abf..e5bcf5b 100644 (file)
@@ -21,7 +21,7 @@ object(o)
   method private addbis (k,v) = 
     let k' = k in
     let v' = 
-      try Marshal.to_string v [] 
+      try Common.marshal__to_string v [] 
       with Out_of_memory -> 
         pr2 ("PBBBBBBB Out_of_memory in: " ^ namedb);
         raise Out_of_memory
@@ -44,7 +44,7 @@ object(o)
            let a = Cursor.dbc_get dbc [Cursor.DB_NEXT] in
             (* minsky ? Cursor.get dbc Cursor.NEXT [] *)
            let key  = (fst a) in 
-           let valu = (Marshal.from_string (snd a) 0) in
+           let valu = (Common.marshal__from_string (snd a) 0) in
            f (key, valu);
             true
         with Failure "ending" -> false
@@ -97,7 +97,7 @@ object(o)
       let k' = k in
       let vget = Db.get data (transact()) k' [] in
       (* minsky ? Db.get data ~txn:(transact() *)
-      (Marshal.from_string vget  0)
+      (Common.marshal__from_string vget  0)
     with Not_found -> 
       log3 ("pb assoc with k = " ^ (k)); 
       raise Not_found
@@ -122,7 +122,7 @@ object(o)
             (* minsky ? Cursor.get dbc Cursor.NEXT [] *)
            let key  = (fst a) in 
            (* 
-               let valu = unv (Marshal.from_string (snd a) 0) in
+               let valu = unv (Common.marshal__from_string (snd a) 0) in
               f (key, valu);
             *)
             Common.push2 key res;
index ff6531e..9a24d1f 100644 (file)
@@ -30,8 +30,8 @@ object(o)
        (Marshal.to_string k []) [] 
        with Not_found -> ());
     *)
-    let k' = Marshal.to_string k [] in
-    let v' = (Marshal.to_string (fv v) [(*Marshal.Closures*)]) in
+    let k' = Common.marshal__to_string k [] in
+    let v' = (Common.marshal__to_string (fv v) [(*Common.marshal__Closures*)]) in
     (try Dbm.add db k' v' 
       with _ -> Dbm.replace db k' v'
     );
@@ -39,8 +39,8 @@ object(o)
 
   method iter f = 
     db +> Dbm.iter (fun key data -> 
-      let k' = (* unkey *) Marshal.from_string key 0 in 
-      let v' = unv (Marshal.from_string data 0) in
+      let k' = (* unkey *) Common.marshal__from_string key 0 in 
+      let v' = unv (Common.marshal__from_string data 0) in
       f (k', v')
     ) 
      
@@ -51,11 +51,11 @@ object(o)
   method null = raise Todo
     
   method assoc k = 
-    let k' = Marshal.to_string k [] in
-    unv (Marshal.from_string (Dbm.find db k') 0)
+    let k' = Common.marshal__to_string k [] in
+    unv (Common.marshal__from_string (Dbm.find db k') 0)
 
   method delkey k = 
-    let k' = Marshal.to_string k [] in
+    let k' = Common.marshal__to_string k [] in
     try 
       Dbm.remove db k';
       o
@@ -65,9 +65,9 @@ object(o)
   method keys = 
     let res = ref [] in 
     db +> Dbm.iter (fun key data -> 
-      let k' = (* unkey *) Marshal.from_string key 0 in 
+      let k' = (* unkey *) Common.marshal__from_string key 0 in 
       (* 
-         let v' = unv (Marshal.from_string data 0) in
+         let v' = unv (Common.marshal__from_string data 0) in
          f (k', v')
       *)
       Common.push2 k' res;
index 9a6741c..bd012c0 100755 (executable)
--- a/configure
+++ b/configure
@@ -8,29 +8,33 @@
 # assume standard: diff
 # assume standard: perl
 
-#TODO python 2.5 and perhaps a --disable-python 
+#TODO python 2.5 and perhaps a --disable-python
 
 #old: --with-menhir=/path/to/menhirLib or `ocamlfind query menhirLib`
 
-my $project = 
+my $project =
     "coccinelle";
-my $projectcmdline = 
+my $projectcmdline =
     "spatch -cocci_file demos/simple.cocci demos/simple.c";
 
-
 ######################################################################
 # Options
 ######################################################################
 
 my $prefix="/usr/local";
 my $python=1;
+my $trac=0;
+my $opt=".opt";
 
 local $_ = join ' ', @ARGV;
 
 # Parse options
-/-h/ || /--help/ and die "usage: $0 [--prefix=path] [--without-python]\n";
+/-h/ || /--help/ and die "usage: $0 [--prefix=path] [--without-python] [--with-trac] [--no-opt]\n\n\t--no-opt\tDo not use the optimimized version of OCaml\n\n";
 /--prefix=([^ ]*)/ and $prefix = $1;
 /--without-python/ and $python = 0;
+/--without-trac/ and $trac = 0;
+/--with-trac/ and $trac = 1;
+/--no-opt/ and $opt = "";
 
 #if($ARGV[0] =~ "--prefix=(.*)") {
 #    $prefix = $1;
@@ -53,7 +57,7 @@ my $src="$prefix/share/$project";
 
 #use Common;
 sub pr2 { print STDERR "@_\n" }
-sub cat { 
+sub cat {
     my ($what) = @_;
     my @list;
     open(TMP, $what);
@@ -66,7 +70,7 @@ sub plural { my ($e) = @_; if ($e > 1) { "s" } else { "" } }
 
 sub check_config { my ($command, $expect, $msggood, $msgbad) = @_;
     my $error = 0;
-                  
+
     my $full = cat($command);
     my $res = join(" ", @{$full});
 #             pr2 $res;
@@ -82,11 +86,10 @@ pr2 "Checking your configuration.\n";
 
 my $error = 0;
 
-
 #---------------------------------------------------------------------
 # Compilers and runtimes
 #---------------------------------------------------------------------
-$error += 
+$error +=
     check_config("echo \"1;;\\n\" | ocaml |",
 #                 "Objective(.*) 3.0[9]",
                  "Objective(.*) 3.",
@@ -94,9 +97,20 @@ $error +=
                  "The program ocaml is missing or is not a good version. We need at least 3.09",
                  );
 
+if ($opt eq ".opt") {
+   my $opt_check = `which ocamlc.opt 2>&1 | cut -d' ' -f2`; 
+   if($opt_check =~ "no") {
+       $opt="";
+       pr2 "Native version of OCaml not found";
+   }
+   else {
+       pr2 "Native version of OCaml is present.";
+   }
+}
+
 #we have cached the result of menhir in the tgz we build.
 
-#$error += 
+#$error +=
 #    check_config("menhir --version |",
 #                 "menhir, version 20071212",
 ##                 "menhir, version 2006.*",
@@ -138,24 +152,25 @@ We need  3.XX",
 ######################################################################
 
 ######################################################################
-# Diagnostic 
+# Diagnostic
 ######################################################################
 
 
-if($error) { 
+if($error) {
     pr2 "
 ----------------------------------------------------------------------
-!!!! There seems to have problem, we have found $error missing package" . 
+!!!! There seems to have problem, we have found $error missing package" .
 plural($error) . ".
-" . (($error > 1) ? "Some of those packages" : "This package") . 
-    " may be installed by picking " . ($error > 1 ? "them" : "it") . 
+" . (($error > 1) ? "Some of those packages" : "This package") .
+    " may be installed by picking " . ($error > 1 ? "them" : "it") .
     " in $project-dependencies.tgz available
 on the $project website. !!!!
 ----------------------------------------------------------------------
 ";
-} else { 
+} else {
 
     pr2 "
+
 ----------------------------------------------------------------------
 
 All seems fine for $project.
@@ -171,8 +186,8 @@ Then, to test $project simply type:
 
 ";
 
-    if($python) {
-        pr2 
+if($python) {
+        pr2
 "To use the python SmPL feature you may have to set some environment variables.
 For bash do:
 export LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:$prefix/lib
@@ -209,6 +224,12 @@ SHAREDIR=$src
 
 # Features
 FEATURE_PYTHON=$python
+
+# The OPTBIN variable is here to allow to use ocamlc.opt instead of
+# ocaml, when it is available, which speeds up compilation. So
+# if you want the fast version of the ocaml chain tools, set this var
+# or setenv it to \".opt\" in your startup script.
+OPTBIN=$opt
 ";
 
 pr2 "Modifying globals/config.ml";
@@ -222,6 +243,17 @@ my $pythonprefix = $python ? "yes_" : "no_";
 my $command = "perl -p -i -e 's#Not_found.\*#Not_found->\\\"$src\\\"#' globals/config.ml";
 `$command`;
 
+#
+# Configuration of python with or without trac
+#
+`cd python/coccilib; ln -sf output_base.py output.py;`;
+if($trac) {
+# Switch between implementation
+# in python/coccilib
+pr2 "Selecting python trac extension";
+`cd python/coccilib; ln -sf output_trac.py output.py;`;
+}
+
 
 
 
index c2e01b7..f50124c 100644 (file)
@@ -1,4 +1,5 @@
 Thanks to
+ - Alexander Faroy <ahf@0x90.dk> for the vim SmPL mode
  - Didier Le Botlan for the name of the tool: spatch.
  - A guy from Cornell for suggesting the term "semantic patch".
 
diff --git a/ctl/.#Makefile.1.21 b/ctl/.#Makefile.1.21
new file mode 100644 (file)
index 0000000..8785901
--- /dev/null
@@ -0,0 +1,95 @@
+# Copyright 2005-2009, 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=ctl
+
+SRC=flag_ctl.ml ast_ctl.ml pretty_print_ctl.ml ctl_engine.ml wrapper_ctl.ml
+
+SYSLIBS=str.cma unix.cma
+LIBS=../commons/commons.cma ../globals/globals.cma
+
+INCLUDES=-I ../commons -I ../commons/ocamlextra -I ../globals
+
+
+#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 $(INCLUDES)
+
+
+
+LIB=$(TARGET).cma
+OPTLIB=$(LIB:.cma=.cmxa)
+
+OBJS = $(SRC:.ml=.cmo)
+OPTOBJS = $(SRC:.ml=.cmx)
+
+all: $(LIB)
+all.opt: $(OPTLIB)
+
+$(TARGET).top: $(LIB) test_ctl.cmo
+       $(OCAMLMKTOP) -o $(TARGET).top $(SYSLIBS) $(LIBS) $(OBJS) test_ctl.cmo
+
+$(LIB):  $(OBJS)
+       $(OCAMLC) -a -o $(LIB) $(OBJS)
+
+$(OPTLIB): $(OPTOBJS)
+       $(OCAMLOPT) -a -o $(OPTLIB) $(OPTOBJS)
+
+clean::
+       rm -f $(LIB)  $(OPTLIB) $(LIB:.cma=.a) $(TARGET).top
+
+
+.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
+
+distclean::
+       rm -f .depend
+
+.depend:
+       $(OCAMLDEP) *.mli *.ml > .depend
+
+-include .depend
diff --git a/ctl/.#Makefile.1.22 b/ctl/.#Makefile.1.22
new file mode 100644 (file)
index 0000000..253b8cf
--- /dev/null
@@ -0,0 +1,95 @@
+# Copyright 2005-2009, 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=ctl
+
+SRC=flag_ctl.ml ast_ctl.ml pretty_print_ctl.ml ctl_engine.ml wrapper_ctl.ml
+
+SYSLIBS=str.cma unix.cma
+LIBS=../commons/commons.cma ../globals/globals.cma
+
+INCLUDES=-I ../commons -I ../commons/ocamlextra -I ../globals
+
+
+#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 $(INCLUDES)
+
+
+
+LIB=$(TARGET).cma
+OPTLIB=$(LIB:.cma=.cmxa)
+
+OBJS = $(SRC:.ml=.cmo)
+OPTOBJS = $(SRC:.ml=.cmx)
+
+all: $(LIB)
+all.opt: $(OPTLIB)
+
+$(TARGET).top: $(LIB) test_ctl.cmo
+       $(OCAMLMKTOP) -o $(TARGET).top $(SYSLIBS) $(LIBS) $(OBJS) test_ctl.cmo
+
+$(LIB):  $(OBJS)
+       $(OCAMLC) -a -o $(LIB) $(OBJS)
+
+$(OPTLIB): $(OPTOBJS)
+       $(OCAMLOPT) -a -o $(OPTLIB) $(OPTOBJS)
+
+clean::
+       rm -f $(LIB)  $(OPTLIB) $(LIB:.cma=.a) $(TARGET).top
+
+
+.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
+
+distclean::
+       rm -f .depend
+
+.depend:
+       $(OCAMLDEP) *.mli *.ml > .depend
+
+-include .depend
dissimilarity index 87%
index 270088d..8733390 100644 (file)
@@ -1,11 +1,21 @@
-ctl_engine.cmi: ast_ctl.cmo 
-pretty_print_ctl.cmi: ast_ctl.cmo 
-wrapper_ctl.cmi: ctl_engine.cmi ast_ctl.cmo 
-ctl_engine.cmo: pretty_print_ctl.cmi flag_ctl.cmo ast_ctl.cmo ctl_engine.cmi 
-ctl_engine.cmx: pretty_print_ctl.cmx flag_ctl.cmx ast_ctl.cmx ctl_engine.cmi 
-pretty_print_ctl.cmo: flag_ctl.cmo ast_ctl.cmo pretty_print_ctl.cmi 
-pretty_print_ctl.cmx: flag_ctl.cmx ast_ctl.cmx pretty_print_ctl.cmi 
-test_ctl.cmo: wrapper_ctl.cmi ctl_engine.cmi ast_ctl.cmo 
-test_ctl.cmx: wrapper_ctl.cmx ctl_engine.cmx ast_ctl.cmx 
-wrapper_ctl.cmo: ctl_engine.cmi ast_ctl.cmo wrapper_ctl.cmi 
-wrapper_ctl.cmx: ctl_engine.cmx ast_ctl.cmx wrapper_ctl.cmi 
+ctl_engine.cmi: ../commons/ograph_extended.cmi ast_ctl.cmo 
+pretty_print_ctl.cmi: ast_ctl.cmo 
+wrapper_ctl.cmi: ctl_engine.cmi ast_ctl.cmo 
+ctl_engine.cmo: pretty_print_ctl.cmi ../commons/ograph_extended.cmi \
+    flag_ctl.cmo ../globals/flag.cmo ../commons/common.cmi ast_ctl.cmo \
+    ctl_engine.cmi 
+ctl_engine.cmx: pretty_print_ctl.cmx ../commons/ograph_extended.cmx \
+    flag_ctl.cmx ../globals/flag.cmx ../commons/common.cmx ast_ctl.cmx \
+    ctl_engine.cmi 
+pretty_print_ctl.cmo: flag_ctl.cmo ../commons/common.cmi ast_ctl.cmo \
+    pretty_print_ctl.cmi 
+pretty_print_ctl.cmx: flag_ctl.cmx ../commons/common.cmx ast_ctl.cmx \
+    pretty_print_ctl.cmi 
+test_ctl.cmo: wrapper_ctl.cmi ../commons/ograph_extended.cmi ctl_engine.cmi \
+    ast_ctl.cmo 
+test_ctl.cmx: wrapper_ctl.cmx ../commons/ograph_extended.cmx ctl_engine.cmx \
+    ast_ctl.cmx 
+wrapper_ctl.cmo: ../globals/flag.cmo ctl_engine.cmi ../commons/common.cmi \
+    ast_ctl.cmo wrapper_ctl.cmi 
+wrapper_ctl.cmx: ../globals/flag.cmx ctl_engine.cmx ../commons/common.cmx \
+    ast_ctl.cmx wrapper_ctl.cmi 
index 8785901..84b98d4 100644 (file)
@@ -20,6 +20,8 @@
 
 #note: if you add a file (a .mli or .ml), dont forget to do a   make depend
 
+-include ../Makefile.config
+
 TARGET=ctl
 
 SRC=flag_ctl.ml ast_ctl.ml pretty_print_ctl.ml ctl_engine.ml wrapper_ctl.ml
@@ -36,7 +38,7 @@ INCLUDES=-I ../commons -I ../commons/ocamlextra -I ../globals
 OCAMLCFLAGS ?= -g -dtypes
 OCAMLC =ocamlc$(OPTBIN) $(OCAMLCFLAGS) $(INCLUDES)
 OCAMLOPT = ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
-OCAMLDEP = ocamldep$(OPTBIN) #$(INCLUDES)
+OCAMLDEP = ocamldep$(OPTBIN) $(INCLUDES)
 OCAMLMKTOP=ocamlmktop -g -custom $(INCLUDES)
 
 
diff --git a/demos/ifdef_skip_tag.c b/demos/ifdef_skip_tag.c
new file mode 100644 (file)
index 0000000..19765b6
--- /dev/null
@@ -0,0 +1,20 @@
+/* Example provided by: Flavien@lebarbe.net */
+
+
+int foo(int x) {
+    /* {{coccinelle:skip_start}} */
+#ifdef PLATFORM_A
+    while(func_a()) {
+#endif
+    /* {{coccinelle:skip_end}} */
+#ifdef PLATFORM_B
+    while(func_b()) {
+#endif
+        do_stuff();
+    }
+}
+
+
+void main()
+{
+}
diff --git a/demos/macro_fix_standard.h b/demos/macro_fix_standard.h
new file mode 100644 (file)
index 0000000..0d3a14f
--- /dev/null
@@ -0,0 +1,5 @@
+// use this file with the -macro_file option of spatch.
+// ex: ./spatch -macro_file demos/macro_fix_standard.h -parse_c demos/macro_parsing_problem.c 
+
+#define MALLOC(A) malloc(a);
+
diff --git a/demos/macro_parsing_problem.c b/demos/macro_parsing_problem.c
new file mode 100644 (file)
index 0000000..3924396
--- /dev/null
@@ -0,0 +1,208 @@
+// note that some of our heuristics can deal with statement
+// without trailing ';', but currently our heuristics don't handle
+// those cases below:
+
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+
+
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
+int main(void)
+{
+        /* Notice that there is NO semicolon at the end of next line. */
+        char *buf = MALLOC(3)
+        return 0;
+}
diff --git a/demos/platform_ifdef.c b/demos/platform_ifdef.c
new file mode 100644 (file)
index 0000000..9f190b3
--- /dev/null
@@ -0,0 +1,12 @@
+void main()
+{
+    buf = alloca(3
+    #ifdef PLATFORM_A
+                    +5
+    #endif
+    #ifdef PLATFORM_B
+                    +2
+    #endif
+            );
+
+}
diff --git a/demos/platform_ifdef.cocci b/demos/platform_ifdef.cocci
new file mode 100644 (file)
index 0000000..5051b4c
--- /dev/null
@@ -0,0 +1,10 @@
+@@ expression E; @@
+
+//-alloca(E)
+//+malloc(E)
+- alloca
++ malloc
+ (E)
+
+
+
index 088be9e..3657fdc 100644 (file)
@@ -33,7 +33,7 @@ install:
        chown apache:apache -R $(WEB)
        chmod a-w -R $(WEB)
 
-emn_install: all html
+emn_install: world
        cp *.css *.gif *.html $(EMNWEB)
        cp $(PDF) $(EMNWEB)
 
index ed2b3fd..8dafbd9 100644 (file)
@@ -22,7 +22,7 @@
 %
 \ifhevea % For HTML generation
 \lstdefinelanguage{Cocci}{
-morekeywords={idexpression,expression,statement,identifier,
+morekeywords={idexpression,expression,statement,identifier,type,
 parameter,list,when,strict,any,forall,local,position,typedef},
 keywordstyle=\color{OliveGreen}\bfseries,
 sensitive=false,
@@ -38,7 +38,7 @@ moredelim=[il][\color{Plum}]{@M}}
 
 \else % For DVI/PS/PDF generation
 \lstdefinelanguage{Cocci}{
-morekeywords={idexpression,expression,statement,identifier,
+morekeywords={idexpression,expression,statement,identifier,type,
 parameter,list,when,strict,any,forall,local,position,typedef},
 keywordstyle=\color{OliveGreen}\bfseries,
 sensitive=false,
@@ -474,6 +474,47 @@ some constraints on the use of these annotations:
   occur on a line with any marking.
 \end{itemize}
 
+Each element of a disjunction must be a proper term like an
+expression, a statement, an identifier or a declaration. Thus, the
+rule on the left below is not a syntaxically correct SmPL rule. One may
+use the rule on the right instead.
+
+\begin{center}
+  \begin{tabular}{l@{\hspace{5cm}}r}
+\begin{lstlisting}[language=Cocci]
+@@
+type T;
+T b;
+@@
+
+(
+ writeb(...,
+|
+ readb(
+)
+@--(T)
+ b)
+\end{lstlisting}
+    &
+\begin{lstlisting}[language=Cocci]
+@@
+type T;
+T b;
+@@
+
+(
+read
+|
+write
+)
+ (...,
+@-- (T)
+  b)
+\end{lstlisting}
+    \\
+  \end{tabular}
+\end{center}
+
 \section{Types}
 \label{types}
 
@@ -798,6 +839,7 @@ in a concise way.
 \end{grammar}
 
 \include{examples}
+\include{tips}
 \end{document}
 
 %%% Local Variables:
index 704bc29..95da6e9 100644 (file)
@@ -403,6 +403,30 @@ from a site to another.
 [[view:/linux-next/arch/powerpc/platforms/pseries/setup.c::face=ovl-face2::linb=245::colb=3::cole=9][return]]
 \end{lstlisting}
 
+Note~: Coccinelle provides some predefined Python functions,
+\emph{i.e.}, \texttt{cocci.print\_main}, \texttt{cocci.print\_sec} and
+\texttt{cocci.print\_secs}. One could alternatively write the following
+SmPL rule instead of the previously presented one.
+
+\begin{tabular}{c}
+\begin{lstlisting}[language=Cocci]
+@M@ script:python @
+p1 << r.p1;
+p2 << r.p2;
+@@@M
+
+cocci.print_main("",p1)
+cocci.print_sec("return",p2)
+\end{lstlisting}
+\end{tabular}\\
+
+The function \texttt{cocci.print\_secs} is used when there is several
+positions which are matched by a single position variable and that
+every matched position should be printed.
+
+Any metavariable could be inherited in the Python code. However,
+accessible fields are not currently equally supported among them.
+
 % \begin{tabular}{ccc}
 % Before & Semantic patch & After \\
 % \begin{minipage}[t]{.3\linewidth}
diff --git a/docs/grammar/tips.tex b/docs/grammar/tips.tex
new file mode 100644 (file)
index 0000000..b7f18d5
--- /dev/null
@@ -0,0 +1,47 @@
+
+\section{Tips and Tricks}
+
+\subsection{How to remove useless parentheses?}
+
+If you want to rewrite any access to a pointer value by a function
+call, you may use the following semantic patch.
+
+\begin{lstlisting}[language=Cocci]
+@-- a = *b
+@++ a = readb(b)
+\end{lstlisting}
+
+However, if for some reason your code looks like \verb|bar = *(foo)|,
+you will end up with \verb|bar = readb((foo))| as the extra
+parentheses around \texttt{foo} are capture by the metavariable
+\texttt{b}.
+
+In order to generate better output code, you can use the following
+semantic patch instead.
+\begin{lstlisting}[language=Cocci]
+@-- a = *(b)
+@++ a = readb(b)
+\end{lstlisting}
+
+\noindent
+And rely on your standard.iso isomorphism file which should contain:
+\begin{lstlisting}[language=Cocci]
+Expression
+@ paren @
+expression E;
+@@
+
+ (E) => E
+\end{lstlisting}
+
+Coccinelle will then consider \verb|bar = *(foo)| as equivalent to
+\verb|bar = *foo| (but not the other way around) and capture both.
+Finally, it will generate \verb|bar = readb(foo)| as expected.
+
+%%% Local Variables:
+%%% mode: LaTeX
+%%% TeX-master: "cocci_syntax"
+%%% coding: latin-9
+%%% TeX-PDF-mode: t
+%%% ispell-local-dictionary: "american"
+%%% End:
index fdd9db0..c38cdc7 100644 (file)
@@ -163,7 +163,7 @@ This manual page was written by Yoann Padioleau <yoann.padioleau@gmail.com>
 and Julia Lawall <julia@diku.dk>.
 
 .SH REPORTING BUGS
-Send a mail to <julia@diku.dk> or <yoann.padioleau@gmail.com>
+Send a mail to <cocci@diku.dk>
 
 .SH COPYRIGHT
 Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen.
similarity index 100%
rename from emacs/cocci.el
rename to editors/emacs/cocci.el
index f3f6d3d..05ed60a 100644 (file)
   "Highlighting the rule names")
 
 (defface cocci-minus-face
-  '((((background light)) (:foreground "dark green"))
+  '((((background light)) (:foreground "red"))
     (((background dark)) (:foreground "SeaGreen3")))
   "Highlighting lines to be removed")
 
 (defface cocci-plus-face
-  '((((background light)) (:foreground "red"))
+  '((((background light)) (:foreground "dark green"))
     (((background dark)) (:foreground "salmon")))
   "Highlighting lines to be added")
 
diff --git a/editors/vim/README b/editors/vim/README
new file mode 100644 (file)
index 0000000..749b5ab
--- /dev/null
@@ -0,0 +1,13 @@
+README for cocci-syntax
+=======================
+
+Syntax highlighting for Coccinelle's cocci files for vim.
+
+Releases are available from http://dev.exherbo.org/~ahf/pub/software/releases/cocci-syntax/
+and a Git repository is available at git://github.com/ahf/cocci-syntax.git
+
+Feel free to submit patches :)
+
+Alexander Færøy <ahf@0x90.dk>
+
+ .. vim: set spell spelllang=en tw=80 : ..
diff --git a/editors/vim/ftdetect/cocci.vim b/editors/vim/ftdetect/cocci.vim
new file mode 100644 (file)
index 0000000..fd78bea
--- /dev/null
@@ -0,0 +1,13 @@
+" Vim filetype detection file
+" Language:     Cocci (SmPL)
+" Author:       Alexander Færøy <ahf@0x90.dk>
+" Copyright:    Copyright (c) 2009 Alexander Færøy
+" License:      You may redistribute this under the same terms as Vim itself.
+
+if &compatible || v:version < 603
+    finish
+endif
+
+au BufNewFile,BufRead *.cocci set filetype=cocci
+
+" vim: set et ts=4 :
diff --git a/editors/vim/syntax/cocci.vim b/editors/vim/syntax/cocci.vim
new file mode 100644 (file)
index 0000000..f3c9c16
--- /dev/null
@@ -0,0 +1,40 @@
+" Vim syntax file
+" Language:     Cocci (SmPL)
+" Author:       Alexander Færøy <ahf@0x90.dk>
+" Copyright:    Copyright (c) 2009 Alexander Færøy
+" License:      You may redistribute this under the same terms as Vim itself.
+
+if &compatible || v:version < 603 || exists("b:current_syntax")
+    finish
+endif
+
+" Keywords
+syn keyword CocciKeywords       identifier type parameter constant expression contained
+syn keyword CocciKeywords       statement function local list fresh position idexpression contained
+
+syn region CocciGroup matchgroup=CocciGroupDelim start="@[^@]*@" end="@@" contains=CocciKeywords
+
+syn match CocciLineRemoved      "^-.*"
+syn match CocciLineAdded        "^+.*"
+syn match CocciComment          "//.*"
+
+syn case ignore
+syn match CocciOperator         "\.\.\."
+syn match CocciOperator         "when"
+syn case match
+
+" Errors
+syn match CocciError            "^[ \t][+-].*"
+
+" Highlight!
+hi def link CocciLineRemoved    Special
+hi def link CocciLineAdded      Identifier
+hi def link CocciError          Error
+hi def link CocciKeywords       Keyword
+hi def link CocciGroupDelim     PreProc
+hi def link CocciComment        Comment
+hi def link CocciOperator       Operator
+
+let b:current_syntax = "cocci"
+
+" vim: set et ts=4 :
diff --git a/engine/.#Makefile.1.52 b/engine/.#Makefile.1.52
new file mode 100644 (file)
index 0000000..c989683
--- /dev/null
@@ -0,0 +1,126 @@
+# Copyright 2005-2009, 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 lib_matcher_c.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
+
+##############################################################################
+# 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/.#Makefile.1.53 b/engine/.#Makefile.1.53
new file mode 100644 (file)
index 0000000..b4f53ac
--- /dev/null
@@ -0,0 +1,126 @@
+# Copyright 2005-2009, 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 lib_matcher_c.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
+
+##############################################################################
+# 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/.#Makefile.1.54 b/engine/.#Makefile.1.54
new file mode 100644 (file)
index 0000000..25f7684
--- /dev/null
@@ -0,0 +1,126 @@
+# Copyright 2005-2009, 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/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
+
+##############################################################################
+# 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/.#asttoctl.ml.1.81 b/engine/.#asttoctl.ml.1.81
new file mode 100644 (file)
index 0000000..a569a97
--- /dev/null
@@ -0,0 +1,1462 @@
+(*
+* Copyright 2005-2009, 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.
+*)
+
+
+(* true = don't see all matched nodes, only modified ones *)
+let onlyModif = ref true(*false*)
+(* set to true for line numbers in the output of ctl_engine *)
+let line_numbers = ref false
+(* if true, only eg if header is included in not for ...s *)
+let simple_get_end = ref false(*true*)
+
+(* Question: where do we put the existential quantifier for or.  At the
+moment, let it float inwards. *)
+
+(* nest shouldn't overlap with what comes after.  not checked for. *)
+
+module Ast = Ast_cocci
+module V = Visitor_ast
+module CTL = Ast_ctl
+module FV = Free_vars
+
+let warning s = Printf.fprintf stderr "warning: %s\n" s
+
+type cocci_predicate = Lib_engine.predicate * string Ast_ctl.modif
+type formula =
+    (cocci_predicate,string, Wrapper_ctl.info) Ast_ctl.generic_ctl
+
+
+let aftpred = (Lib_engine.After,CTL.Control)
+let retpred = (Lib_engine.Return,CTL.Control)
+let exitpred = (Lib_engine.ErrorExit,CTL.Control)
+
+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 rec drop_vs f =
+  CTL.rewrap f
+    (match CTL.unwrap f with
+      CTL.False as x ->  x
+    | CTL.True as x -> x
+    | CTL.Pred(p) as x -> x
+    | CTL.Not(phi) -> CTL.Not(drop_vs phi)
+    | CTL.Exists(v,phi) ->
+       (match CTL.unwrap phi with
+         CTL.Pred((x,CTL.Modif v1)) when v = v1 -> CTL.Pred((x,CTL.Control))
+       | _ -> CTL.Exists(v,drop_vs phi))
+    | CTL.And(phi1,phi2) -> CTL.And(drop_vs phi1,drop_vs phi2)
+    | CTL.Or(phi1,phi2) -> CTL.Or(drop_vs phi1,drop_vs phi2)
+    | CTL.SeqOr(phi1,phi2) -> CTL.SeqOr(drop_vs phi1,drop_vs phi2)
+    | CTL.Implies(phi1,phi2) -> CTL.Implies(drop_vs phi1,drop_vs phi2)
+    | CTL.AF(dir,phi1,phi2) -> CTL.AF(dir,drop_vs phi1,drop_vs phi2)
+    | CTL.AX(dir,phi) -> CTL.AX(dir,drop_vs phi)
+    | CTL.AG(dir,phi) -> CTL.AG(dir,drop_vs phi)
+    | CTL.AU(dir,phi1,phi2,phi3,phi4) ->
+       CTL.AU(dir,drop_vs phi1,drop_vs phi2,drop_vs phi3,drop_vs phi4)
+    | CTL.EF(dir,phi) -> CTL.EF(dir,drop_vs phi)
+    | CTL.EX(dir,phi) -> CTL.EX(dir,drop_vs phi)
+    | CTL.EG(dir,phi) -> CTL.EG(dir,drop_vs phi)
+    | CTL.EU(dir,phi1,phi2) -> CTL.EU(dir,drop_vs phi1,drop_vs phi2)
+    | CTL.Ref(v) as x -> x
+    | CTL.Let(v,term1,body) -> CTL.Let(v,drop_vs term1,drop_vs body))
+
+(* --------------------------------------------------------------------- *)
+
+let wrap n ctl = (ctl,n)
+
+let aftret =
+  wrap 0 (CTL.Or(wrap 0 (CTL.Pred aftpred),wrap 0 (CTL.Pred exitpred)))
+
+let wrapImplies n (x,y) = wrap n (CTL.Implies(x,y))
+let wrapExists n (x,y) = wrap n (CTL.Exists(x,y))
+let wrapAnd n (x,y) = wrap n (CTL.And(x,y))
+let wrapOr n (x,y) = wrap n (CTL.Or(x,y))
+let wrapSeqOr n (x,y) = wrap n (CTL.SeqOr(x,y))
+let wrapAU n (x,y) = wrap n (CTL.AU(CTL.FORWARD,x,y,drop_vs x,drop_vs y))
+let wrapEU n (x,y) = wrap n (CTL.EU(CTL.FORWARD,x,y))
+let wrapAX n (x) = wrap n (CTL.AX(CTL.FORWARD,x))
+let wrapBackAX n (x) = wrap n (CTL.AX(CTL.BACKWARD,x))
+let wrapEX n (x) = wrap n (CTL.EX(CTL.FORWARD,x))
+let wrapBackEX n (x) = wrap n (CTL.EX(CTL.BACKWARD,x))
+let wrapAG n (x) = wrap n (CTL.AG(CTL.FORWARD,x))
+let wrapEG n (x) = wrap n (CTL.EG(CTL.FORWARD,x))
+let wrapAF n (x) = wrap n (CTL.AF(CTL.FORWARD,x,drop_vs x))
+let wrapEF n (x) = wrap n (CTL.EF(CTL.FORWARD,x))
+let wrapNot n (x) = wrap n (CTL.Not(x))
+let wrapPred n (x) = wrap n (CTL.Pred(x))
+let wrapLet n (x,y,z) = wrap n (CTL.Let(x,y,z))
+let wrapRef n (x) = wrap n (CTL.Ref(x))
+
+(* --------------------------------------------------------------------- *)
+
+let get_option fn = function
+    None -> None
+  | Some x -> Some (fn x)
+
+let get_list_option fn = function
+    None -> []
+  | Some x -> fn x
+
+(* --------------------------------------------------------------------- *)
+(* --------------------------------------------------------------------- *)
+(* 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 rec dots_list unwrapped wrapped =
+    match (unwrapped,wrapped) with
+      ([],_) -> []
+
+    | (Ast.Dots(_,_,_)::Ast.OptStm(stm)::(Ast.Dots(_,_,_) as u)::urest,
+       d0::_::d1::rest)
+    | (Ast.Nest(_,_,_)::Ast.OptStm(stm)::(Ast.Dots(_,_,_) as u)::urest,
+       d0::_::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 = fvlist new_rest1 in
+        let fv_rest2 = fvlist new_rest2 in
+        [d0;(Ast.Disj[(Ast.DOTS(new_rest1),l,fv_rest1,Ast.NoDots);
+                       (Ast.DOTS(new_rest2),l,fv_rest2,Ast.NoDots)],
+             l,fv_rest1,Ast.NoDots)]
+
+    | (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 = fvlist new_rest1 in
+        let fv_rest2 = fvlist new_rest2 in
+        [(Ast.Disj[(Ast.DOTS(new_rest2),l,fv_rest2,Ast.NoDots);
+                    (Ast.DOTS(new_rest1),l,fv_rest1,Ast.NoDots)],
+          l,fv_rest2,Ast.NoDots)]
+
+    | ([Ast.Dots(_,_,_);Ast.OptStm(stm)],[d1;_]) ->
+       let l = Ast.get_line stm in
+       let fv_stm = Ast.get_fvs stm in
+       let fv_d1 = Ast.get_fvs d1 in
+       let fv_both = Common.union_set fv_stm fv_d1 in
+       [d1;(Ast.Disj[(Ast.DOTS([stm]),l,fv_stm,Ast.NoDots);
+                      (Ast.DOTS([d1]),l,fv_d1,Ast.NoDots)],
+            l,fv_both,Ast.NoDots)]
+
+    | ([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.line = 0; Ast.column = 0 },
+                   Ast.CONTEXT(Ast.NOTHING)),
+                  Ast.NoWhen,[]) in
+       [d1;rw(Ast.Disj[rwd(Ast.DOTS([stm]));
+                        (Ast.DOTS([rw dots]),l,[],Ast.NoDots)])]
+
+    | (_::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
+    donothing donothing stmtdotsfn
+    donothing donothing donothing donothing donothing donothing donothing
+    donothing donothing donothing
+
+(* --------------------------------------------------------------------- *)
+(* 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
+      donothing donothing donothing
+      donothing donothing donothing donothing donothing donothing
+      donothing stmt_count donothing donothing in
+  "p"^(string_of_int (recursor.V.combiner_statement s))
+
+(* --------------------------------------------------------------------- *)
+(* Top-level code *)
+
+let ctr = ref 0
+let fresh_var _ =
+  let c = !ctr in
+  (*ctr := !ctr + 1;*)
+  Printf.sprintf "v%d" c
+
+let labctr = ref 0
+let fresh_label_var s =
+  let c = !labctr in
+  labctr := !labctr + 1;
+  Printf.sprintf "%s%d" s c
+
+let lctr = ref 0
+let fresh_let_var _ =
+  let c = !lctr in
+  lctr := !lctr + 1;
+  Printf.sprintf "l%d" c
+
+let sctr = ref 0
+let fresh_metavar _ =
+  let c = !sctr in
+(*sctr := !sctr + 1;*)
+  Printf.sprintf "_S%d" c
+
+let get_unquantified quantified vars =
+  List.filter (function x -> not (List.mem x quantified)) vars
+
+type after = After of formula | Guard of formula | Tail
+
+let make_seq n l =
+  let rec loop = function
+      [] -> failwith "not possible"
+    | [x] -> x
+    | x::xs -> wrapAnd n (x,wrapAX n (loop xs)) in
+  loop l
+
+let make_seq_after2 n first = function
+    After rest -> wrapAnd n (first,wrapAX n (wrapAX n rest))
+  | _ -> first
+
+let make_seq_after n first = function
+    After rest -> make_seq n [first;rest]
+  | _ -> first
+
+let a2n = function After f -> Guard f | x -> x
+
+let and_opt n first = function
+    After rest -> wrapAnd n (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 recursor =
+    V.combiner bind option_default
+      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 in
+  recursor.V.combiner_rule_elem
+
+let make_match n guard used_after code =
+  if guard
+  then wrapPred n (Lib_engine.Match(code),CTL.Control)
+  else
+    let v = fresh_var() in
+    if contains_modif code
+    then wrapExists n (v,wrapPred n (Lib_engine.Match(code),CTL.Modif v))
+    else
+      let any_used_after =
+       List.exists (function x -> List.mem x used_after) (Ast.get_fvs code) in
+      if !onlyModif && not any_used_after
+      then wrapPred n (Lib_engine.Match(code),CTL.Control)
+      else wrapExists n (v,wrapPred n (Lib_engine.Match(code),CTL.UnModif v))
+
+let make_raw_match n code = wrapPred n (Lib_engine.Match(code),CTL.Control)
+
+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 seq_fvs2 quantified fv1 fv2 =
+  match seq_fvs quantified [fv1;fv2] with
+    [(t1fvs,bfvs);(t2fvs,[])] -> (t1fvs,bfvs,t2fvs)
+  | _ -> failwith "impossible"
+
+let seq_fvs3 quantified fv1 fv2 fv3 =
+  match seq_fvs quantified [fv1;fv2;fv3] with
+    [(t1fvs,b12fvs);(t2fvs,b23fvs);(t3fvs,[])] ->
+      (t1fvs,b12fvs,t2fvs,b23fvs,t3fvs)
+  | _ -> failwith "impossible"
+
+let seq_fvs4 quantified fv1 fv2 fv3 fv4 =
+  match seq_fvs quantified [fv1;fv2;fv3;fv4] with
+    [(t1fvs,b12fvs);(t2fvs,b23fvs);(t3fvs,b34fvs);(t4fvs,[])] ->
+      (t1fvs,b12fvs,t2fvs,b23fvs,t3fvs,b34fvs,t4fvs)
+  | _ -> failwith "impossible"
+
+let seq_fvs5 quantified fv1 fv2 fv3 fv4 fv5 =
+  match seq_fvs quantified [fv1;fv2;fv3;fv4;fv5] with
+    [(t1fvs,b12fvs);(t2fvs,b23fvs);(t3fvs,b34fvs);(t4fvs,b45fvs);(t5fvs,[])] ->
+      (t1fvs,b12fvs,t2fvs,b23fvs,t3fvs,b34fvs,t4fvs,b45fvs,t5fvs)
+  | _ -> failwith "impossible"
+
+let quantify n =
+  List.fold_right (function cur -> function code -> wrapExists n (cur,code))
+
+let intersectll lst nested_list =
+  List.filter (function x -> List.exists (List.mem x) nested_list) lst
+
+(* --------------------------------------------------------------------- *)
+(* annotate dots with before and after neighbors *)
+
+let rec get_before sl a =
+  match Ast.unwrap sl with
+    Ast.DOTS(x) ->
+      let rec loop sl a =
+       match sl with
+         [] -> ([],a)
+       | 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_e s a =
+  match Ast.unwrap s with
+    Ast.Dots(d,Ast.NoWhen,t) ->
+      (Ast.rewrap s (Ast.Dots(d,Ast.NoWhen,a@t)),a)
+  | Ast.Dots(d,Ast.WhenNot w,t) ->
+      let (w,_) = get_before w [] in
+      (Ast.rewrap s (Ast.Dots(d,Ast.WhenNot w,a@t)),a)
+  | Ast.Dots(d,Ast.WhenAlways w,t) ->
+      let (w,_) = get_before_e w [] in
+      (Ast.rewrap s (Ast.Dots(d,Ast.WhenAlways w,a@t)),a)
+  | Ast.Nest(stmt_dots,w,t) ->
+      let (w,_) = List.split (List.map (function s -> get_before s []) 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,a@t)),[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,dots,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,dots,bd,rbrace)),
+       [Ast.WParen(rbrace,index)])
+  | 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.FunDecl(header,lbrace,decls,dots,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.FunDecl(header,lbrace,de,dots,bd,rbrace)),[])
+  | _ -> failwith "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_e s a =
+  match Ast.unwrap s with
+    Ast.Dots(d,Ast.NoWhen,t) ->
+      (Ast.rewrap s (Ast.Dots(d,Ast.NoWhen,a@t)),a)
+  | Ast.Dots(d,Ast.WhenNot w,t) ->
+      let (w,_) = get_after w [] in
+      (Ast.rewrap s (Ast.Dots(d,Ast.WhenNot w,a@t)),a)
+  | Ast.Dots(d,Ast.WhenAlways w,t) ->
+      let (w,_) = get_after_e w [] in
+      (Ast.rewrap s (Ast.Dots(d,Ast.WhenAlways w,a@t)),a)
+  | Ast.Nest(stmt_dots,w,t) ->
+      let (w,_) = List.split (List.map (function s -> get_after s []) 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,a@t)),[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,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,Ast.SequencibleAfterDots a,i)))),[])
+      |        Ast.MetaStmt(_,_,_) -> (s,[])
+      |        _ -> (s,[Ast.Other s]))
+  | Ast.Seq(lbrace,decls,dots,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,dots,bd,rbrace)),
+       [Ast.WParen(lbrace,index)])
+  | 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.FunDecl(header,lbrace,decls,dots,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.FunDecl(header,lbrace,de,dots,bd,rbrace)),[])
+  | _ -> failwith "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
+
+(* --------------------------------------------------------------------- *)
+(* the main translation loop *)
+
+let decl_to_not_decl n dots stmt make_match f =
+  if dots
+  then f
+  else
+    let de =
+      let md = Ast.make_meta_decl "_d" (Ast.CONTEXT(Ast.NOTHING)) in
+      Ast.rewrap md (Ast.Decl md) in
+    wrapAU n (make_match de,
+             wrap n (CTL.And(wrap n (CTL.Not (make_match de)), f)))
+
+let rec statement_list stmt_list used_after after quantified guard =
+  let n = if !line_numbers then Ast.get_line stmt_list else 0 in
+  match Ast.unwrap stmt_list with
+    Ast.DOTS(x) ->
+      let rec loop quantified = function
+         ([],_) -> (match after with After f -> f | _ -> wrap n CTL.True)
+       | ([e],_) -> statement e used_after after quantified guard
+       | (e::sl,fv::fvs) ->
+           let shared = intersectll fv fvs in
+           let unqshared = get_unquantified quantified shared in
+           let new_quantified = Common.union_set unqshared quantified in
+           quantify n unqshared
+             (statement e used_after (After(loop new_quantified (sl,fvs)))
+                new_quantified guard)
+       | _ -> failwith "not possible" in
+      loop quantified (x,List.map Ast.get_fvs x)
+  | Ast.CIRCLES(x) -> failwith "not supported"
+  | Ast.STARS(x) -> failwith "not supported"
+
+and statement stmt used_after after quantified guard =
+
+  let n = if !line_numbers then Ast.get_line stmt else 0 in
+  let wrapExists = wrapExists n in
+  let wrapAnd = wrapAnd n in
+  let wrapOr = wrapOr n in
+  let wrapSeqOr = wrapSeqOr n in
+  let wrapAU = wrapAU n in
+  let wrapAX = wrapAX n in
+  let wrapBackAX = wrapBackAX n in
+  let wrapEX = wrapEX n in
+  let wrapBackEX = wrapBackEX n in
+  let wrapAG = wrapAG n in
+  let wrapAF = wrapAF n in
+  let wrapEF = wrapEF n in
+  let wrapNot = wrapNot n in
+  let wrapPred = wrapPred n in
+  let make_seq = make_seq n in
+  let make_seq_after2 = make_seq_after2 n in
+  let make_seq_after = make_seq_after n in
+  let and_opt = and_opt n in
+  let quantify = quantify n in
+  let make_match = make_match n guard used_after in
+  let make_raw_match = make_raw_match n in
+
+  let make_meta_rule_elem d =
+    let nm = fresh_metavar() in
+    Ast.make_meta_rule_elem nm d in
+
+  match Ast.unwrap stmt with
+    Ast.Atomic(ast) ->
+      (match Ast.unwrap ast with
+       Ast.MetaStmt((s,i,(Ast.CONTEXT(Ast.BEFOREAFTER(_,_)) as d)),seqible,_)
+      | Ast.MetaStmt((s,i,(Ast.CONTEXT(Ast.AFTER(_)) as d)),seqible,_) ->
+         let label_var = (*fresh_label_var*) "_lab" in
+         let label_pred = wrapPred(Lib_engine.Label(label_var),CTL.Control) in
+         let prelabel_pred =
+           wrapPred(Lib_engine.PrefixLabel(label_var),CTL.Control) in
+         let matcher d = make_match (make_meta_rule_elem d) in
+         let full_metamatch = matcher d in
+         let first_metamatch =
+           matcher
+             (match d with
+               Ast.CONTEXT(Ast.BEFOREAFTER(bef,_)) ->
+                 Ast.CONTEXT(Ast.BEFORE(bef))
+             | Ast.CONTEXT(_) -> Ast.CONTEXT(Ast.NOTHING)
+             | Ast.MINUS(_) | Ast.PLUS -> failwith "not possible") in
+         let middle_metamatch =
+           matcher
+             (match d with
+               Ast.CONTEXT(_) -> Ast.CONTEXT(Ast.NOTHING)
+             | Ast.MINUS(_) | Ast.PLUS -> failwith "not possible") in
+         let last_metamatch =
+           matcher
+             (match d with
+               Ast.CONTEXT(Ast.BEFOREAFTER(_,aft)) ->
+                 Ast.CONTEXT(Ast.AFTER(aft))
+             | Ast.CONTEXT(_) -> d
+             | Ast.MINUS(_) | Ast.PLUS -> failwith "not possible") in
+         
+         let left_or =
+           make_seq
+             [full_metamatch; and_opt (wrapNot(prelabel_pred)) after] in
+         let right_or =
+           make_seq
+             [first_metamatch;
+               wrapAU(middle_metamatch,
+                      make_seq
+                        [wrapAnd(last_metamatch,label_pred);
+                          and_opt (wrapNot(prelabel_pred)) after])] in
+         let body f =
+           wrapAnd(label_pred,
+                   f (wrapAnd(make_raw_match ast,
+                              wrapOr(left_or,right_or)))) in
+         let id x = x in
+         (match seqible with
+           Ast.Sequencible | Ast.SequencibleAfterDots [] ->
+             quantify (label_var::get_unquantified quantified [s])
+               (body
+                  (function x ->
+                    (wrapAnd(wrapNot(wrapBackAX(label_pred)),x))))
+         | Ast.SequencibleAfterDots l ->
+             let afts =
+                List.map (process_bef_aft Tail quantified used_after n) l in
+             let ors =
+               List.fold_left (function x -> function y -> wrapOr(x,y))
+                 (List.hd afts) (List.tl afts) in
+             quantify (label_var::get_unquantified quantified [s])
+               (wrapAnd(wrapEF(wrapAnd(ors,wrapBackAX(label_pred))),
+                        body
+                          (function x ->
+                            wrapAnd(wrapNot(wrapBackAX(label_pred)),x))))
+         | Ast.NotSequencible ->
+             quantify (label_var::get_unquantified quantified [s]) (body id))
+           
+      |        Ast.MetaStmt((s,i,d),seqible,_) ->
+         let label_var = (*fresh_label_var*) "_lab" in
+         let label_pred = wrapPred(Lib_engine.Label(label_var),CTL.Control) in
+         let prelabel_pred =
+           wrapPred(Lib_engine.PrefixLabel(label_var),CTL.Control) in
+         let matcher d = make_match (make_meta_rule_elem d) in
+         let first_metamatch = matcher d in
+         let rest_metamatch =
+           matcher
+             (match d with
+               Ast.MINUS(_) -> Ast.MINUS([])
+             | Ast.CONTEXT(_) -> Ast.CONTEXT(Ast.NOTHING)
+             | Ast.PLUS -> failwith "not possible") in
+         (* first_nodea and first_nodeb are separated here and above to
+            improve let sharing - only first_nodea is unique to this site *)
+         let first_nodeb = first_metamatch in
+         let rest_nodes = wrapAnd(rest_metamatch,prelabel_pred) in
+         let last_node = and_opt (wrapNot(prelabel_pred)) after in
+         let body f =
+           wrapAnd
+             (label_pred,
+              f (wrapAnd
+                   (make_raw_match ast,
+                    (make_seq
+                       [first_nodeb; wrapAU(rest_nodes,last_node)])))) in
+         (match seqible with
+           Ast.Sequencible | Ast.SequencibleAfterDots [] ->
+             quantify (label_var::get_unquantified quantified [s])
+               (body
+                  (function x -> wrapAnd(wrapNot(wrapBackAX(label_pred)),x)))
+         | Ast.SequencibleAfterDots l ->
+             let afts =
+                List.map (process_bef_aft Tail quantified used_after n) l in
+             let ors =
+               List.fold_left (function x -> function y -> wrapOr(x,y))
+                 (List.hd afts) (List.tl afts) in
+             quantify (label_var::get_unquantified quantified [s])
+               (wrapAnd(wrapEF(wrapAnd(ors,wrapBackAX(label_pred))),
+                        body
+                          (function x ->
+                            wrapAnd(wrapNot(wrapBackAX(label_pred)),x))))
+         | Ast.NotSequencible ->
+             quantify (label_var::get_unquantified quantified [s])
+               (body (function x -> x)))
+      |        _ ->
+         let stmt_fvs = Ast.get_fvs stmt in
+         let fvs = get_unquantified quantified stmt_fvs in
+         let between_dots = Ast.get_dots_bef_aft stmt in
+         let term = make_match ast in
+         let term =
+           match between_dots with
+             Ast.BetweenDots brace_term ->
+               (match Ast.unwrap brace_term with
+                 Ast.Atomic(brace_ast) ->
+                   let case1 =
+                     wrapAnd
+                       (wrapOr
+                          (wrapBackEX
+                             (wrapPred(Lib_engine.TrueBranch,CTL.Control)),
+                           wrapBackEX
+                             (wrapBackEX(wrapPred(Lib_engine.FalseBranch,
+                                                  CTL.Control)))),
+                        make_match brace_ast) in
+                   let case2 =
+                     wrapAnd
+                       (wrapNot
+                          (wrapOr
+                             (wrapBackEX
+                                (wrapPred(Lib_engine.TrueBranch,CTL.Control)),
+                              wrapBackEX
+                                (wrapBackEX(wrapPred(Lib_engine.FalseBranch,
+                                                     CTL.Control))))),
+                        term) in
+                   wrapOr(case1,case2)
+               | _ -> failwith "not possible")
+           | Ast.NoDots -> term in
+         make_seq_after (quantify fvs term) after)
+  | Ast.Seq(lbrace,decls,dots,body,rbrace) ->
+      let (lbfvs,b1fvs,_,b2fvs,_,b3fvs,rbfvs) =
+       seq_fvs4 quantified
+         (Ast.get_fvs lbrace) (Ast.get_fvs decls)
+         (Ast.get_fvs body) (Ast.get_fvs rbrace) in
+      let v = count_nested_braces stmt in
+      let paren_pred = wrapPred(Lib_engine.Paren v,CTL.Control) in
+      let start_brace =
+       wrapAnd(quantify lbfvs (make_match lbrace),paren_pred) in
+      let end_brace =
+       wrapAnd(quantify rbfvs (make_match 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
+      wrapExists
+       (v,quantify b1fvs
+          (make_seq
+             [start_brace;
+               quantify b2fvs
+                 (statement_list decls used_after
+                    (After
+                       (decl_to_not_decl n dots stmt make_match
+                          (quantify b3fvs
+                             (statement_list body used_after
+                                (After (make_seq_after end_brace after))
+                                new_quantified3 guard))))
+                    new_quantified2 guard)]))
+  | Ast.IfThen(ifheader,branch,aft) ->
+
+(* "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,_) =
+        seq_fvs2 quantified (Ast.get_fvs ifheader) (Ast.get_fvs branch) in
+       let new_quantified = Common.union_set bfvs quantified in
+       (* if header *)
+       let if_header = quantify efvs (make_match ifheader) in
+       (* then branch and after *)
+       let true_branch =
+        make_seq
+          [wrapPred(Lib_engine.TrueBranch,CTL.Control);
+            statement branch used_after (a2n after) new_quantified guard] in
+       let fall_branch =  wrapPred(Lib_engine.FallThrough,CTL.Control) in
+       let after_pred = wrapPred(Lib_engine.After,CTL.Control) in
+       let (aft_needed,after_branch) =
+        match aft with
+          Ast.CONTEXT(Ast.NOTHING) -> (false,make_seq_after2 after_pred after)
+        | _ ->
+            (true,
+             make_seq_after after_pred
+               (After
+                  (make_seq_after (make_match (make_meta_rule_elem aft))
+                     after))) in
+       let or_cases = wrapOr(true_branch,wrapOr(fall_branch,after_branch)) in
+       (* the code *)
+       (match (after,aft_needed) with
+        (After _,_) (* pattern doesn't end here *)
+       | (_,true) (* + code added after *) ->
+          quantify bfvs
+            (wrapAnd (if_header, wrapAnd(wrapAX or_cases, wrapEX after_pred)))
+       | _ -> quantify bfvs (wrapAnd(if_header, wrapAX or_cases)))
+        
+  | Ast.IfThenElse(ifheader,branch1,els,branch2,aft) ->
+
+(*  "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
+
+
+ Note that we rely on the well-formedness of C programs.  For example, we
+ do not use EX to check that there is at least one then branch, because
+ there is always one.  And we do not check that there is only one then or
+ else branch, because these again are always the case in a well-formed C
+ program. *)
+       (* free variables *)
+       let (e1fvs,b1fvs,s1fvs) =
+        seq_fvs2 quantified (Ast.get_fvs ifheader) (Ast.get_fvs branch1) in
+       let (e2fvs,b2fvs,s2fvs) =
+        seq_fvs2 quantified (Ast.get_fvs ifheader) (Ast.get_fvs branch2) in
+       let bothfvs =
+        Common.union_set
+          (Common.union_set b1fvs b2fvs)
+          (Common.inter_set s1fvs s2fvs) in
+       let exponlyfvs = Common.inter_set e1fvs e2fvs in
+       let new_quantified = Common.union_set bothfvs quantified in
+       (* if header *)
+       let if_header = quantify exponlyfvs (make_match ifheader) in
+       (* then and else branches *)
+       let true_branch =
+        make_seq
+          [wrapPred(Lib_engine.TrueBranch,CTL.Control);
+            statement branch1 used_after (a2n after) new_quantified guard] in
+       let false_pred = wrapPred(Lib_engine.FalseBranch,CTL.Control) in
+       let false_branch =
+          make_seq
+          [false_pred; make_match els;
+            statement branch2 used_after (a2n after) new_quantified guard] in
+       let after_pred = wrapPred(Lib_engine.After,CTL.Control) in
+       let (aft_needed,after_branch) =
+        match aft with
+          Ast.CONTEXT(Ast.NOTHING) -> (false,make_seq_after2 after_pred after)
+        | _ ->
+            (true,
+             make_seq_after after_pred
+               (After
+                  (make_seq_after (make_match (make_meta_rule_elem aft))
+                     after))) in
+       let or_cases = wrapOr(true_branch,wrapOr(false_branch,after_branch)) in
+       (* the code *)
+       (match (after,aft_needed) with
+        (After _,_) (* pattern doesn't end here *)
+       | (_,true) (* + code added after *) ->
+         quantify bothfvs
+           (wrapAnd
+              (if_header,
+                wrapAnd(wrapAX or_cases,
+                        wrapAnd(wrapEX false_pred,wrapEX after_pred))))
+      |        _ ->
+         quantify bothfvs
+           (wrapAnd (if_header, wrapAnd(wrapAX or_cases, wrapEX false_pred))))
+
+  | Ast.While(header,body,aft) | Ast.For(header,body,aft) ->
+   (* the translation in this case is similar to that of an if with no else *)
+       (* free variables *) 
+      let (efvs,bfvs,_) =
+       seq_fvs2 quantified (Ast.get_fvs header) (Ast.get_fvs body) in
+      let new_quantified = Common.union_set bfvs quantified in
+      (* if header *)
+      let header = quantify efvs (make_match header) in
+      let body =
+       make_seq
+         [wrapPred(Lib_engine.TrueBranch,CTL.Control);
+           statement body used_after (a2n after) new_quantified guard] in
+      let after_pred = wrapPred(Lib_engine.FallThrough,CTL.Control) in
+      let (aft_needed,after_branch) =
+       match aft with
+         Ast.CONTEXT(Ast.NOTHING) -> (false,make_seq_after2 after_pred after)
+       | _ ->
+           (true,
+            make_seq_after after_pred
+              (After
+                 (make_seq_after (make_match (make_meta_rule_elem aft))
+                    after))) in
+      let or_cases = wrapOr(body,after_branch) in
+      (* the code *)
+      (match (after,aft_needed) with
+       (After _,_) (* pattern doesn't end here *)
+      | (_,true) (* + code added after *) ->
+         quantify bfvs
+           (wrapAnd (header, wrapAnd(wrapAX or_cases, wrapEX after_pred)))
+      | _ -> quantify bfvs (wrapAnd(header, wrapAX or_cases)))
+
+  | Ast.Disj(stmt_dots_list) ->
+      let processed =
+       List.map
+         (function x -> statement_list x used_after after quantified guard)
+         stmt_dots_list in
+      let rec loop = function
+         [] -> wrap n CTL.True
+       | [x] -> x
+       | x::xs -> wrapSeqOr(x,loop xs) in
+      loop processed
+(*
+      let do_one e =
+       statement_list e used_after (a2n after) quantified true in
+      let add_nots l e =
+       List.fold_left
+         (function rest -> function cur -> wrapAnd(wrapNot(do_one cur),rest))
+         e l in
+      let process_one nots cur =
+       match Ast.unwrap cur with
+         Ast.DOTS(x::xs) ->
+           let on = List.map (function x -> Ast.OrOther_dots x) nots in
+           (match Ast.unwrap x with
+             Ast.Dots(d,w,t) ->
+               List.iter
+                 (function x ->
+                   Printf.printf "a not\n";
+                   Pretty_print_cocci.statement_dots x)
+                 nots;
+               let cur =
+                 Ast.rewrap cur
+                   (Ast.DOTS((Ast.rewrap x (Ast.Dots(d,w,on@t)))::xs)) in
+               statement_list cur used_after after quantified guard
+           | Ast.Nest(sd,w,t) ->
+               let cur =
+                 Ast.rewrap cur
+                   (Ast.DOTS((Ast.rewrap x (Ast.Nest(sd,w,on@t)))::xs)) in
+               statement_list cur used_after after quantified guard
+           | _ ->
+               add_nots nots
+                 (statement_list cur used_after after quantified guard))
+       | Ast.DOTS([]) ->
+           add_nots nots
+             (statement_list cur used_after after quantified guard)
+       | _ -> failwith "CIRCLES, STARS not supported" in
+      let rec loop after = function
+         [] -> failwith "disj shouldn't be empty" (*wrap n CTL.False*)
+       | [(nots,cur)] -> process_one nots cur
+       | (nots,cur)::rest -> wrapOr(process_one nots cur, loop after rest) in
+      loop after (preprocess_disj stmt_dots_list)
+*)
+  | Ast.Nest(stmt_dots,whencode,befaft) ->
+      let dots_pattern =
+       statement_list stmt_dots used_after (a2n after) quantified guard in
+      let udots_pattern =
+       let whencodes =
+         List.map
+           (function sl ->
+             statement_list sl used_after (a2n after) quantified true)
+           whencode in
+       List.fold_left (function rest -> function cur -> wrapOr(cur,rest))
+         (statement_list stmt_dots used_after (a2n after) quantified true)
+         whencodes in
+      (match (after,guard&&(whencode=[])) with
+       (After a,true) ->
+         let nots =
+           List.map (process_bef_aft after quantified used_after n) befaft in
+         (match nots with
+           [] -> wrapAF(wrapOr(a,aftret))
+         | x::xs ->
+             let left =
+               wrapNot
+                 (List.fold_left
+                    (function rest -> function cur -> wrapOr(cur,rest))
+                    x xs) in
+             wrapAU(left,wrapOr(a,aftret)))
+      |        (After a,false) ->
+         let left = wrapOr(dots_pattern,wrapNot udots_pattern) in
+         let nots =
+           List.map (process_bef_aft after quantified used_after n) befaft in
+         let left =
+           match nots with
+             [] -> left
+           | x::xs ->
+               wrapAnd
+                 (wrapNot
+                    (List.fold_left
+                       (function rest -> function cur -> wrapOr(cur,rest))
+                       x xs),
+                  left) in
+         wrapAU(left,wrapOr(a,aftret))
+      |        (_,true) -> wrap n CTL.True
+      |        (_,false) -> wrapAG(wrapOr(dots_pattern,wrapNot udots_pattern)))
+  | Ast.Dots((_,i,d),whencodes,t) ->
+      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
+      let whencodes =
+       (match whencodes with
+         Ast.NoWhen -> []
+       | Ast.WhenNot whencodes ->
+           [wrapNot
+               (statement_list whencodes used_after (a2n after) quantified
+                  true)]
+       | Ast.WhenAlways s ->
+           [statement s used_after (a2n after) quantified true]) @
+       (List.map wrapNot
+          (List.map (process_bef_aft after quantified used_after n) t)) in
+      let phi2 =
+       match whencodes with
+         [] -> None
+       | x::xs ->
+           Some
+             (List.fold_left
+                (function rest -> function cur -> wrapAnd(cur,rest))
+                x xs) in
+      let phi3 =
+       match (dot_code,phi2) with (* add - on dots, if any *)
+         (None,None) -> None
+       | (Some dotcode,None) -> Some dotcode
+       | (None,Some whencode) -> Some whencode
+       | (Some dotcode,Some whencode) -> Some(wrapAnd (dotcode,whencode)) in
+      let exit = wrap n (CTL.Pred (Lib_engine.Exit,CTL.Control)) in
+      (* add in the after code to make the result *)
+      (match (after,phi3) with
+       (Tail,Some whencode) -> wrapAU(whencode,wrapOr(exit,aftret))
+      |        (Tail,None) -> wrapAF(wrapOr(exit,aftret))
+      |        (After f,Some whencode) | (Guard f,Some whencode) ->
+         wrapAU(whencode,wrapOr(f,aftret))
+      |        (After f,None) | (Guard f,None) -> wrapAF(wrapOr(f,aftret)))
+  | Ast.FunDecl(header,lbrace,decls,dots,body,rbrace) ->
+      let (hfvs,b1fvs,lbfvs,b2fvs,_,b3fvs,_,b4fvs,rbfvs) =
+       seq_fvs5 quantified (Ast.get_fvs header) (Ast.get_fvs lbrace)
+         (Ast.get_fvs decls) (Ast.get_fvs body) (Ast.get_fvs rbrace) in
+      let function_header = quantify hfvs (make_match header) in
+      let v = count_nested_braces stmt in
+      let paren_pred = wrapPred(Lib_engine.Paren v,CTL.Control) in
+      let start_brace =
+       wrapAnd(quantify lbfvs (make_match lbrace),paren_pred) in
+      let end_brace =
+       let stripped_rbrace =
+         match Ast.unwrap rbrace with
+           Ast.SeqEnd((data,info,_)) ->
+             Ast.rewrap rbrace
+               (Ast.SeqEnd ((data,info,Ast.CONTEXT(Ast.NOTHING))))
+         | _ -> failwith "unexpected close brace" in
+       let exit = wrap n (CTL.Pred (Lib_engine.Exit,CTL.Control)) in
+       let errorexit = wrap n (CTL.Pred (Lib_engine.ErrorExit,CTL.Control)) in
+       wrapAnd(quantify rbfvs (make_match rbrace),
+               wrapAU(make_match stripped_rbrace,
+                      wrapOr(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
+      quantify b1fvs
+       (make_seq
+          [function_header;
+            wrapExists
+              (v,
+               (quantify b2fvs
+                  (make_seq
+                     [start_brace;
+                       quantify b3fvs
+                         (statement_list decls used_after
+                            (After
+                               (decl_to_not_decl n dots stmt
+                                  make_match
+                                  (quantify b4fvs
+                                     (statement_list body used_after
+                                        (After
+                                           (make_seq_after end_brace after))
+                                        new_quantified4 guard))))
+                            new_quantified3 guard)])))])
+  | Ast.OptStm(stm) ->
+      failwith "OptStm should have been compiled away\n";
+  | Ast.UniqueStm(stm) ->
+      failwith "arities not yet supported"
+  | Ast.MultiStm(stm) ->
+      failwith "arities not yet supported"
+  | _ -> failwith "not supported"
+
+and process_bef_aft after quantified used_after ln = function
+    Ast.WParen (re,n) ->
+      let paren_pred = wrapPred ln (Lib_engine.Paren n,CTL.Control) in
+      wrapAnd ln (make_raw_match ln re,paren_pred)
+  | Ast.Other s -> statement s used_after (a2n after) quantified true
+  | Ast.Other_dots d -> statement_list d used_after (a2n after) quantified true
+  | Ast.OrOther_dots d -> statement_list d used_after Tail quantified true
+
+(* Returns a triple for each disj element.  The first element of the triple is
+Some v if the triple element needs a name, and None otherwise.  The second
+element is a list of names whose negations should be conjuncted with the
+term.  The third element is the original term *)
+and (preprocess_disj :
+       Ast.statement Ast.dots list ->
+        (Ast.statement Ast.dots list * Ast.statement Ast.dots) list) =
+  function
+    [] -> []
+  | [s] -> [([],s)]
+  | cur::rest ->
+      let template =
+       List.map (function r -> Unify_ast.unify_statement_dots cur r) rest in
+      let processed = preprocess_disj rest in
+      if List.exists (function Unify_ast.MAYBE -> true | _ -> false) template
+      then
+       ([], cur) ::
+       (List.map2
+          (function ((nots,r) as x) ->
+            function Unify_ast.MAYBE -> (cur::nots,r) | Unify_ast.NO -> x)
+          processed template)
+      else ([], cur) :: processed
+
+(* --------------------------------------------------------------------- *)
+(* Letify:
+Phase 1: Use a hash table to identify formulas that appear more than once.
+Phase 2: Replace terms by variables.
+Phase 3: Drop lets to the point as close as possible to the uses of their
+variables *)
+
+let formula_table =
+  (Hashtbl.create(50) :
+     ((cocci_predicate,string,Wrapper_ctl.info) CTL.generic_ctl,
+      int ref (* count *) * string ref (* name *) * bool ref (* processed *))
+     Hashtbl.t)
+
+let add_hash phi =
+  let (cell,_,_) =
+    try Hashtbl.find formula_table phi
+    with Not_found ->
+      let c = (ref 0,ref "",ref false) in
+      Hashtbl.add formula_table phi c;
+      c in
+  cell := !cell + 1
+
+let rec collect_duplicates f =
+  add_hash f;
+  match CTL.unwrap f with
+    CTL.False -> ()
+  | CTL.True -> ()
+  | CTL.Pred(p) -> ()
+  | CTL.Not(phi) -> collect_duplicates phi
+  | CTL.Exists(v,phi) -> collect_duplicates phi
+  | CTL.And(phi1,phi2) -> collect_duplicates phi1; collect_duplicates phi2
+  | CTL.Or(phi1,phi2) -> collect_duplicates phi1; collect_duplicates phi2
+  | CTL.SeqOr(phi1,phi2) -> collect_duplicates phi1; collect_duplicates phi2
+  | CTL.Implies(phi1,phi2) -> collect_duplicates phi1; collect_duplicates phi2
+  | CTL.AF(_,phi1,phi2) -> collect_duplicates phi1; collect_duplicates phi2
+  | CTL.AX(_,phi) -> collect_duplicates phi
+  | CTL.AG(_,phi) -> collect_duplicates phi
+  | CTL.AU(_,phi1,phi2,phi3,phi4) ->
+      collect_duplicates phi1; collect_duplicates phi2;
+      collect_duplicates phi3; collect_duplicates phi4
+  | CTL.EF(_,phi) -> collect_duplicates phi
+  | CTL.EX(_,phi) -> collect_duplicates phi
+  | CTL.EG(_,phi) -> collect_duplicates phi
+  | CTL.EU(_,phi1,phi2) -> collect_duplicates phi1; collect_duplicates phi2
+  | CTL.Uncheck(phi) -> collect_duplicates phi
+  | _ -> failwith "not possible"
+
+let assign_variables _ =
+  Hashtbl.iter
+    (function formula ->
+      function (cell,str,_) -> if !cell > 1 then str := fresh_let_var())
+    formula_table
+
+let rec replace_formulas dec f =
+  let (ct,name,treated) = Hashtbl.find formula_table f in
+  let real_ct = !ct - dec in
+  if real_ct > 1
+  then
+    if not !treated
+    then
+      begin
+       treated := true;
+       let (acc,new_f) = replace_subformulas (dec + (real_ct - 1)) f in
+       ((!name,new_f) :: acc, CTL.rewrap f (CTL.Ref !name))
+      end
+    else ([],CTL.rewrap f (CTL.Ref !name))
+  else replace_subformulas dec f
+
+and replace_subformulas dec f =
+  match CTL.unwrap f with
+    CTL.False -> ([],f)
+  | CTL.True -> ([],f)
+  | CTL.Pred(p) -> ([],f)
+  | CTL.Not(phi) ->
+      let (acc,new_phi) = replace_formulas dec phi in
+      (acc,CTL.rewrap f (CTL.Not(new_phi)))
+  | CTL.Exists(v,phi) -> 
+      let (acc,new_phi) = replace_formulas dec phi in
+      (acc,CTL.rewrap f (CTL.Exists(v,new_phi)))
+  | CTL.And(phi1,phi2) ->
+      let (acc1,new_phi1) = replace_formulas dec phi1 in
+      let (acc2,new_phi2) = replace_formulas dec phi2 in
+      (acc1@acc2,CTL.rewrap f (CTL.And(new_phi1,new_phi2)))
+  | CTL.Or(phi1,phi2) ->
+      let (acc1,new_phi1) = replace_formulas dec phi1 in
+      let (acc2,new_phi2) = replace_formulas dec phi2 in
+      (acc1@acc2,CTL.rewrap f (CTL.Or(new_phi1,new_phi2)))
+  | CTL.SeqOr(phi1,phi2) ->
+      let (acc1,new_phi1) = replace_formulas dec phi1 in
+      let (acc2,new_phi2) = replace_formulas dec phi2 in
+      (acc1@acc2,CTL.rewrap f (CTL.SeqOr(new_phi1,new_phi2)))
+  | CTL.Implies(phi1,phi2) -> 
+      let (acc1,new_phi1) = replace_formulas dec phi1 in
+      let (acc2,new_phi2) = replace_formulas dec phi2 in
+      (acc1@acc2,CTL.rewrap f (CTL.Implies(new_phi1,new_phi2)))
+  | CTL.AF(dir,phi1,phi2) ->
+      let (acc,new_phi1) = replace_formulas dec phi1 in
+      let (acc,new_phi2) = replace_formulas dec phi2 in
+      (acc,CTL.rewrap f (CTL.AF(dir,new_phi1,new_phi2)))
+  | CTL.AX(dir,phi) ->
+      let (acc,new_phi) = replace_formulas dec phi in
+      (acc,CTL.rewrap f (CTL.AX(dir,new_phi)))
+  | CTL.AG(dir,phi) ->
+      let (acc,new_phi) = replace_formulas dec phi in
+      (acc,CTL.rewrap f (CTL.AG(dir,new_phi)))
+  | CTL.AU(dir,phi1,phi2,phi3,phi4) ->
+      let (acc1,new_phi1) = replace_formulas dec phi1 in
+      let (acc2,new_phi2) = replace_formulas dec phi2 in
+      let (acc3,new_phi3) = replace_formulas dec phi3 in
+      let (acc4,new_phi4) = replace_formulas dec phi4 in
+      (acc1@acc2@acc3@acc4,
+       CTL.rewrap f (CTL.AU(dir,new_phi1,new_phi2,new_phi3,new_phi4)))
+  | CTL.EF(dir,phi) ->
+      let (acc,new_phi) = replace_formulas dec phi in
+      (acc,CTL.rewrap f (CTL.EF(dir,new_phi)))
+  | CTL.EX(dir,phi) ->
+      let (acc,new_phi) = replace_formulas dec phi in
+      (acc,CTL.rewrap f (CTL.EX(dir,new_phi)))
+  | CTL.EG(dir,phi) -> 
+      let (acc,new_phi) = replace_formulas dec phi in
+      (acc,CTL.rewrap f (CTL.EG(dir,new_phi)))
+  | CTL.EU(dir,phi1,phi2) ->
+      let (acc1,new_phi1) = replace_formulas dec phi1 in
+      let (acc2,new_phi2) = replace_formulas dec phi2 in
+      (acc1@acc2,CTL.rewrap f (CTL.EU(dir,new_phi1,new_phi2)))
+  | _ -> failwith "not possible"
+
+let ctlfv_table =
+  (Hashtbl.create(50) :
+     ((cocci_predicate,string,Wrapper_ctl.info) CTL.generic_ctl,
+      string list (* fvs *) *
+       string list (* intersection of fvs of subterms *))
+     Hashtbl.t)
+
+let rec ctl_fvs f =
+  try let (fvs,_) = Hashtbl.find ctlfv_table f in fvs
+  with Not_found ->
+    let ((fvs,_) as res) =
+      match CTL.unwrap f with
+       CTL.False | CTL.True | CTL.Pred(_) -> ([],[])
+      | CTL.Not(phi) | CTL.Exists(_,phi)
+      | CTL.AX(_,phi) | CTL.AG(_,phi)
+      | CTL.EF(_,phi) | CTL.EX(_,phi) | CTL.EG(_,phi) -> (ctl_fvs phi,[])
+      | CTL.AU(_,phi1,phi2,phi3,phi4) ->
+         let phi1fvs = ctl_fvs phi1 in
+         let phi2fvs = ctl_fvs phi2 in
+         (* phi3 has the same fvs as phi1 and phi4 as phi2 *)
+         (Common.union_set phi1fvs phi2fvs,intersect phi1fvs phi2fvs)
+      | CTL.And(phi1,phi2) | CTL.Or(phi1,phi2) | CTL.SeqOr(phi1,phi2)
+      | CTL.Implies(phi1,phi2) | CTL.AF(_,phi1,phi2) | CTL.EU(_,phi1,phi2) ->
+         let phi1fvs = ctl_fvs phi1 in
+         let phi2fvs = ctl_fvs phi2 in
+         (Common.union_set phi1fvs phi2fvs,intersect phi1fvs phi2fvs)
+      | CTL.Ref(v) -> ([v],[v])
+      | CTL.Let(v,term,body) ->
+         let phi1fvs = ctl_fvs term in
+         let phi2fvs = Common.minus_set (ctl_fvs body) [v] in
+         (Common.union_set phi1fvs phi2fvs,intersect phi1fvs phi2fvs) in
+    Hashtbl.add ctlfv_table f res;
+    fvs
+
+let rev_order_bindings b =
+  let b =
+    List.map
+      (function (nm,term) ->
+       let (fvs,_) = Hashtbl.find ctlfv_table term in (nm,fvs,term))
+      b in
+  let rec loop bound = function
+      [] -> []
+    | unbound ->
+       let (now_bound,still_unbound) =
+         List.partition (function (_,fvs,_) -> subset fvs bound)
+           unbound in
+       let get_names = List.map (function (x,_,_) -> x) in
+       now_bound @ (loop ((get_names now_bound) @ bound) still_unbound) in
+  List.rev(loop [] b)
+
+let drop_bindings b f = (* innermost bindings first in b *)
+  let process_binary f ffvs inter nm term fail =
+    if List.mem nm inter
+    then CTL.rewrap f (CTL.Let(nm,term,f))
+    else CTL.rewrap f (fail()) in
+  let find_fvs f =
+    let _ = ctl_fvs f in Hashtbl.find ctlfv_table f in
+  let rec drop_one nm term f =
+    match CTL.unwrap f with
+      CTL.False ->  f
+    | CTL.True -> f
+    | CTL.Pred(p) -> f
+    | CTL.Not(phi) -> CTL.rewrap f (CTL.Not(drop_one nm term phi))
+    | CTL.Exists(v,phi) -> CTL.rewrap f (CTL.Exists(v,drop_one nm term phi))
+    | CTL.And(phi1,phi2) ->
+       let (ffvs,inter) = find_fvs f in
+       process_binary f ffvs inter nm term
+         (function _ -> CTL.And(drop_one nm term phi1,drop_one nm term phi2))
+    | CTL.Or(phi1,phi2) ->
+       let (ffvs,inter) = find_fvs f in
+       process_binary f ffvs inter nm term
+         (function _ -> CTL.Or(drop_one nm term phi1,drop_one nm term phi2))
+    | CTL.SeqOr(phi1,phi2) ->
+       let (ffvs,inter) = find_fvs f in
+       process_binary f ffvs inter nm term
+         (function _ ->
+           CTL.SeqOr(drop_one nm term phi1,drop_one nm term phi2))
+    | CTL.Implies(phi1,phi2) ->
+       let (ffvs,inter) = find_fvs f in
+       process_binary f ffvs inter nm term
+         (function _ ->
+           CTL.Implies(drop_one nm term phi1,drop_one nm term phi2))
+    | CTL.AF(dir,phi1,phi2) ->
+       let (ffvs,inter) = find_fvs f in
+       process_binary f ffvs inter nm term
+         (function _ ->
+           CTL.AF(dir,drop_one nm term phi1,drop_one nm term phi2))
+    | CTL.AX(dir,phi) ->
+       CTL.rewrap f (CTL.AX(dir,drop_one nm term phi))
+    | CTL.AG(dir,phi) -> CTL.rewrap f (CTL.AG(dir,drop_one nm term phi))
+    | CTL.AU(dir,phi1,phi2,phi3,phi4) ->
+       let (ffvs,inter) = find_fvs f in
+       process_binary f ffvs inter nm term
+         (function _ ->
+           CTL.AU(dir,drop_one nm term phi1,drop_one nm term phi2,
+                  drop_one nm term phi3,drop_one nm term phi4))
+    | CTL.EF(dir,phi) -> CTL.rewrap f (CTL.EF(dir,drop_one nm term phi))
+    | CTL.EX(dir,phi) ->
+       CTL.rewrap f (CTL.EX(dir,drop_one nm term phi))
+    | CTL.EG(dir,phi) -> CTL.rewrap f (CTL.EG(dir,drop_one nm term phi))
+    | CTL.EU(dir,phi1,phi2) ->
+       let (ffvs,inter) = find_fvs f in
+       process_binary f ffvs inter nm term
+         (function _ ->
+           CTL.EU(dir,drop_one nm term phi1,drop_one nm term phi2))
+    | (CTL.Ref(v) as x) -> process_binary f [v] [v] nm term (function _ -> x)
+    | CTL.Let(v,term1,body) ->
+       let (ffvs,inter) = find_fvs f in
+       process_binary f ffvs inter nm term
+         (function _ ->
+           CTL.Let(v,drop_one nm term term1,drop_one nm term body)) in
+  List.fold_left
+    (function processed -> function (nm,_,term) -> drop_one nm term processed)
+    f b
+
+let letify f =
+  failwith "this code should not be used!!!"(*;
+  Hashtbl.clear formula_table;
+  Hashtbl.clear ctlfv_table;
+  (* create a count of the number of occurrences of each subformula *)
+  collect_duplicates f;
+  (* give names to things that appear more than once *)
+  assign_variables();
+  (* replace duplicated formulas by their variables *)
+  let (bindings,new_f) = replace_formulas 0 f in
+  (* collect fvs of terms in bindings and new_f *)
+  List.iter (function f -> let _ = ctl_fvs f in ())
+    (new_f::(List.map (function (_,term) -> term) bindings));
+  (* sort bindings with uses before defs *)
+  let bindings = rev_order_bindings bindings in
+  (* insert bindings as lets into the formula *)
+  let res = drop_bindings bindings new_f in
+  res*)
+
+(* --------------------------------------------------------------------- *)
+(* Function declaration *)
+
+let top_level used_after t =
+  match Ast.unwrap t with
+    Ast.DECL(decl) -> failwith "not supported decl"
+  | Ast.INCLUDE(inc,s) ->
+      (* no indication of whether inc or s is modified *)
+      wrap 0 (CTL.Pred((Lib_engine.Include(inc,s),CTL.Control)))
+  | Ast.FILEINFO(old_file,new_file) -> failwith "not supported fileinfo"
+  | Ast.FUNCTION(stmt) ->
+      (*Printf.printf "orig\n";
+      Pretty_print_cocci.statement "" stmt;
+      Format.print_newline();*)
+      let unopt = elim_opt.V.rebuilder_statement stmt in
+      (*Printf.printf "unopt\n";
+      Pretty_print_cocci.statement "" unopt;
+      Format.print_newline();*)
+      let unopt = preprocess_dots_e unopt in
+      (*letify*)
+       (statement unopt used_after Tail [] false)
+  | Ast.CODE(stmt_dots) ->
+      let unopt = elim_opt.V.rebuilder_statement_dots stmt_dots in
+      let unopt = preprocess_dots unopt in
+      (*letify*)
+       (statement_list unopt used_after Tail [] false)
+  | Ast.ERRORWORDS(exps) -> failwith "not supported errorwords"
+
+(* --------------------------------------------------------------------- *)
+(* Contains dots *)
+
+let contains_dots =
+  let bind x y = x or y in
+  let option_default = false in
+  let mcode r x = false in
+  let statement r k s =
+    match Ast.unwrap s with Ast.Dots(_,_,_) -> true | _ -> k s in
+  let continue r k e = k e in
+  let stop r k e = false in
+  let res =
+    V.combiner bind option_default
+      mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+      continue continue continue
+      stop stop stop stop stop stop stop statement continue continue in
+  res.V.combiner_top_level
+
+(* --------------------------------------------------------------------- *)
+(* Entry points *)
+
+let asttoctl l used_after =
+  ctr := 0;
+  lctr := 0;
+  sctr := 0;
+  let l =
+    List.filter
+      (function t ->
+       match Ast.unwrap t with Ast.ERRORWORDS(exps) -> false | _ -> true)
+      l in
+  List.map2 top_level used_after l
+
+let pp_cocci_predicate (pred,modif) =
+  Pretty_print_engine.pp_predicate pred
+
+let cocci_predicate_to_string (pred,modif) =
+  Pretty_print_engine.predicate_to_string pred
diff --git a/engine/.#asttoctl2.ml.1.152 b/engine/.#asttoctl2.ml.1.152
new file mode 100644 (file)
index 0000000..865a633
--- /dev/null
@@ -0,0 +1,2340 @@
+(*
+* Copyright 2005-2009, 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
+    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,metapos) =
+    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
+      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
+
+let contains_pos =
+  let bind x y = x or y in
+  let option_default = false in
+  let mcode r (_,_,kind,metapos) =
+    match metapos with
+      Ast.MetaPos(_,_,_,_,_) -> true
+    | Ast.NoMetaPos -> false 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
+      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
+      donothing donothing donothing donothing
+      donothing donothing donothing donothing donothing donothing
+      donothing donothing stmt_count donothing donothing donothing in
+  let res = string_of_int (recursor.V.combiner_statement s) in
+  string2var ("p"^res)
+
+let labelctr = ref 0
+let get_label_ctr _ =
+  let cur = !labelctr in
+  labelctr := cur + 1;
+  string2var (Printf.sprintf "l%d" cur)
+
+(* --------------------------------------------------------------------- *)
+(* annotate dots with before and after neighbors *)
+
+let print_bef_aft = function
+    Ast.WParen (re,n) ->
+      Printf.printf "bef/aft\n";
+      Pretty_print_cocci.rule_elem "" re;
+      Format.print_newline()
+  | Ast.Other s ->
+      Printf.printf "bef/aft\n";
+      Pretty_print_cocci.statement "" s;
+      Format.print_newline()
+  | Ast.Other_dots d ->
+      Printf.printf "bef/aft\n";
+      Pretty_print_cocci.statement_dots d;
+      Format.print_newline()
+
+(* [] can only occur if we are in a disj, where it comes from a ?  In that
+case, we want to use a, which accumulates all of the previous patterns in
+their entirety. *)
+let rec get_before_elem sl a =
+  match Ast.unwrap sl with
+    Ast.DOTS(x) ->
+      let rec loop sl a =
+       match sl with
+         [] -> ([],Common.Right a)
+       | [e] ->
+           let (e,ea) = get_before_e e a in
+           ([e],Common.Left ea)
+       | e::sl ->
+           let (e,ea) = get_before_e e a in
+           let (sl,sla) = loop sl ea in
+           (e::sl,sla) in
+      let (l,a) = loop x a in
+      (Ast.rewrap sl (Ast.DOTS(l)),a)
+  | Ast.CIRCLES(x) -> failwith "not supported"
+  | Ast.STARS(x) -> failwith "not supported"
+
+and get_before sl a =
+  match get_before_elem sl a with
+    (term,Common.Left x) -> (term,x)
+  | (term,Common.Right x) -> (term,x)
+
+and get_before_whencode wc =
+  List.map
+    (function
+       Ast.WhenNot w -> let (w,_) = get_before w [] in Ast.WhenNot w
+      | Ast.WhenAlways w -> let (w,_) = get_before_e w [] in Ast.WhenAlways w
+      |        Ast.WhenModifier(x) -> Ast.WhenModifier(x)
+      | Ast.WhenNotTrue w -> Ast.WhenNotTrue w
+      | Ast.WhenNotFalse w -> Ast.WhenNotFalse w)
+    wc
+
+and get_before_e s a =
+  match Ast.unwrap s with
+    Ast.Dots(d,w,_,aft) ->
+      (Ast.rewrap s (Ast.Dots(d,get_before_whencode w,a,aft)),a)
+  | Ast.Nest(stmt_dots,w,multi,_,aft) ->
+      let w = get_before_whencode w in
+      let (sd,_) = get_before stmt_dots a in
+      let a =
+       List.filter
+         (function
+             Ast.Other a ->
+               let unifies =
+                 Unify_ast.unify_statement_dots
+                   (Ast.rewrap s (Ast.DOTS([a]))) stmt_dots in
+               (match unifies with
+                 Unify_ast.MAYBE -> false
+               | _ -> true)
+           | Ast.Other_dots a ->
+               let unifies = Unify_ast.unify_statement_dots a stmt_dots in
+               (match unifies with
+                 Unify_ast.MAYBE -> false
+               | _ -> true)
+           | _ -> true)
+         a in
+      (Ast.rewrap s (Ast.Nest(sd,w,multi,a,aft)),[Ast.Other_dots stmt_dots])
+  | Ast.Disj(stmt_dots_list) ->
+      let (dsl,dsla) =
+       List.split (List.map (function e -> get_before e a) stmt_dots_list) in
+      (Ast.rewrap s (Ast.Disj(dsl)),List.fold_left Common.union_set [] dsla)
+  | Ast.Atomic(ast) ->
+      (match Ast.unwrap ast with
+       Ast.MetaStmt(_,_,_,_) -> (s,[])
+      |        _ -> (s,[Ast.Other s]))
+  | Ast.Seq(lbrace,decls,body,rbrace) ->
+      let index = count_nested_braces s in
+      let (de,dea) = get_before decls [Ast.WParen(lbrace,index)] in
+      let (bd,_) = get_before body dea in
+      (Ast.rewrap s (Ast.Seq(lbrace,de,bd,rbrace)),
+       [Ast.WParen(rbrace,index)])
+  | Ast.Define(header,body) ->
+      let (body,_) = get_before body [] in
+      (Ast.rewrap s (Ast.Define(header,body)), [Ast.Other s])
+  | Ast.IfThen(ifheader,branch,aft) ->
+      let (br,_) = get_before_e branch [] in
+      (Ast.rewrap s (Ast.IfThen(ifheader,br,aft)), [Ast.Other s])
+  | Ast.IfThenElse(ifheader,branch1,els,branch2,aft) ->
+      let (br1,_) = get_before_e branch1 [] in
+      let (br2,_) = get_before_e branch2 [] in
+      (Ast.rewrap s (Ast.IfThenElse(ifheader,br1,els,br2,aft)),[Ast.Other s])
+  | Ast.While(header,body,aft) ->
+      let (bd,_) = get_before_e body [] in
+      (Ast.rewrap s (Ast.While(header,bd,aft)),[Ast.Other s])
+  | Ast.For(header,body,aft) ->
+      let (bd,_) = get_before_e body [] in
+      (Ast.rewrap s (Ast.For(header,bd,aft)),[Ast.Other s])
+  | Ast.Do(header,body,tail) ->
+      let (bd,_) = get_before_e body [] in
+      (Ast.rewrap s (Ast.Do(header,bd,tail)),[Ast.Other s])
+  | Ast.Iterator(header,body,aft) ->
+      let (bd,_) = get_before_e body [] in
+      (Ast.rewrap s (Ast.Iterator(header,bd,aft)),[Ast.Other s])
+  | Ast.Switch(header,lb,cases,rb) ->
+      let cases =
+       List.map
+         (function case_line ->
+           match Ast.unwrap case_line with
+             Ast.CaseLine(header,body) ->
+               let (body,_) = get_before body [] in
+               Ast.rewrap case_line (Ast.CaseLine(header,body))
+           | Ast.OptCase(case_line) -> failwith "not supported")
+         cases in
+      (Ast.rewrap s (Ast.Switch(header,lb,cases,rb)),[Ast.Other s])
+  | Ast.FunDecl(header,lbrace,decls,body,rbrace) ->
+      let (de,dea) = get_before decls [] in
+      let (bd,_) = get_before body dea in
+      (Ast.rewrap s (Ast.FunDecl(header,lbrace,de,bd,rbrace)),[])
+  | _ ->
+      Pretty_print_cocci.statement "" s; Format.print_newline();
+      failwith "get_before_e: not supported"
+
+let rec get_after sl a =
+  match Ast.unwrap sl with
+    Ast.DOTS(x) ->
+      let rec loop sl =
+       match sl with
+         [] -> ([],a)
+       | e::sl ->
+           let (sl,sla) = loop sl in
+           let (e,ea) = get_after_e e sla in
+           (e::sl,ea) in
+      let (l,a) = loop x in
+      (Ast.rewrap sl (Ast.DOTS(l)),a)
+  | Ast.CIRCLES(x) -> failwith "not supported"
+  | Ast.STARS(x) -> failwith "not supported"
+
+and get_after_whencode a wc =
+  List.map
+    (function
+       Ast.WhenNot w -> let (w,_) = get_after w a (*?*) in Ast.WhenNot w
+      | Ast.WhenAlways w -> let (w,_) = get_after_e w a in Ast.WhenAlways w
+      |        Ast.WhenModifier(x) -> Ast.WhenModifier(x)
+      | Ast.WhenNotTrue w -> Ast.WhenNotTrue w
+      | Ast.WhenNotFalse w -> Ast.WhenNotFalse w)
+    wc
+
+and get_after_e s a =
+  match Ast.unwrap s with
+    Ast.Dots(d,w,bef,_) ->
+      (Ast.rewrap s (Ast.Dots(d,get_after_whencode a w,bef,a)),a)
+  | Ast.Nest(stmt_dots,w,multi,bef,_) ->
+      let w = get_after_whencode a w in
+      let (sd,_) = get_after stmt_dots a in
+      let a =
+       List.filter
+         (function
+             Ast.Other a ->
+               let unifies =
+                 Unify_ast.unify_statement_dots
+                   (Ast.rewrap s (Ast.DOTS([a]))) stmt_dots in
+               (match unifies with
+                 Unify_ast.MAYBE -> false
+               | _ -> true)
+           | Ast.Other_dots a ->
+               let unifies = Unify_ast.unify_statement_dots a stmt_dots in
+               (match unifies with
+                 Unify_ast.MAYBE -> false
+               | _ -> true)
+           | _ -> true)
+         a in
+      (Ast.rewrap s (Ast.Nest(sd,w,multi,bef,a)),[Ast.Other_dots stmt_dots])
+  | Ast.Disj(stmt_dots_list) ->
+      let (dsl,dsla) =
+       List.split (List.map (function e -> get_after e a) stmt_dots_list) in
+      (Ast.rewrap s (Ast.Disj(dsl)),List.fold_left Common.union_set [] dsla)
+  | Ast.Atomic(ast) ->
+      (match Ast.unwrap ast with
+       Ast.MetaStmt(nm,keep,Ast.SequencibleAfterDots _,i) ->
+         (* check "after" information for metavar optimization *)
+         (* if the error is not desired, could just return [], then
+            the optimization (check for EF) won't take place *)
+         List.iter
+           (function
+               Ast.Other x ->
+                 (match Ast.unwrap x with
+                   Ast.Dots(_,_,_,_) | Ast.Nest(_,_,_,_,_) ->
+                     failwith
+                       "dots/nest not allowed before and after stmt metavar"
+                 | _ -> ())
+             | Ast.Other_dots x ->
+                 (match Ast.undots x with
+                   x::_ ->
+                     (match Ast.unwrap x with
+                       Ast.Dots(_,_,_,_) | Ast.Nest(_,_,_,_,_) ->
+                         failwith
+                           ("dots/nest not allowed before and after stmt "^
+                            "metavar")
+                     | _ -> ())
+                 | _ -> ())
+             | _ -> ())
+           a;
+         (Ast.rewrap s
+            (Ast.Atomic
+               (Ast.rewrap s
+                  (Ast.MetaStmt(nm,keep,Ast.SequencibleAfterDots a,i)))),[])
+      |        Ast.MetaStmt(_,_,_,_) -> (s,[])
+      |        _ -> (s,[Ast.Other s]))
+  | Ast.Seq(lbrace,decls,body,rbrace) ->
+      let index = count_nested_braces s in
+      let (bd,bda) = get_after body [Ast.WParen(rbrace,index)] in
+      let (de,_) = get_after decls bda in
+      (Ast.rewrap s (Ast.Seq(lbrace,de,bd,rbrace)),
+       [Ast.WParen(lbrace,index)])
+  | Ast.Define(header,body) ->
+      let (body,_) = get_after body a in
+      (Ast.rewrap s (Ast.Define(header,body)), [Ast.Other s])
+  | Ast.IfThen(ifheader,branch,aft) ->
+      let (br,_) = get_after_e branch a in
+      (Ast.rewrap s (Ast.IfThen(ifheader,br,aft)),[Ast.Other s])
+  | Ast.IfThenElse(ifheader,branch1,els,branch2,aft) ->
+      let (br1,_) = get_after_e branch1 a in
+      let (br2,_) = get_after_e branch2 a in
+      (Ast.rewrap s (Ast.IfThenElse(ifheader,br1,els,br2,aft)),[Ast.Other s])
+  | Ast.While(header,body,aft) ->
+      let (bd,_) = get_after_e body a in
+      (Ast.rewrap s (Ast.While(header,bd,aft)),[Ast.Other s])
+  | Ast.For(header,body,aft) ->
+      let (bd,_) = get_after_e body a in
+      (Ast.rewrap s (Ast.For(header,bd,aft)),[Ast.Other s])
+  | Ast.Do(header,body,tail) ->
+      let (bd,_) = get_after_e body a in
+      (Ast.rewrap s (Ast.Do(header,bd,tail)),[Ast.Other s])
+  | Ast.Iterator(header,body,aft) ->
+      let (bd,_) = get_after_e body a in
+      (Ast.rewrap s (Ast.Iterator(header,bd,aft)),[Ast.Other s])
+  | Ast.Switch(header,lb,cases,rb) ->
+      let cases =
+       List.map
+         (function case_line ->
+           match Ast.unwrap case_line with
+             Ast.CaseLine(header,body) ->
+               let (body,_) = get_after body [] in
+               Ast.rewrap case_line (Ast.CaseLine(header,body))
+           | Ast.OptCase(case_line) -> failwith "not supported")
+         cases in
+      (Ast.rewrap s (Ast.Switch(header,lb,cases,rb)),[Ast.Other s])
+  | Ast.FunDecl(header,lbrace,decls,body,rbrace) ->
+      let (bd,bda) = get_after body [] in
+      let (de,_) = get_after decls bda in
+      (Ast.rewrap s (Ast.FunDecl(header,lbrace,de,bd,rbrace)),[])
+  | _ -> failwith "get_after_e: not supported"
+
+let preprocess_dots sl =
+  let (sl,_) = get_before sl [] in
+  let (sl,_) = get_after sl [] in
+  sl
+
+let preprocess_dots_e sl =
+  let (sl,_) = get_before_e sl [] in
+  let (sl,_) = get_after_e sl [] in
+  sl
+
+(* --------------------------------------------------------------------- *)
+(* various return_related things *)
+
+let rec ends_in_return stmt_list =
+  match Ast.unwrap stmt_list with
+    Ast.DOTS(x) ->
+      (match List.rev x with
+       x::_ ->
+         (match Ast.unwrap x with
+           Ast.Atomic(x) ->
+             let rec loop x =
+               match Ast.unwrap x with
+                 Ast.Return(_,_) | Ast.ReturnExpr(_,_,_) -> true
+               | Ast.DisjRuleElem((_::_) as l) -> List.for_all loop l
+               | _ -> false in
+             loop x
+         | Ast.Disj(disjs) -> List.for_all ends_in_return disjs
+         | _ -> false)
+      |        _ -> false)
+  | Ast.CIRCLES(x) -> failwith "not supported"
+  | Ast.STARS(x) -> failwith "not supported"
+
+(* --------------------------------------------------------------------- *)
+(* expressions *)
+
+let exptymatch l make_match make_guard_match =
+  let pos = fresh_pos() in
+  let matches_guard_matches =
+    List.map
+      (function x ->
+       let pos = Ast.make_mcode pos in
+       (make_match (Ast.set_pos x (Some pos)),
+        make_guard_match (Ast.set_pos x (Some pos))))
+      l in
+  let (matches,guard_matches) = List.split matches_guard_matches in
+  let rec suffixes = function
+      [] -> []
+    | x::xs -> xs::(suffixes xs) in
+  let prefixes = List.rev (suffixes (List.rev guard_matches)) in
+  let info = (* not null *)
+    List.map2
+      (function matcher ->
+       function negates ->
+         CTL.Exists
+           (false,pos,
+            ctl_and CTL.NONSTRICT matcher
+              (ctl_not
+                 (ctl_uncheck (List.fold_left ctl_or_fl CTL.False negates)))))
+      matches prefixes in
+  CTL.InnerAnd(List.fold_left ctl_or_fl CTL.False (List.rev info))
+
+(* code might be a DisjRuleElem, in which case we break it apart
+   code might contain an Exp or Ty
+   this one pushes the quantifier inwards *)
+let do_re_matches label guard res quantified minus_quantified =
+  let make_guard_match x =
+    let stmt_fvs = Ast.get_mfvs x in
+    let fvs = get_unquantified minus_quantified stmt_fvs in
+    non_saved_quantify fvs (make_match None true x) in
+  let make_match x =
+    let stmt_fvs = Ast.get_fvs x in
+    let fvs = get_unquantified quantified stmt_fvs in
+    quantify guard fvs (make_match None guard x) in
+  ctl_and CTL.NONSTRICT (label_pred_maker label)
+    (match List.map Ast.unwrap res with
+      [] -> failwith "unexpected empty disj"
+    | Ast.Exp(e)::rest -> exptymatch res make_match make_guard_match
+    | Ast.Ty(t)::rest  -> exptymatch res make_match make_guard_match
+    | all ->
+       if List.exists (function Ast.Exp(_) | Ast.Ty(_) -> true | _ -> false)
+           all
+       then failwith "unexpected exp or ty";
+       List.fold_left ctl_seqor CTL.False
+         (List.rev (List.map make_match res)))
+
+(* code might be a DisjRuleElem, in which case we break it apart
+   code doesn't contain an Exp or Ty
+   this one is for use when it is not practical to push the quantifier inwards
+ *)
+let header_match label guard code : ('a, Ast.meta_name, 'b) CTL.generic_ctl =
+  match Ast.unwrap code with
+    Ast.DisjRuleElem(res) ->
+      let make_match = make_match None guard in
+      let orop = if guard then ctl_or else ctl_seqor in
+      ctl_and CTL.NONSTRICT (label_pred_maker label)
+      (List.fold_left orop CTL.False (List.map make_match res))
+  | _ -> make_match label guard code
+
+(* --------------------------------------------------------------------- *)
+(* control structures *)
+
+let end_control_structure fvs header body after_pred
+    after_checks no_after_checks (afvs,afresh,ainh,aft) after label guard =
+  (* aft indicates what is added after the whole if, which has to be added
+     to the endif node *)
+  let (aft_needed,after_branch) =
+    match aft with
+      Ast.CONTEXT(_,Ast.NOTHING) ->
+       (false,make_seq_after2 guard after_pred after)
+    | _ ->
+       let match_endif =
+         make_match label guard
+           (make_meta_rule_elem aft (afvs,afresh,ainh)) in
+       (true,
+        make_seq_after guard after_pred
+          (After(make_seq_after guard match_endif after))) in
+  let body = body after_branch in
+  let s = guard_to_strict guard in
+  (* the code *)
+  quantify guard fvs
+    (ctl_and s header
+       (opt_and guard
+         (match (after,aft_needed) with
+           (After _,_) (* pattern doesn't end here *)
+         | (_,true) (* + code added after *) -> after_checks
+         | _ -> no_after_checks)
+         (ctl_ax_absolute s body)))
+
+let ifthen ifheader branch ((afvs,_,_,_) as aft) after
+    quantified minus_quantified label llabel slabel recurse make_match guard =
+(* "if (test) thn" becomes:
+    if(test) & AX((TrueBranch & AX thn) v FallThrough v After)
+
+    "if (test) thn; after" becomes:
+    if(test) & AX((TrueBranch & AX thn) v FallThrough v (After & AXAX after))
+             & EX After
+*)
+  (* free variables *) 
+  let (efvs,bfvs) =
+    match seq_fvs quantified
+       [Ast.get_fvs ifheader;Ast.get_fvs branch;afvs] with
+      [(efvs,b1fvs);(_,b2fvs);_] -> (efvs,Common.union_set b1fvs b2fvs)
+    | _ -> failwith "not possible" in
+  let new_quantified = Common.union_set bfvs quantified in
+  let (mefvs,mbfvs) =
+    match seq_fvs minus_quantified
+       [Ast.get_mfvs ifheader;Ast.get_mfvs branch;[]] with
+      [(efvs,b1fvs);(_,b2fvs);_] -> (efvs,Common.union_set b1fvs b2fvs)
+    | _ -> failwith "not possible" in
+  let new_mquantified = Common.union_set mbfvs minus_quantified in
+  (* if header *)
+  let if_header = quantify guard efvs (make_match ifheader) in
+  (* then branch and after *)
+  let lv = get_label_ctr() in
+  let used = ref false in
+  let true_branch =
+    make_seq guard
+      [truepred label; recurse branch Tail new_quantified new_mquantified
+         (Some (lv,used)) llabel slabel guard] in
+  let after_pred = aftpred label in
+  let or_cases after_branch =
+    ctl_or true_branch (ctl_or (fallpred label) after_branch) in
+  let (if_header,wrapper) =
+    if !used
+    then
+      let label_pred = CTL.Pred (Lib_engine.Label(lv),CTL.Control) in
+      (ctl_and CTL.NONSTRICT(*???*) if_header label_pred,
+       (function body -> quantify true [lv] body))
+    else (if_header,function x -> x) in
+  wrapper
+    (end_control_structure bfvs if_header or_cases after_pred
+       (Some(ctl_ex after_pred)) None aft after label guard)
+
+let ifthenelse ifheader branch1 els branch2 ((afvs,_,_,_) as aft) after
+    quantified minus_quantified label llabel slabel recurse make_match guard =
+(*  "if (test) thn else els" becomes:
+    if(test) & AX((TrueBranch & AX thn) v
+                  (FalseBranch & AX (else & AX els)) v After)
+             & EX FalseBranch
+
+    "if (test) thn else els; after" becomes:
+    if(test) & AX((TrueBranch & AX thn) v
+                  (FalseBranch & AX (else & AX els)) v
+                  (After & AXAX after))
+             & EX FalseBranch
+             & EX After
+*)
+  (* free variables *)
+  let (e1fvs,b1fvs,s1fvs) =
+    match seq_fvs quantified
+       [Ast.get_fvs ifheader;Ast.get_fvs branch1;afvs] with
+      [(e1fvs,b1fvs);(s1fvs,b1afvs);_] ->
+       (e1fvs,Common.union_set b1fvs b1afvs,s1fvs)
+    | _ -> failwith "not possible" in
+  let (e2fvs,b2fvs,s2fvs) =
+    (* fvs on else? *)
+    match seq_fvs quantified
+       [Ast.get_fvs ifheader;Ast.get_fvs branch2;afvs] with
+      [(e2fvs,b2fvs);(s2fvs,b2afvs);_] ->
+       (e2fvs,Common.union_set b2fvs b2afvs,s2fvs)
+    | _ -> failwith "not possible" in
+  let bothfvs        = union (union b1fvs b2fvs) (intersect s1fvs s2fvs) in
+  let exponlyfvs     = intersect e1fvs e2fvs in
+  let new_quantified = union bothfvs quantified in
+  (* minus free variables *)
+  let (me1fvs,mb1fvs,ms1fvs) =
+    match seq_fvs minus_quantified
+       [Ast.get_mfvs ifheader;Ast.get_mfvs branch1;[]] with
+      [(e1fvs,b1fvs);(s1fvs,b1afvs);_] ->
+       (e1fvs,Common.union_set b1fvs b1afvs,s1fvs)
+    | _ -> failwith "not possible" in
+  let (me2fvs,mb2fvs,ms2fvs) =
+    (* fvs on else? *)
+    match seq_fvs minus_quantified
+       [Ast.get_mfvs ifheader;Ast.get_mfvs branch2;[]] with
+      [(e2fvs,b2fvs);(s2fvs,b2afvs);_] ->
+       (e2fvs,Common.union_set b2fvs b2afvs,s2fvs)
+    | _ -> failwith "not possible" in
+  let mbothfvs       = union (union mb1fvs mb2fvs) (intersect ms1fvs ms2fvs) in
+  let new_mquantified = union mbothfvs minus_quantified in
+  (* if header *)
+  let if_header = quantify guard exponlyfvs (make_match ifheader) in
+  (* then and else branches *)
+  let lv = get_label_ctr() in
+  let used = ref false in
+  let true_branch =
+    make_seq guard
+      [truepred label; recurse branch1 Tail new_quantified new_mquantified
+         (Some (lv,used)) llabel slabel guard] in
+  let false_branch =
+    make_seq guard
+      [falsepred label; make_match els;
+       recurse branch2 Tail new_quantified new_mquantified
+         (Some (lv,used)) llabel slabel guard] in
+  let after_pred = aftpred label in
+  let or_cases after_branch =
+    ctl_or true_branch (ctl_or false_branch after_branch) in
+  let s = guard_to_strict guard in
+  let (if_header,wrapper) =
+    if !used
+    then
+      let label_pred = CTL.Pred (Lib_engine.Label(lv),CTL.Control) in
+      (ctl_and CTL.NONSTRICT(*???*) if_header label_pred,
+       (function body -> quantify true [lv] body))
+    else (if_header,function x -> x) in
+  wrapper
+    (end_control_structure bothfvs if_header or_cases after_pred
+      (Some(ctl_and s (ctl_ex (falsepred label)) (ctl_ex after_pred)))
+      (Some(ctl_ex (falsepred label)))
+      aft after label guard)
+
+let forwhile header body ((afvs,_,_,_) as aft) after
+    quantified minus_quantified label recurse make_match guard =
+  let process _ =
+    (* the translation in this case is similar to that of an if with no else *)
+    (* free variables *) 
+    let (efvs,bfvs) =
+      match seq_fvs quantified [Ast.get_fvs header;Ast.get_fvs body;afvs] with
+       [(efvs,b1fvs);(_,b2fvs);_] -> (efvs,Common.union_set b1fvs b2fvs)
+      | _ -> failwith "not possible" in
+    let new_quantified = Common.union_set bfvs quantified in
+    (* minus free variables *) 
+    let (mefvs,mbfvs) =
+      match seq_fvs minus_quantified
+         [Ast.get_mfvs header;Ast.get_mfvs body;[]] with
+       [(efvs,b1fvs);(_,b2fvs);_] -> (efvs,Common.union_set b1fvs b2fvs)
+      | _ -> failwith "not possible" in
+    let new_mquantified = Common.union_set mbfvs minus_quantified in
+    (* loop header *)
+    let header = quantify guard efvs (make_match header) in
+    let lv = get_label_ctr() in
+    let used = ref false in
+    let body =
+      make_seq guard
+       [inlooppred label;
+         recurse body Tail new_quantified new_mquantified
+           (Some (lv,used)) (Some (lv,used)) None guard] in
+    let after_pred = fallpred label in
+    let or_cases after_branch = ctl_or body after_branch in
+    let (header,wrapper) =
+      if !used
+      then
+       let label_pred = CTL.Pred (Lib_engine.Label(lv),CTL.Control) in
+       (ctl_and CTL.NONSTRICT(*???*) header label_pred,
+        (function body -> quantify true [lv] body))
+      else (header,function x -> x) in
+    wrapper
+      (end_control_structure bfvs header or_cases after_pred
+        (Some(ctl_ex after_pred)) None aft after label guard) in
+  match (Ast.unwrap body,aft) with
+    (Ast.Atomic(re),(_,_,_,Ast.CONTEXT(_,Ast.NOTHING))) ->
+      (match Ast.unwrap re with
+       Ast.MetaStmt((_,_,Ast.CONTEXT(_,Ast.NOTHING),_),
+                    Type_cocci.Unitary,_,false) ->
+         let (efvs) =
+           match seq_fvs quantified [Ast.get_fvs header] with
+             [(efvs,_)] -> efvs
+           | _ -> failwith "not possible" in
+         quantify guard efvs (make_match header)
+      | _ -> process())
+  | _ -> process()
+  
+(* --------------------------------------------------------------------- *)
+(* statement metavariables *)
+
+(* issue: an S metavariable that is not an if branch/loop body
+   should not match an if branch/loop body, so check that the labels
+   of the nodes before the first node matched by the S are different
+   from the label of the first node matched by the S *)
+let sequencibility body label_pred process_bef_aft = function
+    Ast.Sequencible | Ast.SequencibleAfterDots [] ->
+      body
+       (function x ->
+         (ctl_and CTL.NONSTRICT (ctl_not (ctl_back_ax label_pred)) x))
+  | Ast.SequencibleAfterDots l ->
+      (* S appears after some dots.  l is the code that comes after the S.
+        want to search for that first, because S can match anything, while
+        the stuff after is probably more restricted *)
+      let afts = List.map process_bef_aft l in
+      let ors = foldl1 ctl_or afts in
+      ctl_and CTL.NONSTRICT
+       (ctl_ef (ctl_and CTL.NONSTRICT ors (ctl_back_ax label_pred)))
+       (body
+          (function x ->
+            ctl_and CTL.NONSTRICT (ctl_not (ctl_back_ax label_pred)) x))
+  | Ast.NotSequencible -> body (function x -> x)
+
+let svar_context_with_add_after stmt s label quantified d ast
+    seqible after process_bef_aft guard fvinfo =
+  let label_var = (*fresh_label_var*) string2var "_lab" in
+  let label_pred =
+    CTL.Pred (Lib_engine.Label(label_var),CTL.Control) in
+  let prelabel_pred =
+    CTL.Pred (Lib_engine.PrefixLabel(label_var),CTL.Control) in
+  let matcher d = make_match None guard (make_meta_rule_elem d fvinfo) in
+  let full_metamatch = matcher d in
+  let first_metamatch =
+    matcher
+      (match d with
+       Ast.CONTEXT(pos,Ast.BEFOREAFTER(bef,_)) ->
+         Ast.CONTEXT(pos,Ast.BEFORE(bef))
+      |        Ast.CONTEXT(pos,_) -> Ast.CONTEXT(pos,Ast.NOTHING)
+      | Ast.MINUS(_,_) | Ast.PLUS -> failwith "not possible") in
+  let middle_metamatch =
+    matcher
+      (match d with
+       Ast.CONTEXT(pos,_) -> Ast.CONTEXT(pos,Ast.NOTHING)
+      | Ast.MINUS(_,_) | Ast.PLUS -> failwith "not possible") in
+  let last_metamatch =
+    matcher
+      (match d with
+       Ast.CONTEXT(pos,Ast.BEFOREAFTER(_,aft)) ->
+         Ast.CONTEXT(pos,Ast.AFTER(aft))
+      |        Ast.CONTEXT(_,_) -> d
+      | Ast.MINUS(_,_) | Ast.PLUS -> failwith "not possible") in
+
+  let rest_nodes =
+    ctl_and CTL.NONSTRICT middle_metamatch prelabel_pred in  
+  let left_or = (* the whole statement is one node *)
+    make_seq guard
+      [full_metamatch; and_after guard (ctl_not prelabel_pred) after] in
+  let right_or = (* the statement covers multiple nodes *)
+    make_seq guard
+      [first_metamatch;
+        ctl_au CTL.NONSTRICT
+         rest_nodes
+         (make_seq guard
+            [ctl_and CTL.NONSTRICT last_metamatch label_pred;
+              and_after guard
+                (ctl_not prelabel_pred) after])] in
+  let body f =
+    ctl_and CTL.NONSTRICT label_pred
+       (f (ctl_and CTL.NONSTRICT
+           (make_raw_match label false ast) (ctl_or left_or right_or))) in
+  let stmt_fvs = Ast.get_fvs stmt in
+  let fvs = get_unquantified quantified stmt_fvs in
+  quantify guard (label_var::fvs)
+    (sequencibility body label_pred process_bef_aft seqible)
+
+let svar_minus_or_no_add_after stmt s label quantified d ast
+    seqible after process_bef_aft guard fvinfo =
+  let label_var = (*fresh_label_var*) string2var "_lab" in
+  let label_pred =
+    CTL.Pred (Lib_engine.Label(label_var),CTL.Control) in
+  let prelabel_pred =
+    CTL.Pred (Lib_engine.PrefixLabel(label_var),CTL.Control) in
+  let matcher d = make_match None guard (make_meta_rule_elem d fvinfo) in
+  let pure_d =
+    (* don't have to put anything before the beginning, so don't have to
+       distinguish the first node.  so don't have to bother about paths,
+       just use the label. label ensures that found nodes match up with
+       what they should because it is in the lhs of the andany. *)
+    match d with
+       Ast.MINUS(pos,[]) -> true
+      | Ast.CONTEXT(pos,Ast.NOTHING) -> true
+      | _ -> false in
+  let ender =
+    match (pure_d,after) with
+      (true,Tail) | (true,End) | (true,VeryEnd) ->
+       (* the label sharing makes it safe to use AndAny *)
+       CTL.HackForStmt(CTL.FORWARD,CTL.NONSTRICT,
+                       ctl_and CTL.NONSTRICT label_pred
+                         (make_raw_match label false ast),
+                       ctl_and CTL.NONSTRICT (matcher d) prelabel_pred)
+    | _ ->
+       (* more safe but less efficient *)
+       let first_metamatch = matcher d in
+       let rest_metamatch =
+         matcher
+           (match d with
+             Ast.MINUS(pos,_) -> Ast.MINUS(pos,[])
+           | Ast.CONTEXT(pos,_) -> Ast.CONTEXT(pos,Ast.NOTHING)
+           | Ast.PLUS -> failwith "not possible") in
+       let rest_nodes = ctl_and CTL.NONSTRICT rest_metamatch prelabel_pred in
+       let last_node = and_after guard (ctl_not prelabel_pred) after in
+       (ctl_and CTL.NONSTRICT (make_raw_match label false ast)
+          (make_seq guard
+             [first_metamatch;
+               ctl_au CTL.NONSTRICT rest_nodes last_node])) in
+  let body f = ctl_and CTL.NONSTRICT label_pred (f ender) in
+  let stmt_fvs = Ast.get_fvs stmt in
+  let fvs = get_unquantified quantified stmt_fvs in
+  quantify guard (label_var::fvs)
+    (sequencibility body label_pred process_bef_aft seqible)
+
+(* --------------------------------------------------------------------- *)
+(* dots and nests *)
+
+let dots_au is_strict toend label s wrapcode x seq_after y quantifier =
+  let matchgoto = gotopred None in
+  let matchbreak =
+    make_match None false
+      (wrapcode
+        (Ast.Break(Ast.make_mcode "break",Ast.make_mcode ";"))) in
+  let matchcontinue =
+     make_match None false
+      (wrapcode
+        (Ast.Continue(Ast.make_mcode "continue",Ast.make_mcode ";"))) in
+  let stop_early =
+    if quantifier = Exists
+    then Common.Left(CTL.False)
+    else if toend
+    then Common.Left(CTL.Or(aftpred label,exitpred label))
+    else if is_strict
+    then Common.Left(aftpred label)
+    else
+      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
+                       (if !Flag_matcher.only_return_is_error_exit
+                       then
+                         (ctl_and CTL.NONSTRICT
+                            (retpred None) (ctl_not seq_after))
+                       else
+                         (ctl_or
+                            (ctl_and CTL.NONSTRICT
+                               (ctl_or (retpred None) matchcontinue)
+                               (ctl_not seq_after))
+                            (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
+  let v = get_let_ctr() in
+  op s x
+    (match stop_early with
+      Common.Left x -> ctl_or y x
+    | Common.Right stop_early ->
+       CTL.Let(v,y,ctl_or (CTL.Ref v) (stop_early (CTL.Ref v))))
+
+let rec dots_and_nests plus nest whencodes bef aft dotcode after label
+    process_bef_aft statement_list statement guard quantified wrapcode =
+  let ctl_and_ns = ctl_and CTL.NONSTRICT in
+  (* proces bef_aft *)
+  let shortest l =
+    List.fold_left ctl_or_fl CTL.False (List.map process_bef_aft l) in
+  let bef_aft = (* to be negated *)
+    try
+      let _ =
+       List.find
+         (function Ast.WhenModifier(Ast.WhenAny) -> true | _ -> false)
+         whencodes in
+      CTL.False
+    with Not_found -> shortest (Common.union_set bef aft) in
+  let is_strict =
+    List.exists
+      (function Ast.WhenModifier(Ast.WhenStrict) -> true | _ -> false)
+      whencodes in
+  let check_quantifier quant other =
+    if List.exists
+       (function Ast.WhenModifier(x) -> x = quant | _ -> false)
+       whencodes
+    then
+      if List.exists
+         (function Ast.WhenModifier(x) -> x = other | _ -> false)
+         whencodes
+      then failwith "inconsistent annotation on dots"
+      else true
+    else false in
+  let quantifier =
+    if check_quantifier Ast.WhenExists Ast.WhenForall
+    then Exists
+    else
+      if check_quantifier Ast.WhenForall Ast.WhenExists
+      then Forall
+      else !exists in
+  (* the following is used when we find a goto, etc and consider accepting
+     without finding the rest of the pattern *)
+  let aft = shortest aft in
+  (* process whencode *)
+  let labelled = label_pred_maker label in
+  let whencodes arg =
+    let (poswhen,negwhen) =
+      List.fold_left
+       (function (poswhen,negwhen) ->
+         function
+             Ast.WhenNot whencodes ->
+               (poswhen,ctl_or (statement_list whencodes) negwhen)
+           | Ast.WhenAlways stm ->
+               (ctl_and CTL.NONSTRICT (statement stm) poswhen,negwhen)
+           | Ast.WhenModifier(_) -> (poswhen,negwhen)
+           | Ast.WhenNotTrue(e) ->
+               (poswhen,
+                 ctl_or (whencond_true e label guard quantified) negwhen)
+           | Ast.WhenNotFalse(e) ->
+               (poswhen,
+                 ctl_or (whencond_false e label guard quantified) negwhen))
+       (CTL.True,bef_aft) (List.rev whencodes) in
+    let poswhen = ctl_and_ns arg poswhen in
+    let negwhen =
+(*    if !exists
+      then*)
+        (* add in After, because it's not part of the program *)
+       ctl_or (aftpred label) negwhen
+      (*else negwhen*) in
+    ctl_and_ns poswhen (ctl_not negwhen) in
+  (* process dot code, if any *)
+  let dotcode =
+    match (dotcode,guard) with
+      (None,_) | (_,true) -> CTL.True
+    | (Some dotcode,_) -> dotcode in
+  (* process nest code, if any *)
+  (* whencode goes in the negated part of the nest; if no nest, just goes
+      on the "true" in between code *)
+  let plus_var = if plus then get_label_ctr() else string2var "" in
+  let plus_var2 = if plus then get_label_ctr() else string2var "" in
+  let ornest =
+    match (nest,guard && not plus) with
+      (None,_) | (_,true) -> whencodes CTL.True
+    | (Some nest,false) ->
+       let v = get_let_ctr() in
+       let is_plus x =
+         if plus
+         then
+           (* the idea is that BindGood is sort of a witness; a witness to
+              having found the subterm in at least one place.  If there is
+              not a witness, then there is a risk that it will get thrown
+              away, if it is merged with a node that has an empty
+              environment.  See tests/nestplus.  But this all seems
+              rather suspicious *)
+           CTL.And(CTL.NONSTRICT,x,
+                   CTL.Exists(true,plus_var2,
+                              CTL.Pred(Lib_engine.BindGood(plus_var),
+                                       CTL.Modif plus_var2)))
+         else x in
+        CTL.Let(v,nest,
+               CTL.Or(is_plus (CTL.Ref v),
+                      whencodes (CTL.Not(ctl_uncheck (CTL.Ref v))))) in
+  let plus_modifier x =
+    if plus
+    then
+      CTL.Exists
+       (false,plus_var,
+        (CTL.And
+           (CTL.NONSTRICT,x,
+            CTL.Not(CTL.Pred(Lib_engine.BindBad(plus_var),CTL.Control)))))
+    else x in
+
+  let ender =
+    match after with
+      After f -> f
+    | Guard f -> ctl_uncheck f
+    | VeryEnd ->
+       let exit = endpred label in
+       let errorexit = exitpred label in
+       ctl_or exit errorexit
+    (* not at all sure what the next two mean... *)
+    | End -> CTL.True
+    | Tail ->
+       (match label with
+         Some (lv,used) -> used := true;
+           ctl_or (CTL.Pred(Lib_engine.Label lv,CTL.Control))
+             (ctl_back_ex (ctl_or (retpred label) (gotopred label)))
+       | None -> endpred label)
+         (* was the following, but not clear why sgrep should allow
+            incomplete patterns
+       let exit = endpred label in
+       let errorexit = exitpred label in
+       if !exists
+       then ctl_or exit errorexit (* end anywhere *)
+       else exit (* end at the real end of the function *) *) in
+  plus_modifier
+    (dots_au is_strict ((after = Tail) or (after = VeryEnd))
+       label (guard_to_strict guard) wrapcode
+      (ctl_and_ns dotcode (ctl_and_ns ornest labelled))
+      aft ender quantifier)
+
+and get_whencond_exps e =
+  match Ast.unwrap e with
+    Ast.Exp e -> [e]
+  | Ast.DisjRuleElem(res) ->
+      List.fold_left Common.union_set [] (List.map get_whencond_exps res)
+  | _ -> failwith "not possible"
+
+and make_whencond_headers e e1 label guard quantified =
+  let fvs = Ast.get_fvs e in
+  let header_pred h =
+    quantify guard (get_unquantified quantified fvs)
+      (make_match label guard h) in
+  let if_header e1 =
+    header_pred
+      (Ast.rewrap e
+        (Ast.IfHeader
+           (Ast.make_mcode "if",
+            Ast.make_mcode "(",e1,Ast.make_mcode ")"))) in
+  let while_header e1 =
+    header_pred
+      (Ast.rewrap e
+        (Ast.WhileHeader
+           (Ast.make_mcode "while",
+            Ast.make_mcode "(",e1,Ast.make_mcode ")"))) in
+  let for_header e1 =
+    header_pred
+      (Ast.rewrap e
+        (Ast.ForHeader
+           (Ast.make_mcode "for",Ast.make_mcode "(",None,Ast.make_mcode ";",
+            Some e1,Ast.make_mcode ";",None,Ast.make_mcode ")"))) in
+  let if_headers =
+    List.fold_left ctl_or CTL.False (List.map if_header e1) in
+  let while_headers =
+    List.fold_left ctl_or CTL.False (List.map while_header e1) in
+  let for_headers =
+    List.fold_left ctl_or CTL.False (List.map for_header e1) in
+  (if_headers, while_headers, for_headers)
+
+and whencond_true e label guard quantified =
+  let e1 = get_whencond_exps e in
+  let (if_headers, while_headers, for_headers) =
+    make_whencond_headers e e1 label guard quantified in
+  ctl_or
+    (ctl_and CTL.NONSTRICT (truepred label) (ctl_back_ex if_headers))
+    (ctl_and CTL.NONSTRICT
+       (inlooppred label) (ctl_back_ex (ctl_or while_headers for_headers)))
+
+and whencond_false e label guard quantified =
+  let e1 = get_whencond_exps e in
+  let (if_headers, while_headers, for_headers) =
+    make_whencond_headers e e1 label guard quantified in
+  ctl_or (ctl_and CTL.NONSTRICT (falsepred label) (ctl_back_ex if_headers))
+    (ctl_and CTL.NONSTRICT (fallpred label)
+       (ctl_or (ctl_back_ex if_headers)
+         (ctl_or (ctl_back_ex while_headers) (ctl_back_ex for_headers))))
+
+(* --------------------------------------------------------------------- *)
+(* the main translation loop *)
+  
+let rec statement_list stmt_list after quantified minus_quantified
+    label llabel slabel dots_before guard =
+  let isdots x =
+    (* include Disj to be on the safe side *)
+    match Ast.unwrap x with
+      Ast.Dots _ | Ast.Nest _ | Ast.Disj _ -> true | _ -> false in
+  let compute_label l e db = if db or isdots e then l else None in
+  match Ast.unwrap stmt_list with
+    Ast.DOTS(x) ->
+      let rec loop quantified minus_quantified dots_before label llabel slabel
+         = function
+         ([],_,_) -> (match after with After f -> f | _ -> CTL.True)
+       | ([e],_,_) ->
+           statement e after quantified minus_quantified
+             (compute_label label e dots_before)
+             llabel slabel guard
+       | (e::sl,fv::fvs,mfv::mfvs) ->
+           let shared = intersectll fv fvs in
+           let unqshared = get_unquantified quantified shared in
+           let new_quantified = Common.union_set unqshared quantified in
+           let minus_shared = intersectll mfv mfvs in
+           let munqshared =
+             get_unquantified minus_quantified minus_shared in
+           let new_mquantified =
+             Common.union_set munqshared minus_quantified in
+           quantify guard unqshared
+             (statement e
+                (After
+                   (let (label1,llabel1,slabel1) =
+                     match Ast.unwrap e with
+                       Ast.Atomic(re) ->
+                         (match Ast.unwrap re with
+                           Ast.Goto _ -> (None,None,None)
+                         | _ -> (label,llabel,slabel))
+                     | _ -> (label,llabel,slabel) in
+                   loop new_quantified new_mquantified (isdots e)
+                     label1 llabel1 slabel1
+                     (sl,fvs,mfvs)))
+                new_quantified new_mquantified
+                (compute_label label e dots_before) llabel slabel guard)
+       | _ -> failwith "not possible" in
+      loop quantified minus_quantified dots_before
+       label llabel slabel
+       (x,List.map Ast.get_fvs x,List.map Ast.get_mfvs x)
+  | Ast.CIRCLES(x) -> failwith "not supported"
+  | Ast.STARS(x) -> failwith "not supported"
+
+(* llabel is the label of the enclosing loop and slabel is the label of the
+   enclosing switch *)
+and statement stmt after quantified minus_quantified
+    label llabel slabel guard =
+  let ctl_au     = ctl_au CTL.NONSTRICT in
+  let ctl_ax     = ctl_ax CTL.NONSTRICT in
+  let ctl_and    = ctl_and CTL.NONSTRICT in
+  let make_seq   = make_seq guard in
+  let make_seq_after = make_seq_after guard in
+  let real_make_match = make_match in
+  let make_match = header_match label guard in
+
+  let dots_done = ref false in (* hack for dots cases we can easily handle *)
+
+  let term =
+  match Ast.unwrap stmt with
+    Ast.Atomic(ast) ->
+      (match Ast.unwrap ast with
+       (* the following optimisation is not a good idea, because when S
+          is alone, we would like it not to match a declaration.
+          this makes more matching for things like when (...) S, but perhaps
+          that matching is not so costly anyway *)
+       (*Ast.MetaStmt(_,Type_cocci.Unitary,_,false) when guard -> CTL.True*)
+      |        Ast.MetaStmt((s,_,(Ast.CONTEXT(_,Ast.BEFOREAFTER(_,_)) as d),_),
+                    keep,seqible,_)
+      | Ast.MetaStmt((s,_,(Ast.CONTEXT(_,Ast.AFTER(_)) as d),_),
+                    keep,seqible,_)->
+         svar_context_with_add_after stmt s label quantified d ast seqible
+           after
+           (process_bef_aft quantified minus_quantified
+              label llabel slabel true)
+           guard
+           (Ast.get_fvs stmt, Ast.get_fresh stmt, Ast.get_inherited stmt)
+
+      |        Ast.MetaStmt((s,_,d,_),keep,seqible,_) ->
+         svar_minus_or_no_add_after stmt s label quantified d ast seqible
+           after
+           (process_bef_aft quantified minus_quantified
+              label llabel slabel true)
+           guard
+           (Ast.get_fvs stmt, Ast.get_fresh stmt, Ast.get_inherited stmt)
+
+      |        _ ->
+         let term =
+           match Ast.unwrap ast with
+             Ast.DisjRuleElem(res) ->
+               do_re_matches label guard res quantified minus_quantified
+           | Ast.Exp(_) | Ast.Ty(_) ->
+               let stmt_fvs = Ast.get_fvs stmt in
+               let fvs = get_unquantified quantified stmt_fvs in
+               CTL.InnerAnd(quantify guard fvs (make_match ast))
+           | _ ->
+               let stmt_fvs = Ast.get_fvs stmt in
+               let fvs = get_unquantified quantified stmt_fvs in
+               quantify guard fvs (make_match ast) in
+         match Ast.unwrap ast with
+           Ast.Break(brk,semi) ->
+             (match (llabel,slabel) with
+               (_,Some(lv,used)) -> (* use switch label if there is one *)
+                 ctl_and term (bclabel_pred_maker slabel)
+             | _ -> ctl_and term (bclabel_pred_maker llabel))
+         | Ast.Continue(brk,semi) -> ctl_and term (bclabel_pred_maker llabel)
+          | Ast.Return((_,info,retmc,pos),(_,_,semmc,_)) ->
+             (* discard pattern that comes after return *)
+             let normal_res = make_seq_after term after in
+             (* the following code tries to propagate the modifications on
+                return; to a close brace, in the case where the final return
+                is absent *)
+             let new_mc =
+               match (retmc,semmc) with
+                 (Ast.MINUS(_,l1),Ast.MINUS(_,l2)) when !Flag.sgrep_mode2 ->
+                   (* in sgrep mode, we can propagate the - *)
+                   Some (Ast.MINUS(Ast.NoPos,l1@l2))
+               | (Ast.MINUS(_,l1),Ast.MINUS(_,l2))
+               | (Ast.CONTEXT(_,Ast.BEFORE(l1)),
+                  Ast.CONTEXT(_,Ast.AFTER(l2))) ->
+                   Some (Ast.CONTEXT(Ast.NoPos,Ast.BEFORE(l1@l2)))
+               | (Ast.CONTEXT(_,Ast.BEFORE(_)),Ast.CONTEXT(_,Ast.NOTHING))
+               | (Ast.CONTEXT(_,Ast.NOTHING),Ast.CONTEXT(_,Ast.NOTHING)) ->
+                   Some retmc
+               | (Ast.CONTEXT(_,Ast.NOTHING),Ast.CONTEXT(_,Ast.AFTER(l))) ->
+                   Some (Ast.CONTEXT(Ast.NoPos,Ast.BEFORE(l)))
+               | _ -> None in
+             let ret = Ast.make_mcode "return" in
+             let edots =
+               Ast.rewrap ast (Ast.Edots(Ast.make_mcode "...",None)) in
+             let semi = Ast.make_mcode ";" in
+             let simple_return =
+               make_match(Ast.rewrap ast (Ast.Return(ret,semi))) in
+             let return_expr =
+               make_match(Ast.rewrap ast (Ast.ReturnExpr(ret,edots,semi))) in
+             (match new_mc with
+               Some new_mc ->
+                 let exit = endpred None in
+                 let mod_rbrace =
+                   Ast.rewrap ast (Ast.SeqEnd (("}",info,new_mc,pos))) in
+                 let stripped_rbrace =
+                   Ast.rewrap ast (Ast.SeqEnd(Ast.make_mcode "}")) in
+                 ctl_or normal_res
+                   (ctl_and (make_match mod_rbrace)
+                      (ctl_and
+                         (ctl_back_ax
+                            (ctl_not
+                               (ctl_uncheck
+                                  (ctl_or simple_return return_expr))))
+                         (ctl_au
+                            (make_match stripped_rbrace)
+                            (* error exit not possible; it is in the middle
+                               of code, so a return is needed *)
+                            exit)))
+             | _ ->
+                 (* some change in the middle of the return, so have to
+                    find an actual return *)
+                 normal_res)
+          | _ ->
+             (* should try to deal with the dots_bef_aft problem elsewhere,
+                but don't have the courage... *)
+             let term =
+               if guard
+               then term
+               else
+                 do_between_dots stmt term End
+                   quantified minus_quantified label llabel slabel guard in
+             dots_done := true;
+             make_seq_after term after)
+  | Ast.Seq(lbrace,decls,body,rbrace) ->
+      let (lbfvs,b1fvs,b2fvs,b3fvs,rbfvs) =
+       match
+         seq_fvs quantified
+           [Ast.get_fvs lbrace;Ast.get_fvs decls;
+             Ast.get_fvs body;Ast.get_fvs rbrace]
+       with
+         [(lbfvs,b1fvs);(_,b2fvs);(_,b3fvs);(rbfvs,_)] ->
+           (lbfvs,b1fvs,b2fvs,b3fvs,rbfvs)
+       | _ -> failwith "not possible" in
+      let (mlbfvs,mb1fvs,mb2fvs,mb3fvs,mrbfvs) =
+       match
+         seq_fvs minus_quantified
+           [Ast.get_mfvs lbrace;Ast.get_mfvs decls;
+             Ast.get_mfvs body;Ast.get_mfvs rbrace]
+       with
+         [(lbfvs,b1fvs);(_,b2fvs);(_,b3fvs);(rbfvs,_)] ->
+           (lbfvs,b1fvs,b2fvs,b3fvs,rbfvs)
+       | _ -> failwith "not possible" in
+      let pv = count_nested_braces stmt in
+      let lv = get_label_ctr() in
+      let paren_pred = CTL.Pred(Lib_engine.Paren pv,CTL.Control) in
+      let label_pred = CTL.Pred(Lib_engine.Label lv,CTL.Control) in
+      let start_brace =
+       ctl_and
+         (quantify guard lbfvs (make_match lbrace))
+         (ctl_and paren_pred label_pred) in
+      let empty_rbrace =
+       match Ast.unwrap rbrace with
+         Ast.SeqEnd((data,info,_,pos)) ->
+           Ast.rewrap rbrace(Ast.SeqEnd(Ast.make_mcode data))
+       | _ -> failwith "unexpected close brace" in
+      let end_brace =
+       (* label is not needed; paren_pred is enough *)
+       quantify guard rbfvs
+         (ctl_au (make_match empty_rbrace)
+            (ctl_and
+               (real_make_match None guard rbrace)
+               paren_pred)) in
+      let new_quantified2 =
+       Common.union_set b1fvs (Common.union_set b2fvs quantified) in
+      let new_quantified3 = Common.union_set b3fvs new_quantified2 in
+      let new_mquantified2 =
+       Common.union_set mb1fvs (Common.union_set mb2fvs minus_quantified) in
+      let new_mquantified3 = Common.union_set mb3fvs new_mquantified2 in
+      let pattern_as_given =
+       let new_quantified2 = Common.union_set [pv] new_quantified2 in
+       let new_quantified3 = Common.union_set [pv] new_quantified3 in
+       quantify true [pv;lv]
+         (quantify guard b1fvs
+            (make_seq
+               [start_brace;
+                 quantify guard b2fvs
+                   (statement_list decls
+                      (After
+                         (quantify guard b3fvs
+                            (statement_list body
+                               (After (make_seq_after end_brace after))
+                               new_quantified3 new_mquantified3
+                               (Some (lv,ref true)) (* label mostly useful *)
+                               llabel slabel true guard)))
+                      new_quantified2 new_mquantified2
+                      (Some (lv,ref true)) llabel slabel false guard)])) in
+      if ends_in_return body
+      then
+       (* matching error handling code *)
+       (* Cases:
+          1. The pattern as given
+          2. A goto, and then some close braces, and then the pattern as
+          given, but without the braces (only possible if there are no
+          decls, and open and close braces are unmodified)
+          3. Part of the pattern as given, then a goto, and then the rest
+          of the pattern.  For this case, we just check that all paths have
+          a goto within the current braces.  checking for a goto at every
+          point in the pattern seems expensive and not worthwhile. *)
+       let pattern2 =
+         let body = preprocess_dots body in (* redo, to drop braces *)
+         make_seq
+           [gotopred label;
+             ctl_au
+               (make_match empty_rbrace)
+               (ctl_ax (* skip the destination label *)
+                  (quantify guard b3fvs
+                     (statement_list body End
+                        new_quantified3 new_mquantified3 None llabel slabel
+                        true guard)))] in
+       let pattern3 =
+         let new_quantified2 = Common.union_set [pv] new_quantified2 in
+         let new_quantified3 = Common.union_set [pv] new_quantified3 in
+         quantify true [pv;lv]
+           (quantify guard b1fvs
+              (make_seq
+                 [start_brace;
+                   ctl_and
+                     (CTL.AU (* want AF even for sgrep *)
+                        (CTL.FORWARD,CTL.STRICT,
+                         CTL.Pred(Lib_engine.PrefixLabel(lv),CTL.Control),
+                         ctl_and (* brace must be eventually after goto *)
+                           (gotopred (Some (lv,ref true)))
+                           (* want AF even for sgrep *)
+                           (CTL.AF(CTL.FORWARD,CTL.STRICT,end_brace))))
+                     (quantify guard b2fvs
+                        (statement_list decls
+                           (After
+                              (quantify guard b3fvs
+                                 (statement_list body Tail
+                                       (*After
+                                          (make_seq_after
+                                             nopv_end_brace after)*)
+                                    new_quantified3 new_mquantified3
+                                    None llabel slabel true guard)))
+                           new_quantified2 new_mquantified2
+                           (Some (lv,ref true))
+                           llabel slabel false guard))])) in
+       ctl_or pattern_as_given
+         (match Ast.unwrap decls with
+           Ast.DOTS([]) -> ctl_or pattern2 pattern3
+         | Ast.DOTS(l) -> pattern3
+         | _ -> failwith "circles and stars not supported")
+      else pattern_as_given
+  | Ast.IfThen(ifheader,branch,aft) ->
+      ifthen ifheader branch aft after quantified minus_quantified
+         label llabel slabel statement make_match guard
+        
+  | Ast.IfThenElse(ifheader,branch1,els,branch2,aft) ->
+      ifthenelse ifheader branch1 els branch2 aft after quantified
+         minus_quantified label llabel slabel statement make_match guard
+
+  | Ast.While(header,body,aft) | Ast.For(header,body,aft)
+  | Ast.Iterator(header,body,aft) ->
+      forwhile header body aft after quantified minus_quantified
+       label statement make_match guard
+
+  | Ast.Disj(stmt_dots_list) -> (* list shouldn't be empty *)
+      ctl_and
+       (label_pred_maker label)
+       (List.fold_left ctl_seqor CTL.False
+          (List.map
+             (function sl ->
+               statement_list sl after quantified minus_quantified label
+                 llabel slabel true guard)
+             stmt_dots_list))
+
+  | Ast.Nest(stmt_dots,whencode,multi,bef,aft) ->
+      (* label in recursive call is None because label check is already
+        wrapped around the corresponding code *)
+
+      let bfvs =
+       match seq_fvs quantified [Ast.get_wcfvs whencode;Ast.get_fvs stmt_dots]
+       with
+         [(wcfvs,bothfvs);(bdfvs,_)] -> bothfvs
+       | _ -> failwith "not possible" in
+
+      (* no minus version because when code doesn't contain any minus code *)
+      let new_quantified = Common.union_set bfvs quantified in
+
+      quantify guard bfvs
+       (let dots_pattern =
+         statement_list stmt_dots (a2n after) new_quantified minus_quantified
+           None llabel slabel true guard in
+       dots_and_nests multi
+         (Some dots_pattern) whencode bef aft None after label
+         (process_bef_aft new_quantified minus_quantified
+            None llabel slabel true)
+         (function x ->
+           statement_list x Tail new_quantified minus_quantified None
+             llabel slabel true true)
+         (function x ->
+           statement x Tail new_quantified minus_quantified None
+             llabel slabel true)
+         guard quantified
+         (function x -> Ast.set_fvs [] (Ast.rewrap stmt x)))
+
+  | Ast.Dots((_,i,d,_),whencodes,bef,aft) ->
+      let dot_code =
+       match d with
+         Ast.MINUS(_,_) ->
+            (* no need for the fresh metavar, but ... is a bit wierd as a
+              variable name *)
+           Some(make_match (make_meta_rule_elem d ([],[],[])))
+       | _ -> None in
+      dots_and_nests false None whencodes bef aft dot_code after label
+       (process_bef_aft quantified minus_quantified None llabel slabel true)
+       (function x ->
+         statement_list x Tail quantified minus_quantified
+           None llabel slabel true true)
+       (function x ->
+         statement x Tail quantified minus_quantified None llabel slabel true)
+       guard quantified
+       (function x -> Ast.set_fvs [] (Ast.rewrap stmt x))
+
+  | Ast.Switch(header,lb,cases,rb) ->
+      let rec intersect_all = function
+         [] -> []
+       | [x] -> x
+       | x::xs -> intersect x (intersect_all xs) in
+      let rec union_all l = List.fold_left union [] l in
+      (* start normal variables *)
+      let header_fvs = Ast.get_fvs header in
+      let lb_fvs = Ast.get_fvs lb in
+      let case_fvs = List.map Ast.get_fvs cases in
+      let rb_fvs = Ast.get_fvs rb in
+      let (all_efvs,all_b1fvs,all_lbfvs,all_b2fvs,
+          all_casefvs,all_b3fvs,all_rbfvs) =
+       List.fold_left
+         (function (all_efvs,all_b1fvs,all_lbfvs,all_b2fvs,
+                    all_casefvs,all_b3fvs,all_rbfvs) ->
+           function case_fvs ->
+             match seq_fvs quantified [header_fvs;lb_fvs;case_fvs;rb_fvs] with
+               [(efvs,b1fvs);(lbfvs,b2fvs);(casefvs,b3fvs);(rbfvs,_)] ->
+                 (efvs::all_efvs,b1fvs::all_b1fvs,lbfvs::all_lbfvs,
+                  b2fvs::all_b2fvs,casefvs::all_casefvs,b3fvs::all_b3fvs,
+                  rbfvs::all_rbfvs)
+             | _ -> failwith "not possible")
+         ([],[],[],[],[],[],[]) case_fvs in
+      let (all_efvs,all_b1fvs,all_lbfvs,all_b2fvs,
+          all_casefvs,all_b3fvs,all_rbfvs) =
+       (List.rev all_efvs,List.rev all_b1fvs,List.rev all_lbfvs,
+        List.rev all_b2fvs,List.rev all_casefvs,List.rev all_b3fvs,
+        List.rev all_rbfvs) in
+      let exponlyfvs = intersect_all all_efvs in
+      let lbonlyfvs = intersect_all all_lbfvs in
+(* don't do anything with right brace.  Hope there is no + code on it *)
+(*      let rbonlyfvs = intersect_all all_rbfvs in*)
+      let b1fvs = union_all all_b1fvs in
+      let new1_quantified = union b1fvs quantified in
+      let b2fvs = union (union_all all_b1fvs) (intersect_all all_casefvs) in
+      let new2_quantified = union b2fvs new1_quantified in
+(*      let b3fvs = union_all all_b3fvs in*)
+      (* ------------------- start minus free variables *)
+      let header_mfvs = Ast.get_mfvs header in
+      let lb_mfvs = Ast.get_mfvs lb in
+      let case_mfvs = List.map Ast.get_mfvs cases in
+      let rb_mfvs = Ast.get_mfvs rb in
+      let (all_mefvs,all_mb1fvs,all_mlbfvs,all_mb2fvs,
+          all_mcasefvs,all_mb3fvs,all_mrbfvs) =
+       List.fold_left
+         (function (all_efvs,all_b1fvs,all_lbfvs,all_b2fvs,
+                    all_casefvs,all_b3fvs,all_rbfvs) ->
+           function case_mfvs ->
+             match
+               seq_fvs quantified
+                 [header_mfvs;lb_mfvs;case_mfvs;rb_mfvs] with
+               [(efvs,b1fvs);(lbfvs,b2fvs);(casefvs,b3fvs);(rbfvs,_)] ->
+                 (efvs::all_efvs,b1fvs::all_b1fvs,lbfvs::all_lbfvs,
+                  b2fvs::all_b2fvs,casefvs::all_casefvs,b3fvs::all_b3fvs,
+                  rbfvs::all_rbfvs)
+             | _ -> failwith "not possible")
+         ([],[],[],[],[],[],[]) case_mfvs in
+      let (all_mefvs,all_mb1fvs,all_mlbfvs,all_mb2fvs,
+          all_mcasefvs,all_mb3fvs,all_mrbfvs) =
+       (List.rev all_mefvs,List.rev all_mb1fvs,List.rev all_mlbfvs,
+        List.rev all_mb2fvs,List.rev all_mcasefvs,List.rev all_mb3fvs,
+        List.rev all_mrbfvs) in
+(* don't do anything with right brace.  Hope there is no + code on it *)
+(*      let rbonlyfvs = intersect_all all_rbfvs in*)
+      let mb1fvs = union_all all_mb1fvs in
+      let new1_mquantified = union mb1fvs quantified in
+      let mb2fvs = union (union_all all_mb1fvs) (intersect_all all_mcasefvs) in
+      let new2_mquantified = union mb2fvs new1_mquantified in
+(*      let b3fvs = union_all all_b3fvs in*)
+      (* ------------------- end collection of free variables *)
+      let switch_header = quantify guard exponlyfvs (make_match header) in
+      let lb = quantify guard lbonlyfvs (make_match lb) in
+(*      let rb = quantify guard rbonlyfvs (make_match rb) in*)
+      let case_headers =
+       List.map
+         (function case_line ->
+           match Ast.unwrap case_line with
+             Ast.CaseLine(header,body) ->
+               let e1fvs =
+                 match seq_fvs new2_quantified [Ast.get_fvs header] with
+                   [(e1fvs,_)] -> e1fvs
+                 | _ -> failwith "not possible" in
+               quantify guard e1fvs (real_make_match label true header)
+           | Ast.OptCase(case_line) -> failwith "not supported")
+         cases in
+      let no_header =
+       ctl_not (List.fold_left ctl_or_fl CTL.False case_headers) in
+      let lv = get_label_ctr() in
+      let used = ref false in
+      let case_code =
+       List.map
+         (function case_line ->
+           match Ast.unwrap case_line with
+             Ast.CaseLine(header,body) ->
+                 let (e1fvs,b1fvs,s1fvs) =
+                   let fvs = [Ast.get_fvs header;Ast.get_fvs body] in
+                   match seq_fvs new2_quantified fvs with
+                     [(e1fvs,b1fvs);(s1fvs,_)] -> (e1fvs,b1fvs,s1fvs)
+                   | _ -> failwith "not possible" in
+                 let (me1fvs,mb1fvs,ms1fvs) =
+                   let fvs = [Ast.get_mfvs header;Ast.get_mfvs body] in
+                   match seq_fvs new2_mquantified fvs with
+                     [(e1fvs,b1fvs);(s1fvs,_)] -> (e1fvs,b1fvs,s1fvs)
+                   | _ -> failwith "not possible" in
+                 let case_header =
+                   quantify guard e1fvs (make_match header) in
+                 let new3_quantified = union b1fvs new2_quantified in
+                 let new3_mquantified = union mb1fvs new2_mquantified in
+                 let body =
+                   statement_list body Tail
+                     new3_quantified new3_mquantified label llabel
+                     (Some (lv,used)) true(*?*) guard in
+                 quantify guard b1fvs (make_seq [case_header; body])
+           | Ast.OptCase(case_line) -> failwith "not supported")
+         cases in
+      let default_required =
+       if List.exists
+           (function case ->
+             match Ast.unwrap case with
+               Ast.CaseLine(header,_) ->
+                 (match Ast.unwrap header with
+                   Ast.Default(_,_) -> true
+                 | _ -> false)
+             | _ -> false)
+           cases
+       then function x -> x
+       else function x -> ctl_or (fallpred label) x in
+      let after_pred = aftpred label in
+      let body after_branch =
+       ctl_or
+         (default_required
+            (quantify guard b2fvs
+               (make_seq
+                  [ctl_and lb
+                      (List.fold_left ctl_and CTL.True
+                         (List.map ctl_ex case_headers));
+                    List.fold_left ctl_or_fl no_header case_code])))
+         after_branch in
+      let aft =
+       (rb_fvs,Ast.get_fresh rb,Ast.get_inherited rb,
+       match Ast.unwrap rb with
+         Ast.SeqEnd(rb) -> Ast.get_mcodekind rb
+       | _ -> failwith "not possible") in
+      let (switch_header,wrapper) =
+       if !used
+       then
+         let label_pred = CTL.Pred (Lib_engine.Label(lv),CTL.Control) in
+         (ctl_and switch_header label_pred,
+          (function body -> quantify true [lv] body))
+       else (switch_header,function x -> x) in
+      wrapper
+       (end_control_structure b1fvs switch_header body
+          after_pred (Some(ctl_ex after_pred)) None aft after label guard)
+  | Ast.FunDecl(header,lbrace,decls,body,rbrace) ->
+      let (hfvs,b1fvs,lbfvs,b2fvs,b3fvs,b4fvs,rbfvs) =
+       match
+         seq_fvs quantified
+           [Ast.get_fvs header;Ast.get_fvs lbrace;Ast.get_fvs decls;
+             Ast.get_fvs body;Ast.get_fvs rbrace]
+       with
+         [(hfvs,b1fvs);(lbfvs,b2fvs);(_,b3fvs);(_,b4fvs);(rbfvs,_)] ->
+           (hfvs,b1fvs,lbfvs,b2fvs,b3fvs,b4fvs,rbfvs)
+       | _ -> failwith "not possible" in
+      let (mhfvs,mb1fvs,mlbfvs,mb2fvs,mb3fvs,mb4fvs,mrbfvs) =
+       match
+         seq_fvs quantified
+           [Ast.get_mfvs header;Ast.get_mfvs lbrace;Ast.get_mfvs decls;
+             Ast.get_mfvs body;Ast.get_mfvs rbrace]
+       with
+         [(hfvs,b1fvs);(lbfvs,b2fvs);(_,b3fvs);(_,b4fvs);(rbfvs,_)] ->
+           (hfvs,b1fvs,lbfvs,b2fvs,b3fvs,b4fvs,rbfvs)
+       | _ -> failwith "not possible" in
+      let function_header = quantify guard hfvs (make_match header) in
+      let start_brace = quantify guard lbfvs (make_match lbrace) in
+      let stripped_rbrace =
+       match Ast.unwrap rbrace with
+         Ast.SeqEnd((data,info,_,_)) ->
+           Ast.rewrap rbrace(Ast.SeqEnd (Ast.make_mcode data))
+       | _ -> failwith "unexpected close brace" in
+      let end_brace =
+       let exit = CTL.Pred (Lib_engine.Exit,CTL.Control) in
+       let errorexit = CTL.Pred (Lib_engine.ErrorExit,CTL.Control) in
+       let fake_brace = CTL.Pred (Lib_engine.FakeBrace,CTL.Control) in
+       ctl_and
+         (quantify guard rbfvs (make_match rbrace))
+         (ctl_and
+            (* the following finds the beginning of the fake braces,
+               if there are any, not completely sure how this works.
+            sse the examples sw and return *)
+            (ctl_back_ex (ctl_not fake_brace))
+            (ctl_au (make_match stripped_rbrace) (ctl_or exit errorexit))) in
+      let new_quantified3 =
+       Common.union_set b1fvs
+         (Common.union_set b2fvs (Common.union_set b3fvs quantified)) in
+      let new_quantified4 = Common.union_set b4fvs new_quantified3 in
+      let new_mquantified3 =
+       Common.union_set mb1fvs
+         (Common.union_set mb2fvs
+            (Common.union_set mb3fvs minus_quantified)) in
+      let new_mquantified4 = Common.union_set mb4fvs new_mquantified3 in
+      let fn_nest =
+       match (Ast.undots decls,Ast.undots body,
+              contains_modif rbrace or contains_pos 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,_,_) 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 =
+       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.WhenNotTrue(_) | Ast.WhenNotFalse(_) ->
+                                     failwith "unexpected"
+                                 | 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.WhenNotTrue(_) | Ast.WhenNotFalse(_) ->
+                                  failwith "unexpected"
+                              | Ast.WhenModifier(Ast.WhenAny) -> CTL.True
+                              | Ast.WhenModifier(_) -> prev)
+                          CTL.True whencode) in
+                   ctl_au leftarg (make_match stripped_rbrace)]
+       | None ->
+           make_seq
+             [start_brace;
+               quantify guard b3fvs
+                 (statement_list decls
+                    (After
+                       (quantify guard b4fvs
+                          (statement_list body
+                             (After (make_seq_after end_brace after))
+                             new_quantified4 new_mquantified4
+                             None llabel slabel true guard)))
+                    new_quantified3 new_mquantified3 None llabel slabel
+                    false guard)] in
+      quantify guard b1fvs
+       (make_seq [function_header; quantify guard b2fvs body_code])
+  | Ast.Define(header,body) ->
+      let (hfvs,bfvs,bodyfvs) =
+       match seq_fvs quantified [Ast.get_fvs header;Ast.get_fvs body]
+       with
+         [(hfvs,b1fvs);(bodyfvs,_)] -> (hfvs,b1fvs,bodyfvs)
+       | _ -> failwith "not possible" in
+      let (mhfvs,mbfvs,mbodyfvs) =
+       match seq_fvs minus_quantified [Ast.get_mfvs header;Ast.get_mfvs body]
+       with
+         [(hfvs,b1fvs);(bodyfvs,_)] -> (hfvs,b1fvs,bodyfvs)
+       | _ -> failwith "not possible" in
+      let define_header = quantify guard hfvs (make_match header) in
+      let body_code =
+       statement_list body after
+         (Common.union_set bfvs quantified)
+         (Common.union_set mbfvs minus_quantified)
+         None llabel slabel true guard in
+      quantify guard bfvs (make_seq [define_header; body_code])
+  | Ast.OptStm(stm) ->
+      failwith "OptStm should have been compiled away\n"
+  | Ast.UniqueStm(stm) -> failwith "arities not yet supported"
+  | _ -> failwith "not supported" in
+  if guard or !dots_done
+  then term
+  else
+    do_between_dots stmt term after quantified minus_quantified
+      label llabel slabel guard
+
+(* term is the translation of stmt *)
+and do_between_dots stmt term after quantified minus_quantified
+    label llabel slabel guard =
+    match Ast.get_dots_bef_aft stmt with
+      Ast.AddingBetweenDots (brace_term,n)
+    | Ast.DroppingBetweenDots (brace_term,n) ->
+       let match_brace =
+         statement brace_term after quantified minus_quantified
+           label llabel slabel guard in
+       let v = Printf.sprintf "_r_%d" n in
+       let case1 = ctl_and CTL.NONSTRICT (CTL.Ref v) match_brace in
+       let case2 = ctl_and CTL.NONSTRICT (ctl_not (CTL.Ref v)) term in
+       CTL.Let
+         (v,ctl_or
+            (ctl_back_ex (ctl_or (truepred label) (inlooppred label)))
+            (ctl_back_ex (ctl_back_ex (falsepred label))),
+          ctl_or case1 case2)   
+    | Ast.NoDots -> term
+
+(* un_process_bef_aft is because we don't want to do transformation in this
+  code, and thus don't case about braces before or after it *)
+and process_bef_aft quantified minus_quantified label llabel slabel guard =
+  function
+    Ast.WParen (re,n) ->
+      let paren_pred = CTL.Pred (Lib_engine.Paren n,CTL.Control) in
+      let s = guard_to_strict guard in
+      quantify true (get_unquantified quantified [n])
+       (ctl_and s (make_raw_match None guard re) paren_pred)
+  | Ast.Other s ->
+      statement s Tail quantified minus_quantified label llabel slabel guard
+  | Ast.Other_dots d ->
+      statement_list d Tail quantified minus_quantified
+       label llabel slabel true guard
+
+(* --------------------------------------------------------------------- *)
+(* cleanup: convert AX to EX for pdots.
+Concretely: AX(A[...] & E[...]) becomes AX(A[...]) & EX(E[...])
+This is what we wanted in the first place, but it wasn't possible to make
+because the AX and its argument are not created in the same place.
+Rather clunky... *)
+(* also cleanup XX, which is a marker for the case where the programmer
+specifies to change the quantifier on .... Assumed to only occur after one AX
+or EX, or at top level. *)
+
+let rec cleanup c =
+  let c = match c with CTL.XX(c) -> c | _ -> c in
+  match c with
+    CTL.False    -> CTL.False
+  | CTL.True     -> CTL.True
+  | CTL.Pred(p)  -> CTL.Pred(p)
+  | CTL.Not(phi) -> CTL.Not(cleanup phi)
+  | CTL.Exists(keep,v,phi) -> CTL.Exists(keep,v,cleanup phi)
+  | CTL.AndAny(dir,s,phi1,phi2) ->
+      CTL.AndAny(dir,s,cleanup phi1,cleanup phi2)
+  | CTL.HackForStmt(dir,s,phi1,phi2) ->
+      CTL.HackForStmt(dir,s,cleanup phi1,cleanup phi2)
+  | CTL.And(s,phi1,phi2)   -> CTL.And(s,cleanup phi1,cleanup phi2)
+  | CTL.Or(phi1,phi2)      -> CTL.Or(cleanup phi1,cleanup phi2)
+  | CTL.SeqOr(phi1,phi2)   -> CTL.SeqOr(cleanup phi1,cleanup phi2)
+  | CTL.Implies(phi1,phi2) -> CTL.Implies(cleanup phi1,cleanup phi2)
+  | CTL.AF(dir,s,phi1) -> CTL.AF(dir,s,cleanup phi1)
+  | CTL.AX(CTL.FORWARD,s,
+          CTL.Let(v1,e1,
+                  CTL.And(CTL.NONSTRICT,CTL.AU(CTL.FORWARD,s2,e2,e3),
+                          CTL.EU(CTL.FORWARD,e4,e5)))) ->
+    CTL.Let(v1,e1,
+           CTL.And(CTL.NONSTRICT,
+                   CTL.AX(CTL.FORWARD,s,CTL.AU(CTL.FORWARD,s2,e2,e3)),
+                   CTL.EX(CTL.FORWARD,CTL.EU(CTL.FORWARD,e4,e5))))
+  | CTL.AX(dir,s,CTL.XX(phi)) -> CTL.EX(dir,cleanup phi)
+  | CTL.EX(dir,CTL.XX((CTL.AU(_,s,_,_)) as phi)) ->
+      CTL.AX(dir,s,cleanup phi)
+  | CTL.XX(phi)               -> failwith "bad XX"
+  | CTL.AX(dir,s,phi1) -> CTL.AX(dir,s,cleanup phi1)
+  | CTL.AG(dir,s,phi1) -> CTL.AG(dir,s,cleanup phi1)
+  | CTL.EF(dir,phi1)   -> CTL.EF(dir,cleanup phi1)
+  | CTL.EX(dir,phi1)   -> CTL.EX(dir,cleanup phi1)
+  | CTL.EG(dir,phi1)   -> CTL.EG(dir,cleanup phi1)
+  | CTL.AW(dir,s,phi1,phi2) -> CTL.AW(dir,s,cleanup phi1,cleanup phi2)
+  | CTL.AU(dir,s,phi1,phi2) -> CTL.AU(dir,s,cleanup phi1,cleanup phi2)
+  | CTL.EU(dir,phi1,phi2)   -> CTL.EU(dir,cleanup phi1,cleanup phi2)
+  | CTL.Let (x,phi1,phi2)   -> CTL.Let (x,cleanup phi1,cleanup phi2)
+  | CTL.LetR (dir,x,phi1,phi2) -> CTL.LetR (dir,x,cleanup phi1,cleanup phi2)
+  | CTL.Ref(s) -> CTL.Ref(s)
+  | CTL.Uncheck(phi1)  -> CTL.Uncheck(cleanup phi1)
+  | CTL.InnerAnd(phi1) -> CTL.InnerAnd(cleanup phi1)
+
+(* --------------------------------------------------------------------- *)
+(* Function declaration *)
+
+let top_level name (ua,pos) t =
+  let ua = List.filter (function (nm,_) -> nm = name) ua in
+  used_after := ua;
+  saved := Ast.get_saved t;
+  let quantified = Common.minus_set ua pos in
+  quantify false quantified
+    (match Ast.unwrap t with
+      Ast.FILEINFO(old_file,new_file) -> failwith "not supported fileinfo"
+    | Ast.DECL(stmt) ->
+       let unopt = elim_opt.V.rebuilder_statement stmt in
+       let unopt = preprocess_dots_e unopt in
+       cleanup(statement unopt VeryEnd quantified [] None None None false)
+    | Ast.CODE(stmt_dots) ->
+       let unopt = elim_opt.V.rebuilder_statement_dots stmt_dots in
+       let unopt = preprocess_dots unopt in
+       let starts_with_dots =
+         match Ast.undots stmt_dots with
+           d::ds ->
+             (match Ast.unwrap d with
+               Ast.Dots(_,_,_,_) | Ast.Circles(_,_,_,_)
+             | Ast.Stars(_,_,_,_) -> true
+             | _ -> false)
+         | _ -> false in
+       let starts_with_brace =
+         match Ast.undots stmt_dots with
+           d::ds ->
+             (match Ast.unwrap d with
+               Ast.Seq(_) -> true
+             | _ -> false)
+         | _ -> false in
+       let res =
+         statement_list unopt VeryEnd quantified [] None None None
+           false false in
+       cleanup
+         (if starts_with_dots
+         then
+         (* EX because there is a loop on enter/top *)
+           ctl_and CTL.NONSTRICT (toppred None) (ctl_ex res)
+         else if starts_with_brace
+         then
+            ctl_and CTL.NONSTRICT
+             (ctl_not(CTL.EX(CTL.BACKWARD,(funpred None)))) res
+         else res)
+    | Ast.ERRORWORDS(exps) -> failwith "not supported errorwords")
+
+(* --------------------------------------------------------------------- *)
+(* Entry points *)
+
+let asttoctlz (name,(_,_,exists_flag),l) used_after positions =
+  letctr := 0;
+  labelctr := 0;
+  (match exists_flag with
+    Ast.Exists -> exists := Exists
+  | Ast.Forall -> exists := Forall
+  | Ast.ReverseForall -> exists := ReverseForall
+  | Ast.Undetermined ->
+      exists := if !Flag.sgrep_mode2 then Exists else Forall);
+
+  let (l,used_after) =
+    List.split
+      (List.filter
+        (function (t,_) ->
+          match Ast.unwrap t with Ast.ERRORWORDS(exps) -> false | _ -> true)
+        (List.combine l (List.combine used_after positions))) in
+  let res = List.map2 (top_level name) used_after l in
+  exists := Forall;
+  res
+
+let asttoctl r used_after positions =
+  match r with
+    Ast.ScriptRule _ -> []
+  | Ast.CocciRule (a,b,c,_,Ast_cocci.Normal) ->
+      asttoctlz (a,b,c) used_after positions
+  | Ast.CocciRule (a,b,c,_,Ast_cocci.Generated) -> [CTL.True]
+
+let pp_cocci_predicate (pred,modif) =
+  Pretty_print_engine.pp_predicate pred
+
+let cocci_predicate_to_string (pred,modif) =
+  Pretty_print_engine.predicate_to_string pred
diff --git a/engine/.#cocci_vs_c.ml.1.28 b/engine/.#cocci_vs_c.ml.1.28
new file mode 100644 (file)
index 0000000..4b4bee4
--- /dev/null
@@ -0,0 +1,3765 @@
+(*
+* Copyright 2005-2009, 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
+
+module Flag = Flag_matcher
+
+(*****************************************************************************)
+(* 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)
+
+    | A.CONTEXT ((A.FixPos _|A.DontCarePos), _) 
+    | A.MINUS ((A.FixPos _|A.DontCarePos), _)
+        ->
+        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
+  | _, B.GetRefLabel -> false (* todo cocci? *)
+  | _, (B.Not|B.Tilde|B.UnMinus|B.UnPlus|B.DeRef|B.GetRef) -> false
+      
+
+
+let equal_arithOp a b = 
+  match a, b with
+  | A.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
+  | _, (B.Xor|B.Or|B.And|B.DecRight|B.DecLeft|B.Mod|B.Div|B.Mul|B.Minus|B.Plus)
+      -> false
+
+let equal_logicalOp a b = 
+  match a, b with
+  | A.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
+  | _, (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
+  | _, (B.OpAssign _|B.SimpleAssign) -> false
+
+let equal_fixOp a b = 
+  match a, b with
+  | A.Dec, B.Dec -> true
+  | A.Inc, B.Inc -> true
+  | _, (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
+  | _, (B.Logical _ | B.Arith _) -> false
+
+let equal_structUnion a b = 
+  match a, b with
+  | A.Struct, B.Struct -> true
+  | A.Union,  B.Union -> true
+  | _, (B.Struct|B.Union) -> false
+
+let equal_sign a b = 
+  match a, b with
+  | A.Signed,    B.Signed   -> true
+  | A.Unsigned,  B.UnSigned -> true
+  | _, (B.UnSigned|B.Signed) -> 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
+  | _, (B.NoSto | B.StoTypedef) -> false
+  | _, (B.Sto (B.Register|B.Static|B.Auto|B.Extern)) -> 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.MetaInitVal a, Ast_c.MetaInitVal b -> 
+      Lib_parsing_c.al_init a =*= Lib_parsing_c.al_init 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,cea,posa1,posa2) ->
+         List.exists
+           (function (flb,ceb,posb1,posb2) ->
+             fla = flb && cea = ceb &&
+             Ast_c.equal_posl posa1 posb1 && Ast_c.equal_posl posa2 posb2)
+            l2)
+       l1
+
+  | (B.MetaPosValList _|B.MetaListlenVal _|B.MetaPosVal _|B.MetaStmtVal _
+      |B.MetaTypeVal _ |B.MetaInitVal _
+      |B.MetaParamListVal _|B.MetaParamVal _|B.MetaExprListVal _
+      |B.MetaExprVal _|B.MetaLocalFuncVal _|B.MetaFuncVal _|B.MetaIdVal _
+    ), _
+      -> 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 ({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) -> 
+              (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 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 cocciInit : 
+      (A.initialiser, B.initialiser) matcher -> (A.initialiser, F.node) matcher
+
+    val envf :
+      A.keep_binding -> A.inherited -> 
+      A.meta_name A.mcode * Ast_c.metavar_binding_kind *
+         (unit -> Common.filename * string * 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 *)
+          )
+
+      | _, B.MultiString -> (* todo cocci? *) fail
+      | _, (B.String _ | B.Float _ | B.Char _ | B.Int _) -> 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
+
+
+  | _, 
+     (((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
+
+
+
+
+
+
+(* ------------------------------------------------------------------------- *)
+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))
+          ))))))))
+
+  | _, (B.MacroDecl _ |B.DeclList _) -> 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), 
+   ({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) ->
+
+     (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,
+                     (({B.v_namei = Some ((idb, None),[iidb]);
+                        B.v_type = typb0;
+                        B.v_storage = (B.StoTypedef, inl);
+                        B.v_local = local;
+                        B.v_attr = attrs;
+                     },
+                       iivirg),iiptvirgb,iistob)
+                     )
+                | _ -> raise Impossible    
+             )
+
+           | A.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,
+                     (({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    
+             )
+           | _ -> raise Impossible
+           )
+         | _ -> fail
+       )))))
+     | _ -> fail
+     )
+   | _ -> fail
+   )
+         
+   | A.UnInit (stoa, typa, ida, ptvirga), 
+     ({B.v_namei = Some ((idb, _),[iidb]);
+       B.v_storage = (B.StoTypedef,_);
+     }, iivirg) -> 
+       fail
+
+   | A.Init (stoa, typa, ida, eqa, inia, ptvirga), 
+     ({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), 
+     ({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) -> 
+       storage_optional_allminus allminus stoa (stob, iistob) >>= 
+        (fun stoa (stob, iistob) -> 
+         return (
+           (A.UnInit (stoa, typa, ida, ptvirga)) +>  A.rewrap decla,
+           (({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), 
+     ({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 -> 
+       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,
+           (({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), 
+     ({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,
+             (({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), 
+     ({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 -> 
+       (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,
+           (({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)
+         )
+       ))))
+             
+       
+   | _, ({B.v_namei = None;}, _) -> 
+       (* 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"
+
+   | _, ({B.v_namei=Some _}, _)
+       -> 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.MetaInit(ida,keep,inherited), ib) -> 
+       let max_min _ =
+         Lib_parsing_c.lin_col_by_pos (Lib_parsing_c.ii_of_ini ib) in
+       X.envf keep inherited (ida, Ast_c.MetaInitVal ib, max_min)
+         (fun () -> 
+           X.distrf_ini ida ib >>= (fun ida ib -> 
+             return (
+               A.MetaInit (ida,keep,inherited) +> A.rewrap ia,
+               ib
+            ))
+         )
+
+    | (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.InitGccExt (designatorsa, ia2, inia), 
+      (B.InitDesignators (designatorsb, inib), ii2))->
+
+        let iieq = tuple_of_list1 ii2 in
+
+        tokenf ia2 iieq >>= (fun ia2 iieq -> 
+       designators designatorsa designatorsb >>=
+         (fun designatorsa designatorsb ->
+        initialiser inia inib >>= (fun inia inib -> 
+          return (
+            (A.InitGccExt (designatorsa, ia2, inia)) +> A.rewrap ia,
+            (B.InitDesignators (designatorsb, inib), [iieq])
+          ))))
+
+
+
+
+    | (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"
+
+    | _, (B.InitIndexOld (_, _), _) -> fail 
+    | _, (B.InitFieldOld (_, _), _) -> fail 
+
+    | _, ((B.InitDesignators (_, _)|B.InitList _|B.InitExpr _), _)
+        -> fail
+
+and designators dla dlb =
+  match (dla,dlb) with
+    ([],[]) -> return ([], [])
+  | ([],_) | (_,[]) -> fail
+  | (da::dla,db::dlb) ->
+      designator da db >>= (fun da db ->
+      designators dla dlb >>= (fun dla dlb ->
+      return (da::dla, db::dlb)))
+
+and designator da db =
+  match (da,db) with
+    (A.DesignatorField (ia1, ida), (B.DesignatorField idb,ii1)) ->
+
+        let (iidot, iidb) = tuple_of_list2 ii1 in
+        tokenf ia1 iidot >>= (fun ia1 iidot -> 
+        ident DontKnow ida (idb, iidb) >>= (fun ida (idb, iidb) ->
+          return (
+            A.DesignatorField (ia1, ida),
+            (B.DesignatorField idb, [iidot;iidb])
+          )))
+
+  | (A.DesignatorIndex (ia1,ea,ia2), (B.DesignatorIndex eb, ii1)) ->
+        
+        let (ib1, ib2) = tuple_of_list2 ii1 in
+        tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
+        tokenf ia2 ib2 >>= (fun ia2 ib2 -> 
+        expression ea eb >>= (fun ea eb -> 
+          return (
+            A.DesignatorIndex (ia1,ea,ia2),
+            (B.DesignatorIndex eb, [ib1;ib2])
+          ))))
+
+  | (A.DesignatorRange (ia1,e1a,ia2,e2a,ia3),
+     (B.DesignatorRange (e1b, e2b), ii1)) ->
+
+        let (ib1, ib2, ib3) = tuple_of_list3 ii1 in
+        tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
+        tokenf ia2 ib2 >>= (fun ia2 ib2 -> 
+        tokenf ia3 ib3 >>= (fun ia3 ib3 -> 
+        expression e1a e1b >>= (fun e1a e1b -> 
+        expression e2a e2b >>= (fun e2a e2b -> 
+          return (
+            A.DesignatorRange (ia1,e1a,ia2,e2a,ia3),
+            (B.DesignatorRange (e1b, e2b), [ib1;ib2;ib3])
+          ))))))
+  | (_, ((B.DesignatorField _|B.DesignatorIndex _|B.DesignatorRange _), _)) ->
+      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 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) matcher) = fun fa fb -> 
+  let (xfield, iifield) = fb in
+
+  match xfield with 
+  | B.DeclarationField (B.FieldDeclList (onefield_multivars,iiptvirg)) -> 
+
+    let iiptvirgb = tuple_of_list1 iiptvirg in
+
+    (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 = 
+            ({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
+              | ({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.DeclarationField 
+                        (B.FieldDeclList ([onevar, iivirg], [iiptvirgb]))),
+                    iifield)
+                  )
+              | _ -> raise Impossible
+            )
+      )
+
+    | x::y::xs -> 
+      pr2_once "PB: More that one variable in decl. Have to split";
+      fail
+    )
+  | B.EmptyField -> 
+      let _iiptvirgb = tuple_of_list1 iifield in
+      fail
+
+  | B.MacroStructDeclTodo -> fail
+  | B.CppDirectiveStruct directive -> fail
+  | B.IfdefStruct directive -> 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 simulate_signed ta basea stringsa signaopt tb baseb ii rebuilda =
+      (* 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 basea, baseb with
+      | A.VoidType,  B.Void 
+      | A.FloatType, B.FloatType (B.CFloat)
+      | A.DoubleType, B.FloatType (B.CDouble) -> 
+           assert (signaopt = None); 
+          let stringa = tuple_of_list1 stringsa in
+           let (ibaseb) = tuple_of_list1 ii in 
+           tokenf stringa ibaseb >>= (fun stringa ibaseb -> 
+             return (
+               (rebuilda ([stringa], signaopt)) +> A.rewrap ta,
+               (B.BaseType baseb, [ibaseb])
+             ))
+            
+      | A.CharType,  B.IntType B.CChar when signaopt = None -> 
+         let stringa = tuple_of_list1 stringsa in
+          let ibaseb = tuple_of_list1 ii in
+           tokenf stringa ibaseb >>= (fun stringa ibaseb -> 
+             return (
+               (rebuilda ([stringa], signaopt)) +> A.rewrap ta,
+               (B.BaseType (B.IntType B.CChar), [ibaseb])
+             ))
+            
+      | A.CharType,B.IntType (B.Si (_sign, B.CChar2)) when signaopt <> None -> 
+         let stringa = tuple_of_list1 stringsa in
+          let ibaseb = tuple_of_list1 iibaseb in
+          sign signaopt signbopt >>= (fun signaopt iisignbopt -> 
+          tokenf stringa ibaseb >>= (fun stringa ibaseb -> 
+            return (
+               (rebuilda ([stringa], 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))  ->
+         let stringa = tuple_of_list1 stringsa in
+          (match iibaseb with 
+          | [] -> 
+              (* iso-by-presence ? *)
+              (* when unsigned int in SP,  allow have just unsigned in C ? *)
+              if mcode_contain_plus (mcodekind stringa)
+              then fail
+              else 
+                
+                sign signaopt signbopt >>= (fun signaopt iisignbopt -> 
+                    return (
+                      (rebuilda ([stringa], 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 stringa ibaseb >>= (fun stringa ibaseb -> 
+            return (
+               (rebuilda ([stringa], signaopt)) +> A.rewrap ta,
+               (B.BaseType (baseb), iisignbopt ++ [ibaseb])
+               )))
+          | _ -> raise Impossible
+
+          )
+
+            
+      | A.LongLongType, B.IntType (B.Si (_, B.CLongLong)) ->
+         let (string1a,string2a) = tuple_of_list2 stringsa in
+          (match iibaseb with 
+            [ibase1b;ibase2b] -> 
+              sign signaopt signbopt >>= (fun signaopt iisignbopt -> 
+              tokenf string1a ibase1b >>= (fun base1a ibase1b -> 
+              tokenf string2a ibase2b >>= (fun base2a ibase2b -> 
+              return (
+               (rebuilda ([base1a;base2a], signaopt)) +> A.rewrap ta,
+               (B.BaseType (baseb), iisignbopt ++ [ibase1b;ibase2b])
+              ))))
+         | [] -> fail (* should something be done in this case? *)
+         | _ -> raise Impossible)
+
+
+      | _, B.FloatType B.CLongDouble 
+          -> 
+          pr2_once 
+            "warning: long double not handled by ast_cocci";
+          fail
+
+      | _, (B.Void|B.FloatType _|B.IntType _) -> fail
+
+and simulate_signed_meta ta basea signaopt tb baseb ii rebuilda =
+      (* 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
+
+      let match_to_type rebaseb = 
+       sign signaopt signbopt >>= (fun signaopt iisignbopt -> 
+       let ibaseb = tuple_of_list1 iibaseb in
+       let fta = A.rewrap basea (A.Type(None,basea)) in
+       let ftb = Ast_c.nQ,(B.BaseType (rebaseb), [ibaseb]) in
+       fullType fta ftb >>= (fun fta (_,tb) ->
+         (match A.unwrap fta,tb with
+           A.Type(_,basea), (B.BaseType baseb, ii) ->
+             let ibaseb = tuple_of_list1 ii in
+             return (
+             (rebuilda (basea, signaopt)) +> A.rewrap ta,
+             (B.BaseType (baseb), iisignbopt ++ [ibaseb])
+               )
+         | _ -> failwith "not possible"))) in
+        
+      (* handle some iso on type ? (cf complex C rule for possible implicit
+        casting) *)
+      match baseb with
+      | B.IntType (B.Si (_sign, B.CChar2)) ->
+         match_to_type (B.IntType B.CChar)
+          
+      | B.IntType (B.Si (_, ty)) ->
+          (match iibaseb with 
+          | [] -> fail (* metavariable has to match something *)
+
+          | [x;y] -> 
+              pr2_once 
+                "warning: long int or short int not handled by ast_cocci";
+              fail
+
+          | [ibaseb] -> match_to_type (B.IntType (B.Si (B.Signed, ty)))
+          | _ -> raise Impossible
+
+          )
+
+      | (B.Void|B.FloatType _|B.IntType _) -> fail
+
+and (typeC: (A.typeC, Ast_c.typeC) matcher) = 
+  fun ta tb -> 
+  match A.unwrap ta, tb with
+    | A.BaseType (basea,stringsa), (B.BaseType baseb, ii) -> 
+       simulate_signed ta basea stringsa None tb baseb ii
+         (function (stringsa, signaopt) -> A.BaseType (basea,stringsa))
+    | A.SignedT (signaopt, Some basea), (B.BaseType baseb, ii) -> 
+       (match A.unwrap basea with
+         A.BaseType (basea1,strings1) ->
+           simulate_signed ta basea1 strings1 (Some signaopt) tb baseb ii
+             (function (strings1, Some signaopt) ->
+               A.SignedT
+                 (signaopt,
+                  Some (A.rewrap basea (A.BaseType (basea1,strings1))))
+               | _ -> failwith "not possible")
+       | A.MetaType(ida,keep,inherited) ->
+           simulate_signed_meta ta basea (Some signaopt) tb baseb ii
+             (function (basea, Some signaopt) ->
+               A.SignedT(signaopt,Some basea)
+               | _ -> failwith "not possible")
+       | _ -> failwith "not possible")
+    | A.SignedT (signa,None),   (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.SignedT (signa,None)) +> 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
+
+    | _, (B.ParenType e, ii) -> fail (* todo ?*)
+    | A.EnumName(en,namea), (B.EnumName nameb, ii) ->
+        let (ib1,ib2) = tuple_of_list2 ii in
+       ident DontKnow namea (nameb, ib2) >>= (fun namea (nameb, ib2) -> 
+          tokenf en ib1 >>= (fun en ib1 -> 
+          return (
+          (A.EnumName (en, namea)) +> A.rewrap ta,
+          (B.EnumName nameb, [ib1;ib2])
+          )))
+
+    | _, (B.Enum _, _) -> fail (* todo cocci ?*)
+
+    | _,
+     ((B.TypeName (_, _) | B.StructUnionName (_, _) | B.EnumName _ |
+      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
+ * 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_base_type a signa b =
+  let ok  = return ((),()) in
+
+  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"
+       
+  | _, (B.Void|B.FloatType _|B.IntType _) -> fail
+
+and compatible_base_type_meta a signa qua b ii local =
+  match a, b with
+  | Type_cocci.MetaType(ida,keep,inherited),
+    B.IntType (B.Si (signb, B.CChar2)) -> 
+      compatible_sign signa signb >>= fun _ _ ->
+       let newb = ((qua, (B.BaseType (B.IntType B.CChar),ii)),local) in
+       compatible_type a newb
+  | Type_cocci.MetaType(ida,keep,inherited), B.IntType (B.Si (signb, ty)) -> 
+      compatible_sign signa signb >>= fun _ _ ->
+       let newb =
+         ((qua, (B.BaseType (B.IntType (B.Si (B.Signed, ty))),ii)),local) in
+       compatible_type a newb
+  | _, B.FloatType B.CLongDouble -> 
+      pr2_once "no longdouble in cocci";
+      fail
+       
+  | _, (B.Void|B.FloatType _|B.IntType _) -> fail
+
+
+and compatible_type a (b,local) = 
+  let ok  = return ((),()) in
+
+  let rec loop = function
+    | Type_cocci.BaseType a, (qua, (B.BaseType b,ii)) -> 
+       compatible_base_type a None b
+
+    | Type_cocci.SignedT (signa,None), (qua, (B.BaseType b,ii)) -> 
+       compatible_base_type Type_cocci.IntType (Some signa) b
+
+    | Type_cocci.SignedT (signa,Some ty), (qua, (B.BaseType b,ii)) -> 
+       (match ty with
+         Type_cocci.BaseType ty ->
+           compatible_base_type ty (Some signa) b
+       | Type_cocci.MetaType(ida,keep,inherited) ->
+           compatible_base_type_meta ty (Some signa) qua b ii local
+       | _ -> failwith "not possible")
+
+    | 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.EnumName (_, sa),
+       (qub, (B.EnumName (sb),ii)) -> 
+         if 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
+
+    | (_,
+      (_,
+      ((
+       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 = 
+  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
+  | _, (B.Struct | B.Union) -> 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.TopInit init, nodeb -> 
+      X.cocciInit initialiser init node >>= (fun init node -> 
+        return (
+          A.TopInit init,
+          F.unwrap node
+        )
+      )
+
+
+  | A.FunHeader (mckstart, allminus, fninfoa, ida, oparen, paramsa, cparen),
+    F.FunHeader ({B.f_name = idb;
+                  f_type = (retb, (paramsb, (isvaargs, iidotsb)));
+                  f_storage = stob;
+                  f_attr = attrs;
+                  f_body = body;
+                  f_old_c_style = oldstyle;
+                  }, ii) -> 
+      assert (null body);
+
+      if oldstyle <> None
+      then pr2 "OLD STYLE DECL NOT WELL SUPPORTED";
+
+
+      (* 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 ({B.f_name = idb;
+                             f_type = (retb, (paramsb, (isvaargs, iidotsb)));
+                             f_storage = stob;
+                             f_attr = attrs;
+                             f_body = body;
+                             f_old_c_style = oldstyle; (* TODO *)
+                           },
+                           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 {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 _), _ -> 
+            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 {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
+
+
+
+  | 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.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
+
+
+  )
+end
+
diff --git a/engine/.#cocci_vs_c.ml.1.29 b/engine/.#cocci_vs_c.ml.1.29
new file mode 100644 (file)
index 0000000..75ddf8e
--- /dev/null
@@ -0,0 +1,3765 @@
+(*
+* Copyright 2005-2009, 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
+
+module Flag = Flag_matcher
+
+(*****************************************************************************)
+(* 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)
+
+    | A.CONTEXT ((A.FixPos _|A.DontCarePos), _) 
+    | A.MINUS ((A.FixPos _|A.DontCarePos), _)
+        ->
+        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
+  | _, B.GetRefLabel -> false (* todo cocci? *)
+  | _, (B.Not|B.Tilde|B.UnMinus|B.UnPlus|B.DeRef|B.GetRef) -> false
+      
+
+
+let equal_arithOp a b = 
+  match a, b with
+  | A.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
+  | _, (B.Xor|B.Or|B.And|B.DecRight|B.DecLeft|B.Mod|B.Div|B.Mul|B.Minus|B.Plus)
+      -> false
+
+let equal_logicalOp a b = 
+  match a, b with
+  | A.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
+  | _, (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
+  | _, (B.OpAssign _|B.SimpleAssign) -> false
+
+let equal_fixOp a b = 
+  match a, b with
+  | A.Dec, B.Dec -> true
+  | A.Inc, B.Inc -> true
+  | _, (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
+  | _, (B.Logical _ | B.Arith _) -> false
+
+let equal_structUnion a b = 
+  match a, b with
+  | A.Struct, B.Struct -> true
+  | A.Union,  B.Union -> true
+  | _, (B.Struct|B.Union) -> false
+
+let equal_sign a b = 
+  match a, b with
+  | A.Signed,    B.Signed   -> true
+  | A.Unsigned,  B.UnSigned -> true
+  | _, (B.UnSigned|B.Signed) -> 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
+  | _, (B.NoSto | B.StoTypedef) -> false
+  | _, (B.Sto (B.Register|B.Static|B.Auto|B.Extern)) -> 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.MetaInitVal a, Ast_c.MetaInitVal b -> 
+      Lib_parsing_c.al_init a =*= Lib_parsing_c.al_init 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,cea,posa1,posa2) ->
+         List.exists
+           (function (flb,ceb,posb1,posb2) ->
+             fla = flb && cea = ceb &&
+             Ast_c.equal_posl posa1 posb1 && Ast_c.equal_posl posa2 posb2)
+            l2)
+       l1
+
+  | (B.MetaPosValList _|B.MetaListlenVal _|B.MetaPosVal _|B.MetaStmtVal _
+      |B.MetaTypeVal _ |B.MetaInitVal _
+      |B.MetaParamListVal _|B.MetaParamVal _|B.MetaExprListVal _
+      |B.MetaExprVal _|B.MetaLocalFuncVal _|B.MetaFuncVal _|B.MetaIdVal _
+    ), _
+      -> 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 ({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) -> 
+              (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 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 cocciInit : 
+      (A.initialiser, B.initialiser) matcher -> (A.initialiser, F.node) matcher
+
+    val envf :
+      A.keep_binding -> A.inherited -> 
+      A.meta_name A.mcode * Ast_c.metavar_binding_kind *
+         (unit -> Common.filename * string * 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 *)
+          )
+
+      | _, B.MultiString _ -> (* todo cocci? *) fail
+      | _, (B.String _ | B.Float _ | B.Char _ | B.Int _) -> 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
+
+
+  | _, 
+     (((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
+
+
+
+
+
+
+(* ------------------------------------------------------------------------- *)
+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))
+          ))))))))
+
+  | _, (B.MacroDecl _ |B.DeclList _) -> 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), 
+   ({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) ->
+
+     (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,
+                     (({B.v_namei = Some ((idb, None),[iidb]);
+                        B.v_type = typb0;
+                        B.v_storage = (B.StoTypedef, inl);
+                        B.v_local = local;
+                        B.v_attr = attrs;
+                     },
+                       iivirg),iiptvirgb,iistob)
+                     )
+                | _ -> raise Impossible    
+             )
+
+           | A.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,
+                     (({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    
+             )
+           | _ -> raise Impossible
+           )
+         | _ -> fail
+       )))))
+     | _ -> fail
+     )
+   | _ -> fail
+   )
+         
+   | A.UnInit (stoa, typa, ida, ptvirga), 
+     ({B.v_namei = Some ((idb, _),[iidb]);
+       B.v_storage = (B.StoTypedef,_);
+     }, iivirg) -> 
+       fail
+
+   | A.Init (stoa, typa, ida, eqa, inia, ptvirga), 
+     ({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), 
+     ({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) -> 
+       storage_optional_allminus allminus stoa (stob, iistob) >>= 
+        (fun stoa (stob, iistob) -> 
+         return (
+           (A.UnInit (stoa, typa, ida, ptvirga)) +>  A.rewrap decla,
+           (({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), 
+     ({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 -> 
+       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,
+           (({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), 
+     ({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,
+             (({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), 
+     ({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 -> 
+       (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,
+           (({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)
+         )
+       ))))
+             
+       
+   | _, ({B.v_namei = None;}, _) -> 
+       (* 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"
+
+   | _, ({B.v_namei=Some _}, _)
+       -> 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.MetaInit(ida,keep,inherited), ib) -> 
+       let max_min _ =
+         Lib_parsing_c.lin_col_by_pos (Lib_parsing_c.ii_of_ini ib) in
+       X.envf keep inherited (ida, Ast_c.MetaInitVal ib, max_min)
+         (fun () -> 
+           X.distrf_ini ida ib >>= (fun ida ib -> 
+             return (
+               A.MetaInit (ida,keep,inherited) +> A.rewrap ia,
+               ib
+            ))
+         )
+
+    | (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.InitGccExt (designatorsa, ia2, inia), 
+      (B.InitDesignators (designatorsb, inib), ii2))->
+
+        let iieq = tuple_of_list1 ii2 in
+
+        tokenf ia2 iieq >>= (fun ia2 iieq -> 
+       designators designatorsa designatorsb >>=
+         (fun designatorsa designatorsb ->
+        initialiser inia inib >>= (fun inia inib -> 
+          return (
+            (A.InitGccExt (designatorsa, ia2, inia)) +> A.rewrap ia,
+            (B.InitDesignators (designatorsb, inib), [iieq])
+          ))))
+
+
+
+
+    | (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"
+
+    | _, (B.InitIndexOld (_, _), _) -> fail 
+    | _, (B.InitFieldOld (_, _), _) -> fail 
+
+    | _, ((B.InitDesignators (_, _)|B.InitList _|B.InitExpr _), _)
+        -> fail
+
+and designators dla dlb =
+  match (dla,dlb) with
+    ([],[]) -> return ([], [])
+  | ([],_) | (_,[]) -> fail
+  | (da::dla,db::dlb) ->
+      designator da db >>= (fun da db ->
+      designators dla dlb >>= (fun dla dlb ->
+      return (da::dla, db::dlb)))
+
+and designator da db =
+  match (da,db) with
+    (A.DesignatorField (ia1, ida), (B.DesignatorField idb,ii1)) ->
+
+        let (iidot, iidb) = tuple_of_list2 ii1 in
+        tokenf ia1 iidot >>= (fun ia1 iidot -> 
+        ident DontKnow ida (idb, iidb) >>= (fun ida (idb, iidb) ->
+          return (
+            A.DesignatorField (ia1, ida),
+            (B.DesignatorField idb, [iidot;iidb])
+          )))
+
+  | (A.DesignatorIndex (ia1,ea,ia2), (B.DesignatorIndex eb, ii1)) ->
+        
+        let (ib1, ib2) = tuple_of_list2 ii1 in
+        tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
+        tokenf ia2 ib2 >>= (fun ia2 ib2 -> 
+        expression ea eb >>= (fun ea eb -> 
+          return (
+            A.DesignatorIndex (ia1,ea,ia2),
+            (B.DesignatorIndex eb, [ib1;ib2])
+          ))))
+
+  | (A.DesignatorRange (ia1,e1a,ia2,e2a,ia3),
+     (B.DesignatorRange (e1b, e2b), ii1)) ->
+
+        let (ib1, ib2, ib3) = tuple_of_list3 ii1 in
+        tokenf ia1 ib1 >>= (fun ia1 ib1 -> 
+        tokenf ia2 ib2 >>= (fun ia2 ib2 -> 
+        tokenf ia3 ib3 >>= (fun ia3 ib3 -> 
+        expression e1a e1b >>= (fun e1a e1b -> 
+        expression e2a e2b >>= (fun e2a e2b -> 
+          return (
+            A.DesignatorRange (ia1,e1a,ia2,e2a,ia3),
+            (B.DesignatorRange (e1b, e2b), [ib1;ib2;ib3])
+          ))))))
+  | (_, ((B.DesignatorField _|B.DesignatorIndex _|B.DesignatorRange _), _)) ->
+      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 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) matcher) = fun fa fb -> 
+  let (xfield, iifield) = fb in
+
+  match xfield with 
+  | B.DeclarationField (B.FieldDeclList (onefield_multivars,iiptvirg)) -> 
+
+    let iiptvirgb = tuple_of_list1 iiptvirg in
+
+    (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 = 
+            ({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
+              | ({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.DeclarationField 
+                        (B.FieldDeclList ([onevar, iivirg], [iiptvirgb]))),
+                    iifield)
+                  )
+              | _ -> raise Impossible
+            )
+      )
+
+    | x::y::xs -> 
+      pr2_once "PB: More that one variable in decl. Have to split";
+      fail
+    )
+  | B.EmptyField -> 
+      let _iiptvirgb = tuple_of_list1 iifield in
+      fail
+
+  | B.MacroStructDeclTodo -> fail
+  | B.CppDirectiveStruct directive -> fail
+  | B.IfdefStruct directive -> 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 simulate_signed ta basea stringsa signaopt tb baseb ii rebuilda =
+      (* 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 basea, baseb with
+      | A.VoidType,  B.Void 
+      | A.FloatType, B.FloatType (B.CFloat)
+      | A.DoubleType, B.FloatType (B.CDouble) -> 
+           assert (signaopt = None); 
+          let stringa = tuple_of_list1 stringsa in
+           let (ibaseb) = tuple_of_list1 ii in 
+           tokenf stringa ibaseb >>= (fun stringa ibaseb -> 
+             return (
+               (rebuilda ([stringa], signaopt)) +> A.rewrap ta,
+               (B.BaseType baseb, [ibaseb])
+             ))
+            
+      | A.CharType,  B.IntType B.CChar when signaopt = None -> 
+         let stringa = tuple_of_list1 stringsa in
+          let ibaseb = tuple_of_list1 ii in
+           tokenf stringa ibaseb >>= (fun stringa ibaseb -> 
+             return (
+               (rebuilda ([stringa], signaopt)) +> A.rewrap ta,
+               (B.BaseType (B.IntType B.CChar), [ibaseb])
+             ))
+            
+      | A.CharType,B.IntType (B.Si (_sign, B.CChar2)) when signaopt <> None -> 
+         let stringa = tuple_of_list1 stringsa in
+          let ibaseb = tuple_of_list1 iibaseb in
+          sign signaopt signbopt >>= (fun signaopt iisignbopt -> 
+          tokenf stringa ibaseb >>= (fun stringa ibaseb -> 
+            return (
+               (rebuilda ([stringa], 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))  ->
+         let stringa = tuple_of_list1 stringsa in
+          (match iibaseb with 
+          | [] -> 
+              (* iso-by-presence ? *)
+              (* when unsigned int in SP,  allow have just unsigned in C ? *)
+              if mcode_contain_plus (mcodekind stringa)
+              then fail
+              else 
+                
+                sign signaopt signbopt >>= (fun signaopt iisignbopt -> 
+                    return (
+                      (rebuilda ([stringa], 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 stringa ibaseb >>= (fun stringa ibaseb -> 
+            return (
+               (rebuilda ([stringa], signaopt)) +> A.rewrap ta,
+               (B.BaseType (baseb), iisignbopt ++ [ibaseb])
+               )))
+          | _ -> raise Impossible
+
+          )
+
+            
+      | A.LongLongType, B.IntType (B.Si (_, B.CLongLong)) ->
+         let (string1a,string2a) = tuple_of_list2 stringsa in
+          (match iibaseb with 
+            [ibase1b;ibase2b] -> 
+              sign signaopt signbopt >>= (fun signaopt iisignbopt -> 
+              tokenf string1a ibase1b >>= (fun base1a ibase1b -> 
+              tokenf string2a ibase2b >>= (fun base2a ibase2b -> 
+              return (
+               (rebuilda ([base1a;base2a], signaopt)) +> A.rewrap ta,
+               (B.BaseType (baseb), iisignbopt ++ [ibase1b;ibase2b])
+              ))))
+         | [] -> fail (* should something be done in this case? *)
+         | _ -> raise Impossible)
+
+
+      | _, B.FloatType B.CLongDouble 
+          -> 
+          pr2_once 
+            "warning: long double not handled by ast_cocci";
+          fail
+
+      | _, (B.Void|B.FloatType _|B.IntType _) -> fail
+
+and simulate_signed_meta ta basea signaopt tb baseb ii rebuilda =
+      (* 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
+
+      let match_to_type rebaseb = 
+       sign signaopt signbopt >>= (fun signaopt iisignbopt -> 
+       let ibaseb = tuple_of_list1 iibaseb in
+       let fta = A.rewrap basea (A.Type(None,basea)) in
+       let ftb = Ast_c.nQ,(B.BaseType (rebaseb), [ibaseb]) in
+       fullType fta ftb >>= (fun fta (_,tb) ->
+         (match A.unwrap fta,tb with
+           A.Type(_,basea), (B.BaseType baseb, ii) ->
+             let ibaseb = tuple_of_list1 ii in
+             return (
+             (rebuilda (basea, signaopt)) +> A.rewrap ta,
+             (B.BaseType (baseb), iisignbopt ++ [ibaseb])
+               )
+         | _ -> failwith "not possible"))) in
+        
+      (* handle some iso on type ? (cf complex C rule for possible implicit
+        casting) *)
+      match baseb with
+      | B.IntType (B.Si (_sign, B.CChar2)) ->
+         match_to_type (B.IntType B.CChar)
+          
+      | B.IntType (B.Si (_, ty)) ->
+          (match iibaseb with 
+          | [] -> fail (* metavariable has to match something *)
+
+          | [x;y] -> 
+              pr2_once 
+                "warning: long int or short int not handled by ast_cocci";
+              fail
+
+          | [ibaseb] -> match_to_type (B.IntType (B.Si (B.Signed, ty)))
+          | _ -> raise Impossible
+
+          )
+
+      | (B.Void|B.FloatType _|B.IntType _) -> fail
+
+and (typeC: (A.typeC, Ast_c.typeC) matcher) = 
+  fun ta tb -> 
+  match A.unwrap ta, tb with
+    | A.BaseType (basea,stringsa), (B.BaseType baseb, ii) -> 
+       simulate_signed ta basea stringsa None tb baseb ii
+         (function (stringsa, signaopt) -> A.BaseType (basea,stringsa))
+    | A.SignedT (signaopt, Some basea), (B.BaseType baseb, ii) -> 
+       (match A.unwrap basea with
+         A.BaseType (basea1,strings1) ->
+           simulate_signed ta basea1 strings1 (Some signaopt) tb baseb ii
+             (function (strings1, Some signaopt) ->
+               A.SignedT
+                 (signaopt,
+                  Some (A.rewrap basea (A.BaseType (basea1,strings1))))
+               | _ -> failwith "not possible")
+       | A.MetaType(ida,keep,inherited) ->
+           simulate_signed_meta ta basea (Some signaopt) tb baseb ii
+             (function (basea, Some signaopt) ->
+               A.SignedT(signaopt,Some basea)
+               | _ -> failwith "not possible")
+       | _ -> failwith "not possible")
+    | A.SignedT (signa,None),   (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.SignedT (signa,None)) +> 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
+
+    | _, (B.ParenType e, ii) -> fail (* todo ?*)
+    | A.EnumName(en,namea), (B.EnumName nameb, ii) ->
+        let (ib1,ib2) = tuple_of_list2 ii in
+       ident DontKnow namea (nameb, ib2) >>= (fun namea (nameb, ib2) -> 
+          tokenf en ib1 >>= (fun en ib1 -> 
+          return (
+          (A.EnumName (en, namea)) +> A.rewrap ta,
+          (B.EnumName nameb, [ib1;ib2])
+          )))
+
+    | _, (B.Enum _, _) -> fail (* todo cocci ?*)
+
+    | _,
+     ((B.TypeName (_, _) | B.StructUnionName (_, _) | B.EnumName _ |
+      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
+ * 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_base_type a signa b =
+  let ok  = return ((),()) in
+
+  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"
+       
+  | _, (B.Void|B.FloatType _|B.IntType _) -> fail
+
+and compatible_base_type_meta a signa qua b ii local =
+  match a, b with
+  | Type_cocci.MetaType(ida,keep,inherited),
+    B.IntType (B.Si (signb, B.CChar2)) -> 
+      compatible_sign signa signb >>= fun _ _ ->
+       let newb = ((qua, (B.BaseType (B.IntType B.CChar),ii)),local) in
+       compatible_type a newb
+  | Type_cocci.MetaType(ida,keep,inherited), B.IntType (B.Si (signb, ty)) -> 
+      compatible_sign signa signb >>= fun _ _ ->
+       let newb =
+         ((qua, (B.BaseType (B.IntType (B.Si (B.Signed, ty))),ii)),local) in
+       compatible_type a newb
+  | _, B.FloatType B.CLongDouble -> 
+      pr2_once "no longdouble in cocci";
+      fail
+       
+  | _, (B.Void|B.FloatType _|B.IntType _) -> fail
+
+
+and compatible_type a (b,local) = 
+  let ok  = return ((),()) in
+
+  let rec loop = function
+    | Type_cocci.BaseType a, (qua, (B.BaseType b,ii)) -> 
+       compatible_base_type a None b
+
+    | Type_cocci.SignedT (signa,None), (qua, (B.BaseType b,ii)) -> 
+       compatible_base_type Type_cocci.IntType (Some signa) b
+
+    | Type_cocci.SignedT (signa,Some ty), (qua, (B.BaseType b,ii)) -> 
+       (match ty with
+         Type_cocci.BaseType ty ->
+           compatible_base_type ty (Some signa) b
+       | Type_cocci.MetaType(ida,keep,inherited) ->
+           compatible_base_type_meta ty (Some signa) qua b ii local
+       | _ -> failwith "not possible")
+
+    | 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.EnumName (_, sa),
+       (qub, (B.EnumName (sb),ii)) -> 
+         if 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
+
+    | (_,
+      (_,
+      ((
+       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 = 
+  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
+  | _, (B.Struct | B.Union) -> 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.TopInit init, nodeb -> 
+      X.cocciInit initialiser init node >>= (fun init node -> 
+        return (
+          A.TopInit init,
+          F.unwrap node
+        )
+      )
+
+
+  | A.FunHeader (mckstart, allminus, fninfoa, ida, oparen, paramsa, cparen),
+    F.FunHeader ({B.f_name = idb;
+                  f_type = (retb, (paramsb, (isvaargs, iidotsb)));
+                  f_storage = stob;
+                  f_attr = attrs;
+                  f_body = body;
+                  f_old_c_style = oldstyle;
+                  }, ii) -> 
+      assert (null body);
+
+      if oldstyle <> None
+      then pr2 "OLD STYLE DECL NOT WELL SUPPORTED";
+
+
+      (* 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 ({B.f_name = idb;
+                             f_type = (retb, (paramsb, (isvaargs, iidotsb)));
+                             f_storage = stob;
+                             f_attr = attrs;
+                             f_body = body;
+                             f_old_c_style = oldstyle; (* TODO *)
+                           },
+                           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 {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 _), _ -> 
+            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 {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
+
+
+
+  | 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.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
+
+
+  )
+end
+
diff --git a/engine/.#transformation_c.ml.1.3 b/engine/.#transformation_c.ml.1.3
new file mode 100644 (file)
index 0000000..8dc3f98
--- /dev/null
@@ -0,0 +1,547 @@
+(*
+* Copyright 2005-2009, 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.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)
+
+  let cocciInit = fun expf expa node -> fun tin -> 
+
+    let bigf = { 
+      Visitor_c.default_visitor_c_s with 
+      Visitor_c.kini_s = (fun (k, bigf) expb ->
+       match expf expa expb tin with
+       | None -> (* failed *) k expb
+       | Some (x, expb) -> expb);
+    }
+    in
+    Some (expa, Visitor_c.vk_node_s bigf node)
+
+
+  (* ------------------------------------------------------------------------*)
+  (* Tokens *) 
+  (* ------------------------------------------------------------------------*)
+   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 =
+      (* coccionly: 
+      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_matcher.show_misc 
+          then pr2 "already tagged but with same mcode, so safe";
+          ib
+        end
+        else 
+          (* coccionly: 
+          if !Flag.sgrep_mode2
+          then ib (* safe *)
+          else 
+          *)
+             begin
+            (* coccionly:
+             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.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.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_transinfo
+      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)
dissimilarity index 97%
index 3ef9a54..8179bbb 100644 (file)
-asttoctl.cmi: lib_engine.cmo 
-asttoctl2.cmi: lib_engine.cmo 
-asttomember.cmi: lib_engine.cmo 
-ctlcocci_integration.cmi: lib_engine.cmo 
-ctltotex.cmi: lib_engine.cmo 
-pattern_c.cmi: lib_engine.cmo 
-postprocess_transinfo.cmi: lib_engine.cmo 
-pretty_print_engine.cmi: lib_engine.cmo 
-transformation_c.cmi: lib_engine.cmo 
-asttoctl.cmo: pretty_print_engine.cmi lib_engine.cmo asttoctl.cmi 
-asttoctl.cmx: pretty_print_engine.cmx lib_engine.cmx asttoctl.cmi 
-asttoctl2.cmo: pretty_print_engine.cmi lib_engine.cmo flag_matcher.cmo \
-    asttoctl2.cmi 
-asttoctl2.cmx: pretty_print_engine.cmx lib_engine.cmx flag_matcher.cmx \
-    asttoctl2.cmi 
-asttomember.cmo: lib_engine.cmo asttomember.cmi 
-asttomember.cmx: lib_engine.cmx asttomember.cmi 
-c_vs_c.cmo: c_vs_c.cmi 
-c_vs_c.cmx: c_vs_c.cmi 
-check_reachability.cmo: check_reachability.cmi 
-check_reachability.cmx: check_reachability.cmi 
-cocci_vs_c.cmo: flag_matcher.cmo c_vs_c.cmi cocci_vs_c.cmi 
-cocci_vs_c.cmx: flag_matcher.cmx c_vs_c.cmx cocci_vs_c.cmi 
-ctlcocci_integration.cmo: pretty_print_engine.cmi postprocess_transinfo.cmi \
-    pattern_c.cmi lib_engine.cmo flag_matcher.cmo check_reachability.cmi \
-    c_vs_c.cmi ctlcocci_integration.cmi 
-ctlcocci_integration.cmx: pretty_print_engine.cmx postprocess_transinfo.cmx \
-    pattern_c.cmx lib_engine.cmx flag_matcher.cmx check_reachability.cmx \
-    c_vs_c.cmx ctlcocci_integration.cmi 
-ctltotex.cmo: lib_engine.cmo ctltotex.cmi 
-ctltotex.cmx: lib_engine.cmx ctltotex.cmi 
-lib_matcher_c.cmo: pattern_c.cmi lib_matcher_c.cmi 
-lib_matcher_c.cmx: pattern_c.cmx lib_matcher_c.cmi 
-main.cmo: ctltotex.cmi asttoctl.cmi 
-main.cmx: ctltotex.cmx asttoctl.cmx 
-pattern_c.cmo: lib_engine.cmo flag_matcher.cmo cocci_vs_c.cmi pattern_c.cmi 
-pattern_c.cmx: lib_engine.cmx flag_matcher.cmx cocci_vs_c.cmx pattern_c.cmi 
-postprocess_transinfo.cmo: lib_engine.cmo postprocess_transinfo.cmi 
-postprocess_transinfo.cmx: lib_engine.cmx postprocess_transinfo.cmi 
-pretty_print_engine.cmo: lib_engine.cmo pretty_print_engine.cmi 
-pretty_print_engine.cmx: lib_engine.cmx pretty_print_engine.cmi 
-transformation_c.cmo: lib_engine.cmo flag_matcher.cmo cocci_vs_c.cmi \
-    transformation_c.cmi 
-transformation_c.cmx: lib_engine.cmx flag_matcher.cmx cocci_vs_c.cmx \
-    transformation_c.cmi 
+asttoctl.cmi: ../ctl/wrapper_ctl.cmi lib_engine.cmo ../ctl/ast_ctl.cmo \
+    ../parsing_cocci/ast_cocci.cmi 
+asttoctl2.cmi: ../ctl/wrapper_ctl.cmi lib_engine.cmo ../ctl/ast_ctl.cmo \
+    ../parsing_cocci/ast_cocci.cmi 
+asttomember.cmi: lib_engine.cmo ../ctl/ast_ctl.cmo \
+    ../parsing_cocci/ast_cocci.cmi 
+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.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 
+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 
+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 \
+    ../parsing_cocci/ast_cocci.cmi asttoctl.cmi 
+asttoctl.cmx: ../ctl/wrapper_ctl.cmx ../parsing_cocci/visitor_ast.cmx \
+    ../parsing_cocci/unify_ast.cmx pretty_print_engine.cmx lib_engine.cmx \
+    ../parsing_cocci/free_vars.cmx ../commons/common.cmx ../ctl/ast_ctl.cmx \
+    ../parsing_cocci/ast_cocci.cmx asttoctl.cmi 
+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_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_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 \
+    ../parsing_cocci/pretty_print_cocci.cmi lib_engine.cmo \
+    ../commons/common.cmi ../ctl/ast_ctl.cmo ../parsing_cocci/ast_cocci.cmi \
+    asttomember.cmi 
+asttomember.cmx: ../parsing_cocci/visitor_ast.cmx \
+    ../parsing_cocci/pretty_print_cocci.cmx lib_engine.cmx \
+    ../commons/common.cmx ../ctl/ast_ctl.cmx ../parsing_cocci/ast_cocci.cmx \
+    asttomember.cmi 
+c_vs_c.cmo: ../parsing_c/lib_parsing_c.cmo ../commons/common.cmi \
+    ../parsing_c/ast_c.cmo c_vs_c.cmi 
+c_vs_c.cmx: ../parsing_c/lib_parsing_c.cmx ../commons/common.cmx \
+    ../parsing_c/ast_c.cmx c_vs_c.cmi 
+check_exhaustive_pattern.cmo: ../parsing_c/control_flow_c.cmi \
+    ../parsing_cocci/ast_cocci.cmi ../parsing_c/ast_c.cmo 
+check_exhaustive_pattern.cmx: ../parsing_c/control_flow_c.cmx \
+    ../parsing_cocci/ast_cocci.cmx ../parsing_c/ast_c.cmx 
+check_reachability.cmo: ../ctl/wrapper_ctl.cmi ../commons/ograph_extended.cmi \
+    ../ctl/flag_ctl.cmo ../ctl/ctl_engine.cmi ../parsing_c/control_flow_c.cmi \
+    ../ctl/ast_ctl.cmo check_reachability.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.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.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.cmi 
+ctlcocci_integration.cmo: ../ctl/wrapper_ctl.cmi pretty_print_engine.cmi \
+    ../parsing_cocci/pretty_print_cocci.cmi postprocess_transinfo.cmi \
+    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 \
+    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 \
+    ctlcocci_integration.cmi 
+ctltotex.cmo: ../parsing_cocci/pretty_print_cocci.cmi lib_engine.cmo \
+    ../ctl/ast_ctl.cmo ctltotex.cmi 
+ctltotex.cmx: ../parsing_cocci/pretty_print_cocci.cmx lib_engine.cmx \
+    ../ctl/ast_ctl.cmx ctltotex.cmi 
+isomorphisms_c_c.cmo: ../commons/common.cmi ../parsing_c/ast_c.cmo 
+isomorphisms_c_c.cmx: ../commons/common.cmx ../parsing_c/ast_c.cmx 
+lib_engine.cmo: ../ctl/wrapper_ctl.cmi ../commons/ograph_extended.cmi \
+    ../parsing_c/control_flow_c.cmi ../commons/common.cmi ../ctl/ast_ctl.cmo \
+    ../parsing_cocci/ast_cocci.cmi ../parsing_c/ast_c.cmo 
+lib_engine.cmx: ../ctl/wrapper_ctl.cmx ../commons/ograph_extended.cmx \
+    ../parsing_c/control_flow_c.cmx ../commons/common.cmx ../ctl/ast_ctl.cmx \
+    ../parsing_cocci/ast_cocci.cmx ../parsing_c/ast_c.cmx 
+lib_matcher_c.cmo: lib_matcher_c.cmi 
+lib_matcher_c.cmx: lib_matcher_c.cmi 
+main.cmo: ../parsing_cocci/parse_cocci.cmi ctltotex.cmi asttoctl.cmi 
+main.cmx: ../parsing_cocci/parse_cocci.cmx ctltotex.cmx asttoctl.cmx 
+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 
+postprocess_transinfo.cmx: ../parsing_c/parser_c.cmx ../parsing_c/parse_c.cmx \
+    lib_engine.cmx ../commons/common.cmx ../parsing_cocci/ast_cocci.cmx \
+    ../parsing_c/ast_c.cmx postprocess_transinfo.cmi 
+pretty_print_engine.cmo: ../ctl/pretty_print_ctl.cmi \
+    ../parsing_cocci/pretty_print_cocci.cmi ../parsing_c/pretty_print_c.cmi \
+    lib_engine.cmo ../commons/common.cmi ../ctl/ast_ctl.cmo \
+    ../parsing_cocci/ast_cocci.cmi ../parsing_c/ast_c.cmo \
+    pretty_print_engine.cmi 
+pretty_print_engine.cmx: ../ctl/pretty_print_ctl.cmx \
+    ../parsing_cocci/pretty_print_cocci.cmx ../parsing_c/pretty_print_c.cmx \
+    lib_engine.cmx ../commons/common.cmx ../ctl/ast_ctl.cmx \
+    ../parsing_cocci/ast_cocci.cmx ../parsing_c/ast_c.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 
+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 ../globals/flag.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 ../globals/flag.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 c989683..15fddb0 100644 (file)
@@ -22,6 +22,8 @@
 # Variables
 ##############################################################################
 #TARGET=matcher
+-include ../Makefile.config
+
 TARGET=cocciengine
 CTLTARGET=engine
 
@@ -31,7 +33,7 @@ SRC= flag_matcher.ml lib_engine.ml pretty_print_engine.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 lib_matcher_c.ml
+      postprocess_transinfo.ml ctlcocci_integration.ml
 
 #c_vs_c.ml
 #SRC= flag_matcher.ml \
@@ -65,7 +67,7 @@ OCAMLC=ocamlc$(OPTBIN) $(OCAMLCFLAGS) $(INCLUDES)
 OCAMLOPT=ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
 OCAMLLEX=ocamllex$(OPTBIN) #-ml
 OCAMLYACC=ocamlyacc -v
-OCAMLDEP=ocamldep$(OPTBIN) #$(INCLUDES)
+OCAMLDEP=ocamldep$(OPTBIN) $(INCLUDES)
 OCAMLMKTOP=ocamlmktop -g -custom $(INCLUDES)
 
 
index a569a97..048b389 100644 (file)
@@ -1014,7 +1014,7 @@ and statement stmt used_after after quantified guard =
       let dot_code =
        match d with
          Ast.MINUS(_) ->
-            (* no need for the fresh metavar, but ... is a bit wierd as a
+            (* no need for the fresh metavar, but ... is a bit weird as a
               variable name *)
            Some(make_match (make_meta_rule_elem d))
        | _ -> None in
index 865a633..10f79b1 100644 (file)
@@ -1836,7 +1836,7 @@ and statement stmt after quantified minus_quantified
       let dot_code =
        match d with
          Ast.MINUS(_,_) ->
-            (* no need for the fresh metavar, but ... is a bit wierd as a
+            (* no need for the fresh metavar, but ... is a bit weird as a
               variable name *)
            Some(make_match (make_meta_rule_elem d ([],[],[])))
        | _ -> None in
index 4b4bee4..933f16e 100644 (file)
@@ -798,7 +798,7 @@ let rec (expression: (A.expression, Ast_c.expression) matcher) =
           | _ -> fail (* multi string, not handled *)
           )
 
-      | _, B.MultiString -> (* todo cocci? *) fail
+      | _, B.MultiString -> (* todo cocci? *) fail
       | _, (B.String _ | B.Float _ | B.Char _ | B.Int _) -> fail
       )
 
@@ -1858,7 +1858,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) ->
            tokenf stoa iitypedef >>= (fun stoa iitypedef -> 
              return (stoa, [iitypedef])
            )
-       | _ -> failwith "wierd, have both typedef and inline or nothing";
+       | _ -> failwith "weird, have both typedef and inline or nothing";
        ) >>= (fun stoa iistob -> 
        (match A.unwrap ida with
        | A.MetaType(_,_,_) -> 
@@ -1900,7 +1900,7 @@ and onedecl = fun allminus decla (declb, iiptvirgb, iistob) ->
              
        
    | _, ({B.v_namei = None;}, _) -> 
-       (* old:   failwith "no variable in this declaration, wierd" *)
+       (* old:   failwith "no variable in this declaration, weird" *)
        fail
 
 
dissimilarity index 100%
index 87b0a72..e69de29 100644 (file)
@@ -1,156 +0,0 @@
-(*
-* Copyright 2005-2009, 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
-
-(*****************************************************************************)
-(* Types *)
-(*****************************************************************************)
-
-type protocol_match = 
-  | MatchPos of Ograph_extended.nodei
-  | MatchNeg of Ograph_extended.nodei
-  | NoMatch 
-  (* could generate exn instead, but in many cases as for my acomment gui
-   * I still want to print the match for the other elements, so one failure
-   * should not stop everything
-   *)
-  | MatchProblem of string
-
-
-(*****************************************************************************)
-(* Helpers *)
-(*****************************************************************************)
-
-(*****************************************************************************)
-(* Specific finder wrappers *)
-(*****************************************************************************)
-let (find_nodes_satisfying_pattern: 
-    Control_flow_c.cflow -> Ast_cocci.rule_elem -> Ograph_extended.nodei list)= 
- fun flow pattern -> 
-
-  let nodes = flow#nodes in
-  let nodes = nodes#tolist in
-  nodes +> Common.map_filter (fun (nodei, node) -> 
-    let res = 
-      Pattern_c.match_re_node [] (* dropped isos *)
-        pattern node 
-        [] 
-    in
-    if List.length res > 0
-    then Some nodei
-    else None
-  )
-
-
-let (find_nodes_containing_expr: 
-    Control_flow_c.cflow -> Ast_c.expression -> Ograph_extended.nodei list)= 
- fun flow expr -> 
-
-  let expr = Lib_parsing_c.real_al_expr expr in
-
-  let nodes = flow#nodes in
-  let nodes = nodes#tolist in
-  nodes +> Common.map_filter (fun (nodei, node) -> 
-    let node = Lib_parsing_c.real_al_node node in 
-
-    let found = ref false in 
-    
-    Visitor_c.vk_node { Visitor_c.default_visitor_c with
-      Visitor_c.kexpr = (fun (k, bigf) e2 -> 
-        if e2 =*= expr
-        then found := true
-        else k e2
-      );
-    } node;
-
-    if !found
-    then Some nodei
-    else None
-  )
-
-
-
-(*****************************************************************************)
-(* Main entries *)
-(*****************************************************************************)
-
-(*
- * 
- * todo: Check for all path upwards ?
- *)
-
-let (find_nodes_upward_satisfying_protocol: 
-  Ograph_extended.nodei -> Control_flow_c.cflow -> 
-  Ast_cocci.rule_elem * Ast_cocci.rule_elem -> 
-  protocol_match
-  ) = 
- fun nodei flow (pattern1, pattern2) ->
-
-   let already_done = ref [nodei] in
-   let found = ref [] in
-
-   let rec aux nodei = 
-     let pred = 
-       List.map fst ((flow#predecessors nodei)#tolist)
-     in
-     pred +> List.iter (fun nodei2 -> 
-       if List.mem nodei2 !already_done
-       then ()
-       else begin
-         Common.push2 nodei2 already_done;
-
-         let node2 = flow#nodes#assoc nodei2 in
-
-         let res1 = 
-           Pattern_c.match_re_node [] 
-             pattern1 node2
-             [] 
-         in
-         let res2 = 
-           Pattern_c.match_re_node [] 
-             pattern2 node2
-             [] 
-         in
-         match List.length res1 > 0, List.length res2 > 0 with
-         | true, false -> 
-             Common.push2 (MatchPos nodei2) found
-         | false, true -> 
-             Common.push2 (MatchNeg nodei2) found
-         | true, true -> 
-             failwith "wierd, node match both rule_elem"
-         | false, false -> 
-             aux nodei2
-       end
-     );
-   in
-   aux nodei;
-   (match !found with
-   | [] -> NoMatch
-   | [x] -> x
-   | x::y::ys -> 
-       failwith "multiple found";
-   )
-
-
-
-
dissimilarity index 100%
index 7b42611..e69de29 100644 (file)
@@ -1,21 +0,0 @@
-
-(* a protocol is for the moment represented as 2 rule_elem, a positive 
- * pattern (e.g. spin_lock_irq()) and negative one (e.g. spin_unlock_irq())
- *)
-type protocol_match = 
-  | MatchPos of Ograph_extended.nodei
-  | MatchNeg of Ograph_extended.nodei
-  | NoMatch 
-  | MatchProblem of string
-
-
-val find_nodes_satisfying_pattern: 
-  Control_flow_c.cflow -> Ast_cocci.rule_elem -> Ograph_extended.nodei list
-val find_nodes_containing_expr: 
-  Control_flow_c.cflow -> Ast_c.expression -> Ograph_extended.nodei list
-
-
-val find_nodes_upward_satisfying_protocol: 
-  Ograph_extended.nodei -> Control_flow_c.cflow -> 
-  Ast_cocci.rule_elem * Ast_cocci.rule_elem -> 
-  protocol_match
index 8dc3f98..44e6dfd 100644 (file)
@@ -175,10 +175,10 @@ module XTRANS = struct
           Some info ->
             failwith
               (Printf.sprintf
-                 "wierd: dont have position info for the mcodekind in line %d column %d"
+                 "weird: 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"
+            failwith "weird: dont have position info for the mcodekind"
 
 
   let tag_with_mck mck ib = fun tin -> 
@@ -385,7 +385,7 @@ module XTRANS = struct
      | Ast_cocci.CONTEXT (Ast_cocci.DontCarePos,_) 
      | Ast_cocci.MINUS   (Ast_cocci.DontCarePos,_) -> 
          Ast_cocci.DontCarePos
-     | _ -> failwith "wierd: dont have position info for the mcodekind"      
+     | _ -> failwith "weird: dont have position info for the mcodekind"      
       
   let distrf (ii_of_x_f, distribute_mck_x_f) = 
     fun ia x -> fun tin -> 
diff --git a/env.sh b/env.sh
index ba38c87..1286178 100644 (file)
--- a/env.sh
+++ b/env.sh
@@ -3,9 +3,17 @@
 # but it's not worth it.
 
 #!!!!You need to source me with "source env.sh" from the good directory!!!!
-if [ ! -r standard.iso ]
-    then echo "There is no standard.iso here. 
+
+if [ "$1" ] ; then
+       DIR=$1
+else
+       DIR=`pwd`
+fi
+
+if [ ! -r $DIR/standard.iso ]
+    then echo "There is no standard.iso in '$DIR'. 
 Are you sure you run this script from the coccinelle directory ?
+Alternatively, provide the coccinelle directory as the first argument.
 ";
 else
 
@@ -20,15 +28,15 @@ else
 
 # To find the data/ files such as the default standard.h file.
 # Cf also globals/config.ml
-echo setting COCCINELLE_HOME
-export COCCINELLE_HOME=`pwd`
+echo setting COCCINELLE_HOME=${COCCINELLE_HOME:=$DIR}
 
 # To find pycaml dynamic library
-echo setting LD_LIBRARY_PATH
-export LD_LIBRARY_PATH=$COCCINELLE_HOME:$LD_LIBRARY_PATH
+echo setting LD_LIBRARY_PATH=${LD_LIBRARY_PATH:=$COCCINELLE_HOME:$LD_LIBRARY_PATH}
 
 # To find .py files like the one in python/coccib
-echo setting PYTHONPATH
-export PYTHONPATH=$COCCINELLE_HOME/python:$PYTHONPATH
+echo setting PYTHONPATH=${PYTHONPATH:=$COCCINELLE_HOME/python:$PYTHONPATH}
+
+export COCCINELLE_HOME LD_LIBRARY_PATH PYTHONPATH
+
+fi
 
-fi
\ No newline at end of file
dissimilarity index 100%
index c3ba0c6..8c6112e 100644 (file)
@@ -1,6 +1,9 @@
-classic_patch.cmo: classic_patch.cmi 
-classic_patch.cmx: classic_patch.cmi 
-kbuild.cmo: kbuild.cmi 
-kbuild.cmx: kbuild.cmi 
-maintainers.cmo: maintainers.cmi 
-maintainers.cmx: maintainers.cmi 
+classic_patch.cmi: ../commons/common.cmi 
+kbuild.cmi: ../commons/common.cmi 
+maintainers.cmi: ../commons/common.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 
+kbuild.cmx: ../commons/common.cmx kbuild.cmi 
+maintainers.cmo: ../commons/common.cmi maintainers.cmi 
+maintainers.cmx: ../commons/common.cmx maintainers.cmi 
index 2dd7e18..dc26e71 100644 (file)
@@ -1,3 +1,5 @@
+-include ../Makefile.config
+
 TARGET=extra
 
 SOURCES = classic_patch.ml kbuild.ml maintainers.ml
@@ -12,7 +14,7 @@ INCLUDES= -I ../commons -I ../globals -I  ../parsing_cocci -I  ../parsing_c
 OCAMLCFLAGS ?= -g -dtypes
 OCAMLC =ocamlc$(OPTBIN) $(OCAMLCFLAGS) $(INCLUDES)
 OCAMLOPT = ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
-OCAMLDEP = ocamldep$(OPTBIN) #$(INCLUDES)
+OCAMLDEP = ocamldep$(OPTBIN) $(INCLUDES)
 OCAMLMKTOP=ocamlmktop -g -custom $(INCLUDES)
 
 
index a235bbb..d566808 100644 (file)
@@ -1,3 +1,6 @@
+
+-include ../Makefile.config
+
 ##############################################################################
 # Variables
 ##############################################################################
@@ -14,7 +17,7 @@ INCLUDES=
 OCAMLCFLAGS ?= -g -dtypes
 OCAMLC =ocamlc$(OPTBIN) $(OCAMLCFLAGS) $(INCLUDES)
 OCAMLOPT = ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
-OCAMLDEP = ocamldep$(OPTBIN) #$(INCLUDES)
+OCAMLDEP = ocamldep$(OPTBIN) $(INCLUDES)
 OCAMLMKTOP=ocamlmktop -g -custom $(INCLUDES)
 
 OBJS= $(SRC:.ml=.cmo)
index 48a98ce..cf9f4a3 100644 (file)
@@ -1,4 +1,4 @@
-let version = "0.1.5"
+let version = "0.1.6"
 
 let path = 
   try (Sys.getenv "COCCINELLE_HOME") 
index c177bca..ffc257b 100644 (file)
@@ -16,7 +16,9 @@ let pyoutput = ref "coccilib.output.Console"
 let patch = ref (None : string option)
 
 let make_hrule = ref (None : string (*dir*) option)
+let hrule_per_file = ref true (* if false, then a rule per function *)
 
 let currentfile = ref (None : string option)
 
 let current_element = ref ""
+let dir = ref ""
diff --git a/main.ml b/main.ml
index 992b6ae..a49d8a0 100644 (file)
--- a/main.ml
+++ b/main.ml
@@ -239,7 +239,7 @@ let short_options = [
     "  guess what";
 
   "-date",   Arg.Unit (fun () -> 
-    pr2 "version: $Date: 2009/02/03 17:17:04 $";
+    pr2 "version: $Date: 2009/02/19 16:00:47 $";
     raise (Common.UnixExit 0)
     ), 
   "   guess what";
@@ -701,14 +701,21 @@ let main () =
               | true, "", true -> 
                   if not (null xs)
                   then failwith "-use_glimpse can accept only one dir";
-                  
+
+                 Flag.dir := x;
                   let files =
                    match glimpse_filter (!cocci_file, !Config.std_iso) x with
                      None ->
                        Common.cmd_to_list (* same as "true, "", _" case *)
                          (if !include_headers
+                            (* FIXME : Could we remove xs ?
+                               -use_glimpse requires a singleton.
+                               This is checked some lines before.
                          then ("find "^(join " " (x::xs))^" -name \"*.[ch]\"")
                          else ("find "^(join " " (x::xs))^" -name \"*.c\""))
+                            *)
+                         then ("find "^ x ^" -name \"*.[ch]\"")
+                         else ("find "^ x ^" -name \"*.c\""))
                    | Some files -> files in
                   files +> List.map (fun x -> [x])
               (* normal *)
index 347c951..f98c9e4 100644 (file)
@@ -1,3 +1,6 @@
+
+-include ../Makefile.config
+
 ##############################################################################
 # Variables
 ##############################################################################
@@ -23,7 +26,7 @@ OCAMLOPT= ocamlopt$(OPTBIN) $(OPTFLAGS) $(EXTRAOPT)   $(INCLUDES)
 OCAMLOPT2=ocamlopt$(OPTBIN) $(OPTFLAGS)              $(INCLUDES) 
 OCAMLLEX=ocamllex$(OPTBIN)
 OCAMLYACC=ocamlyacc -v
-OCAMLDEP=ocamldep$(OPTBIN) #$(INCLUDES)
+OCAMLDEP=ocamldep$(OPTBIN) $(INCLUDES)
 OCAMLMKTOP=ocamlmktop -g -custom $(INCLUDES)
 
 OBJS= $(SRC:.ml=.cmo)
dissimilarity index 83%
index b88c717..7af0138 100644 (file)
-ast_to_flow.cmi: control_flow_c.cmi ast_c.cmo 
-control_flow_c.cmi: ast_c.cmo 
-cpp_ast_c.cmi: parsing_stat.cmo parse_c.cmi ast_c.cmo 
-parse_c.cmi: parsing_stat.cmo parsing_hacks.cmi parser_c.cmi ast_c.cmo 
-parser_c.cmi: ast_c.cmo 
-parsing_hacks.cmi: parser_c.cmi 
-pretty_print_c.cmi: control_flow_c.cmi ast_c.cmo 
-token_helpers.cmi: parser_c.cmi ast_c.cmo 
-type_annoter_c.cmi: ast_c.cmo 
-type_c.cmi: ast_c.cmo 
-unparse_c.cmi: parse_c.cmi 
-unparse_cocci.cmi: pretty_print_c.cmi ast_c.cmo 
-unparse_hrule.cmi: ast_c.cmo 
-visitor_c.cmi: control_flow_c.cmi ast_c.cmo 
-ast_to_flow.cmo: visitor_c.cmi flag_parsing_c.cmo control_flow_c.cmi \
-    ast_c.cmo ast_to_flow.cmi 
-ast_to_flow.cmx: visitor_c.cmx flag_parsing_c.cmx control_flow_c.cmx \
-    ast_c.cmx ast_to_flow.cmi 
-compare_c.cmo: visitor_c.cmi token_helpers.cmi parser_c.cmi parse_c.cmi \
-    lib_parsing_c.cmo flag_parsing_c.cmo ast_c.cmo compare_c.cmi 
-compare_c.cmx: visitor_c.cmx token_helpers.cmx parser_c.cmx parse_c.cmx \
-    lib_parsing_c.cmx flag_parsing_c.cmx ast_c.cmx compare_c.cmi 
-control_flow_c.cmo: flag_parsing_c.cmo ast_c.cmo control_flow_c.cmi 
-control_flow_c.cmx: flag_parsing_c.cmx ast_c.cmx control_flow_c.cmi 
-cpp_ast_c.cmo: visitor_c.cmi parse_c.cmi flag_parsing_c.cmo ast_c.cmo \
-    cpp_ast_c.cmi 
-cpp_ast_c.cmx: visitor_c.cmx parse_c.cmx flag_parsing_c.cmx ast_c.cmx \
-    cpp_ast_c.cmi 
-lexer_c.cmo: parser_c.cmi flag_parsing_c.cmo ast_c.cmo 
-lexer_c.cmx: parser_c.cmx flag_parsing_c.cmx ast_c.cmx 
-lexer_parser.cmo: flag_parsing_c.cmo lexer_parser.cmi 
-lexer_parser.cmx: flag_parsing_c.cmx lexer_parser.cmi 
-lib_parsing_c.cmo: visitor_c.cmi ast_c.cmo 
-lib_parsing_c.cmx: visitor_c.cmx ast_c.cmx 
-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 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 ast_c.cmx parse_c.cmi 
-parser_c.cmo: semantic_c.cmo parsing_stat.cmo lexer_parser.cmi \
-    flag_parsing_c.cmo ast_c.cmo parser_c.cmi 
-parser_c.cmx: semantic_c.cmx parsing_stat.cmx lexer_parser.cmx \
-    flag_parsing_c.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 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 ast_c.cmx parsing_hacks.cmi 
-pretty_print_c.cmo: lib_parsing_c.cmo flag_parsing_c.cmo control_flow_c.cmi \
-    ast_c.cmo pretty_print_c.cmi 
-pretty_print_c.cmx: lib_parsing_c.cmx flag_parsing_c.cmx control_flow_c.cmx \
-    ast_c.cmx pretty_print_c.cmi 
-test_parsing_c.cmo: visitor_c.cmi unparse_c.cmi type_annoter_c.cmi \
-    parsing_stat.cmo parse_c.cmi flag_parsing_c.cmo cpp_ast_c.cmi \
-    compare_c.cmi ast_to_flow.cmi ast_c.cmo test_parsing_c.cmi 
-test_parsing_c.cmx: visitor_c.cmx unparse_c.cmx type_annoter_c.cmx \
-    parsing_stat.cmx parse_c.cmx flag_parsing_c.cmx cpp_ast_c.cmx \
-    compare_c.cmx ast_to_flow.cmx ast_c.cmx test_parsing_c.cmi 
-token_helpers.cmo: parser_c.cmi ast_c.cmo token_helpers.cmi 
-token_helpers.cmx: parser_c.cmx ast_c.cmx token_helpers.cmi 
-type_annoter_c.cmo: visitor_c.cmi type_c.cmi parse_c.cmi lib_parsing_c.cmo \
-    flag_parsing_c.cmo ast_c.cmo type_annoter_c.cmi 
-type_annoter_c.cmx: visitor_c.cmx type_c.cmx parse_c.cmx lib_parsing_c.cmx \
-    flag_parsing_c.cmx ast_c.cmx type_annoter_c.cmi 
-type_c.cmo: ast_c.cmo type_c.cmi 
-type_c.cmx: ast_c.cmx type_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 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 ast_c.cmx \
-    unparse_c.cmi 
-unparse_cocci.cmo: pretty_print_c.cmi ast_c.cmo unparse_cocci.cmi 
-unparse_cocci.cmx: pretty_print_c.cmx ast_c.cmx unparse_cocci.cmi 
-unparse_hrule.cmo: visitor_c.cmi unparse_cocci.cmi pretty_print_c.cmi \
-    ast_c.cmo unparse_hrule.cmi 
-unparse_hrule.cmx: visitor_c.cmx unparse_cocci.cmx pretty_print_c.cmx \
-    ast_c.cmx unparse_hrule.cmi 
-visitor_c.cmo: control_flow_c.cmi ast_c.cmo visitor_c.cmi 
-visitor_c.cmx: control_flow_c.cmx ast_c.cmx visitor_c.cmi 
+ast_to_flow.cmi: control_flow_c.cmi ../commons/common.cmi ast_c.cmo 
+comment_annotater_c.cmi: parser_c.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: parsing_stat.cmo parse_c.cmi ../commons/common.cmi ast_c.cmo 
+lexer_parser.cmi: ../commons/common.cmi 
+parse_c.cmi: parsing_stat.cmo parsing_hacks.cmi parser_c.cmi \
+    ../commons/common.cmi ast_c.cmo 
+parser_c.cmi: token_c.cmo ast_c.cmo 
+parsing_hacks.cmi: parser_c.cmi ../commons/common.cmi 
+pretty_print_c.cmi: ../commons/ograph_extended.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 
+type_c.cmi: ast_c.cmo 
+unparse_c.cmi: parse_c.cmi ../commons/common.cmi 
+unparse_cocci.cmi: pretty_print_c.cmi ../parsing_cocci/ast_cocci.cmi \
+    ast_c.cmo 
+unparse_hrule.cmi: ../commons/common.cmi ../parsing_cocci/ast_cocci.cmi \
+    ast_c.cmo 
+visitor_c.cmi: control_flow_c.cmi ../commons/common.cmi ast_c.cmo 
+ast_c.cmo: token_c.cmo ../commons/common.cmi ../parsing_cocci/ast_cocci.cmi 
+ast_c.cmx: token_c.cmx ../commons/common.cmx ../parsing_cocci/ast_cocci.cmx 
+ast_to_flow.cmo: visitor_c.cmi ../commons/ograph_extended.cmi \
+    ../commons/ocollection/oassocb.cmo ../commons/oassoc.cmi \
+    flag_parsing_c.cmo control_flow_c.cmi ../commons/common.cmi ast_c.cmo \
+    ast_to_flow.cmi 
+ast_to_flow.cmx: visitor_c.cmx ../commons/ograph_extended.cmx \
+    ../commons/ocollection/oassocb.cmx ../commons/oassoc.cmx \
+    flag_parsing_c.cmx control_flow_c.cmx ../commons/common.cmx ast_c.cmx \
+    ast_to_flow.cmi 
+comment_annotater_c.cmo: token_helpers.cmi token_c.cmo parser_c.cmi \
+    ../commons/common.cmi ast_c.cmo comment_annotater_c.cmi 
+comment_annotater_c.cmx: token_helpers.cmx token_c.cmx parser_c.cmx \
+    ../commons/common.cmx ast_c.cmx comment_annotater_c.cmi 
+compare_c.cmo: visitor_c.cmi token_helpers.cmi parser_c.cmi parse_c.cmi \
+    lib_parsing_c.cmo flag_parsing_c.cmo ../commons/common.cmi ast_c.cmo \
+    compare_c.cmi 
+compare_c.cmx: visitor_c.cmx token_helpers.cmx parser_c.cmx parse_c.cmx \
+    lib_parsing_c.cmx flag_parsing_c.cmx ../commons/common.cmx ast_c.cmx \
+    compare_c.cmi 
+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 
+lexer_c.cmx: parser_c.cmx flag_parsing_c.cmx ../commons/common.cmx ast_c.cmx 
+lexer_parser.cmo: flag_parsing_c.cmo ../commons/common.cmi lexer_parser.cmi 
+lexer_parser.cmx: flag_parsing_c.cmx ../commons/common.cmx lexer_parser.cmi 
+lib_parsing_c.cmo: visitor_c.cmi ../globals/flag.cmo ../commons/common.cmi \
+    ../parsing_cocci/ast_cocci.cmi ast_c.cmo 
+lib_parsing_c.cmx: visitor_c.cmx ../globals/flag.cmx ../commons/common.cmx \
+    ../parsing_cocci/ast_cocci.cmx ast_c.cmx 
+parse_c.cmo: visitor_c.cmi token_helpers.cmi token_c.cmo 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 token_c.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: token_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: token_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 token_c.cmo 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 token_c.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: ../commons/ograph_extended.cmi lib_parsing_c.cmo \
+    flag_parsing_c.cmo control_flow_c.cmi ../commons/common.cmi ast_c.cmo \
+    pretty_print_c.cmi 
+pretty_print_c.cmx: ../commons/ograph_extended.cmx lib_parsing_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: visitor_c.cmi unparse_c.cmi type_annoter_c.cmi \
+    pretty_print_c.cmi parsing_stat.cmo parse_c.cmi \
+    ../commons/ograph_extended.cmi flag_parsing_c.cmo cpp_ast_c.cmi \
+    compare_c.cmi ../commons/common.cmi comment_annotater_c.cmi \
+    ast_to_flow.cmi ast_c.cmo test_parsing_c.cmi 
+test_parsing_c.cmx: visitor_c.cmx unparse_c.cmx type_annoter_c.cmx \
+    pretty_print_c.cmx parsing_stat.cmx parse_c.cmx \
+    ../commons/ograph_extended.cmx flag_parsing_c.cmx cpp_ast_c.cmx \
+    compare_c.cmx ../commons/common.cmx comment_annotater_c.cmx \
+    ast_to_flow.cmx ast_c.cmx test_parsing_c.cmi 
+token_c.cmo: ../commons/common.cmi 
+token_c.cmx: ../commons/common.cmx 
+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 \
+    token_helpers.cmi 
+type_annoter_c.cmo: visitor_c.cmi type_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 type_c.cmx parse_c.cmx lib_parsing_c.cmx \
+    flag_parsing_c.cmx ../commons/common.cmx ast_c.cmx type_annoter_c.cmi 
+type_c.cmo: ../commons/common.cmi ast_c.cmo type_c.cmi 
+type_c.cmx: ../commons/common.cmx ast_c.cmx type_c.cmi 
+unparse_c.cmo: visitor_c.cmi unparse_cocci.cmi token_helpers.cmi token_c.cmo \
+    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 token_c.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_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_hrule.cmo: visitor_c.cmi ../parsing_cocci/visitor_ast.cmi \
+    unparse_cocci.cmi ../parsing_cocci/type_cocci.cmi pretty_print_c.cmi \
+    ../globals/flag.cmo ../commons/common.cmi ../parsing_cocci/ast_cocci.cmi \
+    ast_c.cmo unparse_hrule.cmi 
+unparse_hrule.cmx: visitor_c.cmx ../parsing_cocci/visitor_ast.cmx \
+    unparse_cocci.cmx ../parsing_cocci/type_cocci.cmx pretty_print_c.cmx \
+    ../globals/flag.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 \
+    visitor_c.cmi 
+visitor_c.cmx: control_flow_c.cmx ../commons/common.cmx ast_c.cmx \
+    visitor_c.cmi 
index 6a38ace..68b0c5a 100644 (file)
@@ -1,3 +1,6 @@
+
+-include ../Makefile.config
+
 ##############################################################################
 # Variables
 ##############################################################################
@@ -6,7 +9,7 @@ TARGET=parsing_c
 
 # - type_cocci.ml ast_cocci.ml  # + unparse_hrule 
 SRC= flag_parsing_c.ml parsing_stat.ml \
- ast_c.ml control_flow_c.ml type_c.ml \
token_c.ml ast_c.ml control_flow_c.ml type_c.ml \
  visitor_c.ml lib_parsing_c.ml \
  ast_to_flow.ml \
  pretty_print_c.ml \
@@ -15,7 +18,8 @@ SRC= flag_parsing_c.ml parsing_stat.ml \
  unparse_cocci.ml unparse_c.ml unparse_hrule.ml  \
  parse_c.ml \
  cpp_ast_c.ml \
- compare_c.ml type_annoter_c.ml \
+ type_annoter_c.ml comment_annotater_c.ml \
+ compare_c.ml \
  test_parsing_c.ml
 
 
@@ -48,7 +52,7 @@ OCAMLC=ocamlc$(OPTBIN) $(OCAMLCFLAGS) $(INCLUDES)
 OCAMLOPT=ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
 OCAMLLEX=ocamllex$(OPTBIN) #-ml
 OCAMLYACC=ocamlyacc -v
-OCAMLDEP=ocamldep$(OPTBIN) #$(INCLUDES)
+OCAMLDEP=ocamldep$(OPTBIN) $(INCLUDES)
 OCAMLMKTOP=ocamlmktop -g -custom $(INCLUDES)
 
 
index 0c4e864..4f4c187 100644 (file)
@@ -1,4 +1,6 @@
-(* Copyright (C) 2002, 2006, 2007, 2008 Yoann Padioleau
+(* Yoann Padioleau
+ * 
+ * Copyright (C) 2002, 2006, 2007, 2008, 2009 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)
@@ -22,6 +24,12 @@ open Common
  * 
  * Update: Now I use a ref! in those 'info' so take care.
  * 
+ * That means that modifications of the info of tokens can have
+ * an effect on the info stored in the ast (which is sometimes 
+ * convenient, cf unparse_c.ml or comment_annotater_c.ml)
+ * 
+ * 
+ * 
  * 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.
@@ -86,6 +94,7 @@ type parse_info =
   | FakeTok of string * virtual_position
   (* Present both in ast and list of tokens.  *)
   | ExpandedTok of Common.parse_info * virtual_position
+
   (* Present neither in ast nor in list of tokens
    * but only in the '+' of the mcode of some tokens. Those kind of tokens
    * are used to be able to use '=' to compare big ast portions.
@@ -98,7 +107,7 @@ type info = {
    * transformations by tagging the tokens involved in this transformation. 
    *)
   cocci_tag: (Ast_cocci.mcodekind * metavars_binding) ref;
-  (* set in comment_annotater.ml *)
+  (* set in comment_annotater_c.ml *)
   comments_tag: comments_around ref;
   (* todo? token_info : sometimes useful to know what token it was *)
   }
@@ -248,7 +257,7 @@ and attribute = attributebis wrap
 (* ------------------------------------------------------------------------- *)
 and expression = (expressionbis * exp_info ref (* semantic: *)) wrap
  and exp_info = exp_type option * test
-  and exp_type = fullType * local
+  and exp_type = fullType (* Type_c.completed_and_simplified *) * local
     and local = LocalVar of parse_info | NotLocalVar (* cocci: *)
   and test = Test | NotTest (* cocci: *)
 
@@ -296,8 +305,8 @@ and expression = (expressionbis * exp_info ref (* semantic: *)) wrap
   (* cppext: IfdefExpr TODO *)
 
   (* cppext: normmally just expression *)
-  and argument = (expression, wierd_argument) either
-   and wierd_argument = 
+  and argument = (expression, weird_argument) either
+   and weird_argument = 
        | ArgType of parameterType
        | ArgAction of action_macro
       and action_macro = 
@@ -314,8 +323,8 @@ and expression = (expressionbis * exp_info ref (* semantic: *)) wrap
    * integer only. *)
 
   and constant = 
-    | String of (string * isWchar) 
-    | MultiString  (* can contain MacroString, todo: more info *)
+    | String of (string * isWchar)
+    | MultiString of string list (* can contain MacroString, todo: more info *)
     | Char   of (string * isWchar) (* normally it is equivalent to Int *)
     | Int    of (string  (* * intType*)) 
     | Float  of (string * floatType)
@@ -562,7 +571,7 @@ and includ =
  and inc_file = 
   | Local    of inc_elem list
   | NonLocal of inc_elem list
-  | Wierd of string (* ex: #include SYSTEM_H *)
+  | Weird of string (* ex: #include SYSTEM_H *)
   and inc_elem = string
 
  (* cocci: to tag the first of #include <xx/> and last of #include <yy/>
@@ -648,11 +657,15 @@ and metavars_binding = (Ast_cocci.meta_name, metavar_binding_kind) assoc
  * (already use for c stuff) and "com" is too long.
  *)
 
-(* this type will be associated to each token *)
+(* this type will be associated to each token.
+ *)
 and comments_around = {
+  mbefore: Token_c.comment_like_token list;
+  mafter:  Token_c.comment_like_token list;
+}
+(* old: can do something simpler than CComment for coccinelle, cf above.
   mbefore: comment_and_relative_pos list;
   mafter:  comment_and_relative_pos list;
-}
   and comment_and_relative_pos = {
 
    minfo: Common.parse_info;
@@ -671,22 +684,7 @@ and comments_around = {
 
 and comment = Common.parse_info
 and com = comment list ref
-
-
-(*****************************************************************************)
-(* Cpp constructs put it comments in lexer or parsing_hack *)
-(*****************************************************************************)
-
-(* This type is not in the Ast but is associated with the TCommentCpp token.
- * I put this enum here because parser_c.mly need it. I could have put
- * it also in lexer_parser.
- *)
-type cppcommentkind = 
-  | CppDirective 
-  | CppAttr 
-  | CppMacro 
-  | CppPassingNormal (* ifdef 0, cplusplus, etc *) 
-  | CppPassingCosWouldGetError (* expr passsing *)
+*)
 
 
 
@@ -747,6 +745,7 @@ let unwrap = fst
 
 let unwrap2 = fst
 
+
 let unwrap_expr ((unwrap_e, typ), iie) = unwrap_e
 let rewrap_expr ((_old_unwrap_e, typ), iie)  newe = ((newe, typ), iie)
 
@@ -760,6 +759,12 @@ let get_onlytype_expr ((unwrap_e, typ), iie) =
   | Some (ft,_local), _test -> Some ft
   | None, _ -> None
 
+let get_onlylocal_expr ((unwrap_e, typ), iie) = 
+  match !typ with
+  | Some (ft,local), _test -> Some local
+  | None, _ -> None
+
+
 
 let unwrap_typeC (qu, (typeC, ii)) = typeC
 let rewrap_typeC (qu, (typeC, ii)) newtypeC  = (qu, (newtypeC, ii))
@@ -998,13 +1003,13 @@ let s_of_inc_file inc_file =
   match inc_file with
   | Local xs -> xs +> Common.join "/"
   | NonLocal xs -> xs +> Common.join "/"
-  | Wierd s -> s
+  | Weird 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
+  | Weird s -> s
 
 let fieldname_of_fieldkind fieldkind = 
   match unwrap fieldkind with
@@ -1021,3 +1026,6 @@ let s_of_attr attr =
 let type_of_parameter param = 
   let ((b, sopt, typ), ii) = param in 
   typ
+let name_of_parameter param = 
+  let ((b, sopt, typ), ii) = param in 
+  sopt
index 5f6e930..7ec3cf2 100644 (file)
@@ -1,3 +1,16 @@
+(* Yoann Padioleau
+ * 
+ * Copyright (C) 2006, 2007 Ecole des Mines de Nantes
+ *
+ * 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
 
 open Ast_c
@@ -1237,7 +1250,7 @@ let deadcode_detection g =
       | x -> 
           (match Control_flow_c.extract_fullstatement node with
           | Some (st, ii) -> raise (Error (DeadCode (Some (pinfo_of_ii ii))))
-          | _ -> pr2 "CFG: orphelin nodes, maybe something wierd happened"
+          | _ -> pr2 "CFG: orphelin nodes, maybe something weird happened"
           )
       )
   )
diff --git a/parsing_c/comment_annotater_c.ml b/parsing_c/comment_annotater_c.ml
new file mode 100644 (file)
index 0000000..d4fb2a3
--- /dev/null
@@ -0,0 +1,140 @@
+(* Yoann Padioleau
+ *
+ * Copyright (C) 2009 University of Urbana Champaign
+ *
+ * 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
+
+module T = Token_c
+
+
+(*****************************************************************************)
+(* Prelude *)
+(*****************************************************************************)
+
+(* A trimmed down version of my comment_annotater of CComment. In CComment
+ * I was also trying to associate the comment to the relevant entity, not 
+ * just the closest token (e.g. a function comment is not placed next to the
+ * identifier of the function but before its return type or storage).
+ *)
+
+
+(*****************************************************************************)
+(* Helpers *)
+(*****************************************************************************)
+
+let is_comment_or_space_or_stuff tok = 
+  Token_helpers.is_not_in_ast tok && Token_helpers.is_origin tok
+
+(* coupling with token_helpers.is_not_in_ast, and of course with tokens_c.ml *)
+let convert_relevant_tokens x = 
+  assert (Token_helpers.is_origin x);
+
+  match x with 
+  | Parser_c.TCommentSpace info -> 
+      Token_c.TCommentSpace, (Ast_c.parse_info_of_info info)
+  | Parser_c.TCommentNewline info -> 
+      Token_c.TCommentNewline, (Ast_c.parse_info_of_info info)
+
+  | Parser_c.TComment info ->
+      Token_c.TComment, (Ast_c.parse_info_of_info info)
+
+  (* the passed tokens because of our limited handling of cpp *)
+  | Parser_c.TCommentCpp(cppcommentkind, info) -> 
+      Token_c.TCommentCpp cppcommentkind, (Ast_c.parse_info_of_info info)
+
+  | _ -> raise Impossible
+
+
+(*****************************************************************************)
+(* Main entry *)
+(*****************************************************************************)
+
+(* right now we just add comment-like and origin-tok tokens, 
+ * as explained in token_c.ml.
+ *
+ * This simplified comment_annotater (compared to CComment) is really
+ * simple as the tokens and the Ast_c.info in the asts actually share
+ * the same refs.
+ * So, modifying fields in the tokens will also modify the info in 
+ * the ast. Sometimes side effects simplify programming ...
+ * We use similar tricks in unparse_c.ml. So really the asts argument
+ * is not needed.
+ * 
+ * ex: C1 C2 T1 T2 C3 C4 T3 C5 T4. 
+ *  => infoT1(-C1C2,+), infoT2(-,+C3C4), infoT3(-C3C4,+C5), infoT4(-C5,+)
+ *)
+
+(*
+let (agglomerate_either: 
+ ('a, 'a) Common.either list -> ('a list, 'a list) Common.either list) = fun xs ->
+  raise Todo
+
+let (span_and_pack: 
+ ('a -> ('a, 'a) Common.either) -> 'a list -> 
+      ('a list, 'a list) Common.either list) = fun f_either xs -> 
+  let xs' = List.map f_either xs in
+  agglomerate_either xs'
+*)
+
+
+(* the asts is not really used, we do all via side effect on the tokens, 
+ * which share the info reference with the elements in the ast.
+ *)
+let annotate_program toks asts = 
+   (* Common.exclude_but_keep_attached gather all comments before a
+    * token and then associates to this token those comments. Note that
+    * if reverse the list of tokens then this function can also be used
+    * to gather all the comments after a token :) 
+    *)
+
+   (* before phase *)
+   let toks_with_before = 
+     Common.exclude_but_keep_attached is_comment_or_space_or_stuff
+       toks 
+   in
+
+  (* after phase. trick: reverse the tokens and reuse previous func *)
+   let toks_with_after =
+     List.rev
+       (List.map
+         (function (x,l) -> (x,List.rev l))
+         (Common.exclude_but_keep_attached is_comment_or_space_or_stuff 
+             (List.rev toks)))
+   in
+
+  (* merge *)
+   assert(List.length toks_with_after = List.length toks_with_before);
+
+   Common.zip toks_with_before toks_with_after 
+   +> List.iter (fun ((t1, before), (t2, after)) -> 
+
+     assert(t1 = t2);
+
+     let before' = before +> List.map convert_relevant_tokens in
+     let after' = after  +> List.map convert_relevant_tokens in
+
+     let info = Token_helpers.info_of_tok t1 in
+     info.Ast_c.comments_tag :=
+       { Ast_c.mbefore = before';
+         Ast_c.mafter = after';
+       };
+     
+   );
+   (* modified via side effect. I return it just to have a 
+    * clean signature.
+    *)
+   asts
+   
+  
+  
+  
diff --git a/parsing_c/comment_annotater_c.mli b/parsing_c/comment_annotater_c.mli
new file mode 100644 (file)
index 0000000..d890cb6
--- /dev/null
@@ -0,0 +1,5 @@
+(* !!Annotate via side effects!!. Fill in the comments_around
+ * information that was put to empty during parsing.
+ *)
+val annotate_program : 
+  Parser_c.token list -> Ast_c.toplevel list -> Ast_c.toplevel list
index 4070927..0a5196f 100644 (file)
@@ -1,3 +1,16 @@
+(* Yoann Padioleau
+ * 
+ * Copyright (C) 2006, 2007 Ecole des Mines de Nantes
+ *
+ * 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
 
 open Ast_c
index 2b23662..77843ae 100644 (file)
@@ -1,3 +1,16 @@
+(* Yoann Padioleau
+ * 
+ * Copyright (C) 2006, 2007, 2008 Ecole des Mines de Nantes
+ *
+ * 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
 
 open Ast_c
index 3d711d6..ec8d3c7 100644 (file)
@@ -1,4 +1,6 @@
-(* Copyright (C) 2008, 2009 University of Urbana Champaign
+(* Yoann Padioleau
+ * 
+ * Copyright (C) 2008, 2009 University of Urbana Champaign
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License (GPL)
@@ -125,8 +127,8 @@ let find_header_file1 cppopts dirname inc_file =
         then Some finalfile
         else None
       )
-  | Wierd s -> 
-      pr2 ("CPPAST: wierd include not handled:" ^ s);
+  | Weird s -> 
+      pr2 ("CPPAST: weird include not handled:" ^ s);
       []
 
 (* todo? can try find most precise ? first just use basename but
@@ -148,7 +150,7 @@ let find_header_file2 inc_file =
           []
       | x::y::xs -> res
       )
-  | Wierd s -> 
+  | Weird s -> 
       []
 
 
@@ -371,8 +373,8 @@ let rec cpp_ifdef_statementize ast =
                       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 
+                    pr2 "weird: first directive is not a ifdef";
+                    (* maybe not weird, just that should_ifdefize 
                      * returned false *)
                     Visitor_c.vk_statement_sequencable_s bigf stseq::aux xs
                 )
index 2a01793..2ee65f7 100644 (file)
@@ -58,6 +58,7 @@ let filter_define_error = ref false
 let filter_passed_level = ref 0
 
 let pretty_print_type_info = ref false
+let pretty_print_comment_info = ref false
 
 (* cocci specific *)
 let show_flow_labels = ref true
index 531b582..7c4e312 100644 (file)
@@ -1,5 +1,7 @@
 {
-(* Copyright (C) 2002, 2006, 2007, 2008 Yoann Padioleau
+(* Yoann Padioleau
+ * 
+ * Copyright (C) 2002, 2006, 2007, 2008, 2009, Ecole des Mines de Nantes
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License (GPL)
@@ -213,7 +215,15 @@ rule token = parse
   | "/*" 
       { let info = tokinfo lexbuf in 
         let com = comment lexbuf in
-        TComment(info +> tok_add_s com) 
+
+        let info' = info +> tok_add_s com in
+        let s = Ast_c.str_of_info info' in
+        match s with
+        | "/* {{coccinelle:skip_start}} */" -> 
+            TCommentSkipTagStart (info')
+        | "/* {{coccinelle:skip_end}} */" -> 
+            TCommentSkipTagEnd (info')
+        | _ -> TComment(info') 
       }
 
 
@@ -522,7 +532,7 @@ rule token = parse
   | "%=" { TAssign (OpAssign Mod, (tokinfo lexbuf))} 
   | "&=" { TAssign (OpAssign And, (tokinfo lexbuf))}  
   | "|=" { TAssign (OpAssign Or, (tokinfo lexbuf)) } 
-  | "^=" { TAssign(OpAssign Xor, (tokinfo lexbuf))} 
+  | "^=" { TAssign (OpAssign Xor, (tokinfo lexbuf))} 
   | "<<=" {TAssign (OpAssign DecLeft, (tokinfo lexbuf)) } 
   | ">>=" {TAssign (OpAssign DecRight, (tokinfo lexbuf))}
 
index 7465bab..c54b786 100644 (file)
@@ -1,4 +1,6 @@
-(* Copyright (C) 2002-2008 Yoann Padioleau
+(* Yoann Padioleau
+ * 
+ * Copyright (C) 2002, 2006 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)
index 9e81a6d..1d328a8 100644 (file)
@@ -1,4 +1,6 @@
-(* Copyright (C) 2007, 2008 Yoann Padioleau
+(* Yoann Padioleau
+ * 
+ * Copyright (C) 2007, 2008, 2009 Ecole des Mines de Nantes
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License (GPL)
@@ -90,7 +92,8 @@ let semi_al_program = List.map (Visitor_c.vk_toplevel_s semi_strip_info_visitor)
 
 
 
-
+(* really strip, do not keep position nor anything specificities, true
+ * abstracted form. *)
 let real_strip_info_visitor _ = 
   { Visitor_c.default_visitor_c_s with
     Visitor_c.kinfo_s = (fun (k,_) i ->
@@ -211,3 +214,26 @@ let (range_of_origin_ii: Ast_c.info list -> (int * int) option) =
       (Ast_c.pos_of_info min, Ast_c.pos_of_info max + String.length strmax)
   with _ -> 
     None
+
+
+(*****************************************************************************)
+(* Ast getters *)
+(*****************************************************************************)
+
+let names_of_parameters_in_def def = 
+  match def.Ast_c.f_old_c_style with
+  | Some _ -> 
+      pr2_once "names_of_parameters_in_def: f_old_c_style not handled";
+      []
+  | None -> 
+      let ftyp = def.Ast_c.f_type in
+      let (ret, (params, bwrap)) = ftyp in
+      params +> Common.map_filter (fun (param,ii) -> 
+        Ast_c.name_of_parameter param
+      )
+
+let names_of_parameters_in_macro xs = 
+  xs +> List.map (fun (xx, ii) -> 
+    let (s, ii2) = xx in
+    s
+  )
index a290261..e27a9db 100644 (file)
@@ -1,4 +1,6 @@
-(* Copyright (C) 2006, 2007, 2008 Yoann Padioleau
+(* Yoann Padioleau
+ * 
+ * Copyright (C) 2006, 2007, 2008 Ecole des Mines de Nantes
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License (GPL)
@@ -99,25 +101,25 @@ let commentized xs = xs +> Common.map_filter (function
         match !Flag_parsing_c.filter_passed_level with 
         | 0 -> false
         | 1 -> 
-            List.mem cppkind [Ast_c.CppAttr]
+            List.mem cppkind [Token_c.CppAttr]
             || 
             (s =~ "__.*")
         | 2 -> 
-            List.mem cppkind [Ast_c.CppAttr;Ast_c.CppPassingNormal]
+            List.mem cppkind [Token_c.CppAttr;Token_c.CppPassingNormal]
             || 
             (s =~ "__.*")
         | 3 -> 
-            List.mem cppkind [Ast_c.CppAttr;Ast_c.CppPassingNormal;Ast_c.CppDirective]
+            List.mem cppkind [Token_c.CppAttr;Token_c.CppPassingNormal;Token_c.CppDirective]
             || 
             (s =~ "__.*")
         | 4 -> 
-            List.mem cppkind [Ast_c.CppAttr;Ast_c.CppPassingNormal;Ast_c.CppMacro]
+            List.mem cppkind [Token_c.CppAttr;Token_c.CppPassingNormal;Token_c.CppMacro]
             || 
             (s =~ "__.*")
 
 
         | 5 -> 
-            List.mem cppkind [Ast_c.CppAttr;Ast_c.CppPassingNormal;Ast_c.CppDirective;Ast_c.CppMacro]
+            List.mem cppkind [Token_c.CppAttr;Token_c.CppPassingNormal;Token_c.CppDirective;Token_c.CppMacro]
             || 
             (s =~ "__.*")
 
@@ -670,14 +672,14 @@ let rec comment_until_defeol xs =
   | x::xs -> 
       (match x with
       | Parser_c.TDefEOL i -> 
-          Parser_c.TCommentCpp (Ast_c.CppDirective, TH.info_of_tok x)
+          Parser_c.TCommentCpp (Token_c.CppDirective, TH.info_of_tok x)
           ::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)
+            else Parser_c.TCommentCpp (Token_c.CppPassingNormal (*good?*), TH.info_of_tok x)
           in
           x'::comment_until_defeol xs
       )
@@ -864,7 +866,7 @@ let rec lexer_function ~pass tr = fun lexbuf ->
           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)
+            let v' = Parser_c.TCommentCpp (Token_c.CppDirective,TH.info_of_tok v)
             in
             tr.passed <- v'::tr.passed;
             tr.rest       <- comment_until_defeol tr.rest;
@@ -883,7 +885,7 @@ let rec lexer_function ~pass tr = fun lexbuf ->
           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
+            let v = Parser_c.TCommentCpp(Token_c.CppDirective, info) in
             tr.passed <- v::tr.passed;
             lexer_function ~pass tr lexbuf
           end
@@ -1087,7 +1089,7 @@ let parse_print_error_heuristic2 file =
               | _ -> false
               )
             else begin
-              pr2 "WIERD: length list of error recovery tokens < 2 ";
+              pr2 "WEIRD: length list of error recovery tokens < 2 ";
               false 
             end
           in
@@ -1132,7 +1134,7 @@ let parse_print_error_heuristic2 file =
 
           let pbline = 
             toks_of_bads 
-            +> Common.filter (TH.is_same_line line_error)
+            +> Common.filter (TH.is_same_line_or_close line_error)
             +> Common.filter TH.is_ident_like 
           in
           let error_info = 
index b586513..f6f91d5 100644 (file)
@@ -1,5 +1,7 @@
 %{
-(* Copyright (C) 2002, 2006, 2007, 2008 Yoann Padioleau
+(* 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)
@@ -191,8 +193,9 @@ let fixDeclSpecForFuncDef x =
   (match fst (unwrap storage) with
   | StoTypedef -> 
       raise (Semantic ("function definition declared 'typedef'", fake_pi))
-  | x -> (returnType, storage)
+  | _ -> (returnType, storage)
   )
+  
 
 (* parameter: (this is the context where we give parameter only when
  * in func DEFINITION not in funct DECLARATION) We must have a name.
@@ -248,7 +251,32 @@ let fixFunc (typ, compound, old_style_opt) =
           | (((bool, Some s, fullt), _), _) -> ()
          | _ -> ()
                 (* failwith "internal errror: fixOldCDecl not good" *)
-          ));
+          )
+      );
+      (* bugfix: cf tests_c/function_pointer4.c. 
+       * Apparemment en C on peut syntaxiquement ecrire ca:
+       * 
+       *   void a(int)(int x);
+       * mais apres gcc gueule au niveau semantique avec:
+       *   xxx.c:1: error: 'a' declared as function returning a function
+       * Je ne faisais pas cette verif. Sur du code comme 
+       *   void METH(foo)(int x) { ...} , le parser croit (a tort) que foo 
+       * est un typedef, et donc c'est parsé comme l'exemple precedent, 
+       * ce qui ensuite confuse l'unparser qui n'est pas habitué
+       * a avoir dans le returnType un FunctionType et qui donc
+       * pr_elem les ii dans le mauvais sens ce qui genere au final
+       * une exception. Hence this fix to at least detect the error 
+       * at parsing time (not unparsing time).
+       *)
+      (match Ast_c.unwrap_typeC fullt with 
+      | FunctionType _ -> 
+          pr2 (spf "WEIRD: %s declared as function returning a function." s);
+          pr2 (spf "This is probably because of a macro. Extend standard.h");
+          raise (Semantic (spf "error: %s " s, Ast_c.parse_info_of_info iis))
+      | _ -> ()
+      );
+
+
       (* it must be nullQualif,cos parser construct only this*)
       {f_name = s;
        f_type = (fullt, (params, bool));
@@ -293,6 +321,8 @@ let fix_add_params_ident = function
       )) 
   | _ -> ()
 
+
+
 (*-------------------------------------------------------------------------- *)
 (* shortcuts *)
 (*-------------------------------------------------------------------------- *)
@@ -456,14 +486,20 @@ let mk_e e ii = ((e, Ast_c.noType()), ii)
 /*(* other         *)*/
 /*(*---------------*)*/
 
+
+/*(* should disappear after parsing_hack *)*/
+%token <Ast_c.info> TCommentSkipTagStart TCommentSkipTagEnd
+
+
 /*(* appear after parsing_hack *)*/
 %token <Ast_c.info> TCParEOL   
 
 %token <Ast_c.info> TAction
 
 
+/*(* TCommentMisc still useful ? obsolete ? *)*/
 %token <Ast_c.info> TCommentMisc
-%token <(Ast_c.cppcommentkind * Ast_c.info)> TCommentCpp
+%token <(Token_c.cppcommentkind * Ast_c.info)> TCommentCpp
 
 
 /*(*-----------------------------------------*)*/
@@ -642,12 +678,12 @@ postfix_expr:
  | postfix_expr TDec          { mk_e(Postfix ($1, Dec)) [$2] }
 
  /*(* gccext: also called compound literals *)*/
- | topar2 type_name tcpar2 TOBrace TCBrace 
+ | topar2 type_name tcpar2 TOBrace TCBrace
      { mk_e(Constructor ($2, [])) [$1;$3;$4;$5] }
  | topar2 type_name tcpar2 TOBrace initialize_list gcc_comma_opt TCBrace
      { mk_e(Constructor ($2, List.rev $5)) ([$1;$3;$4;$7] ++ $6) }
 
-primary_expr: 
+primary_expr:
  | 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] }
@@ -656,11 +692,12 @@ primary_expr:
  | TOPar expr TCPar { mk_e(ParenExpr ($2)) [$1;$3] }  /*(* forunparser: *)*/
 
  /*(* gccext: cppext: TODO better ast ? *)*/
- | TMacroString { mk_e(Constant (MultiString)) [snd $1] }
- | string_elem string_list { mk_e(Constant (MultiString)) ($1 ++ $2) }
+ | TMacroString { mk_e(Constant (MultiString [fst $1])) [snd $1] }
+ | string_elem string_list
+     { mk_e(Constant (MultiString ["TODO: MultiString"])) ($1 ++ $2) }
 
  /*(* gccext: allow statement as expressions via ({ statement }) *)*/
- | TOPar compound TCPar  { mk_e(StatementExpr ($2)) [$1;$3] } 
+ | TOPar compound TCPar  { mk_e(StatementExpr ($2)) [$1;$3] }
 
 
 
@@ -670,7 +707,7 @@ primary_expr:
 
 /*(* cppext: *)*/
 /*(* to avoid conflicts have to introduce a _not_empty (ne) version *)*/
-argument_ne: 
+argument_ne:
  | assign_expr { Left $1 }
  | parameter_decl { Right (ArgType $1)  }
  | action_higherordermacro_ne { Right (ArgAction $1) }
@@ -1013,11 +1050,20 @@ direct_abstract_declarator:
      { 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
+ | topar parameter_type_list tcpar
      { fun x ->   (nQ, (FunctionType (x, $2),           [$1;$3]))}
- | direct_abstract_declarator TOPar TCPar
+/*(* subtle: here must also use topar, not TOPar, otherwise if have for
+   * instance   (xxx ( * )(xxx)) cast, then the second xxx may still be a Tident
+   * but we want to reduce topar, to set the InParameter so that 
+   * parsing_hack can get a chance to change the type of xxx into a typedef.
+   * That's an example where parsing_hack and the lookahead of ocamlyacc does
+   * not go very well together ... we got the info too late. We got 
+   * a similar pb with xxx xxx; declaration, cf parsing_hack.ml and the
+   * "disable typedef cos special case ..." message.
+*)*/
+ | direct_abstract_declarator topar tcpar
      { fun x ->$1 (nQ, (FunctionType (x, (([], (false, [])))),[$2;$3])) }
- | direct_abstract_declarator TOPar parameter_type_list TCPar
+ | direct_abstract_declarator topar parameter_type_list tcpar
      { fun x -> $1 (nQ, (FunctionType (x, $3), [$2;$4])) }
 
 /*(*-----------------------------------------------------------------------*)*/
@@ -1241,7 +1287,7 @@ initialize:
 
 /*
 (* opti: This time we use the weird order of non-terminal which requires in 
- * the "caller" to do a List.rev cos quite critical. With this wierd order it
+ * the "caller" to do a List.rev cos quite critical. With this weird order it
  * allows yacc to use a constant stack space instead of exploding if we would
  * do a  'initialize2 Tcomma initialize_list'.
  *)
@@ -1483,7 +1529,7 @@ cpp_directive:
          | _ when s =~ "^\\<\\(.*\\)\\>$" -> 
              NonLocal (Common.split "/" (matched1 s))
          | _ -> 
-             Wierd s 
+             Weird s 
        in
        Include { i_include = (inc_file, [i1;i2]);
                  i_rel_pos = Ast_c.noRelPos();
@@ -1528,7 +1574,7 @@ define_val:
      {
        (* TOREPUT 
        if fst $5 <> "0" 
-       then pr2 "WIERD: in macro and have not a while(0)";
+       then pr2 "WEIRD: in macro and have not a while(0)";
        *)
        DefineDoWhileZero (($2,$5),   [$1;$3;$4;$6])
      }
index 4c2c111..4468f7a 100644 (file)
@@ -1,4 +1,6 @@
-(* Copyright (C) 2007, 2008 Ecole des Mines de Nantes
+(* Yoann Padioleau
+ * 
+ * Copyright (C) 2007, 2008 Ecole des Mines de Nantes
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License (GPL)
@@ -218,10 +220,6 @@ 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;
@@ -906,6 +904,43 @@ let rec set_ifdef_parenthize_info xs =
 (* CPP handling: macros, ifdefs, macros defs  *)
 (*****************************************************************************)
 
+(* ------------------------------------------------------------------------- *)
+(* special skip_start skip_end handling *)
+(* ------------------------------------------------------------------------- *)
+
+(* note: after this normally the token list should not contain any more the
+ * TCommentSkipTagStart and End tokens.
+ *)
+let rec commentize_skip_start_to_end xs =
+  match xs with
+  | [] -> ()
+  | x::xs -> 
+      (match x with
+      | {tok = TCommentSkipTagStart info} -> 
+          (try 
+            let (before, x2, after) = 
+              xs +> Common.split_when (function
+              | {tok = TCommentSkipTagEnd _ } -> true
+              | _ -> false 
+              )
+            in
+            let topass = x::x2::before in
+            topass +> List.iter (fun tok -> 
+              set_as_comment Token_c.CppPassingExplicit tok
+            );
+            commentize_skip_start_to_end after
+          with Not_found -> 
+            failwith "could not find end of skip_start special comment"
+          )
+      | {tok = TCommentSkipTagEnd info} -> 
+            failwith "found skip_end comment but no skip_start"
+      | _ -> 
+          commentize_skip_start_to_end xs
+      )
+         
+            
+
+
 (* ------------------------------------------------------------------------- *)
 (* ifdef keeping/passing *)
 (* ------------------------------------------------------------------------- *)
@@ -921,18 +956,18 @@ let rec find_ifdef_bool xs =
       (match xxs with
       | [] -> raise Impossible
       | firstclause::xxs -> 
-          info_ifdef_stmt +> List.iter (set_as_comment Ast_c.CppDirective);
+          info_ifdef_stmt +> List.iter (set_as_comment Token_c.CppDirective);
             
           if is_ifdef_positif
           then xxs +> List.iter 
-            (iter_token_ifdef (set_as_comment Ast_c.CppPassingNormal))
+            (iter_token_ifdef (set_as_comment Token_c.CppPassingNormal))
           else begin
-            firstclause +> iter_token_ifdef (set_as_comment Ast_c.CppPassingNormal);
+            firstclause +> iter_token_ifdef (set_as_comment Token_c.CppPassingNormal);
             (match List.rev xxs with
             (* keep only last *)
             | last::startxs -> 
                 startxs +> List.iter 
-                  (iter_token_ifdef (set_as_comment Ast_c.CppPassingNormal))
+                  (iter_token_ifdef (set_as_comment Token_c.CppPassingNormal))
             | [] -> (* not #else *) ()
             );
           end
@@ -977,9 +1012,9 @@ let rec find_ifdef_mid xs =
               msg_ifdef_mid_something();
 
               (* keep only first, treat the rest as comment *)
-              info_ifdef_stmt +> List.iter (set_as_comment Ast_c.CppDirective);
+              info_ifdef_stmt +> List.iter (set_as_comment Token_c.CppDirective);
               (second::rest) +> List.iter 
-                (iter_token_ifdef (set_as_comment Ast_c.CppPassingCosWouldGetError));
+                (iter_token_ifdef (set_as_comment Token_c.CppPassingCosWouldGetError));
             end
               
       );
@@ -1014,10 +1049,10 @@ let rec find_ifdef_funheaders = function
       find_ifdef_funheaders xs;
 
       msg_ifdef_funheaders ();
-      info_ifdef_stmt +> List.iter (set_as_comment Ast_c.CppDirective);
+      info_ifdef_stmt +> List.iter (set_as_comment Token_c.CppDirective);
       let all_toks = [xline2] @ line2 in
-      all_toks +> List.iter (set_as_comment Ast_c.CppPassingCosWouldGetError) ;
-      ifdefblock2 +> iter_token_ifdef (set_as_comment Ast_c.CppPassingCosWouldGetError);
+      all_toks +> List.iter (set_as_comment Token_c.CppPassingCosWouldGetError) ;
+      ifdefblock2 +> iter_token_ifdef (set_as_comment Token_c.CppPassingCosWouldGetError);
 
   (* ifdef with nested ifdef *)
   | Ifdef 
@@ -1036,10 +1071,10 @@ let rec find_ifdef_funheaders = function
       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);
+      info_ifdef_stmt  +> List.iter (set_as_comment Token_c.CppDirective);
+      info_ifdef_stmt2 +> List.iter (set_as_comment Token_c.CppDirective);
       let all_toks = [xline2;xline3] @ line2 @ line3 in
-      all_toks +> List.iter (set_as_comment Ast_c.CppPassingCosWouldGetError);
+      all_toks +> List.iter (set_as_comment Token_c.CppPassingCosWouldGetError);
 
  (* ifdef with elseif *)
   | Ifdef 
@@ -1054,9 +1089,9 @@ let rec find_ifdef_funheaders = function
       find_ifdef_funheaders xs;
 
       msg_ifdef_funheaders ();
-      info_ifdef_stmt +> List.iter (set_as_comment Ast_c.CppDirective);
+      info_ifdef_stmt +> List.iter (set_as_comment Token_c.CppDirective);
       let all_toks = [xline2;xline3] @ line2 @ line3 in
-      all_toks +> List.iter (set_as_comment Ast_c.CppPassingCosWouldGetError)
+      all_toks +> List.iter (set_as_comment Token_c.CppPassingCosWouldGetError)
         
   (* recurse *)
   | Ifdef (xxs,info_ifdef_stmt)::xs 
@@ -1124,12 +1159,12 @@ let rec apply_macro_defs xs =
 
       (match params with
       | NoParam -> 
-          pr2 ("WIERD: macro without param used before parenthize: " ^ s);
+          pr2 ("WEIRD: 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;
+              set_as_comment (Token_c.CppMacro) id;
               id.new_tokens_before <- bodymacro;
           | DefineHint hint -> 
               msg_apply_known_macro_hint s;
@@ -1145,7 +1180,7 @@ let rec apply_macro_defs xs =
                * the number of arguments. *)
               if List.length params != List.length xxs
               then begin 
-                pr2_once ("WIERD: macro with wrong number of arguments: " ^ s);
+                pr2_once ("WEIRD: macro with wrong number of arguments: " ^ s);
                 (* old: id.new_tokens_before <- bodymacro; *)
                 ()
               end
@@ -1164,8 +1199,8 @@ let rec apply_macro_defs xs =
                  * are all TCommentCpp
                  *)
                 [Parenthised (xxs, info_parens)] +> 
-                  iter_token_paren (set_as_comment Ast_c.CppMacro);
-                set_as_comment Ast_c.CppMacro id;
+                  iter_token_paren (set_as_comment Token_c.CppMacro);
+                set_as_comment Token_c.CppMacro id;
 
             | DefineHint (HintMacroStatement as hint) -> 
                 (* important to do that after have apply the macro, otherwise
@@ -1189,14 +1224,14 @@ let rec apply_macro_defs xs =
                     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);
-                    set_as_comment Ast_c.CppMacro id2;
+                      iter_token_paren (set_as_comment Token_c.CppMacro);
+                    set_as_comment Token_c.CppMacro id2;
 
                 | _ ->
                     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);
+                      iter_token_paren (set_as_comment Token_c.CppMacro);
                 )
                 
 
@@ -1215,7 +1250,7 @@ let rec apply_macro_defs xs =
 
       (match params with
       | Params params -> 
-          pr2 ("WIERD: macro with params but no parens found: " ^ s);
+          pr2 ("WEIRD: macro with params but no parens found: " ^ s);
           (* dont apply the macro, perhaps a redefinition *)
           ()
       | NoParam -> 
@@ -1225,7 +1260,7 @@ let rec apply_macro_defs xs =
               id.tok <- (newtok +> TH.visitor_info_of_tok (fun _ -> 
                 TH.info_of_tok id.tok))
           | DefineBody bodymacro -> 
-              set_as_comment Ast_c.CppMacro id;
+              set_as_comment Token_c.CppMacro id;
               id.new_tokens_before <- bodymacro;
           | DefineHint hint -> 
                 msg_apply_known_macro_hint s;
@@ -1293,8 +1328,8 @@ let rec find_macro_paren xs =
      -> 
       pr2_cpp ("MACRO: __attribute detected ");
       [Parenthised (xxs, info_parens)] +> 
-        iter_token_paren (set_as_comment Ast_c.CppAttr);
-      set_as_comment Ast_c.CppAttr id;
+        iter_token_paren (set_as_comment Token_c.CppAttr);
+      set_as_comment Token_c.CppAttr id;
       find_macro_paren xs
 
 (*
@@ -1342,7 +1377,7 @@ let rec find_macro_paren xs =
       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);
+        iter_token_paren (set_as_comment Token_c.CppMacro);
       find_macro_paren xs
 
   (* after case *)
@@ -1354,7 +1389,7 @@ let rec find_macro_paren xs =
       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);
+        iter_token_paren (set_as_comment Token_c.CppMacro);
       find_macro_paren xs
 
 
@@ -1500,7 +1535,7 @@ let rec find_macro_lineparen xs =
    * not have positive is to restrict to .*DECLARE.* macros.
    *
    * but there is a grammar rule for that, so don't need this case anymore
-   * unless the parameter of the DECLARE_xxx are wierd and can not be mapped
+   * unless the parameter of the DECLARE_xxx are weird and can not be mapped
    * on a argument_list
    *)
         
@@ -1623,7 +1658,7 @@ let rec find_macro_lineparen xs =
           msg_macro_noptvirg s;
           macro.tok <- TMacroStmt (s, TH.info_of_tok macro.tok);
           [Parenthised (xxs, info_parens)] +> 
-            iter_token_paren (set_as_comment Ast_c.CppMacro);
+            iter_token_paren (set_as_comment Token_c.CppMacro);
         end;
 
       find_macro_lineparen (line2::xs)
@@ -1777,7 +1812,7 @@ and find_actions_params xxs =
           (* certainly because paren detection had a pb because of
            * some ifdef-exp
            *)
-          pr2 "PB: wierd, I try to tag an EOF token as action"
+          pr2 "PB: weird, I try to tag an EOF token as action"
         else 
           x.tok <- TAction (TH.info_of_tok x.tok);
       );
@@ -1868,8 +1903,12 @@ let fix_tokens_cpp2 tokens =
      * 
      *)
 
+    commentize_skip_start_to_end !tokens2;
+
     (* ifdef *)
     let cleaner = !tokens2 +> List.filter (fun x -> 
+      (* is_comment will also filter the TCommentCpp created in 
+       * commentize_skip_start_to_end *)
       not (TH.is_comment x.tok) (* could filter also #define/#include *)
     ) in
     let ifdef_grouped = mk_ifdef cleaner in
@@ -1970,7 +2009,7 @@ let rec define_line_1 acc xs =
       let acc = (TDefine ii) :: acc in
       define_line_2 acc line ii xs
   | TCppEscapedNewline ii::xs ->
-      pr2 "WIERD: a \\ outside a #define";
+      pr2 "WEIRD: a \\ outside a #define";
       let acc = (TCommentSpace ii) :: acc in
       define_line_1 acc xs
   | x::xs -> define_line_1 (x::acc) xs
@@ -1979,7 +2018,7 @@ and define_line_2 acc line lastinfo xs =
   match xs with 
   | [] -> 
       (* should not happened, should meet EOF before *)
-      pr2 "PB: WIERD";   
+      pr2 "PB: WEIRD";   
       List.rev (mark_end_define lastinfo::acc)
   | x::xs -> 
       let line' = TH.line_of_tok x in
@@ -1991,7 +2030,7 @@ and define_line_2 acc line lastinfo xs =
          let acc = (EOF ii) :: acc in
           define_line_1 acc xs
       | TCppEscapedNewline ii -> 
-          if (line' <> line) then pr2 "PB: WIERD: not same line number";
+          if (line' <> line) then pr2 "PB: WEIRD: not same line number";
          let acc = (TCommentSpace ii) :: acc in
           define_line_2 acc (line+1) info xs
       | x -> 
@@ -2025,7 +2064,7 @@ let rec define_ident acc xs =
          let acc = (TIdentDefine (s,i2)) :: acc in
           define_ident acc xs
       | _ -> 
-          pr2 "WIERD: wierd #define body"; 
+          pr2 "WEIRD: weird #define body"; 
           define_ident acc xs
       )
   | x::xs ->
@@ -2524,30 +2563,29 @@ let lookahead2 ~pass next before =
       then TCommentCpp (Ast_c.CppDirective, ii)
       else 
       *)
-         (* 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
-
+      (* 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_cpp "In Initializer passing"; (* cheat: dont count in stat *)
+          incr Stat.nIfdefInitializer;
+        end else begin 
+          pr2_cpp("IFDEF: or related insde function. I treat it as comment");
+          incr Stat.nIfdefPassing;
+        end;
+        TCommentCpp (Token_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)
+          pr2_cpp("UNDEF: I treat it as comment");
+          TCommentCpp (Token_c.CppDirective, ii)
         end
         else x
 
@@ -2555,8 +2593,8 @@ let lookahead2 ~pass next before =
       -> 
         if (pass = 2)
         then begin
-          pr2_once ("CPP-OTHER: I treat it as comment");
-          TCommentCpp (Ast_c.CppDirective, ii)
+          pr2_cpp ("OTHER directive: I treat it as comment");
+          TCommentCpp (Token_c.CppDirective, ii)
         end
         else x
 
index e365cff..c6270bc 100644 (file)
@@ -1,3 +1,17 @@
+(* Yoann Padioleau
+ * 
+ * Copyright (C) 2008, 2009 University of Urbana Champaign
+ *
+ * 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 
 
 (* if do .mli:
index f6cd8d6..83eaef3 100644 (file)
@@ -1,4 +1,6 @@
-(* Copyright (C) 2006, 2007, 2008, 2009 Ecole des Mines de Nantes and DIKU
+(* Yoann Padioleau, Julia Lawall
+ * 
+ * Copyright (C) 2006, 2007, 2008, 2009 Ecole des Mines de Nantes and DIKU
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License (GPL)
@@ -76,7 +78,7 @@ let pretty_print_c pr_elem pr_space pr_nl pr_indent pr_outdent pr_unindent =
     (match exp, ii with
     | Ident (c),         [i]     -> pr_elem i
     (* only a MultiString can have multiple ii *)
-    | Constant (MultiString), is     -> is +> List.iter pr_elem
+    | Constant (MultiString _), is     -> is +> List.iter pr_elem
     | Constant (c),         [i]     -> pr_elem i 
     | FunCall  (e, es),     [i1;i2] -> 
         pp_expression e; pr_elem i1; 
@@ -166,8 +168,8 @@ let pretty_print_c pr_elem pr_space pr_nl pr_indent pr_outdent pr_unindent =
     let rec pp_action (ActMisc ii) = ii +> List.iter pr_elem in
     match argument with
     | Left e -> pp_expression e
-    | Right wierd -> 
-       (match wierd with
+    | Right weird -> 
+       (match weird with
        | ArgType param -> pp_param param
        | ArgAction action -> pp_action action)
          
@@ -859,7 +861,6 @@ and pp_init (init, iinit) =
     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;
@@ -867,7 +868,6 @@ and pp_init (init, iinit) =
               f_attr = attrs;
            } = defbis
        in
-       
         pr_elem ifakestart;
         
         pp_type_with_ident None (Some (sto, isto)) 
@@ -876,7 +876,6 @@ and pp_init (init, iinit) =
         pp_attributes pr_elem pr_space attrs;
         pr_elem is;
        
-       
         pr_elem iifunc1;
        
         (* not anymore, cf tests/optional_name_parameter and 
@@ -1213,6 +1212,17 @@ and pp_init (init, iinit) =
 (* Here we do not use (mcode, env). It is a simple C pretty printer. *)
 let pr_elem info =
   let s = Ast_c.str_of_info info in
+  if !Flag_parsing_c.pretty_print_comment_info then begin
+    let before = !(info.comments_tag).mbefore in
+    if not (null before) then begin
+      pp "-->";
+      before +> List.iter (fun (comment_like, pinfo) -> 
+        let s = pinfo.Common.str in
+        pp s
+      );
+      pp "<--";
+    end;
+  end;
   pp s
     
 let pr_space _ = Format.print_space()
index c788da0..10ea3ab 100644 (file)
@@ -223,6 +223,36 @@ let test_type_c infile =
   ();;
 
 
+(* ---------------------------------------------------------------------- *)
+(* ex: demos/platform_ifdef.c *)
+let test_comment_annotater infile = 
+  let (program2, _stat) =  Parse_c.parse_print_error_heuristic infile in
+  let asts = program2 +> List.map (fun (ast,_) -> ast) in
+  let toks = program2 +> List.map (fun (ast, (s, toks)) -> toks) +> 
+    List.flatten in
+
+  Flag_parsing_c.pretty_print_comment_info := true;
+
+  pr2 "pretty print, before comment annotation: --->";
+  Common.adjust_pp_with_indent (fun () -> 
+  asts +> List.iter (fun ast -> 
+    Pretty_print_c.pp_toplevel_simple ast;
+  );
+  );
+
+  let _ = Comment_annotater_c.annotate_program toks asts in
+
+  Common.adjust_pp_with_indent (fun () -> 
+  pr2 "pretty print, after comment annotation: --->";
+  asts +> List.iter (fun ast -> 
+    Pretty_print_c.pp_toplevel_simple ast;
+  );
+  );
+
+
+  ()
+  
+  
 (* ---------------------------------------------------------------------- *)
 (* used by generic_makefile now *)
 let test_compare_c file1 file2 = 
@@ -336,6 +366,8 @@ let actions () = [
   Common.mk_action_1_arg test_type_c;
   "-compare_c", "   <file1> <file2>", 
   Common.mk_action_2_arg test_compare_c (* result is in unix code *);
+  "-comment_annotater_c", "   <file>", 
+  Common.mk_action_1_arg test_comment_annotater;
 
   "-compare_c_hardcoded", "  ", 
   Common.mk_action_0_arg test_compare_c_hardcoded;
index 80f45f7..9ea5b37 100644 (file)
@@ -12,6 +12,8 @@ val test_parse_unparse : filename -> unit
 val test_cfg : filename (* foo.c or foo.c:main *) -> unit
 val test_type_c : filename -> unit
 
+val test_comment_annotater : filename -> unit
+
 val test_compare_c : filename -> filename -> unit (* result is in unix code *)
 val test_compare_c_hardcoded : unit -> unit
 
diff --git a/parsing_c/token_c.ml b/parsing_c/token_c.ml
new file mode 100644 (file)
index 0000000..d896141
--- /dev/null
@@ -0,0 +1,258 @@
+(* Yoann Padioleau
+ *
+ * Copyright (C) 2009 University of Urbana Champaign
+ *
+ * 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
+
+(*****************************************************************************)
+(* Prelude *)
+(*****************************************************************************)
+
+(* This file may seems redundant with the tokens generated by Yacc
+ * from parser.mly in parser_c.mli. The problem is that we need for
+ * many reasons to remember in the ast_c the tokens invoved in this
+ * ast, not just the string, especially for the comment and cpp_passed
+ * tokens which pour le coup were not in the ast at all. So,
+ * to avoid recursive mutual dependencies, we provide this file
+ * so that ast_c does not need to depend on yacc which depends on
+ * ast_c, etc. 
+ * 
+ * Also, OcamlYacc imposes some stupid constraints on the way we can define
+ * the token type. OcamlYacc force us to do a token type that
+ * cant be a pair of a sum type, it must be directly a sum type.
+ * We don't have this constraint here.
+ * 
+ * Also, some yacc tokens are not used in the grammar because they are filtered
+ * in some intermediate phases. But they still must be declared because
+ * ocamllex may generate them, or some intermediate phase may also
+ * generate them (like some functions in parsing_hacks.ml).
+ * Here we don't have this problem again so we can have a clearer token type.
+ * 
+ * 
+ *)
+
+(*****************************************************************************)
+(* Cpp constructs put it comments in lexer or parsing_hack *)
+(*****************************************************************************)
+
+(* history: was in ast_c.ml before:
+ *  This type is not in the Ast but is associated with the TCommentCpp 
+ *  token. I put this enum here because parser_c.mly need it. I could have put
+ *  it also in lexer_parser.
+ * 
+ * update: now in token_c.ml, and actually right now we want those tokens
+ * to be in the ast so that in the matching/transforming of C code, we 
+ * can detect if some metavariables match code which have some 
+ * cpp_passed tokens next to them (and so where we should issue a warning).
+ *)
+type cppcommentkind = 
+  | CppDirective 
+  | CppAttr 
+  | CppMacro 
+  | CppPassingNormal (* ifdef 0, cplusplus, etc *) 
+  | CppPassingCosWouldGetError (* expr passsing *)
+  | CppPassingExplicit (* skip_start/end tag *)
+
+(*****************************************************************************)
+(* Types *)
+(*****************************************************************************)
+
+(*
+ * TODO? Do we want to handle also non OriginTok-like tokens here ? 
+ * Right now we use this file to be able to later store in the 
+ * ast some information about comments and passed cpp tokens, to
+ * improve our matching/transforming and unparsing in coccinelle.
+ * So we should be concerned really only with origin tok, so right
+ * now I use a simple Common.parse_info, not the more complex
+ * Ast_c.parse_info, or even more complex Ast_c.info.
+ * Also right now I defined only the token_tags of comment-like
+ * tokens.
+ *) 
+
+type info = Common.parse_info 
+
+(* I try to be consistent with the names in parser_c.mli *)
+type token = token_tag * info
+ and token_tag = 
+  | TCommentSpace
+  | TCommentNewline
+
+  | TComment
+
+  (* the passed tokens because of our limited handling of cpp *)
+  | TCommentCpp of cppcommentkind
+
+  (*| TUnknown ? *)
+
+
+
+(* Later if decide to include more kinds of tokens, then may 
+ * have to move the current token_tag like TCommentXxx in their
+ * own type and have a generic TCommentLike of comment_like_token
+ * in token_tag. Could also do like in token_helpers have some
+ * is_xxx predicate, but it's not very pretty (but required when
+ * some tokens can belong to multiple categories).
+ * 
+ * It's supposed to be all the tokens that are not otherwise represented
+ * in the ast via regular constructors and info.
+ *)
+type comment_like_token = token
+
+
+
+(*****************************************************************************)
+(* Getters *)
+(*****************************************************************************)
+
+(* simpler than in token_helpers :) because we don't have the ocamlyacc
+ * constraints on how to define the token type. *)
+let info_of_token = snd 
+
+
+
+(*****************************************************************************)
+(*****************************************************************************)
+(* remaining tokens 
+
+could define a type  token_class = Comment | Ident | Operator | ... 
+
+  | TInt of (string * Ast_c.info)
+  | TFloat of ((string * Ast_c.floatType) * Ast_c.info)
+  | TChar of ((string * Ast_c.isWchar) * Ast_c.info)
+  | TString of ((string * Ast_c.isWchar) * Ast_c.info)
+
+  | TIdent of (string * Ast_c.info)
+  | TypedefIdent of (string * Ast_c.info)
+
+  | TOPar of (Ast_c.info)
+  | TCPar of (Ast_c.info)
+  | TOBrace of (Ast_c.info)
+  | TCBrace of (Ast_c.info)
+  | TOCro of (Ast_c.info)
+  | TCCro of (Ast_c.info)
+  | TDot of (Ast_c.info)
+  | TComma of (Ast_c.info)
+  | TPtrOp of (Ast_c.info)
+  | TInc of (Ast_c.info)
+  | TDec of (Ast_c.info)
+  | TAssign of (Ast_c.assignOp * Ast_c.info)
+  | TEq of (Ast_c.info)
+  | TWhy of (Ast_c.info)
+  | TTilde of (Ast_c.info)
+  | TBang of (Ast_c.info)
+  | TEllipsis of (Ast_c.info)
+  | TDotDot of (Ast_c.info)
+  | TPtVirg of (Ast_c.info)
+  | TOrLog of (Ast_c.info)
+  | TAndLog of (Ast_c.info)
+  | TOr of (Ast_c.info)
+  | TXor of (Ast_c.info)
+  | TAnd of (Ast_c.info)
+  | TEqEq of (Ast_c.info)
+  | TNotEq of (Ast_c.info)
+  | TInf of (Ast_c.info)
+  | TSup of (Ast_c.info)
+  | TInfEq of (Ast_c.info)
+  | TSupEq of (Ast_c.info)
+  | TShl of (Ast_c.info)
+  | TShr of (Ast_c.info)
+  | TPlus of (Ast_c.info)
+  | TMinus of (Ast_c.info)
+  | TMul of (Ast_c.info)
+  | TDiv of (Ast_c.info)
+  | TMod of (Ast_c.info)
+  | Tchar of (Ast_c.info)
+  | Tshort of (Ast_c.info)
+  | Tint of (Ast_c.info)
+  | Tdouble of (Ast_c.info)
+  | Tfloat of (Ast_c.info)
+  | Tlong of (Ast_c.info)
+  | Tunsigned of (Ast_c.info)
+  | Tsigned of (Ast_c.info)
+  | Tvoid of (Ast_c.info)
+  | Tauto of (Ast_c.info)
+  | Tregister of (Ast_c.info)
+  | Textern of (Ast_c.info)
+  | Tstatic of (Ast_c.info)
+  | Ttypedef of (Ast_c.info)
+  | Tconst of (Ast_c.info)
+  | Tvolatile of (Ast_c.info)
+  | Tstruct of (Ast_c.info)
+  | Tunion of (Ast_c.info)
+  | Tenum of (Ast_c.info)
+  | Tbreak of (Ast_c.info)
+  | Telse of (Ast_c.info)
+  | Tswitch of (Ast_c.info)
+  | Tcase of (Ast_c.info)
+  | Tcontinue of (Ast_c.info)
+  | Tfor of (Ast_c.info)
+  | Tdo of (Ast_c.info)
+  | Tif of (Ast_c.info)
+  | Twhile of (Ast_c.info)
+  | Treturn of (Ast_c.info)
+  | Tgoto of (Ast_c.info)
+  | Tdefault of (Ast_c.info)
+  | Tsizeof of (Ast_c.info)
+  | Trestrict of (Ast_c.info)
+  | Tasm of (Ast_c.info)
+  | Tattribute of (Ast_c.info)
+  | Tinline of (Ast_c.info)
+  | Ttypeof of (Ast_c.info)
+
+  | TDefine of (Ast_c.info)
+  | TDefParamVariadic of ((string * Ast_c.info))
+
+  | TCppEscapedNewline of (Ast_c.info)
+
+  | TOParDefine of (Ast_c.info)
+  | TOBraceDefineInit of (Ast_c.info)
+  | TIdentDefine of ((string * Ast_c.info))
+  | TDefEOL of (Ast_c.info)
+  | TInclude of ((string * string * bool ref * Ast_c.info))
+  | TIncludeStart of ((Ast_c.info * bool ref))
+  | TIncludeFilename of ((string * Ast_c.info))
+  | TIfdef of (((int * int) option ref * Ast_c.info))
+  | TIfdefelse of (((int * int) option ref * Ast_c.info))
+  | TIfdefelif of (((int * int) option ref * Ast_c.info))
+  | TEndif of (((int * int) option ref * Ast_c.info))
+  | TIfdefBool of ((bool * (int * int) option ref * Ast_c.info))
+  | TIfdefMisc of ((bool * (int * int) option ref * Ast_c.info))
+  | TIfdefVersion of ((bool * (int * int) option ref * Ast_c.info))
+  | TUndef of (string * Ast_c.info)
+  | TCppDirectiveOther of (Ast_c.info)
+
+  | TMacroAttr of ((string * Ast_c.info))
+  | TMacroStmt of ((string * Ast_c.info))
+  | TMacroString of ((string * Ast_c.info))
+  | TMacroDecl of ((string * Ast_c.info))
+  | TMacroDeclConst of (Ast_c.info)
+  | TMacroStructDecl of ((string * Ast_c.info))
+  | TMacroIterator of ((string * Ast_c.info))
+  | TMacroAttrStorage of ((string * Ast_c.info))
+
+  | TCommentSkipTagStart of (Ast_c.info)
+  | TCommentSkipTagEnd of (Ast_c.info)
+
+  | TCParEOL of (Ast_c.info)
+  | TAction of (Ast_c.info)
+
+  | TCommentMisc xxx
+
+  | EOF of (Ast_c.info)
+*)
+
+
+(*****************************************************************************)
+(* Helpers *)
+(*****************************************************************************)
index 5d70ad8..65cc96a 100644 (file)
@@ -1,3 +1,18 @@
+(* Yoann Padioleau
+ * 
+ * Copyright (C) 2007, 2008 Ecole des Mines de Nantes
+ *
+ * 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
 
 open Parser_c
@@ -6,10 +21,10 @@ open Parser_c
 (* Is_xxx, categories *)
 (*****************************************************************************)
 
-(* todo? could define a type 
- *   token_class = Comment | Ident | Operator | ... 
- * but sometimes tokens belon to multiple classes. Could maybe return then 
- * a set of classes
+(* could define a type  token_class = Comment | Ident | Operator | ... 
+ * update: now token_c can maybe do that.
+ * but still, sometimes tokens belon to multiple classes. Could maybe 
+ * return then a set of classes.
  *)
 
 let is_space = function
@@ -19,17 +34,20 @@ let is_space = function
 
 let is_whitespace = is_space
 
-let is_comment_or_space = function
+let is_just_comment_or_space = function
   | TComment _ -> true
   | TCommentSpace _ -> true
   | TCommentNewline _ -> true
   | _ -> false
-let is_real_comment = is_comment_or_space
+let is_real_comment = is_just_comment_or_space
 
 let is_just_comment = function
   | TComment _ -> true
   | _ -> false
 
+
+
+
 let is_comment = function
   | TComment _    
   | TCommentSpace _ | TCommentNewline _ 
@@ -37,7 +55,12 @@ let is_comment = function
   | TCommentMisc _ -> true
   | _ -> false
 
-
+(* coupling with comment_annotater_c.ml.
+ * In fact more tokens than comments are not in the ast, but
+ * they were usually temporally created by ocamllex and removed 
+ * in parsing_hacks.
+*)
+let is_not_in_ast = is_comment
 
 let is_fake_comment = function
   | TCommentCpp _    | TCommentMisc _ 
@@ -48,8 +71,7 @@ let is_not_comment x =
   not (is_comment x)
 
 
-
-
+(* ---------------------------------------------------------------------- *)
 
 let is_cpp_instruction = function
   | TInclude _ 
@@ -73,6 +95,7 @@ let is_gcc_token = function
 
 
 
+(* ---------------------------------------------------------------------- *)
 let is_opar = function
   | TOPar _ | TOParDefine _ -> true
   | _ -> false
@@ -93,6 +116,7 @@ let is_cbrace = function
 
 
 
+(* ---------------------------------------------------------------------- *)
 let is_eof = function
   | EOF x -> true
   | _ -> false
@@ -155,6 +179,7 @@ let is_stuff_taking_parenthized = function
   | _ -> false
 
 
+(* used in the algorithms for "10 most problematic errors" *)
 let is_ident_like = function
   | TIdent _
   | TypedefIdent _
@@ -233,6 +258,9 @@ let info_of_tok = function
   | TCommentCpp          (cppkind, i) -> i
   | TCommentMisc         (i) -> i
 
+  | TCommentSkipTagStart (i) -> i
+  | TCommentSkipTagEnd (i) -> i
+
   | TIfdef               (_, i) -> i
   | TIfdefelse           (_, i) -> i
   | TIfdefelif           (_, i) -> i
@@ -377,6 +405,9 @@ let visitor_info_of_tok f = function
   | TCommentCpp          (cppkind, i) -> TCommentCpp (cppkind, f i) 
   | TCommentMisc         (i) -> TCommentMisc         (f i) 
 
+  | TCommentSkipTagStart         (i) -> TCommentSkipTagStart         (f i) 
+  | TCommentSkipTagEnd         (i) -> TCommentSkipTagEnd         (f i) 
+
   | TIfdef               (t, i) -> TIfdef               (t, f i) 
   | TIfdefelse           (t, i) -> TIfdefelse           (t, f i) 
   | TIfdefelif           (t, i) -> TIfdefelif           (t, f i) 
@@ -490,5 +521,8 @@ let is_abstract x =
 (*****************************************************************************)
 (* Helpers *)
 (*****************************************************************************)
-let is_same_line line tok = 
-  line_of_tok tok = line
+let is_same_line_or_close line tok = 
+  line_of_tok tok = line || 
+  line_of_tok tok = line - 1 ||
+  line_of_tok tok = line - 2
+
index b836ee3..bcb1fcd 100644 (file)
@@ -1,11 +1,15 @@
 
 val is_space               : Parser_c.token -> bool
-val is_comment_or_space    : Parser_c.token -> bool
 val is_just_comment        : Parser_c.token -> bool
+val is_just_comment_or_space    : Parser_c.token -> bool
+
 val is_comment             : Parser_c.token -> bool
+val is_not_comment         : Parser_c.token -> bool
+
 val is_real_comment        : Parser_c.token -> bool
 val is_fake_comment        : Parser_c.token -> bool
-val is_not_comment         : Parser_c.token -> bool
+val is_not_in_ast          : Parser_c.token -> bool
+
 
 val is_cpp_instruction     : Parser_c.token -> bool
 val is_gcc_token           : Parser_c.token -> bool
@@ -42,4 +46,4 @@ val is_expanded : Parser_c.token -> bool
 val is_fake : Parser_c.token -> bool
 val is_abstract : Parser_c.token -> bool
 
-val is_same_line: int -> Parser_c.token -> bool
+val is_same_line_or_close: int -> Parser_c.token -> bool
index 3295644..e08b2c7 100644 (file)
@@ -1,5 +1,7 @@
-(* Copyright (C) 2007, 2008 Ecole des Mines de Nantes, University of 
- * Urbana Champaign
+(* Yoann Padioleau
+ * 
+ * Copyright (C) 2007, 2008 Ecole des Mines de Nantes, 
+ * Copyright (C) 2009 University of Urbana Champaign
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License (GPL)
@@ -28,7 +30,7 @@ module Lib = Lib_parsing_c
  *    in coccinelle. Partial type annotater.
  *  - Julia extended it in 2008? to have localvar/notlocalvar and 
  *    test/notest information, again used by coccinelle.
- *  - I extended it Fall 2008 to have more type information for the 
+ *  - I extended it in Fall 2008 to have more type information for the 
  *    global analysis. I also added some optimisations to process
  *    included code faster.
  * 
@@ -71,6 +73,10 @@ module Lib = Lib_parsing_c
  * store all posible variations in ast_c ? a list of type instead of just
  * the type ?
  * 
+ * todo: how to handle multiple possible definitions for entities like
+ * struct or typedefs ? Because of ifdef, we should store list of 
+ * possibilities sometimes.
+ * 
  * todo: define a new type ? like type_cocci ? where have a bool ?
  * 
  * semi: How handle scope ? When search for type of field, we return 
@@ -92,6 +98,10 @@ let pr2 s =
   if !Flag_parsing_c.verbose_type
   then Common.pr2 s
 
+let pr2_once s = 
+  if !Flag_parsing_c.verbose_type
+  then Common.pr2_once s
+
 (*****************************************************************************)
 (* Environment *)
 (*****************************************************************************)
@@ -377,7 +387,10 @@ let rec type_unfold_one_step ty env =
 
 
 (* normalizer. can be seen as the opposite of the previous function as 
- * we "fold" at least for the structUnion.
+ * we "fold" at least for the structUnion. Should return something that
+ * Type_c.is_completed_fullType likes, something that makes it easier
+ * for the programmer to work on, that has all the needed information
+ * for most tasks.
  *)
 let rec typedef_fix ty env = 
   match Ast_c.unwrap_typeC ty with 
@@ -403,19 +416,25 @@ let rec typedef_fix ty env =
   | StructUnionName (su, s) -> ty
 
   (* keep the typename but complete with more information *)
-  | TypeName (s, _typ) -> 
-      (try 
+  | TypeName (s, typ) -> 
+      (match typ with
+      | Some _ -> 
+          pr2 ("typedef value already there:" ^ s);
+          ty
+      | None -> 
+        (try
           if !typedef_debug then pr2 "typedef_fix: lookup_typedef";
           let (t', env') = lookup_typedef s env in
 
           (* bugfix: termination bug if use env instead of env' below, because
-           * can have some wierd mutually recursive typedef which
+           * can have some weird mutually recursive typedef which
            * each new type alias search for its mutual def.
            *)
           TypeName (s, Some (typedef_fix t' env')) +> Ast_c.rewrap_typeC ty
         with Not_found -> 
           ty
-      )
+      ))
+
   (* remove paren for better matching with typed metavar. kind of iso again *)
   | ParenType t -> 
       typedef_fix t env
@@ -553,7 +572,7 @@ let add_binding2 namedef warning =
     if  memberf [current_scope] && warning
     then pr2 ("Type_annoter: warning, " ^ s ^ 
                  " is already in current binding" ^ "\n" ^
-                 " so there is a wierd shadowing");
+                 " so there is a weird shadowing");
   end;
   add_in_scope namedef
 
@@ -601,7 +620,7 @@ let annotater_expr_visitor_subpart = (fun (k,bigf) expr ->
     (* -------------------------------------------------- *)
     (* todo: should analyse the 's' for int to know if unsigned or not *)
     | Constant (String (s,kind)) -> make_info_def (type_of_s "char *")
-    | Constant MultiString       -> make_info_def (type_of_s "char *")
+    | Constant MultiString _  -> make_info_def (type_of_s "char *")
     | Constant (Char   (s,kind)) -> make_info_def (type_of_s "char")
     | Constant (Int (s))         -> make_info_def (type_of_s "int")
     | Constant (Float (s,kind)) -> 
@@ -683,7 +702,7 @@ let annotater_expr_visitor_subpart = (fun (k,bigf) expr ->
                     Type_c.noTypeHere
                 )
             | None -> 
-                pr2 ("type_annotater: no type for function ident: " ^ s);
+                pr2_once ("type_annotater: no type for function ident: " ^ s);
                 Type_c.noTypeHere
             )
         )
@@ -813,7 +832,7 @@ let annotater_expr_visitor_subpart = (fun (k,bigf) expr ->
                                 "TYPE-ERROR: field '%s' does not belong in struct %s"
                                 fld (match sopt with Some s -> s |_ -> "<anon>"));
                         Type_c.noTypeHere
-                    | MultiFound -> 
+                    | Multi_found -> 
                         pr2 "TAC:MultiFound";
                         Type_c.noTypeHere
                   )
index 02f401e..fe61cd8 100644 (file)
@@ -28,7 +28,7 @@ val annotate_test_expressions :
 
 
 
-(* Annotate via side effects. Fill in the type  
+(* !!Annotate via side effects!!. Fill in the type  
  * information that was put to None during parsing.
  *)
 val annotate_program : 
index cc53391..7fc2edc 100644 (file)
@@ -1,4 +1,6 @@
-(* Copyright (C) 2007, 2008 Yoann Padioleau
+(* Yoann Padioleau 
+ *
+ * Copyright (C) 2007, 2008, 2009 University of Urbana Champaign
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License (GPL)
@@ -18,7 +20,30 @@ open Ast_c
 (* Types *)
 (*****************************************************************************)
 
-(* todo? define a new clean fulltype ? as julia did with type_cocci.ml
+(* What info do we want in a clean C type ? Normally it would help
+ * if we remove some of the complexity of C with for instance typedefs
+ * by expanding those typedefs or structname and enumname to their
+ * final value. Then, when we do pattern matching we can conveniently forget
+ * to handle the typedef, enumname and similar cases. But sometimes,
+ * in coccinelle for instance, we want to keep some of those original
+ * info. So right now we have a in-the-middle solution by keeping
+ * the original typename in the ast and expanding some of them
+ * in the type_annotation phase. We don't do this expansion for
+ * structname because usually when we have a struct we actually
+ * prefer to just have the structname. It's only when we access
+ * field that we need that information, but the type_annotater has
+ * already done this job so no need in the parent expression to know
+ * the full definition of the structure. But for typedef, this is different.
+ * 
+ * So really the finalType we want, the completed_type notion below,
+ * corresponds to a type we think is useful enough to work on, to do
+ * pattern matching on, and one where we have all the needed information
+ * and we don't need to look again somewhere else to get the information.
+ *
+ * 
+ * 
+ * 
+ * todo? define a new clean fulltype ? as julia did with type_cocci.ml
  * without the parsing info, with some normalization (for instance have
  * only structUnionName and enumName, and remove the ParenType), some
  * abstractions (don't care for instance about name in parameters of
@@ -33,6 +58,68 @@ open Ast_c
 
 type finalType = Ast_c.fullType
 
+type completed_and_simplified = Ast_c.fullType
+
+type completed_typedef = Ast_c.fullType
+type removed_typedef = Ast_c.fullType
+
+
+(* normally if the type annotated has done a good job, this should always
+ * return true. Cf type_annotater_c.typedef_fix.
+ *)
+let rec is_completed_and_simplified ty = 
+  match Ast_c.unwrap_typeC ty with 
+  | BaseType x  -> true
+  | Pointer t -> is_completed_and_simplified t
+  | Array (e, t) -> is_completed_and_simplified t
+  | StructUnion (su, sopt, fields) -> 
+      (* recurse fields ? Normally actually don't want, 
+       * prefer to have a StructUnionName when it's possible *)
+      (match sopt with
+      | None -> true
+      | Some _ -> false (* should have transformed it in a StructUnionName *)
+      )
+  | FunctionType ft -> 
+      (* todo? return type is completed ? params completed ? *)
+      true
+  | Enum  (s, enumt) -> 
+      true
+  | EnumName s -> 
+      true
+
+  (* we prefer StructUnionName to StructUnion when it comes to typed metavar *)
+  | StructUnionName (su, s) -> true
+
+  (* should have completed with more information *)
+  | TypeName (s, typ) -> 
+      (match typ with
+      | None -> false
+      | Some t -> 
+          (* recurse cos what if it's an alias of an alias ? *)
+          is_completed_and_simplified t
+      )
+
+  (* should have removed paren, for better matching with typed metavar.
+   * kind of iso again *)
+  | ParenType t -> 
+      false
+  (* same *)
+  | TypeOfType t -> 
+      false
+
+  | TypeOfExpr e -> 
+      true (* well we don't handle it, so can't really say it's completed *)
+
+
+let is_completed_typedef_fullType x = raise Todo  
+
+let is_removed_typedef_fullType x = raise Todo
+  
+(*****************************************************************************)
+(* more "virtual" fulltype, the fullType_with_no_typename *)
+(*****************************************************************************)
+let remove_typedef x = raise Todo
+
 (*****************************************************************************)
 (* expression exp_info annotation vs finalType *)
 (*****************************************************************************)
@@ -307,3 +394,47 @@ let (type_field:
     
 
 
+(*****************************************************************************)
+(* helpers *)
+(*****************************************************************************)
+
+
+(* was in aliasing_function_c.ml before*)
+
+(* assume normalized/completed ? so no ParenType handling to do ? 
+*)
+let rec is_function_type x = 
+  match Ast_c.unwrap_typeC x with
+  | FunctionType _ -> true
+  | _ -> false
+
+
+(* assume normalized/completed ? so no ParenType handling to do ? *)
+let rec function_pointer_type_opt x = 
+  match Ast_c.unwrap_typeC x with
+  | Pointer y -> 
+      (match Ast_c.unwrap_typeC y with
+      | FunctionType ft -> Some ft
+
+      (* fix *)
+      | TypeName (_s, Some ft2) -> 
+          (match Ast_c.unwrap_typeC ft2 with
+          | FunctionType ft -> Some ft
+          | _ -> None
+          )
+
+      | _ -> None
+      )
+  (* bugfix: for many fields in structure, the field is a typename 
+   * like irq_handler_t to a function pointer 
+   *)
+  | TypeName (s, Some ft) -> 
+      function_pointer_type_opt ft
+  (* bugfix: in field, usually it has some ParenType *)
+
+  | ParenType ft -> 
+      function_pointer_type_opt ft
+
+  | _ -> None
+
+
index af3b6f0..dfa6345 100644 (file)
@@ -1,6 +1,20 @@
 
 type finalType = Ast_c.fullType
 
+(* completed TypeName, removed ParenType, use StructUnionName when can *)
+type completed_and_simplified = Ast_c.fullType
+
+type completed_typedef = Ast_c.fullType
+type removed_typedef = Ast_c.fullType
+
+val is_completed_and_simplified: finalType -> bool
+val is_completed_typedef_fullType : finalType -> bool
+val is_removed_typedef_fullType: finalType -> bool
+
+val remove_typedef: completed_typedef -> removed_typedef
+
+
+
 (* lookup *)
 val type_field: 
   string -> (Ast_c.structUnion * Ast_c.structType) -> Ast_c.fullType
@@ -34,3 +48,7 @@ val do_with_type:
   (finalType -> Ast_c.exp_info) -> Ast_c.exp_info -> Ast_c.exp_info
 val get_opt_type: 
   Ast_c.expression -> finalType option
+
+(* helpers bis *)
+val is_function_type: finalType -> bool
+val function_pointer_type_opt: finalType -> Ast_c.functionType option
index 045c098..2a4faf6 100644 (file)
@@ -1,4 +1,6 @@
-(* Copyright (C) 2006, 2007, 2008, 2009 Ecole des Mines de Nantes and DIKU
+(* Yoann Padioleau, Julia Lawall
+ * 
+ * Copyright (C) 2006, 2007, 2008, 2009 Ecole des Mines de Nantes and DIKU
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License (GPL)
@@ -195,7 +197,7 @@ let get_fakeInfo_and_tokens celem toks =
         (*old: assert(before +> List.for_all (TH.is_comment)); *)
         before +> List.iter (fun x -> 
           if not (TH.is_comment x)
-          then pr2 ("WIERD: not a comment:" ^ TH.str_of_tok x)
+          then pr2 ("WEIRD: not a comment:" ^ TH.str_of_tok x)
           (* case such as  int asm d3("x"); not yet in ast *)
         );
         before +> List.iter (fun x -> Common.push2 (T1 x) toks_out);
@@ -213,7 +215,7 @@ let get_fakeInfo_and_tokens celem toks =
   Pretty_print_c.pp_program_gen pr_elem pr_space celem;
 
   if not (null !toks_in)
-  then failwith "WIERD: unparsing not finished";
+  then failwith "WEIRD: unparsing not finished";
 
   List.rev !toks_out
 
@@ -277,9 +279,15 @@ let expand_mcode toks =
           
   
     | T1 tok -> 
+       let (a,b) = !((TH.info_of_tok tok).cocci_tag) in
         (* no tag on expandedTok ! *)
-        assert(not (TH.is_expanded tok && 
-            !((TH.info_of_tok tok).cocci_tag) <> Ast_c.emptyAnnot));
+        (if (TH.is_expanded tok && 
+            !((TH.info_of_tok tok).cocci_tag) <> Ast_c.emptyAnnot)
+       then
+         failwith
+           (Printf.sprintf
+              "expanded token %s on line %d is either modified or stored in a metavariable"
+              (TH.str_of_tok tok) (TH.line_of_tok tok)));
 
         let tok' = tok +> TH.visitor_info_of_tok (fun i -> 
           { i with cocci_tag = ref Ast_c.emptyAnnot; }
@@ -365,13 +373,13 @@ let is_minusable_comment = function
       (* patch: coccinelle *)      
       | Parser_c.TCommentNewline _ (* newline plus whitespace *)
       | Parser_c.TComment _ 
-      | Parser_c.TCommentCpp (Ast_c.CppAttr, _) 
-      | Parser_c.TCommentCpp (Ast_c.CppMacro, _) 
+      | Parser_c.TCommentCpp (Token_c.CppAttr, _) 
+      | Parser_c.TCommentCpp (Token_c.CppMacro, _) 
         -> true
 
       | Parser_c.TCommentMisc _ 
-      | Parser_c.TCommentCpp (Ast_c.CppDirective, _)
-      | Parser_c.TCommentCpp (Ast_c.CppPassingCosWouldGetError, _)
+      | Parser_c.TCommentCpp (Token_c.CppDirective, _)
+      | Parser_c.TCommentCpp (Token_c.CppPassingCosWouldGetError, _)
         -> false
 
       | _ -> false
@@ -396,8 +404,8 @@ let set_minus_comment = function
       | Parser_c.TCommentNewline _ -> ()
 
       | Parser_c.TComment _ 
-      | Parser_c.TCommentCpp (Ast_c.CppAttr, _) 
-      | Parser_c.TCommentCpp (Ast_c.CppMacro, _) 
+      | Parser_c.TCommentCpp (Token_c.CppAttr, _) 
+      | Parser_c.TCommentCpp (Token_c.CppMacro, _) 
         -> 
           pr2 ("ERASING_COMMENTS: " ^ str)
       | _ -> raise Impossible
@@ -583,7 +591,7 @@ let rec adjust_indentation xs =
     let current_tab = List.rev(list_of_string current_tab) in
     let rec loop = function
        ([],new_tab) -> string_of_list (List.rev new_tab)
-      |        (_,[]) -> "" (*wierd; tabbing unit used up more than the current tab*)
+      |        (_,[]) -> "" (*weird; tabbing unit used up more than the current tab*)
       |        (t::ts,n::ns) when t = n -> loop (ts,ns)
       |        (_,ns) -> (* mismatch; remove what we can *)
          string_of_list (List.rev ns) in
@@ -643,7 +651,7 @@ let rec adjust_indentation xs =
     | ((T2 (tok,_,_)) as x)::xs when str_of_token2 x = "{" ->  x::aux true xs
     | (Cocci2 "{")::xs -> (Cocci2 "{")::aux true xs
     | ((Cocci2 "\n") as x)::xs -> 
-            (* dont inline in expr because of wierd eval order of ocaml *)
+            (* dont inline in expr because of weird eval order of ocaml *)
         let s = !_current_tabbing in 
         x::Cocci2 (s)::aux started xs
     | x::xs -> x::aux started xs in
index aaa631c..dccb76a 100644 (file)
@@ -78,11 +78,11 @@ let print_around printer term = function
   | Ast.BEFOREAFTER(bef,aft) ->
       print_anything bef; printer term; print_anything aft in
 
-let print_string_befaft fn x info =
-  List.iter (function s -> print_string s; force_newline())
+let print_string_befaft fn fn1 x info =
+  List.iter (function (s,_,_) -> fn1(); print_string s; force_newline())
     info.Ast.strbef;
   fn x;
-  List.iter (function s -> force_newline(); print_string s)
+  List.iter (function (s,_,_) -> force_newline(); fn1(); print_string s)
     info.Ast.straft in
 
 let print_meta (r,x) = print_string x in
@@ -100,16 +100,23 @@ let mcode fn arg =
     (false,(s,info,_,_)) ->
     (* printing for transformation *)
     (* Here we don't care about the annotation on s. *)
-      List.iter (function str -> print_string str; print_string "\n")
-       info.Ast.strbef;
-      if info.Ast.column > 0 && not(info.Ast.strbef = [])
-      then print_string (String.make info.Ast.column ' ');
+      let print_comments lb comments =
+       List.fold_left
+         (function line_before ->
+           function (str,line,col) ->
+             match line_before with
+               None -> print_string str; Some line
+             | Some lb when line = lb -> print_string str; Some line
+             | _ -> print_string "\n"; print_string str; Some line)
+         lb comments in
+      let line_before = print_comments None info.Ast.strbef in
+      (match line_before with
+       None -> ()
+      |        Some lb when lb = info.Ast.line -> ()
+      |        _ -> print_string "\n");
       fn s;
-      (match info.Ast.straft with
-       [] -> ()
-      | aft ->
-         List.iter (function str -> print_string "\n"; print_string str) aft;
-         print_string "\n") (*XXX pr current_tabbing *)
+      let _ = print_comments (Some info.Ast.line) info.Ast.straft in
+      ()
       (* printing for rule generation *)
   | (true, (x, _, Ast.MINUS(_,plus_stream), pos)) ->
       print_string "\n- ";
@@ -120,7 +127,7 @@ let mcode fn arg =
       print_around fn x plus_streams
   | (true,( x, info, Ast.PLUS, pos)) ->
       let fn x = print_string "\n+ "; fn x; print_pos pos in
-      print_string_befaft fn x info
+      print_string_befaft fn (function _ -> print_string "+ ") x info
 in
 
 
@@ -131,7 +138,7 @@ let handle_metavar name fn =
   | None ->
       let name_string (_,s) = s in
       if generating
-      then pr (name_string (term name))
+      then mcode (function _ -> pr (name_string (term name))) name
       else
        failwith
          (Printf.sprintf "SP line %d: Not found a value in env for: %s"
@@ -854,6 +861,7 @@ in
 
 let if_open_brace  = function "{" -> true | _ -> false in
 
+(* boolean result indicates whether an indent is needed *)
 let rec pp_any = function
   (* assert: normally there is only CONTEXT NOTHING tokens in any *)
     Ast.FullTypeTag(x) -> fullType x; false
@@ -884,6 +892,7 @@ let rec pp_any = function
   | Ast.CaseLineTag(x) -> case_line "" x; false
 
   | Ast.ConstVolTag(x) -> const_vol x; false
+  | Ast.Pragma(xs) -> print_between force_newline print_string xs; false
   | Ast.Token(x,None) -> print_string x; if_open_brace x
   | Ast.Token(x,Some info) -> 
       mcode
@@ -937,6 +946,7 @@ in
          let hd = List.hd xxs in
          match hd with
             (Ast.StatementTag s::_) when isfn s -> pr "\n\n"
+         | (Ast.Pragma _::_)
           | (Ast.Rule_elemTag _::_) | (Ast.StatementTag _::_)
          | (Ast.InitTag _::_)
          | (Ast.DeclarationTag _::_) | (Ast.Token ("}",_)::_) -> prnl hd
@@ -945,9 +955,10 @@ in
        if before = Before
        then
          match List.rev(List.hd(List.rev xxs)) with
-           (Ast.StatementTag s::_) when isfn s -> pr "\n\n"
-          | (Ast.Rule_elemTag _::_) | (Ast.StatementTag _::_)
-         | (Ast.InitTag _::_)
+           (Ast.StatementTag s::_) ->
+             if isfn s then pr "\n\n" else pr "\n"
+         | (Ast.Pragma _::_)
+          | (Ast.Rule_elemTag _::_) | (Ast.InitTag _::_)
          | (Ast.DeclarationTag _::_) | (Ast.Token ("{",_)::_) -> pr "\n"
           | _ -> () in
       (* print a newline at the beginning, if needed *)
index 847fe45..060d67c 100644 (file)
@@ -7,18 +7,26 @@ let error x s =
 
 let names = ref ([] : (string * int ref) list)
 
+let started_files = ref ([] : (string * bool) list)
+let typedefs = ref ([] : (string * string list ref) list)
+let current_outfile = ref ""
+
+let prefix = "_cocci_"
+
 (* ----------------------------------------------------------------------- *)
 (* Create rule to check for header include *)
 
 let print_header_rule pr srcfile =
   match Str.split (Str.regexp "/") srcfile with
     [x] ->
-      pr "@header@\n@@\n\n#include \""; pr x; pr "\"\n\n"; true
+      pr "@header@\n@@\n\n#include \"";
+      pr x; pr "\"\n\n"; true
   | l ->
       let rec loop = function
          [] -> false
        | [x] ->
-           pr "@header@\n@@\n\n#include \""; pr x; pr "\"\n\n"; true
+           pr "@header@\n@@\n\n#include \"";
+           pr x; pr "\"\n\n"; true
        | "include"::(x::xs) ->
            pr "@header@\n@@\n\n#include <";
            let x =
@@ -31,16 +39,16 @@ let print_header_rule pr srcfile =
 (* ----------------------------------------------------------------------- *)
 (* Print check that we are not in the defining function *)
 
-let print_check_rule pr function_name header_req =
+let print_check_rule pr function_name function_name_count header_req =
   (if header_req
-  then pr "@same depends on header@\n"
-  else pr "@same@\n");
+  then pr (Printf.sprintf "@same_%s depends on header@\n" function_name_count)
+  else pr (Printf.sprintf "@same_%s@\n" function_name_count));
   pr "position p;\n";
   pr "@@\n\n";
   pr function_name; pr "@p(...) { ... }\n\n"
 
 (* ----------------------------------------------------------------------- *)
-(* get paramaters of the matched function *)
+(* get parameters of the matched function *)
 
 let rec env_lookup fn = function
     [] -> failwith "no binding"
@@ -119,11 +127,17 @@ let get_function_name rule env =
 (* ----------------------------------------------------------------------- *)
 (* Print metavariable declarations *)
 
-let rec print_typedef pr typedefs = function
+let rec print_typedef pr = function
     (Ast_c.TypeName(s,_),_) ->
+      let typedefs =
+       try List.assoc !current_outfile !typedefs
+       with Not_found ->
+         let td = ref [] in
+         typedefs := (!current_outfile,td)::!typedefs;
+         td in
       if not (List.mem s !typedefs)
       then (typedefs := s::!typedefs; pr "typedef "; pr s; pr ";\n")
-  | (Ast_c.Pointer(_,ty),_) -> print_typedef pr typedefs ty
+  | (Ast_c.Pointer(_,ty),_) -> print_typedef pr ty
   | _ -> ()
 
 let rewrap_str s ii =
@@ -137,16 +151,16 @@ let rewrap_str s ii =
     | Ast_c.AbstractLineTok pi ->
        Ast_c.AbstractLineTok { pi with Common.str = s;})}
 
-let print_metavar pr typedefs = function
+let print_metavar pr = function
     ((_,Some param,(_,(Ast_c.Pointer(_,(Ast_c.BaseType(Ast_c.Void),_)),_))),_)
     ->
-      pr "expression _"; pr param
+      pr ("expression "^prefix); pr param
   | (((_,Some param,(_,ty)),il) : Ast_c.parameterType) ->
       let il =
        match List.rev il with
-         name::rest -> (rewrap_str ("_"^param) name) :: rest
+         name::rest -> (rewrap_str (prefix^param) name) :: rest
        | _ -> failwith "no name" in
-      print_typedef pr typedefs ty;
+      print_typedef pr ty;
       Pretty_print_c.pp_param_gen
        (function x ->
          let str = Ast_c.str_of_info x in
@@ -161,19 +175,19 @@ let print_metavar pr typedefs = function
 let make_exp = function
     (((_,Some name,ty),param_ii),comma_ii) ->
       let no_info = (None,Ast_c.NotTest) in
-      let nm = "_"^name in
+      let nm = prefix^name in
       let exp =
        ((Ast_c.Ident nm,ref no_info),
         [rewrap_str nm (List.hd(List.rev param_ii))]) in
       (name,(Common.Left exp,comma_ii))
   | _ -> failwith "bad parameter"
 
-let print_extra_typedefs pr typedefs env =
+let print_extra_typedefs pr env =
   let bigf =
     { Visitor_c.default_visitor_c with
       Visitor_c.ktype = (fun (k, bigf) ty -> 
        match ty with
-         (_,((Ast_c.TypeName(_,_),_) as ty)) -> print_typedef pr typedefs ty
+         (_,((Ast_c.TypeName(_,_),_) as ty)) -> print_typedef pr ty
        | _ -> k ty) } in
   List.iter
     (function (_,vl) ->
@@ -193,7 +207,7 @@ let print_extra_typedefs pr typedefs env =
     env
 
 let rename argids env =
-  let argenv = List.map (function arg -> (arg,"_"^arg)) argids in
+  let argenv = List.map (function arg -> (arg,prefix^arg)) argids in
   let lookup x = try List.assoc x argenv with Not_found -> x in
   let bigf =
     { Visitor_c.default_visitor_c_s with
@@ -228,16 +242,29 @@ let rename argids env =
        | Ast_c.MetaListlenVal _ -> vl))
     env
 
-let print_types pr = function
+let print_one_type pr env = function
+    (Type_cocci.MetaType(name,keep,inherited)) as ty ->
+      (try
+       match List.assoc name env with
+         Ast_c.MetaTypeVal ty -> 
+           Pretty_print_c.pp_type_gen
+             (function x -> pr (Ast_c.str_of_info x))
+             (function _ -> pr " ")
+             ty
+        | _ -> failwith "impossible"
+      with Not_found -> pr (Type_cocci.type2c ty))
+  | ty -> pr (Type_cocci.type2c ty)
+
+let print_types pr env = function
     None -> ()
-  | Some [ty] -> pr (Type_cocci.type2c ty)
+  | Some [ty] -> print_one_type pr env ty
   | Some types ->
       pr "{";
-      Common.print_between (function _ -> pr ", ")
-       (function ty -> pr (Type_cocci.type2c ty)) types;
+      Common.print_between (function _ -> pr ", ") (print_one_type pr env)
+       types;
       pr "}"
 
-let pp_meta_decl pr decl =
+let pp_meta_decl pr env decl =
   let no_arity = function Ast.NONE -> () | _ -> failwith "no arity allowed" in
   let pp_name (_,n) = pr n in
   match decl with
@@ -258,20 +285,20 @@ let pp_meta_decl pr decl =
       no_arity ar; pr "parameter list "; pp_name name;
       pr "["; pp_name len; pr "]"; pr ";\n"
   | Ast.MetaConstDecl(ar, name, types) ->
-      no_arity ar; pr "constant "; print_types pr types;
+      no_arity ar; pr "constant "; print_types pr env types;
       pp_name name; pr ";\n"
   | Ast.MetaErrDecl(ar, name) ->
       no_arity ar; pr "error "; pp_name name; pr ";\n"
   | Ast.MetaExpDecl(ar, name, None) ->
       no_arity ar; pr "expression "; pp_name name; pr ";\n"
   | Ast.MetaExpDecl(ar, name, types) ->
-      no_arity ar; print_types pr types; pp_name name; pr ";\n"
+      no_arity ar; print_types pr env types; pp_name name; pr ";\n"
   | Ast.MetaIdExpDecl(ar, name, types) ->
       no_arity ar; pr "idexpression ";
-      print_types pr types; pp_name name; pr ";\n"
+      print_types pr env types; pp_name name; pr ";\n"
   | Ast.MetaLocalIdExpDecl(ar, name, types) ->
       no_arity ar; pr "local idexpression ";
-      print_types pr types; pp_name name; pr ";\n"
+      print_types pr env types; pp_name name; pr ";\n"
   | Ast.MetaExpListDecl(ar, name, None) ->
       no_arity ar; pr "parameter list "; pp_name name; pr ";\n"
   | Ast.MetaExpListDecl(ar, name, Some len) ->
@@ -292,21 +319,20 @@ let pp_meta_decl pr decl =
   | Ast.MetaIteratorDecl(ar, name) ->
       no_arity ar; pr "iterator "; pp_name name; pr ";\n"
 
-let print_metavariables pr local_metas paramst env header_req =
+let print_metavariables pr local_metas paramst env header_req function_name =
   (if header_req
   then pr "@depends on header@\n"
   else pr "@@\n");
-  pr "position _p!=same.p;\n";
+  pr (Printf.sprintf "position _p!=same_%s.p;\n" function_name);
   pr "identifier _f;\n";
-  let typedefs = ref ([] : string list) in
   let rec loop = function
       [] | [(((_,_,(_,(Ast_c.BaseType(Ast_c.Void),_))),_),_)] -> []
     | ((first,_) as f)::rest ->
-       print_metavar pr typedefs first; pr ";\n";
+       print_metavar pr first; pr ";\n";
        (make_exp f) :: loop rest in
   let args = loop paramst in
-  print_extra_typedefs pr typedefs env;
-  List.iter (pp_meta_decl pr) local_metas;
+  print_extra_typedefs pr env;
+  List.iter (pp_meta_decl pr env) local_metas;
   pr "@@\n\n";
   args
 
@@ -358,20 +384,40 @@ let pp_rule local_metas ast env srcfile =
       Some outdir -> outdir
     | None -> error rule "not possible" in
   let function_name = get_function_name rule env in
-  let outfile = outdir ^ "/" ^ function_name in
-  let outfile =
+  let function_name_count =
     try
-      let cell = List.assoc outfile !names in
+      let cell = List.assoc function_name !names in
       let ct = !cell in
       cell := ct + 1;
-      outfile ^ (string_of_int ct)
+      function_name ^ (string_of_int ct)
     with Not_found ->
-      let cell = ref 1 in names := (outfile,cell) :: !names; outfile in
-  let outfile = outfile ^ ".cocci" in
-  Common.with_open_outfile outfile (fun (pr,chan) ->
-    let header_req = print_header_rule pr srcfile in
-    print_check_rule pr function_name header_req;
-    let args = print_metavariables pr local_metas paramst env header_req in
+      let cell = ref 1 in
+      names := (function_name,cell) :: !names;
+      function_name in
+  let outfile = outdir ^ "/" ^
+    (if !Flag.hrule_per_file
+    then Filename.chop_extension (Filename.basename srcfile)
+    else function_name_count) in
+  let escape_re = Str.regexp_string "/" in
+  let dir = if !Flag.dir = "" then Filename.dirname srcfile else !Flag.dir in
+  let outdirfile = Str.global_replace escape_re "_"dir in
+  let outfile = outfile ^ outdirfile ^ ".cocci" in
+  let saved_header_req =
+    try let res = List.assoc outfile !started_files in Some res
+    with Not_found -> None in
+  current_outfile := outfile;
+  Common.with_open_outfile_append outfile (fun (pr,chan) ->
+    let header_req =
+      match saved_header_req with
+       Some x -> x
+      |        None ->
+         let res = print_header_rule pr srcfile in
+         started_files := (outfile,res)::!started_files;
+         res in
+    print_check_rule pr function_name function_name_count header_req;
+    let args =
+      print_metavariables pr local_metas paramst env header_req
+       function_name_count in
     let (argids,args) = List.split args in
     let env = rename argids env in
     let env = (args_name,Ast_c.MetaExprListVal args)::env in
index 5d87d0c..258699d 100644 (file)
@@ -1,4 +1,6 @@
-(* Copyright (C) 2006, 2007, 2008, 2009 Ecole des Mines de Nantes
+(* Yoann Padioleau
+ * 
+ * Copyright (C) 2006, 2007, 2008, 2009 Ecole des Mines de Nantes
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License (GPL)
@@ -33,7 +35,7 @@ module F = Control_flow_c
  * and some of our analysis need only to specify an action for 
  * specific cases, such as the function call case, and recurse
  * for the other cases. 
- * Here is an simplification of our AST: 
+ * Here is a simplification of our AST: 
  *  
  * type ctype = 
  *  | Basetype of ...
@@ -84,6 +86,22 @@ module F = Control_flow_c
  * kfunction_call, kident, kpostfix hooks as one can just
  * use pattern matching with kexpr to achieve the same effect.
  * 
+ * Note: when want to apply recursively, always apply the continuator
+ * on the toplevel expression, otherwise may miss some intermediate steps.
+ * Do
+ *         match expr with
+ *         | FunCall (e, es) -> ...
+ *             k expr
+ * Or
+ *         match expr with
+ *         | FunCall (e, es) -> ...
+ *             Visitor_c.vk_expr bigf e
+ * Not
+ *         match expr with
+ *         | FunCall (e, es) -> ...
+ *             k e
+ *
+ * 
  * 
  * 
  * 
@@ -99,10 +117,10 @@ module F = Control_flow_c
  *       | other -> super#expr other
  *      end in analysis#expr
  * 
- * Problem is that you don't have control about what is generated 
+ * The problem is that you don't have control about what is generated 
  * and in our case we sometimes dont want to visit too much. For instance
  * our visitor don't recuse on the type annotation of expressions
- * Ok, this could be worked around, but the pb remain, you 
+ * Ok, this could be worked around, but the pb remains, you 
  * don't have control and at some point you may want. In the same
  * way we want to enforce a certain order in the visit (ok this is not good,
  * but it's convenient) of ast elements. For instance first
@@ -221,6 +239,8 @@ type visitor_c =
    kdefineval : (define_val -> unit) * visitor_c -> define_val -> unit;
    kstatementseq: (statement_sequencable   -> unit) * visitor_c -> statement_sequencable   -> unit;
 
+   kfield: (field -> unit) * visitor_c -> field -> unit;
+
    (* CFG *)
    knode: (F.node -> unit) * visitor_c -> F.node -> unit;
    (* AST *)
@@ -242,6 +262,7 @@ let default_visitor_c =
     kcppdirective = (fun (k,_) p  -> k p);
     kdefineval = (fun (k,_) p  -> k p);
     kstatementseq    = (fun (k,_) p  -> k p);
+    kfield    = (fun (k,_) p  -> k p);
   } 
 
 
@@ -287,9 +308,6 @@ let rec vk_expr = fun bigf expr ->
         iif is;
         statxs +> List.iter (vk_statement_sequencable bigf);
 
-    (* TODO, we will certainly have to then do a special visitor for 
-     * initializer 
-     *)
     | Constructor (t, initxs) -> 
         vk_type bigf t;
         initxs +> List.iter (fun (ini, ii) -> 
@@ -495,9 +513,15 @@ and vk_designator = fun bigf design ->
 (* ------------------------------------------------------------------------ *)
 
 and vk_struct_fields = fun bigf fields -> 
+  fields +> List.iter (vk_struct_field bigf);
+
+and vk_struct_field = fun bigf field -> 
   let iif ii = vk_ii bigf ii in
 
-  fields +> List.iter (fun (xfield, ii) -> 
+  let f = bigf.kfield in
+  let rec k field = 
+
+    let (xfield, ii) = field in
     iif ii;
     match xfield with 
     | DeclarationField 
@@ -513,8 +537,11 @@ and vk_struct_fields = fun bigf fields ->
         vk_cpp_directive bigf directive
     | IfdefStruct ifdef -> 
         vk_ifdef_directive bigf ifdef
+  in
+  f (k, bigf) field
+  
 
-  )
+  
 
 and vk_struct_fieldkinds = fun bigf onefield_multivars -> 
   let iif ii = vk_ii bigf ii in
@@ -1095,6 +1122,7 @@ and vk_asmbody_s = fun bigf (string_list, colon_list) ->
   
 
 
+(* todo? a visitor for qualifier *)
 and vk_type_s = fun bigf t -> 
   let rec typef t = bigf.ktype_s (k,bigf) t
   and iif ii = vk_ii_s bigf ii
@@ -1103,7 +1131,7 @@ and vk_type_s = fun bigf t ->
     let (unwrap_q, iiq) = q in
     (* strip_info_visitor needs iiq to be processed before iit *)
     let iif_iiq = iif iiq in
-    let q' = unwrap_q in     (* todo? a visitor for qualifier *)
+    let q' = unwrap_q in
     let (unwrap_t, iit) = t in
     let t' = 
       match unwrap_t with
index 1a31f84..a931e58 100644 (file)
@@ -10,6 +10,9 @@ type visitor_c = {
   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;
+  kfield: (field -> unit) * visitor_c -> field -> unit;
+
+
   knode      :      
     (Control_flow_c.node -> unit) * visitor_c -> Control_flow_c.node -> unit;
   ktoplevel: (toplevel -> unit) * visitor_c -> toplevel -> unit;
diff --git a/parsing_cocci/.#Makefile.1.50 b/parsing_cocci/.#Makefile.1.50
new file mode 100644 (file)
index 0000000..f710d1e
--- /dev/null
@@ -0,0 +1,136 @@
+# Copyright 2005-2009, 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.
+
+
+TARGET=cocci_parser
+
+LEXER_SOURCES = lexer_cocci.mll
+SCRIPT_LEXER_SOURCES = lexer_script.mll
+PARSER_SOURCES = parser_cocci_menhir.mly
+SOURCES = flag_parsing_cocci.ml type_cocci.ml ast_cocci.ml ast0_cocci.ml \
+pretty_print_cocci.ml unparse_ast0.ml \
+visitor_ast.ml visitor_ast0.ml compute_lines.ml comm_assoc.ml \
+iso_pattern.ml iso_compile.ml single_statement.ml simple_assignments.ml \
+ast0toast.ml check_meta.ml top_level.ml type_infer.ml test_exps.ml \
+unitary_ast0.ml arity.ml index.ml context_neg.ml \
+insert_plus.ml function_prototypes.ml \
+unify_ast.ml semantic_cocci.ml data.ml free_vars.ml parse_aux.ml disjdistr.ml \
+$(LEXER_SOURCES:.mll=.ml) $(PARSER_SOURCES:.mly=.ml) \
+$(SCRIPT_LEXER_SOURCES:.mll=.ml) \
+get_constants.ml get_constants2.ml parse_cocci.ml
+
+LIBS=../commons/commons.cma ../globals/globals.cma 
+SYSLIBS = str.cma unix.cma
+
+#MENHIR_PATH=$(shell ocamlfind query menhirLib)
+MENHIR_PATH=../menhirlib
+
+INCLUDES = -I ../commons -I ../commons/ocamlextra -I ../globals \
+-I $(MENHIR_PATH)
+
+MENHIR=$(MENHIR_PATH)/menhirLib.cmo
+MENHIRO=$(MENHIR_PATH)/menhirLib.cmx
+
+
+# The Caml compilers.
+OCAMLCFLAGS ?= -g -dtypes
+OCAMLC =ocamlc$(OPTBIN) $(OCAMLCFLAGS) $(INCLUDES)
+OCAMLOPT = ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
+OCAMLLEX = ocamllex$(OPTBIN)
+OCAMLYACC= menhir --table
+OCAMLDEP = ocamldep$(OPTBIN) #$(INCLUDES)
+EXEC=$(TARGET).byte
+EXEC=$(TARGET)
+LIB=$(TARGET).cma
+OPTLIB=$(LIB:.cma=.cmxa)
+
+GENERATED= $(LEXER_SOURCES:.mll=.ml) $(SCRIPT_LEXER_SOURCES:.mll=.ml) \
+          $(PARSER_SOURCES:.mly=.ml) $(PARSER_SOURCES:.mly=.mli)
+OBJS = $(SOURCES:.ml=.cmo)
+OPTOBJS = $(OBJS:.cmo=.cmx)
+
+
+all: $(LIB)
+local: $(EXEC)
+
+all.opt: $(OPTLIB)
+
+$(LIB): $(GENERATED) $(OBJS)
+       $(OCAMLC) -I $(MENHIR_PATH) -a -o $(LIB) $(MENHIR) $(OBJS)
+
+
+$(OPTLIB): $(GENERATED) $(OPTOBJS) 
+       $(OCAMLOPT) -I $(MENHIR_PATH) -a -o $(OPTLIB) $(MENHIRO) $(OPTOBJS)
+
+
+$(EXEC): $(OBJS) main.cmo $(LIBS)
+       $(OCAMLC) -o $(EXEC) $(SYSLIBS) $(LIBS) $(OBJS) main.cmo
+
+
+
+
+clean::
+       rm -f $(LIB)
+       rm -f $(OPTLIB) $(LIB:.cma=.a)  
+       rm -f $(TARGET)
+
+
+
+
+.SUFFIXES:
+.SUFFIXES: .ml .mli .cmo .cmi .cmx
+
+.ml.cmo:
+       $(OCAMLC) -c $<
+
+.mli.cmi:
+       $(OCAMLC) -c $<
+
+.ml.cmx:
+       $(OCAMLOPT) -c $<
+
+$(LEXER_SOURCES:.mll=.ml) :    $(LEXER_SOURCES)
+       $(OCAMLLEX) $(LEXER_SOURCES)
+
+$(PARSER_SOURCES:.mly=.ml) $(PARSER_SOURCES:.mly=.mli) : $(PARSER_SOURCES)
+       $(OCAMLYACC) $(PARSER_SOURCES)
+
+$(SCRIPT_LEXER_SOURCES:.mll=.ml): $(SCRIPT_LEXER_SOURCES)
+       $(OCAMLLEX) $(SCRIPT_LEXER_SOURCES)
+
+clean::
+       rm -f $(GENERATED)
+
+# clean rule for others files
+clean::
+       rm -f *.cm[iox] *.o *.annot
+       rm -f *~ .*~ #*# 
+
+depend: $(GENERATED)
+       $(OCAMLDEP) *.mli *.ml > .depend
+
+.depend:
+       $(OCAMLDEP) *.mli *.ml > .depend
+
+-include .depend
+
+lexer_cocci.ml: lexer_cocci.mll
+parser_cocci_menhir.ml: parser_cocci_menhir.mly lexer_cocci.mll
+parser_cocci_menhir.mli: parser_cocci_menhir.mly lexer_cocci.mll
+lexer_script.ml: lexer_script.mll
diff --git a/parsing_cocci/.#Makefile.1.51 b/parsing_cocci/.#Makefile.1.51
new file mode 100644 (file)
index 0000000..4028a45
--- /dev/null
@@ -0,0 +1,136 @@
+# Copyright 2005-2009, 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.
+
+
+TARGET=cocci_parser
+
+LEXER_SOURCES = lexer_cocci.mll
+SCRIPT_LEXER_SOURCES = lexer_script.mll
+PARSER_SOURCES = parser_cocci_menhir.mly
+SOURCES = flag_parsing_cocci.ml type_cocci.ml ast_cocci.ml ast0_cocci.ml \
+pretty_print_cocci.ml unparse_ast0.ml \
+visitor_ast.ml visitor_ast0.ml compute_lines.ml comm_assoc.ml \
+iso_pattern.ml iso_compile.ml single_statement.ml simple_assignments.ml \
+ast0toast.ml check_meta.ml top_level.ml type_infer.ml test_exps.ml \
+unitary_ast0.ml arity.ml index.ml context_neg.ml \
+insert_plus.ml function_prototypes.ml \
+unify_ast.ml semantic_cocci.ml data.ml free_vars.ml parse_aux.ml disjdistr.ml \
+$(LEXER_SOURCES:.mll=.ml) $(PARSER_SOURCES:.mly=.ml) \
+$(SCRIPT_LEXER_SOURCES:.mll=.ml) \
+get_constants.ml get_constants2.ml parse_cocci.ml
+
+LIBS=../commons/commons.cma ../globals/globals.cma 
+SYSLIBS = str.cma unix.cma
+
+#MENHIR_PATH=$(shell ocamlfind query menhirLib)
+MENHIR_PATH=../menhirlib
+
+INCLUDES = -I ../commons -I ../commons/ocamlextra -I ../globals \
+-I $(MENHIR_PATH)
+
+MENHIR=$(MENHIR_PATH)/menhirLib.cmo
+MENHIRO=$(MENHIR_PATH)/menhirLib.cmx
+
+
+# The Caml compilers.
+OCAMLCFLAGS ?= -g -dtypes
+OCAMLC =ocamlc$(OPTBIN) $(OCAMLCFLAGS) $(INCLUDES)
+OCAMLOPT = ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
+OCAMLLEX = ocamllex$(OPTBIN)
+OCAMLYACC= menhir --table
+OCAMLDEP = ocamldep$(OPTBIN) $(INCLUDES)
+EXEC=$(TARGET).byte
+EXEC=$(TARGET)
+LIB=$(TARGET).cma
+OPTLIB=$(LIB:.cma=.cmxa)
+
+GENERATED= $(LEXER_SOURCES:.mll=.ml) $(SCRIPT_LEXER_SOURCES:.mll=.ml) \
+          $(PARSER_SOURCES:.mly=.ml) $(PARSER_SOURCES:.mly=.mli)
+OBJS = $(SOURCES:.ml=.cmo)
+OPTOBJS = $(OBJS:.cmo=.cmx)
+
+
+all: $(LIB)
+local: $(EXEC)
+
+all.opt: $(OPTLIB)
+
+$(LIB): $(GENERATED) $(OBJS)
+       $(OCAMLC) -I $(MENHIR_PATH) -a -o $(LIB) $(MENHIR) $(OBJS)
+
+
+$(OPTLIB): $(GENERATED) $(OPTOBJS) 
+       $(OCAMLOPT) -I $(MENHIR_PATH) -a -o $(OPTLIB) $(MENHIRO) $(OPTOBJS)
+
+
+$(EXEC): $(OBJS) main.cmo $(LIBS)
+       $(OCAMLC) -o $(EXEC) $(SYSLIBS) $(LIBS) $(OBJS) main.cmo
+
+
+
+
+clean::
+       rm -f $(LIB)
+       rm -f $(OPTLIB) $(LIB:.cma=.a)  
+       rm -f $(TARGET)
+
+
+
+
+.SUFFIXES:
+.SUFFIXES: .ml .mli .cmo .cmi .cmx
+
+.ml.cmo:
+       $(OCAMLC) -c $<
+
+.mli.cmi:
+       $(OCAMLC) -c $<
+
+.ml.cmx:
+       $(OCAMLOPT) -c $<
+
+$(LEXER_SOURCES:.mll=.ml) :    $(LEXER_SOURCES)
+       $(OCAMLLEX) $(LEXER_SOURCES)
+
+$(PARSER_SOURCES:.mly=.ml) $(PARSER_SOURCES:.mly=.mli) : $(PARSER_SOURCES)
+       $(OCAMLYACC) $(PARSER_SOURCES)
+
+$(SCRIPT_LEXER_SOURCES:.mll=.ml): $(SCRIPT_LEXER_SOURCES)
+       $(OCAMLLEX) $(SCRIPT_LEXER_SOURCES)
+
+clean::
+       rm -f $(GENERATED)
+
+# clean rule for others files
+clean::
+       rm -f *.cm[iox] *.o *.annot
+       rm -f *~ .*~ #*# 
+
+depend: $(GENERATED)
+       $(OCAMLDEP) *.mli *.ml > .depend
+
+.depend:
+       $(OCAMLDEP) *.mli *.ml > .depend
+
+-include .depend
+
+lexer_cocci.ml: lexer_cocci.mll
+parser_cocci_menhir.ml: parser_cocci_menhir.mly lexer_cocci.mll
+parser_cocci_menhir.mli: parser_cocci_menhir.mly lexer_cocci.mll
+lexer_script.ml: lexer_script.mll
diff --git a/parsing_cocci/.#arity.ml.1.88 b/parsing_cocci/.#arity.ml.1.88
new file mode 100644 (file)
index 0000000..56213c8
--- /dev/null
@@ -0,0 +1,1074 @@
+(*
+* Copyright 2005-2009, 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.
+*)
+
+
+(* Arities matter for the minus slice, but not for the plus slice. *)
+
+(* ? only allowed on rule_elems, and on subterms if the context is ? also. *)
+
+module Ast0 = Ast0_cocci
+module Ast = Ast_cocci
+
+(* --------------------------------------------------------------------- *)
+
+let warning s = Printf.printf "warning: %s\n" s
+
+let fail w str =
+  failwith
+    (Printf.sprintf "cocci line %d: %s" ((Ast0.get_info w).Ast0.line_start)
+       str)
+
+let make_opt_unique optfn uniquefn info tgt arity term =
+  let term = Ast0.rewrap info term in
+  if tgt = arity
+  then term
+  else (* tgt must be NONE *)
+    match arity with
+      Ast0.OPT -> Ast0.copywrap info (optfn term)
+    | Ast0.UNIQUE -> Ast0.copywrap info (uniquefn term)
+    | Ast0.NONE -> failwith "tgt must be NONE"
+
+let all_same opt_allowed tgt line arities =
+  let tgt =
+    match tgt with
+      Ast0.NONE ->
+       (match List.hd arities with
+         Ast0.OPT when not opt_allowed ->
+           failwith "opt only allowed for the elements of a statement list"
+       | x -> x)
+    | _ -> tgt in
+  if not(List.for_all (function x -> x = tgt) arities)
+  then warning (Printf.sprintf "incompatible arity found on line %d" line);
+  tgt
+
+let get_option fn = function
+    None -> None
+  | Some x -> Some (fn x)
+
+let anyopt l fn = List.exists (function w -> fn(Ast0.unwrap w)) l
+
+let allopt l fn =
+  let rec loop = function
+      [] -> []
+    | x::xs ->
+       match fn (Ast0.unwrap x) with
+         Some x -> x :: (loop xs)
+       | None -> [] in
+  let res = loop l in
+  if List.length res = List.length l then Some res else None
+
+(* --------------------------------------------------------------------- *)
+(* --------------------------------------------------------------------- *)
+(* Mcode *)
+
+let mcode2line (_,_,info,_,_) = info.Ast0.line_start
+let mcode2arity (_,arity,_,_,_) = arity
+
+let mcode x = x (* nothing to do ... *)
+
+(* --------------------------------------------------------------------- *)
+(* Dots *)
+
+let dots fn d =
+  Ast0.rewrap d
+    (match Ast0.unwrap d with
+      Ast0.DOTS(x) -> Ast0.DOTS(List.map fn x)
+    | Ast0.CIRCLES(x) -> Ast0.CIRCLES(List.map fn x)
+    | Ast0.STARS(x) -> Ast0.STARS(List.map fn x))
+
+let only_dots l =
+  not
+    (List.exists
+       (function x ->
+         match Ast0.unwrap x with
+          Ast0.Circles(_,_) | Ast0.Stars(_,_) -> true
+        | _ -> false)
+       l)
+
+let only_circles l =
+  not (List.exists
+       (function x ->
+         match Ast0.unwrap x with
+           Ast0.Dots(_,_) | Ast0.Stars(_,_) -> true
+         | _ -> false)
+        l)
+
+let only_stars l =
+  not (List.exists
+       (function x ->
+         match Ast0.unwrap x with
+           Ast0.Dots(_,_) | Ast0.Circles(_,_) -> true
+         | _ -> false)
+        l)
+
+let concat_dots fn d =
+  Ast0.rewrap d
+    (match Ast0.unwrap d with
+      Ast0.DOTS(x) ->
+       let l = List.map fn x in
+       if only_dots l
+       then Ast0.DOTS(l)
+       else fail d "inconsistent dots usage"
+    | Ast0.CIRCLES(x) ->
+       let l = List.map fn x in
+       if only_circles l
+       then Ast0.CIRCLES(l)
+       else fail d "inconsistent dots usage"
+    | Ast0.STARS(x) ->
+       let l = List.map fn x in
+       if only_stars l
+       then Ast0.STARS(l)
+       else fail d "inconsistent dots usage")
+
+let flat_concat_dots fn d =
+  match Ast0.unwrap d with
+    Ast0.DOTS(x) -> List.map fn x
+  | Ast0.CIRCLES(x) -> List.map fn x
+  | Ast0.STARS(x) -> List.map fn x
+
+(* --------------------------------------------------------------------- *)
+(* Identifier *)
+
+let make_id =
+  make_opt_unique
+    (function x -> Ast0.OptIdent x)
+    (function x -> Ast0.UniqueIdent x)
+
+let ident opt_allowed tgt i =
+  match Ast0.unwrap i with
+    Ast0.Id(name) ->
+      let arity =
+       all_same opt_allowed tgt (mcode2line name)
+         [mcode2arity name] in
+      let name = mcode name in
+      make_id i tgt arity (Ast0.Id(name))
+  | Ast0.MetaId(name,constraints,pure) ->
+      let arity =
+       all_same opt_allowed tgt (mcode2line name)
+         [mcode2arity name] in
+      let name = mcode name in
+      make_id i tgt arity (Ast0.MetaId(name,constraints,pure))
+  | Ast0.MetaFunc(name,constraints,pure) ->
+      let arity =
+       all_same opt_allowed tgt (mcode2line name)
+         [mcode2arity name] in
+      let name = mcode name in
+      make_id i tgt arity (Ast0.MetaFunc(name,constraints,pure))
+  | Ast0.MetaLocalFunc(name,constraints,pure) ->
+      let arity =
+       all_same opt_allowed tgt (mcode2line name)
+         [mcode2arity name] in
+      let name = mcode name in
+      make_id i tgt arity (Ast0.MetaLocalFunc(name,constraints,pure))
+  | Ast0.OptIdent(_) | Ast0.UniqueIdent(_) ->
+      failwith "unexpected code"
+
+(* --------------------------------------------------------------------- *)
+(* Expression *)
+
+let make_exp =
+  make_opt_unique
+    (function x -> Ast0.OptExp x)
+    (function x -> Ast0.UniqueExp x)
+
+let rec top_expression opt_allowed tgt expr =
+  let exp_same = all_same opt_allowed tgt in
+  match Ast0.unwrap expr with
+    Ast0.Ident(id) ->
+      let new_id = ident opt_allowed tgt id in
+      Ast0.rewrap expr
+       (match Ast0.unwrap new_id with
+         Ast0.OptIdent(id) ->
+           Ast0.OptExp(Ast0.rewrap expr (Ast0.Ident(id)))
+       | Ast0.UniqueIdent(id) ->
+           Ast0.UniqueExp(Ast0.rewrap expr (Ast0.Ident(id)))
+       | _ -> Ast0.Ident(new_id))
+  | Ast0.Constant(const) ->
+      let arity = exp_same (mcode2line const) [mcode2arity const] in
+      let const = mcode const in
+      make_exp expr tgt arity (Ast0.Constant(const))
+  | Ast0.FunCall(fn,lp,args,rp) ->
+      let arity = exp_same (mcode2line lp) [mcode2arity lp;mcode2arity rp] in
+      let fn = expression arity fn in
+      let lp = mcode lp in
+      let args = dots (expression arity) args in
+      let rp = mcode rp in
+      make_exp expr tgt arity (Ast0.FunCall(fn,lp,args,rp))
+  | Ast0.Assignment(left,op,right,simple) ->
+      let arity = exp_same (mcode2line op) [mcode2arity op] in
+      let left = expression arity left in
+      let op = mcode op in
+      let right = expression arity right in
+      make_exp expr tgt arity (Ast0.Assignment(left,op,right,simple))
+  | Ast0.CondExpr(exp1,why,exp2,colon,exp3) ->
+      let arity =
+       exp_same (mcode2line why) [mcode2arity why; mcode2arity colon] in
+      let exp1 = expression arity exp1 in
+      let why = mcode why in
+      let exp2 = get_option (expression arity) exp2 in
+      let colon = mcode colon in
+      let exp3 = expression arity exp3 in
+      make_exp expr tgt arity (Ast0.CondExpr(exp1,why,exp2,colon,exp3))
+  | Ast0.Postfix(exp,op) ->
+      let arity = exp_same (mcode2line op) [mcode2arity op] in
+      let exp = expression arity exp in
+      let op = mcode op in
+      make_exp expr tgt arity (Ast0.Postfix(exp,op))
+  | Ast0.Infix(exp,op) ->
+      let arity = exp_same (mcode2line op) [mcode2arity op] in
+      let exp = expression arity exp in
+      let op = mcode op in
+      make_exp expr tgt arity (Ast0.Infix(exp,op))
+  | Ast0.Unary(exp,op) ->
+      let arity = exp_same (mcode2line op) [mcode2arity op] in
+      let exp = expression arity exp in
+      let op = mcode op in
+      make_exp expr tgt arity (Ast0.Unary(exp,op))
+  | Ast0.Binary(left,op,right) ->
+      let arity = exp_same (mcode2line op) [mcode2arity op] in
+      let left = expression arity left in
+      let op = mcode op in
+      let right = expression arity right in
+      make_exp expr tgt arity (Ast0.Binary(left,op,right))
+  | Ast0.Nested(left,op,right) -> failwith "nested in arity not possible"
+  | Ast0.Paren(lp,exp,rp) ->
+      let arity = exp_same (mcode2line lp) [mcode2arity lp;mcode2arity rp] in
+      let lp = mcode lp in
+      let exp = expression arity exp in
+      let rp = mcode rp in
+      make_exp expr tgt arity (Ast0.Paren(lp,exp,rp))
+  | Ast0.ArrayAccess(exp1,lb,exp2,rb) ->
+      let arity = exp_same (mcode2line lb) [mcode2arity lb; mcode2arity rb] in
+      let exp1 = expression arity exp1 in
+      let lb = mcode lb in
+      let exp2 = expression arity exp2 in
+      let rb = mcode rb in
+      make_exp expr tgt arity (Ast0.ArrayAccess(exp1,lb,exp2,rb))
+  | Ast0.RecordAccess(exp,pt,field) ->
+      let arity = exp_same (mcode2line pt) [mcode2arity pt] in
+      let exp = expression arity exp in
+      let pt = mcode pt in
+      let field = ident false arity field in
+      make_exp expr tgt arity (Ast0.RecordAccess(exp,pt,field))
+  | Ast0.RecordPtAccess(exp,ar,field) ->
+      let arity = exp_same (mcode2line ar) [mcode2arity ar] in
+      let exp = expression arity exp in
+      let ar = mcode ar in
+      let field = ident false arity field in
+      make_exp expr tgt arity (Ast0.RecordPtAccess(exp,ar,field))
+  | Ast0.Cast(lp,ty,rp,exp) ->
+      let arity = exp_same (mcode2line lp) [mcode2arity lp;mcode2arity rp] in
+      let lp = mcode lp in
+      let ty = typeC arity ty in
+      let rp = mcode rp in
+      let exp = expression arity exp in
+      make_exp expr tgt arity (Ast0.Cast(lp,ty,rp,exp))
+  | Ast0.SizeOfExpr(szf,exp) ->
+      let arity = exp_same (mcode2line szf) [mcode2arity szf] in
+      let szf = mcode szf in
+      let exp = expression arity exp in
+      make_exp expr tgt arity (Ast0.SizeOfExpr(szf,exp))
+  | Ast0.SizeOfType(szf,lp,ty,rp) ->
+      let arity =
+       exp_same (mcode2line szf) (List.map mcode2arity [szf;lp;rp]) in
+      let szf = mcode szf in
+      let lp = mcode lp in
+      let ty = typeC arity ty in
+      let rp = mcode rp in
+      make_exp expr tgt arity (Ast0.SizeOfType(szf,lp,ty,rp))
+  | Ast0.TypeExp(ty) -> Ast0.rewrap expr (Ast0.TypeExp(typeC tgt ty))
+  | Ast0.MetaErr(name,constraints,pure)  ->
+      let arity = exp_same (mcode2line name) [mcode2arity name] in
+      let name = mcode name in
+      make_exp expr tgt arity (Ast0.MetaErr(name,constraints,pure))
+  | Ast0.MetaExpr(name,constraints,ty,form,pure)  ->
+      let arity = exp_same (mcode2line name) [mcode2arity name] in
+      let name = mcode name in
+      make_exp expr tgt arity (Ast0.MetaExpr(name,constraints,ty,form,pure))
+  | Ast0.MetaExprList(name,lenname,pure) ->
+      let arity = exp_same (mcode2line name) [mcode2arity name] in
+      let name = mcode name in
+      make_exp expr tgt arity (Ast0.MetaExprList(name,lenname,pure))
+  | Ast0.EComma(cm)         ->
+      let arity = exp_same (mcode2line cm) [mcode2arity cm] in
+      let cm = mcode cm in
+      make_exp expr tgt arity (Ast0.EComma(cm))
+  | Ast0.DisjExpr(starter,exps,mids,ender) ->
+      let exps = List.map (top_expression opt_allowed tgt) exps in
+      (match List.rev exps with
+       _::xs ->
+         if anyopt xs (function Ast0.OptExp(_) -> true | _ -> false)
+         then fail expr "opt only allowed in the last disjunct"
+      |        _ -> ());
+      Ast0.rewrap expr (Ast0.DisjExpr(starter,exps,mids,ender))
+  | Ast0.NestExpr(starter,exp_dots,ender,whencode,multi) ->
+      let res =
+       Ast0.NestExpr(starter,
+                     dots (top_expression true Ast0.NONE) exp_dots,
+                     ender,whencode,multi) in
+      Ast0.rewrap expr res
+  | Ast0.Edots(dots,whencode) ->
+      let arity = exp_same (mcode2line dots) [mcode2arity dots] in
+      let dots = mcode dots in
+      let whencode = get_option (expression Ast0.NONE) whencode in
+      make_exp expr tgt arity (Ast0.Edots(dots,whencode))
+  | Ast0.Ecircles(dots,whencode) ->
+      let arity = exp_same (mcode2line dots) [mcode2arity dots] in
+      let dots = mcode dots in
+      let whencode = get_option (expression Ast0.NONE) whencode in
+      make_exp expr tgt arity (Ast0.Ecircles(dots,whencode))
+  | Ast0.Estars(dots,whencode) ->
+      let arity = exp_same (mcode2line dots) [mcode2arity dots] in
+      let dots = mcode dots in
+      let whencode = get_option (expression Ast0.NONE) whencode in
+      make_exp expr tgt arity (Ast0.Estars(dots,whencode))
+  | Ast0.OptExp(_) | Ast0.UniqueExp(_) ->
+      failwith "unexpected code"
+
+and expression tgt exp = top_expression false tgt exp
+
+(* --------------------------------------------------------------------- *)
+(* Types *)
+
+and make_typeC =
+  make_opt_unique
+    (function x -> Ast0.OptType x)
+    (function x -> Ast0.UniqueType x)
+
+and top_typeC tgt opt_allowed typ =
+  match Ast0.unwrap typ with
+    Ast0.ConstVol(cv,ty) ->
+      let arity = all_same opt_allowed tgt (mcode2line cv)
+         [mcode2arity cv] in
+      let cv = mcode cv in
+      let ty = typeC arity ty in
+      make_typeC typ tgt arity (Ast0.ConstVol(cv,ty))
+  | Ast0.BaseType(ty,strings) ->
+      let arity =
+       all_same opt_allowed tgt (mcode2line (List.hd strings))
+         (List.map mcode2arity strings) in
+      let strings = List.map mcode strings in
+      make_typeC typ tgt arity (Ast0.BaseType(ty,strings))
+  | Ast0.Signed(sign,ty) ->
+      let arity =
+       all_same opt_allowed tgt (mcode2line sign) [mcode2arity sign] in
+      let sign = mcode sign in
+      let ty = get_option (typeC arity) ty in
+      make_typeC typ tgt arity (Ast0.Signed(sign,ty))
+  | Ast0.Pointer(ty,star) ->
+      let arity =
+       all_same opt_allowed tgt (mcode2line star) [mcode2arity star] in
+      let ty = typeC arity ty in
+      let star = mcode star in
+      make_typeC typ tgt arity (Ast0.Pointer(ty,star))
+  | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
+      let arity =
+       all_same opt_allowed tgt (mcode2line lp1)
+         (List.map mcode2arity [lp1;star;rp1;lp2;rp2]) in
+      let ty = typeC arity ty in
+      let params = parameter_list tgt params in
+      make_typeC typ tgt arity
+       (Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2))
+  | Ast0.FunctionType(ty,lp1,params,rp1) ->
+      let arity =
+       all_same opt_allowed tgt (mcode2line lp1)
+         (List.map mcode2arity [lp1;rp1]) in
+      let ty = get_option (typeC arity) ty in
+      let params = parameter_list tgt params in
+      make_typeC typ tgt arity (Ast0.FunctionType(ty,lp1,params,rp1))
+  | Ast0.Array(ty,lb,size,rb) ->
+      let arity =
+       all_same opt_allowed tgt (mcode2line lb)
+         [mcode2arity lb;mcode2arity rb] in
+      let ty = typeC arity ty in
+      let lb = mcode lb in
+      let size = get_option (expression arity) size in
+      let rb = mcode rb in
+      make_typeC typ tgt arity (Ast0.Array(ty,lb,size,rb))
+  | Ast0.EnumName(kind,name) ->
+      let arity =
+       all_same opt_allowed tgt (mcode2line kind) [mcode2arity kind] in
+      let kind = mcode kind in
+      let name = ident false arity name in
+      make_typeC typ tgt arity (Ast0.EnumName(kind,name))
+  | Ast0.StructUnionName(kind,name) ->
+      let arity =
+       all_same opt_allowed tgt (mcode2line kind)
+         [mcode2arity kind] in
+      let kind = mcode kind in
+      let name = get_option (ident false arity) name in
+      make_typeC typ tgt arity (Ast0.StructUnionName(kind,name))
+  | Ast0.StructUnionDef(ty,lb,decls,rb) ->
+      let arity =
+       all_same opt_allowed tgt (mcode2line lb)
+         (List.map mcode2arity [lb;rb]) in
+      let ty = typeC arity ty in
+      let lb = mcode lb in
+      let decls = dots (declaration tgt) decls in
+      let rb = mcode rb in
+      make_typeC typ tgt arity (Ast0.StructUnionDef(ty,lb,decls,rb))
+  | Ast0.TypeName(name) ->
+      let arity =
+       all_same opt_allowed tgt (mcode2line name) [mcode2arity name] in
+      let name = mcode name in
+      make_typeC typ tgt arity (Ast0.TypeName(name))
+  | Ast0.MetaType(name,pure) ->
+      let arity =
+       all_same opt_allowed tgt (mcode2line name) [mcode2arity name] in
+      let name = mcode name in
+      make_typeC typ tgt arity (Ast0.MetaType(name,pure))
+  | Ast0.DisjType(starter,types,mids,ender) ->
+      let types = List.map (typeC tgt) types in
+      (match List.rev types with
+       _::xs ->
+         if anyopt xs (function Ast0.OptType(_) -> true | _ -> false)
+         then fail typ "opt only allowed in the last disjunct"
+      |        _ -> ());
+      let res = Ast0.DisjType(starter,types,mids,ender) in
+      Ast0.rewrap typ res
+  | Ast0.OptType(_) | Ast0.UniqueType(_) ->
+      failwith "unexpected code"
+
+and typeC tgt ty = top_typeC tgt false ty
+
+(* --------------------------------------------------------------------- *)
+(* Variable declaration *)
+(* Even if the Cocci program specifies a list of declarations, they are
+   split out into multiple declarations of a single variable each. *)
+
+and make_decl =
+  make_opt_unique
+    (function x -> Ast0.OptDecl x)
+    (function x -> Ast0.UniqueDecl x)
+
+and declaration tgt decl =
+  match Ast0.unwrap decl with
+    Ast0.Init(stg,ty,id,eq,exp,sem) ->
+      let arity =
+       all_same true tgt (mcode2line eq)
+         ((match stg with None -> [] | Some x -> [mcode2arity x]) @
+          (List.map mcode2arity [eq;sem])) in
+      let stg = get_option mcode stg in
+      let ty = typeC arity ty in
+      let id = ident false arity id in
+      let eq = mcode eq in
+      let exp = initialiser arity exp in
+      let sem = mcode sem in
+      make_decl decl tgt arity (Ast0.Init(stg,ty,id,eq,exp,sem))
+  | Ast0.UnInit(stg,ty,id,sem) ->
+      let arity =
+       all_same true tgt (mcode2line sem)
+         ((match stg with None -> [] | Some x -> [mcode2arity x]) @
+          [mcode2arity sem]) in
+      let stg = get_option mcode stg in
+      let ty = typeC arity ty in
+      let id = ident false arity id in
+      let sem = mcode sem in
+      make_decl decl tgt arity (Ast0.UnInit(stg,ty,id,sem))
+  | Ast0.MacroDecl(name,lp,args,rp,sem) ->
+      let arity =
+       all_same true tgt (mcode2line lp) (List.map mcode2arity [lp;rp;sem]) in
+      let name = ident false arity name in
+      let lp = mcode lp in
+      let args = dots (expression arity) args in
+      let rp = mcode rp in
+      let sem = mcode sem in
+      make_decl decl tgt arity (Ast0.MacroDecl(name,lp,args,rp,sem))
+  | Ast0.TyDecl(ty,sem) ->
+      let arity =
+       all_same true tgt (mcode2line sem) [mcode2arity sem] in
+      let ty = typeC arity ty in
+      let sem = mcode sem in
+      make_decl decl tgt arity (Ast0.TyDecl(ty,sem))
+  | Ast0.Typedef(stg,ty,id,sem) ->
+      let arity =
+       all_same true tgt (mcode2line sem)
+         [mcode2arity stg;mcode2arity sem] in
+      let stg = mcode stg in
+      let ty = typeC arity ty in
+      let id = typeC arity id in
+      let sem = mcode sem in
+      make_decl decl tgt arity (Ast0.Typedef(stg,ty,id,sem))
+  | Ast0.DisjDecl(starter,decls,mids,ender) ->
+      let decls = List.map (declaration tgt) decls in
+      (match List.rev decls with
+       _::xs ->
+         if anyopt xs (function Ast0.OptDecl(_) -> true | _ -> false)
+         then fail decl "opt only allowed in the last disjunct"
+      |        _ -> ());
+      let res = Ast0.DisjDecl(starter,decls,mids,ender) in
+      Ast0.rewrap decl res
+  | Ast0.Ddots(dots,whencode) ->
+      let arity = all_same true tgt (mcode2line dots) [mcode2arity dots] in
+      let dots = mcode dots in
+      let whencode = get_option (declaration Ast0.NONE) whencode in
+      make_decl decl tgt arity (Ast0.Ddots(dots,whencode))
+  | Ast0.OptDecl(_) | Ast0.UniqueDecl(_) ->
+      failwith "unexpected code"
+
+(* --------------------------------------------------------------------- *)
+(* Initializer *)
+
+and make_init =
+  make_opt_unique
+    (function x -> Ast0.OptIni x)
+    (function x -> Ast0.UniqueIni x)
+
+and initialiser tgt i =
+  let init_same = all_same true tgt in
+  match Ast0.unwrap i with
+    Ast0.MetaInit(name,pure) ->
+      let arity = init_same (mcode2line name) [mcode2arity name] in
+      let name = mcode name in
+      make_init i tgt arity (Ast0.MetaInit(name,pure))
+  | Ast0.InitExpr(exp) ->
+      Ast0.rewrap i (Ast0.InitExpr(expression tgt exp))
+  | Ast0.InitList(lb,initlist,rb) ->
+      let arity = init_same (mcode2line lb) [mcode2arity lb; mcode2arity rb] in
+      let lb = mcode lb in
+      let initlist = dots (initialiser arity) initlist in
+      let rb = mcode rb in
+      make_init i tgt arity (Ast0.InitList(lb,initlist,rb))
+  | Ast0.InitGccExt(designators,eq,ini) ->
+      let arity = init_same (mcode2line eq) [mcode2arity eq] in
+      let designators = List.map (designator arity) designators in
+      let eq = mcode eq in
+      let ini = initialiser arity ini in
+      make_init i tgt arity (Ast0.InitGccExt(designators,eq,ini))
+  | Ast0.InitGccName(name,eq,ini) ->
+      let arity = init_same (mcode2line eq) [mcode2arity eq] in
+      let name = ident true arity name in
+      let eq = mcode eq in
+      let ini = initialiser arity ini in
+      make_init i tgt arity (Ast0.InitGccName(name,eq,ini))
+  | Ast0.IComma(cm) ->
+      let arity = init_same (mcode2line cm) [mcode2arity cm] in
+      let cm = mcode cm in
+      make_init i tgt arity (Ast0.IComma(cm))
+  | Ast0.Idots(dots,whencode) ->
+      let arity = init_same (mcode2line dots) [mcode2arity dots] in
+      let dots = mcode dots in
+      let whencode = get_option (initialiser Ast0.NONE) whencode in
+      make_init i tgt arity (Ast0.Idots(dots,whencode))
+  | Ast0.OptIni(_) | Ast0.UniqueIni(_) ->
+      failwith "unexpected code"
+
+and designator tgt d =
+  let dsame = all_same false tgt in
+  match d with
+    Ast0.DesignatorField(dot,id) ->
+      let arity = dsame (mcode2line dot) [mcode2arity dot] in
+      let dot = mcode dot in
+      let id = ident false arity id in
+      Ast0.DesignatorField(dot,id)
+  | Ast0.DesignatorIndex(lb,exp,rb) ->
+      let arity = dsame (mcode2line lb) [mcode2arity lb;mcode2arity rb] in
+      let lb = mcode lb in
+      let exp = top_expression false arity exp in
+      let rb = mcode rb in
+      Ast0.DesignatorIndex(lb,exp,rb)
+  | Ast0.DesignatorRange(lb,min,dots,max,rb) ->
+      let arity =
+       dsame (mcode2line lb)
+         [mcode2arity lb;mcode2arity dots;mcode2arity rb] in
+      let lb = mcode lb in
+      let min = top_expression false arity min in
+      let dots = mcode dots in
+      let max = top_expression false arity max in
+      let rb = mcode rb in
+      Ast0.DesignatorRange(lb,min,dots,max,rb)
+
+(* --------------------------------------------------------------------- *)
+(* Parameter *)
+
+and make_param =
+  make_opt_unique
+    (function x -> Ast0.OptParam x)
+    (function x -> Ast0.UniqueParam x)
+
+and parameterTypeDef tgt param =
+  let param_same = all_same true tgt in
+  match Ast0.unwrap param with
+    Ast0.VoidParam(ty) -> Ast0.rewrap param (Ast0.VoidParam(typeC tgt ty))
+  | Ast0.Param(ty,Some id) ->
+      let ty = top_typeC tgt true ty in
+      let id = ident true tgt id in
+      Ast0.rewrap param
+       (match (Ast0.unwrap ty,Ast0.unwrap id) with
+         (Ast0.OptType(ty),Ast0.OptIdent(id)) ->
+           Ast0.OptParam(Ast0.rewrap param (Ast0.Param(ty,Some id)))
+       | (Ast0.UniqueType(ty),Ast0.UniqueIdent(id)) ->
+           Ast0.UniqueParam(Ast0.rewrap param (Ast0.Param(ty,Some id)))
+       | (Ast0.OptType(ty),_) ->
+           fail param "arity mismatch in param declaration"
+       | (_,Ast0.OptIdent(id)) ->
+           fail param "arity mismatch in param declaration"
+       | _ -> Ast0.Param(ty,Some id))
+  | Ast0.Param(ty,None) ->
+      let ty = top_typeC tgt true ty in
+      Ast0.rewrap param
+       (match Ast0.unwrap ty with
+         Ast0.OptType(ty) ->
+           Ast0.OptParam(Ast0.rewrap param (Ast0.Param(ty,None)))
+       | Ast0.UniqueType(ty) ->
+           Ast0.UniqueParam(Ast0.rewrap param (Ast0.Param(ty,None)))
+       | _ -> Ast0.Param(ty,None))
+  | Ast0.MetaParam(name,pure) ->
+      let arity = param_same (mcode2line name) [mcode2arity name] in
+      let name = mcode name in
+      make_param param tgt arity (Ast0.MetaParam(name,pure))
+  | Ast0.MetaParamList(name,lenname,pure) ->
+      let arity = param_same (mcode2line name) [mcode2arity name] in
+      let name = mcode name in
+      make_param param tgt arity (Ast0.MetaParamList(name,lenname,pure))
+  | Ast0.PComma(cm) ->
+      let arity = param_same (mcode2line cm) [mcode2arity cm] in
+      let cm = mcode cm in
+      make_param param tgt arity (Ast0.PComma(cm))
+  | Ast0.Pdots(dots) ->
+      let arity = param_same (mcode2line dots) [mcode2arity dots] in
+      let dots = mcode dots in
+      make_param param tgt arity (Ast0.Pdots(dots))
+  | Ast0.Pcircles(dots) ->
+      let arity = param_same (mcode2line dots) [mcode2arity dots] in
+      let dots = mcode dots in
+      make_param param tgt arity (Ast0.Pcircles(dots))
+  | Ast0.OptParam(_) | Ast0.UniqueParam(_) ->
+      failwith "unexpected code"
+
+and parameter_list tgt = dots (parameterTypeDef tgt)
+
+(* --------------------------------------------------------------------- *)
+(* Top-level code *)
+
+and make_rule_elem x =
+  make_opt_unique
+    (function x -> Ast0.OptStm x)
+    (function x -> Ast0.UniqueStm x)
+    x
+
+and statement tgt stm =
+  let stm_same = all_same true tgt in
+  match Ast0.unwrap stm with
+    Ast0.Decl(bef,decl) ->
+      let new_decl = declaration tgt decl in
+      Ast0.rewrap stm
+       (match Ast0.unwrap new_decl with
+         Ast0.OptDecl(decl) ->
+           Ast0.OptStm(Ast0.rewrap stm (Ast0.Decl(bef,decl)))
+       | Ast0.UniqueDecl(decl) ->
+           Ast0.UniqueStm(Ast0.rewrap stm (Ast0.Decl(bef,decl)))
+       | _ -> Ast0.Decl(bef,new_decl))
+  | Ast0.Seq(lbrace,body,rbrace) ->
+      let arity =
+       stm_same (mcode2line lbrace)
+         [mcode2arity lbrace; mcode2arity rbrace] in
+      let lbrace = mcode lbrace in
+      let body = dots (statement arity) body in
+      let rbrace = mcode rbrace in
+      make_rule_elem stm tgt arity (Ast0.Seq(lbrace,body,rbrace))
+  | Ast0.ExprStatement(exp,sem) ->
+      let arity = stm_same (mcode2line sem) [mcode2arity sem] in
+      let exp = expression arity exp in
+      let sem = mcode sem in
+      make_rule_elem stm tgt arity (Ast0.ExprStatement(exp,sem))
+  | Ast0.IfThen(iff,lp,exp,rp,branch,aft) ->
+      let arity =
+       stm_same (mcode2line iff) (List.map mcode2arity [iff;lp;rp]) in
+      let iff = mcode iff in
+      let lp = mcode lp in
+      let exp = expression arity exp in
+      let rp = mcode rp in
+      let branch = statement arity branch in
+      make_rule_elem stm tgt arity (Ast0.IfThen(iff,lp,exp,rp,branch,aft))
+  | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,aft) ->
+      let arity =
+       stm_same (mcode2line iff) (List.map mcode2arity [iff;lp;rp;els]) in
+      let iff = mcode iff in
+      let lp = mcode lp in
+      let exp = expression arity exp in
+      let rp = mcode rp in
+      let branch1 = statement arity branch1 in
+      let els = mcode els in
+      let branch2 = statement arity branch2 in
+      make_rule_elem stm tgt arity
+       (Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,aft))
+  | Ast0.While(wh,lp,exp,rp,body,aft) ->
+      let arity =
+       stm_same (mcode2line wh)
+         (List.map mcode2arity [wh;lp;rp]) in
+      let wh = mcode wh in
+      let lp = mcode lp in
+      let exp = expression arity exp in
+      let rp = mcode rp in
+      let body = statement arity body in
+      make_rule_elem stm tgt arity (Ast0.While(wh,lp,exp,rp,body,aft))
+  | Ast0.Do(d,body,wh,lp,exp,rp,sem) ->
+      let arity =
+       stm_same (mcode2line wh) (List.map mcode2arity [d;wh;lp;rp;sem]) in
+      let d = mcode d in
+      let body = statement arity body in
+      let wh = mcode wh in
+      let lp = mcode lp in
+      let exp = expression arity exp in
+      let rp = mcode rp in
+      let sem = mcode sem in
+      make_rule_elem stm tgt arity (Ast0.Do(d,body,wh,lp,exp,rp,sem))
+  | Ast0.For(fr,lp,exp1,sem1,exp2,sem2,exp3,rp,body,aft) ->
+      let arity =
+       stm_same (mcode2line fr) (List.map mcode2arity [fr;lp;sem1;sem2;rp]) in
+      let fr = mcode fr in
+      let lp = mcode lp in
+      let exp1 = get_option (expression arity) exp1 in
+      let sem1 = mcode sem1 in
+      let exp2 = get_option (expression arity) exp2 in
+      let sem2= mcode sem2 in
+      let exp3 = get_option (expression arity) exp3 in
+      let rp = mcode rp in
+      let body = statement arity body in
+      make_rule_elem stm tgt arity
+       (Ast0.For(fr,lp,exp1,sem1,exp2,sem2,exp3,rp,body,aft))
+  | Ast0.Iterator(nm,lp,args,rp,body,aft) ->
+      let arity = stm_same (mcode2line lp) (List.map mcode2arity [lp;rp]) in
+      let nm = ident false arity nm in
+      let lp = mcode lp in
+      let args = dots (expression arity) args in
+      let rp = mcode rp in
+      let body = statement arity body in
+      make_rule_elem stm tgt arity (Ast0.Iterator(nm,lp,args,rp,body,aft))
+  | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) ->
+      let arity =
+       stm_same (mcode2line switch)
+         (List.map mcode2arity [switch;lp;rp;lb;rb]) in
+      let switch = mcode switch in
+      let lp = mcode lp in
+      let exp = expression arity exp in
+      let rp = mcode rp in
+      let lb = mcode lb in
+      let cases = dots (case_line arity) cases in
+      let rb = mcode rb in
+      make_rule_elem stm tgt arity
+       (Ast0.Switch(switch,lp,exp,rp,lb,cases,rb))
+  | Ast0.Break(br,sem) ->
+      let arity = stm_same (mcode2line br) (List.map mcode2arity [br;sem]) in
+      let br = mcode br in
+      let sem = mcode sem in
+      make_rule_elem stm tgt arity (Ast0.Break(br,sem))
+  | Ast0.Continue(cont,sem) ->
+      let arity =
+       stm_same (mcode2line cont) (List.map mcode2arity [cont;sem]) in
+      let cont = mcode cont in
+      let sem = mcode sem in
+      make_rule_elem stm tgt arity (Ast0.Continue(cont,sem))
+  | Ast0.Label(l,dd) ->
+      let arity = mcode2arity dd in
+      let l = ident false tgt l in
+      let dd = mcode dd in
+      make_rule_elem stm tgt arity (Ast0.Label(l,dd))
+  | Ast0.Goto(goto,l,sem) ->
+      let arity =
+       stm_same (mcode2line goto) (List.map mcode2arity [goto;sem]) in
+      let goto = mcode goto in
+      let l = ident false tgt l in
+      let sem = mcode sem in
+      make_rule_elem stm tgt arity (Ast0.Goto(goto,l,sem))
+  | Ast0.Return(ret,sem) ->
+      let arity = stm_same (mcode2line ret) (List.map mcode2arity [ret;sem]) in
+      let ret = mcode ret in
+      let sem = mcode sem in
+      make_rule_elem stm tgt arity (Ast0.Return(ret,sem))
+  | Ast0.ReturnExpr(ret,exp,sem) ->
+      let arity = stm_same (mcode2line ret) (List.map mcode2arity [ret;sem]) in
+      let ret = mcode ret in
+      let exp = expression arity exp in
+      let sem = mcode sem in
+      make_rule_elem stm tgt arity (Ast0.ReturnExpr(ret,exp,sem))
+  | Ast0.MetaStmt(name,pure) ->
+      let arity = stm_same (mcode2line name) [mcode2arity name] in
+      let name = mcode name in
+      make_rule_elem stm tgt arity (Ast0.MetaStmt(name,pure))
+  | Ast0.MetaStmtList(name,pure) ->
+      let arity = stm_same (mcode2line name) [mcode2arity name] in
+      let name = mcode name in
+      make_rule_elem stm tgt arity (Ast0.MetaStmtList(name,pure))
+  | Ast0.Exp(exp) ->
+      let new_exp = top_expression true tgt exp in
+      Ast0.rewrap stm
+       (match Ast0.unwrap new_exp with
+         Ast0.OptExp(exp) ->
+           Ast0.OptStm(Ast0.rewrap stm (Ast0.Exp(exp)))
+       | Ast0.UniqueExp(exp) ->
+           Ast0.UniqueStm(Ast0.rewrap stm (Ast0.Exp(exp)))
+       | _ -> Ast0.Exp(new_exp))
+  | Ast0.TopExp(exp) ->
+      let new_exp = top_expression true tgt exp in
+      Ast0.rewrap stm
+       (match Ast0.unwrap new_exp with
+         Ast0.OptExp(exp) ->
+           Ast0.OptStm(Ast0.rewrap stm (Ast0.TopExp(exp)))
+       | Ast0.UniqueExp(exp) ->
+           Ast0.UniqueStm(Ast0.rewrap stm (Ast0.TopExp(exp)))
+       | _ -> Ast0.TopExp(new_exp))
+  | Ast0.Ty(ty) ->
+      let new_ty = typeC tgt ty in (* opt makes no sense alone at top level *)
+      Ast0.rewrap stm
+       (match Ast0.unwrap new_ty with
+         Ast0.OptType(ty) ->
+           Ast0.OptStm(Ast0.rewrap stm (Ast0.Ty(ty)))
+       | Ast0.UniqueType(ty) ->
+           Ast0.UniqueStm(Ast0.rewrap stm (Ast0.Ty(ty)))
+       | _ -> Ast0.Ty(new_ty))
+  | Ast0.TopInit(init) ->
+      let new_init = initialiser tgt init in
+      Ast0.rewrap stm
+       (match Ast0.unwrap new_init with
+         Ast0.OptIni(init) ->
+           Ast0.OptStm(Ast0.rewrap stm (Ast0.TopInit(init)))
+       | Ast0.UniqueIni(init) ->
+           Ast0.UniqueStm(Ast0.rewrap stm (Ast0.TopInit(init)))
+       | _ -> Ast0.TopInit(new_init))
+  | Ast0.Disj(starter,rule_elem_dots_list,mids,ender) ->
+      let stms =
+       List.map (function x -> concat_dots (statement tgt) x)
+         rule_elem_dots_list in
+      let (found_opt,unopt) =
+       List.fold_left
+         (function (found_opt,lines) ->
+           function x ->
+             let rebuild l =
+               (* previously just checked the last thing in the list,
+                  but everything should be optional for the whole thing to
+                  be optional *)
+               let is_opt x =
+                 match Ast0.unwrap x with
+                   Ast0.OptStm(x) -> true
+                 | _ -> false in
+               let unopt x =
+                 match Ast0.unwrap x with
+                   Ast0.OptStm(x) -> x
+                 | _ -> x in
+               if List.for_all is_opt l
+               then (true,List.map unopt l)
+               else (false, l) in
+             let (l,k) =
+               match Ast0.unwrap x with
+                 Ast0.DOTS(l) ->
+                   (l,function l -> Ast0.rewrap x (Ast0.DOTS l))
+               | Ast0.CIRCLES(l) ->
+                   (l,function l -> Ast0.rewrap x (Ast0.CIRCLES l))
+               | Ast0.STARS(l) ->
+                   (l,function l -> Ast0.rewrap x (Ast0.STARS l)) in
+             let (found_opt,l) = rebuild l in
+             (found_opt,(k l)::lines))
+         (false,[]) stms in
+      let unopt = List.rev unopt in
+      if found_opt
+      then
+       make_rule_elem stm tgt Ast0.OPT (Ast0.Disj(starter,unopt,mids,ender))
+      else Ast0.rewrap stm (Ast0.Disj(starter,stms,mids,ender))
+  | Ast0.Nest(starter,rule_elem_dots,ender,whn,multi) ->
+      let new_rule_elem_dots =
+       concat_dots (statement Ast0.NONE) rule_elem_dots in
+      let whn =
+       List.map
+         (whencode (concat_dots (statement Ast0.NONE)) (statement Ast0.NONE)
+            (expression Ast0.NONE))
+         whn in
+      Ast0.rewrap stm
+       (Ast0.Nest(starter,new_rule_elem_dots,ender,whn,multi))
+  | Ast0.Dots(dots,whn)    ->
+      let arity = stm_same (mcode2line dots) [mcode2arity dots] in
+      let dots = mcode dots in
+      let whn =
+       List.map
+         (whencode (concat_dots (statement Ast0.NONE)) (statement Ast0.NONE)
+            (expression Ast0.NONE))
+         whn in
+      make_rule_elem stm tgt arity (Ast0.Dots(dots,whn))
+  | Ast0.Circles(dots,whn) ->
+      let arity = stm_same (mcode2line dots) [mcode2arity dots] in
+      let dots = mcode dots in
+      let whn =
+       List.map
+         (whencode (concat_dots (statement Ast0.NONE)) (statement Ast0.NONE)
+            (expression Ast0.NONE))
+         whn in
+      make_rule_elem stm tgt arity (Ast0.Circles(dots,whn))
+  | Ast0.Stars(dots,whn)   ->
+      let arity = stm_same (mcode2line dots) [mcode2arity dots] in
+      let dots = mcode dots in
+      let whn =
+       List.map
+         (whencode (concat_dots (statement Ast0.NONE)) (statement Ast0.NONE)
+            (expression Ast0.NONE))
+         whn in
+      make_rule_elem stm tgt arity (Ast0.Stars(dots,whn))
+  | Ast0.FunDecl(bef,fi,name,lp,params,rp,lbrace,body,rbrace) ->
+      let arity =
+       all_same true tgt (mcode2line lp)
+         ((List.map mcode2arity [lp;rp;lbrace;rbrace]) @ (fninfo2arity fi)) in
+      let fi = List.map (fninfo arity) fi in
+      let name = ident false arity name in
+      let lp = mcode lp in
+      let params = parameter_list arity params in
+      let rp = mcode rp in
+      let lbrace = mcode lbrace in
+      let body = dots (statement arity) body in
+      let rbrace = mcode rbrace in
+      make_rule_elem stm tgt arity
+       (Ast0.FunDecl(bef,fi,name,lp,params,rp,lbrace,body,rbrace))
+  | Ast0.Include(inc,s) ->
+      let arity =
+       all_same true tgt (mcode2line inc) [mcode2arity inc; mcode2arity s] in
+      let inc = mcode inc in
+      let s = mcode s in
+      make_rule_elem stm tgt arity (Ast0.Include(inc,s))
+  | Ast0.Define(def,id,params,body) ->
+      let arity = all_same true tgt (mcode2line def) [mcode2arity def] in
+      let def = mcode def in
+      let id = ident false arity id in
+      let params = define_parameters arity params in
+      let body = dots (statement arity) body in
+      make_rule_elem stm tgt arity (Ast0.Define(def,id,params,body))
+  | Ast0.OptStm(_) | Ast0.UniqueStm(_) ->
+      failwith "unexpected code"
+
+and define_parameters tgt params =
+  match Ast0.unwrap params with
+    Ast0.NoParams -> params
+  | Ast0.DParams(lp,params,rp) ->
+      let arity =
+       all_same true tgt (mcode2line lp) [mcode2arity lp;mcode2arity rp] in
+      let lp = mcode lp in
+      let params = dots (define_param arity) params in
+      let rp = mcode rp in
+      Ast0.rewrap params (Ast0.DParams(lp,params,rp))
+
+and make_define_param x =
+  make_opt_unique
+    (function x -> Ast0.OptDParam x)
+    (function x -> Ast0.UniqueDParam x)
+    x
+
+and define_param tgt param =
+  match Ast0.unwrap param with
+    Ast0.DParam(id) ->
+      let new_id = ident true tgt id in
+      Ast0.rewrap param
+       (match Ast0.unwrap new_id with
+         Ast0.OptIdent(id) ->
+           Ast0.OptDParam(Ast0.rewrap param (Ast0.DParam(id)))
+       | Ast0.UniqueIdent(decl) ->
+           Ast0.UniqueDParam(Ast0.rewrap param (Ast0.DParam(id)))
+       | _ -> Ast0.DParam(new_id))
+  | Ast0.DPComma(cm) ->
+      let arity =
+       all_same true tgt (mcode2line cm) [mcode2arity cm] in
+      let cm = mcode cm in
+      make_define_param param tgt arity (Ast0.DPComma(cm))
+  | Ast0.DPdots(dots) ->
+      let arity =
+       all_same true tgt (mcode2line dots) [mcode2arity dots] in
+      let dots = mcode dots in
+      make_define_param param tgt arity (Ast0.DPdots(dots))
+  | Ast0.DPcircles(circles) ->
+      let arity =
+       all_same true tgt (mcode2line circles) [mcode2arity circles] in
+      let circles = mcode circles in
+      make_define_param param tgt arity (Ast0.DPcircles(circles))
+  | Ast0.OptDParam(dp) | Ast0.UniqueDParam(dp) ->
+      failwith "unexpected code"
+
+and fninfo arity = function
+    Ast0.FStorage(stg) -> Ast0.FStorage(mcode stg)
+  | Ast0.FType(ty) -> Ast0.FType(typeC arity ty)
+  | Ast0.FInline(inline) -> Ast0.FInline(mcode inline)
+  | Ast0.FAttr(attr) -> Ast0.FAttr(mcode attr)
+
+and fninfo2arity fninfo =
+  List.concat
+    (List.map
+       (function
+          Ast0.FStorage(stg) -> [mcode2arity stg]
+        | Ast0.FType(ty) -> []
+        | Ast0.FInline(inline) -> [mcode2arity inline]
+        | Ast0.FAttr(attr) -> [mcode2arity attr])
+       fninfo)
+
+and whencode notfn alwaysfn expression = function
+    Ast0.WhenNot a -> Ast0.WhenNot (notfn a)
+  | Ast0.WhenAlways a -> Ast0.WhenAlways (alwaysfn a)
+  | Ast0.WhenModifier(x) -> Ast0.WhenModifier(x)
+  | Ast0.WhenNotTrue a -> Ast0.WhenNotTrue (expression a)
+  | Ast0.WhenNotFalse a -> Ast0.WhenNotFalse (expression a)
+
+and make_case_line =
+  make_opt_unique
+    (function x -> Ast0.OptCase x)
+    (function x -> failwith "unique not allowed for case_line")
+
+and case_line tgt c =
+  match Ast0.unwrap c with
+    Ast0.Default(def,colon,code) ->
+      let arity =
+       all_same true tgt (mcode2line def)
+         [mcode2arity def; mcode2arity colon] in
+      let def = mcode def in
+      let colon = mcode colon in
+      let code = dots (statement arity) code in
+      make_case_line c tgt arity (Ast0.Default(def,colon,code))
+  | Ast0.Case(case,exp,colon,code) ->
+      let arity =
+       all_same true tgt (mcode2line case)
+         [mcode2arity case; mcode2arity colon] in
+      let case = mcode case in
+      let exp = expression arity exp in
+      let colon = mcode colon in
+      let code = dots (statement arity) code in
+      make_case_line c tgt arity (Ast0.Case(case,exp,colon,code))
+  | Ast0.OptCase(_) -> failwith "unexpected OptCase"
+
+(* --------------------------------------------------------------------- *)
+(* Function declaration *)
+(* Haven't thought much about arity here... *)
+
+let top_level tgt t =
+  Ast0.rewrap t
+    (match Ast0.unwrap t with
+      Ast0.FILEINFO(old_file,new_file) ->
+       if mcode2arity old_file = Ast0.NONE && mcode2arity new_file = Ast0.NONE
+       then Ast0.FILEINFO(mcode old_file,mcode new_file)
+       else fail t "unexpected arity for file info"
+    | Ast0.DECL(stmt) ->
+       Ast0.DECL(statement tgt stmt)
+    | Ast0.CODE(rule_elem_dots) ->
+       Ast0.CODE(concat_dots (statement tgt) rule_elem_dots)
+    | Ast0.ERRORWORDS(exps) ->
+       Ast0.ERRORWORDS(List.map (top_expression false Ast0.NONE) exps)
+    | Ast0.OTHER(_) -> fail t "eliminated by top_level")
+
+let rule tgt = List.map (top_level tgt)
+
+(* --------------------------------------------------------------------- *)
+(* Entry points *)
+
+let minus_arity code =
+  rule Ast0.NONE code
diff --git a/parsing_cocci/.#ast0_cocci.ml.1.115 b/parsing_cocci/.#ast0_cocci.ml.1.115
new file mode 100644 (file)
index 0000000..fe3ba6a
--- /dev/null
@@ -0,0 +1,672 @@
+(*
+* Copyright 2005-2009, 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 * string mcode list
+  | Signed          of Ast.sign mcode * typeC option
+  | 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 (* ] *)
+  | EnumName        of string mcode (*enum*) * ident (* name *)
+  | 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 =
+    MetaInit of Ast.meta_name mcode * pure
+  | InitExpr of expression
+  | InitList of string mcode (*{*) * initialiser_list * string mcode (*}*)
+  | InitGccExt of
+      designator list (* name *) * string mcode (*=*) *
+       initialiser (* gccext: *)
+  | InitGccName of ident (* name *) * string mcode (*:*) *
+       initialiser
+  | IComma of string mcode (* , *)
+  | Idots  of string mcode (* ... *) * initialiser option (* whencode *)
+  | OptIni    of initialiser
+  | UniqueIni of initialiser
+
+and designator =
+    DesignatorField of string mcode (* . *) * ident
+  | DesignatorIndex of string mcode (* [ *) * expression * string mcode (* ] *)
+  | DesignatorRange of
+      string mcode (* [ *) * expression * string mcode (* ... *) *
+      expression * string mcode (* ] *)
+
+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) * Ast.ruletype
+  | 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,strings) ->
+      Type_cocci.BaseType(baseType bty)
+  | Signed(sgn,None) ->
+      Type_cocci.SignedT(sign sgn,None)
+  | Signed(sgn,Some ty) ->
+      let bty = ast0_type_to_type ty in
+      Type_cocci.SignedT(sign sgn,Some bty)
+  | 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)
+  | EnumName(su,tag) ->
+      (match unwrap tag with
+       Id(tag) ->
+         Type_cocci.EnumName(false,unwrap_mcode tag)
+      | MetaId(tag,_,_) ->
+         (Printf.printf
+            "warning: enum 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.EnumName(true,rule^tag))
+      | _ -> failwith "unexpected enum type name")
+  | 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 = function
+    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
+  | Ast.LongLongType -> Type_cocci.LongLongType
+
+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 *)
+and 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,context_wrap(reverse_type ty))
+  | Type_cocci.BaseType(bty) ->
+      BaseType(reverse_baseType bty,[(* not used *)])
+  | Type_cocci.SignedT(sgn,None) -> Signed(reverse_sign sgn,None)
+  | Type_cocci.SignedT(sgn,Some bty) ->
+      Signed(reverse_sign sgn,Some (context_wrap(reverse_type ty)))
+  | Type_cocci.Pointer(ty) ->
+      Pointer(context_wrap(reverse_type ty),make_mcode "*")
+  | Type_cocci.EnumName(mv,tag) ->
+      if mv
+      then
+       (* not right... *)
+       EnumName
+         (make_mcode "enum",
+          context_wrap(MetaId(make_mcode ("",tag),[],Impure)))
+      else
+       EnumName(make_mcode "enum",context_wrap(Id(make_mcode tag)))
+  | Type_cocci.StructUnionName(su,mv,tag) ->
+      if mv
+      then
+       (* not right... *)
+       StructUnionName
+         (reverse_structUnion su,
+          Some(context_wrap(MetaId(make_mcode ("",tag),[],Impure))))
+      else
+       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*))
+  | _ -> raise TyConv
+
+and reverse_baseType = function
+    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
+  | Type_cocci.LongLongType -> Ast.LongLongType
+
+and reverse_structUnion t =
+  make_mcode
+    (match t with
+      Type_cocci.Struct -> Ast.Struct
+    | Type_cocci.Union -> Ast.Union)
+
+and reverse_sign t =
+  make_mcode
+    (match t with
+      Type_cocci.Signed -> Ast.Signed
+    | Type_cocci.Unsigned -> Ast.Unsigned)
+
+and reverse_const_vol t =
+  make_mcode
+    (match t with
+      Type_cocci.Const -> Ast.Const
+    | Type_cocci.Volatile -> Ast.Volatile)
+
+(* --------------------------------------------------------------------- *)
+
+let lub_pure x y =
+  match (x,y) with
+    (Impure,_) | (_,Impure) -> Impure
+  | (Pure,Context) | (Context,Pure) -> Impure
+  | (Pure,_) | (_,Pure) -> Pure
+  | (_,Context) | (Context,_) -> Context
+  | _ -> PureContext
+
+(* --------------------------------------------------------------------- *)
+
+let rule_name = ref "" (* for the convenience of the parser *)
diff --git a/parsing_cocci/.#ast0toast.ml.1.140 b/parsing_cocci/.#ast0toast.ml.1.140
new file mode 100644 (file)
index 0000000..274f7f9
--- /dev/null
@@ -0,0 +1,938 @@
+(*
+* Copyright 2005-2009, 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.
+*)
+
+
+(* Arities matter for the minus slice, but not for the plus slice. *)
+
+(* + only allowed on code in a nest (in_nest = true).  ? only allowed on
+rule_elems, and on subterms if the context is ? also. *)
+
+module Ast0 = Ast0_cocci
+module Ast = Ast_cocci
+module V0 = Visitor_ast0
+module V = Visitor_ast
+
+let unitary = Type_cocci.Unitary
+
+let ctr = ref 0
+let get_ctr _ =
+  let c = !ctr in
+  ctr := !ctr + 1;
+  c
+
+(* --------------------------------------------------------------------- *)
+(* Move plus tokens from the MINUS and CONTEXT structured nodes to the
+corresponding leftmost and rightmost mcodes *)
+
+let inline_mcodes =
+  let bind x y = () in
+  let option_default = () in
+  let mcode _ = () in
+  let do_nothing r k e =
+    k e;
+    let einfo = Ast0.get_info e in
+    match (Ast0.get_mcodekind e) with
+      Ast0.MINUS(replacements) ->
+       (match !replacements with
+         ([],_) -> ()
+       | replacements ->
+           let minus_try = function
+               (true,mc) ->
+                 if List.for_all
+                     (function
+                         Ast0.MINUS(mreplacements) -> true | _ -> false)
+                     mc
+                 then
+                   (List.iter
+                      (function
+                          Ast0.MINUS(mreplacements) ->
+                            mreplacements := replacements
+                        | _ -> ())
+                      mc;
+                    true)
+                 else false
+             | _ -> false in
+           if not (minus_try(einfo.Ast0.attachable_start,
+                             einfo.Ast0.mcode_start)
+                     or
+                   minus_try(einfo.Ast0.attachable_end,
+                             einfo.Ast0.mcode_end))
+           then
+             failwith "minus tree should not have bad code on both sides")
+    | Ast0.CONTEXT(befaft)
+    | Ast0.MIXED(befaft) ->
+       let concat starter startinfo ender endinfo =
+         let lst =
+           match (starter,ender) with
+             ([],_) -> ender
+           | (_,[]) -> starter
+           | _ ->
+               if startinfo.Ast0.tline_end = endinfo.Ast0.tline_start
+               then (* put them in the same inner list *)
+                 let last = List.hd (List.rev starter) in
+                 let butlast = List.rev(List.tl(List.rev starter)) in
+                 butlast @ (last@(List.hd ender)) :: (List.tl ender)
+               else starter @ ender in
+         (lst,
+          {endinfo with Ast0.tline_start = startinfo.Ast0.tline_start}) in
+       let attach_bef bef beforeinfo = function
+           (true,mcl) ->
+             List.iter
+               (function
+                   Ast0.MINUS(mreplacements) ->
+                     let (mrepl,tokeninfo) = !mreplacements in
+                     mreplacements := concat bef beforeinfo mrepl tokeninfo
+                 | Ast0.CONTEXT(mbefaft) ->
+                     (match !mbefaft with
+                       (Ast.BEFORE(mbef),mbeforeinfo,a) ->
+                         let (newbef,newinfo) =
+                           concat bef beforeinfo mbef mbeforeinfo in
+                         mbefaft := (Ast.BEFORE(newbef),newinfo,a)
+                     | (Ast.AFTER(maft),_,a) ->
+                         mbefaft :=
+                           (Ast.BEFOREAFTER(bef,maft),beforeinfo,a)
+                     | (Ast.BEFOREAFTER(mbef,maft),mbeforeinfo,a) ->
+                         let (newbef,newinfo) =
+                           concat bef beforeinfo mbef mbeforeinfo in
+                         mbefaft :=
+                           (Ast.BEFOREAFTER(newbef,maft),newinfo,a)
+                     | (Ast.NOTHING,_,a) ->
+                         mbefaft := (Ast.BEFORE(bef),beforeinfo,a))
+                 |     _ -> failwith "unexpected annotation")
+               mcl
+         | _ ->
+             failwith
+               "context tree should not have bad code on both sides" in
+       let attach_aft aft afterinfo = function
+           (true,mcl) ->
+             List.iter
+               (function
+                   Ast0.MINUS(mreplacements) ->
+                     let (mrepl,tokeninfo) = !mreplacements in
+                     mreplacements := concat mrepl tokeninfo aft afterinfo
+                 | Ast0.CONTEXT(mbefaft) ->
+                     (match !mbefaft with
+                       (Ast.BEFORE(mbef),b,_) ->
+                         mbefaft :=
+                           (Ast.BEFOREAFTER(mbef,aft),b,afterinfo)
+                     | (Ast.AFTER(maft),b,mafterinfo) ->
+                         let (newaft,newinfo) =
+                           concat maft mafterinfo aft afterinfo in
+                         mbefaft := (Ast.AFTER(newaft),b,newinfo)
+                     | (Ast.BEFOREAFTER(mbef,maft),b,mafterinfo) ->
+                         let (newaft,newinfo) =
+                           concat maft mafterinfo aft afterinfo in
+                         mbefaft :=
+                           (Ast.BEFOREAFTER(mbef,newaft),b,newinfo)
+                     | (Ast.NOTHING,b,_) ->
+                         mbefaft := (Ast.AFTER(aft),b,afterinfo))
+                 |     _ -> failwith "unexpected annotation")
+               mcl
+         | _ ->
+             failwith
+               "context tree should not have bad code on both sides" in
+       (match !befaft with
+         (Ast.BEFORE(bef),beforeinfo,_) ->
+           attach_bef bef beforeinfo
+             (einfo.Ast0.attachable_start,einfo.Ast0.mcode_start)
+       | (Ast.AFTER(aft),_,afterinfo) ->
+           attach_aft aft afterinfo
+             (einfo.Ast0.attachable_end,einfo.Ast0.mcode_end)
+       | (Ast.BEFOREAFTER(bef,aft),beforeinfo,afterinfo) ->
+           attach_bef bef beforeinfo
+             (einfo.Ast0.attachable_start,einfo.Ast0.mcode_start);
+           attach_aft aft afterinfo
+             (einfo.Ast0.attachable_end,einfo.Ast0.mcode_end)
+       | (Ast.NOTHING,_,_) -> ())
+    | Ast0.PLUS -> () in
+  V0.combiner bind option_default
+    mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+    mcode mcode
+    do_nothing do_nothing do_nothing do_nothing do_nothing do_nothing
+    do_nothing do_nothing do_nothing do_nothing do_nothing do_nothing
+    do_nothing do_nothing do_nothing
+
+(* --------------------------------------------------------------------- *)
+(* For function declarations.  Can't use the mcode at the root, because that
+might be mixed when the function contains ()s, where agglomeration of -s is
+not possible. *)
+
+let check_allminus =
+  let donothing r k e = k e in
+  let bind x y = x && y in
+  let option_default = true in
+  let mcode (_,_,_,mc,_) =
+    match mc with
+      Ast0.MINUS(r) -> let (plusses,_) = !r in plusses = []
+    | _ -> false in
+
+  (* special case for disj *)
+  let expression r k e =
+    match Ast0.unwrap e with
+      Ast0.DisjExpr(starter,expr_list,mids,ender) ->
+       List.for_all r.V0.combiner_expression expr_list
+    | _ -> k e in
+
+  let declaration r k e =
+    match Ast0.unwrap e with
+      Ast0.DisjDecl(starter,decls,mids,ender) ->
+       List.for_all r.V0.combiner_declaration decls
+    | _ -> k e in
+
+  let typeC r k e =
+    match Ast0.unwrap e with
+      Ast0.DisjType(starter,decls,mids,ender) ->
+       List.for_all r.V0.combiner_typeC decls
+    | _ -> k e in
+
+  let statement r k e =
+    match Ast0.unwrap e with
+      Ast0.Disj(starter,statement_dots_list,mids,ender) ->
+       List.for_all r.V0.combiner_statement_dots statement_dots_list
+    | _ -> k e in
+
+  V0.combiner bind option_default
+    mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+    mcode mcode
+    donothing donothing donothing donothing donothing donothing
+    donothing expression typeC donothing donothing declaration
+    statement donothing donothing
+
+(* --------------------------------------------------------------------- *)
+(* --------------------------------------------------------------------- *)
+
+let get_option fn = function
+    None -> None
+  | Some x -> Some (fn x)
+
+(* --------------------------------------------------------------------- *)
+(* --------------------------------------------------------------------- *)
+(* Mcode *)
+
+let convert_info info =
+  { Ast.line = info.Ast0.line_start; Ast.column = info.Ast0.column;
+    Ast.strbef = info.Ast0.strings_before;
+    Ast.straft = info.Ast0.strings_after; }
+
+let convert_mcodekind = function
+    Ast0.MINUS(replacements) ->
+      let (replacements,_) = !replacements in
+      Ast.MINUS(Ast.NoPos,replacements)
+  | Ast0.PLUS -> Ast.PLUS
+  | Ast0.CONTEXT(befaft) ->
+      let (befaft,_,_) = !befaft in Ast.CONTEXT(Ast.NoPos,befaft)
+  | Ast0.MIXED(_) -> failwith "not possible for mcode"
+
+let pos_mcode(term,_,info,mcodekind,pos) =
+  (* avoids a recursion problem *)
+  (term,convert_info info,convert_mcodekind mcodekind,Ast.NoMetaPos)
+
+let mcode(term,_,info,mcodekind,pos) =
+  let pos =
+    match !pos with
+      Ast0.MetaPos(pos,constraints,per) ->
+       Ast.MetaPos(pos_mcode pos,constraints,per,unitary,false)
+    | _ -> Ast.NoMetaPos in
+  (term,convert_info info,convert_mcodekind mcodekind,pos)
+
+(* --------------------------------------------------------------------- *)
+(* Dots *)
+let wrap ast line isos =
+  {(Ast.make_term ast) with Ast.node_line = line;
+    Ast.iso_info = isos}
+
+let rewrap ast0 isos ast =
+  wrap ast ((Ast0.get_info ast0).Ast0.line_start) isos
+
+let no_isos = []
+
+(* no isos on tokens *)
+let tokenwrap (_,info,_,_) s ast = wrap ast info.Ast.line no_isos
+let iso_tokenwrap (_,info,_,_) s ast iso = wrap ast info.Ast.line iso
+
+let dots fn d =
+  rewrap d no_isos
+    (match Ast0.unwrap d with
+      Ast0.DOTS(x) -> Ast.DOTS(List.map fn x)
+    | Ast0.CIRCLES(x) -> Ast.CIRCLES(List.map fn x)
+    | Ast0.STARS(x) -> Ast.STARS(List.map fn x))
+
+(* --------------------------------------------------------------------- *)
+(* Identifier *)
+
+let rec do_isos l = List.map (function (nm,x) -> (nm,anything x)) l
+
+and ident i =
+  rewrap i (do_isos (Ast0.get_iso i))
+    (match Ast0.unwrap i with
+      Ast0.Id(name) -> Ast.Id(mcode name)
+    | Ast0.MetaId(name,constraints,_) ->
+       let constraints = List.map ident constraints in
+       Ast.MetaId(mcode name,constraints,unitary,false)
+    | Ast0.MetaFunc(name,constraints,_) ->
+       let constraints = List.map ident constraints in
+       Ast.MetaFunc(mcode name,constraints,unitary,false)
+    | Ast0.MetaLocalFunc(name,constraints,_) ->
+       let constraints = List.map ident constraints in
+       Ast.MetaLocalFunc(mcode name,constraints,unitary,false)
+    | Ast0.OptIdent(id) -> Ast.OptIdent(ident id)
+    | Ast0.UniqueIdent(id) -> Ast.UniqueIdent(ident id))
+
+(* --------------------------------------------------------------------- *)
+(* Expression *)
+
+and expression e =
+  let e1 =
+  rewrap e (do_isos (Ast0.get_iso e))
+    (match Ast0.unwrap e with
+      Ast0.Ident(id) -> Ast.Ident(ident id)
+    | Ast0.Constant(const) ->
+       Ast.Constant(mcode const)
+    | Ast0.FunCall(fn,lp,args,rp) ->
+       let fn = expression fn in
+       let lp = mcode lp in
+       let args = dots expression args in
+       let rp = mcode rp in
+       Ast.FunCall(fn,lp,args,rp)
+    | Ast0.Assignment(left,op,right,simple) ->
+       Ast.Assignment(expression left,mcode op,expression right,simple)
+    | Ast0.CondExpr(exp1,why,exp2,colon,exp3) ->
+       let exp1 = expression exp1 in
+       let why = mcode why in
+       let exp2 = get_option expression exp2 in
+       let colon = mcode colon in
+       let exp3 = expression exp3 in
+       Ast.CondExpr(exp1,why,exp2,colon,exp3)
+    | Ast0.Postfix(exp,op) ->
+       Ast.Postfix(expression exp,mcode op)
+    | Ast0.Infix(exp,op) ->
+       Ast.Infix(expression exp,mcode op)
+    | Ast0.Unary(exp,op) ->
+       Ast.Unary(expression exp,mcode op)
+    | Ast0.Binary(left,op,right) ->
+       Ast.Binary(expression left,mcode op,expression right)
+    | Ast0.Nested(left,op,right) ->
+       Ast.Nested(expression left,mcode op,expression right)
+    | Ast0.Paren(lp,exp,rp) ->
+       Ast.Paren(mcode lp,expression exp,mcode rp)
+    | Ast0.ArrayAccess(exp1,lb,exp2,rb) ->
+       Ast.ArrayAccess(expression exp1,mcode lb,expression exp2,mcode rb)
+    | Ast0.RecordAccess(exp,pt,field) ->
+       Ast.RecordAccess(expression exp,mcode pt,ident field)
+    | Ast0.RecordPtAccess(exp,ar,field) ->
+       Ast.RecordPtAccess(expression exp,mcode ar,ident field)
+    | Ast0.Cast(lp,ty,rp,exp) ->
+       Ast.Cast(mcode lp,typeC ty,mcode rp,expression exp)
+    | Ast0.SizeOfExpr(szf,exp) ->
+       Ast.SizeOfExpr(mcode szf,expression exp)
+    | Ast0.SizeOfType(szf,lp,ty,rp) ->
+       Ast.SizeOfType(mcode szf, mcode lp,typeC ty,mcode rp)
+    | Ast0.TypeExp(ty) -> Ast.TypeExp(typeC ty)
+    | Ast0.MetaErr(name,constraints,_)  ->
+       let constraints = List.map expression constraints in
+       Ast.MetaErr(mcode name,constraints,unitary,false)
+    | Ast0.MetaExpr(name,constraints,ty,form,_)  ->
+       let constraints = List.map expression constraints in
+       Ast.MetaExpr(mcode name,constraints,unitary,ty,form,false)
+    | Ast0.MetaExprList(name,Some lenname,_) ->
+       Ast.MetaExprList(mcode name,Some (mcode lenname,unitary,false),
+                        unitary,false)
+    | Ast0.MetaExprList(name,None,_) ->
+       Ast.MetaExprList(mcode name,None,unitary,false)
+    | Ast0.EComma(cm)         -> Ast.EComma(mcode cm)
+    | Ast0.DisjExpr(_,exps,_,_)     -> Ast.DisjExpr(List.map expression exps)
+    | Ast0.NestExpr(_,exp_dots,_,whencode,multi) ->
+       let whencode = get_option expression whencode in
+       Ast.NestExpr(dots expression exp_dots,whencode,multi)
+    | Ast0.Edots(dots,whencode) ->
+       let dots = mcode dots in
+       let whencode = get_option expression whencode in
+       Ast.Edots(dots,whencode)
+    | Ast0.Ecircles(dots,whencode) ->
+       let dots = mcode dots in
+       let whencode = get_option expression whencode in
+       Ast.Ecircles(dots,whencode)
+    | Ast0.Estars(dots,whencode) ->
+       let dots = mcode dots in
+       let whencode = get_option expression whencode in
+       Ast.Estars(dots,whencode)
+    | Ast0.OptExp(exp) -> Ast.OptExp(expression exp)
+    | Ast0.UniqueExp(exp) -> Ast.UniqueExp(expression exp)) in
+  if Ast0.get_test_exp e then Ast.set_test_exp e1 else e1
+
+and expression_dots ed = dots expression ed
+
+(* --------------------------------------------------------------------- *)
+(* Types *)
+
+and rewrap_iso t t1 = rewrap t (do_isos (Ast0.get_iso t)) t1
+
+and typeC t =
+  rewrap t (do_isos (Ast0.get_iso t))
+    (match Ast0.unwrap t with
+      Ast0.ConstVol(cv,ty) ->
+       let rec collect_disjs t =
+         match Ast0.unwrap t with
+           Ast0.DisjType(_,types,_,_) ->
+             if Ast0.get_iso t = []
+             then List.concat (List.map collect_disjs types)
+             else failwith "unexpected iso on a disjtype"
+         | _ -> [t] in
+       let res =
+         List.map
+           (function ty ->
+             Ast.Type
+               (Some (mcode cv),rewrap_iso ty (base_typeC ty)))
+           (collect_disjs ty) in
+       (* one could worry that isos are lost because we flatten the
+          disjunctions.  but there should not be isos on the disjunctions
+          themselves. *)
+       (match res with
+         [ty] -> ty
+       | types -> Ast.DisjType(List.map (rewrap t no_isos) types))
+    | Ast0.BaseType(_) | Ast0.Signed(_,_) | Ast0.Pointer(_,_)
+    | Ast0.FunctionPointer(_,_,_,_,_,_,_) | Ast0.FunctionType(_,_,_,_)
+    | Ast0.Array(_,_,_,_) | Ast0.EnumName(_,_) | Ast0.StructUnionName(_,_)
+    | Ast0.StructUnionDef(_,_,_,_) | Ast0.TypeName(_) | Ast0.MetaType(_,_) ->
+       Ast.Type(None,rewrap t no_isos (base_typeC t))
+    | Ast0.DisjType(_,types,_,_) -> Ast.DisjType(List.map typeC types)
+    | Ast0.OptType(ty) -> Ast.OptType(typeC ty)
+    | Ast0.UniqueType(ty) -> Ast.UniqueType(typeC ty))
+
+and base_typeC t =
+  match Ast0.unwrap t with
+    Ast0.BaseType(ty,strings) -> Ast.BaseType(ty,List.map mcode strings)
+  | Ast0.Signed(sgn,ty) ->
+      Ast.SignedT(mcode sgn,
+                 get_option (function x -> rewrap_iso x (base_typeC x)) ty)
+  | Ast0.Pointer(ty,star) -> Ast.Pointer(typeC ty,mcode star)
+  | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
+      Ast.FunctionPointer
+       (typeC ty,mcode lp1,mcode star,mcode rp1,
+        mcode lp2,parameter_list params,mcode rp2)
+  | Ast0.FunctionType(ret,lp,params,rp) ->
+      let allminus = check_allminus.V0.combiner_typeC t in
+      Ast.FunctionType
+       (allminus,get_option typeC ret,mcode lp,
+        parameter_list params,mcode rp)
+  | Ast0.Array(ty,lb,size,rb) ->
+      Ast.Array(typeC ty,mcode lb,get_option expression size,mcode rb)
+  | Ast0.EnumName(kind,name) ->
+      Ast.EnumName(mcode kind,ident name)
+  | Ast0.StructUnionName(kind,name) ->
+      Ast.StructUnionName(mcode kind,get_option ident name)
+  | Ast0.StructUnionDef(ty,lb,decls,rb) ->
+      Ast.StructUnionDef(typeC ty,mcode lb,
+                        dots declaration decls,
+                        mcode rb)
+  | Ast0.TypeName(name) -> Ast.TypeName(mcode name)
+  | Ast0.MetaType(name,_) ->
+      Ast.MetaType(mcode name,unitary,false)
+  | _ -> failwith "ast0toast: unexpected type"
+
+(* --------------------------------------------------------------------- *)
+(* Variable declaration *)
+(* Even if the Cocci program specifies a list of declarations, they are
+   split out into multiple declarations of a single variable each. *)
+
+and declaration d =
+  rewrap d (do_isos (Ast0.get_iso d))
+    (match Ast0.unwrap d with
+      Ast0.Init(stg,ty,id,eq,ini,sem) ->
+       let stg = get_option mcode stg in
+       let ty = typeC ty in
+       let id = ident id in
+       let eq = mcode eq in
+       let ini = initialiser ini in
+       let sem = mcode sem in
+       Ast.Init(stg,ty,id,eq,ini,sem)
+    | Ast0.UnInit(stg,ty,id,sem) ->
+       (match Ast0.unwrap ty with
+         Ast0.FunctionType(tyx,lp1,params,rp1) ->
+           let allminus = check_allminus.V0.combiner_declaration d in
+           Ast.UnInit(get_option mcode stg,
+                      rewrap ty (do_isos (Ast0.get_iso ty))
+                        (Ast.Type
+                           (None,
+                            rewrap ty no_isos
+                              (Ast.FunctionType
+                                 (allminus,get_option typeC tyx,mcode lp1,
+                                  parameter_list params,mcode rp1)))),
+                      ident id,mcode sem)
+       | _ -> Ast.UnInit(get_option mcode stg,typeC ty,ident id,mcode sem))
+    | Ast0.MacroDecl(name,lp,args,rp,sem) ->
+       let name = ident name in
+       let lp = mcode lp in
+       let args = dots expression args in
+       let rp = mcode rp in
+       let sem = mcode sem in
+       Ast.MacroDecl(name,lp,args,rp,sem)
+    | Ast0.TyDecl(ty,sem) -> Ast.TyDecl(typeC ty,mcode sem)
+    | Ast0.Typedef(stg,ty,id,sem) ->
+       let id = typeC id in
+       (match Ast.unwrap id with
+         Ast.Type(None,id) -> (* only MetaType or Id *)
+           Ast.Typedef(mcode stg,typeC ty,id,mcode sem)
+       | _ -> failwith "bad typedef")
+    | Ast0.DisjDecl(_,decls,_,_) -> Ast.DisjDecl(List.map declaration decls)
+    | Ast0.Ddots(dots,whencode) ->
+       let dots = mcode dots in
+       let whencode = get_option declaration whencode in
+       Ast.Ddots(dots,whencode)
+    | Ast0.OptDecl(decl) -> Ast.OptDecl(declaration decl)
+    | Ast0.UniqueDecl(decl) -> Ast.UniqueDecl(declaration decl))
+
+and declaration_dots l = dots declaration l
+
+(* --------------------------------------------------------------------- *)
+(* Initialiser *)
+
+and strip_idots initlist =
+  match Ast0.unwrap initlist with
+    Ast0.DOTS(x) ->
+      let (whencode,init) =
+       List.fold_left
+         (function (prevwhen,previnit) ->
+           function cur ->
+             match Ast0.unwrap cur with
+               Ast0.Idots(dots,Some whencode) ->
+                 (whencode :: prevwhen, previnit)
+             | Ast0.Idots(dots,None) -> (prevwhen,previnit)
+             | _ -> (prevwhen, cur :: previnit))
+         ([],[]) x in
+      (List.rev whencode, List.rev init)
+  | Ast0.CIRCLES(x) | Ast0.STARS(x) -> failwith "not possible for an initlist"
+
+and initialiser i =
+  rewrap i no_isos
+    (match Ast0.unwrap i with
+      Ast0.MetaInit(name,_) -> Ast.MetaInit(mcode name,unitary,false)
+    | Ast0.InitExpr(exp) -> Ast.InitExpr(expression exp)
+    | Ast0.InitList(lb,initlist,rb) ->
+       let (whencode,initlist) =  strip_idots initlist in
+       Ast.InitList(mcode lb,List.map initialiser initlist,mcode rb,
+                    List.map initialiser whencode)
+    | Ast0.InitGccExt(designators,eq,ini) ->
+       Ast.InitGccExt(List.map designator designators,mcode eq,
+                      initialiser ini)
+    | Ast0.InitGccName(name,eq,ini) ->
+       Ast.InitGccName(ident name,mcode eq,initialiser ini)
+    | Ast0.IComma(comma) -> Ast.IComma(mcode comma)
+    | Ast0.Idots(_,_) -> failwith "Idots should have been removed"
+    | Ast0.OptIni(ini) -> Ast.OptIni(initialiser ini)
+    | Ast0.UniqueIni(ini) -> Ast.UniqueIni(initialiser ini))
+
+and designator = function
+    Ast0.DesignatorField(dot,id) -> Ast.DesignatorField(mcode dot,ident id)
+  | Ast0.DesignatorIndex(lb,exp,rb) ->
+      Ast.DesignatorIndex(mcode lb, expression exp, mcode rb)
+  | Ast0.DesignatorRange(lb,min,dots,max,rb) ->
+      Ast.DesignatorRange(mcode lb,expression min,mcode dots,expression max,
+                         mcode rb)
+
+(* --------------------------------------------------------------------- *)
+(* Parameter *)
+
+and parameterTypeDef p =
+  rewrap p no_isos
+    (match Ast0.unwrap p with
+      Ast0.VoidParam(ty) -> Ast.VoidParam(typeC ty)
+    | Ast0.Param(ty,id) -> Ast.Param(typeC ty,get_option ident id)
+    | Ast0.MetaParam(name,_) ->
+       Ast.MetaParam(mcode name,unitary,false)
+    | Ast0.MetaParamList(name,Some lenname,_) ->
+       Ast.MetaParamList(mcode name,Some(mcode lenname,unitary,false),
+                         unitary,false)
+    | Ast0.MetaParamList(name,None,_) ->
+       Ast.MetaParamList(mcode name,None,unitary,false)
+    | Ast0.PComma(cm) -> Ast.PComma(mcode cm)
+    | Ast0.Pdots(dots) -> Ast.Pdots(mcode dots)
+    | Ast0.Pcircles(dots) -> Ast.Pcircles(mcode dots)
+    | Ast0.OptParam(param) -> Ast.OptParam(parameterTypeDef param)
+    | Ast0.UniqueParam(param) -> Ast.UniqueParam(parameterTypeDef param))
+
+and parameter_list l = dots parameterTypeDef l
+
+(* --------------------------------------------------------------------- *)
+(* Top-level code *)
+
+and statement s =
+  let rec statement seqible s =
+    let rewrap_stmt ast0 ast =
+      let befaft =
+       match Ast0.get_dots_bef_aft s with
+         Ast0.NoDots -> Ast.NoDots
+       | Ast0.DroppingBetweenDots s ->
+           Ast.DroppingBetweenDots (statement seqible s,get_ctr())
+       | Ast0.AddingBetweenDots s ->
+           Ast.AddingBetweenDots (statement seqible s,get_ctr()) in
+      Ast.set_dots_bef_aft befaft (rewrap ast0 no_isos ast) in
+    let rewrap_rule_elem ast0 ast =
+      rewrap ast0 (do_isos (Ast0.get_iso ast0)) ast in
+    rewrap_stmt s
+      (match Ast0.unwrap s with
+       Ast0.Decl((_,bef),decl) ->
+         Ast.Atomic(rewrap_rule_elem s
+                      (Ast.Decl(convert_mcodekind bef,
+                                check_allminus.V0.combiner_statement s,
+                                declaration decl)))
+      | Ast0.Seq(lbrace,body,rbrace) ->
+         let lbrace = mcode lbrace in
+         let (decls,body) = separate_decls seqible body in
+         let rbrace = mcode rbrace in
+         Ast.Seq(iso_tokenwrap lbrace s (Ast.SeqStart(lbrace))
+                   (do_isos (Ast0.get_iso s)),
+                 decls,body,
+                 tokenwrap rbrace s (Ast.SeqEnd(rbrace)))
+      | Ast0.ExprStatement(exp,sem) ->
+         Ast.Atomic(rewrap_rule_elem s
+                      (Ast.ExprStatement(expression exp,mcode sem)))
+      | Ast0.IfThen(iff,lp,exp,rp,branch,(_,aft)) ->
+         Ast.IfThen
+           (rewrap_rule_elem s
+              (Ast.IfHeader(mcode iff,mcode lp,expression exp,mcode rp)),
+            statement Ast.NotSequencible branch,
+            ([],[],[],convert_mcodekind aft))
+      | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,(_,aft)) ->
+         let els = mcode els in
+         Ast.IfThenElse
+           (rewrap_rule_elem s
+              (Ast.IfHeader(mcode iff,mcode lp,expression exp,mcode rp)),
+            statement Ast.NotSequencible branch1,
+            tokenwrap els s (Ast.Else(els)),
+            statement Ast.NotSequencible branch2,
+            ([],[],[],convert_mcodekind aft))
+      | Ast0.While(wh,lp,exp,rp,body,(_,aft)) ->
+         Ast.While(rewrap_rule_elem s
+                     (Ast.WhileHeader
+                        (mcode wh,mcode lp,expression exp,mcode rp)),
+                   statement Ast.NotSequencible body,
+                   ([],[],[],convert_mcodekind aft))
+      | Ast0.Do(d,body,wh,lp,exp,rp,sem) ->
+         let wh = mcode wh in
+         Ast.Do(rewrap_rule_elem s (Ast.DoHeader(mcode d)),
+                statement Ast.NotSequencible body,
+                tokenwrap wh s
+                  (Ast.WhileTail(wh,mcode lp,expression exp,mcode rp,
+                                 mcode sem)))
+      | Ast0.For(fr,lp,exp1,sem1,exp2,sem2,exp3,rp,body,(_,aft)) ->
+         let fr = mcode fr in
+         let lp = mcode lp in
+         let exp1 = get_option expression exp1 in
+         let sem1 = mcode sem1 in
+         let exp2 = get_option expression exp2 in
+         let sem2= mcode sem2 in
+         let exp3 = get_option expression exp3 in
+         let rp = mcode rp in
+         let body = statement Ast.NotSequencible body in
+         Ast.For(rewrap_rule_elem s
+                   (Ast.ForHeader(fr,lp,exp1,sem1,exp2,sem2,exp3,rp)),
+                 body,([],[],[],convert_mcodekind aft))
+      | Ast0.Iterator(nm,lp,args,rp,body,(_,aft)) ->
+         Ast.Iterator(rewrap_rule_elem s
+                     (Ast.IteratorHeader
+                        (ident nm,mcode lp,
+                         dots expression args,
+                         mcode rp)),
+                   statement Ast.NotSequencible body,
+                   ([],[],[],convert_mcodekind aft))
+      |        Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) ->
+         let switch = mcode switch in
+         let lp = mcode lp in
+         let exp = expression exp in
+         let rp = mcode rp in
+         let lb = mcode lb in
+         let cases = List.map case_line (Ast0.undots cases) in
+         let rb = mcode rb in
+         Ast.Switch(rewrap_rule_elem s (Ast.SwitchHeader(switch,lp,exp,rp)),
+                    tokenwrap lb s (Ast.SeqStart(lb)),
+                    cases,
+                    tokenwrap rb s (Ast.SeqEnd(rb)))
+      | Ast0.Break(br,sem) ->
+         Ast.Atomic(rewrap_rule_elem s (Ast.Break(mcode br,mcode sem)))
+      | Ast0.Continue(cont,sem) ->
+         Ast.Atomic(rewrap_rule_elem s (Ast.Continue(mcode cont,mcode sem)))
+      |        Ast0.Label(l,dd) ->
+         Ast.Atomic(rewrap_rule_elem s (Ast.Label(ident l,mcode dd)))
+      |        Ast0.Goto(goto,l,sem) ->
+         Ast.Atomic
+           (rewrap_rule_elem s (Ast.Goto(mcode goto,ident l,mcode sem)))
+      | Ast0.Return(ret,sem) ->
+         Ast.Atomic(rewrap_rule_elem s (Ast.Return(mcode ret,mcode sem)))
+      | Ast0.ReturnExpr(ret,exp,sem) ->
+         Ast.Atomic
+           (rewrap_rule_elem s
+              (Ast.ReturnExpr(mcode ret,expression exp,mcode sem)))
+      | Ast0.MetaStmt(name,_) ->
+         Ast.Atomic(rewrap_rule_elem s
+                      (Ast.MetaStmt(mcode name,unitary,seqible,false)))
+      | Ast0.MetaStmtList(name,_) ->
+         Ast.Atomic(rewrap_rule_elem s
+                      (Ast.MetaStmtList(mcode name,unitary,false)))
+      | Ast0.TopExp(exp) ->
+         Ast.Atomic(rewrap_rule_elem s (Ast.TopExp(expression exp)))
+      | Ast0.Exp(exp) ->
+         Ast.Atomic(rewrap_rule_elem s (Ast.Exp(expression exp)))
+      | Ast0.TopInit(init) ->
+         Ast.Atomic(rewrap_rule_elem s (Ast.TopInit(initialiser init)))
+      | Ast0.Ty(ty) ->
+         Ast.Atomic(rewrap_rule_elem s (Ast.Ty(typeC ty)))
+      | Ast0.Disj(_,rule_elem_dots_list,_,_) ->
+         Ast.Disj(List.map (function x -> statement_dots seqible x)
+                    rule_elem_dots_list)
+      | Ast0.Nest(_,rule_elem_dots,_,whn,multi) ->
+         Ast.Nest
+           (statement_dots Ast.Sequencible rule_elem_dots,
+            List.map
+              (whencode (statement_dots Ast.Sequencible)
+                (statement Ast.NotSequencible))
+              whn,
+            multi,[],[])
+      | Ast0.Dots(d,whn) ->
+         let d = mcode d in
+         let whn =
+           List.map
+             (whencode (statement_dots Ast.Sequencible)
+                (statement Ast.NotSequencible))
+             whn in
+         Ast.Dots(d,whn,[],[])
+      | Ast0.Circles(d,whn) ->
+         let d = mcode d in
+         let whn =
+           List.map
+             (whencode (statement_dots Ast.Sequencible)
+                (statement Ast.NotSequencible))
+             whn in
+         Ast.Circles(d,whn,[],[])
+      | Ast0.Stars(d,whn) ->
+         let d = mcode d in
+         let whn =
+           List.map
+             (whencode (statement_dots Ast.Sequencible)
+                (statement Ast.NotSequencible))
+             whn in
+         Ast.Stars(d,whn,[],[])
+      | Ast0.FunDecl((_,bef),fi,name,lp,params,rp,lbrace,body,rbrace) ->
+         let fi = List.map fninfo fi in
+         let name = ident name in
+         let lp = mcode lp in
+         let params = parameter_list params in
+         let rp = mcode rp in
+         let lbrace = mcode lbrace in
+         let (decls,body) = separate_decls seqible body in
+         let rbrace = mcode rbrace in
+         let allminus = check_allminus.V0.combiner_statement s in
+         Ast.FunDecl(rewrap_rule_elem s
+                       (Ast.FunHeader(convert_mcodekind bef,
+                                      allminus,fi,name,lp,params,rp)),
+                     tokenwrap lbrace s (Ast.SeqStart(lbrace)),
+                     decls,body,
+                     tokenwrap rbrace s (Ast.SeqEnd(rbrace)))
+      |        Ast0.Include(inc,str) ->
+         Ast.Atomic(rewrap_rule_elem s (Ast.Include(mcode inc,mcode str)))
+      | Ast0.Define(def,id,params,body) ->
+         Ast.Define
+           (rewrap_rule_elem s
+              (Ast.DefineHeader
+                 (mcode def,ident id, define_parameters params)),
+            statement_dots Ast.NotSequencible (*not sure*) body)
+      | Ast0.OptStm(stm) -> Ast.OptStm(statement seqible stm)
+      | Ast0.UniqueStm(stm) -> Ast.UniqueStm(statement seqible stm))
+
+  and define_parameters p =
+    rewrap p no_isos
+      (match Ast0.unwrap p with
+       Ast0.NoParams -> Ast.NoParams
+      | Ast0.DParams(lp,params,rp) ->
+         Ast.DParams(mcode lp,
+                     dots define_param params,
+                     mcode rp))
+
+  and define_param p =
+    rewrap p no_isos
+      (match Ast0.unwrap p with
+       Ast0.DParam(id) -> Ast.DParam(ident id)
+      | Ast0.DPComma(comma) -> Ast.DPComma(mcode comma)
+      | Ast0.DPdots(d) -> Ast.DPdots(mcode d)
+      | Ast0.DPcircles(c) -> Ast.DPcircles(mcode c)
+      | Ast0.OptDParam(dp) -> Ast.OptDParam(define_param dp)
+      | Ast0.UniqueDParam(dp) -> Ast.UniqueDParam(define_param dp))
+
+  and whencode notfn alwaysfn = function
+      Ast0.WhenNot a -> Ast.WhenNot (notfn a)
+    | Ast0.WhenAlways a -> Ast.WhenAlways (alwaysfn a)
+    | Ast0.WhenModifier(x) -> Ast.WhenModifier(x)
+    | x ->
+       let rewrap_rule_elem ast0 ast =
+         rewrap ast0 (do_isos (Ast0.get_iso ast0)) ast in
+       match x with
+         Ast0.WhenNotTrue(e) ->
+           Ast.WhenNotTrue(rewrap_rule_elem e (Ast.Exp(expression e)))
+       | Ast0.WhenNotFalse(e) ->
+           Ast.WhenNotFalse(rewrap_rule_elem e (Ast.Exp(expression e)))
+       | _ -> failwith "not possible"
+
+  and process_list seqible isos = function
+      [] -> []
+    | x::rest ->
+       let first = statement seqible x in
+       let first =
+         if !Flag.track_iso_usage
+         then Ast.set_isos first (isos@(Ast.get_isos first))
+         else first in
+       (match Ast0.unwrap x with
+         Ast0.Dots(_,_) | Ast0.Nest(_) ->
+           first::(process_list (Ast.SequencibleAfterDots []) no_isos rest)
+       | _ ->
+           first::(process_list Ast.Sequencible no_isos rest))
+
+  and statement_dots seqible d =
+    let isos = do_isos (Ast0.get_iso d) in
+    rewrap d no_isos
+      (match Ast0.unwrap d with
+       Ast0.DOTS(x) -> Ast.DOTS(process_list seqible isos x)
+      | Ast0.CIRCLES(x) -> Ast.CIRCLES(process_list seqible isos x)
+      | Ast0.STARS(x) -> Ast.STARS(process_list seqible isos x))
+
+  and separate_decls seqible d =
+    let rec collect_decls = function
+       [] -> ([],[])
+      | (x::xs) as l ->
+         (match Ast0.unwrap x with
+           Ast0.Decl(_) ->
+             let (decls,other) = collect_decls xs in
+             (x :: decls,other)
+         | Ast0.Dots(_,_) | Ast0.Nest(_,_,_,_,_) ->
+             let (decls,other) = collect_decls xs in
+             (match decls with
+               [] -> ([],x::other)
+             | _ -> (x :: decls,other))
+         | Ast0.Disj(starter,stmt_dots_list,mids,ender) ->
+             let disjs = List.map collect_dot_decls stmt_dots_list in
+             let all_decls = List.for_all (function (_,s) -> s=[]) disjs in
+             if all_decls
+             then
+               let (decls,other) = collect_decls xs in
+               (x :: decls,other)
+             else ([],l)
+         | _ -> ([],l))
+
+    and collect_dot_decls d =
+      match Ast0.unwrap d with
+       Ast0.DOTS(x) -> collect_decls x
+      | Ast0.CIRCLES(x) -> collect_decls x
+      | Ast0.STARS(x) -> collect_decls x in
+
+    let process l d fn =
+      let (decls,other) = collect_decls l in
+      (rewrap d no_isos (fn (List.map (statement seqible) decls)),
+       rewrap d no_isos
+        (fn (process_list seqible (do_isos (Ast0.get_iso d)) other))) in
+    match Ast0.unwrap d with
+      Ast0.DOTS(x) -> process x d (function x -> Ast.DOTS x)
+    | Ast0.CIRCLES(x) -> process x d (function x -> Ast.CIRCLES x)
+    | Ast0.STARS(x) -> process x d (function x -> Ast.STARS x) in
+
+  statement Ast.Sequencible s
+
+and fninfo = function
+    Ast0.FStorage(stg) -> Ast.FStorage(mcode stg)
+  | Ast0.FType(ty) -> Ast.FType(typeC ty)
+  | Ast0.FInline(inline) -> Ast.FInline(mcode inline)
+  | Ast0.FAttr(attr) -> Ast.FAttr(mcode attr)
+
+and option_to_list = function
+    Some x -> [x]
+  | None -> []
+
+and case_line c =
+  rewrap c no_isos
+    (match Ast0.unwrap c with
+      Ast0.Default(def,colon,code) ->
+       let def = mcode def in
+       let colon = mcode colon in
+       let code = dots statement code in
+       Ast.CaseLine(rewrap c no_isos (Ast.Default(def,colon)),code)
+    | Ast0.Case(case,exp,colon,code) ->
+       let case = mcode case in
+       let exp = expression exp in
+       let colon = mcode colon in
+       let code = dots statement code in
+       Ast.CaseLine(rewrap c no_isos (Ast.Case(case,exp,colon)),code)
+    | Ast0.OptCase(case) -> Ast.OptCase(case_line case))
+
+and statement_dots l = dots statement l
+
+(* --------------------------------------------------------------------- *)
+
+(* what is possible is only what is at the top level in an iso *)
+and anything = function
+    Ast0.DotsExprTag(d) -> Ast.ExprDotsTag(expression_dots d)
+  | Ast0.DotsParamTag(d) -> Ast.ParamDotsTag(parameter_list d)
+  | Ast0.DotsInitTag(d) -> failwith "not possible"
+  | Ast0.DotsStmtTag(d) -> Ast.StmtDotsTag(statement_dots d)
+  | Ast0.DotsDeclTag(d) -> Ast.DeclDotsTag(declaration_dots d)
+  | Ast0.DotsCaseTag(d) -> failwith "not possible"
+  | Ast0.IdentTag(d) -> Ast.IdentTag(ident d)
+  | Ast0.ExprTag(d) -> Ast.ExpressionTag(expression d)
+  | Ast0.ArgExprTag(d) | Ast0.TestExprTag(d) ->
+     failwith "only in isos, not converted to ast"
+  | Ast0.TypeCTag(d) -> Ast.FullTypeTag(typeC d)
+  | Ast0.ParamTag(d) -> Ast.ParamTag(parameterTypeDef d)
+  | Ast0.InitTag(d) -> Ast.InitTag(initialiser d)
+  | Ast0.DeclTag(d) -> Ast.DeclarationTag(declaration d)
+  | Ast0.StmtTag(d) -> Ast.StatementTag(statement d)
+  | Ast0.CaseLineTag(d) -> Ast.CaseLineTag(case_line d)
+  | Ast0.TopTag(d) -> Ast.Code(top_level d)
+  | Ast0.IsoWhenTag(_) -> failwith "not possible"
+  | Ast0.IsoWhenTTag(_) -> failwith "not possible"
+  | Ast0.IsoWhenFTag(_) -> failwith "not possible"
+  | Ast0.MetaPosTag _ -> failwith "not possible"
+
+(* --------------------------------------------------------------------- *)
+(* Function declaration *)
+(* top level isos are probably lost to tracking *)
+
+and top_level t =
+  rewrap t no_isos
+    (match Ast0.unwrap t with
+      Ast0.FILEINFO(old_file,new_file) ->
+       Ast.FILEINFO(mcode old_file,mcode new_file)
+    | Ast0.DECL(stmt) -> Ast.DECL(statement stmt)
+    | Ast0.CODE(rule_elem_dots) ->
+       Ast.CODE(statement_dots rule_elem_dots)
+    | Ast0.ERRORWORDS(exps) -> Ast.ERRORWORDS(List.map expression exps)
+    | Ast0.OTHER(_) -> failwith "eliminated by top_level")
+
+(* --------------------------------------------------------------------- *)
+(* Entry point for minus code *)
+
+(* Inline_mcodes is very important - sends + code attached to the - code
+down to the mcodes.  The functions above can only be used when there is no
+attached + code, eg in + code itself. *)
+let ast0toast_toplevel x =
+  inline_mcodes.V0.combiner_top_level x;
+  top_level x
+
+let ast0toast name deps dropped exists x is_exp ruletype =
+  List.iter inline_mcodes.V0.combiner_top_level x;
+  Ast.CocciRule
+    (name,(deps,dropped,exists),List.map top_level x,is_exp,ruletype)
diff --git a/parsing_cocci/.#ast_cocci.ml.1.151 b/parsing_cocci/.#ast_cocci.ml.1.151
new file mode 100644 (file)
index 0000000..ee0a43a
--- /dev/null
@@ -0,0 +1,682 @@
+(*
+* Copyright 2005-2009, 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.
+*)
+
+
+(* --------------------------------------------------------------------- *)
+(* Modified code *)
+
+type info = { line : int; column : int;
+             strbef : string list; straft : string list }
+type line = int
+type meta_name = string * string
+(* need to be careful about rewrapping, to avoid duplicating pos info
+currently, the pos info is always None until asttoctl2. *)
+type 'a wrap =
+    {node : 'a;
+      node_line : line;
+      free_vars : meta_name list; (*free vars*)
+      minus_free_vars : meta_name list; (*minus free vars*)
+      fresh_vars : meta_name list; (*fresh vars*)
+      inherited : meta_name list; (*inherited vars*)
+      saved_witness : meta_name list; (*witness vars*)
+      bef_aft : dots_bef_aft;
+      (* the following is for or expressions *)
+      pos_info : meta_name mcode option; (* pos info, try not to duplicate *)
+      true_if_test_exp : bool;(* true if "test_exp from iso", only for exprs *)
+      (* isos relevant to the term; ultimately only used for rule_elems *)
+      iso_info : (string*anything) list }
+
+and 'a befaft =
+    BEFORE      of 'a list list
+  | AFTER       of 'a list list
+  | BEFOREAFTER of 'a list list * 'a list list
+  | NOTHING
+
+and 'a mcode = 'a * info * mcodekind * meta_pos (* pos variable *)
+ (* pos is an offset indicating where in the C code the mcodekind has an
+ effect *)
+ and mcodekind =
+    MINUS       of pos * anything list list
+  | CONTEXT     of pos * anything befaft
+  | PLUS
+ and fixpos =
+    Real of int (* charpos *) | Virt of int * int (* charpos + offset *)
+ and pos = NoPos | DontCarePos | FixPos of (fixpos * fixpos)
+
+and dots_bef_aft =
+    NoDots
+  | AddingBetweenDots of statement * int (*index of let var*)
+  | DroppingBetweenDots of statement * int (*index of let var*)
+
+and inherited = Type_cocci.inherited
+and keep_binding = Type_cocci.keep_binding
+and multi = bool (*true if a nest is one or more, false if it is zero or more*)
+
+and end_info =
+    meta_name list (*free vars*) * meta_name list (*inherited vars*) *
+      meta_name list (*witness vars*) * mcodekind
+
+(* --------------------------------------------------------------------- *)
+(* Metavariables *)
+
+and arity = UNIQUE | OPT | MULTI | NONE
+
+and metavar =
+    MetaIdDecl of arity * meta_name (* name *)
+  | MetaFreshIdDecl of arity * meta_name (* name *)
+  | MetaTypeDecl of arity * meta_name (* name *)
+  | MetaInitDecl of arity * meta_name (* name *)
+  | MetaListlenDecl of meta_name (* name *)
+  | MetaParamDecl of arity * meta_name (* name *)
+  | MetaParamListDecl of arity * meta_name (*name*) * meta_name option (*len*)
+  | MetaConstDecl of
+      arity * meta_name (* name *) * Type_cocci.typeC list option
+  | MetaErrDecl of arity * meta_name (* name *)
+  | MetaExpDecl of
+      arity * meta_name (* name *) * Type_cocci.typeC list option
+  | MetaIdExpDecl of
+      arity * meta_name (* name *) * Type_cocci.typeC list option
+  | MetaLocalIdExpDecl of
+      arity * meta_name (* name *) * Type_cocci.typeC list option
+  | MetaExpListDecl of arity * meta_name (*name*) * meta_name option (*len*)
+  | MetaStmDecl of arity * meta_name (* name *)
+  | MetaStmListDecl of arity * meta_name (* name *)
+  | MetaFuncDecl of arity * meta_name (* name *)
+  | MetaLocalFuncDecl of arity * meta_name (* name *)
+  | MetaPosDecl of arity * meta_name (* name *)
+  | MetaDeclarerDecl of arity * meta_name (* name *)
+  | MetaIteratorDecl of arity * meta_name (* name *)
+
+(* --------------------------------------------------------------------- *)
+(* --------------------------------------------------------------------- *)
+(* Dots *)
+
+and 'a base_dots =
+    DOTS of 'a list
+  | CIRCLES of 'a list
+  | STARS of 'a list
+
+and 'a dots = 'a base_dots wrap
+
+(* --------------------------------------------------------------------- *)
+(* Identifier *)
+
+and base_ident =
+    Id of string mcode
+
+  | MetaId        of meta_name mcode * ident list * keep_binding * inherited
+  | MetaFunc      of meta_name mcode * ident list * keep_binding * inherited
+  | MetaLocalFunc of meta_name mcode * ident list * keep_binding * inherited
+
+  | OptIdent      of ident
+  | UniqueIdent   of ident
+
+and ident = base_ident wrap
+
+(* --------------------------------------------------------------------- *)
+(* Expression *)
+
+and base_expression =
+    Ident          of ident
+  | Constant       of constant mcode
+  | FunCall        of expression * string mcode (* ( *) *
+                      expression dots * string mcode (* ) *)
+  | Assignment     of expression * assignOp mcode * expression *
+                     bool (* true if it can match an initialization *)
+  | CondExpr       of expression * string mcode (* ? *) * expression option *
+                     string mcode (* : *) * expression
+  | Postfix        of expression * fixOp mcode
+  | Infix          of expression * fixOp mcode
+  | Unary          of expression * unaryOp mcode
+  | Binary         of expression * binaryOp mcode * expression
+  | Nested         of expression * binaryOp mcode * expression
+  | ArrayAccess    of expression * string mcode (* [ *) * expression *
+                     string mcode (* ] *)
+  | RecordAccess   of expression * string mcode (* . *) * ident
+  | RecordPtAccess of expression * string mcode (* -> *) * ident
+  | Cast           of string mcode (* ( *) * fullType * string mcode (* ) *) *
+                      expression
+  | SizeOfExpr     of string mcode (* sizeof *) * expression
+  | SizeOfType     of string mcode (* sizeof *) * string mcode (* ( *) *
+                      fullType * string mcode (* ) *)
+  | TypeExp        of fullType (*type name used as an expression, only in
+                                 arg or #define*)
+
+  | Paren          of string mcode (* ( *) * expression *
+                      string mcode (* ) *)
+
+  | MetaErr        of meta_name mcode * expression list * keep_binding *
+                     inherited
+  | MetaExpr       of meta_name mcode * expression list * keep_binding *
+                     Type_cocci.typeC list option * form * inherited
+  | MetaExprList   of meta_name mcode * listlen option * keep_binding *
+                      inherited (* only in arg lists *)
+
+  | EComma         of string mcode (* only in arg lists *)
+
+  | DisjExpr       of expression list
+  | NestExpr       of expression dots * expression option * multi
+
+  (* can appear in arg lists, and also inside Nest, as in:
+   if(< ... X ... Y ...>)
+   In the following, the expression option is the WHEN  *)
+  | Edots          of string mcode (* ... *) * expression option
+  | Ecircles       of string mcode (* ooo *) * expression option
+  | Estars         of string mcode (* *** *) * expression option
+
+  | OptExp         of expression
+  | UniqueExp      of expression
+
+(* ANY = int E; ID = idexpression int X; CONST = constant int X; *)
+and form = ANY | ID | LocalID | CONST (* form for MetaExp *)
+
+and expression = base_expression wrap
+
+and listlen = meta_name mcode * keep_binding * inherited
+
+and  unaryOp = GetRef | DeRef | UnPlus |  UnMinus | Tilde | Not
+and  assignOp = SimpleAssign | OpAssign of arithOp
+and  fixOp = Dec | Inc
+
+and  binaryOp = Arith of arithOp | Logical of logicalOp
+and  arithOp =
+    Plus | Minus | Mul | Div | Mod | DecLeft | DecRight | And | Or | Xor
+and  logicalOp = Inf | Sup | InfEq | SupEq | Eq | NotEq | AndLog | OrLog
+
+and constant =
+    String of string
+  | Char   of string
+  | Int    of string
+  | Float  of string
+
+(* --------------------------------------------------------------------- *)
+(* Types *)
+
+and base_fullType =
+    Type            of const_vol mcode option * typeC
+  | DisjType        of fullType list (* only after iso *)
+  | OptType         of fullType
+  | UniqueType      of fullType
+
+and base_typeC =
+    BaseType        of baseType * string mcode list (* Yoann style *)
+  | SignedT         of sign mcode * typeC option
+  | Pointer         of fullType * string mcode (* * *)
+  | FunctionPointer of fullType *
+                 string mcode(* ( *)*string mcode(* * *)*string mcode(* ) *)*
+                  string mcode (* ( *)*parameter_list*string mcode(* ) *)
+
+  (* used for the automatic managment of prototypes *)
+  | FunctionType     of bool (* true if all minus for dropping return type *) *
+                   fullType option *
+                  string mcode (* ( *) * parameter_list *
+                   string mcode (* ) *)
+
+  | Array           of fullType * string mcode (* [ *) *
+                      expression option * string mcode (* ] *)
+  | EnumName        of string mcode (*enum*) * ident (* name *)
+  | StructUnionName of structUnion mcode * ident option (* name *)
+  | StructUnionDef  of fullType (* either StructUnionName or metavar *) *
+       string mcode (* { *) * declaration dots * string mcode (* } *)
+  | TypeName        of string mcode
+
+  | MetaType        of meta_name mcode * keep_binding * inherited
+
+and fullType = base_fullType wrap
+and typeC = base_typeC wrap
+
+and baseType = VoidType | CharType | ShortType | IntType | DoubleType
+  | FloatType | LongType | LongLongType
+
+and structUnion = Struct | Union
+
+and sign = Signed | Unsigned
+
+and const_vol = Const | Volatile
+
+(* --------------------------------------------------------------------- *)
+(* Variable declaration *)
+(* Even if the Cocci program specifies a list of declarations, they are
+   split out into multiple declarations of a single variable each. *)
+
+and base_declaration =
+    Init of storage mcode option * fullType * ident * string mcode (*=*) *
+       initialiser * string mcode (*;*)
+  | UnInit of storage mcode option * fullType * ident * string mcode (* ; *)
+  | TyDecl of fullType * string mcode (* ; *)
+  | MacroDecl of ident (* name *) * string mcode (* ( *) *
+        expression dots * string mcode (* ) *) * string mcode (* ; *)
+  | Typedef of string mcode (*typedef*) * fullType *
+               typeC (* either TypeName or metavar *) * string mcode (*;*)
+  | DisjDecl of declaration list
+  (* Ddots is for a structure declaration *)
+  | Ddots    of string mcode (* ... *) * declaration option (* whencode *)
+
+  | MetaDecl of meta_name mcode * keep_binding * inherited
+
+  | OptDecl    of declaration
+  | UniqueDecl of declaration
+
+and declaration = base_declaration wrap
+
+(* --------------------------------------------------------------------- *)
+(* Initializers *)
+
+and base_initialiser =
+    MetaInit of meta_name mcode * keep_binding * inherited
+  | InitExpr of expression
+  | InitList of string mcode (*{*) * initialiser list * string mcode (*}*) *
+       initialiser list (* whencode: elements that shouldn't appear in init *)
+  | InitGccExt of
+      designator list (* name *) * string mcode (*=*) *
+       initialiser (* gccext: *)
+  | InitGccName of ident (* name *) * string mcode (*:*) *
+       initialiser
+  | IComma of string mcode (* , *)
+
+  | OptIni    of initialiser
+  | UniqueIni of initialiser
+
+and designator =
+    DesignatorField of string mcode (* . *) * ident
+  | DesignatorIndex of string mcode (* [ *) * expression * string mcode (* ] *)
+  | DesignatorRange of
+      string mcode (* [ *) * expression * string mcode (* ... *) *
+      expression * string mcode (* ] *)
+
+and initialiser = base_initialiser wrap
+
+(* --------------------------------------------------------------------- *)
+(* Parameter *)
+
+and base_parameterTypeDef =
+    VoidParam     of fullType
+  | Param         of fullType * ident option
+
+  | MetaParam     of meta_name mcode * keep_binding * inherited
+  | MetaParamList of meta_name mcode * listlen option * keep_binding *
+                    inherited
+
+  | PComma        of string mcode
+
+  | Pdots         of string mcode (* ... *)
+  | Pcircles      of string mcode (* ooo *)
+
+  | OptParam      of parameterTypeDef
+  | UniqueParam   of parameterTypeDef
+
+and parameterTypeDef = base_parameterTypeDef wrap
+
+and parameter_list = parameterTypeDef dots
+
+(* --------------------------------------------------------------------- *)
+(* #define Parameters *)
+
+and base_define_param =
+    DParam        of ident
+  | DPComma       of string mcode
+  | DPdots        of string mcode (* ... *)
+  | DPcircles     of string mcode (* ooo *)
+  | OptDParam     of define_param
+  | UniqueDParam  of define_param
+
+and define_param = base_define_param wrap
+
+and base_define_parameters =
+    NoParams     (* not parameter list, not an empty one *)
+  | DParams      of string mcode(*( *) * define_param dots * string mcode(* )*)
+
+and define_parameters = base_define_parameters wrap
+
+(* --------------------------------------------------------------------- *)
+(* positions *)
+
+(* PER = keep bindings separate, ALL = collect them *)
+and meta_collect = PER | ALL
+
+and meta_pos =
+    MetaPos of meta_name mcode * meta_name list *
+       meta_collect * keep_binding * inherited
+  | NoMetaPos
+
+(* --------------------------------------------------------------------- *)
+(* Function declaration *)
+
+and storage = Static | Auto | Register | Extern
+
+(* --------------------------------------------------------------------- *)
+(* Top-level code *)
+
+and base_rule_elem =
+    FunHeader     of mcodekind (* before the function header *) *
+                    bool (* true if all minus, for dropping static, etc *) *
+                    fninfo list * ident (* name *) *
+                    string mcode (* ( *) * parameter_list *
+                     string mcode (* ) *)
+  | Decl          of mcodekind (* before the decl *) *
+                     bool (* true if all minus *) * declaration
+
+  | SeqStart      of string mcode (* { *)
+  | SeqEnd        of string mcode (* } *)
+
+  | ExprStatement of expression * string mcode (*;*)
+  | IfHeader      of string mcode (* if *) * string mcode (* ( *) *
+                    expression * string mcode (* ) *)
+  | Else          of string mcode (* else *)
+  | WhileHeader   of string mcode (* while *) * string mcode (* ( *) *
+                    expression * string mcode (* ) *)
+  | DoHeader      of string mcode (* do *)
+  | WhileTail     of string mcode (* while *) * string mcode (* ( *) *
+                    expression * string mcode (* ) *) *
+                     string mcode (* ; *)
+  | ForHeader     of string mcode (* for *) * string mcode (* ( *) *
+                     expression option * string mcode (*;*) *
+                    expression option * string mcode (*;*) *
+                     expression option * string mcode (* ) *)
+  | IteratorHeader of ident (* name *) * string mcode (* ( *) *
+                    expression dots * string mcode (* ) *)
+  | SwitchHeader  of string mcode (* switch *) * string mcode (* ( *) *
+                    expression * string mcode (* ) *)
+  | Break         of string mcode (* break *) * string mcode (* ; *)
+  | Continue      of string mcode (* continue *) * string mcode (* ; *)
+  | Label         of ident * string mcode (* : *)
+  | Goto          of string mcode (* goto *) * ident * string mcode (* ; *)
+  | Return        of string mcode (* return *) * string mcode (* ; *)
+  | ReturnExpr    of string mcode (* return *) * expression *
+                    string mcode (* ; *)
+
+  | MetaRuleElem  of meta_name mcode * keep_binding * inherited
+  | MetaStmt      of meta_name mcode * keep_binding * metaStmtInfo *
+                    inherited
+  | MetaStmtList  of meta_name mcode * keep_binding * inherited
+
+  | Exp           of expression (* matches a subterm *)
+  | TopExp        of expression (* for macros body, exp at top level,
+                                  not subexp *)
+  | Ty            of fullType (* only at SP top level, matches a subterm *)
+  | TopInit       of initialiser (* only at top level *)
+  | Include       of string mcode (*#include*) * inc_file mcode (*file *)
+  | DefineHeader  of string mcode (* #define *) * ident (* name *) *
+                    define_parameters (*params*)
+  | Case          of string mcode (* case *) * expression * string mcode (*:*)
+  | Default       of string mcode (* default *) * string mcode (*:*)
+  | DisjRuleElem  of rule_elem list
+
+and fninfo =
+    FStorage of storage mcode
+  | FType of fullType
+  | FInline of string mcode
+  | FAttr of string mcode
+
+and metaStmtInfo =
+    NotSequencible | SequencibleAfterDots of dots_whencode list | Sequencible
+
+and rule_elem = base_rule_elem wrap
+
+and base_statement =
+    Seq           of rule_elem (* { *) * statement dots *
+                    statement dots * rule_elem (* } *)
+  | IfThen        of rule_elem (* header *) * statement * end_info (* endif *)
+  | IfThenElse    of rule_elem (* header *) * statement *
+                    rule_elem (* else *) * statement * end_info (* endif *)
+  | While         of rule_elem (* header *) * statement * end_info (*endwhile*)
+  | Do            of rule_elem (* do *) * statement * rule_elem (* tail *)
+  | For           of rule_elem (* header *) * statement * end_info (*endfor*)
+  | Iterator      of rule_elem (* header *) * statement * end_info (*enditer*)
+  | Switch        of rule_elem (* header *) * rule_elem (* { *) *
+                    case_line list * rule_elem (* } *)
+  | Atomic        of rule_elem
+  | Disj          of statement dots list
+  | Nest          of statement dots *
+                    (statement dots,statement) whencode list * multi *
+                    dots_whencode list * dots_whencode list
+  | FunDecl       of rule_elem (* header *) * rule_elem (* { *) *
+                    statement dots * statement dots * rule_elem (* } *)
+  | Define        of rule_elem (* header *) * statement dots
+  | Dots          of string mcode (* ... *) *
+                    (statement dots,statement) whencode list *
+                    dots_whencode list * dots_whencode list
+  | Circles       of string mcode (* ooo *) *
+                    (statement dots,statement) whencode list *
+                    dots_whencode list * dots_whencode list
+  | Stars         of string mcode (* *** *) *
+                    (statement dots,statement) whencode list *
+                    dots_whencode list * dots_whencode list
+  | OptStm        of statement
+  | UniqueStm     of statement
+
+and ('a,'b) whencode =
+    WhenNot of 'a
+  | WhenAlways of 'b
+  | WhenModifier of when_modifier
+  | WhenNotTrue of rule_elem (* useful for fvs *)
+  | WhenNotFalse of rule_elem
+
+and when_modifier =
+  (* The following removes the shortest path constraint.  It can be used
+     with other when modifiers *)
+    WhenAny
+  (* The following removes the special consideration of error paths.  It
+     can be used with other when modifiers *)
+  | WhenStrict
+  | WhenForall
+  | WhenExists
+
+(* only used with asttoctl *)
+and dots_whencode =
+    WParen of rule_elem * meta_name (*pren_var*)
+  | Other of statement
+  | Other_dots of statement dots
+
+and statement = base_statement wrap
+
+and base_case_line =
+    CaseLine of rule_elem (* case/default header *) * statement dots
+  | OptCase of case_line
+
+and case_line = base_case_line wrap
+
+and inc_file =
+    Local of inc_elem list
+  | NonLocal of inc_elem list
+
+and inc_elem =
+    IncPath of string
+  | IncDots
+
+and base_top_level =
+    DECL of statement
+  | CODE of statement dots
+  | FILEINFO of string mcode (* old file *) * string mcode (* new file *)
+  | ERRORWORDS of expression list
+
+and top_level = base_top_level wrap
+
+and rulename =
+    CocciRulename of string option * dependency *
+       string list * string list * exists * bool
+  | GeneratedRulename of string option * dependency *
+       string list * string list * exists * bool
+  | ScriptRulename of string * dependency
+
+and ruletype = Normal | Generated
+
+and rule =
+    CocciRule of string (* name *) *
+       (dependency * string list (* dropped isos *) * exists) * top_level list
+       * bool list * ruletype
+  | ScriptRule of string * dependency * (string * meta_name) list * string
+
+and dependency =
+    Dep of string (* rule applies for the current binding *)
+  | AntiDep of string (* rule doesn't apply for the current binding *)
+  | EverDep of string (* rule applies for some binding *)
+  | NeverDep of string (* rule never applies for any binding *)
+  | AndDep of dependency * dependency
+  | OrDep of dependency * dependency
+  | NoDep
+
+and rule_with_metavars = metavar list * rule
+
+and anything =
+    FullTypeTag         of fullType
+  | BaseTypeTag         of baseType
+  | StructUnionTag      of structUnion
+  | SignTag             of sign
+  | IdentTag            of ident
+  | ExpressionTag       of expression
+  | ConstantTag         of constant
+  | UnaryOpTag          of unaryOp
+  | AssignOpTag         of assignOp
+  | FixOpTag            of fixOp
+  | BinaryOpTag         of binaryOp
+  | ArithOpTag          of arithOp
+  | LogicalOpTag        of logicalOp
+  | DeclarationTag      of declaration
+  | InitTag             of initialiser
+  | StorageTag          of storage
+  | IncFileTag          of inc_file
+  | Rule_elemTag        of rule_elem
+  | StatementTag        of statement
+  | CaseLineTag         of case_line
+  | ConstVolTag         of const_vol
+  | Token               of string * info option
+  | Code                of top_level
+  | ExprDotsTag         of expression dots
+  | ParamDotsTag        of parameterTypeDef dots
+  | StmtDotsTag         of statement dots
+  | DeclDotsTag         of declaration dots
+  | TypeCTag            of typeC
+  | ParamTag            of parameterTypeDef
+  | SgrepStartTag       of string
+  | SgrepEndTag         of string
+
+(* --------------------------------------------------------------------- *)
+
+and exists = Exists | Forall | ReverseForall | Undetermined
+
+(* --------------------------------------------------------------------- *)
+
+let mkToken x = Token (x,None)
+
+(* --------------------------------------------------------------------- *)
+
+let rewrap model x         = {model with node = x}
+let rewrap_mcode (_,a,b,c) x = (x,a,b,c)
+let unwrap x               = x.node
+let unwrap_mcode (x,_,_,_)  = x
+let get_mcodekind (_,_,x,_) = x
+let get_line x             = x.node_line
+let get_mcode_line (_,l,_,_) = l.line
+let get_fvs x              = x.free_vars
+let set_fvs fvs x          = {x with free_vars = fvs}
+let get_mfvs x             = x.minus_free_vars
+let set_mfvs mfvs x        = {x with minus_free_vars = mfvs}
+let get_fresh x            = x.fresh_vars
+let get_inherited x        = x.inherited
+let get_saved x            = x.saved_witness
+let get_dots_bef_aft x     = x.bef_aft
+let set_dots_bef_aft d x   = {x with bef_aft = d}
+let get_pos x              = x.pos_info
+let set_pos x pos          = {x with pos_info = pos}
+let get_test_exp x      = x.true_if_test_exp
+let set_test_exp x      = {x with true_if_test_exp = true}
+let get_isos x             = x.iso_info
+let set_isos x isos        = {x with iso_info = isos}
+let get_pos_var (_,_,_,p)  = p
+let set_pos_var vr (a,b,c,_) = (a,b,c,vr)
+let drop_pos (a,b,c,_)     = (a,b,c,NoMetaPos)
+
+let get_wcfvs (whencode : ('a wrap, 'b wrap) whencode list) =
+  Common.union_all
+    (List.map
+       (function
+          WhenNot(a) -> get_fvs a
+        | WhenAlways(a) -> get_fvs a
+        | WhenModifier(_) -> []
+        | WhenNotTrue(e) -> get_fvs e
+        | WhenNotFalse(e) -> get_fvs e)
+       whencode)
+
+(* --------------------------------------------------------------------- *)
+
+let get_meta_name = function
+    MetaIdDecl(ar,nm) -> nm
+  | MetaFreshIdDecl(ar,nm) -> nm
+  | MetaTypeDecl(ar,nm) -> nm
+  | MetaInitDecl(ar,nm) -> nm
+  | MetaListlenDecl(nm) -> nm
+  | MetaParamDecl(ar,nm) -> nm
+  | MetaParamListDecl(ar,nm,nm1) -> nm
+  | MetaConstDecl(ar,nm,ty) -> nm
+  | MetaErrDecl(ar,nm) -> nm
+  | MetaExpDecl(ar,nm,ty) -> nm
+  | MetaIdExpDecl(ar,nm,ty) -> nm
+  | MetaLocalIdExpDecl(ar,nm,ty) -> nm
+  | MetaExpListDecl(ar,nm,nm1) -> nm
+  | MetaStmDecl(ar,nm) -> nm
+  | MetaStmListDecl(ar,nm) -> nm
+  | MetaFuncDecl(ar,nm) -> nm
+  | MetaLocalFuncDecl(ar,nm) -> nm
+  | MetaPosDecl(ar,nm) -> nm
+  | MetaDeclarerDecl(ar,nm) -> nm
+  | MetaIteratorDecl(ar,nm) -> nm
+
+(* --------------------------------------------------------------------- *)
+
+let no_info = { line = 0; column = 0; strbef = []; straft = [] }
+
+let make_term x =
+  {node = x;
+    node_line = 0;
+    free_vars = [];
+    minus_free_vars = [];
+    fresh_vars = [];
+    inherited = [];
+    saved_witness = [];
+    bef_aft = NoDots;
+    pos_info = None;
+    true_if_test_exp = false;
+    iso_info = [] }
+
+let make_meta_rule_elem s d (fvs,fresh,inh) =
+  {(make_term
+      (MetaRuleElem((("",s),no_info,d,NoMetaPos),Type_cocci.Unitary,false)))
+  with free_vars = fvs; fresh_vars = fresh; inherited = inh}
+
+let make_meta_decl s d (fvs,fresh,inh) =
+  {(make_term
+      (MetaDecl((("",s),no_info,d,NoMetaPos),Type_cocci.Unitary,false))) with
+    free_vars = fvs; fresh_vars = fresh; inherited = inh}
+
+let make_mcode x = (x,no_info,CONTEXT(NoPos,NOTHING),NoMetaPos)
+
+(* --------------------------------------------------------------------- *)
+
+let equal_pos x y = x = y
+
+(* --------------------------------------------------------------------- *)
+
+let undots x =
+  match unwrap x with
+    DOTS    e -> e
+  | CIRCLES e -> e
+  | STARS   e -> e
diff --git a/parsing_cocci/.#check_meta.ml.1.88 b/parsing_cocci/.#check_meta.ml.1.88
new file mode 100644 (file)
index 0000000..ff7d88e
--- /dev/null
@@ -0,0 +1,539 @@
+(*
+* Copyright 2005-2009, 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 fragment, checks that all of the identifier metavariables that
+are used are not declared as fresh, and check that all declared variables
+are used.  For plus fragment, just check that the variables declared as
+fresh are used.  What is the issue about error variables? (don't remember) *)
+
+module Ast0 = Ast0_cocci
+module Ast = Ast_cocci
+module V0 = Visitor_ast0
+
+(* all fresh identifiers *)
+let fresh_table = (Hashtbl.create(50) : ((string * string), unit) Hashtbl.t)
+
+let warning s = Printf.fprintf stderr "warning: %s\n" s
+
+let promote name = (name,(),Ast0.default_info(),(),None)
+
+(* --------------------------------------------------------------------- *)
+
+let find_loop table name =
+  let rec loop = function
+      [] -> raise Not_found
+    | x::xs -> (try Hashtbl.find x name with Not_found -> loop xs) in
+  loop table
+
+let check_table table minus (name,_,info,_,_) =
+  let rl = info.Ast0.line_start in
+  if minus
+  then
+    (try (find_loop table name) := true
+    with
+      Not_found ->
+       (try
+         Hashtbl.find fresh_table name;
+         let (_,name) = name in
+         failwith
+           (Printf.sprintf
+              "%d: unexpected use of a fresh identifier %s" rl name)
+       with Not_found -> ()))
+  else (try (find_loop table name) := true with Not_found -> ())
+
+let get_opt fn = Common.do_option fn
+
+(* --------------------------------------------------------------------- *)
+(* Dots *)
+
+let dots fn d =
+  match Ast0.unwrap d with
+    Ast0.DOTS(x) -> List.iter fn x
+  | Ast0.CIRCLES(x) -> List.iter fn x
+  | Ast0.STARS(x) -> List.iter fn x
+
+(* --------------------------------------------------------------------- *)
+(* Identifier *)
+
+type context = ID | FIELD | FN | GLOBAL
+
+(* heuristic for distinguishing ifdef variables from undeclared metavariables*)
+let is_ifdef name =
+  String.length name > 2 && String.uppercase name = name
+
+let ident context old_metas table minus i =
+  match Ast0.unwrap i with
+    Ast0.Id((name,_,info,_,_) : string Ast0.mcode) ->
+      let rl = info.Ast0.line_start in
+      let err =
+       if List.exists (function x -> x = name) old_metas
+           && (minus || Ast0.get_mcodekind i = Ast0.PLUS)
+       then
+         begin
+           warning
+             (Printf.sprintf
+                "line %d: %s, previously declared as a metavariable, is used as an identifier" rl name);
+             true
+         end
+       else false in
+      (match context with
+       ID ->
+         if not (is_ifdef name) && minus && not err(* warn only once per id *)
+         then
+           warning
+             (Printf.sprintf "line %d: should %s be a metavariable?" rl name)
+      | _ -> ())
+  | Ast0.MetaId(name,_,_) -> check_table table minus name
+  | Ast0.MetaFunc(name,_,_) -> check_table table minus name
+  | Ast0.MetaLocalFunc(name,_,_) -> check_table table minus name
+  | Ast0.OptIdent(_) | Ast0.UniqueIdent(_) ->
+      failwith "unexpected code"
+
+(* --------------------------------------------------------------------- *)
+(* Expression *)
+
+let rec expression context old_metas table minus e =
+  match Ast0.unwrap e with
+    Ast0.Ident(id) ->
+      ident context old_metas table minus id
+  | Ast0.FunCall(fn,lp,args,rp) ->
+      expression FN old_metas table minus fn;
+      dots (expression ID old_metas table minus) args
+  | Ast0.Assignment(left,op,right,_) ->
+      expression context old_metas table minus left;
+      expression ID old_metas table minus right
+  | Ast0.CondExpr(exp1,why,exp2,colon,exp3) ->
+      expression ID old_metas table minus exp1;
+      get_opt (expression ID old_metas table minus) exp2;
+      expression ID old_metas table minus exp3
+  | Ast0.Postfix(exp,op) ->
+      expression ID old_metas table minus exp
+  | Ast0.Infix(exp,op) ->
+      expression ID old_metas table minus exp
+  | Ast0.Unary(exp,op) ->
+      expression ID old_metas table minus exp
+  | Ast0.Binary(left,op,right) ->
+      expression ID old_metas table minus left;
+      expression ID old_metas table minus right
+  | Ast0.Paren(lp,exp,rp) ->
+      expression ID old_metas table minus exp
+  | Ast0.ArrayAccess(exp1,lb,exp2,rb) ->
+      expression ID old_metas table minus exp1;
+      expression ID old_metas table minus exp2
+  | Ast0.RecordAccess(exp,pt,field) ->
+      expression ID old_metas table minus exp;
+      ident FIELD old_metas table minus field
+  | Ast0.RecordPtAccess(exp,ar,field) ->
+      expression ID old_metas table minus exp;
+      ident FIELD old_metas table minus field
+  | Ast0.Cast(lp,ty,rp,exp) ->
+      typeC old_metas table minus ty; expression ID old_metas table minus exp
+  | Ast0.SizeOfExpr(szf,exp) -> expression ID old_metas table minus exp
+  | Ast0.SizeOfType(szf,lp,ty,rp) -> typeC old_metas table minus ty
+  | Ast0.TypeExp(ty) -> typeC old_metas table minus ty
+  | Ast0.MetaExpr(name,_,Some tys,_,_) ->
+      List.iter
+       (function x ->
+         match get_type_name x with
+           Some(ty) -> check_table table minus (promote ty)
+         | None -> ())
+       tys;
+      check_table table minus name
+  | Ast0.MetaExpr(name,_,_,_,_) | Ast0.MetaErr(name,_,_) ->
+      check_table table minus name
+  | Ast0.MetaExprList(name,None,_) ->
+      check_table table minus name
+  | Ast0.MetaExprList(name,Some lenname,_) ->
+      check_table table minus name;
+      check_table table minus lenname
+  | Ast0.DisjExpr(_,exps,_,_) ->
+      List.iter (expression ID old_metas table minus) exps
+  | Ast0.NestExpr(_,exp_dots,_,w,_) ->
+      dots (expression ID old_metas table minus) exp_dots;
+      get_opt (expression ID old_metas table minus) w
+  | Ast0.Edots(_,Some x) | Ast0.Ecircles(_,Some x) | Ast0.Estars(_,Some x) ->
+      expression ID old_metas table minus x
+  | _ -> () (* no metavariable subterms *)
+
+and get_type_name = function
+    Type_cocci.ConstVol(_,ty) | Type_cocci.SignedT(_,Some ty)
+  | Type_cocci.Pointer(ty)
+  | Type_cocci.FunctionPointer(ty) | Type_cocci.Array(ty) -> get_type_name ty
+  | Type_cocci.MetaType(nm,_,_) -> Some nm
+  | _ -> None
+
+(* --------------------------------------------------------------------- *)
+(* Types *)
+
+and typeC old_metas table minus t =
+  match Ast0.unwrap t with
+    Ast0.ConstVol(cv,ty) -> typeC old_metas table minus ty
+  | Ast0.Signed(sgn,ty) ->
+      get_opt (typeC old_metas table minus) ty
+  | Ast0.Pointer(ty,star) -> typeC old_metas table minus ty
+  | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
+      typeC old_metas table minus ty;
+      parameter_list old_metas table minus params
+  | Ast0.FunctionType(ty,lp1,params,rp1) ->
+      get_opt (typeC old_metas table minus) ty;
+      parameter_list old_metas table minus params
+  | Ast0.Array(ty,lb,size,rb) ->
+      typeC old_metas table minus ty;
+      get_opt (expression ID old_metas table minus) size
+  | Ast0.MetaType(name,_) ->
+      check_table table minus name
+  | Ast0.DisjType(_,types,_,_) ->
+      List.iter (typeC old_metas table minus) types
+  | Ast0.EnumName(en,id) -> ident GLOBAL old_metas table minus id
+  | Ast0.StructUnionName(su,Some id) -> ident GLOBAL old_metas table minus id
+  | Ast0.StructUnionDef(ty,lb,decls,rb) ->
+      typeC old_metas table minus ty;
+      dots (declaration GLOBAL old_metas table minus) decls
+  | Ast0.OptType(ty) | Ast0.UniqueType(ty) ->
+      failwith "unexpected code"
+  | _ -> () (* no metavariable subterms *)
+
+(* --------------------------------------------------------------------- *)
+(* Variable declaration *)
+(* Even if the Cocci program specifies a list of declarations, they are
+   split out into multiple declarations of a single variable each. *)
+
+and declaration context old_metas table minus d =
+  match Ast0.unwrap d with
+    Ast0.Init(stg,ty,id,eq,ini,sem) ->
+      (match Ast0.unwrap ini with
+       Ast0.InitExpr exp ->
+         typeC old_metas table minus ty;
+         ident context old_metas table minus id;
+         expression ID old_metas table minus exp
+      |        _ ->
+         (*
+         if minus
+         then
+           failwith "complex initializer specification not allowed in - code"
+         else*)
+           (typeC old_metas table minus ty;
+            ident context old_metas table minus id;
+            initialiser old_metas table minus ini))
+  | Ast0.UnInit(stg,ty,id,sem) ->
+      typeC old_metas table minus ty; ident context old_metas table minus id
+  | Ast0.MacroDecl(name,lp,args,rp,sem) ->
+      ident GLOBAL old_metas table minus name;
+      dots (expression ID old_metas table minus) args
+  | Ast0.TyDecl(ty,sem) -> typeC old_metas table minus ty
+  | Ast0.Typedef(stg,ty,id,sem) ->
+      typeC old_metas table minus ty;
+      typeC old_metas table minus id
+  | Ast0.DisjDecl(_,decls,_,_) ->
+      List.iter (declaration ID old_metas table minus) decls
+  | Ast0.Ddots(_,Some x) -> declaration ID old_metas table minus x
+  | Ast0.Ddots(_,None) -> ()
+  | Ast0.OptDecl(_) | Ast0.UniqueDecl(_) ->
+      failwith "unexpected code"
+
+(* --------------------------------------------------------------------- *)
+(* Initialiser *)
+
+and initialiser old_metas table minus ini =
+  match Ast0.unwrap ini with
+    Ast0.MetaInit(name,_) ->
+      check_table table minus name
+  | Ast0.InitExpr(exp) -> expression ID old_metas table minus exp
+  | Ast0.InitList(lb,initlist,rb) ->
+      dots (initialiser old_metas table minus) initlist
+  | Ast0.InitGccExt(designators,eq,ini) ->
+      List.iter (designator old_metas table minus) designators;
+      initialiser old_metas table minus ini
+  | Ast0.InitGccName(name,eq,ini) ->
+      ident FIELD old_metas table minus name;
+      initialiser old_metas table minus ini
+  | Ast0.Idots(_,Some x) -> initialiser old_metas table minus x
+  | Ast0.OptIni(_) | Ast0.UniqueIni(_) ->
+      failwith "unexpected code"
+  | _ -> () (* no metavariable subterms *)
+
+and designator old_metas table minus = function
+    Ast0.DesignatorField(dot,id) ->
+      ident FIELD old_metas table minus id
+  | Ast0.DesignatorIndex(lb,exp,rb) ->
+      expression ID old_metas table minus exp
+  | Ast0.DesignatorRange(lb,min,dots,max,rb) ->
+      expression ID old_metas table minus min;
+      expression ID old_metas table minus max
+
+and initialiser_list old_metas table minus =
+  dots (initialiser old_metas table minus)
+
+(* --------------------------------------------------------------------- *)
+(* Parameter *)
+
+and parameterTypeDef old_metas table minus param =
+  match Ast0.unwrap param with
+    Ast0.Param(ty,id) ->
+      get_opt (ident ID old_metas table minus) id;
+      typeC old_metas table minus ty
+  | Ast0.MetaParam(name,_) ->
+      check_table table minus name
+  | Ast0.MetaParamList(name,None,_) ->
+      check_table table minus name
+  | Ast0.MetaParamList(name,Some lenname,_) ->
+      check_table table minus name;
+      check_table table minus lenname
+  | _ -> () (* no metavariable subterms *)
+
+and parameter_list old_metas table minus =
+  dots (parameterTypeDef old_metas table minus)
+
+(* --------------------------------------------------------------------- *)
+(* Top-level code *)
+
+and statement old_metas table minus s =
+  match Ast0.unwrap s with
+    Ast0.Decl(_,decl) -> declaration ID old_metas table minus decl
+  | Ast0.Seq(lbrace,body,rbrace) -> dots (statement old_metas table minus) body
+  | Ast0.ExprStatement(exp,sem) -> expression ID old_metas table minus exp
+  | Ast0.IfThen(iff,lp,exp,rp,branch,_) ->
+      expression ID old_metas table minus exp;
+      statement old_metas table minus branch
+  | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,_) ->
+      expression ID old_metas table minus exp;
+      statement old_metas table minus branch1;
+      statement old_metas table minus branch2
+  | Ast0.While(wh,lp,exp,rp,body,_) ->
+      expression ID old_metas table minus exp;
+      statement old_metas table minus body
+  | Ast0.Do(d,body,wh,lp,exp,rp,sem) ->
+      statement old_metas table minus body;
+      expression ID old_metas table minus exp
+  | Ast0.For(fr,lp,exp1,sem1,exp2,sem2,exp3,rp,body,_) ->
+      get_opt (expression ID old_metas table minus) exp1;
+      get_opt (expression ID old_metas table minus) exp2;
+      get_opt (expression ID old_metas table minus) exp3;
+      statement old_metas table minus body
+  | Ast0.Iterator(nm,lp,args,rp,body,_) ->
+      ident GLOBAL old_metas table minus nm;
+      dots (expression ID old_metas table minus) args;
+      statement old_metas table minus body
+  | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) ->
+      expression ID old_metas table minus exp;
+      dots (case_line old_metas table minus) cases
+  | Ast0.ReturnExpr(ret,exp,sem) -> expression ID old_metas table minus exp
+  | Ast0.MetaStmt(name,_) ->     check_table table minus name
+  | Ast0.MetaStmtList(name,_) -> check_table table minus name
+  | Ast0.Exp(exp) -> expression ID old_metas table minus exp
+  | Ast0.TopExp(exp) -> expression ID old_metas table minus exp
+  | Ast0.Ty(ty) -> typeC old_metas table minus ty
+  | Ast0.TopInit(init) -> initialiser old_metas table minus init
+  | Ast0.Disj(_,rule_elem_dots_list,_,_) ->
+      List.iter (dots (statement old_metas table minus)) rule_elem_dots_list
+  | Ast0.Nest(_,rule_elem_dots,_,w,_) ->
+      dots (statement old_metas table minus) rule_elem_dots;
+      List.iter (whencode (dots (statement old_metas table minus))
+                  (statement old_metas table minus)
+                  (expression ID old_metas table minus))
+       w
+  | Ast0.Dots(_,x) | Ast0.Circles(_,x) | Ast0.Stars(_,x) ->
+      List.iter
+       (whencode (dots (statement old_metas table minus))
+          (statement old_metas table minus)
+          (expression ID old_metas table minus)) x
+  | Ast0.FunDecl(_,fi,name,lp,params,rp,lbrace,body,rbrace) ->
+      ident FN old_metas table minus name;
+      List.iter (fninfo old_metas table minus) fi;
+      parameter_list old_metas table minus params;
+      dots (statement old_metas table minus) body
+  | Ast0.Include(inc,s) -> () (* no metavariables possible *)
+  | Ast0.Define(def,id,_,body) ->
+      ident GLOBAL old_metas table minus id;
+      dots (statement old_metas table minus) body
+  | Ast0.Goto(_,i,_) -> ident ID old_metas table minus i
+  | _ -> () (* no metavariable subterms *)
+
+and fninfo old_metas table minus = function
+    Ast0.FStorage(stg) -> ()
+  | Ast0.FType(ty) -> typeC old_metas table minus ty
+  | Ast0.FInline(inline) -> ()
+  | Ast0.FAttr(attr) -> ()
+
+and whencode notfn alwaysfn expression = function
+    Ast0.WhenNot a -> notfn a
+  | Ast0.WhenAlways a -> alwaysfn a
+  | Ast0.WhenModifier(_) -> ()
+  | Ast0.WhenNotTrue a -> expression a
+  | Ast0.WhenNotFalse a -> expression a
+
+and case_line old_metas table minus c =
+  match Ast0.unwrap c with
+    Ast0.Default(def,colon,code) ->
+      dots (statement old_metas table minus) code
+  | Ast0.Case(case,exp,colon,code) ->
+      dots (statement old_metas table minus) code
+  | Ast0.OptCase(case) -> failwith "unexpected code"
+
+(* --------------------------------------------------------------------- *)
+(* Rules *)
+
+let top_level old_metas table minus t =
+  match Ast0.unwrap t with
+    Ast0.DECL(stmt) -> statement old_metas table minus stmt
+  | Ast0.CODE(stmt_dots) -> dots (statement old_metas table minus) stmt_dots
+  | Ast0.ERRORWORDS(exps) ->
+      List.iter (expression FN old_metas table minus) exps
+  | _ -> () (* no metavariables possible *)
+
+let rule old_metas table minus rules =
+  List.iter (top_level old_metas table minus) rules
+
+(* --------------------------------------------------------------------- *)
+
+let positions table rules =
+  let mcode x =
+    match Ast0.get_pos x with
+      Ast0.MetaPos(name,constraints,_) ->
+       let pos = Ast0.unwrap_mcode name in
+       (find_loop table pos) := true
+    | _ -> () in
+  let option_default = () in
+  let bind x y = () in
+  let donothing r k e = k e in
+  let fn =
+    V0.combiner bind option_default
+      mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+      donothing donothing donothing donothing donothing donothing
+      donothing donothing donothing donothing donothing donothing donothing
+      donothing donothing in
+
+  List.iter fn.V0.combiner_top_level rules
+
+let dup_positions rules =
+  let mcode x =
+    match Ast0.get_pos x with
+      Ast0.MetaPos(name,constraints,_) ->
+       let pos = Ast0.unwrap_mcode name in [pos]
+    | _ -> [] in
+  let option_default = [] in
+  let bind x y = x@y in
+
+  (* Case for everything that has a disj.
+     Note, no positions on ( | ) of a disjunction, so no need to recurse on
+     these. *)
+
+  let expression r k e =
+    match Ast0.unwrap e with
+      Ast0.DisjExpr(_,explist,_,_) ->
+       List.fold_left Common.union_set option_default
+         (List.map r.V0.combiner_expression explist)
+    | _ -> k e in
+
+  let typeC r k e = (* not sure relevent because "only after iso" *)
+    match Ast0.unwrap e with
+      Ast0.DisjType(_,types,_,_) ->
+       List.fold_left Common.union_set option_default
+         (List.map r.V0.combiner_typeC types)
+    | _ -> k e in
+
+  let declaration r k e =
+    match Ast0.unwrap e with
+      Ast0.DisjDecl(_,decls,_,_) ->
+       List.fold_left Common.union_set option_default
+         (List.map r.V0.combiner_declaration decls)
+    | _ -> k e in
+
+  let statement r k e =
+    match Ast0.unwrap e with
+      Ast0.Disj(_,stmts,_,_) ->
+       List.fold_left Common.union_set option_default
+         (List.map r.V0.combiner_statement_dots stmts)
+    | _ -> k e in
+
+  let donothing r k e = k e in
+  let fn =
+    V0.combiner bind option_default
+      mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+      donothing donothing donothing donothing donothing donothing
+      donothing expression typeC donothing donothing declaration statement
+      donothing donothing in
+
+  let res =
+    List.sort compare
+      (List.fold_left Common.union_set option_default
+        (List.map fn.V0.combiner_top_level rules)) in
+  let rec loop = function
+      [] | [_] -> ()
+    | ((rule,name) as x)::y::_ when x = y ->
+       failwith (Printf.sprintf "duplicate use of %s.%s" rule name)
+    | _::xs -> loop xs in
+  loop res
+
+(* --------------------------------------------------------------------- *)
+
+let make_table l =
+  let table =
+    (Hashtbl.create(List.length l) :
+       ((string * string), bool ref) Hashtbl.t) in
+  List.iter
+    (function x -> Hashtbl.add table (Ast.get_meta_name x) (ref false)) l;
+  table
+
+let add_to_fresh_table l =
+  List.iter
+    (function x ->
+      let name = Ast.get_meta_name x in Hashtbl.replace fresh_table name ())
+    l
+
+let check_all_marked rname err table after_err =
+  Hashtbl.iter
+    (function name ->
+      function (cell) ->
+       if not (!cell)
+       then
+         let (_,name) = name in
+         warning
+           (Printf.sprintf "%s: %s %s not used %s" rname err name after_err))
+    table
+
+let check_meta rname old_metas inherited_metavars metavars minus plus =
+  let old_metas =
+    List.map (function (_,x) -> x) (List.map Ast.get_meta_name old_metas) in
+  let (fresh,other) =
+    List.partition (function Ast.MetaFreshIdDecl(_,_) -> true | _ -> false)
+      metavars in
+  let (err,other) =
+    List.partition (function Ast.MetaErrDecl(_,_) -> true | _ -> false)
+      other in
+  let (ierr,iother) =
+    List.partition (function Ast.MetaErrDecl(_,_) -> true | _ -> false)
+      inherited_metavars in
+  let fresh_table = make_table fresh in
+  let err_table = make_table (err@ierr) in
+  let other_table = make_table other in
+  let iother_table = make_table iother in
+  add_to_fresh_table fresh;
+  rule old_metas [iother_table;other_table;err_table] true minus;
+  positions [iother_table;other_table] minus;
+  dup_positions minus;
+  check_all_marked rname "metavariable" other_table "in the - or context code";
+  rule old_metas [iother_table;fresh_table;err_table] false plus;
+  check_all_marked rname "inherited metavariable" iother_table
+    "in the -, +, or context code";
+  check_all_marked rname "metavariable" fresh_table "in the + code";
+  check_all_marked rname "error metavariable" err_table ""
diff --git a/parsing_cocci/.#compute_lines.ml.1.92 b/parsing_cocci/.#compute_lines.ml.1.92
new file mode 100644 (file)
index 0000000..d93ed9e
--- /dev/null
@@ -0,0 +1,771 @@
+(*
+* Copyright 2005-2009, 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.
+*)
+
+
+(* Computes starting and ending logical lines for statements and
+expressions.  every node gets an index as well. *)
+
+module Ast0 = Ast0_cocci
+module Ast = Ast_cocci
+
+(* --------------------------------------------------------------------- *)
+(* Result *)
+
+let mkres x e left right =
+  let lstart = Ast0.get_info left in
+  let lend = Ast0.get_info right in
+  let info =
+    { Ast0.line_start = lstart.Ast0.line_start;
+      Ast0.line_end = lend.Ast0.line_end;
+      Ast0.logical_start = lstart.Ast0.logical_start;
+      Ast0.logical_end = lend.Ast0.logical_end;
+      Ast0.attachable_start = lstart.Ast0.attachable_start;
+      Ast0.attachable_end = lend.Ast0.attachable_end;
+      Ast0.mcode_start = lstart.Ast0.mcode_start;
+      Ast0.mcode_end = lend.Ast0.mcode_end;
+      Ast0.column = lstart.Ast0.column;
+      Ast0.offset = lstart.Ast0.offset;
+      (* only for tokens, not inherited upwards *)
+      Ast0.strings_before = []; Ast0.strings_after = []} in
+  {x with Ast0.node = e; Ast0.info = info}
+
+let mkmultires x e left right (astart,start_mcodes) (aend,end_mcodes) =
+  let lstart = Ast0.get_info left in
+  let lend = Ast0.get_info right in
+  let info =
+    { Ast0.line_start = lstart.Ast0.line_start;
+      Ast0.line_end = lend.Ast0.line_end;
+      Ast0.logical_start = lstart.Ast0.logical_start;
+      Ast0.logical_end = lend.Ast0.logical_end;
+      Ast0.attachable_start = astart;
+      Ast0.attachable_end = aend;
+      Ast0.mcode_start = start_mcodes;
+      Ast0.mcode_end = end_mcodes;
+      Ast0.column = lstart.Ast0.column;
+      Ast0.offset = lstart.Ast0.offset;
+      (* only for tokens, not inherited upwards *)
+      Ast0.strings_before = []; Ast0.strings_after = [] } in
+  {x with Ast0.node = e; Ast0.info = info}
+
+(* --------------------------------------------------------------------- *)
+
+let get_option fn = function
+    None -> None
+  | Some x -> Some (fn x)
+
+(* --------------------------------------------------------------------- *)
+(* --------------------------------------------------------------------- *)
+(* Mcode *)
+
+let promote_mcode (_,_,info,mcodekind,_) =
+  let new_info =
+    {info with
+      Ast0.mcode_start = [mcodekind]; Ast0.mcode_end = [mcodekind]} in
+  {(Ast0.wrap ()) with Ast0.info = new_info; Ast0.mcodekind = ref mcodekind}
+
+let promote_mcode_plus_one (_,_,info,mcodekind,_) =
+  let new_info =
+    {info with
+      Ast0.line_start = info.Ast0.line_start + 1;
+      Ast0.logical_start = info.Ast0.logical_start + 1;
+      Ast0.line_end = info.Ast0.line_end + 1;
+      Ast0.logical_end = info.Ast0.logical_end + 1;
+      Ast0.mcode_start = [mcodekind]; Ast0.mcode_end = [mcodekind]} in
+  {(Ast0.wrap ()) with Ast0.info = new_info; Ast0.mcodekind = ref mcodekind}
+
+let promote_to_statement stm mcodekind =
+  let info = Ast0.get_info stm in
+  let new_info =
+    {info with
+      Ast0.logical_start = info.Ast0.logical_end;
+      Ast0.line_start = info.Ast0.line_end;
+      Ast0.mcode_start = [mcodekind]; Ast0.mcode_end = [mcodekind];
+      Ast0.attachable_start = true; Ast0.attachable_end = true} in
+  {(Ast0.wrap ()) with Ast0.info = new_info; Ast0.mcodekind = ref mcodekind}
+
+let promote_to_statement_start stm mcodekind =
+  let info = Ast0.get_info stm in
+  let new_info =
+    {info with
+      Ast0.logical_end = info.Ast0.logical_start;
+      Ast0.line_end = info.Ast0.line_start;
+      Ast0.mcode_start = [mcodekind]; Ast0.mcode_end = [mcodekind];
+      Ast0.attachable_start = true; Ast0.attachable_end = true} in
+  {(Ast0.wrap ()) with Ast0.info = new_info; Ast0.mcodekind = ref mcodekind}
+
+(* mcode is good by default *)
+let bad_mcode (t,a,info,mcodekind,pos) =
+  let new_info =
+    {info with Ast0.attachable_start = false; Ast0.attachable_end = false} in
+  (t,a,new_info,mcodekind,pos)
+
+let get_all_start_info l =
+  (List.for_all (function x -> (Ast0.get_info x).Ast0.attachable_start) l,
+   List.concat (List.map (function x -> (Ast0.get_info x).Ast0.mcode_start) l))
+
+let get_all_end_info l =
+  (List.for_all (function x -> (Ast0.get_info x).Ast0.attachable_end) l,
+   List.concat (List.map (function x -> (Ast0.get_info x).Ast0.mcode_end) l))
+
+(* --------------------------------------------------------------------- *)
+(* Dots *)
+
+(* for the logline classification and the mcode field, on both sides, skip
+over initial minus dots, as they don't contribute anything *)
+let dot_list is_dots fn = function
+    [] -> failwith "dots should not be empty"
+  | l ->
+      let get_node l fn =
+       let first = List.hd l in
+       let chosen =
+         match (is_dots first, l) with (true,_::x::_) -> x | _ -> first in
+       (* get the logline decorator and the mcodekind of the chosen node *)
+       fn (Ast0.get_info chosen) in
+      let forward = List.map fn l in
+      let backward = List.rev forward in
+      let (first_attachable,first_mcode) =
+       get_node forward
+         (function x -> (x.Ast0.attachable_start,x.Ast0.mcode_start)) in
+      let (last_attachable,last_mcode) =
+       get_node backward
+         (function x -> (x.Ast0.attachable_end,x.Ast0.mcode_end)) in
+      let first = List.hd forward in
+      let last = List.hd backward in
+      let first_info =
+       { (Ast0.get_info first) with
+         Ast0.attachable_start = first_attachable;
+         Ast0.mcode_start = first_mcode } in
+      let last_info =
+       { (Ast0.get_info last) with
+         Ast0.attachable_end = last_attachable;
+         Ast0.mcode_end = last_mcode } in
+      let first = Ast0.set_info first first_info in
+      let last = Ast0.set_info last last_info in
+      (forward,first,last)
+
+let dots is_dots prev fn d =
+  match (prev,Ast0.unwrap d) with
+    (Some prev,Ast0.DOTS([])) ->
+      mkres d (Ast0.DOTS []) prev prev
+  | (None,Ast0.DOTS([])) ->
+      Ast0.set_info d
+       {(Ast0.get_info d)
+       with Ast0.attachable_start = false; Ast0.attachable_end = false}
+  | (_,Ast0.DOTS(x)) ->
+      let (l,lstart,lend) = dot_list is_dots fn x in
+      mkres d (Ast0.DOTS l) lstart lend
+  | (_,Ast0.CIRCLES(x)) ->
+      let (l,lstart,lend) = dot_list is_dots fn x in
+      mkres d (Ast0.CIRCLES l) lstart lend
+  | (_,Ast0.STARS(x)) ->
+      let (l,lstart,lend) = dot_list is_dots fn x in
+      mkres d (Ast0.STARS l) lstart lend
+
+(* --------------------------------------------------------------------- *)
+(* Identifier *)
+
+let rec ident i =
+  match Ast0.unwrap i with
+    Ast0.Id(name) as ui ->
+      let name = promote_mcode name in mkres i ui name name
+  | Ast0.MetaId(name,_,_)
+  | Ast0.MetaFunc(name,_,_) | Ast0.MetaLocalFunc(name,_,_) as ui ->
+      let name = promote_mcode name in mkres i ui name name
+  | Ast0.OptIdent(id) ->
+      let id = ident id in mkres i (Ast0.OptIdent(id)) id id
+  | Ast0.UniqueIdent(id) ->
+      let id = ident id in mkres i (Ast0.UniqueIdent(id)) id id
+
+(* --------------------------------------------------------------------- *)
+(* Expression *)
+
+let is_exp_dots e =
+  match Ast0.unwrap e with
+    Ast0.Edots(_,_) | Ast0.Ecircles(_,_) | Ast0.Estars(_,_) -> true
+  | _ -> false
+
+let rec expression e =
+  match Ast0.unwrap e with
+    Ast0.Ident(id) ->
+      let id = ident id in
+      mkres e (Ast0.Ident(id)) id id
+  | Ast0.Constant(const) as ue ->
+      let ln = promote_mcode const in
+      mkres e ue ln ln
+  | Ast0.FunCall(fn,lp,args,rp) ->
+      let fn = expression fn in
+      let args = dots is_exp_dots (Some(promote_mcode lp)) expression args in
+      mkres e (Ast0.FunCall(fn,lp,args,rp)) fn (promote_mcode rp)
+  | Ast0.Assignment(left,op,right,simple) ->
+      let left = expression left in
+      let right = expression right in
+      mkres e (Ast0.Assignment(left,op,right,simple)) left right
+  | Ast0.CondExpr(exp1,why,exp2,colon,exp3) ->
+      let exp1 = expression exp1 in
+      let exp2 = get_option expression exp2 in
+      let exp3 = expression exp3 in
+      mkres e (Ast0.CondExpr(exp1,why,exp2,colon,exp3)) exp1 exp3
+  | Ast0.Postfix(exp,op) ->
+      let exp = expression exp in
+      mkres e (Ast0.Postfix(exp,op)) exp (promote_mcode op)
+  | Ast0.Infix(exp,op) ->
+      let exp = expression exp in
+      mkres e (Ast0.Infix(exp,op)) (promote_mcode op) exp
+  | Ast0.Unary(exp,op) ->
+      let exp = expression exp in
+      mkres e (Ast0.Unary(exp,op)) (promote_mcode op) exp
+  | Ast0.Binary(left,op,right) ->
+      let left = expression left in
+      let right = expression right in
+      mkres e (Ast0.Binary(left,op,right)) left right
+  | Ast0.Nested(left,op,right) ->
+      let left = expression left in
+      let right = expression right in
+      mkres e (Ast0.Nested(left,op,right)) left right
+  | Ast0.Paren(lp,exp,rp) ->
+      mkres e (Ast0.Paren(lp,expression exp,rp))
+       (promote_mcode lp) (promote_mcode rp)
+  | Ast0.ArrayAccess(exp1,lb,exp2,rb) ->
+      let exp1 = expression exp1 in
+      let exp2 = expression exp2 in
+      mkres e (Ast0.ArrayAccess(exp1,lb,exp2,rb)) exp1 (promote_mcode rb)
+  | Ast0.RecordAccess(exp,pt,field) ->
+      let exp = expression exp in
+      let field = ident field in
+      mkres e (Ast0.RecordAccess(exp,pt,field)) exp field
+  | Ast0.RecordPtAccess(exp,ar,field) ->
+      let exp = expression exp in
+      let field = ident field in
+      mkres e (Ast0.RecordPtAccess(exp,ar,field)) exp field
+  | Ast0.Cast(lp,ty,rp,exp) ->
+      let exp = expression exp in
+      mkres e (Ast0.Cast(lp,typeC ty,rp,exp)) (promote_mcode lp) exp
+  | Ast0.SizeOfExpr(szf,exp) ->
+      let exp = expression exp in
+      mkres e (Ast0.SizeOfExpr(szf,exp)) (promote_mcode szf) exp
+  | Ast0.SizeOfType(szf,lp,ty,rp) ->
+      mkres e (Ast0.SizeOfType(szf,lp,typeC ty,rp))
+        (promote_mcode szf)  (promote_mcode rp)
+  | Ast0.TypeExp(ty) ->
+      let ty = typeC ty in mkres e (Ast0.TypeExp(ty)) ty ty
+  | Ast0.MetaErr(name,_,_) | Ast0.MetaExpr(name,_,_,_,_)
+  | Ast0.MetaExprList(name,_,_) as ue ->
+      let ln = promote_mcode name in mkres e ue ln ln
+  | Ast0.EComma(cm) ->
+      let cm = bad_mcode cm in
+      let ln = promote_mcode cm in
+      mkres e (Ast0.EComma(cm)) ln ln
+  | Ast0.DisjExpr(starter,exps,mids,ender) ->
+      let starter = bad_mcode starter in
+      let exps = List.map expression exps in
+      let mids = List.map bad_mcode mids in
+      let ender = bad_mcode ender in
+      mkmultires e (Ast0.DisjExpr(starter,exps,mids,ender))
+       (promote_mcode starter) (promote_mcode ender)
+       (get_all_start_info exps) (get_all_end_info exps)
+  | Ast0.NestExpr(starter,exp_dots,ender,whencode,multi) ->
+      let exp_dots = dots is_exp_dots None expression exp_dots in
+      let starter = bad_mcode starter in
+      let ender = bad_mcode ender in
+      mkres e (Ast0.NestExpr(starter,exp_dots,ender,whencode,multi))
+       (promote_mcode starter) (promote_mcode ender)
+  | Ast0.Edots(dots,whencode) ->
+      let dots = bad_mcode dots in
+      let ln = promote_mcode dots in
+      mkres e (Ast0.Edots(dots,whencode)) ln ln
+  | Ast0.Ecircles(dots,whencode) ->
+      let dots = bad_mcode dots in
+      let ln = promote_mcode dots in
+      mkres e (Ast0.Ecircles(dots,whencode)) ln ln
+  | Ast0.Estars(dots,whencode) ->
+      let dots = bad_mcode dots in
+      let ln = promote_mcode dots in
+      mkres e (Ast0.Estars(dots,whencode)) ln ln
+  | Ast0.OptExp(exp) ->
+      let exp = expression exp in
+      mkres e (Ast0.OptExp(exp)) exp exp
+  | Ast0.UniqueExp(exp) ->
+      let exp = expression exp in
+      mkres e (Ast0.UniqueExp(exp)) exp exp
+
+and expression_dots x = dots is_exp_dots None expression x
+
+(* --------------------------------------------------------------------- *)
+(* Types *)
+
+and typeC t =
+  match Ast0.unwrap t with
+    Ast0.ConstVol(cv,ty) ->
+      let ty = typeC ty in
+      mkres t (Ast0.ConstVol(cv,ty)) (promote_mcode cv) ty
+  | Ast0.BaseType(ty,strings) as ut ->
+      let first = List.hd strings in
+      let last = List.hd (List.rev strings) in
+      mkres t ut (promote_mcode first) (promote_mcode last)
+  | Ast0.Signed(sgn,None) as ut ->
+      mkres t ut (promote_mcode sgn) (promote_mcode sgn)
+  | Ast0.Signed(sgn,Some ty) ->
+      let ty = typeC ty in
+      mkres t (Ast0.Signed(sgn,Some ty)) (promote_mcode sgn) ty
+  | Ast0.Pointer(ty,star) ->
+      let ty = typeC ty in
+      mkres t (Ast0.Pointer(ty,star)) ty (promote_mcode star)
+  | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
+      let ty = typeC ty in
+      let params = parameter_list (Some(promote_mcode lp2)) params in
+      mkres t (Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2))
+       ty (promote_mcode rp2)
+  | Ast0.FunctionType(Some ty,lp1,params,rp1) ->
+      let ty = typeC ty in
+      let params = parameter_list (Some(promote_mcode lp1)) params in
+      let res = Ast0.FunctionType(Some ty,lp1,params,rp1) in
+      mkres t res ty (promote_mcode rp1)
+  | Ast0.FunctionType(None,lp1,params,rp1) ->
+      let params = parameter_list (Some(promote_mcode lp1)) params in
+      let res = Ast0.FunctionType(None,lp1,params,rp1) in
+      mkres t res (promote_mcode lp1) (promote_mcode rp1)
+  | Ast0.Array(ty,lb,size,rb) ->
+      let ty = typeC ty in
+      mkres t (Ast0.Array(ty,lb,get_option expression size,rb))
+       ty (promote_mcode rb)
+  | Ast0.EnumName(kind,name) ->
+      let name = ident name in
+      mkres t (Ast0.EnumName(kind,name)) (promote_mcode kind) name
+  | Ast0.StructUnionName(kind,Some name) ->
+      let name = ident name in
+      mkres t (Ast0.StructUnionName(kind,Some name)) (promote_mcode kind) name
+  | Ast0.StructUnionName(kind,None) ->
+      let mc = promote_mcode kind in
+      mkres t (Ast0.StructUnionName(kind,None)) mc mc
+  | Ast0.StructUnionDef(ty,lb,decls,rb) ->
+      let ty = typeC ty in
+      let decls =
+       dots is_decl_dots (Some(promote_mcode lb)) declaration decls in
+      mkres t (Ast0.StructUnionDef(ty,lb,decls,rb)) ty (promote_mcode rb)
+  | Ast0.TypeName(name) as ut ->
+      let ln = promote_mcode name in mkres t ut ln ln
+  | Ast0.MetaType(name,_) as ut ->
+      let ln = promote_mcode name in mkres t ut ln ln
+  | Ast0.DisjType(starter,types,mids,ender) ->
+      let starter = bad_mcode starter in
+      let types = List.map typeC types in
+      let mids = List.map bad_mcode mids in
+      let ender = bad_mcode ender in
+      mkmultires t (Ast0.DisjType(starter,types,mids,ender))
+       (promote_mcode starter) (promote_mcode ender)
+       (get_all_start_info types) (get_all_end_info types)
+  | Ast0.OptType(ty) ->
+      let ty = typeC ty in mkres t (Ast0.OptType(ty)) ty ty
+  | Ast0.UniqueType(ty) ->
+      let ty = typeC ty in mkres t (Ast0.UniqueType(ty)) ty ty
+
+(* --------------------------------------------------------------------- *)
+(* Variable declaration *)
+(* Even if the Cocci program specifies a list of declarations, they are
+   split out into multiple declarations of a single variable each. *)
+
+and is_decl_dots s =
+  match Ast0.unwrap s with
+    Ast0.Ddots(_,_) -> true
+  | _ -> false
+
+and declaration d =
+  match Ast0.unwrap d with
+    Ast0.Init(stg,ty,id,eq,exp,sem) ->
+      let ty = typeC ty in
+      let id = ident id in
+      let exp = initialiser exp in
+      (match stg with
+       None ->
+         mkres d (Ast0.Init(stg,ty,id,eq,exp,sem)) ty (promote_mcode sem)
+      | Some x ->
+         mkres d (Ast0.Init(stg,ty,id,eq,exp,sem))
+           (promote_mcode x) (promote_mcode sem))
+  | Ast0.UnInit(stg,ty,id,sem) ->
+      let ty = typeC ty in
+      let id = ident id in
+      (match stg with
+       None ->
+         mkres d (Ast0.UnInit(stg,ty,id,sem)) ty (promote_mcode sem)
+      | Some x ->
+         mkres d (Ast0.UnInit(stg,ty,id,sem))
+           (promote_mcode x) (promote_mcode sem))
+  | Ast0.MacroDecl(name,lp,args,rp,sem) ->
+      let name = ident name in
+      let args = dots is_exp_dots (Some(promote_mcode lp)) expression args in
+      mkres d (Ast0.MacroDecl(name,lp,args,rp,sem)) name (promote_mcode sem)
+  | Ast0.TyDecl(ty,sem) ->
+      let ty = typeC ty in
+      mkres d (Ast0.TyDecl(ty,sem)) ty (promote_mcode sem)
+  | Ast0.Typedef(stg,ty,id,sem) ->
+      let ty = typeC ty in
+      let id = typeC id in
+      mkres d (Ast0.Typedef(stg,ty,id,sem))
+       (promote_mcode stg) (promote_mcode sem)
+  | Ast0.DisjDecl(starter,decls,mids,ender) ->
+      let starter = bad_mcode starter in
+      let decls = List.map declaration decls in
+      let mids = List.map bad_mcode mids in
+      let ender = bad_mcode ender in
+      mkmultires d (Ast0.DisjDecl(starter,decls,mids,ender))
+       (promote_mcode starter) (promote_mcode ender)
+       (get_all_start_info decls) (get_all_end_info decls)
+  | Ast0.Ddots(dots,whencode) ->
+      let dots = bad_mcode dots in
+      let ln = promote_mcode dots in
+      mkres d (Ast0.Ddots(dots,whencode)) ln ln
+  | Ast0.OptDecl(decl) ->
+      let decl = declaration decl in
+      mkres d (Ast0.OptDecl(declaration decl)) decl decl
+  | Ast0.UniqueDecl(decl) ->
+      let decl = declaration decl in
+      mkres d (Ast0.UniqueDecl(declaration decl)) decl decl
+
+(* --------------------------------------------------------------------- *)
+(* Initializer *)
+
+and is_init_dots i =
+  match Ast0.unwrap i with
+    Ast0.Idots(_,_) -> true
+  | _ -> false
+
+and initialiser i =
+  match Ast0.unwrap i with
+    Ast0.MetaInit(name,_) as ut ->
+      let ln = promote_mcode name in mkres i ut ln ln
+  | Ast0.InitExpr(exp) ->
+      let exp = expression exp in
+      mkres i (Ast0.InitExpr(exp)) exp exp
+  | Ast0.InitList(lb,initlist,rb) ->
+      let initlist =
+       dots is_init_dots (Some(promote_mcode lb)) initialiser initlist in
+      mkres i (Ast0.InitList(lb,initlist,rb))
+       (promote_mcode lb) (promote_mcode rb)
+  | Ast0.InitGccExt(designators,eq,ini) ->
+      let (delims,designators) = (* non empty due to parsing *)
+       List.split (List.map designator designators) in
+      let ini = initialiser ini in
+      mkres i (Ast0.InitGccExt(designators,eq,ini))
+       (promote_mcode (List.hd delims)) ini
+  | Ast0.InitGccName(name,eq,ini) ->
+      let name = ident name in
+      let ini = initialiser ini in
+      mkres i (Ast0.InitGccName(name,eq,ini)) name ini
+  | Ast0.IComma(cm) as up ->
+      let ln = promote_mcode cm in mkres i up ln ln
+  | Ast0.Idots(dots,whencode) ->
+      let dots = bad_mcode dots in
+      let ln = promote_mcode dots in
+      mkres i (Ast0.Idots(dots,whencode)) ln ln
+  | Ast0.OptIni(ini) ->
+      let ini = initialiser ini in
+      mkres i (Ast0.OptIni(ini)) ini ini
+  | Ast0.UniqueIni(ini) ->
+      let ini = initialiser ini in
+      mkres i (Ast0.UniqueIni(ini)) ini ini
+
+and designator = function
+    Ast0.DesignatorField(dot,id) ->
+      (dot,Ast0.DesignatorField(dot,ident id))
+  | Ast0.DesignatorIndex(lb,exp,rb) ->
+      (lb,Ast0.DesignatorIndex(lb,expression exp,rb))
+  | Ast0.DesignatorRange(lb,min,dots,max,rb) ->
+      (lb,Ast0.DesignatorRange(lb,expression min,dots,expression max,rb))
+
+and initialiser_list prev = dots is_init_dots prev initialiser
+
+(* for export *)
+and initialiser_dots x = dots is_init_dots None initialiser x
+
+(* --------------------------------------------------------------------- *)
+(* Parameter *)
+
+and is_param_dots p =
+  match Ast0.unwrap p with
+    Ast0.Pdots(_) | Ast0.Pcircles(_) -> true
+  | _ -> false
+
+and parameterTypeDef p =
+  match Ast0.unwrap p with
+    Ast0.VoidParam(ty) ->
+      let ty = typeC ty in mkres p (Ast0.VoidParam(ty)) ty ty
+  | Ast0.Param(ty,Some id) ->
+      let id = ident id in
+      let ty = typeC ty in mkres p (Ast0.Param(ty,Some id)) ty id
+  | Ast0.Param(ty,None) ->
+      let ty = typeC ty in mkres p (Ast0.Param(ty,None)) ty ty
+  | Ast0.MetaParam(name,_) as up ->
+      let ln = promote_mcode name in mkres p up ln ln
+  | Ast0.MetaParamList(name,_,_) as up ->
+      let ln = promote_mcode name in mkres p up ln ln
+  | Ast0.PComma(cm) ->
+      let cm = bad_mcode cm in
+      let ln = promote_mcode cm in
+      mkres p (Ast0.PComma(cm)) ln ln
+  | Ast0.Pdots(dots) ->
+      let dots = bad_mcode dots in
+      let ln = promote_mcode dots in
+      mkres p (Ast0.Pdots(dots)) ln ln
+  | Ast0.Pcircles(dots) ->
+      let dots = bad_mcode dots in
+      let ln = promote_mcode dots in
+      mkres p (Ast0.Pcircles(dots)) ln ln
+  | Ast0.OptParam(param) ->
+      let res = parameterTypeDef param in
+      mkres p (Ast0.OptParam(res)) res res
+  | Ast0.UniqueParam(param) ->
+      let res = parameterTypeDef param in
+      mkres p (Ast0.UniqueParam(res)) res res
+
+and parameter_list prev = dots is_param_dots prev parameterTypeDef
+
+(* for export *)
+let parameter_dots x = dots is_param_dots None parameterTypeDef x
+
+(* --------------------------------------------------------------------- *)
+(* Top-level code *)
+
+let is_stm_dots s =
+  match Ast0.unwrap s with
+    Ast0.Dots(_,_) | Ast0.Circles(_,_) | Ast0.Stars(_,_) -> true
+  | _ -> false
+
+let rec statement s =
+  let res =
+    match Ast0.unwrap s with
+      Ast0.Decl((_,bef),decl) ->
+       let decl = declaration decl in
+       let left = promote_to_statement_start decl bef in
+       mkres s (Ast0.Decl((Ast0.get_info left,bef),decl)) decl decl
+    | Ast0.Seq(lbrace,body,rbrace) ->
+       let body =
+         dots is_stm_dots (Some(promote_mcode lbrace)) statement body in
+       mkres s (Ast0.Seq(lbrace,body,rbrace))
+         (promote_mcode lbrace) (promote_mcode rbrace)
+    | Ast0.ExprStatement(exp,sem) ->
+       let exp = expression exp in
+       mkres s (Ast0.ExprStatement(exp,sem)) exp (promote_mcode sem)
+    | Ast0.IfThen(iff,lp,exp,rp,branch,(_,aft)) ->
+       let exp = expression exp in
+       let branch = statement branch in
+       let right = promote_to_statement branch aft in
+       mkres s (Ast0.IfThen(iff,lp,exp,rp,branch,(Ast0.get_info right,aft)))
+         (promote_mcode iff) right
+    | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,(_,aft)) ->
+       let exp = expression exp in
+       let branch1 = statement branch1 in
+       let branch2 = statement branch2 in
+       let right = promote_to_statement branch2 aft in
+       mkres s
+         (Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,
+           (Ast0.get_info right,aft)))
+         (promote_mcode iff) right
+    | Ast0.While(wh,lp,exp,rp,body,(_,aft)) ->
+       let exp = expression exp in
+       let body = statement body in
+       let right = promote_to_statement body aft in
+       mkres s (Ast0.While(wh,lp,exp,rp,body,(Ast0.get_info right,aft)))
+         (promote_mcode wh) right
+    | Ast0.Do(d,body,wh,lp,exp,rp,sem) ->
+       let body = statement body in
+       let exp = expression exp in
+       mkres s (Ast0.Do(d,body,wh,lp,exp,rp,sem))
+         (promote_mcode d) (promote_mcode sem)
+    | Ast0.For(fr,lp,exp1,sem1,exp2,sem2,exp3,rp,body,(_,aft)) ->
+       let exp1 = get_option expression exp1 in
+       let exp2 = get_option expression exp2 in
+       let exp3 = get_option expression exp3 in
+       let body = statement body in
+       let right = promote_to_statement body aft in
+       mkres s (Ast0.For(fr,lp,exp1,sem1,exp2,sem2,exp3,rp,body,
+                         (Ast0.get_info right,aft)))
+         (promote_mcode fr) right
+    | Ast0.Iterator(nm,lp,args,rp,body,(_,aft)) ->
+       let nm = ident nm in
+       let args = dots is_exp_dots (Some(promote_mcode lp)) expression args in
+       let body = statement body in
+       let right = promote_to_statement body aft in
+       mkres s (Ast0.Iterator(nm,lp,args,rp,body,(Ast0.get_info right,aft)))
+         nm right
+    | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) ->
+       let exp = expression exp in
+       let cases =
+         dots (function _ -> false) (Some(promote_mcode lb)) case_line cases in
+       mkres s
+         (Ast0.Switch(switch,lp,exp,rp,lb,cases,rb))
+         (promote_mcode switch) (promote_mcode rb)
+    | Ast0.Break(br,sem) as us ->
+       mkres s us (promote_mcode br) (promote_mcode sem)
+    | Ast0.Continue(cont,sem) as us ->
+       mkres s us (promote_mcode cont) (promote_mcode sem)
+    | Ast0.Label(l,dd) ->
+       let l = ident l in
+       mkres s (Ast0.Label(l,dd)) l (promote_mcode dd)
+    | Ast0.Goto(goto,id,sem) ->
+       let id = ident id in
+       mkres s (Ast0.Goto(goto,id,sem))
+         (promote_mcode goto) (promote_mcode sem)
+    | Ast0.Return(ret,sem) as us ->
+       mkres s us (promote_mcode ret) (promote_mcode sem)
+    | Ast0.ReturnExpr(ret,exp,sem) ->
+       let exp = expression exp in
+       mkres s (Ast0.ReturnExpr(ret,exp,sem))
+         (promote_mcode ret) (promote_mcode sem)
+    | Ast0.MetaStmt(name,_)
+    | Ast0.MetaStmtList(name,_) as us ->
+       let ln = promote_mcode name in mkres s us ln ln
+    | Ast0.Exp(exp) ->
+       let exp = expression exp in
+       mkres s (Ast0.Exp(exp)) exp exp
+    | Ast0.TopExp(exp) ->
+       let exp = expression exp in
+       mkres s (Ast0.TopExp(exp)) exp exp
+    | Ast0.Ty(ty) ->
+       let ty = typeC ty in
+       mkres s (Ast0.Ty(ty)) ty ty
+    | Ast0.TopInit(init) ->
+       let init = initialiser init in
+       mkres s (Ast0.TopInit(init)) init init
+    | Ast0.Disj(starter,rule_elem_dots_list,mids,ender) ->
+       let starter = bad_mcode starter in
+       let mids = List.map bad_mcode mids in
+       let ender = bad_mcode ender in
+       let rec loop prevs = function
+           [] -> []
+         | stm::stms ->
+             (dots is_stm_dots (Some(promote_mcode_plus_one(List.hd prevs)))
+                statement stm)::
+             (loop (List.tl prevs) stms) in
+       let elems = loop (starter::mids) rule_elem_dots_list in
+       mkmultires s (Ast0.Disj(starter,elems,mids,ender))
+         (promote_mcode starter) (promote_mcode ender)
+         (get_all_start_info elems) (get_all_end_info elems)
+    | Ast0.Nest(starter,rule_elem_dots,ender,whencode,multi) ->
+       let starter = bad_mcode starter in
+       let ender = bad_mcode ender in
+       let rule_elem_dots = dots is_stm_dots None statement rule_elem_dots in
+       mkres s (Ast0.Nest(starter,rule_elem_dots,ender,whencode,multi))
+         (promote_mcode starter) (promote_mcode ender)
+    | Ast0.Dots(dots,whencode) ->
+       let dots = bad_mcode dots in
+       let ln = promote_mcode dots in
+       mkres s (Ast0.Dots(dots,whencode)) ln ln
+    | Ast0.Circles(dots,whencode) ->
+       let dots = bad_mcode dots in
+       let ln = promote_mcode dots in
+       mkres s (Ast0.Circles(dots,whencode)) ln ln
+    | Ast0.Stars(dots,whencode) ->
+       let dots = bad_mcode dots in
+       let ln = promote_mcode dots in
+       mkres s (Ast0.Stars(dots,whencode)) ln ln
+    | Ast0.FunDecl((_,bef),fninfo,name,lp,params,rp,lbrace,body,rbrace) ->
+       let fninfo =
+         List.map
+           (function Ast0.FType(ty) -> Ast0.FType(typeC ty) | x -> x)
+           fninfo in
+       let name = ident name in
+       let params = parameter_list (Some(promote_mcode lp)) params in
+       let body =
+         dots is_stm_dots (Some(promote_mcode lbrace)) statement body in
+       let left =
+       (* cases on what is leftmost *)
+         match fninfo with
+           [] -> promote_to_statement_start name bef
+         | Ast0.FStorage(stg)::_ ->
+             promote_to_statement_start (promote_mcode stg) bef
+         | Ast0.FType(ty)::_ ->
+             promote_to_statement_start ty bef
+         | Ast0.FInline(inline)::_ ->
+             promote_to_statement_start (promote_mcode inline) bef
+         | Ast0.FAttr(attr)::_ ->
+             promote_to_statement_start (promote_mcode attr) bef in
+      (* pretend it is one line before the start of the function, so that it
+        will catch things defined at top level.  We assume that these will not
+        be defined on the same line as the function.  This is a HACK.
+        A better approach would be to attach top_level things to this node,
+        and other things to the node after, but that would complicate
+        insert_plus, which doesn't distinguish between different mcodekinds *)
+       let res =
+         Ast0.FunDecl((Ast0.get_info left,bef),fninfo,name,lp,params,rp,lbrace,
+                      body,rbrace) in
+      (* have to do this test again, because of typing problems - can't save
+        the result, only use it *)
+       (match fninfo with
+         [] -> mkres s res name (promote_mcode rbrace)
+       | Ast0.FStorage(stg)::_ ->
+           mkres s res (promote_mcode stg) (promote_mcode rbrace)
+       | Ast0.FType(ty)::_ -> mkres s res ty (promote_mcode rbrace)
+       | Ast0.FInline(inline)::_ ->
+           mkres s res (promote_mcode inline) (promote_mcode rbrace)
+       | Ast0.FAttr(attr)::_ ->
+           mkres s res (promote_mcode attr) (promote_mcode rbrace))
+
+    | Ast0.Include(inc,stm) ->
+       mkres s (Ast0.Include(inc,stm)) (promote_mcode inc) (promote_mcode stm)
+    | Ast0.Define(def,id,params,body) ->
+       let id = ident id in
+       let body = dots is_stm_dots None statement body in
+       mkres s (Ast0.Define(def,id,params,body)) (promote_mcode def) body
+    | Ast0.OptStm(stm) ->
+       let stm = statement stm in mkres s (Ast0.OptStm(stm)) stm stm
+    | Ast0.UniqueStm(stm) ->
+       let stm = statement stm in mkres s (Ast0.UniqueStm(stm)) stm stm in
+  Ast0.set_dots_bef_aft res
+    (match Ast0.get_dots_bef_aft res with
+      Ast0.NoDots -> Ast0.NoDots
+    | Ast0.AddingBetweenDots s ->
+       Ast0.AddingBetweenDots(statement s)
+    | Ast0.DroppingBetweenDots s ->
+       Ast0.DroppingBetweenDots(statement s))
+
+and case_line c =
+  match Ast0.unwrap c with
+    Ast0.Default(def,colon,code) ->
+      let code = dots is_stm_dots (Some(promote_mcode colon)) statement code in
+      mkres c (Ast0.Default(def,colon,code)) (promote_mcode def) code
+  | Ast0.Case(case,exp,colon,code) ->
+      let exp = expression exp in
+      let code = dots is_stm_dots (Some(promote_mcode colon)) statement code in
+      mkres c (Ast0.Case(case,exp,colon,code)) (promote_mcode case) code
+  | Ast0.OptCase(case) ->
+      let case = case_line case in mkres c (Ast0.OptCase(case)) case case
+
+and statement_dots x = dots is_stm_dots None statement x
+
+(* --------------------------------------------------------------------- *)
+(* Function declaration *)
+
+let top_level t =
+  match Ast0.unwrap t with
+    Ast0.FILEINFO(old_file,new_file) -> t
+  | Ast0.DECL(stmt) ->
+      let stmt = statement stmt in mkres t (Ast0.DECL(stmt)) stmt stmt
+  | Ast0.CODE(rule_elem_dots) ->
+      let rule_elem_dots = dots is_stm_dots None statement rule_elem_dots in
+      mkres t (Ast0.CODE(rule_elem_dots)) rule_elem_dots rule_elem_dots
+  | Ast0.ERRORWORDS(exps) -> t
+  | Ast0.OTHER(_) -> failwith "eliminated by top_level"
+
+(* --------------------------------------------------------------------- *)
+(* Entry points *)
+
+let compute_lines = List.map top_level
+
diff --git a/parsing_cocci/.#context_neg.ml.1.104 b/parsing_cocci/.#context_neg.ml.1.104
new file mode 100644 (file)
index 0000000..67b3317
--- /dev/null
@@ -0,0 +1,1023 @@
+(*
+* Copyright 2005-2009, 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
+      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 "line %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
+      (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,stringsa),Ast0.BaseType(ty2,stringsb)) ->
+      List.for_all2 equal_mcode stringsa stringsb
+  | (Ast0.Signed(sign1,_),Ast0.Signed(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.EnumName(kind1,_),Ast0.EnumName(kind2,_)) ->
+      equal_mcode kind1 kind2
+  | (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_designator d1 d2 =
+  match (d1,d2) with
+    (Ast0.DesignatorField(dot1,_),Ast0.DesignatorField(dot2,_)) ->
+      equal_mcode dot1 dot2
+  | (Ast0.DesignatorIndex(lb1,_,rb1),Ast0.DesignatorIndex(lb2,_,rb2)) ->
+      (equal_mcode lb1 lb2) && (equal_mcode rb1 rb2)
+  | (Ast0.DesignatorRange(lb1,_,dots1,_,rb1),
+     Ast0.DesignatorRange(lb2,_,dots2,_,rb2)) ->
+       (equal_mcode lb1 lb2) && (equal_mcode dots1 dots2) &&
+       (equal_mcode rb1 rb2)
+  | _ -> false
+
+let equal_initialiser i1 i2 =
+  match (Ast0.unwrap i1,Ast0.unwrap i2) with
+    (Ast0.MetaInit(name1,_),Ast0.MetaInit(name2,_)) ->
+      equal_mcode name1 name2
+  | (Ast0.InitExpr(_),Ast0.InitExpr(_)) -> true
+  | (Ast0.InitList(lb1,_,rb1),Ast0.InitList(lb2,_,rb2)) ->
+      (equal_mcode lb1 lb2) && (equal_mcode rb1 rb2)
+  | (Ast0.InitGccExt(designators1,eq1,_),
+     Ast0.InitGccExt(designators2,eq2,_)) ->
+       (List.for_all2 equal_designator designators1 designators2) &&
+       (equal_mcode eq1 eq2)
+  | (Ast0.InitGccName(_,eq1,_),Ast0.InitGccName(_,eq2,_)) ->
+      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
+    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
+      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_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
+  | 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 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()
+
+(* ------------------------------------------------------------------- *)
+
+(* 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/.#data.ml.1.38 b/parsing_cocci/.#data.ml.1.38
new file mode 100644 (file)
index 0000000..f6fe909
--- /dev/null
@@ -0,0 +1,151 @@
+(*
+* Copyright 2005-2009, 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 Ast0 = Ast0_cocci
+module Ast = Ast_cocci
+
+(* types that clutter the .mly file *)
+(* for iso metavariables, true if they can only match nonmodified, unitary
+   metavariables *)
+type fresh = bool
+
+type clt =
+    line_type * int * int * int * int (* starting spaces *) *
+      string list (* code before *) * string list (* code after *) *
+      Ast0.meta_pos (* position variable, minus only *)
+
+(* ---------------------------------------------------------------------- *)
+
+(* Things that need to be seen by the lexer and parser. *)
+
+and line_type =
+    MINUS | OPTMINUS | UNIQUEMINUS
+  | PLUS
+  | CONTEXT | UNIQUE | OPT
+
+type iconstraints = Ast0.ident list
+type econstraints = Ast0.expression list
+type pconstraints = Ast.meta_name list
+
+let in_rule_name = ref false
+let in_meta = ref false
+let in_iso = ref false
+let in_generating = ref false
+let in_prolog = ref false
+let inheritable_positions =
+  ref ([] : string list) (* rules from which posns can be inherited *)
+
+let all_metadecls =
+  (Hashtbl.create(100) : (string, Ast.metavar list) Hashtbl.t)
+
+let clear_meta: (unit -> unit) ref =
+  ref (fun _ -> failwith "uninitialized add_meta")
+
+let add_id_meta:
+    (Ast.meta_name -> iconstraints -> Ast0.pure -> unit) ref =
+  ref (fun _ -> failwith "uninitialized add_meta")
+
+let add_type_meta: (Ast.meta_name -> Ast0.pure -> unit) ref =
+  ref (fun _ -> failwith "uninitialized add_meta")
+
+let add_init_meta: (Ast.meta_name -> Ast0.pure -> unit) ref =
+  ref (fun _ -> failwith "uninitialized add_meta")
+
+let add_param_meta: (Ast.meta_name -> Ast0.pure -> unit) ref =
+  ref (fun _ -> failwith "uninitialized add_meta")
+
+let add_paramlist_meta:
+    (Ast.meta_name -> Ast.meta_name option -> Ast0.pure -> unit) ref =
+  ref (fun _ -> failwith "uninitialized add_meta")
+
+let add_const_meta:
+    (Type_cocci.typeC list option -> Ast.meta_name -> econstraints ->
+      Ast0.pure -> unit)
+    ref =
+  ref (fun _ -> failwith "uninitialized add_meta")
+
+let add_err_meta:
+    (Ast.meta_name -> econstraints -> Ast0.pure -> unit) ref =
+  ref (fun _ -> failwith "uninitialized add_meta")
+
+let add_exp_meta:
+    (Type_cocci.typeC list option -> Ast.meta_name -> econstraints ->
+      Ast0.pure -> unit)
+    ref =
+  ref (fun _ -> failwith "uninitialized add_meta")
+
+let add_idexp_meta:
+    (Type_cocci.typeC list option -> Ast.meta_name -> econstraints ->
+      Ast0.pure -> unit)
+    ref =
+  ref (fun _ -> failwith "uninitialized add_meta")
+
+let add_local_idexp_meta:
+    (Type_cocci.typeC list option -> Ast.meta_name -> econstraints ->
+      Ast0.pure -> unit)
+    ref =
+  ref (fun _ -> failwith "uninitialized add_meta")
+
+let add_explist_meta:
+    (Ast.meta_name -> Ast.meta_name option -> Ast0.pure -> unit) ref =
+  ref (fun _ -> failwith "uninitialized add_meta")
+
+let add_stm_meta: (Ast.meta_name -> Ast0.pure -> unit) ref =
+  ref (fun _ -> failwith "uninitialized add_meta")
+
+let add_stmlist_meta: (Ast.meta_name -> Ast0.pure -> unit) ref =
+  ref (fun _ -> failwith "uninitialized add_meta")
+
+let add_func_meta:
+    (Ast.meta_name -> iconstraints -> Ast0.pure -> unit) ref =
+  ref (fun _ -> failwith "uninitialized add_meta")
+
+let add_local_func_meta:
+    (Ast.meta_name -> iconstraints -> Ast0.pure -> unit) ref =
+  ref (fun _ -> failwith "uninitialized add_meta")
+
+let add_declarer_meta:
+    (Ast.meta_name -> iconstraints -> Ast0.pure -> unit) ref =
+  ref (fun _ -> failwith "uninitialized add_decl")
+
+let add_iterator_meta:
+    (Ast.meta_name -> iconstraints -> Ast0.pure -> unit) ref =
+  ref (fun _ -> failwith "uninitialized add_iter")
+
+let add_pos_meta:
+    (Ast.meta_name -> pconstraints -> Ast.meta_collect -> unit) ref =
+  ref (fun _ -> failwith "uninitialized add_meta")
+
+let add_type_name: (string -> unit) ref =
+  ref (fun _ -> failwith "uninitialized add_type")
+
+let add_declarer_name: (string -> unit) ref =
+  ref (fun _ -> failwith "uninitialized add_decl")
+
+let add_iterator_name: (string -> unit) ref =
+  ref (fun _ -> failwith "uninitialized add_iter")
+
+let init_rule: (unit -> unit) ref =
+  ref (fun _ -> failwith "uninitialized install_bindings")
+
+let install_bindings: (string -> unit) ref =
+  ref (fun _ -> failwith "uninitialized install_bindings")
diff --git a/parsing_cocci/.#index.ml.1.60 b/parsing_cocci/.#index.ml.1.60
new file mode 100644 (file)
index 0000000..a28bb8d
--- /dev/null
@@ -0,0 +1,221 @@
+(*
+* Copyright 2005-2009, 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.
+*)
+
+
+(* create an index for each constructor *)
+(* current max is 147, but 107 is free *)
+
+(* doesn't really work - requires that identical terms with no token
+subterms (eg dots) not appear on the same line *)
+
+module Ast = Ast_cocci
+module Ast0 = Ast0_cocci
+
+(* if a dot list is empty, add the starting line of the dot list to the
+address.  Otherwise add 0.  An empty dot list should only match with another
+empty one. *)
+let expression_dots d =
+  let ln = (Ast0.get_info d).Ast0.line_start in
+  match Ast0.unwrap d with
+    Ast0.DOTS(l) -> 1::(if l = [] then [ln] else [0])
+  | Ast0.CIRCLES(l) -> 2::(if l = [] then [ln] else [0])
+  | Ast0.STARS(l) -> 3::(if l = [] then [ln] else [0])
+
+let initialiser_dots d =
+  let ln = (Ast0.get_info d).Ast0.line_start in
+  match Ast0.unwrap d with
+    Ast0.DOTS(l) -> 113::(if l = [] then [ln] else [0])
+  | Ast0.CIRCLES(l) -> 114::(if l = [] then [ln] else [0])
+  | Ast0.STARS(l) -> 115::(if l = [] then [ln] else [0])
+
+let parameter_dots d =
+  let ln = (Ast0.get_info d).Ast0.line_start in
+  match Ast0.unwrap d with
+    Ast0.DOTS(l) -> 4::(if l = [] then [ln] else [0])
+  | Ast0.CIRCLES(l) -> 5::(if l = [] then [ln] else [0])
+  | Ast0.STARS(l) -> 6::(if l = [] then [ln] else [0])
+
+let statement_dots d =
+  let ln = (Ast0.get_info d).Ast0.line_start in
+  match Ast0.unwrap d with
+    Ast0.DOTS(l) -> 7::(if l = [] then [ln] else [0])
+  | Ast0.CIRCLES(l) -> 8::(if l = [] then [ln] else [0])
+  | Ast0.STARS(l) -> 9::(if l = [] then [ln] else [0])
+
+let declaration_dots d =
+  let ln = (Ast0.get_info d).Ast0.line_start in
+  match Ast0.unwrap d with
+    Ast0.DOTS(l) -> 134::(if l = [] then [ln] else [0])
+  | Ast0.CIRCLES(l) -> 135::(if l = [] then [ln] else [0])
+  | Ast0.STARS(l) -> 136::(if l = [] then [ln] else [0])
+
+let case_line_dots d =
+  let ln = (Ast0.get_info d).Ast0.line_start in
+  match Ast0.unwrap d with
+    Ast0.DOTS(l) -> 138::(if l = [] then [ln] else [0])
+  | Ast0.CIRCLES(l) -> 139::(if l = [] then [ln] else [0])
+  | Ast0.STARS(l) -> 140::(if l = [] then [ln] else [0])
+
+let ident i =
+  match Ast0.unwrap i with
+    Ast0.Id(name) -> [10]
+  | Ast0.MetaId(name,_,_) -> [11]
+  | Ast0.MetaFunc(name,_,_) -> [12]
+  | Ast0.MetaLocalFunc(name,_,_) -> [13]
+  | Ast0.OptIdent(id) -> [14]
+  | Ast0.UniqueIdent(id) -> [15]
+
+let expression e =
+  match Ast0.unwrap e with
+    Ast0.Ident(id) -> [17]
+  | Ast0.Constant(const) -> [18]
+  | Ast0.FunCall(fn,lp,args,rp) -> [19]
+  | Ast0.Assignment(left,op,right,simple) -> [20]
+  | Ast0.CondExpr(exp1,why,exp2,colon,exp3) -> [21]
+  | Ast0.Postfix(exp,op) -> [22]
+  | Ast0.Infix(exp,op) -> [23]
+  | Ast0.Unary(exp,op) -> [24]
+  | Ast0.Binary(left,op,right) -> [25]
+  | Ast0.Nested(left,op,right) -> failwith "nested in index not possible"
+  | Ast0.Paren(lp,exp,rp) -> [26]
+  | Ast0.ArrayAccess(exp1,lb,exp2,rb) -> [27]
+  | Ast0.RecordAccess(exp,pt,field) -> [28]
+  | Ast0.RecordPtAccess(exp,ar,field) -> [29]
+  | Ast0.Cast(lp,ty,rp,exp) -> [30]
+  | Ast0.SizeOfExpr(szf,exp) -> [98] (* added after *)
+  | Ast0.SizeOfType(szf,lp,ty,rp) -> [99] (* added after *)
+  | Ast0.TypeExp(ty) -> [123] (* added after *)
+  | Ast0.MetaErr(name,_,_) -> [32]
+  | Ast0.MetaExpr(name,_,ty,_,_) -> [33]
+  | Ast0.MetaExprList(name,_,_) -> [34]
+  | Ast0.EComma(cm) -> [35]
+  | Ast0.DisjExpr(_,expr_list,_,_) -> [36]
+  | Ast0.NestExpr(_,expr_dots,_,_,_) -> [37]
+  | Ast0.Edots(dots,whencode) -> [38]
+  | Ast0.Ecircles(dots,whencode) -> [39]
+  | Ast0.Estars(dots,whencode) -> [40]
+  | Ast0.OptExp(exp) -> [41]
+  | Ast0.UniqueExp(exp) -> [42]
+
+let typeC t =
+  match Ast0.unwrap t with
+    Ast0.ConstVol(cv,ty) -> [44]
+  | Ast0.BaseType(ty,strings) -> [48]
+  | Ast0.Signed(sign,ty) -> [129]
+  | Ast0.Pointer(ty,star) -> [49]
+  | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) -> [131]
+  | Ast0.FunctionType(ty,lp1,params,rp1) -> [132]
+  | Ast0.Array(ty,lb,size,rb) -> [50]
+  | Ast0.EnumName(kind,name) -> [146]
+  | Ast0.StructUnionName(kind,name) -> [51]
+  | Ast0.StructUnionDef(ty,lb,decls,rb) -> [117]
+  | Ast0.TypeName(name) -> [52]
+  | Ast0.MetaType(name,_) -> [53]
+  | Ast0.DisjType(_,type_list,_,_) -> [130]
+  | Ast0.OptType(ty) -> [45]
+  | Ast0.UniqueType(ty) -> [46]
+
+let declaration d =
+  match Ast0.unwrap d with
+    Ast0.Init(stg,ty,id,eq,exp,sem) -> [54]
+  | Ast0.UnInit(stg,ty,id,sem) -> [55]
+  | Ast0.MacroDecl(name,lp,args,rp,sem) -> [137]
+  | Ast0.TyDecl(ty,sem) -> [116]
+  | Ast0.Typedef(stg,ty,id,sem) -> [143]
+  | Ast0.DisjDecl(_,decls,_,_) -> [97] (* added after *)
+  | Ast0.Ddots(dots,whencode) -> [133]
+  | Ast0.OptDecl(decl) -> [56]
+  | Ast0.UniqueDecl(decl) -> [57]
+
+let initialiser i =
+  match Ast0.unwrap i with
+    Ast0.MetaInit(nm,_) -> [106] (* added after *)
+  | Ast0.InitExpr(exp) -> [102]
+  | Ast0.InitList(lb,initlist,rb) -> [103]
+  | Ast0.InitGccExt(designators,eq,ini) -> [104]
+  | Ast0.InitGccName(name,eq,ini) -> [105]
+  | Ast0.IComma(cm) -> [108]
+  | Ast0.Idots(d,whencode) -> [109]
+  | Ast0.OptIni(id) -> [110]
+  | Ast0.UniqueIni(id) -> [111]
+
+let parameterTypeDef p =
+  match Ast0.unwrap p with
+    Ast0.VoidParam(ty) -> [59]
+  | Ast0.Param(ty,id) -> [60]
+  | Ast0.MetaParam(name,_) -> [61]
+  | Ast0.MetaParamList(name,_,_) -> [62]
+  | Ast0.PComma(cm) -> [63]
+  | Ast0.Pdots(dots) -> [64]
+  | Ast0.Pcircles(dots) -> [65]
+  | Ast0.OptParam(param) -> [66]
+  | Ast0.UniqueParam(param) -> [67]
+
+let statement s =
+  match Ast0.unwrap s with
+    Ast0.FunDecl(bef,fninfo,name,lp,params,rp,lbrace,body,rbrace) -> [68]
+  | Ast0.Decl(bef,decl) -> [69]
+  | Ast0.Seq(lbrace,body,rbrace) -> [70]
+  | Ast0.ExprStatement(exp,sem) -> [71]
+  | Ast0.IfThen(iff,lp,exp,rp,branch1,aft) -> [72]
+  | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,aft) -> [73]
+  | Ast0.While(whl,lp,exp,rp,body,_) -> [74]
+  | Ast0.Do(d,body,whl,lp,exp,rp,sem) -> [75]
+  | Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,_) -> [76]
+  | Ast0.Iterator(nm,lp,args,rp,body,_) -> [142]
+  | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) -> [125]
+  | Ast0.Break(br,sem) -> [100]
+  | Ast0.Continue(cont,sem) -> [101]
+  | Ast0.Label(l,dd) -> [144]
+  | Ast0.Goto(goto,l,sem) -> [145]
+  | Ast0.Return(ret,sem) -> [77]
+  | Ast0.ReturnExpr(ret,exp,sem) -> [78]
+  | Ast0.MetaStmt(name,_) -> [79]
+  | Ast0.MetaStmtList(name,_) -> [80]
+  | Ast0.Disj(_,statement_dots_list,_,_) -> [81]
+  | Ast0.Nest(_,stmt_dots,_,_,_) -> [82]
+  | Ast0.Exp(exp) -> [83]
+  | Ast0.TopExp(exp) -> [141]
+  | Ast0.Ty(ty) -> [124]
+  | Ast0.TopInit(init) -> [146]
+  | Ast0.Dots(d,whencode) -> [84]
+  | Ast0.Circles(d,whencode) -> [85]
+  | Ast0.Stars(d,whencode) -> [86]
+  | Ast0.Include(inc,name) -> [118]
+  | Ast0.Define(def,id,params,body) -> [119]
+  | Ast0.OptStm(re) -> [87]
+  | Ast0.UniqueStm(re) -> [88]
+
+let case_line c =
+  match Ast0.unwrap c with
+    Ast0.Default(def,colon,code) -> [126]
+  | Ast0.Case(case,exp,colon,code) -> [127]
+  | Ast0.OptCase(case) -> [128]
+
+let top_level t =
+  match Ast0.unwrap t with
+    Ast0.DECL(stmt) -> [90]
+  | Ast0.FILEINFO(old_file,new_file) -> [92]
+  | Ast0.CODE(stmt_dots) -> [94]
+  | Ast0.ERRORWORDS(exps) -> [95]
+  | Ast0.OTHER(_) -> [96]
+
+(* 99-101 already used *)
diff --git a/parsing_cocci/.#insert_plus.ml.1.74 b/parsing_cocci/.#insert_plus.ml.1.74
new file mode 100644 (file)
index 0000000..706f922
--- /dev/null
@@ -0,0 +1,952 @@
+(*
+* Copyright 2005-2009, 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.
+*)
+
+
+(* The error message "no available token to attach to" often comes in an
+argument list of unbounded length.  In this case, one should move a comma so
+that there is a comma after the + code. *)
+
+(* Start at all of the corresponding BindContext nodes in the minus and
+plus trees, and traverse their children.  We take the same strategy as
+before: collect the list of minus/context nodes/tokens and the list of plus
+tokens, and then merge them. *)
+
+module Ast = Ast_cocci
+module Ast0 = Ast0_cocci
+module V0 = Visitor_ast0
+module CN = Context_neg
+
+let empty_isos = ref false
+
+let get_option f = function
+    None -> []
+  | Some x -> f x
+
+(* --------------------------------------------------------------------- *)
+(* Collect root and all context nodes in a tree *)
+
+let collect_context e =
+  let bind x y = x @ y in
+  let option_default = [] in
+
+  let mcode _ = [] in
+
+  let donothing builder r k e =
+    match Ast0.get_mcodekind e with
+      Ast0.CONTEXT(_) -> (builder e) :: (k e)
+    | _ -> k e in
+
+(* special case for everything that contains whencode, so that we skip over
+it *)
+  let expression r k e =
+    donothing Ast0.expr r k
+      (Ast0.rewrap e
+        (match Ast0.unwrap e with
+          Ast0.NestExpr(starter,exp,ender,whencode,multi) ->
+            Ast0.NestExpr(starter,exp,ender,None,multi)
+        | Ast0.Edots(dots,whencode) -> Ast0.Edots(dots,None)
+        | Ast0.Ecircles(dots,whencode) -> Ast0.Ecircles(dots,None)
+        | Ast0.Estars(dots,whencode) -> Ast0.Estars(dots,None)
+        | e -> e)) in
+
+  let initialiser r k i =
+    donothing Ast0.ini r k
+      (Ast0.rewrap i
+        (match Ast0.unwrap i with
+          Ast0.Idots(dots,whencode) -> Ast0.Idots(dots,None)
+        | i -> i)) in
+
+  let statement r k s =
+    donothing Ast0.stmt r k
+      (Ast0.rewrap s
+        (match Ast0.unwrap s with
+          Ast0.Nest(started,stm_dots,ender,whencode,multi) ->
+            Ast0.Nest(started,stm_dots,ender,[],multi)
+        | Ast0.Dots(dots,whencode) -> Ast0.Dots(dots,[])
+        | Ast0.Circles(dots,whencode) -> Ast0.Circles(dots,[])
+        | Ast0.Stars(dots,whencode) -> Ast0.Stars(dots,[])
+        | s -> s)) in
+
+  let topfn r k e = Ast0.TopTag(e) :: (k e) in
+
+  let res =
+    V0.combiner bind option_default
+      mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+      (donothing Ast0.dotsExpr) (donothing Ast0.dotsInit)
+      (donothing Ast0.dotsParam) (donothing Ast0.dotsStmt)
+      (donothing Ast0.dotsDecl) (donothing Ast0.dotsCase)
+      (donothing Ast0.ident) expression (donothing Ast0.typeC) initialiser
+      (donothing Ast0.param) (donothing Ast0.decl) statement
+      (donothing Ast0.case_line) topfn in
+  res.V0.combiner_top_level e
+
+(* --------------------------------------------------------------------- *)
+(* --------------------------------------------------------------------- *)
+(* collect the possible join points, in order, among the children of a
+BindContext.  Dots are not allowed.  Nests and disjunctions are no problem,
+because their delimiters take up a line by themselves *)
+
+(* An Unfavored token is one that is in a BindContext node; using this causes
+  the node to become Neither, meaning that isomorphisms can't be applied *)
+(* Toplevel is for the bef token of a function declaration and is for
+attaching top-level definitions that should come before the complete
+declaration *)
+type minus_join_point = Favored | Unfavored | Toplevel | Decl
+
+(* Maps the index of a node to the indices of the mcodes it contains *)
+let root_token_table = (Hashtbl.create(50) : (int, int list) Hashtbl.t)
+
+let create_root_token_table minus =
+  Hashtbl.iter
+    (function tokens ->
+      function (node,_) ->
+       let key =
+         match node with
+           Ast0.DotsExprTag(d) -> Ast0.get_index d
+         | Ast0.DotsInitTag(d) -> Ast0.get_index d
+         | Ast0.DotsParamTag(d) -> Ast0.get_index d
+         | Ast0.DotsStmtTag(d) -> Ast0.get_index d
+         | Ast0.DotsDeclTag(d) -> Ast0.get_index d
+         | Ast0.DotsCaseTag(d) -> Ast0.get_index d
+         | Ast0.IdentTag(d) -> Ast0.get_index d
+         | Ast0.ExprTag(d) -> Ast0.get_index d
+         | Ast0.ArgExprTag(d) | Ast0.TestExprTag(d) ->
+             failwith "not possible - iso only"
+         | Ast0.TypeCTag(d) -> Ast0.get_index d
+         | Ast0.ParamTag(d) -> Ast0.get_index d
+         | Ast0.InitTag(d) -> Ast0.get_index d
+         | Ast0.DeclTag(d) -> Ast0.get_index d
+         | Ast0.StmtTag(d) -> Ast0.get_index d
+         | Ast0.CaseLineTag(d) -> Ast0.get_index d
+         | Ast0.TopTag(d) -> Ast0.get_index d
+         | Ast0.IsoWhenTag(_) -> failwith "only within iso phase"
+         | Ast0.IsoWhenTTag(_) -> failwith "only within iso phase"
+         | Ast0.IsoWhenFTag(_) -> failwith "only within iso phase"
+         | Ast0.MetaPosTag(p) -> failwith "metapostag only within iso phase"
+       in
+       Hashtbl.add root_token_table key tokens)
+    CN.minus_table;
+  List.iter
+    (function r ->
+      let index = Ast0.get_index r in
+      try let _ = Hashtbl.find root_token_table index in ()
+      with Not_found -> Hashtbl.add root_token_table index [])
+    minus
+
+let collect_minus_join_points root =
+  let root_index = Ast0.get_index root in
+  let unfavored_tokens = Hashtbl.find root_token_table root_index in
+  let bind x y = x @ y in
+  let option_default = [] in
+
+  let mcode (_,_,info,mcodekind,_) =
+    if List.mem (info.Ast0.offset) unfavored_tokens
+    then [(Unfavored,info,mcodekind)]
+    else [(Favored,info,mcodekind)] in
+
+  let do_nothing r k e =
+    let info = Ast0.get_info e in
+    let index = Ast0.get_index e in
+    match Ast0.get_mcodekind e with
+      (Ast0.MINUS(_)) as mc -> [(Favored,info,mc)]
+    | (Ast0.CONTEXT(_)) as mc when not(index = root_index) ->
+       (* This was unfavored at one point, but I don't remember why *)
+      [(Favored,info,mc)]
+    | _ -> k e in
+
+(* don't want to attach to the outside of DOTS, because metavariables can't
+bind to that; not good for isomorphisms *)
+
+  let dots f k d =
+    let multibind l =
+      let rec loop = function
+         [] -> option_default
+       | [x] -> x
+       | x::xs -> bind x (loop xs) in
+      loop l in
+
+    match Ast0.unwrap d with
+      Ast0.DOTS(l) -> multibind (List.map f l)
+    | Ast0.CIRCLES(l) -> multibind (List.map f l)
+    | Ast0.STARS(l) -> multibind (List.map f l) in
+
+  let edots r k d = dots r.V0.combiner_expression k d in
+  let idots r k d = dots r.V0.combiner_initialiser k d in
+  let pdots r k d = dots r.V0.combiner_parameter k d in
+  let sdots r k d = dots r.V0.combiner_statement k d in
+  let ddots r k d = dots r.V0.combiner_declaration k d in
+  let cdots r k d = dots r.V0.combiner_case_line k d in
+
+  (* a case for everything that has a Opt *)
+
+  let statement r k s =
+    (*
+    let redo_branched res (ifinfo,aftmc) =
+      let redo fv info mc rest =
+       let new_info = {info with Ast0.attachable_end = false} in
+       List.rev ((Favored,ifinfo,aftmc)::(fv,new_info,mc)::rest) in
+      match List.rev res with
+       [(fv,info,mc)] ->
+         (match mc with
+           Ast0.MINUS(_) | Ast0.CONTEXT(_) ->
+               (* even for -, better for isos not to integrate code after an
+                  if into the if body.
+                  but the problem is that this can extend the region in
+                  which a variable is bound, because a variable bound in the
+                  aft node would seem to have to be live in the whole if,
+                  whereas we might like it to be live in only one branch.
+                  ie ideally, if we can keep the minus code in the right
+                  order, we would like to drop it as close to the bindings
+                  of its free variables.  This could be anywhere in the minus
+                  code.  Perhaps we would like to do this after the
+                  application of isomorphisms, though.
+               *)
+             redo fv info mc []
+         | _ -> res)
+      | (fv,info,mc)::rest ->
+         (match mc with
+           Ast0.CONTEXT(_) -> redo fv info mc rest
+         | _ -> res)
+      | _ -> failwith "unexpected empty code" in *)
+    match Ast0.unwrap s with
+ (*     Ast0.IfThen(_,_,_,_,_,aft)
+    | Ast0.IfThenElse(_,_,_,_,_,_,_,aft)
+    | Ast0.While(_,_,_,_,_,aft)
+    | Ast0.For(_,_,_,_,_,_,_,_,_,aft)
+    | Ast0.Iterator(_,_,_,_,_,aft) ->
+       redo_branched (do_nothing r k s) aft*)
+    | Ast0.FunDecl((info,bef),fninfo,name,lp,params,rp,lbrace,body,rbrace) ->
+       (Toplevel,info,bef)::(k s)
+    | Ast0.Decl((info,bef),decl) -> (Decl,info,bef)::(k s)
+    | Ast0.Nest(starter,stmt_dots,ender,whencode,multi) ->
+       mcode starter @ r.V0.combiner_statement_dots stmt_dots @ mcode ender
+    | Ast0.Dots(d,whencode) | Ast0.Circles(d,whencode)
+    | Ast0.Stars(d,whencode) -> mcode d (* ignore whencode *)
+    | Ast0.OptStm s | Ast0.UniqueStm s ->
+       (* put the + code on the thing, not on the opt *)
+       r.V0.combiner_statement s
+    | _ -> do_nothing r k s in
+
+  let expression r k e =
+    match Ast0.unwrap e with
+      Ast0.NestExpr(starter,expr_dots,ender,whencode,multi) ->
+       mcode starter @
+       r.V0.combiner_expression_dots expr_dots @ mcode ender
+    | Ast0.Edots(d,whencode) | Ast0.Ecircles(d,whencode)
+    | Ast0.Estars(d,whencode) -> mcode d (* ignore whencode *)
+    | Ast0.OptExp e | Ast0.UniqueExp e ->
+       (* put the + code on the thing, not on the opt *)
+       r.V0.combiner_expression e
+    | _ -> do_nothing r k e in
+
+  let ident r k e =
+    match Ast0.unwrap e with
+      Ast0.OptIdent i | Ast0.UniqueIdent i ->
+       (* put the + code on the thing, not on the opt *)
+       r.V0.combiner_ident i
+    | _ -> do_nothing r k e in
+
+  let typeC r k e =
+    match Ast0.unwrap e with
+      Ast0.OptType t | Ast0.UniqueType t ->
+       (* put the + code on the thing, not on the opt *)
+       r.V0.combiner_typeC t
+    | _ -> do_nothing r k e in
+
+  let decl r k e =
+    match Ast0.unwrap e with
+      Ast0.OptDecl d | Ast0.UniqueDecl d ->
+       (* put the + code on the thing, not on the opt *)
+       r.V0.combiner_declaration d
+    | _ -> do_nothing r k e in
+
+  let initialiser r k e =
+    match Ast0.unwrap e with
+      Ast0.Idots(d,whencode) -> mcode d (* ignore whencode *)
+    | Ast0.OptIni i | Ast0.UniqueIni i ->
+       (* put the + code on the thing, not on the opt *)
+       r.V0.combiner_initialiser i
+    | _ -> do_nothing r k e in
+
+  let param r k e =
+    match Ast0.unwrap e with
+      Ast0.OptParam p | Ast0.UniqueParam p ->
+       (* put the + code on the thing, not on the opt *)
+       r.V0.combiner_parameter p
+    | _ -> do_nothing r k e in
+
+  let case_line r k e =
+    match Ast0.unwrap e with
+      Ast0.OptCase c ->
+       (* put the + code on the thing, not on the opt *)
+       r.V0.combiner_case_line c
+    | _ -> do_nothing r k e in
+
+  let do_top r k (e: Ast0.top_level) = k e in
+
+  V0.combiner bind option_default
+    mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+    edots idots pdots sdots ddots cdots
+    ident expression typeC initialiser param decl statement case_line do_top
+
+
+let call_collect_minus context_nodes :
+    (int * (minus_join_point * Ast0.info * Ast0.mcodekind) list) list =
+  List.map
+    (function e ->
+      match e with
+       Ast0.DotsExprTag(e) ->
+         (Ast0.get_index e,
+          (collect_minus_join_points e).V0.combiner_expression_dots e)
+      | Ast0.DotsInitTag(e) ->
+         (Ast0.get_index e,
+          (collect_minus_join_points e).V0.combiner_initialiser_list e)
+      | Ast0.DotsParamTag(e) ->
+         (Ast0.get_index e,
+          (collect_minus_join_points e).V0.combiner_parameter_list e)
+      | Ast0.DotsStmtTag(e) ->
+         (Ast0.get_index e,
+          (collect_minus_join_points e).V0.combiner_statement_dots e)
+      | Ast0.DotsDeclTag(e) ->
+         (Ast0.get_index e,
+          (collect_minus_join_points e).V0.combiner_declaration_dots e)
+      | Ast0.DotsCaseTag(e) ->
+         (Ast0.get_index e,
+          (collect_minus_join_points e).V0.combiner_case_line_dots e)
+      | Ast0.IdentTag(e) ->
+         (Ast0.get_index e,
+          (collect_minus_join_points e).V0.combiner_ident e)
+      | Ast0.ExprTag(e) ->
+         (Ast0.get_index e,
+          (collect_minus_join_points e).V0.combiner_expression e)
+      | Ast0.ArgExprTag(e) | Ast0.TestExprTag(e) ->
+         failwith "not possible - iso only"
+      | Ast0.TypeCTag(e) ->
+         (Ast0.get_index e,
+          (collect_minus_join_points e).V0.combiner_typeC e)
+      | Ast0.ParamTag(e) ->
+         (Ast0.get_index e,
+          (collect_minus_join_points e).V0.combiner_parameter e)
+      | Ast0.InitTag(e) ->
+         (Ast0.get_index e,
+          (collect_minus_join_points e).V0.combiner_initialiser e)
+      | Ast0.DeclTag(e) ->
+         (Ast0.get_index e,
+          (collect_minus_join_points e).V0.combiner_declaration e)
+      | Ast0.StmtTag(e) ->
+         (Ast0.get_index e,
+          (collect_minus_join_points e).V0.combiner_statement e)
+      | Ast0.CaseLineTag(e) ->
+         (Ast0.get_index e,
+          (collect_minus_join_points e).V0.combiner_case_line e)
+      | Ast0.TopTag(e) ->
+         (Ast0.get_index e,
+          (collect_minus_join_points e).V0.combiner_top_level e)
+      | Ast0.IsoWhenTag(_) -> failwith "only within iso phase"
+      | Ast0.IsoWhenTTag(_) -> failwith "only within iso phase"
+      | Ast0.IsoWhenFTag(_) -> failwith "only within iso phase"
+      | Ast0.MetaPosTag(p) -> failwith "metapostag only within iso phase")
+    context_nodes
+
+(* result of collecting the join points should be sorted in nondecreasing
+   order by line *)
+let verify l =
+  let get_info = function
+      (Favored,info,_) | (Unfavored,info,_) | (Toplevel,info,_)
+    | (Decl,info,_) -> info in
+  let token_start_line      x = (get_info x).Ast0.logical_start in
+  let token_end_line        x = (get_info x).Ast0.logical_end in
+  let token_real_start_line x = (get_info x).Ast0.line_start in
+  let token_real_end_line   x = (get_info x).Ast0.line_end in
+  List.iter
+    (function
+       (index,((_::_) as l1)) ->
+         let _ =
+           List.fold_left
+             (function (prev,real_prev) ->
+               function cur ->
+                 let ln = token_start_line cur in
+                 if ln < prev
+                 then
+                   failwith
+                     (Printf.sprintf
+                        "error in collection of - tokens %d less than %d"
+                        (token_real_start_line cur) real_prev);
+                 (token_end_line cur,token_real_end_line cur))
+             (token_end_line (List.hd l1), token_real_end_line (List.hd l1))
+             (List.tl l1) in
+         ()
+      |        _ -> ()) (* dots, in eg f() has no join points *)
+    l
+
+let process_minus minus =
+  create_root_token_table minus;
+  List.concat
+    (List.map
+       (function x ->
+        let res = call_collect_minus (collect_context x) in
+        verify res;
+        res)
+       minus)
+
+(* --------------------------------------------------------------------- *)
+(* --------------------------------------------------------------------- *)
+(* collect the plus tokens *)
+
+let mk_structUnion x      = Ast.StructUnionTag x
+let mk_sign x             = Ast.SignTag x
+let mk_ident x            = Ast.IdentTag (Ast0toast.ident x)
+let mk_expression x       = Ast.ExpressionTag (Ast0toast.expression x)
+let mk_constant x         = Ast.ConstantTag x
+let mk_unaryOp x          = Ast.UnaryOpTag x
+let mk_assignOp x         = Ast.AssignOpTag x
+let mk_fixOp x            = Ast.FixOpTag x
+let mk_binaryOp x         = Ast.BinaryOpTag x
+let mk_arithOp x          = Ast.ArithOpTag x
+let mk_logicalOp x        = Ast.LogicalOpTag x
+let mk_declaration x      = Ast.DeclarationTag (Ast0toast.declaration x)
+let mk_topdeclaration x   = Ast.DeclarationTag (Ast0toast.declaration x)
+let mk_storage x          = Ast.StorageTag x
+let mk_inc_file x         = Ast.IncFileTag x
+let mk_statement x        = Ast.StatementTag (Ast0toast.statement x)
+let mk_case_line x        = Ast.CaseLineTag (Ast0toast.case_line x)
+let mk_const_vol x        = Ast.ConstVolTag x
+let mk_token x info       = Ast.Token (x,Some info)
+let mk_meta (_,x) info    = Ast.Token (x,Some info)
+let mk_code x             = Ast.Code (Ast0toast.top_level x)
+
+let mk_exprdots x  = Ast.ExprDotsTag (Ast0toast.expression_dots x)
+let mk_paramdots x = Ast.ParamDotsTag (Ast0toast.parameter_list x)
+let mk_stmtdots x  = Ast.StmtDotsTag (Ast0toast.statement_dots x)
+let mk_decldots x  = Ast.DeclDotsTag (Ast0toast.declaration_dots x)
+let mk_casedots x  = failwith "+ case lines not supported"
+let mk_typeC x     = Ast.FullTypeTag (Ast0toast.typeC x)
+let mk_init x      = Ast.InitTag (Ast0toast.initialiser x)
+let mk_param x     = Ast.ParamTag (Ast0toast.parameterTypeDef x)
+
+let collect_plus_nodes root =
+  let root_index = Ast0.get_index root in
+
+  let bind x y = x @ y in
+  let option_default = [] in
+
+  let mcode fn (term,_,info,mcodekind,_) =
+    match mcodekind with Ast0.PLUS -> [(info,fn term)] | _ -> [] in
+
+  let imcode fn (term,_,info,mcodekind,_) =
+    match mcodekind with
+      Ast0.PLUS -> [(info,fn term (Ast0toast.convert_info info))]
+    | _ -> [] in
+
+  let do_nothing fn r k e =
+    match Ast0.get_mcodekind e with
+      (Ast0.CONTEXT(_)) when not(Ast0.get_index e = root_index) -> []
+    | Ast0.PLUS -> [(Ast0.get_info e,fn e)]
+    | _ -> k e in
+
+  (* case for everything that is just a wrapper for a simpler thing *)
+  let stmt r k e =
+    match Ast0.unwrap e with
+      Ast0.Exp(exp) -> r.V0.combiner_expression exp
+    | Ast0.TopExp(exp) -> r.V0.combiner_expression exp
+    | Ast0.Ty(ty) -> r.V0.combiner_typeC ty
+    | Ast0.TopInit(init) -> r.V0.combiner_initialiser init
+    | Ast0.Decl(_,decl) -> r.V0.combiner_declaration decl
+    | _ -> do_nothing mk_statement r k e in
+
+  (* statementTag is preferred, because it indicates that one statement is
+  replaced by one statement, in single_statement *)
+  let stmt_dots r k e =
+    match Ast0.unwrap e with
+      Ast0.DOTS([s]) | Ast0.CIRCLES([s]) | Ast0.STARS([s]) ->
+       r.V0.combiner_statement s
+    | _ -> do_nothing mk_stmtdots r k e in
+
+  let toplevel r k e =
+    match Ast0.unwrap e with
+      Ast0.DECL(s) -> r.V0.combiner_statement s
+    | Ast0.CODE(sdots) -> r.V0.combiner_statement_dots sdots
+    | _ -> do_nothing mk_code r k e in
+
+  let initdots r k e = k e in
+
+  V0.combiner bind option_default
+    (imcode mk_meta) (imcode mk_token) (mcode mk_constant) (mcode mk_assignOp)
+    (mcode mk_fixOp)
+    (mcode mk_unaryOp) (mcode mk_binaryOp) (mcode mk_const_vol)
+    (mcode mk_sign) (mcode mk_structUnion)
+    (mcode mk_storage) (mcode mk_inc_file)
+    (do_nothing mk_exprdots) initdots
+    (do_nothing mk_paramdots) stmt_dots (do_nothing mk_decldots)
+    (do_nothing mk_casedots)
+    (do_nothing mk_ident) (do_nothing mk_expression)
+    (do_nothing mk_typeC) (do_nothing mk_init) (do_nothing mk_param)
+    (do_nothing mk_declaration)
+    stmt (do_nothing mk_case_line) toplevel
+
+let call_collect_plus context_nodes :
+    (int * (Ast0.info * Ast.anything) list) list =
+  List.map
+    (function e ->
+      match e with
+       Ast0.DotsExprTag(e) ->
+         (Ast0.get_index e,
+          (collect_plus_nodes e).V0.combiner_expression_dots e)
+      | Ast0.DotsInitTag(e) ->
+         (Ast0.get_index e,
+          (collect_plus_nodes e).V0.combiner_initialiser_list e)
+      | Ast0.DotsParamTag(e) ->
+         (Ast0.get_index e,
+          (collect_plus_nodes e).V0.combiner_parameter_list e)
+      | Ast0.DotsStmtTag(e) ->
+         (Ast0.get_index e,
+          (collect_plus_nodes e).V0.combiner_statement_dots e)
+      | Ast0.DotsDeclTag(e) ->
+         (Ast0.get_index e,
+          (collect_plus_nodes e).V0.combiner_declaration_dots e)
+      | Ast0.DotsCaseTag(e) ->
+         (Ast0.get_index e,
+          (collect_plus_nodes e).V0.combiner_case_line_dots e)
+      | Ast0.IdentTag(e) ->
+         (Ast0.get_index e,
+          (collect_plus_nodes e).V0.combiner_ident e)
+      | Ast0.ExprTag(e) ->
+         (Ast0.get_index e,
+          (collect_plus_nodes e).V0.combiner_expression e)
+      | Ast0.ArgExprTag(_) | Ast0.TestExprTag(_) ->
+         failwith "not possible - iso only"
+      | Ast0.TypeCTag(e) ->
+         (Ast0.get_index e,
+          (collect_plus_nodes e).V0.combiner_typeC e)
+      | Ast0.InitTag(e) ->
+         (Ast0.get_index e,
+          (collect_plus_nodes e).V0.combiner_initialiser e)
+      | Ast0.ParamTag(e) ->
+         (Ast0.get_index e,
+          (collect_plus_nodes e).V0.combiner_parameter e)
+      | Ast0.DeclTag(e) ->
+         (Ast0.get_index e,
+          (collect_plus_nodes e).V0.combiner_declaration e)
+      | Ast0.StmtTag(e) ->
+         (Ast0.get_index e,
+          (collect_plus_nodes e).V0.combiner_statement e)
+      | Ast0.CaseLineTag(e) ->
+         (Ast0.get_index e,
+          (collect_plus_nodes e).V0.combiner_case_line e)
+      | Ast0.TopTag(e) ->
+         (Ast0.get_index e,
+          (collect_plus_nodes e).V0.combiner_top_level e)
+      | Ast0.IsoWhenTag(_) -> failwith "only within iso phase"
+      | Ast0.IsoWhenTTag(_) -> failwith "only within iso phase"
+      | Ast0.IsoWhenFTag(_) -> failwith "only within iso phase"
+      | Ast0.MetaPosTag(p) -> failwith "metapostag only within iso phase")
+    context_nodes
+
+(* The plus fragments are converted to a list of lists of lists.
+Innermost list: Elements have type anything.  For any pair of successive
+elements, n and n+1, the ending line of n is the same as the starting line
+of n+1.
+Middle lists: For any pair of successive elements, n and n+1, the ending
+line of n is one less than the starting line of n+1.
+Outer list: For any pair of successive elements, n and n+1, the ending
+line of n is more than one less than the starting line of n+1. *)
+
+let logstart info = info.Ast0.logical_start
+let logend info = info.Ast0.logical_end
+
+let redo info start finish =
+  {{info with Ast0.logical_start = start} with Ast0.logical_end = finish}
+
+let rec find_neighbors (index,l) :
+    int * (Ast0.info * (Ast.anything list list)) list =
+  let rec loop = function
+      [] -> []
+    | (i,x)::rest ->
+       (match loop rest with
+         ((i1,(x1::rest_inner))::rest_middle)::rest_outer ->
+           let finish1 = logend i in
+           let start2 = logstart i1 in
+           if finish1 = start2
+           then
+             ((redo i (logstart i) (logend i1),(x::x1::rest_inner))
+              ::rest_middle)
+             ::rest_outer
+           else if finish1 + 1 = start2
+           then ((i,[x])::(i1,(x1::rest_inner))::rest_middle)::rest_outer
+           else [(i,[x])]::((i1,(x1::rest_inner))::rest_middle)::rest_outer
+       | _ -> [[(i,[x])]]) (* rest must be [] *) in
+  let res =
+    List.map
+      (function l ->
+       let (start_info,_) = List.hd l in
+       let (end_info,_) = List.hd (List.rev l) in
+       (redo start_info (logstart start_info) (logend end_info),
+        List.map (function (_,x) -> x) l))
+      (loop l) in
+  (index,res)
+
+let process_plus plus :
+    (int * (Ast0.info * Ast.anything list list) list) list =
+  List.concat
+    (List.map
+       (function x ->
+        List.map find_neighbors (call_collect_plus (collect_context x)))
+       plus)
+
+(* --------------------------------------------------------------------- *)
+(* --------------------------------------------------------------------- *)
+(* merge *)
+(*
+let merge_one = function
+    (m1::m2::minus_info,p::plus_info) ->
+      if p < m1, then
+         attach p to the beginning of m1.bef if m1 is Good, fail if it is bad
+      if p > m1 && p < m2, then consider the following possibilities, in order
+         m1 is Good and favored: attach to the beginning of m1.aft
+         m2 is Good and favored: attach to the beginning of m2.bef; drop m1
+         m1 is Good and unfavored: attach to the beginning of m1.aft
+         m2 is Good and unfavored: attach to the beginning of m2.bef; drop m1
+         also flip m1.bef if the first where > m1
+         if we drop m1, then flip m1.aft first
+      if p > m2
+         m2 is Good and favored: attach to the beginning of m2.aft; drop m1
+*)
+
+(* end of first argument < start/end of second argument *)
+let less_than_start info1 info2 =
+  info1.Ast0.logical_end < info2.Ast0.logical_start
+let less_than_end info1 info2 =
+  info1.Ast0.logical_end < info2.Ast0.logical_end
+let greater_than_end info1 info2 =
+  info1.Ast0.logical_start > info2.Ast0.logical_end
+let good_start info = info.Ast0.attachable_start
+let good_end info = info.Ast0.attachable_end
+
+let toplevel = function Toplevel -> true | Favored | Unfavored | Decl -> false
+let decl = function Decl -> true | Favored | Unfavored | Toplevel -> false
+let favored = function Favored -> true | Unfavored | Toplevel | Decl -> false
+
+let top_code =
+  List.for_all (List.for_all (function Ast.Code _ -> true | _ -> false))
+
+(* The following is probably not correct.  The idea is to detect what
+should be placed completely before the declaration.  So type/storage
+related things do not fall into this category, and complete statements do
+fall into this category.  But perhaps other things should be in this
+category as well, such as { or ;? *)
+let predecl_code =
+  let tester = function
+      (* the following should definitely be true *)
+      Ast.DeclarationTag _
+    | Ast.StatementTag _
+    | Ast.Rule_elemTag _
+    | Ast.StmtDotsTag _
+    | Ast.Code _ -> true
+      (* the following should definitely be false *)
+    | Ast.FullTypeTag _ | Ast.BaseTypeTag _ | Ast.StructUnionTag _
+    | Ast.SignTag _
+    | Ast.StorageTag _ | Ast.ConstVolTag _ | Ast.TypeCTag _ -> false
+      (* not sure about the rest *)
+    | _ -> false in
+  List.for_all (List.for_all tester)
+
+let pr = Printf.sprintf
+
+let insert thing thinginfo into intoinfo =
+  let get_last l = let l = List.rev l in (List.rev(List.tl l),List.hd l) in
+  let get_first l = (List.hd l,List.tl l) in
+  let thing_start = thinginfo.Ast0.logical_start in
+  let thing_end = thinginfo.Ast0.logical_end in
+  let thing_offset = thinginfo.Ast0.offset in
+  let into_start = intoinfo.Ast0.tline_start in
+  let into_end = intoinfo.Ast0.tline_end in
+  let into_left_offset = intoinfo.Ast0.left_offset in
+  let into_right_offset = intoinfo.Ast0.right_offset in
+  if thing_end < into_start && thing_start < into_start
+  then (thing@into,
+       {{intoinfo with Ast0.tline_start = thing_start}
+       with Ast0.left_offset = thing_offset})
+  else if thing_end = into_start && thing_offset < into_left_offset
+  then
+    let (prev,last) = get_last thing in
+    let (first,rest) = get_first into in
+    (prev@[last@first]@rest,
+     {{intoinfo with Ast0.tline_start = thing_start}
+     with Ast0.left_offset = thing_offset})
+  else if thing_start > into_end && thing_end > into_end
+  then (into@thing,
+       {{intoinfo with Ast0.tline_end = thing_end}
+       with Ast0.right_offset = thing_offset})
+  else if thing_start = into_end && thing_offset > into_right_offset
+  then
+    let (first,rest) = get_first thing in
+    let (prev,last) = get_last into in
+    (prev@[last@first]@rest,
+     {{intoinfo with Ast0.tline_end = thing_end}
+     with Ast0.right_offset = thing_offset})
+  else
+    begin
+      Printf.printf "thing start %d thing end %d into start %d into end %d\n"
+       thing_start thing_end into_start into_end;
+      Printf.printf "thing offset %d left offset %d right offset %d\n"
+       thing_offset into_left_offset into_right_offset;
+      Pretty_print_cocci.print_anything "" thing;
+      Pretty_print_cocci.print_anything "" into;
+      failwith "can't figure out where to put the + code"
+    end
+
+let init thing info =
+  (thing,
+   {Ast0.tline_start = info.Ast0.logical_start;
+     Ast0.tline_end = info.Ast0.logical_end;
+     Ast0.left_offset = info.Ast0.offset;
+     Ast0.right_offset = info.Ast0.offset})
+
+let attachbefore (infop,p) = function
+    Ast0.MINUS(replacements) ->
+      (match !replacements with
+       ([],ti) -> replacements := init p infop
+      |        (repl,ti) -> replacements := insert p infop repl ti)
+  | Ast0.CONTEXT(neighbors) ->
+      let (repl,ti1,ti2) = !neighbors in
+      (match repl with
+       Ast.BEFORE(bef) ->
+         let (bef,ti1) = insert p infop bef ti1 in
+         neighbors := (Ast.BEFORE(bef),ti1,ti2)
+      |        Ast.AFTER(aft) ->
+         let (bef,ti1) = init p infop in
+         neighbors := (Ast.BEFOREAFTER(bef,aft),ti1,ti2)
+      |        Ast.BEFOREAFTER(bef,aft) ->
+         let (bef,ti1) = insert p infop bef ti1 in
+         neighbors := (Ast.BEFOREAFTER(bef,aft),ti1,ti2)
+      |        Ast.NOTHING ->
+         let (bef,ti1) = init p infop in
+         neighbors := (Ast.BEFORE(bef),ti1,ti2))
+  | _ -> failwith "not possible for attachbefore"
+
+let attachafter (infop,p) = function
+    Ast0.MINUS(replacements) ->
+      (match !replacements with
+       ([],ti) -> replacements := init p infop
+      |        (repl,ti) -> replacements := insert p infop repl ti)
+  | Ast0.CONTEXT(neighbors) ->
+      let (repl,ti1,ti2) = !neighbors in
+      (match repl with
+       Ast.BEFORE(bef) ->
+         let (aft,ti2) = init p infop in
+         neighbors := (Ast.BEFOREAFTER(bef,aft),ti1,ti2)
+      |        Ast.AFTER(aft) ->
+         let (aft,ti2) = insert p infop aft ti2 in
+         neighbors := (Ast.AFTER(aft),ti1,ti2)
+      |        Ast.BEFOREAFTER(bef,aft) ->
+         let (aft,ti2) = insert p infop aft ti2 in
+         neighbors := (Ast.BEFOREAFTER(bef,aft),ti1,ti2)
+      |        Ast.NOTHING ->
+         let (aft,ti2) = init p infop in
+         neighbors := (Ast.AFTER(aft),ti1,ti2))
+  | _ -> failwith "not possible for attachbefore"
+
+let attach_all_before ps m =
+  List.iter (function x -> attachbefore x m) ps
+
+let attach_all_after ps m =
+  List.iter (function x -> attachafter x m) ps
+
+let split_at_end info ps =
+  let split_point =  info.Ast0.logical_end in
+  List.partition
+    (function (info,_) -> info.Ast0.logical_end < split_point)
+    ps
+
+let allminus = function
+    Ast0.MINUS(_) -> true
+  | _ -> false
+
+let rec before_m1 ((f1,infom1,m1) as x1) ((f2,infom2,m2) as x2) rest = function
+    [] -> ()
+  | (((infop,_) as p) :: ps) as all ->
+      if less_than_start infop infom1 or
+       (allminus m1 && less_than_end infop infom1) (* account for trees *)
+      then
+       if good_start infom1
+       then (attachbefore p m1; before_m1 x1 x2 rest ps)
+       else
+         failwith
+           (pr "%d: no available token to attach to" infop.Ast0.line_start)
+      else after_m1 x1 x2 rest all
+
+and after_m1 ((f1,infom1,m1) as x1) ((f2,infom2,m2) as x2) rest = function
+    [] -> ()
+  | (((infop,pcode) as p) :: ps) as all ->
+      (* if the following is false, then some + code is stuck in the middle
+        of some context code (m1).  could drop down to the token level.
+        this might require adjustments in ast0toast as well, when + code on
+        expressions is dropped down to + code on expressions.  it might
+        also break some invariants on which iso depends, particularly on
+        what it can infer from something being CONTEXT with no top-level
+        modifications.  for the moment, we thus give an error, asking the
+        user to rewrite the semantic patch. *)
+      if greater_than_end infop infom1 or is_minus m1 or !empty_isos
+      then
+       if less_than_start infop infom2
+       then
+         if predecl_code pcode && good_end infom1 && decl f1
+         then (attachafter p m1; after_m1 x1 x2 rest ps)
+         else if predecl_code pcode && good_start infom2 && decl f2
+         then before_m2 x2 rest all
+         else if top_code pcode && good_end infom1 && toplevel f1
+         then (attachafter p m1; after_m1 x1 x2 rest ps)
+         else if top_code pcode && good_start infom2 && toplevel f2
+         then before_m2 x2 rest all
+         else if good_end infom1 && favored f1
+         then (attachafter p m1; after_m1 x1 x2 rest ps)
+         else if good_start infom2 && favored f2
+         then before_m2 x2 rest all
+         else if good_end infom1
+         then (attachafter p m1; after_m1 x1 x2 rest ps)
+         else if good_start infom2
+         then before_m2 x2 rest all
+         else
+           failwith
+             (pr "%d: no available token to attach to" infop.Ast0.line_start)
+       else after_m2 x2 rest all
+      else
+       begin
+         Printf.printf "between: p start %d p end %d m1 start %d m1 end %d m2 start %d m2 end %d\n"
+           infop.Ast0.line_start infop.Ast0.line_end
+           infom1.Ast0.line_start infom1.Ast0.line_end
+           infom2.Ast0.line_start infom2.Ast0.line_end;
+         Pretty_print_cocci.print_anything "" pcode;
+         failwith
+           "The semantic patch is structured in a way that may give bad results with isomorphisms.  Please try to rewrite it by moving + code out from -/context terms."
+       end
+
+(* not sure this is safe.  if have iso problems, consider changing this
+to always return false *)
+and is_minus = function
+    Ast0.MINUS _ -> true
+  | _ -> false
+
+and before_m2 ((f2,infom2,m2) as x2) rest
+    (p : (Ast0.info * Ast.anything list list) list) =
+  match (rest,p) with
+    (_,[]) -> ()
+  | ([],((infop,_)::_)) ->
+      let (bef_m2,aft_m2) = split_at_end infom2 p in (* bef_m2 isn't empty *)
+      if good_start infom2
+      then (attach_all_before bef_m2 m2; after_m2 x2 rest aft_m2)
+      else
+       failwith
+         (pr "%d: no available token to attach to" infop.Ast0.line_start)
+  | (m::ms,_) -> before_m1 x2 m ms p
+
+and after_m2 ((f2,infom2,m2) as x2) rest
+    (p : (Ast0.info * Ast.anything list list) list) =
+  match (rest,p) with
+    (_,[]) -> ()
+  | ([],((infop,_)::_)) ->
+      if good_end infom2
+      then attach_all_after p m2
+      else
+       failwith
+         (pr "%d: no available token to attach to" infop.Ast0.line_start)
+  | (m::ms,_) -> after_m1 x2 m ms p
+
+let merge_one : (minus_join_point * Ast0.info * 'a) list *
+    (Ast0.info * Ast.anything list list) list -> unit = function (m,p) ->
+  (*
+  Printf.printf "minus code\n";
+  List.iter
+    (function (_,info,_) ->
+      Printf.printf "start %d end %d real_start %d real_end %d\n"
+       info.Ast0.logical_start info.Ast0.logical_end
+       info.Ast0.line_start info.Ast0.line_end)
+    m;
+  Printf.printf "plus code\n";
+  List.iter
+    (function (info,p) ->
+      Printf.printf "start %d end %d real_start %d real_end %d\n"
+       info.Ast0.logical_start info.Ast0.logical_end
+       info.Ast0.line_end info.Ast0.line_end;
+      Pretty_print_cocci.print_anything "" p;
+      Format.print_newline())
+    p;
+  *)
+  match (m,p) with
+    (_,[]) -> ()
+  | (m1::m2::restm,p) -> before_m1 m1 m2 restm p
+  | ([m],p) -> before_m2 m [] p
+  | ([],_) -> failwith "minus tree ran out before the plus tree"
+
+let merge minus_list plus_list =
+  (*
+  Printf.printf "minus list %s\n"
+    (String.concat " "
+       (List.map (function (x,_) -> string_of_int x) minus_list));
+  Printf.printf "plus list %s\n"
+    (String.concat " "
+       (List.map (function (x,_) -> string_of_int x) plus_list));
+  *)
+  List.iter
+    (function (index,minus_info) ->
+      let plus_info = List.assoc index plus_list in
+      merge_one (minus_info,plus_info))
+    minus_list
+
+(* --------------------------------------------------------------------- *)
+(* --------------------------------------------------------------------- *)
+(* Need to check that CONTEXT nodes have nothing attached to their tokens.
+If they do, they become MIXED *)
+
+let reevaluate_contextness =
+   let bind = (@) in
+   let option_default = [] in
+
+   let mcode (_,_,_,mc,_) =
+     match mc with
+       Ast0.CONTEXT(mc) -> let (ba,_,_) = !mc in [ba]
+     | _ -> [] in
+
+   let donothing r k e =
+     match Ast0.get_mcodekind e with
+       Ast0.CONTEXT(mc) ->
+        if List.exists (function Ast.NOTHING -> false | _ -> true) (k e)
+        then Ast0.set_mcodekind e (Ast0.MIXED(mc));
+        []
+     | _ -> let _ = k e in [] in
+
+  let res =
+    V0.combiner bind option_default
+      mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+      donothing donothing donothing donothing donothing donothing donothing
+      donothing
+      donothing donothing donothing donothing donothing donothing donothing in
+  res.V0.combiner_top_level
+
+(* --------------------------------------------------------------------- *)
+(* --------------------------------------------------------------------- *)
+
+let insert_plus minus plus ei =
+  empty_isos := ei;
+  let minus_stream = process_minus minus in
+  let plus_stream = process_plus plus in
+  merge minus_stream plus_stream;
+  List.iter (function x -> let _ =  reevaluate_contextness x in ()) minus
diff --git a/parsing_cocci/.#iso_pattern.ml.1.152 b/parsing_cocci/.#iso_pattern.ml.1.152
new file mode 100644 (file)
index 0000000..2a3bb2e
--- /dev/null
@@ -0,0 +1,2379 @@
+(*
+* Copyright 2005-2009, 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
+    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
+  | TypeMatch of reason list
+
+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();
+  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;
+  | TypeMatch reason_list ->
+      List.iter (function r -> interpret_reason name line r printer)
+       reason_list
+  | _ -> failwith "not possible"
+
+type 'a either = OK of 'a | Fail of reason
+
+let 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 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
+
+    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 init r k t =
+      bind (bind (pure_mcodekind (Ast0.get_mcodekind t)) (k t))
+       (match Ast0.unwrap t with
+         Ast0.MetaInit(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
+      donothing donothing donothing donothing donothing donothing
+      ident expression typeC init 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
+                       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)
+               | _ ->
+                   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,stringsa),Ast0.BaseType(tyb,stringsb)) ->
+             if tya = tyb
+             then
+               match_list check_mcode
+                 (function _ -> false) (function _ -> failwith "")
+                 stringsa stringsb
+             else return false
+         | (Ast0.Signed(signa,tya),Ast0.Signed(signb,tyb)) ->
+             if mcode_equal signa signb
+             then
+               conjunct_bindings (check_mcode signa signb)
+                 (match_option match_typeC tya tyb)
+             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.EnumName(kinda,namea),Ast0.EnumName(kindb,nameb)) ->
+             conjunct_bindings (check_mcode kinda kindb)
+               (match_ident namea nameb)
+         | (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 =
+    match Ast0.unwrap pattern with
+      Ast0.MetaInit(name,pure) ->
+       add_pure_binding name pure pure_sp_code.V0.combiner_initialiser
+         (function ini -> Ast0.InitTag ini)
+         i
+    | up ->
+       if not(checks_needed) or not(context_required) or is_context i
+       then
+         match (up,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.InitGccExt(designators1,e1,inia),
+            Ast0.InitGccExt(designators2,e2,inib)) ->
+              conjunct_many_bindings
+                [match_list match_designator
+                    (function _ -> false) (function _ -> failwith "")
+                    designators1 designators2;
+                  check_mcode e1 e2;
+                  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.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_designator pattern d =
+    match (pattern,d) with
+      (Ast0.DesignatorField(dota,ida),Ast0.DesignatorField(dotb,idb)) ->
+       conjunct_bindings (check_mcode dota dotb) (match_ident ida idb)
+    | (Ast0.DesignatorIndex(lba,expa,rba),
+       Ast0.DesignatorIndex(lbb,expb,rbb)) ->
+        conjunct_many_bindings
+          [check_mcode lba lbb; match_expr expa expb;
+            check_mcode rba rbb]
+    | (Ast0.DesignatorRange(lba,mina,dotsa,maxa,rba),
+       Ast0.DesignatorRange(lbb,minb,dotsb,maxb,rbb)) ->
+        conjunct_many_bindings
+          [check_mcode lba lbb; match_expr mina minb;
+            check_mcode dotsa dotsb; match_expr maxa maxb;
+            check_mcode rba rbb]
+    | _ -> return false
+
+  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 (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.CONTEXT(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: %s"
+                info.Ast0.line_start (Dumper.dump e)))
+    | _ -> donothing r k e in
+
+  V0.rebuilder
+    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
+    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
+    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
+    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
+    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 idcont x = x in
+             let rec negate e (*for rewrapping*) res (*code to process*) k =
+               (* k accumulates parens, to keep negation outside if no
+                  propagation is possible *)
+               match Ast0.unwrap res with
+                 Ast0.Unary(e1,op) when Ast0.unwrap_mcode op = Ast.Not ->
+                   k (Ast0.rewrap e (Ast0.unwrap e1))
+               | Ast0.Edots(_,_) -> k (Ast0.rewrap e (Ast0.unwrap res))
+               | Ast0.Paren(lp,e,rp) ->
+                   negate e e
+                     (function x ->
+                       k (Ast0.rewrap res (Ast0.Paren(lp,x,rp))))
+               | Ast0.Binary(e1,op,e2) ->
+                   let reb nop = Ast0.rewrap_mcode op (Ast.Logical(nop)) in
+                   let k1 x = k (Ast0.rewrap e x) in
+                   (match Ast0.unwrap_mcode op with
+                     Ast.Logical(Ast.Inf) ->
+                       k1 (Ast0.Binary(e1,reb Ast.SupEq,e2))
+                   | Ast.Logical(Ast.Sup) ->
+                       k1 (Ast0.Binary(e1,reb Ast.InfEq,e2))
+                   | Ast.Logical(Ast.InfEq) ->
+                       k1 (Ast0.Binary(e1,reb Ast.Sup,e2))
+                   | Ast.Logical(Ast.SupEq) ->
+                       k1 (Ast0.Binary(e1,reb Ast.Inf,e2))
+                   | Ast.Logical(Ast.Eq) ->
+                       k1 (Ast0.Binary(e1,reb Ast.NotEq,e2))
+                   | Ast.Logical(Ast.NotEq) ->
+                       k1 (Ast0.Binary(e1,reb Ast.Eq,e2))
+                   | Ast.Logical(Ast.AndLog) ->
+                       k1 (Ast0.Binary(negate e1 e1 idcont,reb Ast.OrLog,
+                                      negate e2 e2 idcont))
+                   | Ast.Logical(Ast.OrLog) ->
+                       k1 (Ast0.Binary(negate e1 e1 idcont,reb Ast.AndLog,
+                                      negate e2 e2 idcont))
+                   | _ ->
+                       Ast0.rewrap e
+                         (Ast0.Unary(k res,Ast0.rewrap_mcode op Ast.Not)))
+               | Ast0.DisjExpr(lp,exps,mids,rp) ->
+                     (* use res because it is the transformed argument *)
+                   let exps = List.map (function e -> negate e e k) 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(k res,Ast0.rewrap_mcode unop Ast.Not)) in
+             negate e exp idcont
+           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 initfn r k e =
+    let e = k e in
+    match Ast0.unwrap e with
+      Ast0.MetaInit(name,pure) ->
+       (rebuild_mcode None).V0.rebuilder_initialiser
+         (match lookup name bindings mv_bindings with
+           Common.Left(Ast0.InitTag(ty)) -> ty
+         | Common.Left(_) -> failwith "not possible 1"
+         | Common.Right(new_mv) ->
+             Ast0.rewrap e
+               (Ast0.MetaInit(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
+    (dots elist) donothing (dots plist) (dots slist) donothing donothing
+    identfn exprfn tyfn initfn 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.MetaInitDecl(ar,nm) ->
+      (nm,function nm -> Ast.MetaInitDecl(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])))
+             (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
+      (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 continue =
+     match Ast0.unwrap e with
+       Ast0.Signed(signb,tyb) ->
+       (* Hack!  How else to prevent iso from applying under an
+         unsigned??? *)
+        e
+     | _ -> k e in
+   let (extra_meta,ty) = transform_type alts continue 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
+      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
+    donothing donothing donothing donothing donothing donothing
+    donothing donothing donothing donothing donothing donothing donothing
+    donothing donothing
+
+let rewrap_anything = function
+    Ast0.DotsExprTag(d) ->
+      Ast0.DotsExprTag(rewrap.V0.rebuilder_expression_dots d)
+  | Ast0.DotsInitTag(d) ->
+      Ast0.DotsInitTag(rewrap.V0.rebuilder_initialiser_list d)
+  | Ast0.DotsParamTag(d) ->
+      Ast0.DotsParamTag(rewrap.V0.rebuilder_parameter_list d)
+  | Ast0.DotsStmtTag(d) ->
+      Ast0.DotsStmtTag(rewrap.V0.rebuilder_statement_dots d)
+  | Ast0.DotsDeclTag(d) ->
+      Ast0.DotsDeclTag(rewrap.V0.rebuilder_declaration_dots d)
+  | Ast0.DotsCaseTag(d) ->
+      Ast0.DotsCaseTag(rewrap.V0.rebuilder_case_line_dots d)
+  | Ast0.IdentTag(d) -> Ast0.IdentTag(rewrap.V0.rebuilder_ident d)
+  | Ast0.ExprTag(d) -> Ast0.ExprTag(rewrap.V0.rebuilder_expression d)
+  | Ast0.ArgExprTag(d) -> Ast0.ArgExprTag(rewrap.V0.rebuilder_expression d)
+  | Ast0.TestExprTag(d) -> Ast0.TestExprTag(rewrap.V0.rebuilder_expression d)
+  | Ast0.TypeCTag(d) -> Ast0.TypeCTag(rewrap.V0.rebuilder_typeC d)
+  | Ast0.InitTag(d) -> Ast0.InitTag(rewrap.V0.rebuilder_initialiser d)
+  | Ast0.ParamTag(d) -> Ast0.ParamTag(rewrap.V0.rebuilder_parameter d)
+  | Ast0.DeclTag(d) -> Ast0.DeclTag(rewrap.V0.rebuilder_declaration d)
+  | Ast0.StmtTag(d) -> Ast0.StmtTag(rewrap.V0.rebuilder_statement d)
+  | Ast0.CaseLineTag(d) -> Ast0.CaseLineTag(rewrap.V0.rebuilder_case_line d)
+  | Ast0.TopTag(d) -> Ast0.TopTag(rewrap.V0.rebuilder_top_level d)
+  | Ast0.IsoWhenTag(_) | Ast0.IsoWhenTTag(_) | Ast0.IsoWhenFTag(_) ->
+      failwith "only for isos within iso phase"
+  | Ast0.MetaPosTag(p) -> Ast0.MetaPosTag(p)
+
+(* --------------------------------------------------------------------- *)
+
+let apply_isos isos rule rule_name =
+  if isos = []
+  then ([],rule)
+  else
+    begin
+      current_rule := rule_name;
+      let isos =
+       List.map
+         (function (metavars,iso,name) ->
+           (metavars,List.map (List.map rewrap_anything) iso,name))
+         isos in
+      let (extra_meta,rule) =
+       List.split
+         (List.map
+            (function t ->
+              List.fold_left
+                (function (extra_meta,t) -> function iso ->
+                  let (new_extra_meta,t) = transform iso t in
+                  (new_extra_meta@extra_meta,t))
+                ([],t) isos)
+            rule) in
+      (List.concat extra_meta, Compute_lines.compute_lines rule)
+    end
diff --git a/parsing_cocci/.#lexer_cocci.mll.1.86 b/parsing_cocci/.#lexer_cocci.mll.1.86
new file mode 100644 (file)
index 0000000..f02c923
--- /dev/null
@@ -0,0 +1,712 @@
+(*
+* Copyright 2005-2009, 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 Parser_cocci_menhir
+module D = Data
+module Ast = Ast_cocci
+module Ast0 = Ast0_cocci
+module P = Parse_aux
+exception Lexical of string
+let tok = Lexing.lexeme
+
+let line = ref 1
+let logical_line = ref 0
+
+(* ---------------------------------------------------------------------- *)
+(* control codes *)
+
+(* Defined in data.ml
+type line_type = MINUS | OPTMINUS | UNIQUEMINUS | PLUS | CONTEXT | UNIQUE | OPT
+*)
+
+let current_line_type = ref (D.CONTEXT,!line,!logical_line)
+
+let prev_plus = ref false
+let line_start = ref 0 (* offset of the beginning of the line *)
+let get_current_line_type lexbuf =
+  let (c,l,ll) = !current_line_type in
+  let lex_start = Lexing.lexeme_start lexbuf in
+  let preceeding_spaces =
+    if !line_start < 0 then 0 else lex_start - !line_start in
+  line_start := -1;
+  prev_plus := (c = D.PLUS);
+  (c,l,ll,lex_start,preceeding_spaces,[],[],Ast0.NoMetaPos)
+let current_line_started = ref false
+let col_zero = ref true
+
+let reset_line lexbuf =
+  line := !line + 1;
+  current_line_type := (D.CONTEXT,!line,!logical_line);
+  current_line_started := false;
+  col_zero := true;
+  line_start := Lexing.lexeme_start lexbuf + 1
+
+let started_line = ref (-1)
+
+let start_line seen_char =
+  current_line_started := true;
+  col_zero := false;
+  (if seen_char && not(!line = !started_line)
+  then
+    begin
+      started_line := !line;
+      logical_line := !logical_line + 1
+    end)
+
+let pass_zero _ = col_zero := false
+
+let lexerr s1 s2 = raise (Lexical (Printf.sprintf "%s%s" s1 s2))
+
+let add_current_line_type x =
+  match (x,!current_line_type) with
+    (D.MINUS,(D.CONTEXT,ln,lln))  ->
+      current_line_type := (D.MINUS,ln,lln)
+  | (D.MINUS,(D.UNIQUE,ln,lln))   ->
+      current_line_type := (D.UNIQUEMINUS,ln,lln)
+  | (D.MINUS,(D.OPT,ln,lln))      ->
+      current_line_type := (D.OPTMINUS,ln,lln)
+  | (D.PLUS,(D.CONTEXT,ln,lln))   ->
+      current_line_type := (D.PLUS,ln,lln)
+  | (D.UNIQUE,(D.CONTEXT,ln,lln)) ->
+      current_line_type := (D.UNIQUE,ln,lln)
+  | (D.OPT,(D.CONTEXT,ln,lln))    ->
+      current_line_type := (D.OPT,ln,lln)
+  | _ -> lexerr "invalid control character combination" ""
+
+let check_minus_context_linetype s =
+  match !current_line_type with
+    (D.PLUS,_,_) -> lexerr "invalid in a + context: " s
+  | _ -> ()
+
+let check_context_linetype s =
+  match !current_line_type with
+    (D.CONTEXT,_,_) -> ()
+  | _ -> lexerr "invalid in a nonempty context: " s
+
+let check_plus_linetype s =
+  match !current_line_type with
+    (D.PLUS,_,_) -> ()
+  | _ -> lexerr "invalid in a non + context: " s
+
+let check_arity_context_linetype s =
+  match !current_line_type with
+    (D.CONTEXT,_,_) | (D.PLUS,_,_) | (D.UNIQUE,_,_) | (D.OPT,_,_) -> ()
+  | _ -> lexerr "invalid in a nonempty context: " s
+
+let process_include start finish str =
+  (match !current_line_type with
+    (D.PLUS,_,_) ->
+      (try
+       let _ = Str.search_forward (Str.regexp "\\.\\.\\.") str start in
+       lexerr "... not allowed in + include" ""
+      with Not_found -> ())
+  | _ -> ());
+  String.sub str (start + 1) (finish - start - 1)
+
+(* ---------------------------------------------------------------------- *)
+type pm = PATCH | MATCH | UNKNOWN
+
+let pm = ref UNKNOWN
+
+let patch_or_match = function
+    PATCH ->
+      (match !pm with
+       MATCH -> lexerr "- or + not allowed in the first column for a match" ""
+      |        PATCH -> ()
+      |        UNKNOWN -> Flag.sgrep_mode2 := false; pm := PATCH)
+  | MATCH ->
+      (match !pm with
+       PATCH -> lexerr "* not allowed in the first column for a patch" ""
+      |        MATCH -> ()
+      |        UNKNOWN -> Flag.sgrep_mode2 := true; pm := MATCH)
+  | _ -> failwith "unexpected argument"
+
+(* ---------------------------------------------------------------------- *)
+(* identifiers, including metavariables *)
+
+let metavariables = (Hashtbl.create(100) : (string, D.clt -> token) Hashtbl.t)
+
+let all_metavariables =
+  (Hashtbl.create(100) : (string,(string * (D.clt -> token)) list) Hashtbl.t)
+
+let type_names = (Hashtbl.create(100) : (string, D.clt -> token) Hashtbl.t)
+
+let declarer_names = (Hashtbl.create(100) : (string, D.clt -> token) Hashtbl.t)
+
+let iterator_names = (Hashtbl.create(100) : (string, D.clt -> token) Hashtbl.t)
+
+let rule_names = (Hashtbl.create(100) : (string, unit) Hashtbl.t)
+
+let check_var s linetype =
+  let fail _ =
+    if (!Data.in_prolog || !Data.in_rule_name) &&
+      Str.string_match (Str.regexp "<.*>") s 0
+    then TPathIsoFile s
+    else
+      try (Hashtbl.find metavariables s) linetype
+      with Not_found ->
+       (try (Hashtbl.find type_names s) linetype
+       with Not_found ->
+         (try (Hashtbl.find declarer_names s) linetype
+         with Not_found ->
+           (try (Hashtbl.find iterator_names s) linetype
+           with Not_found -> TIdent (s,linetype)))) in
+  if !Data.in_meta or !Data.in_rule_name
+  then (try Hashtbl.find rule_names s; TRuleName s with Not_found -> fail())
+  else fail()
+
+let id_tokens lexbuf =
+  let s = tok lexbuf in
+  let linetype = get_current_line_type lexbuf in
+  let in_rule_name = !Data.in_rule_name in
+  let in_meta = !Data.in_meta in
+  let in_iso = !Data.in_iso in
+  let in_prolog = !Data.in_prolog in
+  match s with
+    "identifier" when in_meta -> check_arity_context_linetype s; TIdentifier
+  | "type" when in_meta ->       check_arity_context_linetype s; TType
+  | "parameter" when in_meta ->  check_arity_context_linetype s; TParameter
+  | "constant"  when in_meta ->  check_arity_context_linetype s; TConstant
+  | "generated" when in_rule_name && not (!Flag.make_hrule = None) ->
+      check_arity_context_linetype s; TGenerated
+  | "expression" when in_meta || in_rule_name ->
+      check_arity_context_linetype s; TExpression
+  | "initialiser" when in_meta || in_rule_name ->
+      check_arity_context_linetype s; TInitialiser
+  | "initializer" when in_meta || in_rule_name ->
+      check_arity_context_linetype s; TInitialiser
+  | "idexpression" when in_meta ->
+      check_arity_context_linetype s; TIdExpression
+  | "statement" when in_meta ->  check_arity_context_linetype s; TStatement
+  | "function"  when in_meta ->  check_arity_context_linetype s; TFunction
+  | "local" when in_meta ->      check_arity_context_linetype s; TLocal
+  | "list" when in_meta ->       check_arity_context_linetype s; Tlist
+  | "fresh" when in_meta ->      check_arity_context_linetype s; TFresh
+  | "typedef" when in_meta ->    check_arity_context_linetype s; TTypedef
+  | "declarer" when in_meta ->   check_arity_context_linetype s; TDeclarer
+  | "iterator" when in_meta ->   check_arity_context_linetype s; TIterator
+  | "name" when in_meta ->       check_arity_context_linetype s; TName
+  | "position" when in_meta ->   check_arity_context_linetype s; TPosition
+  | "any" when in_meta ->        check_arity_context_linetype s; TPosAny
+  | "pure" when in_meta && in_iso ->
+      check_arity_context_linetype s; TPure
+  | "context" when in_meta && in_iso ->
+      check_arity_context_linetype s; TContext
+  | "error" when in_meta ->      check_arity_context_linetype s; TError
+  | "words" when in_meta ->      check_context_linetype s; TWords
+
+  | "using" when in_rule_name || in_prolog ->  check_context_linetype s; TUsing
+  | "disable" when in_rule_name ->  check_context_linetype s; TDisable
+  | "extends" when in_rule_name -> check_context_linetype s; TExtends
+  | "depends" when in_rule_name -> check_context_linetype s; TDepends
+  | "on" when in_rule_name      -> check_context_linetype s; TOn
+  | "ever" when in_rule_name    -> check_context_linetype s; TEver
+  | "never" when in_rule_name   -> check_context_linetype s; TNever
+  | "exists" when in_rule_name  -> check_context_linetype s; TExists
+  | "forall" when in_rule_name  -> check_context_linetype s; TForall
+  | "reverse" when in_rule_name -> check_context_linetype s; TReverse
+  | "script" when in_rule_name -> check_context_linetype s; TScript
+
+  | "char" ->       Tchar     linetype
+  | "short" ->      Tshort    linetype
+  | "int" ->        Tint      linetype
+  | "double" ->     Tdouble   linetype
+  | "float" ->      Tfloat    linetype
+  | "long" ->       Tlong     linetype
+  | "void" ->       Tvoid     linetype
+  | "struct" ->     Tstruct   linetype
+  | "union" ->      Tunion    linetype
+  | "enum" ->       Tenum     linetype
+  | "unsigned" ->   Tunsigned linetype
+  | "signed" ->     Tsigned   linetype
+
+  | "auto"  ->      Tauto     linetype
+  | "register" ->   Tregister linetype
+  | "extern" ->     Textern   linetype
+  | "static" ->     Tstatic   linetype
+  | "inline" ->     Tinline   linetype
+  | "typedef" ->    Ttypedef  linetype
+
+  | "const" ->      Tconst    linetype
+  | "volatile" ->   Tvolatile linetype
+
+  | "if" ->         TIf       linetype
+  | "else" ->       TElse     linetype
+  | "while" ->      TWhile    linetype
+  | "do" ->         TDo       linetype
+  | "for" ->        TFor      linetype
+  | "switch" ->     TSwitch   linetype
+  | "case" ->       TCase     linetype
+  | "default" ->    TDefault  linetype
+  | "return" ->     TReturn   linetype
+  | "break" ->      TBreak    linetype
+  | "continue" ->   TContinue linetype
+  | "goto" ->       TGoto     linetype
+
+  | "sizeof" ->     TSizeof   linetype
+
+  | "Expression"     -> TIsoExpression
+  | "ArgExpression"  -> TIsoArgExpression
+  | "TestExpression" -> TIsoTestExpression
+  | "Statement"      -> TIsoStatement
+  | "Declaration"    -> TIsoDeclaration
+  | "Type"           -> TIsoType
+  | "TopLevel"       -> TIsoTopLevel
+
+  | s -> check_var s linetype
+
+let mkassign op lexbuf =
+  TAssign (Ast.OpAssign op, (get_current_line_type lexbuf))
+
+let init _ =
+  line := 1;
+  logical_line := 0;
+  prev_plus := false;
+  line_start := 0;
+  current_line_started := false;
+  col_zero := true;
+  pm := UNKNOWN;
+  Data.in_rule_name := false;
+  Data.in_meta := false;
+  Data.in_prolog := false;
+  Data.inheritable_positions := [];
+  Hashtbl.clear all_metavariables;
+  Hashtbl.clear Data.all_metadecls;
+  Hashtbl.clear metavariables;
+  Hashtbl.clear type_names;
+  Hashtbl.clear rule_names;
+  let get_name (_,x) = x in
+  Data.add_id_meta :=
+    (fun name constraints pure ->
+      let fn clt = TMetaId(name,constraints,pure,clt) in
+      Hashtbl.replace metavariables (get_name name) fn);
+  Data.add_type_meta :=
+    (fun name pure ->
+      let fn clt = TMetaType(name,pure,clt) in
+      Hashtbl.replace metavariables (get_name name) fn);
+  Data.add_init_meta :=
+    (fun name pure ->
+      let fn clt = TMetaInit(name,pure,clt) in
+      Hashtbl.replace metavariables (get_name name) fn);
+  Data.add_param_meta :=
+    (function name -> function pure ->
+      let fn clt = TMetaParam(name,pure,clt) in
+      Hashtbl.replace metavariables (get_name name) fn);
+  Data.add_paramlist_meta :=
+    (function name -> function lenname -> function pure ->
+      let fn clt = TMetaParamList(name,lenname,pure,clt) in
+      Hashtbl.replace metavariables (get_name name) fn);
+  Data.add_const_meta :=
+    (fun tyopt name constraints pure ->
+      let fn clt = TMetaConst(name,constraints,pure,tyopt,clt) in
+      Hashtbl.replace metavariables (get_name name) fn);
+  Data.add_err_meta :=
+    (fun name constraints pure ->
+      let fn clt = TMetaErr(name,constraints,pure,clt) in
+      Hashtbl.replace metavariables (get_name name) fn);
+  Data.add_exp_meta :=
+    (fun tyopt name constraints pure ->
+      let fn clt = TMetaExp(name,constraints,pure,tyopt,clt) in
+      Hashtbl.replace metavariables (get_name name) fn);
+  Data.add_idexp_meta :=
+    (fun tyopt name constraints pure ->
+      let fn clt = TMetaIdExp(name,constraints,pure,tyopt,clt) in
+      Hashtbl.replace metavariables (get_name name) fn);
+  Data.add_local_idexp_meta :=
+    (fun tyopt name constraints pure ->
+      let fn clt = TMetaLocalIdExp(name,constraints,pure,tyopt,clt) in
+      Hashtbl.replace metavariables (get_name name) fn);
+  Data.add_explist_meta :=
+    (function name -> function lenname -> function pure ->
+      let fn clt = TMetaExpList(name,lenname,pure,clt) in
+      Hashtbl.replace metavariables (get_name name) fn);
+  Data.add_stm_meta :=
+    (function name -> function pure ->
+      let fn clt = TMetaStm(name,pure,clt) in
+      Hashtbl.replace metavariables (get_name name) fn);
+  Data.add_stmlist_meta :=
+    (function name -> function pure ->
+      let fn clt = TMetaStmList(name,pure,clt) in
+      Hashtbl.replace metavariables (get_name name) fn);
+  Data.add_func_meta :=
+    (fun name constraints pure ->
+      let fn clt = TMetaFunc(name,constraints,pure,clt) in
+      Hashtbl.replace metavariables (get_name name) fn);
+  Data.add_local_func_meta :=
+    (fun name constraints pure ->
+      let fn clt = TMetaLocalFunc(name,constraints,pure,clt) in
+      Hashtbl.replace metavariables (get_name name) fn);
+  Data.add_iterator_meta :=
+    (fun name constraints pure ->
+      let fn clt = TMetaIterator(name,constraints,pure,clt) in
+      Hashtbl.replace metavariables (get_name name) fn);
+  Data.add_declarer_meta :=
+    (fun name constraints pure ->
+      let fn clt = TMetaDeclarer(name,constraints,pure,clt) in
+      Hashtbl.replace metavariables (get_name name) fn);
+  Data.add_pos_meta :=
+    (fun name constraints any ->
+      let fn ((d,ln,_,_,_,_,_,_) as clt) =
+       (if d = Data.PLUS
+       then
+         failwith
+           (Printf.sprintf "%d: positions only allowed in minus code" ln));
+       TMetaPos(name,constraints,any,clt) in
+      Hashtbl.replace metavariables (get_name name) fn);
+  Data.add_type_name :=
+    (function name ->
+      let fn clt = TTypeId(name,clt) in
+      Hashtbl.replace type_names name fn);
+  Data.add_declarer_name :=
+    (function name ->
+      let fn clt = TDeclarerId(name,clt) in
+      Hashtbl.replace declarer_names name fn);
+  Data.add_iterator_name :=
+    (function name ->
+      let fn clt = TIteratorId(name,clt) in
+      Hashtbl.replace iterator_names name fn);
+  Data.init_rule := (function _ -> Hashtbl.clear metavariables);
+  Data.install_bindings :=
+    (function parent ->
+      List.iter (function (name,fn) -> Hashtbl.add metavariables name fn)
+       (Hashtbl.find all_metavariables parent))
+
+let drop_spaces s =
+  let len = String.length s in
+  let rec loop n =
+    if n = len
+    then n
+    else
+      if List.mem (String.get s n) [' ';'\t']
+      then loop (n+1)
+      else n in
+  let start = loop 0 in
+  String.sub s start (len - start)
+}
+
+(* ---------------------------------------------------------------------- *)
+(* tokens *)
+
+let letter = ['A'-'Z' 'a'-'z' '_']
+let digit  = ['0'-'9']
+
+let dec = ['0'-'9']
+let oct = ['0'-'7']
+let hex = ['0'-'9' 'a'-'f' 'A'-'F']
+
+let decimal = ('0' | (['1'-'9'] dec*))
+let octal   = ['0']        oct+
+let hexa    = ("0x" |"0X") hex+
+
+let pent   = dec+
+let pfract = dec+
+let sign = ['-' '+']
+let exp  = ['e''E'] sign? dec+
+let real = pent exp | ((pent? '.' pfract | pent '.' pfract? ) exp?)
+
+
+rule token = parse
+  | [' ' '\t'  ]+             { start_line false; token lexbuf }
+  | ['\n' '\r' '\011' '\012'] { reset_line lexbuf; token lexbuf }
+
+  | "//" [^ '\n']* { start_line false; token lexbuf }
+
+  | "@@" { start_line true; TArobArob }
+  | "@"  { pass_zero();
+          if !Data.in_rule_name or not !current_line_started
+          then (start_line true; TArob)
+          else (check_minus_context_linetype "@"; TPArob) }
+
+  | "WHEN" | "when"
+      { start_line true; check_minus_context_linetype (tok lexbuf);
+       TWhen (get_current_line_type lexbuf) }
+
+  | "..."
+      { start_line true; check_minus_context_linetype (tok lexbuf);
+       TEllipsis (get_current_line_type lexbuf) }
+(*
+  | "ooo"
+      { start_line true; check_minus_context_linetype (tok lexbuf);
+       TCircles (get_current_line_type lexbuf) }
+
+  | "***"
+      { start_line true; check_minus_context_linetype (tok lexbuf);
+       TStars (get_current_line_type lexbuf) }
+*)
+  | "<..." { start_line true; check_context_linetype (tok lexbuf);
+            TOEllipsis (get_current_line_type lexbuf) }
+  | "...>" { start_line true; check_context_linetype (tok lexbuf);
+            TCEllipsis (get_current_line_type lexbuf) }
+  | "<+..." { start_line true; check_context_linetype (tok lexbuf);
+            TPOEllipsis (get_current_line_type lexbuf) }
+  | "...+>" { start_line true; check_context_linetype (tok lexbuf);
+            TPCEllipsis (get_current_line_type lexbuf) }
+(*
+  | "<ooo" { start_line true; check_context_linetype (tok lexbuf);
+            TOCircles (get_current_line_type lexbuf) }
+  | "ooo>" { start_line true; check_context_linetype (tok lexbuf);
+            TCCircles (get_current_line_type lexbuf) }
+
+  | "<***" { start_line true; check_context_linetype (tok lexbuf);
+            TOStars (get_current_line_type lexbuf) }
+  | "***>" { start_line true; check_context_linetype (tok lexbuf);
+            TCStars (get_current_line_type lexbuf) }
+*)
+  | "-" { pass_zero();
+         if !current_line_started
+         then (start_line true; TMinus (get_current_line_type lexbuf))
+          else (patch_or_match PATCH;
+               add_current_line_type D.MINUS; token lexbuf) }
+  | "+" { pass_zero();
+         if !current_line_started
+         then (start_line true; TPlus (get_current_line_type lexbuf))
+          else if !Data.in_meta
+         then TPlus0
+          else (patch_or_match PATCH;
+               add_current_line_type D.PLUS; token lexbuf) }
+  | "?" { pass_zero();
+         if !current_line_started
+         then (start_line true; TWhy (get_current_line_type lexbuf))
+          else if !Data.in_meta
+         then TWhy0
+          else (add_current_line_type D.OPT; token lexbuf) }
+  | "!" { pass_zero();
+         if !current_line_started
+         then (start_line true; TBang (get_current_line_type lexbuf))
+          else if !Data.in_meta
+         then TBang0
+          else (add_current_line_type D.UNIQUE; token lexbuf) }
+  | "(" { if not !col_zero
+         then (start_line true; TOPar (get_current_line_type lexbuf))
+          else
+            (start_line true; check_context_linetype (tok lexbuf);
+            TOPar0 (get_current_line_type lexbuf))}
+  | "\\(" { start_line true; TOPar0 (get_current_line_type lexbuf) }
+  | "|" { if not (!col_zero)
+         then (start_line true; TOr(get_current_line_type lexbuf))
+          else (start_line true;
+               check_context_linetype (tok lexbuf);
+               TMid0 (get_current_line_type lexbuf))}
+  | "\\|" { start_line true; TMid0 (get_current_line_type lexbuf) }
+  | ")" { if not !col_zero
+         then (start_line true; TCPar (get_current_line_type lexbuf))
+          else
+            (start_line true; check_context_linetype (tok lexbuf);
+            TCPar0 (get_current_line_type lexbuf))}
+  | "\\)" { start_line true; TCPar0 (get_current_line_type lexbuf) }
+
+  | '[' { start_line true; TOCro (get_current_line_type lexbuf)   }
+  | ']' { start_line true; TCCro (get_current_line_type lexbuf)   }
+  | '{' { start_line true; TOBrace (get_current_line_type lexbuf) }
+  | '}' { start_line true; TCBrace (get_current_line_type lexbuf) }
+
+  | "->"           { start_line true; TPtrOp (get_current_line_type lexbuf)  }
+  | '.'            { start_line true; TDot (get_current_line_type lexbuf)    }
+  | ','            { start_line true; TComma (get_current_line_type lexbuf)  }
+  | ";"            { start_line true;
+                    if !Data.in_meta
+                    then TMPtVirg (* works better with tokens_all *)
+                    else TPtVirg (get_current_line_type lexbuf) }
+
+
+  | '*'            { pass_zero();
+                    if !current_line_started
+                    then
+                      (start_line true; TMul (get_current_line_type lexbuf))
+                    else
+                      (patch_or_match MATCH;
+                       add_current_line_type D.MINUS; token lexbuf) }
+  | '/'            { start_line true;
+                    TDmOp (Ast.Div,get_current_line_type lexbuf) }
+  | '%'            { start_line true;
+                    TDmOp (Ast.Mod,get_current_line_type lexbuf) }
+  | '~'            { start_line true;  TTilde (get_current_line_type lexbuf) }
+
+  | "++"           { start_line true;  TInc (get_current_line_type lexbuf) }
+  | "--"           { start_line true;  TDec (get_current_line_type lexbuf) }
+
+  | "="            { start_line true; TEq (get_current_line_type lexbuf) }
+
+  | "-="           { start_line true; mkassign Ast.Minus lexbuf }
+  | "+="           { start_line true; mkassign Ast.Plus lexbuf }
+
+  | "*="           { start_line true; mkassign Ast.Mul lexbuf }
+  | "/="           { start_line true; mkassign Ast.Div lexbuf }
+  | "%="           { start_line true; mkassign Ast.Mod lexbuf }
+
+  | "&="           { start_line true; mkassign Ast.And lexbuf }
+  | "|="           { start_line true; mkassign Ast.Or lexbuf }
+  | "^="           { start_line true; mkassign Ast.Xor lexbuf }
+
+  | "<<="          { start_line true; mkassign Ast.DecLeft lexbuf }
+  | ">>="          { start_line true; mkassign Ast.DecRight lexbuf }
+
+  | ":"            { start_line true; TDotDot (get_current_line_type lexbuf) }
+
+  | "=="           { start_line true; TEqEq   (get_current_line_type lexbuf) }
+  | "!="           { start_line true; TNotEq  (get_current_line_type lexbuf) }
+  | ">="           { start_line true;
+                    TLogOp(Ast.SupEq,get_current_line_type lexbuf) }
+  | "<="           { start_line true;
+                    TLogOp(Ast.InfEq,get_current_line_type lexbuf) }
+  | "<"            { start_line true;
+                    TLogOp(Ast.Inf,get_current_line_type lexbuf) }
+  | ">"            { start_line true;
+                    TLogOp(Ast.Sup,get_current_line_type lexbuf) }
+
+  | "&&"           { start_line true; TAndLog (get_current_line_type lexbuf) }
+  | "||"           { start_line true; TOrLog  (get_current_line_type lexbuf) }
+
+  | ">>"           { start_line true;
+                    TShOp(Ast.DecRight,get_current_line_type lexbuf) }
+  | "<<"           { start_line true;
+                    TShOp(Ast.DecLeft,get_current_line_type lexbuf) }
+
+  | "&"            { start_line true; TAnd    (get_current_line_type lexbuf) }
+  | "^"            { start_line true; TXor(get_current_line_type lexbuf) }
+
+  | ( ("#" [' ' '\t']*  "define" [' ' '\t']+))
+    ( (letter (letter |digit)*) as ident)
+      { start_line true;
+       let (arity,line,lline,offset,col,strbef,straft,pos) as lt =
+         get_current_line_type lexbuf in
+       let off = String.length "#define " in
+       (* -1 in the code below because the ident is not at the line start *)
+       TDefine
+         (lt,
+          check_var ident
+            (arity,line,lline,offset+off,(-1),[],[],Ast0.NoMetaPos)) }
+  | ( ("#" [' ' '\t']*  "define" [' ' '\t']+))
+    ( (letter (letter | digit)*) as ident)
+    '('
+      { start_line true;
+       let (arity,line,lline,offset,col,strbef,straft,pos) as lt =
+         get_current_line_type lexbuf in
+       let off = String.length "#define " in
+       TDefineParam
+        (lt,
+        check_var ident
+          (* why pos here but not above? *)
+          (arity,line,lline,offset+off,(-1),strbef,straft,pos),
+        offset + off + (String.length ident)) }
+  | "#" [' ' '\t']* "include" [' ' '\t']* '"' [^ '"']+ '"'
+      { TIncludeL
+         (let str = tok lexbuf in
+         let start = String.index str '"' in
+         let finish = String.rindex str '"' in
+         start_line true;
+         (process_include start finish str,get_current_line_type lexbuf)) }
+  | "#" [' ' '\t']* "include" [' ' '\t']* '<' [^ '>']+ '>'
+      { TIncludeNL
+         (let str = tok lexbuf in
+         let start = String.index str '<' in
+         let finish = String.rindex str '>' in
+         start_line true;
+         (process_include start finish str,get_current_line_type lexbuf)) }
+  | "#" [' ' '\t']* "if" [^'\n']*
+  | "#" [' ' '\t']* "ifdef" [^'\n']*
+  | "#" [' ' '\t']* "ifndef" [^'\n']*
+  | "#" [' ' '\t']* "else" [^'\n']*
+  | "#" [' ' '\t']* "elif" [^'\n']*
+  | "#" [' ' '\t']* "endif" [^'\n']*
+  | "#" [' ' '\t']* "error" [^'\n']*
+      { start_line true; check_plus_linetype (tok lexbuf);
+       TPragma (tok lexbuf) }
+  | "---" [^'\n']*
+      { (if !current_line_started
+      then lexerr "--- must be at the beginning of the line" "");
+       start_line true;
+       TMinusFile
+         (let str = tok lexbuf in
+         (drop_spaces(String.sub str 3 (String.length str - 3)),
+          (get_current_line_type lexbuf))) }
+  | "+++" [^'\n']*
+      { (if !current_line_started
+      then lexerr "+++ must be at the beginning of the line" "");
+       start_line true;
+       TPlusFile
+         (let str = tok lexbuf in
+         (drop_spaces(String.sub str 3 (String.length str - 3)),
+          (get_current_line_type lexbuf))) }
+
+  | letter (letter | digit)*
+      { start_line true; id_tokens lexbuf }
+
+  | "'" { start_line true;
+         TChar(char lexbuf,get_current_line_type lexbuf) }
+  | '"' { start_line true;
+         TString(string lexbuf,(get_current_line_type lexbuf)) }
+  | (real as x)    { start_line true;
+                    TFloat(x,(get_current_line_type lexbuf)) }
+  | ((( decimal | hexa | octal)
+      ( ['u' 'U']
+      | ['l' 'L']
+      | (['l' 'L'] ['u' 'U'])
+      | (['u' 'U'] ['l' 'L'])
+      | (['u' 'U'] ['l' 'L'] ['l' 'L'])
+      | (['l' 'L'] ['l' 'L'])
+      )?
+    ) as x) { start_line true; TInt(x,(get_current_line_type lexbuf)) }
+
+  | "<=>"          { TIso }
+  | "=>"           { TRightIso }
+
+  | eof            { EOF }
+
+  | _ { lexerr "unrecognised symbol, in token rule: " (tok lexbuf) }
+
+
+and char = parse
+  | (_ as x) "'"                                     { String.make 1 x }
+  | (("\\" (oct | oct oct | oct oct oct)) as x  "'") { x }
+  | (("\\x" (hex | hex hex)) as x  "'")       { x }
+  | (("\\" (_ as v)) as x "'")
+       { (match v with
+            | 'n' -> ()  | 't' -> ()   | 'v' -> ()  | 'b' -> ()
+           | 'r' -> ()  | 'f' -> () | 'a' -> ()
+           | '\\' -> () | '?'  -> () | '\'' -> ()  | '"' -> ()
+            | 'e' -> ()
+           | _ -> lexerr "unrecognised symbol: " (tok lexbuf)
+           );
+          x
+       }
+  | _ { lexerr "unrecognised symbol: " (tok lexbuf) }
+
+and string  = parse
+  | '"'                                       { "" }
+  | (_ as x)                   { Common.string_of_char x ^ string lexbuf }
+  | ("\\" (oct | oct oct | oct oct oct)) as x { x ^ string lexbuf }
+  | ("\\x" (hex | hex hex)) as x              { x ^ string lexbuf }
+  | ("\\" (_ as v)) as x
+       {
+         (match v with
+         | 'n' -> ()  | 't' -> ()   | 'v' -> ()  | 'b' -> () | 'r' -> ()
+        | 'f' -> () | 'a' -> ()
+        | '\\' -> () | '?'  -> () | '\'' -> ()  | '"' -> ()
+         | 'e' -> ()
+         | '\n' -> ()
+         | _ -> lexerr "unrecognised symbol:" (tok lexbuf)
+        );
+          x ^ string lexbuf
+       }
+  | _ { lexerr "unrecognised symbol: " (tok lexbuf) }
diff --git a/parsing_cocci/.#parse_aux.ml.1.27 b/parsing_cocci/.#parse_aux.ml.1.27
new file mode 100644 (file)
index 0000000..91df7e7
--- /dev/null
@@ -0,0 +1,482 @@
+(*
+* Copyright 2005-2009, 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.
+*)
+
+
+(* exports everything, used only by parser_cocci_menhir.mly *)
+module Ast0 = Ast0_cocci
+module Ast = Ast_cocci
+
+(* types for metavariable tokens *)
+type info = Ast.meta_name * Ast0.pure * Data.clt
+type idinfo = Ast.meta_name * Data.iconstraints * Ast0.pure * Data.clt
+type expinfo = Ast.meta_name * Data.econstraints * Ast0.pure * Data.clt
+type tyinfo = Ast.meta_name * Ast0.typeC list * Ast0.pure * Data.clt
+type list_info = Ast.meta_name * Ast.meta_name option * Ast0.pure * Data.clt
+type typed_info =
+    Ast.meta_name * Data.econstraints * Ast0.pure *
+      Type_cocci.typeC list option * Data.clt
+type pos_info = Ast.meta_name * Data.pconstraints * Ast.meta_collect * Data.clt
+
+
+let get_option fn = function
+    None -> None
+  | Some x -> Some (fn x)
+
+let make_info line logical_line offset col strbef straft =
+  { Ast0.line_start = line; Ast0.line_end = line;
+    Ast0.logical_start = logical_line; Ast0.logical_end = logical_line;
+    Ast0.attachable_start = true; Ast0.attachable_end = true;
+    Ast0.mcode_start = []; Ast0.mcode_end = [];
+    Ast0.column = col; Ast0.offset = offset;
+    Ast0.strings_before = strbef; Ast0.strings_after = straft; }
+
+let clt2info (_,line,logical_line,offset,col,strbef,straft,pos) =
+  make_info line logical_line offset col strbef straft
+
+let drop_bef (arity,line,lline,offset,col,strbef,straft,pos) =
+  (arity,line,lline,offset,col,[],straft,pos)
+
+let drop_aft (arity,line,lline,offset,col,strbef,straft,pos) =
+  (arity,line,lline,offset,col,strbef,[],pos)
+
+let clt2mcode str = function
+    (Data.MINUS,line,lline,offset,col,strbef,straft,pos)       ->
+      (str,Ast0.NONE,make_info line lline offset col strbef straft,
+       Ast0.MINUS(ref([],Ast0.default_token_info)),ref pos)
+  | (Data.OPTMINUS,line,lline,offset,col,strbef,straft,pos)    ->
+      (str,Ast0.OPT,make_info line lline offset col strbef straft,
+       Ast0.MINUS(ref([],Ast0.default_token_info)),ref pos)
+  | (Data.UNIQUEMINUS,line,lline,offset,col,strbef,straft,pos) ->
+      (str,Ast0.UNIQUE,make_info line lline offset col strbef straft,
+       Ast0.MINUS(ref([],Ast0.default_token_info)),ref pos)
+  | (Data.PLUS,line,lline,offset,col,strbef,straft,pos)        ->
+      (str,Ast0.NONE,make_info line lline offset col strbef straft,Ast0.PLUS,
+       ref pos)
+  | (Data.CONTEXT,line,lline,offset,col,strbef,straft,pos)     ->
+      (str,Ast0.NONE,make_info line lline offset col strbef straft,
+       Ast0.CONTEXT(ref(Ast.NOTHING,
+                       Ast0.default_token_info,Ast0.default_token_info)),
+       ref pos)
+  | (Data.OPT,line,lline,offset,col,strbef,straft,pos)         ->
+      (str,Ast0.OPT,make_info line lline offset col strbef straft,
+       Ast0.CONTEXT(ref(Ast.NOTHING,
+                       Ast0.default_token_info,Ast0.default_token_info)),
+       ref pos)
+  | (Data.UNIQUE,line,lline,offset,col,strbef,straft,pos)      ->
+      (str,Ast0.UNIQUE,make_info line lline offset col strbef straft,
+       Ast0.CONTEXT(ref(Ast.NOTHING,
+                       Ast0.default_token_info,Ast0.default_token_info)),
+       ref pos)
+
+let id2name   (name, clt) = name
+let id2clt    (name, clt) = clt
+let id2mcode  (name, clt) = clt2mcode name clt
+
+let mkdots str (dot,whencode) =
+  match str with
+    "..." -> Ast0.wrap(Ast0.Dots(clt2mcode str dot, whencode))
+  | "ooo" -> Ast0.wrap(Ast0.Circles(clt2mcode str dot, whencode))
+  | "***" -> Ast0.wrap(Ast0.Stars(clt2mcode str dot, whencode))
+  | _ -> failwith "cannot happen"
+
+let mkedots str (dot,whencode) =
+  match str with
+    "..." -> Ast0.wrap(Ast0.Edots(clt2mcode str dot, whencode))
+  | "ooo" -> Ast0.wrap(Ast0.Ecircles(clt2mcode str dot, whencode))
+  | "***" -> Ast0.wrap(Ast0.Estars(clt2mcode str dot, whencode))
+  | _ -> failwith "cannot happen"
+
+let mkdpdots str dot =
+  match str with
+    "..." -> Ast0.wrap(Ast0.DPdots(clt2mcode str dot))
+  | "ooo" -> Ast0.wrap(Ast0.DPcircles(clt2mcode str dot))
+  | _ -> failwith "cannot happen"
+
+let mkidots str (dot,whencode) =
+  match str with
+    "..." -> Ast0.wrap(Ast0.Idots(clt2mcode str dot, whencode))
+  | _ -> failwith "cannot happen"
+
+let mkddots str (dot,whencode) =
+  match (str,whencode) with
+    ("...",None) -> Ast0.wrap(Ast0.Ddots(clt2mcode str dot, None))
+  | ("...",Some [w]) -> Ast0.wrap(Ast0.Ddots(clt2mcode str dot, Some w))
+  | _ -> failwith "cannot happen"
+
+let mkpdots str dot =
+  match str with
+    "..." -> Ast0.wrap(Ast0.Pdots(clt2mcode str dot))
+  | "ooo" -> Ast0.wrap(Ast0.Pcircles(clt2mcode str dot))
+  | _ -> failwith "cannot happen"
+
+let arith_op ast_op left op right =
+  Ast0.wrap
+    (Ast0.Binary(left, clt2mcode (Ast.Arith ast_op) op, right))
+
+let logic_op ast_op left op right =
+  Ast0.wrap
+    (Ast0.Binary(left, clt2mcode (Ast.Logical ast_op) op, right))
+
+let make_cv cv ty =
+  match cv with None -> ty | Some x -> Ast0.wrap (Ast0.ConstVol(x,ty))
+
+let top_dots l =
+  let circle x =
+    match Ast0.unwrap x with Ast0.Circles(_) -> true | _ -> false in
+  let star x =
+    match Ast0.unwrap x with Ast0.Stars(_) -> true | _ -> false in
+  if List.exists circle l
+  then Ast0.wrap(Ast0.CIRCLES(l))
+  else
+    if List.exists star l
+    then Ast0.wrap(Ast0.STARS(l))
+    else Ast0.wrap(Ast0.DOTS(l))
+
+(* here the offset is that of the first in the sequence of *s, not that of
+each * individually *)
+let pointerify ty m =
+  List.fold_left
+    (function inner ->
+      function cur ->
+       Ast0.wrap(Ast0.Pointer(inner,clt2mcode "*" cur)))
+    ty m
+
+let ty_pointerify ty m =
+  List.fold_left
+    (function inner -> function cur -> Type_cocci.Pointer(inner))
+    ty m
+
+(* Left is <=>, Right is =>.  Collect <=>s. *)
+(* The parser should have done this, with precedences.  But whatever... *)
+let iso_adjust fn first rest =
+  let rec loop = function
+      [] -> [[]]
+    | (Common.Left x)::rest ->
+       (match loop rest with
+         front::after -> (fn x::front)::after
+       | _ -> failwith "not possible")
+    | (Common.Right x)::rest ->
+       (match loop rest with
+         front::after -> []::(fn x::front)::after
+       | _ -> failwith "not possible") in
+  match loop rest with
+    front::after -> (fn first::front)::after
+  | _ -> failwith "not possible"
+
+let check_meta tok =
+  let lookup rule name =
+    try
+      let info = Hashtbl.find Data.all_metadecls rule in
+      List.find (function mv -> Ast.get_meta_name mv = (rule,name)) info
+    with
+      Not_found ->
+       raise
+         (Semantic_cocci.Semantic
+            ("bad rule "^rule^" or bad variable "^name)) in
+  match tok with
+    Ast.MetaIdDecl(Ast.NONE,(rule,name)) ->
+      (match lookup rule name with
+       Ast.MetaIdDecl(_,_) | Ast.MetaFreshIdDecl(_,_) -> ()
+      | _ ->
+         raise
+           (Semantic_cocci.Semantic
+              ("incompatible inheritance declaration "^name)))
+  | Ast.MetaFreshIdDecl(Ast.NONE,(rule,name)) ->
+      raise
+       (Semantic_cocci.Semantic
+          "can't inherit the freshness of an identifier")
+  | Ast.MetaListlenDecl((rule,name)) ->
+      (match lookup rule name with
+       Ast.MetaListlenDecl(_) -> ()
+      | _ ->
+         raise
+           (Semantic_cocci.Semantic
+              ("incompatible inheritance declaration "^name)))
+  | Ast.MetaTypeDecl(Ast.NONE,(rule,name)) ->
+      (match lookup rule name with
+       Ast.MetaTypeDecl(_,_) -> ()
+      | _ ->
+         raise
+           (Semantic_cocci.Semantic
+              ("incompatible inheritance declaration "^name)))
+  | Ast.MetaInitDecl(Ast.NONE,(rule,name)) ->
+      (match lookup rule name with
+       Ast.MetaInitDecl(_,_) -> ()
+      | _ ->
+         raise
+           (Semantic_cocci.Semantic
+              ("incompatible inheritance declaration "^name)))
+  | Ast.MetaParamDecl(Ast.NONE,(rule,name)) ->
+      (match lookup rule name with
+       Ast.MetaParamDecl(_,_) -> ()
+      | _ ->
+         raise
+           (Semantic_cocci.Semantic
+              ("incompatible inheritance declaration "^name)))
+  | Ast.MetaParamListDecl(Ast.NONE,(rule,name),len_name) ->
+      (match lookup rule name with
+       Ast.MetaParamListDecl(_,_,_) -> ()
+      | _ ->
+         raise
+           (Semantic_cocci.Semantic
+              ("incompatible inheritance declaration "^name)))
+  | Ast.MetaErrDecl(Ast.NONE,(rule,name)) ->
+      (match lookup rule name with
+       Ast.MetaErrDecl(_,_) -> ()
+      | _ ->
+         raise
+           (Semantic_cocci.Semantic
+              ("incompatible inheritance declaration "^name)))
+  | Ast.MetaExpDecl(Ast.NONE,(rule,name),ty) ->
+      (match lookup rule name with
+       Ast.MetaExpDecl(_,_,ty1) when ty = ty1 -> ()
+      | _ ->
+         raise
+           (Semantic_cocci.Semantic
+              ("incompatible inheritance declaration "^name)))
+  | Ast.MetaIdExpDecl(Ast.NONE,(rule,name),ty) ->
+      (match lookup rule name with
+       Ast.MetaIdExpDecl(_,_,ty1) when ty = ty1 -> ()
+      | _ ->
+         raise
+           (Semantic_cocci.Semantic
+              ("incompatible inheritance declaration "^name)))
+  | Ast.MetaLocalIdExpDecl(Ast.NONE,(rule,name),ty) ->
+      (match lookup rule name with
+       Ast.MetaLocalIdExpDecl(_,_,ty1) when ty = ty1 -> ()
+      | _ ->
+         raise
+           (Semantic_cocci.Semantic
+              ("incompatible inheritance declaration "^name)))
+  | Ast.MetaExpListDecl(Ast.NONE,(rule,name),len_name) ->
+      (match lookup rule name with
+       Ast.MetaExpListDecl(_,_,_) -> ()
+      | Ast.MetaParamListDecl(_,_,_) when not (!Flag.make_hrule = None) -> ()
+      | _ ->
+         raise
+           (Semantic_cocci.Semantic
+              ("incompatible inheritance declaration "^name)))
+  | Ast.MetaStmDecl(Ast.NONE,(rule,name)) ->
+      (match lookup rule name with
+       Ast.MetaStmDecl(_,_) -> ()
+      | _ ->
+         raise
+           (Semantic_cocci.Semantic
+              ("incompatible inheritance declaration "^name)))
+  | Ast.MetaStmListDecl(Ast.NONE,(rule,name)) ->
+      (match lookup rule name with
+       Ast.MetaStmListDecl(_,_) -> ()
+      | _ ->
+         raise
+           (Semantic_cocci.Semantic
+              ("incompatible inheritance declaration "^name)))
+  | Ast.MetaFuncDecl(Ast.NONE,(rule,name)) ->
+      (match lookup rule name with
+       Ast.MetaFuncDecl(_,_) -> ()
+      | _ ->
+         raise
+           (Semantic_cocci.Semantic
+              ("incompatible inheritance declaration "^name)))
+  | Ast.MetaLocalFuncDecl(Ast.NONE,(rule,name)) ->
+      (match lookup rule name with
+       Ast.MetaLocalFuncDecl(_,_) -> ()
+      | _ ->
+         raise
+           (Semantic_cocci.Semantic
+              ("incompatible inheritance declaration "^name)))
+  | Ast.MetaConstDecl(Ast.NONE,(rule,name),ty) ->
+      (match lookup rule name with
+       Ast.MetaConstDecl(_,_,ty1) when ty = ty1 -> ()
+      | _ ->
+         raise
+           (Semantic_cocci.Semantic
+              ("incompatible inheritance declaration "^name)))
+  | Ast.MetaPosDecl(Ast.NONE,(rule,name)) ->
+      (match lookup rule name with
+       Ast.MetaPosDecl(_,_) ->
+         if not (List.mem rule !Data.inheritable_positions)
+         then
+           raise
+             (Semantic_cocci.Semantic
+                ("position cannot be inherited over modifications: "^name))
+      | _ ->
+         raise
+           (Semantic_cocci.Semantic
+              ("incompatible inheritance declaration "^name)))
+  | _ ->
+      raise
+       (Semantic_cocci.Semantic ("arity not allowed on imported declaration"))
+
+let create_metadec ar ispure kindfn ids current_rule =
+  List.concat
+    (List.map
+       (function (rule,nm) ->
+        let (rule,checker) =
+          match rule with
+            None -> ((current_rule,nm),function x -> [Common.Left x])
+          | Some rule ->
+              ((rule,nm),
+               function x -> check_meta x; [Common.Right x]) in
+        kindfn ar rule ispure checker)
+       ids)
+
+let create_metadec_ne ar ispure kindfn ids current_rule =
+  List.concat
+    (List.map
+       (function ((rule,nm),constraints) ->
+        let (rule,checker) =
+          match rule with
+            None -> ((current_rule,nm),function x -> [Common.Left x])
+          | Some rule ->
+              ((rule,nm),
+               function x -> check_meta x; [Common.Right x]) in
+        kindfn ar rule ispure checker constraints)
+       ids)
+
+let create_metadec_ty ar ispure kindfn ids current_rule =
+  List.concat
+    (List.map
+       (function ((rule,nm),constraints) ->
+        let (rule,checker) =
+          match rule with
+            None -> ((current_rule,nm),function x -> [Common.Left x])
+          | Some rule ->
+              ((rule,nm),
+               function x -> check_meta x; [Common.Right x]) in
+        kindfn ar rule ispure checker constraints)
+       ids)
+
+let create_len_metadec ar ispure kindfn lenid ids current_rule =
+  let lendec =
+    create_metadec Ast.NONE Ast0.Impure
+      (fun _ name _ check_meta -> check_meta(Ast.MetaListlenDecl(name)))
+      [lenid] current_rule in
+  let lenname =
+    match lendec with
+      [Common.Left (Ast.MetaListlenDecl(x))] -> x
+    | [Common.Right (Ast.MetaListlenDecl(x))] -> x
+    | _ -> failwith "unexpected length declaration" in
+  lendec@(create_metadec ar ispure (kindfn lenname) ids current_rule)
+
+(* ---------------------------------------------------------------------- *)
+
+let str2inc s =
+  let elements = Str.split (Str.regexp "/") s in
+  List.map (function "..." -> Ast.IncDots | s -> Ast.IncPath s) elements
+
+(* ---------------------------------------------------------------------- *)
+(* statements *)
+
+let meta_stm name =
+  let (nm,pure,clt) = name in
+  Ast0.wrap(Ast0.MetaStmt(clt2mcode nm clt,pure))
+
+let exp_stm exp pv =
+  Ast0.wrap(Ast0.ExprStatement (exp, clt2mcode ";" pv))
+
+let ifthen iff lp tst rp thn =
+  Ast0.wrap(Ast0.IfThen(clt2mcode "if" iff,
+    clt2mcode "(" lp,tst,clt2mcode ")" rp,thn,
+    (Ast0.default_info(),Ast0.context_befaft())))
+
+let ifthenelse iff lp tst rp thn e els =
+  Ast0.wrap(Ast0.IfThenElse(clt2mcode "if" iff,
+    clt2mcode "(" lp,tst,clt2mcode ")" rp,thn,
+    clt2mcode "else" e,els,
+    (Ast0.default_info(),Ast0.context_befaft())))
+
+let forloop fr lp e1 sc1 e2 sc2 e3 rp s =
+  Ast0.wrap(Ast0.For(clt2mcode "for" fr,clt2mcode "(" lp,e1,
+                    clt2mcode ";" sc1,e2,
+                    clt2mcode ";" sc2,e3,clt2mcode ")" rp,s,
+                    (Ast0.default_info(),Ast0.context_befaft())))
+
+let whileloop w lp e rp s =
+  Ast0.wrap(Ast0.While(clt2mcode "while" w,clt2mcode "(" lp,
+                      e,clt2mcode ")" rp,s,
+                      (Ast0.default_info(),Ast0.context_befaft())))
+
+let doloop d s w lp e rp pv =
+  Ast0.wrap(Ast0.Do(clt2mcode "do" d,s,clt2mcode "while" w,
+                   clt2mcode "(" lp,e,clt2mcode ")" rp,
+                   clt2mcode ";" pv))
+
+let iterator i lp e rp s =
+  Ast0.wrap(Ast0.Iterator(i,clt2mcode "(" lp,e,clt2mcode ")" rp,s,
+                         (Ast0.default_info(),Ast0.context_befaft())))
+
+let switch s lp e rp lb c rb =
+  Ast0.wrap(Ast0.Switch(clt2mcode "switch" s,clt2mcode "(" lp,e,
+                       clt2mcode ")" rp,clt2mcode "{" lb,
+                       Ast0.wrap(Ast0.DOTS(c)),clt2mcode "}" rb))
+
+let ret_exp r e pv =
+  Ast0.wrap(Ast0.ReturnExpr(clt2mcode "return" r,e,clt2mcode ";" pv))
+
+let ret r pv =
+  Ast0.wrap(Ast0.Return(clt2mcode "return" r,clt2mcode ";" pv))
+
+let break b pv =
+  Ast0.wrap(Ast0.Break(clt2mcode "break" b,clt2mcode ";" pv))
+
+let cont c pv =
+  Ast0.wrap(Ast0.Continue(clt2mcode "continue" c,clt2mcode ";" pv))
+
+let label i dd =
+  Ast0.wrap(Ast0.Label(i,clt2mcode ":" dd))
+
+let goto g i pv =
+  Ast0.wrap(Ast0.Goto(clt2mcode "goto" g,i,clt2mcode ";" pv))
+
+let seq lb s rb =
+  Ast0.wrap(Ast0.Seq(clt2mcode "{" lb,s,clt2mcode "}" rb))
+
+(* ---------------------------------------------------------------------- *)
+
+let make_iso_rule_name_result n =
+    (try let _ =  Hashtbl.find Data.all_metadecls n in
+    raise (Semantic_cocci.Semantic ("repeated rule name"))
+    with Not_found -> ());
+    Ast.CocciRulename (Some n,Ast.NoDep,[],[],Ast.Undetermined,false (*discarded*))
+
+let make_cocci_rule_name_result nm d i a e ee =
+  match nm with
+    Some nm ->
+      let n = id2name nm in
+      (try let _ =  Hashtbl.find Data.all_metadecls n in
+      raise (Semantic_cocci.Semantic ("repeated rule name"))
+      with Not_found -> ());
+      Ast.CocciRulename (Some n,d,i,a,e,ee)
+  | None -> Ast.CocciRulename (None,d,i,a,e,ee)
+
+let make_generated_rule_name_result nm d i a e ee =
+  match nm with
+    Some nm ->
+      let n = id2name nm in
+      (try let _ =  Hashtbl.find Data.all_metadecls n in
+      raise (Semantic_cocci.Semantic ("repeated rule name"))
+      with Not_found -> ());
+      Ast.GeneratedRulename (Some n,d,i,a,e,ee)
+  | None -> Ast.GeneratedRulename (None,d,i,a,e,ee)
+
+let make_script_rule_name_result lang deps =
+  let l = id2name lang in
+       Ast.ScriptRulename (l,deps)
diff --git a/parsing_cocci/.#parse_cocci.ml.1.180 b/parsing_cocci/.#parse_cocci.ml.1.180
new file mode 100644 (file)
index 0000000..91c0768
--- /dev/null
@@ -0,0 +1,1628 @@
+(*
+* Copyright 2005-2009, 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.
+*)
+
+
+(* splits the entire file into minus and plus fragments, and parses each
+separately (thus duplicating work for the parsing of the context elements) *)
+
+module D = Data
+module PC = Parser_cocci_menhir
+module V0 = Visitor_ast0
+module Ast = Ast_cocci
+module Ast0 = Ast0_cocci
+let pr = Printf.sprintf
+(*let pr2 s = prerr_string s; prerr_string "\n"; flush stderr*)
+let pr2 s = Printf.printf "%s\n" s
+
+(* for isomorphisms.  all should be at the front!!! *)
+let reserved_names =
+  ["all";"optional_storage";"optional_qualifier";"value_format";"comm_assoc"]
+
+(* ----------------------------------------------------------------------- *)
+(* Debugging... *)
+
+let line_type (d,_,_,_,_,_,_,_) = d
+
+let line_type2c tok =
+  match line_type tok with
+    D.MINUS | D.OPTMINUS | D.UNIQUEMINUS -> ":-"
+  | D.PLUS -> ":+"
+  | D.CONTEXT | D.UNIQUE | D.OPT -> ""
+
+let token2c (tok,_) =
+ match tok with
+    PC.TIdentifier -> "identifier"
+  | PC.TType -> "type"
+  | PC.TParameter -> "parameter"
+  | PC.TConstant -> "constant"
+  | PC.TExpression -> "expression"
+  | PC.TIdExpression -> "idexpression"
+  | PC.TInitialiser -> "initialiser"
+  | PC.TStatement -> "statement"
+  | PC.TPosition -> "position"
+  | PC.TPosAny -> "any"
+  | PC.TFunction -> "function"
+  | PC.TLocal -> "local"
+  | PC.Tlist -> "list"
+  | PC.TFresh -> "fresh"
+  | PC.TPure -> "pure"
+  | PC.TContext -> "context"
+  | PC.TTypedef -> "typedef"
+  | PC.TDeclarer -> "declarer"
+  | PC.TIterator -> "iterator"
+  | PC.TName -> "name"
+  | PC.TRuleName str -> "rule_name-"^str
+  | PC.TUsing -> "using"
+  | PC.TPathIsoFile str -> "path_iso_file-"^str
+  | PC.TDisable -> "disable"
+  | PC.TExtends -> "extends"
+  | PC.TDepends -> "depends"
+  | PC.TOn -> "on"
+  | PC.TEver -> "ever"
+  | PC.TNever -> "never"
+  | PC.TExists -> "exists"
+  | PC.TForall -> "forall"
+  | PC.TReverse -> "reverse"
+  | PC.TError -> "error"
+  | PC.TWords -> "words"
+  | PC.TGenerated -> "generated"
+
+  | PC.TNothing -> "nothing"
+
+  | PC.Tchar(clt) -> "char"^(line_type2c  clt)
+  | PC.Tshort(clt) -> "short"^(line_type2c clt)
+  | PC.Tint(clt) -> "int"^(line_type2c clt)
+  | PC.Tdouble(clt) -> "double"^(line_type2c clt)
+  | PC.Tfloat(clt) -> "float"^(line_type2c clt)
+  | PC.Tlong(clt) -> "long"^(line_type2c clt)
+  | PC.Tvoid(clt) -> "void"^(line_type2c clt)
+  | PC.Tstruct(clt) -> "struct"^(line_type2c clt)
+  | PC.Tunion(clt) -> "union"^(line_type2c clt)
+  | PC.Tenum(clt) -> "enum"^(line_type2c clt)
+  | PC.Tunsigned(clt) -> "unsigned"^(line_type2c clt)
+  | PC.Tsigned(clt) -> "signed"^(line_type2c clt)
+  | PC.Tstatic(clt) -> "static"^(line_type2c clt)
+  | PC.Tinline(clt) -> "inline"^(line_type2c clt)
+  | PC.Ttypedef(clt) -> "typedef"^(line_type2c clt)
+  | PC.Tattr(s,clt) -> s^(line_type2c clt)
+  | PC.Tauto(clt) -> "auto"^(line_type2c clt)
+  | PC.Tregister(clt) -> "register"^(line_type2c clt)
+  | PC.Textern(clt) -> "extern"^(line_type2c clt)
+  | PC.Tconst(clt) -> "const"^(line_type2c clt)
+  | PC.Tvolatile(clt) -> "volatile"^(line_type2c clt)
+
+  | PC.TPragma(s) -> s
+  | PC.TIncludeL(s,clt) -> (pr "#include \"%s\"" s)^(line_type2c clt)
+  | PC.TIncludeNL(s,clt) -> (pr "#include <%s>" s)^(line_type2c clt)
+  | PC.TDefine(clt,_) -> "#define"^(line_type2c clt)
+  | PC.TDefineParam(clt,_,_) -> "#define_param"^(line_type2c clt)
+  | PC.TMinusFile(s,clt) -> (pr "--- %s" s)^(line_type2c clt)
+  | PC.TPlusFile(s,clt) -> (pr "+++ %s" s)^(line_type2c clt)
+
+  | PC.TInc(clt) -> "++"^(line_type2c clt)
+  | PC.TDec(clt) -> "--"^(line_type2c clt)
+
+  | PC.TIf(clt) -> "if"^(line_type2c clt)
+  | PC.TElse(clt) -> "else"^(line_type2c clt)
+  | PC.TWhile(clt) -> "while"^(line_type2c clt)
+  | PC.TFor(clt) -> "for"^(line_type2c clt)
+  | PC.TDo(clt) -> "do"^(line_type2c clt)
+  | PC.TSwitch(clt) -> "switch"^(line_type2c clt)
+  | PC.TCase(clt) -> "case"^(line_type2c clt)
+  | PC.TDefault(clt) -> "default"^(line_type2c clt)
+  | PC.TReturn(clt) -> "return"^(line_type2c clt)
+  | PC.TBreak(clt) -> "break"^(line_type2c clt)
+  | PC.TContinue(clt) -> "continue"^(line_type2c clt)
+  | PC.TGoto(clt) -> "goto"^(line_type2c clt)
+  | PC.TIdent(s,clt) -> (pr "ident-%s" s)^(line_type2c clt)
+  | PC.TTypeId(s,clt) -> (pr "typename-%s" s)^(line_type2c clt)
+  | PC.TDeclarerId(s,clt) -> (pr "declarername-%s" s)^(line_type2c clt)
+  | PC.TIteratorId(s,clt) -> (pr "iteratorname-%s" s)^(line_type2c clt)
+  | PC.TMetaDeclarer(_,_,_,clt) -> "declmeta"^(line_type2c clt)
+  | PC.TMetaIterator(_,_,_,clt) -> "itermeta"^(line_type2c clt)
+
+  | PC.TSizeof(clt) -> "sizeof"^(line_type2c clt)
+
+  | PC.TString(x,clt) -> x^(line_type2c clt)
+  | PC.TChar(x,clt) -> x^(line_type2c clt)
+  | PC.TFloat(x,clt) -> x^(line_type2c clt)
+  | PC.TInt(x,clt) -> x^(line_type2c clt)
+
+  | PC.TOrLog(clt) -> "||"^(line_type2c clt)
+  | PC.TAndLog(clt) -> "&&"^(line_type2c clt)
+  | PC.TOr(clt) -> "|"^(line_type2c clt)
+  | PC.TXor(clt) -> "^"^(line_type2c clt)
+  | PC.TAnd (clt) -> "&"^(line_type2c clt)
+  | PC.TEqEq(clt) -> "=="^(line_type2c clt)
+  | PC.TNotEq(clt) -> "!="^(line_type2c clt)
+  | PC.TLogOp(op,clt) ->
+      (match op with
+       Ast.Inf -> "<"
+      |        Ast.InfEq -> "<="
+      |        Ast.Sup -> ">"
+      |        Ast.SupEq -> ">="
+      |        _ -> failwith "not possible")
+      ^(line_type2c clt)
+  | PC.TShOp(op,clt) ->
+      (match op with
+       Ast.DecLeft -> "<<"
+      |        Ast.DecRight -> ">>"
+      |        _ -> failwith "not possible")
+      ^(line_type2c clt)
+  | PC.TPlus(clt) -> "+"^(line_type2c clt)
+  | PC.TMinus(clt) -> "-"^(line_type2c clt)
+  | PC.TMul(clt) -> "*"^(line_type2c clt)
+  | PC.TDmOp(op,clt) ->
+      (match op with
+       Ast.Div -> "/"
+      |        Ast.Mod -> "%"
+      |        _ -> failwith "not possible")
+      ^(line_type2c clt)
+  | PC.TTilde (clt) -> "~"^(line_type2c clt)
+
+  | PC.TMetaParam(_,_,clt) -> "parammeta"^(line_type2c clt)
+  | PC.TMetaParamList(_,_,_,clt) -> "paramlistmeta"^(line_type2c clt)
+  | PC.TMetaConst(_,_,_,_,clt) -> "constmeta"^(line_type2c clt)
+  | PC.TMetaErr(_,_,_,clt) -> "errmeta"^(line_type2c clt)
+  | PC.TMetaExp(_,_,_,_,clt) -> "expmeta"^(line_type2c clt)
+  | PC.TMetaIdExp(_,_,_,_,clt) -> "idexpmeta"^(line_type2c clt)
+  | PC.TMetaLocalIdExp(_,_,_,_,clt) -> "localidexpmeta"^(line_type2c clt)
+  | PC.TMetaExpList(_,_,_,clt) -> "explistmeta"^(line_type2c clt)
+  | PC.TMetaId(_,_,_,clt)    -> "idmeta"^(line_type2c clt)
+  | PC.TMetaType(_,_,clt)    -> "typemeta"^(line_type2c clt)
+  | PC.TMetaInit(_,_,clt)    -> "initmeta"^(line_type2c clt)
+  | PC.TMetaStm(_,_,clt)   -> "stmmeta"^(line_type2c clt)
+  | PC.TMetaStmList(_,_,clt)   -> "stmlistmeta"^(line_type2c clt)
+  | PC.TMetaFunc(_,_,_,clt)  -> "funcmeta"^(line_type2c clt)
+  | PC.TMetaLocalFunc(_,_,_,clt) -> "funcmeta"^(line_type2c clt)
+  | PC.TMetaPos(_,_,_,clt)   -> "posmeta"
+  | PC.TMPtVirg -> ";"
+  | PC.TArobArob -> "@@"
+  | PC.TArob -> "@"
+  | PC.TPArob -> "P@"
+  | PC.TScript -> "script"
+
+  | PC.TWhen(clt) -> "WHEN"^(line_type2c clt)
+  | PC.TWhenTrue(clt) -> "WHEN TRUE"^(line_type2c clt)
+  | PC.TWhenFalse(clt) -> "WHEN FALSE"^(line_type2c clt)
+  | PC.TAny(clt) -> "ANY"^(line_type2c clt)
+  | PC.TStrict(clt) -> "STRICT"^(line_type2c clt)
+  | PC.TEllipsis(clt) -> "..."^(line_type2c clt)
+(*
+  | PC.TCircles(clt)  -> "ooo"^(line_type2c clt)
+  | PC.TStars(clt)    -> "***"^(line_type2c clt)
+*)
+
+  | PC.TOEllipsis(clt) -> "<..."^(line_type2c clt)
+  | PC.TCEllipsis(clt) -> "...>"^(line_type2c clt)
+  | PC.TPOEllipsis(clt) -> "<+..."^(line_type2c clt)
+  | PC.TPCEllipsis(clt) -> "...+>"^(line_type2c clt)
+(*
+  | PC.TOCircles(clt)  -> "<ooo"^(line_type2c clt)
+  | PC.TCCircles(clt)  -> "ooo>"^(line_type2c clt)
+  | PC.TOStars(clt)    -> "<***"^(line_type2c clt)
+  | PC.TCStars(clt)    -> "***>"^(line_type2c clt)
+*)
+  | PC.TBang0 -> "!"
+  | PC.TPlus0 -> "+"
+  | PC.TWhy0  -> "?"
+
+  | PC.TWhy(clt)   -> "?"^(line_type2c clt)
+  | PC.TDotDot(clt)   -> ":"^(line_type2c clt)
+  | PC.TBang(clt)  -> "!"^(line_type2c clt)
+  | PC.TOPar(clt)  -> "("^(line_type2c clt)
+  | PC.TOPar0(clt) -> "("^(line_type2c clt)
+  | PC.TMid0(clt)  -> "|"^(line_type2c clt)
+  | PC.TCPar(clt)  -> ")"^(line_type2c clt)
+  | PC.TCPar0(clt) -> ")"^(line_type2c clt)
+
+  | PC.TOBrace(clt) -> "{"^(line_type2c clt)
+  | PC.TCBrace(clt) -> "}"^(line_type2c clt)
+  | PC.TOCro(clt) -> "["^(line_type2c clt)
+  | PC.TCCro(clt) -> "]"^(line_type2c clt)
+  | PC.TOInit(clt) -> "{"^(line_type2c clt)
+
+  | PC.TPtrOp(clt) -> "->"^(line_type2c clt)
+
+  | PC.TEq(clt) -> "="^(line_type2c clt)
+  | PC.TAssign(_,clt) -> "=op"^(line_type2c clt)
+  | PC.TDot(clt) -> "."^(line_type2c clt)
+  | PC.TComma(clt) -> ","^(line_type2c clt)
+  | PC.TPtVirg(clt) -> ";"^(line_type2c clt)
+
+  | PC.EOF -> "eof"
+  | PC.TLineEnd(clt) -> "line end"
+  | PC.TInvalid -> "invalid"
+  | PC.TFunDecl(clt) -> "fundecl"
+
+  | PC.TIso -> "<=>"
+  | PC.TRightIso -> "=>"
+  | PC.TIsoTopLevel -> "TopLevel"
+  | PC.TIsoExpression -> "Expression"
+  | PC.TIsoArgExpression -> "ArgExpression"
+  | PC.TIsoTestExpression -> "TestExpression"
+  | PC.TIsoStatement -> "Statement"
+  | PC.TIsoDeclaration -> "Declaration"
+  | PC.TIsoType -> "Type"
+  | PC.TScriptData s -> s
+
+let print_tokens s tokens =
+  Printf.printf "%s\n" s;
+  List.iter (function x -> Printf.printf "%s " (token2c x)) tokens;
+  Printf.printf "\n\n";
+  flush stdout
+
+type plus = PLUS | NOTPLUS | SKIP
+
+let plus_attachable (tok,_) =
+  match tok with
+    PC.Tchar(clt) | PC.Tshort(clt) | PC.Tint(clt) | PC.Tdouble(clt)
+  | PC.Tfloat(clt) | PC.Tlong(clt) | PC.Tvoid(clt) | PC.Tstruct(clt)
+  | PC.Tunion(clt) | PC.Tenum(clt) | PC.Tunsigned(clt) | PC.Tsigned(clt)
+  | PC.Tstatic(clt)
+  | PC.Tinline(clt) | PC.Ttypedef(clt) | PC.Tattr(_,clt)
+  | PC.Tauto(clt) | PC.Tregister(clt)
+  | PC.Textern(clt) | PC.Tconst(clt) | PC.Tvolatile(clt)
+
+  | PC.TIncludeL(_,clt) | PC.TIncludeNL(_,clt) | PC.TDefine(clt,_)
+  | PC.TDefineParam(clt,_,_) | PC.TMinusFile(_,clt) | PC.TPlusFile(_,clt)
+
+  | PC.TInc(clt) | PC.TDec(clt)
+
+  | PC.TIf(clt) | PC.TElse(clt) | PC.TWhile(clt) | PC.TFor(clt) | PC.TDo(clt)
+  | PC.TSwitch(clt) | PC.TCase(clt) | PC.TDefault(clt) | PC.TReturn(clt)
+  | PC.TBreak(clt) | PC.TContinue(clt) | PC.TGoto(clt) | PC.TIdent(_,clt)
+  | PC.TTypeId(_,clt) | PC.TDeclarerId(_,clt) | PC.TIteratorId(_,clt)
+
+  | PC.TSizeof(clt)
+
+  | PC.TString(_,clt) | PC.TChar(_,clt) | PC.TFloat(_,clt) | PC.TInt(_,clt)
+
+  | PC.TOrLog(clt) | PC.TAndLog(clt) | PC.TOr(clt) | PC.TXor(clt)
+  | PC.TAnd (clt) | PC.TEqEq(clt) | PC.TNotEq(clt) | PC.TLogOp(_,clt)
+  | PC.TShOp(_,clt) | PC.TPlus(clt) | PC.TMinus(clt) | PC.TMul(clt)
+  | PC.TDmOp(_,clt) | PC.TTilde (clt)
+
+  | PC.TMetaParam(_,_,clt) | PC.TMetaParamList(_,_,_,clt)
+  | PC.TMetaConst(_,_,_,_,clt) | PC.TMetaErr(_,_,_,clt)
+  | PC.TMetaExp(_,_,_,_,clt) | PC.TMetaIdExp(_,_,_,_,clt)
+  | PC.TMetaLocalIdExp(_,_,_,_,clt)
+  | PC.TMetaExpList(_,_,_,clt)
+  | PC.TMetaId(_,_,_,clt)
+  | PC.TMetaType(_,_,clt) | PC.TMetaInit(_,_,clt) | PC.TMetaStm(_,_,clt)
+  | PC.TMetaStmList(_,_,clt)  | PC.TMetaFunc(_,_,_,clt)
+  | PC.TMetaLocalFunc(_,_,_,clt)
+
+  | PC.TWhen(clt) |  PC.TWhenTrue(clt) |  PC.TWhenFalse(clt)
+  | PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt)
+  (* | PC.TCircles(clt) | PC.TStars(clt) *)
+
+  | PC.TWhy(clt) | PC.TDotDot(clt) | PC.TBang(clt) | PC.TOPar(clt)
+  | PC.TCPar(clt)
+
+  | PC.TOBrace(clt) | PC.TCBrace(clt) | PC.TOCro(clt) | PC.TCCro(clt)
+  | PC.TOInit(clt)
+
+  | PC.TPtrOp(clt)
+
+  | PC.TEq(clt) | PC.TAssign(_,clt) | PC.TDot(clt) | PC.TComma(clt)
+  | PC.TPtVirg(clt) ->
+      if line_type clt = D.PLUS then PLUS else NOTPLUS
+
+  | PC.TOPar0(clt) | PC.TMid0(clt) | PC.TCPar0(clt)
+  | PC.TOEllipsis(clt) | PC.TCEllipsis(clt)
+  | PC.TPOEllipsis(clt) | PC.TPCEllipsis(clt) (* | PC.TOCircles(clt)
+  | PC.TCCircles(clt) | PC.TOStars(clt) | PC.TCStars(clt) *) -> NOTPLUS
+  | PC.TMetaPos(nm,_,_,_) -> NOTPLUS
+
+  | _ -> SKIP
+
+let get_clt (tok,_) =
+  match tok with
+    PC.Tchar(clt) | PC.Tshort(clt) | PC.Tint(clt) | PC.Tdouble(clt)
+  | PC.Tfloat(clt) | PC.Tlong(clt) | PC.Tvoid(clt) | PC.Tstruct(clt)
+  | PC.Tunion(clt) | PC.Tenum(clt) | PC.Tunsigned(clt) | PC.Tsigned(clt)
+  | PC.Tstatic(clt)
+  | PC.Tinline(clt) | PC.Tattr(_,clt) | PC.Tauto(clt) | PC.Tregister(clt)
+  | PC.Textern(clt) | PC.Tconst(clt) | PC.Tvolatile(clt)
+
+  | PC.TIncludeL(_,clt) | PC.TIncludeNL(_,clt) | PC.TDefine(clt,_)
+  | PC.TDefineParam(clt,_,_) | PC.TMinusFile(_,clt) | PC.TPlusFile(_,clt)
+
+  | PC.TInc(clt) | PC.TDec(clt)
+
+  | PC.TIf(clt) | PC.TElse(clt) | PC.TWhile(clt) | PC.TFor(clt) | PC.TDo(clt)
+  | PC.TSwitch(clt) | PC.TCase(clt) | PC.TDefault(clt) | PC.TReturn(clt)
+  | PC.TBreak(clt) | PC.TContinue(clt) | PC.TGoto(clt) | PC.TIdent(_,clt)
+  | PC.TTypeId(_,clt) | PC.TDeclarerId(_,clt) | PC.TIteratorId(_,clt)
+
+  | PC.TSizeof(clt)
+
+  | PC.TString(_,clt) | PC.TChar(_,clt) | PC.TFloat(_,clt) | PC.TInt(_,clt)
+
+  | PC.TOrLog(clt) | PC.TAndLog(clt) | PC.TOr(clt) | PC.TXor(clt)
+  | PC.TAnd (clt) | PC.TEqEq(clt) | PC.TNotEq(clt) | PC.TLogOp(_,clt)
+  | PC.TShOp(_,clt) | PC.TPlus(clt) | PC.TMinus(clt) | PC.TMul(clt)
+  | PC.TDmOp(_,clt) | PC.TTilde (clt)
+
+  | PC.TMetaParam(_,_,clt) | PC.TMetaParamList(_,_,_,clt)
+  | PC.TMetaConst(_,_,_,_,clt) | PC.TMetaErr(_,_,_,clt)
+  | PC.TMetaExp(_,_,_,_,clt) | PC.TMetaIdExp(_,_,_,_,clt)
+  | PC.TMetaLocalIdExp(_,_,_,_,clt)
+  | PC.TMetaExpList(_,_,_,clt)
+  | PC.TMetaId(_,_,_,clt)
+  | PC.TMetaType(_,_,clt) | PC.TMetaInit(_,_,clt) | PC.TMetaStm(_,_,clt)
+  | PC.TMetaStmList(_,_,clt)  | PC.TMetaFunc(_,_,_,clt)
+  | PC.TMetaLocalFunc(_,_,_,clt) | PC.TMetaPos(_,_,_,clt)
+
+  | PC.TWhen(clt) | PC.TWhenTrue(clt) | PC.TWhenFalse(clt) |
+    PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt)
+  (* | PC.TCircles(clt) | PC.TStars(clt) *)
+
+  | PC.TWhy(clt) | PC.TDotDot(clt) | PC.TBang(clt) | PC.TOPar(clt)
+  | PC.TCPar(clt)
+
+  | PC.TOBrace(clt) | PC.TCBrace(clt) | PC.TOCro(clt) | PC.TCCro(clt)
+  | PC.TOInit(clt)
+
+  | PC.TPtrOp(clt)
+
+  | PC.TEq(clt) | PC.TAssign(_,clt) | PC.TDot(clt) | PC.TComma(clt)
+  | PC.TPtVirg(clt)
+
+  | PC.TOPar0(clt) | PC.TMid0(clt) | PC.TCPar0(clt)
+  | PC.TOEllipsis(clt) | PC.TCEllipsis(clt)
+  | PC.TPOEllipsis(clt) | PC.TPCEllipsis(clt) (* | PC.TOCircles(clt)
+  | PC.TCCircles(clt) | PC.TOStars(clt) | PC.TCStars(clt) *) -> clt
+
+  | _ -> failwith "no clt"
+
+let update_clt (tok,x) clt =
+  match tok with
+    PC.Tchar(_) -> (PC.Tchar(clt),x)
+  | PC.Tshort(_) -> (PC.Tshort(clt),x)
+  | PC.Tint(_) -> (PC.Tint(clt),x)
+  | PC.Tdouble(_) -> (PC.Tdouble(clt),x)
+  | PC.Tfloat(_) -> (PC.Tfloat(clt),x)
+  | PC.Tlong(_) -> (PC.Tlong(clt),x)
+  | PC.Tvoid(_) -> (PC.Tvoid(clt),x)
+  | PC.Tstruct(_) -> (PC.Tstruct(clt),x)
+  | PC.Tunion(_) -> (PC.Tunion(clt),x)
+  | PC.Tenum(_) -> (PC.Tenum(clt),x)
+  | PC.Tunsigned(_) -> (PC.Tunsigned(clt),x)
+  | PC.Tsigned(_) -> (PC.Tsigned(clt),x)
+  | PC.Tstatic(_) -> (PC.Tstatic(clt),x)
+  | PC.Tinline(_) -> (PC.Tinline(clt),x)
+  | PC.Ttypedef(_) -> (PC.Ttypedef(clt),x)
+  | PC.Tattr(s,_) -> (PC.Tattr(s,clt),x)
+  | PC.Tauto(_) -> (PC.Tauto(clt),x)
+  | PC.Tregister(_) -> (PC.Tregister(clt),x)
+  | PC.Textern(_) -> (PC.Textern(clt),x)
+  | PC.Tconst(_) -> (PC.Tconst(clt),x)
+  | PC.Tvolatile(_) -> (PC.Tvolatile(clt),x)
+
+  | PC.TIncludeL(s,_) -> (PC.TIncludeL(s,clt),x)
+  | PC.TIncludeNL(s,_) -> (PC.TIncludeNL(s,clt),x)
+  | PC.TDefine(_,a) -> (PC.TDefine(clt,a),x)
+  | PC.TDefineParam(_,a,b) -> (PC.TDefineParam(clt,a,b),x)
+  | PC.TMinusFile(s,_) -> (PC.TMinusFile(s,clt),x)
+  | PC.TPlusFile(s,_) -> (PC.TPlusFile(s,clt),x)
+
+  | PC.TInc(_) -> (PC.TInc(clt),x)
+  | PC.TDec(_) -> (PC.TDec(clt),x)
+
+  | PC.TIf(_) -> (PC.TIf(clt),x)
+  | PC.TElse(_) -> (PC.TElse(clt),x)
+  | PC.TWhile(_) -> (PC.TWhile(clt),x)
+  | PC.TFor(_) -> (PC.TFor(clt),x)
+  | PC.TDo(_) -> (PC.TDo(clt),x)
+  | PC.TSwitch(_) -> (PC.TSwitch(clt),x)
+  | PC.TCase(_) -> (PC.TCase(clt),x)
+  | PC.TDefault(_) -> (PC.TDefault(clt),x)
+  | PC.TReturn(_) -> (PC.TReturn(clt),x)
+  | PC.TBreak(_) -> (PC.TBreak(clt),x)
+  | PC.TContinue(_) -> (PC.TContinue(clt),x)
+  | PC.TGoto(_) -> (PC.TGoto(clt),x)
+  | PC.TIdent(s,_) -> (PC.TIdent(s,clt),x)
+  | PC.TTypeId(s,_) -> (PC.TTypeId(s,clt),x)
+  | PC.TDeclarerId(s,_) -> (PC.TDeclarerId(s,clt),x)
+  | PC.TIteratorId(s,_) -> (PC.TIteratorId(s,clt),x)
+
+  | PC.TSizeof(_) -> (PC.TSizeof(clt),x)
+
+  | PC.TString(s,_) -> (PC.TString(s,clt),x)
+  | PC.TChar(s,_) -> (PC.TChar(s,clt),x)
+  | PC.TFloat(s,_) -> (PC.TFloat(s,clt),x)
+  | PC.TInt(s,_) -> (PC.TInt(s,clt),x)
+
+  | PC.TOrLog(_) -> (PC.TOrLog(clt),x)
+  | PC.TAndLog(_) -> (PC.TAndLog(clt),x)
+  | PC.TOr(_) -> (PC.TOr(clt),x)
+  | PC.TXor(_) -> (PC.TXor(clt),x)
+  | PC.TAnd (_) -> (PC.TAnd (clt),x)
+  | PC.TEqEq(_) -> (PC.TEqEq(clt),x)
+  | PC.TNotEq(_) -> (PC.TNotEq(clt),x)
+  | PC.TLogOp(op,_) -> (PC.TLogOp(op,clt),x)
+  | PC.TShOp(op,_) -> (PC.TShOp(op,clt),x)
+  | PC.TPlus(_) -> (PC.TPlus(clt),x)
+  | PC.TMinus(_) -> (PC.TMinus(clt),x)
+  | PC.TMul(_) -> (PC.TMul(clt),x)
+  | PC.TDmOp(op,_) -> (PC.TDmOp(op,clt),x)
+  | PC.TTilde (_) -> (PC.TTilde (clt),x)
+
+  | PC.TMetaParam(a,b,_) -> (PC.TMetaParam(a,b,clt),x)
+  | PC.TMetaParamList(a,b,c,_) -> (PC.TMetaParamList(a,b,c,clt),x)
+  | PC.TMetaConst(a,b,c,d,_) -> (PC.TMetaConst(a,b,c,d,clt),x)
+  | PC.TMetaErr(a,b,c,_) -> (PC.TMetaErr(a,b,c,clt),x)
+  | PC.TMetaExp(a,b,c,d,_) -> (PC.TMetaExp(a,b,c,d,clt),x)
+  | PC.TMetaIdExp(a,b,c,d,_) -> (PC.TMetaIdExp(a,b,c,d,clt),x)
+  | PC.TMetaLocalIdExp(a,b,c,d,_) -> (PC.TMetaLocalIdExp(a,b,c,d,clt),x)
+  | PC.TMetaExpList(a,b,c,_) -> (PC.TMetaExpList(a,b,c,clt),x)
+  | PC.TMetaId(a,b,c,_)    -> (PC.TMetaId(a,b,c,clt),x)
+  | PC.TMetaType(a,b,_)    -> (PC.TMetaType(a,b,clt),x)
+  | PC.TMetaInit(a,b,_)    -> (PC.TMetaInit(a,b,clt),x)
+  | PC.TMetaStm(a,b,_)   -> (PC.TMetaStm(a,b,clt),x)
+  | PC.TMetaStmList(a,b,_)   -> (PC.TMetaStmList(a,b,clt),x)
+  | PC.TMetaFunc(a,b,c,_)  -> (PC.TMetaFunc(a,b,c,clt),x)
+  | PC.TMetaLocalFunc(a,b,c,_) -> (PC.TMetaLocalFunc(a,b,c,clt),x)
+
+  | PC.TWhen(_) -> (PC.TWhen(clt),x)
+  | PC.TWhenTrue(_) -> (PC.TWhenTrue(clt),x)
+  | PC.TWhenFalse(_) -> (PC.TWhenFalse(clt),x)
+  | PC.TAny(_) -> (PC.TAny(clt),x)
+  | PC.TStrict(_) -> (PC.TStrict(clt),x)
+  | PC.TEllipsis(_) -> (PC.TEllipsis(clt),x)
+(*
+  | PC.TCircles(_)  -> (PC.TCircles(clt),x)
+  | PC.TStars(_)    -> (PC.TStars(clt),x)
+*)
+
+  | PC.TOEllipsis(_) -> (PC.TOEllipsis(clt),x)
+  | PC.TCEllipsis(_) -> (PC.TCEllipsis(clt),x)
+  | PC.TPOEllipsis(_) -> (PC.TPOEllipsis(clt),x)
+  | PC.TPCEllipsis(_) -> (PC.TPCEllipsis(clt),x)
+(*
+  | PC.TOCircles(_)  -> (PC.TOCircles(clt),x)
+  | PC.TCCircles(_)  -> (PC.TCCircles(clt),x)
+  | PC.TOStars(_)    -> (PC.TOStars(clt),x)
+  | PC.TCStars(_)    -> (PC.TCStars(clt),x)
+*)
+
+  | PC.TWhy(_)   -> (PC.TWhy(clt),x)
+  | PC.TDotDot(_)   -> (PC.TDotDot(clt),x)
+  | PC.TBang(_)  -> (PC.TBang(clt),x)
+  | PC.TOPar(_)  -> (PC.TOPar(clt),x)
+  | PC.TOPar0(_) -> (PC.TOPar0(clt),x)
+  | PC.TMid0(_)  -> (PC.TMid0(clt),x)
+  | PC.TCPar(_)  -> (PC.TCPar(clt),x)
+  | PC.TCPar0(_) -> (PC.TCPar0(clt),x)
+
+  | PC.TOBrace(_) -> (PC.TOBrace(clt),x)
+  | PC.TCBrace(_) -> (PC.TCBrace(clt),x)
+  | PC.TOCro(_) -> (PC.TOCro(clt),x)
+  | PC.TCCro(_) -> (PC.TCCro(clt),x)
+  | PC.TOInit(_) -> (PC.TOInit(clt),x)
+
+  | PC.TPtrOp(_) -> (PC.TPtrOp(clt),x)
+
+  | PC.TEq(_) -> (PC.TEq(clt),x)
+  | PC.TAssign(s,_) -> (PC.TAssign(s,clt),x)
+  | PC.TDot(_) -> (PC.TDot(clt),x)
+  | PC.TComma(_) -> (PC.TComma(clt),x)
+  | PC.TPtVirg(_) -> (PC.TPtVirg(clt),x)
+
+  | PC.TLineEnd(_) -> (PC.TLineEnd(clt),x)
+  | PC.TFunDecl(_) -> (PC.TFunDecl(clt),x)
+
+  | _ -> failwith "no clt"
+
+
+(* ----------------------------------------------------------------------- *)
+
+let make_name prefix ln = Printf.sprintf "%s starting on line %d" prefix ln
+
+(* ----------------------------------------------------------------------- *)
+(* Read tokens *)
+
+let wrap_lexbuf_info lexbuf =
+  (Lexing.lexeme lexbuf, Lexing.lexeme_start lexbuf)
+
+let tokens_all_full token table file get_ats lexbuf end_markers :
+    (bool * ((PC.token * (string * (int * int) * (int * int))) list)) =
+  try
+    let rec aux () =
+      let result = token lexbuf in
+      let info = (Lexing.lexeme lexbuf,
+                  (table.(Lexing.lexeme_start lexbuf)),
+                  (Lexing.lexeme_start lexbuf, Lexing.lexeme_end lexbuf)) in
+      if result = PC.EOF
+      then
+       if get_ats
+       then failwith "unexpected end of file in a metavariable declaration"
+       else (false,[(result,info)])
+      else if List.mem result end_markers
+      then (true,[(result,info)])
+      else
+       let (more,rest) = aux() in
+       (more,(result, info)::rest)
+    in aux ()
+  with
+    e -> pr2 (Common.error_message file (wrap_lexbuf_info lexbuf) ); raise e
+
+let tokens_all table file get_ats lexbuf end_markers :
+    (bool * ((PC.token * (string * (int * int) * (int * int))) list)) =
+  tokens_all_full Lexer_cocci.token table file get_ats lexbuf end_markers
+
+let tokens_script_all table file get_ats lexbuf end_markers :
+    (bool * ((PC.token * (string * (int * int) * (int * int))) list)) =
+  tokens_all_full Lexer_script.token table file get_ats lexbuf end_markers
+
+(* ----------------------------------------------------------------------- *)
+(* Split tokens into minus and plus fragments *)
+
+let split t clt =
+  let (d,_,_,_,_,_,_,_) = clt in
+  match d with
+    D.MINUS | D.OPTMINUS | D.UNIQUEMINUS -> ([t],[])
+  | D.PLUS -> ([],[t])
+  | D.CONTEXT | D.UNIQUE | D.OPT -> ([t],[t])
+
+let split_token ((tok,_) as t) =
+  match tok with
+    PC.TIdentifier | PC.TConstant | PC.TExpression | PC.TIdExpression
+  | PC.TStatement | PC.TPosition | PC.TPosAny | PC.TInitialiser
+  | PC.TFunction | PC.TTypedef | PC.TDeclarer | PC.TIterator | PC.TName
+  | PC.TType | PC.TParameter | PC.TLocal | PC.Tlist | PC.TFresh | PC.TPure
+  | PC.TContext | PC.TRuleName(_) | PC.TUsing | PC.TDisable | PC.TExtends
+  | PC.TPathIsoFile(_)
+  | PC.TDepends | PC.TOn | PC.TEver | PC.TNever | PC.TExists | PC.TForall
+  | PC.TReverse
+  | PC.TError | PC.TWords | PC.TGenerated | PC.TNothing -> ([t],[t])
+
+  | PC.Tchar(clt) | PC.Tshort(clt) | PC.Tint(clt) | PC.Tdouble(clt)
+  | PC.Tfloat(clt) | PC.Tlong(clt) | PC.Tvoid(clt) | PC.Tstruct(clt)
+  | PC.Tunion(clt) | PC.Tenum(clt) | PC.Tunsigned(clt) | PC.Tsigned(clt)
+  | PC.Tstatic(clt) | PC.Tauto(clt) | PC.Tregister(clt) | PC.Textern(clt)
+  | PC.Tinline(clt) | PC.Ttypedef(clt) | PC.Tattr(_,clt)
+  | PC.Tconst(clt) | PC.Tvolatile(clt) -> split t clt
+
+  | PC.TPragma(s) -> ([],[t]) (* only allowed in + *)
+  | PC.TPlusFile(s,clt) | PC.TMinusFile(s,clt)
+  | PC.TIncludeL(s,clt) | PC.TIncludeNL(s,clt) ->
+      split t clt
+  | PC.TDefine(clt,_) | PC.TDefineParam(clt,_,_) -> split t clt
+
+  | PC.TIf(clt) | PC.TElse(clt)  | PC.TWhile(clt) | PC.TFor(clt) | PC.TDo(clt)
+  | PC.TSwitch(clt) | PC.TCase(clt) | PC.TDefault(clt)
+  | PC.TSizeof(clt)
+  | PC.TReturn(clt) | PC.TBreak(clt) | PC.TContinue(clt) | PC.TGoto(clt)
+  | PC.TIdent(_,clt)
+  | PC.TTypeId(_,clt) | PC.TDeclarerId(_,clt) | PC.TIteratorId(_,clt)
+  | PC.TMetaConst(_,_,_,_,clt) | PC.TMetaExp(_,_,_,_,clt)
+  | PC.TMetaIdExp(_,_,_,_,clt) | PC.TMetaLocalIdExp(_,_,_,_,clt)
+  | PC.TMetaExpList(_,_,_,clt)
+  | PC.TMetaParam(_,_,clt) | PC.TMetaParamList(_,_,_,clt)
+  | PC.TMetaId(_,_,_,clt) | PC.TMetaType(_,_,clt) | PC.TMetaInit(_,_,clt)
+  | PC.TMetaStm(_,_,clt) | PC.TMetaStmList(_,_,clt) | PC.TMetaErr(_,_,_,clt)
+  | PC.TMetaFunc(_,_,_,clt) | PC.TMetaLocalFunc(_,_,_,clt)
+  | PC.TMetaDeclarer(_,_,_,clt) | PC.TMetaIterator(_,_,_,clt) -> split t clt
+  | PC.TMPtVirg | PC.TArob | PC.TArobArob | PC.TScript -> ([t],[t])
+  | PC.TPArob | PC.TMetaPos(_,_,_,_) -> ([t],[])
+
+  | PC.TFunDecl(clt)
+  | PC.TWhen(clt) | PC.TWhenTrue(clt) | PC.TWhenFalse(clt)
+  | PC.TAny(clt) | PC.TStrict(clt) | PC.TLineEnd(clt)
+  | PC.TEllipsis(clt) (* | PC.TCircles(clt) | PC.TStars(clt) *) -> split t clt
+
+  | PC.TOEllipsis(_) | PC.TCEllipsis(_) (* clt must be context *)
+  | PC.TPOEllipsis(_) | PC.TPCEllipsis(_) (* clt must be context *)
+(*
+  | PC.TOCircles(_) | PC.TCCircles(_)   (* clt must be context *)
+  | PC.TOStars(_) | PC.TCStars(_)       (* clt must be context *)
+*)
+  | PC.TBang0 | PC.TPlus0 | PC.TWhy0 ->
+      ([t],[t])
+
+  | PC.TWhy(clt)  | PC.TDotDot(clt)
+  | PC.TBang(clt) | PC.TOPar(clt) | PC.TOPar0(clt)
+  | PC.TMid0(clt) | PC.TCPar(clt) | PC.TCPar0(clt) -> split t clt
+
+  | PC.TInc(clt) | PC.TDec(clt) -> split t clt
+
+  | PC.TString(_,clt) | PC.TChar(_,clt) | PC.TFloat(_,clt) | PC.TInt(_,clt) ->
+      split t clt
+
+  | PC.TOrLog(clt) | PC.TAndLog(clt) | PC.TOr(clt) | PC.TXor(clt)
+  | PC.TAnd (clt) | PC.TEqEq(clt) | PC.TNotEq(clt) | PC.TLogOp(_,clt)
+  | PC.TShOp(_,clt) | PC.TPlus(clt) | PC.TMinus(clt) | PC.TMul(clt)
+  | PC.TDmOp(_,clt) | PC.TTilde (clt) -> split t clt
+
+  | PC.TOBrace(clt) | PC.TCBrace(clt) | PC.TOInit(clt) -> split t clt
+  | PC.TOCro(clt) | PC.TCCro(clt) -> split t clt
+
+  | PC.TPtrOp(clt) -> split t clt
+
+  | PC.TEq(clt) | PC.TAssign(_,clt) | PC.TDot(clt) | PC.TComma(clt)
+  | PC.TPtVirg(clt) -> split t clt
+
+  | PC.EOF | PC.TInvalid -> ([t],[t])
+
+  | PC.TIso | PC.TRightIso
+  | PC.TIsoExpression | PC.TIsoStatement | PC.TIsoDeclaration | PC.TIsoType
+  | PC.TIsoTopLevel | PC.TIsoArgExpression | PC.TIsoTestExpression ->
+      failwith "unexpected tokens"
+  | PC.TScriptData s -> ([t],[t])
+
+let split_token_stream tokens =
+  let rec loop = function
+      [] -> ([],[])
+    | token::tokens ->
+       let (minus,plus) = split_token token in
+       let (minus_stream,plus_stream) = loop tokens in
+       (minus@minus_stream,plus@plus_stream) in
+  loop tokens
+
+(* ----------------------------------------------------------------------- *)
+(* Find function names *)
+(* This addresses a shift-reduce problem in the parser, allowing us to
+distinguish a function declaration from a function call even if the latter
+has no return type.  Undoubtedly, this is not very nice, but it doesn't
+seem very convenient to refactor the grammar to get around the problem. *)
+
+let rec find_function_names = function
+    [] -> []
+  | ((PC.TIdent(_,clt),info) as t1) :: ((PC.TOPar(_),_) as t2) :: rest
+  | ((PC.TMetaId(_,_,_,clt),info) as t1) :: ((PC.TOPar(_),_) as t2) :: rest
+  | ((PC.TMetaFunc(_,_,_,clt),info) as t1) :: ((PC.TOPar(_),_) as t2) :: rest
+  | ((PC.TMetaLocalFunc(_,_,_,clt),info) as t1)::((PC.TOPar(_),_) as t2)::rest
+    ->
+      let rec skip level = function
+         [] -> ([],false,[])
+       | ((PC.TCPar(_),_) as t)::rest ->
+           let level = level - 1 in
+           if level = 0
+           then ([t],true,rest)
+           else let (pre,found,post) = skip level rest in (t::pre,found,post)
+       | ((PC.TOPar(_),_) as t)::rest ->
+           let level = level + 1 in
+           let (pre,found,post) = skip level rest in (t::pre,found,post)
+       | ((PC.TArobArob,_) as t)::rest
+       | ((PC.TArob,_) as t)::rest
+       | ((PC.EOF,_) as t)::rest -> ([t],false,rest)
+       | t::rest ->
+           let (pre,found,post) = skip level rest in (t::pre,found,post) in
+      let (pre,found,post) = skip 1 rest in
+      (match (found,post) with
+       (true,((PC.TOBrace(_),_) as t3)::rest) ->
+         (PC.TFunDecl(clt),info) :: t1 :: t2 :: pre @
+         t3 :: (find_function_names rest)
+      |        _ -> t1 :: t2 :: pre @ find_function_names post)
+  | t :: rest -> t :: find_function_names rest
+
+(* ----------------------------------------------------------------------- *)
+(* an attribute is an identifier that preceeds another identifier and
+   begins with __ *)
+
+let rec detect_attr l =
+  let is_id = function
+      (PC.TIdent(_,_),_) | (PC.TMetaId(_,_,_,_),_) | (PC.TMetaFunc(_,_,_,_),_)
+    | (PC.TMetaLocalFunc(_,_,_,_),_) -> true
+    | _ -> false in
+  let rec loop = function
+      [] -> []
+    | [x] -> [x]
+    | ((PC.TIdent(nm,clt),info) as t1)::id::rest when is_id id ->
+       if String.length nm > 2 && String.sub nm 0 2 = "__"
+       then (PC.Tattr(nm,clt),info)::(loop (id::rest))
+       else t1::(loop (id::rest))
+    | x::xs -> x::(loop xs) in
+  loop l
+
+(* ----------------------------------------------------------------------- *)
+(* Look for variable declarations where the name is a typedef name.
+We assume that C code does not contain a multiplication as a top-level
+statement. *)
+
+(* bug: once a type, always a type, even if the same name is later intended
+   to be used as a real identifier *)
+let detect_types in_meta_decls l =
+  let is_delim infn = function
+      (PC.TOEllipsis(_),_) (* | (PC.TOCircles(_),_) | (PC.TOStars(_),_) *)
+    | (PC.TPOEllipsis(_),_) (* | (PC.TOCircles(_),_) | (PC.TOStars(_),_) *)
+    | (PC.TEllipsis(_),_) (* | (PC.TCircles(_),_) | (PC.TStars(_),_) *)
+    | (PC.TPtVirg(_),_) | (PC.TOBrace(_),_) | (PC.TOInit(_),_)
+    | (PC.TCBrace(_),_)
+    | (PC.TPure,_) | (PC.TContext,_)
+    | (PC.Tstatic(_),_) | (PC.Textern(_),_)
+    | (PC.Tinline(_),_) | (PC.Ttypedef(_),_) | (PC.Tattr(_),_) -> true
+    | (PC.TComma(_),_) when infn > 0 or in_meta_decls -> true
+    | (PC.TDotDot(_),_) when in_meta_decls -> true
+    | _ -> false in
+  let is_choices_delim = function
+      (PC.TOBrace(_),_) | (PC.TComma(_),_) -> true | _ -> false in
+  let is_id = function
+      (PC.TIdent(_,_),_) | (PC.TMetaId(_,_,_,_),_) | (PC.TMetaFunc(_,_,_,_),_)
+    | (PC.TMetaLocalFunc(_,_,_,_),_) -> true
+    | (PC.TMetaParam(_,_,_),_)
+    | (PC.TMetaParamList(_,_,_,_),_)
+    | (PC.TMetaConst(_,_,_,_,_),_)
+    | (PC.TMetaErr(_,_,_,_),_)
+    | (PC.TMetaExp(_,_,_,_,_),_)
+    | (PC.TMetaIdExp(_,_,_,_,_),_)
+    | (PC.TMetaLocalIdExp(_,_,_,_,_),_)
+    | (PC.TMetaExpList(_,_,_,_),_)
+    | (PC.TMetaType(_,_,_),_)
+    | (PC.TMetaInit(_,_,_),_)
+    | (PC.TMetaStm(_,_,_),_)
+    | (PC.TMetaStmList(_,_,_),_)
+    | (PC.TMetaPos(_,_,_,_),_) -> in_meta_decls
+    | _ -> false in
+  let redo_id ident clt v =
+    !Data.add_type_name ident;
+    (PC.TTypeId(ident,clt),v) in
+  let rec loop start infn type_names = function
+      (* infn: 0 means not in a function header
+        > 0 means in a function header, after infn - 1 unmatched open parens*)
+      [] -> []
+    | ((PC.TOBrace(clt),v)::_) as all when in_meta_decls ->
+       collect_choices type_names all (* never a function header *)
+    | delim::(PC.TIdent(ident,clt),v)::((PC.TMul(_),_) as x)::rest
+      when is_delim infn delim ->
+       let newid = redo_id ident clt v in
+       delim::newid::x::(loop false infn (ident::type_names) rest)
+    | delim::(PC.TIdent(ident,clt),v)::id::rest
+      when is_delim infn delim && is_id id ->
+       let newid = redo_id ident clt v in
+       delim::newid::id::(loop false infn (ident::type_names) rest)
+    | ((PC.TFunDecl(_),_) as fn)::rest ->
+       fn::(loop false 1 type_names rest)
+    | ((PC.TOPar(_),_) as lp)::rest when infn > 0 ->
+       lp::(loop false (infn + 1) type_names rest)
+    | ((PC.TCPar(_),_) as rp)::rest when infn > 0 ->
+       if infn - 1 = 1
+       then rp::(loop false 0 type_names rest) (* 0 means not in fn header *)
+       else rp::(loop false (infn - 1) type_names rest)
+    | (PC.TIdent(ident,clt),v)::((PC.TMul(_),_) as x)::rest when start ->
+       let newid = redo_id ident clt v in
+       newid::x::(loop false infn (ident::type_names) rest)
+    | (PC.TIdent(ident,clt),v)::id::rest when start && is_id id ->
+       let newid = redo_id ident clt v in
+       newid::id::(loop false infn (ident::type_names) rest)
+    | (PC.TIdent(ident,clt),v)::rest when List.mem ident type_names ->
+       (PC.TTypeId(ident,clt),v)::(loop false infn type_names rest)
+    | ((PC.TIdent(ident,clt),v) as x)::rest ->
+       x::(loop false infn type_names rest)
+    | x::rest -> x::(loop false infn type_names rest)
+  and collect_choices type_names = function
+      [] -> [] (* should happen, but let the parser detect that *)
+    | (PC.TCBrace(clt),v)::rest ->
+       (PC.TCBrace(clt),v)::(loop false 0 type_names rest)
+    | delim::(PC.TIdent(ident,clt),v)::rest
+      when is_choices_delim delim ->
+       let newid = redo_id ident clt v in
+       delim::newid::(collect_choices (ident::type_names) rest)
+    | x::rest -> x::(collect_choices type_names rest) in
+  loop true 0 [] l
+
+
+(* ----------------------------------------------------------------------- *)
+(* Insert TLineEnd tokens at the end of a line that contains a WHEN.
+   WHEN is restricted to a single line, to avoid ambiguity in eg:
+   ... WHEN != x
+   +3 *)
+
+let token2line (tok,_) =
+  match tok with
+    PC.Tchar(clt) | PC.Tshort(clt) | PC.Tint(clt) | PC.Tdouble(clt)
+  | PC.Tfloat(clt) | PC.Tlong(clt) | PC.Tvoid(clt) | PC.Tstruct(clt)
+  | PC.Tunion(clt) | PC.Tenum(clt) | PC.Tunsigned(clt) | PC.Tsigned(clt)
+  | PC.Tstatic(clt) | PC.Tauto(clt) | PC.Tregister(clt) | PC.Textern(clt)
+  | PC.Tinline(clt) | PC.Ttypedef(clt) | PC.Tattr(_,clt) | PC.Tconst(clt)
+  | PC.Tvolatile(clt)
+
+  | PC.TInc(clt) | PC.TDec(clt)
+
+  | PC.TIf(clt) | PC.TElse(clt) | PC.TWhile(clt) | PC.TFor(clt) | PC.TDo(clt)
+  | PC.TSwitch (clt) | PC.TCase (clt) | PC.TDefault (clt) | PC.TSizeof (clt)
+  | PC.TReturn(clt) | PC.TBreak(clt) | PC.TContinue(clt) | PC.TGoto(clt)
+  | PC.TIdent(_,clt)
+  | PC.TTypeId(_,clt) | PC.TDeclarerId(_,clt) | PC.TIteratorId(_,clt)
+  | PC.TMetaDeclarer(_,_,_,clt) | PC.TMetaIterator(_,_,_,clt)
+
+  | PC.TString(_,clt) | PC.TChar(_,clt) | PC.TFloat(_,clt) | PC.TInt(_,clt)
+
+  | PC.TOrLog(clt) | PC.TAndLog(clt) | PC.TOr(clt) | PC.TXor(clt)
+  | PC.TAnd (clt) | PC.TEqEq(clt) | PC.TNotEq(clt) | PC.TLogOp(_,clt)
+  | PC.TShOp(_,clt) | PC.TPlus(clt) | PC.TMinus(clt) | PC.TMul(clt)
+  | PC.TDmOp(_,clt) | PC.TTilde (clt)
+
+  | PC.TMetaParam(_,_,clt) | PC.TMetaParamList(_,_,_,clt)
+  | PC.TMetaConst(_,_,_,_,clt) | PC.TMetaExp(_,_,_,_,clt)
+  | PC.TMetaIdExp(_,_,_,_,clt) | PC.TMetaLocalIdExp(_,_,_,_,clt)
+  | PC.TMetaExpList(_,_,_,clt)
+  | PC.TMetaId(_,_,_,clt) | PC.TMetaType(_,_,clt) | PC.TMetaInit(_,_,clt)
+  | PC.TMetaStm(_,_,clt) | PC.TMetaStmList(_,_,clt) | PC.TMetaFunc(_,_,_,clt)
+  | PC.TMetaLocalFunc(_,_,_,clt) | PC.TMetaPos(_,_,_,clt)
+
+  | PC.TFunDecl(clt)
+  | PC.TWhen(clt) | PC.TWhenTrue(clt) | PC.TWhenFalse(clt)
+  | PC.TAny(clt) | PC.TStrict(clt) | PC.TEllipsis(clt)
+  (* | PC.TCircles(clt) | PC.TStars(clt) *)
+
+  | PC.TOEllipsis(clt) | PC.TCEllipsis(clt)
+  | PC.TPOEllipsis(clt) | PC.TPCEllipsis(clt) (*| PC.TOCircles(clt)
+  | PC.TCCircles(clt) | PC.TOStars(clt) | PC.TCStars(clt) *)
+
+  | PC.TWhy(clt) | PC.TDotDot(clt) | PC.TBang(clt) | PC.TOPar(clt)
+  | PC.TOPar0(clt) | PC.TMid0(clt) | PC.TCPar(clt)
+  | PC.TCPar0(clt)
+
+  | PC.TOBrace(clt) | PC.TCBrace(clt) | PC.TOCro(clt) | PC.TCCro(clt)
+  | PC.TOInit(clt)
+
+  | PC.TPtrOp(clt)
+
+  | PC.TDefine(clt,_) | PC.TDefineParam(clt,_,_)
+  | PC.TIncludeL(_,clt) | PC.TIncludeNL(_,clt)
+
+  | PC.TEq(clt) | PC.TAssign(_,clt) | PC.TDot(clt) | PC.TComma(clt)
+  | PC.TPtVirg(clt) ->
+      let (_,line,_,_,_,_,_,_) = clt in Some line
+
+  | _ -> None
+
+let rec insert_line_end = function
+    [] -> []
+  | (((PC.TWhen(clt),q) as x)::xs) ->
+      x::(find_line_end true (token2line x) clt q xs)
+  | (((PC.TDefine(clt,_),q) as x)::xs)
+  | (((PC.TDefineParam(clt,_,_),q) as x)::xs) ->
+      x::(find_line_end false (token2line x) clt q xs)
+  | x::xs -> x::(insert_line_end xs)
+
+and find_line_end inwhen line clt q = function
+    (* don't know what 2nd component should be so just use the info of
+       the When.  Also inherit - of when, if any *)
+    [] -> [(PC.TLineEnd(clt),q)]
+  | ((PC.TIdent("strict",clt),a) as x)::xs when token2line x = line ->
+      (PC.TStrict(clt),a) :: (find_line_end inwhen line clt q xs)
+  | ((PC.TIdent("STRICT",clt),a) as x)::xs when token2line x = line ->
+      (PC.TStrict(clt),a) :: (find_line_end inwhen line clt q xs)
+  | ((PC.TIdent("any",clt),a) as x)::xs when token2line x = line ->
+      (PC.TAny(clt),a) :: (find_line_end inwhen line clt q xs)
+  | ((PC.TIdent("ANY",clt),a) as x)::xs when token2line x = line ->
+      (PC.TAny(clt),a) :: (find_line_end inwhen line clt q xs)
+  | ((PC.TIdent("forall",clt),a) as x)::xs when token2line x = line ->
+      (PC.TForall,a) :: (find_line_end inwhen line clt q xs)
+  | ((PC.TIdent("exists",clt),a) as x)::xs when token2line x = line ->
+      (PC.TExists,a) :: (find_line_end inwhen line clt q xs)
+  | ((PC.TComma(clt),a) as x)::xs when token2line x = line ->
+      (PC.TComma(clt),a) :: (find_line_end inwhen line clt q xs)
+  | ((PC.TPArob,a) as x)::xs -> (* no line #, just assume on the same line *)
+      x :: (find_line_end inwhen line clt q xs)
+  | x::xs when token2line x = line -> x :: (find_line_end inwhen line clt q xs)
+  | xs -> (PC.TLineEnd(clt),q)::(insert_line_end xs)
+
+let rec translate_when_true_false = function
+    [] -> []
+  | (PC.TWhen(clt),q)::((PC.TNotEq(_),_) as x)::(PC.TIdent("true",_),_)::xs ->
+      (PC.TWhenTrue(clt),q)::x::(translate_when_true_false xs)
+  | (PC.TWhen(clt),q)::((PC.TNotEq(_),_) as x)::(PC.TIdent("false",_),_)::xs ->
+      (PC.TWhenFalse(clt),q)::x::(translate_when_true_false xs)
+  | x::xs -> x :: (translate_when_true_false xs)
+
+(* ----------------------------------------------------------------------- *)
+(* top level initializers: a sequence of braces followed by a dot *)
+
+let find_top_init tokens =
+  match tokens with
+    (PC.TOBrace(clt),q) :: rest ->
+      let rec dot_start acc = function
+         ((PC.TOBrace(_),_) as x) :: rest ->
+           dot_start (x::acc) rest
+       | ((PC.TDot(_),_) :: rest) as x ->
+           Some ((PC.TOInit(clt),q) :: (List.rev acc) @ x)
+       | l -> None in
+      let rec comma_end acc = function
+         ((PC.TCBrace(_),_) as x) :: rest ->
+           comma_end (x::acc) rest
+       | ((PC.TComma(_),_) :: rest) as x ->
+           Some ((PC.TOInit(clt),q) :: (List.rev x) @ acc)
+       | l -> None in
+      (match dot_start [] rest with
+       Some x -> x
+      |        None ->
+         (match List.rev rest with
+           (* not super sure what this does, but EOF, @, and @@ should be
+              the same, markind the end of a rule *)
+           ((PC.EOF,_) as x)::rest | ((PC.TArob,_) as x)::rest
+         | ((PC.TArobArob,_) as x)::rest ->
+             (match comma_end [x] rest with
+               Some x -> x
+             | None -> tokens)
+         | _ ->
+             failwith "unexpected empty token list"))
+  | _ -> tokens
+
+(* ----------------------------------------------------------------------- *)
+(* process pragmas: they can only be used in + code, and adjacent to
+another + token.  They are concatenated to the string representation of
+that other token. *)
+
+let rec collect_all_pragmas collected = function
+    (PC.TPragma(s),_)::rest -> collect_all_pragmas (s::collected) rest
+  | l -> (List.rev collected,l)
+
+let rec collect_up_to_pragmas skipped = function
+    [] -> None (* didn't reach a pragma, so nothing to do *)
+  | ((PC.TPragma(s),_) as t)::rest ->
+      let (pragmas,rest) = collect_all_pragmas [] (t::rest) in
+      Some (List.rev skipped,pragmas,rest)
+  | x::xs ->
+      match plus_attachable x with
+       PLUS -> None
+      |        NOTPLUS -> None
+      |        SKIP -> collect_up_to_pragmas (x::skipped) xs
+
+let rec collect_up_to_plus skipped = function
+    [] -> failwith "nothing to attach a pragma to (empty)"
+  | x::xs ->
+      match plus_attachable x with
+       PLUS -> (List.rev skipped,x,xs)
+      |        NOTPLUS -> failwith "nothing to attach a pragma to"
+      |        SKIP -> collect_up_to_plus (x::skipped) xs
+
+let rec process_pragmas = function
+    [] -> []
+  | ((PC.TPragma(s),_)::_) as l ->
+      let (pragmas,rest) = collect_all_pragmas [] l in
+      let (skipped,aft,rest) = collect_up_to_plus [] rest in
+      let (a,b,c,d,e,strbef,straft,pos) = get_clt aft in
+      skipped@
+      (process_pragmas ((update_clt aft (a,b,c,d,e,pragmas,straft,pos))::rest))
+  | bef::xs ->
+      (match plus_attachable bef with
+       PLUS ->
+         (match collect_up_to_pragmas [] xs with
+           Some(skipped,pragmas,rest) ->
+             let (a,b,c,d,e,strbef,straft,pos) = get_clt bef in
+             (update_clt bef (a,b,c,d,e,strbef,pragmas,pos))::
+             skipped@(process_pragmas rest)
+         | None -> bef::(process_pragmas xs))
+      |        _ -> bef::(process_pragmas xs))
+
+(* ----------------------------------------------------------------------- *)
+(* Drop ... ... .  This is only allowed in + code, and arises when there is
+some - code between the ... *)
+(* drop whens as well - they serve no purpose in + code and they cause
+problems for drop_double_dots *)
+
+let rec drop_when = function
+    [] -> []
+  | (PC.TWhen(clt),info)::xs ->
+      let rec loop = function
+         [] -> []
+       | (PC.TLineEnd(_),info)::xs -> drop_when xs
+       | x::xs -> loop xs in
+      loop xs
+  | x::xs -> x::drop_when xs
+
+(* instead of dropping the double dots, we put TNothing in between them.
+these vanish after the parser, but keeping all the ...s in the + code makes
+it easier to align the + and - code in context_neg and in preparation for the
+isomorphisms.  This shouldn't matter because the context code of the +
+slice is mostly ignored anyway *)
+let minus_to_nothing l =
+  (* for cases like | <..., which may or may not arise from removing minus
+     code, depending on whether <... is a statement or expression *)
+  let is_minus tok =
+    try
+      let (d,_,_,_,_,_,_,_) = get_clt tok in
+      (match d with
+       D.MINUS | D.OPTMINUS | D.UNIQUEMINUS -> true
+      | D.PLUS -> false
+      | D.CONTEXT | D.UNIQUE | D.OPT -> false)
+    with _ -> false in
+  let rec minus_loop = function
+      [] -> []
+    | (d::ds) as l -> if is_minus d then minus_loop ds else l in
+  let rec loop = function
+      [] -> []
+    | ((PC.TMid0(clt),i) as x)::t1::ts when is_minus t1 ->
+       (match minus_loop ts with
+         ((PC.TOEllipsis(_),_)::_) | ((PC.TPOEllipsis(_),_)::_)
+       | ((PC.TEllipsis(_),_)::_) as l -> x::(PC.TNothing,i)::(loop l)
+       | l -> x::(loop l))
+    | t::ts -> t::(loop ts) in
+  loop l
+
+let rec drop_double_dots l =
+  let start = function
+      (PC.TOEllipsis(_),_) | (PC.TPOEllipsis(_),_)
+ (* | (PC.TOCircles(_),_) | (PC.TOStars(_),_) *) ->
+       true
+    | _ -> false in
+  let middle = function
+      (PC.TEllipsis(_),_) (* | (PC.TCircles(_),_) | (PC.TStars(_),_) *) -> true
+    | _ -> false in
+  let whenline = function
+      (PC.TLineEnd(_),_) -> true
+    (*| (PC.TMid0(_),_) -> true*)
+    | _ -> false in
+  let final = function
+      (PC.TCEllipsis(_),_) | (PC.TPCEllipsis(_),_)
+ (* | (PC.TCCircles(_),_) | (PC.TCStars(_),_) *) ->
+       true
+    | _ -> false in
+  let any_before x = start x or middle x or final x or whenline x in
+  let any_after x = start x or middle x or final x in
+  let rec loop ((_,i) as prev) = function
+      [] -> []
+    | x::rest when any_before prev && any_after x ->
+       (PC.TNothing,i)::x::(loop x rest)
+    | x::rest -> x :: (loop x rest) in
+  match l with
+    [] -> []
+  | (x::xs) -> x :: loop x xs
+
+let rec fix f l =
+  let cur = f l in
+  if l = cur then l else fix f cur
+
+(* ( | ... | ) also causes parsing problems *)
+
+exception Not_empty
+
+let rec drop_empty_thing starter middle ender = function
+    [] -> []
+  | hd::rest when starter hd ->
+      let rec loop = function
+         x::rest when middle x -> loop rest
+       | x::rest when ender x -> rest
+       | _ -> raise Not_empty in
+      (match try Some(loop rest) with Not_empty -> None with
+       Some x -> drop_empty_thing starter middle ender x
+      |        None -> hd :: drop_empty_thing starter middle ender rest)
+  | x::rest -> x :: drop_empty_thing starter middle ender rest
+
+let drop_empty_or =
+  drop_empty_thing
+    (function (PC.TOPar0(_),_) -> true | _ -> false)
+    (function (PC.TMid0(_),_) -> true | _ -> false)
+    (function (PC.TCPar0(_),_) -> true | _ -> false)
+
+let drop_empty_nest = drop_empty_thing
+
+(* ----------------------------------------------------------------------- *)
+(* Read tokens *)
+
+let get_s_starts (_, (s,_,(starts, ends))) =
+  Printf.printf "%d %d\n" starts ends; (s, starts)
+
+let pop2 l =
+  let v = List.hd !l in
+  l := List.tl !l;
+  v
+
+let reinit _ =
+  PC.reinit (function _ -> PC.TArobArob (* a handy token *))
+    (Lexing.from_function
+       (function buf -> function n -> raise Common.Impossible))
+
+let parse_one str parsefn file toks =
+  let all_tokens = ref toks in
+  let cur_tok    = ref (List.hd !all_tokens) in
+
+  let lexer_function _ =
+      let (v, info) = pop2 all_tokens in
+      cur_tok := (v, info);
+      v in
+
+  let lexbuf_fake =
+    Lexing.from_function
+      (function buf -> function n -> raise Common.Impossible)
+  in
+
+  reinit();
+
+  try parsefn lexer_function lexbuf_fake
+  with
+    Lexer_cocci.Lexical s ->
+      failwith
+       (Printf.sprintf "%s: lexical error: %s\n =%s\n" str s
+          (Common.error_message file (get_s_starts !cur_tok) ))
+  | Parser_cocci_menhir.Error ->
+      failwith
+       (Printf.sprintf "%s: parse error: \n = %s\n" str
+          (Common.error_message file (get_s_starts !cur_tok) ))
+  | Semantic_cocci.Semantic s ->
+      failwith
+       (Printf.sprintf "%s: semantic error: %s\n =%s\n" str s
+          (Common.error_message file (get_s_starts !cur_tok) ))
+
+  | e -> raise e
+
+let prepare_tokens tokens =
+  find_top_init
+    (translate_when_true_false (* after insert_line_end *)
+       (insert_line_end
+         (detect_types false (find_function_names (detect_attr tokens)))))
+
+let prepare_mv_tokens tokens =
+  detect_types false (detect_attr tokens)
+
+let rec consume_minus_positions = function
+    [] -> []
+  | ((PC.TOPar0(_),_) as x)::xs | ((PC.TCPar0(_),_) as x)::xs
+  | ((PC.TMid0(_),_) as x)::xs -> x::consume_minus_positions xs
+  | x::(PC.TPArob,_)::(PC.TMetaPos(name,constraints,per,clt),_)::xs ->
+      let (arity,ln,lln,offset,col,strbef,straft,_) = get_clt x in
+      let name = Parse_aux.clt2mcode name clt in
+      let x =
+       update_clt x
+         (arity,ln,lln,offset,col,strbef,straft,
+          Ast0.MetaPos(name,constraints,per)) in
+      x::(consume_minus_positions xs)
+  | x::xs -> x::consume_minus_positions xs
+
+let any_modif rule =
+  let mcode x =
+    match Ast0.get_mcode_mcodekind x with
+      Ast0.MINUS _ | Ast0.PLUS -> true
+    | _ -> false in
+  let donothing r k e = k e in
+  let bind x y = x or y in
+  let option_default = false in
+  let fn =
+    V0.combiner bind option_default
+      mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+      donothing donothing donothing donothing donothing donothing
+      donothing donothing donothing donothing donothing donothing donothing
+      donothing donothing in
+  List.exists fn.V0.combiner_top_level rule
+
+let drop_last extra l = List.rev(extra@(List.tl(List.rev l)))
+
+let partition_either l =
+  let rec part_either left right = function
+  | [] -> (List.rev left, List.rev right)
+  | x :: l ->
+      (match x with
+      | Common.Left  e -> part_either (e :: left) right l
+      | Common.Right e -> part_either left (e :: right) l) in
+  part_either [] [] l
+
+let get_metavars parse_fn table file lexbuf =
+  let rec meta_loop acc (* read one decl at a time *) =
+    let (_,tokens) =
+      tokens_all table file true lexbuf [PC.TArobArob;PC.TMPtVirg] in
+    let tokens = prepare_mv_tokens tokens in
+    match tokens with
+      [(PC.TArobArob,_)] -> List.rev acc
+    | _ ->
+       let metavars = parse_one "meta" parse_fn file tokens in
+       meta_loop (metavars@acc) in
+  partition_either (meta_loop [])
+
+let get_script_metavars parse_fn table file lexbuf =
+  let rec meta_loop acc =
+    let (_, tokens) =
+      tokens_all table file true lexbuf [PC.TArobArob; PC.TMPtVirg] in
+    let tokens = prepare_tokens tokens in
+    match tokens with
+      [(PC.TArobArob, _)] -> List.rev acc
+    | _ ->
+      let metavar = parse_one "scriptmeta" parse_fn file tokens in
+      meta_loop (metavar :: acc)
+  in
+  meta_loop []
+
+let get_rule_name parse_fn starts_with_name get_tokens file prefix =
+  Data.in_rule_name := true;
+  let mknm _ = make_name prefix (!Lexer_cocci.line) in
+  let name_res =
+    if starts_with_name
+    then
+      let (_,tokens) = get_tokens [PC.TArob] in
+      let check_name = function
+         None -> Some (mknm())
+       | Some nm ->
+           (if List.mem nm reserved_names
+           then failwith (Printf.sprintf "invalid name %s\n" nm));
+           Some nm in
+      match parse_one "rule name" parse_fn file tokens with
+       Ast.CocciRulename (nm,a,b,c,d,e) ->
+          Ast.CocciRulename (check_name nm,a,b,c,d,e)
+      | Ast.GeneratedRulename (nm,a,b,c,d,e) ->
+          Ast.GeneratedRulename (check_name nm,a,b,c,d,e)
+      | Ast.ScriptRulename(s,deps) -> Ast.ScriptRulename(s,deps)
+    else
+      Ast.CocciRulename(Some(mknm()),Ast.NoDep,[],[],Ast.Undetermined,false) in
+  Data.in_rule_name := false;
+  name_res
+
+let parse_iso file =
+  let table = Common.full_charpos_to_pos file in
+  Common.with_open_infile file (fun channel ->
+    let lexbuf = Lexing.from_channel channel in
+    let get_tokens = tokens_all table file false lexbuf in
+    let res =
+      match get_tokens [PC.TArobArob;PC.TArob] with
+       (true,start) ->
+         let parse_start start =
+           let rev = List.rev start in
+           let (arob,_) = List.hd rev in
+           (arob = PC.TArob,List.rev(List.tl rev)) in
+         let (starts_with_name,start) = parse_start start in
+         let rec loop starts_with_name start =
+           (!Data.init_rule)();
+           (* get metavariable declarations - have to be read before the
+              rest *)
+           let (rule_name,_,_,_,_,_) =
+              match get_rule_name PC.iso_rule_name starts_with_name get_tokens
+               file ("iso file "^file) with
+                Ast.CocciRulename (Some n,a,b,c,d,e) -> (n,a,b,c,d,e)
+              | _ -> failwith "Script rules cannot appear in isomorphism rules"
+              in
+           Ast0.rule_name := rule_name;
+           Data.in_meta := true;
+           let iso_metavars =
+             match get_metavars PC.iso_meta_main table file lexbuf with
+               (iso_metavars,[]) -> iso_metavars
+             | _ -> failwith "unexpected inheritance in iso" in
+           Data.in_meta := false;
+           (* get the rule *)
+           let (more,tokens) =
+             get_tokens
+               [PC.TIsoStatement;PC.TIsoExpression;PC.TIsoArgExpression;
+                 PC.TIsoTestExpression;
+                 PC.TIsoDeclaration;PC.TIsoType;PC.TIsoTopLevel] in
+           let next_start = List.hd(List.rev tokens) in
+           let dummy_info = ("",(-1,-1),(-1,-1)) in
+           let tokens = drop_last [(PC.EOF,dummy_info)] tokens in
+           let tokens = prepare_tokens (start@tokens) in
+            (*
+              print_tokens "iso tokens" tokens;
+           *)
+           let entry = parse_one "iso main" PC.iso_main file tokens in
+           let entry = List.map (List.map Test_exps.process_anything) entry in
+           if more
+           then (* The code below allows a header like Statement list,
+                   which is more than one word.  We don't have that any more,
+                   but the code is left here in case it is put back. *)
+             match get_tokens [PC.TArobArob;PC.TArob] with
+               (true,start) ->
+                 let (starts_with_name,start) = parse_start start in
+                 (iso_metavars,entry,rule_name) ::
+                 (loop starts_with_name (next_start::start))
+             | _ -> failwith "isomorphism ends early"
+           else [(iso_metavars,entry,rule_name)] in
+         loop starts_with_name start
+      | (false,_) -> [] in
+    res)
+
+let parse_iso_files existing_isos iso_files extra_path =
+  let get_names = List.map (function (_,_,nm) -> nm) in
+  let old_names = get_names existing_isos in
+  Data.in_iso := true;
+  let (res,_) =
+    List.fold_left
+      (function (prev,names) ->
+       function file ->
+         Lexer_cocci.init ();
+         let file =
+           match file with
+             Common.Left(fl)  -> Filename.concat extra_path fl
+           | Common.Right(fl) -> Filename.concat Config.path fl in
+         let current = parse_iso file in
+         let new_names = get_names current in
+         if List.exists (function x -> List.mem x names) new_names
+         then failwith (Printf.sprintf "repeated iso name found in %s" file);
+         (current::prev,new_names @ names))
+      ([],old_names) iso_files in
+  Data.in_iso := false;
+  existing_isos@(List.concat (List.rev res))
+
+let parse file =
+  let table = Common.full_charpos_to_pos file in
+  Common.with_open_infile file (fun channel ->
+  let lexbuf = Lexing.from_channel channel in
+  let get_tokens = tokens_all table file false lexbuf in
+  Data.in_prolog := true;
+  let initial_tokens = get_tokens [PC.TArobArob;PC.TArob] in
+  Data.in_prolog := false;
+  let res =
+    match initial_tokens with
+    (true,data) ->
+      (match List.rev data with
+       ((PC.TArobArob as x),_)::_ | ((PC.TArob as x),_)::_ ->
+         let iso_files =
+           parse_one "iso file names" PC.include_main file data in
+
+          let parse_cocci_rule ruletype old_metas
+             (rule_name, dependencies, iso, dropiso, exists, is_expression) =
+            Ast0.rule_name := rule_name;
+            Data.inheritable_positions :=
+               rule_name :: !Data.inheritable_positions;
+
+            (* get metavariable declarations *)
+            Data.in_meta := true;
+            let (metavars, inherited_metavars) =
+              get_metavars PC.meta_main table file lexbuf in
+            Data.in_meta := false;
+            Hashtbl.add Data.all_metadecls rule_name metavars;
+            Hashtbl.add Lexer_cocci.rule_names rule_name ();
+            Hashtbl.add Lexer_cocci.all_metavariables rule_name
+              (Hashtbl.fold
+                (fun key v rest -> (key,v)::rest)
+                Lexer_cocci.metavariables []);
+
+            (* get transformation rules *)
+            let (more, tokens) = get_tokens [PC.TArobArob; PC.TArob] in
+            let (minus_tokens, _) = split_token_stream tokens in
+            let (_, plus_tokens) =
+             split_token_stream (minus_to_nothing tokens) in
+
+           let minus_tokens = consume_minus_positions minus_tokens in
+           let minus_tokens = prepare_tokens minus_tokens in
+           let plus_tokens = prepare_tokens plus_tokens in
+
+           (*
+              print_tokens "minus tokens" minus_tokens;
+              print_tokens "plus tokens" plus_tokens;
+           *)
+
+           let plus_tokens =
+             process_pragmas
+               (fix (function x -> drop_double_dots (drop_empty_or x))
+                  (drop_when plus_tokens)) in
+           (*
+               print_tokens "plus tokens" plus_tokens;
+              Printf.printf "before minus parse\n";
+           *)
+           let minus_res =
+             if is_expression
+             then parse_one "minus" PC.minus_exp_main file minus_tokens
+             else parse_one "minus" PC.minus_main file minus_tokens in
+           (*
+              Unparse_ast0.unparse minus_res;
+              Printf.printf "before plus parse\n";
+           *)
+           let plus_res =
+             if !Flag.sgrep_mode2
+             then (* not actually used for anything, except context_neg *)
+               List.map
+                 (Iso_pattern.rebuild_mcode None).V0.rebuilder_top_level
+                 minus_res
+             else
+               if is_expression
+               then parse_one "plus" PC.plus_exp_main file plus_tokens
+               else parse_one "plus" PC.plus_main file plus_tokens in
+           (*
+              Printf.printf "after plus parse\n";
+           *)
+
+           (if not !Flag.sgrep_mode2 &&
+             (any_modif minus_res or any_modif plus_res)
+           then Data.inheritable_positions := []);
+
+           Check_meta.check_meta rule_name old_metas inherited_metavars
+             metavars minus_res plus_res;
+
+            (more, Ast0.CocciRule ((minus_res, metavars,
+              (iso, dropiso, dependencies, rule_name, exists)),
+              (plus_res, metavars), ruletype), metavars, tokens) in
+
+          let parse_script_rule language old_metas deps =
+            let get_tokens = tokens_script_all table file false lexbuf in
+
+              (* meta-variables *)
+            Data.in_meta := true;
+            let metavars =
+             get_script_metavars PC.script_meta_main table file lexbuf in
+            Data.in_meta := false;
+
+            let exists_in old_metas (py,(r,m)) =
+              let test (rr,mr) x =
+                let (ro,vo) = Ast.get_meta_name x in
+                ro = rr && vo = mr in
+              List.exists (test (r,m)) old_metas in
+
+           List.iter
+             (function x ->
+               let meta2c (r,n) = Printf.sprintf "%s.%s" r n in
+               if not (exists_in old_metas x) then
+                 failwith
+                   (Printf.sprintf
+                      "Script references unknown meta-variable: %s"
+                      (meta2c(snd x))))
+             metavars;
+
+              (* script code *)
+            let (more, tokens) = get_tokens [PC.TArobArob; PC.TArob] in
+            let data =
+              match List.hd tokens with
+                (PC.TScriptData(s),_) -> s
+              | (PC.TArobArob,_) | (PC.TArob,_) -> ""
+              | _ -> failwith "Malformed script rule" in
+            (more,Ast0.ScriptRule(language, deps, metavars, data),[],tokens) in
+
+          let parse_rule old_metas starts_with_name =
+            let rulename =
+             get_rule_name PC.rule_name starts_with_name get_tokens file
+               "rule" in
+            match rulename with
+              Ast.CocciRulename (Some s, a, b, c, d, e) ->
+                parse_cocci_rule Ast.Normal old_metas (s, a, b, c, d, e)
+            | Ast.GeneratedRulename (Some s, a, b, c, d, e) ->
+               Data.in_generating := true;
+                let res =
+                 parse_cocci_rule Ast.Generated old_metas (s,a,b,c,d,e) in
+               Data.in_generating := false;
+               res
+            | Ast.ScriptRulename (l,deps) -> parse_script_rule l old_metas deps
+            | _ -> failwith "Malformed rule name"
+            in
+
+         let rec loop old_metas starts_with_name =
+           (!Data.init_rule)();
+
+            let gen_starts_with_name more tokens =
+              more &&
+              (match List.hd (List.rev tokens) with
+                    (PC.TArobArob,_) -> false
+                  | (PC.TArob,_) -> true
+                  | _ -> failwith "unexpected token")
+            in
+
+            let (more, rule, metavars, tokens) =
+              parse_rule old_metas starts_with_name in
+            if more then
+              rule::
+             (loop (metavars @ old_metas) (gen_starts_with_name more tokens))
+            else [rule];
+
+            in
+
+         (iso_files, loop [] (x = PC.TArob))
+      |        _ -> failwith "unexpected code before the first rule\n")
+  | (false,[(PC.TArobArob,_)]) | (false,[(PC.TArob,_)]) ->
+      ([],([] : Ast0.parsed_rule list))
+  | _ -> failwith "unexpected code before the first rule\n" in
+  res)
+
+(* parse to ast0 and then convert to ast *)
+let process file isofile verbose =
+  let extra_path = Filename.dirname file in
+  Lexer_cocci.init();
+  let (iso_files, rules) = parse file in
+  let std_isos =
+    match isofile with
+      None -> []
+    | Some iso_file -> parse_iso_files [] [Common.Left iso_file] "" in
+  let global_isos = parse_iso_files std_isos iso_files extra_path in
+  let rules = Unitary_ast0.do_unitary rules in
+  let parsed =
+    List.map
+      (function
+          Ast0.ScriptRule (a,b,c,d) -> [([],Ast.ScriptRule (a,b,c,d))]
+       | Ast0.CocciRule
+           ((minus, metavarsm,
+             (iso, dropiso, dependencies, rule_name, exists)),
+            (plus, metavars),ruletype) ->
+              let chosen_isos =
+                parse_iso_files global_isos
+                  (List.map (function x -> Common.Left x) iso)
+                  extra_path in
+              let chosen_isos =
+            (* check that dropped isos are actually available *)
+                (try
+                  let iso_names =
+                    List.map (function (_,_,nm) -> nm) chosen_isos in
+                  let local_iso_names = reserved_names @ iso_names in
+                  let bad_dropped =
+                    List.find
+                      (function dropped ->
+                        not (List.mem dropped local_iso_names))
+                      dropiso in
+                  failwith
+                    ("invalid iso name " ^ bad_dropped ^ " in " ^ rule_name)
+                with Not_found -> ());
+                if List.mem "all" dropiso
+                then
+                  if List.length dropiso = 1
+                  then []
+                  else failwith "disable all should only be by itself"
+                else (* drop those isos *)
+                  List.filter
+                    (function (_,_,nm) -> not (List.mem nm dropiso))
+                    chosen_isos in
+              List.iter Iso_compile.process chosen_isos;
+              let dropped_isos =
+                match reserved_names with
+                  "all"::others ->
+                    (match dropiso with
+                      ["all"] -> others
+                    | _ ->
+                        List.filter (function x -> List.mem x dropiso) others)
+                | _ ->
+                    failwith
+                      "bad list of reserved names - all must be at start" in
+              let minus = Test_exps.process minus in
+              let minus = Compute_lines.compute_lines minus in
+              let plus = Compute_lines.compute_lines plus in
+              let is_exp =
+                (* only relevant to Flag.make_hrule *)
+                (* doesn't handle multiple minirules properly, but since
+                   we don't really handle them in lots of other ways, it
+                   doesn't seem very important *)
+                match plus with
+                  [] -> [false]
+                | p::_ ->
+                    [match Ast0.unwrap p with
+                      Ast0.CODE c ->
+                        (match List.map Ast0.unwrap (Ast0.undots c) with
+                          [Ast0.Exp e] -> true | _ -> false)
+                    | _ -> false] in
+              let minus = Arity.minus_arity minus in
+              let ((metavars,minus),function_prototypes) =
+                Function_prototypes.process
+                  rule_name metavars dropped_isos minus plus ruletype in
+          (* warning! context_neg side-effects its arguments *)
+              let (m,p) = List.split (Context_neg.context_neg minus plus) in
+              Type_infer.type_infer p;
+              (if not !Flag.sgrep_mode2
+              then Insert_plus.insert_plus m p (chosen_isos = []));
+              Type_infer.type_infer minus;
+              let (extra_meta, minus) =
+                match (chosen_isos,ruletype) with
+                  (* separate case for [] because applying isos puts
+                     some restrictions on the -+ code *)
+                  ([],_) | (_,Ast.Generated) -> ([],minus)
+                | _ -> Iso_pattern.apply_isos chosen_isos minus rule_name in
+              let minus = Comm_assoc.comm_assoc minus rule_name dropiso in
+              let minus =
+                if !Flag.sgrep_mode2 then minus
+                else Single_statement.single_statement minus in
+              let minus = Simple_assignments.simple_assignments minus in
+              let minus_ast =
+                Ast0toast.ast0toast rule_name dependencies dropped_isos
+                  exists minus is_exp ruletype in
+              match function_prototypes with
+                None -> [(extra_meta @ metavars, minus_ast)]
+              | Some mv_fp ->
+                  [(extra_meta @ metavars, minus_ast); mv_fp])
+(*          Ast0.CocciRule ((minus, metavarsm, (iso, dropiso, dependencies, rule_name, exists)), (plus, metavars))*)
+      rules in
+  let parsed = List.concat parsed in
+  let disjd = Disjdistr.disj parsed in
+
+  let (metavars,code,fvs,neg_pos,ua,pos) = Free_vars.free_vars disjd in
+  if !Flag_parsing_cocci.show_SP
+  then List.iter Pretty_print_cocci.unparse code;
+
+  let grep_tokens =
+    Common.profile_code "get_constants"
+      (fun () -> Get_constants.get_constants code) in (* for grep *)
+  let glimpse_tokens2 =
+    Common.profile_code "get_glimpse_constants"
+      (fun () -> Get_constants2.get_constants code neg_pos) in(* for glimpse *)
+  (metavars,code,fvs,neg_pos,ua,pos,grep_tokens,glimpse_tokens2)
diff --git a/parsing_cocci/.#parser_cocci_menhir.mly.1.168 b/parsing_cocci/.#parser_cocci_menhir.mly.1.168
new file mode 100644 (file)
index 0000000..09fb8ad
--- /dev/null
@@ -0,0 +1,1859 @@
+/*
+* Copyright 2005-2009, 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 TInitialiser
+%token Tlist TFresh TConstant TError TWords TWhy0 TPlus0 TBang0
+%token TPure TContext TGenerated
+%token TTypedef TDeclarer TIterator TName TPosition TPosAny
+%token TUsing TDisable TExtends TDepends TOn TEver TNever TExists TForall
+%token TScript TReverse TNothing
+%token<string> TRuleName
+
+%token<Data.clt> Tchar Tshort Tint Tdouble Tfloat Tlong
+%token<Data.clt> Tvoid Tstruct Tunion Tenum
+%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.info>       TMetaInit
+%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 }
+  | TGenerated extends d=depends i=loption(choose_iso)
+    a=loption(disable) e=exists ee=is_expression TArob
+      /* these rules have no name as a cheap way to ensure that no normal
+      rule inherits their metavariables or depends on them */
+      { P.make_generated_rule_name_result None 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
+    (* pb: position variables can't be inherited from normal rules, and then
+       there is no way to inherit from a generated rule, so there is no point
+       to have a position variable *)
+    { (if !Data.in_generating
+      then failwith "position variables not allowed in a generated rule file");
+      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) }
+| TInitialiser
+    { (fun arity name pure check_meta ->
+      let tok = check_meta(Ast.MetaInitDecl(arity,name)) in
+      !Data.add_init_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_full:
+       q=ctype_qualif_opt ty=Tchar
+        { q (Ast0.wrap(Ast0.BaseType(Ast.CharType,[P.clt2mcode "char" ty]))) }
+     | q=ctype_qualif_opt ty=Tshort
+        { q (Ast0.wrap(Ast0.BaseType(Ast.ShortType,[P.clt2mcode "short" ty])))}
+     | q=ctype_qualif_opt ty=Tint
+         { q (Ast0.wrap(Ast0.BaseType(Ast.IntType,[P.clt2mcode "int" ty]))) }
+     | t=Tdouble
+         { Ast0.wrap(Ast0.BaseType(Ast.DoubleType,[P.clt2mcode "double" t])) }
+     | t=Tfloat
+         { Ast0.wrap(Ast0.BaseType(Ast.FloatType,[P.clt2mcode "float" t])) }
+     | q=ctype_qualif_opt ty=Tlong
+         { q (Ast0.wrap(Ast0.BaseType(Ast.LongType,[P.clt2mcode "long" ty]))) }
+     | q=ctype_qualif_opt ty=Tlong ty1=Tlong
+         { q (Ast0.wrap
+               (Ast0.BaseType
+                  (Ast.LongLongType,
+                     [P.clt2mcode "long" ty;P.clt2mcode "long" ty1]))) }
+     | s=Tenum i=ident
+        { Ast0.wrap(Ast0.EnumName(P.clt2mcode "enum" s, i)) }
+     | 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)) }
+     | q=ctype_qualif_opt p=TMetaType
+        { let (nm,pure,clt) = p in
+        q (Ast0.wrap(Ast0.MetaType(P.clt2mcode nm clt,pure))) }
+
+generic_ctype:
+       q=ctype_qualif     { q None }
+     | generic_ctype_full { $1 }
+
+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(Ast.VoidType,[P.clt2mcode "void" t])) 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)) }
+
+ctype_full:
+       cv=ioption(const_vol) ty=generic_ctype_full 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(Ast.VoidType,[P.clt2mcode "void" t])) 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(Ast.VoidType,[P.clt2mcode "void" t])))
+            m }
+
+%inline ctype_qualif:
+  r=Tunsigned
+   { function x -> Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Unsigned r,x)) }
+| r=Tsigned
+   { function x -> Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Signed r,x)) }
+
+%inline ctype_qualif_opt:
+  s=ctype_qualif  { function x -> s (Some x) }
+| /* empty */   { function x -> x }
+
+/*****************************************************************************/
+
+/* 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(Ast.VoidType,[P.clt2mcode "void" t])) 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(Ast.VoidType,[P.clt2mcode "void" t])) 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)) }
+
+%inline stm_dots_ell:
+  a=TEllipsis w=list(whenppdecs)
+    { Ast0.wrap(Ast0.Dots(P.clt2mcode "..." a, List.concat w)) }
+
+%inline stm_dots_nest:
+  a=TOEllipsis w=list(whenppdecs) b=nest_start c=TCEllipsis
+    { Ast0.wrap(Ast0.Nest(P.clt2mcode "<..." a, b,
+                         P.clt2mcode "...>" c, List.concat w, false)) }
+| a=TPOEllipsis w=list(whenppdecs) b=nest_start c=TPCEllipsis
+    { Ast0.wrap(Ast0.Nest(P.clt2mcode "<+..." a, 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_full 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)) }
+  | TMetaInit
+      {let (nm,pure,clt) = $1 in
+      Ast0.wrap(Ast0.MetaInit(P.clt2mcode nm clt,pure)) }
+
+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 */
+| list(designator) TEq initialize2
+    { Ast0.wrap(Ast0.InitGccExt($1,P.clt2mcode "=" $2,$3)) }
+| ident TDotDot initialize2
+    { Ast0.wrap(Ast0.InitGccName($1,P.clt2mcode ":" $2,$3)) } /* in old kernel */
+
+designator: 
+ | TDot ident 
+     { Ast0.DesignatorField (P.clt2mcode "." $1,$2) } 
+ | TOCro eexpr TCCro 
+     { Ast0.DesignatorIndex (P.clt2mcode "[" $1,$2,P.clt2mcode "]" $3) }
+ | TOCro eexpr TEllipsis eexpr TCCro 
+     { Ast0.DesignatorRange (P.clt2mcode "[" $1,$2,P.clt2mcode "..." $3,
+                            $4,P.clt2mcode "]" $5) }
+
+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 }
+
+/* not clear what whencode would mean, so just drop it */
+nest_expressions:
+  TOEllipsis e=expr_dots(TEllipsis) c=TCEllipsis
+    { Ast0.wrap(Ast0.NestExpr(P.clt2mcode "<..." $1,
+                             Ast0.wrap(Ast0.DOTS(e (P.mkedots "..."))),
+                             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, None, 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") }
+     | TName                     { (None,"name") }
+
+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");
+          (if !Data.in_generating
+           (* pb: constraints not stored with metavars; too lazy to search for
+             them in the pattern *)
+          then failwith "constraints not allowed in a generated rule 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");
+          (if !Data.in_generating
+          then failwith "constraints not allowed in a generated rule 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");
+          (if !Data.in_generating
+          then failwith "constraints not allowed in a generated rule 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");
+          (if !Data.in_generating
+          then failwith "constraints not allowed in a generated rule 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");
+          (if !Data.in_generating
+          then failwith "constraints not allowed in a generated rule file");
+          [i] }
+     | TNotEq TOBrace l=comma_list(ident_or_const) TCBrace
+        { (if !Data.in_iso
+          then failwith "constraints not allowed in iso file");
+          (if !Data.in_generating
+          then failwith "constraints not allowed in a generated rule 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");
+          (if !Data.in_generating
+          then failwith "constraints not allowed in a generated rule 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");
+          (if !Data.in_generating
+          then failwith "constraints not allowed in a generated rule 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):
+  /* empty */ { Ast0.wrap(Ast0.DOTS([])) }
+| 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_startne(toplevel_after_dots_init)
+    { List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) $1 }
+
+toplevel_seq_startne(after_dots_init):
+  a=stm_dots_ell b=after_dots_init           { a::b }
+| a=stm_dots_nest b=after_dots_init           { a::b }
+| a=stm_dots_nest                      { [a] }
+| expr toplevel_after_exp            { (Ast0.wrap(Ast0.Exp($1)))::$2 }
+| decl_statement_expr toplevel_after_stm  { $1@$2 }
+
+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/.#parser_cocci_menhir.mly.1.169 b/parsing_cocci/.#parser_cocci_menhir.mly.1.169
new file mode 100644 (file)
index 0000000..71ed6ef
--- /dev/null
@@ -0,0 +1,1859 @@
+/*
+* Copyright 2005-2009, 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 TInitialiser
+%token Tlist TFresh TConstant TError TWords TWhy0 TPlus0 TBang0
+%token TPure TContext TGenerated
+%token TTypedef TDeclarer TIterator TName TPosition TPosAny
+%token TUsing TDisable TExtends TDepends TOn TEver TNever TExists TForall
+%token TScript TReverse TNothing
+%token<string> TRuleName
+
+%token<Data.clt> Tchar Tshort Tint Tdouble Tfloat Tlong
+%token<Data.clt> Tvoid Tstruct Tunion Tenum
+%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.info>       TMetaInit
+%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 }
+  | TGenerated extends d=depends i=loption(choose_iso)
+    a=loption(disable) e=exists ee=is_expression TArob
+      /* these rules have no name as a cheap way to ensure that no normal
+      rule inherits their metavariables or depends on them */
+      { P.make_generated_rule_name_result None 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
+    (* pb: position variables can't be inherited from normal rules, and then
+       there is no way to inherit from a generated rule, so there is no point
+       to have a position variable *)
+    { (if !Data.in_generating
+      then failwith "position variables not allowed in a generated rule file");
+      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) }
+| TInitialiser
+    { (fun arity name pure check_meta ->
+      let tok = check_meta(Ast.MetaInitDecl(arity,name)) in
+      !Data.add_init_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_full:
+       q=ctype_qualif_opt ty=Tchar
+        { q (Ast0.wrap(Ast0.BaseType(Ast.CharType,[P.clt2mcode "char" ty]))) }
+     | q=ctype_qualif_opt ty=Tshort
+        { q (Ast0.wrap(Ast0.BaseType(Ast.ShortType,[P.clt2mcode "short" ty])))}
+     | q=ctype_qualif_opt ty=Tint
+         { q (Ast0.wrap(Ast0.BaseType(Ast.IntType,[P.clt2mcode "int" ty]))) }
+     | t=Tdouble
+         { Ast0.wrap(Ast0.BaseType(Ast.DoubleType,[P.clt2mcode "double" t])) }
+     | t=Tfloat
+         { Ast0.wrap(Ast0.BaseType(Ast.FloatType,[P.clt2mcode "float" t])) }
+     | q=ctype_qualif_opt ty=Tlong
+         { q (Ast0.wrap(Ast0.BaseType(Ast.LongType,[P.clt2mcode "long" ty]))) }
+     | q=ctype_qualif_opt ty=Tlong ty1=Tlong
+         { q (Ast0.wrap
+               (Ast0.BaseType
+                  (Ast.LongLongType,
+                     [P.clt2mcode "long" ty;P.clt2mcode "long" ty1]))) }
+     | s=Tenum i=ident
+        { Ast0.wrap(Ast0.EnumName(P.clt2mcode "enum" s, i)) }
+     | 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)) }
+     | q=ctype_qualif_opt p=TMetaType
+        { let (nm,pure,clt) = p in
+        q (Ast0.wrap(Ast0.MetaType(P.clt2mcode nm clt,pure))) }
+
+generic_ctype:
+       q=ctype_qualif     { q None }
+     | generic_ctype_full { $1 }
+
+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(Ast.VoidType,[P.clt2mcode "void" t])) 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)) }
+
+ctype_full:
+       cv=ioption(const_vol) ty=generic_ctype_full 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(Ast.VoidType,[P.clt2mcode "void" t])) 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(Ast.VoidType,[P.clt2mcode "void" t])))
+            m }
+
+%inline ctype_qualif:
+  r=Tunsigned
+   { function x -> Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Unsigned r,x)) }
+| r=Tsigned
+   { function x -> Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Signed r,x)) }
+
+%inline ctype_qualif_opt:
+  s=ctype_qualif  { function x -> s (Some x) }
+| /* empty */   { function x -> x }
+
+/*****************************************************************************/
+
+/* 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(Ast.VoidType,[P.clt2mcode "void" t])) 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(Ast.VoidType,[P.clt2mcode "void" t])) 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)) }
+
+%inline stm_dots_ell:
+  a=TEllipsis w=list(whenppdecs)
+    { Ast0.wrap(Ast0.Dots(P.clt2mcode "..." a, List.concat w)) }
+
+%inline stm_dots_nest:
+  a=TOEllipsis w=list(whenppdecs) b=nest_start c=TCEllipsis
+    { Ast0.wrap(Ast0.Nest(P.clt2mcode "<..." a, b,
+                         P.clt2mcode "...>" c, List.concat w, false)) }
+| a=TPOEllipsis w=list(whenppdecs) b=nest_start c=TPCEllipsis
+    { Ast0.wrap(Ast0.Nest(P.clt2mcode "<+..." a, 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_full 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)) }
+  | TMetaInit
+      {let (nm,pure,clt) = $1 in
+      Ast0.wrap(Ast0.MetaInit(P.clt2mcode nm clt,pure)) }
+
+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 */
+| list(designator) TEq initialize2
+    { Ast0.wrap(Ast0.InitGccExt($1,P.clt2mcode "=" $2,$3)) }
+| ident TDotDot initialize2
+    { Ast0.wrap(Ast0.InitGccName($1,P.clt2mcode ":" $2,$3)) } /* in old kernel */
+
+designator: 
+ | TDot ident 
+     { Ast0.DesignatorField (P.clt2mcode "." $1,$2) } 
+ | TOCro eexpr TCCro 
+     { Ast0.DesignatorIndex (P.clt2mcode "[" $1,$2,P.clt2mcode "]" $3) }
+ | TOCro eexpr TEllipsis eexpr TCCro 
+     { Ast0.DesignatorRange (P.clt2mcode "[" $1,$2,P.clt2mcode "..." $3,
+                            $4,P.clt2mcode "]" $5) }
+
+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 }
+
+/* not clear what whencode would mean, so just drop it */
+nest_expressions:
+  TOEllipsis e=expr_dots(TEllipsis) c=TCEllipsis
+    { Ast0.wrap(Ast0.NestExpr(P.clt2mcode "<..." $1,
+                             Ast0.wrap(Ast0.DOTS(e (P.mkedots "..."))),
+                             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, None, 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 cast_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") }
+     | TName                     { (None,"name") }
+
+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");
+          (if !Data.in_generating
+           (* pb: constraints not stored with metavars; too lazy to search for
+             them in the pattern *)
+          then failwith "constraints not allowed in a generated rule 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");
+          (if !Data.in_generating
+          then failwith "constraints not allowed in a generated rule 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");
+          (if !Data.in_generating
+          then failwith "constraints not allowed in a generated rule 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");
+          (if !Data.in_generating
+          then failwith "constraints not allowed in a generated rule 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");
+          (if !Data.in_generating
+          then failwith "constraints not allowed in a generated rule file");
+          [i] }
+     | TNotEq TOBrace l=comma_list(ident_or_const) TCBrace
+        { (if !Data.in_iso
+          then failwith "constraints not allowed in iso file");
+          (if !Data.in_generating
+          then failwith "constraints not allowed in a generated rule 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");
+          (if !Data.in_generating
+          then failwith "constraints not allowed in a generated rule 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");
+          (if !Data.in_generating
+          then failwith "constraints not allowed in a generated rule 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):
+  /* empty */ { Ast0.wrap(Ast0.DOTS([])) }
+| 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_startne(toplevel_after_dots_init)
+    { List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) $1 }
+
+toplevel_seq_startne(after_dots_init):
+  a=stm_dots_ell b=after_dots_init           { a::b }
+| a=stm_dots_nest b=after_dots_init           { a::b }
+| a=stm_dots_nest                      { [a] }
+| expr toplevel_after_exp            { (Ast0.wrap(Ast0.Exp($1)))::$2 }
+| decl_statement_expr toplevel_after_stm  { $1@$2 }
+
+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/.#pretty_print_cocci.ml.1.135 b/parsing_cocci/.#pretty_print_cocci.ml.1.135
new file mode 100644 (file)
index 0000000..9675e49
--- /dev/null
@@ -0,0 +1,865 @@
+(*
+* Copyright 2005-2009, 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 Ast = Ast_cocci
+
+let print_plus_flag = ref true
+let print_minus_flag = ref true
+let print_newlines_disj = ref true
+
+let start_block str =
+  force_newline(); print_string "  "; open_box 0
+
+let end_block str =
+  close_box(); force_newline ()
+
+let print_string_box s = print_string s; open_box 0
+
+
+let print_option = Common.do_option
+let print_between = Common.print_between
+
+(* --------------------------------------------------------------------- *)
+(* Modified code *)
+
+(* avoid polyvariance problems *)
+let anything : (Ast.anything -> unit) ref = ref (function _ -> ())
+
+let rec print_anything str = function
+    [] -> ()
+  | stream ->
+      start_block();
+      print_between force_newline
+       (function x ->
+         print_string str; open_box 0; print_anything_list x; close_box())
+       stream;
+      end_block()
+
+and print_anything_list = function
+    [] -> ()
+  | [x] -> !anything x
+  | bef::((aft::_) as rest) ->
+      !anything bef;
+      let space =
+       (match bef with
+         Ast.Rule_elemTag(_) | Ast.AssignOpTag(_) | Ast.BinaryOpTag(_)
+       | Ast.ArithOpTag(_) | Ast.LogicalOpTag(_)
+       | Ast.Token("if",_) | Ast.Token("while",_) -> true | _ -> false) or
+       (match aft with
+         Ast.Rule_elemTag(_) | Ast.AssignOpTag(_) | Ast.BinaryOpTag(_)
+       | Ast.ArithOpTag(_) | Ast.LogicalOpTag(_) | Ast.Token("{",_) -> true
+       | _ -> false) in
+      if space then print_string " ";
+      print_anything_list rest
+
+let print_around printer term = function
+    Ast.NOTHING -> printer term
+  | Ast.BEFORE(bef) -> print_anything "<<< " bef; printer term
+  | Ast.AFTER(aft) -> printer term; print_anything ">>> " aft
+  | Ast.BEFOREAFTER(bef,aft) ->
+      print_anything "<<< " bef; printer term; print_anything ">>> " aft
+
+let print_string_befaft fn x info =
+  List.iter (function s -> print_string s; force_newline())
+    info.Ast.strbef;
+  fn x;
+  List.iter (function s -> force_newline(); print_string s)
+    info.Ast.straft
+
+let print_meta (r,x) = print_string r; print_string ":"; print_string x
+
+let print_pos = function
+    Ast.MetaPos(name,_,_,_,_) ->
+      let name = Ast.unwrap_mcode name in
+      print_string "@"; print_meta name
+  | _ -> ()
+
+let mcode fn = function
+    (x, _, Ast.MINUS(_,plus_stream), pos) ->
+      if !print_minus_flag
+      then print_string (if !Flag.sgrep_mode2 then "*" else "-");
+      fn x; print_pos pos;
+      if !print_plus_flag
+      then print_anything ">>> " plus_stream
+  | (x, _, Ast.CONTEXT(_,plus_streams), pos) ->
+      if !print_plus_flag
+      then
+       let fn x = fn x; print_pos pos in
+       print_around fn x plus_streams
+      else (fn x; print_pos pos)
+  | (x, info, Ast.PLUS, pos) ->
+      let fn x = fn x; print_pos pos in
+      print_string_befaft fn x info
+
+let print_mcodekind = function
+    Ast.MINUS(_,plus_stream) ->
+      print_string "MINUS";
+      print_anything ">>> " plus_stream
+  | Ast.CONTEXT(_,plus_streams) ->
+      print_around (function _ -> print_string "CONTEXT") () plus_streams
+  | Ast.PLUS -> print_string "PLUS"
+
+(* --------------------------------------------------------------------- *)
+(* --------------------------------------------------------------------- *)
+(* Dots *)
+
+let dots between fn d =
+  match Ast.unwrap d with
+    Ast.DOTS(l) -> print_between between fn l
+  | Ast.CIRCLES(l) -> print_between between fn l
+  | Ast.STARS(l) -> print_between between fn l
+
+let nest_dots multi fn f d =
+  let mo s = if multi then "<+"^s else "<"^s in
+  let mc s = if multi then s^"+>" else s^">" in
+  match Ast.unwrap d with
+    Ast.DOTS(l) ->
+      print_string (mo "..."); f(); start_block();
+      print_between force_newline fn l;
+      end_block(); print_string (mc "...")
+  | Ast.CIRCLES(l) ->
+      print_string (mo "ooo"); f(); start_block();
+      print_between force_newline fn l;
+      end_block(); print_string (mc "ooo")
+  | Ast.STARS(l) ->
+      print_string (mo "***"); f(); start_block();
+      print_between force_newline fn l;
+      end_block(); print_string (mc "***")
+
+(* --------------------------------------------------------------------- *)
+
+let print_type keep info = function
+    None -> ()
+       (* print_string "/* ";
+           print_string "keep:"; print_unitary keep;
+           print_string " inherited:"; print_bool inherited;
+           print_string " */"*)
+  | Some ty -> ()
+      (*;
+      print_string "/* ";
+      print_between (function _ -> print_string ", ") Type_cocci.typeC ty;(*
+      print_string "keep:"; print_unitary keep;
+      print_string " inherited:"; print_bool inherited;*)
+      print_string " */"*)
+
+(* --------------------------------------------------------------------- *)
+(* Identifier *)
+
+let rec ident i =
+  match Ast.unwrap i with
+    Ast.Id(name) -> mcode print_string name
+  | Ast.MetaId(name,_,keep,inherited) -> mcode print_meta name
+  | Ast.MetaFunc(name,_,_,_) -> mcode print_meta name
+  | Ast.MetaLocalFunc(name,_,_,_) -> mcode print_meta name
+  | Ast.OptIdent(id) -> print_string "?"; ident id
+  | Ast.UniqueIdent(id) -> print_string "!"; ident id
+
+and print_unitary = function
+    Type_cocci.Unitary -> print_string "unitary"
+  | Type_cocci.Nonunitary -> print_string "nonunitary"
+  | Type_cocci.Saved -> print_string "saved"
+
+(* --------------------------------------------------------------------- *)
+(* Expression *)
+
+let print_disj_list fn l =
+  if !print_newlines_disj
+  then (force_newline(); print_string "("; force_newline())
+  else print_string "(";
+  print_between
+    (function _ ->
+      if !print_newlines_disj
+      then (force_newline(); print_string "|"; force_newline())
+      else print_string " | ")
+    fn l;
+  if !print_newlines_disj
+  then (force_newline(); print_string ")"; force_newline())
+  else print_string ")"
+
+let rec expression e =
+  match Ast.unwrap e with
+    Ast.Ident(id) -> ident id
+  | Ast.Constant(const) -> mcode constant const
+  | Ast.FunCall(fn,lp,args,rp) ->
+      expression fn; mcode print_string_box lp;
+      dots (function _ -> ()) expression args;
+      close_box(); mcode print_string rp
+  | Ast.Assignment(left,op,right,simple) ->
+      expression left; print_string " "; mcode assignOp op;
+      print_string " "; expression right
+  | Ast.CondExpr(exp1,why,exp2,colon,exp3) ->
+      expression exp1; print_string " "; mcode print_string why;
+      print_option (function e -> print_string " "; expression e) exp2;
+      print_string " "; mcode print_string colon; expression exp3
+  | Ast.Postfix(exp,op) -> expression exp; mcode fixOp op
+  | Ast.Infix(exp,op) -> mcode fixOp op; expression exp
+  | Ast.Unary(exp,op) -> mcode unaryOp op; expression exp
+  | Ast.Binary(left,op,right) ->
+      expression left; print_string " "; mcode binaryOp op; print_string " ";
+      expression right
+  | Ast.Nested(left,op,right) ->
+      expression left; print_string " "; mcode binaryOp op; print_string " ";
+      expression right
+  | Ast.Paren(lp,exp,rp) ->
+      mcode print_string_box lp; expression exp; close_box();
+      mcode print_string rp
+  | Ast.ArrayAccess(exp1,lb,exp2,rb) ->
+      expression exp1; mcode print_string_box lb; expression exp2; close_box();
+      mcode print_string rb
+  | Ast.RecordAccess(exp,pt,field) ->
+      expression exp; mcode print_string pt; ident field
+  | Ast.RecordPtAccess(exp,ar,field) ->
+      expression exp; mcode print_string ar; ident field
+  | Ast.Cast(lp,ty,rp,exp) ->
+      mcode print_string_box lp; fullType ty; close_box();
+      mcode print_string rp; expression exp
+  | Ast.SizeOfExpr(sizeof,exp) ->
+      mcode print_string sizeof; expression exp
+  | Ast.SizeOfType(sizeof,lp,ty,rp) ->
+      mcode print_string sizeof;
+      mcode print_string_box lp; fullType ty; close_box();
+      mcode print_string rp
+  | Ast.TypeExp(ty) -> fullType ty
+
+  | Ast.MetaErr(name,_,_,_) -> mcode print_meta name
+  | Ast.MetaExpr(name,_,keep,ty,form,inherited) ->
+      mcode print_meta name; print_type keep inherited ty
+  | Ast.MetaExprList(name,_,_,_) -> mcode print_meta name
+  | Ast.EComma(cm) -> mcode print_string cm; print_space()
+  | Ast.DisjExpr(exp_list) -> print_disj_list expression exp_list
+  | Ast.NestExpr(expr_dots,Some whencode,multi) ->
+      nest_dots multi expression
+       (function _ -> print_string "   when != "; expression whencode)
+       expr_dots
+  | Ast.NestExpr(expr_dots,None,multi) ->
+      nest_dots multi expression (function _ -> ()) expr_dots
+  | Ast.Edots(dots,Some whencode)
+  | Ast.Ecircles(dots,Some whencode)
+  | Ast.Estars(dots,Some whencode) ->
+      mcode print_string dots; print_string "   when != "; expression whencode
+  | Ast.Edots(dots,None)
+  | Ast.Ecircles(dots,None)
+  | Ast.Estars(dots,None) -> mcode print_string dots
+  | Ast.OptExp(exp) -> print_string "?"; expression exp
+  | Ast.UniqueExp(exp) -> print_string "!"; expression exp
+
+and  unaryOp = function
+    Ast.GetRef -> print_string "&"
+  | Ast.DeRef -> print_string "*"
+  | Ast.UnPlus -> print_string "+"
+  | Ast.UnMinus -> print_string "-"
+  | Ast.Tilde -> print_string "~"
+  | Ast.Not -> print_string "!"
+
+and  assignOp = function
+    Ast.SimpleAssign -> print_string "="
+  | Ast.OpAssign(aop) -> arithOp aop; print_string "="
+
+and  fixOp = function
+    Ast.Dec -> print_string "--"
+  | Ast.Inc -> print_string "++"
+
+and  binaryOp = function
+    Ast.Arith(aop) -> arithOp aop
+  | Ast.Logical(lop) -> logicalOp lop
+
+and  arithOp = function
+    Ast.Plus -> print_string "+"
+  | Ast.Minus -> print_string "-"
+  | Ast.Mul -> print_string "*"
+  | Ast.Div -> print_string "/"
+  | Ast.Mod -> print_string "%"
+  | Ast.DecLeft -> print_string "<<"
+  | Ast.DecRight -> print_string ">>"
+  | Ast.And -> print_string "&"
+  | Ast.Or -> print_string "|"
+  | Ast.Xor -> print_string "^"
+
+and  logicalOp = function
+    Ast.Inf -> print_string "<"
+  | Ast.Sup -> print_string ">"
+  | Ast.InfEq -> print_string "<="
+  | Ast.SupEq -> print_string ">="
+  | Ast.Eq -> print_string "=="
+  | Ast.NotEq -> print_string "!="
+  | Ast.AndLog -> print_string "&&"
+  | Ast.OrLog -> print_string "||"
+
+and constant = function
+    Ast.String(s) -> print_string "\""; print_string s; print_string "\""
+  | Ast.Char(s) -> print_string "'"; print_string s; print_string "'"
+  | Ast.Int(s) -> print_string s
+  | Ast.Float(s) -> print_string s
+
+(* --------------------------------------------------------------------- *)
+(* Declarations *)
+
+and storage = function
+    Ast.Static -> print_string "static "
+  | Ast.Auto -> print_string "auto "
+  | Ast.Register -> print_string "register "
+  | Ast.Extern -> print_string "extern "
+
+(* --------------------------------------------------------------------- *)
+(* Types *)
+
+and fullType ft =
+  match Ast.unwrap ft with
+    Ast.Type(cv,ty) ->
+      print_option (function x -> mcode const_vol x; print_string " ") cv;
+      typeC ty
+  | Ast.DisjType(decls) -> print_disj_list fullType decls
+  | Ast.OptType(ty) -> print_string "?"; fullType ty
+  | Ast.UniqueType(ty) -> print_string "!"; fullType ty
+
+and print_function_pointer (ty,lp1,star,rp1,lp2,params,rp2) fn =
+  fullType ty; mcode print_string lp1; mcode print_string star; fn();
+  mcode print_string rp1; mcode print_string lp1;
+  parameter_list params; mcode print_string rp2
+
+and print_function_type (ty,lp1,params,rp1) fn =
+  print_option fullType ty; fn(); mcode print_string lp1;
+  parameter_list params; mcode print_string rp1
+
+and print_fninfo = function
+    Ast.FStorage(stg) -> mcode storage stg
+  | Ast.FType(ty) -> fullType ty
+  | Ast.FInline(inline) -> mcode print_string inline; print_string " "
+  | Ast.FAttr(attr) -> mcode print_string attr; print_string " "
+
+and typeC ty =
+  match Ast.unwrap ty with
+    Ast.BaseType(ty,strings) ->
+      List.iter (function s -> mcode print_string s; print_string " ") strings
+  | Ast.SignedT(sgn,ty) -> mcode sign sgn; print_option typeC ty
+  | Ast.Pointer(ty,star) -> fullType ty; mcode print_string star
+  | Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
+      print_function_pointer (ty,lp1,star,rp1,lp2,params,rp2)
+       (function _ -> ())
+  | Ast.FunctionType (_,ty,lp1,params,rp1) ->
+      print_function_type (ty,lp1,params,rp1) (function _ -> ())
+  | Ast.Array(ty,lb,size,rb) ->
+      fullType ty; mcode print_string lb; print_option expression size;
+      mcode print_string rb
+  | Ast.EnumName(kind,name) -> mcode print_string kind; print_string " ";
+      ident name
+  | Ast.StructUnionName(kind,name) ->
+      mcode structUnion kind;
+      print_option (function x -> ident x; print_string " ") name
+  | Ast.StructUnionDef(ty,lb,decls,rb) ->
+      fullType ty; mcode print_string lb;
+      dots force_newline declaration decls;
+      mcode print_string rb
+  | Ast.TypeName(name) -> mcode print_string name; print_string " "
+  | Ast.MetaType(name,_,_) ->
+      mcode print_meta name; print_string " "
+
+and baseType = function
+    Ast.VoidType -> print_string "void "
+  | Ast.CharType -> print_string "char "
+  | Ast.ShortType -> print_string "short "
+  | Ast.IntType -> print_string "int "
+  | Ast.DoubleType -> print_string "double "
+  | Ast.FloatType -> print_string "float "
+  | Ast.LongType -> print_string "long "
+  | Ast.LongLongType -> print_string "long long "
+
+and structUnion = function
+    Ast.Struct -> print_string "struct "
+  | Ast.Union -> print_string "union "
+
+and sign = function
+    Ast.Signed -> print_string "signed "
+  | Ast.Unsigned -> print_string "unsigned "
+
+and const_vol = function
+    Ast.Const -> print_string "const"
+  | Ast.Volatile -> print_string "volatile"
+
+(* --------------------------------------------------------------------- *)
+(* Variable declaration *)
+(* Even if the Cocci program specifies a list of declarations, they are
+   split out into multiple declarations of a single variable each. *)
+
+and print_named_type ty id =
+  match Ast.unwrap ty with
+    Ast.Type(None,ty1) ->
+      (match Ast.unwrap ty1 with
+       Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
+         print_function_pointer (ty,lp1,star,rp1,lp2,params,rp2)
+           (function _ -> print_string " "; ident id)
+      | Ast.FunctionType(_,ty,lp1,params,rp1) ->
+         print_function_type (ty,lp1,params,rp1)
+           (function _ -> print_string " "; ident id)
+      | Ast.Array(ty,lb,size,rb) ->
+         let rec loop ty k =
+           match Ast.unwrap ty with
+             Ast.Array(ty,lb,size,rb) ->
+               (match Ast.unwrap ty with
+                 Ast.Type(None,ty) ->
+                   loop ty
+                     (function _ ->
+                       k ();
+                       mcode print_string lb;
+                       print_option expression size;
+                       mcode print_string rb)
+               | _ -> failwith "complex array types not supported")
+           | _ -> typeC ty; ident id; k () in
+         loop ty1 (function _ -> ())
+      | _ -> fullType ty; ident id)
+  | _ -> fullType ty; ident id
+
+and declaration d =
+  match Ast.unwrap d with
+    Ast.Init(stg,ty,id,eq,ini,sem) ->
+      print_option (mcode storage) stg; print_named_type ty id;
+      print_string " "; mcode print_string eq;
+      print_string " "; initialiser ini; mcode print_string sem
+  | Ast.UnInit(stg,ty,id,sem) ->
+      print_option (mcode storage) stg; print_named_type ty id;
+      mcode print_string sem
+  | Ast.MacroDecl(name,lp,args,rp,sem) ->
+      ident name; mcode print_string_box lp;
+      dots (function _ -> ()) expression args;
+      close_box(); mcode print_string rp; mcode print_string sem
+  | Ast.TyDecl(ty,sem) -> fullType ty; mcode print_string sem
+  | Ast.Typedef(stg,ty,id,sem) ->
+      mcode print_string stg; print_string " "; fullType ty; typeC id;
+      mcode print_string sem
+  | Ast.DisjDecl(decls) -> print_disj_list declaration decls
+  | Ast.Ddots(dots,Some whencode) ->
+      mcode print_string dots; print_string "   when != "; declaration whencode
+  | Ast.Ddots(dots,None) -> mcode print_string dots
+  | Ast.MetaDecl(name,_,_) -> mcode print_meta name
+  | Ast.OptDecl(decl) -> print_string "?"; declaration decl
+  | Ast.UniqueDecl(decl) -> print_string "!"; declaration decl
+
+(* --------------------------------------------------------------------- *)
+(* Initialiser *)
+
+and initialiser i =
+  match Ast.unwrap i with
+    Ast.MetaInit(name,_,_) ->
+      mcode print_meta name; print_string " "
+  | Ast.InitExpr(exp) -> expression exp
+  | Ast.InitList(lb,initlist,rb,whencode) ->
+      mcode print_string lb; open_box 0;
+      if not (whencode = [])
+      then
+       (print_string "   WHEN != ";
+        print_between (function _ -> print_string " v ")
+          initialiser whencode;
+        force_newline());
+      List.iter initialiser initlist; close_box();
+      mcode print_string rb
+  | Ast.InitGccExt(designators,eq,ini) ->
+      List.iter designator designators; print_string " ";
+      mcode print_string eq; print_string " "; initialiser ini
+  | Ast.InitGccName(name,eq,ini) ->
+      ident name; mcode print_string eq; initialiser ini
+  | Ast.IComma(comma) -> mcode print_string comma; force_newline()
+  | Ast.OptIni(ini) -> print_string "?"; initialiser ini
+  | Ast.UniqueIni(ini) -> print_string "!"; initialiser ini
+
+and designator = function
+    Ast.DesignatorField(dot,id) -> mcode print_string dot; ident id
+  | Ast.DesignatorIndex(lb,exp,rb) ->
+      mcode print_string lb; expression exp; mcode print_string rb
+  | Ast.DesignatorRange(lb,min,dots,max,rb) ->
+      mcode print_string lb; expression min; mcode print_string dots;
+      expression max; mcode print_string rb
+
+(* --------------------------------------------------------------------- *)
+(* Parameter *)
+
+and parameterTypeDef p =
+  match Ast.unwrap p with
+    Ast.VoidParam(ty) -> fullType ty
+  | Ast.Param(ty,Some id) -> print_named_type ty id
+  | Ast.Param(ty,None) -> fullType ty
+  | Ast.MetaParam(name,_,_) -> mcode print_meta name
+  | Ast.MetaParamList(name,_,_,_) -> mcode print_meta name
+  | Ast.PComma(cm) -> mcode print_string cm; print_space()
+  | Ast.Pdots(dots) -> mcode print_string dots
+  | Ast.Pcircles(dots) -> mcode print_string dots
+  | Ast.OptParam(param) -> print_string "?"; parameterTypeDef param
+  | Ast.UniqueParam(param) -> print_string "!"; parameterTypeDef param
+
+and parameter_list l = dots (function _ -> ()) parameterTypeDef l
+
+(* --------------------------------------------------------------------- *)
+(* Top-level code *)
+
+let rec rule_elem arity re =
+  match Ast.unwrap re with
+    Ast.FunHeader(bef,allminus,fninfo,name,lp,params,rp) ->
+      mcode (function _ -> ()) ((),Ast.no_info,bef,Ast.NoMetaPos);
+      print_string arity; List.iter print_fninfo fninfo;
+      ident name; mcode print_string_box lp;
+      parameter_list params; close_box(); mcode print_string rp;
+      print_string " "
+  | Ast.Decl(bef,allminus,decl) ->
+      mcode (function _ -> ()) ((),Ast.no_info,bef,Ast.NoMetaPos);
+      print_string arity;
+      declaration decl
+  | Ast.SeqStart(brace) ->
+      print_string arity; mcode print_string brace;
+      if !print_newlines_disj then start_block()
+  | Ast.SeqEnd(brace) ->
+      if !print_newlines_disj then end_block();
+      print_string arity; mcode print_string brace
+  | Ast.ExprStatement(exp,sem) ->
+      print_string arity; expression exp; mcode print_string sem
+  | Ast.IfHeader(iff,lp,exp,rp) ->
+      print_string arity;
+      mcode print_string iff; print_string " "; mcode print_string_box lp;
+      expression exp; close_box(); mcode print_string rp; print_string " "
+  | Ast.Else(els) ->
+      print_string arity; mcode print_string els; print_string " "
+  | Ast.WhileHeader(whl,lp,exp,rp) ->
+      print_string arity;
+      mcode print_string whl; print_string " "; mcode print_string_box lp;
+      expression exp; close_box(); mcode print_string rp; print_string " "
+  | Ast.DoHeader(d) ->
+      print_string arity; mcode print_string d; print_string " "
+  | Ast.WhileTail(whl,lp,exp,rp,sem) ->
+      print_string arity;
+      mcode print_string whl; print_string " "; mcode print_string_box lp;
+      expression exp; close_box(); mcode print_string rp;
+      mcode print_string sem
+  | Ast.ForHeader(fr,lp,e1,sem1,e2,sem2,e3,rp) ->
+      print_string arity;
+      mcode print_string fr; mcode print_string_box lp;
+      print_option expression e1; mcode print_string sem1;
+      print_option expression e2; mcode print_string sem2;
+      print_option expression e3; close_box();
+      mcode print_string rp; print_string " "
+  | Ast.IteratorHeader(nm,lp,args,rp) ->
+      print_string arity;
+      ident nm; print_string " "; mcode print_string_box lp;
+      dots (function _ -> ()) expression args; close_box();
+      mcode print_string rp; print_string " "
+  | Ast.SwitchHeader(switch,lp,exp,rp) ->
+      print_string arity;
+      mcode print_string switch; print_string " "; mcode print_string_box lp;
+      expression exp; close_box(); mcode print_string rp; print_string " "
+  | Ast.Break(br,sem) ->
+      print_string arity; mcode print_string br; mcode print_string sem
+  | Ast.Continue(cont,sem) ->
+      print_string arity; mcode print_string cont; mcode print_string sem
+  | Ast.Label(l,dd) -> ident l; mcode print_string dd
+  | Ast.Goto(goto,l,sem) ->
+      mcode print_string goto; ident l; mcode print_string sem
+  | Ast.Return(ret,sem) ->
+      print_string arity; mcode print_string ret; mcode print_string sem
+  | Ast.ReturnExpr(ret,exp,sem) ->
+      print_string arity; mcode print_string ret; print_string " ";
+      expression exp; mcode print_string sem
+  | Ast.MetaRuleElem(name,_,_) ->
+      print_string arity; mcode print_meta name
+  | Ast.MetaStmt(name,_,_,_) ->
+      print_string arity; mcode print_meta name
+  | Ast.MetaStmtList(name,_,_) ->
+      print_string arity;  mcode print_meta name
+  | Ast.Exp(exp) -> print_string arity; expression exp
+  | Ast.TopExp(exp) -> print_string arity; expression exp
+  | Ast.Ty(ty) -> print_string arity; fullType ty
+  | Ast.TopInit(init) -> initialiser init
+  | Ast.Include(inc,s) ->
+      mcode print_string inc; print_string " "; mcode inc_file s
+  | Ast.DefineHeader(def,id,params) ->
+      mcode print_string def; print_string " "; ident id;
+      print_define_parameters params
+  | Ast.Default(def,colon) ->
+      mcode print_string def; mcode print_string colon; print_string " "
+  | Ast.Case(case,exp,colon) ->
+      mcode print_string case; print_string " "; expression exp;
+      mcode print_string colon; print_string " "
+  | Ast.DisjRuleElem(res) ->
+      print_string arity;
+      force_newline(); print_string "("; force_newline();
+      print_between
+       (function _ -> force_newline();print_string "|"; force_newline())
+       (rule_elem arity)
+       res;
+      force_newline(); print_string ")"
+
+
+and print_define_parameters params =
+  match Ast.unwrap params with
+    Ast.NoParams -> ()
+  | Ast.DParams(lp,params,rp) ->
+      mcode print_string lp;
+      dots (function _ -> ()) print_define_param params; mcode print_string rp
+
+and print_define_param param =
+  match Ast.unwrap param with
+    Ast.DParam(id) -> ident id
+  | Ast.DPComma(comma) -> mcode print_string comma
+  | Ast.DPdots(dots) -> mcode print_string dots
+  | Ast.DPcircles(circles) -> mcode print_string circles
+  | Ast.OptDParam(dp) -> print_string "?"; print_define_param dp
+  | Ast.UniqueDParam(dp) -> print_string "!"; print_define_param dp
+
+and statement arity s =
+  match Ast.unwrap s with
+    Ast.Seq(lbrace,decls,body,rbrace) ->
+      rule_elem arity lbrace;
+      dots force_newline (statement arity) decls;
+      dots force_newline (statement arity) body;
+      rule_elem arity rbrace
+  | Ast.IfThen(header,branch,(_,_,_,aft)) ->
+      rule_elem arity header; statement arity branch;
+      mcode (function _ -> ()) ((),Ast.no_info,aft,Ast.NoMetaPos)
+  | Ast.IfThenElse(header,branch1,els,branch2,(_,_,_,aft)) ->
+      rule_elem arity header; statement arity branch1; print_string " ";
+      rule_elem arity els; statement arity branch2;
+      mcode (function _ -> ()) ((),Ast.no_info,aft,Ast.NoMetaPos)
+  | Ast.While(header,body,(_,_,_,aft)) ->
+      rule_elem arity header; statement arity body;
+      mcode (function _ -> ()) ((),Ast.no_info,aft,Ast.NoMetaPos)
+  | Ast.Do(header,body,tail) ->
+      rule_elem arity header; statement arity body;
+      rule_elem arity tail
+  | Ast.For(header,body,(_,_,_,aft)) ->
+      rule_elem arity header; statement arity body;
+      mcode (function _ -> ()) ((),Ast.no_info,aft,Ast.NoMetaPos)
+  | Ast.Iterator(header,body,(_,_,_,aft)) ->
+      rule_elem arity header; statement arity body;
+      mcode (function _ -> ()) ((),Ast.no_info,aft,Ast.NoMetaPos)
+  | Ast.Switch(header,lb,cases,rb) ->
+      rule_elem arity header; rule_elem arity lb;
+      List.iter (function x -> case_line arity x; force_newline()) cases;
+      rule_elem arity rb
+  | Ast.Atomic(re) -> rule_elem arity re
+  | Ast.FunDecl(header,lbrace,decls,body,rbrace) ->
+      rule_elem arity header; rule_elem arity lbrace;
+      dots force_newline (statement arity) decls;
+      dots force_newline (statement arity) body;
+      rule_elem arity rbrace
+  | Ast.Disj([stmt_dots]) ->
+      print_string arity;
+      dots (function _ -> if !print_newlines_disj then force_newline())
+       (statement arity) stmt_dots
+  | Ast.Disj(stmt_dots_list) -> (* ignores newline directive for readability *)
+      print_string arity;
+      force_newline(); print_string "("; force_newline();
+      print_between
+       (function _ -> force_newline();print_string "|"; force_newline())
+       (dots force_newline (statement arity))
+       stmt_dots_list;
+      force_newline(); print_string ")"
+  | Ast.Define(header,body) ->
+      rule_elem arity header; print_string " ";
+      dots force_newline (statement arity) body
+  | Ast.Nest(stmt_dots,whn,multi,_,_) ->
+      print_string arity;
+      nest_dots multi (statement arity)
+       (function _ ->
+         open_box 0;
+         print_between force_newline
+           (whencode (dots force_newline (statement "")) (statement "")) whn;
+         close_box(); force_newline())
+       stmt_dots
+  | Ast.Dots(d,whn,_,_) | Ast.Circles(d,whn,_,_) | Ast.Stars(d,whn,_,_) ->
+      print_string arity; mcode print_string d;
+      open_box 0;
+      print_between force_newline
+       (whencode (dots force_newline (statement "")) (statement "")) whn;
+      close_box(); force_newline()
+  | Ast.OptStm(s) -> statement "?" s
+  | Ast.UniqueStm(s) -> statement "!" s
+
+and print_statement_when whencode =
+  print_string "   WHEN != ";
+  open_box 0;
+  print_between (function _ -> print_string " &"; force_newline())
+    (dots force_newline (statement "")) whencode;
+  close_box()
+
+
+and whencode notfn alwaysfn = function
+    Ast.WhenNot a ->
+      print_string "   WHEN != "; open_box 0; notfn a; close_box()
+  | Ast.WhenAlways a ->
+      print_string "   WHEN = "; open_box 0; alwaysfn a; close_box()
+  | Ast.WhenModifier x -> print_string "   WHEN "; print_when_modif x
+  | Ast.WhenNotTrue a ->
+      print_string "   WHEN != TRUE "; open_box 0; rule_elem "" a; close_box()
+  | Ast.WhenNotFalse a ->
+      print_string "   WHEN != FALSE "; open_box 0; rule_elem "" a; close_box()
+
+and print_when_modif = function
+  | Ast.WhenAny    -> print_string "ANY"
+  | Ast.WhenStrict -> print_string "STRICT"
+  | Ast.WhenForall -> print_string "FORALL"
+  | Ast.WhenExists -> print_string "EXISTS"
+
+and case_line arity c =
+  match Ast.unwrap c with
+    Ast.CaseLine(header,code) ->
+      rule_elem arity header; print_string " ";
+      dots force_newline (statement arity) code
+  | Ast.OptCase(case) -> case_line "?" case
+
+(* --------------------------------------------------------------------- *)
+(* CPP code *)
+
+and inc_file = function
+    Ast.Local(elems) ->
+      print_string "\"";
+      print_between (function _ -> print_string "/") inc_elem elems;
+      print_string "\""
+  | Ast.NonLocal(elems) ->
+      print_string "<";
+      print_between (function _ -> print_string "/") inc_elem elems;
+      print_string ">"
+
+and inc_elem = function
+    Ast.IncPath s -> print_string s
+  | Ast.IncDots -> print_string "..."
+
+(* for export only *)
+let statement_dots l = dots force_newline (statement "") l
+
+let top_level t =
+  match Ast.unwrap t with
+    Ast.FILEINFO(old_file,new_file) ->
+      print_string "--- "; mcode print_string old_file; force_newline();
+      print_string "+++ "; mcode print_string new_file
+  | Ast.DECL(stmt) -> statement "" stmt
+  | Ast.CODE(stmt_dots) ->
+      dots force_newline (statement "") stmt_dots
+  | Ast.ERRORWORDS(exps) ->
+      print_string "error words = [";
+      print_between (function _ -> print_string ", ") expression exps;
+      print_string "]"
+
+let rule =
+  print_between (function _ -> force_newline(); force_newline()) top_level
+
+let pp_print_anything x = !anything x
+
+let _ =
+  anything := function
+      Ast.FullTypeTag(x) -> fullType x
+    | Ast.BaseTypeTag(x) -> baseType x
+    | Ast.StructUnionTag(x) -> structUnion x
+    | Ast.SignTag(x) -> sign x
+    | Ast.IdentTag(x) -> ident x
+    | Ast.ExpressionTag(x) -> expression x
+    | Ast.ConstantTag(x) -> constant x
+    | Ast.UnaryOpTag(x) -> unaryOp x
+    | Ast.AssignOpTag(x) -> assignOp x
+    | Ast.FixOpTag(x) -> fixOp x
+    | Ast.BinaryOpTag(x) -> binaryOp x
+    | Ast.ArithOpTag(x) -> arithOp x
+    | Ast.LogicalOpTag(x) -> logicalOp x
+    | Ast.InitTag(x) -> initialiser x
+    | Ast.DeclarationTag(x) -> declaration x
+    | Ast.StorageTag(x) -> storage x
+    | Ast.IncFileTag(x) -> inc_file x
+    | Ast.Rule_elemTag(x) -> rule_elem "" x
+    | Ast.StatementTag(x) -> statement "" x
+    | Ast.CaseLineTag(x) -> case_line "" x
+    | Ast.ConstVolTag(x) -> const_vol x
+    | Ast.Token(x,Some info) -> print_string_befaft print_string x info
+    | Ast.Token(x,None) -> print_string x
+    | Ast.Code(x) -> let _ = top_level x in ()
+    | Ast.ExprDotsTag(x) -> dots (function _ -> ()) expression x
+    | Ast.ParamDotsTag(x) -> parameter_list x
+    | Ast.StmtDotsTag(x) -> dots (function _ -> ()) (statement "") x
+    | Ast.DeclDotsTag(x) -> dots (function _ -> ()) declaration x
+    | Ast.TypeCTag(x) -> typeC x
+    | Ast.ParamTag(x) -> parameterTypeDef x
+    | Ast.SgrepStartTag(x) -> print_string x
+    | Ast.SgrepEndTag(x) -> print_string x
+
+let rec dep in_and = function
+    Ast.Dep(s) -> print_string s
+  | Ast.AntiDep(s) -> print_string "!"; print_string s
+  | Ast.EverDep(s) -> print_string "ever "; print_string s
+  | Ast.NeverDep(s) -> print_string "never "; print_string s
+  | Ast.AndDep(s1,s2) ->
+      let print_and _ = dep true s1; print_string " && "; dep true s2 in
+      if in_and
+      then print_and ()
+      else (print_string "("; print_and(); print_string ")")
+  | Ast.OrDep(s1,s2) ->
+      let print_or _ = dep false s1; print_string " || "; dep false s2 in
+      if not in_and
+      then print_or ()
+      else (print_string "("; print_or(); print_string ")")
+  | Ast.NoDep -> failwith "not possible"
+
+let unparse z =
+  match z with
+    Ast.ScriptRule (lang,deps,bindings,code) ->
+    print_string "@@";
+    force_newline();
+    print_string ("script:" ^ lang);
+    (match deps with
+      Ast.NoDep -> ()
+    | _ -> print_string " depends on "; dep true deps);
+    force_newline();
+    print_string "@@";
+    force_newline();
+    print_string code;
+    force_newline()
+  | Ast.CocciRule (nm, (deps, drops, exists), x, _, _) ->
+    print_string "@@";
+    force_newline();
+    print_string nm;
+    (match deps with
+      Ast.NoDep -> ()
+    | _ -> print_string " depends on "; dep true deps);
+    (*
+    print_string "line ";
+    print_int (Ast.get_line (List.hd x));
+    *)
+    force_newline();
+    print_string "@@";
+    print_newlines_disj := true;
+    force_newline();
+    force_newline();
+    rule x;
+    force_newline()
+
+let rule_elem_to_string x =
+  print_newlines_disj := true;
+  Common.format_to_string (function _ -> rule_elem "" x)
+
+let ident_to_string x =
+  print_newlines_disj := true;
+  Common.format_to_string (function _ -> ident x)
+
+let unparse_to_string x =
+  print_newlines_disj := true;
+  Common.format_to_string (function _ -> unparse x)
+
+let print_rule_elem re =
+  let nl = !print_newlines_disj in
+  print_newlines_disj := false;
+  rule_elem "" re;
+  print_newlines_disj := nl
+
diff --git a/parsing_cocci/.#type_infer.ml.1.60 b/parsing_cocci/.#type_infer.ml.1.60
new file mode 100644 (file)
index 0000000..24448ad
--- /dev/null
@@ -0,0 +1,384 @@
+(*
+* Copyright 2005-2009, 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 T = Type_cocci
+module Ast = Ast_cocci
+module Ast0 = Ast0_cocci
+module V0 = Visitor_ast0
+
+(* Type inference:
+Just propagates information based on declarations.  Could try to infer
+more precise information about expression metavariables, but not sure it is
+worth it.  The most obvious goal is to distinguish between test expressions
+that have pointer, integer, and boolean type when matching isomorphisms,
+but perhaps other needs will become apparent. *)
+
+(* "functions" that return a boolean value *)
+let bool_functions = ["likely";"unlikely"]
+
+let err wrapped ty s =
+  T.typeC ty; Format.print_newline();
+  failwith (Printf.sprintf "line %d: %s" (Ast0.get_line wrapped) s)
+
+type id = Id of string | Meta of (string * string)
+
+let int_type = T.BaseType(T.IntType)
+let bool_type = T.BaseType(T.BoolType)
+let char_type = T.BaseType(T.CharType)
+let float_type = T.BaseType(T.FloatType)
+
+let rec lub_type t1 t2 =
+  match (t1,t2) with
+    (None,None) -> None
+  | (None,Some t) -> t2
+  | (Some t,None) -> t1
+  | (Some t1,Some t2) ->
+      let rec loop = function
+         (T.Unknown,t2) -> t2
+       | (t1,T.Unknown) -> t1
+       | (T.ConstVol(cv1,ty1),T.ConstVol(cv2,ty2)) when cv1 = cv2 ->
+           T.ConstVol(cv1,loop(ty1,ty2))
+
+        (* pad: in pointer arithmetic, as in ptr+1, the lub must be ptr *)
+       | (T.Pointer(ty1),T.Pointer(ty2)) ->
+           T.Pointer(loop(ty1,ty2))
+       | (ty1,T.Pointer(ty2)) -> T.Pointer(ty2)
+       | (T.Pointer(ty1),ty2) -> T.Pointer(ty1)
+
+       | (T.Array(ty1),T.Array(ty2)) -> T.Array(loop(ty1,ty2))
+       | (T.TypeName(s1),t2) -> t2
+       | (t1,T.TypeName(s1)) -> t1
+       | (t1,_) -> t1 in (* arbitrarily pick the first, assume type correct *)
+      Some (loop (t1,t2))
+
+let lub_envs envs =
+  List.fold_left
+    (function acc ->
+      function env ->
+       List.fold_left
+         (function acc ->
+           function (var,ty) ->
+             let (relevant,irrelevant) =
+               List.partition (function (x,_) -> x = var) acc in
+             match relevant with
+               [] -> (var,ty)::acc
+             | [(x,ty1)] ->
+                 (match lub_type (Some ty) (Some ty1) with
+                   Some new_ty -> (var,new_ty)::irrelevant
+                 | None -> irrelevant)
+             | _ -> failwith "bad type environment")
+         acc env)
+    [] envs
+
+let rec propagate_types env =
+  let option_default = None in
+  let bind x y = option_default in (* no generic way of combining types *)
+
+  let mcode x = option_default in
+
+  let ident r k i =
+    match Ast0.unwrap i with
+      Ast0.Id(id) ->
+       (try Some(List.assoc (Id(Ast0.unwrap_mcode id)) env)
+       with Not_found -> None)
+    | Ast0.MetaId(id,_,_) ->
+       (try Some(List.assoc (Meta(Ast0.unwrap_mcode id)) env)
+       with Not_found -> None)
+    | _ -> k i in
+
+  let strip_cv = function
+      Some (T.ConstVol(_,t)) -> Some t
+    | t -> t in
+
+  (* types that might be integer types.  should char be allowed? *)
+  let rec is_int_type = function
+      T.BaseType(T.IntType)
+    | T.BaseType(T.LongType)
+    | T.BaseType(T.ShortType)
+    | T.MetaType(_,_,_)
+    | T.TypeName _
+    | T.SignedT(_,None) -> true
+    | T.SignedT(_,Some ty) -> is_int_type ty
+    | _ -> false in
+
+  let expression r k e =
+    let res = k e in
+    let ty =
+      match Ast0.unwrap e with
+        (* pad: the type of id is set in the ident visitor *)
+       Ast0.Ident(id) -> Ast0.set_type e res; res
+      | Ast0.Constant(const) ->
+         (match Ast0.unwrap_mcode const with
+           Ast.String(_) -> Some (T.Pointer(char_type))
+         | Ast.Char(_) -> Some (char_type)
+         | Ast.Int(_) -> Some (int_type)
+         | Ast.Float(_) ->  Some (float_type))
+        (* pad: note that in C can do either ptr(...) or ( *ptr)(...)
+         * so I am not sure this code is enough.
+         *)
+      | Ast0.FunCall(fn,lp,args,rp) ->
+         (match Ast0.get_type fn with
+           Some (T.FunctionPointer(ty)) -> Some ty
+         |  _ ->
+             (match Ast0.unwrap fn with
+               Ast0.Ident(id) ->
+                 (match Ast0.unwrap id with
+                   Ast0.Id(id) ->
+                     if List.mem (Ast0.unwrap_mcode id) bool_functions
+                     then Some(bool_type)
+                     else None
+                 | _ -> None)
+             | _ -> None))
+      | Ast0.Assignment(exp1,op,exp2,_) ->
+         let ty = lub_type (Ast0.get_type exp1) (Ast0.get_type exp2) in
+         Ast0.set_type exp1 ty; Ast0.set_type exp2 ty; ty
+      | Ast0.CondExpr(exp1,why,Some exp2,colon,exp3) ->
+         let ty = lub_type (Ast0.get_type exp2) (Ast0.get_type exp3) in
+         Ast0.set_type exp2 ty; Ast0.set_type exp3 ty; ty
+      | Ast0.CondExpr(exp1,why,None,colon,exp3) -> Ast0.get_type exp3
+      | Ast0.Postfix(exp,op) | Ast0.Infix(exp,op) -> (* op is dec or inc *)
+         Ast0.get_type exp
+      | Ast0.Unary(exp,op) ->
+         (match Ast0.unwrap_mcode op with
+           Ast.GetRef ->
+             (match Ast0.get_type exp with
+               None -> Some (T.Pointer(T.Unknown))
+             | Some t -> Some (T.Pointer(t)))
+         | Ast.DeRef ->
+             (match Ast0.get_type exp with
+               Some (T.Pointer(t)) -> Some t
+             | _ -> None)
+         | Ast.UnPlus -> Ast0.get_type exp
+         | Ast.UnMinus -> Ast0.get_type exp
+         | Ast.Tilde -> Ast0.get_type exp
+         | Ast.Not -> Some(bool_type))
+      | Ast0.Nested(exp1,op,exp2) -> failwith "nested in type inf not possible"
+      | Ast0.Binary(exp1,op,exp2) ->
+         let ty1 = Ast0.get_type exp1 in
+         let ty2 = Ast0.get_type exp2 in
+         let same_type = function
+             (None,None) -> Some (int_type)
+
+            (* pad: pointer arithmetic handling as in ptr+1 *)
+           | (Some (T.Pointer ty1),Some ty2) when is_int_type ty2 ->
+               Some (T.Pointer ty1)
+           | (Some ty1,Some (T.Pointer ty2)) when is_int_type ty1 ->
+               Some (T.Pointer ty2)
+
+           | (t1,t2) ->
+               let ty = lub_type t1 t2 in
+               Ast0.set_type exp1 ty; Ast0.set_type exp2 ty; ty in
+         (match Ast0.unwrap_mcode op with
+           Ast.Arith(op) -> same_type (ty1, ty2)
+         | Ast.Logical(op) ->
+             let ty = lub_type ty1 ty2 in
+             Ast0.set_type exp1 ty; Ast0.set_type exp2 ty;
+             Some(bool_type))
+      | Ast0.Paren(lp,exp,rp) -> Ast0.get_type exp
+      | Ast0.ArrayAccess(exp1,lb,exp2,rb) ->
+         (match strip_cv (Ast0.get_type exp2) with
+           None -> Ast0.set_type exp2 (Some(int_type))
+         | Some(ty) when is_int_type ty -> ()
+         | Some ty -> err exp2 ty "bad type for an array index");
+         (match strip_cv (Ast0.get_type exp1) with
+           None -> None
+         | Some (T.Array(ty)) -> Some ty
+         | Some (T.Pointer(ty)) -> Some ty
+         | Some (T.MetaType(_,_,_)) -> None
+         | Some x -> err exp1 x "ill-typed array reference")
+      (* pad: should handle structure one day and look 'field' in environment *)
+      | Ast0.RecordAccess(exp,pt,field) ->
+         (match strip_cv (Ast0.get_type exp) with
+           None -> None
+         | Some (T.StructUnionName(_,_,_)) -> None
+         | Some (T.TypeName(_)) -> None
+         | Some (T.MetaType(_,_,_)) -> None
+         | Some x -> err exp x "non-structure type in field ref")
+      | Ast0.RecordPtAccess(exp,ar,field) ->
+         (match strip_cv (Ast0.get_type exp) with
+           None -> None
+         | Some (T.Pointer(t)) ->
+             (match strip_cv (Some t) with
+             | Some (T.Unknown) -> None
+             | Some (T.MetaType(_,_,_)) -> None
+             | Some (T.TypeName(_)) -> None
+             | Some (T.StructUnionName(_,_,_)) -> None
+             | Some x ->
+                 err exp (T.Pointer(t))
+                   "non-structure pointer type in field ref"
+             | _ -> failwith "not possible")
+         | Some (T.MetaType(_,_,_)) -> None
+         | Some (T.TypeName(_)) -> None
+         | Some x -> err exp x "non-structure pointer type in field ref")
+      | Ast0.Cast(lp,ty,rp,exp) -> Some(Ast0.ast0_type_to_type ty)
+      | Ast0.SizeOfExpr(szf,exp) -> Some(int_type)
+      | Ast0.SizeOfType(szf,lp,ty,rp) -> Some(int_type)
+      | Ast0.TypeExp(ty) -> None
+      | Ast0.MetaErr(name,_,_) -> None
+      | Ast0.MetaExpr(name,_,Some [ty],_,_) -> Some ty
+      | Ast0.MetaExpr(name,_,ty,_,_) -> None
+      | Ast0.MetaExprList(name,_,_) -> None
+      | Ast0.EComma(cm) -> None
+      | Ast0.DisjExpr(_,exp_list,_,_) ->
+         let types = List.map Ast0.get_type exp_list in
+         let combined = List.fold_left lub_type None types in
+         (match combined with
+           None -> None
+         | Some t ->
+             List.iter (function e -> Ast0.set_type e (Some t)) exp_list;
+             Some t)
+      | Ast0.NestExpr(starter,expr_dots,ender,None,multi) ->
+         let _ = r.V0.combiner_expression_dots expr_dots in None
+      | Ast0.NestExpr(starter,expr_dots,ender,Some e,multi) ->
+         let _ = r.V0.combiner_expression_dots expr_dots in
+         let _ = r.V0.combiner_expression e in None
+      | Ast0.Edots(_,None) | Ast0.Ecircles(_,None) | Ast0.Estars(_,None) ->
+         None
+      | Ast0.Edots(_,Some e) | Ast0.Ecircles(_,Some e)
+      | Ast0.Estars(_,Some e) ->
+         let _ = r.V0.combiner_expression e in None
+      | Ast0.OptExp(exp) -> Ast0.get_type exp
+      | Ast0.UniqueExp(exp) -> Ast0.get_type exp in
+    Ast0.set_type e ty;
+    ty in
+
+  let donothing r k e = k e in
+
+  let rec strip id =
+    match Ast0.unwrap id with
+      Ast0.Id(name)              -> Id(Ast0.unwrap_mcode name)
+    | Ast0.MetaId(name,_,_)        -> Meta(Ast0.unwrap_mcode name)
+    | Ast0.MetaFunc(name,_,_)      -> Meta(Ast0.unwrap_mcode name)
+    | Ast0.MetaLocalFunc(name,_,_) -> Meta(Ast0.unwrap_mcode name)
+    | Ast0.OptIdent(id)    -> strip id
+    | Ast0.UniqueIdent(id) -> strip id in
+
+  let process_whencode notfn allfn exp = function
+      Ast0.WhenNot(x) -> let _ = notfn x in ()
+    | Ast0.WhenAlways(x) -> let _ = allfn x in ()
+    | Ast0.WhenModifier(_) -> ()
+    | Ast0.WhenNotTrue(x) -> let _ = exp x in ()
+    | Ast0.WhenNotFalse(x) -> let _ = exp x in () in
+
+  (* assume that all of the declarations are at the beginning of a statement
+     list, which is required by C, but not actually required by the cocci
+     parser *)
+  let rec process_statement_list r acc = function
+      [] -> acc
+    | (s::ss) ->
+       (match Ast0.unwrap s with
+         Ast0.Decl(_,decl) ->
+           let rec process_decl decl =
+             match Ast0.unwrap decl with
+               Ast0.Init(_,ty,id,_,exp,_) ->
+                 let _ =
+                   (propagate_types acc).V0.combiner_initialiser exp in
+                 [(strip id,Ast0.ast0_type_to_type ty)]
+             | Ast0.UnInit(_,ty,id,_) ->
+                 [(strip id,Ast0.ast0_type_to_type ty)]
+             | Ast0.MacroDecl(_,_,_,_,_) -> []
+             | Ast0.TyDecl(ty,_) -> []
+              (* pad: should handle typedef one day and add a binding *)
+             | Ast0.Typedef(_,_,_,_) -> []
+             | Ast0.DisjDecl(_,disjs,_,_) ->
+                 List.concat(List.map process_decl disjs)
+             | Ast0.Ddots(_,_) -> [] (* not in a statement list anyway *)
+             | Ast0.OptDecl(decl) -> process_decl decl
+             | Ast0.UniqueDecl(decl) -> process_decl decl in
+           let new_acc = (process_decl decl)@acc in
+           process_statement_list r new_acc ss
+       | Ast0.Dots(_,wc) ->
+           (* why is this case here?  why is there none for nests? *)
+           List.iter
+             (process_whencode r.V0.combiner_statement_dots
+                r.V0.combiner_statement r.V0.combiner_expression)
+             wc;
+           process_statement_list r acc ss
+       | Ast0.Disj(_,statement_dots_list,_,_) ->
+           let new_acc =
+             lub_envs
+               (List.map
+                  (function x -> process_statement_list r acc (Ast0.undots x))
+                  statement_dots_list) in
+           process_statement_list r new_acc ss
+       | _ ->
+           let _ = (propagate_types acc).V0.combiner_statement s in
+           process_statement_list r acc ss) in
+
+  let statement_dots r k d =
+    match Ast0.unwrap d with
+      Ast0.DOTS(l) | Ast0.CIRCLES(l) | Ast0.STARS(l) ->
+       let _ = process_statement_list r env l in option_default in
+  let statement r k s =
+    match Ast0.unwrap s with
+      Ast0.FunDecl(_,fninfo,name,lp,params,rp,lbrace,body,rbrace) ->
+       let rec get_binding p =
+         match Ast0.unwrap p with
+           Ast0.Param(ty,Some id) ->
+             [(strip id,Ast0.ast0_type_to_type ty)]
+         | Ast0.OptParam(param) -> get_binding param
+         | _ -> [] in
+       let fenv = List.concat (List.map get_binding (Ast0.undots params)) in
+       (propagate_types (fenv@env)).V0.combiner_statement_dots body
+    | Ast0.IfThen(_,_,exp,_,_,_) | Ast0.IfThenElse(_,_,exp,_,_,_,_,_)
+    | Ast0.While(_,_,exp,_,_,_) | Ast0.Do(_,_,_,_,exp,_,_)
+    | Ast0.For(_,_,_,_,Some exp,_,_,_,_,_) | Ast0.Switch(_,_,exp,_,_,_,_) ->
+       let _ = k s in
+       let rec process_test exp =
+         match (Ast0.unwrap exp,Ast0.get_type exp) with
+           (Ast0.Edots(_,_),_) -> None
+         | (Ast0.NestExpr(_,_,_,_,_),_) -> None
+         | (Ast0.MetaExpr(_,_,_,_,_),_) ->
+           (* if a type is known, it is specified in the decl *)
+             None
+         | (Ast0.Paren(lp,exp,rp),None) -> process_test exp
+         | (_,None) -> Some (int_type)
+         | _ -> None in
+       let new_expty = process_test exp in
+       (match new_expty with
+         None -> () (* leave things as they are *)
+       | Some ty -> Ast0.set_type exp new_expty);
+       None
+    |  _ -> k s
+
+  and case_line r k c =
+    match Ast0.unwrap c with
+      Ast0.Default(def,colon,code) -> let _ = k c in None
+    | Ast0.Case(case,exp,colon,code) ->
+       let _ = k c in
+       (match Ast0.get_type exp with
+         None -> Ast0.set_type exp (Some (int_type))
+       | _ -> ());
+       None
+    | Ast0.OptCase(case) -> k c in
+
+  V0.combiner bind option_default
+    mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
+    donothing donothing donothing statement_dots donothing donothing
+    ident expression donothing donothing donothing donothing statement
+    case_line donothing
+
+let type_infer code =
+  let prop = propagate_types [(Id("NULL"),T.Pointer(T.Unknown))] in
+  let fn = prop.V0.combiner_top_level in
+  let _ = List.map fn code in
+  ()
diff --git a/parsing_cocci/.#unparse_ast0.ml.1.118 b/parsing_cocci/.#unparse_ast0.ml.1.118
new file mode 100644 (file)
index 0000000..b295646
--- /dev/null
@@ -0,0 +1,667 @@
+(*
+* Copyright 2005-2009, 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,_,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,_,_) ->
+         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,strings) ->
+         List.iter (function s -> mcode print_string s; print_string " ")
+           strings
+      |        Ast0.Signed(sgn,ty) -> mcode U.sign sgn; print_option typeC ty
+      | 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.EnumName(kind,name) -> mcode print_string kind; print_string " ";
+         ident name
+      | 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.MetaInit(name,_)-> mcode print_meta name; print_string " "
+      |        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.InitGccExt(designators,eq,ini) ->
+         List.iter designator designators; print_string " ";
+         mcode print_string eq; print_string " "; initialiser ini
+      | Ast0.InitGccName(name,eq,ini) ->
+         ident name; mcode print_string eq; 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 designator = function
+      Ast0.DesignatorField(dot,id) -> mcode print_string dot; ident id
+    | Ast0.DesignatorIndex(lb,exp,rb) ->
+       mcode print_string lb; expression exp; mcode print_string rb
+    | Ast0.DesignatorRange(lb,min,dots,max,rb) ->
+       mcode print_string lb; expression min; mcode print_string dots;
+       expression max; mcode print_string rb
+
+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_ast.ml.1.97 b/parsing_cocci/.#visitor_ast.ml.1.97
new file mode 100644 (file)
index 0000000..f0ca9c8
--- /dev/null
@@ -0,0 +1,1061 @@
+(*
+* Copyright 2005-2009, 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
+
+(* --------------------------------------------------------------------- *)
+(* Generic traversal: combiner *)
+(* parameters:
+   combining function
+   treatment of: mcode, identifiers, expressions, fullTypes, types,
+   declarations, statements, toplevels
+   default value for options *)
+
+type 'a combiner =
+    {combiner_ident : Ast.ident -> 'a;
+     combiner_expression : Ast.expression -> 'a;
+     combiner_fullType : Ast.fullType -> 'a;
+     combiner_typeC : Ast.typeC -> 'a;
+     combiner_declaration : Ast.declaration -> 'a;
+     combiner_initialiser : Ast.initialiser -> 'a;
+     combiner_parameter : Ast.parameterTypeDef -> 'a;
+     combiner_parameter_list : Ast.parameter_list -> 'a;
+     combiner_rule_elem : Ast.rule_elem -> 'a;
+     combiner_statement : Ast.statement -> 'a;
+     combiner_case_line : Ast.case_line -> 'a;
+     combiner_top_level : Ast.top_level -> 'a;
+     combiner_anything : Ast.anything  -> 'a;
+     combiner_expression_dots : Ast.expression Ast.dots -> 'a;
+     combiner_statement_dots : Ast.statement Ast.dots -> 'a;
+     combiner_declaration_dots : Ast.declaration Ast.dots -> 'a}
+
+type ('mc,'a) cmcode = 'a combiner -> 'mc Ast_cocci.mcode -> 'a
+type ('cd,'a) ccode = 'a combiner -> ('cd -> 'a) -> 'cd -> 'a
+
+
+let combiner bind option_default
+    meta_mcodefn string_mcodefn const_mcodefn assign_mcodefn fix_mcodefn
+    unary_mcodefn binary_mcodefn
+    cv_mcodefn sign_mcodefn struct_mcodefn storage_mcodefn
+    inc_file_mcodefn
+    expdotsfn paramdotsfn stmtdotsfn decldotsfn
+    identfn exprfn ftfn tyfn initfn paramfn declfn rulefn stmtfn casefn
+    topfn anyfn =
+  let multibind l =
+    let rec loop = function
+       [] -> option_default
+      |        [x] -> x
+      |        x::xs -> bind x (loop xs) in
+    loop l in
+  let get_option f = function
+      Some x -> f x
+    | None -> option_default in
+
+  let rec meta_mcode x = meta_mcodefn all_functions x
+  and string_mcode x = string_mcodefn all_functions x
+  and const_mcode x = const_mcodefn all_functions x
+  and assign_mcode x = assign_mcodefn all_functions x
+  and fix_mcode x = fix_mcodefn all_functions x
+  and unary_mcode x = unary_mcodefn all_functions x
+  and binary_mcode x = binary_mcodefn all_functions x
+  and cv_mcode x = cv_mcodefn all_functions x
+  and sign_mcode x = sign_mcodefn all_functions x
+  and struct_mcode x = struct_mcodefn all_functions x
+  and storage_mcode x = storage_mcodefn all_functions x
+  and inc_file_mcode x = inc_file_mcodefn all_functions x
+
+  and expression_dots d =
+    let k d =
+      match Ast.unwrap d with
+       Ast.DOTS(l) | Ast.CIRCLES(l) | Ast.STARS(l) ->
+         multibind (List.map expression l) in
+    expdotsfn all_functions k d
+
+  and parameter_dots d =
+    let k d =
+      match Ast.unwrap d with
+       Ast.DOTS(l) | Ast.CIRCLES(l) | Ast.STARS(l) ->
+         multibind (List.map parameterTypeDef l) in
+    paramdotsfn all_functions k d
+
+  and statement_dots d =
+    let k d =
+      match Ast.unwrap d with
+       Ast.DOTS(l) | Ast.CIRCLES(l) | Ast.STARS(l) ->
+         multibind (List.map statement l) in
+    stmtdotsfn all_functions k d
+
+  and declaration_dots d =
+    let k d =
+      match Ast.unwrap d with
+       Ast.DOTS(l) | Ast.CIRCLES(l) | Ast.STARS(l) ->
+         multibind (List.map declaration l) in
+    decldotsfn all_functions k d
+
+  and ident i =
+    let k i =
+      match Ast.unwrap i with
+       Ast.Id(name) -> string_mcode name
+      | Ast.MetaId(name,_,_,_) -> meta_mcode name
+      | Ast.MetaFunc(name,_,_,_) -> meta_mcode name
+      | Ast.MetaLocalFunc(name,_,_,_) -> meta_mcode name
+      | Ast.OptIdent(id) -> ident id
+      | Ast.UniqueIdent(id) -> ident id in
+    identfn all_functions k i
+
+  and expression e =
+    let k e =
+      match Ast.unwrap e with
+       Ast.Ident(id) -> ident id
+      | Ast.Constant(const) -> const_mcode const
+      | Ast.FunCall(fn,lp,args,rp) ->
+         multibind [expression fn; string_mcode lp; expression_dots args;
+                     string_mcode rp]
+      | Ast.Assignment(left,op,right,simple) ->
+         multibind [expression left; assign_mcode op; expression right]
+      | Ast.CondExpr(exp1,why,exp2,colon,exp3) ->
+         multibind [expression exp1; string_mcode why;
+                     get_option expression exp2; string_mcode colon;
+                     expression exp3]
+      | Ast.Postfix(exp,op) -> bind (expression exp) (fix_mcode op)
+      | Ast.Infix(exp,op) -> bind (fix_mcode op) (expression exp)
+      | Ast.Unary(exp,op) -> bind (unary_mcode op) (expression exp)
+      | Ast.Binary(left,op,right) ->
+         multibind [expression left; binary_mcode op; expression right]
+      | Ast.Nested(left,op,right) ->
+         multibind [expression left; binary_mcode op; expression right]
+      | Ast.Paren(lp,exp,rp) ->
+         multibind [string_mcode lp; expression exp; string_mcode rp]
+      | Ast.ArrayAccess(exp1,lb,exp2,rb) ->
+         multibind
+           [expression exp1; string_mcode lb; expression exp2;
+             string_mcode rb]
+      | Ast.RecordAccess(exp,pt,field) ->
+         multibind [expression exp; string_mcode pt; ident field]
+      | Ast.RecordPtAccess(exp,ar,field) ->
+         multibind [expression exp; string_mcode ar; ident field]
+      | Ast.Cast(lp,ty,rp,exp) ->
+         multibind
+           [string_mcode lp; fullType ty; string_mcode rp; expression exp]
+      | Ast.SizeOfExpr(szf,exp) ->
+         multibind [string_mcode szf; expression exp]
+      | Ast.SizeOfType(szf,lp,ty,rp) ->
+         multibind
+           [string_mcode szf; string_mcode lp; fullType ty; string_mcode rp]
+      | Ast.TypeExp(ty) -> fullType ty
+      | Ast.MetaErr(name,_,_,_)
+      | Ast.MetaExpr(name,_,_,_,_,_)
+      | Ast.MetaExprList(name,_,_,_) -> meta_mcode name
+      | Ast.EComma(cm) -> string_mcode cm
+      | Ast.DisjExpr(exp_list) -> multibind (List.map expression exp_list)
+      | Ast.NestExpr(expr_dots,whencode,multi) ->
+         bind (expression_dots expr_dots) (get_option expression whencode)
+      | Ast.Edots(dots,whencode) | Ast.Ecircles(dots,whencode)
+      | Ast.Estars(dots,whencode) ->
+         bind (string_mcode dots) (get_option expression whencode)
+      | Ast.OptExp(exp) | Ast.UniqueExp(exp) ->
+         expression exp in
+    exprfn all_functions k e
+
+  and fullType ft =
+    let k ft =
+      match Ast.unwrap ft with
+       Ast.Type(cv,ty) -> bind (get_option cv_mcode cv) (typeC ty)
+      | Ast.DisjType(types) -> multibind (List.map fullType types)
+      | Ast.OptType(ty) -> fullType ty
+      | Ast.UniqueType(ty) -> fullType ty in
+    ftfn all_functions k ft
+
+  and function_pointer (ty,lp1,star,rp1,lp2,params,rp2) extra =
+    (* have to put the treatment of the identifier into the right position *)
+    multibind
+      ([fullType ty; string_mcode lp1; string_mcode star] @ extra @
+       [string_mcode rp1;
+        string_mcode lp2; parameter_dots params; string_mcode rp2])
+
+  and function_type (ty,lp1,params,rp1) extra =
+    (* have to put the treatment of the identifier into the right position *)
+    multibind
+      ([get_option fullType ty] @ extra @
+       [string_mcode lp1; parameter_dots params; string_mcode rp1])
+
+  and array_type (ty,lb,size,rb) extra =
+    multibind
+      ([fullType ty] @ extra @
+       [string_mcode lb; get_option expression size; string_mcode rb])
+
+  and typeC ty =
+    let k ty =
+      match Ast.unwrap ty with
+       Ast.BaseType(ty,strings) -> multibind (List.map string_mcode strings)
+      | Ast.SignedT(sgn,ty) -> bind (sign_mcode sgn) (get_option typeC ty)
+      | Ast.Pointer(ty,star) ->
+         bind (fullType ty) (string_mcode star)
+      | Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
+         function_pointer (ty,lp1,star,rp1,lp2,params,rp2) []
+      |        Ast.FunctionType (_,ty,lp1,params,rp1) ->
+         function_type (ty,lp1,params,rp1) []
+      | Ast.Array(ty,lb,size,rb) -> array_type (ty,lb,size,rb) []
+      | Ast.EnumName(kind,name) -> bind (string_mcode kind) (ident name)
+      | Ast.StructUnionName(kind,name) ->
+         bind (struct_mcode kind) (get_option ident name)
+      | Ast.StructUnionDef(ty,lb,decls,rb) ->
+         multibind
+           [fullType ty; string_mcode lb; declaration_dots decls;
+             string_mcode rb]
+      | Ast.TypeName(name) -> string_mcode name
+      | Ast.MetaType(name,_,_) -> meta_mcode name in
+    tyfn all_functions k ty
+
+  and named_type ty id =
+    match Ast.unwrap ty with
+      Ast.Type(None,ty1) ->
+       (match Ast.unwrap ty1 with
+         Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
+           function_pointer (ty,lp1,star,rp1,lp2,params,rp2) [ident id]
+       | Ast.FunctionType(_,ty,lp1,params,rp1) ->
+           function_type (ty,lp1,params,rp1) [ident id]
+       | Ast.Array(ty,lb,size,rb) -> array_type (ty,lb,size,rb) [ident id]
+       | _ -> bind (fullType ty) (ident id))
+    | _ -> bind (fullType ty) (ident id)
+
+  and declaration d =
+    let k d =
+      match Ast.unwrap d with
+       Ast.Init(stg,ty,id,eq,ini,sem) ->
+         bind (get_option storage_mcode stg)
+           (bind (named_type ty id)
+              (multibind
+                 [string_mcode eq; initialiser ini; string_mcode sem]))
+      | Ast.UnInit(stg,ty,id,sem) ->
+         bind (get_option storage_mcode stg)
+           (bind (named_type ty id) (string_mcode sem))
+      | Ast.MacroDecl(name,lp,args,rp,sem) ->
+         multibind
+           [ident name; string_mcode lp; expression_dots args;
+             string_mcode rp; string_mcode sem]
+      | Ast.TyDecl(ty,sem) -> bind (fullType ty) (string_mcode sem)
+      | Ast.Typedef(stg,ty,id,sem) ->
+         bind (string_mcode stg)
+           (bind (fullType ty) (bind (typeC id) (string_mcode sem)))
+      | Ast.DisjDecl(decls) -> multibind (List.map declaration decls)
+      |        Ast.Ddots(dots,whencode) ->
+         bind (string_mcode dots) (get_option declaration whencode)
+      | Ast.MetaDecl(name,_,_) -> meta_mcode name
+      | Ast.OptDecl(decl) -> declaration decl
+      | Ast.UniqueDecl(decl) -> declaration decl in
+    declfn all_functions k d
+
+  and initialiser i =
+    let k i =
+      match Ast.unwrap i with
+       Ast.MetaInit(name,_,_) -> meta_mcode name
+      |        Ast.InitExpr(exp) -> expression exp
+      | Ast.InitList(lb,initlist,rb,whencode) ->
+         multibind
+           [string_mcode lb;
+             multibind (List.map initialiser initlist);
+             string_mcode rb;
+             multibind (List.map initialiser whencode)]
+      | Ast.InitGccName(name,eq,ini) ->
+         multibind [ident name; string_mcode eq; initialiser ini]
+      | Ast.InitGccExt(designators,eq,ini) ->
+         multibind
+           ((List.map designator designators) @
+            [string_mcode eq; initialiser ini])
+      | Ast.IComma(cm) -> string_mcode cm
+      | Ast.OptIni(i) -> initialiser i
+      | Ast.UniqueIni(i) -> initialiser i in
+    initfn all_functions k i
+
+  and designator = function
+      Ast.DesignatorField(dot,id) -> bind (string_mcode dot) (ident id)
+    | Ast.DesignatorIndex(lb,exp,rb) ->
+       bind (string_mcode lb) (bind (expression exp) (string_mcode rb))
+    | Ast.DesignatorRange(lb,min,dots,max,rb) ->
+       multibind
+         [string_mcode lb; expression min; string_mcode dots;
+           expression max; string_mcode rb]
+
+  and parameterTypeDef p =
+    let k p =
+      match Ast.unwrap p with
+       Ast.VoidParam(ty) -> fullType ty
+      | Ast.Param(ty,Some id) -> named_type ty id
+      | Ast.Param(ty,None) -> fullType ty
+      | Ast.MetaParam(name,_,_) -> meta_mcode name
+      | Ast.MetaParamList(name,_,_,_) -> meta_mcode name
+      | Ast.PComma(cm) -> string_mcode cm
+      | Ast.Pdots(dots) -> string_mcode dots
+      | Ast.Pcircles(dots) -> string_mcode dots
+      | Ast.OptParam(param) -> parameterTypeDef param
+      | Ast.UniqueParam(param) -> parameterTypeDef param in
+    paramfn all_functions k p
+
+  and rule_elem re =
+    let k re =
+      match Ast.unwrap re with
+       Ast.FunHeader(_,_,fi,name,lp,params,rp) ->
+         multibind
+           ((List.map fninfo fi) @
+            [ident name;string_mcode lp;parameter_dots params;
+              string_mcode rp])
+      | Ast.Decl(_,_,decl) -> declaration decl
+      | Ast.SeqStart(brace) -> string_mcode brace
+      | Ast.SeqEnd(brace) -> string_mcode brace
+      | Ast.ExprStatement(exp,sem) ->
+         bind (expression exp) (string_mcode sem)
+      | Ast.IfHeader(iff,lp,exp,rp) ->
+         multibind [string_mcode iff; string_mcode lp; expression exp;
+                     string_mcode rp]
+      | Ast.Else(els) -> string_mcode els
+      | Ast.WhileHeader(whl,lp,exp,rp) ->
+         multibind [string_mcode whl; string_mcode lp; expression exp;
+                     string_mcode rp]
+      | Ast.DoHeader(d) -> string_mcode d
+      | Ast.WhileTail(whl,lp,exp,rp,sem) ->
+         multibind [string_mcode whl; string_mcode lp; expression exp;
+                     string_mcode rp; string_mcode sem]
+      | Ast.ForHeader(fr,lp,e1,sem1,e2,sem2,e3,rp) ->
+         multibind [string_mcode fr; string_mcode lp;
+                     get_option expression e1; string_mcode sem1;
+                     get_option expression e2; string_mcode sem2;
+                     get_option expression e3; string_mcode rp]
+      | Ast.IteratorHeader(nm,lp,args,rp) ->
+         multibind [ident nm; string_mcode lp;
+                     expression_dots args; string_mcode rp]
+      | Ast.SwitchHeader(switch,lp,exp,rp) ->
+         multibind [string_mcode switch; string_mcode lp; expression exp;
+                     string_mcode rp]
+      | Ast.Break(br,sem) -> bind (string_mcode br) (string_mcode sem)
+      | Ast.Continue(cont,sem) -> bind (string_mcode cont) (string_mcode sem)
+      |        Ast.Label(l,dd) -> bind (ident l) (string_mcode dd)
+      |        Ast.Goto(goto,l,sem) ->
+         bind (string_mcode goto) (bind (ident l) (string_mcode sem))
+      | Ast.Return(ret,sem) -> bind (string_mcode ret) (string_mcode sem)
+      | Ast.ReturnExpr(ret,exp,sem) ->
+         multibind [string_mcode ret; expression exp; string_mcode sem]
+      | Ast.MetaStmt(name,_,_,_) -> meta_mcode name
+      | Ast.MetaStmtList(name,_,_) -> meta_mcode name
+      | Ast.MetaRuleElem(name,_,_) -> meta_mcode name
+      | Ast.Exp(exp) -> expression exp
+      | Ast.TopExp(exp) -> expression exp
+      | Ast.Ty(ty) -> fullType ty
+      | Ast.TopInit(init) -> initialiser init
+      |        Ast.Include(inc,name) -> bind (string_mcode inc) (inc_file_mcode name)
+      |        Ast.DefineHeader(def,id,params) ->
+         multibind [string_mcode def; ident id; define_parameters params]
+      |        Ast.Default(def,colon) -> bind (string_mcode def) (string_mcode colon)
+      |        Ast.Case(case,exp,colon) ->
+         multibind [string_mcode case; expression exp; string_mcode colon]
+      |        Ast.DisjRuleElem(res) -> multibind (List.map rule_elem res) in
+    rulefn all_functions k re
+
+  (* not parameterizable for now... *)
+  and define_parameters p =
+    let k p =
+      match Ast.unwrap p with
+       Ast.NoParams -> option_default
+      | Ast.DParams(lp,params,rp) ->
+         multibind
+           [string_mcode lp; define_param_dots params; string_mcode rp] in
+    k p
+
+  and define_param_dots d =
+    let k d =
+      match Ast.unwrap d with
+       Ast.DOTS(l) | Ast.CIRCLES(l) | Ast.STARS(l) ->
+         multibind (List.map define_param l) in
+    k d
+
+  and define_param p =
+    let k p =
+      match Ast.unwrap p with
+       Ast.DParam(id) -> ident id
+      | Ast.DPComma(comma) -> string_mcode comma
+      | Ast.DPdots(d) -> string_mcode d
+      | Ast.DPcircles(c) -> string_mcode c
+      | Ast.OptDParam(dp) -> define_param dp
+      | Ast.UniqueDParam(dp) -> define_param dp in
+    k p
+
+  (* discard the result, because the statement is assumed to be already
+     represented elsewhere in the code *)
+  and process_bef_aft s =
+    match Ast.get_dots_bef_aft s with
+      Ast.NoDots -> ()
+    | Ast.DroppingBetweenDots(stm,ind) -> let _ = statement stm in ()
+    | Ast.AddingBetweenDots(stm,ind) -> let _ = statement stm in ()
+
+  and statement s =
+    process_bef_aft s;
+    let k s =
+      match Ast.unwrap s with
+       Ast.Seq(lbrace,decls,body,rbrace) ->
+         multibind [rule_elem lbrace; statement_dots decls;
+                     statement_dots body; rule_elem rbrace]
+      | Ast.IfThen(header,branch,_) ->
+         multibind [rule_elem header; statement branch]
+      | Ast.IfThenElse(header,branch1,els,branch2,_) ->
+         multibind [rule_elem header; statement branch1; rule_elem els;
+                     statement branch2]
+      | Ast.While(header,body,_) ->
+         multibind [rule_elem header; statement body]
+      | Ast.Do(header,body,tail) ->
+         multibind [rule_elem header; statement body; rule_elem tail]
+      | Ast.For(header,body,_) -> multibind [rule_elem header; statement body]
+      | Ast.Iterator(header,body,_) ->
+         multibind [rule_elem header; statement body]
+      |        Ast.Switch(header,lb,cases,rb) ->
+         multibind [rule_elem header;rule_elem lb;
+                     multibind (List.map case_line cases);
+                     rule_elem rb]
+      | Ast.Atomic(re) -> rule_elem re
+      | Ast.Disj(stmt_dots_list) ->
+         multibind (List.map statement_dots stmt_dots_list)
+      | Ast.Nest(stmt_dots,whn,_,_,_) ->
+         bind (statement_dots stmt_dots)
+           (multibind (List.map (whencode statement_dots statement) whn))
+      | Ast.FunDecl(header,lbrace,decls,body,rbrace) ->
+         multibind [rule_elem header; rule_elem lbrace;
+                     statement_dots decls; statement_dots body;
+                     rule_elem rbrace]
+      | Ast.Define(header,body) ->
+         bind (rule_elem header) (statement_dots body)
+      | Ast.Dots(d,whn,_,_) | Ast.Circles(d,whn,_,_) | Ast.Stars(d,whn,_,_) ->
+         bind (string_mcode d)
+           (multibind (List.map (whencode statement_dots statement) whn))
+      | Ast.OptStm(stmt) | Ast.UniqueStm(stmt) ->
+         statement stmt in
+    stmtfn all_functions k s
+
+  and fninfo = function
+      Ast.FStorage(stg) -> storage_mcode stg
+    | Ast.FType(ty) -> fullType ty
+    | Ast.FInline(inline) -> string_mcode inline
+    | Ast.FAttr(attr) -> string_mcode attr
+
+  and whencode notfn alwaysfn = function
+      Ast.WhenNot a -> notfn a
+    | Ast.WhenAlways a -> alwaysfn a
+    | Ast.WhenModifier(_) -> option_default
+    | Ast.WhenNotTrue(e) -> rule_elem e
+    | Ast.WhenNotFalse(e) -> rule_elem e
+
+  and case_line c =
+    let k c =
+      match Ast.unwrap c with
+       Ast.CaseLine(header,code) ->
+         bind (rule_elem header) (statement_dots code)
+      |        Ast.OptCase(case) -> case_line case in
+    casefn all_functions k c
+
+  and top_level t =
+    let k t =
+      match Ast.unwrap t with
+       Ast.FILEINFO(old_file,new_file) ->
+         bind (string_mcode old_file) (string_mcode new_file)
+      | Ast.DECL(stmt) -> statement stmt
+      | Ast.CODE(stmt_dots) -> statement_dots stmt_dots
+      | Ast.ERRORWORDS(exps) -> multibind (List.map expression exps) in
+    topfn all_functions k t
+
+  and anything a =
+    let k = function
+       (*in many cases below, the thing is not even mcode, so we do nothing*)
+       Ast.FullTypeTag(ft) -> fullType ft
+      | Ast.BaseTypeTag(bt) -> option_default
+      | Ast.StructUnionTag(su) -> option_default
+      | Ast.SignTag(sgn) -> option_default
+      | Ast.IdentTag(id) -> ident id
+      | Ast.ExpressionTag(exp) -> expression exp
+      | Ast.ConstantTag(cst) -> option_default
+      | Ast.UnaryOpTag(unop) -> option_default
+      | Ast.AssignOpTag(asgnop) -> option_default
+      | Ast.FixOpTag(fixop) -> option_default
+      | Ast.BinaryOpTag(binop) -> option_default
+      | Ast.ArithOpTag(arithop) -> option_default
+      | Ast.LogicalOpTag(logop) -> option_default
+      | Ast.DeclarationTag(decl) -> declaration decl
+      | Ast.InitTag(ini) -> initialiser ini
+      | Ast.StorageTag(stg) -> option_default
+      | Ast.IncFileTag(stg) -> option_default
+      | Ast.Rule_elemTag(rule) -> rule_elem rule
+      | Ast.StatementTag(rule) -> statement rule
+      | Ast.CaseLineTag(case) -> case_line case
+      | Ast.ConstVolTag(cv) -> option_default
+      | Ast.Token(tok,info) -> option_default
+      | Ast.Code(cd) -> top_level cd
+      | Ast.ExprDotsTag(ed) -> expression_dots ed
+      | Ast.ParamDotsTag(pd) -> parameter_dots pd
+      | Ast.StmtDotsTag(sd) -> statement_dots sd
+      | Ast.DeclDotsTag(sd) -> declaration_dots sd
+      | Ast.TypeCTag(ty) -> typeC ty
+      | Ast.ParamTag(param) -> parameterTypeDef param
+      | Ast.SgrepStartTag(tok) -> option_default
+      | Ast.SgrepEndTag(tok) -> option_default in
+    anyfn all_functions k a
+
+  and all_functions =
+    {combiner_ident = ident;
+      combiner_expression = expression;
+      combiner_fullType = fullType;
+      combiner_typeC = typeC;
+      combiner_declaration = declaration;
+      combiner_initialiser = initialiser;
+      combiner_parameter = parameterTypeDef;
+      combiner_parameter_list = parameter_dots;
+      combiner_rule_elem = rule_elem;
+      combiner_statement = statement;
+      combiner_case_line = case_line;
+      combiner_top_level = top_level;
+      combiner_anything = anything;
+      combiner_expression_dots = expression_dots;
+      combiner_statement_dots = statement_dots;
+      combiner_declaration_dots = declaration_dots} in
+  all_functions
+
+(* ---------------------------------------------------------------------- *)
+
+type 'a inout = 'a -> 'a (* for specifying the type of rebuilder *)
+
+type rebuilder =
+    {rebuilder_ident : Ast.ident inout;
+      rebuilder_expression : Ast.expression inout;
+      rebuilder_fullType : Ast.fullType inout;
+      rebuilder_typeC : Ast.typeC inout;
+      rebuilder_declaration : Ast.declaration inout;
+      rebuilder_initialiser : Ast.initialiser inout;
+      rebuilder_parameter : Ast.parameterTypeDef inout;
+      rebuilder_parameter_list : Ast.parameter_list inout;
+      rebuilder_statement : Ast.statement inout;
+      rebuilder_case_line : Ast.case_line inout;
+      rebuilder_rule_elem : Ast.rule_elem inout;
+      rebuilder_top_level : Ast.top_level inout;
+      rebuilder_expression_dots : Ast.expression Ast.dots inout;
+      rebuilder_statement_dots : Ast.statement Ast.dots inout;
+      rebuilder_declaration_dots : Ast.declaration Ast.dots inout;
+      rebuilder_define_param_dots : Ast.define_param Ast.dots inout;
+      rebuilder_define_param : Ast.define_param inout;
+      rebuilder_define_parameters : Ast.define_parameters inout;
+      rebuilder_anything : Ast.anything inout}
+
+type 'mc rmcode = 'mc Ast.mcode inout
+type 'cd rcode = rebuilder -> ('cd inout) -> 'cd inout
+
+
+let rebuilder
+    meta_mcode string_mcode const_mcode assign_mcode fix_mcode unary_mcode
+    binary_mcode cv_mcode sign_mcode struct_mcode storage_mcode
+    inc_file_mcode
+    expdotsfn paramdotsfn stmtdotsfn decldotsfn
+    identfn exprfn ftfn tyfn initfn paramfn declfn rulefn stmtfn casefn
+    topfn anyfn =
+  let get_option f = function
+      Some x -> Some (f x)
+    | None -> None in
+  let rec expression_dots d =
+    let k d =
+      Ast.rewrap d
+       (match Ast.unwrap d with
+         Ast.DOTS(l) -> Ast.DOTS(List.map expression l)
+       | Ast.CIRCLES(l) -> Ast.CIRCLES(List.map expression l)
+       | Ast.STARS(l) -> Ast.STARS(List.map expression l)) in
+    expdotsfn all_functions k d
+
+  and parameter_dots d =
+    let k d =
+      Ast.rewrap d
+       (match Ast.unwrap d with
+         Ast.DOTS(l) -> Ast.DOTS(List.map parameterTypeDef l)
+       | Ast.CIRCLES(l) -> Ast.CIRCLES(List.map parameterTypeDef l)
+       | Ast.STARS(l) -> Ast.STARS(List.map parameterTypeDef l)) in
+    paramdotsfn all_functions k d
+
+  and statement_dots d =
+    let k d =
+      Ast.rewrap d
+       (match Ast.unwrap d with
+         Ast.DOTS(l) -> Ast.DOTS(List.map statement l)
+       | Ast.CIRCLES(l) -> Ast.CIRCLES(List.map statement l)
+       | Ast.STARS(l) -> Ast.STARS(List.map statement l)) in
+    stmtdotsfn all_functions k d
+
+  and declaration_dots d =
+    let k d =
+      Ast.rewrap d
+       (match Ast.unwrap d with
+         Ast.DOTS(l) -> Ast.DOTS(List.map declaration l)
+       | Ast.CIRCLES(l) -> Ast.CIRCLES(List.map declaration l)
+       | Ast.STARS(l) -> Ast.STARS(List.map declaration l)) in
+    decldotsfn all_functions k d
+
+  and ident i =
+    let k i =
+      Ast.rewrap i
+       (match Ast.unwrap i with
+         Ast.Id(name) -> Ast.Id(string_mcode name)
+       | Ast.MetaId(name,constraints,keep,inherited) ->
+           Ast.MetaId(meta_mcode name,constraints,keep,inherited)
+       | Ast.MetaFunc(name,constraints,keep,inherited) ->
+           Ast.MetaFunc(meta_mcode name,constraints,keep,inherited)
+       | Ast.MetaLocalFunc(name,constraints,keep,inherited) ->
+           Ast.MetaLocalFunc(meta_mcode name,constraints,keep,inherited)
+       | Ast.OptIdent(id) -> Ast.OptIdent(ident id)
+       | Ast.UniqueIdent(id) -> Ast.UniqueIdent(ident id)) in
+    identfn all_functions k i
+
+  and expression e =
+    let k e =
+      Ast.rewrap e
+       (match Ast.unwrap e with
+         Ast.Ident(id) -> Ast.Ident(ident id)
+       | Ast.Constant(const) -> Ast.Constant(const_mcode const)
+       | Ast.FunCall(fn,lp,args,rp) ->
+           Ast.FunCall(expression fn, string_mcode lp, expression_dots args,
+                       string_mcode rp)
+       | Ast.Assignment(left,op,right,simple) ->
+           Ast.Assignment(expression left, assign_mcode op, expression right,
+                          simple)
+       | Ast.CondExpr(exp1,why,exp2,colon,exp3) ->
+           Ast.CondExpr(expression exp1, string_mcode why,
+                        get_option expression exp2, string_mcode colon,
+                        expression exp3)
+       | Ast.Postfix(exp,op) -> Ast.Postfix(expression exp,fix_mcode op)
+       | Ast.Infix(exp,op) -> Ast.Infix(expression exp,fix_mcode op)
+       | Ast.Unary(exp,op) -> Ast.Unary(expression exp,unary_mcode op)
+       | Ast.Binary(left,op,right) ->
+           Ast.Binary(expression left, binary_mcode op, expression right)
+       | Ast.Nested(left,op,right) ->
+           Ast.Nested(expression left, binary_mcode op, expression right)
+       | Ast.Paren(lp,exp,rp) ->
+           Ast.Paren(string_mcode lp, expression exp, string_mcode rp)
+       | Ast.ArrayAccess(exp1,lb,exp2,rb) ->
+           Ast.ArrayAccess(expression exp1, string_mcode lb, expression exp2,
+                           string_mcode rb)
+       | Ast.RecordAccess(exp,pt,field) ->
+           Ast.RecordAccess(expression exp, string_mcode pt, ident field)
+       | Ast.RecordPtAccess(exp,ar,field) ->
+           Ast.RecordPtAccess(expression exp, string_mcode ar, ident field)
+       | Ast.Cast(lp,ty,rp,exp) ->
+           Ast.Cast(string_mcode lp, fullType ty, string_mcode rp,
+                    expression exp)
+       | Ast.SizeOfExpr(szf,exp) ->
+           Ast.SizeOfExpr(string_mcode szf, expression exp)
+       | Ast.SizeOfType(szf,lp,ty,rp) ->
+           Ast.SizeOfType(string_mcode szf,string_mcode lp, fullType ty,
+                           string_mcode rp)
+       | Ast.TypeExp(ty) -> Ast.TypeExp(fullType ty)
+       | Ast.MetaErr(name,constraints,keep,inherited) ->
+           Ast.MetaErr(meta_mcode name,constraints,keep,inherited)
+       | Ast.MetaExpr(name,constraints,keep,ty,form,inherited) ->
+           Ast.MetaExpr(meta_mcode name,constraints,keep,ty,form,inherited)
+       | Ast.MetaExprList(name,lenname_inh,keep,inherited) ->
+           Ast.MetaExprList(meta_mcode name,lenname_inh,keep,inherited)
+       | Ast.EComma(cm) -> Ast.EComma(string_mcode cm)
+       | Ast.DisjExpr(exp_list) -> Ast.DisjExpr(List.map expression exp_list)
+       | Ast.NestExpr(expr_dots,whencode,multi) ->
+           Ast.NestExpr(expression_dots expr_dots,
+                        get_option expression whencode,multi)
+       | Ast.Edots(dots,whencode) ->
+           Ast.Edots(string_mcode dots,get_option expression whencode)
+       | Ast.Ecircles(dots,whencode) ->
+           Ast.Ecircles(string_mcode dots,get_option expression whencode)
+       | Ast.Estars(dots,whencode) ->
+           Ast.Estars(string_mcode dots,get_option expression whencode)
+       | Ast.OptExp(exp) -> Ast.OptExp(expression exp)
+       | Ast.UniqueExp(exp) -> Ast.UniqueExp(expression exp)) in
+    exprfn all_functions k e
+
+  and fullType ft =
+    let k ft =
+      Ast.rewrap ft
+       (match Ast.unwrap ft with
+         Ast.Type(cv,ty) -> Ast.Type (get_option cv_mcode cv, typeC ty)
+       | Ast.DisjType(types) -> Ast.DisjType(List.map fullType types)
+       | Ast.OptType(ty) -> Ast.OptType(fullType ty)
+       | Ast.UniqueType(ty) -> Ast.UniqueType(fullType ty)) in
+    ftfn all_functions k ft
+
+  and typeC ty =
+    let k ty =
+      Ast.rewrap ty
+       (match Ast.unwrap ty with
+         Ast.BaseType(ty,strings) ->
+           Ast.BaseType (ty, List.map string_mcode strings)
+       | Ast.SignedT(sgn,ty) ->
+           Ast.SignedT(sign_mcode sgn,get_option typeC ty)
+       | Ast.Pointer(ty,star) ->
+           Ast.Pointer (fullType ty, string_mcode star)
+       | Ast.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
+           Ast.FunctionPointer(fullType ty,string_mcode lp1,string_mcode star,
+                               string_mcode rp1,string_mcode lp2,
+                               parameter_dots params,
+                               string_mcode rp2)
+       | Ast.FunctionType(allminus,ty,lp,params,rp) ->
+           Ast.FunctionType(allminus,get_option fullType ty,string_mcode lp,
+                            parameter_dots params,string_mcode rp)
+       | Ast.Array(ty,lb,size,rb) ->
+           Ast.Array(fullType ty, string_mcode lb,
+                     get_option expression size, string_mcode rb)
+       | Ast.EnumName(kind,name) ->
+           Ast.EnumName(string_mcode kind, ident name)
+       | Ast.StructUnionName(kind,name) ->
+           Ast.StructUnionName (struct_mcode kind, get_option ident name)
+       | Ast.StructUnionDef(ty,lb,decls,rb) ->
+           Ast.StructUnionDef (fullType ty,
+                               string_mcode lb, declaration_dots decls,
+                               string_mcode rb)
+       | Ast.TypeName(name) -> Ast.TypeName(string_mcode name)
+       | Ast.MetaType(name,keep,inherited) ->
+           Ast.MetaType(meta_mcode name,keep,inherited)) in
+    tyfn all_functions k ty
+
+  and declaration d =
+    let k d =
+      Ast.rewrap d
+       (match Ast.unwrap d with
+         Ast.Init(stg,ty,id,eq,ini,sem) ->
+           Ast.Init(get_option storage_mcode stg, fullType ty, ident id,
+                    string_mcode eq, initialiser ini, string_mcode sem)
+       | Ast.UnInit(stg,ty,id,sem) ->
+           Ast.UnInit(get_option storage_mcode stg, fullType ty, ident id,
+                      string_mcode sem)
+       | Ast.MacroDecl(name,lp,args,rp,sem) ->
+           Ast.MacroDecl(ident name, string_mcode lp, expression_dots args,
+                         string_mcode rp,string_mcode sem)
+       | Ast.TyDecl(ty,sem) -> Ast.TyDecl(fullType ty, string_mcode sem)
+       | Ast.Typedef(stg,ty,id,sem) ->
+           Ast.Typedef(string_mcode stg, fullType ty, typeC id,
+                       string_mcode sem)
+       | Ast.DisjDecl(decls) -> Ast.DisjDecl(List.map declaration decls)
+       | Ast.Ddots(dots,whencode) ->
+           Ast.Ddots(string_mcode dots, get_option declaration whencode)
+       | Ast.MetaDecl(name,keep,inherited) ->
+           Ast.MetaDecl(meta_mcode name,keep,inherited)
+       | Ast.OptDecl(decl) -> Ast.OptDecl(declaration decl)
+       | Ast.UniqueDecl(decl) -> Ast.UniqueDecl(declaration decl)) in
+    declfn all_functions k d
+
+  and initialiser i =
+    let k i =
+      Ast.rewrap i
+       (match Ast.unwrap i with
+         Ast.MetaInit(name,keep,inherited) ->
+           Ast.MetaInit(meta_mcode name,keep,inherited)
+       | Ast.InitExpr(exp) -> Ast.InitExpr(expression exp)
+       | Ast.InitList(lb,initlist,rb,whencode) ->
+           Ast.InitList(string_mcode lb, List.map initialiser initlist,
+                        string_mcode rb, List.map initialiser whencode)
+       | Ast.InitGccName(name,eq,ini) ->
+           Ast.InitGccName(ident name, string_mcode eq, initialiser ini)
+       | Ast.InitGccExt(designators,eq,ini) ->
+           Ast.InitGccExt
+             (List.map designator designators, string_mcode eq,
+              initialiser ini)
+       | Ast.IComma(cm) -> Ast.IComma(string_mcode cm)
+       | Ast.OptIni(i) -> Ast.OptIni(initialiser i)
+       | Ast.UniqueIni(i) -> Ast.UniqueIni(initialiser i)) in
+    initfn all_functions k i
+
+  and designator = function
+      Ast.DesignatorField(dot,id) ->
+       Ast.DesignatorField(string_mcode dot,ident id)
+    | Ast.DesignatorIndex(lb,exp,rb) ->
+       Ast.DesignatorIndex(string_mcode lb,expression exp,string_mcode rb)
+    | Ast.DesignatorRange(lb,min,dots,max,rb) ->
+       Ast.DesignatorRange(string_mcode lb,expression min,string_mcode dots,
+                            expression max,string_mcode rb)
+
+  and parameterTypeDef p =
+    let k p =
+      Ast.rewrap p
+       (match Ast.unwrap p with
+         Ast.VoidParam(ty) -> Ast.VoidParam(fullType ty)
+       | Ast.Param(ty,id) -> Ast.Param(fullType ty, get_option ident id)
+       | Ast.MetaParam(name,keep,inherited) ->
+           Ast.MetaParam(meta_mcode name,keep,inherited)
+       | Ast.MetaParamList(name,lenname_inh,keep,inherited) ->
+           Ast.MetaParamList(meta_mcode name,lenname_inh,keep,inherited)
+       | Ast.PComma(cm) -> Ast.PComma(string_mcode cm)
+       | Ast.Pdots(dots) -> Ast.Pdots(string_mcode dots)
+       | Ast.Pcircles(dots) -> Ast.Pcircles(string_mcode dots)
+       | Ast.OptParam(param) -> Ast.OptParam(parameterTypeDef param)
+       | Ast.UniqueParam(param) -> Ast.UniqueParam(parameterTypeDef param)) in
+    paramfn all_functions k p
+
+  and rule_elem re =
+    let k re =
+      Ast.rewrap re
+       (match Ast.unwrap re with
+         Ast.FunHeader(bef,allminus,fi,name,lp,params,rp) ->
+           Ast.FunHeader(bef,allminus,List.map fninfo fi,ident name,
+                         string_mcode lp, parameter_dots params,
+                         string_mcode rp)
+       | Ast.Decl(bef,allminus,decl) ->
+           Ast.Decl(bef,allminus,declaration decl)
+       | Ast.SeqStart(brace) -> Ast.SeqStart(string_mcode brace)
+       | Ast.SeqEnd(brace) -> Ast.SeqEnd(string_mcode brace)
+       | Ast.ExprStatement(exp,sem) ->
+           Ast.ExprStatement (expression exp, string_mcode sem)
+       | Ast.IfHeader(iff,lp,exp,rp) ->
+           Ast.IfHeader(string_mcode iff, string_mcode lp, expression exp,
+             string_mcode rp)
+       | Ast.Else(els) -> Ast.Else(string_mcode els)
+       | Ast.WhileHeader(whl,lp,exp,rp) ->
+           Ast.WhileHeader(string_mcode whl, string_mcode lp, expression exp,
+                           string_mcode rp)
+       | Ast.DoHeader(d) -> Ast.DoHeader(string_mcode d)
+       | Ast.WhileTail(whl,lp,exp,rp,sem) ->
+           Ast.WhileTail(string_mcode whl, string_mcode lp, expression exp,
+                         string_mcode rp, string_mcode sem)
+       | Ast.ForHeader(fr,lp,e1,sem1,e2,sem2,e3,rp) ->
+           Ast.ForHeader(string_mcode fr, string_mcode lp,
+                         get_option expression e1, string_mcode sem1,
+                         get_option expression e2, string_mcode sem2,
+                         get_option expression e3, string_mcode rp)
+       | Ast.IteratorHeader(whl,lp,args,rp) ->
+           Ast.IteratorHeader(ident whl, string_mcode lp,
+                              expression_dots args, string_mcode rp)
+       | Ast.SwitchHeader(switch,lp,exp,rp) ->
+           Ast.SwitchHeader(string_mcode switch, string_mcode lp,
+                            expression exp, string_mcode rp)
+       | Ast.Break(br,sem) ->
+           Ast.Break(string_mcode br, string_mcode sem)
+       | Ast.Continue(cont,sem) ->
+           Ast.Continue(string_mcode cont, string_mcode sem)
+       | Ast.Label(l,dd) -> Ast.Label(ident l, string_mcode dd)
+       | Ast.Goto(goto,l,sem) ->
+           Ast.Goto(string_mcode goto,ident l,string_mcode sem)
+       | Ast.Return(ret,sem) ->
+           Ast.Return(string_mcode ret, string_mcode sem)
+       | Ast.ReturnExpr(ret,exp,sem) ->
+           Ast.ReturnExpr(string_mcode ret, expression exp, string_mcode sem)
+       | Ast.MetaStmt(name,keep,seqible,inherited) ->
+           Ast.MetaStmt(meta_mcode name,keep,seqible,inherited)
+       | Ast.MetaStmtList(name,keep,inherited) ->
+           Ast.MetaStmtList(meta_mcode name,keep,inherited)
+       | Ast.MetaRuleElem(name,keep,inherited) ->
+           Ast.MetaRuleElem(meta_mcode name,keep,inherited)
+       | Ast.Exp(exp) -> Ast.Exp(expression exp)
+       | Ast.TopExp(exp) -> Ast.TopExp(expression exp)
+       | Ast.Ty(ty) -> Ast.Ty(fullType ty)
+       | Ast.TopInit(init) -> Ast.TopInit(initialiser init)
+       | Ast.Include(inc,name) ->
+           Ast.Include(string_mcode inc,inc_file_mcode name)
+       | Ast.DefineHeader(def,id,params) ->
+           Ast.DefineHeader(string_mcode def,ident id,
+                            define_parameters params)
+       | Ast.Default(def,colon) ->
+           Ast.Default(string_mcode def,string_mcode colon)
+       | Ast.Case(case,exp,colon) ->
+           Ast.Case(string_mcode case,expression exp,string_mcode colon)
+       | Ast.DisjRuleElem(res) -> Ast.DisjRuleElem(List.map rule_elem res)) in
+    rulefn all_functions k re
+
+  (* not parameterizable for now... *)
+  and define_parameters p =
+    let k p =
+      Ast.rewrap p
+       (match Ast.unwrap p with
+         Ast.NoParams -> Ast.NoParams
+       | Ast.DParams(lp,params,rp) ->
+           Ast.DParams(string_mcode lp,define_param_dots params,
+                       string_mcode rp)) in
+    k p
+
+  and define_param_dots d =
+    let k d =
+      Ast.rewrap d
+       (match Ast.unwrap d with
+         Ast.DOTS(l) -> Ast.DOTS(List.map define_param l)
+       | Ast.CIRCLES(l) -> Ast.CIRCLES(List.map define_param l)
+       | Ast.STARS(l) -> Ast.STARS(List.map define_param l)) in
+    k d
+
+  and define_param p =
+    let k p =
+      Ast.rewrap p
+       (match Ast.unwrap p with
+         Ast.DParam(id) -> Ast.DParam(ident id)
+       | Ast.DPComma(comma) -> Ast.DPComma(string_mcode comma)
+       | Ast.DPdots(d) -> Ast.DPdots(string_mcode d)
+       | Ast.DPcircles(c) -> Ast.DPcircles(string_mcode c)
+       | Ast.OptDParam(dp) -> Ast.OptDParam(define_param dp)
+       | Ast.UniqueDParam(dp) -> Ast.UniqueDParam(define_param dp)) in
+    k p
+
+  and process_bef_aft s =
+    Ast.set_dots_bef_aft
+      (match Ast.get_dots_bef_aft s with
+       Ast.NoDots -> Ast.NoDots
+      | Ast.DroppingBetweenDots(stm,ind) ->
+         Ast.DroppingBetweenDots(statement stm,ind)
+      | Ast.AddingBetweenDots(stm,ind) ->
+         Ast.AddingBetweenDots(statement stm,ind))
+      s
+
+  and statement s =
+    let k s =
+      Ast.rewrap s
+       (match Ast.unwrap s with
+         Ast.Seq(lbrace,decls,body,rbrace) ->
+           Ast.Seq(rule_elem lbrace, statement_dots decls,
+                   statement_dots body, rule_elem rbrace)
+       | Ast.IfThen(header,branch,aft) ->
+           Ast.IfThen(rule_elem header, statement branch,aft)
+       | Ast.IfThenElse(header,branch1,els,branch2,aft) ->
+           Ast.IfThenElse(rule_elem header, statement branch1, rule_elem els,
+                          statement branch2, aft)
+       | Ast.While(header,body,aft) ->
+           Ast.While(rule_elem header, statement body, aft)
+       | Ast.Do(header,body,tail) ->
+           Ast.Do(rule_elem header, statement body, rule_elem tail)
+       | Ast.For(header,body,aft) ->
+           Ast.For(rule_elem header, statement body, aft)
+       | Ast.Iterator(header,body,aft) ->
+           Ast.Iterator(rule_elem header, statement body, aft)
+       | Ast.Switch(header,lb,cases,rb) ->
+           Ast.Switch(rule_elem header,rule_elem lb,
+                      List.map case_line cases,rule_elem rb)
+       | Ast.Atomic(re) -> Ast.Atomic(rule_elem re)
+       | Ast.Disj(stmt_dots_list) ->
+           Ast.Disj (List.map statement_dots stmt_dots_list)
+       | Ast.Nest(stmt_dots,whn,multi,bef,aft) ->
+           Ast.Nest(statement_dots stmt_dots,
+                    List.map (whencode statement_dots statement) whn,
+                    multi,bef,aft)
+       | Ast.FunDecl(header,lbrace,decls,body,rbrace) ->
+           Ast.FunDecl(rule_elem header,rule_elem lbrace,
+                       statement_dots decls,
+                       statement_dots body, rule_elem rbrace)
+       | Ast.Define(header,body) ->
+           Ast.Define(rule_elem header,statement_dots body)
+       | Ast.Dots(d,whn,bef,aft) ->
+           Ast.Dots(string_mcode d,
+                    List.map (whencode statement_dots statement) whn,bef,aft)
+       | Ast.Circles(d,whn,bef,aft) ->
+           Ast.Circles(string_mcode d,
+                       List.map (whencode statement_dots statement) whn,
+                       bef,aft)
+       | Ast.Stars(d,whn,bef,aft) ->
+           Ast.Stars(string_mcode d,
+                     List.map (whencode statement_dots statement) whn,bef,aft)
+       | Ast.OptStm(stmt) -> Ast.OptStm(statement stmt)
+       | Ast.UniqueStm(stmt) -> Ast.UniqueStm(statement stmt)) in
+    let s = stmtfn all_functions k s in
+    (* better to do this after, in case there is an equality test on the whole
+       statement, eg in free_vars.  equality test would require that this
+       subterm not already be changed *)
+    process_bef_aft s
+
+  and fninfo = function
+      Ast.FStorage(stg) -> Ast.FStorage(storage_mcode stg)
+    | Ast.FType(ty) -> Ast.FType(fullType ty)
+    | Ast.FInline(inline) -> Ast.FInline(string_mcode inline)
+    | Ast.FAttr(attr) -> Ast.FAttr(string_mcode attr)
+
+  and whencode notfn alwaysfn = function
+      Ast.WhenNot a -> Ast.WhenNot (notfn a)
+    | Ast.WhenAlways a -> Ast.WhenAlways (alwaysfn a)
+    | Ast.WhenModifier(x)    -> Ast.WhenModifier(x)
+    | Ast.WhenNotTrue(e) -> Ast.WhenNotTrue(rule_elem e)
+    | Ast.WhenNotFalse(e) -> Ast.WhenNotFalse(rule_elem e)
+
+  and case_line c =
+    let k c =
+      Ast.rewrap c
+       (match Ast.unwrap c with
+         Ast.CaseLine(header,code) ->
+           Ast.CaseLine(rule_elem header,statement_dots code)
+       | Ast.OptCase(case) -> Ast.OptCase(case_line case)) in
+    casefn all_functions k c
+
+  and top_level t =
+    let k t =
+      Ast.rewrap t
+       (match Ast.unwrap t with
+         Ast.FILEINFO(old_file,new_file) ->
+           Ast.FILEINFO (string_mcode old_file, string_mcode new_file)
+       | Ast.DECL(stmt) -> Ast.DECL(statement stmt)
+       | Ast.CODE(stmt_dots) -> Ast.CODE(statement_dots stmt_dots)
+       | Ast.ERRORWORDS(exps) -> Ast.ERRORWORDS (List.map expression exps)) in
+    topfn all_functions k t
+
+  and anything a =
+    let k = function
+       (*in many cases below, the thing is not even mcode, so we do nothing*)
+       Ast.FullTypeTag(ft) -> Ast.FullTypeTag(fullType ft)
+      | Ast.BaseTypeTag(bt) as x -> x
+      | Ast.StructUnionTag(su) as x -> x
+      | Ast.SignTag(sgn) as x -> x
+      | Ast.IdentTag(id) -> Ast.IdentTag(ident id)
+      | Ast.ExpressionTag(exp) -> Ast.ExpressionTag(expression exp)
+      | Ast.ConstantTag(cst) as x -> x
+      | Ast.UnaryOpTag(unop) as x -> x
+      | Ast.AssignOpTag(asgnop) as x -> x
+      | Ast.FixOpTag(fixop) as x -> x
+      | Ast.BinaryOpTag(binop) as x -> x
+      | Ast.ArithOpTag(arithop) as x -> x
+      | Ast.LogicalOpTag(logop) as x -> x
+      | Ast.InitTag(decl) -> Ast.InitTag(initialiser decl)
+      | Ast.DeclarationTag(decl) -> Ast.DeclarationTag(declaration decl)
+      | Ast.StorageTag(stg) as x -> x
+      | Ast.IncFileTag(stg) as x -> x
+      | Ast.Rule_elemTag(rule) -> Ast.Rule_elemTag(rule_elem rule)
+      | Ast.StatementTag(rule) -> Ast.StatementTag(statement rule)
+      | Ast.CaseLineTag(case) -> Ast.CaseLineTag(case_line case)
+      | Ast.ConstVolTag(cv) as x -> x
+      | Ast.Token(tok,info) as x -> x
+      | Ast.Code(cd) -> Ast.Code(top_level cd)
+      | Ast.ExprDotsTag(ed) -> Ast.ExprDotsTag(expression_dots ed)
+      | Ast.ParamDotsTag(pd) -> Ast.ParamDotsTag(parameter_dots pd)
+      | Ast.StmtDotsTag(sd) -> Ast.StmtDotsTag(statement_dots sd)
+      | Ast.DeclDotsTag(sd) -> Ast.DeclDotsTag(declaration_dots sd)
+      | Ast.TypeCTag(ty) -> Ast.TypeCTag(typeC ty)
+      | Ast.ParamTag(param) -> Ast.ParamTag(parameterTypeDef param)
+      | Ast.SgrepStartTag(tok) as x -> x
+      | Ast.SgrepEndTag(tok) as x -> x in
+    anyfn all_functions k a
+
+  and all_functions =
+    {rebuilder_ident = ident;
+      rebuilder_expression = expression;
+      rebuilder_fullType= fullType;
+      rebuilder_typeC = typeC;
+      rebuilder_declaration = declaration;
+      rebuilder_initialiser = initialiser;
+      rebuilder_parameter = parameterTypeDef;
+      rebuilder_parameter_list = parameter_dots;
+      rebuilder_rule_elem = rule_elem;
+      rebuilder_statement = statement;
+      rebuilder_case_line = case_line;
+      rebuilder_top_level = top_level;
+      rebuilder_expression_dots = expression_dots;
+      rebuilder_statement_dots = statement_dots;
+      rebuilder_declaration_dots = declaration_dots;
+      rebuilder_define_param_dots = define_param_dots;
+      rebuilder_define_param = define_param;
+      rebuilder_define_parameters = define_parameters;
+      rebuilder_anything = anything} in
+  all_functions
+
index f39c46e..aa6bc06 100644 (file)
@@ -1,3 +1,4 @@
+adjust_pragmas.cmi: ast0_cocci.cmi 
 arity.cmi: ast0_cocci.cmi 
 ast0_cocci.cmi: type_cocci.cmi ast_cocci.cmi 
 ast0toast.cmi: ast_cocci.cmi ast0_cocci.cmi 
@@ -5,7 +6,7 @@ ast_cocci.cmi: type_cocci.cmi
 check_meta.cmi: ast_cocci.cmi ast0_cocci.cmi 
 comm_assoc.cmi: ast0_cocci.cmi 
 compute_lines.cmi: ast0_cocci.cmi 
-context_neg.cmi: ast0_cocci.cmi 
+context_neg.cmi: ../commons/common.cmi ast0_cocci.cmi 
 data.cmi: type_cocci.cmi ast_cocci.cmi ast0_cocci.cmi 
 disjdistr.cmi: ast_cocci.cmi 
 free_vars.cmi: ast_cocci.cmi 
@@ -18,7 +19,8 @@ iso_compile.cmi: iso_pattern.cmi
 iso_pattern.cmi: visitor_ast0.cmi ast_cocci.cmi ast0_cocci.cmi 
 merge.cmi: ast_cocci.cmi ast0_cocci.cmi 
 parse_cocci.cmi: ast_cocci.cmi 
-parser_cocci_menhir.cmi: parse_aux.cmo data.cmi ast_cocci.cmi ast0_cocci.cmi 
+parser_cocci_menhir.cmi: parse_aux.cmo data.cmi ../commons/common.cmi \
+    ast_cocci.cmi ast0_cocci.cmi 
 plus.cmi: ast_cocci.cmi 
 pretty_print_cocci.cmi: ast_cocci.cmi 
 simple_assignments.cmi: ast0_cocci.cmi 
@@ -31,112 +33,128 @@ unitary_ast0.cmi: ast0_cocci.cmi
 unparse_ast0.cmi: ast0_cocci.cmi 
 visitor_ast.cmi: ast_cocci.cmi 
 visitor_ast0.cmi: ast_cocci.cmi ast0_cocci.cmi 
+adjust_pragmas.cmo: visitor_ast0.cmi ast0_cocci.cmi adjust_pragmas.cmi 
+adjust_pragmas.cmx: visitor_ast0.cmx ast0_cocci.cmx adjust_pragmas.cmi 
 arity.cmo: ast_cocci.cmi ast0_cocci.cmi arity.cmi 
 arity.cmx: ast_cocci.cmx ast0_cocci.cmx arity.cmi 
-ast0_cocci.cmo: type_cocci.cmi ast_cocci.cmi ast0_cocci.cmi 
-ast0_cocci.cmx: type_cocci.cmx ast_cocci.cmx ast0_cocci.cmi 
-ast0toast.cmo: visitor_ast0.cmi visitor_ast.cmi type_cocci.cmi ast_cocci.cmi \
-    ast0_cocci.cmi ast0toast.cmi 
-ast0toast.cmx: visitor_ast0.cmx visitor_ast.cmx type_cocci.cmx ast_cocci.cmx \
-    ast0_cocci.cmx ast0toast.cmi 
-ast_cocci.cmo: type_cocci.cmi ast_cocci.cmi 
-ast_cocci.cmx: type_cocci.cmx ast_cocci.cmi 
-check_meta.cmo: visitor_ast0.cmi type_cocci.cmi ast_cocci.cmi ast0_cocci.cmi \
-    check_meta.cmi 
-check_meta.cmx: visitor_ast0.cmx type_cocci.cmx ast_cocci.cmx ast0_cocci.cmx \
-    check_meta.cmi 
-comm_assoc.cmo: visitor_ast0.cmi unparse_ast0.cmi ast_cocci.cmi \
-    ast0_cocci.cmi comm_assoc.cmi 
-comm_assoc.cmx: visitor_ast0.cmx unparse_ast0.cmx ast_cocci.cmx \
-    ast0_cocci.cmx comm_assoc.cmi 
+ast0_cocci.cmo: type_cocci.cmi ../globals/flag.cmo ast_cocci.cmi \
+    ast0_cocci.cmi 
+ast0_cocci.cmx: type_cocci.cmx ../globals/flag.cmx ast_cocci.cmx \
+    ast0_cocci.cmi 
+ast0toast.cmo: visitor_ast0.cmi visitor_ast.cmi type_cocci.cmi \
+    ../globals/flag.cmo ast_cocci.cmi ast0_cocci.cmi ast0toast.cmi 
+ast0toast.cmx: visitor_ast0.cmx visitor_ast.cmx type_cocci.cmx \
+    ../globals/flag.cmx ast_cocci.cmx ast0_cocci.cmx ast0toast.cmi 
+ast_cocci.cmo: type_cocci.cmi ../commons/common.cmi ast_cocci.cmi 
+ast_cocci.cmx: type_cocci.cmx ../commons/common.cmx ast_cocci.cmi 
+check_meta.cmo: visitor_ast0.cmi type_cocci.cmi ../commons/common.cmi \
+    ast_cocci.cmi ast0_cocci.cmi check_meta.cmi 
+check_meta.cmx: visitor_ast0.cmx type_cocci.cmx ../commons/common.cmx \
+    ast_cocci.cmx ast0_cocci.cmx check_meta.cmi 
+comm_assoc.cmo: visitor_ast0.cmi unparse_ast0.cmi ../globals/flag.cmo \
+    ast_cocci.cmi ast0_cocci.cmi comm_assoc.cmi 
+comm_assoc.cmx: visitor_ast0.cmx unparse_ast0.cmx ../globals/flag.cmx \
+    ast_cocci.cmx ast0_cocci.cmx comm_assoc.cmi 
 compute_lines.cmo: ast_cocci.cmi ast0_cocci.cmi compute_lines.cmi 
 compute_lines.cmx: ast_cocci.cmx ast0_cocci.cmx compute_lines.cmi 
 context_neg.cmo: visitor_ast0.cmi unparse_ast0.cmi index.cmi \
-    compute_lines.cmi ast_cocci.cmi ast0_cocci.cmi context_neg.cmi 
+    ../globals/flag.cmo compute_lines.cmi ../commons/common.cmi ast_cocci.cmi \
+    ast0_cocci.cmi context_neg.cmi 
 context_neg.cmx: visitor_ast0.cmx unparse_ast0.cmx index.cmx \
-    compute_lines.cmx ast_cocci.cmx ast0_cocci.cmx context_neg.cmi 
+    ../globals/flag.cmx compute_lines.cmx ../commons/common.cmx ast_cocci.cmx \
+    ast0_cocci.cmx context_neg.cmi 
 data.cmo: type_cocci.cmi ast_cocci.cmi ast0_cocci.cmi data.cmi 
 data.cmx: type_cocci.cmx ast_cocci.cmx ast0_cocci.cmx data.cmi 
-disjdistr.cmo: visitor_ast.cmi ast_cocci.cmi disjdistr.cmi 
-disjdistr.cmx: visitor_ast.cmx ast_cocci.cmx disjdistr.cmi 
-free_vars.cmo: visitor_ast.cmi type_cocci.cmi ast_cocci.cmi free_vars.cmi 
-free_vars.cmx: visitor_ast.cmx type_cocci.cmx ast_cocci.cmx free_vars.cmi 
+disjdistr.cmo: visitor_ast.cmi ../globals/flag.cmo ../commons/common.cmi \
+    ast_cocci.cmi disjdistr.cmi 
+disjdistr.cmx: visitor_ast.cmx ../globals/flag.cmx ../commons/common.cmx \
+    ast_cocci.cmx disjdistr.cmi 
+free_vars.cmo: visitor_ast.cmi type_cocci.cmi ../commons/common.cmi \
+    ast_cocci.cmi free_vars.cmi 
+free_vars.cmx: visitor_ast.cmx type_cocci.cmx ../commons/common.cmx \
+    ast_cocci.cmx free_vars.cmi 
 function_prototypes.cmo: visitor_ast0.cmi iso_pattern.cmi insert_plus.cmi \
     context_neg.cmi compute_lines.cmi ast_cocci.cmi ast0toast.cmi \
     ast0_cocci.cmi function_prototypes.cmi 
 function_prototypes.cmx: visitor_ast0.cmx iso_pattern.cmx insert_plus.cmx \
     context_neg.cmx compute_lines.cmx ast_cocci.cmx ast0toast.cmx \
     ast0_cocci.cmx function_prototypes.cmi 
-get_constants.cmo: visitor_ast.cmi type_cocci.cmi ast_cocci.cmi \
-    get_constants.cmi 
-get_constants.cmx: visitor_ast.cmx type_cocci.cmx ast_cocci.cmx \
-    get_constants.cmi 
-get_constants2.cmo: visitor_ast.cmi type_cocci.cmi ast_cocci.cmi \
-    get_constants2.cmi 
-get_constants2.cmx: visitor_ast.cmx type_cocci.cmx ast_cocci.cmx \
-    get_constants2.cmi 
+get_constants.cmo: visitor_ast.cmi type_cocci.cmi ../globals/flag.cmo \
+    ../commons/common.cmi ast_cocci.cmi get_constants.cmi 
+get_constants.cmx: visitor_ast.cmx type_cocci.cmx ../globals/flag.cmx \
+    ../commons/common.cmx ast_cocci.cmx get_constants.cmi 
+get_constants2.cmo: visitor_ast.cmi type_cocci.cmi ../globals/flag.cmo \
+    ../commons/common.cmi ast_cocci.cmi get_constants2.cmi 
+get_constants2.cmx: visitor_ast.cmx type_cocci.cmx ../globals/flag.cmx \
+    ../commons/common.cmx ast_cocci.cmx get_constants2.cmi 
 index.cmo: ast_cocci.cmi ast0_cocci.cmi index.cmi 
 index.cmx: ast_cocci.cmx ast0_cocci.cmx index.cmi 
 insert_plus.cmo: visitor_ast0.cmi pretty_print_cocci.cmi context_neg.cmi \
     ast_cocci.cmi ast0toast.cmi ast0_cocci.cmi insert_plus.cmi 
 insert_plus.cmx: visitor_ast0.cmx pretty_print_cocci.cmx context_neg.cmx \
     ast_cocci.cmx ast0toast.cmx ast0_cocci.cmx insert_plus.cmi 
-iso_compile.cmo: visitor_ast0.cmi ast_cocci.cmi ast0_cocci.cmi \
-    iso_compile.cmi 
-iso_compile.cmx: visitor_ast0.cmx ast_cocci.cmx ast0_cocci.cmx \
-    iso_compile.cmi 
+iso_compile.cmo: visitor_ast0.cmi ../commons/common.cmi ast_cocci.cmi \
+    ast0_cocci.cmi iso_compile.cmi 
+iso_compile.cmx: visitor_ast0.cmx ../commons/common.cmx ast_cocci.cmx \
+    ast0_cocci.cmx iso_compile.cmi 
 iso_pattern.cmo: visitor_ast0.cmi unparse_ast0.cmi type_cocci.cmi \
-    flag_parsing_cocci.cmo compute_lines.cmi ast_cocci.cmi ast0_cocci.cmi \
-    iso_pattern.cmi 
+    flag_parsing_cocci.cmo ../globals/flag.cmo \
+    ../commons/ocamlextra/dumper.cmi compute_lines.cmi ../commons/common.cmi \
+    ast_cocci.cmi ast0_cocci.cmi iso_pattern.cmi 
 iso_pattern.cmx: visitor_ast0.cmx unparse_ast0.cmx type_cocci.cmx \
-    flag_parsing_cocci.cmx compute_lines.cmx ast_cocci.cmx ast0_cocci.cmx \
-    iso_pattern.cmi 
-lexer_cocci.cmo: parser_cocci_menhir.cmi parse_aux.cmo data.cmi ast_cocci.cmi \
-    ast0_cocci.cmi 
-lexer_cocci.cmx: parser_cocci_menhir.cmx parse_aux.cmx data.cmx ast_cocci.cmx \
-    ast0_cocci.cmx 
+    flag_parsing_cocci.cmx ../globals/flag.cmx \
+    ../commons/ocamlextra/dumper.cmx compute_lines.cmx ../commons/common.cmx \
+    ast_cocci.cmx ast0_cocci.cmx iso_pattern.cmi 
+lexer_cocci.cmo: parser_cocci_menhir.cmi parse_aux.cmo ../globals/flag.cmo \
+    data.cmi ../commons/common.cmi ast_cocci.cmi ast0_cocci.cmi 
+lexer_cocci.cmx: parser_cocci_menhir.cmx parse_aux.cmx ../globals/flag.cmx \
+    data.cmx ../commons/common.cmx ast_cocci.cmx ast0_cocci.cmx 
 lexer_script.cmo: parser_cocci_menhir.cmi data.cmi ast_cocci.cmi 
 lexer_script.cmx: parser_cocci_menhir.cmx data.cmx ast_cocci.cmx 
 main.cmo: parse_cocci.cmi 
 main.cmx: parse_cocci.cmx 
 merge.cmo: visitor_ast0.cmi ast_cocci.cmi ast0_cocci.cmi merge.cmi 
 merge.cmx: visitor_ast0.cmx ast_cocci.cmx ast0_cocci.cmx merge.cmi 
-parse_aux.cmo: type_cocci.cmi semantic_cocci.cmo data.cmi ast_cocci.cmi \
-    ast0_cocci.cmi 
-parse_aux.cmx: type_cocci.cmx semantic_cocci.cmx data.cmx ast_cocci.cmx \
-    ast0_cocci.cmx 
+parse_aux.cmo: type_cocci.cmi semantic_cocci.cmo ../globals/flag.cmo data.cmi \
+    ../commons/common.cmi ast_cocci.cmi ast0_cocci.cmi 
+parse_aux.cmx: type_cocci.cmx semantic_cocci.cmx ../globals/flag.cmx data.cmx \
+    ../commons/common.cmx ast_cocci.cmx ast0_cocci.cmx 
 parse_cocci.cmo: visitor_ast0.cmi unitary_ast0.cmi type_infer.cmi \
     test_exps.cmi single_statement.cmi simple_assignments.cmi \
     semantic_cocci.cmo pretty_print_cocci.cmi parser_cocci_menhir.cmi \
     parse_aux.cmo lexer_script.cmo lexer_cocci.cmo iso_pattern.cmi \
     iso_compile.cmi insert_plus.cmi get_constants2.cmi get_constants.cmi \
     function_prototypes.cmi free_vars.cmi flag_parsing_cocci.cmo \
-    disjdistr.cmi data.cmi context_neg.cmi compute_lines.cmi comm_assoc.cmi \
-    check_meta.cmi ast_cocci.cmi ast0toast.cmi ast0_cocci.cmi arity.cmi \
-    parse_cocci.cmi 
+    ../globals/flag.cmo disjdistr.cmi data.cmi context_neg.cmi \
+    ../globals/config.cmo compute_lines.cmi ../commons/common.cmi \
+    comm_assoc.cmi check_meta.cmi ast_cocci.cmi ast0toast.cmi ast0_cocci.cmi \
+    arity.cmi adjust_pragmas.cmi parse_cocci.cmi 
 parse_cocci.cmx: visitor_ast0.cmx unitary_ast0.cmx type_infer.cmx \
     test_exps.cmx single_statement.cmx simple_assignments.cmx \
     semantic_cocci.cmx pretty_print_cocci.cmx parser_cocci_menhir.cmx \
     parse_aux.cmx lexer_script.cmx lexer_cocci.cmx iso_pattern.cmx \
     iso_compile.cmx insert_plus.cmx get_constants2.cmx get_constants.cmx \
     function_prototypes.cmx free_vars.cmx flag_parsing_cocci.cmx \
-    disjdistr.cmx data.cmx context_neg.cmx compute_lines.cmx comm_assoc.cmx \
-    check_meta.cmx ast_cocci.cmx ast0toast.cmx ast0_cocci.cmx arity.cmx \
-    parse_cocci.cmi 
+    ../globals/flag.cmx disjdistr.cmx data.cmx context_neg.cmx \
+    ../globals/config.cmx compute_lines.cmx ../commons/common.cmx \
+    comm_assoc.cmx check_meta.cmx ast_cocci.cmx ast0toast.cmx ast0_cocci.cmx \
+    arity.cmx adjust_pragmas.cmx parse_cocci.cmi 
 parser_cocci_menhir.cmo: type_cocci.cmi top_level.cmi semantic_cocci.cmo \
-    parse_aux.cmo data.cmi ast_cocci.cmi ast0_cocci.cmi \
+    parse_aux.cmo data.cmi ../commons/common.cmi ast_cocci.cmi ast0_cocci.cmi \
     parser_cocci_menhir.cmi 
 parser_cocci_menhir.cmx: type_cocci.cmx top_level.cmx semantic_cocci.cmx \
-    parse_aux.cmx data.cmx ast_cocci.cmx ast0_cocci.cmx \
+    parse_aux.cmx data.cmx ../commons/common.cmx ast_cocci.cmx ast0_cocci.cmx \
     parser_cocci_menhir.cmi 
 plus.cmo: visitor_ast.cmi ast_cocci.cmi plus.cmi 
 plus.cmx: visitor_ast.cmx ast_cocci.cmx plus.cmi 
-pretty_print_cocci.cmo: type_cocci.cmi ast_cocci.cmi pretty_print_cocci.cmi 
-pretty_print_cocci.cmx: type_cocci.cmx ast_cocci.cmx pretty_print_cocci.cmi 
-simple_assignments.cmo: visitor_ast0.cmi ast_cocci.cmi ast0_cocci.cmi \
-    simple_assignments.cmi 
-simple_assignments.cmx: visitor_ast0.cmx ast_cocci.cmx ast0_cocci.cmx \
-    simple_assignments.cmi 
+pretty_print_cocci.cmo: type_cocci.cmi ../globals/flag.cmo \
+    ../commons/common.cmi ast_cocci.cmi pretty_print_cocci.cmi 
+pretty_print_cocci.cmx: type_cocci.cmx ../globals/flag.cmx \
+    ../commons/common.cmx ast_cocci.cmx pretty_print_cocci.cmi 
+simple_assignments.cmo: visitor_ast0.cmi ../globals/flag.cmo \
+    ../commons/common.cmi ast_cocci.cmi ast0_cocci.cmi simple_assignments.cmi 
+simple_assignments.cmx: visitor_ast0.cmx ../globals/flag.cmx \
+    ../commons/common.cmx ast_cocci.cmx ast0_cocci.cmx simple_assignments.cmi 
 single_statement.cmo: visitor_ast0.cmi iso_pattern.cmi flag_parsing_cocci.cmo \
     compute_lines.cmi ast_cocci.cmi ast0_cocci.cmi single_statement.cmi 
 single_statement.cmx: visitor_ast0.cmx iso_pattern.cmx flag_parsing_cocci.cmx \
@@ -153,14 +171,14 @@ type_infer.cmx: visitor_ast0.cmx type_cocci.cmx ast_cocci.cmx ast0_cocci.cmx \
     type_infer.cmi 
 unify_ast.cmo: visitor_ast.cmi ast_cocci.cmi unify_ast.cmi 
 unify_ast.cmx: visitor_ast.cmx ast_cocci.cmx unify_ast.cmi 
-unitary_ast0.cmo: visitor_ast0.cmi ast_cocci.cmi ast0_cocci.cmi \
-    unitary_ast0.cmi 
-unitary_ast0.cmx: visitor_ast0.cmx ast_cocci.cmx ast0_cocci.cmx \
-    unitary_ast0.cmi 
-unparse_ast0.cmo: type_cocci.cmi pretty_print_cocci.cmi ast0_cocci.cmi \
-    unparse_ast0.cmi 
-unparse_ast0.cmx: type_cocci.cmx pretty_print_cocci.cmx ast0_cocci.cmx \
-    unparse_ast0.cmi 
+unitary_ast0.cmo: visitor_ast0.cmi ../globals/flag.cmo ast_cocci.cmi \
+    ast0_cocci.cmi unitary_ast0.cmi 
+unitary_ast0.cmx: visitor_ast0.cmx ../globals/flag.cmx ast_cocci.cmx \
+    ast0_cocci.cmx unitary_ast0.cmi 
+unparse_ast0.cmo: type_cocci.cmi pretty_print_cocci.cmi ../commons/common.cmi \
+    ast0_cocci.cmi unparse_ast0.cmi 
+unparse_ast0.cmx: type_cocci.cmx pretty_print_cocci.cmx ../commons/common.cmx \
+    ast0_cocci.cmx unparse_ast0.cmi 
 visitor_ast.cmo: ast_cocci.cmi visitor_ast.cmi 
 visitor_ast.cmx: ast_cocci.cmx visitor_ast.cmi 
 visitor_ast0.cmo: ast_cocci.cmi ast0_cocci.cmi visitor_ast0.cmi 
index f710d1e..b0044d9 100644 (file)
@@ -18,6 +18,8 @@
 # Coccinelle under other licenses.
 
 
+-include ../Makefile.config
+
 TARGET=cocci_parser
 
 LEXER_SOURCES = lexer_cocci.mll
@@ -29,7 +31,7 @@ visitor_ast.ml visitor_ast0.ml compute_lines.ml comm_assoc.ml \
 iso_pattern.ml iso_compile.ml single_statement.ml simple_assignments.ml \
 ast0toast.ml check_meta.ml top_level.ml type_infer.ml test_exps.ml \
 unitary_ast0.ml arity.ml index.ml context_neg.ml \
-insert_plus.ml function_prototypes.ml \
+adjust_pragmas.ml insert_plus.ml function_prototypes.ml \
 unify_ast.ml semantic_cocci.ml data.ml free_vars.ml parse_aux.ml disjdistr.ml \
 $(LEXER_SOURCES:.mll=.ml) $(PARSER_SOURCES:.mly=.ml) \
 $(SCRIPT_LEXER_SOURCES:.mll=.ml) \
@@ -54,7 +56,7 @@ OCAMLC =ocamlc$(OPTBIN) $(OCAMLCFLAGS) $(INCLUDES)
 OCAMLOPT = ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
 OCAMLLEX = ocamllex$(OPTBIN)
 OCAMLYACC= menhir --table
-OCAMLDEP = ocamldep$(OPTBIN) #$(INCLUDES)
+OCAMLDEP = ocamldep$(OPTBIN) $(INCLUDES)
 EXEC=$(TARGET).byte
 EXEC=$(TARGET)
 LIB=$(TARGET).cma
diff --git a/parsing_cocci/adjust_pragmas.ml b/parsing_cocci/adjust_pragmas.ml
new file mode 100644 (file)
index 0000000..d4a9f8c
--- /dev/null
@@ -0,0 +1,303 @@
+(* Find a directive or comment at the end of a statement.  Things with aft
+given None, because they can accomodate their own directives or comments *)
+
+module Ast0 = Ast0_cocci
+module V0 = Visitor_ast0
+
+let call_right processor data s cont =
+  match processor data with
+    None -> None
+  | Some(pragmas,data) -> Some (pragmas,Ast0.rewrap s (cont data))
+
+let left_mcode (a,b,info,mcodekind,d) =
+  match (info.Ast0.strings_before,mcodekind) with
+    ([],_) | (_,Ast0.PLUS) -> None
+  | (l,_) -> Some(l,(a,b,{info with Ast0.strings_before = []},mcodekind,d))
+
+let right_mcode (a,b,info,mcodekind,d) =
+  match (info.Ast0.strings_after,mcodekind) with
+    ([],_) | (_,Ast0.PLUS) -> None
+  | (l,_) -> Some(l,(a,b,{info with Ast0.strings_after = []},mcodekind,d))
+
+let update_before pragmas (info,x) =
+  ({info with Ast0.strings_before = pragmas @ info.Ast0.strings_before},
+   Ast0.PLUS)
+
+let update_after pragmas (info,x) =
+  ({info with Ast0.strings_after = info.Ast0.strings_after @ pragmas},
+   Ast0.PLUS)
+
+let rec right_decl d =
+  match Ast0.unwrap d with
+    Ast0.Init(Some stg,ty,id,eq,ini,sem) ->
+      call_right right_mcode sem d
+       (function sem -> Ast0.Init(Some stg,ty,id,eq,ini,sem))
+  | Ast0.Init(None,ty,id,eq,ini,sem) ->
+      call_right right_mcode sem d
+       (function sem -> Ast0.Init(None,ty,id,eq,ini,sem))
+  | Ast0.UnInit(Some stg,ty,id,sem) ->
+      call_right right_mcode sem d
+       (function sem -> Ast0.UnInit(Some stg,ty,id,sem))
+  | Ast0.UnInit(None,ty,id,sem) ->
+      call_right right_mcode sem d
+       (function sem -> Ast0.UnInit(None,ty,id,sem))
+  | Ast0.MacroDecl(name,lp,args,rp,sem) ->
+      call_right right_mcode sem d
+       (function sem -> Ast0.MacroDecl(name,lp,args,rp,sem))
+  | Ast0.TyDecl(ty,sem) ->
+      call_right right_mcode sem d
+       (function sem -> Ast0.TyDecl(ty,sem))
+  | Ast0.Typedef(stg,ty,id,sem) ->
+      call_right right_mcode sem d
+       (function sem -> Ast0.Typedef(stg,ty,id,sem))
+  | Ast0.DisjDecl(starter,decls,mids,ender) -> None
+  | Ast0.Ddots(dots,whencode) -> None
+  | Ast0.OptDecl(decl) ->
+      call_right right_decl decl d (function decl -> Ast0.OptDecl(decl))
+  | Ast0.UniqueDecl(decl) ->
+      call_right right_decl decl d (function decl -> Ast0.UniqueDecl(decl))
+
+let rec right_statement s =
+  match Ast0.unwrap s with
+    Ast0.FunDecl(bef,fi,name,lp,params,rp,lbrace,body,rbrace) -> None
+  | Ast0.Decl(bef,decl) ->
+      call_right right_decl decl s
+       (function decl -> Ast0.Decl(bef,decl))
+  | Ast0.Seq(lbrace,body,rbrace) ->
+      call_right right_mcode rbrace s
+       (function rbrace -> Ast0.Seq(lbrace,body,rbrace))
+  | Ast0.ExprStatement(exp,sem) ->
+      call_right right_mcode sem s
+       (function sem -> Ast0.ExprStatement(exp,sem))
+  | Ast0.IfThen(iff,lp,exp,rp,branch1,aft) -> None
+  | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,aft) -> None
+  | Ast0.While(whl,lp,exp,rp,body,aft) -> None
+  | Ast0.Do(d,body,whl,lp,exp,rp,sem) ->
+      call_right right_mcode sem s
+       (function sem -> Ast0.Do(d,body,whl,lp,exp,rp,sem))
+  | Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,aft) -> None
+  | Ast0.Iterator(nm,lp,args,rp,body,aft) -> None
+  | Ast0.Switch(switch,lp,exp,rp,lb,cases,rb) ->
+      call_right right_mcode rb s
+       (function rb -> Ast0.Switch(switch,lp,exp,rp,lb,cases,rb))
+  | Ast0.Break(br,sem) ->
+      call_right right_mcode sem s
+       (function sem -> Ast0.Break(br,sem))
+  | Ast0.Continue(cont,sem) ->
+      call_right right_mcode sem s
+       (function sem -> Ast0.Continue(cont,sem))
+  | Ast0.Label(l,dd) ->
+      call_right right_mcode dd s
+       (function dd -> Ast0.Label(l,dd))
+  | Ast0.Goto(goto,l,sem) ->
+      call_right right_mcode sem s
+       (function sem -> Ast0.Goto(goto,l,sem))
+  | Ast0.Return(ret,sem) ->
+      call_right right_mcode sem s
+       (function sem -> Ast0.Return(ret,sem))
+  | Ast0.ReturnExpr(ret,exp,sem) ->
+      call_right right_mcode sem s
+       (function sem -> Ast0.ReturnExpr(ret,exp,sem))
+  | Ast0.MetaStmt(name,pure) ->
+      call_right right_mcode name s
+       (function name -> Ast0.MetaStmt(name,pure))
+  | Ast0.MetaStmtList(name,pure) ->
+      call_right right_mcode name s
+       (function name -> Ast0.MetaStmtList(name,pure))
+  | Ast0.Disj(starter,statement_dots_list,mids,ender) -> None
+  | Ast0.Nest(starter,stmt_dots,ender,whn,multi) -> None
+  (* the following are None, because they can't be adjacent to an aft node *)
+  | Ast0.Exp(exp) -> None
+  | Ast0.TopExp(exp) -> None
+  | Ast0.Ty(ty) -> None
+  | Ast0.TopInit(init) -> None
+  | Ast0.Dots(d,whn) -> None
+  | Ast0.Circles(d,whn) -> None
+  | Ast0.Stars(d,whn) -> None
+  | Ast0.Include(inc,name) ->
+      call_right right_mcode name s
+       (function name -> Ast0.Include(inc,name))
+  | Ast0.Define(def,id,params,body) ->
+      call_right right_statement_dots body s
+       (function body -> Ast0.Define(def,id,params,body))
+  | Ast0.OptStm(re) ->
+      call_right right_statement re s (function re -> Ast0.OptStm(re))
+  | Ast0.UniqueStm(re) ->
+      call_right right_statement re s (function re -> Ast0.UniqueStm(re))
+
+and right_statement_dots sd =
+  match Ast0.unwrap sd with
+    Ast0.DOTS([]) -> failwith "empty statement dots"
+  | Ast0.DOTS(s::r) ->
+      call_right right_statement s sd
+       (function s -> Ast0.DOTS(List.rev(s::r)))
+  | _ -> failwith "circles and stars not supported"
+
+let rec left_ty t =
+  match Ast0.unwrap t with
+    Ast0.ConstVol(cv,ty) ->
+      call_right left_mcode cv t (function cv -> Ast0.ConstVol(cv,ty))
+  | Ast0.BaseType(ty,strings) ->
+      (match strings with
+       [] -> failwith "empty strings in type"
+      |        s::r ->
+         call_right left_mcode s t (function s -> Ast0.BaseType(ty,s::r)))
+  | Ast0.Signed(sign,ty) ->
+      call_right left_mcode sign t (function sign -> Ast0.Signed(sign,ty))
+  | Ast0.Pointer(ty,star) ->
+      call_right left_ty ty t (function ty -> Ast0.Pointer(ty,star))
+  | Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2) ->
+      call_right left_ty ty t
+       (function ty -> Ast0.FunctionPointer(ty,lp1,star,rp1,lp2,params,rp2))
+  | Ast0.FunctionType(Some ty,lp1,params,rp1) ->
+      call_right left_ty ty t
+       (function ty -> Ast0.FunctionType(Some ty,lp1,params,rp1))
+  | Ast0.FunctionType(None,lp1,params,rp1) ->
+      call_right left_mcode lp1 t
+       (function lp1 -> Ast0.FunctionType(None,lp1,params,rp1))
+  | Ast0.Array(ty,lb,size,rb) ->
+      call_right left_ty ty t (function ty -> Ast0.Array(ty,lb,size,rb))
+  | Ast0.EnumName(kind,name) ->
+      call_right left_mcode kind t (function kind -> Ast0.EnumName(kind,name))
+  | Ast0.StructUnionName(kind,name) ->
+      call_right left_mcode kind t
+       (function kind -> Ast0.StructUnionName(kind,name))
+  | Ast0.StructUnionDef(ty,lb,decls,rb) ->
+      call_right left_ty ty t
+       (function ty -> Ast0.StructUnionDef(ty,lb,decls,rb))
+  | Ast0.TypeName(name) ->
+      call_right left_mcode name t (function name -> Ast0.TypeName(name))
+  | Ast0.MetaType(name,x) ->
+      call_right left_mcode name t (function name -> Ast0.MetaType(name,x))
+  | Ast0.DisjType(starter,types,mids,ender) -> None
+  | Ast0.OptType(ty) ->
+      call_right left_ty ty t (function ty -> Ast0.OptType(ty))
+  | Ast0.UniqueType(ty) ->
+      call_right left_ty ty t (function ty -> Ast0.UniqueType(ty))
+
+let rec left_ident i =
+  match Ast0.unwrap i with
+    Ast0.Id(name) ->
+      call_right left_mcode name i
+       (function name -> Ast0.Id(name))
+  | Ast0.MetaId(name,a,b) ->
+      call_right left_mcode name i
+       (function name -> Ast0.MetaId(name,a,b))
+  | Ast0.MetaFunc(name,a,b) ->
+      call_right left_mcode name i
+       (function name -> Ast0.MetaFunc(name,a,b))
+  | Ast0.MetaLocalFunc(name,a,b) ->
+      call_right left_mcode name i
+       (function name -> Ast0.MetaLocalFunc(name,a,b))
+  | Ast0.OptIdent(id) ->
+      call_right left_ident id i (function id -> Ast0.OptIdent(id))
+  | Ast0.UniqueIdent(id) ->
+      call_right left_ident id i (function id -> Ast0.UniqueIdent(id))
+
+let left_fundecl name fninfo =
+  let fncall_right processor data cont =
+    match processor data with
+      None -> None
+    | Some(pragmas,data) -> Some (pragmas,cont data,name) in
+  match fninfo with
+    [] ->
+      (match left_ident name with
+       None -> None
+      |        Some(pragmas,name) -> Some(pragmas,fninfo,name))
+  | (Ast0.FStorage sto)::x ->
+      fncall_right left_mcode sto (function sto -> (Ast0.FStorage sto)::x)
+  | (Ast0.FType ty)::x ->
+      fncall_right left_ty ty (function ty -> (Ast0.FType ty)::x)
+  | (Ast0.FInline inl)::x ->
+      fncall_right left_mcode inl (function inl -> (Ast0.FInline inl)::x)
+  | (Ast0.FAttr atr)::x ->
+      fncall_right left_mcode atr (function atr -> (Ast0.FAttr atr)::x)
+
+let rec left_decl decl =
+  match Ast0.unwrap decl with
+    Ast0.Init(Some stg,ty,id,eq,ini,sem) ->
+      call_right left_mcode stg decl
+       (function stg -> Ast0.Init(Some stg,ty,id,eq,ini,sem))
+  | Ast0.Init(None,ty,id,eq,ini,sem) ->
+      call_right left_ty ty decl
+       (function ty -> Ast0.Init(None,ty,id,eq,ini,sem))
+  | Ast0.UnInit(Some stg,ty,id,sem) ->
+      call_right left_mcode stg decl
+       (function stg -> Ast0.UnInit(Some stg,ty,id,sem))
+  | Ast0.UnInit(None,ty,id,sem) ->
+      call_right left_ty ty decl
+       (function ty -> Ast0.UnInit(None,ty,id,sem))
+  | Ast0.MacroDecl(name,lp,args,rp,sem) ->
+      call_right left_ident name decl
+       (function name -> Ast0.MacroDecl(name,lp,args,rp,sem))
+  | Ast0.TyDecl(ty,sem) ->
+      call_right left_ty ty decl (function ty -> Ast0.TyDecl(ty,sem))
+  | Ast0.Typedef(stg,ty,id,sem) ->
+      call_right left_mcode stg decl
+       (function stg -> Ast0.Typedef(stg,ty,id,sem))
+  | Ast0.DisjDecl(starter,decls,mids,ender) -> None
+  | Ast0.Ddots(dots,whencode) -> None
+  | Ast0.OptDecl(d) ->
+      call_right left_decl d decl (function decl -> Ast0.OptDecl(decl))
+  | Ast0.UniqueDecl(d) ->
+      call_right left_decl d decl (function decl -> Ast0.UniqueDecl(decl))
+
+let process =
+  let donothing r k e = k e in
+  let mcode x = x in
+
+  let statement r k s =
+    let s = k s in
+    Ast0.rewrap s
+      (match Ast0.unwrap s with
+       Ast0.FunDecl(bef,fi,name,lp,params,rp,lbrace,body,rbrace) ->
+         (match left_fundecl name fi with
+           None -> Ast0.unwrap s
+         | Some (pragmas,fi,name) ->
+             Ast0.FunDecl
+               (update_after pragmas bef,
+                fi,name,lp,params,rp,lbrace,body,rbrace))
+      | Ast0.Decl(bef,decl) ->
+         (match left_decl decl with
+           None -> Ast0.unwrap s
+         | Some (pragmas,decl) ->
+             Ast0.Decl(update_after pragmas bef,decl))
+      | Ast0.IfThen(iff,lp,exp,rp,branch1,aft) ->
+         (match right_statement branch1 with
+           None -> Ast0.unwrap s
+         | Some (pragmas,branch1) ->
+             Ast0.IfThen
+               (iff,lp,exp,rp,branch1,update_before pragmas aft))
+      | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,aft) ->
+         (match right_statement branch2 with
+           None -> Ast0.unwrap s
+         | Some (pragmas,branch2) ->
+             Ast0.IfThenElse
+               (iff,lp,exp,rp,branch1,els,branch2,
+                 update_before pragmas aft))
+      | Ast0.While(whl,lp,exp,rp,body,aft) ->
+         (match right_statement body with
+           None -> Ast0.unwrap s
+         | Some (pragmas,body) ->
+             Ast0.While(whl,lp,exp,rp,body,update_before pragmas aft))
+      | Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,aft) ->
+         (match right_statement body with
+           None -> Ast0.unwrap s
+         | Some (pragmas,body) ->
+             Ast0.For
+               (fr,lp,e1,sem1,e2,sem2,e3,rp,body,
+                update_before pragmas aft))
+      | Ast0.Iterator(nm,lp,args,rp,body,aft) ->
+         (match right_statement body with
+           None -> Ast0.unwrap s
+         | Some (pragmas,body) ->
+             Ast0.Iterator(nm,lp,args,rp,body,update_before pragmas aft))
+      | _ -> Ast0.unwrap s) in
+
+  let res = V0.rebuilder
+      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 in
+
+  List.map res.V0.rebuilder_top_level
diff --git a/parsing_cocci/adjust_pragmas.mli b/parsing_cocci/adjust_pragmas.mli
new file mode 100644 (file)
index 0000000..b87cd1a
--- /dev/null
@@ -0,0 +1 @@
+val process : Ast0_cocci.rule -> Ast0_cocci.rule
index 56213c8..65863ec 100644 (file)
@@ -33,7 +33,8 @@ let warning s = Printf.printf "warning: %s\n" s
 
 let fail w str =
   failwith
-    (Printf.sprintf "cocci line %d: %s" ((Ast0.get_info w).Ast0.line_start)
+    (Printf.sprintf "cocci line %d: %s"
+       ((Ast0.get_info w).Ast0.pos_info.Ast0.line_start)
        str)
 
 let make_opt_unique optfn uniquefn info tgt arity term =
@@ -79,7 +80,7 @@ let allopt l fn =
 (* --------------------------------------------------------------------- *)
 (* Mcode *)
 
-let mcode2line (_,_,info,_,_) = info.Ast0.line_start
+let mcode2line (_,_,info,_,_) = info.Ast0.pos_info.Ast0.line_start
 let mcode2arity (_,arity,_,_,_) = arity
 
 let mcode x = x (* nothing to do ... *)
index fe3ba6a..462a24d 100644 (file)
@@ -41,13 +41,16 @@ type mcodekind =
   | 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;
+type position_info = { line_start : int; line_end : int;
+                      logical_start : int; logical_end : int;
+                      column : int; offset : int; }
+
+type info = { pos_info : position_info;
              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 }
+             strings_before : (string * position_info) list;
+             strings_after : (string * position_info) list }
 
 type 'a mcode = 'a * arity * info * mcodekind * meta_pos ref (* pos, - only *)
 (* int ref is an index *)
@@ -426,12 +429,16 @@ let top x = TopTag x
 (* --------------------------------------------------------------------- *)
 (* Avoid cluttering the parser.  Calculated in compute_lines.ml. *)
 
-let default_info _ = (* why is this a function? *)
+let pos_info =
   { line_start = -1; line_end = -1;
     logical_start = -1; logical_end = -1;
+    column = -1; offset = -1; }
+
+let default_info _ = (* why is this a function? *)
+  { pos_info = pos_info;
     attachable_start = true; attachable_end = true;
     mcode_start = []; mcode_end = [];
-    column = -1; offset = -1; strings_before = []; strings_after = [] }
+    strings_before = []; strings_after = [] }
 
 let default_befaft _ =
   MIXED(ref (Ast.NOTHING,default_token_info,default_token_info))
@@ -472,8 +479,8 @@ 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_line x      = x.info.pos_info.line_start
+let get_line_end x  = x.info.pos_info.line_end
 let get_index x     = !(x.index)
 let set_index x i   = x.index := i
 let get_mcodekind x = !(x.mcodekind)
index 2eca940..bd78144 100644 (file)
@@ -16,13 +16,16 @@ type mcodekind =
   | MIXED       of (Ast_cocci.anything Ast_cocci.befaft *
                      token_info * token_info) ref
 
-type info = { line_start : int; line_end : int;
-             logical_start : int; logical_end : int;
+type position_info = { line_start : int; line_end : int;
+                      logical_start : int; logical_end : int;
+                      column : int; offset : int; }
+
+type info = { pos_info : position_info;
              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 }
+             strings_before : (string * position_info) list;
+             strings_after : (string * position_info) list }
 
 type 'a mcode = 'a * arity * info * mcodekind * meta_pos ref (* pos, - only *)
 and 'a wrap =
index 274f7f9..33c0349 100644 (file)
@@ -228,9 +228,14 @@ let get_option fn = function
 (* Mcode *)
 
 let convert_info info =
-  { Ast.line = info.Ast0.line_start; Ast.column = info.Ast0.column;
-    Ast.strbef = info.Ast0.strings_before;
-    Ast.straft = info.Ast0.strings_after; }
+  let strings_to_s l =
+    List.map
+      (function (s,info) -> (s,info.Ast0.line_start,info.Ast0.column))
+      l in
+  { Ast.line = info.Ast0.pos_info.Ast0.line_start;
+    Ast.column = info.Ast0.pos_info.Ast0.column;
+    Ast.strbef = strings_to_s info.Ast0.strings_before;
+    Ast.straft = strings_to_s info.Ast0.strings_after; }
 
 let convert_mcodekind = function
     Ast0.MINUS(replacements) ->
@@ -260,7 +265,7 @@ let wrap ast line isos =
     Ast.iso_info = isos}
 
 let rewrap ast0 isos ast =
-  wrap ast ((Ast0.get_info ast0).Ast0.line_start) isos
+  wrap ast ((Ast0.get_info ast0).Ast0.pos_info.Ast0.line_start) isos
 
 let no_isos = []
 
index ee0a43a..ff69cc6 100644 (file)
@@ -24,7 +24,8 @@
 (* Modified code *)
 
 type info = { line : int; column : int;
-             strbef : string list; straft : string list }
+             strbef : (string * int (* line *) * int (* col *)) list;
+             straft : (string * int (* line *) * int (* col *)) list }
 type line = int
 type meta_name = string * string
 (* need to be careful about rewrapping, to avoid duplicating pos info
@@ -559,6 +560,7 @@ and anything =
   | CaseLineTag         of case_line
   | ConstVolTag         of const_vol
   | Token               of string * info option
+  | Pragma              of string list
   | Code                of top_level
   | ExprDotsTag         of expression dots
   | ParamDotsTag        of parameterTypeDef dots
@@ -642,6 +644,42 @@ let get_meta_name = function
 
 (* --------------------------------------------------------------------- *)
 
+and tag2c = function
+    FullTypeTag _ -> "FullTypeTag"
+  | BaseTypeTag _ -> "BaseTypeTag"
+  | StructUnionTag _ -> "StructUnionTag"
+  | SignTag _ -> "SignTag"
+  | IdentTag _ -> "IdentTag"
+  | ExpressionTag _ -> "ExpressionTag"
+  | ConstantTag _ -> "ConstantTag"
+  | UnaryOpTag _ -> "UnaryOpTag"
+  | AssignOpTag _ -> "AssignOpTag"
+  | FixOpTag _ -> "FixOpTag"
+  | BinaryOpTag _ -> "BinaryOpTag"
+  | ArithOpTag _ -> "ArithOpTag"
+  | LogicalOpTag _ -> "LogicalOpTag"
+  | DeclarationTag _ -> "DeclarationTag"
+  | InitTag _ -> "InitTag"
+  | StorageTag _ -> "StorageTag"
+  | IncFileTag _ -> "IncFileTag"
+  | Rule_elemTag _ -> "Rule_elemTag"
+  | StatementTag _ -> "StatementTag"
+  | CaseLineTag _ -> "CaseLineTag"
+  | ConstVolTag _ -> "ConstVolTag"
+  | Token _ -> "Token"
+  | Pragma _ -> "Pragma"
+  | Code _ -> "Code"
+  | ExprDotsTag _ -> "ExprDotsTag"
+  | ParamDotsTag _ -> "ParamDotsTag"
+  | StmtDotsTag _ -> "StmtDotsTag"
+  | DeclDotsTag _ -> "DeclDotsTag"
+  | TypeCTag _ -> "TypeCTag"
+  | ParamTag _ -> "ParamTag"
+  | SgrepStartTag _ -> "SgrepStartTag"
+  | SgrepEndTag _ -> "SgrepEndTag"
+
+(* --------------------------------------------------------------------- *)
+
 let no_info = { line = 0; column = 0; strbef = []; straft = [] }
 
 let make_term x =
index a207334..cb06c36 100644 (file)
@@ -2,7 +2,8 @@
 (* Modified code *)
 
 type info = { line : int; column : int;
-             strbef : string list; straft : string list }
+             strbef : (string * int (* line *) * int (* col *)) list;
+             straft : (string * int (* line *) * int (* col *)) list }
 type line = int
 type meta_name = string * string
 type 'a wrap =
@@ -522,6 +523,7 @@ and anything =
   | CaseLineTag         of case_line
   | ConstVolTag         of const_vol
   | Token               of string * info option
+  | Pragma              of string list
   | Code                of top_level
   | ExprDotsTag         of expression dots
   | ParamDotsTag        of parameterTypeDef dots
@@ -573,6 +575,8 @@ val drop_pos : 'a mcode -> 'a mcode
 
 val get_meta_name : metavar -> meta_name
 
+val tag2c : anything -> string
+
 val no_info : info
 
 val make_meta_rule_elem :
index ff7d88e..daa2a2e 100644 (file)
@@ -45,7 +45,7 @@ let find_loop table name =
   loop table
 
 let check_table table minus (name,_,info,_,_) =
-  let rl = info.Ast0.line_start in
+  let rl = info.Ast0.pos_info.Ast0.line_start in
   if minus
   then
     (try (find_loop table name) := true
@@ -83,7 +83,7 @@ let is_ifdef name =
 let ident context old_metas table minus i =
   match Ast0.unwrap i with
     Ast0.Id((name,_,info,_,_) : string Ast0.mcode) ->
-      let rl = info.Ast0.line_start in
+      let rl = info.Ast0.pos_info.Ast0.line_start in
       let err =
        if List.exists (function x -> x = name) old_metas
            && (minus || Ast0.get_mcodekind i = Ast0.PLUS)
@@ -166,7 +166,7 @@ let rec expression context old_metas table minus e =
       check_table table minus name;
       check_table table minus lenname
   | Ast0.DisjExpr(_,exps,_,_) ->
-      List.iter (expression ID old_metas table minus) exps
+      List.iter (expression context old_metas table minus) exps
   | Ast0.NestExpr(_,exp_dots,_,w,_) ->
       dots (expression ID old_metas table minus) exp_dots;
       get_opt (expression ID old_metas table minus) w
index d93ed9e..b862e75 100644 (file)
@@ -32,35 +32,39 @@ module Ast = Ast_cocci
 let mkres x e left right =
   let lstart = Ast0.get_info left in
   let lend = Ast0.get_info right in
+  let pos_info =
+    { Ast0.line_start = lstart.Ast0.pos_info.Ast0.line_start;
+      Ast0.line_end = lend.Ast0.pos_info.Ast0.line_end;
+      Ast0.logical_start = lstart.Ast0.pos_info.Ast0.logical_start;
+      Ast0.logical_end = lend.Ast0.pos_info.Ast0.logical_end;
+      Ast0.column = lstart.Ast0.pos_info.Ast0.column;
+      Ast0.offset = lstart.Ast0.pos_info.Ast0.offset; } in
   let info =
-    { Ast0.line_start = lstart.Ast0.line_start;
-      Ast0.line_end = lend.Ast0.line_end;
-      Ast0.logical_start = lstart.Ast0.logical_start;
-      Ast0.logical_end = lend.Ast0.logical_end;
+    { Ast0.pos_info = pos_info;
       Ast0.attachable_start = lstart.Ast0.attachable_start;
       Ast0.attachable_end = lend.Ast0.attachable_end;
       Ast0.mcode_start = lstart.Ast0.mcode_start;
       Ast0.mcode_end = lend.Ast0.mcode_end;
-      Ast0.column = lstart.Ast0.column;
-      Ast0.offset = lstart.Ast0.offset;
       (* only for tokens, not inherited upwards *)
-      Ast0.strings_before = []; Ast0.strings_after = []} in
+      Ast0.strings_before = []; Ast0.strings_after = [] } in
   {x with Ast0.node = e; Ast0.info = info}
 
 let mkmultires x e left right (astart,start_mcodes) (aend,end_mcodes) =
   let lstart = Ast0.get_info left in
   let lend = Ast0.get_info right in
+  let pos_info =
+    { Ast0.line_start = lstart.Ast0.pos_info.Ast0.line_start;
+      Ast0.line_end = lend.Ast0.pos_info.Ast0.line_end;
+      Ast0.logical_start = lstart.Ast0.pos_info.Ast0.logical_start;
+      Ast0.logical_end = lend.Ast0.pos_info.Ast0.logical_end;
+      Ast0.column = lstart.Ast0.pos_info.Ast0.column;
+      Ast0.offset = lstart.Ast0.pos_info.Ast0.offset; } in
   let info =
-    { Ast0.line_start = lstart.Ast0.line_start;
-      Ast0.line_end = lend.Ast0.line_end;
-      Ast0.logical_start = lstart.Ast0.logical_start;
-      Ast0.logical_end = lend.Ast0.logical_end;
+    { Ast0.pos_info = pos_info;
       Ast0.attachable_start = astart;
       Ast0.attachable_end = aend;
       Ast0.mcode_start = start_mcodes;
       Ast0.mcode_end = end_mcodes;
-      Ast0.column = lstart.Ast0.column;
-      Ast0.offset = lstart.Ast0.offset;
       (* only for tokens, not inherited upwards *)
       Ast0.strings_before = []; Ast0.strings_after = [] } in
   {x with Ast0.node = e; Ast0.info = info}
@@ -82,31 +86,40 @@ let promote_mcode (_,_,info,mcodekind,_) =
   {(Ast0.wrap ()) with Ast0.info = new_info; Ast0.mcodekind = ref mcodekind}
 
 let promote_mcode_plus_one (_,_,info,mcodekind,_) =
+  let new_pos_info = 
+    {info.Ast0.pos_info with
+      Ast0.line_start = info.Ast0.pos_info.Ast0.line_start + 1;
+      Ast0.logical_start = info.Ast0.pos_info.Ast0.logical_start + 1;
+      Ast0.line_end = info.Ast0.pos_info.Ast0.line_end + 1;
+      Ast0.logical_end = info.Ast0.pos_info.Ast0.logical_end + 1; } in
   let new_info =
     {info with
-      Ast0.line_start = info.Ast0.line_start + 1;
-      Ast0.logical_start = info.Ast0.logical_start + 1;
-      Ast0.line_end = info.Ast0.line_end + 1;
-      Ast0.logical_end = info.Ast0.logical_end + 1;
+      Ast0.pos_info = new_pos_info;
       Ast0.mcode_start = [mcodekind]; Ast0.mcode_end = [mcodekind]} in
   {(Ast0.wrap ()) with Ast0.info = new_info; Ast0.mcodekind = ref mcodekind}
 
 let promote_to_statement stm mcodekind =
   let info = Ast0.get_info stm in
+  let new_pos_info =
+    {info.Ast0.pos_info with
+      Ast0.logical_start = info.Ast0.pos_info.Ast0.logical_end;
+      Ast0.line_start = info.Ast0.pos_info.Ast0.line_end; } in
   let new_info =
     {info with
-      Ast0.logical_start = info.Ast0.logical_end;
-      Ast0.line_start = info.Ast0.line_end;
+      Ast0.pos_info = new_pos_info;
       Ast0.mcode_start = [mcodekind]; Ast0.mcode_end = [mcodekind];
       Ast0.attachable_start = true; Ast0.attachable_end = true} in
   {(Ast0.wrap ()) with Ast0.info = new_info; Ast0.mcodekind = ref mcodekind}
 
 let promote_to_statement_start stm mcodekind =
   let info = Ast0.get_info stm in
+  let new_pos_info =
+    {info.Ast0.pos_info with
+      Ast0.logical_end = info.Ast0.pos_info.Ast0.logical_start;
+      Ast0.line_end = info.Ast0.pos_info.Ast0.line_start; } in
   let new_info =
     {info with
-      Ast0.logical_end = info.Ast0.logical_start;
-      Ast0.line_end = info.Ast0.line_start;
+      Ast0.pos_info = new_pos_info;
       Ast0.mcode_start = [mcodekind]; Ast0.mcode_end = [mcodekind];
       Ast0.attachable_start = true; Ast0.attachable_end = true} in
   {(Ast0.wrap ()) with Ast0.info = new_info; Ast0.mcodekind = ref mcodekind}
index 67b3317..9341b33 100644 (file)
@@ -140,7 +140,7 @@ let collect_plus_lines top =
   let donothing r k e = k e in
   let mcode (_,_,info,mcodekind,_) =
     match mcodekind with
-      Ast0.PLUS -> insert info.Ast0.line_start
+      Ast0.PLUS -> insert info.Ast0.pos_info.Ast0.line_start
     | _ -> () in
   let fn =
     V0.combiner bind option_default
@@ -228,7 +228,7 @@ let option_default = (*Bind(Neutral,[],[],[],[],[])*)
   Recursor(Neutral,[],[],[])
 
 let mcode (_,_,info,mcodekind,pos) =
-  let offset = info.Ast0.offset in
+  let offset = info.Ast0.pos_info.Ast0.offset in
   match mcodekind with
     Ast0.MINUS(_) -> Token(AllMarked,offset,mcodekind,[])
   | Ast0.PLUS -> Token(AllMarked,offset,mcodekind,[])
@@ -236,13 +236,23 @@ let mcode (_,_,info,mcodekind,pos) =
   | _ -> failwith "not possible"
 
 let neutral_mcode (_,_,info,mcodekind,pos) =
-  let offset = info.Ast0.offset in
+  let offset = info.Ast0.pos_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"
 
+(* neutral for context; used for mcode in bef aft nodes that don't represent
+anything if they don't contain some information *)
+let nc_mcode (_,_,info,mcodekind,pos) =
+  let offset = info.Ast0.pos_info.Ast0.offset in
+  match mcodekind with
+    Ast0.MINUS(_) -> Token(AllMarked,offset,mcodekind,[])
+  | Ast0.PLUS -> Token(AllMarked,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
@@ -263,7 +273,7 @@ let classify is_minus all_marked table code =
            let _ = Hashtbl.find table index in
            failwith
              (Printf.sprintf "line %d: index %s already used\n"
-                (Ast0.get_info e).Ast0.line_start
+                (Ast0.get_info e).Ast0.pos_info.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);
@@ -389,18 +399,16 @@ let classify is_minus all_marked table code =
       | 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)
+         bind (nc_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))
-*)
+      | Ast0.While(_,_,_,_,_,(info,aft))
+      | Ast0.For(_,_,_,_,_,_,_,_,_,(info,aft)) ->
+         bind (k s) (nc_mcode ((),(),info,aft,()))
       |        _ -> k s
 
 ) in
@@ -424,7 +432,7 @@ 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
+  info1.Ast0.pos_info.Ast0.offset = info2.Ast0.pos_info.Ast0.offset
 
 let equal_option e1 e2 =
   match (e1,e2) with
@@ -840,12 +848,12 @@ let concat = function
 
 let collect_up_to m plus =
   let minfo = Ast0.get_info m in
-  let mend = minfo.Ast0.logical_end in
+  let mend = minfo.Ast0.pos_info.Ast0.logical_end in
   let rec loop = function
       [] -> ([],[])
     | p::plus ->
        let pinfo = Ast0.get_info p in
-       let pstart = pinfo.Ast0.logical_start in
+       let pstart = pinfo.Ast0.pos_info.Ast0.logical_start in
        if pstart > mend
        then ([],p::plus)
        else let (plus,rest) = loop plus in (p::plus,rest) in
@@ -980,10 +988,10 @@ let context_neg minus plus =
     | (((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
+       let mstart = minfo.Ast0.pos_info.Ast0.logical_start in
+       let mend = minfo.Ast0.pos_info.Ast0.logical_end in
+       let pstart = pinfo.Ast0.pos_info.Ast0.logical_start in
+       let pend = pinfo.Ast0.pos_info.Ast0.logical_end in
        if (iscode m or iscode p) &&
          (mend + 1 = pstart or pend + 1 = mstart or (* adjacent *)
           (mstart <= pstart && mend >= pstart) or
index f6fe909..1a208c9 100644 (file)
@@ -30,7 +30,8 @@ type fresh = bool
 
 type clt =
     line_type * int * int * int * int (* starting spaces *) *
-      string list (* code before *) * string list (* code after *) *
+      (string * Ast0.position_info) list (* code before *) *
+      (string * Ast0.position_info) list (* code after *) *
       Ast0.meta_pos (* position variable, minus only *)
 
 (* ---------------------------------------------------------------------- *)
index 65c15d9..6dcb387 100644 (file)
@@ -5,7 +5,8 @@ type fresh = bool
 
 type clt =
     line_type * int * int * int * int (* starting spaces *) *
-      string list (* code before *) * string list (* code after *) *
+      (string * Ast0_cocci.position_info) list (* code before *) *
+      (string * Ast0_cocci.position_info) list (* code after *) *
       Ast0_cocci.meta_pos (* position variable, minus only *)
 
 (* ---------------------------------------------------------------------- *)
index a28bb8d..47bfe8e 100644 (file)
@@ -33,42 +33,42 @@ module Ast0 = Ast0_cocci
 address.  Otherwise add 0.  An empty dot list should only match with another
 empty one. *)
 let expression_dots d =
-  let ln = (Ast0.get_info d).Ast0.line_start in
+  let ln = (Ast0.get_info d).Ast0.pos_info.Ast0.line_start in
   match Ast0.unwrap d with
     Ast0.DOTS(l) -> 1::(if l = [] then [ln] else [0])
   | Ast0.CIRCLES(l) -> 2::(if l = [] then [ln] else [0])
   | Ast0.STARS(l) -> 3::(if l = [] then [ln] else [0])
 
 let initialiser_dots d =
-  let ln = (Ast0.get_info d).Ast0.line_start in
+  let ln = (Ast0.get_info d).Ast0.pos_info.Ast0.line_start in
   match Ast0.unwrap d with
     Ast0.DOTS(l) -> 113::(if l = [] then [ln] else [0])
   | Ast0.CIRCLES(l) -> 114::(if l = [] then [ln] else [0])
   | Ast0.STARS(l) -> 115::(if l = [] then [ln] else [0])
 
 let parameter_dots d =
-  let ln = (Ast0.get_info d).Ast0.line_start in
+  let ln = (Ast0.get_info d).Ast0.pos_info.Ast0.line_start in
   match Ast0.unwrap d with
     Ast0.DOTS(l) -> 4::(if l = [] then [ln] else [0])
   | Ast0.CIRCLES(l) -> 5::(if l = [] then [ln] else [0])
   | Ast0.STARS(l) -> 6::(if l = [] then [ln] else [0])
 
 let statement_dots d =
-  let ln = (Ast0.get_info d).Ast0.line_start in
+  let ln = (Ast0.get_info d).Ast0.pos_info.Ast0.line_start in
   match Ast0.unwrap d with
     Ast0.DOTS(l) -> 7::(if l = [] then [ln] else [0])
   | Ast0.CIRCLES(l) -> 8::(if l = [] then [ln] else [0])
   | Ast0.STARS(l) -> 9::(if l = [] then [ln] else [0])
 
 let declaration_dots d =
-  let ln = (Ast0.get_info d).Ast0.line_start in
+  let ln = (Ast0.get_info d).Ast0.pos_info.Ast0.line_start in
   match Ast0.unwrap d with
     Ast0.DOTS(l) -> 134::(if l = [] then [ln] else [0])
   | Ast0.CIRCLES(l) -> 135::(if l = [] then [ln] else [0])
   | Ast0.STARS(l) -> 136::(if l = [] then [ln] else [0])
 
 let case_line_dots d =
-  let ln = (Ast0.get_info d).Ast0.line_start in
+  let ln = (Ast0.get_info d).Ast0.pos_info.Ast0.line_start in
   match Ast0.unwrap d with
     Ast0.DOTS(l) -> 138::(if l = [] then [ln] else [0])
   | Ast0.CIRCLES(l) -> 139::(if l = [] then [ln] else [0])
index 706f922..ff3c59a 100644 (file)
@@ -158,7 +158,7 @@ let collect_minus_join_points root =
   let option_default = [] in
 
   let mcode (_,_,info,mcodekind,_) =
-    if List.mem (info.Ast0.offset) unfavored_tokens
+    if List.mem (info.Ast0.pos_info.Ast0.offset) unfavored_tokens
     then [(Unfavored,info,mcodekind)]
     else [(Favored,info,mcodekind)] in
 
@@ -372,10 +372,10 @@ let verify l =
   let get_info = function
       (Favored,info,_) | (Unfavored,info,_) | (Toplevel,info,_)
     | (Decl,info,_) -> info in
-  let token_start_line      x = (get_info x).Ast0.logical_start in
-  let token_end_line        x = (get_info x).Ast0.logical_end in
-  let token_real_start_line x = (get_info x).Ast0.line_start in
-  let token_real_end_line   x = (get_info x).Ast0.line_end in
+  let token_start_line    x = (get_info x).Ast0.pos_info.Ast0.logical_start in
+  let token_end_line        x = (get_info x).Ast0.pos_info.Ast0.logical_end in
+  let token_real_start_line x = (get_info x).Ast0.pos_info.Ast0.line_start in
+  let token_real_end_line   x = (get_info x).Ast0.pos_info.Ast0.line_end in
   List.iter
     (function
        (index,((_::_) as l1)) ->
@@ -448,14 +448,42 @@ let collect_plus_nodes root =
   let bind x y = x @ y in
   let option_default = [] in
 
+  let extract_strings info =
+    let adjust_info =
+      {info with Ast0.strings_before = [];  Ast0.strings_after = []} in
+    let extract = function
+       [] -> []
+      |        strings_before ->
+         let (_,first) = List.hd strings_before in
+         let (_,last) = List.hd (List.rev strings_before) in
+         let new_pos_info =
+           {Ast0.line_start = first.Ast0.line_start;
+             Ast0.line_end = last.Ast0.line_start;
+             Ast0.logical_start = first.Ast0.logical_start;
+             Ast0.logical_end = last.Ast0.logical_start;
+             Ast0.column = first.Ast0.column;
+             Ast0.offset = first.Ast0.offset} in
+         let new_info = {adjust_info with Ast0.pos_info = new_pos_info} in
+         let string = List.map (function (s,_) -> s) strings_before in
+         [(new_info, Ast.Pragma (string))] in
+    let bef = extract info.Ast0.strings_before in
+    let aft = extract info.Ast0.strings_after in
+    (bef,aft) in
+
   let mcode fn (term,_,info,mcodekind,_) =
-    match mcodekind with Ast0.PLUS -> [(info,fn term)] | _ -> [] in
+    match mcodekind with
+      Ast0.PLUS -> [(info,fn term)]
+    | Ast0.CONTEXT _ -> let (bef,aft) = extract_strings info in bef@aft
+    | _ -> [] in
 
   let imcode fn (term,_,info,mcodekind,_) =
     match mcodekind with
       Ast0.PLUS -> [(info,fn term (Ast0toast.convert_info info))]
+    | Ast0.CONTEXT _ -> let (bef,aft) = extract_strings info in bef@aft
     | _ -> [] in
 
+  let info (i,_) = let (bef,aft) = extract_strings i in bef@aft in
+
   let do_nothing fn r k e =
     match Ast0.get_mcodekind e with
       (Ast0.CONTEXT(_)) when not(Ast0.get_index e = root_index) -> []
@@ -463,13 +491,27 @@ let collect_plus_nodes root =
     | _ -> k e in
 
   (* case for everything that is just a wrapper for a simpler thing *)
+  (* case for things with bef aft *)
   let stmt r k e =
     match Ast0.unwrap e with
       Ast0.Exp(exp) -> r.V0.combiner_expression exp
     | Ast0.TopExp(exp) -> r.V0.combiner_expression exp
     | Ast0.Ty(ty) -> r.V0.combiner_typeC ty
     | Ast0.TopInit(init) -> r.V0.combiner_initialiser init
-    | Ast0.Decl(_,decl) -> r.V0.combiner_declaration decl
+    | Ast0.Decl(bef,decl) ->
+       (info bef) @ (do_nothing mk_statement r k e)
+    | Ast0.FunDecl(bef,fi,name,lp,params,rp,lbrace,body,rbrace) ->
+       (info bef) @ (do_nothing mk_statement r k e)
+    | Ast0.IfThen(iff,lp,exp,rp,branch1,aft) ->
+       (do_nothing mk_statement r k e) @ (info aft)
+    | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,aft) ->
+       (do_nothing mk_statement r k e) @ (info aft)
+    | Ast0.While(whl,lp,exp,rp,body,aft) ->
+       (do_nothing mk_statement r k e) @ (info aft)
+    | Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,aft) ->
+       (do_nothing mk_statement r k e) @ (info aft)
+    | Ast0.Iterator(nm,lp,args,rp,body,aft) ->
+       (do_nothing mk_statement r k e) @ (info aft)
     | _ -> do_nothing mk_statement r k e in
 
   (* statementTag is preferred, because it indicates that one statement is
@@ -569,11 +611,15 @@ line of n is one less than the starting line of n+1.
 Outer list: For any pair of successive elements, n and n+1, the ending
 line of n is more than one less than the starting line of n+1. *)
 
-let logstart info = info.Ast0.logical_start
-let logend info = info.Ast0.logical_end
+let logstart info = info.Ast0.pos_info.Ast0.logical_start
+let logend info = info.Ast0.pos_info.Ast0.logical_end
 
 let redo info start finish =
-  {{info with Ast0.logical_start = start} with Ast0.logical_end = finish}
+  let new_pos_info =
+    {info.Ast0.pos_info with
+      Ast0.logical_start = start;
+      Ast0.logical_end = finish} in
+  {info with Ast0.pos_info = new_pos_info}
 
 let rec find_neighbors (index,l) :
     int * (Ast0.info * (Ast.anything list list)) list =
@@ -632,11 +678,11 @@ let merge_one = function
 
 (* end of first argument < start/end of second argument *)
 let less_than_start info1 info2 =
-  info1.Ast0.logical_end < info2.Ast0.logical_start
+  info1.Ast0.pos_info.Ast0.logical_end < info2.Ast0.pos_info.Ast0.logical_start
 let less_than_end info1 info2 =
-  info1.Ast0.logical_end < info2.Ast0.logical_end
+  info1.Ast0.pos_info.Ast0.logical_end < info2.Ast0.pos_info.Ast0.logical_end
 let greater_than_end info1 info2 =
-  info1.Ast0.logical_start > info2.Ast0.logical_end
+  info1.Ast0.pos_info.Ast0.logical_start > info2.Ast0.pos_info.Ast0.logical_end
 let good_start info = info.Ast0.attachable_start
 let good_end info = info.Ast0.attachable_end
 
@@ -659,7 +705,8 @@ let predecl_code =
     | Ast.StatementTag _
     | Ast.Rule_elemTag _
     | Ast.StmtDotsTag _
-    | Ast.Code _ -> true
+    | Ast.Code _
+    | Ast.Pragma _ -> true
       (* the following should definitely be false *)
     | Ast.FullTypeTag _ | Ast.BaseTypeTag _ | Ast.StructUnionTag _
     | Ast.SignTag _
@@ -673,9 +720,9 @@ let pr = Printf.sprintf
 let insert thing thinginfo into intoinfo =
   let get_last l = let l = List.rev l in (List.rev(List.tl l),List.hd l) in
   let get_first l = (List.hd l,List.tl l) in
-  let thing_start = thinginfo.Ast0.logical_start in
-  let thing_end = thinginfo.Ast0.logical_end in
-  let thing_offset = thinginfo.Ast0.offset in
+  let thing_start = thinginfo.Ast0.pos_info.Ast0.logical_start in
+  let thing_end = thinginfo.Ast0.pos_info.Ast0.logical_end in
+  let thing_offset = thinginfo.Ast0.pos_info.Ast0.offset in
   let into_start = intoinfo.Ast0.tline_start in
   let into_end = intoinfo.Ast0.tline_end in
   let into_left_offset = intoinfo.Ast0.left_offset in
@@ -715,10 +762,10 @@ let insert thing thinginfo into intoinfo =
 
 let init thing info =
   (thing,
-   {Ast0.tline_start = info.Ast0.logical_start;
-     Ast0.tline_end = info.Ast0.logical_end;
-     Ast0.left_offset = info.Ast0.offset;
-     Ast0.right_offset = info.Ast0.offset})
+   {Ast0.tline_start = info.Ast0.pos_info.Ast0.logical_start;
+     Ast0.tline_end = info.Ast0.pos_info.Ast0.logical_end;
+     Ast0.left_offset = info.Ast0.pos_info.Ast0.offset;
+     Ast0.right_offset = info.Ast0.pos_info.Ast0.offset})
 
 let attachbefore (infop,p) = function
     Ast0.MINUS(replacements) ->
@@ -771,9 +818,9 @@ let attach_all_after ps m =
   List.iter (function x -> attachafter x m) ps
 
 let split_at_end info ps =
-  let split_point =  info.Ast0.logical_end in
+  let split_point =  info.Ast0.pos_info.Ast0.logical_end in
   List.partition
-    (function (info,_) -> info.Ast0.logical_end < split_point)
+    (function (info,_) -> info.Ast0.pos_info.Ast0.logical_end < split_point)
     ps
 
 let allminus = function
@@ -790,7 +837,8 @@ let rec before_m1 ((f1,infom1,m1) as x1) ((f2,infom2,m2) as x2) rest = function
        then (attachbefore p m1; before_m1 x1 x2 rest ps)
        else
          failwith
-           (pr "%d: no available token to attach to" infop.Ast0.line_start)
+           (pr "%d: no available token to attach to"
+              infop.Ast0.pos_info.Ast0.line_start)
       else after_m1 x1 x2 rest all
 
 and after_m1 ((f1,infom1,m1) as x1) ((f2,infom2,m2) as x2) rest = function
@@ -826,14 +874,18 @@ and after_m1 ((f1,infom1,m1) as x1) ((f2,infom2,m2) as x2) rest = function
          then before_m2 x2 rest all
          else
            failwith
-             (pr "%d: no available token to attach to" infop.Ast0.line_start)
+             (pr "%d: no available token to attach to"
+                infop.Ast0.pos_info.Ast0.line_start)
        else after_m2 x2 rest all
       else
        begin
          Printf.printf "between: p start %d p end %d m1 start %d m1 end %d m2 start %d m2 end %d\n"
-           infop.Ast0.line_start infop.Ast0.line_end
-           infom1.Ast0.line_start infom1.Ast0.line_end
-           infom2.Ast0.line_start infom2.Ast0.line_end;
+           infop.Ast0.pos_info.Ast0.line_start
+           infop.Ast0.pos_info.Ast0.line_end
+           infom1.Ast0.pos_info.Ast0.line_start
+           infom1.Ast0.pos_info.Ast0.line_end
+           infom2.Ast0.pos_info.Ast0.line_start
+           infom2.Ast0.pos_info.Ast0.line_end;
          Pretty_print_cocci.print_anything "" pcode;
          failwith
            "The semantic patch is structured in a way that may give bad results with isomorphisms.  Please try to rewrite it by moving + code out from -/context terms."
@@ -855,7 +907,8 @@ and before_m2 ((f2,infom2,m2) as x2) rest
       then (attach_all_before bef_m2 m2; after_m2 x2 rest aft_m2)
       else
        failwith
-         (pr "%d: no available token to attach to" infop.Ast0.line_start)
+         (pr "%d: no available token to attach to"
+            infop.Ast0.pos_info.Ast0.line_start)
   | (m::ms,_) -> before_m1 x2 m ms p
 
 and after_m2 ((f2,infom2,m2) as x2) rest
@@ -867,7 +920,8 @@ and after_m2 ((f2,infom2,m2) as x2) rest
       then attach_all_after p m2
       else
        failwith
-         (pr "%d: no available token to attach to" infop.Ast0.line_start)
+         (pr "%d: no available token to attach to"
+            infop.Ast0.pos_info.Ast0.line_start)
   | (m::ms,_) -> after_m1 x2 m ms p
 
 let merge_one : (minus_join_point * Ast0.info * 'a) list *
@@ -877,15 +931,19 @@ let merge_one : (minus_join_point * Ast0.info * 'a) list *
   List.iter
     (function (_,info,_) ->
       Printf.printf "start %d end %d real_start %d real_end %d\n"
-       info.Ast0.logical_start info.Ast0.logical_end
-       info.Ast0.line_start info.Ast0.line_end)
+       info.Ast0.pos_info.Ast0.logical_start
+       info.Ast0.pos_info.Ast0.logical_end
+       info.Ast0.pos_info.Ast0.line_start
+       info.Ast0.pos_info.Ast0.line_end)
     m;
   Printf.printf "plus code\n";
   List.iter
     (function (info,p) ->
       Printf.printf "start %d end %d real_start %d real_end %d\n"
-       info.Ast0.logical_start info.Ast0.logical_end
-       info.Ast0.line_end info.Ast0.line_end;
+       info.Ast0.pos_info.Ast0.logical_start
+       info.Ast0.pos_info.Ast0.logical_end
+       info.Ast0.pos_info.Ast0.line_end
+       info.Ast0.pos_info.Ast0.line_end;
       Pretty_print_cocci.print_anything "" p;
       Format.print_newline())
     p;
@@ -925,6 +983,11 @@ let reevaluate_contextness =
        Ast0.CONTEXT(mc) -> let (ba,_,_) = !mc in [ba]
      | _ -> [] in
 
+   let info (_,mc) =
+     match mc with
+       Ast0.CONTEXT(mc) -> let (ba,_,_) = !mc in [ba]
+     | _ -> [] in
+
    let donothing r k e =
      match Ast0.get_mcodekind e with
        Ast0.CONTEXT(mc) ->
@@ -933,12 +996,31 @@ let reevaluate_contextness =
         []
      | _ -> let _ = k e in [] in
 
+   (* a case for everything with bef or aft *)
+   let stmt r k e =
+     match Ast0.unwrap e with
+       Ast0.Decl(bef,decl) ->
+        (info bef) @ (donothing r k e)
+     | Ast0.FunDecl(bef,fi,name,lp,params,rp,lbrace,body,rbrace) ->
+        (info bef) @ (donothing r k e)
+     | Ast0.IfThen(iff,lp,exp,rp,branch1,aft) ->
+        (donothing r k e) @ (info aft)
+     | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,aft) ->
+        (donothing r k e) @ (info aft)
+     | Ast0.While(whl,lp,exp,rp,body,aft) ->
+        (donothing r k e) @ (info aft)
+     | Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,aft) ->
+        (donothing r k e) @ (info aft)
+     | Ast0.Iterator(nm,lp,args,rp,body,aft) ->
+        (donothing r k e) @ (info aft)
+     | _ -> donothing r k e in
+
   let res =
     V0.combiner bind option_default
       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
+      donothing donothing donothing donothing stmt donothing donothing in
   res.V0.combiner_top_level
 
 (* --------------------------------------------------------------------- *)
index 2a3bb2e..f4036ee 100644 (file)
@@ -108,7 +108,8 @@ let anything_equal = function
   | _ -> false
 
 let term (var1,_,_,_,_) = var1
-let dot_term (var1,_,info,_,_) = ("", var1 ^ (string_of_int info.Ast0.offset))
+let dot_term (var1,_,info,_,_) =
+  ("", var1 ^ (string_of_int info.Ast0.pos_info.Ast0.offset))
 
 
 type reason =
@@ -1300,7 +1301,7 @@ let make_minus =
            failwith
              (Printf.sprintf
                 "%d: make_minus donothingxxx: unexpected mcodekind: %s"
-                info.Ast0.line_start (Dumper.dump e)))
+                info.Ast0.pos_info.Ast0.line_start (Dumper.dump e)))
     | _ -> donothing r k e in
 
   V0.rebuilder
@@ -1331,7 +1332,12 @@ let rebuild_mcode start_line =
   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}
+       Some x ->
+         let new_pos_info =
+           {info.Ast0.pos_info with
+             Ast0.line_start = x;
+             Ast0.line_end = x; } in
+         {info with Ast0.pos_info = new_pos_info}
       |        None -> info in
     (term,arity,info,copy_mcodekind mcodekind,pos) in
 
@@ -1339,7 +1345,12 @@ let rebuild_mcode start_line =
     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}
+       Some x ->
+         let new_pos_info =
+           {old_info.Ast0.pos_info with
+             Ast0.line_start = x;
+             Ast0.line_end = x; } in
+         {old_info with Ast0.pos_info = new_pos_info}
       |        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
@@ -2052,10 +2063,12 @@ let mkdisj matcher metavars alts e instantiater mkiso disj_maker minusify
 (* 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 new_pos_info =
+    { old_info.Ast0.pos_info with
+      Ast0.line_end = old_info.Ast0.pos_info.Ast0.line_start;
+      Ast0.logical_end = old_info.Ast0.pos_info.Ast0.logical_start; } in
   let info =
-    { old_info with
-      Ast0.line_end = old_info.Ast0.line_start;
-      Ast0.logical_end = old_info.Ast0.logical_start;
+    { Ast0.pos_info = new_pos_info;
       Ast0.attachable_start = false; Ast0.attachable_end = false;
       Ast0.mcode_start = []; Ast0.mcode_end = [];
       Ast0.strings_before = []; Ast0.strings_after = [] } in
@@ -2063,10 +2076,12 @@ let disj_starter lst =
 
 let disj_ender lst =
   let old_info = Ast0.get_info(List.hd lst) in
+  let new_pos_info =
+    { old_info.Ast0.pos_info with
+      Ast0.line_start = old_info.Ast0.pos_info.Ast0.line_end;
+      Ast0.logical_start = old_info.Ast0.pos_info.Ast0.logical_end; } in
   let info =
-    { old_info with
-      Ast0.line_start = old_info.Ast0.line_end;
-      Ast0.logical_start = old_info.Ast0.logical_end;
+    { Ast0.pos_info = new_pos_info;
       Ast0.attachable_start = false; Ast0.attachable_end = false;
       Ast0.mcode_start = []; Ast0.mcode_end = [];
       Ast0.strings_before = []; Ast0.strings_after = [] } in
@@ -2117,7 +2132,8 @@ 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 start_line =
+       Some ((Ast0.get_info e).Ast0.pos_info.Ast0.line_start) in
       let alts =
        List.map
          (List.map
@@ -2141,7 +2157,8 @@ let transform_type (metavars,alts,name) 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 start_line =
+      Some ((Ast0.get_info e).Ast0.pos_info.Ast0.line_start) in
     let alts =
       List.map
        (List.map
@@ -2171,7 +2188,8 @@ 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 start_line =
+       Some (Ast0.get_info e).Ast0.pos_info.Ast0.line_start in
       let alts =
        List.map
          (List.map
@@ -2196,7 +2214,8 @@ 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 start_line =
+       Some (Ast0.get_info e).Ast0.pos_info.Ast0.line_start in
       let alts =
        List.map
          (List.map
@@ -2239,7 +2258,8 @@ let transform_top (metavars,alts,name) e =
        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 start_line =
+             Some ((Ast0.get_info e).Ast0.pos_info.Ast0.line_start) in
            let alts =
              List.map
                (List.map
index f02c923..a9a31fb 100644 (file)
@@ -631,7 +631,13 @@ rule token = parse
   | "#" [' ' '\t']* "endif" [^'\n']*
   | "#" [' ' '\t']* "error" [^'\n']*
       { start_line true; check_plus_linetype (tok lexbuf);
-       TPragma (tok lexbuf) }
+       TPragma (tok lexbuf, get_current_line_type lexbuf) }
+  | "/*"
+      { start_line true; check_plus_linetype (tok lexbuf);
+       (* second argument to TPragma is not quite right, because
+          it represents only the first token of the comemnt, but that
+          should be good enough *)
+       TPragma ("/*"^(comment lexbuf), get_current_line_type lexbuf) }
   | "---" [^'\n']*
       { (if !current_line_started
       then lexerr "--- must be at the beginning of the line" "");
@@ -710,3 +716,21 @@ and string  = parse
           x ^ string lexbuf
        }
   | _ { lexerr "unrecognised symbol: " (tok lexbuf) }
+
+and comment = parse
+  | "*/"     { start_line true; tok lexbuf }
+  | ['\n' '\r' '\011' '\012']
+      { reset_line lexbuf; let s = tok lexbuf in s ^ comment lexbuf }
+  | "+" { pass_zero();
+         if !current_line_started
+         then (start_line true; let s = tok lexbuf in s^(comment lexbuf))
+         else comment lexbuf }
+  (* noteopti: *)
+  | [^ '*'] { start_line true; let s = tok lexbuf in s ^ comment lexbuf }
+  | [ '*']   { start_line true; let s = tok lexbuf in s ^ comment lexbuf }
+  | _  
+      { start_line true; let s = tok lexbuf in
+        Common.pr2 ("LEXER: unrecognised symbol in comment:"^s);
+        s ^ comment lexbuf
+      }
+
index 91df7e7..d2900ca 100644 (file)
@@ -41,11 +41,13 @@ let get_option fn = function
   | Some x -> Some (fn x)
 
 let make_info line logical_line offset col strbef straft =
-  { Ast0.line_start = line; Ast0.line_end = line;
-    Ast0.logical_start = logical_line; Ast0.logical_end = logical_line;
+  let new_pos_info =
+    {Ast0.line_start = line; Ast0.line_end = line;
+      Ast0.logical_start = logical_line; Ast0.logical_end = logical_line;
+      Ast0.column = col; Ast0.offset = offset;} in
+  { Ast0.pos_info = new_pos_info;
     Ast0.attachable_start = true; Ast0.attachable_end = true;
     Ast0.mcode_start = []; Ast0.mcode_end = [];
-    Ast0.column = col; Ast0.offset = offset;
     Ast0.strings_before = strbef; Ast0.strings_after = straft; }
 
 let clt2info (_,line,logical_line,offset,col,strbef,straft,pos) =
index 91c0768..04c0afd 100644 (file)
@@ -109,7 +109,7 @@ let token2c (tok,_) =
   | PC.Tconst(clt) -> "const"^(line_type2c clt)
   | PC.Tvolatile(clt) -> "volatile"^(line_type2c clt)
 
-  | PC.TPragma(s) -> s
+  | PC.TPragma(s,_) -> s
   | PC.TIncludeL(s,clt) -> (pr "#include \"%s\"" s)^(line_type2c clt)
   | PC.TIncludeNL(s,clt) -> (pr "#include <%s>" s)^(line_type2c clt)
   | PC.TDefine(clt,_) -> "#define"^(line_type2c clt)
@@ -272,7 +272,7 @@ let print_tokens s tokens =
 
 type plus = PLUS | NOTPLUS | SKIP
 
-let plus_attachable (tok,_) =
+let plus_attachable only_plus (tok,_) =
   match tok with
     PC.Tchar(clt) | PC.Tshort(clt) | PC.Tint(clt) | PC.Tdouble(clt)
   | PC.Tfloat(clt) | PC.Tlong(clt) | PC.Tvoid(clt) | PC.Tstruct(clt)
@@ -325,7 +325,10 @@ let plus_attachable (tok,_) =
 
   | PC.TEq(clt) | PC.TAssign(_,clt) | PC.TDot(clt) | PC.TComma(clt)
   | PC.TPtVirg(clt) ->
-      if line_type clt = D.PLUS then PLUS else NOTPLUS
+      if line_type clt = D.PLUS
+      then PLUS
+      else if only_plus then NOTPLUS
+      else if line_type clt = D.CONTEXT then PLUS else NOTPLUS
 
   | PC.TOPar0(clt) | PC.TMid0(clt) | PC.TCPar0(clt)
   | PC.TOEllipsis(clt) | PC.TCEllipsis(clt)
@@ -604,7 +607,7 @@ let split_token ((tok,_) as t) =
   | PC.Tinline(clt) | PC.Ttypedef(clt) | PC.Tattr(_,clt)
   | PC.Tconst(clt) | PC.Tvolatile(clt) -> split t clt
 
-  | PC.TPragma(s) -> ([],[t]) (* only allowed in + *)
+  | PC.TPragma(s,_) -> ([],[t]) (* only allowed in + *)
   | PC.TPlusFile(s,clt) | PC.TMinusFile(s,clt)
   | PC.TIncludeL(s,clt) | PC.TIncludeNL(s,clt) ->
       split t clt
@@ -963,51 +966,71 @@ let find_top_init tokens =
   | _ -> tokens
 
 (* ----------------------------------------------------------------------- *)
-(* process pragmas: they can only be used in + code, and adjacent to
-another + token.  They are concatenated to the string representation of
-that other token. *)
+(* Integrate pragmas into some adjacent token.  + tokens are preferred.  Dots
+are not allowed. *)
 
 let rec collect_all_pragmas collected = function
-    (PC.TPragma(s),_)::rest -> collect_all_pragmas (s::collected) rest
+    (PC.TPragma(s,(_,line,logical_line,offset,col,_,_,pos)),_)::rest ->
+      let i =
+       { Ast0.line_start = line; Ast0.line_end = line;
+         Ast0.logical_start = logical_line; Ast0.logical_end = logical_line;
+         Ast0.column = col; Ast0.offset = offset; } in
+      collect_all_pragmas ((s,i)::collected) rest
   | l -> (List.rev collected,l)
 
-let rec collect_up_to_pragmas skipped = function
-    [] -> None (* didn't reach a pragma, so nothing to do *)
-  | ((PC.TPragma(s),_) as t)::rest ->
-      let (pragmas,rest) = collect_all_pragmas [] (t::rest) in
-      Some (List.rev skipped,pragmas,rest)
+let rec collect_pass = function
+    [] -> ([],[])
   | x::xs ->
-      match plus_attachable x with
-       PLUS -> None
-      |        NOTPLUS -> None
-      |        SKIP -> collect_up_to_pragmas (x::skipped) xs
-
-let rec collect_up_to_plus skipped = function
-    [] -> failwith "nothing to attach a pragma to (empty)"
-  | x::xs ->
-      match plus_attachable x with
-       PLUS -> (List.rev skipped,x,xs)
-      |        NOTPLUS -> failwith "nothing to attach a pragma to"
-      |        SKIP -> collect_up_to_plus (x::skipped) xs
-
-let rec process_pragmas = function
-    [] -> []
-  | ((PC.TPragma(s),_)::_) as l ->
+      match plus_attachable false x with
+       SKIP ->
+         let (pass,rest) = collect_pass xs in
+         (x::pass,rest)
+      |        _ -> ([],x::xs)
+
+let plus_attach strict = function
+    None -> NOTPLUS
+  | Some x -> plus_attachable strict x
+
+let add_bef = function Some x -> [x] | None -> []
+
+(*skips should be things like line end
+skips is things before pragmas that can't be attached to, pass is things
+after.  pass is used immediately.  skips accumulates. *)
+let rec process_pragmas bef skips = function
+    [] -> add_bef bef @ List.rev skips
+  | ((PC.TPragma(s,i),_)::_) as l ->
       let (pragmas,rest) = collect_all_pragmas [] l in
-      let (skipped,aft,rest) = collect_up_to_plus [] rest in
-      let (a,b,c,d,e,strbef,straft,pos) = get_clt aft in
-      skipped@
-      (process_pragmas ((update_clt aft (a,b,c,d,e,pragmas,straft,pos))::rest))
-  | bef::xs ->
-      (match plus_attachable bef with
-       PLUS ->
-         (match collect_up_to_pragmas [] xs with
-           Some(skipped,pragmas,rest) ->
+      let (pass,rest0) = collect_pass rest in
+      let (next,rest) =
+       match rest0 with [] -> (None,[]) | next::rest -> (Some next,rest) in
+      (match (bef,plus_attach true bef,next,plus_attach true next) with
+       (Some bef,PLUS,_,_) ->
+         let (a,b,c,d,e,strbef,straft,pos) = get_clt bef in
+         (update_clt bef (a,b,c,d,e,strbef,pragmas,pos))::List.rev skips@
+         pass@process_pragmas None [] rest0
+      |        (_,_,Some next,PLUS) ->
+         let (a,b,c,d,e,strbef,straft,pos) = get_clt next in
+         (add_bef bef) @ List.rev skips @ pass @
+         (process_pragmas
+            (Some (update_clt next (a,b,c,d,e,pragmas,straft,pos)))
+            [] rest)
+      |        _ ->
+         (match (bef,plus_attach false bef,next,plus_attach false next) with
+           (Some bef,PLUS,_,_) ->
              let (a,b,c,d,e,strbef,straft,pos) = get_clt bef in
-             (update_clt bef (a,b,c,d,e,strbef,pragmas,pos))::
-             skipped@(process_pragmas rest)
-         | None -> bef::(process_pragmas xs))
-      |        _ -> bef::(process_pragmas xs))
+             (update_clt bef (a,b,c,d,e,strbef,pragmas,pos))::List.rev skips@
+             pass@process_pragmas None [] rest0
+         | (_,_,Some next,PLUS) ->
+             let (a,b,c,d,e,strbef,straft,pos) = get_clt next in
+             (add_bef bef) @ List.rev skips @ pass @
+             (process_pragmas
+                (Some (update_clt next (a,b,c,d,e,pragmas,straft,pos)))
+                [] rest)
+         | _ -> failwith "nothing to attach pragma to"))
+  | x::xs ->
+      (match plus_attachable false x with
+       SKIP -> process_pragmas bef (x::skips) xs
+      |        _ -> (add_bef bef) @ List.rev skips @ (process_pragmas (Some x) [] xs))
 
 (* ----------------------------------------------------------------------- *)
 (* Drop ... ... .  This is only allowed in + code, and arises when there is
@@ -1391,7 +1414,7 @@ let parse file =
            *)
 
            let plus_tokens =
-             process_pragmas
+             process_pragmas None []
                (fix (function x -> drop_double_dots (drop_empty_or x))
                   (drop_when plus_tokens)) in
            (*
@@ -1586,6 +1609,7 @@ let process file isofile verbose =
               let ((metavars,minus),function_prototypes) =
                 Function_prototypes.process
                   rule_name metavars dropped_isos minus plus ruletype in
+              let plus = Adjust_pragmas.process plus in
           (* warning! context_neg side-effects its arguments *)
               let (m,p) = List.split (Context_neg.context_neg minus plus) in
               Type_infer.type_infer p;
index 803d8b3..eed5248 100644 (file)
@@ -225,8 +225,8 @@ type token =
 # 226 "parser_cocci_menhir.ml"
 )
   | TPragma of (
-# 79 "parser_cocci_menhir.mly"
-       (string)
+# 59 "parser_cocci_menhir.mly"
+       (string * Data.clt)
 # 231 "parser_cocci_menhir.ml"
 )
   | TPosition
@@ -1360,19 +1360,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           Obj.repr _v
   
   let default_reduction =
-    (16, "\000\000\000\000\0014\0015\000\000\0017\0016\000\001\000\000\001p\000\000\000\000\000\136\000\000\000\000\001\236\000\142\000\000\001\024\000\000\001#\001\027\001\021\001-\002\219\002\218\000\000\001\025\000\000\001$\001\028\001\022\001.\001\026\000\000\001%\001\029\001\031\000\000\0011\002\133\0010\001&\001\030\000\135\001\023\001,\000\000\000\000\001+\000\000\000\000\000\000\000\000\000\000\001b\000\240\002\209\000\000\000\000\000\000\000\000\000\000\002\214\000\000\001(\000\000\002\216\000\000\000\000\000\000\003\022\002O\000\000\003\020\000\000\002i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\019\003\021\002U\001\012\002T\001\n\001\011\002S\002R\002Q\002M\000\000\000\000\002N\000\213\000\000\002P\000\000\003\018\000\000\002\249\001\t\0020\000\000\000\000\0023\000\000\000\015\000\000\000\000\000\000\000\000\000\214\002L\002X\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\002\017\000R\000\223\000^\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\\\000T\000\000\000S\001\020\000\000\000\000\000\140\000\224\000\000\0026\000\225\000\014\000\016\000\000\000\000\000\143\000\000\000\141\000\000\000\000\000\228\000\000\000\000\0021\0024\000\000\0022\0025\002\250\002\248\000\000\002V\002\247\000\000\002p\000\000\000\000\002o\002n\002m\002l\002k\002g\000\000\000\000\002h\000\000\002j\000\000\000\000\003\007\002>\000\000\000\000\002A\000\000\000\000\002D\000\000\000\000\002?\002B\000\000\002@\002C\002r\002f\003\008\003\006\003\005\000g\000h\000\000\000\000\000W\000\000\000V\000\235\000\000\001\228\000\000\000\000\000\000\000\000\000\000\000\218\001\234\000\000\000\000\001\136\000U\0001\000\211\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\002W\000\000\000\144\000\000\000\000\001\212\000\000\001~\001\193\000\000\000\000\001\211\000\000\001|\001\192\000\000\000\000\000d\000\000\002q\000\000\000\000\003\n\003\t\000\000\001\229\000\000\000\000\002\252\002\251\000\000\000Q\000\150\000\000\001d\000\000\002\212\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\248\000\154\000\000\000\000\000n\000o\001\247\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\165\001\217\000\000\000\151\000\160\000\000\001\219\000\000\000\000\000\000\000\000\000\152\000\166\000\000\001j\000\000\000\000\002\211\000\000\000\000\000\138\000\000\000\000\002\210\000\000\000\000\000\000\002\213\002\217\000\000\000\000\000\000\001)\000\000\000\222\000\000\001*\000\000\000\000\001M\000\000\001L\000\000\001Z\000\000\001r\000\000\000\000\000\000\000\000\000\000\000\000\001\016\000\000\000\000\000\147\000\000\000\000\000\000\000\000\000\149\000\000\000\145\000\000\002\245\000\000\000\194\002\244\000\000\000\000\000\148\000\000\000\146\002\205\002\207\002\208\002\206\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002v\000\000\000\000\000\000\000\000\002}\000\000\000\000\002|\002{\002z\002y\002x\001I\002t\000\000\000\000\002u\000\000\002w\000\000\000\000\003\014\002E\000\000\000\000\002H\000\000\000\000\002K\000\000\000\000\002F\002I\000\000\002G\002J\002\127\002s\003\015\003\013\003\012\000i\000j\000\000\000\000\000Z\000\000\000Y\000\000\002~\000\000\001\194\000X\000?\000\234\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\003\017\003\016\000\000\002\196\000\000\002\195\000\000\000\000\000\000\000\000\003\029\000\000\000\000\000\000\003\030\000\000\000\018\000\000\000\000\000\000\003\025\000\000\001\138\000\000\000\000\000\000\000\167\002\186\001`\000\000\000\156\001_\0019\0018\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\215\000\216\000\200\000\000\001n\000\000\000\000\000\199\000\195\000\000\000\202\000\196\000\201\000\000\002\198\000\000\002\197\002\183\000\000\000\000\000\000\000\000\000\000\002\192\000\000\000\000\000\000\000\000\000\000\002\193\002\185\000\000\002\199\000\000\002\187\000\000\000\171\000\000\002\202\000\155\000\000\001;\000\000\000\000\000\000\000\000\000\000\000\000\001\017\000\000\000w\000\000\000\000\000\000\002\\\000\000\000\000\000\000\002d\000\000\000\000\002c\000\000\003\003\002b\002a\002`\002_\002^\002Z\000\000\000\000\002[\000\000\002]\000\000\000\000\003\000\0027\000\000\000\000\002:\000\000\000\000\002=\000\000\000\000\0028\002;\000\000\0029\002<\002e\002Y\003\001\002\255\002\254\003\002\000\000\000\000\000\000\000e\000f\000\000\000\000\000\000\000\000\000\210\000\209\000\000\000\000\000\000\000\000\001?\000\000\000\220\001<\000\000\000\208\001B\000\000\000\000\001C\000\000\000\000\001D\000\000\001l\000#\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000$\000\000\000%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001E\000\000\001A\000\000\000\000\001G\000\000\000\000\000\000\000\000\000\000\000\000\000t\000q\000r\001H\001>\000\000\001=\000\000\000\187\000\000\002\164\000\000\000\000\000\183\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\190\000\000\000\000\000\193\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\015\000\000\000\000\000\000\000\180\000\000\000\177\000\000\000\000\000\000\000\000\000\000\000\188\000\000\000\184\000\000\000\000\002\223\000\000\002\230\000\173\000\000\000\000\000\000\000\000\000\185\000\000\000\181\000\178\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\189\000\000\000\000\000\192\000\000\002\224\000\172\000\000\002\225\000\000\002\232\000\000\000\000\000\000\000\000\000\191\000\000\000\175\000\000\000\000\000\000\000\000\001\014\000\000\000\000\000\000\000\179\000\000\000\176\000\000\000\000\000\000\000\000\000\000\000\186\000\000\000\182\000\169\000\168\000\000\002\233\002\234\000\000\002\235\000\000\002\236\000\000\001:\002\190\000\000\000\000\001\216\000\000\001\134\001\198\000\000\002\184\000\000\000\000\000\000\002\189\000\000\000\000\000\000\001\002\000\000\000\252\000\000\000\253\000\000\001\007\000\251\001\006\000\000\002\201\001\008\000\000\000\174\000\000\000\000\000\000\000\000\001\004\000\255\001\213\000\000\001\000\000\000\001\001\000\000\001\128\001\195\000\000\000\000\000\000\001\224\000\000\001\222\000\000\000\000\001\226\001\220\000\000\001\227\001\221\000\000\002\203\001\230\000\000\000\170\000\000\000\000\001\214\000\000\001\130\001\196\000\000\003\026\000\000\003\023\000\000\003\024\000\019\000\020\000\000\000\000\002\148\000\000\002\147\000\000\000\000\002\150\000\000\002\149\000\000\000\000\000\000\002\001\000\000\000\000\002\005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\008\000\000\000\000\002\011\000\000\000\000\001\251\000\000\000\000\001\254\000\000\000\000\000\000\002\002\000\000\000\000\002\006\000\000\000\000\001\215\000\000\000\000\001\255\000\000\000\000\002\003\002\145\001\252\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\007\000\000\000\000\002\n\000\000\002\146\000\000\000\000\000\000\000\000\002\t\000\000\001\249\000\000\001\250\000\000\000\000\001\253\000\000\000\000\000\000\002\000\000\000\000\000\002\004\000\000\001\132\001\197\000\000\002\151\000\000\000\000\000\000\003\027\000\017\000u\000\000\003\028\000\000\000\000\002\160\000\000\000\000\002\204\000a\000\000\000\000\000\000\000b\000\000\002\194\000\000\001f\002\191\000\000\000\000\001S\000\000\001R\000\000\001[\000\000\001x\000\000\000\000\000\000\001Q\000\000\001P\000\000\001X\000\000\001v\000\000\000\000\000\000\001U\000\000\001T\000\000\001Y\000\000\001z\000\000\000\000\000\000\001V\000\000\000\000\000\000\000\000\001O\000\000\001N\000\000\001\\\000\000\001t\000\000\000\000\000\000\001W\000\002\000\000\000N\000O\000M\001]\000\003\000\000\000\000\002\130\000\000\002\015\000\000\002\136\002\138\000\000\000\000\001\161\002\139\002\137\000\128\000\000\000\000\002\182\000\000\000\000\000\000\000z\000\000\000\000\002\170\000\000\001\244\001\243\001\156\002\143\002\134\002\135\000\000\001\189\000\000\002\131\000\000\000\000\000|\000\000\000\000\002\174\000\000\001\171\000\000\000\000\001\167\000\000\000\000\000\000\001\170\000\000\001\169\000\000\000\000\000\000\000\000\000\000\000\000\001\190\000\000\001\165\000\000\001\164\000\000\000v\000\000\000\000\002\162\000\000\000\000\001\160\000\000\000\000\000~\000\000\000\000\002\178\000\000\000\000\000\000\000{\000\000\000\000\002\172\000\000\001\240\001\239\001\152\002\141\000\000\001\176\000\000\000\000\000\000\001\173\000\000\001\178\000\000\000\000\001\168\000\000\000\000\001\174\000\000\000\000\001\175\000\000\000\000\000\000\001\163\000\000\000\000\000\000\000\000\000\000\000\000\001\191\000\000\001\166\000}\000\000\000\000\002\176\000\000\000\000\000\000\0013\000y\0012\000\000\000\000\002\168\000\000\001\238\001\237\001\150\002\140\000\000\000\127\000\000\000\000\002\180\000\000\000\000\000\000\000\000\001\242\001\241\001\154\002\142\000\000\001\183\000\000\001\187\000\000\000\000\001\179\000\000\000\000\000\000\001\172\000\000\001\177\000\000\000\000\000\000\000\000\000\000\000\000\001\186\001\159\000\000\001\185\000\000\000\000\000\000\000\000\001\182\000\000\000\000\001\181\000\000\001\180\000\000\000\000\000\000\000\000\001\184\000\000\001\188\000\000\000\000\001^\000\004\000\000\001\162\000\005\000\000\000\000\000\238\000\006\000\000\001\202\001\203\001\201\000\000\000\000\000\000\000\000\000\000\000\000\000x\000\000\000\000\002\166\000\000\000\229\001\200\001\144\002\220\001\146\000\000\000\007\000\000\001\205\001\206\001\204\000\000\000\000\000\000\000\000\000\000\000\000\000\239\000\242\000\000\000\000\000\000\000\000\000\247\000\249\000\248\000\243\000\245\000\244\000\000\000\000\000\000\000\000\000\000\002\226\002\239\000\000\002\227\000\000\002\228\000\000\000\000\002\221\000\000\000\000\000\000\000\000\002\238\000\000\000\000\002\237\001\210\001\209\000\000\000\000\001\148\000\000\001\199\001\207\000\000\000\000\000\000\000\000\001\246\000\000\000\000\000l\000m\000\000\000\000\000\000\001\245\000\000\000\163\000\000\001h\000\000\000\000\000\162\000\158\000\000\000\000\000\000\000\000\001\013\000\000\000\000\002\242\000\000\002\243\000\000\000\000\001\233\001\231\000\000\001\232\000\008\000\000\000\t\000\000\002 \002!\002\031\000\000\000\000\002\030\000\000\000\n\000\000\002#\002$\002\"\000\000\002&\000\000\000\000\000\000\002\024\000\000\000\000\002\026\000\000\002\020\000\000\002\022\000\000\002\027\000\000\002\028\002\021\002\019\002'\001\158\000\000\002\029\000\000\002)\000\000\002(\000\000\002*\000\000\002\144\000\011\000\000\000\000\000\000\000\000\000\000\000\000\002+\000\000\000\000\002.\000\000\002-\000\000\002,\000\203\000\000\000\000\000\000\000\000\000\204\002/\000\000\000\000\002\155\000\000\000\000\000\237\000\000\000\000\000\000\000\000\000\000\002\158\000k\000\000\000\000\000\212\000\000\000\000\000\232\000\231\000\230\000\000\001K\000\000\002\154\001\142\001\140\000\012\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\153\000\000\000\000\000\000\000\000\000\000\000\000\002\152\000\000\000\013\000\000\000\000\000\000\000\000\000\000\002\156")
+    (16, "\000\000\000\000\0014\0015\000\000\0017\0016\000\001\000\000\001p\000\000\000\000\000\136\000\000\000\000\001\236\000\142\000\000\001\024\000\000\001#\001\027\001\021\001-\002\219\002\218\000\000\001\025\000\000\001$\001\028\001\022\001.\001\026\000\000\001%\001\029\001\031\000\000\0011\002\133\0010\001&\001\030\000\135\001\023\001,\000\000\000\000\001+\000\000\000\000\000\000\000\000\000\000\001b\000\240\002\209\000\000\000\000\000\000\000\000\000\000\002\214\000\000\001(\000\000\002\216\000\000\000\000\000\000\003\022\002O\000\000\003\020\000\000\002i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\019\003\021\002U\001\012\002T\001\n\001\011\002S\002R\002Q\002M\000\000\000\000\002N\000\213\000\000\002P\000\000\003\018\000\000\000c\001\t\0020\000\000\000\000\0023\000\000\000\015\000\000\000\000\000\000\000\000\000\214\002L\002X\000[\000\021\000]\000\000\000\000\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\002\017\000R\000\223\000^\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\\\000T\000\000\000S\001\020\000\000\000\000\000\140\000\224\000\000\0026\000\225\000\014\000\016\000\000\000\000\000\143\000\000\000\141\000\000\000\000\000\228\000\000\000\000\0021\0024\000\000\0022\0025\002\249\002\250\002\248\000\000\002V\002\247\000\000\002p\000\000\000\000\002o\002n\002m\002l\002k\002g\000\000\000\000\002h\000\000\002j\000\000\000\000\000g\002>\000\000\000\000\002A\000\000\000\000\002D\000\000\000\000\002?\002B\000\000\002@\002C\002r\002f\003\007\003\008\003\006\003\005\000h\000\000\000\000\000W\000\000\000V\000\235\000\000\001\228\000\000\000\000\000\000\000\000\000\000\000\218\001\234\000\000\000\000\001\136\000U\0001\000\211\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\002W\000\000\000\144\000\000\000\000\001\212\000\000\001~\001\193\000\000\000\000\001\211\000\000\001|\001\192\000\000\000\000\000d\000\000\002q\000\000\000\000\003\n\003\t\000\000\001\229\000\000\000\000\002\252\002\251\000\000\000Q\000\150\000\000\001d\000\000\002\212\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\248\000\154\000\000\000\000\000n\000o\001\247\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\165\001\217\000\000\000\151\000\160\000\000\001\219\000\000\000\000\000\000\000\000\000\152\000\166\000\000\001j\000\000\000\000\002\211\000\000\000\000\000\138\000\000\000\000\002\210\000\000\000\000\000\000\002\213\002\217\000\000\000\000\000\000\001)\000\000\000\222\000\000\001*\000\000\000\000\001M\000\000\001L\000\000\001Z\000\000\001r\000\000\000\000\000\000\000\000\000\000\000\000\001\016\000\000\000\000\000\147\000\000\000\000\000\000\000\000\000\149\000\000\000\145\000\000\002\245\000\000\000\194\002\244\000\000\000\000\000\148\000\000\000\146\002\205\002\207\002\208\002\206\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002v\000\000\000\000\000\000\000\000\002}\000\000\000\000\002|\002{\002z\002y\002x\001I\002t\000\000\000\000\002u\000\000\002w\000\000\000\000\000i\002E\000\000\000\000\002H\000\000\000\000\002K\000\000\000\000\002F\002I\000\000\002G\002J\002\127\002s\003\014\003\015\003\013\003\012\000j\000\000\000\000\000Z\000\000\000Y\000\000\002~\000\000\001\194\000X\000?\000\234\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\003\017\003\016\000\000\002\196\000\000\002\195\000\000\000\000\000\000\000\000\003\029\000\000\000\000\000\000\003\030\000\000\000\018\000\000\000\000\000\000\003\025\000\000\001\138\000\000\000\000\000\000\000\167\002\186\001`\000\000\000\156\001_\0019\0018\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\215\000\216\000\200\000\000\001n\000\000\000\000\000\199\000\195\000\000\000\202\000\196\000\201\000\000\002\198\000\000\002\197\002\183\000\000\000\000\000\000\000\000\000\000\002\192\000\000\000\000\000\000\000\000\000\000\002\193\002\185\000\000\002\199\000\000\002\187\000\000\000\171\000\000\002\202\000\155\000\000\001;\000\000\000\000\000\000\000\000\000\000\000\000\001\017\000\000\000w\000\000\000\000\000\000\002\\\000\000\000\000\000\000\002d\000\000\000\000\002c\000\000\003\003\002b\002a\002`\002_\002^\002Z\000\000\000\000\002[\000\000\002]\000\000\000\000\000\000\000\000\000\000\000e\0027\000\000\000\000\002:\000\000\000\000\002=\000\000\000\000\0028\002;\000\000\0029\002<\002e\002Y\000f\003\000\003\001\002\255\002\254\003\002\000\000\000\000\000\000\000\000\000\210\000\209\000\000\000\000\000\000\000\000\001?\000\000\000\220\001<\000\000\000\208\001B\000\000\000\000\001C\000\000\000\000\001D\000\000\001l\000#\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000$\000\000\000%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001E\000\000\001A\000\000\000\000\001G\000\000\000\000\000\000\000\000\000\000\000\000\000t\000q\000r\001H\001>\000\000\001=\000\000\000\187\000\000\002\164\000\000\000\000\000\183\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\190\000\000\000\000\000\193\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\015\000\000\000\000\000\000\000\180\000\000\000\177\000\000\000\000\000\000\000\000\000\000\000\188\000\000\000\184\000\000\000\000\002\223\000\000\002\230\000\173\000\000\000\000\000\000\000\000\000\185\000\000\000\181\000\178\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\189\000\000\000\000\000\192\000\000\002\224\000\172\000\000\002\225\000\000\002\232\000\000\000\000\000\000\000\000\000\191\000\000\000\175\000\000\000\000\000\000\000\000\001\014\000\000\000\000\000\000\000\179\000\000\000\176\000\000\000\000\000\000\000\000\000\000\000\186\000\000\000\182\000\169\000\168\000\000\002\233\002\234\000\000\002\235\000\000\002\236\000\000\001:\002\190\000\000\000\000\001\216\000\000\001\134\001\198\000\000\002\184\000\000\000\000\000\000\002\189\000\000\000\000\000\000\001\002\000\000\000\252\000\000\000\253\000\000\001\007\000\251\001\006\000\000\002\201\001\008\000\000\000\174\000\000\000\000\000\000\000\000\001\004\000\255\001\213\000\000\001\000\000\000\001\001\000\000\001\128\001\195\000\000\000\000\000\000\001\224\000\000\001\222\000\000\000\000\001\226\001\220\000\000\001\227\001\221\000\000\002\203\001\230\000\000\000\170\000\000\000\000\001\214\000\000\001\130\001\196\000\000\003\026\000\000\003\023\000\000\003\024\000\019\000\020\000\000\000\000\002\148\000\000\002\147\000\000\000\000\002\150\000\000\002\149\000\000\000\000\000\000\002\001\000\000\000\000\002\005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\008\000\000\000\000\002\011\000\000\000\000\001\251\000\000\000\000\001\254\000\000\000\000\000\000\002\002\000\000\000\000\002\006\000\000\000\000\001\215\000\000\000\000\001\255\000\000\000\000\002\003\002\145\001\252\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\007\000\000\000\000\002\n\000\000\002\146\000\000\000\000\000\000\000\000\002\t\000\000\001\249\000\000\001\250\000\000\000\000\001\253\000\000\000\000\000\000\002\000\000\000\000\000\002\004\000\000\001\132\001\197\000\000\002\151\000\000\000\000\000\000\003\027\000\017\000u\000\000\003\028\000\000\000\000\002\160\000\000\000\000\002\204\000a\000\000\000\000\000\000\000b\000\000\002\194\000\000\001f\002\191\000\000\000\000\001S\000\000\001R\000\000\001[\000\000\001x\000\000\000\000\000\000\001Q\000\000\001P\000\000\001X\000\000\001v\000\000\000\000\000\000\001U\000\000\001T\000\000\001Y\000\000\001z\000\000\000\000\000\000\001V\000\000\000\000\000\000\000\000\001O\000\000\001N\000\000\001\\\000\000\001t\000\000\000\000\000\000\001W\000\002\000\000\000N\000O\000M\001]\000\003\000\000\000\000\002\130\000\000\002\015\000\000\002\136\002\138\000\000\000\000\001\161\002\139\002\137\000\128\000\000\000\000\002\182\000\000\000\000\000\000\000z\000\000\000\000\002\170\000\000\001\244\001\243\001\156\002\143\002\134\002\135\000\000\001\189\000\000\002\131\000\000\000\000\000|\000\000\000\000\002\174\000\000\001\171\000\000\000\000\001\167\000\000\000\000\000\000\001\170\000\000\001\169\000\000\000\000\000\000\000\000\000\000\000\000\001\190\000\000\001\165\000\000\001\164\000\000\000v\000\000\000\000\002\162\000\000\000\000\001\160\000\000\000\000\000~\000\000\000\000\002\178\000\000\000\000\000\000\000{\000\000\000\000\002\172\000\000\001\240\001\239\001\152\002\141\000\000\001\176\000\000\000\000\000\000\001\173\000\000\001\178\000\000\000\000\001\168\000\000\000\000\001\174\000\000\000\000\001\175\000\000\000\000\000\000\001\163\000\000\000\000\000\000\000\000\000\000\000\000\001\191\000\000\001\166\000}\000\000\000\000\002\176\000\000\000\000\000\000\0013\000y\0012\000\000\000\000\002\168\000\000\001\238\001\237\001\150\002\140\000\000\000\127\000\000\000\000\002\180\000\000\000\000\000\000\000\000\001\242\001\241\001\154\002\142\000\000\001\183\000\000\001\187\000\000\000\000\001\179\000\000\000\000\000\000\001\172\000\000\001\177\000\000\000\000\000\000\000\000\000\000\000\000\001\186\001\159\000\000\001\185\000\000\000\000\000\000\000\000\001\182\000\000\000\000\001\181\000\000\001\180\000\000\000\000\000\000\000\000\001\184\000\000\001\188\000\000\000\000\001^\000\004\000\000\001\162\000\005\000\000\000\000\000\238\000\006\000\000\001\202\001\203\001\201\000\000\000\000\000\000\000\000\000\000\000\000\000x\000\000\000\000\002\166\000\000\000\229\001\200\001\144\002\220\001\146\000\000\000\007\000\000\001\205\001\206\001\204\000\000\000\000\000\000\000\000\000\000\000\000\000\239\000\242\000\000\000\000\000\000\000\000\000\247\000\249\000\248\000\243\000\245\000\244\000\000\000\000\000\000\000\000\000\000\002\226\002\239\000\000\002\227\000\000\002\228\000\000\000\000\002\221\000\000\000\000\000\000\000\000\002\238\000\000\000\000\002\237\001\210\001\209\000\000\000\000\001\148\000\000\001\199\001\207\000\000\000\000\000\000\000\000\001\246\000\000\000\000\000l\000m\000\000\000\000\000\000\001\245\000\000\000\163\000\000\001h\000\000\000\000\000\162\000\158\000\000\000\000\000\000\000\000\001\013\000\000\000\000\002\242\000\000\002\243\000\000\000\000\001\233\001\231\000\000\001\232\000\008\000\000\000\t\000\000\002 \002!\002\031\000\000\000\000\002\030\000\000\000\n\000\000\002#\002$\002\"\000\000\002&\000\000\000\000\000\000\002\024\000\000\000\000\002\026\000\000\002\020\000\000\002\022\000\000\002\027\000\000\002\028\002\021\002\019\002'\001\158\000\000\002\029\000\000\002)\000\000\002(\000\000\002*\000\000\002\144\000\011\000\000\000\000\000\000\000\000\000\000\000\000\002+\000\000\000\000\002.\000\000\002-\000\000\002,\000\203\000\000\000\000\000\000\000\000\000\204\002/\000\000\000\000\002\155\000\000\000\000\000\237\000\000\000\000\000\000\000\000\000\000\002\158\000k\000\000\000\000\000\212\000\000\000\000\000\232\000\231\000\230\000\000\001K\000\000\002\154\001\142\001\140\000\012\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\153\000\000\000\000\000\000\000\000\000\000\000\000\002\152\000\000\000\013\000\000\000\000\000\000\000\000\000\000\002\156")
   
   let error =
-    (171, "\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\000\000\000\000\000\128\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\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\007\240\000\000\000\000\000\000\000=j\188\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\000\000\002\000\000\008\003\008\000\001\012\192\140\002\000\128@\001\000\000\019!\136\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000/\209\192\004\001\132\000\004\134`F\001\000@!\000\128\000\t\144\196\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\157C\000\016\006\016\000\018\025\129\024\004\001\000\132\002\000\000&C\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\2508\000\1280\128\000\144\204\008\192 \008\004 \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\019\168`\002\000\194\000\002C0#\000\128 \016\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\234\024\000\1280\128\000\144\204\008\192 \008\004 \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\008\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001\000\000\000\000\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\224\001\000 \000\001\000\004\000\000\000\000\000\000\000\000\000\000\000\000\149C\000\016\006\016\000\019\025\129\024\004\001\000\132\002\000\000&C\023\173W\128\004\000\128\000\004\016\016\000\000\000\000\016\000\004\000\000\000\000\000\000\000\000\000\000\000\000@ \000\000\000\000\000\000\000\000\000\000\000\000H\161\128\000\000\008\000\008\004\128\140\002\000\000B\001\000\000\019\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\001\235U\224\t\000 \000\001\004\004\000\000\000\000\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\007\173W\128\004\000\128\000\004\016\016\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000@\000\000\002\000\000\000\000\000\000\030\181^\000\016\002\000\000\016@@\000\000\000\000@\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\235U\224\001\000 \000\001\004\004\000\000\000\000\004\000\001\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000@\000\008\000\000\000\000\000\000\000\002\000\000\136\000\000\000\000\000\005 \000$\026\005\001\157\160\000\"@ \016\001\008D\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\206\208\000\017 \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\n@\000H4\n\003;@\000D\128@\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\001 \208(\012\237\000\001\018\001\000\000\008@ \128\000\000\000\005 \000$\026\005\001\157\160\000\"@ \016\001\008\004\016\000\000\000\000\164\000\004\131@\1603\180\000\004H\004\002\000!\000\130z\213x\000T\136\000\144h\021\006v\128\000\137\000\128@\004 \016OZ\175\000\n\145\000\018\013\002\160\206\208\000\017 \016\008\000\132\002\008\000\000\000\000R\000\002A\160P\025\218\000\002$\002\000\000\016\128A=j\188\000*D\000H4\n\131;@\000D\128@ \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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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@\1603\180\000\004H\004\002\000!\000\130\000\000\000\000\020\128\000\144h\020\006v\128\000\137\000\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\n@\000H4\n\003;@\000D\128@ \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\001 \208(\012\237\000\001\018\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\164\000\004\131@\1603\180\000\004H\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\144\000\"0M\150K\000\000\020\001\004\000\003\186\002'\135p\000\000\000\000\000\000\000\000\000\000\002\000\000\000\016\000\000\000\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\021\"\000$\026\005A\159\160\000\"@ \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\001 \000@ \131\000\150\000\000(\000\000\000\007d\000M\014\224\000\000\000\002\144\000\018\013\002\128\206\208\000\017 \016\008\000\132\002\008\000\000\004\128\001\016\130l\"X\000\000\160\008\000\000\029\144\001<;\128\000\000\000\n@\000H4\n\003;@\000D\128@ \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\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\000\160\008\000\000\025\144\001<\027\128\000\000\000\n@\000H4\n\003;@\000D\128@ \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\002@\000\136A6\017,\000\000P\004\000\000\012\200\000\158\013\192\000\000\000\005 \000$\026\005\001\157\160\000\"@ \016\001\008\004\016\000\000\t\000\002!\004\216D\176\000\001@\016\000\0003 \002x7\000\000\000\000\020\128\000\144h\020\006v\128\000\137\000\128@\004 \016@\000\000$\000\008\132\019a\018\192\000\005\000@\000\000\204\128\t\224\220\000\000\000\000R\000\002A\160P\025\218\000\002$\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\001H\000\t\006\129@gh\000\008\144\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\005 \000$\026\005\001\157\160\000\"@ \016\001\008\004\016\000\000\t\000\002!\004\216D\176\000\001@\016\000\0003 \002x7\000\000\000\000\020\128\000\144h\020\006v\128\000\137\000\128@\004 \016@\000\000$\000\008\132\019a\018\192\000\005\000@\000\000\204\128\t\224\220\000\000\000\000R\000\002A\160P\025\218\000\002$\002\001\000\016\128A\000\000\000\144\000\"\016M\132K\000\000\020\001\000\000\0032\000'\131p\000\000\000\001H\000\t\006\129@gh\000\008\144\008\004\000B\001\004\000\000\002@\000\136A6\017,\000\000P\004\000\000\012\200\000\158\013\192\000\000\000\005 \000$\026\005\001\157\160\000\"@ \016\001\008\004\016\000\000\t\000\002!\004\216D\176\000\001@\016\000\0003 \002x7\000\000\000\000\020\128\000\144h\020\006v\128\000\137\000\128`\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000R\000\002A\160P\025\218\000\002$\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\000\000\000\020\128\000\144h\020\006v\128\000\137\000\128@\004 \016@\000\000$\000\008\132\019a\018\192\000\005\000@\000\000\204\128\t\224\220\000\000\000\000R\000\002A\160P\025\218\000\002$\002\001\000\016\128A\000\000\000\144\000\"\016M\132K\000\000\020\001\000\000\0032\000'\131p\000\000\000\001H\000\t\006\129@gh\000\008\144\008\004\000B\001\004\000\000\002@\000\136A6\017,\000\000P\004\000\000\012\200\000\158\013\192\000\000\000\005 \000$\026\005\001\157\160\000\"@ \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\144\000\018\013\002\128\206\208\000\017 \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\128\000\002\000\192\000\000C \000\000\000 \016\000@\000\004\200\002\002U\012\000@\024@\000Hf\004`\016\004\002\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\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\208\000\128\016\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\008\000\000 \012 \000\0042\0020\008\002\001\000\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\001\016\000=j\188\000*D\000H4\n\131?@\000D\128@ \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\001 \208(\012\237\000\001\018\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\001H\000\t\006\129@gh\000\008\144\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\n@\000H4\n\003;@\000D\128@\000\002\016\008 \000\000\000\001H\000\t\006\129@gh\000\008\144\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\005 \000$\026\005\001\157\160\000\"@ \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\020\128\000\144h\020\006v\128\000\137\000\128\000\004 \016@\000\000\000\002\144\000\018\013\002\128\206\208\000\017 \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\018\000\004D\008\178I@\000\002\000 \128\0005@D0\142\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\003\214\171\192\002\164@\004\131@\1683\244\000\004H\004\002\000! \130\000\000\000\000\000\000\000\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\000R\000\002A\160P\025\218\000\002$\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\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000\139\000\148\000\000 \002\000\000\003D\000C\008\224\000\000\000\002\144\000\018\013\002\128\206\208\000\017 \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\n@\000H4\n\003;@\000D\128@ \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\128\000\000\000\000\000\000\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\002\000\000\000\000\000B\144\000\018\013\002\128\206\208\000\017 \016\000\000\132\002\008\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003;@\000D\128@ \002\016\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\164\000\004\131@\1603\180\000\004H\004\000\000!\000\130\000\000\000\000\000\000\000\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\000\128\000\000\145\000\016\1928\000\000\000\000\164\000\004\131@\1603\180\000\004H\004\000\000!\000\130\000\000\001 \000D\000\139\000\148\000\000 \002\000\000\002D\000C\000\224\000\000\000\002\144\000\018\013\002\128\206\208\000\017 \016\000\000\132\002\008\000\000\004\128\001\016\002,\002P\000\000\128\008\000\000\t\016\001\012\003\128\000\000\000\n@\000H4\n\003;@\000D\128@\000\002\016\008 \000\000\018\000\004@\008\176\t@\000\002\000 \000\000$@\0040\014\000\000\000\000)\000\001 \208(\012\237\000\001\018\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\164\000\004\131@\1603\180\000\004H\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\002\144\000\018\013\002\128\206\208\000\017 \016\000\000\132\002\008\000\000\004\128\001\016\002,\002P\000\000\128\008\000\000\t\016\001\012\003\128\000\000\000\n@\000H4\n\003;@\000D\128@\000\002\016\008 \000\000\018\000\004@\008\176\t@\000\002\000 \000\000$@\0040\014\000\000\000\000)\000\001 \208(\012\237\000\001\018\001\000\000\008@ \128\000\000H\000\017\000\"\192%\000\000\008\000\128\000\000\145\000\016\1928\000\000\000\000\164\000\004\131@\1603\180\000\004H\004\000\000!\000\130\000\000\001 \000D\000\139\000\148\000\000 \002\000\000\002D\000C\000\224\000\000\000\002\144\000\018\013\002\128\206\208\000\017 \016\000\000\132\002\008\000\000\004\128\001\016\002,\002P\000\000\128\008\000\000\t\016\001\012\003\128\000\000\000\n@\000H4\n\003;@\000D\128@0\002\016\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\001 \208(\012\237\000\001\018\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\164\000\004\131@\1603\180\000\004H\004\000\000!\000\130\000\000\001 \000D\000\139\000\148\000\000 \002\000\000\002D\000C\000\224\000\000\000\002\144\000\018\013\002\128\206\208\000\017 \016\000\000\132\002\008\000\000\004\128\001\016\002,\002P\000\000\128\008\000\000\t\016\001\012\003\128\000\000\000\n@\000H4\n\003;@\000D\128@\000\002\016\008 \000\000\018\000\004@\008\176\t@\000\002\000 \000\000$@\0040\014\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\001\000\000\000\000\000\000R\000\002A\160P\025\218\000\002$\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\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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@\000z\213x\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\008\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\005 \000$\026\005\001\157\160\000\"@ \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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\235U\224\001R \002A\160T\025\218\000\002$\002\001\000\016\128A\000\000\000\000\000\000\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\002\000\000\000\000\000\000\000\000\000\000\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\213x\000T\136\000\144h\021\006v\128\000\137\000\128@\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\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\000\002 \000\000\000\000\000\000\000\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\145C\000\000\000\016\000\016\t\001\024\004\000\000\132\002\000\000&\003\016\018(`\000\000\002\000\002\000 #\000\128\000\016\128@\000\004\192b\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\008\000\000\000\000\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\004\000\000\000\000\000\000\000\000\000\000\000\000\001\235U\224\001\000 \000\001\000\004`\000\000\000\000\000\001\000\000\016\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\000\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\192\002\000@\000\002\000\008\192\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\002\000\000\000\000\008\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\192\002\000@\000\002\000\008\192\000\000\000\000\000\002\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000D\000\015Z\175\000\008\001\000\000\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\016\000\000\000\004@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\128\000\000\000\000\000\000\000\000\000\000\000\000=j\188\000 \004\000\000 \000\140\000\000\000\000\000\000 \000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\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\007\173W\128\004\000\128\000\004\016\016\000\000\000\000\016\000\000\000\000\008\000\245\170\240\000\128\016\000\000\130\002\000\000\000\000\002\000\000\128\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\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\235U\160\001\000 \000\000\000\004\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\128\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\tT0\001\000a\000\0011\152\017\128@\016\008@ \000\002d1z\213x\000@\008\000\000A\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\016\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001z\213x\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\001\235U\224\001\000 \000\001\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001\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\127\245\252\016\\\137\000\128c\021\199w\132\001\189A\128\008\214 P@$P\192\000\000\000\000\004\002\000F\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=j\188\000 \004\000\000 \000\140\000\000\000\000\000\000 \000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\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\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\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001P \000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000*\004\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\007\173W\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\016\000\000\000\000\000\000\000\000\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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\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\014\181Z\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\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\020\006v\128\000\137\000\128@\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@r\004\002\001\136Q\029\218\016\006\245\006\000#\024\129A\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\129@gh\000\008\144\008\004\000B\001\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\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\132\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\015\254\191\130\011\145 \018\013B\184\238\240\1287\1680\t\030\198\026\008\000\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\003;@\000\196\128@\000\002\016\008 \000\000\000\001H\000\008\006\001@gh\000\024\144\008\000\000B\001\004\245\170\240\000\169\016\001 \208*\012\237\000\001\018\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\002\144\000\016\012\002\128\206\208\0001 \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\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\206\208\0001 \016\000\000\132\002\008\000\000\000\000R\000\002A\160P\025\218\000\002$\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\001H\000\008\006\001@gh\000\024\144\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\005 \000 \024\005\001\157\160\000b@ \000\001\008\004\016\000\000\000\000\164\000\004\003\000\1603\180\000\012H\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\004\128\001\017\130l\178X\000\000\160\008 \000\029P\016(;\128\000\000\000\000\000\000\000\000\000\000\016\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\245\170\240\000\169\016\001 \208*\012\253\000\001\018\001\000\128\008H \128\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\020\128\000\144h\020\006v\128\000\137\000\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\002\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\n\000\128\000\001\209\000\002\131\184\000\000\000\000\164\000\004\131@\1603\180\000\004H\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\002\144\000\018\013\002\128\206\208\000\017 \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\004\000\000\000\000\000\000\000\000\000\000\000\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\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\020\001\000\000\003\"\000\005\003p\000\000\000\001H\000\008\006\001@gh\000\024\144\008\000\000B\001\004\000\000\002@\000\136A6\017,\000\000P\004\000\000\012\136\000\020\013\192\000\000\000\005 \000 \024\005\001\157\160\000b@ \000\001\008\004\016\000\000\t\000\002!\004\216D\176\000\001@\016\000\0002 \000P7\000\000\000\000\020\128\000\128`\020\006v\128\001\137\000\128\000\004 \016@\000\000$\000\008\132\019a\018\192\000\005\000@\000\000\200\128\001@\220\000\000\000\000R\000\002\001\128P\025\218\000\006$\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\001H\000\008\006\001@gh\000\024\144\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\005 \000 \024\005\001\157\160\000b@ \000\001\008\004\016\000\000\t\000\002!\004\216D\176\000\001@\016\000\0002 \000P7\000\000\000\000\020\128\000\128`\020\006v\128\001\137\000\128\000\004 \016@\000\000$\000\008\132\019a\018\192\000\005\000@\000\000\200\128\001@\220\000\000\000\000R\000\002\001\128P\025\218\000\006$\002\000\000\016\128A\000\000\000\144\000\"\016M\132K\000\000\020\001\000\000\003\"\000\005\003p\000\000\000\001H\000\008\006\001@gh\000\024\144\008\000\000B\001\004\000\000\002@\000\136A6\017,\000\000P\004\000\000\012\136\000\020\013\192\000\000\000\005 \000 \024\005\001\157\160\000b@ \000\001\008\004\016\000\000\t\000\002!\004\216D\176\000\001@\016\000\0002 \000P7\000\000\000\000\020\128\000\144h\020\006v\128\000\137\000\128`\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000R\000\002\001\128P\025\218\000\006$\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\001H\000\008\006\001@gh\000\024\144\008\000\000B\001\004\000\000\002@\000\136A6\017,\000\000P\004\000\000\012\136\000\020\013\192\000\000\000\005 \000 \024\005\001\157\160\000b@ \000\001\008\004\016\000\000\t\000\002!\004\216D\176\000\001@\016\000\0002 \000P7\000\000\000\000\020\128\000\128`\020\006v\128\001\137\000\128\000\004 \016@\000\000$\000\008\132\019a\018\192\000\005\000@\000\000\200\128\001@\221\235U\224\001R \002A\160T\025\218\000\002$\002\001\000\016\128A\000\000\000\000\000\000\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\005 \008$\026\005\001\157\160\000\"@ \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\255\215\240yr$\002\001\140W\029\222\016\006\245\006\000#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\001H\000\t\006\129@gh\000\008\144\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\020\128\000\144h\020\006v\128\000\137\000\128@\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\001\000\000\000\000@\000\000\000\000\000\001\008\128\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\255\235\248 \185\018\001\000\196+\142\239\008\003z\131\000\017\172@\160\159\253\127\004\023\"@$\026\133\241\221\225\000oP`\0185\138\020\019\255\175\224\242\228H\004\003\024\174;\188 \013\234\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\015\254\255\195\203\145 \016\012b\248\238\241\1287\1690\129\030\199\026\204\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000?\250\254\008.D\128@1\138\227\187\194\000\222\160\192\004k\016('\255_\193\005\200\144\t\006\161|wx@\027\212\024\004\141b\133\004\255\235\248 \185\018\001 \212+\142\239\008\003z\131\000\145\172A\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\000\000\000\000\000\000\000\000\000$\000\008\140\019e\146\192\000\005\000A\000\000\238\128\137A\220\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\164\000\004\131@\1603\180\000\004H\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\002\003\144 \016\012B\136\238\208\1287\1680\001\024\196\n\008\000\000\000@r\004\002\001\136Q\029\218\016\006\245\006\000#\024\129A\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\128\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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\001\004\131@\1603\180\000\004H\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\002\144\004\018\013\002\128\206\208\000\017 \016\008\000\132\002\008\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\n@\000H4\n\003;@\000D\128@ \002\018\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000 9\002\001\000\196(\142\237\008\003z\131\000\017\140@\160\128\000\000\004\007 @ \024\133\017\221\161\000oP`\0021\136\020\016\000\000\000\000\000\000\000\000\000\000\001\000\000\000\008\000\002\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\004\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\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\002 \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\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\005 \000$\026\005\001\157\160\000\"@ \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\128\001\001\130\012\146X\000\000\128\000 \000\012\208\017 #\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\128\005H\128\t\006\129Pg\232\000\008\144\008\004\000BA\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\004\007 @ \024\133\017\221\161\000oP`\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\016\000\000\000\000\000\000\000\000\000\000\000\000\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\248 \185\018\001 \212+\142\239\008\003z\131\000\145\172@\160\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\191\240\242\228H\004\003\024\190;\188`\013\234L 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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\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\128\004\000\128\000\004\000\016\000\000\000\000\016\000\000\000\000\000\000\002E\012\000\000\000\000\000@ \004`\000\000\002\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\003\214\171\192\002\000@\000\002\000\008\192\000\000\000\000\000\002\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000\000\000\000\000\005 \000$\026\133\001\189\160\000\"@ \016\001\008\004\016\000\000\000\000\164\000\004\0030\1603\180\000\012H\004\n\128!\004\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\002\144\000\016\012\002\128\206\208\0001 \016\000\000\132\002\008\000\000\000\000R\000\002A\160P\025\218\000\002$\002\001\000\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\245\170\240\000\169\016\001 \208*\012\237\000\001\018\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\006v\128\001\137\000\128\000\004 \016@\000\000\000\002\144\000\018\013\002\128\206\208\000\017 \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\n@\000@0\n\003;@\000\196\128@\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\001\000\192(\012\237\000\003\018\001\000\000\008@ \128\000\000\000\005 \000 \024\005\001\157\160\000b@ \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\008\008\016d\146\128\000\004\000\001\000\000B\128\136\000\024\000\000\000\000\000\000\000\000\000\000\000\128\000\000\004\000\000\000\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\128\005H\128\t\006\129Pg\232\000\008\144\008\004\000BA\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\164\000\004\131@\1603\180\000\004H\004\002\000!\000\130\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\016\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\128\005H\128\t\006\129Pgh\000\008\144\008\004\000B\001\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\005 \000 \024\005\001\157\160\000b@ \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\002\144\000\018\013\002\128\206\208\000\017 \016\008\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\004\000\000\000\000\000\n@\000H4\n\003;@\000D\128@ \002\016\008 \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\164\000\004\0030\1603\180\000\012H\004\n\128!\004\130\000\000\000\002\020\128\000\128f\020\006v\128\001\137\000\129P\004 \144@\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002A\168P\027\218\000\002$\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\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\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\004\000\000\000\000\000\000\000\000\n@\000@3\n\003;@\000\196\128@\136\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\005 \000 \025\133\001\157\160\000b@ D\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\004\000\000\000\000\000\000\000\001\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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 \000A\128J\000\000\016\000\000\000\001\002\000 \000`\000\000\000\001H\000\008\006\001@gh\000\024\144\008\000\000B\001\004\000\000\002\000\000\128\001\006\001(\000\000@\000\000\000\004\008\000\128\001\128\000\000\000\005 \000 \024\005\001\157\160\000b@ \000\001\008\004\016\000\000\008\000\002\000\004\024\004\160\000\001\000\000\000\000\016 \002\000\006\000\000\000\000\020\128\000\128`\020\006v\128\001\137\000\128\000\004 \016@\000\000 \000\008\000\016`\018\128\000\004\000\000\000\000@\128\008\000\024\000\000\000\000R\000\002\001\128P\025\218\000\006$\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\001H\000\008\006\001@gh\000\024\144\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\005 \000 \024\005\001\157\160\000b@ \000\001\008\004\016\000\000\008\000\002\000\004\024\004\160\000\001\000\000\000\000\016 \002\000\006\000\000\000\000\020\128\000\128`\020\006v\128\001\137\000\128\000\004 \016@\000\000 \000\008\000\016`\018\128\000\004\000\000\000\000@\128\008\000\024\000\000\000\000R\000\002\001\128P\025\218\000\006$\002\000\000\016\128A\000\000\000\128\000 \000A\128J\000\000\016\000\000\000\001\002\000 \000`\000\000\000\001H\000\008\006\001@gh\000\024\144\008\000\000B\001\004\000\000\002\000\000\128\001\006\001(\000\000@\000\000\000\004\008\000\128\001\128\000\000\000\005 \000 \024\005\001\157\160\000b@ \000\001\008\004\016\000\000\008\000\002\000\004\024\004\160\000\001\000\000\000\000\016 \002\000\006\000\000\000\000\020\128\000\128`\020\006v\128\001\137\000\128\000\004 \016@\000\000 \000\008\000\016`\018\128\000\004\000\000\000\000@\128\008\000\024\000\000\000\000R\000\002\001\128P\025\218\000\006$\002\000\000\016\128A\000\000\000\128\000 \000A\128J\000\000\016\000\000\000\001\002\000 \000`\000\000\000\001H\000\008\006\001@gh\000\024\144\008\000\000B\001\004\000\000\002\000\000\128\001\006\001(\000\000@\000\000\000\004\008\000\128\001\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\000\000\000\000\000\000R\000\002\001\152P\025\218\000\006$\002\005@\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\001H\000\008\006a@gh\000\024\144\008\021\000B\t\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\005 \000 \025\133\001\157\160\000b@ T\001\008$\016\000\000\000\000\164\000\004\0030\1603\180\000\012H\004\008\128!\004\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\002\144\000\016\012\194\128\206\208\0001 \016*\000\132\018\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\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\128\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\245\170\240\000\128\016\000\000\128\0020\000\000\000\000\000\000\128\000\008\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\008\000\000\000\000\000\000\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\222\208\000\017 \016\008\000\132\002\008\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\016\000\000\000\000\000\000\000\000\000\000\000\000@\000H\000\000\000\000\000\000\000\002\000\000\128\000\000\000\000\000\000\000\008\000\t\000\000\000\000\000\000\000\000@\000\016\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000z\213x\000@\008\000\000@\001\024\000\000\000\000\000\000@\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\016\000\004\000\000\000\000\000\000)\000\001 \212(\013\237\000\001\018\001\000\128\008@ \128\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\235U\160\001\000 \000\000\000\004\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\016\000\004\000\000\000\000\000\000)\000\001 \212(\013\237\000\001\018\001\000\128\008@ \128\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\255\215\240Ar$\002\001\140W\029\2220\006\245\006\000#X\129A\000\000\000\000\000\000\000\008\004\000\000\000\004\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\255\235\248 \185\018\001\000\198+\142\239\024\003z\131\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001 \000D`\155,\150\000 (\002\t\000\007t\004\n\014\224\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000 \000\008\000\000\000\000\000\000R\000\002A\168P\027\218\000\002$\002\001\000\016\128A\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\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\128\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\245\170\240\000\128\016\000\000\128\0020\000\000\000\000\000\000\128\000\008\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\008\000\000\000\000\000\000\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\222\208\000\017 \016\008\000\132\002\008\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\002\001\000\128\000\000\000\128\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\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\224\130\228H\004\131P\174;\188`\013\234\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\015\254\191\130\011\145 \016\012b\184\238\241\1287\1680\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\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\128\005H\128\t\006\129Pg\232\000\008\144\008\004\000BA\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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001\000\000\000\000\000\000\000\000\000\000\000\000\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=j\188\000 \004\000\000 \000\140\000\000\000\000\000\000 \000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\000\002\000\000\000\000\000\000\020\128\000\144j\020\006\246\128\000\137\000\128@\004 \016@\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000u\170\208\000\128\016\000\000\000\002\000\000\000\000\002\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\001\000\000\000\000\000\000\000\000\000\000\008\000\002\000\000\000\000\000\000\020\128\000\144j\020\006\246\128\000\137\000\128@\004 \016@\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\003\255\175\224\130\228H\004\131P\174;\188`\013\234\012\"F\177\002\179\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\007\255_\193\005\200\144\t\006\161\\wx\192\027\212\024\004\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\008\000\000\000\000\140\002\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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@r\004\002\001\136Q\029\218\016\006\245\006\000#\024\129A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\004\000\000\000@\000\000\000\000\000\000\000\000\001\000\001\255\223\248Ar4\002a\168_\029\2220\014\245&\019#\216\235Y\128\000\000\008\014@\128@1\n#\187B\000\222\160\192\004c\016( \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\255\235\248 \185\018\001\000\198/\142\239\008\003z\131\000\017\236q\160\128\000\000\000\000\000\000\004\002\000\000\000\000\000\000\000\000\016\000\000\000\003\255\175\224\130\228H\004\003\024\190;\188 \013\234\012\000G\177\198\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\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\000\000\000?\250\254\008.D\128H5\011\227\187\194\000\222\160\192${\028h \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\255\235\248 \185\018\001 \212/\142\239\008\003z\131\000\145\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\128\000\000\000\000\000\000\000\000\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\002\000\003\255\175\224\130\228H\004\003\024\190;\188 \013\234\012\000F\177B\130\000\000\000\000\000\000\000\016\008\002\000\000\000\000\000\000\000@\000\008\000\015\254\191\130\011\145 \016\012b\248\238\240\1287\1680\001\026\197\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\000\000\000\000\000@ \016\004\000\000\000\000\000\000\000\128\000\016\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\224\130\228H\004\131P\190;\188 \013\234\012\002F\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\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000 #\000\000\000\016\000\000\000\000\128\000\000\000\000\000\000\008\0000\016\000\000\000\000\004\000\000\000\128\000\004\000_\253\127\004\023\"@ \024\197q\221\225\000oP`\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\004 \024\008\000\000\000\000\002\000\000\000@\000\002\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\255\215\240Ar4\002a\168W\029\222\016\014\245\006\001#X\137A\191\250\254\008.D\128@1\138\227\187\194\000\222\160\192\004k\016( \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\127\004\023#@&\026\133q\221\225\000\239P`\0185\136\148\024\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\128\000\000\000\000\000\000\000\000\002\000\003\255\175\224\130\228H\004\131P\190;\188 \013\234\012\002F\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\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\004\002\000\000\000\002\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\245\252\016\\\137\000\144j\021\199w\140\001\189A\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\000\000\000\007\191_\192\005H\144\008\006\001Pgx\000\024\144\008\000\001b\005\004\000\000\000\000)\000A \208(\012\237\000\001\018\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\001\000\000\000\000\000\000\000\000\000\000\000\000\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~\191\128\n\145 \016\012\002\160\206\240\0001 \016\000\002\196\n\008\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\002\000\000\000\000\000\000\000\000\000\000\000\000\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\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\001\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\001\000\000\000\000\000\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\218\000\002$\002\001\000\016\128A\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\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\001\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\004\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\001\235U\224\001\000 \000\001\000\004`\000\000\000\000\000\001\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\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\189\160\000\"@ \016\001\008\004\016\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000F\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\004\000\000\000\000\000\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@oh\000\008\144\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\001\214\171@\002\000@\000\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\001\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\n@\000H5\n\003{@\000D\128@ \002\016\008 \000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\002\000\003\223\175\224\002\164H\004\003\000\1683\188\000\012H\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\008\012\016d\146\192\004\004\000\001 \000b\128\129\001\024\000\000\000\000\000\000\128\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\001H\000\t\006\161@oh\000\008\144\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\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\016\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\030\181^\000\016\002\000\000\016\000F\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\001\000\000\000\000\000\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\218\000\002$\002\001\000\016\128A\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000z\213x\000T\136\000\144h\021\006~\128\000\137\000\128@\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\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000#\000\000\000\016\000\000\000\000\000\000\000\000\000\000\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\020\128\000\144j\020\006\246\128\000\137\000\128@\004 \016@\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\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\180\000 \004\000\000\000\000\128\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\016\000\000\000\000\000\000\000\000\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\164\000\004\131P\1607\180\000\004H\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\008\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000 \000\000\002\0020\000\000\001\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\002\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\002\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\000\001\255\215\240Ar$\002\001\140W\029\222\016\006\245\006\000#X\129A\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\157\160\000\"@ \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\127\245\252\016\\\137\000\144j\021\199w\132\001\189A\128H\2460\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\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\016\000\000\000\000\000\000\001\127\245\252\016\\\137\000\128c\021\199w\132\001\189A\128\008\214 P@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\255\215\240Ar$\002\001\140W\029\222\016\006\245\006\000#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\002\000\000\000\000\000\000\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\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\000\020\128\000\144h\020\006v\128\000\137\000\128\000\004 \016@\000\000\000\000\000\128\000\000\000\000\000\000\000@\000\000\000\000\000\000\004\000\000\000\000R\000\002A\160P\025\218\000\002$\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\001H\000\t\006\129@gh\000\008\144\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\008\000\000\000\000\000\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\002\000\000\000\000\000\000\000 \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\029\218\016\006\245\006\000#\024\129A\000\000\000\000\000\002\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\016\000\000\001\001\200\016\008\006!Dwh@\027\212\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\004\007 @ \024\133\017\221\161\000oP`\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\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\008\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\129@gh\000\008\144\008\000\000B\001\004\000\000\000\000\000\008\000\000\000\000\000\000\000\004\000\000\000\000\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\127\245\252\000@\008\000\000@\001\000\001\000\000\001\000\000\000\016\000\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\016\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\191\250\254\000 \004\000\000 \000\128\000\128\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\255\235\248\000\128\016\000\000\128\002\000\002\000\000\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\128\000\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\n@\000H4\n\003;@\000D\128@\000\002\016\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\213x@\225\008\137 B\001\000\000\018\000B\148$\000\t\128 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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^\0008B\"\008\016\128@\000\004\128\016\165\t\000\002`\000\003\214\171\192\007\008@\001\002\016\008\000\000\144\002\020\161 \000L\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\004\001\000\128\000\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\004\000\000\016\004\000\000\000\016\000\000\000\000\000\128\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\004\000\000\000\016\000\000@\016\000\000\000@\000\000\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\004\000\000\002\000\000\000\000\000\000\002\000\000\000\000\000\000\000\008\000\000\002\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\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\003\214\171\192\007\008D\001\002\016\008\000\000\144\002\020\161 \000D\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015Z\175\000\028!\000\004\008@ \000\002@\008R\132\128\001\016\000\000\000 \000\000\128 \000\000\000\128\000\000\000\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\004\000\000\000\000\000\000\004\000\000\000\016\000\000@\016\000\000\000@\000\000\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\002\000\000\000\000\000\000\000\000\000\000\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\001\000\000\000\004\000\000\000\000\000 \000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\002\000\128\000\000\002\000\000\000\000\000\016\000@\000\000\000\000\000\016\000\000@\016\000\000\000@\000\000\128\000\002\000\008\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\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\128\000\000\000\000\004\000\016\000\000\000\000\000\004\000\000\016\004\000\000\002\016\000\000 \000\000\128\002\000\000 \000\000\000\128\000\002\000\128\000\000\002\000\000\000\000\000\016\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\002\000\000\008\002\000\000\000\008\000\000\000\000\000@\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\245\170\240\000\128\016\000\000\128\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\004\000z\213x\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\002\000\000\004\000\000\016\004\000\000\002\024\000\000\000\000\000\128\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001 \000\000\000\000\000\000\002\000\000\008\002\000\000\000\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\001\000\000\004\001\000\000\000\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\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\017\128\000\002\004\016\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\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001\000\000\004\001\000\000\000\004\000\000\000\000\000 \000\128\000\000\000\000\000 \000\000\128 \000\000\002\128\000\001\000\000\004\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\128\000\000\000\000\000\000\000\000\000\000\000\000\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\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\128 \000\000\000\128\000\000\000\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\016\000\000@\016\000\000\000@\000\000\000\000\002\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000\004\001\000\000\000\004\000\000\000\000\000 \000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\002\000\128\000\000\003\000\000\000\000\000\016\000@\000\000\000\000\000\016\000\000@\016\000\000\t@\000\000\128\000\002\000\008\000\000\128\000\000\002\000\000\008\002\000\000\000\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\008\000\000\008\000\000 \008\000\000\000 \000\000\000\000\001\000\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\016\000\000\000@\000\001\000@\000\000\001\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\016\000\000\008\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\002\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001\000@\000\000\001\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\008\000\000\000\000\000\000\008\000\000\000 \000\000\128 \000\000\000\128\000\000\000\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\008\000\000\004\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\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\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\000\000 \008\000\000\000 \000\000\000\000\001\000\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\016\004\000\000\000\016\000\000\000\000\000\128\002\000\000\000\000\000\000\128\000\002\000\128\000\000\n\000\000\004\000\000\016\000@\000\004\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\002\000\000\000\000\000\000\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[\175\000\012\001\000\000\008D \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\128\000\000\000\000\000\000\000\128\000\002\000\128\000\000\011\000\000\004\000\000\016\000@\000\004\000\000\000\016\000\000@\016\000\000\000@\000\000\000\000\002\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\007\173\215\128\006\000\128\000\004#\016\000\000\000\000\016\000@\000\000\000\000\000\016\000\000@\016\000\000\000@\000\000\000\000\002\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\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\001\000\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\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\008@\000\000\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\001\000@\000\000\001\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\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\213x@\225\008\137 B\001\000\000\018\000B\148$\000\t\128 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\003;@\000D\128@ \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\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\000\000\000\000\000\000\n@\000H4\n\003;@\000D\128@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000b\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\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\006v\128\000\137\000\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\001\004\000\000\000\000\000\n@\000H4\n\003;@\000D\128@\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\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000?\251\255\008.D\128H=\014\227\187\194\000\222\164\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\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\015\254\255\194\011\145 \018\015B\184\238\240\1287\1690\137\026\196\n\204\239\223\184\001\000 \000\000\000\004\000\000\000\000\000 \000\000\000\000\000\000\145C\000\000\000\000\000\000\008\000\000\000\000\000\004\000\000\000\000\000\003\191~\224\004\000\128\000\000\000\016\000\000\000\000\000\128\000\000\000\000\000w\239\220\000\128\016\000\000\000\002\000\000\000\000\000\016\000\000\000\000\000\000H\161\128\000\000\000\000\000\004\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000$P\192\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\004\138\024\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\145C\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\018(`\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?\250\254\015.D\128@1\138\227\187\194\000\222\160\192\004k\016('\255_\193\005\200\144\008\0061\\wx@\027\212\024\000\141b\005\004\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253\127\004\023\"@ \024\197q\221\225\000oPa\0025\136\021\152\000\000\000\000\000\000\000\128@\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\128@ \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\007\255_\193\005\200\144\t\006\161\\wx@\027\212\024D\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\005 \000 \025\133\001\157\160\000b@ T\001\008\004\016\000\000\000\000\000\000\000\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\015\254\191\131\203\145 \016\012b\184\238\240\1287\1680\001\026\196\n\t\255\215\240Ar$\002\001\140W\029\222\016\006\245\006\000#X\129A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\007\255_\193\005\200\144\008\0061\\wx@\027\212\024@\141b\005f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253\127\007\151\"@ \024\197q\221\225\000oP`\0025\136\020\019\255\175\224\130\228H\004\003\024\174;\188 \013\234\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000=\251\255\000 \004\000\000 \000\128\000\000\000\000\132\000\000\000\000\000\000\018(`\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\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\192\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\128\004\000\128\000\004\000\017\128\000\000\000\000\000\004\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\192\002\000@\000\002\000\008\192\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\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\001\016\000=j\188\000 \004\000\000 \000\140\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\016\000\000\000\000\000\000\000\000\000\000\000\000\127\245\252\016\\\137\000\144j\021\199w\132\001\189A\128H\214 \208@\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\145C\000\000\000\000\000\016\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\002\001\000\128\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\000\031\253\127\004\023\"@$\026\133q\221\225\000oPa\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\0020\000\000\001\000\004\000\000\000\006 \000\000\000\000\004\002\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\164\000\004\131@\2243\180\000\004H\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\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\000\000)\000\001 \208(\012\237\000\001\018\001\000\128\008@ \128\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\000\127\247\254\016\\\137\000\144z\029\199w\132\001\189I\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\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\031\253\255\132\023\"@$\030\133q\221\225\000oRa\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\127\247\254\016\\\137\000\128c\021\199w\132\001\189I\132\008\214 V`\000\000\000\000\000\000\002\001\000\000\000\000\000\000\000\000\136\000\000\000\197\255\223\248Ar$\002\001\140W\029\222\016\006\245&\016#X\129Y\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255\127\225\005\200\144\t\006\161\\wx@\027\212\152D\141b\005f\255\239\252 \185\018\001\000\198+\142\239\008\003z\147\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\001\000\128@\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\015\254\255\194\011\145 \018\013B\184\238\240\1287\1690\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?\251\255\008.D\128H5\n\227\187\194\000\222\164\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\255\239\252 \185\018\001 \212+\142\239\008\003z\147\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\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\255\239\252 \185\018\001 \212+\142\239\008\003z\147\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\001\000\128@\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\015\254\255\194\011\145 \018\013B\184\238\240\1287\1690\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\000\016\000\000\000\001\024\000\000\000\128\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\000@\004\128\000\000\000\000\000\000\000\000H\156\000\192\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\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\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\016 \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\000\016\000\000@\128\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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\001\000\000\000\000\000\002\000\000\008\016\000\000\000\000\000\000\002\000\000\000\004\000\000\000\000\008\000\016\000\016\000\000\000\000\000\000\000\017\128\016\000 \020\000\000\000\000\000\008\000\000 @\000\000\000\000\000\000\008\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001\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\000 \000\000\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\156\000\192\000\000\128\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000@\000\000\000\000\000\000\000\000\000F\000`\000\000@\000\000\000\004\000\008\000\000\000\000\000\000\000\000\000\008\192\008\000\000\008\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\0020\002\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\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\024\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000\000\000\000\000\000\000\000\019\128\024\000\000\016\000\000\000\001\000\002\000\000\000\000\000\000\000\000\000\0020\003\000\000\002\000\000\000\000 \000@\000\000\000\000\000\000\000\000\000F\000@\000\000@\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\008\192\008\000\000\008\000\000\000\000\000\001\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\000\002\000\000\000\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\008\000\016\000\000\000\000\000\000\000\000\000\017\128\024\000\000\016\000\000\000\001\000\002\000\000\000\000\000\000\000\000\000\0020\002\000\000\002\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000F\000@\000\000@\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\008\192\000\000\000\008\000\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\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\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\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\000\000\000\000\000\000\000\000")
+    (171, "\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\000\000\000\000\000\128\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000`\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\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\007\240\000\000\000\000\000\000\000=j\188\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\000\000\002\000\000\008\003\008\000\001\012\192\140\002\000\128@\001\000\000\019!\136\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000/\209\192\004\001\132\000\004\134`F\001\000@!\000\128\000\t\144\196\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\157C\000\016\006\016\000\018\025\129\024\004\001\000\132\002\000\000&C\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\2508\000\1280\128\000\144\204\008\192 \008\004 \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\019\168`\002\000\194\000\002C0#\000\128 \016\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\234\024\000\1280\128\000\144\204\008\192 \008\004 \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\008\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001\000\000\000\000\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\224\001\000 \000\001\000\004\000\000\000\000\000\000\000\000\000\000\000\000\149C\000\016\006\016\000\019\025\129\024\004\001\000\132\002\000\000&C\023\173W\128\004\000\128\000\004\016\016\000\000\000\000\016\000\004\000\000\000\000\000\000\000\000\000\000\000\000@ \000\000\000\000\000\000\000\000\000\000\000\000H\161\128\000\000\008\000\008\004\128\140\002\000\000B\001\000\000\019\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\001\235U\224\t\000 \000\001\004\004\000\000\000\000\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\007\173W\128\004\000\128\000\004\016\016\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000@\000\000\002\000\000\000\000\000\000\030\181^\000\016\002\000\000\016@@\000\000\000\000@\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\235U\224\001\000 \000\001\004\004\000\000\000\000\004\000\001\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000@\000\008\000\000\000\000\000\000\000\002\000\000\136\000\000\000\000\000\005 \000$\026\005\001\157\160\000\"@ \016\001\008D\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\206\208\000\017 \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\n@\000H4\n\003;@\000D\128@\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\001 \208(\012\237\000\001\018\001\000\000\008@ \128\000\000\000\005 \000$\026\005\001\157\160\000\"@ \016\001\008\004\016\000\000\000\000\164\000\004\131@\1603\180\000\004H\004\002\000!\000\130z\213x\000T\136\000\144h\021\006v\128\000\137\000\128@\004 \016OZ\175\000\n\145\000\018\013\002\160\206\208\000\017 \016\008\000\132\002\008\000\000\000\000R\000\002A\160P\025\218\000\002$\002\000\000\016\128A=j\188\000*D\000H4\n\131;@\000D\128@ \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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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@\1603\180\000\004H\004\002\000!\000\130\000\000\000\000\020\128\000\144h\020\006v\128\000\137\000\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\n@\000H4\n\003;@\000D\128@ \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\001 \208(\012\237\000\001\018\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\164\000\004\131@\1603\180\000\004H\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\144\000\"0M\150K\000\000\020\001\004\000\003\186\002'\135p\000\000\000\000\000\000\000\000\000\000\002\000\000\000\016\000\000\000\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\021\"\000$\026\005A\159\160\000\"@ \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\001 \000@ \131\000\150\000\000(\000\000\000\007d\000M\014\224\000\000\000\002\144\000\018\013\002\128\206\208\000\017 \016\008\000\132\002\008\000\000\004\128\001\016\130l\"X\000\000\160\008\000\000\029\144\001<;\128\000\000\000\n@\000H4\n\003;@\000D\128@ \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\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\000\160\008\000\000\025\144\001<\027\128\000\000\000\n@\000H4\n\003;@\000D\128@ \002\016\008 \000\000\018\000\004B\t\176\137`\000\002\128 \000\000f@\004\240n\000\000\000\000)\000\001 \208(\012\237\000\001\018\001\000\128\008@ \128\000\000H\000\017\008&\194%\128\000\n\000\128\000\001\153\000\019\193\184\000\000\000\000\164\000\004\131@\1603\180\000\004H\004\002\000!\000\130\000\000\001 \000D \155\008\150\000\000(\002\000\000\006d\000O\006\224\000\000\000\002\144\000\018\013\002\128\206\208\000\017 \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\n@\000H4\n\003;@\000D\128@ \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\001 \208(\012\237\000\001\018\001\000\128\008@ \128\000\000H\000\017\008&\194%\128\000\n\000\128\000\001\153\000\019\193\184\000\000\000\000\164\000\004\131@\1603\180\000\004H\004\002\000!\000\130\000\000\001 \000D \155\008\150\000\000(\002\000\000\006d\000O\006\224\000\000\000\002\144\000\018\013\002\128\206\208\000\017 \016\008\000\132\002\008\000\000\004\128\001\016\130l\"X\000\000\160\008\000\000\025\144\001<\027\128\000\000\000\n@\000H4\n\003;@\000D\128@ \002\016\008 \000\000\018\000\004B\t\176\137`\000\002\128 \000\000f@\004\240n\000\000\000\000)\000\001 \208(\012\237\000\001\018\001\000\128\008@ \128\000\000H\000\017\008&\194%\128\000\n\000\128\000\001\153\000\019\193\184\000\000\000\000\164\000\004\131@\1603\180\000\004H\004\003\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\002\144\000\018\013\002\128\206\208\000\017 \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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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@\1603\180\000\004H\004\002\000!\000\130\000\000\001 \000D \155\008\150\000\000(\002\000\000\006d\000O\006\224\000\000\000\002\144\000\018\013\002\128\206\208\000\017 \016\008\000\132\002\008\000\000\004\128\001\016\130l\"X\000\000\160\008\000\000\025\144\001<\027\128\000\000\000\n@\000H4\n\003;@\000D\128@ \002\016\008 \000\000\018\000\004B\t\176\137`\000\002\128 \000\000f@\004\240n\000\000\000\000)\000\001 \208(\012\237\000\001\018\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\020\128\000\144h\020\006v\128\000\137\000\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\004\000\000\016\006\000\000\002\025\000\000\000\001\000\128\002\000\000&@\016\018\168`\002\000\194\000\002C0#\000\128 \016\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\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\173V\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 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\001\000a\000\000!\144\017\128@\016\008\000 \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\008\128\001\235U\224\001R \002A\160T\025\250\000\002$\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\001H\000\t\006\129@gh\000\008\144\008\004\000B\001\004\000\000\000\000\000\000\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\001H\000\t\006\129@gh\000\008\144\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\n@\000H4\n\003;@\000D\128@\000\002\016\008 \000\000\000\001H\000\t\006\129@gh\000\008\144\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\005 \000$\026\005\001\157\160\000\"@ \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\020\128\000\144h\020\006v\128\000\137\000\128\000\004 \016@\000\000\000\002\144\000\018\013\002\128\206\208\000\017 \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\018\000\004D\008\178I@\000\002\000 \128\0005@D0\142\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\003\214\171\192\002\164@\004\131@\1683\244\000\004H\004\002\000! \130\000\000\000\000\000\000\000\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\000R\000\002A\160P\025\218\000\002$\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\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000\139\000\148\000\000 \002\000\000\003D\000C\008\224\000\000\000\002\144\000\018\013\002\128\206\208\000\017 \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\n@\000H4\n\003;@\000D\128@ \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\128\000\000\000\000\000\000\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\002\000\000\000\000\000B\144\000\018\013\002\128\206\208\000\017 \016\000\000\132\002\008\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n@\000H4\n\003;@\000D\128@ \002\016\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\164\000\004\131@\1603\180\000\004H\004\000\000!\000\130\000\000\000\000\000\000\000\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\000\128\000\000\145\000\016\1928\000\000\000\000\164\000\004\131@\1603\180\000\004H\004\000\000!\000\130\000\000\001 \000D\000\139\000\148\000\000 \002\000\000\002D\000C\000\224\000\000\000\002\144\000\018\013\002\128\206\208\000\017 \016\000\000\132\002\008\000\000\004\128\001\016\002,\002P\000\000\128\008\000\000\t\016\001\012\003\128\000\000\000\n@\000H4\n\003;@\000D\128@\000\002\016\008 \000\000\018\000\004@\008\176\t@\000\002\000 \000\000$@\0040\014\000\000\000\000)\000\001 \208(\012\237\000\001\018\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\164\000\004\131@\1603\180\000\004H\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\002\144\000\018\013\002\128\206\208\000\017 \016\000\000\132\002\008\000\000\004\128\001\016\002,\002P\000\000\128\008\000\000\t\016\001\012\003\128\000\000\000\n@\000H4\n\003;@\000D\128@\000\002\016\008 \000\000\018\000\004@\008\176\t@\000\002\000 \000\000$@\0040\014\000\000\000\000)\000\001 \208(\012\237\000\001\018\001\000\000\008@ \128\000\000H\000\017\000\"\192%\000\000\008\000\128\000\000\145\000\016\1928\000\000\000\000\164\000\004\131@\1603\180\000\004H\004\000\000!\000\130\000\000\001 \000D\000\139\000\148\000\000 \002\000\000\002D\000C\000\224\000\000\000\002\144\000\018\013\002\128\206\208\000\017 \016\000\000\132\002\008\000\000\004\128\001\016\002,\002P\000\000\128\008\000\000\t\016\001\012\003\128\000\000\000\n@\000H4\n\003;@\000D\128@0\002\016\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\001 \208(\012\237\000\001\018\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\164\000\004\131@\1603\180\000\004H\004\000\000!\000\130\000\000\001 \000D\000\139\000\148\000\000 \002\000\000\002D\000C\000\224\000\000\000\002\144\000\018\013\002\128\206\208\000\017 \016\000\000\132\002\008\000\000\004\128\001\016\002,\002P\000\000\128\008\000\000\t\016\001\012\003\128\000\000\000\n@\000H4\n\003;@\000D\128@\000\002\016\008 \000\000\018\000\004@\008\176\t@\000\002\000 \000\000$@\0040\014\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\001\000\000\000\000\000\000R\000\002A\160P\025\218\000\002$\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\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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@\000z\213x\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\008\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\005 \000$\026\005\001\157\160\000\"@ \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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\235U\224\001R \002A\160T\025\218\000\002$\002\001\000\016\128A\000\000\000\000\000\000\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\002\000\000\000\000\000\000\000\000\000\000\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\213x\000T\136\000\144h\021\006v\128\000\137\000\128@\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\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\000\002 \000\000\000\000\000\000\000\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\145C\000\000\000\016\000\016\t\001\024\004\000\000\132\002\000\000&\003\016\018(`\000\000\002\000\002\000 #\000\128\000\016\128@\000\004\192b\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\008\000\000\000\000\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\004\000\000\000\000\000\000\000\000\000\000\000\000\001\235U\224\001\000 \000\001\000\004`\000\000\000\000\000\001\000\000\016\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\000\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\192\002\000@\000\002\000\008\192\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\002\000\000\000\000\008\000\000\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\003\214\171\192\002\000@\000\002\000\008\192\000\000\000\000\000\002\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000D\000\015Z\175\000\008\001\000\000\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\016\000\000\000\004@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\128\000\000\000\000\000\000\000\000\000\000\000\000=j\188\000 \004\000\000 \000\140\000\000\000\000\000\000 \000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\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\007\173W\128\004\000\128\000\004\016\016\000\000\000\000\016\000\000\000\000\008\000\245\170\240\000\128\016\000\000\130\002\000\000\000\000\002\000\000\128\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\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\235U\160\001\000 \000\000\000\004\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\128\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\tT0\001\000a\000\0011\152\017\128@\016\008@ \000\002d1z\213x\000@\008\000\000A\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\016\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001z\213x\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\001\235U\224\001\000 \000\001\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001\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\127\245\252\016\\\137\000\128c\021\199w\132\001\189A\128\008\214 P@$P\192\000\000\000\000\004\002\000F\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=j\188\000 \004\000\000 \000\140\000\000\000\000\000\000 \000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\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\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\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001P \000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000*\004\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\007\173W\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\016\000\000\000\000\000\000\000\000\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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\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\014\181Z\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\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\128\000\144h\020\006v\128\000\137\000\128@\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@r\004\002\001\136Q\029\218\016\006\245\006\000#\024\129A\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\129@gh\000\008\144\008\004\000B\001\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\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\132\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\015\254\191\130\011\145 \018\013B\184\238\240\1287\1680\t\030\198\026\008\000\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\003;@\000\196\128@\000\002\016\008 \000\000\000\001H\000\008\006\001@gh\000\024\144\008\000\000B\001\004\245\170\240\000\169\016\001 \208*\012\237\000\001\018\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\002\144\000\016\012\002\128\206\208\0001 \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\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\206\208\0001 \016\000\000\132\002\008\000\000\000\000R\000\002A\160P\025\218\000\002$\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\001H\000\008\006\001@gh\000\024\144\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\005 \000 \024\005\001\157\160\000b@ \000\001\008\004\016\000\000\000\000\164\000\004\003\000\1603\180\000\012H\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\004\128\001\017\130l\178X\000\000\160\008 \000\029P\016(;\128\000\000\000\000\000\000\000\000\000\000\016\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\245\170\240\000\169\016\001 \208*\012\253\000\001\018\001\000\128\008H \128\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\020\128\000\144h\020\006v\128\000\137\000\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\002\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\n\000\128\000\001\209\000\002\131\184\000\000\000\000\164\000\004\131@\1603\180\000\004H\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\002\144\000\018\013\002\128\206\208\000\017 \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\004\000\000\000\000\000\000\000\000\000\000\000\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\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\020\001\000\000\003\"\000\005\003p\000\000\000\001H\000\008\006\001@gh\000\024\144\008\000\000B\001\004\000\000\002@\000\136A6\017,\000\000P\004\000\000\012\136\000\020\013\192\000\000\000\005 \000 \024\005\001\157\160\000b@ \000\001\008\004\016\000\000\t\000\002!\004\216D\176\000\001@\016\000\0002 \000P7\000\000\000\000\020\128\000\128`\020\006v\128\001\137\000\128\000\004 \016@\000\000$\000\008\132\019a\018\192\000\005\000@\000\000\200\128\001@\220\000\000\000\000R\000\002\001\128P\025\218\000\006$\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\001H\000\008\006\001@gh\000\024\144\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\005 \000 \024\005\001\157\160\000b@ \000\001\008\004\016\000\000\t\000\002!\004\216D\176\000\001@\016\000\0002 \000P7\000\000\000\000\020\128\000\128`\020\006v\128\001\137\000\128\000\004 \016@\000\000$\000\008\132\019a\018\192\000\005\000@\000\000\200\128\001@\220\000\000\000\000R\000\002\001\128P\025\218\000\006$\002\000\000\016\128A\000\000\000\144\000\"\016M\132K\000\000\020\001\000\000\003\"\000\005\003p\000\000\000\001H\000\008\006\001@gh\000\024\144\008\000\000B\001\004\000\000\002@\000\136A6\017,\000\000P\004\000\000\012\136\000\020\013\192\000\000\000\005 \000 \024\005\001\157\160\000b@ \000\001\008\004\016\000\000\t\000\002!\004\216D\176\000\001@\016\000\0002 \000P7\000\000\000\000\020\128\000\144h\020\006v\128\000\137\000\128`\004 \016@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000R\000\002\001\128P\025\218\000\006$\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\001H\000\008\006\001@gh\000\024\144\008\000\000B\001\004\000\000\002@\000\136A6\017,\000\000P\004\000\000\012\136\000\020\013\192\000\000\000\005 \000 \024\005\001\157\160\000b@ \000\001\008\004\016\000\000\t\000\002!\004\216D\176\000\001@\016\000\0002 \000P7\000\000\000\000\020\128\000\128`\020\006v\128\001\137\000\128\000\004 \016@\000\000$\000\008\132\019a\018\192\000\005\000@\000\000\200\128\001@\221\235U\224\001R \002A\160T\025\218\000\002$\002\001\000\016\128A\000\000\000\000\000\000\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\005 \008$\026\005\001\157\160\000\"@ \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\255\215\240yr$\002\001\140W\029\222\016\006\245\006\000#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\001H\000\t\006\129@gh\000\008\144\008\004\000B\001\004\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\020\128\000\144h\020\006v\128\000\137\000\128@\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\001\000\000\000\000@\000\000\000\000\000\001\008\128\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\255\235\248 \185\018\001\000\196+\142\239\008\003z\131\000\017\172@\160\159\253\127\004\023\"@$\026\133\241\221\225\000oP`\0185\138\020\019\255\175\224\242\228H\004\003\024\174;\188 \013\234\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\015\254\255\195\203\145 \016\012b\248\238\241\1287\1690\129\030\199\026\204\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000?\250\254\008.D\128@1\138\227\187\194\000\222\160\192\004k\016('\255_\193\005\200\144\t\006\161|wx@\027\212\024\004\141b\133\004\255\235\248 \185\018\001 \212+\142\239\008\003z\131\000\145\172A\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\000\000\000\000\000\000\000\000\000$\000\008\140\019e\146\192\000\005\000A\000\000\238\128\137A\220\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\164\000\004\131@\1603\180\000\004H\004\002\000!\000\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\002\003\144 \016\012B\136\238\208\1287\1680\001\024\196\n\008\000\000\000@r\004\002\001\136Q\029\218\016\006\245\006\000#\024\129A\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\128\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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\164\001\004\131@\1603\180\000\004H\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\002\144\004\018\013\002\128\206\208\000\017 \016\008\000\132\002\008\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\n@\000H4\n\003;@\000D\128@ \002\018\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000 9\002\001\000\196(\142\237\008\003z\131\000\017\140@\160\128\000\000\004\007 @ \024\133\017\221\161\000oP`\0021\136\020\016\000\000\000\000\000\000\000\000\000\000\001\000\000\000\008\000\002\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\004\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\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\002 \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\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\005 \000$\026\005\001\157\160\000\"@ \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\128\001\001\130\012\146X\000\000\128\000 \000\012\208\017 #\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\128\005H\128\t\006\129Pg\232\000\008\144\008\004\000BA\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\004\007 @ \024\133\017\221\161\000oP`\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\016\000\000\000\000\000\000\000\000\000\000\000\000\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\248 \185\018\001 \212+\142\239\008\003z\131\000\145\172@\160\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\255\191\240\242\228H\004\003\024\190;\188`\013\234L 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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\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\128\004\000\128\000\004\000\016\000\000\000\000\016\000\000\000\000\000\000\002E\012\000\000\000\000\000@ \004`\000\000\002\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\003\214\171\192\002\000@\000\002\000\008\192\000\000\000\000\000\002\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000\000\000\000\000\005 \000$\026\133\001\189\160\000\"@ \016\001\008\004\016\000\000\000\000\164\000\004\0030\1603\180\000\012H\004\n\128!\004\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\002\144\000\016\012\002\128\206\208\0001 \016\000\000\132\002\008\000\000\000\000R\000\002A\160P\025\218\000\002$\002\001\000\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\245\170\240\000\169\016\001 \208*\012\237\000\001\018\001\000\128\008@ \128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\006v\128\001\137\000\128\000\004 \016@\000\000\000\002\144\000\018\013\002\128\206\208\000\017 \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\n@\000@0\n\003;@\000\196\128@\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\001\000\192(\012\237\000\003\018\001\000\000\008@ \128\000\000\000\005 \000 \024\005\001\157\160\000b@ \000\001\008\004\019\214\171\192\002\164@\004\131@\1683\180\000\004H\004\002\000!\000\130\000\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\016\012\002\128\206\208\0001 \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\016\000\004\004\0082I@\000\002\000\000\128\000!@D\000\012\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\003\214\171\192\002\164@\004\131@\1683\244\000\004H\004\002\000! \130\000\000\000\000\000\000\000\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\000R\000\002A\160P\025\218\000\002$\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\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\206\208\000\017 \016\008\000\132\002\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\004\000\000\000\000\000\n@\000H4\n\003;@\000D\128@ \002\016\008 \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\164\000\004\0030\1603\180\000\012H\004\n\128!\004\130\000\000\000\002\020\128\000\128f\020\006v\128\001\137\000\129P\004 \144@\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\002A\168P\027\218\000\002$\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\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\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\004\000\000\000\000\000\000\000\000\n@\000@3\n\003;@\000\196\128@\136\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\005 \000 \025\133\001\157\160\000b@ D\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\004\000\000\000\000\000\000\000\001\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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 \000A\128J\000\000\016\000\000\000\001\002\000 \000`\000\000\000\001H\000\008\006\001@gh\000\024\144\008\000\000B\001\004\000\000\002\000\000\128\001\006\001(\000\000@\000\000\000\004\008\000\128\001\128\000\000\000\005 \000 \024\005\001\157\160\000b@ \000\001\008\004\016\000\000\008\000\002\000\004\024\004\160\000\001\000\000\000\000\016 \002\000\006\000\000\000\000\020\128\000\128`\020\006v\128\001\137\000\128\000\004 \016@\000\000 \000\008\000\016`\018\128\000\004\000\000\000\000@\128\008\000\024\000\000\000\000R\000\002\001\128P\025\218\000\006$\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\001H\000\008\006\001@gh\000\024\144\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\005 \000 \024\005\001\157\160\000b@ \000\001\008\004\016\000\000\008\000\002\000\004\024\004\160\000\001\000\000\000\000\016 \002\000\006\000\000\000\000\020\128\000\128`\020\006v\128\001\137\000\128\000\004 \016@\000\000 \000\008\000\016`\018\128\000\004\000\000\000\000@\128\008\000\024\000\000\000\000R\000\002\001\128P\025\218\000\006$\002\000\000\016\128A\000\000\000\128\000 \000A\128J\000\000\016\000\000\000\001\002\000 \000`\000\000\000\001H\000\008\006\001@gh\000\024\144\008\000\000B\001\004\000\000\002\000\000\128\001\006\001(\000\000@\000\000\000\004\008\000\128\001\128\000\000\000\005 \000 \024\005\001\157\160\000b@ \000\001\008\004\016\000\000\008\000\002\000\004\024\004\160\000\001\000\000\000\000\016 \002\000\006\000\000\000\000\020\128\000\128`\020\006v\128\001\137\000\128\000\004 \016@\000\000 \000\008\000\016`\018\128\000\004\000\000\000\000@\128\008\000\024\000\000\000\000R\000\002\001\128P\025\218\000\006$\002\000\000\016\128A\000\000\000\128\000 \000A\128J\000\000\016\000\000\000\001\002\000 \000`\000\000\000\001H\000\008\006\001@gh\000\024\144\008\000\000B\001\004\000\000\002\000\000\128\001\006\001(\000\000@\000\000\000\004\008\000\128\001\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\000\000\000\000\000\000R\000\002\001\152P\025\218\000\006$\002\005@\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\001H\000\008\006a@gh\000\024\144\008\021\000B\t\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\005 \000 \025\133\001\157\160\000b@ T\001\008$\016\000\000\000\000\164\000\004\0030\1603\180\000\012H\004\008\128!\004\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\002\144\000\016\012\194\128\206\208\0001 \016*\000\132\018\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\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\128\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\245\170\240\000\128\016\000\000\128\0020\000\000\000\000\000\000\128\000\008\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\008\000\000\000\000\000\000\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\222\208\000\017 \016\008\000\132\002\008\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\016\000\000\000\000\000\000\000\000\000\000\000\000@\000H\000\000\000\000\000\000\000\002\000\000\128\000\000\000\000\000\000\000\008\000\t\000\000\000\000\000\000\000\000@\000\016\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000z\213x\000@\008\000\000@\001\024\000\000\000\000\000\000@\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\016\000\004\000\000\000\000\000\000)\000\001 \212(\013\237\000\001\018\001\000\128\008@ \128\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\235U\160\001\000 \000\000\000\004\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\016\000\004\000\000\000\000\000\000)\000\001 \212(\013\237\000\001\018\001\000\128\008@ \128\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\255\215\240Ar$\002\001\140W\029\2220\006\245\006\000#X\129A\000\000\000\000\000\000\000\008\004\000\000\000\004\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\255\235\248 \185\018\001\000\198+\142\239\024\003z\131\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001 \000D`\155,\150\000 (\002\t\000\007t\004\n\014\224\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000 \000\008\000\000\000\000\000\000R\000\002A\168P\027\218\000\002$\002\001\000\016\128A\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\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\128\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\245\170\240\000\128\016\000\000\128\0020\000\000\000\000\000\000\128\000\008\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\008\000\000\000\000\000\000\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\222\208\000\017 \016\008\000\132\002\008\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\002\001\000\128\000\000\000\128\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\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\224\130\228H\004\131P\174;\188`\013\234\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\015\254\191\130\011\145 \016\012b\184\238\241\1287\1680\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\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\128\005H\128\t\006\129Pg\232\000\008\144\008\004\000BA\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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001\000\000\000\000\000\000\000\000\000\000\000\000\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=j\188\000 \004\000\000 \000\140\000\000\000\000\000\000 \000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\000\002\000\000\000\000\000\000\020\128\000\144j\020\006\246\128\000\137\000\128@\004 \016@\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000u\170\208\000\128\016\000\000\000\002\000\000\000\000\002\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\001\000\000\000\000\000\000\000\000\000\000\008\000\002\000\000\000\000\000\000\020\128\000\144j\020\006\246\128\000\137\000\128@\004 \016@\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\003\255\175\224\130\228H\004\131P\174;\188`\013\234\012\"F\177\002\179\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\007\255_\193\005\200\144\t\006\161\\wx\192\027\212\024\004\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\008\000\000\000\000\140\002\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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@r\004\002\001\136Q\029\218\016\006\245\006\000#\024\129A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\004\000\000\000@\000\000\000\000\000\000\000\000\001\000\001\255\223\248Ar4\002a\168_\029\2220\014\245&\019#\216\235Y\128\000\000\008\014@\128@1\n#\187B\000\222\160\192\004c\016( \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\255\235\248 \185\018\001\000\198/\142\239\008\003z\131\000\017\236q\160\128\000\000\000\000\000\000\004\002\000\000\000\000\000\000\000\000\016\000\000\000\003\255\175\224\130\228H\004\003\024\190;\188 \013\234\012\000G\177\198\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\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\000\000\000?\250\254\008.D\128H5\011\227\187\194\000\222\160\192${\028h \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\255\235\248 \185\018\001 \212/\142\239\008\003z\131\000\145\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\128\000\000\000\000\000\000\000\000\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\002\000\003\255\175\224\130\228H\004\003\024\190;\188 \013\234\012\000F\177B\130\000\000\000\000\000\000\000\016\008\002\000\000\000\000\000\000\000@\000\008\000\015\254\191\130\011\145 \016\012b\248\238\240\1287\1680\001\026\197\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\000\000\000\000\000@ \016\004\000\000\000\000\000\000\000\128\000\016\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\224\130\228H\004\131P\190;\188 \013\234\012\002F\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\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000 #\000\000\000\016\000\000\000\000\128\000\000\000\000\000\000\008\0000\016\000\000\000\000\004\000\000\000\128\000\004\000_\253\127\004\023\"@ \024\197q\221\225\000oP`\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\004 \024\008\000\000\000\000\002\000\000\000@\000\002\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\255\215\240Ar4\002a\168W\029\222\016\014\245\006\001#X\137A\191\250\254\008.D\128@1\138\227\187\194\000\222\160\192\004k\016( \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\127\004\023#@&\026\133q\221\225\000\239P`\0185\136\148\024\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\128\000\000\000\000\000\000\000\000\002\000\003\255\175\224\130\228H\004\131P\190;\188 \013\234\012\002F\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\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\004\002\000\000\000\002\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\127\245\252\016\\\137\000\144j\021\199w\140\001\189A\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\000\000\000\007\191_\192\005H\144\008\006\001Pgx\000\024\144\008\000\001b\005\004\000\000\000\000)\000A \208(\012\237\000\001\018\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\001\000\000\000\000\000\000\000\000\000\000\000\000\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~\191\128\n\145 \016\012\002\160\206\240\0001 \016\000\002\196\n\008\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\002\000\000\000\000\000\000\000\000\000\000\000\000\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\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\001\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\001\000\000\000\000\000\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\218\000\002$\002\001\000\016\128A\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\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\001\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\004\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\001\235U\224\001\000 \000\001\000\004`\000\000\000\000\000\001\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\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\189\160\000\"@ \016\001\008\004\016\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000F\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\004\000\000\000\000\000\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@oh\000\008\144\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\001\214\171@\002\000@\000\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\001\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\n@\000H5\n\003{@\000D\128@ \002\016\008 \000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\002\000\003\223\175\224\002\164H\004\003\000\1683\188\000\012H\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\008\012\016d\146\192\004\004\000\001 \000b\128\129\001\024\000\000\000\000\000\000\128\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\001H\000\t\006\161@oh\000\008\144\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\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\016\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\030\181^\000\016\002\000\000\016\000F\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\001\000\000\000\000\000\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\218\000\002$\002\001\000\016\128A\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000z\213x\000T\136\000\144h\021\006~\128\000\137\000\128@\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\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000#\000\000\000\016\000\000\000\000\000\000\000\000\000\000\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\020\128\000\144j\020\006\246\128\000\137\000\128@\004 \016@\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\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\180\000 \004\000\000\000\000\128\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\016\000\000\000\000\000\000\000\000\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\164\000\004\131P\1607\180\000\004H\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\008\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\016\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000 \000\000\002\0020\000\000\001\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\002\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\002\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\000\001\255\215\240Ar$\002\001\140W\029\222\016\006\245\006\000#X\129A\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\157\160\000\"@ \016\001\008\004\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\127\245\252\016\\\137\000\144j\021\199w\132\001\189A\128H\2460\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\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\016\000\000\000\000\000\000\001\127\245\252\016\\\137\000\128c\021\199w\132\001\189A\128\008\214 P@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\255\215\240Ar$\002\001\140W\029\222\016\006\245\006\000#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\002\000\000\000\000\000\000\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\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\000\020\128\000\144h\020\006v\128\000\137\000\128\000\004 \016@\000\000\000\000\000\128\000\000\000\000\000\000\000@\000\000\000\000\000\000\004\000\000\000\000R\000\002A\160P\025\218\000\002$\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\001H\000\t\006\129@gh\000\008\144\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\008\000\000\000\000\000\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\002\000\000\000\000\000\000\000 \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\029\218\016\006\245\006\000#\024\129A\000\000\000\000\000\002\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\016\000\000\001\001\200\016\008\006!Dwh@\027\212\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\004\007 @ \024\133\017\221\161\000oP`\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\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\008\000\000\000\000\000\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001H\000\t\006\129@gh\000\008\144\008\000\000B\001\004\000\000\000\000\000\008\000\000\000\000\000\000\000\004\000\000\000\000\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\127\245\252\000@\008\000\000@\001\000\001\000\000\001\000\000\000\016\000\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\016\000\000\000\000\000\000\000\008\000\000\000\000\000\000\000\191\250\254\000 \004\000\000 \000\128\000\128\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\255\235\248\000\128\016\000\000\128\002\000\002\000\000\002\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\128\000\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\n@\000H4\n\003;@\000D\128@\000\002\016\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\213x@\225\008\137 B\001\000\000\018\000B\148$\000\t\128 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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^\0008B\"\008\016\128@\000\004\128\016\165\t\000\002`\000\003\214\171\192\007\008@\001\002\016\008\000\000\144\002\020\161 \000L\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\004\001\000\128\000\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\004\000\000\016\004\000\000\000\016\000\000\000\000\000\128\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\004\000\000\000\016\000\000@\016\000\000\000@\000\000\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\004\000\000\002\000\000\000\000\000\000\002\000\000\000\000\000\000\000\008\000\000\002\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\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\003\214\171\192\007\008D\001\002\016\008\000\000\144\002\020\161 \000D\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015Z\175\000\028!\000\004\008@ \000\002@\008R\132\128\001\016\000\000\000 \000\000\128 \000\000\000\128\000\000\000\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\004\000\000\000\000\000\000\004\000\000\000\016\000\000@\016\000\000\000@\000\000\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\002\000\000\000\000\000\000\000\000\000\000\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\001\000\000\000\004\000\000\000\000\000 \000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\002\000\128\000\000\002\000\000\000\000\000\016\000@\000\000\000\000\000\016\000\000@\016\000\000\000@\000\000\128\000\002\000\008\000\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\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\128\000\000\000\000\004\000\016\000\000\000\000\000\004\000\000\016\004\000\000\002\016\000\000 \000\000\128\002\000\000 \000\000\000\128\000\002\000\128\000\000\002\000\000\000\000\000\016\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\002\000\000\008\002\000\000\000\008\000\000\000\000\000@\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\245\170\240\000\128\016\000\000\128\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\004\000z\213x\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\002\000\000\004\000\000\016\004\000\000\002\024\000\000\000\000\000\128\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001 \000\000\000\000\000\000\002\000\000\008\002\000\000\000\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\001\000\000\004\001\000\000\000\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\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\017\128\000\002\004\016\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\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001\000\000\004\001\000\000\000\004\000\000\000\000\000 \000\128\000\000\000\000\000 \000\000\128 \000\000\002\128\000\001\000\000\004\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\128\000\000\000\000\000\000\000\000\000\000\000\000\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\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\128 \000\000\000\128\000\000\000\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\016\000\000@\016\000\000\000@\000\000\000\000\002\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000\004\001\000\000\000\004\000\000\000\000\000 \000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\128\000\002\000\128\000\000\003\000\000\000\000\000\016\000@\000\000\000\000\000\016\000\000@\016\000\000\t@\000\000\128\000\002\000\008\000\000\128\000\000\002\000\000\008\002\000\000\000\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\008\000\000\008\000\000 \008\000\000\000 \000\000\000\000\001\000\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\016\000\000\000@\000\001\000@\000\000\001\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\016\000\000\008\000\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\000\008\000\000\000\000\002\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001\000@\000\000\001\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\008\000\000\000\000\000\000\008\000\000\000 \000\000\128 \000\000\000\128\000\000\000\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\008\000\000\004\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\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\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\000\000 \008\000\000\000 \000\000\000\000\001\000\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\016\004\000\000\000\016\000\000\000\000\000\128\002\000\000\000\000\000\000\128\000\002\000\128\000\000\n\000\000\004\000\000\016\000@\000\004\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\002\000\000\000\000\000\000\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[\175\000\012\001\000\000\008D \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\128\000\000\000\000\000\000\000\128\000\002\000\128\000\000\011\000\000\004\000\000\016\000@\000\004\000\000\000\016\000\000@\016\000\000\000@\000\000\000\000\002\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\007\173\215\128\006\000\128\000\004#\016\000\000\000\000\016\000@\000\000\000\000\000\016\000\000@\016\000\000\000@\000\000\000\000\002\000\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\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\001\000\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\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\008@\000\000\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\001\000@\000\000\001\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\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\213x@\225\008\137 B\001\000\000\018\000B\148$\000\t\128 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\003;@\000D\128@ \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\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\000\000\000\000\000\000\n@\000H4\n\003;@\000D\128@ \002\016\008 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000b\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\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\006v\128\000\137\000\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\001\004\000\000\000\000\000\n@\000H4\n\003;@\000D\128@\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\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000?\251\255\008.D\128H=\014\227\187\194\000\222\164\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\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\015\254\255\194\011\145 \018\015B\184\238\240\1287\1690\137\026\196\n\204\239\223\184\001\000 \000\000\000\004\000\000\000\000\000 \000\000\000\000\000\000\145C\000\000\000\000\000\000\008\000\000\000\000\000\004\000\000\000\000\000\003\191~\224\004\000\128\000\000\000\016\000\000\000\000\000\128\000\000\000\000\000w\239\220\000\128\016\000\000\000\002\000\000\000\000\000\016\000\000\000\000\000\000H\161\128\000\000\000\000\000\004\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000$P\192\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\004\138\024\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\145C\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\018(`\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?\250\254\015.D\128@1\138\227\187\194\000\222\160\192\004k\016('\255_\193\005\200\144\008\0061\\wx@\027\212\024\000\141b\005\004\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253\127\004\023\"@ \024\197q\221\225\000oPa\0025\136\021\152\000\000\000\000\000\000\000\128@\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\128@ \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\007\255_\193\005\200\144\t\006\161\\wx@\027\212\024D\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\005 \000 \025\133\001\157\160\000b@ T\001\008\004\016\000\000\000\000\000\000\000\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\015\254\191\131\203\145 \016\012b\184\238\240\1287\1680\001\026\196\n\t\255\215\240Ar$\002\001\140W\029\222\016\006\245\006\000#X\129A\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\007\255_\193\005\200\144\008\0061\\wx@\027\212\024@\141b\005f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\031\253\127\007\151\"@ \024\197q\221\225\000oP`\0025\136\020\019\255\175\224\130\228H\004\003\024\174;\188 \013\234\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000=\251\255\000 \004\000\000 \000\128\000\000\000\000\132\000\000\000\000\000\000\018(`\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\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\192\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\007\173W\128\004\000\128\000\004\000\017\128\000\000\000\000\000\004\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\192\002\000@\000\002\000\008\192\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\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\001\016\000=j\188\000 \004\000\000 \000\140\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\016\000\000\000\000\000\000\000\000\000\000\000\000\127\245\252\016\\\137\000\144j\021\199w\132\001\189A\128H\214 \208@\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\145C\000\000\000\000\000\016\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\002\001\000\128\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\000\031\253\127\004\023\"@$\026\133q\221\225\000oPa\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\0020\000\000\001\000\004\000\000\000\006 \000\000\000\000\004\002\000\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\164\000\004\131@\2243\180\000\004H\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\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\000\000)\000\001 \208(\012\237\000\001\018\001\000\128\008@ \128\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\000\127\247\254\016\\\137\000\144z\029\199w\132\001\189I\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\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\031\253\255\132\023\"@$\030\133q\221\225\000oRa\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\127\247\254\016\\\137\000\128c\021\199w\132\001\189I\132\008\214 V`\000\000\000\000\000\000\002\001\000\000\000\000\000\000\000\000\136\000\000\000\197\255\223\248Ar$\002\001\140W\029\222\016\006\245&\016#X\129Y\128\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\255\127\225\005\200\144\t\006\161\\wx@\027\212\152D\141b\005f\255\239\252 \185\018\001\000\198+\142\239\008\003z\147\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\001\000\128@\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\015\254\255\194\011\145 \018\013B\184\238\240\1287\1690\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?\251\255\008.D\128H5\n\227\187\194\000\222\164\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\255\239\252 \185\018\001 \212+\142\239\008\003z\147\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\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\255\239\252 \185\018\001 \212+\142\239\008\003z\147\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\001\000\128@\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\015\254\255\194\011\145 \018\013B\184\238\240\1287\1690\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\000\016\000\000\000\001\024\000\000\000\128\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\000@\004\128\000\000\000\000\000\000\000\000H\156\000\192\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\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\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\016 \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\000\016\000\000@\128\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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\001\000\000\000\000\000\002\000\000\008\016\000\000\000\000\000\000\002\000\000\000\004\000\000\000\000\008\000\016\000\016\000\000\000\000\000\000\000\017\128\016\000 \020\000\000\000\000\000\008\000\000 @\000\000\000\000\000\000\008\000\000\000\016\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001\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\000 \000\000\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\156\000\192\000\000\128\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000@\000\000\000\000\000\000\000\000\000F\000`\000\000@\000\000\000\004\000\008\000\000\000\000\000\000\000\000\000\008\192\008\000\000\008\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\0020\002\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\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\024\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\008\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000\000\000\000\000\000\000\000\019\128\024\000\000\016\000\000\000\001\000\002\000\000\000\000\000\000\000\000\000\0020\003\000\000\002\000\000\000\000 \000@\000\000\000\000\000\000\000\000\000F\000@\000\000@\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\008\192\008\000\000\008\000\000\000\000\000\001\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\000\002\000\000\000\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\008\000\016\000\000\000\000\000\000\000\000\000\017\128\024\000\000\016\000\000\000\001\000\002\000\000\000\000\000\000\000\000\000\0020\002\000\000\002\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000F\000@\000\000@\000\000\000\000\000\008\000\000\000\000\000\000\000\000\000\008\192\000\000\000\008\000\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\000 \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000@\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\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\000\000\000\000\000\000\000\000")
   
   let action =
-    ((16, "\000\212\000\031\000\000\000\000\000\235\000\000\000\000\000\000\000\212\000\000\000\228\031D\000\000\000\129F\002\000\000\000\000\026v\000\000\031\210\000\000\000\000\000\000\000\000\000\000\000\000\027b\000\000 d\000\000\000\000\000\000\000\000\000\000!P\000\000\000\000\000\000\000k\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\165\000c\000\000\031D!\158G\168\000+GD\000\000\000\000\000\0000h\000rG\168\000\015G\168\000\000\000\156\000\000G\168\000\000\000k\003\250<J\000\000\000\000>\144\000\000@\182\000\000Ad<J<J\018~\018~@\182\018~\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000?:<J\000\000\000\000?:\000\000?:\000\000?:\000\000\000\000\000\000\020\246\000k\000\000\018~\000\0004^<J\027\176<J\000\000\000\000\000\000\000\000\000\000\000\000\"d<J\000\000#X<J$L<J%@<J\000\000<J\000\000<J&4<J'(<J(\028<J)\016<J*\004<J\000\230<J\000\000\000\000\000\000\000\000\000\000<J*\248<J+\236<J,\224<J\000\000\000\000<J\000\000\000\000\021\144.D\000\000\000\000\000\250\000\000\000\000\000\000\000\000\019F\000\129\000\000.:\000\000\000\160\018~\000\000<J\001\028\000\000\000\000\000k\000\000\000\000\000\000\000\000\001F\000\000\000\000\001\210\000\000\001\212@\182\000\000\000\000\000\000\000\000\000\000\000\000A\232<J\000\000A\232\000\000A\232A\232\000\000\000\0003\018\000k\000\000\018~\001\228\000\000<J\002D\000\000\000\000\000k\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000FP<J\000\000<J\000\000\000\000\002\136\000\000\000=?\228\003\158<J\003p\000\000\000\000@\182\000=\000\000\000\000\000\000\000\000\000\000G\164@\182HT@\182H\210@\182I$@\182\000\000@\182\000\000@\182I\162@\182J\018@\182Jl@\182J\220@\182KZ<J\003*@\182\000\000@\182K\172@\182L*@\182L\154\003\016\000\000\003V\000\000\001\016<J\000\000\001\016\000\000\000\000\000\234\031D\000\000\000\234\000\000\000\000\003X<J\000\000\003\136\000\000\018~\003\150\000\000\000\000\004r\000\000\018~\003\238\000\000\000\000\004(\000\000\000\000\003\250\000\000\005\030\000\000.DM\030\005\008\005\012\000k\004\134\005BN\012\001\168\000\000\000\000\002$Oh\000\000\000\000\000\000\005^\005`\000k\005\146N\012\002nN\012\000\000\000\000\001\028\000\000\000\000\004\232\000\000\004\234\005\224N\012\005.\000\000\000\000\002$\000\000\005D\006\028\000\000O\150Nv\000\000\000k\0068\000\000\019F\000k\006l\000\000\000\000-\178G\168\005\150\000\000\006\018\000\000\005\156\000\000\000\029\031D\000\000\031D\000\000\005\138\000\000\000\029\000\000\015\238\0086\006\\N\012\005\168\006\130\000\000(\004\000\129\000\000\000|\001\208\031D\005\182\000\000\0009\000\000\000\023\000\000\006\140\000\000\000\000\023~\000\129\000\000\0009\000\000\000\000\000\000\000\000\000\000\006r<J\005\190\019<\006x<J\005\196\006v\000\138\005\240\006\162\000\000B0B\180\018~\005\206\000\000\005\208B\180\000\000\000\000\000\000\000\000\000\000\000\000\000\000C^<J\000\000C^\000\000C^C^\000\000\000\000\024\204\000k\000\000\018~\005\214\000\000<J\005\214\000\000\000\000\000k\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000/\184<J\000\000<J\000\000\005\222\000\000\001\016\000\000\000\000\000\000\000\000\000\0004\184B\1805\172B\1806DB\1806\220B\180\000\000B\180\000\000B\1807tB\1808\012B\1808\164B\1809<B\1809\212<J\006\008B\180\000\000B\180:lB\180;\004B\180;\156\018~\005\228\000\000\000\000<\244\000\000\006\190\000\000\001R\006\156<J\006n\000\000\006\170<J\006~\000\000\007(\000\000\006\162\006\162\001R\000\000\001R\000\000\015\238\006\162\006\162\000\000\000\000\000\000\023\216\000\000\000\000\000\000\000\000\006\206<J\006 \019<\020\016\000k\007\000\000\000\006\228=\158\007\n=\158\007\018<J\006@\019<\019<\002`\003\180\001p\000\000\000\000\000\000\003\180\000\000\004v\002`\000\000\000\000\006B\000\000\000\000\000\000\007\026\000\000\007 \000\000\000\000\007X\007\018<J\006^\0078\000\000@\134\007\026\018~\006j\019<\000\000\000\000\006\146\000\000\000\148\000\000\005N\000\000\001R\000\000\000\000\006\224\000\000$4\0086\007&N\012\006t\007L\000\000\000k\000\000\002p<J0\142\000\000C\226<J\006z\000\000\018~\006|\000\000\006\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000D\140<J\000\000D\140\000\000D\140D\140\000\000\000\000\029H\000k\000\000\018~\006\134\000\000<J\006\146\000\000\000\000\000k\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\018~\006\154E\016\000\000\000\000<J\001\004<J\006\158\000\000\000\0001</\016\007N<J\000\000\007\024\000\000\000\000\000k\000\000\000\000\006\2200\142\000\000\006\2200\142\000\000\001\250\000\000\000\000\017\172E\016\023^E\016\026\158E\016\029\240E\016\000\000E\016\000\000E\016\030rE\016\031\136E\0163vE\0164\200E\016C\016E\016D>E\016H\"E\016O\240\000\000\006\178\000\000\006\2241\234\000\0002\152\006\2402\1523\190\006\2442\152\000\000\000\000\000\000\000\000\000\000\006\232\000\000\007\198\000\000\000k\000\000\002p\007\204\000\000\007\174\007\158\000k\007\000\007\190N\012\007\018\000\232\000\000<J\007\236\000\000\000\127\003\226\004x\007\212N\012\007 \007\248\000\000\003\028<J\007\250\000\000\008\000\000\000\019F\000k\003$<J\008\006\000\000\008\n\000\000\011\242\001\028\000\000\011\242\000\000\000\000\021\234\003F<J\008\012\000\000\008\014\000\000\000\000\007\248\007\234\000k\007L\008\006N\012\007T\001\252\000\000<J\008.\000\000\001\028\000\000\000\000\007\246\000\000\011\242\000\000\008\022\018~\007b\008:\000\000\000>\000\000\008\"N\012\007t\008T\000\000\003\248<J\008X\000\000\008^\000\000\019F\000k\004\166<J\008d\000\000\008f\000\000\000\000\000\000\007\246\000\000\000\000\001\028\000\000\006\162\000\000\000>\000\000\000\000\001\254\020\016\000\000\001\254\000\000\000\000\007\150\000\000\003\024\000\003\019<\000\000\003\250\000%\003\250\000\000\000\148\000\000\006\162\000\000\006\162\000\000\000\000\000\000\007\144\000\000\000\000\007\154\000\000\003:\005N\000%\003\250\000\000\000\000\000\000\000\148\000\000\006\162\000\000\003:\000\000\000\000\000\234\000\015\015\238\000\000\020\016\000\000\tJ\015\238\000\000\000\000\tJ\000\000\000\000\007\156\000\000\000\000\007\174\000\000\004z\006\162\000\000\004z\000\000\000\000\008&\000\000\001\028\000\000\006\162\000\000\000\000\000\000\0176>H\000\000\008\140\000\000\0176\008\142\000\000\008\148\000\000$4\000k\002*\000\000<J\008\150\000\000\008x\008h\000k\007\200\008\128N\012\007\204\002\180\000\000<J\008\166\000\000\000\127\003\174\000\000<J\008\168\000\000\019F\000k\004:\000\000<J\008\172\000\000\004\174\0176\000\000\021\234\005d\000\000<J\008\174\000\000\000\000\000\000\008\144\008\132\000k\007\236\008\164N\012\007\242\005\198\000\000<J\008\204\000\000\005\026\000\000\008\174\018~\007\250\008\210\000\000\004\018\000\000\005\248\000\000<J\008\218\000\000\019F\000k\005\254\000\000<J\008\224\000\000\004\174\000\000\000\000\008*\000\000\005\026\008\226\008\158\000\000\000\000\000\000\008\174\000\000\000\027\002r\000\000\015\238\t\000\000\000\000\000<J\008f\006\162\000\000\008<\000\000\000\138\000\000\000\000\000\025\015\238\000\000\015\238\000\000\008.\000\000\000\025\000\000@\182\002\154@\182\000\000@\182\000\000\0080\000\000\002\154\000\000\019<\004\220\019<\000\000\019<\000\000\0082\000\000\004\220\000\000@\182\002\154\0086\000\000#@\000k\0058#@\000\000#@\000\000\008H\000\000\0058\000\000@\182\002\154\008J\000\000\000\000\023\006\000\000\000\000\000\000\000\000\000\000\025\232\029\004\000\000\005\136\000\000\0008\000\000\000\000\008\150\000\127\000\000\000\000\000\000\000\000\000\230\0008\000\000\004\016\002\020\0008\000\000\000P\0008\000\000\008n\000\000\000\000\000\000\000\000\000\000\000\000\008\240\000\000\0304\000\000\031D\0008\000\000\003\240\0008\000\000\008\242\000\000\0008\008\244\000\000\007z\0008\008\252\000\000\t\002\000\000\n\194\0008\0008\008\140\0008\t\018\000\000\t\022\000\000\t\024\000\000\031D\000\000\001\164\031D\000\000\008\156\006\220\000\000\002\236\0008\000\000\004|\0008\000\000\005\012\001<\000\127\000\000\t\230\000\127\000\000\008\158\000\000\000\000\000\000\000\000\t \000\000\012\022\018\"\t$\000\000\t,\000\000\0008\t.\000\000\0008\t0\000\000\0008\t8\000\000\t\022\0008\tJ\000\000\0080\016\218\0008\008\208\0008\tN\000\000\tP\000\000\000\000\004\204\0008\000\000\005d\002\220\002\220\000\000\000\000\000\000\004\138\002\220\000\000\008\214\000\000\000\000\000\000\000\000\0008\000\000\005\136\0008\000\000\005\220\005\024\000\127\008\216\000\000\000\000\000\000\000\000\tZ\000\000\t\\\000\000\0008\t`\000\000\012,\018\"\tb\000\000\tj\000\000F\006\t \tL\017l\0008\t~\000\000\000\000\t\130\000\000\tbF\006\0008\t\146\000\000\0008\t\148\000\000\t\150\000\000\n\216\t\028\0008\t\156\000\000\t\158\000\000\000\127\t\024\000\000\000\000\023\006\000\000\000\000\002F\n\002\000\000\000\000\001\027\000\000\000\000\000\000<J\000z\nB\tj\t\240@\182\000\000\0036@\182\000\000\tB\000\000\000\000\000\000\000\000\000\000\002\166\000\000\003\170\000\000\000\000\000\000\003\250&\028\003\202&\028&\028\003\202\000\000\000\000\0028\0028\0028\0028\000\000\000\000\000\000\000\000\000\000\000\000\001R\015\238\n\012\013F\001\028\000\000\000\000\001\028\000\000\007\246\000\0000\142\tH\000\000\001R\015\238\tV\014\154\000\000\001R\013F\000\000\000\000\000\000$4\t\156\000\000\000z\000\000\000\000\t\190\000\030\nHN\186\000\000\005\022P&\000\000\000\000\nJ\n:\000k\000\000\000k\000\000\005\022\000\000\005JN\186\000\000\000\000\t\152\nJ\006\162\t\152\000\000\nn\001\028\000\000\007\246\000\000\003\128\001\174\000\000\000\000\n8\000\000\000\000\002F\000\000\004\198\000\000\000\000\000\000<J\000z\000\000\002\166\000\000\005\n\000\000\000\000\000\000\005N\000\000\n\158\002b\n\158\000\000\006\162\n\158\000\000\003\196\000\000\006\162\000\000\006\162\000\000\006\162\000\000\000\000\000\000\000\000\000\000\000z\000\000\006\162\000\000\003\196\000\000\006\162\000\000\004\212\000\000\000\000\tJ\t\202\000\127\002\148\nt\002\142\000\000\002\142\n\160\000\000\n\162\000\000\n\166\000\000\000\000\003R\002\142\016\134\002\142\000\000\000\000\005>\t\180\000\000\tJ\n\170\000\000\006,\003^\n\186\011\194\n\186\000\000\000\000\002\030\000\127\000\000\002F\n\012\000\000\000\000\000\000\005\206\000\000\t\190\000\000\000\000\000\000\000\000\tJ\006,\003^\002\030\002F\005\206\t\192\000\000\006,\003^\002\030\002F\005\206\t\196\000\000\000\127\000\000\n\192\n\188\n\000\000\127\n\\\000\000"), (16, "\n\237\n\237\n\237\n\237\n\237\n\237\n\237\n\237\n\237\n\237\n\237\000:\n\237\n\237\n\237\n\237\n\237\n\237\n\237\n\237\n\237\n\237\000\n\001^\020\131\020\135\n\237\012\022\001j\020\139\006\025\006\002\n\237\016\130\n\237\n\237\n\237\000\158\007y\n\237\017r\008J\000\014\n\237\n\237\005\129\n\237\002\150\000\023\000\027\008~\005\129\008J\007y\000\218\n\237\000\162\000\194\n\237\n\237\004\t\008~\017v\000\250\n\237\n\237\000\162\n\237\006j\n\237\000\198\000J\017z\000N\n\237\000V\n\237\n\237\n\237\n\237\n\237\013\006\000Z\000\158\n\237\n\237\n\237\ny\n\237\n\237\n\237\005\129\n\237\n\237\n\237\n\237\006\n\0182\016\138\n\237\n\237\001^\017\134\007y\005Z\001f\001j\003\198\000\162\n\237\n\237\n\237\000\162\n\237\n\237\n\237\n\237\001^\n\237\t\158\n\237\012\022\001j\n\237\t\146\n\029\n\237\n\237\006\025\000\242\t\158\013~\n\237\008J\000\162\013\174\n\237\000\006\004\t\n\237\016B\000^\008~\n\237\n\237\n\237\n\237\000\162\n\237\n\237\000\162\007y\004\t\n\237\n\237\n\237\005\193\n\237\005\217\n\237\n\237\017\138\n\237\007y\n\237\n\237\012\002\013\006\n\237\n\237\006!\006!\006!\006!\006!\006!\006!\006!\006!\006!\006!\n\029\006!\006!\006!\006!\006!\006!\006!\006!\006!\006!\t\146\017\178\020\150\004\162\006!\008N\008^\008n\n\161\008J\006!\001^\006!\006!\006!\012\022\001j\006!\008~\t\158\n\209\006!\004\138\006\194\006!\000.\006\"\016\162\016\202\016\242\017\002\017.\016Z\006!\0069\0069\018\150\005\145\004\t\0069\000\158\002\206\006!\006!\000\162\003\137\001\006\006!\006!\000n\011\145\000r\006!\000z\006!\006!\006!\006!\006!\012\006\000~\002J\006!\006!\006!\022+\006!\006!\006!\000\162\006!\006!\006!\006!\022/\n\174\017\150\006!\006!\005\185\005\185\005\233\000\158\011\145\0222\000\162\005\129\t\158\006!\006!\002\166\006!\006!\006!\006!\000\218\006!\n\186\006!\006\142\005\241\006!\006\146\007e\006!\006!\021\n\007e\006\150\002\222\006!\000\162\012\194\006\154\021\014\011\145\011\145\006!\017z\000\130\011\145\006!\006!\006!\006!\0061\006!\006!\002\254\t\n\n\166\006!\006!\006!\006A\014\230\006A\006!\006!\006A\006!\013\138\006!\006!\017\166\023\146\006!\006!\006A\006A\006A\006A\006A\006A\006A\006A\006A\006A\006A\008r\006A\006A\006A\006A\006A\006A\006A\006A\006A\006A\n\137\018b\008J\002a\006A\020r\006A\002a\n\129\023\018\006A\008~\006A\006A\006A\006A\016\170\006A\006A\006A\006A\006A\006A\006A\006A\006A\005\169\012\198\003\n\003\018\n\222\023\022\000\158\006A\015\022\0061\006A\003f\023\026\0061\0061\006A\006A\006A\006A\006A\003\213\006A\006A\006\017\014\234\023\134\006A\020r\006A\023\154\006A\006A\006A\003\161\023\158\000\162\006A\006A\006A\005>\006A\006A\006A\005\161\006A\006A\006A\006A\019N\0061\008Y\014\170\006A\t\002\t\158\016\178\014\174\006A\t\146\t\218\n\137\003r\006A\006A\n\137\006A\006A\006A\006A\003\161\006A\023\"\006A\003\017\023n\006A\005f\011\206\006A\006A\002\141\n\137\008Y\008Y\006A\023\n\004\138\008Y\006A\006)\019R\006A\016.\015\026\003\190\006A\006A\000\162\006A\023:\006A\006A\023*\013\254\005\129\006A\0081\005\129\0035\018z\013\006\005\129\006A\005\129\006A\005\209\006A\006A\005\129\005\129\006A\006A\0002\006&\000F\000b\006>\000f\006\142\000j\000\134\006\146\000\138\015.\000\146\020\234\000\150\006\150\000\154\000\174\000\178\000\182\006\154\020\242\t\146\0126\001^\003\206\006\158\012V\012\022\001j\003\214\008J\000\186\004V\001\030\006\174\006\202\004\193\004z\006\206\008~\011\206\005\241\000\190\012\138\011\206\008:\006)\n\137\005\137\002\150\006)\006)\004%\020\174\001*\004\193\000\162\021.\005\249\n\145\015\214\011\206\006)\008\146\006\214\021Z\021f\001\026\008\150\013\186\007=\023J\004\130\001R\004\186\001V\003\229\000\206\t\154\008\158\015J\017\162\023B\006\234\001^\008\162\006)\006\238\008\166\001j\n\177\006\242\006\246\008\170\006\250\0152\001^\004\198\005\129\008\174\012\022\001j\007=\007=\008Y\004\210\006i\007=\t\158\006\254\007\002\004\189\008\178\008\182\007\006\008\186\t\006\000\162\004\222\008\206\005\177\004\193\003\193\020\219\020\223\008\218\007\014\004!\020\227\000\162\004\189\006I\013\"\005\137\n\137\021z\008Y\008Y\008\250\004\193\014~\008Y\008\254\t:\003\229\t\166\017\246\007\018\t>\004\234\011\206\005\137\007\022\003\229\003\229\005\137\016\210\013\006\003\229\tF\n\193\007\026\006i\006I\006I\015N\015^\001\154\006I\0002\006&\000F\000b\006>\000f\006\142\000j\000\134\006\146\000\138\004\246\000\146\020\234\000\150\006\150\000\154\000\174\000\178\000\182\006\154\020\242\0039\015\186\001^\005\n\006\158\004\189\012\022\001j\005\026\n\185\000\186\017\014\001\030\006\174\006\202\0039\018\146\006\206\0085\005\030\019\154\000\190\t\"\004\189\008:\018\134\003\021\006\001\013B\004\138\016\218\023:\019b\001*\005&\000\162\008J\005*\015n\n\153\0085\006Y\008\146\006\214\021Z\008~\011\206\008\150\014\002\008\145\0085\005R\001R\006\t\001V\003\245\000\206\t\154\008\158\017j\019J\005V\006\234\001^\008\162\019>\006\238\008\166\001j\000\162\006\242\006\246\008\170\006\250\022K\022O\017\022\005^\008\174\022S\0085\008\145\008\145\005\130\005\138\006Q\008\145\015\166\006\254\007\002\005\225\008\178\008\182\007\006\008\186\0039\000\162\006Y\008\206\0039\0039\003\193\021\190\n\201\008\218\007\014\005\153\005\241\022o\022s\006q\0039\015\222\022w\t\158\015\250\005\142\008\250\005\150\0035\019\150\008\254\t:\015r\t\166\0085\007\018\t>\021\238\005\170\005\174\007\022\002\129\003\245\0035\0039\005\201\023B\tF\0085\007\026\006Q\006q\006q\005\198\006a\001\154\006q\0002\006&\000F\000b\006>\000f\006\142\000j\000\134\006\146\000\138\019\138\000\146\020\234\000\150\006\150\000\154\000\174\000\178\000\182\006\154\020\242\005\214\023\166\015\170\005\234\006\158\005\242\005\250\006\023\006.\0066\000\186\006:\001\030\006\174\006\202\006Z\006r\006\206\005\129\006\162\006\170\000\190\006\178\006\186\008:\006\190\006\198\015\226\006\222\006\230\015\254\006a\007>\001*\007J\007\146\008J\005%\008\n\0082\005\129\008F\008z\006\214\0035\008~\008R\008\150\0035\0035\005\129\008Z\001R\008b\001V\004\017\000\206\008\154\008\158\008j\0035\023\n\006\234\001^\008\162\008\190\006\238\008\166\001j\008\198\006\242\006\246\008\170\006\250\008\214\005\129\008\222\011\153\008\174\008\230\005\129\002\150\008r\008\238\0035\008\246\t2\tB\006\254\007\002\tJ\008\178\008\182\007\006\008\186\tV\000\162\018\022\008\206\tZ\tb\003\193\tf\tr\008\218\007\014\tz\t\138\t\174\t\190\008a\t\198\t\202\t\242\t\158\t\254\008v\008\250\n\006\017v\nZ\008\254\t:\004\017\t\166\005\129\007\018\t>\nf\017z\n\154\007\022\004\017\004\017\n\182\n\202\n\214\004\017\tF\005\129\007\026\n\238\008a\008a\n\250\011\130\001\154\008a\0002\006&\000F\000b\006>\000f\006\142\000j\000\134\006\146\000\138\017\134\000\146\011\138\000\150\006\150\000\154\000\174\000\178\000\182\006\154\011\154\014\170\011\166\011\194\011\202\006\158\014\174\011\222\011\230\011\234\014\178\000\186\011\242\001\030\006\174\006\202\011\246\005\129\006\206\019\022\005\129\011\254\000\190\012\014\005\129\008:\005\129\012\"\012*\012.\012>\005\129\005\129\012F\001*\000\162\012^\008J\012f\012\146\012\154\017v\016.\008z\006\214\012\166\008~\012\170\008\150\017\138\012\178\017z\012\182\001R\012\190\001V\012\206\000\206\008\154\008\158\012\242\012\250\012\254\006\234\001^\008\162\013\014\006\238\008\166\001j\013\022\006\242\006\246\008\170\006\250\013\026\005\129\013*\011\153\008\174\0132\017\134\000:\013J\013R\000\218\013\162\013\234\013\246\006\254\007\002\014j\008\178\008\182\007\006\008\186\001^\000\162\014v\008\206\001f\001j\014\150\014\194\014\206\008\218\007\014\014\214\014\242\014\250\014\254\011\153\015\006\015\n\015\018\t\158\015\"\015:\008\250\015V\015z\015\138\008\254\t:\015\142\t\166\000\162\007\018\t>\000\162\015\150\015\154\007\022\015\162\005\129\015\178\015\194\015\202\015\206\tF\017\138\007\026\015\234\011\153\011\153\016\006\015\214\001\154\011\153\0002\006&\000F\000b\006>\000f\006\142\000j\000\134\006\146\000\138\016\026\000\146\016*\000\150\006\150\000\154\000\174\000\178\000\182\006\154\016:\016R\016b\016n\004\162\006\158\016\151\016\191\016\231\003\173\016\255\000\186\001^\001\030\006\174\006\202\012\022\001j\006\206\017#\017;\022\254\000\190\007\129\003\173\008:\006\142\017~\017\190\006\146\017\219\018\003\018\015\021\n\001*\006\150\018\031\008J\007\129\018'\006\154\021\014\018:\008z\006\214\000\162\008~\018C\008\150\018K\018S\018n\018\174\001R\018\195\001V\018\211\000\206\008\154\008\158\018\219\018\231\018\243\006\234\001^\008\162\018\255\006\238\008\166\001j\019\006\006\242\006\246\008\170\006\250\019\015\019\"\019+\0193\008\174\019n\019\162\005\233\019\183\019\191\011\230\019\203\019\219\007\129\006\254\007\002\019\227\008\178\008\182\007\006\008\186\019\238\000\162\019\242\008\206\023Z\019\255\n\169\020\011\003\173\008\218\007\014\023^\003\173\003\173\020\018\020\031\020+\0203\020>\t\158\020G\020O\008\250\020[\003\173\003\173\008\254\t:\020v\t\166\020\154\007\018\t>\020\158\020\162\006\142\007\022\020\186\006\146\021:\007\129\021b\021\n\tF\006\150\007\026\021r\003\213\003\173\006\154\021\014\001\154\007\129\0002\006&\000F\000b\006>\000f\006\142\000j\000\134\006\146\000\138\021\170\000\146\020\234\000\150\006\150\000\154\000\174\000\178\000\182\006\154\020\242\021\178\021\206\021\210\021\254\006\158\022\002\022\n\018.\0227\023\002\000\186\n\169\001\030\006\174\006\202\n\169\n\169\006\206\017r\012\166\023\014\000\190\023\030\023&\008:\023.\023W\023b\023r\017v\023\150\023\175\023\219\001*\023\247\024\006\024\n\024\014\018\162\017z\017v\024\023\008\146\006\214\000\000\n\169\000\000\008\150\022\134\000\000\017z\n\169\001R\000\000\001V\000\000\000\206\t\154\008\158\000\000\000\000\000\000\006\234\001^\008\162\000\000\006\238\008\166\001j\017\134\006\242\006\246\008\170\006\250\000\000\020:\000\000\003\213\008\174\000\000\017\134\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\254\007\002\000\000\008\178\008\182\007\006\008\186\000\000\000\162\000\000\008\206\000\000\000\000\003\193\000\000\000\000\008\218\007\014\000\000\000\000\000\000\000\000\008E\000\000\000\000\000\000\000\162\000\000\000\000\008\250\000\000\000\000\000\000\008\254\t:\000\000\t\166\000\162\007\018\t>\017\138\000\000\000\000\007\022\000\000\000\000\000\000\000\000\000\000\000\000\tF\017\138\007\026\000\000\008E\008E\000\000\000\000\001\154\008E\0002\006&\000F\000b\006>\000f\006\142\000j\000\134\006\146\000\138\000\000\000\146\000\000\000\150\006\150\000\154\000\174\000\178\000\182\006\154\nq\000\000\000\000\000\000\000\000\006\158\000\000\000\000\017r\000\000\000\000\000\186\000\000\001\030\006\174\006\202\000\000\000\000\006\206\017r\000\000\000\000\000\190\000\000\000\000\008:\000\000\000\000\000\000\000\000\017v\000\000\000\000\000\000\001*\000\000\000\000\000\000\000\000\000\000\017z\017v\000\000\008\146\006\214\000\000\000\000\000\000\008\150\012n\000\000\017z\000\000\001R\000\000\001V\000\000\000\206\t\154\008\158\000\000\000\000\000\000\006\234\001^\008\162\000\000\006\238\008\166\001j\018\202\006\242\006\246\008\170\006\250\000\000\000\000\000\000\011u\008\174\nq\019\210\000\000\000\000\nq\nq\000\000\000\000\000\000\006\254\007\002\000\000\008\178\008\182\007\006\008\186\nq\000\162\000\000\008\206\000\000\000\000\000\000\000\000\000\000\008\218\007\014\023v\000\000\000\000\000\000\011u\000\000\000\000\000\000\000\162\000\000\000\000\008\250\000\000\nq\000\000\008\254\t:\000\000\t\166\000\162\007\018\t>\017\138\000\000\000\000\007\022\000\000\000\000\000\000\000\000\000\000\000\000\tF\017\138\007\026\000\000\011u\011u\000\000\000\000\001\154\011u\0002\006&\000F\000b\006>\000f\006\142\000j\000\134\006\146\000\138\000\000\000\146\000\000\000\150\006\150\000\154\000\174\000\178\000\182\006\154\000\000\000\000\000\000\000\000\000\000\006\158\000\000\000\000\000\000\000\000\000\000\000\186\000\000\001\030\006\174\006\202\000\000\000\000\006\206\000\000\000\000\000\000\000\190\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\000\000\000\000\000\000\000\000\000\000\000\000\000\008\146\006\214\000\000\000\000\000\000\008\150\021>\000\000\000\000\000\000\001R\000\000\001V\000\000\000\206\t\154\008\158\000\000\000\000\000\000\006\234\001^\008\162\000\000\006\238\008\166\001j\000\000\006\242\006\246\008\170\006\250\000\000\000\000\000\000\000\000\008\174\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\254\007\002\000\000\008\178\008\182\007\006\008\186\000\000\000\162\000\000\008\206\000\000\000\000\000\000\000\000\000\000\008\218\007\014\000\000\000\000\000\000\000\000\011\193\000\000\000\000\000\000\000\000\000\000\000\000\008\250\000\000\000\000\000\000\008\254\t:\000\000\t\166\000\000\007\018\t>\000\000\000\000\000\000\007\022\000\000\000\000\000\000\000\000\000\000\000\000\tF\000\000\007\026\000\000\011\193\011\193\000\000\000\000\001\154\011\193\0002\006&\000F\000b\006>\000f\006\142\000j\000\134\006\146\000\138\000\000\000\146\000\000\000\150\006\150\000\154\000\174\000\178\000\182\006\154\000\000\000\000\000\000\000\000\000\000\006\158\000\000\000\000\000\000\000\000\000\000\000\186\000\000\001\030\006\174\006\202\000\000\000\000\006\206\000\000\000\000\000\000\000\190\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\000\000\000\000\000\000\000\000\000\000\000\000\000\008\146\006\214\000\000\000\000\000\000\008\150\021>\000\000\000\000\000\000\001R\000\000\001V\000\000\000\206\t\154\008\158\000\000\000\000\000\000\006\234\001^\008\162\000\000\006\238\008\166\001j\000\000\006\242\006\246\008\170\006\250\000\000\000\000\000\000\000\000\008\174\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\254\007\002\000\000\008\178\008\182\007\006\008\186\000\000\000\162\000\000\008\206\000\000\000\000\000\000\000\000\000\000\008\218\007\014\000\000\000\000\000\000\000\000\011\189\000\000\000\000\000\000\000\000\000\000\000\000\008\250\000\000\000\000\000\000\008\254\t:\000\000\t\166\000\000\007\018\t>\000\000\000\000\000\000\007\022\000\000\000\000\000\000\000\000\000\000\000\000\tF\000\000\007\026\000\000\011\189\011\189\000\000\000\000\001\154\011\189\0002\006&\000F\000b\006>\000f\006\142\000j\000\134\006\146\000\138\000\000\000\146\000\000\000\150\006\150\000\154\000\174\000\178\000\182\006\154\000\000\000\000\000\000\000\000\000\000\006\158\000\000\000\000\000\000\000\000\000\000\000\186\000\000\001\030\006\174\006\202\000\000\000\000\006\206\000\000\000\000\000\000\000\190\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\000\000\000\000\000\000\000\000\000\000\000\000\000\008\146\006\214\000\000\000\000\000\000\008\150\0146\000\000\000\000\000\000\001R\000\000\001V\000\000\000\206\t\154\008\158\000\000\000\000\000\000\006\234\001^\008\162\000\000\006\238\008\166\001j\000\000\006\242\006\246\008\170\006\250\000\000\000\000\000\000\000\000\008\174\000\000\000\000\000\000\000\000\000\000\0031\000\000\000\000\000\000\006\254\007\002\000\000\008\178\008\182\007\006\008\186\000\000\000\162\000\000\008\206\0031\000\000\000\000\000\000\000\000\008\218\007\014\000\000\017r\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0031\000\000\008\250\000\000\000\000\000\000\008\254\t:\000\000\t\166\000\000\007\018\t>\000\000\017v\000\000\007\022\000\000\000\000\000\000\000\000\000\000\000\000\tF\017z\007\026\000\000\0002\006&\000F\000b\001\154\000f\006\142\000j\000\134\006\146\000\138\000\000\000\146\000\000\000\150\006\150\000\154\000\174\000\178\000\182\006\154\000\000\019\026\000\000\000\000\n\029\000\000\017\134\000\000\000\000\000\000\000\000\000\186\000\000\001\030\000\000\006\202\0031\004\169\006\206\000\000\0031\0031\000\190\000\000\000\000\014\182\000\000\000\000\000\000\n\029\000\000\000\000\0031\000\000\001*\000\000\000\000\000\000\000\000\004\169\000\000\000\000\000\000\014\198\006\214\000\000\000\000\0031\000\000\004\169\000\000\000\162\000\000\001R\000\000\001V\0031\000\206\023B\000\000\011\018\000\000\000\000\006\234\001^\017\138\000\000\006\238\001f\001j\000\000\006\242\006\246\008\170\006\250\000\000\000\000\n\017\011\026\004\169\004\169\000\000\000\000\000\000\000\000\n\029\000\000\000\000\000\000\006\254\007\002\000\000\000\000\011\"\007\006\000\000\000\000\000\162\000\000\011b\011j\000\000\n\017\000\000\000\000\000\000\007\014\000\000\017r\011B\000\000\000\000\011*\000\000\011:\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\169\t\166\000\000\007\018\014\202\000\000\017v\000\000\007\022\000\000\000\000\011J\000\000\000\000\004\169\014\210\017z\007\026\000\000\0002\0006\000F\000b\001\154\000f\000\000\000j\000\134\000\000\000\138\000\000\000\146\000\000\000\150\n\017\000\154\000\174\000\178\000\182\000\000\000\000\000\000\000\000\000\000\n)\000\000\017\134\011R\000\000\000\000\000\000\000\186\000\000\001\030\0112\001\"\000\000\000\000\001&\000\000\000\000\000\000\000\190\000\000\000\000\000\000\004\253\000\000\000\000\n)\000\000\000\000\000\000\000\000\001*\000\000\000\000\001.\000\000\000\000\000\000\011r\011Z\001F\001B\000\000\001J\000\000\000\000\000\000\000\000\000\162\000\000\001R\000\000\001V\000\000\000\206\000\000\000\000\000\000\000\000\000\000\001Z\001^\017\138\000\000\001b\001f\001j\001\190\001n\001r\000\000\001v\000\000\000\000\000\000\000\000\000\000\002\186\000F\000b\000\000\000f\n)\000j\000\134\000\000\000\138\001z\000\146\000\000\000\150\001~\000\154\000\174\000\162\000\182\000\000\006\158\000\000\000\000\000\000\000\000\000\000\001\134\000\000\001\030\006\174\006\202\000\186\000\000\006\206\000\000\001\138\000\000\000\000\000\000\000\000\008:\000\000\000\190\000\000\000\000\000\000\000\000\001\142\000\000\001*\000\000\000\000\001\146\000\000\000\000\003\133\000\000\000\000\008\202\006\214\000\000\001\150\000\000\008\150\000\000\000\000\000\000\001\154\001R\000\000\001V\000\000\000\000\000\000\008\158\000\000\000\000\000\206\006\234\001^\008\162\000\000\006\238\008\166\001j\000\000\006\242\006\246\000\000\006\250\000\000\000\000\000\000\000\000\008\174\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\254\007\002\000\000\008\178\008\182\007\006\008\186\000\000\000\162\000\000\008\206\000\000\000\000\000\162\000\000\000\000\008\218\007\014\000\000\000\000\000\000\000\000\006\158\000\000\000\000\000\000\000\000\000\000\000\000\008\250\001\030\006\174\006\202\008\254\t:\006\206\000\000\000\000\007\018\t>\007y\000\000\008:\007\022\000\000\t\146\000\000\000\000\000\000\000\000\tF\001*\007\026\000\000\008J\007y\000\000\000\000\001\154\000\000\006\210\006\214\000\000\008~\000\000\008\150\000\000\000\000\000\000\000\000\001R\000\000\001V\000\000\000\000\000\000\008\158\000\000\000\000\000\000\006\234\001^\008\162\000\000\006\238\008\166\001j\000\000\006\242\006\246\000\000\006\250\000\000\000\000\000\000\000\000\008\174\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007y\006\254\007\002\000\000\008\178\008\182\007\006\008\186\000\000\000\162\000\000\008\206\000\000\000\000\000\000\000\000\000\000\008\218\007\014\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\158\011\213\000\000\008\250\011\213\000\000\000\000\008\254\t:\000\000\000\000\000\000\007\018\t>\000\000\000\000\000\000\007\022\000\000\011\213\000\000\007y\000\000\011\213\tF\000\000\007\026\001\178\011\213\000\000\000\000\000\000\001\154\007y\011\213\000\000\000\000\011\213\011\213\000\000\011\213\011\213\000\000\000\000\001\186\000\000\011\213\002\214\000\000\000\000\011\213\000\000\000\000\011\213\000\000\011\213\011\213\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\213\000\000\011\213\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\213\005\129\000\000\000\000\000\000\000\000\002\226\000\000\000\000\000\000\000\000\005\129\005\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\213\011\213\011\213\000\000\011\213\011\213\002\230\000\000\011\213\000\000\000\000\000\000\004!\005\129\000\000\004!\002\238\000\000\005\129\002\150\011\213\000\000\005\129\011\213\011\213\011\213\011\213\000\000\000\000\000\000\004!\011\213\011\213\011\213\004!\011\213\011\213\011\213\004!\004!\000\000\000\000\000\000\000\000\000\000\004!\000\000\000\000\004!\004!\000\000\004!\004!\000\000\005\129\004!\000\000\004!\004!\000\000\000\000\004!\000\000\005\129\004!\000\000\004!\004!\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\129\000\000\000\158\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004!\000\000\004!\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\129\000\000\004!\005\129\005\129\000\000\000\000\005\129\004!\000\000\000\000\000\162\000\000\000\000\000\000\000\000\000\000\005\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004!\004!\004!\000\000\004!\004\189\004!\000\000\004!\000\000\001=\001=\001=\001=\000\000\001=\004!\001=\001=\000\000\001=\000\000\001=\004!\001=\004!\001=\001=\001=\001=\000\000\004!\004!\004!\017F\004!\004!\004!\000\000\000\000\000\000\001=\001=\001=\000\000\000\000\000\000\000\000\001=\000\000\000\000\000\000\000\000\001=\000\000\000\000\000\000\001=\000\000\000\000\000\000\001=\000\000\000\000\017J\000\000\000\000\001=\000\000\000\000\000\000\006~\006J\000b\001=\000f\000\181\006N\000\134\001=\000\138\000\000\000\146\000\000\000\150\000\000\000\154\000\174\001=\000\182\000\000\000\000\000\000\000\000\011\026\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\186\000\000\000\000\000\000\000\000\000\000\001=\011\"\000\000\001=\000\000\000\190\000\000\000\181\000\181\000\000\000\000\000\000\000\000\000\000\001=\000\000\000\000\011B\000\000\001=\011*\001=\011:\000\000\001=\000\000\001=\000\000\000\000\004%\000\000\001=\004%\000\000\001=\000\000\000\000\000\000\000\000\000\000\000\206\000\000\000\000\011J\000\000\000\000\000\000\004%\000\000\001=\000\000\004%\001=\001=\000\000\004%\004%\000\000\000\000\000\000\000\000\000\000\004%\017N\000\000\004%\004%\000\000\004%\004%\000\000\000\000\004%\000\000\004%\004%\000\000\000\000\004%\011R\000\000\004%\000\000\004%\004%\000\000\0112\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\181\000\000\000\000\000\000\000\000\000\000\004%\000\000\004%\000\000\000\000\000\000\000\000\000\000\000\000\000\181\011Z\000\000\004%\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\004%\004%\004%\000\000\004%\004\193\004%\000\000\004%\000\000\000\000\000\000\012)\000\000\000\000\012)\004%\000\000\000\000\000\000\004%\000\000\000\000\004%\000\000\004%\000\000\000\000\000\000\000\000\012)\004%\004%\004%\012)\004%\004%\004%\007.\012)\000\000\000\000\000\000\000\000\000\000\012)\000\000\000\000\012)\012)\000\000\012)\012)\000\000\000\000\0076\000\000\012)\007B\000\000\000\000\012)\000\000\000\000\012)\000\000\012)\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\012)\000\000\012)\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012)\000\000\000\000\000\000\000\000\000\000\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\000\000\000\000\012)\012)\012)\000\000\012)\000\000\007R\000\000\012)\000\000\n\013\n\013\n\013\n\013\000\000\n\013\007Z\n\013\n\013\000\000\n\013\000\000\n\013\012)\n\013\012)\n\013\n\013\n\013\n\013\000\000\012)\012)\012)\000\000\012)\012)\012)\000\000\000\000\000\000\n\013\n\013\n\013\000\000\000\000\000\000\000\000\n\013\000\000\000\000\000\000\000\000\n\013\000\000\000\000\000\000\017^\000\000\000\000\000\000\017f\000\000\000\000\000\000\000\000\000\000\n\013\000\000\000\000\000\000\000\000\000\000\000\000\n\013\000\000\000\000\000\000\000\000\n\013\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004E\n\013\000J\004E\000N\004E\000V\004E\000\000\004E\000\000\000\000\000\000\000Z\004E\004E\000\000\000\000\000\000\000\000\000\000\n\013\000\000\000\000\n\013\000\000\000\000\004E\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\013\000\157\004E\004E\000\000\n\013\000\000\n\013\004E\000\000\n\013\000\000\n\013\000\000\000\000\000\000\000\000\n\013\000\000\000\157\n\013\000\000\000\000\000\000\004E\000\000\000\000\004E\000\000\000\000\000\000\000\000\004E\004E\011\"\n\013\004E\000^\017\222\n\013\000\157\000\157\000\000\000\000\004E\000\000\000\000\000\000\004E\004E\000\157\000\000\000\000\011*\000\000\011:\000\000\000\000\004E\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004E\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\157\004E\000\000\000\000\000\000\000\000\004E\004I\000\000\000n\004I\000r\004I\000z\004I\004E\004I\000\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\000\000\004I\004E\000\157\000\000\004E\004E\000\000\000\000\004E\0112\004I\004I\000\000\004E\004E\000\000\004I\000\000\004E\000\000\000\000\000\157\000\000\000\000\000\000\000\000\000\000\000\000\001\137\000\000\000\000\001\137\004I\000\000\000\000\004I\000\157\000\157\000\000\000\000\004I\004I\000\000\000\000\004I\000\130\001\137\000\000\000\000\000\000\001\137\000\000\004I\000\000\000\000\001\137\004I\004I\000\000\000\000\000\000\001\137\000\000\000\000\001\137\001\137\004I\001\137\001\137\000\000\000\000\000\000\000\000\001\137\000\000\000\000\004I\001\137\000\000\000\000\001\137\000\000\001\137\001\137\000\000\004I\000\000\000\000\000\000\000\000\004I\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004I\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\000\000\000\000\000\000\004I\000\000\000\000\004I\004I\000\000\000\000\004I\000\000\000\000\000\000\000\000\004I\004I\000\000\000\000\000\000\004I\000\000\001\137\001\137\001\206\000\000\001\137\001\137\000\000\000\000\001\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\137\000\000\000\000\001\137\001\137\001\137\001\137\000\000\000\000\000\000\000\000\002z\001\137\001\137\000\000\001\137\001\137\001\137\t\253\t\253\t\253\t\253\000\000\t\253\000\000\t\253\t\253\000\000\t\253\000\000\t\253\000\000\t\253\000\000\t\253\t\253\t\253\t\253\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\253\t\253\t\253\000\000\000\000\000\000\000\000\t\253\000\000\000\000\000\000\000\000\t\253\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\241\t\253\000\000\000\000\000\000\000\000\000\000\000\000\t\253\000\000\000\000\000\000\000\000\t\253\000\000\000\000\000\000\000\000\011\241\000\000\000\000\000\000\t\253\000\000\000\000\000\000\nJ\000\000\000\000\000\000\000\000\000\000\000\000\011\241\000\000\000\000\000\000\000\000\000\000\011\241\011\241\000\000\t\253\nR\000\000\t\253\n^\000\000\000\000\011\241\000\000\000\000\011\241\000\000\011\241\000\000\t\253\000\000\000\000\000\000\000\000\t\253\000\000\t\253\000\000\000\000\t\253\000\000\t\253\000\000\000\000\000\000\000\000\t\253\000\000\011\241\t\253\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\149\000\000\000\000\000\000\000\000\000\000\000\000\t\253\000\000\nj\017b\t\253\n\001\n\001\n\001\n\001\000\000\n\001\000\149\n\001\n\001\000\000\n\001\000\000\n\001\000\000\n\001\011\241\n\001\n\001\n\001\n\001\nn\000\149\011\241\000\000\000\000\000\000\000\000\000\149\000\149\000\000\nv\n\001\n\001\n\001\011\241\000\000\000\000\000\149\n\001\000\000\011*\000\000\000\149\n\001\000\000\000\000\000\000\017\226\000\000\011\241\011\241\000\000\000\000\000\153\000\000\000\000\000\000\n\001\000\000\000\000\000\000\000\000\000\000\000\149\n\001\000\000\000\000\000\000\000\000\n\001\000\000\000\153\000\000\000\000\000\000\000\000\000\000\000\000\n\001\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\000\000\000\000\n\001\000\149\000\000\n\001\000\153\000\000\000\000\011*\0112\000\153\000\000\000\000\000\000\000\000\n\001\000\000\000\000\000\000\000\000\n\001\000\149\n\001\000\000\000\000\n\001\000\000\n\001\000\000\000\000\000\000\000\153\n\001\000\000\000\000\n\001\000\149\000\149\000\000\0002\0006\000F\000b\000\000\000f\000\000\000j\000\134\000\000\000\138\n\001\000\146\000\000\000\150\n\001\000\154\000\174\000\178\000\182\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\153\000\000\000\000\017\234\000\186\018\006\000\000\0112\000\000\000\000\018\018\000\000\000\000\000\000\000\000\000\190\000\000\000\000\000\000\000\153\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\169\018*\000\000\000\000\000\000\000\000\000\153\000\153\000\202\000\000\000\000\000\000\000\000\018V\000\000\000\000\000\000\000\000\011\026\000\000\000\000\004}\000\206\000\000\004}\000R\004}\000\000\004}\000\000\004}\000\000\000\000\011\"\000\000\004}\004}\000\000\000\000\000\169\000\169\000\000\018v\000\000\000\000\018\198\000\000\000\000\004}\000\169\000\000\000\000\011*\000\000\011:\000\000\018\222\000\000\004}\004}\000\000\018\234\000\000\008-\004}\000\000\018\246\000\000\019\002\000\000\000\000\000\000\000\000\019\018\000\000\011J\019\194\000\000\000\000\000\000\004}\000\000\000\000\004}\000\000\000\000\000\000\000\000\004}\004}\000\000\019\206\004}\004}\004\129\019\230\000\000\004\129\000v\004\129\004}\004\129\000\000\004\129\004}\004}\000\000\000\000\004\129\004\129\000\000\000\169\000\000\000\000\004}\000\000\000\000\000\000\0112\000\000\000\000\004\129\000\000\000\000\004}\000\000\000\000\000\000\000\000\000\000\000\169\004\129\004\129\004}\000\000\000\000\000\000\004\129\004}\000\000\000\000\000\000\000\000\000\000\000\000\000\169\000\169\004}\000\000\000\000\000\000\000\000\000\000\004\129\000\000\000\000\004\129\000\000\000\000\000\000\000\000\004\129\004\129\000\000\000\000\004\129\004\129\004}\000\000\000\000\004}\004}\000\000\004\129\004}\000\000\000\000\004\129\004\129\004}\004}\000\000\000\000\000\000\004}\000\000\000\000\004\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\129\000\000\000\000\000\000\000\000\004\129\004\133\000\000\000\000\004\133\000\142\004\133\000\000\004\133\004\129\004\133\000\000\000\000\000\000\000\000\004\133\004\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\133\004\129\000\000\000\000\004\129\004\129\000\000\000\000\004\129\000\000\004\133\004\133\004\185\004\129\004\129\004\185\004\133\004\185\004\129\004\185\000\000\004\185\000\000\000\000\000\000\000\000\004\185\004\185\000\000\000\000\000\000\000\000\004\133\000\000\000\000\004\133\000\000\000\000\000\000\004\185\004\133\004\133\000\000\000\000\004\133\004\133\000\000\000\000\000\000\004\185\004\185\000\000\004\133\000\000\000\000\004\185\004\133\004\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\133\000\000\000\000\000\000\000\000\004\185\000\000\000\000\004\185\000\210\004\133\000\000\000\000\004\185\004\185\000\000\000\000\004\185\004\185\004\133\000\000\000\000\000\000\000\000\004\133\004\185\000\000\000\000\000\000\004\185\004\185\000\000\000\000\004\133\000\000\000\000\000\000\000\000\000\000\004\185\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\185\000\000\000\000\000\000\004\133\000\000\000\000\004\133\004\133\004\185\000\000\004\133\001\238\000\000\004\185\002B\004\133\004\133\000\000\000\000\000\000\004\133\000\000\004\185\000\000\000\000\000\000\000\000\000\000\000\000\001\250\000\000\000\000\000\000\002\001\000\000\000\000\000\000\000\000\002\001\000\000\000\000\000\000\004\185\000\000\002\002\004\185\004\185\002\001\002\001\004\185\002b\002j\000\000\000\000\004\185\004\185\002\001\000\000\000\000\004\185\002\"\000\000\000\000\002\n\000\000\002\026\002\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\001\0002\006&\000F\000b\006>\000f\006\142\000j\000\134\006\146\000\138\000\000\000\146\000\000\000\150\006\150\000\154\000\174\000\178\000\182\006\154\000\000\002\001\0022\000\000\000\000\002\001\002\001\000\000\000\000\002\018\000\000\000\186\000\000\000}\000\000\000\000\000}\000\000\000\000\000\000\000\000\002\001\000\190\000\000\002\001\002\001\002\001\002\001\000\000\000\000\000\000\001\250\000\000\002\001\002\001\000}\002r\002:\002\001\000\000\000}\000\000\000\000\000\202\000\000\000\000\002\002\000\000\000\000\000}\000}\000\000\000}\000}\000\000\000\000\000\000\000\206\000}\000\000\000\000\000\000\002\"\000\000\000\000\002\n\000\000\002\026\000}\000\000\000\000\000\000\000\000\008\170\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\162\000\000\000\000\000}\0002\t\182\000F\000b\000\000\000f\006\142\000j\000\134\006\146\000\138\000\000\000\146\020\234\000\150\006\150\000\154\000\174\000\178\000\182\006\154\020\242\000}\0022\t\166\000\000\000}\000}\000\000\000\000\002\018\000\000\000\186\000\000\000e\000\000\000\000\000e\000\000\000\000\000\000\000\000\000}\000\190\000\000\000}\000}\000}\000}\000\000\000\000\000\000\000e\000\000\000}\000}\000e\000}\002:\000}\000\000\000e\000\000\000\000\000\202\000\000\000\000\002\002\000\000\000\000\000e\000e\000\000\000e\000e\000\000\000\000\000\000\000\206\000e\000\000\000\000\000\000\000e\000\000\000\000\002\n\000\000\002\026\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\000\000e\000\000\000e\000\000\000\000\000\000\000\000\000\000\000\000\000\162\000\000\000\000\000e\000\000\003\193\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\002\018\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\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000]\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\238\000F\000b\000\000\000f\006\142\000j\000\134\006\146\000\138\000\000\000\146\020\234\000\150\006\150\000\154\000\174\000\000\000\182\006\154\020\242\000]\000]\000\000\000\000\000]\000]\000\000\000\000\002\018\000\000\000\186\000\000\000a\000\000\000\000\000a\000\000\000\000\000\000\000\000\000]\000\190\000\000\000]\000]\000]\000]\000\000\000\000\000\000\000a\000\000\000]\000]\000a\000]\000]\000]\000\000\000a\000\000\000\000\000\000\000\000\000\000\000a\000\000\000\000\000a\000a\000\000\000a\000a\000\000\000\000\000\000\000\206\000a\000\000\000\000\000\000\000a\000\000\000\000\002\n\000\000\000a\000a\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000\000\000\000\000\000a\000\000\003\193\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\002\018\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\250\000\000\000a\000a\000q\000a\000a\000a\000\000\000q\000\000\000\000\000\000\000\000\000\000\002\002\000\000\000\000\000q\000q\000\000\000q\000q\000\000\000\000\000\000\000\000\000q\000\000\000\000\000\000\000q\000\000\000\000\002\n\000\000\002\026\000q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002*\000\000\000q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000q\0002\006B\006J\000b\000\000\000f\000\000\006N\000\134\000\000\000\138\000\000\000\146\000\000\000\150\000\000\000\154\000\174\000\178\000\182\000\000\000\000\000q\000q\000\000\000\000\000q\000q\000\000\000\000\002\018\000\000\000\186\000\000\000i\000\000\000\000\000i\000\000\000\000\000\000\000\000\000q\000\190\000\000\000q\000q\000q\000q\000\000\000\000\000\000\001\250\000\000\000q\000q\000i\000q\000q\000q\000\000\000i\000\000\000\000\006R\000\000\000\000\002\002\000\000\000\000\000i\000i\000\000\000i\000i\000\000\000\000\000\000\000\206\000i\000\000\000\000\000\000\000i\000\000\000\000\002\n\000\000\002\026\000i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000i\000\000\000i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000i\000\000\000\000\000i\000i\000\000\000\000\002\018\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\250\000\000\000i\000i\000m\000i\000i\000i\000\000\000m\000\000\000\000\000\000\000\000\000\000\002\002\000\000\000\000\000m\000m\000\000\000m\000m\000\000\000\000\000\000\000\000\000m\000\000\000\000\000\000\000m\000\000\000\000\002\n\000\000\002\026\000m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002*\000\000\000m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000m\000m\000\000\000\000\000m\000m\000\000\000\000\002\018\000\000\000\000\000\000\000u\000\000\000\000\000u\000\000\000\000\000\000\000\000\000m\000\000\000\000\000m\000m\000m\000m\000\000\000\000\000\000\001\250\000\000\000m\000m\000u\000m\000m\000m\000\000\000u\000\000\000\000\000\000\000\000\000\000\002\002\000\000\000\000\000u\000u\000\000\000u\000u\000\000\000\000\000\000\000\000\000u\000\000\000\000\000\000\002\"\000\000\000\000\002\n\000\000\002\026\000u\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002*\000\000\000u\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000u\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000u\0022\000\000\000\000\000u\000u\000\000\000\000\002\018\000\000\000\000\000\000\001\238\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\250\000\000\000u\000u\000\133\000u\000u\000u\000\000\000\133\000\000\000\000\000\000\000\000\000\000\002\002\000\000\000\000\000\133\000\133\000\000\000\133\002j\000\000\000\000\000\000\000\000\000\133\000\000\000\000\000\000\002\"\000\000\000\000\002\n\000\000\002\026\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002*\000\000\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\133\0022\000\000\000\000\000\133\000\133\000\000\000\000\002\018\000\000\000\000\000\000\001\238\000\000\000\000\000y\000\000\000\000\000\000\000\000\000\133\000\000\000\000\000\133\000\133\000\133\000\133\000\000\000\000\000\000\001\250\000\000\000\133\000\133\000y\002r\002:\000\133\000\000\000y\000\000\000\000\000\000\000\000\000\000\002\002\000\000\000\000\000y\000y\000\000\000y\000y\000\000\000\000\000\000\000\000\000y\000\000\000\000\000\000\002\"\000\000\000\000\002\n\000\000\002\026\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\000\000\000\000\002*\000\000\000y\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000y\0022\000\000\000\000\000y\000y\000\000\000\000\002\018\000\000\000\000\000\000\001\238\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\250\000\000\000y\000y\000\129\000y\002:\000y\000\000\000\129\000\000\000\000\000\000\000\000\000\000\002\002\000\000\000\000\000\129\000\129\000\000\000\129\002j\000\000\000\000\000\000\000\000\000\129\000\000\000\000\000\000\002\"\000\000\000\000\002\n\000\000\002\026\000\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002*\000\000\000\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\129\000\000\004\153\000\000\000\000\004\153\000\000\004\153\000\000\004\153\000\000\004\153\000\000\000\000\000\000\000\000\004\153\004\153\000\000\000\000\000\000\000\000\000\000\000\129\0022\000\000\000\000\000\129\000\129\004\153\000\000\002\018\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\153\004\153\000\000\000\000\000\129\000\000\004\153\000\129\000\129\000\129\000\129\000\000\000\000\000\000\000\000\000\000\000\129\000\129\000\000\000\129\002:\000\129\004\153\000\000\000\000\004\153\005\226\000\000\000\000\000\000\004\153\004\153\000\000\000\000\004\153\004\153\005\129\000\000\000\000\005\129\000\000\005\129\004\153\005\129\000\000\005\129\004\153\004\153\000\000\000\000\005\129\005\129\000\000\000\000\000\000\000\000\004\153\000\000\005\129\000\000\000\000\000\000\000\000\005\129\000\000\000\000\004\153\000\000\005\129\005\129\000\000\000\000\000\000\005\129\005\129\004\153\000\000\000\000\000\000\005\129\004\153\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\153\000\000\000\000\000\000\005\129\000\000\005\129\000\000\000\000\005\129\002\150\000\000\000\000\005\129\005\129\002\150\000\000\000\000\005\129\005\129\004\153\005\129\000\000\004\153\004\153\005\129\005\129\004\153\000\000\000\000\005\129\005\129\004\153\004\153\000\000\005\129\000\000\004\153\000\000\000\000\005\129\000\000\000\000\000\000\000\000\005\129\000\000\000\000\000\000\000\000\005\129\000\000\000\000\000\000\005\129\000\000\000\000\000\000\000\000\005\129\000\000\000\000\000\000\000\000\005\129\000\000\000\000\000\000\005\129\000\000\000\000\000\000\n\198\005\129\000\000\000\000\000\000\003i\000\000\003i\000\000\000\000\003i\000\000\000\000\000\000\000\000\000\000\005\129\000\000\000\000\005\129\005\129\005\129\000\000\005\129\005\129\005\129\003i\000\000\005\129\005\129\000\000\000\000\000\000\005\129\005\129\003i\003i\000\000\005\129\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\000\000\003i\003i\003i\000\000\003i\003i\000\000\003i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\161\000\000\000\000\001\161\003i\003i\000\000\000\000\000\000\003i\000\000\000\000\003i\000\000\000\000\000\000\000\000\000\000\001\161\000\000\000\000\003i\001\161\000\000\000\000\000\000\000\000\001\161\003i\000\000\003i\000\000\003i\001\161\000\000\000\000\001\161\001\161\000\000\001\161\001\161\000\000\003i\000\000\000\000\001\161\000\000\003i\000\000\001\161\000\000\000\000\001\161\003i\001\161\001\161\003i\000\000\000\000\000\000\000\000\000\000\003i\000\000\000\000\000\000\003q\003q\003q\003q\000\000\003q\000\000\003q\003q\001\161\003q\001\161\003q\000\000\003q\000\000\003q\003q\003q\003q\000\000\001\161\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\003q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003q\001\161\001\161\007~\000\000\001\161\000\000\000\000\000\000\001\161\001\030\000\000\t\226\000\000\000\000\t\230\000\000\000\000\000\000\000\000\000\000\003q\000\000\000\000\001\161\000\000\001\161\003q\000\000\000\000\000\000\001*\007\134\001\161\001\161\003q\001\161\001\161\001\161\000\000\t\234\n\146\000\000\000\000\n\166\n\190\000\000\000\000\000\000\000\000\001R\000\000\001V\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\n\001^\000\000\000\000\n\014\008\166\001j\000\000\n\018\n\022\000\000\n\026\000\000\000\000\000\000\003q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\254\n\030\000\000\000\000\000\000\n\"\000\000\000\000\000\162\000\000\000\000\001\030\000\000\t\226\000\000\000\000\t\230\n*\000\000\000\000\000\000\000\000\000\000\000\000\005\169\000\000\n\194\000\000\n\222\000\000\003q\000\000\001*\000\000\000\000\000\000\000\000\000\000\n.\000\000\000\000\t\234\n\146\n2\000\000\n\166\n\190\000\000\000\000\011\186\000\000\001R\n6\001V\000\000\000\000\000\000\000\000\001\154\000\000\000\000\n\n\001^\000\000\000\000\n\014\008\166\001j\000\000\n\018\n\022\000\000\n\026\000\000\000\000\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\254\n\030\000\000\000\000\000\000\n\"\000\000\000\000\000\162\000\000\000\000\001\030\000\000\t\226\000\000\000\000\t\230\n*\000\000\000\000\000\000\000\000\000\000\000\000\005\169\000\000\n\194\000\000\n\222\000\000\000\000\000\000\001*\000\000\000\000\000\000\000\000\000\000\n.\000\000\000\000\t\234\n\146\n2\000\000\n\166\n\190\000\000\000\000\n\230\000\000\001R\n6\001V\000\000\000\000\000\000\000\000\001\154\000\000\000\000\n\n\001^\000\000\000\000\n\014\008\166\001j\000\000\n\018\n\022\000\000\n\026\000\000\000\000\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\254\n\030\000\000\000\000\000\000\n\"\000\000\000\000\000\162\000\000\000\000\001\030\000\000\t\226\000\000\000\000\t\230\n*\000\000\000\000\000\000\000\000\000\000\000\000\005\169\000\000\n\194\000\000\n\222\000\000\000\000\000\000\001*\000\000\000\000\000\000\000\000\000\000\n.\000\000\000\000\t\234\n\146\n2\000\000\n\166\n\190\000\000\000\000\005\021\000\000\001R\n6\001V\000\000\000\000\000\000\000\000\001\154\000\000\012\013\n\n\001^\012\013\000\000\n\014\008\166\001j\000\000\n\018\n\022\000\000\n\026\000\000\000\000\000\000\000\000\000\000\012\013\000\000\000\000\000\000\012\013\000\000\000\000\000\000\003V\006\254\n\030\000\000\000\000\000\000\n\"\012\013\000\000\000\162\000\000\012\013\000\000\012\013\012\013\000\000\000\000\003^\n*\000\000\003j\000\000\000\000\012\013\000\161\005\169\012\013\n\194\012\013\n\222\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n.\000\000\000\000\011\026\000\000\n2\000\000\000\000\000\000\000\000\012\013\001\189\000\000\000\000\n6\000\000\000\000\000\000\011\"\000\000\001\154\000\000\012\013\000\000\000\161\000\161\000\000\000\000\003v\000\000\000\000\000\000\000\000\001\030\000\161\t\226\000\000\011*\t\230\011:\000\000\000\000\000\000\000\000\000\000\000\000\012\013\012\013\000\000\012\013\000\000\003z\000\000\012\013\001*\000\000\000\000\000\000\000\000\000\000\000\161\003\130\000\000\t\234\n\146\012\013\000\000\n\166\n\190\000\000\012\013\012\013\000\000\001R\000\000\001V\012\013\000\000\000\000\000\000\012\013\012\013\012\013\n\n\001^\000\000\000\000\n\014\008\166\001j\000\000\n\018\n\022\000\000\n\026\000\000\000\161\000\000\000\000\000\000\000\000\001\137\000\000\0112\001\137\000\000\000\000\000\000\000\000\006\254\n\030\000\000\000\000\000\000\n\"\000\161\000\000\000\162\000\000\001\137\000\000\000\000\000\000\000\000\000\000\000\000\n*\000\000\001\137\000\000\000\161\000\161\000\000\005\169\001\137\000\000\000\000\n\222\000\000\000\000\001\137\001\137\000\000\000\000\000\000\000\000\007\178\n.\000\000\008\002\001\137\000\000\n2\001\137\000\165\001\137\001\137\000\000\001\201\000\000\000\000\n6\000\000\000\000\007\186\000\000\000\000\001\154\002\017\000\000\000\000\000\000\011\026\002\017\000\000\000\000\001\137\000\000\001\137\007\194\000\000\000\000\002\017\002\017\000\000\008\018\008\026\011\"\000\000\000\000\000\000\002\017\000\000\000\165\000\165\007\226\000\000\000\000\007\202\000\000\007\218\002\017\000\000\000\165\000\000\000\000\011*\000\000\011:\000\000\000\000\001\137\001\137\001\198\000\000\001\137\001\137\000\000\000\000\001\137\000\000\007\234\000\000\002\017\000\000\000\000\000\000\000\000\000\000\011J\000\000\001\137\000\000\002\017\001\137\001\137\000\000\001\137\000\000\000\000\000\000\000\000\002\134\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\002\017\007\242\000\000\000\000\002\017\000\000\000\000\000\000\007\210\000\165\000\000\000\000\001%\000\000\000\000\001%\0112\000\000\000\000\000\000\000\000\000\000\000\000\002\017\000\000\002\017\000\000\000\000\000\165\000\000\007\186\000\000\002\017\002\017\001%\008\"\007\250\002\017\000\000\001%\000\000\000\000\000\000\000\165\000\165\007\194\000\000\000\000\001%\001%\000\000\001%\001%\000\000\000\000\000\000\000\000\001%\000\000\000\000\000\000\007\226\000\000\000\000\007\202\000\000\007\218\001%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\234\001\013\001%\000\000\001\013\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\001\013\000\000\000\000\000\000\001\013\000\000\000\000\000\000\000\000\001\013\000\000\000\000\000\000\000\000\000\000\007\194\001%\007\242\001\013\001\013\001%\001\013\001\013\000\000\007\210\000\000\000\000\001\013\000\000\000\000\000\000\001\013\000\000\000\000\007\202\000\000\007\218\001\013\000\000\001%\000\000\001%\000\000\000\000\000\000\000\000\000\000\000\000\001%\001%\000\000\001%\007\250\001%\000\000\000\000\000\000\001\013\001\005\001\013\000\000\001\005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\013\000\000\000\000\000\000\000\000\000\000\000\000\001\005\000\000\000\000\000\000\001\005\000\000\000\000\000\000\000\000\001\005\000\000\000\000\000\000\000\000\000\000\001\005\001\013\001\013\001\005\001\005\001\013\001\005\001\005\000\000\007\210\000\000\000\000\001\005\000\000\000\000\000\000\001\005\000\000\000\000\007\202\000\000\001\005\001\005\000\000\001\013\000\000\001\013\000\000\000\000\000\000\000\000\000\000\000\000\001\013\001\013\000\000\001\013\001\013\001\013\000\000\000\000\000\000\001\005\001\t\001\005\000\000\001\t\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\005\000\000\000\000\000\000\000\000\000\000\000\000\001\t\000\000\000\000\000\000\001\t\000\000\000\000\000\000\000\000\001\t\000\000\000\000\000\000\000\000\000\000\001\t\001\005\001\005\001\t\001\t\001\005\001\t\001\t\000\000\007\210\000\000\000\000\001\t\000\000\000\000\000\000\001\t\000\000\000\000\007\202\000\000\001\t\001\t\000\000\001\005\000\000\001\005\000\000\000\000\000\000\000\000\000\000\000\000\001\005\001\005\000\000\001\005\001\005\001\005\000\000\000\000\000\000\001\t\001\025\001\t\000\000\001\025\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\t\000\000\000\000\000\000\000\000\000\000\000\000\007\186\000\000\000\000\000\000\001\025\000\000\000\000\000\000\000\000\001\025\000\000\000\000\000\000\000\000\000\000\007\194\001\t\001\t\001\025\001\025\001\t\001\025\001\025\000\000\007\210\000\000\000\000\001\025\000\000\000\000\000\000\001\025\000\000\000\000\007\202\000\000\007\218\001\025\000\000\001\t\000\000\001\t\000\000\000\000\000\000\000\000\000\000\000\000\001\t\001\t\000\000\001\t\001\t\001\t\000\000\000\000\000\000\007\234\001\017\001\025\000\000\001\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\025\000\000\000\000\000\000\000\000\000\000\000\000\007\186\000\000\000\000\000\000\001\017\000\000\000\000\000\000\000\000\001\017\000\000\000\000\000\000\000\000\000\000\007\194\001\025\001\025\001\017\001\017\001\025\001\017\001\017\000\000\007\210\000\000\000\000\001\017\000\000\000\000\000\000\001\017\000\000\000\000\007\202\000\000\007\218\001\017\000\000\001\025\000\000\001\025\000\000\000\000\000\000\000\000\000\000\000\000\001\025\001\025\000\000\001\025\001\025\001\025\000\000\000\000\000\000\001\017\001\021\001\017\000\000\001\021\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\017\000\000\000\000\000\000\000\000\000\000\000\000\007\186\000\000\000\000\000\000\001\021\000\000\000\000\000\000\000\000\001\021\000\000\000\000\000\000\000\000\000\000\007\194\001\017\001\017\001\021\001\021\001\017\001\021\001\021\000\000\007\210\000\000\000\000\001\021\000\000\000\000\000\000\001\021\000\000\000\000\007\202\000\000\007\218\001\021\000\000\001\017\000\000\001\017\000\000\000\000\000\000\000\000\000\000\000\000\001\017\001\017\000\000\001\017\001\017\001\017\000\000\000\000\000\000\007\234\001\029\001\021\000\000\001\029\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\021\000\000\000\000\000\000\000\000\000\000\000\000\007\186\000\000\000\000\000\000\001\029\000\000\000\000\000\000\000\000\001\029\000\000\000\000\000\000\000\000\000\000\007\194\001\021\001\021\001\029\001\029\001\021\001\029\001\029\000\000\007\210\000\000\000\000\001\029\000\000\000\000\000\000\007\226\000\000\000\000\007\202\000\000\007\218\001\029\000\000\001\021\000\000\001\021\000\000\000\000\000\000\000\000\000\000\000\000\001\021\001\021\000\000\001\021\001\021\001\021\000\000\000\000\000\000\007\234\007\178\001\029\000\000\001-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\029\000\000\000\000\000\000\000\000\000\000\000\000\007\186\000\000\000\000\000\000\001-\000\000\000\000\000\000\000\000\001-\000\000\000\000\000\000\000\000\000\000\007\194\001\029\007\242\001-\001-\001\029\001-\008\026\000\000\007\210\000\000\000\000\001-\000\000\000\000\000\000\007\226\000\000\000\000\007\202\000\000\007\218\001-\000\000\001\029\000\000\001\029\000\000\000\000\000\000\000\000\000\000\000\000\001\029\001\029\000\000\001\029\001\029\001\029\000\000\000\000\000\000\007\234\007\178\001-\000\000\001!\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\007\186\000\000\000\000\000\000\001!\000\000\000\000\000\000\000\000\001!\000\000\000\000\000\000\000\000\000\000\007\194\001-\007\242\001!\001!\001-\001!\001!\000\000\007\210\000\000\000\000\001!\000\000\000\000\000\000\007\226\000\000\000\000\007\202\000\000\007\218\001!\000\000\001-\000\000\001-\000\000\000\000\000\000\000\000\000\000\000\000\001-\001-\000\000\008\"\007\250\001-\000\000\000\000\000\000\007\234\007\178\001!\000\000\001)\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\007\186\000\000\000\000\000\000\001)\000\000\000\000\000\000\000\000\001)\000\000\000\000\000\000\000\000\000\000\007\194\001!\007\242\001)\001)\001!\001)\008\026\000\000\007\210\000\000\000\000\001)\000\000\000\000\000\000\007\226\000\000\000\000\007\202\000\000\007\218\001)\000\000\001!\000\000\001!\000\000\000\000\000\000\000\000\000\000\000\000\001!\001!\000\000\001!\007\250\001!\000\000\000\000\000\000\007\234\000\000\001)\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\001\030\000\000\001\"\000\000\000\000\001&\000\000\000\000\000\000\000\000\000\000\001)\007\242\000\000\000\000\001)\000\000\000\000\000\000\007\210\000\000\001*\000\000\000\000\001.\000\000\000\000\000\000\000\000\000\000\001>\001B\000\000\001J\001)\t\222\001)\000\000\000\000\000\000\001R\000\000\001V\001)\001)\000\000\001)\007\250\001)\000\000\001Z\001^\000\000\n\206\001b\001f\001j\000\000\001n\001r\000\000\001v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001z\000\000\000\000\000\000\001~\000\000\000\000\000\162\001\030\000\000\001\"\000\000\000\000\001&\000\000\000\000\001\134\000\000\000\000\000\000\000\000\000\000\000\000\008>\000\000\001\138\008=\000\000\000\000\001*\000\000\000\000\001.\000\000\000\000\000\000\000\000\001\142\001>\001B\000\000\001J\001\146\000\000\000\000\008=\000\000\008=\001R\000\000\001V\001\150\000\000\000\000\000\000\000\000\000\000\001\154\001Z\001^\000\000\000\000\001b\001f\001j\000\000\001n\001r\000\000\001v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001z\000\000\000\000\000\000\001~\000\000\000\000\000\162\001\030\000\000\001\"\000\000\000\000\001&\000\000\000\000\001\134\000\000\000\000\000\000\000\000\000\000\000\000\008=\000\000\001\138\000\000\000\000\000\000\001*\000\000\000\000\001.\000\000\000\000\000\000\000\000\001\142\001>\001B\000\000\001J\001\146\000\000\000\000\000\000\000\000\000\000\001R\000\000\001V\001\150\000\000\000\000\000\000\000\000\000\000\001\154\001Z\001^\000\000\000\000\001b\001f\001j\000\000\001n\001r\000\000\001v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001z\000\000\000\000\000\000\001~\000\000\000\000\000\162\001\030\000\000\001\"\000\000\000\000\001&\000\000\000\000\001\134\000\000\000\000\000\000\000\000\000\000\000\000\014\186\000\000\001\138\000\000\000\000\000\000\001*\000\000\000\000\001.\000\000\000\000\000\000\000\000\001\142\001>\001B\000\000\001J\001\146\000\000\001\030\000\000\001\"\000\000\001R\001&\001V\001\150\000\000\000\000\000\000\000\000\000\000\001\154\001Z\001^\000\000\000\000\001b\001f\001j\001*\001n\001r\001.\001v\000\000\000\000\000\000\000\000\001>\004\226\000\000\001J\000\000\000\000\000\000\000\000\000\000\000\000\001R\001z\001V\000\000\000\000\001~\000\000\000\000\000\162\000\000\001Z\001^\000\000\000\000\001b\001f\001j\001\134\001n\001r\000\000\001v\000\000\000\000\000\000\000\000\001\138\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001z\001\142\000\000\000\000\001~\000\000\001\146\000\162\001\030\000\000\001\"\000\000\000\000\001&\000\000\001\150\001\134\000\000\000\000\000\000\000\000\001\154\000\000\000\000\000\000\001\138\000\000\000\000\000\000\001*\000\000\000\000\001.\000\000\000\000\000\000\000\000\001\142\001>\001\130\000\000\001J\001\146\000\000\000\000\000\000\000\000\000\000\001R\000\000\001V\001\150\000\000\000\000\000\000\000\000\000\000\001\154\001Z\001^\000\000\000\000\001b\001f\001j\000\000\001n\001r\000\000\001v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001z\000\000\000\000\003\202\001~\000\000\000\000\000\162\003a\000\000\003a\000\000\000\000\003a\000\000\000\000\001\134\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\138\000\000\000\000\000\000\003a\000\000\000\000\003a\000\000\000\000\000\000\000\000\001\142\003a\003a\000\000\003a\001\146\000\000\000\000\000\000\000\000\000\000\003a\000\000\003a\001\150\000\000\000\000\000\000\000\000\000\000\001\154\003a\003a\000\000\000\000\003a\003a\003a\000\000\003a\003a\000\000\003a\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004!\000\000\000\000\004!\000\000\000\000\000\000\000\000\003a\000\000\000\000\000\000\003a\000\000\000\000\003a\000\000\000\000\004!\000\000\000\000\000\000\000\000\000\000\003a\000\000\004!\004!\000\000\000\000\000\000\000\000\000\000\004!\000\000\000\000\001\030\000\000\0012\004!\004!\0016\000\000\004!\000\000\003a\004!\000\000\000\000\004!\003a\000\000\004!\000\000\004!\004!\000\000\001*\000\000\003a\001.\000\000\000\000\000\000\000\000\003a\001:\001N\000\000\001J\000\000\000\000\000\000\000\000\000\000\004!\001R\000\000\001V\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\022\001^\000\000\000\000\003\026\001f\001j\004!\003\030\003\"\000\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\004!\004!\003*\000\000\004\189\004!\003.\004!\000\000\000\162\000\000\000\000\001\030\000\000\0012\004!\000\000\0016\0036\004!\000\000\000\000\004!\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004!\000\000\000\000\001*\004!\004!\001.\000\000\000\000\003:\000\000\000\000\001:\004\202\003>\001J\000\000\000\000\000\000\000\000\000\000\000\000\001R\003B\001V\000\000\000\000\000\000\000\000\001\154\000\000\000\000\003\022\001^\000\000\000\000\003\026\001f\001j\000\000\003\030\003\"\000\000\003&\000\000\000\000\000\000\000\000\001\030\000\000\0012\000\000\000\000\0016\000\000\000\000\000\000\000\000\000\000\003*\000\000\000\000\000\000\003.\000\000\000\000\000\162\000\000\000\000\001*\000\000\000\000\001.\000\000\000\000\0036\000\000\000\000\001:\0032\000\000\001J\000\000\000\000\001\030\000\000\006\202\000\000\001R\006\206\001V\000\000\000\000\000\000\000\000\000\000\003:\000\000\003\022\001^\000\000\003>\003\026\001f\001j\001*\003\030\003\"\000\000\003&\003B\000\000\000\000\000\000\006\210\008*\001\154\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001R\003*\001V\000\000\000\000\003.\000\000\000\000\000\162\000\000\006\234\001^\000\000\000\000\006\238\001f\001j\0036\006\242\006\246\000\000\006\250\000\000\000\000\000\000\000\000\001\030\000\000\006\202\000\000\000\000\006\206\000\000\000\000\000\000\000\000\006\254\007\002\003:\000\000\000\000\007\006\000\000\003>\000\162\000\000\000\000\001*\000\000\000\000\000\000\000\000\003B\007\014\000\000\000\000\006\210\006\214\001\154\000\000\000\173\000\000\000\000\000\000\000\000\000\000\001R\000\000\001V\000\000\000\000\000\000\000\000\000\000\007\018\000\000\006\234\001^\011\026\007\022\006\238\001f\001j\000\000\006\242\006\246\000\000\006\250\007\026\000\000\000\000\000\000\000\000\011\"\001\154\000\000\000\000\000\000\000\000\000\173\000\173\000\000\006\254\007\002\000\000\000\000\000\000\007\006\000\000\011B\000\162\001\030\011*\006\202\011:\000\000\006\206\000\000\000\000\007\014\000\000\000\000\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\011J\000\000\000\000\000\000\000\000\007\018\006\210\007\n\000\000\000\000\007\022\000\000\000\000\000\000\000\000\000\000\001R\000\000\001V\007\026\000\000\000\000\000\000\000\000\000\000\001\154\006\234\001^\000\000\000\000\006\238\001f\001j\000\000\006\242\006\246\011R\006\250\000\000\000\000\000\000\000\000\001\030\0112\t\226\000\000\000\000\t\230\000\000\000\000\000\000\000\000\006\254\007\002\000\000\000\173\000\000\007\006\000\000\000\000\000\162\000\000\000\000\001*\000\000\000\000\000\000\000\000\000\000\007\014\000\173\000\173\t\234\t\246\000\000\000\000\011\018\000\000\000\000\000\000\000\000\000\000\001R\000\000\001V\000\000\000\000\000\000\000\000\000\000\007\018\000\000\n\n\001^\011\026\007\022\n\014\001f\001j\000\000\n\018\n\022\000\000\n\026\007\026\000\000\000\000\000\000\000\000\011\"\001\154\000\000\000\000\000\000\000\000\000\189\011j\000\000\006\254\n\030\000\000\000\000\000\000\n\"\000\000\011B\000\162\001\030\011*\t\226\011:\000\000\t\230\000\000\000\000\n*\000\000\000\000\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\011J\000\000\000\000\000\000\000\000\n.\t\234\n&\000\000\000\000\n2\000\000\000\000\000\000\000\000\000\000\001R\000\000\001V\n6\000\000\000\000\000\000\000\000\000\000\001\154\n\n\001^\000\000\000\000\n\014\001f\001j\000\000\n\018\n\022\011R\n\026\000\000\000\000\000\000\000\000\001\030\0112\t\226\000\000\000\000\t\230\000\000\000\000\000\000\000\000\006\254\n\030\000\000\000\189\000\000\n\"\000\000\000\000\000\162\000\000\000\000\001*\000\000\000\000\000\000\000\000\000\000\n*\011r\011Z\t\234\n\146\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001R\000\000\001V\000\000\000\000\000\000\000\000\000\000\n.\000\000\n\n\001^\000\000\n2\n\014\001f\001j\000\000\n\018\n\022\000\000\n\026\n6\000\000\000\000\000\000\000\000\000\000\001\154\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\254\n\030\000\000\000\000\000\000\n\"\000\000\000\000\000\162\000\000\000\000\000\000\000\000\0002\0006\000F\000b\n*\000f\000\000\000j\000\134\007\169\000\138\017r\000\146\000\000\000\150\000\000\000\154\000\174\000\178\000\182\000\000\000\000\000\000\000\000\000\000\n.\000\000\000\000\000\000\000\000\n2\007\169\000\186\017v\000\000\000\000\000\000\000\000\000\000\n6\000\000\007\169\007\169\019\234\000\000\001\154\000\000\007\169\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\153\000\000\000\000\001\153\000\000\000\202\000\000\007\169\000\000\000\000\018V\000\000\007\169\000:\017\134\000:\007\169\007\169\001\153\000\206\000\000\000\000\001\153\000\000\007\169\000\000\000\000\000\000\007\169\007\169\000\000\000\000\000\000\001\153\000\000\000\000\000\000\001\153\007\169\001\153\001\153\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\169\001\153\000\000\000\000\001\153\000\000\001\153\000\000\000\000\007\169\000\000\000\162\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\169\000\000\017\138\000\000\001\153\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\153\000\000\000\000\000\000\007\169\000\000\000\000\007\169\007\169\000\000\000\000\007\169\000\000\000\000\000\000\000\000\007\169\007\169\000\000\005\129\000\000\007\169\005\129\000\000\001\153\003\166\005\129\001\153\005\129\000\000\000\000\001\153\000\000\005\129\005\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\153\000\000\000\000\000\000\000\000\001\153\001\153\000\000\000\000\000\000\000\000\003\174\000\000\000\000\000\000\001\153\001\153\001\153\000\000\007\169\0002\000\214\000F\000b\000\000\000f\000\000\000j\000\134\000\000\000\138\000\000\000\146\000\000\000\150\005\129\000\154\000\174\000\178\000\182\003\254\000\000\000\000\004N\000\218\000\000\000\000\007\169\000\000\000\000\000\000\000\000\000\186\000\000\000\000\007\169\000\000\000\000\004\006\007\169\007\169\000\000\002\t\000\190\000\000\000\000\000\000\000\000\000\000\007\169\000\000\000\000\000\000\004\014\000\000\000\000\000\000\002\t\000\000\004^\004f\000\000\000\000\000\000\000\202\000\000\000\000\000\000\007\169\004.\000\230\000\000\004\022\005\129\004&\000\000\000\000\000\000\000\206\000\000\000\000\000\000\007\169\011\018\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0046\000\000\000\000\000\000\000\000\000\000\011\026\007\169\000\000\000\000\007\169\007\169\002\t\000\237\000\000\000\000\000\237\000\000\000\000\007\169\007\169\011\"\000\000\000\162\007\169\000\000\000\000\000\177\000\177\000\000\000\000\004\006\000\000\000\000\000\000\000\237\004>\011B\000\000\002\t\011*\000\234\011:\004\030\000\000\000\000\004\014\000\000\000\000\000\000\000\237\000\000\000\237\000\237\000\000\002\t\000\000\000\000\000\000\000\000\002\t\002\t\004.\011J\011Y\004\022\000\000\004&\000\000\000\000\004n\004F\002\t\000\000\000\000\000\000\000\213\000\000\000\000\000\213\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0046\000\000\000\000\000\000\000\000\000\000\000\213\000\000\000\000\000\000\000\213\011R\000\237\000\000\000\000\000\000\000\000\000\000\0112\000\000\000\000\004\014\000\000\000\000\000\000\000\213\000\000\000\213\000\213\000\205\000\177\000\000\000\205\000\000\000\000\000\000\004>\000\213\000\000\000\237\004\022\000\000\004&\004\030\000\000\000\177\011Z\000\205\000\000\000\000\000\000\000\205\000\000\000\000\000\000\000\237\000\000\000\000\000\000\000\000\000\237\000\237\000\205\000\213\000\000\000\000\000\205\000\000\000\205\000\205\000\237\004F\000\237\000\000\000\000\000\213\000\000\000\000\000\205\000\000\000\000\004\022\000\000\000\205\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\209\000\000\000\000\000\209\000\000\000\000\000\000\000\213\000\000\000\000\000\213\000\000\000\205\000\000\004\030\000\000\000\000\000\000\000\209\000\000\000\000\000\000\000\209\000\000\000\205\000\000\000\213\000\000\000\000\000\000\000\000\000\213\000\213\000\209\000\000\000\000\000\000\000\209\000\000\000\209\000\209\000\213\000\213\000\213\000\000\000\000\000\000\000\000\000\205\000\209\000\000\000\205\004\022\000\000\000\209\004\030\000\225\000\000\000\000\000\225\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\205\000\000\000\000\000\000\000\000\000\205\000\205\004\006\000\209\000\000\000\000\000\225\000\000\000\000\000\000\000\205\000\205\000\205\000\000\000\000\000\209\000\000\004\014\000\000\000\000\000\000\000\225\000\000\000\225\000\225\000\000\000\000\000\000\000\000\000\217\000\000\000\000\000\217\000\225\000\000\000\000\004\022\000\000\004&\000\209\000\000\000\000\000\209\000\000\000\000\000\000\004\030\004\006\000\000\000\000\000\000\000\217\000\000\000\000\000\000\000\000\000\000\000\000\000\209\0046\000\000\000\000\004\014\000\209\000\209\000\000\000\217\000\000\000\217\000\217\000\000\000\225\000\000\000\209\000\209\000\209\000\000\000\000\000\217\000\000\000\000\004\022\000\000\004&\000\000\000\221\000\000\000\000\000\221\000\000\000\000\000\000\000\000\000\000\000\000\000\225\000\000\000\000\000\225\000\000\000\000\000\000\004\030\004\006\000\217\000\000\000\000\000\221\000\000\000\000\000\000\000\000\000\000\000\000\000\225\000\000\000\217\000\000\004\014\000\225\000\225\000\000\000\221\000\000\000\221\000\221\000\000\000\000\000\000\000\225\000\225\000\225\000\000\000\000\000\221\000\000\000\000\004\022\000\000\004&\000\217\000\000\000\000\000\217\000\000\000\000\000\000\004\030\000\229\000\000\000\000\000\229\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\217\0046\000\000\000\000\000\000\000\217\000\217\004\006\000\000\000\000\000\000\000\229\000\000\000\221\000\000\000\217\000\217\000\217\000\000\000\000\000\000\000\000\004\014\000\000\000\000\000\000\000\229\000\000\000\229\000\229\003\254\000\000\000\000\000\245\000\000\000\000\000\000\000\221\004.\000\000\000\221\004\022\000\000\004&\004\030\000\000\000\000\000\000\004\006\000\000\000\000\000\000\000\245\000\000\000\000\000\000\000\221\000\000\000\000\000\000\000\000\000\221\000\221\004\014\0046\000\000\000\000\000\245\000\000\000\245\004f\000\221\000\221\000\221\000\000\000\000\000\229\000\000\000\000\004.\000\000\000\000\004\022\000\000\004&\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\254\000\000\000\000\000\233\000\000\000\000\000\000\004>\000\000\000\000\000\229\000\000\0046\000\000\004\030\000\000\000\000\000\000\004\006\000\000\000\000\000\000\000\233\000\000\000\245\000\000\000\229\000\000\000\000\000\000\000\000\000\229\000\229\004\014\000\000\000\000\000\000\000\233\000\000\000\233\000\233\000\229\000\229\000\229\000\000\000\000\000\000\000\000\004>\004.\000\000\000\245\004\022\000\000\004&\004\030\003\254\000\000\000\000\000\241\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\245\000\000\000\000\000\000\000\000\000\245\000\245\004\006\0046\000\000\000\000\000\241\000\000\000\000\000\000\004n\004F\000\245\000\000\000\000\000\233\000\000\004\014\000\000\000\000\000\000\000\241\000\000\000\241\004f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004.\003\185\000\000\004\022\003\185\004&\004>\000\000\003\185\000\233\003\185\000\000\000\000\004\030\000\000\003\185\003\185\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\233\0046\000\000\000\000\000\000\000\233\000\233\000\000\000\000\000\000\000\000\000\000\000\000\000\241\000\000\000\233\004F\000\233\000\000\002-\000\000\000\000\000\000\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\185\000\000\004>\000\000\000\000\000\241\000\000\000\000\000\000\004\030\000\000\000\000\002-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002-\000\241\000\000\000\000\002-\002-\000\241\000\241\000\000\000\000\000\000\000\000\000\000\000\000\002-\000\000\000\241\004F\000\241\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002-\0002\005.\000F\000b\003\185\000f\000\000\000j\000\134\000\000\000\138\000\000\000\146\002-\000\150\000\000\000\154\000\174\000\178\000\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\186\002-\000\000\000\000\002-\002-\000\000\000\000\000\000\000\000\000\000\000\190\000\000\002-\002-\000\000\000\000\000\000\002-\000\000\000\000\0002\000\214\000F\000b\000\000\000f\000\000\000j\000\134\000\000\000\138\000\202\000\146\000\000\000\150\000\000\000\154\000\174\000\178\000\182\000\000\000\000\000\000\000\000\000\000\000\206\000\000\000\000\000\000\0052\0056\000\000\000\186\000\000\0002\005.\000F\000b\000\000\000f\000\000\000j\000\134\000\190\000\138\000\000\000\146\000\000\000\150\000\000\000\154\000\174\000\178\000\182\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\202\000\000\000\186\000\000\000\000\000\000\000\230\000\000\000\000\000\000\000\000\000\000\000\000\000\190\000\206\000\000\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\000\000\000\000\000\000\000\000\000\000\202\000\000\000\000\000\000\000\000\002y\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\206\000\000\000\000\000\000\021\182\0056\000\162\000\000\000\000\0002\005.\000F\000b\000\000\000f\000\000\000j\000\134\000\000\000\138\000\000\000\146\000\000\000\150\000\234\000\154\000\174\000\178\000\182\000\000\000\000\000\000\0002\000\214\000F\000b\000\000\000f\000\000\000j\000\134\000\186\000\138\000\000\000\146\000\000\000\150\002)\000\154\000\174\000\178\000\182\000\190\000\000\000\000\000\000\000\000\000\000\021\186\000\000\000\000\000\000\000\000\000\000\000\186\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\202\000\000\000\190\000\000\000\000\002q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\206\000\000\000\000\000\000\0052\0056\000\000\000\000\000\000\000\202\000\000\000\000\011\018\000\000\000\000\000\230\000\000\0002\005.\000F\000b\000\000\000f\000\206\000j\000\134\000\000\000\138\000\000\000\146\011\026\000\150\000\000\000\154\000\174\000\178\000\182\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\"\000\000\000\000\000\000\000\186\000\000\000\185\011j\000\000\000\000\000\000\000\000\000\000\005B\000\000\000\190\011B\000\000\000\162\011*\000\000\011:\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\202\000\000\000\000\000\000\000\000\000\000\011J\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\206\000\000\000\000\000\000\021\182\0056\000\000\000\000\000\000\002!\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011R\000\000\000\000\000\000\000\000\000\000\000\000\0112\000\000\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\000\000\000\000\000\000\000\000\000\000\000\000\000\021\194\000\000\000\000\000\000\000\185\011Z"))
+    ((16, "\000\212\000\031\000\000\000\000\000\235\000\000\000\000\000\000\000\212\000\000\000\228\031D\000\000\000\129F\002\000\000\000\000\026v\000\000\031\210\000\000\000\000\000\000\000\000\000\000\000\000\027b\000\000 d\000\000\000\000\000\000\000\000\000\000!P\000\000\000\000\000\000\000k\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\165\000c\000\000\031D!\158G\168\000+GD\000\000\000\000\000\0000h\000rG\168\000\015G\168\000\000\000\156\000\000G\168\000\000\000k\003\250<J\000\000\000\000>\144\000\000@\182\000\000Ad<J<J\018~\018~@\182\018~\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000?:<J\000\000\000\000?:\000\000?:\000\000<J\000\000\000\000\000\000\020\246\000k\000\000\018~\000\0004^<J\027\176<J\000\000\000\000\000\000\000\000\000\000\000\000\"d<J#X<J$L<J%@<J\000\000<J\000\000<J&4<J'(<J(\028<J)\016<J*\004<J\000\230<J\000\000\000\000\000\000\000\000\000\000<J*\248<J+\236<J,\224<J\000\000\000\000<J\000\000\000\000\021\144.D\000\000\000\000\000\250\000\000\000\000\000\000\000\000\019F\000\129\000\000.:\000\000\000\160\018~\000\000<J\001\028\000\000\000\000\000k\000\000\000\000\000\000\000\000\000\000\001F\000\000\000\000\001\210\000\000\001\212@\182\000\000\000\000\000\000\000\000\000\000\000\000A\232<J\000\000A\232\000\000A\232@\182\000\000\000\0003\018\000k\000\000\018~\001\228\000\000<J\002D\000\000\000\000\000k\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000FP<J\000\000<J\000\000\000\000\002\136\000\000\000=?\228\003\158<J\003p\000\000\000\000@\182\000=\000\000\000\000\000\000\000\000\000\000G\164@\182HT@\182H\210@\182I$@\182\000\000@\182\000\000@\182I\162@\182J\018@\182Jl@\182J\220@\182KZ<J\003*@\182\000\000@\182K\172@\182L*@\182L\154\003\016\000\000\003V\000\000\001\016<J\000\000\001\016\000\000\000\000\000\234\031D\000\000\000\234\000\000\000\000\003X<J\000\000\003\136\000\000\018~\003\150\000\000\000\000\004r\000\000\018~\003\238\000\000\000\000\004(\000\000\000\000\003\250\000\000\005\030\000\000.DM\030\005\008\005\012\000k\004\134\005BN\012\001\168\000\000\000\000\002$Oh\000\000\000\000\000\000\005^\005`\000k\005\146N\012\002nN\012\000\000\000\000\001\028\000\000\000\000\004\232\000\000\004\234\005\224N\012\005.\000\000\000\000\002$\000\000\005D\006\028\000\000O\150Nv\000\000\000k\0068\000\000\019F\000k\006l\000\000\000\000-\178G\168\005\150\000\000\006\018\000\000\005\156\000\000\000\029\031D\000\000\031D\000\000\005\138\000\000\000\029\000\000\015\238\0086\006\\N\012\005\168\006\130\000\000(\004\000\129\000\000\000|\001\208\031D\005\182\000\000\0009\000\000\000\023\000\000\006\140\000\000\000\000\023~\000\129\000\000\0009\000\000\000\000\000\000\000\000\000\000\006r<J\005\190\019<\006x<J\005\196\006v\000\138\005\240\006\162\000\000B0B\180\018~\005\206\000\000\005\208B\180\000\000\000\000\000\000\000\000\000\000\000\000\000\000C^<J\000\000C^\000\000C^B\180\000\000\000\000\024\204\000k\000\000\018~\005\214\000\000<J\005\214\000\000\000\000\000k\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000/\184<J\000\000<J\000\000\005\222\000\000\001\016\000\000\000\000\000\000\000\000\000\0004\184B\1805\172B\1806DB\1806\220B\180\000\000B\180\000\000B\1807tB\1808\012B\1808\164B\1809<B\1809\212<J\006\008B\180\000\000B\180:lB\180;\004B\180;\156\018~\005\228\000\000\000\000<\244\000\000\006\190\000\000\001R\006\156<J\006n\000\000\006\170<J\006~\000\000\007(\000\000\006\162\006\162\001R\000\000\001R\000\000\015\238\006\162\006\162\000\000\000\000\000\000\023\216\000\000\000\000\000\000\000\000\006\206<J\006 \019<\020\016\000k\007\000\000\000\006\228=\158\007\n=\158\007\018<J\006@\019<\019<\002`\003\180\001p\000\000\000\000\000\000\003\180\000\000\004v\002`\000\000\000\000\006B\000\000\000\000\000\000\007\026\000\000\007 \000\000\000\000\007X\007\018<J\006^\0078\000\000@\134\007\026\018~\006j\019<\000\000\000\000\006\146\000\000\000\148\000\000\005N\000\000\001R\000\000\000\000\006\224\000\000$4\0086\007&N\012\006t\007L\000\000\000k\000\000\002p<J0\142\000\000C\226<J\006z\000\000\018~\006|\000\000\006\130\000\000\000\000\000\000\000\000\000\000\000\000\000\000D\140<J\000\000D\140\000\000D\140E\016\018~\006\134E\016\000\000\000\000\029H\000k\000\000\018~\006\150\000\000<J\006\150\000\000\000\000\000k\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000<J\001\004<J\006\158\000\000\000\0001</\016\007N<J\000\000\007\024\000\000\000\000\000k\000\000\000\000\006\2200\142\000\000\006\2200\142\000\000\001\250\000\000\000\000\017\172E\016\023^E\016\026\158E\016\029\240E\016\000\000E\016\000\000E\016\030rE\016\031\136E\0163vE\0164\200E\016C\016E\016D>E\016H\"E\016O\240\000\000\006\178\000\000\006\2241\234\000\0002\152\006\2402\1523\190\006\2442\152\000\000\000\000\000\000\000\000\000\000\006\232\000\000\007\198\000\000\000k\000\000\002p\007\204\000\000\007\174\007\158\000k\007\000\007\190N\012\007\018\000\232\000\000<J\007\236\000\000\000\127\003\226\004x\007\212N\012\007 \007\248\000\000\003\028<J\007\250\000\000\008\000\000\000\019F\000k\003$<J\008\006\000\000\008\n\000\000\011\242\001\028\000\000\011\242\000\000\000\000\021\234\003F<J\008\012\000\000\008\014\000\000\000\000\007\248\007\234\000k\007L\008\006N\012\007T\001\252\000\000<J\008.\000\000\001\028\000\000\000\000\007\246\000\000\011\242\000\000\008\022\018~\007b\008:\000\000\000>\000\000\008\"N\012\007t\008T\000\000\003\248<J\008X\000\000\008^\000\000\019F\000k\004\166<J\008d\000\000\008f\000\000\000\000\000\000\007\246\000\000\000\000\001\028\000\000\006\162\000\000\000>\000\000\000\000\001\254\020\016\000\000\001\254\000\000\000\000\007\150\000\000\003\024\000\003\019<\000\000\003\250\000%\003\250\000\000\000\148\000\000\006\162\000\000\006\162\000\000\000\000\000\000\007\144\000\000\000\000\007\154\000\000\003:\005N\000%\003\250\000\000\000\000\000\000\000\148\000\000\006\162\000\000\003:\000\000\000\000\000\234\000\015\015\238\000\000\020\016\000\000\tJ\015\238\000\000\000\000\tJ\000\000\000\000\007\156\000\000\000\000\007\174\000\000\004z\006\162\000\000\004z\000\000\000\000\008&\000\000\001\028\000\000\006\162\000\000\000\000\000\000\0176>H\000\000\008\140\000\000\0176\008\142\000\000\008\148\000\000$4\000k\002*\000\000<J\008\150\000\000\008x\008h\000k\007\200\008\128N\012\007\204\002\180\000\000<J\008\166\000\000\000\127\003\174\000\000<J\008\168\000\000\019F\000k\004:\000\000<J\008\172\000\000\004\174\0176\000\000\021\234\005d\000\000<J\008\174\000\000\000\000\000\000\008\144\008\132\000k\007\236\008\164N\012\007\242\005\198\000\000<J\008\204\000\000\005\026\000\000\008\174\018~\007\250\008\210\000\000\004\018\000\000\005\248\000\000<J\008\218\000\000\019F\000k\005\254\000\000<J\008\224\000\000\004\174\000\000\000\000\008*\000\000\005\026\008\226\008\158\000\000\000\000\000\000\008\174\000\000\000\027\002r\000\000\015\238\t\000\000\000\000\000<J\008f\006\162\000\000\008<\000\000\000\138\000\000\000\000\000\025\015\238\000\000\015\238\000\000\008.\000\000\000\025\000\000@\182\002\154@\182\000\000@\182\000\000\0080\000\000\002\154\000\000\019<\004\220\019<\000\000\019<\000\000\0082\000\000\004\220\000\000@\182\002\154\0086\000\000#@\000k\0058#@\000\000#@\000\000\008H\000\000\0058\000\000@\182\002\154\008J\000\000\000\000\023\006\000\000\000\000\000\000\000\000\000\000\025\232\029\004\000\000\005\136\000\000\0008\000\000\000\000\008\150\000\127\000\000\000\000\000\000\000\000\000\230\0008\000\000\004\016\002\020\0008\000\000\000P\0008\000\000\008n\000\000\000\000\000\000\000\000\000\000\000\000\008\240\000\000\0304\000\000\031D\0008\000\000\003\240\0008\000\000\008\242\000\000\0008\008\244\000\000\007z\0008\008\252\000\000\t\002\000\000\n\194\0008\0008\008\140\0008\t\018\000\000\t\022\000\000\t\024\000\000\031D\000\000\001\164\031D\000\000\008\156\006\220\000\000\002\236\0008\000\000\004|\0008\000\000\005\012\001<\000\127\000\000\t\230\000\127\000\000\008\158\000\000\000\000\000\000\000\000\t \000\000\012\022\018\"\t$\000\000\t,\000\000\0008\t.\000\000\0008\t0\000\000\0008\t8\000\000\t\022\0008\tJ\000\000\0080\016\218\0008\008\208\0008\tN\000\000\tP\000\000\000\000\004\204\0008\000\000\005d\002\220\002\220\000\000\000\000\000\000\004\138\002\220\000\000\008\214\000\000\000\000\000\000\000\000\0008\000\000\005\136\0008\000\000\005\220\005\024\000\127\008\216\000\000\000\000\000\000\000\000\tZ\000\000\t\\\000\000\0008\t`\000\000\012,\018\"\tb\000\000\tj\000\000F\006\t \tL\017l\0008\t~\000\000\000\000\t\130\000\000\tbF\006\0008\t\146\000\000\0008\t\148\000\000\t\150\000\000\n\216\t\028\0008\t\156\000\000\t\158\000\000\000\127\t\024\000\000\000\000\023\006\000\000\000\000\002F\n\002\000\000\000\000\001\027\000\000\000\000\000\000<J\000z\nB\tj\t\240@\182\000\000\0036@\182\000\000\tB\000\000\000\000\000\000\000\000\000\000\002\166\000\000\003\170\000\000\000\000\000\000\003\250&\028\003\202&\028&\028\003\202\000\000\000\000\0028\0028\0028\0028\000\000\000\000\000\000\000\000\000\000\000\000\001R\015\238\n\012\013F\001\028\000\000\000\000\001\028\000\000\007\246\000\0000\142\tH\000\000\001R\015\238\tV\014\154\000\000\001R\013F\000\000\000\000\000\000$4\t\156\000\000\000z\000\000\000\000\t\190\000\030\nHN\186\000\000\005\022P&\000\000\000\000\nJ\n:\000k\000\000\000k\000\000\005\022\000\000\005JN\186\000\000\000\000\t\152\nJ\006\162\t\152\000\000\nn\001\028\000\000\007\246\000\000\003\128\001\174\000\000\000\000\n8\000\000\000\000\002F\000\000\004\198\000\000\000\000\000\000<J\000z\000\000\002\166\000\000\005\n\000\000\000\000\000\000\005N\000\000\n\158\002b\n\158\000\000\006\162\n\158\000\000\003\196\000\000\006\162\000\000\006\162\000\000\006\162\000\000\000\000\000\000\000\000\000\000\000z\000\000\006\162\000\000\003\196\000\000\006\162\000\000\004\212\000\000\000\000\tJ\t\202\000\127\002\148\nt\002\142\000\000\002\142\n\160\000\000\n\162\000\000\n\166\000\000\000\000\003R\002\142\016\134\002\142\000\000\000\000\005>\t\180\000\000\tJ\n\170\000\000\006,\003^\n\186\011\194\n\186\000\000\000\000\002\030\000\127\000\000\002F\n\012\000\000\000\000\000\000\005\206\000\000\t\190\000\000\000\000\000\000\000\000\tJ\006,\003^\002\030\002F\005\206\t\192\000\000\006,\003^\002\030\002F\005\206\t\196\000\000\000\127\000\000\n\192\n\188\n\000\000\127\n\\\000\000"), (16, "\n\237\n\237\n\237\n\237\n\237\n\237\n\237\n\237\n\237\n\237\n\237\000:\n\237\n\237\n\237\n\237\n\237\n\237\n\237\n\237\n\237\n\237\000\n\001^\020\131\020\135\n\237\012\022\001j\020\139\006\025\006\002\n\237\016\130\n\237\n\237\n\237\000\158\007y\n\237\017r\008J\000\014\n\237\n\237\005\129\n\237\002\146\000\023\000\027\008~\005\129\008J\007y\000\218\n\237\000\162\000\194\n\237\n\237\004\t\008~\017v\000\250\n\237\n\237\000\162\n\237\006j\n\237\000\198\000J\017z\000N\n\237\000V\n\237\n\237\n\237\n\237\n\237\013\006\000Z\000\158\n\237\n\237\n\237\ny\n\237\n\237\n\237\005\129\n\237\n\237\n\237\n\237\006\n\0182\016\138\n\237\n\237\001^\017\134\007y\005Z\001f\001j\003\198\000\162\n\237\n\237\n\237\000\162\n\237\n\237\n\237\n\237\001^\n\237\t\158\n\237\012\022\001j\n\237\t\146\n\029\n\237\n\237\006\025\000\242\t\158\013~\n\237\008J\000\162\013\174\n\237\000\006\004\t\n\237\016B\000^\008~\n\237\n\237\n\237\n\237\000\162\n\237\n\237\000\162\007y\004\t\n\237\n\237\n\237\005\193\n\237\005\217\n\237\n\237\017\138\n\237\007y\n\237\n\237\012\002\013\006\n\237\n\237\006!\006!\006!\006!\006!\006!\006!\006!\006!\006!\006!\n\029\006!\006!\006!\006!\006!\006!\006!\006!\006!\006!\t\146\017\178\020\150\004\162\006!\008N\008^\008n\n\161\008J\006!\001^\006!\006!\006!\012\022\001j\006!\008~\t\158\n\209\006!\004\138\006\194\006!\000.\006\"\016\162\016\202\016\242\017\002\017.\016Z\006!\0069\0069\018\150\005\145\004\t\0069\000\158\002\202\006!\006!\000\162\003\137\001\006\006!\006!\000n\011\145\000r\006!\000z\006!\006!\006!\006!\006!\012\006\000~\002F\006!\006!\006!\022+\006!\006!\006!\000\162\006!\006!\006!\006!\022/\n\174\017\150\006!\006!\005\185\005\185\005\233\000\158\011\145\0222\000\162\005\129\t\158\006!\006!\002\162\006!\006!\006!\006!\000\218\006!\n\186\006!\006\142\005\241\006!\006\146\007e\006!\006!\021\n\007e\006\150\002\218\006!\000\162\012\194\006\154\021\014\011\145\011\145\006!\017z\000\130\011\145\006!\006!\006!\006!\0061\006!\006!\002\254\t\n\n\166\006!\006!\006!\006A\014\230\006A\006!\006!\006A\006!\013\138\006!\006!\017\166\023\146\006!\006!\006A\006A\006A\006A\006A\006A\006A\006A\006A\006A\006A\008r\006A\006A\006A\006A\006A\006A\006A\006A\006A\006A\n\137\018b\008J\002a\006A\020r\006A\002a\n\129\023\018\006A\008~\006A\006A\006A\006A\016\170\006A\006A\006A\006A\006A\006A\006A\006A\006A\005\169\012\198\003\n\003\018\n\222\023\022\000\158\006A\015\022\0061\006A\003f\023\026\0061\0061\006A\006A\006A\006A\006A\003\213\006A\006A\006\017\014\234\023\134\006A\020r\006A\023\154\006A\006A\006A\003\161\023\158\000\162\006A\006A\006A\005>\006A\006A\006A\005\161\006A\006A\006A\006A\019N\0061\008Y\014\170\006A\t\002\t\158\016\178\014\174\006A\t\146\t\218\n\137\003r\006A\006A\n\137\006A\006A\006A\006A\003\161\006A\023\"\006A\003\017\023n\006A\005f\011\206\006A\006A\002\141\n\137\008Y\008Y\006A\023\n\004\138\008Y\006A\006)\019R\006A\016.\015\026\003\190\006A\006A\000\162\006A\023:\006A\006A\023*\013\254\005\129\006A\0081\005\129\0035\018z\013\006\005\129\006A\005\129\006A\005\209\006A\006A\005\129\005\129\006A\006A\0002\006&\000F\000b\006>\000f\006\142\000j\000\134\006\146\000\138\015.\000\146\020\234\000\150\006\150\000\154\000\174\000\178\000\182\006\154\020\242\t\146\0126\001^\003\206\006\158\012V\012\022\001j\003\214\008J\000\186\004V\001\030\006\174\006\202\004\193\004z\006\206\008~\011\206\005\241\000\190\012\138\011\206\008:\006)\n\137\005\137\002\146\006)\006)\004%\020\174\001*\004\193\000\162\021.\005\249\n\145\015\214\011\206\006)\008\146\006\214\021Z\021f\001\026\008\150\013\186\007=\023J\004\130\001R\004\186\001V\003\229\000\206\t\154\008\158\015J\017\162\023B\006\234\001^\008\162\006)\006\238\008\166\001j\n\177\006\242\006\246\008\170\006\250\0152\001^\004\198\005\129\008\174\012\022\001j\007=\007=\008Y\004\210\006i\007=\t\158\006\254\007\002\004\189\008\178\008\182\007\006\008\186\t\006\000\162\004\222\008\206\005\177\004\193\003\193\020\219\020\223\008\218\007\014\004!\020\227\000\162\004\189\006I\013\"\005\137\n\137\021z\008Y\008Y\008\250\004\193\014~\008Y\008\254\t:\003\229\t\166\017\246\007\018\t>\004\234\011\206\005\137\007\022\003\229\003\229\005\137\016\210\013\006\003\229\tF\n\193\007\026\006i\006I\006I\015N\015^\001\154\006I\0002\006&\000F\000b\006>\000f\006\142\000j\000\134\006\146\000\138\004\246\000\146\020\234\000\150\006\150\000\154\000\174\000\178\000\182\006\154\020\242\0039\015\186\001^\005\n\006\158\004\189\012\022\001j\005\026\n\185\000\186\017\014\001\030\006\174\006\202\0039\018\146\006\206\0085\005\030\019\154\000\190\t\"\004\189\008:\018\134\003\021\006\001\013B\004\138\016\218\023:\019b\001*\005&\000\162\008J\005*\015n\n\153\0085\006Y\008\146\006\214\021Z\008~\011\206\008\150\014\002\008\145\0085\005R\001R\006\t\001V\003\245\000\206\t\154\008\158\017j\019J\005V\006\234\001^\008\162\019>\006\238\008\166\001j\000\162\006\242\006\246\008\170\006\250\022K\022O\017\022\005^\008\174\022S\0085\008\145\008\145\005\130\005\138\006Q\008\145\015\166\006\254\007\002\005\225\008\178\008\182\007\006\008\186\0039\000\162\006Y\008\206\0039\0039\003\193\021\190\n\201\008\218\007\014\005\153\005\241\022o\022s\006q\0039\015\222\022w\t\158\015\250\005\142\008\250\005\150\0035\019\150\008\254\t:\015r\t\166\0085\007\018\t>\021\238\005\170\005\174\007\022\002\129\003\245\0035\0039\005\201\023B\tF\0085\007\026\006Q\006q\006q\005\198\006a\001\154\006q\0002\006&\000F\000b\006>\000f\006\142\000j\000\134\006\146\000\138\019\138\000\146\020\234\000\150\006\150\000\154\000\174\000\178\000\182\006\154\020\242\005\214\023\166\015\170\005\234\006\158\005\242\005\250\006\023\006.\0066\000\186\006:\001\030\006\174\006\202\006Z\006r\006\206\005\129\006\162\006\170\000\190\006\178\006\186\008:\006\190\006\198\015\226\006\222\006\230\015\254\006a\007>\001*\007J\007\146\008J\005%\008\n\0082\005\129\008F\008z\006\214\0035\008~\008R\008\150\0035\0035\005\129\008Z\001R\008b\001V\004\017\000\206\008\154\008\158\008j\0035\023\n\006\234\001^\008\162\008\190\006\238\008\166\001j\008\198\006\242\006\246\008\170\006\250\008\214\005\129\008\222\011\153\008\174\008\230\005\129\002\146\008r\008\238\0035\008\246\t2\tB\006\254\007\002\tJ\008\178\008\182\007\006\008\186\tV\000\162\018\022\008\206\tZ\tb\003\193\tf\tr\008\218\007\014\tz\t\138\t\174\t\190\008a\t\198\t\202\t\242\t\158\t\254\008v\008\250\n\006\017v\nF\008\254\t:\004\017\t\166\005\129\007\018\t>\nf\017z\nr\007\022\004\017\004\017\n\182\n\202\n\214\004\017\tF\005\129\007\026\n\238\008a\008a\n\250\011\130\001\154\008a\0002\006&\000F\000b\006>\000f\006\142\000j\000\134\006\146\000\138\017\134\000\146\011\138\000\150\006\150\000\154\000\174\000\178\000\182\006\154\011\154\014\170\011\166\011\194\011\202\006\158\014\174\011\222\011\230\011\234\014\178\000\186\011\242\001\030\006\174\006\202\011\246\005\129\006\206\019\022\005\129\011\254\000\190\012\014\005\129\008:\005\129\012\"\012*\012.\012>\005\129\005\129\012F\001*\000\162\012^\008J\012f\012\146\012\154\017v\016.\008z\006\214\012\166\008~\012\170\008\150\017\138\012\178\017z\012\182\001R\012\190\001V\012\206\000\206\008\154\008\158\012\242\012\250\012\254\006\234\001^\008\162\013\014\006\238\008\166\001j\013\022\006\242\006\246\008\170\006\250\013\026\005\129\013*\011\153\008\174\0132\017\134\000:\013J\013R\000\218\013\162\013\234\013\246\006\254\007\002\014j\008\178\008\182\007\006\008\186\001^\000\162\014v\008\206\001f\001j\014\150\014\194\014\206\008\218\007\014\014\214\014\242\014\250\014\254\011\153\015\006\015\n\015\018\t\158\015\"\015:\008\250\015V\015z\015\138\008\254\t:\015\142\t\166\000\162\007\018\t>\000\162\015\150\015\154\007\022\015\162\005\129\015\178\015\194\015\202\015\206\tF\017\138\007\026\015\234\011\153\011\153\016\006\015\214\001\154\011\153\0002\006&\000F\000b\006>\000f\006\142\000j\000\134\006\146\000\138\016\026\000\146\016*\000\150\006\150\000\154\000\174\000\178\000\182\006\154\016:\016R\016b\016n\004\162\006\158\016\151\016\191\016\231\003\173\016\255\000\186\001^\001\030\006\174\006\202\012\022\001j\006\206\017#\017;\022\254\000\190\007\129\003\173\008:\006\142\017~\017\190\006\146\017\219\018\003\018\015\021\n\001*\006\150\018\031\008J\007\129\018'\006\154\021\014\018:\008z\006\214\000\162\008~\018C\008\150\018K\018S\018n\018\174\001R\018\195\001V\018\211\000\206\008\154\008\158\018\219\018\231\018\243\006\234\001^\008\162\018\255\006\238\008\166\001j\019\006\006\242\006\246\008\170\006\250\019\015\019\"\019+\0193\008\174\019n\019\162\005\233\019\183\019\191\011\230\019\203\019\219\007\129\006\254\007\002\019\227\008\178\008\182\007\006\008\186\019\238\000\162\019\242\008\206\023Z\019\255\n\169\020\011\003\173\008\218\007\014\023^\003\173\003\173\020\018\020\031\020+\0203\020>\t\158\020G\020O\008\250\020[\003\173\003\173\008\254\t:\020v\t\166\020\154\007\018\t>\020\158\020\162\006\142\007\022\020\186\006\146\021:\007\129\021b\021\n\tF\006\150\007\026\021r\003\213\003\173\006\154\021\014\001\154\007\129\0002\006&\000F\000b\006>\000f\006\142\000j\000\134\006\146\000\138\021\170\000\146\020\234\000\150\006\150\000\154\000\174\000\178\000\182\006\154\020\242\021\178\021\206\021\210\021\254\006\158\022\002\022\n\018.\0227\023\002\000\186\n\169\001\030\006\174\006\202\n\169\n\169\006\206\017r\012\166\023\014\000\190\023\030\023&\008:\023.\023W\023b\023r\017v\023\150\023\175\023\219\001*\023\247\024\006\024\n\024\014\018\162\017z\017v\024\023\008\146\006\214\000\000\n\169\000\000\008\150\022\134\000\000\017z\n\169\001R\000\000\001V\000\000\000\206\t\154\008\158\000\000\000\000\000\000\006\234\001^\008\162\000\000\006\238\008\166\001j\017\134\006\242\006\246\008\170\006\250\000\000\020:\000\000\003\213\008\174\000\000\017\134\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\254\007\002\000\000\008\178\008\182\007\006\008\186\000\000\000\162\000\000\008\206\000\000\000\000\003\193\000\000\000\000\008\218\007\014\000\000\000\000\000\000\000\000\008E\000\000\000\000\000\000\000\162\000\000\000\000\008\250\000\000\000\000\000\000\008\254\t:\000\000\t\166\000\162\007\018\t>\017\138\000\000\000\000\007\022\000\000\000\000\000\000\000\000\000\000\000\000\tF\017\138\007\026\000\000\008E\008E\000\000\000\000\001\154\008E\0002\006&\000F\000b\006>\000f\006\142\000j\000\134\006\146\000\138\000\000\000\146\000\000\000\150\006\150\000\154\000\174\000\178\000\182\006\154\nq\000\000\000\000\000\000\000\000\006\158\000\000\000\000\017r\000\000\000\000\000\186\000\000\001\030\006\174\006\202\000\000\000\000\006\206\017r\000\000\000\000\000\190\000\000\000\000\008:\000\000\000\000\000\000\000\000\017v\000\000\000\000\000\000\001*\000\000\000\000\000\000\000\000\000\000\017z\017v\000\000\008\146\006\214\000\000\000\000\000\000\008\150\012n\000\000\017z\000\000\001R\000\000\001V\000\000\000\206\t\154\008\158\000\000\000\000\000\000\006\234\001^\008\162\000\000\006\238\008\166\001j\018\202\006\242\006\246\008\170\006\250\000\000\000\000\000\000\011u\008\174\nq\019\210\000\000\000\000\nq\nq\000\000\000\000\000\000\006\254\007\002\000\000\008\178\008\182\007\006\008\186\nq\000\162\000\000\008\206\000\000\000\000\000\000\000\000\000\000\008\218\007\014\023v\000\000\000\000\000\000\011u\000\000\000\000\000\000\000\162\000\000\000\000\008\250\000\000\nq\000\000\008\254\t:\000\000\t\166\000\162\007\018\t>\017\138\000\000\000\000\007\022\000\000\000\000\000\000\000\000\000\000\000\000\tF\017\138\007\026\000\000\011u\011u\000\000\000\000\001\154\011u\0002\006&\000F\000b\006>\000f\006\142\000j\000\134\006\146\000\138\000\000\000\146\000\000\000\150\006\150\000\154\000\174\000\178\000\182\006\154\000\000\000\000\000\000\000\000\000\000\006\158\000\000\000\000\000\000\000\000\000\000\000\186\000\000\001\030\006\174\006\202\000\000\000\000\006\206\000\000\000\000\000\000\000\190\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\000\000\000\000\000\000\000\000\000\000\000\000\000\008\146\006\214\000\000\000\000\000\000\008\150\021>\000\000\000\000\000\000\001R\000\000\001V\000\000\000\206\t\154\008\158\000\000\000\000\000\000\006\234\001^\008\162\000\000\006\238\008\166\001j\000\000\006\242\006\246\008\170\006\250\000\000\000\000\000\000\000\000\008\174\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\254\007\002\000\000\008\178\008\182\007\006\008\186\000\000\000\162\000\000\008\206\000\000\000\000\000\000\000\000\000\000\008\218\007\014\000\000\000\000\000\000\000\000\011\193\000\000\000\000\000\000\000\000\000\000\000\000\008\250\000\000\000\000\000\000\008\254\t:\000\000\t\166\000\000\007\018\t>\000\000\000\000\000\000\007\022\000\000\000\000\000\000\000\000\000\000\000\000\tF\000\000\007\026\000\000\011\193\011\193\000\000\000\000\001\154\011\193\0002\006&\000F\000b\006>\000f\006\142\000j\000\134\006\146\000\138\000\000\000\146\000\000\000\150\006\150\000\154\000\174\000\178\000\182\006\154\000\000\000\000\000\000\000\000\000\000\006\158\000\000\000\000\000\000\000\000\000\000\000\186\000\000\001\030\006\174\006\202\000\000\000\000\006\206\000\000\000\000\000\000\000\190\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\000\000\000\000\000\000\000\000\000\000\000\000\000\008\146\006\214\000\000\000\000\000\000\008\150\021>\000\000\000\000\000\000\001R\000\000\001V\000\000\000\206\t\154\008\158\000\000\000\000\000\000\006\234\001^\008\162\000\000\006\238\008\166\001j\000\000\006\242\006\246\008\170\006\250\000\000\000\000\000\000\000\000\008\174\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\254\007\002\000\000\008\178\008\182\007\006\008\186\000\000\000\162\000\000\008\206\000\000\000\000\000\000\000\000\000\000\008\218\007\014\000\000\000\000\000\000\000\000\011\189\000\000\000\000\000\000\000\000\000\000\000\000\008\250\000\000\000\000\000\000\008\254\t:\000\000\t\166\000\000\007\018\t>\000\000\000\000\000\000\007\022\000\000\000\000\000\000\000\000\000\000\000\000\tF\000\000\007\026\000\000\011\189\011\189\000\000\000\000\001\154\011\189\0002\006&\000F\000b\006>\000f\006\142\000j\000\134\006\146\000\138\000\000\000\146\000\000\000\150\006\150\000\154\000\174\000\178\000\182\006\154\000\000\000\000\000\000\000\000\000\000\006\158\000\000\000\000\000\000\000\000\000\000\000\186\000\000\001\030\006\174\006\202\000\000\000\000\006\206\000\000\000\000\000\000\000\190\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\000\000\000\000\000\000\000\000\000\000\000\000\000\008\146\006\214\000\000\000\000\000\000\008\150\0146\000\000\000\000\000\000\001R\000\000\001V\000\000\000\206\t\154\008\158\000\000\000\000\000\000\006\234\001^\008\162\000\000\006\238\008\166\001j\000\000\006\242\006\246\008\170\006\250\000\000\000\000\000\000\000\000\008\174\000\000\000\000\000\000\000\000\000\000\0031\000\000\000\000\000\000\006\254\007\002\000\000\008\178\008\182\007\006\008\186\000\000\000\162\000\000\008\206\0031\000\000\000\000\000\000\000\000\008\218\007\014\000\000\017r\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0031\000\000\008\250\000\000\000\000\000\000\008\254\t:\000\000\t\166\000\000\007\018\t>\000\000\017v\000\000\007\022\000\000\000\000\000\000\000\000\000\000\000\000\tF\017z\007\026\000\000\0002\006&\000F\000b\001\154\000f\006\142\000j\000\134\006\146\000\138\000\000\000\146\000\000\000\150\006\150\000\154\000\174\000\178\000\182\006\154\000\000\019\026\000\000\000\000\n\029\000\000\017\134\000\000\000\000\000\000\000\000\000\186\000\000\001\030\000\000\006\202\0031\004\169\006\206\000\000\0031\0031\000\190\000\000\000\000\014\182\000\000\000\000\000\000\n\029\000\000\000\000\0031\000\000\001*\000\000\000\000\000\000\000\000\004\169\000\000\000\000\000\000\014\198\006\214\000\000\000\000\0031\000\000\004\169\000\000\000\162\000\000\001R\000\000\001V\0031\000\206\023B\000\000\011\018\000\000\000\000\006\234\001^\017\138\000\000\006\238\001f\001j\000\000\006\242\006\246\008\170\006\250\000\000\000\000\n\017\011\026\004\169\004\169\000\000\000\000\000\000\000\000\n\029\000\000\000\000\000\000\006\254\007\002\000\000\000\000\011\"\007\006\000\000\000\000\000\162\000\000\011b\011j\000\000\n\017\000\000\000\000\000\000\007\014\000\000\017r\011B\000\000\000\000\011*\000\000\011:\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\169\t\166\000\000\007\018\014\202\000\000\017v\000\000\007\022\000\000\000\000\011J\000\000\000\000\004\169\014\210\017z\007\026\000\000\0002\0006\000F\000b\001\154\000f\000\000\000j\000\134\000\000\000\138\000\000\000\146\000\000\000\150\n\017\000\154\000\174\000\178\000\182\000\000\000\000\000\000\000\000\000\000\n)\000\000\017\134\011R\000\000\000\000\000\000\000\186\000\000\001\030\0112\001\"\000\000\000\000\001&\000\000\000\000\000\000\000\190\000\000\000\000\000\000\004\253\000\000\000\000\n)\000\000\000\000\000\000\000\000\001*\000\000\000\000\001.\000\000\000\000\000\000\011r\011Z\001F\001B\000\000\001J\000\000\000\000\000\000\000\000\000\162\000\000\001R\000\000\001V\000\000\000\206\000\000\000\000\000\000\000\000\000\000\001Z\001^\017\138\000\000\001b\001f\001j\001\190\001n\001r\000\000\001v\000\000\000\000\000\000\000\000\000\000\002\182\000F\000b\000\000\000f\n)\000j\000\134\000\000\000\138\001z\000\146\000\000\000\150\001~\000\154\000\174\000\162\000\182\000\000\006\158\000\000\000\000\000\000\000\000\000\000\001\134\000\000\001\030\006\174\006\202\000\186\000\000\006\206\000\000\001\138\000\000\000\000\000\000\000\000\008:\000\000\000\190\000\000\000\000\000\000\000\000\001\142\000\000\001*\000\000\000\000\001\146\000\000\000\000\003\133\000\000\000\000\008\202\006\214\000\000\001\150\000\000\008\150\000\000\000\000\000\000\001\154\001R\000\000\001V\000\000\000\000\000\000\008\158\000\000\000\000\000\206\006\234\001^\008\162\000\000\006\238\008\166\001j\000\000\006\242\006\246\000\000\006\250\000\000\000\000\000\000\000\000\008\174\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\254\007\002\000\000\008\178\008\182\007\006\008\186\000\000\000\162\000\000\008\206\000\000\000\000\000\162\000\000\000\000\008\218\007\014\000\000\000\000\000\000\000\000\006\158\000\000\000\000\000\000\000\000\000\000\000\000\008\250\001\030\006\174\006\202\008\254\t:\006\206\000\000\000\000\007\018\t>\007y\000\000\008:\007\022\000\000\t\146\000\000\000\000\000\000\000\000\tF\001*\007\026\000\000\008J\007y\000\000\000\000\001\154\000\000\006\210\006\214\000\000\008~\000\000\008\150\000\000\000\000\000\000\000\000\001R\000\000\001V\000\000\000\000\000\000\008\158\000\000\000\000\000\000\006\234\001^\008\162\000\000\006\238\008\166\001j\000\000\006\242\006\246\000\000\006\250\000\000\000\000\000\000\000\000\008\174\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007y\006\254\007\002\000\000\008\178\008\182\007\006\008\186\000\000\000\162\000\000\008\206\000\000\000\000\000\000\000\000\000\000\008\218\007\014\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\158\011\213\000\000\008\250\011\213\000\000\000\000\008\254\t:\000\000\000\000\000\000\007\018\t>\000\000\000\000\000\000\007\022\000\000\011\213\000\000\007y\000\000\011\213\tF\000\000\007\026\001\178\011\213\000\000\000\000\000\000\001\154\007y\011\213\000\000\000\000\011\213\011\213\000\000\011\213\011\213\000\000\000\000\001\186\000\000\011\213\002\210\000\000\000\000\011\213\000\000\000\000\011\213\000\000\011\213\011\213\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\213\000\000\011\213\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\213\005\129\000\000\000\000\000\000\000\000\002\222\000\000\000\000\000\000\000\000\005\129\005\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\213\011\213\011\213\000\000\011\213\011\213\002\226\000\000\011\213\000\000\000\000\000\000\004!\005\129\000\000\004!\002\234\000\000\005\129\002\146\011\213\000\000\005\129\011\213\011\213\011\213\011\213\000\000\000\000\000\000\004!\011\213\011\213\011\213\004!\011\213\011\213\011\213\004!\004!\000\000\000\000\000\000\000\000\000\000\004!\000\000\000\000\004!\004!\000\000\004!\004!\000\000\005\129\004!\000\000\004!\004!\000\000\000\000\004!\000\000\005\129\004!\000\000\004!\004!\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\129\000\000\000\158\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004!\000\000\004!\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\129\000\000\004!\005\129\005\129\000\000\000\000\005\129\004!\000\000\000\000\000\162\000\000\000\000\000\000\000\000\000\000\005\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004!\004!\004!\000\000\004!\004\189\004!\000\000\004!\000\000\001=\001=\001=\001=\000\000\001=\004!\001=\001=\000\000\001=\000\000\001=\004!\001=\004!\001=\001=\001=\001=\000\000\004!\004!\004!\017F\004!\004!\004!\000\000\000\000\000\000\001=\001=\001=\000\000\000\000\000\000\000\000\001=\000\000\000\000\000\000\000\000\001=\000\000\000\000\000\000\001=\000\000\000\000\000\000\001=\000\000\000\000\017J\000\000\000\000\001=\000\000\000\000\000\000\006~\006J\000b\001=\000f\000\181\006N\000\134\001=\000\138\000\000\000\146\000\000\000\150\000\000\000\154\000\174\001=\000\182\000\000\000\000\000\000\000\000\011\026\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\186\000\000\000\000\000\000\000\000\000\000\001=\011\"\000\000\001=\000\000\000\190\000\000\000\181\000\181\000\000\000\000\000\000\000\000\000\000\001=\000\000\000\000\011B\000\000\001=\011*\001=\011:\000\000\001=\000\000\001=\000\000\000\000\004%\000\000\001=\004%\000\000\001=\000\000\000\000\000\000\000\000\000\000\000\206\000\000\000\000\011J\000\000\000\000\000\000\004%\000\000\001=\000\000\004%\001=\001=\000\000\004%\004%\000\000\000\000\000\000\000\000\000\000\004%\017N\000\000\004%\004%\000\000\004%\004%\000\000\000\000\004%\000\000\004%\004%\000\000\000\000\004%\011R\000\000\004%\000\000\004%\004%\000\000\0112\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\181\000\000\000\000\000\000\000\000\000\000\004%\000\000\004%\000\000\000\000\000\000\000\000\000\000\000\000\000\181\011Z\000\000\004%\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\004%\004%\004%\000\000\004%\004\193\004%\000\000\004%\000\000\000\000\000\000\012)\000\000\000\000\012)\004%\000\000\000\000\000\000\004%\000\000\000\000\004%\000\000\004%\000\000\000\000\000\000\000\000\012)\004%\004%\004%\012)\004%\004%\004%\007.\012)\000\000\000\000\000\000\000\000\000\000\012)\000\000\000\000\012)\012)\000\000\012)\012)\000\000\000\000\0076\000\000\012)\007B\000\000\000\000\012)\000\000\000\000\012)\000\000\012)\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\012)\000\000\012)\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012)\000\000\000\000\000\000\000\000\000\000\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\000\000\000\000\012)\012)\012)\000\000\012)\000\000\007R\000\000\012)\000\000\n\013\n\013\n\013\n\013\000\000\n\013\007Z\n\013\n\013\000\000\n\013\000\000\n\013\012)\n\013\012)\n\013\n\013\n\013\n\013\000\000\012)\012)\012)\000\000\012)\012)\012)\000\000\000\000\000\000\n\013\n\013\n\013\000\000\000\000\000\000\000\000\n\013\000\000\000\000\000\000\000\000\n\013\000\000\000\000\000\000\017^\000\000\000\000\000\000\017f\000\000\000\000\000\000\000\000\000\000\n\013\000\000\000\000\000\000\000\000\000\000\000\000\n\013\000\000\000\000\000\000\000\000\n\013\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004E\n\013\000J\004E\000N\004E\000V\004E\000\000\004E\000\000\000\000\000\000\000Z\004E\004E\000\000\000\000\000\000\000\000\000\000\n\013\000\000\000\000\n\013\000\000\000\000\004E\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\013\000\157\004E\004E\000\000\n\013\000\000\n\013\004E\000\000\n\013\000\000\n\013\000\000\000\000\000\000\000\000\n\013\000\000\000\157\n\013\000\000\000\000\000\000\004E\000\000\000\000\004E\000\000\000\000\000\000\000\000\004E\004E\011\"\n\013\004E\000^\017\222\n\013\000\157\000\157\000\000\000\000\004E\000\000\000\000\000\000\004E\004E\000\157\000\000\000\000\011*\000\000\011:\000\000\000\000\004E\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004E\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\157\004E\000\000\000\000\000\000\000\000\004E\004I\000\000\000n\004I\000r\004I\000z\004I\004E\004I\000\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\000\000\004I\004E\000\157\000\000\004E\004E\000\000\000\000\004E\0112\004I\004I\000\000\004E\004E\000\000\004I\000\000\004E\000\000\000\000\000\157\000\000\000\000\000\000\000\000\000\000\000\000\001\137\000\000\000\000\001\137\004I\000\000\000\000\004I\000\157\000\157\000\000\000\000\004I\004I\000\000\000\000\004I\000\130\001\137\000\000\000\000\000\000\001\137\000\000\004I\000\000\000\000\001\137\004I\004I\000\000\000\000\000\000\001\137\000\000\000\000\001\137\001\137\004I\001\137\001\137\000\000\000\000\000\000\000\000\001\137\000\000\000\000\004I\001\137\000\000\000\000\001\137\000\000\001\137\001\137\000\000\004I\000\000\000\000\000\000\000\000\004I\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004I\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\000\000\000\000\000\000\004I\000\000\000\000\004I\004I\000\000\000\000\004I\000\000\000\000\000\000\000\000\004I\004I\000\000\000\000\000\000\004I\000\000\001\137\001\137\001\206\000\000\001\137\001\137\000\000\000\000\001\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\137\000\000\000\000\001\137\001\137\001\137\001\137\000\000\000\000\000\000\000\000\002v\001\137\001\137\000\000\001\137\001\137\001\137\t\253\t\253\t\253\t\253\000\000\t\253\000\000\t\253\t\253\000\000\t\253\000\000\t\253\000\000\t\253\000\000\t\253\t\253\t\253\t\253\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t\253\t\253\t\253\000\000\000\000\000\000\000\000\t\253\000\000\000\000\000\000\000\000\t\253\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\241\t\253\000\000\000\000\000\000\000\000\000\000\000\000\t\253\000\000\000\000\000\000\000\000\t\253\000\000\000\000\000\000\000\000\011\241\000\000\000\000\000\000\t\253\000\000\000\000\000\000\nV\000\000\000\000\000\000\000\000\000\000\000\000\011\241\000\000\000\000\000\000\000\000\000\000\011\241\011\241\000\000\t\253\n^\000\000\t\253\nj\000\000\000\000\011\241\000\000\000\000\011\241\000\000\011\241\000\000\t\253\000\000\000\000\000\000\000\000\t\253\000\000\t\253\000\000\000\000\t\253\000\000\t\253\000\000\000\000\000\000\000\000\t\253\000\000\011\241\t\253\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\149\000\000\000\000\000\000\000\000\000\000\000\000\t\253\000\000\nv\017b\t\253\n\001\n\001\n\001\n\001\000\000\n\001\000\149\n\001\n\001\000\000\n\001\000\000\n\001\000\000\n\001\011\241\n\001\n\001\n\001\n\001\nz\000\149\011\241\000\000\000\000\000\000\000\000\000\149\000\149\000\000\n\130\n\001\n\001\n\001\011\241\000\000\000\000\000\149\n\001\000\000\011*\000\000\000\149\n\001\000\000\000\000\000\000\017\226\000\000\011\241\011\241\000\000\000\000\000\153\000\000\000\000\000\000\n\001\000\000\000\000\000\000\000\000\000\000\000\149\n\001\000\000\000\000\000\000\000\000\n\001\000\000\000\153\000\000\000\000\000\000\000\000\000\000\000\000\n\001\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\000\000\000\000\n\001\000\149\000\000\n\001\000\153\000\000\000\000\011*\0112\000\153\000\000\000\000\000\000\000\000\n\001\000\000\000\000\000\000\000\000\n\001\000\149\n\001\000\000\000\000\n\001\000\000\n\001\000\000\000\000\000\000\000\153\n\001\000\000\000\000\n\001\000\149\000\149\000\000\0002\0006\000F\000b\000\000\000f\000\000\000j\000\134\000\000\000\138\n\001\000\146\000\000\000\150\n\001\000\154\000\174\000\178\000\182\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\153\000\000\000\000\017\234\000\186\018\006\000\000\0112\000\000\000\000\018\018\000\000\000\000\000\000\000\000\000\190\000\000\000\000\000\000\000\153\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\169\018*\000\000\000\000\000\000\000\000\000\153\000\153\000\202\000\000\000\000\000\000\000\000\018V\000\000\000\000\000\000\000\000\011\026\000\000\000\000\004}\000\206\000\000\004}\000R\004}\000\000\004}\000\000\004}\000\000\000\000\011\"\000\000\004}\004}\000\000\000\000\000\169\000\169\000\000\018v\000\000\000\000\018\198\000\000\000\000\004}\000\169\000\000\000\000\011*\000\000\011:\000\000\018\222\000\000\004}\004}\000\000\018\234\000\000\008-\004}\000\000\018\246\000\000\019\002\000\000\000\000\000\000\000\000\019\018\000\000\011J\019\194\000\000\000\000\000\000\004}\000\000\000\000\004}\000\000\000\000\000\000\000\000\004}\004}\000\000\019\206\004}\004}\004\129\019\230\000\000\004\129\000v\004\129\004}\004\129\000\000\004\129\004}\004}\000\000\000\000\004\129\004\129\000\000\000\169\000\000\000\000\004}\000\000\000\000\000\000\0112\000\000\000\000\004\129\000\000\000\000\004}\000\000\000\000\000\000\000\000\000\000\000\169\004\129\004\129\004}\000\000\000\000\000\000\004\129\004}\000\000\000\000\000\000\000\000\000\000\000\000\000\169\000\169\004}\000\000\000\000\000\000\000\000\000\000\004\129\000\000\000\000\004\129\000\000\000\000\000\000\000\000\004\129\004\129\000\000\000\000\004\129\004\129\004}\000\000\000\000\004}\004}\000\000\004\129\004}\000\000\000\000\004\129\004\129\004}\004}\000\000\000\000\000\000\004}\000\000\000\000\004\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\129\000\000\000\000\000\000\000\000\004\129\004\133\000\000\000\000\004\133\000\142\004\133\000\000\004\133\004\129\004\133\000\000\000\000\000\000\000\000\004\133\004\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\133\004\129\000\000\000\000\004\129\004\129\000\000\000\000\004\129\000\000\004\133\004\133\004\185\004\129\004\129\004\185\004\133\004\185\004\129\004\185\000\000\004\185\000\000\000\000\000\000\000\000\004\185\004\185\000\000\000\000\000\000\000\000\004\133\000\000\000\000\004\133\000\000\000\000\000\000\004\185\004\133\004\133\000\000\000\000\004\133\004\133\000\000\000\000\000\000\004\185\004\185\000\000\004\133\000\000\000\000\004\185\004\133\004\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\133\000\000\000\000\000\000\000\000\004\185\000\000\000\000\004\185\000\210\004\133\000\000\000\000\004\185\004\185\000\000\000\000\004\185\004\185\004\133\000\000\000\000\000\000\000\000\004\133\004\185\000\000\000\000\000\000\004\185\004\185\000\000\000\000\004\133\000\000\000\000\000\000\000\000\000\000\004\185\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\185\000\000\000\000\000\000\004\133\000\000\000\000\004\133\004\133\004\185\000\000\004\133\001\238\000\000\004\185\002>\004\133\004\133\000\000\000\000\000\000\004\133\000\000\004\185\000\000\000\000\000\000\000\000\000\000\000\000\001\246\000\000\000\000\000\000\002\001\000\000\000\000\000\000\000\000\002\001\000\000\000\000\000\000\004\185\000\000\001\254\004\185\004\185\002\001\002\001\004\185\002^\002f\000\000\000\000\004\185\004\185\002\001\000\000\000\000\004\185\002\030\000\000\000\000\002\006\000\000\002\022\002\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\001\0002\006&\000F\000b\006>\000f\006\142\000j\000\134\006\146\000\138\000\000\000\146\000\000\000\150\006\150\000\154\000\174\000\178\000\182\006\154\000\000\002\001\002.\000\000\000\000\002\001\002\001\000\000\000\000\002\014\000\000\000\186\000\000\000}\000\000\000\000\000}\000\000\000\000\000\000\000\000\002\001\000\190\000\000\002\001\002\001\002\001\002\001\000\000\000\000\000\000\001\246\000\000\002\001\002\001\000}\002n\0026\002\001\000\000\000}\000\000\000\000\000\202\000\000\000\000\001\254\000\000\000\000\000}\000}\000\000\000}\000}\000\000\000\000\000\000\000\206\000}\000\000\000\000\000\000\002\030\000\000\000\000\002\006\000\000\002\022\000}\000\000\000\000\000\000\000\000\008\170\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\162\000\000\000\000\000}\0002\t\182\000F\000b\000\000\000f\006\142\000j\000\134\006\146\000\138\000\000\000\146\020\234\000\150\006\150\000\154\000\174\000\178\000\182\006\154\020\242\000}\002.\t\166\000\000\000}\000}\000\000\000\000\002\014\000\000\000\186\000\000\000e\000\000\000\000\000e\000\000\000\000\000\000\000\000\000}\000\190\000\000\000}\000}\000}\000}\000\000\000\000\000\000\000e\000\000\000}\000}\000e\000}\0026\000}\000\000\000e\000\000\000\000\000\202\000\000\000\000\001\254\000\000\000\000\000e\000e\000\000\000e\000e\000\000\000\000\000\000\000\206\000e\000\000\000\000\000\000\000e\000\000\000\000\002\006\000\000\002\022\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\000\000e\000\000\000e\000\000\000\000\000\000\000\000\000\000\000\000\000\162\000\000\000\000\000e\000\000\003\193\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\002\014\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\000\000\000]\000\000\000\000\002\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\020\238\000F\000b\000\000\000f\006\142\000j\000\134\006\146\000\138\000\000\000\146\020\234\000\150\006\150\000\154\000\174\000\000\000\182\006\154\020\242\000]\000]\000\000\000\000\000]\000]\000\000\000\000\002\014\000\000\000\186\000\000\000a\000\000\000\000\000a\000\000\000\000\000\000\000\000\000]\000\190\000\000\000]\000]\000]\000]\000\000\000\000\000\000\000a\000\000\000]\000]\000a\000]\000]\000]\000\000\000a\000\000\000\000\000\000\000\000\000\000\000a\000\000\000\000\000a\000a\000\000\000a\000a\000\000\000\000\000\000\000\206\000a\000\000\000\000\000\000\000a\000\000\000\000\002\006\000\000\000a\000a\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000\000\000\000\000\000a\000\000\003\193\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\002\014\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\246\000\000\000a\000a\000q\000a\000a\000a\000\000\000q\000\000\000\000\000\000\000\000\000\000\001\254\000\000\000\000\000q\000q\000\000\000q\000q\000\000\000\000\000\000\000\000\000q\000\000\000\000\000\000\000q\000\000\000\000\002\006\000\000\002\022\000q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002&\000\000\000q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000q\0002\006B\006J\000b\000\000\000f\000\000\006N\000\134\000\000\000\138\000\000\000\146\000\000\000\150\000\000\000\154\000\174\000\178\000\182\000\000\000\000\000q\000q\000\000\000\000\000q\000q\000\000\000\000\002\014\000\000\000\186\000\000\000i\000\000\000\000\000i\000\000\000\000\000\000\000\000\000q\000\190\000\000\000q\000q\000q\000q\000\000\000\000\000\000\001\246\000\000\000q\000q\000i\000q\000q\000q\000\000\000i\000\000\000\000\006R\000\000\000\000\001\254\000\000\000\000\000i\000i\000\000\000i\000i\000\000\000\000\000\000\000\206\000i\000\000\000\000\000\000\000i\000\000\000\000\002\006\000\000\002\022\000i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000i\000\000\000i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000i\000\000\000\000\000i\000i\000\000\000\000\002\014\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\246\000\000\000i\000i\000m\000i\000i\000i\000\000\000m\000\000\000\000\000\000\000\000\000\000\001\254\000\000\000\000\000m\000m\000\000\000m\000m\000\000\000\000\000\000\000\000\000m\000\000\000\000\000\000\000m\000\000\000\000\002\006\000\000\002\022\000m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002&\000\000\000m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000m\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000m\000m\000\000\000\000\000m\000m\000\000\000\000\002\014\000\000\000\000\000\000\000u\000\000\000\000\000u\000\000\000\000\000\000\000\000\000m\000\000\000\000\000m\000m\000m\000m\000\000\000\000\000\000\001\246\000\000\000m\000m\000u\000m\000m\000m\000\000\000u\000\000\000\000\000\000\000\000\000\000\001\254\000\000\000\000\000u\000u\000\000\000u\000u\000\000\000\000\000\000\000\000\000u\000\000\000\000\000\000\002\030\000\000\000\000\002\006\000\000\002\022\000u\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002&\000\000\000u\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000u\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000u\002.\000\000\000\000\000u\000u\000\000\000\000\002\014\000\000\000\000\000\000\001\238\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\246\000\000\000u\000u\000\133\000u\000u\000u\000\000\000\133\000\000\000\000\000\000\000\000\000\000\001\254\000\000\000\000\000\133\000\133\000\000\000\133\002f\000\000\000\000\000\000\000\000\000\133\000\000\000\000\000\000\002\030\000\000\000\000\002\006\000\000\002\022\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002&\000\000\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\133\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\133\002.\000\000\000\000\000\133\000\133\000\000\000\000\002\014\000\000\000\000\000\000\001\238\000\000\000\000\000y\000\000\000\000\000\000\000\000\000\133\000\000\000\000\000\133\000\133\000\133\000\133\000\000\000\000\000\000\001\246\000\000\000\133\000\133\000y\002n\0026\000\133\000\000\000y\000\000\000\000\000\000\000\000\000\000\001\254\000\000\000\000\000y\000y\000\000\000y\000y\000\000\000\000\000\000\000\000\000y\000\000\000\000\000\000\002\030\000\000\000\000\002\006\000\000\002\022\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\000\000\000\000\002&\000\000\000y\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000y\002.\000\000\000\000\000y\000y\000\000\000\000\002\014\000\000\000\000\000\000\001\238\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\246\000\000\000y\000y\000\129\000y\0026\000y\000\000\000\129\000\000\000\000\000\000\000\000\000\000\001\254\000\000\000\000\000\129\000\129\000\000\000\129\002f\000\000\000\000\000\000\000\000\000\129\000\000\000\000\000\000\002\030\000\000\000\000\002\006\000\000\002\022\000\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002&\000\000\000\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\129\000\000\004\153\000\000\000\000\004\153\000\000\004\153\000\000\004\153\000\000\004\153\000\000\000\000\000\000\000\000\004\153\004\153\000\000\000\000\000\000\000\000\000\000\000\129\002.\000\000\000\000\000\129\000\129\004\153\000\000\002\014\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\153\004\153\000\000\000\000\000\129\000\000\004\153\000\129\000\129\000\129\000\129\000\000\000\000\000\000\000\000\000\000\000\129\000\129\000\000\000\129\0026\000\129\004\153\000\000\000\000\004\153\005\226\000\000\000\000\000\000\004\153\004\153\000\000\000\000\004\153\004\153\005\129\000\000\000\000\005\129\000\000\005\129\004\153\005\129\000\000\005\129\004\153\004\153\000\000\000\000\005\129\005\129\000\000\000\000\000\000\000\000\004\153\000\000\005\129\000\000\000\000\000\000\000\000\005\129\000\000\000\000\004\153\000\000\005\129\005\129\000\000\000\000\000\000\005\129\005\129\004\153\000\000\000\000\000\000\005\129\004\153\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\153\000\000\000\000\000\000\005\129\000\000\005\129\000\000\000\000\005\129\002\146\000\000\000\000\005\129\005\129\002\146\000\000\000\000\005\129\005\129\004\153\005\129\000\000\004\153\004\153\005\129\005\129\004\153\000\000\000\000\005\129\005\129\004\153\004\153\000\000\005\129\000\000\004\153\000\000\000\000\005\129\000\000\000\000\000\000\000\000\005\129\000\000\000\000\000\000\000\000\005\129\000\000\000\000\000\000\005\129\000\000\000\000\000\000\000\000\005\129\000\000\000\000\000\000\000\000\005\129\000\000\000\000\000\000\005\129\000\000\000\000\000\000\n\198\005\129\000\000\000\000\000\000\003i\000\000\003i\000\000\000\000\003i\000\000\000\000\000\000\000\000\000\000\005\129\000\000\000\000\005\129\005\129\005\129\000\000\005\129\005\129\005\129\003i\000\000\005\129\005\129\000\000\000\000\000\000\005\129\005\129\003i\003i\000\000\005\129\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\000\000\003i\003i\003i\000\000\003i\003i\000\000\003i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\161\000\000\000\000\001\161\003i\003i\000\000\000\000\000\000\003i\000\000\000\000\003i\000\000\000\000\000\000\000\000\000\000\001\161\000\000\000\000\003i\001\161\000\000\000\000\000\000\000\000\001\161\003i\000\000\003i\000\000\003i\001\161\000\000\000\000\001\161\001\161\000\000\001\161\001\161\000\000\003i\000\000\000\000\001\161\000\000\003i\000\000\001\161\000\000\000\000\001\161\003i\001\161\001\161\003i\000\000\000\000\000\000\000\000\000\000\003i\000\000\000\000\000\000\003q\003q\003q\003q\000\000\003q\000\000\003q\003q\001\161\003q\001\161\003q\000\000\003q\000\000\003q\003q\003q\003q\000\000\001\161\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\238\000\000\000\000\003q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003q\001\161\001\161\007~\000\000\001\161\000\000\000\000\000\000\001\161\001\030\000\000\t\226\000\000\000\000\t\230\000\000\000\000\000\000\000\000\000\000\003q\000\000\000\000\001\161\000\000\001\161\003q\000\000\000\000\000\000\001*\007\134\001\161\001\161\003q\001\161\001\161\001\161\000\000\t\234\n>\000\000\000\000\n\166\n\190\000\000\000\000\000\000\000\000\001R\000\000\001V\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\n\001^\000\000\000\000\n\014\008\166\001j\000\000\n\018\n\022\000\000\n\026\000\000\000\000\000\000\003q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\254\n\030\000\000\000\000\000\000\n\"\000\000\000\000\000\162\000\000\000\000\001\030\000\000\t\226\000\000\000\000\t\230\n*\000\000\000\000\000\000\000\000\000\000\000\000\005\169\000\000\n\194\000\000\n\222\000\000\003q\000\000\001*\000\000\000\000\000\000\000\000\000\000\n.\000\000\000\000\t\234\n>\n2\000\000\n\166\n\190\000\000\000\000\011\186\000\000\001R\n6\001V\000\000\000\000\000\000\000\000\001\154\000\000\000\000\n\n\001^\000\000\000\000\n\014\008\166\001j\000\000\n\018\n\022\000\000\n\026\000\000\000\000\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\254\n\030\000\000\000\000\000\000\n\"\000\000\000\000\000\162\000\000\000\000\001\030\000\000\t\226\000\000\000\000\t\230\n*\000\000\000\000\000\000\000\000\000\000\000\000\005\169\000\000\n\194\000\000\n\222\000\000\000\000\000\000\001*\000\000\000\000\000\000\000\000\000\000\n.\000\000\000\000\t\234\n>\n2\000\000\n\166\n\190\000\000\000\000\n\230\000\000\001R\n6\001V\000\000\000\000\000\000\000\000\001\154\000\000\000\000\n\n\001^\000\000\000\000\n\014\008\166\001j\000\000\n\018\n\022\000\000\n\026\000\000\000\000\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\254\n\030\000\000\000\000\000\000\n\"\000\000\000\000\000\162\000\000\000\000\001\030\000\000\t\226\000\000\000\000\t\230\n*\000\000\000\000\000\000\000\000\000\000\000\000\005\169\000\000\n\194\000\000\n\222\000\000\000\000\000\000\001*\000\000\000\000\000\000\000\000\000\000\n.\000\000\000\000\t\234\n>\n2\000\000\n\166\n\190\000\000\000\000\005\021\000\000\001R\n6\001V\000\000\000\000\000\000\000\000\001\154\000\000\012\013\n\n\001^\012\013\000\000\n\014\008\166\001j\000\000\n\018\n\022\000\000\n\026\000\000\000\000\000\000\000\000\000\000\012\013\000\000\000\000\000\000\012\013\000\000\000\000\000\000\003V\006\254\n\030\000\000\000\000\000\000\n\"\012\013\000\000\000\162\000\000\012\013\000\000\012\013\012\013\000\000\000\000\003^\n*\000\000\003j\000\000\000\000\012\013\000\161\005\169\012\013\n\194\012\013\n\222\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n.\000\000\000\000\011\026\000\000\n2\000\000\000\000\000\000\000\000\012\013\001\189\000\000\000\000\n6\000\000\000\000\000\000\011\"\000\000\001\154\000\000\012\013\000\000\000\161\000\161\000\000\000\000\003v\000\000\000\000\000\000\000\000\001\030\000\161\t\226\000\000\011*\t\230\011:\000\000\000\000\000\000\000\000\000\000\000\000\012\013\012\013\000\000\012\013\000\000\003z\000\000\012\013\001*\000\000\000\000\000\000\000\000\000\000\000\161\003\130\000\000\t\234\n>\012\013\000\000\n\166\n\190\000\000\012\013\012\013\000\000\001R\000\000\001V\012\013\000\000\000\000\000\000\012\013\012\013\012\013\n\n\001^\000\000\000\000\n\014\008\166\001j\000\000\n\018\n\022\000\000\n\026\000\000\000\161\000\000\000\000\000\000\000\000\001\137\000\000\0112\001\137\000\000\000\000\000\000\000\000\006\254\n\030\000\000\000\000\000\000\n\"\000\161\000\000\000\162\000\000\001\137\000\000\000\000\000\000\000\000\000\000\000\000\n*\000\000\001\137\000\000\000\161\000\161\000\000\005\169\001\137\000\000\000\000\n\222\000\000\000\000\001\137\001\137\000\000\000\000\000\000\000\000\007\178\n.\000\000\008\002\001\137\000\000\n2\001\137\000\165\001\137\001\137\000\000\001\201\000\000\000\000\n6\000\000\000\000\007\186\000\000\000\000\001\154\002\017\000\000\000\000\000\000\011\026\002\017\000\000\000\000\001\137\000\000\001\137\007\194\000\000\000\000\002\017\002\017\000\000\008\018\008\026\011\"\000\000\000\000\000\000\002\017\000\000\000\165\000\165\007\226\000\000\000\000\007\202\000\000\007\218\002\017\000\000\000\165\000\000\000\000\011*\000\000\011:\000\000\000\000\001\137\001\137\001\198\000\000\001\137\001\137\000\000\000\000\001\137\000\000\007\234\000\000\002\017\000\000\000\000\000\000\000\000\000\000\011J\000\000\001\137\000\000\002\017\001\137\001\137\000\000\001\137\000\000\000\000\000\000\000\000\002\130\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\002\017\007\242\000\000\000\000\002\017\000\000\000\000\000\000\007\210\000\165\000\000\000\000\001%\000\000\000\000\001%\0112\000\000\000\000\000\000\000\000\000\000\000\000\002\017\000\000\002\017\000\000\000\000\000\165\000\000\007\186\000\000\002\017\002\017\001%\008\"\007\250\002\017\000\000\001%\000\000\000\000\000\000\000\165\000\165\007\194\000\000\000\000\001%\001%\000\000\001%\001%\000\000\000\000\000\000\000\000\001%\000\000\000\000\000\000\007\226\000\000\000\000\007\202\000\000\007\218\001%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\234\001\013\001%\000\000\001\013\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\001\013\000\000\000\000\000\000\001\013\000\000\000\000\000\000\000\000\001\013\000\000\000\000\000\000\000\000\000\000\007\194\001%\007\242\001\013\001\013\001%\001\013\001\013\000\000\007\210\000\000\000\000\001\013\000\000\000\000\000\000\001\013\000\000\000\000\007\202\000\000\007\218\001\013\000\000\001%\000\000\001%\000\000\000\000\000\000\000\000\000\000\000\000\001%\001%\000\000\001%\007\250\001%\000\000\000\000\000\000\001\013\001\005\001\013\000\000\001\005\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\013\000\000\000\000\000\000\000\000\000\000\000\000\001\005\000\000\000\000\000\000\001\005\000\000\000\000\000\000\000\000\001\005\000\000\000\000\000\000\000\000\000\000\001\005\001\013\001\013\001\005\001\005\001\013\001\005\001\005\000\000\007\210\000\000\000\000\001\005\000\000\000\000\000\000\001\005\000\000\000\000\007\202\000\000\001\005\001\005\000\000\001\013\000\000\001\013\000\000\000\000\000\000\000\000\000\000\000\000\001\013\001\013\000\000\001\013\001\013\001\013\000\000\000\000\000\000\001\005\001\t\001\005\000\000\001\t\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\005\000\000\000\000\000\000\000\000\000\000\000\000\001\t\000\000\000\000\000\000\001\t\000\000\000\000\000\000\000\000\001\t\000\000\000\000\000\000\000\000\000\000\001\t\001\005\001\005\001\t\001\t\001\005\001\t\001\t\000\000\007\210\000\000\000\000\001\t\000\000\000\000\000\000\001\t\000\000\000\000\007\202\000\000\001\t\001\t\000\000\001\005\000\000\001\005\000\000\000\000\000\000\000\000\000\000\000\000\001\005\001\005\000\000\001\005\001\005\001\005\000\000\000\000\000\000\001\t\001\025\001\t\000\000\001\025\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\t\000\000\000\000\000\000\000\000\000\000\000\000\007\186\000\000\000\000\000\000\001\025\000\000\000\000\000\000\000\000\001\025\000\000\000\000\000\000\000\000\000\000\007\194\001\t\001\t\001\025\001\025\001\t\001\025\001\025\000\000\007\210\000\000\000\000\001\025\000\000\000\000\000\000\001\025\000\000\000\000\007\202\000\000\007\218\001\025\000\000\001\t\000\000\001\t\000\000\000\000\000\000\000\000\000\000\000\000\001\t\001\t\000\000\001\t\001\t\001\t\000\000\000\000\000\000\007\234\001\017\001\025\000\000\001\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\025\000\000\000\000\000\000\000\000\000\000\000\000\007\186\000\000\000\000\000\000\001\017\000\000\000\000\000\000\000\000\001\017\000\000\000\000\000\000\000\000\000\000\007\194\001\025\001\025\001\017\001\017\001\025\001\017\001\017\000\000\007\210\000\000\000\000\001\017\000\000\000\000\000\000\001\017\000\000\000\000\007\202\000\000\007\218\001\017\000\000\001\025\000\000\001\025\000\000\000\000\000\000\000\000\000\000\000\000\001\025\001\025\000\000\001\025\001\025\001\025\000\000\000\000\000\000\001\017\001\021\001\017\000\000\001\021\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\017\000\000\000\000\000\000\000\000\000\000\000\000\007\186\000\000\000\000\000\000\001\021\000\000\000\000\000\000\000\000\001\021\000\000\000\000\000\000\000\000\000\000\007\194\001\017\001\017\001\021\001\021\001\017\001\021\001\021\000\000\007\210\000\000\000\000\001\021\000\000\000\000\000\000\001\021\000\000\000\000\007\202\000\000\007\218\001\021\000\000\001\017\000\000\001\017\000\000\000\000\000\000\000\000\000\000\000\000\001\017\001\017\000\000\001\017\001\017\001\017\000\000\000\000\000\000\007\234\001\029\001\021\000\000\001\029\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\021\000\000\000\000\000\000\000\000\000\000\000\000\007\186\000\000\000\000\000\000\001\029\000\000\000\000\000\000\000\000\001\029\000\000\000\000\000\000\000\000\000\000\007\194\001\021\001\021\001\029\001\029\001\021\001\029\001\029\000\000\007\210\000\000\000\000\001\029\000\000\000\000\000\000\007\226\000\000\000\000\007\202\000\000\007\218\001\029\000\000\001\021\000\000\001\021\000\000\000\000\000\000\000\000\000\000\000\000\001\021\001\021\000\000\001\021\001\021\001\021\000\000\000\000\000\000\007\234\007\178\001\029\000\000\001-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\029\000\000\000\000\000\000\000\000\000\000\000\000\007\186\000\000\000\000\000\000\001-\000\000\000\000\000\000\000\000\001-\000\000\000\000\000\000\000\000\000\000\007\194\001\029\007\242\001-\001-\001\029\001-\008\026\000\000\007\210\000\000\000\000\001-\000\000\000\000\000\000\007\226\000\000\000\000\007\202\000\000\007\218\001-\000\000\001\029\000\000\001\029\000\000\000\000\000\000\000\000\000\000\000\000\001\029\001\029\000\000\001\029\001\029\001\029\000\000\000\000\000\000\007\234\007\178\001-\000\000\001!\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\007\186\000\000\000\000\000\000\001!\000\000\000\000\000\000\000\000\001!\000\000\000\000\000\000\000\000\000\000\007\194\001-\007\242\001!\001!\001-\001!\001!\000\000\007\210\000\000\000\000\001!\000\000\000\000\000\000\007\226\000\000\000\000\007\202\000\000\007\218\001!\000\000\001-\000\000\001-\000\000\000\000\000\000\000\000\000\000\000\000\001-\001-\000\000\008\"\007\250\001-\000\000\000\000\000\000\007\234\007\178\001!\000\000\001)\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\007\186\000\000\000\000\000\000\001)\000\000\000\000\000\000\000\000\001)\000\000\000\000\000\000\000\000\000\000\007\194\001!\007\242\001)\001)\001!\001)\008\026\000\000\007\210\000\000\000\000\001)\000\000\000\000\000\000\007\226\000\000\000\000\007\202\000\000\007\218\001)\000\000\001!\000\000\001!\000\000\000\000\000\000\000\000\000\000\000\000\001!\001!\000\000\001!\007\250\001!\000\000\000\000\000\000\007\234\000\000\001)\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\001\030\000\000\001\"\000\000\000\000\001&\000\000\000\000\000\000\000\000\000\000\001)\007\242\000\000\000\000\001)\000\000\000\000\000\000\007\210\000\000\001*\000\000\000\000\001.\000\000\000\000\000\000\000\000\000\000\001>\001B\000\000\001J\001)\t\222\001)\000\000\000\000\000\000\001R\000\000\001V\001)\001)\000\000\001)\007\250\001)\000\000\001Z\001^\000\000\n\206\001b\001f\001j\000\000\001n\001r\000\000\001v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001z\000\000\000\000\000\000\001~\000\000\000\000\000\162\001\030\000\000\001\"\000\000\000\000\001&\000\000\000\000\001\134\000\000\000\000\000\000\000\000\000\000\000\000\008>\000\000\001\138\008=\000\000\000\000\001*\000\000\000\000\001.\000\000\000\000\000\000\000\000\001\142\001>\001B\000\000\001J\001\146\000\000\000\000\008=\000\000\008=\001R\000\000\001V\001\150\000\000\000\000\000\000\000\000\000\000\001\154\001Z\001^\000\000\000\000\001b\001f\001j\000\000\001n\001r\000\000\001v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001z\000\000\000\000\000\000\001~\000\000\000\000\000\162\001\030\000\000\001\"\000\000\000\000\001&\000\000\000\000\001\134\000\000\000\000\000\000\000\000\000\000\000\000\008=\000\000\001\138\000\000\000\000\000\000\001*\000\000\000\000\001.\000\000\000\000\000\000\000\000\001\142\001>\001B\000\000\001J\001\146\000\000\000\000\000\000\000\000\000\000\001R\000\000\001V\001\150\000\000\000\000\000\000\000\000\000\000\001\154\001Z\001^\000\000\000\000\001b\001f\001j\000\000\001n\001r\000\000\001v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001z\000\000\000\000\000\000\001~\000\000\000\000\000\162\001\030\000\000\001\"\000\000\000\000\001&\000\000\000\000\001\134\000\000\000\000\000\000\000\000\000\000\000\000\014\186\000\000\001\138\000\000\000\000\000\000\001*\000\000\000\000\001.\000\000\000\000\000\000\000\000\001\142\001>\001B\000\000\001J\001\146\000\000\001\030\000\000\001\"\000\000\001R\001&\001V\001\150\000\000\000\000\000\000\000\000\000\000\001\154\001Z\001^\000\000\000\000\001b\001f\001j\001*\001n\001r\001.\001v\000\000\000\000\000\000\000\000\001>\004\226\000\000\001J\000\000\000\000\000\000\000\000\000\000\000\000\001R\001z\001V\000\000\000\000\001~\000\000\000\000\000\162\000\000\001Z\001^\000\000\000\000\001b\001f\001j\001\134\001n\001r\000\000\001v\000\000\000\000\000\000\000\000\001\138\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001z\001\142\000\000\000\000\001~\000\000\001\146\000\162\001\030\000\000\001\"\000\000\000\000\001&\000\000\001\150\001\134\000\000\000\000\000\000\000\000\001\154\000\000\000\000\000\000\001\138\000\000\000\000\000\000\001*\000\000\000\000\001.\000\000\000\000\000\000\000\000\001\142\001>\001\130\000\000\001J\001\146\000\000\000\000\000\000\000\000\000\000\001R\000\000\001V\001\150\000\000\000\000\000\000\000\000\000\000\001\154\001Z\001^\000\000\000\000\001b\001f\001j\000\000\001n\001r\000\000\001v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001z\000\000\000\000\003\202\001~\000\000\000\000\000\162\003a\000\000\003a\000\000\000\000\003a\000\000\000\000\001\134\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\138\000\000\000\000\000\000\003a\000\000\000\000\003a\000\000\000\000\000\000\000\000\001\142\003a\003a\000\000\003a\001\146\000\000\000\000\000\000\000\000\000\000\003a\000\000\003a\001\150\000\000\000\000\000\000\000\000\000\000\001\154\003a\003a\000\000\000\000\003a\003a\003a\000\000\003a\003a\000\000\003a\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004!\000\000\000\000\004!\000\000\000\000\000\000\000\000\003a\000\000\000\000\000\000\003a\000\000\000\000\003a\000\000\000\000\004!\000\000\000\000\000\000\000\000\000\000\003a\000\000\004!\004!\000\000\000\000\000\000\000\000\000\000\004!\000\000\000\000\001\030\000\000\0012\004!\004!\0016\000\000\004!\000\000\003a\004!\000\000\000\000\004!\003a\000\000\004!\000\000\004!\004!\000\000\001*\000\000\003a\001.\000\000\000\000\000\000\000\000\003a\001:\001N\000\000\001J\000\000\000\000\000\000\000\000\000\000\004!\001R\000\000\001V\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\022\001^\000\000\000\000\003\026\001f\001j\004!\003\030\003\"\000\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\004!\004!\003*\000\000\004\189\004!\003.\004!\000\000\000\162\000\000\000\000\001\030\000\000\0012\004!\000\000\0016\0036\004!\000\000\000\000\004!\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004!\000\000\000\000\001*\004!\004!\001.\000\000\000\000\003:\000\000\000\000\001:\004\202\003>\001J\000\000\000\000\000\000\000\000\000\000\000\000\001R\003B\001V\000\000\000\000\000\000\000\000\001\154\000\000\000\000\003\022\001^\000\000\000\000\003\026\001f\001j\000\000\003\030\003\"\000\000\003&\000\000\000\000\000\000\000\000\001\030\000\000\0012\000\000\000\000\0016\000\000\000\000\000\000\000\000\000\000\003*\000\000\000\000\000\000\003.\000\000\000\000\000\162\000\000\000\000\001*\000\000\000\000\001.\000\000\000\000\0036\000\000\000\000\001:\0032\000\000\001J\000\000\000\000\001\030\000\000\006\202\000\000\001R\006\206\001V\000\000\000\000\000\000\000\000\000\000\003:\000\000\003\022\001^\000\000\003>\003\026\001f\001j\001*\003\030\003\"\000\000\003&\003B\000\000\000\000\000\000\006\210\008*\001\154\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001R\003*\001V\000\000\000\000\003.\000\000\000\000\000\162\000\000\006\234\001^\000\000\000\000\006\238\001f\001j\0036\006\242\006\246\000\000\006\250\000\000\000\000\000\000\000\000\001\030\000\000\006\202\000\000\000\000\006\206\000\000\000\000\000\000\000\000\006\254\007\002\003:\000\000\000\000\007\006\000\000\003>\000\162\000\000\000\000\001*\000\000\000\000\000\000\000\000\003B\007\014\000\000\000\000\006\210\006\214\001\154\000\000\000\173\000\000\000\000\000\000\000\000\000\000\001R\000\000\001V\000\000\000\000\000\000\000\000\000\000\007\018\000\000\006\234\001^\011\026\007\022\006\238\001f\001j\000\000\006\242\006\246\000\000\006\250\007\026\000\000\000\000\000\000\000\000\011\"\001\154\000\000\000\000\000\000\000\000\000\173\000\173\000\000\006\254\007\002\000\000\000\000\000\000\007\006\000\000\011B\000\162\001\030\011*\006\202\011:\000\000\006\206\000\000\000\000\007\014\000\000\000\000\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\011J\000\000\000\000\000\000\000\000\007\018\006\210\007\n\000\000\000\000\007\022\000\000\000\000\000\000\000\000\000\000\001R\000\000\001V\007\026\000\000\000\000\000\000\000\000\000\000\001\154\006\234\001^\000\000\000\000\006\238\001f\001j\000\000\006\242\006\246\011R\006\250\000\000\000\000\000\000\000\000\001\030\0112\t\226\000\000\000\000\t\230\000\000\000\000\000\000\000\000\006\254\007\002\000\000\000\173\000\000\007\006\000\000\000\000\000\162\000\000\000\000\001*\000\000\000\000\000\000\000\000\000\000\007\014\000\173\000\173\t\234\t\246\000\000\000\000\011\018\000\000\000\000\000\000\000\000\000\000\001R\000\000\001V\000\000\000\000\000\000\000\000\000\000\007\018\000\000\n\n\001^\011\026\007\022\n\014\001f\001j\000\000\n\018\n\022\000\000\n\026\007\026\000\000\000\000\000\000\000\000\011\"\001\154\000\000\000\000\000\000\000\000\000\189\011j\000\000\006\254\n\030\000\000\000\000\000\000\n\"\000\000\011B\000\162\001\030\011*\t\226\011:\000\000\t\230\000\000\000\000\n*\000\000\000\000\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\011J\000\000\000\000\000\000\000\000\n.\t\234\n&\000\000\000\000\n2\000\000\000\000\000\000\000\000\000\000\001R\000\000\001V\n6\000\000\000\000\000\000\000\000\000\000\001\154\n\n\001^\000\000\000\000\n\014\001f\001j\000\000\n\018\n\022\011R\n\026\000\000\000\000\000\000\000\000\001\030\0112\t\226\000\000\000\000\t\230\000\000\000\000\000\000\000\000\006\254\n\030\000\000\000\189\000\000\n\"\000\000\000\000\000\162\000\000\000\000\001*\000\000\000\000\000\000\000\000\000\000\n*\011r\011Z\t\234\n>\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001R\000\000\001V\000\000\000\000\000\000\000\000\000\000\n.\000\000\n\n\001^\000\000\n2\n\014\001f\001j\000\000\n\018\n\022\000\000\n\026\n6\000\000\000\000\000\000\000\000\000\000\001\154\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\254\n\030\000\000\000\000\000\000\n\"\000\000\000\000\000\162\000\000\000\000\000\000\000\000\0002\0006\000F\000b\n*\000f\000\000\000j\000\134\007\169\000\138\017r\000\146\000\000\000\150\000\000\000\154\000\174\000\178\000\182\000\000\000\000\000\000\000\000\000\000\n.\000\000\000\000\000\000\000\000\n2\007\169\000\186\017v\000\000\000\000\000\000\000\000\000\000\n6\000\000\007\169\007\169\019\234\000\000\001\154\000\000\007\169\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\153\000\000\000\000\001\153\000\000\000\202\000\000\007\169\000\000\000\000\018V\000\000\007\169\000:\017\134\000:\007\169\007\169\001\153\000\206\000\000\000\000\001\153\000\000\007\169\000\000\000\000\000\000\007\169\007\169\000\000\000\000\000\000\001\153\000\000\000\000\000\000\001\153\007\169\001\153\001\153\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\169\001\153\000\000\000\000\001\153\000\000\001\153\000\000\000\000\007\169\000\000\000\162\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\169\000\000\017\138\000\000\001\153\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\153\000\000\000\000\000\000\007\169\000\000\000\000\007\169\007\169\000\000\000\000\007\169\000\000\000\000\000\000\000\000\007\169\007\169\000\000\005\129\000\000\007\169\005\129\000\000\001\153\003\166\005\129\001\153\005\129\000\000\000\000\001\153\000\000\005\129\005\129\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\153\000\000\000\000\000\000\000\000\001\153\001\153\000\000\000\000\000\000\000\000\003\174\000\000\000\000\000\000\001\153\001\153\001\153\000\000\007\169\0002\000\214\000F\000b\000\000\000f\000\000\000j\000\134\000\000\000\138\000\000\000\146\000\000\000\150\005\129\000\154\000\174\000\178\000\182\003\254\000\000\000\000\004N\000\218\000\000\000\000\007\169\000\000\000\000\000\000\000\000\000\186\000\000\000\000\007\169\000\000\000\000\004\006\007\169\007\169\000\000\002\t\000\190\000\000\000\000\000\000\000\000\000\000\007\169\000\000\000\000\000\000\004\014\000\000\000\000\000\000\002\t\000\000\004^\004f\000\000\000\000\000\000\000\202\000\000\000\000\000\000\007\169\004.\000\230\000\000\004\022\005\129\004&\000\000\000\000\000\000\000\206\000\000\000\000\000\000\007\169\011\018\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0046\000\000\000\000\000\000\000\000\000\000\011\026\007\169\000\000\000\000\007\169\007\169\002\t\000\237\000\000\000\000\000\237\000\000\000\000\007\169\007\169\011\"\000\000\000\162\007\169\000\000\000\000\000\177\000\177\000\000\000\000\004\006\000\000\000\000\000\000\000\237\004>\011B\000\000\002\t\011*\000\234\011:\004\030\000\000\000\000\004\014\000\000\000\000\000\000\000\237\000\000\000\237\000\237\000\000\002\t\000\000\000\000\000\000\000\000\002\t\002\t\004.\011J\011Y\004\022\000\000\004&\000\000\000\000\004n\004F\002\t\000\000\000\000\000\000\000\213\000\000\000\000\000\213\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0046\000\000\000\000\000\000\000\000\000\000\000\213\000\000\000\000\000\000\000\213\011R\000\237\000\000\000\000\000\000\000\000\000\000\0112\000\000\000\000\004\014\000\000\000\000\000\000\000\213\000\000\000\213\000\213\000\205\000\177\000\000\000\205\000\000\000\000\000\000\004>\000\213\000\000\000\237\004\022\000\000\004&\004\030\000\000\000\177\011Z\000\205\000\000\000\000\000\000\000\205\000\000\000\000\000\000\000\237\000\000\000\000\000\000\000\000\000\237\000\237\000\205\000\213\000\000\000\000\000\205\000\000\000\205\000\205\000\237\004F\000\237\000\000\000\000\000\213\000\000\000\000\000\205\000\000\000\000\004\022\000\000\000\205\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\209\000\000\000\000\000\209\000\000\000\000\000\000\000\213\000\000\000\000\000\213\000\000\000\205\000\000\004\030\000\000\000\000\000\000\000\209\000\000\000\000\000\000\000\209\000\000\000\205\000\000\000\213\000\000\000\000\000\000\000\000\000\213\000\213\000\209\000\000\000\000\000\000\000\209\000\000\000\209\000\209\000\213\000\213\000\213\000\000\000\000\000\000\000\000\000\205\000\209\000\000\000\205\004\022\000\000\000\209\004\030\000\225\000\000\000\000\000\225\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\205\000\000\000\000\000\000\000\000\000\205\000\205\004\006\000\209\000\000\000\000\000\225\000\000\000\000\000\000\000\205\000\205\000\205\000\000\000\000\000\209\000\000\004\014\000\000\000\000\000\000\000\225\000\000\000\225\000\225\000\000\000\000\000\000\000\000\000\217\000\000\000\000\000\217\000\225\000\000\000\000\004\022\000\000\004&\000\209\000\000\000\000\000\209\000\000\000\000\000\000\004\030\004\006\000\000\000\000\000\000\000\217\000\000\000\000\000\000\000\000\000\000\000\000\000\209\0046\000\000\000\000\004\014\000\209\000\209\000\000\000\217\000\000\000\217\000\217\000\000\000\225\000\000\000\209\000\209\000\209\000\000\000\000\000\217\000\000\000\000\004\022\000\000\004&\000\000\000\221\000\000\000\000\000\221\000\000\000\000\000\000\000\000\000\000\000\000\000\225\000\000\000\000\000\225\000\000\000\000\000\000\004\030\004\006\000\217\000\000\000\000\000\221\000\000\000\000\000\000\000\000\000\000\000\000\000\225\000\000\000\217\000\000\004\014\000\225\000\225\000\000\000\221\000\000\000\221\000\221\000\000\000\000\000\000\000\225\000\225\000\225\000\000\000\000\000\221\000\000\000\000\004\022\000\000\004&\000\217\000\000\000\000\000\217\000\000\000\000\000\000\004\030\000\229\000\000\000\000\000\229\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\217\0046\000\000\000\000\000\000\000\217\000\217\004\006\000\000\000\000\000\000\000\229\000\000\000\221\000\000\000\217\000\217\000\217\000\000\000\000\000\000\000\000\004\014\000\000\000\000\000\000\000\229\000\000\000\229\000\229\003\254\000\000\000\000\000\245\000\000\000\000\000\000\000\221\004.\000\000\000\221\004\022\000\000\004&\004\030\000\000\000\000\000\000\004\006\000\000\000\000\000\000\000\245\000\000\000\000\000\000\000\221\000\000\000\000\000\000\000\000\000\221\000\221\004\014\0046\000\000\000\000\000\245\000\000\000\245\004f\000\221\000\221\000\221\000\000\000\000\000\229\000\000\000\000\004.\000\000\000\000\004\022\000\000\004&\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\254\000\000\000\000\000\233\000\000\000\000\000\000\004>\000\000\000\000\000\229\000\000\0046\000\000\004\030\000\000\000\000\000\000\004\006\000\000\000\000\000\000\000\233\000\000\000\245\000\000\000\229\000\000\000\000\000\000\000\000\000\229\000\229\004\014\000\000\000\000\000\000\000\233\000\000\000\233\000\233\000\229\000\229\000\229\000\000\000\000\000\000\000\000\004>\004.\000\000\000\245\004\022\000\000\004&\004\030\003\254\000\000\000\000\000\241\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\245\000\000\000\000\000\000\000\000\000\245\000\245\004\006\0046\000\000\000\000\000\241\000\000\000\000\000\000\004n\004F\000\245\000\000\000\000\000\233\000\000\004\014\000\000\000\000\000\000\000\241\000\000\000\241\004f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004.\003\185\000\000\004\022\003\185\004&\004>\000\000\003\185\000\233\003\185\000\000\000\000\004\030\000\000\003\185\003\185\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\233\0046\000\000\000\000\000\000\000\233\000\233\000\000\000\000\000\000\000\000\000\000\000\000\000\241\000\000\000\233\004F\000\233\000\000\002-\000\000\000\000\000\000\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\185\000\000\004>\000\000\000\000\000\241\000\000\000\000\000\000\004\030\000\000\000\000\002-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002-\000\241\000\000\000\000\002-\002-\000\241\000\241\000\000\000\000\000\000\000\000\000\000\000\000\002-\000\000\000\241\004F\000\241\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002-\0002\005.\000F\000b\003\185\000f\000\000\000j\000\134\000\000\000\138\000\000\000\146\002-\000\150\000\000\000\154\000\174\000\178\000\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\186\002-\000\000\000\000\002-\002-\000\000\000\000\000\000\000\000\000\000\000\190\000\000\002-\002-\000\000\000\000\000\000\002-\000\000\000\000\0002\000\214\000F\000b\000\000\000f\000\000\000j\000\134\000\000\000\138\000\202\000\146\000\000\000\150\000\000\000\154\000\174\000\178\000\182\000\000\000\000\000\000\000\000\000\000\000\206\000\000\000\000\000\000\0052\0056\000\000\000\186\000\000\0002\005.\000F\000b\000\000\000f\000\000\000j\000\134\000\190\000\138\000\000\000\146\000\000\000\150\000\000\000\154\000\174\000\178\000\182\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\202\000\000\000\186\000\000\000\000\000\000\000\230\000\000\000\000\000\000\000\000\000\000\000\000\000\190\000\206\000\000\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\000\000\000\000\000\000\000\000\000\000\202\000\000\000\000\000\000\000\000\002y\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\206\000\000\000\000\000\000\021\182\0056\000\162\000\000\000\000\0002\005.\000F\000b\000\000\000f\000\000\000j\000\134\000\000\000\138\000\000\000\146\000\000\000\150\000\234\000\154\000\174\000\178\000\182\000\000\000\000\000\000\0002\000\214\000F\000b\000\000\000f\000\000\000j\000\134\000\186\000\138\000\000\000\146\000\000\000\150\002)\000\154\000\174\000\178\000\182\000\190\000\000\000\000\000\000\000\000\000\000\021\186\000\000\000\000\000\000\000\000\000\000\000\186\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\202\000\000\000\190\000\000\000\000\002q\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\206\000\000\000\000\000\000\0052\0056\000\000\000\000\000\000\000\202\000\000\000\000\011\018\000\000\000\000\000\230\000\000\0002\005.\000F\000b\000\000\000f\000\206\000j\000\134\000\000\000\138\000\000\000\146\011\026\000\150\000\000\000\154\000\174\000\178\000\182\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\"\000\000\000\000\000\000\000\186\000\000\000\185\011j\000\000\000\000\000\000\000\000\000\000\005B\000\000\000\190\011B\000\000\000\162\011*\000\000\011:\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\202\000\000\000\000\000\000\000\000\000\000\011J\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\206\000\000\000\000\000\000\021\182\0056\000\000\000\000\000\000\002!\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\011R\000\000\000\000\000\000\000\000\000\000\000\000\0112\000\000\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\000\000\000\000\000\000\000\000\000\000\000\000\000\021\194\000\000\000\000\000\000\000\185\011Z"))
   
   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\006\001\006\001\006\001\005\001\005\001\005\001\005\001\004\001\004\001\004\001\004\001\004\001\004\001\004\001\004\001\004\001\004\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\000\255\000\254\000\254\000\254\000\253\000\253\000\253\000\252\000\252\000\252\000\251\000\251\000\251\000\250\000\249\000\248\000\247\000\247\000\246\000\246\000\245\000\245\000\244\000\244\000\243\000\243\000\242\000\241\000\241\000\240\000\240\000\239\000\239\000\239\000\238\000\238\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\225\000\224\000\224\000\223\000\223\000\222\000\222\000\221\000\221\000\221\000\220\000\220\000\220\000\220\000\220\000\219\000\219\000\219\000\219\000\219\000\218\000\217\000\217\000\217\000\217\000\216\000\216\000\215\000\215\000\214\000\214\000\213\000\213\000\213\000\212\000\212\000\212\000\211\000\211\000\211\000\211\000\210\000\210\000\210\000\210\000\209\000\209\000\209\000\209\000\209\000\209\000\209\000\209\000\209\000\209\000\209\000\209\000\209\000\209\000\209\000\209\000\209\000\209\000\209\000\209\000\208\000\207\000\207\000\206\000\206\000\206\000\205\000\205\000\204\000\204\000\204\000\203\000\203\000\202\000\202\000\202\000\201\000\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\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\171\000\170\000\170\000\169\000\169\000\168\000\168\000\167\000\167\000\166\000\166\000\166\000\166\000\165\000\165\000\165\000\165\000\164\000\164\000\164\000\164\000\164\000\163\000\162\000\162\000\162\000\161\000\160\000\160\000\159\000\159\000\158\000\158\000\157\000\157\000\156\000\156\000\155\000\155\000\154\000\154\000\154\000\154\000\154\000\154\000\154\000\153\000\152\000\151\000\151\000\150\000\150\000\149\000\149\000\148\000\148\000\147\000\147\000\146\000\146\000\145\000\145\000\144\000\144\000\143\000\143\000\142\000\142\000\141\000\141\000\140\000\140\000\139\000\139\000\138\000\138\000\137\000\137\000\136\000\136\000\135\000\135\000\134\000\134\000\133\000\133\000\132\000\132\000\131\000\131\000\130\000\130\000\129\000\129\000\128\000\128\000\127\000\127\000~\000~\000}\000}\000|\000|\000{\000{\000z\000z\000y\000y\000x\000x\000w\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\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;\000:\0009\0008\0007\0006\0005\0005\0005\0005\0005\0005\0005\0004\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\022\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, "\001\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\011\000\000\000\223\012\200\000\000\000\167\000_\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\025\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003`\000\000\006\204\000\167\000_\000\000\000\000\000\000\000\000\000\000\017l\000$\008t\000\000\000\000\000\000\005\014\000\000\001\138\000\233\023\246\000\000\000\000\000\027\000\000\nH\000\000\007\178\019V\004\254\027\196\004\254\017\030)N\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\013^\027\196\000\000\000\000\013\128\000\000\014p\000\000\016\020\000\000\000\000\000\000\000\000\000\246\000\000$\198\000\000\000\000\008T\000\000\t\202\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000v\000\000\000\000\031.\000\000\031\194\000\000\"6\000\000%N\000\000'\192\000\000*X\000\000,f\000\000,\210\000\0002R\000\000 R\000\000\007\012\000\000\000\000\000\000\000\000\000\0008B\000\0009\246\000\000:\026\000\000\016\018\000\000\000\000\017r\000\000\000\000\000\211\000\173\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0009\000\164\000\000\000\136\000\000\000\000\002\236\000\00050\000\000\000\000\000\000\000\254\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\140\000\000\000\000\000\000\000\000\000\000\000\000\012\234)N\000\000\021\156\000\000\026d\026\154\000\000\000\000\000\000\0010\000\000&\002\000\000\000\0005\132\000\000\000\000\000\000\002\152\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\030\224\000\000#\146\000\000\000\000\000\000\000\000\000\012\000\000\000\0005\166\000\000\000\000\000\000 \146\002\182\000\000\000\000\000\000\000\000\000\000\000\000\004\162\000\000\n\002\000\000\018\232\000\000\022\174\000\000\023\216\000\000\024\238\000\000%\188\000\000%\246\000\000(H\000\000+\184\000\000)\170\000\000\000\n\000\000-\028\000\000/t\000\0003\012\000\000\000\000\000\000\000\000\000\000\000D6\028\000\000\002*\000\000\000\000\000-\016\238\000\000\002\158\000\000\000\000\000\000\005\180\000\000\000\000\000\000)f\000\000\000\000\000\000\000\000\000\000*\006\000\000\000\000\000\000\000\000\000\000\000\000\000\140\000\000\000\000\000\000\000\150\000\000\000\000\000\000\0026\000\000\000\000\011.\000\167\000\000\000\000\001\005\013F\000\000\000\000\000\000\000\000\000\000\004(\000\000\011r\000\000%n\000\000\000\000\005\192\000\000\000\000\000\000\000\000\000\000\000\000\012z\000\000\000\000\000\000\000\245\000\000\000\000\000\000\000\000\003B\015\204\000\000\002\138\000\000\000\000\001|\002\226\000\000\000\000\000\000\000\000\t\026\000\000\000\000\000\000\000\000\000\000\000\000\000'\019\214\000\000\0218\000\000\000\000\000\000\001\006\000\000\013\244\001~\000\000\016$\000\000\000\000\000\000\000\232\001\168\000\000\000\000\000\000\007(\000\000\000\000\001\206\000\000\000\242\000\000\000\000\000\000\000\000\001@\002\182\000\000\002v\000\000\000\000\000\000\000\000\000\000\000\00066\000\000\001(\000\0006\184\000\000\000\000\0024\000\000\008N\000\000\005\158\004V*\030\000\000\000\000\000\000\002\192\000\000\000\000\000\000\000\000\000\000\000\000\000\000\t@*\030\000\000\n\\\000\000\015f\015\240\000\000\000\000\000\000\006\166\000\000&X\000\000\000\0006\214\000\000\000\000\000\000\007\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000$\174\000\000&\196\000\000\000\000\000\000\003*\000\000\000\000\000\000\000\000\000\000\000\000\007j\000\000\014\030\000\000\0178\000\000\023\250\000\000\030D\000\000#\240\000\000'\172\000\000(\028\000\000)\238\000\000.x\000\000/\002\000\000\012\242\000\0005\008\000\0005&\000\0005\224\000\000*\190\000\000\000\000\000\0007|\000\000\000\000\000\000\000\011\000\0007\184\000\000\000\000\000\0007\210\000\000\000\000\0000\000\000\026\176\000!\000\196\000\000\002\156\000\000\014\254\002l\tX\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0008.\000\000*l\000x\007\006\000\000\000\000\000\000/\008\000\000/\168\000\000/\190\000\000+\136,\012\000z\001\003\007$\000\000\000\000\000\000\000\183\000\000\000\000\001\246\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0008j\000\000\000\000\000\000\000\000\000\000&\240\000\000,\134\000\000\000\000\000\000\000\000\000\000\000\000\015|\000\000\005&\000\000\000\000\000\000\000\000\t\252\001\250\000\000\016\162\000\000\000\000\000\000\000W\000\000\000\000 \230\006\152\000\000\003`/\136\000\000\000\000,b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0052,b\000\000\013|\000\000\018j\019\150\000\000\000\000\000\000\007\194\000\000'\168\000\000\000\0008n\000\000\000\000\000\000\007\230\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000,\212\000\000\002t\000\000\000\0008\142\000\0009^\000\000\000\000\000\000\022\028\000\000\000\00000\000\000\000\000\000\000\000\000\007\254\000\000\000\000\000\000\005\226\000\000\000\000\007\174\000\000\002v\000\000\000\000\000\000\000R\000\000\007\216\000\000\020\134\000\000\027\"\000\0001\018\000\0003P\000\0004\244\000\0006(\000\0007\140\000\0008\000\000\0008\226\000\0009\\\000\000:.\000\000\000\000\000\000\000\000\000\000\000\228\000\000\013\012\000\000\027\182\002\222\000\000\028\204\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\214\000\000\000\000\000\000\000\000\000\000\000\000\003\232\000\000\000\000\022\138\000\000\000\000\000\0000\166\000\000\000\000\015<\000\000\000\000\000\000\025T\000\000\000\000\000\000\000\0000\188\000\000\000\000\000\000\000\000\002\n\006\002\000\0001>\000\000\000\000\000\000\000\000\027D\004X\000\000\028\140\000\000\000\000\006j\000\0001\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\234\000\000\000\000\028\030\000\000\000\000\000\0001\198\000\000\000\000\004z\000\000\000\000\014\192\000\000\029 \000\000\000\000'\254\000\000\000\000\000\000\004$\000\000\000\000\028\234\000\000\000\000\000\000\000\0002\028\000\000\000\000\000\000\000\000\003<\018D\000\00022\000\000\000\000\000\000\000\000\000\000\000\000\016\200\000\000\000\000\0058\000\000\017F\000\000\004$\000\000\000\000\004@.~\000\000\005&\000\000\000\000\000\000\000\000\003*\000\000-f\000\000\029\212\001\182\030h\000\000\003*\000\000\017\236\000\000\018\146\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\158\031\140\005\014  \000\000\000\000\000\000\007\014\000\000\019\016\000\000\005\222\000\000\000\000\004$\001\222!D\000\000\005(\000\000\019\220!\234\000\000\000\000\020Z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\190\t\214\000\000\007\200\000\000\000\000\000\000\000\000\007\214\000\000\021&\000\000\000\000\000\000\030\2169~\000\000\000\000\000\000$\160\000\000\000\000\000\000\000\000\n*\004\158\000\000\000\0002\146\000\000\000\000\000\000\000\000\004\240\000\000\000\000 F\000\000\000\000\000\0002\222\000\000\000\000\002.\000\000\000\0003v\000\000\000\000\003\216\004\252\000\000\000\0003z\000\000\000\000\007\252%P\000\000\005J\000\000\000\0003\214\000\000\000\000\000\000\000\000\000\000\000\000\005h\000\000\000\000\"\254\000\000\000\000\000\0003\236\000\000\000\000\000\000\000\000\000\000(\150\000\000\000\000\000\000\000-\000\000\000\000\000\0004\002\000\000\000\000\003\220\005\230\000\000\000\0004v\000\000\000\000\008\020\000\000\000\000\000\000\000\000\003*\000-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\204\000\000\021d\000\000\000\000\000\0009\130\000\000\n\162\000\000\000\000\000\000\002\238\000\000\000\000\003\148\021\226\000\000\023.\000\000\000\000\000\000\004\232\000\000\"\170\007L-V\000\0000\004\000\000\000\000\000\000\007\192\000\000.*\007\236.\192\000\000.\248\000\000\000\000\000\000\0082\000\0000\156\0084\000\000\000\000\001f\006j\008J\014\026\000\000\015\164\000\000\000\000\000\000\008\192\000\0005\252\008\212\000\000\000\000\000\000\002l\000\000\000\000\000\000\000\000\000\000\003*\000\000\000\000\003\008\000\000\000\022\000\000\000\000\000\000\003\134\000\000\000\000\000\000\000\000\000\000\000C\000\000\008>\003\234\001B\000\000\000\000\007\246\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\246\000?\000\000\000\000\000\003\000\000\000\000\000\000\004v\000\000\000\000\006~\008H\000\000\000\000\000\000\000\000\017p\019\176\006<\000\000\020\140\000\000\000\000\000\000\000\000\000\000\000\000\003.\000\000\000\000\004\180\000\000\000\000\004\026\000\000\000\000\003|\000\000\000\000\004\022\000\000\t*\0056\002z\000\000\000\000\t\152\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\252\022\016\000\000\000\000\000\000\000\000\022\140\000\000\000\000\011:\000\000\000\000\015\026\000\000\000\000\000\000\023\024\000\000\000\000\0009\023@\007\204\000\000\023`\000\000\000\000\000\000\000\000\000\000\000\000\005\154\000\000\t0\003\140\000\142\000\000\000\000\000\000\000\000\002`\000\000\000\000\000\000\000\000\000\000\000\000\012\134\000\000\000\000\006*\000\000\t:\005v\003\144\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012\200\000\000\000\000\019(\023\240\000\000\000\000\000\000\000\000\002T\000\000\003\134\000\000\0208\000\000\000\000\000\000\000\000\000\000\000\000\000\011\020\164\000\000\000\000\021\128\000\000\000\000\000\000\000\000\000B\000\000\021\254\000\000\000\000\000\000\000\000\005\254\000\000\000\000\000\000\000\155\000\000\000\000\000Y\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\190\005\008\000\000\000\000\000\000\001\006\000\000\000\000\026\234\000\000\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\n\180\000\167\013\028\019\030\005b\000\000\000\000\006\164\006\188\007\250\008j\000\000\000\000\000\000\000\000\000\000\000\000\006\180\023\172\000\000\"(\t\024\000\000\000\000\t>\000\000\024x\000\000\025n\000\000\000\000\007.\024\182\000\000\"\216\000\000\007\136#\188\000\000\000\000\000\000\018\020\006\164\000\000\006\004\000\000\000\000\000\000\008\220\000\000\011\000\000\000\004:\006\170\000\000\000\000\000\000\000\000\004(\000\000\005\192\000\000\008\148\000\000\000\000\020\130\000\000\000\000\000\000\000\000\011 \000\000\000\000\006\164\tP\000\000\026\\\000\000\004$\005\220\000\000\000\000\000\000\000\000\000\000\0058\000\000\000\000\000\000\000\000\000\0004\132\t\026\000\000\tr\000\000\000\000\000\000\000\000\000\000\001\216\000\000\011\238\t\190\012l\000\000\003\180\013v\000\000\t\222\000\000\0048\000\000\005\128\000\000\006\004\000\000\000\000\000\000\000\000\000\000\t,\000\000\007L\000\000\t\246\000\000\007\208\000\000\004$\006*\000\000\004\\\000\000\006L\005\210\000\000\008h\000\000\008\172\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\tB\000\000\t\202\000\000\000\000\000\000\000\000\000\000\006$\000\000\000\000\006\018\002r\007\208\000\000\008x\000\000\000\000\t^\t\242\000\000\007\158\000\000\000\000\000\000\000\000\007\224\000\000\000\000\000\000\000\000\000\000\000\000\008\022\008\156\008|\td\008\188\t\"\000\000\000\000\008\248\008\168\t\148\t\024\t\\\000\000\000\000\n2\000\000\000\000\000\000\000\000\n.\000\000\000\000"), (16, "\001\200\001\223\000>\000h\002u\004g\000\017\001<\002!\002\"\000\n\004|\000\005\004\206\000>\002E\001g\000*\002m\003n\003V\000\210\004e\000\231\001i\000>\004h\004t\004}\004t\004\207\004\210\004t\001?\004\225\000\t\000\008\000\t\003\007\005\026\005\027\004\127\000\016\004P\003!\000\167\001\202\000j\000*\004d\001\203\004\226\000k\002G\004\229\004t\000l\002\143\004}\004t\002\168\004\224\005\031\005 \0008\000j\004e\0009\000\212\002F\004h\004t\000\213\004\013\004\206\000h\001\200\001\223\000*\000}\000u\001+\005$\0055\005\006\004u\0056\004u\001\200\001\223\004u\004\207\004\210\004t\005b\003\157\003b\001\228\000\226\001 \005c\000j\000>\0008\005:\002\145\005d\002F\003 \002\146\001h\002!\002\"\004u\005\t\001-\004\214\004u\001h\000j\002[\000*\001\202\001\133\000k\004\019\001\203\000F\000l\004u\002\143\004\215\003!\002\168\001\202\002\\\001%\000\247\001\203\001@\001\135\0053\001\156\000\164\000\177\001\216\000>\000\210\000F\000\233\002a\004u\000u\003C\002b\000\164\001D\003(\000+\001\217\003\159\003|\000v\0053\001\200\001\223\000\164\000\165\003)\003h\001'\000\176\003j\001\228\002[\002v\005f\005*\002\145\004W\000\227\001\158\002\146\000*\002T\004\031\000w\000*\001x\002f\000>\000j\002\247\003W\000\212\003v\003\247\005g\000\213\004\128\003<\004\239\002\159\000\248\003\141\004k\003N\001\232\002[\000>\001\202\002\\\000*\002m\001\203\005\001\002\160\000\174\000\178\001A\000>\001\216\005\012\002\\\000\226\001E\002a\001\233\002$\001\023\002b\002H\001\234\001\216\000v\001\217\001\235\004v\002a\004B\004\216\001\236\002b\000\164\001D\003(\005i\001\217\003j\000\252\001t\000j\001\200\001\223\003p\005j\005\132\000*\000w\002\187\005\133\004\014\005\019\000\255\005\160\002f\000>\002K\002L\002N\005d\005\161\003 \001\136\003\143\002\159\002\228\002f\002\226\004l\000\017\0037\005\135\001\232\002\190\004\016\002\195\001\152\003<\002\160\001\135\000>\005\137\000n\003N\001\232\003!\000\187\001\202\002\\\002\198\001\146\001\203\001\233\004\219\000y\000\227\005\179\001\234\001\216\002\229\000*\001\235\000j\002a\001\233\002\193\001\236\002b\000~\001\234\003\020\000\215\001\217\001\235\001@\001\200\001\223\000>\001\236\002\143\001\162\005+\002\168\003\153\001\154\002d\004\225\001\159\003\007\000>\0009\000\017\000*\002m\003n\003V\002!\002\"\004\218\000\164\001D\003(\002f\004\226\000\251\005\180\004\229\004t\002\195\004\167\000\164\000\177\003)\004\215\005.\001\139\000F\001\200\001\221\003!\001\232\001\202\002\196\000j\000\252\001\203\004\168\002\145\001%\000\253\001\153\002\146\002\143\000\254\000*\002\168\002\\\004C\000\255\000h\001\233\000*\004o\000q\003<\001\234\001\216\003x\003A\001\235\003N\002a\0009\000>\001\236\002b\000\164\001D\003(\005\182\001\217\000j\001&\001\202\001B\004u\004\254\001\203\005j\005\132\002H\003}\001\228\005\184\001 \004U\002[\002o\000*\004\027\002\145\000\164\000\177\000j\002\146\001\161\000>\001+\000k\003p\002f\005\225\000l\000>\0037\005\186\000>\002\143\000F\001n\002\164\003<\000F\003\008\004\151\005\188\002J\003N\001\232\002\194\002\\\000>\004V\002#\001\163\004z\000u\004\\\000\164\000\165\001\216\001,\004\216\003O\002\159\002a\000E\000\250\001\233\002b\000\164\001D\003(\001\234\001\217\004\160\003\127\001\235\002\160\001\200\001\223\000j\001\236\003)\000F\002\145\003\203\003j\004\167\002\146\001I\000\224\004\161\000>\004\164\004t\001%\005d\005\166\003V\004a\002\187\001\216\004\215\002f\004\168\002\193\005\001\003W\000\174\003v\000>\004\030\000>\005\002\003<\001\217\002\159\004\029\003\141\002\233\003N\001\232\003!\004\018\001\202\002\190\002\245\000F\001\203\001\231\002\160\001q\000\248\000\164\000\165\001 \004\171\000v\005\176\000*\003\209\001\233\003\253\005\238\001\200\001\223\001\234\002\169\000*\000*\001\235\004\163\004u\000\181\004W\001\236\000\172\002\193\000>\001\200\001\223\000w\005d\005\166\003V\002u\000\164\000\165\004\161\003\029\004\164\004t\003s\000\164\000\177\001u\000\164\001D\003\007\003\030\000*\002\159\000\173\001\222\000\174\004%\0036\000\150\003!\001F\001\202\000\164\000\165\002\236\001\203\002\160\003\030\000\210\005\239\000\231\002\195\004|\004'\000j\005\171\001\202\005\240\004q\000y\001\203\004\029\004\221\000\151\002\\\002\196\004\152\000\152\000\174\004}\004t\000>\001+\000{\001\216\000\179\001p\001w\001s\002a\004u\003e\004\155\002b\000\164\001D\003(\005\172\001\217\004\154\000*\001(\000j\000\174\000h\000\212\005j\005\132\000q\000\213\000F\002d\000\164\000\177\000\164\000\177\001-\001\228\000>\000F\000F\002!\002\"\004\176\004\157\003g\000>\000D\002f\000C\002\143\003\130\003W\002\163\005\174\000\226\004\232\005x\004u\003<\002\\\000*\003\\\003A\003\143\003N\001\232\000*\000j\000F\001\216\001b\003\030\000k\003C\002a\000E\000l\002\246\002b\000\164\001D\003(\005\172\001\217\001\216\001\233\002\252\003,\001\200\001\223\001\234\005j\005\132\000j\001\235\004\173\002d\002\145\001\217\001\236\000u\002\146\000>\001\200\002\014\000*\005d\005\166\003V\005\145\005\146\001\230\005\248\002f\000h\004\016\003H\003W\000}\005\174\000*\001\030\001 \003\146\003<\003e\004\209\004\234\003A\000F\003N\001\232\003!\003L\001\202\004(\000\227\002\143\001\203\0050\002\168\000\164\000\165\004\207\004\210\004t\001\232\000j\005\173\001\202\005y\001\233\004'\001\203\001\200\001\223\001\234\002i\000j\003f\001\235\000>\005\150\000k\000*\001\236\001\233\000l\000>\004\131\000F\001\234\005d\005\166\003V\001\235\000F\003\185\000\164\000\165\001\236\002[\000v\000*\002u\002\145\000\164\001D\003\138\002\146\004\152\000u\000\174\003\132\002\159\005\022\004\228\000*\003!\001F\001\202\001\"\0051\004u\001\203\000\252\000w\005@\002\160\005\143\001m\005\190\005\004\004\226\005\175\000F\004\229\004t\003\193\001\001\003\138\0053\003\140\002\\\003\210\004\142\004t\001(\002\143\000\174\000F\002\168\000\150\001\216\005\194\001p\002u\001s\002a\002!\002\"\004|\002b\000\164\001D\003(\005\172\001\217\001\216\000*\005\014\000>\005E\000y\003\139\005j\005\132\000\151\004}\004t\002d\000\152\001\217\003\219\005E\005h\002\187\000{\000>\000@\001~\000C\002[\000v\001^\004u\002\145\002f\003\229\000*\002\146\003W\002\159\005\174\004u\002\189\000h\005\024\003<\002\\\000}\002\190\003A\000F\003N\001\232\002\160\000w\000E\001\216\002!\002\"\000\164\000\165\002a\005r\003\130\000F\002b\000\164\001D\003(\005\172\001\217\000>\001\233\005\213\004u\001\200\001\223\001\234\005j\005\132\002\193\001\235\000*\002d\000*\0051\001\236\000j\003\162\000>\001\200\001\221\000k\005d\005\166\003V\000l\005\218\003\254\000*\002f\0010\002!\002\"\003W\005\219\005\174\000\210\005\001\000\231\000\174\003<\003\021\005M\002\187\003A\000F\003N\001\232\003!\000u\001\202\003\164\002\195\002\143\001\203\000\210\002\168\0016\003\025\002\159\002\223\002\240\002\226\000j\005\183\001\202\002\196\001\233\002\190\001\203\001\200\001\223\001\234\002\160\002\143\001\205\001\235\002\168\000\164\001D\000j\001\236\003\168\000\212\000>\001\150\005I\000\213\005d\005\166\003V\005s\003\030\003\"\002\229\000\164\001D\002[\005H\000j\002\193\002\145\000\212\005[\005\224\002\146\000\213\000*\001F\005E\003&\004\200\004t\000\226\003!\004\137\001\202\004n\000j\001m\001\203\001\214\002\145\0025\005v\000*\002\146\005w\004/\000\174\005\187\000v\000\226\001\200\001\223\003\135\000h\000*\002D\002\\\000s\000\164\000\165\002\195\001p\0041\001s\000>\005`\001\216\003\162\002m\003n\003V\002a\000w\004|\002\196\002b\000\164\001D\003(\005\172\001\217\001\216\005E\000>\000@\000A\000C\004u\005j\005\132\004}\004t\004\003\002d\003!\001\217\001\202\000j\000\148\002\187\001\203\003\163\000k\0042\004\003\005\223\000l\001(\004l\000\174\002f\004r\000\227\000E\003W\002\159\005\174\005\205\002\192\000y\0041\003<\002\\\0049\002\190\003A\004\005\003N\001\232\002\160\000u\000\227\001\216\000{\002\148\005\233\002\159\002a\004\004\005\235\004;\002b\000\164\001D\003(\005\172\001\217\004s\001\233\004u\002\160\005\205\002\157\001\234\005j\005\132\002\193\001\235\004<\002d\005Q\004?\001\236\001\233\002\185\000j\000>\000@\001z\000C\003\030\001\200\001\220\004H\005G\004;\002f\001\238\0041\005T\003W\000\232\005\174\001\200\001\223\002\\\005\243\003<\005\134\003\030\004J\003A\005\241\003N\001\232\001\216\000E\000>\003\030\002\195\002a\002m\003n\003V\002b\000\164\001D\003(\005\250\001\217\004\022\003|\000v\002\196\001\233\000j\005z\001\202\003)\001\234\002\195\001\203\002d\001\235\000\164\001D\005\205\003!\001\236\001\202\005F\004\174\004K\001\203\002\200\004\222\000w\001F\004\235\002f\000h\004N\004\170\003W\000s\003v\001\200\001\223\001m\004J\003<\005\212\005\154\005\163\003A\005\155\003N\001\232\0041\004\168\000>\004\135\000x\005\152\002m\003n\003V\004\175\000\210\005\163\000\231\004\223\005\181\001p\004\236\001s\005\242\001\233\005\245\000>\005l\005\163\001\234\000y\000j\005\206\001\235\005\227\000\161\000k\003!\001\236\001\202\000l\005\205\005\177\001\203\000{\005\228\005\238\005\246\005\244\000>\000\210\004\168\000\233\005\159\000\164\001D\002t\005y\005\169\000j\001\200\001\219\000\212\001\216\000u\002\\\000\213\001F\005\238\005\249\005\185\005\252\005\251\0051\006\000\001\216\005\253\001\217\001m\003\184\002a\006\005\0051\006\001\002b\000\164\001D\003(\000\000\001\217\003z\003|\000\226\000\000\000j\001\200\001\223\000\212\003)\000\000\000\000\000\213\002d\001p\000j\001s\001\202\005\208\000\000\000>\001\203\000\000\0053\002m\003n\003V\000\000\005\237\000>\002f\005\237\000\000\005>\003W\000\238\003v\000\000\000\226\002\\\000\000\003<\000\000\000\000\000\000\003A\000\000\003N\001\232\001\216\003!\000\000\001\202\000\000\002a\005\237\001\203\000v\002b\000\164\001D\003(\000\000\001\217\003\161\003|\000\000\000>\001\233\001\200\001\223\000\000\003)\001\234\000\000\004\160\002d\001\235\000\164\001D\000\000\000w\001\236\000>\000\000\000\227\005\210\002m\003n\003V\000>\002\249\004\161\002f\004\164\004t\000\000\003W\000\000\003v\000\000\000\164\001D\000\000\003<\000\000\004\160\000x\003A\000\000\003N\001\232\000\000\003!\003\190\001\202\001\216\000\000\000\000\001\203\000\227\005{\000\000\004\161\000>\004\164\004t\003\005\000y\003\019\001\217\001\233\0017\000z\000\000\000\000\001\234\000\000\000\000\000\000\001\235\002\\\000{\001Y\000\000\001\236\000\241\000\000\000\000\000\000\003\202\001\216\003\208\004u\000\252\000\000\002a\001S\000\000\000\000\002b\000\164\001D\003(\000\000\001\217\004\026\003|\001\003\000\251\000\164\005?\001\200\001\223\003)\000\000\000\000\001Y\002d\000\000\000\000\000\000\005K\005B\004u\000\000\000>\000\000\000\000\000\252\005d\001S\003 \000\000\000\253\002f\000\000\000\000\000\254\003W\000\000\003v\000\000\000\255\002\\\000\000\003<\000\000\000\164\001D\003A\000\000\003N\001\232\001\216\000\000\003!\000\000\001\202\002a\000\000\005s\001\203\002b\000\164\001D\003(\000\000\001\217\005\130\003|\000\164\001D\001\233\005\178\001\200\001\223\003)\001\234\000\000\000\000\002d\001\235\000\000\001T\000\000\000\000\001\236\000\000\000>\005~\000\000\005\127\005d\005v\003 \000>\005w\002f\000\174\000\000\000\000\003W\004\182\003v\000\164\001D\000\000\000\000\003<\000\000\004\225\001_\003A\001j\003N\001\232\001\\\001T\003!\001]\001\202\000\174\000\000\000\000\001\203\000\000\000\000\004\226\000\000\000\000\004\229\004t\000\000\004\188\000>\001\233\005\164\000\210\000\000\000\230\001\234\001\200\001\221\004\225\001\235\001_\002\\\001`\001Y\001\236\001\\\000\000\000\000\001]\002\143\000\174\001\216\002\168\000\000\000\000\004\226\002a\001S\004\229\004t\002b\000\164\001D\003(\005\165\001\217\000\000\000\000\000\000\000\000\000\000\000>\000\000\005j\005\132\005>\000j\000\000\005\168\000\212\000j\000\000\001\202\000\213\004u\000\000\001\203\000\000\000\000\000\000\000h\000\000\000>\002[\000\193\002f\000\000\002\145\000\000\0037\005\170\002\146\001\200\001\223\002\\\002\143\003<\000h\002\162\000\226\003A\000\190\003N\001\232\001\216\000\000\000>\004u\000\000\002a\005d\000\000\003 \002b\000\164\001D\003(\005\165\001\217\000\000\000\000\000\164\001D\001\233\000j\000\000\005j\005\132\001\234\000k\000\000\005\168\001\235\000l\001T\001R\003!\001\236\001\202\000j\000\000\000j\001\203\002\145\000\000\000\000\000k\002\146\002f\001S\000l\000\000\0037\005\170\005\167\001\200\001\223\000u\000\000\003<\000\164\000\165\001_\003A\001e\003N\001\232\001\\\002\187\000>\001]\001\216\000\174\002m\000u\003 \001\200\001\221\000\000\000\000\000\000\000\227\000\000\004\237\002\159\001\217\001\233\002\230\000>\000\000\000\000\001\234\002m\002\190\000\000\001\235\000\000\000\000\002\160\003!\001\236\001\202\000\164\005?\000\000\001\203\000\000\000\000\000\000\001\128\000\000\000\174\000\000\000\000\005J\005B\004\242\000h\004B\002\232\000j\000\189\001\202\000\164\001D\002\193\001\203\002\\\000\000\000\000\000\000\004 \000\000\002\004\000\000\003\156\001T\001\216\000\000\000v\002\159\000\000\002a\000\000\000\000\000\000\002b\000\164\001D\003(\005\165\001\217\000\000\001\233\002\160\000\000\000v\001\200\001\223\005j\005\132\000j\002\238\000w\005\168\0039\000k\001\236\002\195\001\\\000l\000>\001]\000\000\000\174\002m\003:\003V\000\000\000\000\000w\002f\002\196\000\000\000\000\0037\005\170\000\000\001\200\001\223\002\\\000\000\003<\000\000\000u\000\000\003A\000\000\003N\001\232\001\216\003!\000>\001\202\000\000\002a\002m\001\203\003 \002b\000\164\001D\003(\000\000\001\217\000\000\000\000\000\000\000\000\001\233\000\000\001\216\000\000\003)\001\234\000\000\004\160\003\145\001\235\000\164\001D\003(\003!\001\236\001\202\001\217\000\000\000\000\001\203\000\000\001\200\001\218\003)\004\161\002f\004\164\004t\000\000\0037\003\147\002u\001\200\001\223\000\000\000\000\003<\000\000\000\000\002k\003A\000\000\003N\001\232\003\007\003\154\000>\000\000\004E\003\156\002m\003\027\003 \000\000\000\000\003<\000\000\000v\000\000\003A\000\000\003N\000\000\001\233\000\000\000j\000>\001\202\001\234\000\000\002m\001\203\001\235\002\\\000\000\000\000\003!\001\236\001\202\000\000\000\000\000w\001\203\001\216\001\233\004u\000>\001o\002a\000C\001\200\001\201\002b\000\164\001D\003(\004B\001\217\001\240\000\000\000\000\000\000\000\000\000\000\002\\\000\000\003)\000h\000h\000\000\002d\000s\000i\000\000\001\216\000\000\000E\000\000\000\000\002a\000\000\000\000\000\000\002b\000\164\001D\003(\002f\001\217\000\000\000>\003W\000\000\003X\000j\000\000\001\202\003)\003<\000\000\001\203\003\145\003A\000\000\003N\001\232\000\000\000\000\000\000\000\000\000\000\000j\000j\000\000\000F\000\000\000k\000k\002f\003\008\000l\000l\0037\003\147\000\000\001\233\001\216\002\\\000\000\003<\001\234\000\000\000\000\003A\001\235\003N\001\232\001\216\000\000\001\236\001\217\000\000\002a\001Y\000u\000u\002b\000\164\001D\003(\000\000\001\217\000\000\000>\000\000\004\191\001\233\001S\001\200\001\223\003)\001\234\003\013\000\000\003[\001\235\003Y\000\164\001D\003(\001\236\000\000\000>\000\000\000\000\000\000\002m\003:\003V\003\017\003)\002f\000\000\000\000\000\000\0037\003]\000\164\001D\000\000\000\000\000>\003<\000\000\000\000\001\216\003_\000\000\003N\001\232\001F\000\210\003!\000\233\001\202\004G\001Y\000\000\001\203\001\217\000\000\001m\003<\000\000\001\200\001\221\003A\000\000\003N\001\233\001S\001\200\001\223\000\000\001\234\000\000\000v\000v\001\235\003^\000\000\000\164\001D\001\236\000\000\000>\001p\000\000\001s\002m\003:\003V\000\000\000h\001T\000j\000\000\000s\000\212\000\000\000w\000w\000\213\000\000\000>\000\000\000\000\001|\000j\000\000\001\202\000\000\000\000\000\000\001\203\003!\000\000\001\202\004|\000\000\000\000\001\203\001_\000\000\001\141\000\238\000x\001\\\000\226\000\000\001]\000\000\000\174\000\000\000E\004}\004t\000j\000\000\000\000\000\000\000\000\000k\002\\\000\164\001D\000l\000y\000\000\000\000\000\000\000\000\000\160\001\216\001\200\001\223\000\000\001T\002a\000\000\000\000\000{\002b\000\164\001D\003(\000\000\001\217\000>\000\000\000u\000\000\002m\003n\003V\000\000\003)\000\000\000\000\000\000\002d\000\000\000\164\000\165\000\000\001_\000\000\002q\000>\000\000\001\\\000\000\005>\001]\004u\000\174\000\000\002f\003!\000\000\001\202\003W\000\000\003X\001\203\000\000\002\\\000\000\003<\001\216\000\227\000\000\003A\000\000\003N\001\232\001\216\002\143\002t\000\000\002\161\002a\000\239\001\217\000\000\002b\000\164\001D\003(\002u\001\217\001*\000\000\000\174\000\000\001\233\000\241\001\200\001\223\003)\001\234\000\000\000*\002d\001\235\000\164\001D\000\000\000\000\001\236\000\000\000>\000v\000\000\000\000\002m\003n\003V\001F\000\251\002f\000j\000\000\000\000\003W\002\145\003X\000\000\000\000\002\146\000\000\003<\000\000\000\000\000\000\003A\000w\003N\001\232\000\252\000\210\003!\000\231\001\202\000\253\000\000\000\000\001\203\000\254\002\\\000\000\001\233\000\000\000\255\001p\000\000\001s\000\000\001\233\001\216\001\200\001\223\000x\001\234\002a\001\242\004\148\001\235\002b\000\164\001D\003(\001\236\001\217\000>\003u\000\000\000\000\002m\003n\003V\000>\003)\000y\000j\005>\002d\000\212\000\163\000\164\001D\000\213\000\000\000\000\000\000\000h\004\160\000{\000\000\000q\000\000\005A\005e\002f\003!\000\000\001\202\003W\000\000\003v\001\203\000\000\000F\004\161\003<\004\164\004t\000\226\003A\000\000\003N\001\232\002\159\000\000\000\000\000\000\000\000\002\143\000\000\000\000\002\144\000\000\002\\\000\000\000\000\000\000\002\160\000\000\003\005\000j\003\019\001\233\001\216\000\000\000k\000\000\001\234\002a\000l\000\000\001\235\002b\000\164\001D\003(\001\236\001\217\000\000\003w\000\000\003P\000\000\001\200\001\223\000\000\003)\004|\000\000\000\000\002d\000\000\000j\000u\000>\004u\002\145\000>\003T\000\000\002\146\002m\003\148\003V\004}\004t\000\000\002f\000\000\000\000\000\000\003W\000\000\003v\0011\000\000\002\\\000\000\003<\000\000\000\227\000\000\003A\000\000\003N\001\232\001\216\003!\000\000\001\202\000\000\002a\000\000\001\203\000\000\002b\000\164\001D\003(\000\000\001\217\000\000\003\137\000\164\005?\001\233\001\200\001\223\000\000\003)\001\234\000\000\004\225\002d\001\235\005A\005B\000\000\000\000\001\236\000>\003\150\000\000\004u\002m\003\148\003V\000\000\002\143\004\226\002f\002\168\004\229\004t\003W\000v\003v\000\000\000\000\000\000\000>\003<\000\000\000\000\000\000\003A\000\000\003N\001\232\000\252\003!\000\000\001\202\002\159\001\"\000\000\001\203\004|\000\000\000w\000\000\000\000\000\000\001\005\000\000\004\248\004\225\002\160\001\233\000\000\000\000\000\000\000j\001\234\004}\004t\002\145\001\235\002\\\000\000\002\146\000\000\001\236\004\226\003\152\000\150\004\229\004t\001\216\000\000\000\000\004u\000\000\002a\005{\000\164\000\165\002b\000\164\001D\003(\000\000\001\217\000\000\000\000\000\000\000y\000\000\001\200\001\223\000\151\003)\000\000\000\000\000\152\002d\003\170\000\000\000\000\000\000\000{\000\000\000>\000\000\000\000\000\000\002m\003:\003V\000\000\000\000\000>\002f\004u\000\000\004\146\003W\000\000\003\151\001\200\001\223\002\\\000\000\003<\001\130\004u\000\174\003A\000\000\003N\001\232\001\216\003!\000>\001\202\000\000\002a\002m\001\203\003 \002b\000\164\001D\003(\000\000\001\217\000\000\000\210\000\000\000\229\001\233\000\000\000\000\002\159\003)\001\234\004\225\000\000\002d\001\235\000\000\000\164\001D\003!\001\236\001\202\000\000\002\160\000\000\001\203\000\000\000\000\000\000\004\226\005s\002f\004\229\004t\000\000\003W\004\255\003\151\001\200\001\223\000\000\000\000\003<\000\000\000\000\000\000\003A\000j\003N\001\232\000\212\004\020\000>\000\000\000\213\003\156\002m\000\000\003 \005}\000\000\000\000\000\000\005v\000\000\000\000\005w\002\143\000\174\001\233\002\168\000\000\000\000\000\000\001\234\004\225\000\000\000\000\001\235\002\\\000\226\004\144\003!\001\236\001\202\000\000\000\000\004|\001\203\001\216\005\007\004u\004\226\002\195\002a\004\229\004t\000\000\002b\000\164\001D\003(\000\000\001\217\004}\004t\000\000\002\202\000\164\000\165\002\\\002[\003)\000\000\004\"\002\145\002d\000\000\003\156\002\146\001\216\000\000\000\000\000\000\000\000\002a\000\000\000\000\000\000\002b\000\164\001D\003(\002f\001\217\000\000\000>\003W\000\000\003X\000\210\000\000\000\231\003)\003<\000\000\000\000\003\145\003A\004|\003N\001\232\000\000\000\000\004u\000\000\000\000\001\132\000\000\000\174\000\000\000\000\000\227\004u\002f\000\000\004}\004t\0037\003\147\000\000\001\233\000\000\002\\\000\000\003<\001\234\000\000\000\000\003A\001\235\003N\001\232\001\216\000j\001\236\000\000\000\212\002a\001Y\000\000\000\213\002b\000\164\001D\003(\002\187\001\217\000\000\000\000\005\n\000\000\001\233\001S\001\200\001\223\003)\001\234\000\000\000\000\003\145\001\235\002\159\002\223\002\224\002\226\001\236\000\226\000>\004|\000\000\002\190\002m\000\000\003 \004u\002\160\002f\000\000\000\000\000\000\0037\003\147\000\000\000\000\000\000\004}\004t\003<\004|\000\000\000\000\003A\000\000\003N\001\232\000\000\002\229\003!\000\000\001\202\000\000\000\000\002\193\001\203\004|\004}\004t\000\000\000\000\000\000\000\000\000\000\005\017\000\000\001\233\000\000\001\200\001\223\000\000\001\234\000\000\004}\004t\001\235\004\180\000\000\000\164\001D\001\236\004$\000>\000\000\000\000\003\156\002m\000\000\003 \000\000\000\210\001T\000\231\000\000\000\000\000\000\004u\002\195\000\000\000\000\000\227\000\000\000\000\000\000\000\000\000h\000\000\001\200\001\221\000q\000\000\002\196\003!\000\000\001\202\000\000\004u\000\000\001\203\001_\000\000\002\255\000\000\000\000\001\\\000\000\000\000\001]\004|\000\174\000\000\000\000\004u\000\000\000j\000\000\000\000\000\212\004\185\000\000\002\\\000\213\000\000\000\000\005N\004}\004t\000\000\003\156\000j\001\216\000j\000\000\001\202\000k\002a\000\000\001\203\000l\002b\000\164\001D\003(\000\000\001\217\000\000\000\000\000\226\001=\000\252\001\200\001\223\000\000\003)\000\000\000\000\000\000\003\145\005V\000\000\000\000\000\000\000u\001\007\000>\000\000\000\000\000\000\002m\003:\003V\000\000\000\000\000\000\002f\000\000\000\000\000\000\0037\003\147\000\000\001\200\001\223\002\\\004u\003<\000\000\000\000\004\195\003A\000\000\003N\001\232\001\216\003!\000>\001\202\000\000\002a\002m\001\203\003 \002b\000\164\001D\003(\000\000\001\217\004\204\000\210\000\000\000\231\001\233\000\000\000\000\000\000\003)\001\234\000\000\000\000\003\145\001\235\000\000\000\000\004\202\003!\001\236\001\202\000\000\000\227\000\000\001\203\001\216\000\000\000\000\000\000\000\000\002f\000\000\000\000\000\000\0037\003\147\000\000\000v\000\000\001\217\000\000\003<\000\000\000\000\000\000\003A\000j\003N\001\232\000\212\005\\\000\000\000\000\000\213\003\156\000\000\000\149\000\000\000\000\000\000\000\000\000w\000\000\000\000\000\000\000\000\002\143\000>\001\233\002\168\000\000\000\000\000\000\001\234\000\000\000\000\000\000\001\235\002\\\000\226\000\000\000\000\001\236\000\000\000\000\000\000\000\000\000\150\001\216\004\246\000\000\000\252\000\000\002a\000\000\000\000\000\000\002b\000\164\001D\003(\000\000\001\217\000\000\000\000\001\t\000\000\001\233\000y\002\\\002[\003)\000\151\000\000\002\145\002d\000\152\000\000\002\146\001\216\001Y\001\244\000{\000\000\002a\000\000\000\000\000\000\002b\000\164\001D\003(\002f\001\217\001S\000\000\003W\000\000\003X\000\000\000\000\000\000\003)\003<\000\000\000\000\003\145\003A\000\000\003N\001\232\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\227\000\000\002f\000\000\000\000\000\000\0037\003\147\000\000\001\233\000\000\000\000\000\000\003<\001\234\000\000\000\000\003A\001\235\003N\001\232\000\000\000\000\001\236\001\200\001\223\000\000\000\000\000\210\000\000\000\228\000\000\005\136\000\000\002\187\000\000\000\000\000\000\000>\000\000\001\233\000\000\002m\003:\003V\001\234\000\000\000\164\001D\001\235\002\159\002\223\005X\002\226\001\236\000\210\000\000\000\211\000\000\002\190\001T\000\000\000\000\000\000\002\160\003\165\001\200\001\223\003!\000\252\001\202\000\000\000j\000\000\001\203\000\212\000\000\000\000\000\000\000\213\000>\000\000\000\000\001\011\002m\002\229\003V\000\000\001_\000\000\003\n\002\193\000\000\001\\\000\000\000\210\001]\000\233\000\174\000j\000\000\000\000\000\212\000\000\000\000\000\226\000\213\000\000\000\000\000\000\003!\000\000\001\202\000\000\000\000\000\000\001\203\000\000\000\000\000\000\000\000\000\000\000\000\002\143\000\000\005-\002\168\000\000\000\000\000\000\000\000\000\000\000\226\000\000\002\195\000\000\000\000\000\000\000\000\000j\001\200\001\223\000\212\000\000\000\000\000\000\000\213\000\000\002\196\000\000\000\000\003Z\000\000\000\000\000>\000\000\000\000\000\000\002m\002\\\003 \000\000\000\000\000\000\000\000\000\000\000\000\000j\000\000\001\216\000\000\002\145\000\226\000\000\002a\002\146\000\000\000\000\002b\000\164\001D\003(\000\000\001\217\003!\000\000\001\202\000\227\000\000\000\000\001\203\000\000\003)\000\000\000\000\000\000\002d\002\143\000\000\000\000\002\168\002\\\000\000\000\000\000h\000\000\000\000\000\000\000q\000\000\000\000\001\216\000\000\002f\000\227\000\000\002a\003W\000>\003X\002b\000\164\001D\003(\003<\001\217\000\000\000\000\003A\000\000\003N\001\232\000\000\000\000\003)\000\000\000\000\000\000\003\167\000\000\000\000\002[\000\000\000\000\000\000\002\145\000\000\000\000\000j\002\146\000\000\001\233\000\000\000k\000\227\002f\001\234\000l\000\000\003W\001\235\003\169\000\000\000>\000\000\001\236\003<\000\000\002\159\000\000\003A\000\000\003N\001\232\000\000\002\\\000\000\000\000\000\000\000\000\005+\000u\002\160\000\000\000\000\001\216\000\000\000\000\000\000\000\000\002a\000\000\000\000\001\233\002b\000\164\001D\003(\001\234\001\217\000\000\000\000\001\235\000\251\001\200\001\223\000\000\001\236\003)\000\000\000\000\000\000\0035\000\000\000\000\003\031\001Y\000\000\000>\000\000\000\000\000\000\002m\000\252\003 \000\000\002\187\000\000\000\253\002f\001S\000\000\000\254\0037\0038\000\000\002\143\000\255\000\000\002\168\003<\000\000\002\159\000\000\003A\002\230\003N\001\232\003!\000\000\001\202\002\190\002\195\000\000\001\203\000\000\002\160\000\000\000\000\000\164\000\165\000\000\000\000\000v\000\000\000>\002\204\001\233\000\000\000\000\000\000\000\000\001\234\000\000\000\000\000\000\001\235\002\232\001\200\001\223\002[\001\236\000\191\002\193\002\145\000\000\000\000\000w\002\146\003;\000\000\000\000\000>\000\000\000\000\000\000\002m\000\000\003 \000\000\000\000\000\000\000\000\000\000\000\164\001D\000\000\000\000\001.\000\000\000\174\000\000\000\000\000\150\000\000\000\000\000\000\001T\001Y\000\000\002\237\000\000\003!\000\000\001\202\000\000\002\195\000\000\001\203\000\000\000\000\000\000\001S\000\000\000y\000\000\000\000\000\000\000\151\002\\\002\196\000\000\000\152\000\000\000\000\001_\000\000\003/\000{\001\216\001\\\000\000\000\000\001]\002a\000\174\000\000\000\000\002b\000\164\001D\003(\000\000\001\217\000\000\002\187\000\000\000\000\001\200\001\223\000\000\000\000\003)\000\000\000\000\000\000\0035\000\000\000\000\000\000\000\000\002\159\000>\000\000\002\230\000\000\002m\000\000\003 \000\000\002\190\000\000\000\000\002f\000\000\002\160\000\000\0037\0038\000\000\000\000\000\000\000\000\000\000\003<\000\000\000\164\001D\003A\000\000\003N\001\232\003!\002\\\001\202\000\000\002\232\000\000\001\203\001T\000\000\000\000\002\193\001\216\001\200\001\221\000\000\000\000\002a\000\000\000\000\001\233\002b\000\164\001D\003(\001\234\001\217\000\000\000\000\001\235\000\000\001\200\001\223\000\000\001\236\003)\001_\000\000\003E\0035\000\000\001\\\000\000\000\000\001]\000>\000\174\000\000\002\235\002m\000\000\003 \000\000\000\000\002\195\000\000\002f\000j\000\000\001\202\0037\0038\000\000\001\203\000\000\000\000\000\000\003<\002\196\000\000\000\000\003A\000\000\003N\001\232\003!\000\000\001\202\000\000\000\000\000\000\001\203\000\000\000\000\000\000\000\000\000\000\001\200\001\223\000\000\000\000\000h\002\\\000\000\001\233\000s\000\000\000\000\000\000\001\234\000\000\000>\001\216\001\235\000\000\003\183\000\000\002a\001\236\000\000\000\000\002b\000\164\001D\003(\000\000\001\217\000\000\000\000\000\000\000\000\000\000\003y\000\000\004\n\003)\000\000\000\000\000\000\003r\000h\003\218\000\000\001\202\000}\000j\000\000\001\203\000\000\000\000\000k\000\000\000\000\000\000\000l\000\000\002f\000\000\000\000\000\000\0037\003t\000\000\003\224\000\000\000\000\000\000\003<\001\216\000\000\000\000\003A\000\000\003N\001\232\000\000\002\\\000\000\000u\000\000\000\000\000\000\001\217\000\000\000j\000\000\001\216\001\200\001\223\000k\000\000\002a\000\000\000l\001\233\002b\000\164\001D\003(\001\234\001\217\000>\000\000\001\235\000\000\002m\003q\003 \001\236\003)\000\000\000\000\000\000\003r\000h\000\000\000\000\000u\000}\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002f\003!\000\000\001\202\0037\003t\000\000\001\203\000\000\000\000\000\000\003<\001\216\000\000\000\000\003A\000\000\003N\001\232\000\000\001\233\000\000\000\164\001D\003\225\000\000\001\217\000\000\000j\000\000\000v\001\200\001\223\000k\001\246\003\226\000\000\000l\001\233\003\238\000\000\000\000\000\000\001\234\000\000\000>\000\000\001\235\000\000\002m\000\000\003 \001\236\000\000\000w\000\000\000h\000\000\000\000\000\000\000q\000u\000\000\000\000\000>\000\000\000\000\003\240\000\000\000v\000\000\003\245\000\000\003\252\001\232\003!\000\000\001\202\000\000\000\000\000x\001\203\000\000\000\000\000\000\000\000\000\000\000\000\000\210\000\000\000\233\000\000\002\\\000w\001\233\000\000\000\000\000\000\000\000\001\234\000j\000y\001\216\001\235\000\000\000k\000\235\002a\001\236\000l\000\000\002b\000\164\001D\003(\000{\001\217\001Y\000\000\000\146\000\000\003\133\000\000\000\000\000\000\003)\000\000\000\000\000\000\003\134\000h\001S\000j\000u\000q\000\212\000\000\000\000\000\000\000\213\000y\000\000\000\000\000v\000\000\000\000\002f\000\000\000\000\000\000\0037\003\136\000\000\000\000\000\128\000\000\000\000\003<\000\000\000\000\000\000\003A\000\000\003N\001\232\000\226\002\\\000w\000\000\000\000\000\000\000\000\000\000\000\000\000j\000\000\001\216\001\200\001\223\000k\000\000\002a\000\000\000l\001\233\002b\000\164\001D\003(\001\234\001\217\000>\000\000\001\235\000\000\002m\003\131\003 \001\236\003)\000\000\000\000\000\000\003r\000\000\000\164\001D\000u\000\000\000\000\000\000\000\000\000\000\000\000\000y\000v\000\000\000\000\001T\000\000\002f\003!\000\000\001\202\0037\003t\000\000\001\203\000\130\000\000\000\000\003<\000\000\000\000\000\149\003A\000\000\003N\001\232\000w\000\000\000\000\000\000\000\000\000\000\000\000\001_\000\227\003\196\000\000\000\000\001\\\000\000\000\000\001]\000\000\000\174\003\144\001\233\000\000\001\200\001\223\000\000\001\234\000\000\000\150\000\000\001\235\000\000\000\000\000\000\000\000\001\236\000\249\000>\000\000\000\000\000\000\002m\002\242\003 \000\000\000\000\000\000\000\000\000\000\000y\000\000\000\000\000v\000\151\001\200\001\223\000\000\000\152\000\000\000\251\000\000\000h\000\000\000{\005R\000}\000\000\003!\000>\001\202\000\000\002\183\002m\001\203\003 \002\\\000w\000\000\000\000\000\252\000\000\000\000\000\000\000\000\000\253\001\216\000\000\000\000\000\254\000\000\002a\000\000\000\000\000\255\002b\000\164\001D\003(\003!\001\217\001\202\000\000\000\150\003\149\001\203\000j\000\000\000\000\003)\000\000\000k\000\000\003\145\000\000\000l\000\000\000\000\000\000\000\000\000\210\000\000\000\233\000\000\000y\000\000\000\000\000\000\000\151\000\000\002f\000\000\000\152\000\000\0037\003\147\000\000\000\000\000{\000u\000\000\003<\000\000\001\200\001\223\003A\000\000\003N\001\232\000\000\000\000\000\000\000\000\005^\000\000\000\000\000\000\000>\000\000\002\\\000\000\002m\000\000\003 \000j\000\000\000\000\000\212\001\233\001\216\000\000\000\213\000\000\001\234\002a\000\000\000>\001\235\002b\000\164\001D\003(\001\236\001\217\000\000\000\000\000\000\003!\000\000\001\202\002\\\000\000\003)\001\203\000\000\000\000\003\145\000\226\000\000\000\000\001\216\000\000\000\000\000\000\000\000\002a\000\000\000\000\000\000\002b\000\164\001D\003(\002f\001\217\000\000\000\000\0037\003\147\000\000\000\000\000v\000\000\003)\003<\000\000\000\000\005S\003A\001Y\003N\001\232\000\000\000\000\000\000\000\000\000h\000\000\000\000\000\000\000s\000\000\000\000\001S\002f\000w\000\000\000\000\0037\005U\000\000\001\233\000\000\000\000\000\000\003<\001\234\001\200\001\223\003A\001\235\003N\001\232\000\000\000\000\001\236\000\000\005a\000\000\000\000\000\000\000>\000\000\000\000\000\000\002m\000\000\003 \002\\\000\227\000j\000\000\001\233\001\200\001\221\000k\000\000\001\234\001\216\000l\000\000\001\235\000y\002a\000\000\000\000\001\236\002b\000\164\001D\003(\003!\001\217\001\202\000\000\004*\000\132\001\203\000\000\000\000\000\000\003)\000\000\000u\000\000\005S\000\000\000\164\001D\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000j\000\251\001\202\001T\000\000\002f\001\203\000\000\000\000\0037\005U\000\000\000\000\000\000\000\000\000\000\003<\000\000\000\000\000\000\003A\000\252\003N\001\232\000\000\000\000\000\253\000\000\000\000\000\000\000\254\001_\000\000\003\232\000\000\000\255\001\\\000\000\000\000\001]\000\000\000\174\000\000\001\233\001\200\001\223\000\000\000\000\001\234\000\000\000\000\000h\001\235\000\000\000\000\000s\000\000\001\236\000>\000\000\000\000\000\000\003\183\000h\000\000\002\\\000\000\000q\000v\000\000\000\000\000\000\000\000\000\000\000\000\001\216\000\000\000>\000\000\000\000\002a\003\215\000\000\000\000\002b\000\164\001D\003(\003\218\001\217\001\202\000\000\000w\000\000\001\203\000j\000\000\000\000\003)\000\000\000k\001\216\005S\000\000\000l\000\000\000\000\000j\000\000\000\000\003\224\000\000\000k\000\000\000\000\001\217\000l\000\000\000x\002f\000\000\000\000\000\000\0037\005U\000\000\000\000\000\000\000u\000\000\003<\000h\001\200\001\223\003A\000}\003N\001\232\004\006\000y\000u\001\228\000\000\001 \000\237\000\000\000>\000\000\000\000\000\000\003\183\000\000\000\000\000{\000\000\000\000\000\000\001\233\000\000\000\000\000\000\000>\001\234\000\000\000\000\000\000\001\235\000\000\000\000\003\217\000\000\001\236\000\000\000\000\000\000\000j\003\218\000\000\001\202\000\000\000k\000\000\001\203\001\233\000l\000\000\000\210\000\000\000\231\001\216\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\248\003\224\000\164\001D\003\225\000\000\001\217\000\000\000\000\000\000\000\000\000u\000\000\000v\000\000\003\226\000\000\001Y\000\210\004\008\000\231\000\164\000\165\000\000\000h\000v\000\000\000\000\000q\000\000\000\000\001S\000\000\000j\000\000\000\000\000\212\000w\000>\000\000\000\213\000\168\000\169\000\171\000\172\000\000\000\000\003\240\000\000\000w\000\000\004\t\000\000\003\252\001\232\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000j\000x\000\000\000\212\000\226\000h\000j\000\213\000\173\000q\000\174\000k\001\233\000\150\000\000\000l\000\000\001\234\001\216\000>\000\000\001\235\000y\000\000\000\000\000\000\001\236\001\225\000\164\001D\003\225\000v\001\217\000\226\000y\000\000\000{\000\000\000\151\000u\000\000\003\226\000\152\000\164\001D\003\238\000\000\000\000\000{\000j\000\179\000\000\000\000\000\000\000k\000w\001T\000\000\000l\000h\000\000\000\000\000\000\000s\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\240\000\000\000\000\000\000\003\245\000\000\003\252\001\232\000h\000u\000\000\001[\000q\000\227\000\000\000\000\001\\\000\000\000\000\001]\000\000\000\174\000>\000\000\000\000\000\000\000\000\001\233\000\000\000y\000j\000\000\001\234\000\000\000\000\000k\001\235\000\000\000\000\000l\000\000\001\236\000\227\000\134\000\164\000\165\000\000\000\000\000v\000\000\000\000\000\000\000j\000\000\000\000\000\000\000\000\000k\000\000\000\000\000\000\000l\000\000\000u\000\168\000\217\000\171\000\172\000\000\000\000\000\000\000\000\000w\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\252\000\000\000\000\000u\000\000\000\164\000\165\000\000\000\000\000v\000\000\000\173\000\000\000\174\001\013\000\000\000\150\000\000\000h\000\000\001\200\001\221\000q\000\000\000\000\000\168\001\207\000\171\000\172\000\252\000h\000\000\000>\000w\000}\000\000\000\000\000y\000\000\000\000\000\000\000\151\000\000\001\015\000\000\000\152\000\000\000\000\000\000\000\000\000\000\000{\000\000\000\179\000\173\000\000\000\174\000\000\000\000\000\150\000\000\000h\000j\000v\000j\000q\001\202\000k\000\000\000\000\001\203\000l\000\000\000\000\000j\000>\001\200\001\221\000\000\000k\000y\000\164\000\165\000l\000\151\000v\000\000\000w\000\152\000\000\000\000\000\000\000\000\000\000\000{\000u\000\179\000\000\000\210\000\000\000\231\000\168\002^\000\171\000\172\000j\000\000\000u\000\000\000w\000k\000\000\000\000\000x\000l\000\000\000\000\000\000\000\000\000\000\000j\000\000\001\202\000\000\000\000\000\000\001\203\000\000\000\000\000\000\000\173\000\000\000\174\000\000\000y\000\150\000\000\000h\000u\001\227\000\000\000q\000j\000\000\000\000\000\212\000\000\000\000\000{\000\213\000\000\000>\000\000\000\000\000\000\000\000\000y\000\000\000\000\000\000\000\151\000\000\000\000\000\000\000\152\001\216\000\000\000\000\000\000\000\000\000{\000\000\000\179\000\164\000\165\000\226\000\000\000v\000\000\001\217\000\000\000j\000\000\000\000\000\000\000\000\000k\000\000\000\000\000v\000l\000\000\000\000\000\168\002\150\000\171\000\172\000\000\000\000\000\000\000\000\000w\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000w\000u\000\000\000\164\000\165\000\000\000\000\000v\001\216\000\173\000\000\000\174\000\000\000\000\000\150\000\000\000h\000\000\000\000\000\000\000q\000\000\001\217\000\168\003>\000\171\000\172\000\000\000h\000\000\000>\000w\000q\000\000\001\233\000y\000\000\000\000\000\000\000\151\000\000\000\000\000>\000\152\000\227\000\000\000\000\000y\001\250\000{\000\000\000\179\000\173\000\000\000\174\000\000\000\000\000\150\000\000\000\000\000j\000\136\000h\000\000\000\000\000k\000q\000\000\000\000\000l\000\000\000\000\000j\000\000\000\000\000\000\000\000\000k\000y\000\164\000\165\000l\000\151\000v\000\000\000\000\000\152\000\000\000\000\000\000\001\233\000\000\000{\000u\000\179\000\000\001\200\001\221\000\000\000\168\003\242\000\171\000\172\000\000\001\252\000u\000j\000w\000h\000\000\000\000\000k\000q\000\252\000\000\000l\000\000\000\000\000\000\000\000\000h\000\000\000>\000\000\000q\001\021\000\000\001\017\000\173\000\000\000\174\000\000\000\000\000\150\000>\000\000\000\000\000\000\000\000\000u\000j\000\000\001\202\000\000\000\000\000\000\001\203\000\000\000\000\000h\000\000\000\000\000j\000}\000y\000\000\000\000\000k\000\151\001\200\001\223\000l\000\152\000\000\000j\000\000\000\000\000\000\000{\000k\000\179\000\164\000\165\000l\000\000\000v\000\000\000\000\000\000\002T\003k\000\000\000\000\000\164\000\165\000u\000\000\000v\000\000\000\000\000\000\000\000\000\000\000j\000\194\000\000\000\000\000u\000k\000w\000h\000\000\000l\002[\000q\001\202\000\194\000\000\000\000\001\203\000\000\000w\000\000\000\000\000>\000\000\000\000\000\000\000\000\000\000\000\196\000v\000\174\000\000\000\000\000\150\000u\000\000\000\000\000\000\000\000\000\000\0014\000\000\000\174\000\000\000\000\000\150\000\000\000\000\000\149\001\216\000\000\000\000\000j\000w\000y\000\000\000\000\000k\000\151\000\000\000\000\000l\000\152\001\217\000\000\000\000\000y\000\000\000{\000\000\000\151\000\164\000\165\000\000\000\152\000v\000\000\000\000\000\000\000\150\000{\000\000\000\000\000\164\000\165\000u\000\000\000v\000\000\000\000\000\000\000\000\000\000\000\000\000\191\000\000\000\000\000\000\000\000\000w\000y\000\000\002\\\000\000\000\151\000\000\001\183\000\000\000\152\001\200\001\223\000w\001\216\000\000\000{\000\000\000v\002a\000\000\000\000\001:\002b\000\174\000\000\000\000\000\150\001\217\000\000\000\000\002T\003a\001\233\001\185\000\210\000\174\000\231\000\000\000\150\000\000\002d\000w\000\000\000\000\000\000\000\000\001\254\000y\000\000\000\000\000\000\000\151\000\000\000\000\002[\000\152\001\202\002f\000\000\000y\001\203\000{\000\000\000\151\000\164\000\165\000\000\000\152\000v\000\000\000\000\000\000\000\000\000{\000\000\001\232\001\200\001\223\000j\000\000\000\000\000\212\000\000\000\000\000\000\000\213\000\000\001\183\000y\000\000\000\000\000\000\000w\000\000\000\000\001\233\002T\002U\000\000\000\000\001\234\000\000\000\138\000\000\001\235\000\000\000\000\000\000\000\000\001\236\000\000\000\226\000\000\002\012\000\000\000\174\000\000\000\000\000\150\000h\002[\000h\001\202\000q\000\000\000}\001\203\000\000\000\000\000\000\000\000\000\000\000\000\000>\000\000\000\000\000\000\001\200\001\223\000y\000\000\000\000\000\000\000\151\000\000\002\\\000\000\000\152\000\000\000\000\000\000\000\000\000\000\000{\000\000\001\216\000\000\002T\002`\000\000\002a\000\000\000\000\000j\002b\000j\000\000\000\000\000k\001\217\000k\000\000\000l\000\000\000l\000h\000h\000\000\000\000\000}\000q\002[\002d\001\202\000\000\000\000\000\000\001\203\000\000\000\000\000>\000\000\000\000\000\227\000\000\000\000\000u\000\000\000u\002f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\\\000\210\000\000\000\231\000\000\000\000\001\232\000\000\000j\000j\001\216\000\000\000\000\000k\000k\002a\000\000\000l\000l\002b\000\000\000\000\000\000\000\000\001\217\000\000\001\233\000\000\000\000\000\000\000\210\001\234\000\233\000\000\000\000\001\235\000\000\002d\001\200\001\223\001\236\000u\000u\000\000\000\000\000j\000\000\000\000\000\212\000\000\000\000\000\252\000\213\000\000\002f\000\000\000\000\000\000\002T\003m\000\000\002\\\000\000\000\164\000\165\001\019\000\000\000v\000\000\000v\000\000\001\216\001\232\000\000\000j\000\000\002a\000\212\000\226\000\000\002b\000\213\002[\000\000\001\202\001\217\002\127\000\000\001\203\000\000\000\000\000w\001\233\000w\000\000\000\000\000\000\001\234\002d\000\000\000\000\001\235\000\000\000\000\000\000\000\000\001\236\000\226\000\000\000\000\000\000\000\000\002\129\000\000\000\174\002f\000\000\000\150\000\000\000\000\000\164\000\165\000\000\000v\000v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\232\000\000\000\000\001\200\001\223\000y\000\000\000y\000\000\000\151\002\127\000\000\000\000\000\152\000w\000w\000\000\000\000\000\000\000{\001\233\000\140\000\000\002T\0044\001\234\000\000\000\227\000\000\001\235\000\000\000\000\000\000\000\000\001\236\000\000\002\166\000\000\000\174\000\000\002\\\000\150\001\200\001\221\000\000\001\200\001\223\002[\000\000\001\202\001\216\000\000\000\000\001\203\000\000\002a\000\227\000\000\000\000\002b\000\000\000y\000y\000\000\001\217\003d\000\151\000\000\000\000\000\000\000\152\000\000\000\000\000\000\000\000\000\142\000{\002d\001\200\001\223\000\000\000\000\004,\000\000\000\000\000\000\000j\000\000\001\202\002[\000\000\001\202\001\203\000\000\002f\001\203\000\252\000\000\002T\0046\000\000\000\000\000\000\000\000\000\000\000\251\001\200\001\223\000\000\000\000\001\025\000h\001\232\000\000\000h\000q\000\000\000\000\000q\000\000\000\000\000\000\002[\000\000\001\202\000\252\002T\0048\001\203\000\000\000\253\000\000\001\233\000\000\000\254\000\000\000\000\001\234\002\\\000\255\000\000\001\235\000\000\000\000\000\000\000\000\001\236\000\000\001\216\000\000\002[\000\000\001\202\002a\000\000\000j\001\203\002b\000j\000\000\000k\000\000\001\217\000k\000l\000\000\000\000\000l\000\210\000\000\000\231\000\000\000\000\000\000\002\002\002d\000\000\0029\000h\000\000\002\\\000\000\000q\000\000\000\000\000\000\000\000\001\216\000u\000\000\001\216\000u\002f\000\000\000h\002a\000\000\000\000\000q\002b\000\000\001\217\000\000\000\000\001\217\000h\000\000\000\000\000\000\000q\001\232\000\000\000j\002\\\000\000\000\212\000\000\002d\000\000\000\213\000\000\000\000\000j\001\216\000\000\000\000\000\000\000k\002a\000\000\001\233\000l\002b\000\000\002f\001\234\000\000\001\217\000j\001\235\000\210\002\\\000\233\000k\001\236\000\226\000\000\000l\000\000\000j\002d\001\216\001\232\000\000\000k\000u\002a\002;\000l\000\000\002b\000\000\000h\000\000\000\000\001\217\000q\002f\002=\001\233\000v\000u\001\233\000v\000\000\000\000\002|\001\234\002d\000\000\000\000\001\235\000u\002\000\000j\001\232\001\236\000\212\000\000\000\149\000\000\000\213\000\149\000\000\000w\002f\000\000\000w\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\233\000j\000\000\000\000\000\000\001\234\000k\000\000\001\232\001\235\000l\000\210\000\226\000\233\001\236\000\150\000h\000\000\000\150\000\000\000q\000\000\000\227\000\000\000\000\000\000\000\000\000h\001\233\000\000\000\000\000q\000v\001\234\000u\000\000\000y\001\235\000\000\000y\000\151\000\000\001\236\000\151\000\152\000\000\000\000\000\152\000v\000\000\000{\001\"\000\000\000{\000\000\000j\000w\000\000\000\212\000v\000j\000\000\000\213\000\000\000\000\000k\000\000\000\149\000\000\000l\002\143\000j\000w\002\168\000\000\000\000\000k\000\000\000\149\000\000\000l\000\000\000\150\000w\000\000\000\000\000\000\000\000\000\226\000\000\000\000\000\252\000h\000u\000\227\000\000\000q\000\000\000\150\000\000\000\000\000\000\000\000\000y\000u\001\027\002\181\000\151\000\000\000\150\000\000\000\152\000\000\000\000\000j\000\000\000v\000{\002\145\000y\004.\000\000\002\146\000\151\000\000\000\000\000\000\000\152\000\000\000\000\000y\000\000\000\000\000{\000\151\002\183\000j\000\000\000\152\000\000\000w\000k\000\000\000\251\000{\000l\000\000\000\000\000\000\000h\000\000\000\000\000\000\000q\000\000\000\000\000\000\000\000\000\000\000\000\000h\000\000\000\000\000\252\000q\003\003\000\150\000\000\000\253\000u\000\227\000\000\000\254\000\000\000\000\000v\003\015\000\255\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000v\000y\000\000\000\000\000\000\000\151\000\000\000j\002\183\000\152\004>\000\000\000k\000w\000\000\000{\000l\000h\000j\002\183\000\000\000q\000\000\000k\000w\000\000\000\000\000l\000h\002\159\000\000\000\000\000q\000\251\000\000\000\000\000\000\000\000\000\000\000\150\000u\000\000\000\000\002\160\000h\000\000\000\000\000\000\000}\000\000\000\150\000u\000\000\000\252\000\000\003\023\000\000\000\000\000\253\000\000\000y\000j\000\254\000\000\000\151\000v\000k\000\255\000\152\000\000\000l\000y\000j\000\000\000{\000\151\000h\000k\000\000\000\152\000q\000l\000\000\000\000\002\183\000{\000\000\000\000\000j\000w\000\000\000\000\000\000\000k\000u\000\000\000\000\000l\000h\000\000\000\000\000\000\000q\000\000\000\000\000u\000\000\000\000\000\000\000\000\000\000\005%\003$\002\195\000h\000\150\000\000\000\000\000q\000\000\000j\000u\000v\0033\000\000\000k\000\000\002\206\000\000\000l\000\000\000\000\000\000\000v\000\000\000\000\000y\000\210\000\000\000\231\000\151\002\183\000j\000\000\000\152\000\000\000w\000k\000\000\000\000\000{\000l\002\183\000u\000\000\000\000\000\000\000w\000j\000\000\000\000\000\000\000\000\000k\000\000\000\000\003J\000l\000\000\000\000\000\000\002\143\000\150\000\000\002\168\000u\000v\003R\000\000\000\000\000\000\000j\000\000\000\150\000\212\000\000\000\000\000v\000\213\000\000\000h\000u\000h\000y\000q\002\183\000q\000\151\000\000\000\000\000w\000\152\000\000\000v\000y\000\000\002\183\000{\000\151\000\000\000\000\000w\000\152\000\000\000\226\000j\000\000\000\000\000{\002\145\000\000\000\000\000\000\002\146\000\000\003\188\000\150\000w\000\000\000\000\000\000\000\000\000\000\000\000\000j\000v\000j\000\150\000h\000k\000\000\000k\000q\000l\000\000\000l\000\000\000y\000\000\000h\000\000\000\151\000\000\000q\002\183\000\152\000\000\000v\000y\000w\000h\000{\000\151\003\200\000q\000\000\000\152\000u\000\000\000u\000\000\000\000\000{\000v\000y\000\000\0052\000\000\000\000\000\000\000\000\000w\000j\000\000\000\000\000\150\000\000\000k\000\144\000\000\000\000\000l\002\183\000j\000\000\000\000\000\227\000w\000k\000\000\000\000\000\000\000l\000\000\000j\000\000\000y\000\150\000\000\000k\000\151\000\000\000\000\000l\000\152\000u\002\159\000\000\000h\000\000\000{\000\000\000q\000\150\000\000\000h\000u\000\000\000y\000q\002\160\000\000\000\151\000\000\000\000\000\000\000\152\000u\005\151\003\206\000\000\003\213\000{\000\000\000y\000\000\000\000\000\000\000\151\000v\000\000\000v\000\152\000\000\000\000\000\000\000\000\000\000\000{\000\000\000\000\000\000\000j\000\000\000\000\000\252\000\000\000k\002\183\000j\002\183\000l\000\000\000w\000k\000w\000\000\000\000\000l\001\029\000\000\002\143\000\000\000\000\002\168\000\000\000\000\003\222\000\000\000\000\000\000\001\200\001\221\000\000\000\000\000u\000\000\000v\003\236\000\150\002\195\000\150\000u\000\000\000\000\000\000\001\200\001\221\000v\003\250\000\000\000h\000\000\000\000\002\208\000q\002\183\000\000\000\000\000v\000y\000w\000y\000\000\000\151\000j\000\151\002\183\000\152\002\145\000\152\000\000\000w\002\146\000{\000j\000{\001\202\002\183\000\000\000\000\001\203\000\000\000w\000\000\000\000\000\000\000\150\000\000\000\000\000j\000\000\001\202\000h\000\000\000j\001\203\000q\000\150\000\000\000k\000\000\000\000\000\000\000l\000\000\000\000\004\001\000y\000\150\000h\000\000\000\151\000\000\000q\000\000\000\152\000v\000\000\000y\000\000\000\000\000{\000\151\000v\000\000\000\000\000\152\000u\000\000\000y\000\000\000\000\000{\000\151\000\000\002\183\000j\000\152\001\200\001\221\000w\000k\0052\000{\000\000\000l\000\000\000w\000\000\000\000\000\000\000\000\000\210\000j\000\233\000\000\000\000\000\000\000k\000\000\000\000\000\000\000l\000\000\000\000\002\159\000\150\000\000\000h\000u\000\000\000\000\000q\000\150\002\143\001\216\000\000\002\168\000\000\002\160\000\000\000h\000j\000\000\001\202\000q\000u\000y\001\203\001\217\001\216\000\151\000\000\000\000\000y\000\152\000j\000\000\000\151\000\212\000\000\000{\000\152\000\213\001\217\000\000\000\000\000\000\000{\000v\000\000\000\000\000j\000\000\000\000\000\000\000\000\000k\000j\000\000\000\000\000l\002\145\000\000\000\000\000j\002\146\000\000\000\183\000\226\000k\000\000\000\000\000w\000l\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000u\000h\000\000\000\000\002\195\000q\000v\000\000\000\000\000\000\000\000\000\000\001\233\000u\000\150\000\000\000h\000\000\002\210\000\000\000q\000\000\000\000\000v\000\000\000\220\002\006\001\233\000\000\000\000\000w\000\000\000\000\000\000\000\000\000y\000\000\000\000\001\216\000\151\000\000\002\008\000\245\000\152\000\000\000j\000\000\000w\000\000\000{\000k\000\000\001\217\000\000\000l\000\000\000\150\000\000\000\000\000\000\000j\000\000\000\000\000\000\000\000\000k\000\227\000\000\000\000\000l\000\000\000\000\000\000\000\150\002\159\000\000\000\000\000y\000u\000\000\000\000\000\151\000v\000\000\000\000\000\152\000\000\000\000\002\160\000\000\000\000\000{\004M\000u\000y\000v\000\000\000\000\000\151\000h\000\000\001$\000\152\000q\000\000\000\000\000w\002\143\000{\000\000\002\168\000\000\000\000\000\000\001\170\000\251\000\000\000\000\000\000\000w\001\233\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000h\000\000\000\000\000\150\000q\002\n\000\252\000\000\000\000\000\000\000\000\000\253\000\000\000h\000j\000\254\000\150\000q\000\000\000k\000\255\000\000\000j\000l\000y\000\000\002\145\000\000\000\151\002\195\002\146\000v\000\152\000\000\000\000\000\000\002\143\000y\000{\002\168\000\000\000\151\000\000\002\212\000j\000\152\000v\000u\000\000\000k\001\174\000{\000\000\000l\000\000\000w\000\000\000j\000\000\000h\000\000\000\000\000k\000q\000\000\001\210\000l\000\000\000\000\000h\000w\000\000\000\000\000}\000\000\000\000\000\000\000u\000\000\000\000\000j\000\150\000\000\000\000\002\145\000\000\000\000\000\000\002\146\000h\000u\000h\000\000\000q\000\000\000q\000\150\000\000\000\000\000\000\000\000\000\000\000y\000j\000\000\000\000\000\151\000h\000k\000\000\000\152\000q\000l\000j\000\000\000\000\000{\000y\000k\000\000\000\000\000\151\000l\002\159\000\000\000\152\000\000\000\000\000\000\000v\000\000\000{\000\000\000j\000\000\000j\000u\002\160\000k\000\000\000k\000\000\000l\000\000\000l\000\000\000u\000\000\002\017\002\143\000\000\000j\002\168\000w\000\000\000\000\000k\000\000\000\000\000v\000l\000\000\000\000\000\000\000\000\000\000\000u\000\000\000u\000\000\000\000\000\000\000v\000\000\000\000\000\000\000\000\000\000\002\022\000\150\000\000\002\159\000\000\000w\000u\000\000\000\000\000\000\000\000\000\000\000\000\002\026\000\000\000j\000\000\002\160\000w\002\145\000\000\000\000\000y\002\146\000\000\000\000\000\151\000\000\000\000\002\195\000\152\000\150\002\143\000h\000\000\002\168\000{\000q\000\000\000\000\000v\000\000\000\000\002\214\000\150\000\000\000\000\000\000\000\000\000h\000v\000h\000y\000q\000\000\000q\000\151\000\000\000\000\0021\000\152\000\000\000\000\000\000\000w\000y\000{\000\000\000\000\000\151\000v\000\000\000v\000\152\000w\000\000\000j\000j\000\000\000{\002\145\000\000\000k\000\000\002\146\000\000\000l\002\195\000v\002X\000\150\002\153\000\000\000j\000w\000j\000w\000\000\000k\000\000\000k\002\216\000l\000\000\000l\000\000\000\000\002\171\000\000\000h\000u\000y\000w\000}\000\000\000\151\002\159\000\000\000\000\000\152\000\150\000y\000\150\000\000\000\000\000{\000u\000h\000u\000\000\002\160\000}\000\000\000\000\000\000\000\154\000\000\002\143\000\150\000\000\002\168\000y\000\000\000y\000\000\000\151\000\000\000\151\000\000\000\152\000\000\000\152\000\000\000j\000\000\000{\000\000\000{\000k\000y\000\000\000\000\000l\000\151\000\000\000\000\000\000\000\152\000\000\000\000\000\000\000j\000\000\000{\000\000\000\000\000k\002\159\000\000\000\000\000l\000j\000\000\000\000\000\000\002\145\000u\000\000\000\000\002\146\000\000\002\160\000v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\195\000\000\000\000\000\000\000u\000\000\000\000\000\000\000v\000\000\000v\002\173\000\000\000\000\002\218\000\000\000w\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\176\000\000\004\024\000\000\000\000\000w\000\000\000w\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\150\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\150\000\000\000\150\002\195\000\000\000y\000\000\000\000\000\000\000\151\000v\000\000\000\000\000\152\000\000\000\000\000\000\002\220\000\000\000{\000\000\000y\000\000\000y\002\159\000\151\000\000\000\151\000v\000\152\000\000\000\152\000\000\000\000\000w\000{\000\000\000{\002\160\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000w\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000\000\000\156\000\000\000\000\000\000\000y\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\195\000\000\000\000\000\000\000\000\000\158\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\222"))
+    ((16, "\001\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\011\000\000\000\223\012\200\000\000\000\167\000_\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\025\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003`\000\000\006\204\000\167\000_\000\000\000\000\000\000\000\000\000\000\017l\000$\008t\000\000\000\000\000\000\005\014\000\000\001\138\000\233\023\246\000\000\000\000\000\027\000\000\nH\000\000\007\178\019V\004\254\027\196\004\254\017\030)N\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\013^\027\196\000\000\000\000\013\128\000\000\014p\000\000\005\000\000\000\000\000\000\000\000\000\000\246\000\000$\198\000\000\000\000\008T\000\000\t\202\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000v\000\000\031.\000\000\031\194\000\000\"6\000\000%N\000\000'\192\000\000*X\000\000,f\000\000,\210\000\0002R\000\000 R\000\000\007\012\000\000\000\000\000\000\000\000\000\0008B\000\0009\246\000\000:\026\000\000\016\018\000\000\000\000\017r\000\000\000\000\000\211\000\173\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0009\000\164\000\000\000\136\000\000\000\000\002\236\000\00050\000\000\000\000\000\000\000\254\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\140\000\000\000\000\000\000\000\000\000\000\000\000\012\234)N\000\000\021\156\000\000\026d\026\154\000\000\000\000\000\000\0010\000\000&\002\000\000\000\0005\132\000\000\000\000\000\000\002\152\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\030\224\000\000#\146\000\000\000\000\000\000\000\000\000\012\000\000\000\0005\166\000\000\000\000\000\000 \146\002\182\000\000\000\000\000\000\000\000\000\000\000\000\n\002\000\000\018\232\000\000\022\174\000\000\023\216\000\000\024\238\000\000%\188\000\000%\246\000\000(H\000\000+\184\000\000-\028\000\000)\170\000\000\000\n\000\000/t\000\0003\012\000\0004X\000\000\000\000\000\000\000\000\000\000\000D6\028\000\000\002*\000\000\000\000\000-\016\238\000\000\002\158\000\000\000\000\000\000\005\180\000\000\000\000\000\000)f\000\000\000\000\000\000\000\000\000\000*\006\000\000\000\000\000\000\000\000\000\000\000\000\000\140\000\000\000\000\000\000\000\150\000\000\000\000\000\000\0026\000\000\000\000\011.\000\167\000\000\000\000\001\005\013F\000\000\000\000\000\000\000\000\000\000\004H\000\000\011r\000\000%n\000\000\000\000\004\178\000\000\000\000\000\000\000\000\000\000\000\000\012z\000\000\000\000\000\000\000\245\000\000\000\000\000\000\000\000\003B\015\204\000\000\002\138\000\000\000\000\001|\002\226\000\000\000\000\000\000\000\000\t\026\000\000\000\000\000\000\000\000\000\000\000\000\000'\0218\000\000\022\170\000\000\000\000\000\000\001\006\000\000\013\244\001~\000\000\016$\000\000\000\000\000\000\000\232\001\168\000\000\000\000\000\000\011>\000\000\000\000\001\206\000\000\000\242\000\000\000\000\000\000\000\000\001@\002\182\000\000\002D\000\000\000\000\000\000\000\000\000\000\000\00066\000\000\001(\000\0006\184\000\000\000\000\0024\000\000\008N\000\000\005\158\004V*\030\000\000\000\000\000\000\006\"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\015f*\030\000\000\015\240\000\000\021\204\019\150\000\000\000\000\000\000\004\224\000\000&X\000\000\000\0006\214\000\000\000\000\000\000\004\228\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000$\174\000\000&\196\000\000\000\000\000\000\004 \000\000\000\000\000\000\000\000\000\000\000\000\002\192\000\000\007j\000\000\014\030\000\000\0178\000\000\023\250\000\000\030D\000\000#\240\000\000'\172\000\000(\028\000\000)\238\000\000/\002\000\000\012\242\000\000.x\000\0005\008\000\0005&\000\000*\190\000\000\000\000\000\0007|\000\000\000\000\000\000\000\011\000\0007\184\000\000\000\000\000\0007\210\000\000\000\000\0000\000\000\026\176\000!\000\196\000\000\002\156\000\000\014\254\002l\tX\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0008.\000\000*l\000x\005T\000\000\000\000\000\000/\008\000\000/\168\000\000/\190\000\000+\136,\012\000z\001\003\005X\000\000\000\000\000\000\000\183\000\000\000\000\001\246\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\0008j\000\000\000\000\000\000\000\000\000\000&\240\000\000,\134\000\000\000\000\000\000\000\000\000\000\000\000\015|\000\000\003\136\000\000\000\000\000\000\000\000\t\252\001\250\000\000\016\162\000\000\000\000\000\000\000W\000\000\000\000 \230\006\152\000\000\003`/\136\000\000\000\000,b\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\013|,b\000\000\018j\000\000\019\158\002t,\212\000\000\n\\\000\000\000\000\000\000\006\000\000\000'\168\000\000\000\0008n\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\0008\142\000\0009^\000\000\000\000\000\000\022\028\000\000\000\00000\000\000\000\000\000\000\000\000\0062\000\000\000\000\000\000\005\226\000\000\000\000\007\174\000\000\002v\000\000\000\000\000\000\000R\000\000\007\216\000\000\020\134\000\000\027\"\000\0001\018\000\0003P\000\0004\244\000\0006(\000\0007\140\000\0008\000\000\0008\226\000\0009\\\000\000:.\000\000\000\000\000\000\000\000\000\000\000\228\000\000\013\012\000\000\027\182\002\222\000\000\028\204\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004v\000\000\000\000\000\000\000\000\000\000\000\000\003\158\000\000\000\000\022\138\000\000\000\000\000\0000\166\000\000\000\000\008\130\000\000\000\000\000\000\025T\000\000\000\000\000\000\000\0000\188\000\000\000\000\000\000\000\000\002\n\006\002\000\0001>\000\000\000\000\000\000\000\000\027D\003\210\000\000\028\140\000\000\000\000\006j\000\0001\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\252\000\000\000\000\028\030\000\000\000\000\000\0001\198\000\000\000\000\005\180\000\000\000\000\014\192\000\000\029 \000\000\000\000'\254\000\000\000\000\000\000\015<\000\000\000\000\028\234\000\000\000\000\000\000\000\0002\028\000\000\000\000\000\000\000\000\003<\008d\000\00022\000\000\000\000\000\000\000\000\000\000\000\000\016\200\000\000\000\000\006D\000\000\017F\000\000\015<\000\000\000\000\004>.~\000\000\005&\000\000\000\000\000\000\000\000\004 \000\000-f\000\000\029\212\001\182\030h\000\000\005\002\000\000\017\236\000\000\018\146\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005\136\031\140\005\014  \000\000\000\000\000\000\006>\000\000\019\016\000\000\005\218\000\000\000\000\015z\001\222!D\000\000\006\188\000\000\019\220!\234\000\000\000\000\020Z\000\000\000\000\000\000\000\000\000\000\000\000\000\000\007\002\t\214\000\000\007\200\000\000\000\000\000\000\000\000\007r\000\000\021&\000\000\000\000\000\000\030\2169~\000\000\000\000\000\000$\160\000\000\000\000\000\000\000\000\n*\005`\000\000\000\0002\146\000\000\000\000\000\000\000\000\005h\000\000\000\000 F\000\000\000\000\000\0002\222\000\000\000\000\002.\000\000\000\0003v\000\000\000\000\004\018\005z\000\000\000\0003z\000\000\000\000\008@%P\000\000\006\166\000\000\000\0003\214\000\000\000\000\000\000\000\000\000\000\000\000\007\202\000\000\000\000\"\254\000\000\000\000\000\0003\236\000\000\000\000\000\000\000\000\000\000(\150\000\000\000\000\000\000\000-\000\000\000\000\000\0004\002\000\000\000\000\004&\008p\000\000\000\0004v\000\000\000\000\008Z\000\000\000\000\000\000\000\000\004 \000-\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\148\000\000\021d\000\000\000\000\000\0009\130\000\000\n\162\000\000\000\000\000\000\006p\000\000\000\000\003J\021\226\000\000\023.\000\000\000\000\000\000\003\148\000\000\"\170\007\004-V\000\0000\004\000\000\000\000\000\000\007L\000\000.*\007x.\192\000\000.\248\000\000\000\000\000\000\007\164\000\0000\156\007\232\000\000\000\000\001f\006j\007\252\014\026\000\000\015\164\000\000\000\000\000\000\007\254\000\0005\252\008\024\000\000\000\000\000\000\002l\000\000\000\000\000\000\000\000\000\000\003.\000\000\000\000\003^\000\000\000\022\000\000\000\000\000\000\003\156\000\000\000\000\000\000\000\000\000\000\000C\000\000\008\184\003\192\001B\000\000\000\000\004\214\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\246\000?\000\000\000\000\000\003\000\000\000\000\000\000\004\198\000\000\000\000\006~\008H\000\000\000\000\000\000\000\000\017p\019D\004\234\000\000\022\016\000\000\000\000\000\000\000\000\000\000\000\000\003.\000\000\000\000\004\180\000\000\000\000\003\170\000\000\000\000\003|\000\000\000\000\003\222\000\000\t\012\004d\002z\000\000\000\000\008\240\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\n\252\022\140\000\000\000\000\000\000\000\000\023\024\000\000\000\000\011:\000\000\000\000\015\026\000\000\000\000\000\000\023@\000\000\000\000\0009\023`\005\136\000\000\024L\000\000\000\000\000\000\000\000\000\000\000\000\005\154\000\000\t\012\007\250\000\142\000\000\000\000\000\000\000\000\002`\000\000\000\000\000\000\000\000\000\000\000\000\008\008\000\000\000\000\004\024\000\000\t,\006X\003\144\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\012\200\000\000\000\000\019(\024V\000\000\000\000\000\000\000\000\002T\000\000\003\156\000\000\0208\000\000\000\000\000\000\000\000\000\000\000\000\000\011\020\164\000\000\000\000\021\128\000\000\000\000\000\000\000\000\000B\000\000\021\254\000\000\000\000\000\000\000\000\004\190\000\000\000\000\000\000\000\155\000\000\000\000\000Y\000\000\000\000\000\000\000\000\000\000\000\000\000\0002\190\007\228\000\000\000\000\000\000\001\006\000\000\000\000\026\234\000\000\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\n\156\000\167\013\028\019\030\005\210\000\000\000\000\0030\006\188\008\148\t\"\000\000\000\000\000\000\000\000\000\000\000\000\004\170\023\172\000\000\"(\008\008\000\000\000\000\t<\000\000\024x\000\000\025n\000\000\000\000\005\024\024\182\000\000\"\216\000\000\007.#\188\000\000\000\000\000\000\018\020\0030\000\000\008r\000\000\000\000\000\000\008\230\000\000\011\000\000\000\008.\006\170\000\000\000\000\000\000\000\000\004H\000\000\004\178\000\000\008\180\000\000\000\000\020\130\000\000\000\000\000\000\000\000\011 \000\000\000\000\0030\t\246\000\000\026\\\000\000\015<\006`\000\000\000\000\000\000\000\000\000\000\004\174\000\000\000\000\000\000\000\000\000\0004\132\008\140\000\000\003\164\000\000\000\000\000\000\000\000\000\000\001\216\000\000\011\238\t\200\012l\000\000\003\180\013v\000\000\t\228\000\000\0048\000\000\005\128\000\000\006\004\000\000\000\000\000\000\000\000\000\000\008\232\000\000\007L\000\000\n\002\000\000\007\208\000\000\015<\006\206\000\000\006(\000\000\006\240\006\004\000\000\006\156\000\000\008\248\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\008\250\000\000\t`\000\000\000\000\000\000\000\000\000\000\0064\000\000\000\000\006z\008\148\007\224\000\000\008\018\000\000\000\000\003\222\n\020\000\000\007j\000\000\000\000\000\000\000\000\008\188\000\000\000\000\000\000\000\000\000\000\000\000\008\190\008\192\t\146\t.\008\230\t.\000\000\000\000\008\224\t\164\t^\t\030\t^\000\000\000\000\006L\000\000\000\000\000\000\000\000\n0\000\000\000\000"), (16, "\001\200\001\223\000>\000h\002u\004g\000\017\001<\002!\002\"\000\n\004|\000\005\004\206\000>\002E\001g\000*\002m\003n\003V\000\210\004e\000\211\001i\000>\004h\004t\004}\004t\004\207\004\210\004t\001?\004\225\000\t\000\008\000\t\003\007\005\026\005\027\004\127\000\016\004P\003!\000\166\001\202\000j\000*\004d\001\203\004\226\000k\002G\004\229\004t\000l\002\143\004}\004t\002\147\004\224\005\031\005 \0008\000j\004e\0009\000\212\002F\004h\004t\000\213\004\013\004\206\000h\001\200\001\223\000*\000i\000u\001+\005$\0055\005\006\004u\0056\004u\001\200\001\223\004u\004\207\004\210\004t\005b\003\157\003b\001\228\000\226\001 \005c\000j\000>\0008\005:\002\148\005d\002F\003 \002\149\001h\002!\002\"\004u\005\t\001-\004\214\004u\001h\000j\002[\000*\001\202\001\133\000k\004\019\001\203\000F\000l\004u\002\143\004\215\003!\002\147\001\202\002\\\001%\000\247\001\203\001@\001\135\0053\001\156\000\163\000\176\001\216\000>\000\210\000F\000\233\002a\004u\000u\003C\002b\000\163\001D\003(\000+\001\217\003\159\003|\000v\0053\001\200\001\223\000\163\000\164\003)\003h\001'\000\175\003j\001\228\002[\002v\005f\005*\002\148\004W\000\227\001\158\002\149\000*\002T\004\031\000w\000*\001x\002f\000>\000j\002\247\003W\000\212\003v\003\247\005g\000\213\004\128\003<\004\239\002\162\000\248\003\141\004k\003N\001\232\002[\000>\001\202\002\\\000*\002m\001\203\005\001\002\163\000\173\000\177\001A\000>\001\216\005\012\002\\\000\226\001E\002a\001\233\002$\001\023\002b\002H\001\234\001\216\000v\001\217\001\235\004v\002a\004B\004\216\001\236\002b\000\163\001D\003(\005i\001\217\003j\000\252\001t\000j\001\200\001\223\003p\005j\005\132\000*\000w\002\187\005\133\004\014\005\019\000\255\005\160\002f\000>\002K\002L\002N\005d\005\161\003 \001\136\003\143\002\162\002\228\002f\002\226\004l\000\017\0037\005\135\001\232\002\190\004\016\002\195\001\152\003<\002\163\001\135\000>\005\137\000n\003N\001\232\003!\000\186\001\202\002\\\002\198\001\146\001\203\001\233\004\219\000y\000\227\005\179\001\234\001\216\002\229\000*\001\235\000j\002a\001\233\002\193\001\236\002b\000}\001\234\003\020\000\215\001\217\001\235\001@\001\200\001\223\000>\001\236\002\143\001\162\005+\002\147\003\153\001\154\002d\004\225\001\159\003\007\000>\0009\000\017\000*\002m\003n\003V\002!\002\"\004\218\000\163\001D\003(\002f\004\226\000\251\005\180\004\229\004t\002\195\004\167\000\163\000\176\003)\004\215\005.\001\139\000F\001\200\001\201\003!\001\232\001\202\002\196\000j\000\252\001\203\004\168\002\148\001%\000\253\001\153\002\149\002\143\000\254\000*\002\147\002\\\004C\000\255\000h\001\233\000*\004o\000q\003<\001\234\001\216\003x\003A\001\235\003N\002a\0009\000>\001\236\002b\000\163\001D\003(\005\182\001\217\000j\001&\001\202\001B\004u\004\254\001\203\005j\005\132\002H\003}\001\228\005\184\001 \004U\002[\002o\000*\004\027\002\148\000\163\000\176\000j\002\149\001\161\000>\001+\000k\001\163\002f\005E\000l\000>\0037\005\186\000>\002\143\000F\001n\002\169\003<\000F\003\008\004\151\005\188\002J\003N\001\232\002\194\002\\\000>\004V\002#\002!\002\"\000u\004z\000\163\000\164\001\216\001,\004\216\003O\002\162\002a\000E\000\250\001\233\002b\000\163\001D\003(\001\234\001\217\004\160\003\127\001\235\002\163\001\200\001\223\000j\001\236\003)\000F\002\148\003\203\003j\004\167\002\149\001I\000\224\004\161\000>\004\164\004t\004\018\005d\005\166\003V\004\\\002\187\001\216\003\029\002f\004\168\002\193\005\001\003W\000\173\003v\004a\000*\003\030\005\002\003<\001\217\002\162\004\029\003\141\002\233\003N\001\232\003!\004\163\001\202\002\190\005\154\000F\001\203\005\155\002\163\001q\000\248\000\163\000\164\001 \004\171\000v\005\176\000>\004\161\001\233\004\164\004t\001\200\001\223\001\234\002\165\004%\000>\001\235\004\228\004u\000\180\004W\001\236\000\171\002\193\000>\001\200\001\223\000w\005d\005\166\003V\004'\000\163\000\164\004\226\003\209\002i\004\229\004t\000\163\000\176\001u\000\163\001D\005I\003\253\005\159\002\162\000\172\001\233\000\173\004(\004q\000\149\003!\001F\001\202\000\163\000\164\002\236\001\203\002\163\000*\001\238\002!\002\"\002\195\004u\004'\000j\005\171\001\202\002\245\004\157\000y\001\203\004\173\005\228\000\150\002\\\002\196\004\152\000\151\000\173\001%\000*\000>\000F\000{\001\216\000\178\001p\001w\001s\002a\003e\004u\004\155\002b\000\163\001D\003(\005\172\001\217\004\154\0053\001(\004|\000\173\000h\000h\005j\005\132\000q\000i\000*\002d\004n\001\231\002!\002\"\005\022\001\228\000>\004}\004t\005\145\005\146\004\176\003g\003p\000>\000D\002f\000C\002\252\003\130\003W\000*\005\174\000*\004\232\004\142\004t\003<\002\\\000\163\000\176\003A\005\237\003N\001\232\000*\000j\000j\001\216\000\163\000\176\000k\000k\002a\000E\000l\000l\002b\000\163\001D\003(\005\172\001\217\001\216\001\233\001b\004\016\001\200\001\223\001\234\005j\005\132\005\150\001\235\005M\002d\004u\001\217\001\236\000u\000u\000>\001\200\002\014\004l\005d\005\166\003V\000F\000*\001\230\000*\002f\000h\004u\000*\003W\000i\005\174\000*\001\030\001 \0036\003<\003e\004\209\005\024\003A\000*\003N\001\232\003!\003\030\001\202\004\200\004t\002\143\001\203\001^\002\147\000\163\000\164\004\207\004\210\004t\001\232\000j\005\173\001\202\005[\001\233\0053\001\203\001\200\001\223\001\234\002\246\000j\003f\001\235\000>\001\205\000k\001\214\001\236\001\233\000l\000>\001\200\001\201\001\234\005d\005\166\003V\001\235\000F\003\138\000\163\000\164\001\236\002[\000v\000v\002u\002\148\000\163\001D\003s\002\149\004\152\000u\000\173\003\132\004u\003\\\000*\000*\003!\001F\001\202\001\"\003\130\004u\001\203\003\030\000w\000w\005\239\004\131\001m\003\140\005\004\000j\005\175\001\202\005\240\000*\003\138\001\203\0025\000*\002D\002\\\003,\006\000\000F\001(\002\143\000\173\000F\002\147\000\149\001\216\006\001\001p\002u\001s\002a\000F\004\234\004|\002b\000\163\001D\003(\005\172\001\217\001\216\000*\005\014\000>\003\139\000y\000\188\005j\005\132\000\150\004}\004t\002d\000\151\001\217\005@\005E\003\143\002\187\000{\000>\000@\001~\000C\002[\000v\003\185\005\143\002\148\002f\003\193\000*\002\149\003W\002\162\005\174\005\205\002\189\000h\003\210\003<\002\\\000i\002\190\003A\005\190\003N\001\232\002\163\000w\000E\001\216\002!\002\"\000\163\000\164\002a\005r\002\151\000F\002b\000\163\001D\003(\005\172\001\217\001\216\001\233\005\194\004u\001\200\001\223\001\234\005j\005\132\002\193\001\235\003\146\002d\002\160\001\217\001\236\000j\002\185\000>\001\200\001\201\000k\005d\005\166\003V\000l\004\030\005\213\005\248\002f\0010\003\135\003\168\003W\005\218\005\174\000\210\005\001\000\211\000\173\003<\003\021\003\030\002\187\003A\000F\003N\001\232\003!\000u\001\202\003\162\002\195\002\143\001\203\000\210\002\147\0016\003\025\002\162\002\223\002\240\002\226\000j\005\183\001\202\002\196\001\233\002\190\001\203\001\200\001\223\001\234\002\163\002\143\000F\001\235\002\147\000\163\001D\000j\001\236\001\222\000\212\000>\003\164\005\219\000\213\005d\005\166\003V\005s\004/\003\"\002\229\000\163\001D\002[\005H\000j\002\193\002\148\000\212\005`\005\212\002\149\000\213\005Q\001F\0041\003&\000*\005\224\000\226\003!\004\137\001\202\003\030\000j\001m\001\203\004\225\002\148\003\219\005v\004\029\002\149\005w\0042\000\173\005\187\000v\000\226\001\200\001\223\004\215\000h\005\223\004\226\002\\\000s\004\229\004t\002\195\001p\0041\001s\000>\0049\001\216\003\162\002m\003n\003V\002a\000w\004|\002\196\002b\000\163\001D\003(\005\172\001\217\001\216\004;\000>\000@\000A\000C\004<\005j\005\132\004}\004t\002u\002d\003!\001\217\001\202\000j\000\147\002\187\001\203\003\163\000k\005E\004;\000*\000l\002u\0050\005\233\002f\000*\000\227\000E\003W\002\162\005\174\004u\002\192\000y\003\007\003<\002\\\004?\002\190\003A\004\003\003N\001\232\002\163\000u\000\227\001\216\000{\004H\004K\002\162\002a\000F\004\003\0041\002b\000\163\001D\003(\005\172\001\217\004N\001\233\004u\002\163\004J\004J\001\234\005j\005\132\002\193\001\235\004\170\002d\004\005\004\221\001\236\001\233\0041\005x\000>\000@\001z\000C\000j\0051\004r\004\004\005E\004\168\002f\001\240\005T\005h\003W\000\232\005\174\001\200\001\223\002\\\003\229\003<\003\030\005\205\005\205\003A\005\152\003N\001\232\001\216\000E\000>\005\225\002\195\002a\002m\003n\003V\002b\000\163\001D\003(\004s\001\217\004\022\003|\000v\002\196\001\233\000F\004\174\004\222\003)\001\234\002\195\000F\002d\001\235\000\163\001D\004\237\003!\001\236\001\202\000F\004\235\005z\001\203\002\200\003\008\000w\001F\005\181\002f\000h\005\205\0051\003W\000s\003v\001\200\001\223\001m\005\235\003<\005G\004\175\004\223\003A\0051\003N\001\232\005\163\005y\000>\004\135\000x\003P\002m\003n\003V\004\236\000\210\003\254\000\211\005\134\005\163\001p\005\244\001s\005\241\001\233\003\013\000>\003T\003\030\001\234\000y\000j\005l\001\235\005\163\000\160\000k\003!\001\236\001\202\000l\005\242\003\017\001\203\000{\005\251\005\245\005\177\0051\000>\000\210\005\227\000\233\005\246\000\163\001D\002t\005\249\005\238\000j\002\143\005\169\000\212\002\147\000u\002\\\000\213\001F\004\168\005F\005\206\005\208\005\243\005y\005\252\001\216\005\185\005\253\001m\003\184\002a\005\250\006\005\000\000\002b\000\163\001D\003(\000\000\001\217\003z\003|\000\226\005\237\000j\001\200\001\223\000\212\003)\000\000\000\000\000\213\002d\001p\000j\001s\000>\000\000\002\148\000>\005>\000\000\002\149\002m\003n\003V\000\000\005\237\000\000\002f\000\000\000\000\005\210\003W\000\238\003v\000\000\000\226\002\\\000\000\003<\000\000\000\000\000\000\003A\000\000\003N\001\232\001\216\003!\000\000\001\202\000\000\002a\000\000\001\203\000v\002b\000\163\001D\003(\000\000\001\217\003\161\003|\000\000\000>\001\233\001\200\001\223\000\000\003)\001\234\000\000\004\160\002d\001\235\000\163\001D\000\000\000w\001\236\000>\000\000\000\227\000\000\002m\003n\003V\000>\002\249\004\161\002f\004\164\004t\005\238\003W\000>\003v\000\000\000\163\001D\000\000\003<\005\238\004\160\000x\003A\000\000\003N\001\232\000\000\003!\003\190\001\202\002\162\000\000\000\000\001\203\000\227\005{\000\000\004\161\000>\004\164\004t\003\005\000y\003\019\002\163\001\233\0017\000z\000\000\000\000\001\234\000\000\000\000\000\000\001\235\002\\\000{\001Y\000\000\001\236\000\241\000\000\000\000\000\000\003\202\001\216\003\208\004u\000\252\000\000\002a\001S\000\163\005?\002b\000\163\001D\003(\000\000\001\217\004\026\003|\001\001\000\251\005K\005B\001\200\001\223\003)\000\000\000\000\001Y\002d\000\000\000\000\000\000\000\000\001\150\004u\000\000\000>\000\000\000\000\000\252\005d\001S\003 \000\000\000\253\002f\000\000\000\000\000\254\003W\002\164\003v\000\000\000\255\002\\\000\000\003<\000\000\000\163\001D\003A\000\000\003N\001\232\001\216\000\000\003!\000\000\001\202\002a\000\000\005s\001\203\002b\000\163\001D\003(\000\000\001\217\005\130\003|\000\163\001D\001\233\005\178\001\200\001\223\003)\001\234\000\163\000\164\002d\001\235\000\000\001T\000\000\000\000\001\236\000\000\000>\005~\000\000\005\127\005d\005v\003 \000>\005w\002f\000\173\000\000\000\000\003W\004\182\003v\000\163\001D\000\000\000\000\003<\000\000\000\000\001_\003A\001j\003N\001\232\001\\\001T\003!\001]\001\202\000\173\000\000\000\000\001\203\000\000\000\000\001(\000\000\000\173\000\000\000\000\000\000\004\188\000>\001\233\005\164\000\210\000\000\000\231\001\234\001\200\001\201\004\225\001\235\001_\002\\\001`\001Y\001\236\001\\\000\000\000\000\001]\002\143\000\173\001\216\002\147\000\000\000\000\004\226\002a\001S\004\229\004t\002b\000\163\001D\003(\005\165\001\217\000\000\000\000\000\000\000\000\000\000\000>\000\000\005j\005\132\005>\000j\000\000\005\168\000\212\000j\000\000\001\202\000\213\000\000\000\000\001\203\000\000\000\000\000\000\000h\000\000\000>\002[\000\193\002f\000\000\002\148\000\000\0037\005\170\002\149\001\200\001\223\002\\\002\143\003<\000h\002\168\000\226\003A\000\190\003N\001\232\001\216\000\000\000>\004u\000\000\002a\005d\000\000\003 \002b\000\163\001D\003(\005\165\001\217\000\000\000\000\000\163\001D\001\233\000j\000\000\005j\005\132\001\234\000k\000\000\005\168\001\235\000l\001T\001R\003!\001\236\001\202\000j\000\000\000j\001\203\002\148\000\000\000\000\000k\002\149\002f\001S\000l\000\000\0037\005\170\005\167\001\200\001\223\000u\000\000\003<\000\163\000\164\001_\003A\001e\003N\001\232\001\\\002\187\000>\001]\001\216\000\173\002m\000u\003 \001\200\001\201\000\000\000\000\000\000\000\227\000\000\000\000\002\162\001\217\001\233\002\230\000>\000\000\000\000\001\234\002m\002\190\000\000\001\235\000\000\000\000\002\163\003!\001\236\001\202\000\163\005?\000\000\001\203\000\000\000\000\000\000\001\128\000\000\000\173\000\000\000\000\005J\005B\004\242\000h\004B\002\232\000j\000\189\001\202\000\163\001D\002\193\001\203\002\\\000\000\000\000\000\000\004 \000\000\002\004\000\000\003\156\001T\001\216\000\000\000v\002\162\000\000\002a\000\000\000\000\000\000\002b\000\163\001D\003(\005\165\001\217\000\000\001\233\002\163\000\000\000v\001\200\001\223\005j\005\132\000j\002\238\000w\005\168\0039\000k\001\236\002\195\001\\\000l\000>\001]\000\000\000\173\002m\003:\003V\000\000\000\000\000w\002f\002\196\000\000\000\000\0037\005\170\000\000\001\200\001\223\002\\\000\000\003<\000\000\000u\000\000\003A\000\000\003N\001\232\001\216\003!\000>\001\202\000\000\002a\002m\001\203\003 \002b\000\163\001D\003(\000\000\001\217\000\000\000\000\000\000\000\000\001\233\000\000\001\216\000\000\003)\001\234\000\000\004\160\003\145\001\235\000\163\001D\003(\003!\001\236\001\202\001\217\000\000\000\000\001\203\000\000\001\200\001\221\003)\004\161\002f\004\164\004t\000\000\0037\003\147\002u\001\200\001\223\000\000\000\000\003<\000\000\000\000\002k\003A\000\000\003N\001\232\003\007\003\154\000>\000\000\004E\003\156\002m\003\027\003 \000\000\000\000\003<\000\000\000v\000\000\003A\000\000\003N\002u\001\233\000\000\000j\000>\001\202\001\234\000\000\002m\001\203\001\235\002\\\000\000\003\007\003!\001\236\001\202\000\000\000\000\000w\001\203\001\216\001\233\004u\000>\001o\002a\000C\001\200\001\220\002b\000\163\001D\003(\004B\001\217\001\242\000\000\000\000\000\000\000\000\000\000\002\\\000\000\003)\000h\000\000\000\000\002d\000s\000\000\000\000\001\216\000\000\000E\000\000\001+\002a\000\000\000\000\000\000\002b\000\163\001D\003(\002f\001\217\000\000\000>\003W\000\000\003X\000j\000\000\001\202\003)\003<\000\000\001\203\003\145\003A\000\000\003N\001\232\000\000\000\000\000\000\000\000\000\000\000j\001-\000\000\000F\000\000\000k\000\000\002f\003C\000l\000\000\0037\003\147\000\000\001\233\001\216\002\\\000\000\003<\001\234\000\000\000\000\003A\001\235\003N\001\232\001\216\000\000\001\236\001\217\000\000\002a\001Y\000u\000F\002b\000\163\001D\003(\003C\001\217\000\000\000>\000\000\004\191\001\233\001S\001\200\001\223\003)\001\234\003H\000\000\003[\001\235\003Y\000\163\001D\003(\001\236\000\000\000>\000\000\000\000\000\000\002m\003:\003V\003L\003)\002f\000\000\000\000\000\000\0037\003]\000\163\001D\000\000\000\000\000>\003<\003H\000\000\001\216\003_\000\000\003N\001\232\001F\000\210\003!\000\233\001\202\004G\001Y\000\000\001\203\001\217\003L\001m\003<\000\000\001\200\001\201\003A\000\000\003N\001\233\001S\001\200\001\223\000\000\001\234\000\000\000v\000\000\001\235\003^\000\000\000\163\001D\001\236\000\000\000>\001p\000\000\001s\002m\003:\003V\000\000\000h\001T\000j\000\000\000s\000\212\000\000\000w\000\000\000\213\000\000\000>\000\000\000\000\001|\000j\000\000\001\202\000\000\000\000\000\000\001\203\003!\000\000\001\202\004|\000\000\000\000\001\203\001_\000\000\001\141\000\238\000x\001\\\000\226\000\000\001]\000\000\000\173\000\000\000E\004}\004t\000j\000\000\000\000\000\000\000\000\000k\002\\\000\163\001D\000l\000y\000\000\000\000\000\000\000\000\000\159\001\216\001\200\001\223\000\000\001T\002a\000\000\000\000\000{\002b\000\163\001D\003(\000\000\001\217\000>\000\000\000u\000\000\002m\003n\003V\000\000\003)\000\000\000\000\000\000\002d\000\000\000\163\000\164\000\000\001_\000\000\002q\000>\000\000\001\\\000\000\005>\001]\004u\000\173\000\000\002f\003!\000\000\001\202\003W\000\000\003X\001\203\000\000\002\\\000\000\003<\001\216\000\227\000\000\003A\000\000\003N\001\232\001\216\002\143\002t\000\000\002\167\002a\000\239\001\217\000\000\002b\000\163\001D\003(\000\000\001\217\001*\000\000\000\173\000\000\001\233\000\241\001\200\001\223\003)\001\234\000\000\000\000\002d\001\235\000\163\001D\000\000\000\000\001\236\000\000\000>\000v\000\000\000\000\002m\003n\003V\001F\000\251\002f\000j\000\000\000\000\003W\002\148\003X\000\000\000\000\002\149\000\000\003<\000\000\000\000\000\000\003A\000w\003N\001\232\000\252\000\210\003!\000\211\001\202\000\253\000\000\000\000\001\203\000\254\002\\\000\000\001\233\000\000\000\255\001p\000\000\001s\000\000\001\233\001\216\001\200\001\223\000x\001\234\002a\001\244\004\148\001\235\002b\000\163\001D\003(\001\236\001\217\000>\003u\000\000\000\000\002m\003n\003V\000>\003)\000y\000j\005>\002d\000\212\000\162\000\163\001D\000\213\000\000\000\000\000\000\000h\004\160\000{\000\000\000q\000\000\005A\005e\002f\003!\000\000\001\202\003W\000\000\003v\001\203\000\000\004|\004\161\003<\004\164\004t\000\226\003A\000\000\003N\001\232\002\162\000\000\000\000\000\000\000\000\001\200\001\201\004}\004t\002\143\002\\\000\000\002\166\000\000\002\163\000\000\003\005\000j\003\019\001\233\001\216\000\000\000k\000\000\001\234\002a\000l\000\000\001\235\002b\000\163\001D\003(\001\236\001\217\000\000\003w\000\000\000\000\000\000\001\200\001\223\000\000\003)\000\000\000\000\000\000\002d\000\000\000j\000u\001\202\004u\000j\000>\001\203\000\000\002\148\002m\003\148\003V\002\149\000\000\000\000\002f\000\000\004u\000\000\003W\000\000\003v\0011\000\000\002\\\000\000\003<\000\000\000\227\000\000\003A\000\000\003N\001\232\001\216\003!\000\000\001\202\000\000\002a\000\000\001\203\000\000\002b\000\163\001D\003(\000\000\001\217\000\000\003\137\000\163\005?\001\233\001\200\001\223\000\000\003)\001\234\000\000\004\225\002d\001\235\005A\005B\000\000\000\000\001\236\000>\003\150\000\000\000\000\002m\003\148\003V\000\000\002\143\004\226\002f\002\147\004\229\004t\003W\000v\003v\000\000\000\000\000\000\000>\003<\000\000\000\000\000\000\003A\000\000\003N\001\232\000\252\003!\000\000\001\202\001\216\001\"\000\000\001\203\002\162\000\000\000w\000\000\000\000\000\000\001\003\000\000\004\248\004\225\001\217\001\233\000\000\000\000\002\163\000j\001\234\000\000\000\000\002\148\001\235\002\\\000\000\002\149\004\146\001\236\004\226\003\152\000\149\004\229\004t\001\216\000\000\000\000\004u\000\000\002a\005{\000\000\000\000\002b\000\163\001D\003(\000\000\001\217\000\000\000\000\000\000\000y\000\000\001\200\001\223\000\150\003)\000\000\000\000\000\151\002d\003\170\000\000\000\000\000\000\000{\000\000\000>\000\000\000\000\000\000\002m\003:\003V\000\000\000\000\000>\002f\000\000\000\000\001\218\003W\000\000\003\151\001\200\001\223\002\\\000\000\003<\000\000\004u\000\000\003A\000\000\003N\001\232\001\216\003!\000>\001\202\000\000\002a\002m\001\203\003 \002b\000\163\001D\003(\000\000\001\217\000\000\000\210\000\000\000\230\001\233\000\000\000\000\002\162\003)\001\234\004\225\000\000\002d\001\235\000\000\000\163\001D\003!\001\236\001\202\000\000\002\163\000\000\001\203\000\000\001\200\001\219\004\226\005s\002f\004\229\004t\000\000\003W\004\255\003\151\001\200\001\223\000\000\000\000\003<\000\000\000\000\000\000\003A\000j\003N\001\232\000\212\004\020\000>\000\000\000\213\003\156\002m\000\000\003 \005}\000\000\000\000\000\000\005v\000\000\000\000\005w\002\143\000\173\001\233\002\147\000j\000\000\001\202\001\234\004\225\000\000\001\203\001\235\002\\\000\226\000\000\003!\001\236\001\202\000\000\000\000\004|\001\203\001\216\005\007\004u\004\226\002\195\002a\004\229\004t\000\000\002b\000\163\001D\003(\000\000\001\217\004}\004t\000\000\002\202\000\163\000\164\002\\\002[\003)\000\000\004\"\002\148\002d\000\000\003\156\002\149\001\216\000\000\000\000\000\000\000\000\002a\000\000\000\000\000\000\002b\000\163\001D\003(\002f\001\217\000\000\000>\003W\000\000\003X\000\210\000\000\000\211\003)\003<\000\000\000\000\003\145\003A\004|\003N\001\232\000>\000\000\004u\000\000\000\000\001\130\000\000\000\173\000\000\000\000\000\227\004u\002f\000\000\004}\004t\0037\003\147\000\000\001\233\001\216\002\\\000\000\003<\001\234\000\000\000\000\003A\001\235\003N\001\232\001\216\000j\001\236\001\217\000\212\002a\001Y\000\000\000\213\002b\000\163\001D\003(\002\187\001\217\000\000\000\000\005\n\000\000\001\233\001S\001\200\001\223\003)\001\234\000\000\000\000\003\145\001\235\002\162\002\223\002\224\002\226\001\236\000\226\000>\004|\000\000\002\190\002m\000\000\003 \004u\002\163\002f\000\000\000\000\000\000\0037\003\147\000\000\000\000\000\000\004}\004t\003<\004|\000\000\000\000\003A\000\000\003N\001\232\000\000\002\229\003!\000\000\001\202\000\000\000\000\002\193\001\203\004|\004}\004t\000\000\000\000\000\000\000\000\000\000\005\017\000\000\001\233\000\000\001\200\001\223\000\000\001\234\000\000\004}\004t\001\235\004\144\000\000\000\163\001D\001\236\004$\000>\000\000\000\000\003\156\002m\000\000\003 \000\000\000\210\001T\000\211\000\000\000\163\000\164\004u\002\195\000\000\000\000\000\227\000\000\000\000\000\000\000\000\000h\000\000\001\200\001\201\000q\000\000\002\196\003!\000\000\001\202\000\000\004u\000\000\001\203\001_\000\000\002\255\000\000\000\000\001\\\000\000\000\000\001]\000\000\000\173\000\000\000\000\004u\000\000\000j\000\000\000\000\000\212\004\180\000\000\002\\\000\213\000\000\001\132\005N\000\173\000\000\000\000\003\156\000j\001\216\000j\000\000\001\202\000k\002a\000\000\001\203\000l\002b\000\163\001D\003(\000\000\001\217\000\000\000\000\000\226\001=\000\252\001\200\001\223\000\000\003)\004|\000\000\000\000\003\145\005V\004|\000\000\000\000\000u\001\005\000>\000\000\000\000\000\000\002m\003:\003V\004}\004t\000\000\002f\000\000\004}\004t\0037\003\147\000\000\001\200\001\223\002\\\000\000\003<\000\000\000\000\004\185\003A\000\000\003N\001\232\001\216\003!\000>\001\202\000\000\002a\002m\001\203\003 \002b\000\163\001D\003(\000\000\001\217\004\195\000\210\000\000\000\211\001\233\000\000\000\000\000\000\003)\001\234\000\000\000\000\003\145\001\235\000\000\000\000\004\204\003!\001\236\001\202\000\000\000\227\004u\001\203\001\216\000\000\000\000\004u\000\000\002f\000\000\000\000\000\000\0037\003\147\000\000\000v\000\000\001\217\000\000\003<\000\000\000\000\000\000\003A\000j\003N\001\232\000\212\005\\\000\000\000\000\000\213\003\156\000\000\000\148\000\000\000\000\000\000\000\000\000w\000\000\000\000\000\000\000\000\002\143\000>\001\233\002\147\000\000\000\000\000\000\001\234\000\000\000\000\000\000\001\235\002\\\000\226\000\000\000\000\001\236\000\000\000\000\000\000\000\000\000\149\001\216\000\000\000\000\000\252\000\000\002a\000\000\000\000\000\000\002b\000\163\001D\003(\000\000\001\217\000\000\000\000\001\007\000\000\001\233\000y\002\\\002[\003)\000\150\000\000\002\148\002d\000\151\000\000\002\149\001\216\001Y\001\246\000{\000\000\002a\000\000\000\000\000\000\002b\000\163\001D\003(\002f\001\217\001S\004\202\003W\000\000\003X\000\000\004\246\000\000\003)\003<\000\000\000\000\003\145\003A\000\000\003N\001\232\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\227\000\000\002f\000\000\000\000\000\000\0037\003\147\000\000\001\233\000\000\000\000\000\000\003<\001\234\000\000\000\000\003A\001\235\003N\001\232\000\000\000\000\001\236\001\200\001\223\000\000\000\000\000\210\000\000\000\229\000\000\005\136\000\000\002\187\000\000\000\000\000\000\000>\000\000\001\233\000\000\002m\003:\003V\001\234\000\000\000\163\001D\001\235\002\162\002\223\005X\002\226\001\236\000\210\000\000\000\211\000\000\002\190\001T\000\000\000\000\000\000\002\163\003\165\001\200\001\223\003!\000\252\001\202\000\000\000j\000\000\001\203\000\212\000\000\000\000\000\000\000\213\000>\000\000\000\000\001\t\002m\002\229\003V\000\000\001_\000\000\003\n\002\193\000\000\001\\\000\000\000\210\001]\000\233\000\173\000j\000\000\000\000\000\212\000\000\000\000\000\226\000\213\000\000\000\000\000\000\003!\000\000\001\202\000\000\000\000\000\000\001\203\000\000\000\000\000\000\000\000\000\000\000\000\002\143\000\000\005-\002\147\000\000\000\000\000\000\000\000\000\000\000\226\000\000\002\195\000\000\000\000\000\000\000\000\000j\001\200\001\223\000\212\000\000\000\000\000\000\000\213\000\000\002\196\000\000\000\000\003Z\000\000\000\000\000>\000\000\000\000\000\000\002m\002\\\003 \000\000\000\000\000\000\000\000\000\000\000\000\000j\000\000\001\216\000\000\002\148\000\226\000\000\002a\002\149\000\000\000\000\002b\000\163\001D\003(\000\000\001\217\003!\000\000\001\202\000\227\000\000\000\000\001\203\000\000\003)\000\000\000\000\000\000\002d\002\143\000\000\000\000\002\147\002\\\000\000\000\000\000h\000\000\000\000\000\000\000q\000\000\000\000\001\216\000\000\002f\000\227\000\000\002a\003W\000>\003X\002b\000\163\001D\003(\003<\001\217\000\000\000\000\003A\000\000\003N\001\232\000\000\000\000\003)\000\000\000\000\000\000\003\167\000\000\000\000\002[\000\000\000\000\000\000\002\148\000\000\000\000\000j\002\149\000\000\001\233\000\000\000k\000\227\002f\001\234\000l\000\000\003W\001\235\003\169\000\000\000>\000\000\001\236\003<\000\000\002\162\000\000\003A\000\000\003N\001\232\000\000\002\\\000\000\000\000\000\000\000\000\005+\000u\002\163\000\228\000\000\001\216\000\000\000\000\000\000\000\000\002a\000\000\000\000\001\233\002b\000\163\001D\003(\001\234\001\217\000\000\000\000\001\235\000\251\001\200\001\223\000\000\001\236\003)\000\000\000\000\000\000\0035\000\000\000\000\003\031\001Y\000\000\000>\000\000\000\000\000\000\002m\000\252\003 \000\000\002\187\000\000\000\253\002f\001S\000\000\000\254\0037\0038\000\000\002\143\000\255\000\000\002\147\003<\000\000\002\162\000\000\003A\002\230\003N\001\232\003!\000\000\001\202\002\190\002\195\000\000\001\203\000\000\002\163\000\000\000\000\000\163\000\164\000\000\000\000\000v\000\000\000>\002\204\001\233\000\000\000\000\000\000\000\000\001\234\000\000\000\000\000\000\001\235\002\232\001\200\001\223\002[\001\236\000\191\002\193\002\148\000\000\000\000\000w\002\149\003;\000\000\000\000\000>\000\000\000\000\000\000\002m\000\000\003 \000\000\000\000\000\000\000\000\000\000\000\163\001D\000\000\000\000\001.\000\000\000\173\000\000\000\000\000\149\000\000\000\000\000\000\001T\001Y\000\000\002\237\000\000\003!\000\000\001\202\000\000\002\195\000\000\001\203\000\000\000\000\000\000\001S\000\000\000y\000\000\000\000\000\000\000\150\002\\\002\196\000\000\000\151\000\000\000\000\001_\000\000\003/\000{\001\216\001\\\000\000\000\000\001]\002a\000\173\000\000\000\000\002b\000\163\001D\003(\000\000\001\217\000\000\002\187\000\000\000\000\001\200\001\223\000\000\000\000\003)\000\000\000\000\000\000\0035\000\000\000\000\000\000\000\000\002\162\000>\000\000\002\230\000\000\002m\000\000\003 \000\000\002\190\000\000\000\000\002f\000\000\002\163\000\000\0037\0038\000\000\000\000\000\000\000\000\000\000\003<\000\000\000\163\001D\003A\000\000\003N\001\232\003!\002\\\001\202\000\000\002\232\000\000\001\203\001T\000\000\000\000\002\193\001\216\001\200\001\201\000\000\000\000\002a\000\000\000\000\001\233\002b\000\163\001D\003(\001\234\001\217\000\000\000\000\001\235\000\000\001\200\001\223\000\000\001\236\003)\001_\000\000\003E\0035\000\000\001\\\000\000\000\000\001]\000>\000\173\000\000\002\235\002m\000\000\003 \000\000\000\000\002\195\000\000\002f\000j\000\000\001\202\0037\0038\000\000\001\203\000\000\000\000\000\000\003<\002\196\000\000\000\000\003A\000\000\003N\001\232\003!\000\000\001\202\000\000\000\000\000\000\001\203\000\000\000\000\000\000\000\000\000\000\001\200\001\223\000\000\000\000\000h\002\\\000\000\001\233\000s\000\000\000\000\000\000\001\234\000\000\000>\001\216\001\235\000\000\003\183\000\000\002a\001\236\000\000\000\000\002b\000\163\001D\003(\000\000\001\217\000\000\000\000\000\000\000\000\000\000\003y\000\000\004\n\003)\000\000\000\000\000\000\003r\000h\003\218\000\000\001\202\000i\000j\000\000\001\203\000\000\000\000\000k\000\000\000\000\000\000\000l\000\000\002f\000\000\000\000\000\000\0037\003t\000\000\003\224\000\000\000\000\000\000\003<\001\216\000\000\000\000\003A\000\000\003N\001\232\000\000\002\\\000\000\000u\000\000\000\000\000\000\001\217\000\000\000j\000\000\001\216\001\200\001\223\000k\000\000\002a\000\000\000l\001\233\002b\000\163\001D\003(\001\234\001\217\000>\000\000\001\235\000\000\002m\003q\003 \001\236\003)\000\000\000\000\000\000\003r\000h\000\000\000\000\000u\000i\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002f\003!\000\000\001\202\0037\003t\000\000\001\203\000\000\000\000\000\000\003<\001\216\000\000\000\000\003A\000\000\003N\001\232\000\000\001\233\000\000\000\163\001D\003\225\000\000\001\217\000\000\000j\000\000\000v\001\200\001\223\000k\001\248\003\226\000\000\000l\001\233\003\238\000\000\000\000\000\000\001\234\000\000\000>\000\000\001\235\000\000\002m\000\000\003 \001\236\000\000\000w\000\000\000h\000\000\000\000\000\000\000q\000u\000\000\000\000\000>\000\000\000\000\003\240\000\000\000v\000\000\003\245\000\000\003\252\001\232\003!\000\000\001\202\000\000\000\000\000x\001\203\000\000\000\000\000\000\000\000\000\000\000\000\000\210\000\000\000\233\000\000\002\\\000w\001\233\000\000\000\000\000\000\000\000\001\234\000j\000y\001\216\001\235\000\000\000k\000\235\002a\001\236\000l\000\000\002b\000\163\001D\003(\000{\001\217\001Y\000\000\000\145\000\000\003\133\000\000\000\000\000\000\003)\000\000\000\000\000\000\003\134\000h\001S\000j\000u\000q\000\212\000\000\000\000\000\000\000\213\000y\000\000\000\000\000v\000\000\000\000\002f\000\000\000\000\000\000\0037\003\136\000\000\000\000\000\127\000\000\000\000\003<\000\000\000\000\000\000\003A\000\000\003N\001\232\000\226\002\\\000w\000\000\000\000\000\000\000\000\000\000\000\000\000j\000\000\001\216\001\200\001\223\000k\000\000\002a\000\000\000l\001\233\002b\000\163\001D\003(\001\234\001\217\000>\000\000\001\235\000\000\002m\003\131\003 \001\236\003)\000\000\000\000\000\000\003r\000\000\000\163\001D\000u\000\000\000\000\000\000\000\000\000\000\000\000\000y\000v\000\000\000\000\001T\000\000\002f\003!\000\000\001\202\0037\003t\000\000\001\203\000\129\000\000\000\000\003<\000\000\000\000\000\148\003A\000\000\003N\001\232\000w\000\000\000\000\000\000\000\000\000\000\000\000\001_\000\227\003\196\000\000\000\000\001\\\000\000\000\000\001]\000\000\000\173\003\144\001\233\000\000\001\200\001\223\000\000\001\234\000\000\000\149\000\000\001\235\000\000\000\000\000\000\000\000\001\236\000\249\000>\000\000\000\000\000\000\002m\002\242\003 \000\000\000\000\000\000\000\000\000\000\000y\000\000\000\000\000v\000\150\001\200\001\223\000\000\000\151\000\000\000\251\000\000\000h\000\000\000{\005R\000i\000\000\003!\000>\001\202\000\000\002\183\002m\001\203\003 \002\\\000w\000\000\000\000\000\252\000\000\000\000\000\000\000\000\000\253\001\216\000\000\000\000\000\254\000\000\002a\000\000\000\000\000\255\002b\000\163\001D\003(\003!\001\217\001\202\000\000\000\149\003\149\001\203\000j\000\000\000\000\003)\000\000\000k\000\000\003\145\000\000\000l\000\000\000\000\000\000\000\000\000\210\000\000\000\233\000\000\000y\000\000\000\000\000\000\000\150\000\000\002f\000\000\000\151\000\000\0037\003\147\000\000\000\000\000{\000u\000\000\003<\000\000\001\200\001\223\003A\000\000\003N\001\232\000\000\000\000\000\000\000\000\005^\000\000\000\000\000\000\000>\000\000\002\\\000\000\002m\000\000\003 \000j\000\000\000\000\000\212\001\233\001\216\000\000\000\213\000\000\001\234\002a\000\000\000>\001\235\002b\000\163\001D\003(\001\236\001\217\000\000\000\000\000\000\003!\000\000\001\202\002\\\000\000\003)\001\203\000\000\000\000\003\145\000\226\000\000\000\000\001\216\000\000\000\000\000\000\000\000\002a\000\000\000\000\000\000\002b\000\163\001D\003(\002f\001\217\000\000\000\000\0037\003\147\000\000\000\000\000v\000\000\003)\003<\000\000\000\000\005S\003A\001Y\003N\001\232\000\000\000\000\000\000\000\000\000h\000\000\000\000\000\000\000s\000\000\000\000\001S\002f\000w\000\000\000\000\0037\005U\000\000\001\233\000\000\000\000\000\000\003<\001\234\001\200\001\223\003A\001\235\003N\001\232\000\000\000\000\001\236\000\000\005a\000\000\000\000\000\000\000>\000\000\000\000\000\000\002m\000\000\003 \002\\\000\227\000j\000\000\001\233\001\200\001\201\000k\000\000\001\234\001\216\000l\000\000\001\235\000y\002a\000\000\000\000\001\236\002b\000\163\001D\003(\003!\001\217\001\202\000\000\004*\000\131\001\203\000\000\000\000\000\000\003)\000\000\000u\000\000\005S\000\000\000\163\001D\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000j\000\251\001\202\001T\000\000\002f\001\203\000\000\000\000\0037\005U\000\000\000\000\000\000\000\000\000\000\003<\000\000\000\000\000\000\003A\000\252\003N\001\232\000\000\000\000\000\253\000\000\000\000\000\000\000\254\001_\000\000\003\232\000\000\000\255\001\\\000\000\000\000\001]\000\000\000\173\000\000\001\233\001\200\001\223\000\000\000\000\001\234\000\000\000\000\000h\001\235\000\000\000\000\000s\000\000\001\236\000>\000\000\000\000\000\000\003\183\000h\000\000\002\\\000\000\000q\000v\000\000\000\000\000\000\000\000\000\000\000\000\001\216\000\000\000>\000\000\000\000\002a\003\215\000\000\000\000\002b\000\163\001D\003(\003\218\001\217\001\202\000\000\000w\000\000\001\203\000j\000\000\000\000\003)\000\000\000k\001\216\005S\000\000\000l\000\000\000\000\000j\000\000\000\000\003\224\000\000\000k\000\000\000\000\001\217\000l\000\000\000x\002f\000\000\000\000\000\000\0037\005U\000\000\000\000\000\000\000u\000\000\003<\000h\001\200\001\223\003A\000i\003N\001\232\004\006\000y\000u\001\228\000\000\001 \000\237\000\000\000>\000\000\000\000\000\000\003\183\000\000\000\000\000{\000\000\000\000\000\000\001\233\000\000\000\000\000\000\000>\001\234\000\000\000\000\000\000\001\235\000\000\000\000\003\217\000\000\001\236\000\000\000\000\000\000\000j\003\218\000\000\001\202\000\000\000k\000\000\001\203\001\233\000l\000\000\000\210\000\000\000\211\001\216\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\250\003\224\000\163\001D\003\225\000\000\001\217\000\000\000\000\000\000\000\000\000u\000\000\000v\000\000\003\226\000\000\001Y\000\210\004\008\000\211\000\163\000\164\000\000\000h\000v\000\000\000\000\000q\000\000\000\000\001S\000\000\000j\000\000\000\000\000\212\000w\000>\000\000\000\213\000\167\000\168\000\170\000\171\000\000\000\000\003\240\000\000\000w\000\000\004\t\000\000\003\252\001\232\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000j\000x\000\000\000\212\000\226\000h\000j\000\213\000\172\000q\000\173\000k\001\233\000\149\000\000\000l\000\000\001\234\001\216\000>\000\000\001\235\000y\000\000\000\000\000\000\001\236\001\225\000\163\001D\003\225\000v\001\217\000\226\000y\000\000\000{\000\000\000\150\000u\000\000\003\226\000\151\000\163\001D\003\238\000\000\000\000\000{\000j\000\178\000\000\000\000\000\000\000k\000w\001T\000\000\000l\000h\000\000\000\000\000\000\000s\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\240\000\000\000\000\000\000\003\245\000\000\003\252\001\232\000h\000u\000\000\001[\000q\000\227\000\000\000\000\001\\\000\000\000\000\001]\000\000\000\173\000>\000\000\000\000\000\000\000\000\001\233\000\000\000y\000j\000\000\001\234\000\000\000\000\000k\001\235\000\000\000\000\000l\000\000\001\236\000\227\000\133\000\163\000\164\000\000\000\000\000v\000\000\000\000\000\000\000j\000\000\000\000\000\000\000\000\000k\000\000\000\000\000\000\000l\000\000\000u\000\167\000\217\000\170\000\171\000\000\000\000\000\000\000\000\000w\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\252\000\000\000\000\000u\000\000\000\163\000\164\000\000\000\000\000v\000\000\000\172\000\000\000\173\001\011\000\000\000\149\000\000\000h\000\000\001\200\001\201\000q\000\000\000\000\000\167\001\207\000\170\000\171\000\252\000h\000\000\000>\000w\000i\000\000\000\000\000y\000\000\000\000\000\000\000\150\000\000\001\013\000\000\000\151\000\000\000\000\000\000\000\000\000\000\000{\000\000\000\178\000\172\000\000\000\173\000\000\000\000\000\149\000\000\000h\000j\000v\000j\000q\001\202\000k\000\000\000\000\001\203\000l\000\000\000\000\000j\000>\001\200\001\201\000\000\000k\000y\000\163\000\164\000l\000\150\000v\000\000\000w\000\151\000\000\000\000\000\000\000\000\000\000\000{\000u\000\178\000\000\000\210\000\000\000\211\000\167\002^\000\170\000\171\000j\000\000\000u\000\000\000w\000k\000\000\000\000\000x\000l\000\000\000\000\000\000\000\000\000\000\000j\000\000\001\202\000\000\000\000\000\000\001\203\000\000\000\000\000\000\000\172\000\000\000\173\000\000\000y\000\149\000\000\000h\000u\001\227\000\000\000q\000j\000\000\000\000\000\212\000\000\000\000\000{\000\213\000\000\000>\000\000\000\000\000\000\000\000\000y\000\000\000\000\000\000\000\150\000\000\000\000\000\000\000\151\001\216\000\000\000\000\000\000\000\000\000{\000\000\000\178\000\163\000\164\000\226\000\000\000v\000\000\001\217\000\000\000j\000\000\000\000\000\000\000\000\000k\000\000\000\000\000v\000l\000\000\000\000\000\167\002\153\000\170\000\171\000\000\000\000\000\000\000\000\000w\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000w\000u\000\000\000\163\000\164\000\000\000\000\000v\001\216\000\172\000\000\000\173\000\000\000\000\000\149\000\000\000h\000\000\000\000\000\000\000q\000\000\001\217\000\167\003>\000\170\000\171\000\000\000h\000\000\000>\000w\000q\000\000\001\233\000y\000\000\000\000\000\000\000\150\000\000\000\000\000>\000\151\000\227\000\000\000\000\000y\001\252\000{\000\000\000\178\000\172\000\000\000\173\000\000\000\000\000\149\000\000\000\000\000j\000\135\000h\000\000\000\000\000k\000q\000\000\000\000\000l\000\000\000\000\000j\000\000\000\000\000\000\000\000\000k\000y\000\163\000\164\000l\000\150\000v\000\000\000\000\000\151\000\000\000\000\000\000\001\233\000\000\000{\000u\000\178\000\000\001\200\001\201\000\000\000\167\003\242\000\170\000\171\000\000\001\254\000u\000j\000w\000h\000\000\000\000\000k\000q\000\252\000\000\000l\000\000\000\000\000\000\000\000\000h\000\000\000>\000\000\000q\001\021\000\000\001\015\000\172\000\000\000\173\000\000\000\000\000\149\000>\000\000\000\000\000\000\000\000\000u\000j\000\000\001\202\000\000\000\000\000\000\001\203\000\000\000\000\000h\000\000\000\000\000j\000i\000y\000\000\000\000\000k\000\150\001\200\001\223\000l\000\151\000\000\000j\000\000\000\000\000\000\000{\000k\000\178\000\163\000\164\000l\000\000\000v\000\000\000\000\000\000\002T\003k\000\000\000\000\000\163\000\164\000u\000\000\000v\000\000\000\000\000\000\000\000\000\000\000j\000\194\000\000\000\000\000u\000k\000w\000h\000\000\000l\002[\000q\001\202\000\194\000\000\000\000\001\203\000\000\000w\000\000\000\000\000>\000\000\000\000\000\000\000\000\000\000\000\196\000v\000\173\000\000\000\000\000\149\000u\000\000\000\000\000\000\000\000\000\000\0014\000\000\000\173\000\000\000\000\000\149\000\000\000\000\000\148\001\216\000\000\000\000\000j\000w\000y\000\000\000\000\000k\000\150\000\000\000\000\000l\000\151\001\217\000\000\000\000\000y\000\000\000{\000\000\000\150\000\163\000\164\000\000\000\151\000v\000\000\000\000\000\000\000\149\000{\000\000\000\000\000\163\000\164\000u\000\000\000v\000\000\000\000\000\000\000\000\000\000\000\000\000\191\000\000\000\000\000\000\000\000\000w\000y\000\000\002\\\000\000\000\150\000\000\001\183\000\000\000\151\001\200\001\223\000w\001\216\000\000\000{\000\000\000v\002a\000\000\000\000\001:\002b\000\173\000\000\000\000\000\149\001\217\000\000\000\000\002T\003a\001\233\001\185\000\210\000\173\000\211\000\000\000\149\000\000\002d\000w\000\000\000\000\000\000\000\000\002\000\000y\000\000\000\000\000\000\000\150\000\000\000\000\002[\000\151\001\202\002f\000\000\000y\001\203\000{\000\000\000\150\000\163\000\164\000\000\000\151\000v\000\000\000\000\000\000\000\000\000{\000\000\001\232\001\200\001\223\000j\000\000\000\000\000\212\000\000\000\000\000\000\000\213\000\000\001\183\000y\000\000\000\000\000\000\000w\000\000\000\000\001\233\002T\002U\000\000\000\000\001\234\000\000\000\137\000\000\001\235\000\000\000\000\000\000\000\000\001\236\000\000\000\226\000\000\002\012\000\000\000\173\000\000\000\000\000\149\000h\002[\000h\001\202\000q\000\000\000i\001\203\000\000\000\000\000\000\000\000\000\000\000\000\000>\000\000\000\000\000\000\001\200\001\223\000y\000\000\000\000\000\000\000\150\000\000\002\\\000\000\000\151\000\000\000\000\000\000\000\000\000\000\000{\000\000\001\216\000\000\002T\002`\000\000\002a\000\000\000\000\000j\002b\000j\000\000\000\000\000k\001\217\000k\000\000\000l\000\000\000l\000h\000h\000\000\000\000\000i\000q\002[\002d\001\202\000\000\000\000\000\000\001\203\000\000\000\000\000>\000\000\000\000\000\227\000\000\000\000\000u\000\000\000u\002f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\\\000\210\000\000\000\211\000\000\000\000\001\232\000\000\000j\000j\001\216\000\000\000\000\000k\000k\002a\000\000\000l\000l\002b\000\000\000\000\000\000\000\000\001\217\000\000\001\233\000\000\000\000\000\000\000\210\001\234\000\233\000\000\000\000\001\235\000\000\002d\001\200\001\223\001\236\000u\000u\000\000\000\000\000j\000\000\000\000\000\212\000\000\000\000\000\252\000\213\000\000\002f\000\000\000\000\000\000\002T\003m\000\000\002\\\000\000\000\163\000\164\001\017\000\000\000v\000\000\000v\000\000\001\216\001\232\000\000\000j\000\000\002a\000\212\000\226\000\000\002b\000\213\002[\000\000\001\202\001\217\002\127\000\000\001\203\000\000\000\000\000w\001\233\000w\000\000\000\000\000\000\001\234\002d\000\000\000\000\001\235\000\000\000\000\000\000\000\000\001\236\000\226\000\000\000\000\000\000\000\000\002\129\000\000\000\173\002f\000\000\000\149\000\000\000\000\000\163\000\164\000\000\000v\000v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\232\000\000\000\000\001\200\001\223\000y\000\000\000y\000\000\000\150\002\127\000\000\000\000\000\151\000w\000w\000\000\000\000\000\000\000{\001\233\000\139\000\000\002T\0044\001\234\000\000\000\227\000\000\001\235\000\000\000\000\000\000\000\000\001\236\000\000\002\145\000\000\000\173\000\000\002\\\000\149\001\200\001\201\000\000\001\200\001\223\002[\000\000\001\202\001\216\000\000\000\000\001\203\000\000\002a\000\227\000\000\000\000\002b\000\000\000y\000y\000\000\001\217\003d\000\150\000\000\000\000\000\000\000\151\000\000\000\000\000\000\000\000\000\141\000{\002d\001\200\001\223\000\000\000\000\004,\000\000\000\000\000\000\000j\000\000\001\202\002[\000\000\001\202\001\203\000\000\002f\001\203\000\252\000\000\002T\0046\000\000\000\000\000\000\000\000\000\000\000\251\001\200\001\223\000\000\000\000\001\019\000h\001\232\000\000\000h\000q\000\000\000\000\000q\000\000\000\000\000\000\002[\000\000\001\202\000\252\002T\0048\001\203\000\000\000\253\000\000\001\233\000\000\000\254\000\000\000\000\001\234\002\\\000\255\000\000\001\235\000\000\000\000\000\000\000\000\001\236\000\000\001\216\000\000\002[\000\000\001\202\002a\000\000\000j\001\203\002b\000j\000\000\000k\000\000\001\217\000k\000l\000\000\000\000\000l\000\210\000\000\000\211\000\000\000\000\000\000\002\002\002d\000\000\0029\000h\000\000\002\\\000\000\000q\000\000\000\000\000\000\000\000\001\216\000u\000\000\001\216\000u\002f\000\000\000h\002a\000\000\000\000\000q\002b\000\000\001\217\000\000\000\000\001\217\000h\000\000\000\000\000\000\000q\001\232\000\000\000j\002\\\000\000\000\212\000\000\002d\000\000\000\213\000\000\000\000\000j\001\216\000\000\000\000\000\000\000k\002a\000\000\001\233\000l\002b\000\000\002f\001\234\000\000\001\217\000j\001\235\000\210\002\\\000\233\000k\001\236\000\226\000\000\000l\000\000\000j\002d\001\216\001\232\000\000\000k\000u\002a\002;\000l\000\000\002b\000\000\000h\000\000\000\000\001\217\000q\002f\002=\001\233\000v\000u\001\233\000v\000\000\000\000\002|\001\234\002d\000\000\000\000\001\235\000u\002\006\000j\001\232\001\236\000\212\000\000\000\148\000\000\000\213\000\148\000\000\000w\002f\000\000\000w\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\233\000j\000\000\000\000\000\000\001\234\000k\000\000\001\232\001\235\000l\000\210\000\226\000\233\001\236\000\149\000h\000\000\000\149\000\000\000q\000\000\000\227\000\000\000\000\000\000\000\000\000h\001\233\000\000\000\000\000q\000v\001\234\000u\000\000\000y\001\235\000\000\000y\000\150\000\000\001\236\000\150\000\151\000\000\000\000\000\151\000v\000\000\000{\001\"\000\000\000{\000\000\000j\000w\000\000\000\212\000v\000j\000\000\000\213\000\000\000\000\000k\000\000\000\148\000\000\000l\002\143\000j\000w\002\147\000\000\000\000\000k\000\000\000\148\000\000\000l\000\000\000\149\000w\000\000\000\000\000\000\000\000\000\226\000\000\000\000\000\252\000h\000u\000\227\000\000\000q\000\000\000\149\000\000\000\000\000\000\000\000\000y\000u\001\025\002\181\000\150\000\000\000\149\000\000\000\151\000\000\000\000\000j\000\000\000v\000{\002\148\000y\004.\000\000\002\149\000\150\000\000\000\000\000\000\000\151\000\000\000\000\000y\000\000\000\000\000{\000\150\002\183\000j\000\000\000\151\000\000\000w\000k\000\000\000\251\000{\000l\000\000\000\000\000\000\000h\000\000\000\000\000\000\000q\000\000\000\000\000\000\000\000\000\000\000\000\000h\000\000\000\000\000\252\000q\003\003\000\149\000\000\000\253\000u\000\227\000\000\000\254\000\000\000\000\000v\003\015\000\255\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000v\000y\000\000\000\000\000\000\000\150\000\000\000j\002\183\000\151\004>\000\000\000k\000w\000\000\000{\000l\000h\000j\002\183\000\000\000q\000\000\000k\000w\000\000\000\000\000l\000h\002\162\000\000\000\000\000q\000\251\000\000\000\000\000\000\000\000\000\000\000\149\000u\000\000\000\000\002\163\000h\000\000\000\000\000\000\000i\000\000\000\149\000u\000\000\000\252\000\000\003\023\000\000\000\000\000\253\000\000\000y\000j\000\254\000\000\000\150\000v\000k\000\255\000\151\000\000\000l\000y\000j\000\000\000{\000\150\000h\000k\000\000\000\151\000q\000l\000\000\000\000\002\183\000{\000\000\000\000\000j\000w\000\000\000\000\000\000\000k\000u\000\000\000\000\000l\000h\000\000\000\000\000\000\000q\000\000\000\000\000u\000\000\000\000\000\000\000\000\000\000\005%\003$\002\195\000h\000\149\000\000\000\000\000q\000\000\000j\000u\000v\0033\000\000\000k\000\000\002\206\000\000\000l\000\000\000\000\000\000\000v\000\000\000\000\000y\000\210\000\000\000\211\000\150\002\183\000j\000\000\000\151\000\000\000w\000k\000\000\000\000\000{\000l\002\183\000u\000\000\000\000\000\000\000w\000j\000\000\000\000\000\000\000\000\000k\000\000\000\000\003J\000l\000\000\000\000\000\000\002\143\000\149\000\000\002\147\000u\000v\003R\000\000\000\000\000\000\000j\000\000\000\149\000\212\000\000\000\000\000v\000\213\000\000\000h\000u\000h\000y\000q\002\183\000q\000\150\000\000\000\000\000w\000\151\000\000\000v\000y\000\000\002\183\000{\000\150\000\000\000\000\000w\000\151\000\000\000\226\000j\000\000\000\000\000{\002\148\000\000\000\000\000\000\002\149\000\000\003\188\000\149\000w\000\000\000\000\000\000\000\000\000\000\000\000\000j\000v\000j\000\149\000h\000k\000\000\000k\000q\000l\000\000\000l\000\000\000y\000\000\000h\000\000\000\150\000\000\000q\002\183\000\151\000\000\000v\000y\000w\000h\000{\000\150\003\200\000q\000\000\000\151\000u\000\000\000u\000\000\000\000\000{\000v\000y\000\000\0052\000\000\000\000\000\000\000\000\000w\000j\000\000\000\000\000\149\000\000\000k\000\143\000\000\000\000\000l\002\183\000j\000\000\000\000\000\227\000w\000k\000\000\000\000\000\000\000l\000\210\000j\000\211\000y\000\149\000\000\000k\000\150\000\000\000\000\000l\000\151\000u\002\162\000\000\000h\000\000\000{\000\000\000q\000\149\000\000\000h\000u\000\000\000y\000q\002\163\000\000\000\150\000\000\000\000\000\000\000\151\000u\005\151\003\206\000\000\003\213\000{\000\000\000y\000\000\000\000\000j\000\150\000v\000\212\000v\000\151\000\000\000\213\000\000\000\000\000\000\000{\000\000\000\000\000\000\000j\000\000\000\000\000\252\000\000\000k\002\183\000j\002\183\000l\000\000\000w\000k\000w\000\000\000\000\000l\001\027\000\226\002\143\000\000\000\000\002\147\000\000\000\000\003\222\000\000\000\000\000\000\001\200\001\201\000\000\000\000\000u\000\000\000v\003\236\000\149\002\195\000\149\000u\000\000\000\000\000\000\001\200\001\201\000v\003\250\000\000\000h\000\000\000\000\002\208\000q\002\183\000\000\000\000\000v\000y\000w\000y\000\000\000\150\000j\000\150\002\183\000\151\002\148\000\151\000\000\000w\002\149\000{\000j\000{\001\202\002\183\000\000\000\000\001\203\000\000\000w\000\000\000\000\000\000\000\149\000\000\000\000\000j\000\000\001\202\000h\000\000\000j\001\203\000q\000\149\000\000\000k\000\000\000\227\000\000\000l\000\000\000\000\004\001\000y\000\149\000h\000\000\000\150\000\000\000q\000\000\000\151\000v\000\000\000y\000\000\000\000\000{\000\150\000v\000\000\000\000\000\151\000u\000\000\000y\000\000\000\000\000{\000\150\000\000\002\183\000j\000\151\000\000\000\000\000w\000k\0052\000{\000\000\000l\000\000\000w\000\000\000\000\000\000\000\000\000\210\000j\000\233\000\000\000\000\000\000\000k\000\000\000\000\000\000\000l\000\000\000\000\002\162\000\149\000\000\000h\000u\000\252\000\000\000q\000\149\002\143\001\216\000\000\002\147\000\000\002\163\000\000\000h\000\000\000\000\001\029\000q\000u\000y\000\000\001\217\001\216\000\150\000\000\000\000\000y\000\151\000j\000\000\000\150\000\212\000\000\000{\000\151\000\213\001\217\000\000\000\000\000\000\000{\000v\000\000\000\000\000j\000\000\000\000\000\000\000\000\000k\000j\000\000\000\000\000l\002\148\000\000\000\000\000j\002\149\000\000\000\182\000\226\000k\000\000\000\000\000w\000l\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000u\000h\000\000\000\000\002\195\000q\000v\000\000\000\000\000\000\000\000\000\000\001\233\000u\000\149\000\000\000h\000\000\002\210\000\000\000q\000\000\000\000\000v\000\000\000\220\002\008\001\233\000\000\000\000\000w\000\000\000\000\000\000\000\000\000y\000\000\000\000\000\000\000\150\000\000\002\n\000\245\000\151\000\000\000j\000\000\000w\000\000\000{\000k\000\000\000\000\000\000\000l\000\000\000\149\000\000\000\000\000\000\000j\000\000\000\000\000\000\000\000\000k\000\227\000\000\000\000\000l\000\000\000\000\000\000\000\149\002\162\000\000\000\000\000y\000u\000\000\000\000\000\150\000v\000\000\000\000\000\151\000\000\000\000\002\163\000\000\000\000\000{\004M\000u\000y\000v\000\000\000\000\000\150\000h\000\000\001$\000\151\000q\000\000\000\000\000w\002\143\000{\000\000\002\147\000\000\000\000\000\000\001\170\000\251\000\000\000\000\000\000\000w\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000h\000\000\000\000\000\149\000q\000\000\000\252\000\000\000\000\000\000\000\000\000\253\000\000\000h\000j\000\254\000\149\000q\000\000\000k\000\255\000\000\000j\000l\000y\000\000\002\148\000\000\000\150\002\195\002\149\000v\000\151\000\000\000\000\000\000\002\143\000y\000{\002\147\000\000\000\150\000\000\002\212\000j\000\151\000v\000u\000\000\000k\001\174\000{\000\000\000l\000\000\000w\000\000\000j\000\000\000h\000\000\000\000\000k\000q\000\000\001\210\000l\000\000\000\000\000h\000w\000\000\000\000\000i\000\000\000\000\000\000\000u\000\000\000\000\000j\000\149\000\000\000\000\002\148\000\000\000\000\000\000\002\149\000h\000u\000h\000\000\000q\000\000\000q\000\149\000\000\000\000\000\000\000\000\000\000\000y\000j\000\000\000\000\000\150\000h\000k\000\000\000\151\000q\000l\000j\000\000\000\000\000{\000y\000k\000\000\000\000\000\150\000l\002\162\000\000\000\151\000\000\000\000\000\000\000v\000\000\000{\000\000\000j\000\000\000j\000u\002\163\000k\000\000\000k\000\000\000l\000\000\000l\000\000\000u\000\000\002\017\002\143\000\000\000j\002\147\000w\000\000\000\000\000k\000\000\000\000\000v\000l\000\000\000\000\000\000\000\000\000\000\000u\000\000\000u\000\000\000\000\000\000\000v\000\000\000\000\000\000\000\000\000\000\002\022\000\149\000\000\002\162\000\000\000w\000u\000\000\000\000\000\000\000\000\000\000\000\000\002\026\000\000\000j\000\000\002\163\000w\002\148\000\000\000\000\000y\002\149\000\000\000\000\000\150\000\000\000\000\002\195\000\151\000\149\002\143\000h\000\000\002\147\000{\000q\000\000\000\000\000v\000\000\000\000\002\214\000\149\000\000\000\000\000\000\000\000\000h\000v\000h\000y\000q\000\000\000q\000\150\000\000\000\000\0021\000\151\000\000\000\000\000\000\000w\000y\000{\000\000\000\000\000\150\000v\000\000\000v\000\151\000w\000\000\000j\000j\000\000\000{\002\148\000\000\000k\000\000\002\149\000\000\000l\002\195\000v\002X\000\149\002\156\000\000\000j\000w\000j\000w\000\000\000k\000\000\000k\002\216\000l\000\000\000l\000\000\000\000\002\171\000\000\000h\000u\000y\000w\000i\000\000\000\150\002\162\000\000\000\000\000\151\000\149\000y\000\149\000\000\000\000\000{\000u\000h\000u\000\000\002\163\000i\000\000\000\000\000\000\000\153\000\000\002\143\000\149\000\000\002\147\000y\000\000\000y\000\000\000\150\000\000\000\150\000\000\000\151\000\000\000\151\000\000\000j\000\000\000{\000\000\000{\000k\000y\000\000\000\000\000l\000\150\000\000\000\000\000\000\000\151\000\000\000\000\000\000\000j\000\000\000{\000\000\000\000\000k\002\162\000\000\000\000\000l\000j\000\000\000\000\000\000\002\148\000u\000\000\000\000\002\149\000\000\002\163\000v\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\195\000\000\000\000\000\000\000u\000\000\000\000\000\000\000v\000\000\000v\002\173\000\000\000\000\002\218\000\000\000w\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\003\176\000\000\004\024\000\000\000\000\000w\000\000\000w\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\149\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\149\000\000\000\149\002\195\000\000\000y\000\000\000\000\000\000\000\150\000v\000\000\000\000\000\151\000\000\000\000\000\000\002\220\000\000\000{\000\000\000y\000\000\000y\002\162\000\150\000\000\000\150\000v\000\151\000\000\000\151\000\000\000\000\000w\000{\000\000\000{\002\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\000w\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\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\000\000\000\155\000\000\000\000\000\000\000y\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\195\000\000\000\000\000\000\000\000\000\157\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\222"))
   
   let semantic_action =
     [|
@@ -1519,7 +1519,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_aexpr = 
-# 1752 "parser_cocci_menhir.mly"
+# 1753 "parser_cocci_menhir.mly"
       ( Ast0.set_arg_exp _1 )
 # 1525 "parser_cocci_menhir.ml"
          in
@@ -1547,7 +1547,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_aexpr = 
-# 1754 "parser_cocci_menhir.mly"
+# 1755 "parser_cocci_menhir.mly"
       ( let (nm,lenname,pure,clt) = _1 in
       let nm = P.clt2mcode nm clt in
       let lenname =
@@ -1577,7 +1577,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_aexpr = 
-# 1762 "parser_cocci_menhir.mly"
+# 1763 "parser_cocci_menhir.mly"
       ( Ast0.set_arg_exp(Ast0.wrap(Ast0.TypeExp(_1))) )
 # 1583 "parser_cocci_menhir.ml"
          in
@@ -1599,7 +1599,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_any_strict = 
-# 1806 "parser_cocci_menhir.mly"
+# 1807 "parser_cocci_menhir.mly"
             ( Ast.WhenAny )
 # 1605 "parser_cocci_menhir.ml"
          in
@@ -1621,7 +1621,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_any_strict = 
-# 1807 "parser_cocci_menhir.mly"
+# 1808 "parser_cocci_menhir.mly"
             ( Ast.WhenStrict )
 # 1627 "parser_cocci_menhir.ml"
          in
@@ -1643,7 +1643,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_any_strict = 
-# 1808 "parser_cocci_menhir.mly"
+# 1809 "parser_cocci_menhir.mly"
             ( Ast.WhenForall )
 # 1649 "parser_cocci_menhir.ml"
          in
@@ -1665,7 +1665,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_any_strict = 
-# 1809 "parser_cocci_menhir.mly"
+# 1810 "parser_cocci_menhir.mly"
             ( Ast.WhenExists )
 # 1671 "parser_cocci_menhir.ml"
          in
@@ -1689,7 +1689,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_ = 
-# 1253 "parser_cocci_menhir.mly"
+# 1254 "parser_cocci_menhir.mly"
                                             ( _1 )
 # 1695 "parser_cocci_menhir.ml"
          in
@@ -1729,7 +1729,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_ = 
-# 1255 "parser_cocci_menhir.mly"
+# 1256 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Mul _1 _2 _3 )
 # 1735 "parser_cocci_menhir.ml"
          in
@@ -1769,7 +1769,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_ = 
-# 1257 "parser_cocci_menhir.mly"
+# 1258 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
 # 1775 "parser_cocci_menhir.ml"
          in
@@ -1809,7 +1809,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_ = 
-# 1259 "parser_cocci_menhir.mly"
+# 1260 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Plus _1 _2 _3 )
 # 1815 "parser_cocci_menhir.ml"
          in
@@ -1849,7 +1849,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_ = 
-# 1261 "parser_cocci_menhir.mly"
+# 1262 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Minus _1 _2 _3 )
 # 1855 "parser_cocci_menhir.ml"
          in
@@ -1889,7 +1889,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_ = 
-# 1263 "parser_cocci_menhir.mly"
+# 1264 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
 # 1895 "parser_cocci_menhir.ml"
          in
@@ -1929,7 +1929,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_ = 
-# 1265 "parser_cocci_menhir.mly"
+# 1266 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.logic_op op _1 clt _3 )
 # 1935 "parser_cocci_menhir.ml"
          in
@@ -1969,7 +1969,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_ = 
-# 1267 "parser_cocci_menhir.mly"
+# 1268 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.Eq _1 _2 _3 )
 # 1975 "parser_cocci_menhir.ml"
          in
@@ -2009,7 +2009,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_ = 
-# 1269 "parser_cocci_menhir.mly"
+# 1270 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.NotEq _1 _2 _3 )
 # 2015 "parser_cocci_menhir.ml"
          in
@@ -2049,7 +2049,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_ = 
-# 1271 "parser_cocci_menhir.mly"
+# 1272 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.And _1 _2 _3 )
 # 2055 "parser_cocci_menhir.ml"
          in
@@ -2089,7 +2089,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_ = 
-# 1273 "parser_cocci_menhir.mly"
+# 1274 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Or _1 _2 _3 )
 # 2095 "parser_cocci_menhir.ml"
          in
@@ -2129,7 +2129,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_ = 
-# 1275 "parser_cocci_menhir.mly"
+# 1276 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Xor _1 _2 _3 )
 # 2135 "parser_cocci_menhir.ml"
          in
@@ -2169,7 +2169,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_ = 
-# 1277 "parser_cocci_menhir.mly"
+# 1278 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.AndLog _1 _2 _3 )
 # 2175 "parser_cocci_menhir.ml"
          in
@@ -2209,7 +2209,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_ = 
-# 1279 "parser_cocci_menhir.mly"
+# 1280 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.OrLog _1 _2 _3 )
 # 2215 "parser_cocci_menhir.ml"
          in
@@ -2233,7 +2233,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1253 "parser_cocci_menhir.mly"
+# 1254 "parser_cocci_menhir.mly"
                                             ( _1 )
 # 2239 "parser_cocci_menhir.ml"
          in
@@ -2273,7 +2273,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1255 "parser_cocci_menhir.mly"
+# 1256 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Mul _1 _2 _3 )
 # 2279 "parser_cocci_menhir.ml"
          in
@@ -2313,7 +2313,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1257 "parser_cocci_menhir.mly"
+# 1258 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
 # 2319 "parser_cocci_menhir.ml"
          in
@@ -2353,7 +2353,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1259 "parser_cocci_menhir.mly"
+# 1260 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Plus _1 _2 _3 )
 # 2359 "parser_cocci_menhir.ml"
          in
@@ -2393,7 +2393,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1261 "parser_cocci_menhir.mly"
+# 1262 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Minus _1 _2 _3 )
 # 2399 "parser_cocci_menhir.ml"
          in
@@ -2433,7 +2433,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1263 "parser_cocci_menhir.mly"
+# 1264 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
 # 2439 "parser_cocci_menhir.ml"
          in
@@ -2473,7 +2473,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1265 "parser_cocci_menhir.mly"
+# 1266 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.logic_op op _1 clt _3 )
 # 2479 "parser_cocci_menhir.ml"
          in
@@ -2513,7 +2513,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1267 "parser_cocci_menhir.mly"
+# 1268 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.Eq _1 _2 _3 )
 # 2519 "parser_cocci_menhir.ml"
          in
@@ -2553,7 +2553,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1269 "parser_cocci_menhir.mly"
+# 1270 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.NotEq _1 _2 _3 )
 # 2559 "parser_cocci_menhir.ml"
          in
@@ -2593,7 +2593,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1271 "parser_cocci_menhir.mly"
+# 1272 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.And _1 _2 _3 )
 # 2599 "parser_cocci_menhir.ml"
          in
@@ -2633,7 +2633,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1273 "parser_cocci_menhir.mly"
+# 1274 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Or _1 _2 _3 )
 # 2639 "parser_cocci_menhir.ml"
          in
@@ -2673,7 +2673,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1275 "parser_cocci_menhir.mly"
+# 1276 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Xor _1 _2 _3 )
 # 2679 "parser_cocci_menhir.ml"
          in
@@ -2713,7 +2713,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1277 "parser_cocci_menhir.mly"
+# 1278 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.AndLog _1 _2 _3 )
 # 2719 "parser_cocci_menhir.ml"
          in
@@ -2753,7 +2753,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_eexpr_invalid_ = 
-# 1279 "parser_cocci_menhir.mly"
+# 1280 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.OrLog _1 _2 _3 )
 # 2759 "parser_cocci_menhir.ml"
          in
@@ -2777,7 +2777,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_ = 
-# 1253 "parser_cocci_menhir.mly"
+# 1254 "parser_cocci_menhir.mly"
                                             ( _1 )
 # 2783 "parser_cocci_menhir.ml"
          in
@@ -2817,7 +2817,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_ = 
-# 1255 "parser_cocci_menhir.mly"
+# 1256 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Mul _1 _2 _3 )
 # 2823 "parser_cocci_menhir.ml"
          in
@@ -2857,7 +2857,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_ = 
-# 1257 "parser_cocci_menhir.mly"
+# 1258 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
 # 2863 "parser_cocci_menhir.ml"
          in
@@ -2897,7 +2897,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_ = 
-# 1259 "parser_cocci_menhir.mly"
+# 1260 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Plus _1 _2 _3 )
 # 2903 "parser_cocci_menhir.ml"
          in
@@ -2937,7 +2937,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_ = 
-# 1261 "parser_cocci_menhir.mly"
+# 1262 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Minus _1 _2 _3 )
 # 2943 "parser_cocci_menhir.ml"
          in
@@ -2977,7 +2977,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_ = 
-# 1263 "parser_cocci_menhir.mly"
+# 1264 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
 # 2983 "parser_cocci_menhir.ml"
          in
@@ -3017,7 +3017,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_ = 
-# 1265 "parser_cocci_menhir.mly"
+# 1266 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.logic_op op _1 clt _3 )
 # 3023 "parser_cocci_menhir.ml"
          in
@@ -3057,7 +3057,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_ = 
-# 1267 "parser_cocci_menhir.mly"
+# 1268 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.Eq _1 _2 _3 )
 # 3063 "parser_cocci_menhir.ml"
          in
@@ -3097,7 +3097,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_ = 
-# 1269 "parser_cocci_menhir.mly"
+# 1270 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.NotEq _1 _2 _3 )
 # 3103 "parser_cocci_menhir.ml"
          in
@@ -3137,7 +3137,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_ = 
-# 1271 "parser_cocci_menhir.mly"
+# 1272 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.And _1 _2 _3 )
 # 3143 "parser_cocci_menhir.ml"
          in
@@ -3177,7 +3177,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_ = 
-# 1273 "parser_cocci_menhir.mly"
+# 1274 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Or _1 _2 _3 )
 # 3183 "parser_cocci_menhir.ml"
          in
@@ -3217,7 +3217,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_ = 
-# 1275 "parser_cocci_menhir.mly"
+# 1276 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Xor _1 _2 _3 )
 # 3223 "parser_cocci_menhir.ml"
          in
@@ -3257,7 +3257,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_ = 
-# 1277 "parser_cocci_menhir.mly"
+# 1278 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.AndLog _1 _2 _3 )
 # 3263 "parser_cocci_menhir.ml"
          in
@@ -3297,7 +3297,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_ = 
-# 1279 "parser_cocci_menhir.mly"
+# 1280 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.OrLog _1 _2 _3 )
 # 3303 "parser_cocci_menhir.ml"
          in
@@ -3321,7 +3321,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1253 "parser_cocci_menhir.mly"
+# 1254 "parser_cocci_menhir.mly"
                                             ( _1 )
 # 3327 "parser_cocci_menhir.ml"
          in
@@ -3361,7 +3361,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1255 "parser_cocci_menhir.mly"
+# 1256 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Mul _1 _2 _3 )
 # 3367 "parser_cocci_menhir.ml"
          in
@@ -3401,7 +3401,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1257 "parser_cocci_menhir.mly"
+# 1258 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
 # 3407 "parser_cocci_menhir.ml"
          in
@@ -3441,7 +3441,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1259 "parser_cocci_menhir.mly"
+# 1260 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Plus _1 _2 _3 )
 # 3447 "parser_cocci_menhir.ml"
          in
@@ -3481,7 +3481,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1261 "parser_cocci_menhir.mly"
+# 1262 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Minus _1 _2 _3 )
 # 3487 "parser_cocci_menhir.ml"
          in
@@ -3521,7 +3521,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1263 "parser_cocci_menhir.mly"
+# 1264 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.arith_op op _1 clt _3 )
 # 3527 "parser_cocci_menhir.ml"
          in
@@ -3561,7 +3561,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1265 "parser_cocci_menhir.mly"
+# 1266 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in P.logic_op op _1 clt _3 )
 # 3567 "parser_cocci_menhir.ml"
          in
@@ -3601,7 +3601,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1267 "parser_cocci_menhir.mly"
+# 1268 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.Eq _1 _2 _3 )
 # 3607 "parser_cocci_menhir.ml"
          in
@@ -3641,7 +3641,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1269 "parser_cocci_menhir.mly"
+# 1270 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.NotEq _1 _2 _3 )
 # 3647 "parser_cocci_menhir.ml"
          in
@@ -3681,7 +3681,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1271 "parser_cocci_menhir.mly"
+# 1272 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.And _1 _2 _3 )
 # 3687 "parser_cocci_menhir.ml"
          in
@@ -3721,7 +3721,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1273 "parser_cocci_menhir.mly"
+# 1274 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Or _1 _2 _3 )
 # 3727 "parser_cocci_menhir.ml"
          in
@@ -3761,7 +3761,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1275 "parser_cocci_menhir.mly"
+# 1276 "parser_cocci_menhir.mly"
       ( P.arith_op Ast.Xor _1 _2 _3 )
 # 3767 "parser_cocci_menhir.ml"
          in
@@ -3801,7 +3801,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1277 "parser_cocci_menhir.mly"
+# 1278 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.AndLog _1 _2 _3 )
 # 3807 "parser_cocci_menhir.ml"
          in
@@ -3841,7 +3841,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_arith_expr_expr_invalid_ = 
-# 1279 "parser_cocci_menhir.mly"
+# 1280 "parser_cocci_menhir.mly"
       ( P.logic_op Ast.OrLog _1 _2 _3 )
 # 3847 "parser_cocci_menhir.ml"
          in
@@ -3968,7 +3968,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_l_ in
         let _endpos = _endpos_r_ in
         let _v : 'tv_array_dec = 
-# 1060 "parser_cocci_menhir.mly"
+# 1061 "parser_cocci_menhir.mly"
                                            ( (l,i,r) )
 # 3974 "parser_cocci_menhir.ml"
          in
@@ -3992,7 +3992,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_ = 
-# 1225 "parser_cocci_menhir.mly"
+# 1226 "parser_cocci_menhir.mly"
                                            ( _1 )
 # 3998 "parser_cocci_menhir.ml"
          in
@@ -4032,7 +4032,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_ = 
-# 1227 "parser_cocci_menhir.mly"
+# 1228 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in
       Ast0.wrap(Ast0.Assignment(_1,P.clt2mcode op clt,
                                Ast0.set_arg_exp _3,false)) )
@@ -4074,7 +4074,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_ = 
-# 1231 "parser_cocci_menhir.mly"
+# 1232 "parser_cocci_menhir.mly"
       ( Ast0.wrap
          (Ast0.Assignment
             (_1,P.clt2mcode Ast.SimpleAssign _2,Ast0.set_arg_exp _3,false)) )
@@ -4100,7 +4100,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_ = 
-# 1225 "parser_cocci_menhir.mly"
+# 1226 "parser_cocci_menhir.mly"
                                            ( _1 )
 # 4106 "parser_cocci_menhir.ml"
          in
@@ -4140,7 +4140,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_ = 
-# 1227 "parser_cocci_menhir.mly"
+# 1228 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in
       Ast0.wrap(Ast0.Assignment(_1,P.clt2mcode op clt,
                                Ast0.set_arg_exp _3,false)) )
@@ -4182,7 +4182,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_ = 
-# 1231 "parser_cocci_menhir.mly"
+# 1232 "parser_cocci_menhir.mly"
       ( Ast0.wrap
          (Ast0.Assignment
             (_1,P.clt2mcode Ast.SimpleAssign _2,Ast0.set_arg_exp _3,false)) )
@@ -4208,7 +4208,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_assign_expr_expr_invalid_ = 
-# 1225 "parser_cocci_menhir.mly"
+# 1226 "parser_cocci_menhir.mly"
                                            ( _1 )
 # 4214 "parser_cocci_menhir.ml"
          in
@@ -4248,7 +4248,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_assign_expr_expr_invalid_ = 
-# 1227 "parser_cocci_menhir.mly"
+# 1228 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in
       Ast0.wrap(Ast0.Assignment(_1,P.clt2mcode op clt,
                                Ast0.set_arg_exp _3,false)) )
@@ -4290,7 +4290,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_assign_expr_expr_invalid_ = 
-# 1231 "parser_cocci_menhir.mly"
+# 1232 "parser_cocci_menhir.mly"
       ( Ast0.wrap
          (Ast0.Assignment
             (_1,P.clt2mcode Ast.SimpleAssign _2,Ast0.set_arg_exp _3,false)) )
@@ -4316,7 +4316,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_assign_expr_bis = 
-# 1236 "parser_cocci_menhir.mly"
+# 1237 "parser_cocci_menhir.mly"
                                                             ( _1 )
 # 4322 "parser_cocci_menhir.ml"
          in
@@ -4356,7 +4356,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_assign_expr_bis = 
-# 1238 "parser_cocci_menhir.mly"
+# 1239 "parser_cocci_menhir.mly"
       ( let (op,clt) = _2 in
       Ast0.wrap(Ast0.Assignment(_1,P.clt2mcode op clt,
                                Ast0.set_arg_exp _3,false)) )
@@ -4398,7 +4398,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_assign_expr_bis = 
-# 1242 "parser_cocci_menhir.mly"
+# 1243 "parser_cocci_menhir.mly"
       ( Ast0.wrap
          (Ast0.Assignment
             (_1,P.clt2mcode Ast.SimpleAssign _2,Ast0.set_arg_exp _3,false)) )
@@ -4424,7 +4424,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_ = 
-# 1222 "parser_cocci_menhir.mly"
+# 1223 "parser_cocci_menhir.mly"
                                                              ( _1 )
 # 4430 "parser_cocci_menhir.ml"
          in
@@ -4448,7 +4448,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_ = 
-# 1222 "parser_cocci_menhir.mly"
+# 1223 "parser_cocci_menhir.mly"
                                                              ( _1 )
 # 4454 "parser_cocci_menhir.ml"
          in
@@ -4472,7 +4472,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_basic_expr_expr_invalid_ = 
-# 1222 "parser_cocci_menhir.mly"
+# 1223 "parser_cocci_menhir.mly"
                                                              ( _1 )
 # 4478 "parser_cocci_menhir.ml"
          in
@@ -4516,7 +4516,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_case_line = 
-# 932 "parser_cocci_menhir.mly"
+# 933 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Default(P.clt2mcode "default" _1,P.clt2mcode ":" _2,_3)) )
 # 4522 "parser_cocci_menhir.ml"
          in
@@ -4566,7 +4566,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__4_ in
         let _v : 'tv_case_line = 
-# 934 "parser_cocci_menhir.mly"
+# 935 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Case(P.clt2mcode "case" _1,_2,P.clt2mcode ":" _3,_4)) )
 # 4572 "parser_cocci_menhir.ml"
          in
@@ -4590,7 +4590,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_ = 
-# 1282 "parser_cocci_menhir.mly"
+# 1283 "parser_cocci_menhir.mly"
                                           ( _1 )
 # 4596 "parser_cocci_menhir.ml"
          in
@@ -4640,7 +4640,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_ = 
-# 1284 "parser_cocci_menhir.mly"
+# 1285 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Cast (P.clt2mcode "(" lp, t,
                             P.clt2mcode ")" rp, e)) )
 # 4647 "parser_cocci_menhir.ml"
@@ -4665,7 +4665,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_cast_expr_eexpr_invalid_ = 
-# 1282 "parser_cocci_menhir.mly"
+# 1283 "parser_cocci_menhir.mly"
                                           ( _1 )
 # 4671 "parser_cocci_menhir.ml"
          in
@@ -4715,7 +4715,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_lp_ in
         let _endpos = _endpos_e_ in
         let _v : 'tv_cast_expr_eexpr_invalid_ = 
-# 1284 "parser_cocci_menhir.mly"
+# 1285 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Cast (P.clt2mcode "(" lp, t,
                             P.clt2mcode ")" rp, e)) )
 # 4722 "parser_cocci_menhir.ml"
@@ -4740,7 +4740,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_ = 
-# 1282 "parser_cocci_menhir.mly"
+# 1283 "parser_cocci_menhir.mly"
                                           ( _1 )
 # 4746 "parser_cocci_menhir.ml"
          in
@@ -4790,7 +4790,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_ = 
-# 1284 "parser_cocci_menhir.mly"
+# 1285 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Cast (P.clt2mcode "(" lp, t,
                             P.clt2mcode ")" rp, e)) )
 # 4797 "parser_cocci_menhir.ml"
@@ -4815,7 +4815,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_cast_expr_expr_invalid_ = 
-# 1282 "parser_cocci_menhir.mly"
+# 1283 "parser_cocci_menhir.mly"
                                           ( _1 )
 # 4821 "parser_cocci_menhir.ml"
          in
@@ -4865,7 +4865,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_lp_ in
         let _endpos = _endpos_e_ in
         let _v : 'tv_cast_expr_expr_invalid_ = 
-# 1284 "parser_cocci_menhir.mly"
+# 1285 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Cast (P.clt2mcode "(" lp, t,
                             P.clt2mcode ")" rp, e)) )
 # 4872 "parser_cocci_menhir.ml"
@@ -4932,7 +4932,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_comma_decls_TEllipsis_decl_ = 
-# 1553 "parser_cocci_menhir.mly"
+# 1554 "parser_cocci_menhir.mly"
     ( function dot_builder ->
       [Ast0.wrap(Ast0.PComma(P.clt2mcode "," _1));
        dot_builder _2] )
@@ -4968,7 +4968,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_comma_decls_TEllipsis_decl_ = 
-# 1557 "parser_cocci_menhir.mly"
+# 1558 "parser_cocci_menhir.mly"
     ( function dot_builder ->
       [Ast0.wrap(Ast0.PComma(P.clt2mcode "," _1)); _2] )
 # 4975 "parser_cocci_menhir.ml"
@@ -5007,7 +5007,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_ = 
-# 1553 "parser_cocci_menhir.mly"
+# 1554 "parser_cocci_menhir.mly"
     ( function dot_builder ->
       [Ast0.wrap(Ast0.PComma(P.clt2mcode "," _1));
        dot_builder _2] )
@@ -5043,7 +5043,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_ = 
-# 1557 "parser_cocci_menhir.mly"
+# 1558 "parser_cocci_menhir.mly"
     ( function dot_builder ->
       [Ast0.wrap(Ast0.PComma(P.clt2mcode "," _1)); _2] )
 # 5050 "parser_cocci_menhir.ml"
@@ -5061,7 +5061,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_comma_initializers_edots_when_TEllipsis_initialize__ = 
-# 1113 "parser_cocci_menhir.mly"
+# 1114 "parser_cocci_menhir.mly"
               ( [] )
 # 5067 "parser_cocci_menhir.ml"
          in
@@ -5091,7 +5091,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_d_ in
         let _endpos = _endpos_r_ in
         let _v : 'tv_comma_initializers_edots_when_TEllipsis_initialize__ = 
-# 1115 "parser_cocci_menhir.mly"
+# 1116 "parser_cocci_menhir.mly"
       ( (function dot_builder -> [dot_builder d])::r )
 # 5097 "parser_cocci_menhir.ml"
          in
@@ -5131,7 +5131,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_i_ in
         let _endpos = _endpos_r_ in
         let _v : 'tv_comma_initializers_edots_when_TEllipsis_initialize__ = 
-# 1117 "parser_cocci_menhir.mly"
+# 1118 "parser_cocci_menhir.mly"
     ( (function dot_builder -> [i; Ast0.wrap(Ast0.IComma(P.clt2mcode "," c))])::
       r )
 # 5138 "parser_cocci_menhir.ml"
@@ -5149,7 +5149,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_comma_initializers2_edots_when_TEllipsis_initialize__ = 
-# 1121 "parser_cocci_menhir.mly"
+# 1122 "parser_cocci_menhir.mly"
               ( [] )
 # 5155 "parser_cocci_menhir.ml"
          in
@@ -5189,7 +5189,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_i_ in
         let _endpos = _endpos_r_ in
         let _v : 'tv_comma_initializers2_edots_when_TEllipsis_initialize__ = 
-# 1123 "parser_cocci_menhir.mly"
+# 1124 "parser_cocci_menhir.mly"
     ( (function dot_builder -> [i; Ast0.wrap(Ast0.IComma(P.clt2mcode "," c))])::
       r )
 # 5196 "parser_cocci_menhir.ml"
@@ -5214,7 +5214,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_comma_list_any_strict_ = 
-# 1784 "parser_cocci_menhir.mly"
+# 1785 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5220 "parser_cocci_menhir.ml"
          in
@@ -5238,7 +5238,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_comma_list_ctype_ = 
-# 1784 "parser_cocci_menhir.mly"
+# 1785 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5244 "parser_cocci_menhir.ml"
          in
@@ -5262,7 +5262,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_comma_list_d_ident_ = 
-# 1784 "parser_cocci_menhir.mly"
+# 1785 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5268 "parser_cocci_menhir.ml"
          in
@@ -5286,7 +5286,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_comma_list_dexpr_ = 
-# 1784 "parser_cocci_menhir.mly"
+# 1785 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5292 "parser_cocci_menhir.ml"
          in
@@ -5310,7 +5310,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_ = 
-# 1784 "parser_cocci_menhir.mly"
+# 1785 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5316 "parser_cocci_menhir.ml"
          in
@@ -5334,7 +5334,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_comma_list_meta_ident_ = 
-# 1784 "parser_cocci_menhir.mly"
+# 1785 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5340 "parser_cocci_menhir.ml"
          in
@@ -5358,7 +5358,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_comma_list_pure_ident_ = 
-# 1784 "parser_cocci_menhir.mly"
+# 1785 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5364 "parser_cocci_menhir.ml"
          in
@@ -5382,7 +5382,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_ = 
-# 1784 "parser_cocci_menhir.mly"
+# 1785 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5388 "parser_cocci_menhir.ml"
          in
@@ -5406,7 +5406,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__ = 
-# 1784 "parser_cocci_menhir.mly"
+# 1785 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5412 "parser_cocci_menhir.ml"
          in
@@ -5430,7 +5430,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__ = 
-# 1784 "parser_cocci_menhir.mly"
+# 1785 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5436 "parser_cocci_menhir.ml"
          in
@@ -5454,7 +5454,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__ = 
-# 1784 "parser_cocci_menhir.mly"
+# 1785 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5460 "parser_cocci_menhir.ml"
          in
@@ -5478,7 +5478,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__ = 
-# 1784 "parser_cocci_menhir.mly"
+# 1785 "parser_cocci_menhir.mly"
                                        ( _1 )
 # 5484 "parser_cocci_menhir.ml"
          in
@@ -5502,7 +5502,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_ = 
-# 1247 "parser_cocci_menhir.mly"
+# 1248 "parser_cocci_menhir.mly"
                                              ( _1 )
 # 5508 "parser_cocci_menhir.ml"
          in
@@ -5558,7 +5558,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_ = 
-# 1249 "parser_cocci_menhir.mly"
+# 1250 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.CondExpr (l, P.clt2mcode "?" w, t,
                                 P.clt2mcode ":" dd, r)) )
 # 5565 "parser_cocci_menhir.ml"
@@ -5583,7 +5583,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_ = 
-# 1247 "parser_cocci_menhir.mly"
+# 1248 "parser_cocci_menhir.mly"
                                              ( _1 )
 # 5589 "parser_cocci_menhir.ml"
          in
@@ -5639,7 +5639,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_ = 
-# 1249 "parser_cocci_menhir.mly"
+# 1250 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.CondExpr (l, P.clt2mcode "?" w, t,
                                 P.clt2mcode ":" dd, r)) )
 # 5646 "parser_cocci_menhir.ml"
@@ -5664,7 +5664,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_cond_expr_expr_invalid_ = 
-# 1247 "parser_cocci_menhir.mly"
+# 1248 "parser_cocci_menhir.mly"
                                              ( _1 )
 # 5670 "parser_cocci_menhir.ml"
          in
@@ -5720,7 +5720,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_l_ in
         let _endpos = _endpos_r_ in
         let _v : 'tv_cond_expr_expr_invalid_ = 
-# 1249 "parser_cocci_menhir.mly"
+# 1250 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.CondExpr (l, P.clt2mcode "?" w, t,
                                 P.clt2mcode ":" dd, r)) )
 # 5727 "parser_cocci_menhir.ml"
@@ -5749,7 +5749,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_const_vol = 
-# 841 "parser_cocci_menhir.mly"
+# 842 "parser_cocci_menhir.mly"
                    ( P.clt2mcode Ast.Const _1 )
 # 5755 "parser_cocci_menhir.ml"
          in
@@ -5777,7 +5777,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_const_vol = 
-# 842 "parser_cocci_menhir.mly"
+# 843 "parser_cocci_menhir.mly"
                    ( P.clt2mcode Ast.Volatile _1 )
 # 5783 "parser_cocci_menhir.ml"
          in
@@ -6318,7 +6318,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_d_ident = 
-# 1051 "parser_cocci_menhir.mly"
+# 1052 "parser_cocci_menhir.mly"
       ( (_1,
         function t ->
           List.fold_right
@@ -6355,7 +6355,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_t_ in
         let _endpos = _endpos_i_ in
         let _v : 'tv_decl = 
-# 811 "parser_cocci_menhir.mly"
+# 812 "parser_cocci_menhir.mly"
  ( Ast0.wrap(Ast0.Param(t, Some i)) )
 # 6361 "parser_cocci_menhir.ml"
          in
@@ -6441,7 +6441,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_t_ in
         let _endpos = _endpos_rp1_ in
         let _v : 'tv_decl = 
-# 814 "parser_cocci_menhir.mly"
+# 815 "parser_cocci_menhir.mly"
         ( let fnptr =
          Ast0.wrap
            (Ast0.FunctionPointer
@@ -6474,7 +6474,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_t_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_decl = 
-# 821 "parser_cocci_menhir.mly"
+# 822 "parser_cocci_menhir.mly"
  ( let ty =
          Ast0.wrap(Ast0.BaseType(Ast.VoidType,[P.clt2mcode "void" t])) in
           Ast0.wrap(Ast0.VoidParam(ty)) )
@@ -6504,7 +6504,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_decl = 
-# 825 "parser_cocci_menhir.mly"
+# 826 "parser_cocci_menhir.mly"
  ( let (nm,pure,clt) = _1 in
        Ast0.wrap(Ast0.MetaParam(P.clt2mcode nm clt,pure)) )
 # 6511 "parser_cocci_menhir.ml"
@@ -6533,7 +6533,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_decl_ident = 
-# 1502 "parser_cocci_menhir.mly"
+# 1503 "parser_cocci_menhir.mly"
          ( Ast0.wrap(Ast0.Id(P.id2mcode _1)) )
 # 6539 "parser_cocci_menhir.ml"
          in
@@ -6561,7 +6561,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_decl_ident = 
-# 1504 "parser_cocci_menhir.mly"
+# 1505 "parser_cocci_menhir.mly"
          ( let (nm,constraints,pure,clt) = _1 in
          Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) )
 # 6568 "parser_cocci_menhir.ml"
@@ -6579,7 +6579,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_decl_list_decl_ = 
-# 1524 "parser_cocci_menhir.mly"
+# 1525 "parser_cocci_menhir.mly"
               ( Ast0.wrap(Ast0.DOTS([])) )
 # 6585 "parser_cocci_menhir.ml"
          in
@@ -6603,7 +6603,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_decl_list_decl_ = 
-# 1526 "parser_cocci_menhir.mly"
+# 1527 "parser_cocci_menhir.mly"
      (let circle x =
        match Ast0.unwrap x with Ast0.Pcircles(_) -> true | _ -> false in
      if List.exists circle _1
@@ -6624,7 +6624,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_decl_list_name_opt_decl_ = 
-# 1524 "parser_cocci_menhir.mly"
+# 1525 "parser_cocci_menhir.mly"
               ( Ast0.wrap(Ast0.DOTS([])) )
 # 6630 "parser_cocci_menhir.ml"
          in
@@ -6648,7 +6648,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_ = 
-# 1526 "parser_cocci_menhir.mly"
+# 1527 "parser_cocci_menhir.mly"
      (let circle x =
        match Ast0.unwrap x with Ast0.Pcircles(_) -> true | _ -> false in
      if List.exists circle _1
@@ -6676,7 +6676,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_decl_list_start_decl_ = 
-# 1533 "parser_cocci_menhir.mly"
+# 1534 "parser_cocci_menhir.mly"
                  ( [_1] )
 # 6682 "parser_cocci_menhir.ml"
          in
@@ -6716,7 +6716,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_decl_list_start_decl_ = 
-# 1535 "parser_cocci_menhir.mly"
+# 1536 "parser_cocci_menhir.mly"
     ( _1::Ast0.wrap(Ast0.PComma(P.clt2mcode "," _2))::_3 )
 # 6722 "parser_cocci_menhir.ml"
          in
@@ -6750,7 +6750,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_decl_list_start_decl_ = 
-# 1537 "parser_cocci_menhir.mly"
+# 1538 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.Pdots(P.clt2mcode "..." _1))::
       (List.concat(List.map (function x -> x (P.mkpdots "...")) _2)) )
 # 6757 "parser_cocci_menhir.ml"
@@ -6775,7 +6775,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_ = 
-# 1533 "parser_cocci_menhir.mly"
+# 1534 "parser_cocci_menhir.mly"
                  ( [_1] )
 # 6781 "parser_cocci_menhir.ml"
          in
@@ -6815,7 +6815,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_ = 
-# 1535 "parser_cocci_menhir.mly"
+# 1536 "parser_cocci_menhir.mly"
     ( _1::Ast0.wrap(Ast0.PComma(P.clt2mcode "," _2))::_3 )
 # 6821 "parser_cocci_menhir.ml"
          in
@@ -6849,7 +6849,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_ = 
-# 1537 "parser_cocci_menhir.mly"
+# 1538 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.Pdots(P.clt2mcode "..." _1))::
       (List.concat(List.map (function x -> x (P.mkpdots "...")) _2)) )
 # 6856 "parser_cocci_menhir.ml"
@@ -6878,7 +6878,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_decl_statement = 
-# 1129 "parser_cocci_menhir.mly"
+# 1130 "parser_cocci_menhir.mly"
       ( let (nm,pure,clt) = _1 in
       [Ast0.wrap(Ast0.MetaStmt(P.clt2mcode nm clt,pure))] )
 # 6885 "parser_cocci_menhir.ml"
@@ -6903,7 +6903,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_decl_statement = 
-# 1132 "parser_cocci_menhir.mly"
+# 1133 "parser_cocci_menhir.mly"
       ( List.map
          (function x ->
            Ast0.wrap
@@ -6931,7 +6931,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_decl_statement = 
-# 1137 "parser_cocci_menhir.mly"
+# 1138 "parser_cocci_menhir.mly"
               ( [_1] )
 # 6937 "parser_cocci_menhir.ml"
          in
@@ -6975,7 +6975,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_decl_statement = 
-# 1146 "parser_cocci_menhir.mly"
+# 1147 "parser_cocci_menhir.mly"
       ( let (mids,code) = t in
        if List.for_all
            (function x ->
@@ -7011,7 +7011,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_decl_statement_expr = 
-# 1159 "parser_cocci_menhir.mly"
+# 1160 "parser_cocci_menhir.mly"
       ( let (nm,pure,clt) = _1 in
       [Ast0.wrap(Ast0.MetaStmt(P.clt2mcode nm clt,pure))] )
 # 7018 "parser_cocci_menhir.ml"
@@ -7036,7 +7036,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_decl_statement_expr = 
-# 1162 "parser_cocci_menhir.mly"
+# 1163 "parser_cocci_menhir.mly"
       ( List.map
          (function x ->
            Ast0.wrap
@@ -7064,7 +7064,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_decl_statement_expr = 
-# 1167 "parser_cocci_menhir.mly"
+# 1168 "parser_cocci_menhir.mly"
               ( [_1] )
 # 7070 "parser_cocci_menhir.ml"
          in
@@ -7108,7 +7108,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_decl_statement_expr = 
-# 1176 "parser_cocci_menhir.mly"
+# 1177 "parser_cocci_menhir.mly"
       ( let (mids,code) = t in
        if List.for_all (function [] -> true | _ -> false) code
       then []
@@ -7149,7 +7149,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_t_ in
         let _endpos = _endpos_pv_ in
         let _v : 'tv_decl_var = 
-# 942 "parser_cocci_menhir.mly"
+# 943 "parser_cocci_menhir.mly"
       ( [Ast0.wrap(Ast0.TyDecl(t,P.clt2mcode ";" pv))] )
 # 7155 "parser_cocci_menhir.ml"
          in
@@ -7196,7 +7196,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
         in
         
-# 944 "parser_cocci_menhir.mly"
+# 945 "parser_cocci_menhir.mly"
       ( List.map
          (function (id,fn) ->
            Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv)))
@@ -7253,7 +7253,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
         in
         
-# 944 "parser_cocci_menhir.mly"
+# 945 "parser_cocci_menhir.mly"
       ( List.map
          (function (id,fn) ->
            Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv)))
@@ -7280,7 +7280,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_f_ in
         let _endpos = _endpos_f_ in
         let _v : 'tv_decl_var = 
-# 948 "parser_cocci_menhir.mly"
+# 949 "parser_cocci_menhir.mly"
                ( [f] )
 # 7286 "parser_cocci_menhir.ml"
          in
@@ -7343,7 +7343,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
         in
         
-# 950 "parser_cocci_menhir.mly"
+# 951 "parser_cocci_menhir.mly"
       (let (id,fn) = d in
       [Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv))])
 # 7350 "parser_cocci_menhir.ml"
@@ -7414,7 +7414,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
         in
         
-# 950 "parser_cocci_menhir.mly"
+# 951 "parser_cocci_menhir.mly"
       (let (id,fn) = d in
       [Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv))])
 # 7421 "parser_cocci_menhir.ml"
@@ -7469,7 +7469,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
         in
         
-# 955 "parser_cocci_menhir.mly"
+# 956 "parser_cocci_menhir.mly"
       ( List.map
          (function (id,fn) ->
            let idtype =
@@ -7535,7 +7535,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
         in
         
-# 955 "parser_cocci_menhir.mly"
+# 956 "parser_cocci_menhir.mly"
       ( List.map
          (function (id,fn) ->
            let idtype =
@@ -7601,7 +7601,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
         in
         
-# 955 "parser_cocci_menhir.mly"
+# 956 "parser_cocci_menhir.mly"
       ( List.map
          (function (id,fn) ->
            let idtype =
@@ -7674,7 +7674,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
         in
         
-# 955 "parser_cocci_menhir.mly"
+# 956 "parser_cocci_menhir.mly"
       ( List.map
          (function (id,fn) ->
            let idtype =
@@ -7749,7 +7749,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
         in
         
-# 963 "parser_cocci_menhir.mly"
+# 964 "parser_cocci_menhir.mly"
       ( 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
@@ -7830,7 +7830,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
         in
         
-# 963 "parser_cocci_menhir.mly"
+# 964 "parser_cocci_menhir.mly"
       ( 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
@@ -7911,7 +7911,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
         in
         
-# 963 "parser_cocci_menhir.mly"
+# 964 "parser_cocci_menhir.mly"
       ( 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
@@ -7999,7 +7999,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
         in
         
-# 963 "parser_cocci_menhir.mly"
+# 964 "parser_cocci_menhir.mly"
       ( 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
@@ -8106,7 +8106,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
         in
         
-# 973 "parser_cocci_menhir.mly"
+# 974 "parser_cocci_menhir.mly"
       ( let (id,fn) = d in
         let t =
          Ast0.wrap
@@ -8222,7 +8222,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
         in
         
-# 973 "parser_cocci_menhir.mly"
+# 974 "parser_cocci_menhir.mly"
       ( let (id,fn) = d in
         let t =
          Ast0.wrap
@@ -8288,7 +8288,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__5_ in
         let _v : 'tv_decl_var = 
-# 981 "parser_cocci_menhir.mly"
+# 982 "parser_cocci_menhir.mly"
       ( [Ast0.wrap(Ast0.MacroDecl(_1,P.clt2mcode "(" _2,_3,
                                  P.clt2mcode ")" _4,P.clt2mcode ";" _5))] )
 # 8295 "parser_cocci_menhir.ml"
@@ -8408,7 +8408,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
         in
         
-# 987 "parser_cocci_menhir.mly"
+# 988 "parser_cocci_menhir.mly"
       ( let (id,fn) = d in
         let t =
          Ast0.wrap
@@ -8540,7 +8540,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
         in
         
-# 987 "parser_cocci_menhir.mly"
+# 988 "parser_cocci_menhir.mly"
       ( let (id,fn) = d in
         let t =
          Ast0.wrap
@@ -8596,7 +8596,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_s_ in
         let _endpos = _endpos_pv_ in
         let _v : 'tv_decl_var = 
-# 995 "parser_cocci_menhir.mly"
+# 996 "parser_cocci_menhir.mly"
       ( let s = P.clt2mcode "typedef" s in
         [Ast0.wrap(Ast0.Typedef(s,t,id,P.clt2mcode ";" pv))] )
 # 8603 "parser_cocci_menhir.ml"
@@ -8621,7 +8621,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_define_param_list = 
-# 703 "parser_cocci_menhir.mly"
+# 704 "parser_cocci_menhir.mly"
      (let circle x =
        match Ast0.unwrap x with Ast0.DPcircles(_) -> true | _ -> false in
      if List.exists circle _1
@@ -8649,7 +8649,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_define_param_list_option = 
-# 727 "parser_cocci_menhir.mly"
+# 728 "parser_cocci_menhir.mly"
                                             ( _1 )
 # 8655 "parser_cocci_menhir.ml"
          in
@@ -8666,7 +8666,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_define_param_list_option = 
-# 728 "parser_cocci_menhir.mly"
+# 729 "parser_cocci_menhir.mly"
                            ( Ast0.wrap(Ast0.DOTS([])) )
 # 8672 "parser_cocci_menhir.ml"
          in
@@ -8690,7 +8690,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_define_param_list_start = 
-# 710 "parser_cocci_menhir.mly"
+# 711 "parser_cocci_menhir.mly"
           ( [Ast0.wrap(Ast0.DParam _1)] )
 # 8696 "parser_cocci_menhir.ml"
          in
@@ -8730,7 +8730,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_define_param_list_start = 
-# 712 "parser_cocci_menhir.mly"
+# 713 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.DParam _1)::
        Ast0.wrap(Ast0.DPComma(P.clt2mcode "," _2))::_3 )
 # 8737 "parser_cocci_menhir.ml"
@@ -8765,7 +8765,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_d_ in
         let _endpos = _endpos_r_ in
         let _v : 'tv_define_param_list_start = 
-# 715 "parser_cocci_menhir.mly"
+# 716 "parser_cocci_menhir.mly"
       ( (P.mkdpdots "..." d)::
        (List.concat (List.map (function x -> x (P.mkdpdots "...")) r)) )
 # 8772 "parser_cocci_menhir.ml"
@@ -8857,7 +8857,8 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
     ( 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
+       P.clt2mcode "("
+         (arity,line,lline,parenoff,0,[],[],Ast0.NoMetaPos) in
       function body ->
        Ast0.wrap
          (Ast0.Define
@@ -8872,7 +8873,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
                    (Semantic_cocci.Semantic
                       "unexpected name for a #define")),
              Ast0.wrap (Ast0.DParams (lp,_2,P.clt2mcode ")" _3)),body)) )
-# 8876 "parser_cocci_menhir.ml"
+# 8877 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -8896,7 +8897,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_dep = 
 # 221 "parser_cocci_menhir.mly"
                    ( _1 )
-# 8900 "parser_cocci_menhir.ml"
+# 8901 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -8930,7 +8931,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_dep = 
 # 222 "parser_cocci_menhir.mly"
                    ( Ast.AndDep(_1, _3) )
-# 8934 "parser_cocci_menhir.ml"
+# 8935 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -8964,7 +8965,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_dep = 
 # 223 "parser_cocci_menhir.mly"
                    ( Ast.OrDep (_1, _3) )
-# 8968 "parser_cocci_menhir.ml"
+# 8969 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -8981,7 +8982,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_depends = 
 # 217 "parser_cocci_menhir.mly"
                            ( Ast.NoDep )
-# 8985 "parser_cocci_menhir.ml"
+# 8986 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9013,7 +9014,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_depends = 
 # 218 "parser_cocci_menhir.mly"
                            ( parents )
-# 9017 "parser_cocci_menhir.ml"
+# 9018 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9040,14 +9041,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 9044 "parser_cocci_menhir.ml"
+# 9045 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_designator = 
-# 1093 "parser_cocci_menhir.mly"
+# 1094 "parser_cocci_menhir.mly"
      ( Ast0.DesignatorField (P.clt2mcode "." _1,_2) )
-# 9051 "parser_cocci_menhir.ml"
+# 9052 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9078,20 +9079,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 102 "parser_cocci_menhir.mly"
        (Data.clt)
-# 9082 "parser_cocci_menhir.ml"
+# 9083 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_eexpr = Obj.magic _2 in
         let _1 : (
 # 102 "parser_cocci_menhir.mly"
        (Data.clt)
-# 9088 "parser_cocci_menhir.ml"
+# 9089 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_designator = 
-# 1095 "parser_cocci_menhir.mly"
+# 1096 "parser_cocci_menhir.mly"
      ( Ast0.DesignatorIndex (P.clt2mcode "[" _1,_2,P.clt2mcode "]" _3) )
-# 9095 "parser_cocci_menhir.ml"
+# 9096 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9132,27 +9133,27 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _5 : (
 # 102 "parser_cocci_menhir.mly"
        (Data.clt)
-# 9136 "parser_cocci_menhir.ml"
+# 9137 "parser_cocci_menhir.ml"
         ) = Obj.magic _5 in
         let _4 : 'tv_eexpr = Obj.magic _4 in
         let _3 : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 9142 "parser_cocci_menhir.ml"
+# 9143 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_eexpr = Obj.magic _2 in
         let _1 : (
 # 102 "parser_cocci_menhir.mly"
        (Data.clt)
-# 9148 "parser_cocci_menhir.ml"
+# 9149 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__5_ in
         let _v : 'tv_designator = 
-# 1097 "parser_cocci_menhir.mly"
+# 1098 "parser_cocci_menhir.mly"
      ( Ast0.DesignatorRange (P.clt2mcode "[" _1,_2,P.clt2mcode "..." _3,
                             _4,P.clt2mcode "]" _5) )
-# 9156 "parser_cocci_menhir.ml"
+# 9157 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9174,9 +9175,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_dexpr = 
-# 1196 "parser_cocci_menhir.mly"
+# 1197 "parser_cocci_menhir.mly"
                                           ( _1 )
-# 9180 "parser_cocci_menhir.ml"
+# 9181 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9204,7 +9205,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_disable = 
 # 236 "parser_cocci_menhir.mly"
                                                       ( List.map P.id2name _2 )
-# 9208 "parser_cocci_menhir.ml"
+# 9209 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9225,14 +9226,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 9229 "parser_cocci_menhir.ml"
+# 9230 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_dot_expressions = 
-# 1205 "parser_cocci_menhir.mly"
+# 1206 "parser_cocci_menhir.mly"
             ( Ast0.wrap(Ast0.Edots(P.clt2mcode "..." _1,None)) )
-# 9236 "parser_cocci_menhir.ml"
+# 9237 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9254,9 +9255,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_dot_expressions = 
-# 1206 "parser_cocci_menhir.mly"
+# 1207 "parser_cocci_menhir.mly"
                    ( _1 )
-# 9260 "parser_cocci_menhir.ml"
+# 9261 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9282,20 +9283,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let d : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 9286 "parser_cocci_menhir.ml"
+# 9287 "parser_cocci_menhir.ml"
         ) = Obj.magic d in
         let c : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 9291 "parser_cocci_menhir.ml"
+# 9292 "parser_cocci_menhir.ml"
         ) = Obj.magic c in
         let _startpos = _startpos_c_ in
         let _endpos = _endpos_d_ in
         let _v : 'tv_dp_comma_args_TEllipsis_ = 
-# 720 "parser_cocci_menhir.mly"
+# 721 "parser_cocci_menhir.mly"
     ( function dot_builder ->
       [Ast0.wrap(Ast0.DPComma(P.clt2mcode "," c)); dot_builder d] )
-# 9299 "parser_cocci_menhir.ml"
+# 9300 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9322,16 +9323,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 9326 "parser_cocci_menhir.ml"
+# 9327 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_dp_comma_args_TEllipsis_ = 
-# 723 "parser_cocci_menhir.mly"
+# 724 "parser_cocci_menhir.mly"
     ( function dot_builder ->
       [Ast0.wrap(Ast0.DPComma(P.clt2mcode "," _1));
        Ast0.wrap(Ast0.DParam _2)] )
-# 9335 "parser_cocci_menhir.ml"
+# 9336 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9352,14 +9353,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let d : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 9356 "parser_cocci_menhir.ml"
+# 9357 "parser_cocci_menhir.ml"
         ) = Obj.magic d in
         let _startpos = _startpos_d_ in
         let _endpos = _endpos_d_ in
         let _v : 'tv_edots_when_TEllipsis_eexpr_ = 
-# 1794 "parser_cocci_menhir.mly"
+# 1795 "parser_cocci_menhir.mly"
                                                   ( (d,None) )
-# 9363 "parser_cocci_menhir.ml"
+# 9364 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9398,14 +9399,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let d : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 9402 "parser_cocci_menhir.ml"
+# 9403 "parser_cocci_menhir.ml"
         ) = Obj.magic d in
         let _startpos = _startpos_d_ in
         let _endpos = _endpos__5_ in
         let _v : 'tv_edots_when_TEllipsis_eexpr_ = 
-# 1795 "parser_cocci_menhir.mly"
+# 1796 "parser_cocci_menhir.mly"
                                                   ( (d,Some w) )
-# 9409 "parser_cocci_menhir.ml"
+# 9410 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9426,14 +9427,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let d : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 9430 "parser_cocci_menhir.ml"
+# 9431 "parser_cocci_menhir.ml"
         ) = Obj.magic d in
         let _startpos = _startpos_d_ in
         let _endpos = _endpos_d_ in
         let _v : 'tv_edots_when_TEllipsis_initialize_ = 
-# 1794 "parser_cocci_menhir.mly"
+# 1795 "parser_cocci_menhir.mly"
                                                   ( (d,None) )
-# 9437 "parser_cocci_menhir.ml"
+# 9438 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9472,14 +9473,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let d : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 9476 "parser_cocci_menhir.ml"
+# 9477 "parser_cocci_menhir.ml"
         ) = Obj.magic d in
         let _startpos = _startpos_d_ in
         let _endpos = _endpos__5_ in
         let _v : 'tv_edots_when_TEllipsis_initialize_ = 
-# 1795 "parser_cocci_menhir.mly"
+# 1796 "parser_cocci_menhir.mly"
                                                   ( (d,Some w) )
-# 9483 "parser_cocci_menhir.ml"
+# 9484 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9500,14 +9501,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let d : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 9504 "parser_cocci_menhir.ml"
+# 9505 "parser_cocci_menhir.ml"
         ) = Obj.magic d in
         let _startpos = _startpos_d_ in
         let _endpos = _endpos_d_ in
         let _v : 'tv_edots_when_TEllipsis_struct_decl_ = 
-# 1794 "parser_cocci_menhir.mly"
+# 1795 "parser_cocci_menhir.mly"
                                                   ( (d,None) )
-# 9511 "parser_cocci_menhir.ml"
+# 9512 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9546,14 +9547,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let d : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 9550 "parser_cocci_menhir.ml"
+# 9551 "parser_cocci_menhir.ml"
         ) = Obj.magic d in
         let _startpos = _startpos_d_ in
         let _endpos = _endpos__5_ in
         let _v : 'tv_edots_when_TEllipsis_struct_decl_ = 
-# 1795 "parser_cocci_menhir.mly"
+# 1796 "parser_cocci_menhir.mly"
                                                   ( (d,Some w) )
-# 9557 "parser_cocci_menhir.ml"
+# 9558 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9575,9 +9576,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_eexpr = 
-# 1194 "parser_cocci_menhir.mly"
+# 1195 "parser_cocci_menhir.mly"
                                          ( _1 )
-# 9581 "parser_cocci_menhir.ml"
+# 9582 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9599,7 +9600,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_eexpr_list = 
-# 1738 "parser_cocci_menhir.mly"
+# 1739 "parser_cocci_menhir.mly"
      (let circle x =
        match Ast0.unwrap x with Ast0.Ecircles(_) -> true | _ -> false in
      let star x =
@@ -9610,7 +9611,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
        if List.exists star _1
        then Ast0.wrap(Ast0.STARS(_1))
        else Ast0.wrap(Ast0.DOTS(_1)) )
-# 9614 "parser_cocci_menhir.ml"
+# 9615 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9632,9 +9633,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_eexpr_list_option = 
-# 1777 "parser_cocci_menhir.mly"
+# 1778 "parser_cocci_menhir.mly"
                               ( _1 )
-# 9638 "parser_cocci_menhir.ml"
+# 9639 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9649,9 +9650,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
         let _endpos = _startpos in
         let _v : 'tv_eexpr_list_option = 
-# 1778 "parser_cocci_menhir.mly"
+# 1779 "parser_cocci_menhir.mly"
                            ( Ast0.wrap(Ast0.DOTS([])) )
-# 9655 "parser_cocci_menhir.ml"
+# 9656 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9673,9 +9674,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_eexpr_list_start = 
-# 1765 "parser_cocci_menhir.mly"
+# 1766 "parser_cocci_menhir.mly"
           ( [_1] )
-# 9679 "parser_cocci_menhir.ml"
+# 9680 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9707,15 +9708,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 9711 "parser_cocci_menhir.ml"
+# 9712 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_aexpr = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_eexpr_list_start = 
-# 1767 "parser_cocci_menhir.mly"
+# 1768 "parser_cocci_menhir.mly"
       ( _1::Ast0.wrap(Ast0.EComma(P.clt2mcode "," _2))::_3 )
-# 9719 "parser_cocci_menhir.ml"
+# 9720 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9757,9 +9758,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__6_ in
         let _v : 'tv_error_words = 
-# 1564 "parser_cocci_menhir.mly"
+# 1565 "parser_cocci_menhir.mly"
       ( [Ast0.wrap(Ast0.ERRORWORDS(cl))] )
-# 9763 "parser_cocci_menhir.ml"
+# 9764 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9781,7 +9782,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_exists = 
 # 239 "parser_cocci_menhir.mly"
           ( Ast.Exists )
-# 9785 "parser_cocci_menhir.ml"
+# 9786 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9803,7 +9804,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_exists = 
 # 240 "parser_cocci_menhir.mly"
           ( Ast.Forall )
-# 9807 "parser_cocci_menhir.ml"
+# 9808 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9829,7 +9830,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_exists = 
 # 241 "parser_cocci_menhir.mly"
                    ( Ast.ReverseForall )
-# 9833 "parser_cocci_menhir.ml"
+# 9834 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9846,7 +9847,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_exists = 
 # 242 "parser_cocci_menhir.mly"
           ( Ast.Undetermined )
-# 9850 "parser_cocci_menhir.ml"
+# 9851 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9868,9 +9869,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_expr = 
-# 1192 "parser_cocci_menhir.mly"
+# 1193 "parser_cocci_menhir.mly"
                                 ( _1 )
-# 9874 "parser_cocci_menhir.ml"
+# 9875 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9892,9 +9893,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_r_ in
         let _endpos = _endpos_r_ in
         let _v : 'tv_expr_dots_TEllipsis_ = 
-# 1374 "parser_cocci_menhir.mly"
+# 1375 "parser_cocci_menhir.mly"
                                                        ( r )
-# 9898 "parser_cocci_menhir.ml"
+# 9899 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9911,7 +9912,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_extends = 
 # 212 "parser_cocci_menhir.mly"
                                                   ( () )
-# 9915 "parser_cocci_menhir.ml"
+# 9916 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9936,14 +9937,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let parent : (
 # 47 "parser_cocci_menhir.mly"
       (string)
-# 9940 "parser_cocci_menhir.ml"
+# 9941 "parser_cocci_menhir.ml"
         ) = Obj.magic parent in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_parent_ in
         let _v : 'tv_extends = 
 # 214 "parser_cocci_menhir.mly"
     ( !Data.install_bindings (parent) )
-# 9947 "parser_cocci_menhir.ml"
+# 9948 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -9969,12 +9970,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 83 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 9973 "parser_cocci_menhir.ml"
+# 9974 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 83 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 9978 "parser_cocci_menhir.ml"
+# 9979 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
@@ -9983,7 +9984,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
     ( [Ast0.wrap
          (Ast0.FILEINFO(P.id2mcode _1,
                         P.id2mcode _2))] )
-# 9987 "parser_cocci_menhir.ml"
+# 9988 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10013,7 +10014,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_fn_ctype = 
 # 572 "parser_cocci_menhir.mly"
                                      ( P.pointerify ty m )
-# 10017 "parser_cocci_menhir.ml"
+# 10018 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10040,7 +10041,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let t : (
 # 50 "parser_cocci_menhir.mly"
       (Data.clt)
-# 10044 "parser_cocci_menhir.ml"
+# 10045 "parser_cocci_menhir.ml"
         ) = Obj.magic t in
         let _startpos = _startpos_t_ in
         let _endpos = _endpos_m_ in
@@ -10049,7 +10050,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
          ( P.pointerify
             (Ast0.wrap(Ast0.BaseType(Ast.VoidType,[P.clt2mcode "void" t])))
             m )
-# 10053 "parser_cocci_menhir.ml"
+# 10054 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10064,9 +10065,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_fninfo = 
-# 766 "parser_cocci_menhir.mly"
+# 767 "parser_cocci_menhir.mly"
                 ( [] )
-# 10070 "parser_cocci_menhir.ml"
+# 10071 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10094,13 +10095,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fninfo = 
-# 768 "parser_cocci_menhir.mly"
+# 769 "parser_cocci_menhir.mly"
       ( try
        let _ =
          List.find (function Ast0.FStorage(_) -> true | _ -> false) _2 in
        raise (Semantic_cocci.Semantic "duplicate storage")
       with Not_found -> (Ast0.FStorage(_1))::_2 )
-# 10104 "parser_cocci_menhir.ml"
+# 10105 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10128,9 +10129,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_t_ in
         let _endpos = _endpos_r_ in
         let _v : 'tv_fninfo = 
-# 773 "parser_cocci_menhir.mly"
+# 774 "parser_cocci_menhir.mly"
                            ( (Ast0.FType(t))::r )
-# 10134 "parser_cocci_menhir.ml"
+# 10135 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10157,17 +10158,17 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 53 "parser_cocci_menhir.mly"
       (Data.clt)
-# 10161 "parser_cocci_menhir.ml"
+# 10162 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fninfo = 
-# 775 "parser_cocci_menhir.mly"
+# 776 "parser_cocci_menhir.mly"
       ( 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 )
-# 10171 "parser_cocci_menhir.ml"
+# 10172 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10194,17 +10195,17 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 55 "parser_cocci_menhir.mly"
       (string * Data.clt)
-# 10198 "parser_cocci_menhir.ml"
+# 10199 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fninfo = 
-# 780 "parser_cocci_menhir.mly"
+# 781 "parser_cocci_menhir.mly"
       ( 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 )
-# 10208 "parser_cocci_menhir.ml"
+# 10209 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10219,9 +10220,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_fninfo_nt = 
-# 786 "parser_cocci_menhir.mly"
+# 787 "parser_cocci_menhir.mly"
                 ( [] )
-# 10225 "parser_cocci_menhir.ml"
+# 10226 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10249,13 +10250,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fninfo_nt = 
-# 788 "parser_cocci_menhir.mly"
+# 789 "parser_cocci_menhir.mly"
       ( try
        let _ =
          List.find (function Ast0.FStorage(_) -> true | _ -> false) _2 in
        raise (Semantic_cocci.Semantic "duplicate storage")
       with Not_found -> (Ast0.FStorage(_1))::_2 )
-# 10259 "parser_cocci_menhir.ml"
+# 10260 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10282,17 +10283,17 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 53 "parser_cocci_menhir.mly"
       (Data.clt)
-# 10286 "parser_cocci_menhir.ml"
+# 10287 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fninfo_nt = 
-# 794 "parser_cocci_menhir.mly"
+# 795 "parser_cocci_menhir.mly"
       ( 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 )
-# 10296 "parser_cocci_menhir.ml"
+# 10297 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10319,17 +10320,17 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 55 "parser_cocci_menhir.mly"
       (string * Data.clt)
-# 10323 "parser_cocci_menhir.ml"
+# 10324 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fninfo_nt = 
-# 799 "parser_cocci_menhir.mly"
+# 800 "parser_cocci_menhir.mly"
       ( 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 )
-# 10333 "parser_cocci_menhir.ml"
+# 10334 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10344,9 +10345,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
         let _endpos = _startpos in
         let _v : 'tv_fun_after_dots = 
-# 1686 "parser_cocci_menhir.mly"
+# 1687 "parser_cocci_menhir.mly"
                                ([])
-# 10350 "parser_cocci_menhir.ml"
+# 10351 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10372,9 +10373,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fun_after_dots = 
-# 1687 "parser_cocci_menhir.mly"
+# 1688 "parser_cocci_menhir.mly"
                                (_2)
-# 10378 "parser_cocci_menhir.ml"
+# 10379 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10402,9 +10403,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fun_after_dots = 
-# 1688 "parser_cocci_menhir.mly"
+# 1689 "parser_cocci_menhir.mly"
                                (Ast0.wrap(Ast0.Exp(_1))::_2)
-# 10408 "parser_cocci_menhir.ml"
+# 10409 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10432,9 +10433,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fun_after_dots = 
-# 1689 "parser_cocci_menhir.mly"
+# 1690 "parser_cocci_menhir.mly"
                                     (_1@_2)
-# 10438 "parser_cocci_menhir.ml"
+# 10439 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10449,9 +10450,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
         let _endpos = _startpos in
         let _v : 'tv_fun_after_dots_or = 
-# 1696 "parser_cocci_menhir.mly"
+# 1697 "parser_cocci_menhir.mly"
                                ([])
-# 10455 "parser_cocci_menhir.ml"
+# 10456 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10477,9 +10478,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fun_after_dots_or = 
-# 1697 "parser_cocci_menhir.mly"
+# 1698 "parser_cocci_menhir.mly"
                                (_2)
-# 10483 "parser_cocci_menhir.ml"
+# 10484 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10507,9 +10508,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fun_after_dots_or = 
-# 1698 "parser_cocci_menhir.mly"
+# 1699 "parser_cocci_menhir.mly"
                                (Ast0.wrap(Ast0.Exp(_1))::_2)
-# 10513 "parser_cocci_menhir.ml"
+# 10514 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10537,9 +10538,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fun_after_dots_or = 
-# 1699 "parser_cocci_menhir.mly"
+# 1700 "parser_cocci_menhir.mly"
                                     (_1@_2)
-# 10543 "parser_cocci_menhir.ml"
+# 10544 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10567,9 +10568,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fun_after_exp = 
-# 1692 "parser_cocci_menhir.mly"
+# 1693 "parser_cocci_menhir.mly"
                                (_1::_2)
-# 10573 "parser_cocci_menhir.ml"
+# 10574 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10584,9 +10585,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
         let _endpos = _startpos in
         let _v : 'tv_fun_after_exp_or = 
-# 1702 "parser_cocci_menhir.mly"
+# 1703 "parser_cocci_menhir.mly"
                                ([])
-# 10590 "parser_cocci_menhir.ml"
+# 10591 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10614,9 +10615,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fun_after_exp_or = 
-# 1703 "parser_cocci_menhir.mly"
+# 1704 "parser_cocci_menhir.mly"
                                (_1::_2)
-# 10620 "parser_cocci_menhir.ml"
+# 10621 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10631,9 +10632,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
         let _endpos = _startpos in
         let _v : 'tv_fun_after_stm = 
-# 1681 "parser_cocci_menhir.mly"
+# 1682 "parser_cocci_menhir.mly"
                                ([])
-# 10637 "parser_cocci_menhir.ml"
+# 10638 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10661,9 +10662,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fun_after_stm = 
-# 1682 "parser_cocci_menhir.mly"
+# 1683 "parser_cocci_menhir.mly"
                                (_1::_2)
-# 10667 "parser_cocci_menhir.ml"
+# 10668 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10691,9 +10692,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_fun_after_stm = 
-# 1683 "parser_cocci_menhir.mly"
+# 1684 "parser_cocci_menhir.mly"
                                (_1@_2)
-# 10697 "parser_cocci_menhir.ml"
+# 10698 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10715,9 +10716,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_fun_start = 
-# 1678 "parser_cocci_menhir.mly"
+# 1679 "parser_cocci_menhir.mly"
                  ( Ast0.wrap(Ast0.DOTS(_1)) )
-# 10721 "parser_cocci_menhir.ml"
+# 10722 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10739,9 +10740,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_func_ident = 
-# 1482 "parser_cocci_menhir.mly"
+# 1483 "parser_cocci_menhir.mly"
          ( Ast0.wrap(Ast0.Id(P.id2mcode _1)) )
-# 10745 "parser_cocci_menhir.ml"
+# 10746 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10762,15 +10763,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 61 "parser_cocci_menhir.mly"
        (Parse_aux.idinfo)
-# 10766 "parser_cocci_menhir.ml"
+# 10767 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_func_ident = 
-# 1484 "parser_cocci_menhir.mly"
+# 1485 "parser_cocci_menhir.mly"
          ( let (nm,constraints,pure,clt) = _1 in
         Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) )
-# 10774 "parser_cocci_menhir.ml"
+# 10775 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10791,15 +10792,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 61 "parser_cocci_menhir.mly"
        (Parse_aux.idinfo)
-# 10795 "parser_cocci_menhir.ml"
+# 10796 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_func_ident = 
-# 1487 "parser_cocci_menhir.mly"
+# 1488 "parser_cocci_menhir.mly"
          ( let (nm,constraints,pure,clt) = _1 in
         Ast0.wrap(Ast0.MetaFunc(P.clt2mcode nm clt,constraints,pure)) )
-# 10803 "parser_cocci_menhir.ml"
+# 10804 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10820,16 +10821,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 61 "parser_cocci_menhir.mly"
        (Parse_aux.idinfo)
-# 10824 "parser_cocci_menhir.ml"
+# 10825 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_func_ident = 
-# 1490 "parser_cocci_menhir.mly"
+# 1491 "parser_cocci_menhir.mly"
   ( let (nm,constraints,pure,clt) = _1 in
         Ast0.wrap
           (Ast0.MetaLocalFunc(P.clt2mcode nm clt,constraints,pure)) )
-# 10833 "parser_cocci_menhir.ml"
+# 10834 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10889,38 +10890,38 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let rb : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 10893 "parser_cocci_menhir.ml"
+# 10894 "parser_cocci_menhir.ml"
         ) = Obj.magic rb in
         let b : 'tv_fun_start = Obj.magic b in
         let lb : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 10899 "parser_cocci_menhir.ml"
+# 10900 "parser_cocci_menhir.ml"
         ) = Obj.magic lb in
         let rp : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 10904 "parser_cocci_menhir.ml"
+# 10905 "parser_cocci_menhir.ml"
         ) = Obj.magic rp in
         let d : 'tv_decl_list_decl_ = Obj.magic d in
         let lp : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 10910 "parser_cocci_menhir.ml"
+# 10911 "parser_cocci_menhir.ml"
         ) = Obj.magic lp in
         let i : 'tv_func_ident = Obj.magic i in
         let f : 'tv_fninfo = Obj.magic f in
         let _startpos = _startpos_f_ in
         let _endpos = _endpos_rb_ in
         let _v : 'tv_fundecl = 
-# 758 "parser_cocci_menhir.mly"
+# 759 "parser_cocci_menhir.mly"
       ( 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)) )
-# 10924 "parser_cocci_menhir.ml"
+# 10925 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -10966,18 +10967,18 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pt : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 10970 "parser_cocci_menhir.ml"
+# 10971 "parser_cocci_menhir.ml"
         ) = Obj.magic pt in
         let rp : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 10975 "parser_cocci_menhir.ml"
+# 10976 "parser_cocci_menhir.ml"
         ) = Obj.magic rp in
         let d : 'tv_decl_list_name_opt_decl_ = Obj.magic d in
         let lp : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 10981 "parser_cocci_menhir.ml"
+# 10982 "parser_cocci_menhir.ml"
         ) = Obj.magic lp in
         let id : 'tv_func_ident = Obj.magic id in
         let t : 'tv_ctype = Obj.magic t in
@@ -10987,11 +10988,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 39 "standard.mly"
     ( None )
-# 10991 "parser_cocci_menhir.ml"
+# 10992 "parser_cocci_menhir.ml"
           
         in
         
-# 735 "parser_cocci_menhir.mly"
+# 736 "parser_cocci_menhir.mly"
       ( Ast0.wrap
          (Ast0.UnInit
             (s,
@@ -10999,7 +11000,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
                (Ast0.FunctionType(Some t,
                                   P.clt2mcode "(" lp, d, P.clt2mcode ")" rp)),
              id, P.clt2mcode ";" pt)) )
-# 11003 "parser_cocci_menhir.ml"
+# 11004 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -11050,18 +11051,18 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pt : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 11054 "parser_cocci_menhir.ml"
+# 11055 "parser_cocci_menhir.ml"
         ) = Obj.magic pt in
         let rp : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 11059 "parser_cocci_menhir.ml"
+# 11060 "parser_cocci_menhir.ml"
         ) = Obj.magic rp in
         let d : 'tv_decl_list_name_opt_decl_ = Obj.magic d in
         let lp : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 11065 "parser_cocci_menhir.ml"
+# 11066 "parser_cocci_menhir.ml"
         ) = Obj.magic lp in
         let id : 'tv_func_ident = Obj.magic id in
         let t : 'tv_ctype = Obj.magic t in
@@ -11073,11 +11074,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 11077 "parser_cocci_menhir.ml"
+# 11078 "parser_cocci_menhir.ml"
           
         in
         
-# 735 "parser_cocci_menhir.mly"
+# 736 "parser_cocci_menhir.mly"
       ( Ast0.wrap
          (Ast0.UnInit
             (s,
@@ -11085,7 +11086,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
                (Ast0.FunctionType(Some t,
                                   P.clt2mcode "(" lp, d, P.clt2mcode ")" rp)),
              id, P.clt2mcode ";" pt)) )
-# 11089 "parser_cocci_menhir.ml"
+# 11090 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -11131,24 +11132,24 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pt : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 11135 "parser_cocci_menhir.ml"
+# 11136 "parser_cocci_menhir.ml"
         ) = Obj.magic pt in
         let rp : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 11140 "parser_cocci_menhir.ml"
+# 11141 "parser_cocci_menhir.ml"
         ) = Obj.magic rp in
         let d : 'tv_decl_list_name_opt_decl_ = Obj.magic d in
         let lp : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 11146 "parser_cocci_menhir.ml"
+# 11147 "parser_cocci_menhir.ml"
         ) = Obj.magic lp in
         let id : 'tv_func_ident = Obj.magic id in
         let t : (
 # 50 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11152 "parser_cocci_menhir.ml"
+# 11153 "parser_cocci_menhir.ml"
         ) = Obj.magic t in
         let _startpos = _startpos_t_ in
         let _endpos = _endpos_pt_ in
@@ -11156,11 +11157,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 39 "standard.mly"
     ( None )
-# 11160 "parser_cocci_menhir.ml"
+# 11161 "parser_cocci_menhir.ml"
           
         in
         
-# 744 "parser_cocci_menhir.mly"
+# 745 "parser_cocci_menhir.mly"
     ( let t = Ast0.wrap(Ast0.BaseType(Ast.VoidType,[P.clt2mcode "void" t])) in
       Ast0.wrap
         (Ast0.UnInit
@@ -11169,7 +11170,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
              (Ast0.FunctionType(Some t,
                                 P.clt2mcode "(" lp, d, P.clt2mcode ")" rp)),
            id, P.clt2mcode ";" pt)) )
-# 11173 "parser_cocci_menhir.ml"
+# 11174 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -11220,24 +11221,24 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pt : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 11224 "parser_cocci_menhir.ml"
+# 11225 "parser_cocci_menhir.ml"
         ) = Obj.magic pt in
         let rp : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 11229 "parser_cocci_menhir.ml"
+# 11230 "parser_cocci_menhir.ml"
         ) = Obj.magic rp in
         let d : 'tv_decl_list_name_opt_decl_ = Obj.magic d in
         let lp : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 11235 "parser_cocci_menhir.ml"
+# 11236 "parser_cocci_menhir.ml"
         ) = Obj.magic lp in
         let id : 'tv_func_ident = Obj.magic id in
         let t : (
 # 50 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11241 "parser_cocci_menhir.ml"
+# 11242 "parser_cocci_menhir.ml"
         ) = Obj.magic t in
         let x0 : 'tv_storage = Obj.magic x0 in
         let _startpos = _startpos_x0_ in
@@ -11247,11 +11248,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 11251 "parser_cocci_menhir.ml"
+# 11252 "parser_cocci_menhir.ml"
           
         in
         
-# 744 "parser_cocci_menhir.mly"
+# 745 "parser_cocci_menhir.mly"
     ( let t = Ast0.wrap(Ast0.BaseType(Ast.VoidType,[P.clt2mcode "void" t])) in
       Ast0.wrap
         (Ast0.UnInit
@@ -11260,7 +11261,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
              (Ast0.FunctionType(Some t,
                                 P.clt2mcode "(" lp, d, P.clt2mcode ")" rp)),
            id, P.clt2mcode ";" pt)) )
-# 11264 "parser_cocci_menhir.ml"
+# 11265 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -11281,7 +11282,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let r0 : (
 # 51 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11285 "parser_cocci_menhir.ml"
+# 11286 "parser_cocci_menhir.ml"
         ) = Obj.magic r0 in
         let _startpos = _startpos_r0_ in
         let _endpos = _endpos_r0_ in
@@ -11290,13 +11291,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 580 "parser_cocci_menhir.mly"
    ( function x -> Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Unsigned r,x)) )
-# 11294 "parser_cocci_menhir.ml"
+# 11295 "parser_cocci_menhir.ml"
           
         in
         
 # 504 "parser_cocci_menhir.mly"
                           ( q None )
-# 11300 "parser_cocci_menhir.ml"
+# 11301 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -11317,7 +11318,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let r0 : (
 # 51 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11321 "parser_cocci_menhir.ml"
+# 11322 "parser_cocci_menhir.ml"
         ) = Obj.magic r0 in
         let _startpos = _startpos_r0_ in
         let _endpos = _endpos_r0_ in
@@ -11326,13 +11327,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 582 "parser_cocci_menhir.mly"
    ( function x -> Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Signed r,x)) )
-# 11330 "parser_cocci_menhir.ml"
+# 11331 "parser_cocci_menhir.ml"
           
         in
         
 # 504 "parser_cocci_menhir.mly"
                           ( q None )
-# 11336 "parser_cocci_menhir.ml"
+# 11337 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -11356,7 +11357,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_generic_ctype = 
 # 505 "parser_cocci_menhir.mly"
                           ( _1 )
-# 11360 "parser_cocci_menhir.ml"
+# 11361 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -11382,12 +11383,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let ty : (
 # 49 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11386 "parser_cocci_menhir.ml"
+# 11387 "parser_cocci_menhir.ml"
         ) = Obj.magic ty in
         let r00 : (
 # 51 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11391 "parser_cocci_menhir.ml"
+# 11392 "parser_cocci_menhir.ml"
         ) = Obj.magic r00 in
         let _startpos = _startpos_r00_ in
         let _endpos = _endpos_ty_ in
@@ -11398,19 +11399,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             
 # 580 "parser_cocci_menhir.mly"
    ( function x -> Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Unsigned r,x)) )
-# 11402 "parser_cocci_menhir.ml"
+# 11403 "parser_cocci_menhir.ml"
             
           in
           
 # 585 "parser_cocci_menhir.mly"
                   ( function x -> s (Some x) )
-# 11408 "parser_cocci_menhir.ml"
+# 11409 "parser_cocci_menhir.ml"
           
         in
         
 # 457 "parser_cocci_menhir.mly"
         ( q (Ast0.wrap(Ast0.BaseType(Ast.CharType,[P.clt2mcode "char" ty]))) )
-# 11414 "parser_cocci_menhir.ml"
+# 11415 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -11436,12 +11437,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let ty : (
 # 49 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11440 "parser_cocci_menhir.ml"
+# 11441 "parser_cocci_menhir.ml"
         ) = Obj.magic ty in
         let r00 : (
 # 51 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11445 "parser_cocci_menhir.ml"
+# 11446 "parser_cocci_menhir.ml"
         ) = Obj.magic r00 in
         let _startpos = _startpos_r00_ in
         let _endpos = _endpos_ty_ in
@@ -11452,19 +11453,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             
 # 582 "parser_cocci_menhir.mly"
    ( function x -> Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Signed r,x)) )
-# 11456 "parser_cocci_menhir.ml"
+# 11457 "parser_cocci_menhir.ml"
             
           in
           
 # 585 "parser_cocci_menhir.mly"
                   ( function x -> s (Some x) )
-# 11462 "parser_cocci_menhir.ml"
+# 11463 "parser_cocci_menhir.ml"
           
         in
         
 # 457 "parser_cocci_menhir.mly"
         ( q (Ast0.wrap(Ast0.BaseType(Ast.CharType,[P.clt2mcode "char" ty]))) )
-# 11468 "parser_cocci_menhir.ml"
+# 11469 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -11485,7 +11486,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let ty : (
 # 49 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11489 "parser_cocci_menhir.ml"
+# 11490 "parser_cocci_menhir.ml"
         ) = Obj.magic ty in
         let _startpos = _startpos_ty_ in
         let _endpos = _endpos_ty_ in
@@ -11493,13 +11494,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 586 "parser_cocci_menhir.mly"
                 ( function x -> x )
-# 11497 "parser_cocci_menhir.ml"
+# 11498 "parser_cocci_menhir.ml"
           
         in
         
 # 457 "parser_cocci_menhir.mly"
         ( q (Ast0.wrap(Ast0.BaseType(Ast.CharType,[P.clt2mcode "char" ty]))) )
-# 11503 "parser_cocci_menhir.ml"
+# 11504 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -11525,12 +11526,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let ty : (
 # 49 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11529 "parser_cocci_menhir.ml"
+# 11530 "parser_cocci_menhir.ml"
         ) = Obj.magic ty in
         let r00 : (
 # 51 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11534 "parser_cocci_menhir.ml"
+# 11535 "parser_cocci_menhir.ml"
         ) = Obj.magic r00 in
         let _startpos = _startpos_r00_ in
         let _endpos = _endpos_ty_ in
@@ -11541,19 +11542,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             
 # 580 "parser_cocci_menhir.mly"
    ( function x -> Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Unsigned r,x)) )
-# 11545 "parser_cocci_menhir.ml"
+# 11546 "parser_cocci_menhir.ml"
             
           in
           
 # 585 "parser_cocci_menhir.mly"
                   ( function x -> s (Some x) )
-# 11551 "parser_cocci_menhir.ml"
+# 11552 "parser_cocci_menhir.ml"
           
         in
         
 # 459 "parser_cocci_menhir.mly"
         ( q (Ast0.wrap(Ast0.BaseType(Ast.ShortType,[P.clt2mcode "short" ty]))))
-# 11557 "parser_cocci_menhir.ml"
+# 11558 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -11579,12 +11580,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let ty : (
 # 49 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11583 "parser_cocci_menhir.ml"
+# 11584 "parser_cocci_menhir.ml"
         ) = Obj.magic ty in
         let r00 : (
 # 51 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11588 "parser_cocci_menhir.ml"
+# 11589 "parser_cocci_menhir.ml"
         ) = Obj.magic r00 in
         let _startpos = _startpos_r00_ in
         let _endpos = _endpos_ty_ in
@@ -11595,19 +11596,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             
 # 582 "parser_cocci_menhir.mly"
    ( function x -> Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Signed r,x)) )
-# 11599 "parser_cocci_menhir.ml"
+# 11600 "parser_cocci_menhir.ml"
             
           in
           
 # 585 "parser_cocci_menhir.mly"
                   ( function x -> s (Some x) )
-# 11605 "parser_cocci_menhir.ml"
+# 11606 "parser_cocci_menhir.ml"
           
         in
         
 # 459 "parser_cocci_menhir.mly"
         ( q (Ast0.wrap(Ast0.BaseType(Ast.ShortType,[P.clt2mcode "short" ty]))))
-# 11611 "parser_cocci_menhir.ml"
+# 11612 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -11628,7 +11629,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let ty : (
 # 49 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11632 "parser_cocci_menhir.ml"
+# 11633 "parser_cocci_menhir.ml"
         ) = Obj.magic ty in
         let _startpos = _startpos_ty_ in
         let _endpos = _endpos_ty_ in
@@ -11636,13 +11637,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 586 "parser_cocci_menhir.mly"
                 ( function x -> x )
-# 11640 "parser_cocci_menhir.ml"
+# 11641 "parser_cocci_menhir.ml"
           
         in
         
 # 459 "parser_cocci_menhir.mly"
         ( q (Ast0.wrap(Ast0.BaseType(Ast.ShortType,[P.clt2mcode "short" ty]))))
-# 11646 "parser_cocci_menhir.ml"
+# 11647 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -11668,12 +11669,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let ty : (
 # 49 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11672 "parser_cocci_menhir.ml"
+# 11673 "parser_cocci_menhir.ml"
         ) = Obj.magic ty in
         let r00 : (
 # 51 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11677 "parser_cocci_menhir.ml"
+# 11678 "parser_cocci_menhir.ml"
         ) = Obj.magic r00 in
         let _startpos = _startpos_r00_ in
         let _endpos = _endpos_ty_ in
@@ -11684,19 +11685,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             
 # 580 "parser_cocci_menhir.mly"
    ( function x -> Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Unsigned r,x)) )
-# 11688 "parser_cocci_menhir.ml"
+# 11689 "parser_cocci_menhir.ml"
             
           in
           
 # 585 "parser_cocci_menhir.mly"
                   ( function x -> s (Some x) )
-# 11694 "parser_cocci_menhir.ml"
+# 11695 "parser_cocci_menhir.ml"
           
         in
         
 # 461 "parser_cocci_menhir.mly"
          ( q (Ast0.wrap(Ast0.BaseType(Ast.IntType,[P.clt2mcode "int" ty]))) )
-# 11700 "parser_cocci_menhir.ml"
+# 11701 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -11722,12 +11723,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let ty : (
 # 49 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11726 "parser_cocci_menhir.ml"
+# 11727 "parser_cocci_menhir.ml"
         ) = Obj.magic ty in
         let r00 : (
 # 51 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11731 "parser_cocci_menhir.ml"
+# 11732 "parser_cocci_menhir.ml"
         ) = Obj.magic r00 in
         let _startpos = _startpos_r00_ in
         let _endpos = _endpos_ty_ in
@@ -11738,19 +11739,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             
 # 582 "parser_cocci_menhir.mly"
    ( function x -> Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Signed r,x)) )
-# 11742 "parser_cocci_menhir.ml"
+# 11743 "parser_cocci_menhir.ml"
             
           in
           
 # 585 "parser_cocci_menhir.mly"
                   ( function x -> s (Some x) )
-# 11748 "parser_cocci_menhir.ml"
+# 11749 "parser_cocci_menhir.ml"
           
         in
         
 # 461 "parser_cocci_menhir.mly"
          ( q (Ast0.wrap(Ast0.BaseType(Ast.IntType,[P.clt2mcode "int" ty]))) )
-# 11754 "parser_cocci_menhir.ml"
+# 11755 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -11771,7 +11772,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let ty : (
 # 49 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11775 "parser_cocci_menhir.ml"
+# 11776 "parser_cocci_menhir.ml"
         ) = Obj.magic ty in
         let _startpos = _startpos_ty_ in
         let _endpos = _endpos_ty_ in
@@ -11779,13 +11780,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 586 "parser_cocci_menhir.mly"
                 ( function x -> x )
-# 11783 "parser_cocci_menhir.ml"
+# 11784 "parser_cocci_menhir.ml"
           
         in
         
 # 461 "parser_cocci_menhir.mly"
          ( q (Ast0.wrap(Ast0.BaseType(Ast.IntType,[P.clt2mcode "int" ty]))) )
-# 11789 "parser_cocci_menhir.ml"
+# 11790 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -11806,14 +11807,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let t : (
 # 49 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11810 "parser_cocci_menhir.ml"
+# 11811 "parser_cocci_menhir.ml"
         ) = Obj.magic t in
         let _startpos = _startpos_t_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_generic_ctype_full = 
 # 463 "parser_cocci_menhir.mly"
          ( Ast0.wrap(Ast0.BaseType(Ast.DoubleType,[P.clt2mcode "double" t])) )
-# 11817 "parser_cocci_menhir.ml"
+# 11818 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -11834,14 +11835,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let t : (
 # 49 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11838 "parser_cocci_menhir.ml"
+# 11839 "parser_cocci_menhir.ml"
         ) = Obj.magic t in
         let _startpos = _startpos_t_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_generic_ctype_full = 
 # 465 "parser_cocci_menhir.mly"
          ( Ast0.wrap(Ast0.BaseType(Ast.FloatType,[P.clt2mcode "float" t])) )
-# 11845 "parser_cocci_menhir.ml"
+# 11846 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -11867,12 +11868,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let ty : (
 # 49 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11871 "parser_cocci_menhir.ml"
+# 11872 "parser_cocci_menhir.ml"
         ) = Obj.magic ty in
         let r00 : (
 # 51 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11876 "parser_cocci_menhir.ml"
+# 11877 "parser_cocci_menhir.ml"
         ) = Obj.magic r00 in
         let _startpos = _startpos_r00_ in
         let _endpos = _endpos_ty_ in
@@ -11883,19 +11884,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             
 # 580 "parser_cocci_menhir.mly"
    ( function x -> Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Unsigned r,x)) )
-# 11887 "parser_cocci_menhir.ml"
+# 11888 "parser_cocci_menhir.ml"
             
           in
           
 # 585 "parser_cocci_menhir.mly"
                   ( function x -> s (Some x) )
-# 11893 "parser_cocci_menhir.ml"
+# 11894 "parser_cocci_menhir.ml"
           
         in
         
 # 467 "parser_cocci_menhir.mly"
          ( q (Ast0.wrap(Ast0.BaseType(Ast.LongType,[P.clt2mcode "long" ty]))) )
-# 11899 "parser_cocci_menhir.ml"
+# 11900 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -11921,12 +11922,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let ty : (
 # 49 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11925 "parser_cocci_menhir.ml"
+# 11926 "parser_cocci_menhir.ml"
         ) = Obj.magic ty in
         let r00 : (
 # 51 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11930 "parser_cocci_menhir.ml"
+# 11931 "parser_cocci_menhir.ml"
         ) = Obj.magic r00 in
         let _startpos = _startpos_r00_ in
         let _endpos = _endpos_ty_ in
@@ -11937,19 +11938,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             
 # 582 "parser_cocci_menhir.mly"
    ( function x -> Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Signed r,x)) )
-# 11941 "parser_cocci_menhir.ml"
+# 11942 "parser_cocci_menhir.ml"
             
           in
           
 # 585 "parser_cocci_menhir.mly"
                   ( function x -> s (Some x) )
-# 11947 "parser_cocci_menhir.ml"
+# 11948 "parser_cocci_menhir.ml"
           
         in
         
 # 467 "parser_cocci_menhir.mly"
          ( q (Ast0.wrap(Ast0.BaseType(Ast.LongType,[P.clt2mcode "long" ty]))) )
-# 11953 "parser_cocci_menhir.ml"
+# 11954 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -11970,7 +11971,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let ty : (
 # 49 "parser_cocci_menhir.mly"
       (Data.clt)
-# 11974 "parser_cocci_menhir.ml"
+# 11975 "parser_cocci_menhir.ml"
         ) = Obj.magic ty in
         let _startpos = _startpos_ty_ in
         let _endpos = _endpos_ty_ in
@@ -11978,13 +11979,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 586 "parser_cocci_menhir.mly"
                 ( function x -> x )
-# 11982 "parser_cocci_menhir.ml"
+# 11983 "parser_cocci_menhir.ml"
           
         in
         
 # 467 "parser_cocci_menhir.mly"
          ( q (Ast0.wrap(Ast0.BaseType(Ast.LongType,[P.clt2mcode "long" ty]))) )
-# 11988 "parser_cocci_menhir.ml"
+# 11989 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12015,17 +12016,17 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let ty1 : (
 # 49 "parser_cocci_menhir.mly"
       (Data.clt)
-# 12019 "parser_cocci_menhir.ml"
+# 12020 "parser_cocci_menhir.ml"
         ) = Obj.magic ty1 in
         let ty : (
 # 49 "parser_cocci_menhir.mly"
       (Data.clt)
-# 12024 "parser_cocci_menhir.ml"
+# 12025 "parser_cocci_menhir.ml"
         ) = Obj.magic ty in
         let r00 : (
 # 51 "parser_cocci_menhir.mly"
       (Data.clt)
-# 12029 "parser_cocci_menhir.ml"
+# 12030 "parser_cocci_menhir.ml"
         ) = Obj.magic r00 in
         let _startpos = _startpos_r00_ in
         let _endpos = _endpos_ty1_ in
@@ -12036,13 +12037,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             
 # 580 "parser_cocci_menhir.mly"
    ( function x -> Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Unsigned r,x)) )
-# 12040 "parser_cocci_menhir.ml"
+# 12041 "parser_cocci_menhir.ml"
             
           in
           
 # 585 "parser_cocci_menhir.mly"
                   ( function x -> s (Some x) )
-# 12046 "parser_cocci_menhir.ml"
+# 12047 "parser_cocci_menhir.ml"
           
         in
         
@@ -12051,7 +12052,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
                (Ast0.BaseType
                   (Ast.LongLongType,
                      [P.clt2mcode "long" ty;P.clt2mcode "long" ty1]))) )
-# 12055 "parser_cocci_menhir.ml"
+# 12056 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12082,17 +12083,17 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let ty1 : (
 # 49 "parser_cocci_menhir.mly"
       (Data.clt)
-# 12086 "parser_cocci_menhir.ml"
+# 12087 "parser_cocci_menhir.ml"
         ) = Obj.magic ty1 in
         let ty : (
 # 49 "parser_cocci_menhir.mly"
       (Data.clt)
-# 12091 "parser_cocci_menhir.ml"
+# 12092 "parser_cocci_menhir.ml"
         ) = Obj.magic ty in
         let r00 : (
 # 51 "parser_cocci_menhir.mly"
       (Data.clt)
-# 12096 "parser_cocci_menhir.ml"
+# 12097 "parser_cocci_menhir.ml"
         ) = Obj.magic r00 in
         let _startpos = _startpos_r00_ in
         let _endpos = _endpos_ty1_ in
@@ -12103,13 +12104,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             
 # 582 "parser_cocci_menhir.mly"
    ( function x -> Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Signed r,x)) )
-# 12107 "parser_cocci_menhir.ml"
+# 12108 "parser_cocci_menhir.ml"
             
           in
           
 # 585 "parser_cocci_menhir.mly"
                   ( function x -> s (Some x) )
-# 12113 "parser_cocci_menhir.ml"
+# 12114 "parser_cocci_menhir.ml"
           
         in
         
@@ -12118,7 +12119,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
                (Ast0.BaseType
                   (Ast.LongLongType,
                      [P.clt2mcode "long" ty;P.clt2mcode "long" ty1]))) )
-# 12122 "parser_cocci_menhir.ml"
+# 12123 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12144,12 +12145,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let ty1 : (
 # 49 "parser_cocci_menhir.mly"
       (Data.clt)
-# 12148 "parser_cocci_menhir.ml"
+# 12149 "parser_cocci_menhir.ml"
         ) = Obj.magic ty1 in
         let ty : (
 # 49 "parser_cocci_menhir.mly"
       (Data.clt)
-# 12153 "parser_cocci_menhir.ml"
+# 12154 "parser_cocci_menhir.ml"
         ) = Obj.magic ty in
         let _startpos = _startpos_ty_ in
         let _endpos = _endpos_ty1_ in
@@ -12157,7 +12158,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 586 "parser_cocci_menhir.mly"
                 ( function x -> x )
-# 12161 "parser_cocci_menhir.ml"
+# 12162 "parser_cocci_menhir.ml"
           
         in
         
@@ -12166,7 +12167,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
                (Ast0.BaseType
                   (Ast.LongLongType,
                      [P.clt2mcode "long" ty;P.clt2mcode "long" ty1]))) )
-# 12170 "parser_cocci_menhir.ml"
+# 12171 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12193,14 +12194,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let s : (
 # 50 "parser_cocci_menhir.mly"
       (Data.clt)
-# 12197 "parser_cocci_menhir.ml"
+# 12198 "parser_cocci_menhir.ml"
         ) = Obj.magic s in
         let _startpos = _startpos_s_ in
         let _endpos = _endpos_i_ in
         let _v : 'tv_generic_ctype_full = 
 # 474 "parser_cocci_menhir.mly"
   ( Ast0.wrap(Ast0.EnumName(P.clt2mcode "enum" s, i)) )
-# 12204 "parser_cocci_menhir.ml"
+# 12205 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12230,7 +12231,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_generic_ctype_full = 
 # 476 "parser_cocci_menhir.mly"
   ( Ast0.wrap(Ast0.StructUnionName(s, Some i)) )
-# 12234 "parser_cocci_menhir.ml"
+# 12235 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12266,13 +12267,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let r : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 12270 "parser_cocci_menhir.ml"
+# 12271 "parser_cocci_menhir.ml"
         ) = Obj.magic r in
         let d : 'tv_struct_decl_list = Obj.magic d in
         let l : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 12276 "parser_cocci_menhir.ml"
+# 12277 "parser_cocci_menhir.ml"
         ) = Obj.magic l in
         let s : 'tv_struct_or_union = Obj.magic s in
         let _startpos = _startpos_s_ in
@@ -12281,7 +12282,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 39 "standard.mly"
     ( None )
-# 12285 "parser_cocci_menhir.ml"
+# 12286 "parser_cocci_menhir.ml"
           
         in
         
@@ -12291,7 +12292,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
            Ast0.wrap(Ast0.StructUnionDef(Ast0.wrap(Ast0.StructUnionName(s, i)),
                                         P.clt2mcode "{" l,
                                         d, P.clt2mcode "}" r)) )
-# 12295 "parser_cocci_menhir.ml"
+# 12296 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12332,13 +12333,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let r : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 12336 "parser_cocci_menhir.ml"
+# 12337 "parser_cocci_menhir.ml"
         ) = Obj.magic r in
         let d : 'tv_struct_decl_list = Obj.magic d in
         let l : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 12342 "parser_cocci_menhir.ml"
+# 12343 "parser_cocci_menhir.ml"
         ) = Obj.magic l in
         let x0 : 'tv_ident = Obj.magic x0 in
         let s : 'tv_struct_or_union = Obj.magic s in
@@ -12349,7 +12350,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 12353 "parser_cocci_menhir.ml"
+# 12354 "parser_cocci_menhir.ml"
           
         in
         
@@ -12359,7 +12360,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
            Ast0.wrap(Ast0.StructUnionDef(Ast0.wrap(Ast0.StructUnionName(s, i)),
                                         P.clt2mcode "{" l,
                                         d, P.clt2mcode "}" r)) )
-# 12363 "parser_cocci_menhir.ml"
+# 12364 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12395,18 +12396,18 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let r : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 12399 "parser_cocci_menhir.ml"
+# 12400 "parser_cocci_menhir.ml"
         ) = Obj.magic r in
         let d : 'tv_struct_decl_list = Obj.magic d in
         let l : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 12405 "parser_cocci_menhir.ml"
+# 12406 "parser_cocci_menhir.ml"
         ) = Obj.magic l in
         let s : (
 # 64 "parser_cocci_menhir.mly"
        (Parse_aux.info)
-# 12410 "parser_cocci_menhir.ml"
+# 12411 "parser_cocci_menhir.ml"
         ) = Obj.magic s in
         let _startpos = _startpos_s_ in
         let _endpos = _endpos_r_ in
@@ -12417,7 +12418,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           Ast0.wrap(Ast0.MetaType(P.clt2mcode nm clt,pure)) in
         Ast0.wrap
           (Ast0.StructUnionDef(ty,P.clt2mcode "{" l,d,P.clt2mcode "}" r)) )
-# 12421 "parser_cocci_menhir.ml"
+# 12422 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12447,12 +12448,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let p : (
 # 59 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 12451 "parser_cocci_menhir.ml"
+# 12452 "parser_cocci_menhir.ml"
         ) = Obj.magic p in
         let r : (
 # 47 "parser_cocci_menhir.mly"
       (string)
-# 12456 "parser_cocci_menhir.ml"
+# 12457 "parser_cocci_menhir.ml"
         ) = Obj.magic r in
         let _startpos = _startpos_r_ in
         let _endpos = _endpos_p_ in
@@ -12464,7 +12465,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _ = P.check_meta(Ast.MetaTypeDecl(Ast.NONE,nm)) in
         Ast0.wrap(Ast0.MetaType(P.clt2mcode nm (P.id2clt p),
                                 Ast0.Impure (*will be ignored*))) )
-# 12468 "parser_cocci_menhir.ml"
+# 12469 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12485,14 +12486,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let p : (
 # 59 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 12489 "parser_cocci_menhir.ml"
+# 12490 "parser_cocci_menhir.ml"
         ) = Obj.magic p in
         let _startpos = _startpos_p_ in
         let _endpos = _endpos_p_ in
         let _v : 'tv_generic_ctype_full = 
 # 498 "parser_cocci_menhir.mly"
   ( Ast0.wrap(Ast0.TypeName(P.id2mcode p)) )
-# 12496 "parser_cocci_menhir.ml"
+# 12497 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12518,12 +12519,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let p : (
 # 64 "parser_cocci_menhir.mly"
        (Parse_aux.info)
-# 12522 "parser_cocci_menhir.ml"
+# 12523 "parser_cocci_menhir.ml"
         ) = Obj.magic p in
         let r00 : (
 # 51 "parser_cocci_menhir.mly"
       (Data.clt)
-# 12527 "parser_cocci_menhir.ml"
+# 12528 "parser_cocci_menhir.ml"
         ) = Obj.magic r00 in
         let _startpos = _startpos_r00_ in
         let _endpos = _endpos_p_ in
@@ -12534,20 +12535,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             
 # 580 "parser_cocci_menhir.mly"
    ( function x -> Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Unsigned r,x)) )
-# 12538 "parser_cocci_menhir.ml"
+# 12539 "parser_cocci_menhir.ml"
             
           in
           
 # 585 "parser_cocci_menhir.mly"
                   ( function x -> s (Some x) )
-# 12544 "parser_cocci_menhir.ml"
+# 12545 "parser_cocci_menhir.ml"
           
         in
         
 # 500 "parser_cocci_menhir.mly"
   ( let (nm,pure,clt) = p in
         q (Ast0.wrap(Ast0.MetaType(P.clt2mcode nm clt,pure))) )
-# 12551 "parser_cocci_menhir.ml"
+# 12552 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12573,12 +12574,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let p : (
 # 64 "parser_cocci_menhir.mly"
        (Parse_aux.info)
-# 12577 "parser_cocci_menhir.ml"
+# 12578 "parser_cocci_menhir.ml"
         ) = Obj.magic p in
         let r00 : (
 # 51 "parser_cocci_menhir.mly"
       (Data.clt)
-# 12582 "parser_cocci_menhir.ml"
+# 12583 "parser_cocci_menhir.ml"
         ) = Obj.magic r00 in
         let _startpos = _startpos_r00_ in
         let _endpos = _endpos_p_ in
@@ -12589,20 +12590,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             
 # 582 "parser_cocci_menhir.mly"
    ( function x -> Ast0.wrap(Ast0.Signed(P.clt2mcode Ast.Signed r,x)) )
-# 12593 "parser_cocci_menhir.ml"
+# 12594 "parser_cocci_menhir.ml"
             
           in
           
 # 585 "parser_cocci_menhir.mly"
                   ( function x -> s (Some x) )
-# 12599 "parser_cocci_menhir.ml"
+# 12600 "parser_cocci_menhir.ml"
           
         in
         
 # 500 "parser_cocci_menhir.mly"
   ( let (nm,pure,clt) = p in
         q (Ast0.wrap(Ast0.MetaType(P.clt2mcode nm clt,pure))) )
-# 12606 "parser_cocci_menhir.ml"
+# 12607 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12623,7 +12624,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let p : (
 # 64 "parser_cocci_menhir.mly"
        (Parse_aux.info)
-# 12627 "parser_cocci_menhir.ml"
+# 12628 "parser_cocci_menhir.ml"
         ) = Obj.magic p in
         let _startpos = _startpos_p_ in
         let _endpos = _endpos_p_ in
@@ -12631,14 +12632,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 586 "parser_cocci_menhir.mly"
                 ( function x -> x )
-# 12635 "parser_cocci_menhir.ml"
+# 12636 "parser_cocci_menhir.ml"
           
         in
         
 # 500 "parser_cocci_menhir.mly"
   ( let (nm,pure,clt) = p in
         q (Ast0.wrap(Ast0.MetaType(P.clt2mcode nm clt,pure))) )
-# 12642 "parser_cocci_menhir.ml"
+# 12643 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12660,9 +12661,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_ident = 
-# 1495 "parser_cocci_menhir.mly"
+# 1496 "parser_cocci_menhir.mly"
          ( Ast0.wrap(Ast0.Id(P.id2mcode _1)) )
-# 12666 "parser_cocci_menhir.ml"
+# 12667 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12683,15 +12684,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 61 "parser_cocci_menhir.mly"
        (Parse_aux.idinfo)
-# 12687 "parser_cocci_menhir.ml"
+# 12688 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_ident = 
-# 1497 "parser_cocci_menhir.mly"
+# 1498 "parser_cocci_menhir.mly"
          ( let (nm,constraints,pure,clt) = _1 in
          Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) )
-# 12695 "parser_cocci_menhir.ml"
+# 12696 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12713,9 +12714,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_i_ in
         let _endpos = _endpos_i_ in
         let _v : 'tv_ident_or_const = 
-# 1449 "parser_cocci_menhir.mly"
+# 1450 "parser_cocci_menhir.mly"
                     ( Ast0.wrap(Ast0.Ident(Ast0.wrap(Ast0.Id(P.id2mcode i)))) )
-# 12719 "parser_cocci_menhir.ml"
+# 12720 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12736,15 +12737,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 87 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 12740 "parser_cocci_menhir.ml"
+# 12741 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_ident_or_const = 
-# 1451 "parser_cocci_menhir.mly"
+# 1452 "parser_cocci_menhir.mly"
   ( let (x,clt) = _1 in
         Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) )
-# 12748 "parser_cocci_menhir.ml"
+# 12749 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12769,14 +12770,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 87 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 12773 "parser_cocci_menhir.ml"
+# 12774 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_incl = 
 # 253 "parser_cocci_menhir.mly"
                       ( Common.Left(P.id2name _2) )
-# 12780 "parser_cocci_menhir.ml"
+# 12781 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12801,14 +12802,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 79 "parser_cocci_menhir.mly"
        (string)
-# 12805 "parser_cocci_menhir.ml"
+# 12806 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_incl = 
 # 254 "parser_cocci_menhir.mly"
                       ( Common.Right _2 )
-# 12812 "parser_cocci_menhir.ml"
+# 12813 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12836,11 +12837,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 146 "parser_cocci_menhir.mly"
       ((string,string) Common.either list)
-# 12840 "parser_cocci_menhir.ml"
+# 12841 "parser_cocci_menhir.ml"
         ) = 
 # 249 "parser_cocci_menhir.mly"
                        ( _1 )
-# 12844 "parser_cocci_menhir.ml"
+# 12845 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12868,11 +12869,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 146 "parser_cocci_menhir.mly"
       ((string,string) Common.either list)
-# 12872 "parser_cocci_menhir.ml"
+# 12873 "parser_cocci_menhir.ml"
         ) = 
 # 250 "parser_cocci_menhir.mly"
                        ( _1 )
-# 12876 "parser_cocci_menhir.ml"
+# 12877 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12893,7 +12894,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 80 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 12897 "parser_cocci_menhir.ml"
+# 12898 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
@@ -12908,7 +12909,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
                            P.clt2mcode
                              (Ast.Local (Parse_aux.str2inc (P.id2name _1)))
                              (P.drop_bef clt))) )
-# 12912 "parser_cocci_menhir.ml"
+# 12913 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12929,7 +12930,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 80 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 12933 "parser_cocci_menhir.ml"
+# 12934 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
@@ -12944,7 +12945,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
                            P.clt2mcode
                              (Ast.NonLocal (Parse_aux.str2inc (P.id2name _1)))
                              (P.drop_bef clt))) )
-# 12948 "parser_cocci_menhir.ml"
+# 12949 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -12979,7 +12980,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
 # 649 "parser_cocci_menhir.mly"
     ( let ty = Ast0.wrap(Ast0.TopExp(Ast0.wrap(Ast0.TypeExp(t)))) in
       d (Ast0.wrap(Ast0.DOTS([ty]))) )
-# 12983 "parser_cocci_menhir.ml"
+# 12984 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13021,7 +13022,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
            | _ -> b)
        | _ -> b in
       _1 (Ast0.wrap(Ast0.DOTS(body))) )
-# 13025 "parser_cocci_menhir.ml"
+# 13026 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13043,9 +13044,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_initialize = 
-# 1064 "parser_cocci_menhir.mly"
+# 1065 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.InitExpr(_1)) )
-# 13049 "parser_cocci_menhir.ml"
+# 13050 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13076,20 +13077,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 13080 "parser_cocci_menhir.ml"
+# 13081 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_initialize_list = Obj.magic _2 in
         let _1 : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 13086 "parser_cocci_menhir.ml"
+# 13087 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_initialize = 
-# 1066 "parser_cocci_menhir.mly"
+# 1067 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.InitList(P.clt2mcode "{" _1,_2,P.clt2mcode "}" _3)) )
-# 13093 "parser_cocci_menhir.ml"
+# 13094 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13115,21 +13116,21 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 13119 "parser_cocci_menhir.ml"
+# 13120 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 13124 "parser_cocci_menhir.ml"
+# 13125 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_initialize = 
-# 1068 "parser_cocci_menhir.mly"
+# 1069 "parser_cocci_menhir.mly"
       ( Ast0.wrap
          (Ast0.InitList(P.clt2mcode "{" _1,Ast0.wrap(Ast0.DOTS []),
                         P.clt2mcode "}" _2)) )
-# 13133 "parser_cocci_menhir.ml"
+# 13134 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13150,15 +13151,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 65 "parser_cocci_menhir.mly"
        (Parse_aux.info)
-# 13154 "parser_cocci_menhir.ml"
+# 13155 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_initialize = 
-# 1072 "parser_cocci_menhir.mly"
+# 1073 "parser_cocci_menhir.mly"
       (let (nm,pure,clt) = _1 in
       Ast0.wrap(Ast0.MetaInit(P.clt2mcode nm clt,pure)) )
-# 13162 "parser_cocci_menhir.ml"
+# 13163 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13180,9 +13181,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_initialize2 = 
-# 1078 "parser_cocci_menhir.mly"
+# 1079 "parser_cocci_menhir.mly"
                             ( Ast0.wrap(Ast0.InitExpr(_1)) )
-# 13186 "parser_cocci_menhir.ml"
+# 13187 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13213,20 +13214,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 13217 "parser_cocci_menhir.ml"
+# 13218 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_initialize_list = Obj.magic _2 in
         let _1 : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 13223 "parser_cocci_menhir.ml"
+# 13224 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_initialize2 = 
-# 1080 "parser_cocci_menhir.mly"
+# 1081 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.InitList(P.clt2mcode "{" _1,_2,P.clt2mcode "}" _3)) )
-# 13230 "parser_cocci_menhir.ml"
+# 13231 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13252,21 +13253,21 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 13256 "parser_cocci_menhir.ml"
+# 13257 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 13261 "parser_cocci_menhir.ml"
+# 13262 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_initialize2 = 
-# 1082 "parser_cocci_menhir.mly"
+# 1083 "parser_cocci_menhir.mly"
     ( Ast0.wrap
        (Ast0.InitList(P.clt2mcode "{" _1,Ast0.wrap(Ast0.DOTS []),
                       P.clt2mcode "}" _2)) )
-# 13270 "parser_cocci_menhir.ml"
+# 13271 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13298,15 +13299,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 13302 "parser_cocci_menhir.ml"
+# 13303 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_list_designator_ = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_initialize2 = 
-# 1087 "parser_cocci_menhir.mly"
+# 1088 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.InitGccExt(_1,P.clt2mcode "=" _2,_3)) )
-# 13310 "parser_cocci_menhir.ml"
+# 13311 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13338,15 +13339,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 13342 "parser_cocci_menhir.ml"
+# 13343 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_ident = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_initialize2 = 
-# 1089 "parser_cocci_menhir.mly"
+# 1090 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.InitGccName(_1,P.clt2mcode ":" _2,_3)) )
-# 13350 "parser_cocci_menhir.ml"
+# 13351 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13368,9 +13369,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_initialize_list = 
-# 1101 "parser_cocci_menhir.mly"
+# 1102 "parser_cocci_menhir.mly"
                          ( Ast0.wrap(Ast0.DOTS(_1)) )
-# 13374 "parser_cocci_menhir.ml"
+# 13375 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13396,15 +13397,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 13400 "parser_cocci_menhir.ml"
+# 13401 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_initialize2 = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_initialize_list_start = 
-# 1104 "parser_cocci_menhir.mly"
+# 1105 "parser_cocci_menhir.mly"
                      ( [_1;Ast0.wrap(Ast0.IComma(P.clt2mcode "," _2))] )
-# 13408 "parser_cocci_menhir.ml"
+# 13409 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13436,15 +13437,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 13440 "parser_cocci_menhir.ml"
+# 13441 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_initialize2 = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_initialize_list_start = 
-# 1106 "parser_cocci_menhir.mly"
+# 1107 "parser_cocci_menhir.mly"
     ( _1::Ast0.wrap(Ast0.IComma(P.clt2mcode "," _2))::_3 )
-# 13448 "parser_cocci_menhir.ml"
+# 13449 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13472,10 +13473,10 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_d_ in
         let _endpos = _endpos_r_ in
         let _v : 'tv_initialize_list_start = 
-# 1109 "parser_cocci_menhir.mly"
+# 1110 "parser_cocci_menhir.mly"
     ( (P.mkidots "..." d)::
       (List.concat(List.map (function x -> x (P.mkidots "...")) r)) )
-# 13479 "parser_cocci_menhir.ml"
+# 13480 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13495,9 +13496,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_invalid = 
-# 1202 "parser_cocci_menhir.mly"
+# 1203 "parser_cocci_menhir.mly"
            ( raise (Semantic_cocci.Semantic "not matchable") )
-# 13501 "parser_cocci_menhir.ml"
+# 13502 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13514,7 +13515,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_is_expression = 
 # 245 "parser_cocci_menhir.mly"
               ( false )
-# 13518 "parser_cocci_menhir.ml"
+# 13519 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13536,7 +13537,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_is_expression = 
 # 246 "parser_cocci_menhir.mly"
               ( true )
-# 13540 "parser_cocci_menhir.ml"
+# 13541 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13562,9 +13563,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_iso_ctype_ = 
-# 1846 "parser_cocci_menhir.mly"
+# 1847 "parser_cocci_menhir.mly"
                 ( Common.Left t )
-# 13568 "parser_cocci_menhir.ml"
+# 13569 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13590,9 +13591,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_iso_ctype_ = 
-# 1847 "parser_cocci_menhir.mly"
+# 1848 "parser_cocci_menhir.mly"
                      ( Common.Right t )
-# 13596 "parser_cocci_menhir.ml"
+# 13597 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13618,9 +13619,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_iso_decl_var_ = 
-# 1846 "parser_cocci_menhir.mly"
+# 1847 "parser_cocci_menhir.mly"
                 ( Common.Left t )
-# 13624 "parser_cocci_menhir.ml"
+# 13625 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13646,9 +13647,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_iso_decl_var_ = 
-# 1847 "parser_cocci_menhir.mly"
+# 1848 "parser_cocci_menhir.mly"
                      ( Common.Right t )
-# 13652 "parser_cocci_menhir.ml"
+# 13653 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13674,9 +13675,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_iso_dexpr_ = 
-# 1846 "parser_cocci_menhir.mly"
+# 1847 "parser_cocci_menhir.mly"
                 ( Common.Left t )
-# 13680 "parser_cocci_menhir.ml"
+# 13681 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13702,9 +13703,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_iso_dexpr_ = 
-# 1847 "parser_cocci_menhir.mly"
+# 1848 "parser_cocci_menhir.mly"
                      ( Common.Right t )
-# 13708 "parser_cocci_menhir.ml"
+# 13709 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13730,9 +13731,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_iso_nest_start_ = 
-# 1846 "parser_cocci_menhir.mly"
+# 1847 "parser_cocci_menhir.mly"
                 ( Common.Left t )
-# 13736 "parser_cocci_menhir.ml"
+# 13737 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13758,9 +13759,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_iso_nest_start_ = 
-# 1847 "parser_cocci_menhir.mly"
+# 1848 "parser_cocci_menhir.mly"
                      ( Common.Right t )
-# 13764 "parser_cocci_menhir.ml"
+# 13765 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13786,9 +13787,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_iso_single_statement_ = 
-# 1846 "parser_cocci_menhir.mly"
+# 1847 "parser_cocci_menhir.mly"
                 ( Common.Left t )
-# 13792 "parser_cocci_menhir.ml"
+# 13793 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13814,9 +13815,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_iso_single_statement_ = 
-# 1847 "parser_cocci_menhir.mly"
+# 1848 "parser_cocci_menhir.mly"
                      ( Common.Right t )
-# 13820 "parser_cocci_menhir.ml"
+# 13821 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13854,11 +13855,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 162 "parser_cocci_menhir.mly"
       (Ast0_cocci.anything list list)
-# 13858 "parser_cocci_menhir.ml"
+# 13859 "parser_cocci_menhir.ml"
         ) = 
-# 1818 "parser_cocci_menhir.mly"
+# 1819 "parser_cocci_menhir.mly"
     ( P.iso_adjust (function x -> Ast0.ExprTag x) e1 el )
-# 13862 "parser_cocci_menhir.ml"
+# 13863 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13896,11 +13897,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 162 "parser_cocci_menhir.mly"
       (Ast0_cocci.anything list list)
-# 13900 "parser_cocci_menhir.ml"
+# 13901 "parser_cocci_menhir.ml"
         ) = 
-# 1820 "parser_cocci_menhir.mly"
+# 1821 "parser_cocci_menhir.mly"
     ( P.iso_adjust (function x -> Ast0.ArgExprTag x) e1 el )
-# 13904 "parser_cocci_menhir.ml"
+# 13905 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13938,11 +13939,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 162 "parser_cocci_menhir.mly"
       (Ast0_cocci.anything list list)
-# 13942 "parser_cocci_menhir.ml"
+# 13943 "parser_cocci_menhir.ml"
         ) = 
-# 1822 "parser_cocci_menhir.mly"
+# 1823 "parser_cocci_menhir.mly"
     ( P.iso_adjust (function x -> Ast0.TestExprTag x) e1 el )
-# 13946 "parser_cocci_menhir.ml"
+# 13947 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -13980,11 +13981,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 162 "parser_cocci_menhir.mly"
       (Ast0_cocci.anything list list)
-# 13984 "parser_cocci_menhir.ml"
+# 13985 "parser_cocci_menhir.ml"
         ) = 
-# 1824 "parser_cocci_menhir.mly"
+# 1825 "parser_cocci_menhir.mly"
     ( P.iso_adjust (function x -> Ast0.StmtTag x) s1 sl )
-# 13988 "parser_cocci_menhir.ml"
+# 13989 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14022,11 +14023,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 162 "parser_cocci_menhir.mly"
       (Ast0_cocci.anything list list)
-# 14026 "parser_cocci_menhir.ml"
+# 14027 "parser_cocci_menhir.ml"
         ) = 
-# 1826 "parser_cocci_menhir.mly"
+# 1827 "parser_cocci_menhir.mly"
     ( P.iso_adjust (function x -> Ast0.TypeCTag x) t1 tl )
-# 14030 "parser_cocci_menhir.ml"
+# 14031 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14064,11 +14065,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 162 "parser_cocci_menhir.mly"
       (Ast0_cocci.anything list list)
-# 14068 "parser_cocci_menhir.ml"
+# 14069 "parser_cocci_menhir.ml"
         ) = 
-# 1828 "parser_cocci_menhir.mly"
+# 1829 "parser_cocci_menhir.mly"
     ( P.iso_adjust (function x -> Ast0.DotsStmtTag x) e1 el )
-# 14072 "parser_cocci_menhir.ml"
+# 14073 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14106,9 +14107,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 162 "parser_cocci_menhir.mly"
       (Ast0_cocci.anything list list)
-# 14110 "parser_cocci_menhir.ml"
+# 14111 "parser_cocci_menhir.ml"
         ) = 
-# 1830 "parser_cocci_menhir.mly"
+# 1831 "parser_cocci_menhir.mly"
     ( let check_one = function
        [x] -> x
       | _ ->
@@ -14123,7 +14124,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
          | Common.Right x -> Common.Right(check_one x))
        dl in
     P.iso_adjust (function x -> Ast0.DeclTag x) d1 dl )
-# 14127 "parser_cocci_menhir.ml"
+# 14128 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14147,11 +14148,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 165 "parser_cocci_menhir.mly"
       ((Ast_cocci.metavar,Ast_cocci.metavar) Common.either list)
-# 14151 "parser_cocci_menhir.ml"
+# 14152 "parser_cocci_menhir.ml"
         ) = 
 # 182 "parser_cocci_menhir.mly"
                          ( m "" )
-# 14155 "parser_cocci_menhir.ml"
+# 14156 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14179,11 +14180,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 149 "parser_cocci_menhir.mly"
       (Ast_cocci.rulename)
-# 14183 "parser_cocci_menhir.ml"
+# 14184 "parser_cocci_menhir.ml"
         ) = 
 # 197 "parser_cocci_menhir.mly"
                       ( P.make_iso_rule_name_result (P.id2name nm) )
-# 14187 "parser_cocci_menhir.ml"
+# 14188 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14204,14 +14205,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 59 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 14208 "parser_cocci_menhir.ml"
+# 14209 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_iter_ident = 
-# 1509 "parser_cocci_menhir.mly"
+# 1510 "parser_cocci_menhir.mly"
          ( Ast0.wrap(Ast0.Id(P.id2mcode _1)) )
-# 14215 "parser_cocci_menhir.ml"
+# 14216 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14232,15 +14233,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 62 "parser_cocci_menhir.mly"
        (Parse_aux.idinfo)
-# 14236 "parser_cocci_menhir.ml"
+# 14237 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_iter_ident = 
-# 1511 "parser_cocci_menhir.mly"
+# 1512 "parser_cocci_menhir.mly"
          ( let (nm,constraints,pure,clt) = _1 in
          Ast0.wrap(Ast0.MetaId(P.clt2mcode nm clt,constraints,pure)) )
-# 14244 "parser_cocci_menhir.ml"
+# 14245 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14257,7 +14258,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_TMul_ = 
 # 114 "standard.mly"
     ( [] )
-# 14261 "parser_cocci_menhir.ml"
+# 14262 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14284,14 +14285,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let x : (
 # 99 "parser_cocci_menhir.mly"
        (Data.clt)
-# 14288 "parser_cocci_menhir.ml"
+# 14289 "parser_cocci_menhir.ml"
         ) = Obj.magic x in
         let _startpos = _startpos_x_ in
         let _endpos = _endpos_xs_ in
         let _v : 'tv_list_TMul_ = 
 # 116 "standard.mly"
     ( x :: xs )
-# 14295 "parser_cocci_menhir.ml"
+# 14296 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14308,7 +14309,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_array_dec_ = 
 # 114 "standard.mly"
     ( [] )
-# 14312 "parser_cocci_menhir.ml"
+# 14313 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14338,7 +14339,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_array_dec_ = 
 # 116 "standard.mly"
     ( x :: xs )
-# 14342 "parser_cocci_menhir.ml"
+# 14343 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14355,7 +14356,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_case_line_ = 
 # 114 "standard.mly"
     ( [] )
-# 14359 "parser_cocci_menhir.ml"
+# 14360 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14385,7 +14386,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_case_line_ = 
 # 116 "standard.mly"
     ( x :: xs )
-# 14389 "parser_cocci_menhir.ml"
+# 14390 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14402,7 +14403,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_comma_decls_TEllipsis_decl__ = 
 # 114 "standard.mly"
     ( [] )
-# 14406 "parser_cocci_menhir.ml"
+# 14407 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14432,7 +14433,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_comma_decls_TEllipsis_decl__ = 
 # 116 "standard.mly"
     ( x :: xs )
-# 14436 "parser_cocci_menhir.ml"
+# 14437 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14449,7 +14450,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_comma_decls_TEllipsis_name_opt_decl__ = 
 # 114 "standard.mly"
     ( [] )
-# 14453 "parser_cocci_menhir.ml"
+# 14454 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14479,7 +14480,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_comma_decls_TEllipsis_name_opt_decl__ = 
 # 116 "standard.mly"
     ( x :: xs )
-# 14483 "parser_cocci_menhir.ml"
+# 14484 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14496,7 +14497,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_designator_ = 
 # 114 "standard.mly"
     ( [] )
-# 14500 "parser_cocci_menhir.ml"
+# 14501 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14526,7 +14527,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_designator_ = 
 # 116 "standard.mly"
     ( x :: xs )
-# 14530 "parser_cocci_menhir.ml"
+# 14531 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14543,7 +14544,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_dp_comma_args_TEllipsis__ = 
 # 114 "standard.mly"
     ( [] )
-# 14547 "parser_cocci_menhir.ml"
+# 14548 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14573,7 +14574,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_dp_comma_args_TEllipsis__ = 
 # 116 "standard.mly"
     ( x :: xs )
-# 14577 "parser_cocci_menhir.ml"
+# 14578 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14590,7 +14591,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_incl_ = 
 # 114 "standard.mly"
     ( [] )
-# 14594 "parser_cocci_menhir.ml"
+# 14595 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14620,7 +14621,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_incl_ = 
 # 116 "standard.mly"
     ( x :: xs )
-# 14624 "parser_cocci_menhir.ml"
+# 14625 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14637,7 +14638,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_iso_ctype__ = 
 # 114 "standard.mly"
     ( [] )
-# 14641 "parser_cocci_menhir.ml"
+# 14642 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14667,7 +14668,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_iso_ctype__ = 
 # 116 "standard.mly"
     ( x :: xs )
-# 14671 "parser_cocci_menhir.ml"
+# 14672 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14684,7 +14685,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_iso_decl_var__ = 
 # 114 "standard.mly"
     ( [] )
-# 14688 "parser_cocci_menhir.ml"
+# 14689 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14714,7 +14715,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_iso_decl_var__ = 
 # 116 "standard.mly"
     ( x :: xs )
-# 14718 "parser_cocci_menhir.ml"
+# 14719 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14731,7 +14732,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_iso_dexpr__ = 
 # 114 "standard.mly"
     ( [] )
-# 14735 "parser_cocci_menhir.ml"
+# 14736 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14761,7 +14762,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_iso_dexpr__ = 
 # 116 "standard.mly"
     ( x :: xs )
-# 14765 "parser_cocci_menhir.ml"
+# 14766 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14778,7 +14779,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_iso_nest_start__ = 
 # 114 "standard.mly"
     ( [] )
-# 14782 "parser_cocci_menhir.ml"
+# 14783 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14808,7 +14809,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_iso_nest_start__ = 
 # 116 "standard.mly"
     ( x :: xs )
-# 14812 "parser_cocci_menhir.ml"
+# 14813 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14825,7 +14826,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_iso_single_statement__ = 
 # 114 "standard.mly"
     ( [] )
-# 14829 "parser_cocci_menhir.ml"
+# 14830 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14855,7 +14856,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_iso_single_statement__ = 
 # 116 "standard.mly"
     ( x :: xs )
-# 14859 "parser_cocci_menhir.ml"
+# 14860 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14872,7 +14873,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_mzl_ctype__ = 
 # 114 "standard.mly"
     ( [] )
-# 14876 "parser_cocci_menhir.ml"
+# 14877 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14902,7 +14903,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_mzl_ctype__ = 
 # 116 "standard.mly"
     ( x :: xs )
-# 14906 "parser_cocci_menhir.ml"
+# 14907 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14919,7 +14920,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_mzl_eexpr__ = 
 # 114 "standard.mly"
     ( [] )
-# 14923 "parser_cocci_menhir.ml"
+# 14924 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14949,7 +14950,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_mzl_eexpr__ = 
 # 116 "standard.mly"
     ( x :: xs )
-# 14953 "parser_cocci_menhir.ml"
+# 14954 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14966,7 +14967,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_mzl_fun_after_dots_or__ = 
 # 114 "standard.mly"
     ( [] )
-# 14970 "parser_cocci_menhir.ml"
+# 14971 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -14996,7 +14997,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_mzl_fun_after_dots_or__ = 
 # 116 "standard.mly"
     ( x :: xs )
-# 15000 "parser_cocci_menhir.ml"
+# 15001 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15013,7 +15014,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_mzl_fun_start__ = 
 # 114 "standard.mly"
     ( [] )
-# 15017 "parser_cocci_menhir.ml"
+# 15018 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15043,7 +15044,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_mzl_fun_start__ = 
 # 116 "standard.mly"
     ( x :: xs )
-# 15047 "parser_cocci_menhir.ml"
+# 15048 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15060,7 +15061,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_mzl_rule_elem_statement__ = 
 # 114 "standard.mly"
     ( [] )
-# 15064 "parser_cocci_menhir.ml"
+# 15065 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15090,7 +15091,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_mzl_rule_elem_statement__ = 
 # 116 "standard.mly"
     ( x :: xs )
-# 15094 "parser_cocci_menhir.ml"
+# 15095 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15107,7 +15108,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_mzl_statement__ = 
 # 114 "standard.mly"
     ( [] )
-# 15111 "parser_cocci_menhir.ml"
+# 15112 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15137,7 +15138,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_mzl_statement__ = 
 # 116 "standard.mly"
     ( x :: xs )
-# 15141 "parser_cocci_menhir.ml"
+# 15142 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15154,7 +15155,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_pair_edots_when_TEllipsis_eexpr__dexpr__ = 
 # 114 "standard.mly"
     ( [] )
-# 15158 "parser_cocci_menhir.ml"
+# 15159 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15193,13 +15194,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 70 "standard.mly"
     ( (x, y) )
-# 15197 "parser_cocci_menhir.ml"
+# 15198 "parser_cocci_menhir.ml"
           
         in
         
 # 116 "standard.mly"
     ( x :: xs )
-# 15203 "parser_cocci_menhir.ml"
+# 15204 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15216,7 +15217,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_whenppdecs_ = 
 # 114 "standard.mly"
     ( [] )
-# 15220 "parser_cocci_menhir.ml"
+# 15221 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15246,7 +15247,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_list_whenppdecs_ = 
 # 116 "standard.mly"
     ( x :: xs )
-# 15250 "parser_cocci_menhir.ml"
+# 15251 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15263,7 +15264,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_loption_choose_iso_ = 
 # 57 "standard.mly"
     ( [] )
-# 15267 "parser_cocci_menhir.ml"
+# 15268 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15287,7 +15288,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_loption_choose_iso_ = 
 # 59 "standard.mly"
     ( x )
-# 15291 "parser_cocci_menhir.ml"
+# 15292 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15304,7 +15305,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_loption_disable_ = 
 # 57 "standard.mly"
     ( [] )
-# 15308 "parser_cocci_menhir.ml"
+# 15309 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15328,7 +15329,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_loption_disable_ = 
 # 59 "standard.mly"
     ( x )
-# 15332 "parser_cocci_menhir.ml"
+# 15333 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15345,7 +15346,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_loption_error_words_ = 
 # 57 "standard.mly"
     ( [] )
-# 15349 "parser_cocci_menhir.ml"
+# 15350 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15369,7 +15370,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_loption_error_words_ = 
 # 59 "standard.mly"
     ( x )
-# 15373 "parser_cocci_menhir.ml"
+# 15374 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15386,7 +15387,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_loption_filespec_ = 
 # 57 "standard.mly"
     ( [] )
-# 15390 "parser_cocci_menhir.ml"
+# 15391 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15410,7 +15411,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_loption_filespec_ = 
 # 59 "standard.mly"
     ( x )
-# 15414 "parser_cocci_menhir.ml"
+# 15415 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15427,7 +15428,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_loption_minus_start_ = 
 # 57 "standard.mly"
     ( [] )
-# 15431 "parser_cocci_menhir.ml"
+# 15432 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15451,7 +15452,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_loption_minus_start_ = 
 # 59 "standard.mly"
     ( x )
-# 15455 "parser_cocci_menhir.ml"
+# 15456 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15468,7 +15469,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_loption_not_ceq_ = 
 # 57 "standard.mly"
     ( [] )
-# 15472 "parser_cocci_menhir.ml"
+# 15473 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15492,7 +15493,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_loption_not_ceq_ = 
 # 59 "standard.mly"
     ( x )
-# 15496 "parser_cocci_menhir.ml"
+# 15497 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15509,7 +15510,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_loption_not_eq_ = 
 # 57 "standard.mly"
     ( [] )
-# 15513 "parser_cocci_menhir.ml"
+# 15514 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15533,7 +15534,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_loption_not_eq_ = 
 # 59 "standard.mly"
     ( x )
-# 15537 "parser_cocci_menhir.ml"
+# 15538 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15550,7 +15551,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_loption_not_eqe_ = 
 # 57 "standard.mly"
     ( [] )
-# 15554 "parser_cocci_menhir.ml"
+# 15555 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15574,7 +15575,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_loption_not_eqe_ = 
 # 59 "standard.mly"
     ( x )
-# 15578 "parser_cocci_menhir.ml"
+# 15579 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15591,7 +15592,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_loption_not_pos_ = 
 # 57 "standard.mly"
     ( [] )
-# 15595 "parser_cocci_menhir.ml"
+# 15596 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15615,7 +15616,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_loption_not_pos_ = 
 # 59 "standard.mly"
     ( x )
-# 15619 "parser_cocci_menhir.ml"
+# 15620 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15632,7 +15633,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_loption_plus_start_ = 
 # 57 "standard.mly"
     ( [] )
-# 15636 "parser_cocci_menhir.ml"
+# 15637 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15656,7 +15657,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_loption_plus_start_ = 
 # 59 "standard.mly"
     ( x )
-# 15660 "parser_cocci_menhir.ml"
+# 15661 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15680,7 +15681,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_meta_exp_type = 
 # 444 "parser_cocci_menhir.mly"
     ( [Ast0_cocci.ast0_type_to_type t] )
-# 15684 "parser_cocci_menhir.ml"
+# 15685 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15720,7 +15721,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
     ( List.map
        (function x -> P.ty_pointerify (Ast0_cocci.ast0_type_to_type x) m)
        t )
-# 15724 "parser_cocci_menhir.ml"
+# 15725 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15751,14 +15752,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 47 "parser_cocci_menhir.mly"
       (string)
-# 15755 "parser_cocci_menhir.ml"
+# 15756 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_meta_ident = 
-# 1388 "parser_cocci_menhir.mly"
+# 1389 "parser_cocci_menhir.mly"
                                  ( (Some _1,P.id2name _3) )
-# 15762 "parser_cocci_menhir.ml"
+# 15763 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15782,11 +15783,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 157 "parser_cocci_menhir.mly"
       ((Ast_cocci.metavar,Ast_cocci.metavar) Common.either list)
-# 15786 "parser_cocci_menhir.ml"
+# 15787 "parser_cocci_menhir.ml"
         ) = 
 # 181 "parser_cocci_menhir.mly"
                        ( m (!Ast0.rule_name) )
-# 15790 "parser_cocci_menhir.ml"
+# 15791 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15837,13 +15838,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
     ( (fun arity name pure check_meta ->
       let tok = check_meta(Ast.MetaFreshIdDecl(arity,name)) in
       !Data.add_id_meta name [] pure; tok) )
-# 15841 "parser_cocci_menhir.ml"
+# 15842 "parser_cocci_menhir.ml"
           
         in
         
 # 259 "parser_cocci_menhir.mly"
     ( P.create_metadec ar ispure kindfn ids )
-# 15847 "parser_cocci_menhir.ml"
+# 15848 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15890,13 +15891,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
     ( (fun arity name pure check_meta ->
       let tok = check_meta(Ast.MetaParamDecl(arity,name)) in
       !Data.add_param_meta name pure; tok) )
-# 15894 "parser_cocci_menhir.ml"
+# 15895 "parser_cocci_menhir.ml"
           
         in
         
 # 259 "parser_cocci_menhir.mly"
     ( P.create_metadec ar ispure kindfn ids )
-# 15900 "parser_cocci_menhir.ml"
+# 15901 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -15947,13 +15948,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
     ( (fun arity name pure check_meta ->
       let tok = check_meta(Ast.MetaParamListDecl(arity,name,None)) in
       !Data.add_paramlist_meta name None pure; tok) )
-# 15951 "parser_cocci_menhir.ml"
+# 15952 "parser_cocci_menhir.ml"
           
         in
         
 # 259 "parser_cocci_menhir.mly"
     ( P.create_metadec ar ispure kindfn ids )
-# 15957 "parser_cocci_menhir.ml"
+# 15958 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -16004,13 +16005,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
     ( (fun arity name pure check_meta ->
       let tok = check_meta(Ast.MetaExpListDecl(arity,name,None)) in
       !Data.add_explist_meta name None pure; tok) )
-# 16008 "parser_cocci_menhir.ml"
+# 16009 "parser_cocci_menhir.ml"
           
         in
         
 # 259 "parser_cocci_menhir.mly"
     ( P.create_metadec ar ispure kindfn ids )
-# 16014 "parser_cocci_menhir.ml"
+# 16015 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -16057,13 +16058,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
     ( (fun arity name pure check_meta ->
       let tok = check_meta(Ast.MetaTypeDecl(arity,name)) in
       !Data.add_type_meta name pure; tok) )
-# 16061 "parser_cocci_menhir.ml"
+# 16062 "parser_cocci_menhir.ml"
           
         in
         
 # 259 "parser_cocci_menhir.mly"
     ( P.create_metadec ar ispure kindfn ids )
-# 16067 "parser_cocci_menhir.ml"
+# 16068 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -16110,13 +16111,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
     ( (fun arity name pure check_meta ->
       let tok = check_meta(Ast.MetaInitDecl(arity,name)) in
       !Data.add_init_meta name pure; tok) )
-# 16114 "parser_cocci_menhir.ml"
+# 16115 "parser_cocci_menhir.ml"
           
         in
         
 # 259 "parser_cocci_menhir.mly"
     ( P.create_metadec ar ispure kindfn ids )
-# 16120 "parser_cocci_menhir.ml"
+# 16121 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -16163,13 +16164,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
     ( (fun arity name pure check_meta ->
       let tok = check_meta(Ast.MetaStmDecl(arity,name)) in
       !Data.add_stm_meta name pure; tok) )
-# 16167 "parser_cocci_menhir.ml"
+# 16168 "parser_cocci_menhir.ml"
           
         in
         
 # 259 "parser_cocci_menhir.mly"
     ( P.create_metadec ar ispure kindfn ids )
-# 16173 "parser_cocci_menhir.ml"
+# 16174 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -16220,13 +16221,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
     ( (fun arity name pure check_meta ->
       let tok = check_meta(Ast.MetaStmListDecl(arity,name)) in
       !Data.add_stmlist_meta name pure; tok) )
-# 16224 "parser_cocci_menhir.ml"
+# 16225 "parser_cocci_menhir.ml"
           
         in
         
 # 259 "parser_cocci_menhir.mly"
     ( P.create_metadec ar ispure kindfn ids )
-# 16230 "parser_cocci_menhir.ml"
+# 16231 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -16274,13 +16275,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       if arity = Ast.NONE && pure = Ast0.Impure
       then (!Data.add_type_name name; [])
       else raise (Semantic_cocci.Semantic "bad typedef")) )
-# 16278 "parser_cocci_menhir.ml"
+# 16279 "parser_cocci_menhir.ml"
           
         in
         
 # 259 "parser_cocci_menhir.mly"
     ( P.create_metadec ar ispure kindfn ids )
-# 16284 "parser_cocci_menhir.ml"
+# 16285 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -16332,13 +16333,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       if arity = Ast.NONE && pure = Ast0.Impure
       then (!Data.add_declarer_name name; [])
       else raise (Semantic_cocci.Semantic "bad declarer")) )
-# 16336 "parser_cocci_menhir.ml"
+# 16337 "parser_cocci_menhir.ml"
           
         in
         
 # 259 "parser_cocci_menhir.mly"
     ( P.create_metadec ar ispure kindfn ids )
-# 16342 "parser_cocci_menhir.ml"
+# 16343 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -16390,13 +16391,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       if arity = Ast.NONE && pure = Ast0.Impure
       then (!Data.add_iterator_name name; [])
       else raise (Semantic_cocci.Semantic "bad iterator")) )
-# 16394 "parser_cocci_menhir.ml"
+# 16395 "parser_cocci_menhir.ml"
           
         in
         
 # 259 "parser_cocci_menhir.mly"
     ( P.create_metadec ar ispure kindfn ids )
-# 16400 "parser_cocci_menhir.ml"
+# 16401 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -16443,13 +16444,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
     ( (fun arity name pure check_meta constraints ->
       let tok = check_meta(Ast.MetaIdDecl(arity,name)) in
       !Data.add_id_meta name constraints pure; tok) )
-# 16447 "parser_cocci_menhir.ml"
+# 16448 "parser_cocci_menhir.ml"
           
         in
         
 # 263 "parser_cocci_menhir.mly"
     ( P.create_metadec_ne ar ispure kindfn ids )
-# 16453 "parser_cocci_menhir.ml"
+# 16454 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -16496,13 +16497,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
     ( (fun arity name pure check_meta constraints ->
       let tok = check_meta(Ast.MetaFuncDecl(arity,name)) in
       !Data.add_func_meta name constraints pure; tok) )
-# 16500 "parser_cocci_menhir.ml"
+# 16501 "parser_cocci_menhir.ml"
           
         in
         
 # 263 "parser_cocci_menhir.mly"
     ( P.create_metadec_ne ar ispure kindfn ids )
-# 16506 "parser_cocci_menhir.ml"
+# 16507 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -16554,13 +16555,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       let tok = check_meta(Ast.MetaLocalFuncDecl(arity,name)) in
       !Data.add_local_func_meta name constraints pure;
       tok) )
-# 16558 "parser_cocci_menhir.ml"
+# 16559 "parser_cocci_menhir.ml"
           
         in
         
 # 263 "parser_cocci_menhir.mly"
     ( P.create_metadec_ne ar ispure kindfn ids )
-# 16564 "parser_cocci_menhir.ml"
+# 16565 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -16607,13 +16608,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
     ( (fun arity name pure check_meta constraints ->
       let tok = check_meta(Ast.MetaDeclarerDecl(arity,name)) in
       !Data.add_declarer_meta name constraints pure; tok) )
-# 16611 "parser_cocci_menhir.ml"
+# 16612 "parser_cocci_menhir.ml"
           
         in
         
 # 263 "parser_cocci_menhir.mly"
     ( P.create_metadec_ne ar ispure kindfn ids )
-# 16617 "parser_cocci_menhir.ml"
+# 16618 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -16660,13 +16661,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
     ( (fun arity name pure check_meta constraints ->
       let tok = check_meta(Ast.MetaIteratorDecl(arity,name)) in
       !Data.add_iterator_meta name constraints pure; tok) )
-# 16664 "parser_cocci_menhir.ml"
+# 16665 "parser_cocci_menhir.ml"
           
         in
         
 # 263 "parser_cocci_menhir.mly"
     ( P.create_metadec_ne ar ispure kindfn ids )
-# 16670 "parser_cocci_menhir.ml"
+# 16671 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -16713,13 +16714,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
     ( (fun arity name pure check_meta constraints ->
       let tok = check_meta(Ast.MetaErrDecl(arity,name)) in
       !Data.add_err_meta name constraints pure; tok) )
-# 16717 "parser_cocci_menhir.ml"
+# 16718 "parser_cocci_menhir.ml"
           
         in
         
 # 267 "parser_cocci_menhir.mly"
     ( P.create_metadec_ne ar ispure kindfn ids )
-# 16723 "parser_cocci_menhir.ml"
+# 16724 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -16772,7 +16773,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             
 # 39 "standard.mly"
     ( None )
-# 16776 "parser_cocci_menhir.ml"
+# 16777 "parser_cocci_menhir.ml"
             
           in
           
@@ -16785,13 +16786,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       | Some _ ->
          !Data.add_local_idexp_meta ty name constraints pure;
          check_meta(Ast.MetaLocalIdExpDecl(arity,name,ty))) )
-# 16789 "parser_cocci_menhir.ml"
+# 16790 "parser_cocci_menhir.ml"
           
         in
         
 # 267 "parser_cocci_menhir.mly"
     ( P.create_metadec_ne ar ispure kindfn ids )
-# 16795 "parser_cocci_menhir.ml"
+# 16796 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -16852,7 +16853,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             
 # 41 "standard.mly"
     ( Some x )
-# 16856 "parser_cocci_menhir.ml"
+# 16857 "parser_cocci_menhir.ml"
             
           in
           
@@ -16865,13 +16866,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       | Some _ ->
          !Data.add_local_idexp_meta ty name constraints pure;
          check_meta(Ast.MetaLocalIdExpDecl(arity,name,ty))) )
-# 16869 "parser_cocci_menhir.ml"
+# 16870 "parser_cocci_menhir.ml"
           
         in
         
 # 267 "parser_cocci_menhir.mly"
     ( P.create_metadec_ne ar ispure kindfn ids )
-# 16875 "parser_cocci_menhir.ml"
+# 16876 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -16938,13 +16939,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       | Some _ ->
          !Data.add_local_idexp_meta ty name constraints pure;
          check_meta(Ast.MetaLocalIdExpDecl(arity,name,ty))) )
-# 16942 "parser_cocci_menhir.ml"
+# 16943 "parser_cocci_menhir.ml"
           
         in
         
 # 267 "parser_cocci_menhir.mly"
     ( P.create_metadec_ne ar ispure kindfn ids )
-# 16948 "parser_cocci_menhir.ml"
+# 16949 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -16999,13 +17000,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       let ty = Some [P.ty_pointerify Type_cocci.Unknown m] in
       let tok = check_meta(Ast.MetaExpDecl(arity,name,ty)) in
       !Data.add_exp_meta ty name constraints pure; tok) )
-# 17003 "parser_cocci_menhir.ml"
+# 17004 "parser_cocci_menhir.ml"
           
         in
         
 # 267 "parser_cocci_menhir.mly"
     ( P.create_metadec_ne ar ispure kindfn ids )
-# 17009 "parser_cocci_menhir.ml"
+# 17010 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17064,13 +17065,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       let ty = Some (List.map (function x -> Type_cocci.Array x) vl) in
       let tok = check_meta(Ast.MetaExpDecl(arity,name,ty)) in
       !Data.add_exp_meta ty name constraints pure; tok) )
-# 17068 "parser_cocci_menhir.ml"
+# 17069 "parser_cocci_menhir.ml"
           
         in
         
 # 267 "parser_cocci_menhir.mly"
     ( P.create_metadec_ne ar ispure kindfn ids )
-# 17074 "parser_cocci_menhir.ml"
+# 17075 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17116,7 +17117,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             
 # 39 "standard.mly"
     ( None )
-# 17120 "parser_cocci_menhir.ml"
+# 17121 "parser_cocci_menhir.ml"
             
           in
           
@@ -17124,13 +17125,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
     ( (fun arity name pure check_meta constraints ->
       let tok = check_meta(Ast.MetaConstDecl(arity,name,ty)) in
       !Data.add_const_meta ty name constraints pure; tok) )
-# 17128 "parser_cocci_menhir.ml"
+# 17129 "parser_cocci_menhir.ml"
           
         in
         
 # 267 "parser_cocci_menhir.mly"
     ( P.create_metadec_ne ar ispure kindfn ids )
-# 17134 "parser_cocci_menhir.ml"
+# 17135 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17184,7 +17185,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             
 # 41 "standard.mly"
     ( Some x )
-# 17188 "parser_cocci_menhir.ml"
+# 17189 "parser_cocci_menhir.ml"
             
           in
           
@@ -17192,13 +17193,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
     ( (fun arity name pure check_meta constraints ->
       let tok = check_meta(Ast.MetaConstDecl(arity,name,ty)) in
       !Data.add_const_meta ty name constraints pure; tok) )
-# 17196 "parser_cocci_menhir.ml"
+# 17197 "parser_cocci_menhir.ml"
           
         in
         
 # 267 "parser_cocci_menhir.mly"
     ( P.create_metadec_ne ar ispure kindfn ids )
-# 17202 "parser_cocci_menhir.ml"
+# 17203 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17245,13 +17246,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
     ( (fun arity name pure check_meta constraints ->
       let tok = check_meta(Ast.MetaExpDecl(arity,name,None)) in
       !Data.add_exp_meta None name constraints pure; tok) )
-# 17249 "parser_cocci_menhir.ml"
+# 17250 "parser_cocci_menhir.ml"
           
         in
         
 # 271 "parser_cocci_menhir.mly"
     ( P.create_metadec_ne ar ispure kindfn ids )
-# 17255 "parser_cocci_menhir.ml"
+# 17256 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17317,13 +17318,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
        constraints;
       let tok = check_meta(Ast.MetaExpDecl(arity,name,ty)) in
       !Data.add_exp_meta ty name constraints pure; tok) )
-# 17321 "parser_cocci_menhir.ml"
+# 17322 "parser_cocci_menhir.ml"
           
         in
         
 # 271 "parser_cocci_menhir.mly"
     ( P.create_metadec_ne ar ispure kindfn ids )
-# 17327 "parser_cocci_menhir.ml"
+# 17328 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17373,7 +17374,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
       let any = match a with None -> Ast.PER | Some _ -> Ast.ALL in
       !Data.add_pos_meta name constraints any; tok in
     P.create_metadec_ne ar false kindfn ids )
-# 17377 "parser_cocci_menhir.ml"
+# 17378 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17440,7 +17441,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
            check_meta(Ast.MetaParamListDecl(arity,name,Some lenname)) in
          !Data.add_paramlist_meta name (Some lenname) pure; tok)
        id ids )
-# 17444 "parser_cocci_menhir.ml"
+# 17445 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17507,7 +17508,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
            check_meta(Ast.MetaExpListDecl(arity,name,Some lenname)) in
          !Data.add_explist_meta name (Some lenname) pure; tok)
        id ids )
-# 17511 "parser_cocci_menhir.ml"
+# 17512 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17535,9 +17536,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_midzero_list_ctype_ctype_ = 
-# 1788 "parser_cocci_menhir.mly"
+# 1789 "parser_cocci_menhir.mly"
      ( let (mids,code) = List.split b in (mids,(a::code)) )
-# 17541 "parser_cocci_menhir.ml"
+# 17542 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17565,9 +17566,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_midzero_list_eexpr_eexpr_ = 
-# 1788 "parser_cocci_menhir.mly"
+# 1789 "parser_cocci_menhir.mly"
      ( let (mids,code) = List.split b in (mids,(a::code)) )
-# 17571 "parser_cocci_menhir.ml"
+# 17572 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17595,9 +17596,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_midzero_list_expr_eexpr_ = 
-# 1788 "parser_cocci_menhir.mly"
+# 1789 "parser_cocci_menhir.mly"
      ( let (mids,code) = List.split b in (mids,(a::code)) )
-# 17601 "parser_cocci_menhir.ml"
+# 17602 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17625,9 +17626,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_midzero_list_fun_after_stm_fun_after_dots_or_ = 
-# 1788 "parser_cocci_menhir.mly"
+# 1789 "parser_cocci_menhir.mly"
      ( let (mids,code) = List.split b in (mids,(a::code)) )
-# 17631 "parser_cocci_menhir.ml"
+# 17632 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17655,9 +17656,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_midzero_list_fun_start_fun_start_ = 
-# 1788 "parser_cocci_menhir.mly"
+# 1789 "parser_cocci_menhir.mly"
      ( let (mids,code) = List.split b in (mids,(a::code)) )
-# 17661 "parser_cocci_menhir.ml"
+# 17662 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17685,9 +17686,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_midzero_list_rule_elem_statement_rule_elem_statement_ = 
-# 1788 "parser_cocci_menhir.mly"
+# 1789 "parser_cocci_menhir.mly"
      ( let (mids,code) = List.split b in (mids,(a::code)) )
-# 17691 "parser_cocci_menhir.ml"
+# 17692 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17715,9 +17716,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_midzero_list_statement_statement_ = 
-# 1788 "parser_cocci_menhir.mly"
+# 1789 "parser_cocci_menhir.mly"
      ( let (mids,code) = List.split b in (mids,(a::code)) )
-# 17721 "parser_cocci_menhir.ml"
+# 17722 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17755,7 +17756,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
     ( match f@b@ew with
       [] -> raise (Semantic_cocci.Semantic "minus slice can't be empty")
     | code -> Top_level.top_level code )
-# 17759 "parser_cocci_menhir.ml"
+# 17760 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17793,7 +17794,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
     ( match f@[b]@ew with
       [] -> raise (Semantic_cocci.Semantic "minus slice can't be empty")
     | code -> Top_level.top_level code )
-# 17797 "parser_cocci_menhir.ml"
+# 17798 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17821,11 +17822,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 137 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 17825 "parser_cocci_menhir.ml"
+# 17826 "parser_cocci_menhir.ml"
         ) = 
 # 177 "parser_cocci_menhir.mly"
                                    ( _1 )
-# 17829 "parser_cocci_menhir.ml"
+# 17830 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17853,11 +17854,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 137 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 17857 "parser_cocci_menhir.ml"
+# 17858 "parser_cocci_menhir.ml"
         ) = 
 # 177 "parser_cocci_menhir.mly"
                                                                        ( m )
-# 17861 "parser_cocci_menhir.ml"
+# 17862 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17885,11 +17886,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 137 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 17889 "parser_cocci_menhir.ml"
+# 17890 "parser_cocci_menhir.ml"
         ) = 
 # 178 "parser_cocci_menhir.mly"
                          ( m )
-# 17893 "parser_cocci_menhir.ml"
+# 17894 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17917,11 +17918,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 134 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 17921 "parser_cocci_menhir.ml"
+# 17922 "parser_cocci_menhir.ml"
         ) = 
 # 173 "parser_cocci_menhir.mly"
                            ( _1 )
-# 17925 "parser_cocci_menhir.ml"
+# 17926 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17949,11 +17950,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 134 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 17953 "parser_cocci_menhir.ml"
+# 17954 "parser_cocci_menhir.ml"
         ) = 
 # 173 "parser_cocci_menhir.mly"
                                                            ( m )
-# 17957 "parser_cocci_menhir.ml"
+# 17958 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -17981,11 +17982,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 134 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 17985 "parser_cocci_menhir.ml"
+# 17986 "parser_cocci_menhir.ml"
         ) = 
 # 174 "parser_cocci_menhir.mly"
                      ( m )
-# 17989 "parser_cocci_menhir.ml"
+# 17990 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18007,9 +18008,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_minus_start = 
-# 1597 "parser_cocci_menhir.mly"
+# 1598 "parser_cocci_menhir.mly"
                          ( [Ast0.wrap(Ast0.DECL(_1))] )
-# 18013 "parser_cocci_menhir.ml"
+# 18014 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18031,9 +18032,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_minus_start = 
-# 1598 "parser_cocci_menhir.mly"
+# 1599 "parser_cocci_menhir.mly"
                          ( [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Ty(_1))))] )
-# 18037 "parser_cocci_menhir.ml"
+# 18038 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18055,9 +18056,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_minus_start = 
-# 1599 "parser_cocci_menhir.mly"
+# 1600 "parser_cocci_menhir.mly"
                     ( [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.TopInit(_1))))] )
-# 18061 "parser_cocci_menhir.ml"
+# 18062 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18079,9 +18080,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_minus_start = 
-# 1601 "parser_cocci_menhir.mly"
+# 1602 "parser_cocci_menhir.mly"
     ( List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) _1 )
-# 18085 "parser_cocci_menhir.ml"
+# 18086 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18108,14 +18109,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let a : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18112 "parser_cocci_menhir.ml"
+# 18113 "parser_cocci_menhir.ml"
         ) = Obj.magic a in
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_mzl_ctype_ = 
-# 1791 "parser_cocci_menhir.mly"
+# 1792 "parser_cocci_menhir.mly"
                  ( (P.clt2mcode "|" a, b) )
-# 18119 "parser_cocci_menhir.ml"
+# 18120 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18142,14 +18143,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let a : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18146 "parser_cocci_menhir.ml"
+# 18147 "parser_cocci_menhir.ml"
         ) = Obj.magic a in
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_mzl_eexpr_ = 
-# 1791 "parser_cocci_menhir.mly"
+# 1792 "parser_cocci_menhir.mly"
                  ( (P.clt2mcode "|" a, b) )
-# 18153 "parser_cocci_menhir.ml"
+# 18154 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18176,14 +18177,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let a : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18180 "parser_cocci_menhir.ml"
+# 18181 "parser_cocci_menhir.ml"
         ) = Obj.magic a in
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_mzl_fun_after_dots_or_ = 
-# 1791 "parser_cocci_menhir.mly"
+# 1792 "parser_cocci_menhir.mly"
                  ( (P.clt2mcode "|" a, b) )
-# 18187 "parser_cocci_menhir.ml"
+# 18188 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18210,14 +18211,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let a : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18214 "parser_cocci_menhir.ml"
+# 18215 "parser_cocci_menhir.ml"
         ) = Obj.magic a in
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_mzl_fun_start_ = 
-# 1791 "parser_cocci_menhir.mly"
+# 1792 "parser_cocci_menhir.mly"
                  ( (P.clt2mcode "|" a, b) )
-# 18221 "parser_cocci_menhir.ml"
+# 18222 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18244,14 +18245,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let a : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18248 "parser_cocci_menhir.ml"
+# 18249 "parser_cocci_menhir.ml"
         ) = Obj.magic a in
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_mzl_rule_elem_statement_ = 
-# 1791 "parser_cocci_menhir.mly"
+# 1792 "parser_cocci_menhir.mly"
                  ( (P.clt2mcode "|" a, b) )
-# 18255 "parser_cocci_menhir.ml"
+# 18256 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18278,14 +18279,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let a : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18282 "parser_cocci_menhir.ml"
+# 18283 "parser_cocci_menhir.ml"
         ) = Obj.magic a in
         let _startpos = _startpos_a_ in
         let _endpos = _endpos_b_ in
         let _v : 'tv_mzl_statement_ = 
-# 1791 "parser_cocci_menhir.mly"
+# 1792 "parser_cocci_menhir.mly"
                  ( (P.clt2mcode "|" a, b) )
-# 18289 "parser_cocci_menhir.ml"
+# 18290 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18307,9 +18308,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_name_opt_decl = 
-# 829 "parser_cocci_menhir.mly"
+# 830 "parser_cocci_menhir.mly"
             ( _1 )
-# 18313 "parser_cocci_menhir.ml"
+# 18314 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18331,9 +18332,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_t_ in
         let _endpos = _endpos_t_ in
         let _v : 'tv_name_opt_decl = 
-# 830 "parser_cocci_menhir.mly"
+# 831 "parser_cocci_menhir.mly"
               ( Ast0.wrap(Ast0.Param(t, None)) )
-# 18337 "parser_cocci_menhir.ml"
+# 18338 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18384,41 +18385,41 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let rp1 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18388 "parser_cocci_menhir.ml"
+# 18389 "parser_cocci_menhir.ml"
         ) = Obj.magic rp1 in
         let d : 'tv_decl_list_name_opt_decl_ = Obj.magic d in
         let lp1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18394 "parser_cocci_menhir.ml"
+# 18395 "parser_cocci_menhir.ml"
         ) = Obj.magic lp1 in
         let rp : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18399 "parser_cocci_menhir.ml"
+# 18400 "parser_cocci_menhir.ml"
         ) = Obj.magic rp in
         let s : (
 # 99 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18404 "parser_cocci_menhir.ml"
+# 18405 "parser_cocci_menhir.ml"
         ) = Obj.magic s in
         let lp : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18409 "parser_cocci_menhir.ml"
+# 18410 "parser_cocci_menhir.ml"
         ) = Obj.magic lp in
         let t : 'tv_fn_ctype = Obj.magic t in
         let _startpos = _startpos_t_ in
         let _endpos = _endpos_rp1_ in
         let _v : 'tv_name_opt_decl = 
-# 833 "parser_cocci_menhir.mly"
+# 834 "parser_cocci_menhir.mly"
         ( 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)) )
-# 18422 "parser_cocci_menhir.ml"
+# 18423 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18446,9 +18447,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_nest_after_dots = 
-# 1712 "parser_cocci_menhir.mly"
+# 1713 "parser_cocci_menhir.mly"
                                      (_1@_2)
-# 18452 "parser_cocci_menhir.ml"
+# 18453 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18474,9 +18475,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_nest_after_dots = 
-# 1713 "parser_cocci_menhir.mly"
+# 1714 "parser_cocci_menhir.mly"
                                 (_2)
-# 18480 "parser_cocci_menhir.ml"
+# 18481 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18504,9 +18505,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_nest_after_dots = 
-# 1714 "parser_cocci_menhir.mly"
+# 1715 "parser_cocci_menhir.mly"
                                 ((Ast0.wrap(Ast0.Exp(_1)))::_2)
-# 18510 "parser_cocci_menhir.ml"
+# 18511 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18521,9 +18522,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
         let _endpos = _startpos in
         let _v : 'tv_nest_after_exp = 
-# 1722 "parser_cocci_menhir.mly"
+# 1723 "parser_cocci_menhir.mly"
                                 ([])
-# 18527 "parser_cocci_menhir.ml"
+# 18528 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18551,9 +18552,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_nest_after_exp = 
-# 1723 "parser_cocci_menhir.mly"
+# 1724 "parser_cocci_menhir.mly"
                                 (_1::_2)
-# 18557 "parser_cocci_menhir.ml"
+# 18558 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18568,9 +18569,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _menhir_env.MenhirLib.EngineTypes.lexbuf.Lexing.lex_start_p in
         let _endpos = _startpos in
         let _v : 'tv_nest_after_stm = 
-# 1717 "parser_cocci_menhir.mly"
+# 1718 "parser_cocci_menhir.mly"
                                 ([])
-# 18574 "parser_cocci_menhir.ml"
+# 18575 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18598,9 +18599,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_nest_after_stm = 
-# 1718 "parser_cocci_menhir.mly"
+# 1719 "parser_cocci_menhir.mly"
                                 (_1::_2)
-# 18604 "parser_cocci_menhir.ml"
+# 18605 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18628,9 +18629,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_nest_after_stm = 
-# 1719 "parser_cocci_menhir.mly"
+# 1720 "parser_cocci_menhir.mly"
                                 (_1@_2)
-# 18634 "parser_cocci_menhir.ml"
+# 18635 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18661,22 +18662,22 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let c : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18665 "parser_cocci_menhir.ml"
+# 18666 "parser_cocci_menhir.ml"
         ) = Obj.magic c in
         let e : 'tv_expr_dots_TEllipsis_ = Obj.magic e in
         let _1 : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18671 "parser_cocci_menhir.ml"
+# 18672 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_c_ in
         let _v : 'tv_nest_expressions = 
-# 1211 "parser_cocci_menhir.mly"
+# 1212 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.NestExpr(P.clt2mcode "<..." _1,
                              Ast0.wrap(Ast0.DOTS(e (P.mkedots "..."))),
                              P.clt2mcode "...>" c, None, false)) )
-# 18680 "parser_cocci_menhir.ml"
+# 18681 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18707,22 +18708,22 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let c : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18711 "parser_cocci_menhir.ml"
+# 18712 "parser_cocci_menhir.ml"
         ) = Obj.magic c in
         let e : 'tv_expr_dots_TEllipsis_ = Obj.magic e in
         let _1 : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18717 "parser_cocci_menhir.ml"
+# 18718 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_c_ in
         let _v : 'tv_nest_expressions = 
-# 1215 "parser_cocci_menhir.mly"
+# 1216 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.NestExpr(P.clt2mcode "<+..." _1,
                              Ast0.wrap(Ast0.DOTS(e (P.mkedots "..."))),
                              P.clt2mcode "...+>" c, None, true)) )
-# 18726 "parser_cocci_menhir.ml"
+# 18727 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18744,9 +18745,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_nest_start = 
-# 1709 "parser_cocci_menhir.mly"
+# 1710 "parser_cocci_menhir.mly"
                    ( Ast0.wrap(Ast0.DOTS(_1)) )
-# 18750 "parser_cocci_menhir.ml"
+# 18751 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18768,11 +18769,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 168 "parser_cocci_menhir.mly"
       (unit)
-# 18772 "parser_cocci_menhir.ml"
+# 18773 "parser_cocci_menhir.ml"
         ) = 
-# 1854 "parser_cocci_menhir.mly"
+# 1855 "parser_cocci_menhir.mly"
                     ( () )
-# 18776 "parser_cocci_menhir.ml"
+# 18777 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18798,11 +18799,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 168 "parser_cocci_menhir.mly"
       (unit)
-# 18802 "parser_cocci_menhir.ml"
+# 18803 "parser_cocci_menhir.ml"
         ) = 
-# 1855 "parser_cocci_menhir.mly"
+# 1856 "parser_cocci_menhir.mly"
                     ( () )
-# 18806 "parser_cocci_menhir.ml"
+# 18807 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18824,11 +18825,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 168 "parser_cocci_menhir.mly"
       (unit)
-# 18828 "parser_cocci_menhir.ml"
+# 18829 "parser_cocci_menhir.ml"
         ) = 
-# 1856 "parser_cocci_menhir.mly"
+# 1857 "parser_cocci_menhir.mly"
                     ( () )
-# 18832 "parser_cocci_menhir.ml"
+# 18833 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18856,10 +18857,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__ = 
-# 1379 "parser_cocci_menhir.mly"
+# 1380 "parser_cocci_menhir.mly"
   ( function dot_builder ->
       g :: (List.concat(List.map (function (d,g) -> [dot_builder d;g]) dg)) )
-# 18863 "parser_cocci_menhir.ml"
+# 18864 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18880,14 +18881,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let x : (
 # 99 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18884 "parser_cocci_menhir.ml"
+# 18885 "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 ] )
-# 18891 "parser_cocci_menhir.ml"
+# 18892 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18914,14 +18915,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let x : (
 # 99 "parser_cocci_menhir.mly"
        (Data.clt)
-# 18918 "parser_cocci_menhir.ml"
+# 18919 "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 )
-# 18925 "parser_cocci_menhir.ml"
+# 18926 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18947,13 +18948,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_i_ in
         let _v : 'tv_not_ceq = 
-# 1436 "parser_cocci_menhir.mly"
+# 1437 "parser_cocci_menhir.mly"
          ( (if !Data.in_iso
           then failwith "constraints not allowed in iso file");
           (if !Data.in_generating
           then failwith "constraints not allowed in a generated rule file");
           [i] )
-# 18957 "parser_cocci_menhir.ml"
+# 18958 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -18987,13 +18988,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__4_ in
         let _v : 'tv_not_ceq = 
-# 1442 "parser_cocci_menhir.mly"
+# 1443 "parser_cocci_menhir.mly"
   ( (if !Data.in_iso
           then failwith "constraints not allowed in iso file");
           (if !Data.in_generating
           then failwith "constraints not allowed in a generated rule file");
           l )
-# 18997 "parser_cocci_menhir.ml"
+# 18998 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19019,7 +19020,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_i_ in
         let _v : 'tv_not_eq = 
-# 1403 "parser_cocci_menhir.mly"
+# 1404 "parser_cocci_menhir.mly"
          ( (if !Data.in_iso
           then failwith "constraints not allowed in iso file");
           (if !Data.in_generating
@@ -19027,7 +19028,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
              them in the pattern *)
           then failwith "constraints not allowed in a generated rule file");
           [Ast0.wrap(Ast0.Id(P.id2mcode i))] )
-# 19031 "parser_cocci_menhir.ml"
+# 19032 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19061,13 +19062,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__4_ in
         let _v : 'tv_not_eq = 
-# 1411 "parser_cocci_menhir.mly"
+# 1412 "parser_cocci_menhir.mly"
   ( (if !Data.in_iso
           then failwith "constraints not allowed in iso file");
           (if !Data.in_generating
           then failwith "constraints not allowed in a generated rule file");
           List.map (function i -> Ast0.wrap(Ast0.Id(P.id2mcode i))) l )
-# 19071 "parser_cocci_menhir.ml"
+# 19072 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19093,13 +19094,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_i_ in
         let _v : 'tv_not_eqe = 
-# 1419 "parser_cocci_menhir.mly"
+# 1420 "parser_cocci_menhir.mly"
          ( (if !Data.in_iso
           then failwith "constraints not allowed in iso file");
           (if !Data.in_generating
           then failwith "constraints not allowed in a generated rule file");
           [Ast0.wrap(Ast0.Ident(Ast0.wrap(Ast0.Id(P.id2mcode i))))] )
-# 19103 "parser_cocci_menhir.ml"
+# 19104 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19133,7 +19134,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__4_ in
         let _v : 'tv_not_eqe = 
-# 1425 "parser_cocci_menhir.mly"
+# 1426 "parser_cocci_menhir.mly"
   ( (if !Data.in_iso
           then failwith "constraints not allowed in iso file");
           (if !Data.in_generating
@@ -19142,7 +19143,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             (function i ->
               Ast0.wrap(Ast0.Ident(Ast0.wrap(Ast0.Id(P.id2mcode i)))))
             l )
-# 19146 "parser_cocci_menhir.ml"
+# 19147 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19168,7 +19169,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_i_ in
         let _v : 'tv_not_pos = 
-# 1456 "parser_cocci_menhir.mly"
+# 1457 "parser_cocci_menhir.mly"
          ( (if !Data.in_iso
           then failwith "constraints not allowed in iso file");
           (if !Data.in_generating
@@ -19179,7 +19180,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
               let i = (rule,name) in
               P.check_meta(Ast.MetaPosDecl(Ast.NONE,i));
               [i] )
-# 19183 "parser_cocci_menhir.ml"
+# 19184 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19213,7 +19214,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__4_ in
         let _v : 'tv_not_pos = 
-# 1467 "parser_cocci_menhir.mly"
+# 1468 "parser_cocci_menhir.mly"
   ( (if !Data.in_iso
           then failwith "constraints not allowed in iso file");
           (if !Data.in_generating
@@ -19227,7 +19228,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
                   P.check_meta(Ast.MetaPosDecl(Ast.NONE,i));
                   i)
             l )
-# 19231 "parser_cocci_menhir.ml"
+# 19232 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19249,9 +19250,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_one_dec_decl_ = 
-# 1541 "parser_cocci_menhir.mly"
+# 1542 "parser_cocci_menhir.mly"
         ( _1 )
-# 19255 "parser_cocci_menhir.ml"
+# 19256 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19272,12 +19273,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 66 "parser_cocci_menhir.mly"
        (Parse_aux.list_info)
-# 19276 "parser_cocci_menhir.ml"
+# 19277 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_one_dec_decl_ = 
-# 1543 "parser_cocci_menhir.mly"
+# 1544 "parser_cocci_menhir.mly"
     ( let (nm,lenname,pure,clt) = _1 in
     let nm = P.clt2mcode nm clt in
     let lenname =
@@ -19285,7 +19286,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
        Some nm -> Some(P.clt2mcode nm clt)
       | None -> None in
     Ast0.wrap(Ast0.MetaParamList(nm,lenname,pure)) )
-# 19289 "parser_cocci_menhir.ml"
+# 19290 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19307,9 +19308,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_ = 
-# 1541 "parser_cocci_menhir.mly"
+# 1542 "parser_cocci_menhir.mly"
         ( _1 )
-# 19313 "parser_cocci_menhir.ml"
+# 19314 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19330,12 +19331,12 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 66 "parser_cocci_menhir.mly"
        (Parse_aux.list_info)
-# 19334 "parser_cocci_menhir.ml"
+# 19335 "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_ = 
-# 1543 "parser_cocci_menhir.mly"
+# 1544 "parser_cocci_menhir.mly"
     ( let (nm,lenname,pure,clt) = _1 in
     let nm = P.clt2mcode nm clt in
     let lenname =
@@ -19343,7 +19344,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
        Some nm -> Some(P.clt2mcode nm clt)
       | None -> None in
     Ast0.wrap(Ast0.MetaParamList(nm,lenname,pure)) )
-# 19347 "parser_cocci_menhir.ml"
+# 19348 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19369,15 +19370,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19373 "parser_cocci_menhir.ml"
+# 19374 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let t : 'tv_ctype = Obj.magic t in
         let _startpos = _startpos_t_ in
         let _endpos = _endpos_pv_ in
         let _v : 'tv_one_decl_var = 
-# 1000 "parser_cocci_menhir.mly"
+# 1001 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.TyDecl(t,P.clt2mcode ";" pv)) )
-# 19381 "parser_cocci_menhir.ml"
+# 19382 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19408,7 +19409,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19412 "parser_cocci_menhir.ml"
+# 19413 "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
@@ -19418,14 +19419,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 39 "standard.mly"
     ( None )
-# 19422 "parser_cocci_menhir.ml"
+# 19423 "parser_cocci_menhir.ml"
           
         in
         
-# 1002 "parser_cocci_menhir.mly"
+# 1003 "parser_cocci_menhir.mly"
       ( let (id,fn) = d in
         Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv)) )
-# 19429 "parser_cocci_menhir.ml"
+# 19430 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19461,7 +19462,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19465 "parser_cocci_menhir.ml"
+# 19466 "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
@@ -19473,14 +19474,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 19477 "parser_cocci_menhir.ml"
+# 19478 "parser_cocci_menhir.ml"
           
         in
         
-# 1002 "parser_cocci_menhir.mly"
+# 1003 "parser_cocci_menhir.mly"
       ( let (id,fn) = d in
         Ast0.wrap(Ast0.UnInit(s,fn t,id,P.clt2mcode ";" pv)) )
-# 19484 "parser_cocci_menhir.ml"
+# 19485 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19502,9 +19503,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_f_ in
         let _endpos = _endpos_f_ in
         let _v : 'tv_one_decl_var = 
-# 1004 "parser_cocci_menhir.mly"
+# 1005 "parser_cocci_menhir.mly"
                ( f )
-# 19508 "parser_cocci_menhir.ml"
+# 19509 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19545,13 +19546,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19549 "parser_cocci_menhir.ml"
+# 19550 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let e : 'tv_initialize = Obj.magic e in
         let q : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19555 "parser_cocci_menhir.ml"
+# 19556 "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
@@ -19561,14 +19562,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 39 "standard.mly"
     ( None )
-# 19565 "parser_cocci_menhir.ml"
+# 19566 "parser_cocci_menhir.ml"
           
         in
         
-# 1006 "parser_cocci_menhir.mly"
+# 1007 "parser_cocci_menhir.mly"
       ( let (id,fn) = d in
       Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv)) )
-# 19572 "parser_cocci_menhir.ml"
+# 19573 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19614,13 +19615,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19618 "parser_cocci_menhir.ml"
+# 19619 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let e : 'tv_initialize = Obj.magic e in
         let q : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19624 "parser_cocci_menhir.ml"
+# 19625 "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
@@ -19632,14 +19633,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 19636 "parser_cocci_menhir.ml"
+# 19637 "parser_cocci_menhir.ml"
           
         in
         
-# 1006 "parser_cocci_menhir.mly"
+# 1007 "parser_cocci_menhir.mly"
       ( let (id,fn) = d in
       Ast0.wrap(Ast0.Init(s,fn t,id,P.clt2mcode "=" q,e,P.clt2mcode ";" pv)) )
-# 19643 "parser_cocci_menhir.ml"
+# 19644 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19670,7 +19671,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19674 "parser_cocci_menhir.ml"
+# 19675 "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
@@ -19680,22 +19681,22 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 39 "standard.mly"
     ( None )
-# 19684 "parser_cocci_menhir.ml"
+# 19685 "parser_cocci_menhir.ml"
           
         in
         let s =
           
 # 39 "standard.mly"
     ( None )
-# 19691 "parser_cocci_menhir.ml"
+# 19692 "parser_cocci_menhir.ml"
           
         in
         
-# 1011 "parser_cocci_menhir.mly"
+# 1012 "parser_cocci_menhir.mly"
       ( 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)) )
-# 19699 "parser_cocci_menhir.ml"
+# 19700 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19731,7 +19732,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19735 "parser_cocci_menhir.ml"
+# 19736 "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
@@ -19743,22 +19744,22 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 19747 "parser_cocci_menhir.ml"
+# 19748 "parser_cocci_menhir.ml"
           
         in
         let s =
           
 # 39 "standard.mly"
     ( None )
-# 19754 "parser_cocci_menhir.ml"
+# 19755 "parser_cocci_menhir.ml"
           
         in
         
-# 1011 "parser_cocci_menhir.mly"
+# 1012 "parser_cocci_menhir.mly"
       ( 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)) )
-# 19762 "parser_cocci_menhir.ml"
+# 19763 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19794,7 +19795,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19798 "parser_cocci_menhir.ml"
+# 19799 "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
@@ -19805,7 +19806,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 39 "standard.mly"
     ( None )
-# 19809 "parser_cocci_menhir.ml"
+# 19810 "parser_cocci_menhir.ml"
           
         in
         let s =
@@ -19813,15 +19814,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 19817 "parser_cocci_menhir.ml"
+# 19818 "parser_cocci_menhir.ml"
           
         in
         
-# 1011 "parser_cocci_menhir.mly"
+# 1012 "parser_cocci_menhir.mly"
       ( 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)) )
-# 19825 "parser_cocci_menhir.ml"
+# 19826 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19862,7 +19863,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19866 "parser_cocci_menhir.ml"
+# 19867 "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
@@ -19875,7 +19876,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 19879 "parser_cocci_menhir.ml"
+# 19880 "parser_cocci_menhir.ml"
           
         in
         let s =
@@ -19883,15 +19884,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 19887 "parser_cocci_menhir.ml"
+# 19888 "parser_cocci_menhir.ml"
           
         in
         
-# 1011 "parser_cocci_menhir.mly"
+# 1012 "parser_cocci_menhir.mly"
       ( 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)) )
-# 19895 "parser_cocci_menhir.ml"
+# 19896 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -19932,13 +19933,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19936 "parser_cocci_menhir.ml"
+# 19937 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let e : 'tv_initialize = Obj.magic e in
         let q : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 19942 "parser_cocci_menhir.ml"
+# 19943 "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
@@ -19948,24 +19949,24 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 39 "standard.mly"
     ( None )
-# 19952 "parser_cocci_menhir.ml"
+# 19953 "parser_cocci_menhir.ml"
           
         in
         let s =
           
 # 39 "standard.mly"
     ( None )
-# 19959 "parser_cocci_menhir.ml"
+# 19960 "parser_cocci_menhir.ml"
           
         in
         
-# 1016 "parser_cocci_menhir.mly"
+# 1017 "parser_cocci_menhir.mly"
       ( 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)) )
-# 19969 "parser_cocci_menhir.ml"
+# 19970 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20011,13 +20012,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20015 "parser_cocci_menhir.ml"
+# 20016 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let e : 'tv_initialize = Obj.magic e in
         let q : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20021 "parser_cocci_menhir.ml"
+# 20022 "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
@@ -20029,24 +20030,24 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 20033 "parser_cocci_menhir.ml"
+# 20034 "parser_cocci_menhir.ml"
           
         in
         let s =
           
 # 39 "standard.mly"
     ( None )
-# 20040 "parser_cocci_menhir.ml"
+# 20041 "parser_cocci_menhir.ml"
           
         in
         
-# 1016 "parser_cocci_menhir.mly"
+# 1017 "parser_cocci_menhir.mly"
       ( 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)) )
-# 20050 "parser_cocci_menhir.ml"
+# 20051 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20092,13 +20093,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20096 "parser_cocci_menhir.ml"
+# 20097 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let e : 'tv_initialize = Obj.magic e in
         let q : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20102 "parser_cocci_menhir.ml"
+# 20103 "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
@@ -20109,7 +20110,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 39 "standard.mly"
     ( None )
-# 20113 "parser_cocci_menhir.ml"
+# 20114 "parser_cocci_menhir.ml"
           
         in
         let s =
@@ -20117,17 +20118,17 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 20121 "parser_cocci_menhir.ml"
+# 20122 "parser_cocci_menhir.ml"
           
         in
         
-# 1016 "parser_cocci_menhir.mly"
+# 1017 "parser_cocci_menhir.mly"
       ( 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)) )
-# 20131 "parser_cocci_menhir.ml"
+# 20132 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20178,13 +20179,13 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20182 "parser_cocci_menhir.ml"
+# 20183 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let e : 'tv_initialize = Obj.magic e in
         let q : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20188 "parser_cocci_menhir.ml"
+# 20189 "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
@@ -20197,7 +20198,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 20201 "parser_cocci_menhir.ml"
+# 20202 "parser_cocci_menhir.ml"
           
         in
         let s =
@@ -20205,17 +20206,17 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 20209 "parser_cocci_menhir.ml"
+# 20210 "parser_cocci_menhir.ml"
           
         in
         
-# 1016 "parser_cocci_menhir.mly"
+# 1017 "parser_cocci_menhir.mly"
       ( 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)) )
-# 20219 "parser_cocci_menhir.ml"
+# 20220 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20276,34 +20277,34 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20280 "parser_cocci_menhir.ml"
+# 20281 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let rp2 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20285 "parser_cocci_menhir.ml"
+# 20286 "parser_cocci_menhir.ml"
         ) = Obj.magic rp2 in
         let p : 'tv_decl_list_name_opt_decl_ = Obj.magic p in
         let lp2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20291 "parser_cocci_menhir.ml"
+# 20292 "parser_cocci_menhir.ml"
         ) = Obj.magic lp2 in
         let rp1 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20296 "parser_cocci_menhir.ml"
+# 20297 "parser_cocci_menhir.ml"
         ) = Obj.magic rp1 in
         let d : 'tv_d_ident = Obj.magic d in
         let st : (
 # 99 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20302 "parser_cocci_menhir.ml"
+# 20303 "parser_cocci_menhir.ml"
         ) = Obj.magic st in
         let lp1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20307 "parser_cocci_menhir.ml"
+# 20308 "parser_cocci_menhir.ml"
         ) = Obj.magic lp1 in
         let t : 'tv_fn_ctype = Obj.magic t in
         let _startpos = _startpos_t_ in
@@ -20312,11 +20313,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 39 "standard.mly"
     ( None )
-# 20316 "parser_cocci_menhir.ml"
+# 20317 "parser_cocci_menhir.ml"
           
         in
         
-# 1026 "parser_cocci_menhir.mly"
+# 1027 "parser_cocci_menhir.mly"
       ( let (id,fn) = d in
         let t =
          Ast0.wrap
@@ -20324,7 +20325,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)) )
-# 20328 "parser_cocci_menhir.ml"
+# 20329 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20390,34 +20391,34 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20394 "parser_cocci_menhir.ml"
+# 20395 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let rp2 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20399 "parser_cocci_menhir.ml"
+# 20400 "parser_cocci_menhir.ml"
         ) = Obj.magic rp2 in
         let p : 'tv_decl_list_name_opt_decl_ = Obj.magic p in
         let lp2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20405 "parser_cocci_menhir.ml"
+# 20406 "parser_cocci_menhir.ml"
         ) = Obj.magic lp2 in
         let rp1 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20410 "parser_cocci_menhir.ml"
+# 20411 "parser_cocci_menhir.ml"
         ) = Obj.magic rp1 in
         let d : 'tv_d_ident = Obj.magic d in
         let st : (
 # 99 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20416 "parser_cocci_menhir.ml"
+# 20417 "parser_cocci_menhir.ml"
         ) = Obj.magic st in
         let lp1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20421 "parser_cocci_menhir.ml"
+# 20422 "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
@@ -20428,11 +20429,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 20432 "parser_cocci_menhir.ml"
+# 20433 "parser_cocci_menhir.ml"
           
         in
         
-# 1026 "parser_cocci_menhir.mly"
+# 1027 "parser_cocci_menhir.mly"
       ( let (id,fn) = d in
         let t =
          Ast0.wrap
@@ -20440,7 +20441,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)) )
-# 20444 "parser_cocci_menhir.ml"
+# 20445 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20481,27 +20482,27 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _5 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20485 "parser_cocci_menhir.ml"
+# 20486 "parser_cocci_menhir.ml"
         ) = Obj.magic _5 in
         let _4 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20490 "parser_cocci_menhir.ml"
+# 20491 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr_list_option = Obj.magic _3 in
         let _2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20496 "parser_cocci_menhir.ml"
+# 20497 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_decl_ident = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__5_ in
         let _v : 'tv_one_decl_var = 
-# 1034 "parser_cocci_menhir.mly"
+# 1035 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.MacroDecl(_1,P.clt2mcode "(" _2,_3,
                                  P.clt2mcode ")" _4,P.clt2mcode ";" _5)) )
-# 20505 "parser_cocci_menhir.ml"
+# 20506 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20572,40 +20573,40 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20576 "parser_cocci_menhir.ml"
+# 20577 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let e : 'tv_initialize = Obj.magic e in
         let q : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20582 "parser_cocci_menhir.ml"
+# 20583 "parser_cocci_menhir.ml"
         ) = Obj.magic q in
         let rp2 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20587 "parser_cocci_menhir.ml"
+# 20588 "parser_cocci_menhir.ml"
         ) = Obj.magic rp2 in
         let p : 'tv_decl_list_name_opt_decl_ = Obj.magic p in
         let lp2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20593 "parser_cocci_menhir.ml"
+# 20594 "parser_cocci_menhir.ml"
         ) = Obj.magic lp2 in
         let rp1 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20598 "parser_cocci_menhir.ml"
+# 20599 "parser_cocci_menhir.ml"
         ) = Obj.magic rp1 in
         let d : 'tv_d_ident = Obj.magic d in
         let st : (
 # 99 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20604 "parser_cocci_menhir.ml"
+# 20605 "parser_cocci_menhir.ml"
         ) = Obj.magic st in
         let lp1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20609 "parser_cocci_menhir.ml"
+# 20610 "parser_cocci_menhir.ml"
         ) = Obj.magic lp1 in
         let t : 'tv_fn_ctype = Obj.magic t in
         let _startpos = _startpos_t_ in
@@ -20614,11 +20615,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 39 "standard.mly"
     ( None )
-# 20618 "parser_cocci_menhir.ml"
+# 20619 "parser_cocci_menhir.ml"
           
         in
         
-# 1040 "parser_cocci_menhir.mly"
+# 1041 "parser_cocci_menhir.mly"
       ( let (id,fn) = d in
         let t =
          Ast0.wrap
@@ -20626,7 +20627,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)))
-# 20630 "parser_cocci_menhir.ml"
+# 20631 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20702,40 +20703,40 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20706 "parser_cocci_menhir.ml"
+# 20707 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let e : 'tv_initialize = Obj.magic e in
         let q : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20712 "parser_cocci_menhir.ml"
+# 20713 "parser_cocci_menhir.ml"
         ) = Obj.magic q in
         let rp2 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20717 "parser_cocci_menhir.ml"
+# 20718 "parser_cocci_menhir.ml"
         ) = Obj.magic rp2 in
         let p : 'tv_decl_list_name_opt_decl_ = Obj.magic p in
         let lp2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20723 "parser_cocci_menhir.ml"
+# 20724 "parser_cocci_menhir.ml"
         ) = Obj.magic lp2 in
         let rp1 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20728 "parser_cocci_menhir.ml"
+# 20729 "parser_cocci_menhir.ml"
         ) = Obj.magic rp1 in
         let d : 'tv_d_ident = Obj.magic d in
         let st : (
 # 99 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20734 "parser_cocci_menhir.ml"
+# 20735 "parser_cocci_menhir.ml"
         ) = Obj.magic st in
         let lp1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 20739 "parser_cocci_menhir.ml"
+# 20740 "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
@@ -20746,11 +20747,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 20750 "parser_cocci_menhir.ml"
+# 20751 "parser_cocci_menhir.ml"
           
         in
         
-# 1040 "parser_cocci_menhir.mly"
+# 1041 "parser_cocci_menhir.mly"
       ( let (id,fn) = d in
         let t =
          Ast0.wrap
@@ -20758,7 +20759,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)))
-# 20762 "parser_cocci_menhir.ml"
+# 20763 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20775,7 +20776,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_option_TLocal_ = 
 # 29 "standard.mly"
     ( None )
-# 20779 "parser_cocci_menhir.ml"
+# 20780 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20799,7 +20800,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_option_TLocal_ = 
 # 31 "standard.mly"
     ( Some x )
-# 20803 "parser_cocci_menhir.ml"
+# 20804 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20816,7 +20817,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_option_TPosAny_ = 
 # 29 "standard.mly"
     ( None )
-# 20820 "parser_cocci_menhir.ml"
+# 20821 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20840,7 +20841,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_option_TPosAny_ = 
 # 31 "standard.mly"
     ( Some x )
-# 20844 "parser_cocci_menhir.ml"
+# 20845 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20857,7 +20858,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_option_eexpr_ = 
 # 29 "standard.mly"
     ( None )
-# 20861 "parser_cocci_menhir.ml"
+# 20862 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20881,7 +20882,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_option_eexpr_ = 
 # 31 "standard.mly"
     ( Some x )
-# 20885 "parser_cocci_menhir.ml"
+# 20886 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20896,9 +20897,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 = 
-# 1659 "parser_cocci_menhir.mly"
+# 1660 "parser_cocci_menhir.mly"
                                                                          ([])
-# 20902 "parser_cocci_menhir.ml"
+# 20903 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20924,9 +20925,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_after_dots = 
-# 1660 "parser_cocci_menhir.mly"
+# 1661 "parser_cocci_menhir.mly"
                                                                          (_2)
-# 20930 "parser_cocci_menhir.ml"
+# 20931 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20954,9 +20955,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_after_dots = 
-# 1662 "parser_cocci_menhir.mly"
+# 1663 "parser_cocci_menhir.mly"
                      ( (Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Exp(_1)))))::_2 )
-# 20960 "parser_cocci_menhir.ml"
+# 20961 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -20984,9 +20985,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_after_dots = 
-# 1663 "parser_cocci_menhir.mly"
+# 1664 "parser_cocci_menhir.mly"
                                              ( Ast0.wrap(Ast0.DECL(_1))::_2 )
-# 20990 "parser_cocci_menhir.ml"
+# 20991 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21014,9 +21015,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_after_dots = 
-# 1665 "parser_cocci_menhir.mly"
+# 1666 "parser_cocci_menhir.mly"
                 ( (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) _1)@_2 )
-# 21020 "parser_cocci_menhir.ml"
+# 21021 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21031,9 +21032,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 = 
-# 1655 "parser_cocci_menhir.mly"
+# 1656 "parser_cocci_menhir.mly"
                                                                          ([])
-# 21037 "parser_cocci_menhir.ml"
+# 21038 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21061,9 +21062,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_after_exp = 
-# 1656 "parser_cocci_menhir.mly"
+# 1657 "parser_cocci_menhir.mly"
                                           ( (Ast0.wrap(Ast0.OTHER(_1)))::_2 )
-# 21067 "parser_cocci_menhir.ml"
+# 21068 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21078,9 +21079,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 = 
-# 1668 "parser_cocci_menhir.mly"
+# 1669 "parser_cocci_menhir.mly"
                                                                          ([])
-# 21084 "parser_cocci_menhir.ml"
+# 21085 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21108,9 +21109,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_after_stm = 
-# 1669 "parser_cocci_menhir.mly"
+# 1670 "parser_cocci_menhir.mly"
                                           ( (Ast0.wrap(Ast0.OTHER(_1)))::_2 )
-# 21114 "parser_cocci_menhir.ml"
+# 21115 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21138,9 +21139,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_after_stm = 
-# 1670 "parser_cocci_menhir.mly"
+# 1671 "parser_cocci_menhir.mly"
                                              ( Ast0.wrap(Ast0.DECL(_1))::_2 )
-# 21144 "parser_cocci_menhir.ml"
+# 21145 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21168,9 +21169,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_after_stm = 
-# 1672 "parser_cocci_menhir.mly"
+# 1673 "parser_cocci_menhir.mly"
                 ( (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) _1)@_2 )
-# 21174 "parser_cocci_menhir.ml"
+# 21175 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21206,7 +21207,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_plus_body = 
 # 605 "parser_cocci_menhir.mly"
     ( Top_level.top_level (f@b@ew) )
-# 21210 "parser_cocci_menhir.ml"
+# 21211 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21242,7 +21243,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_plus_exp_body = 
 # 619 "parser_cocci_menhir.mly"
     ( Top_level.top_level (f@[b]@ew) )
-# 21246 "parser_cocci_menhir.ml"
+# 21247 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21270,11 +21271,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 143 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 21274 "parser_cocci_menhir.ml"
+# 21275 "parser_cocci_menhir.ml"
         ) = 
 # 179 "parser_cocci_menhir.mly"
                                  ( _1 )
-# 21278 "parser_cocci_menhir.ml"
+# 21279 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21302,11 +21303,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 143 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 21306 "parser_cocci_menhir.ml"
+# 21307 "parser_cocci_menhir.ml"
         ) = 
 # 179 "parser_cocci_menhir.mly"
                                                                     ( p )
-# 21310 "parser_cocci_menhir.ml"
+# 21311 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21334,11 +21335,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 143 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 21338 "parser_cocci_menhir.ml"
+# 21339 "parser_cocci_menhir.ml"
         ) = 
 # 180 "parser_cocci_menhir.mly"
                         ( p )
-# 21342 "parser_cocci_menhir.ml"
+# 21343 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21366,11 +21367,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 140 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 21370 "parser_cocci_menhir.ml"
+# 21371 "parser_cocci_menhir.ml"
         ) = 
 # 175 "parser_cocci_menhir.mly"
                          ( _1 )
-# 21374 "parser_cocci_menhir.ml"
+# 21375 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21398,11 +21399,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 140 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 21402 "parser_cocci_menhir.ml"
+# 21403 "parser_cocci_menhir.ml"
         ) = 
 # 175 "parser_cocci_menhir.mly"
                                                         ( p )
-# 21406 "parser_cocci_menhir.ml"
+# 21407 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21430,11 +21431,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 140 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 21434 "parser_cocci_menhir.ml"
+# 21435 "parser_cocci_menhir.ml"
         ) = 
 # 176 "parser_cocci_menhir.mly"
                     ( p )
-# 21438 "parser_cocci_menhir.ml"
+# 21439 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21456,9 +21457,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_plus_start = 
-# 1644 "parser_cocci_menhir.mly"
+# 1645 "parser_cocci_menhir.mly"
                           ( [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Ty(_1))))] )
-# 21462 "parser_cocci_menhir.ml"
+# 21463 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21480,9 +21481,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_plus_start = 
-# 1645 "parser_cocci_menhir.mly"
+# 1646 "parser_cocci_menhir.mly"
                      ( [Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.TopInit(_1))))] )
-# 21486 "parser_cocci_menhir.ml"
+# 21487 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21510,9 +21511,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_start = 
-# 1647 "parser_cocci_menhir.mly"
+# 1648 "parser_cocci_menhir.mly"
                                           ( (Ast0.wrap(Ast0.OTHER(_1)))::_2 )
-# 21516 "parser_cocci_menhir.ml"
+# 21517 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21540,9 +21541,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_start = 
-# 1649 "parser_cocci_menhir.mly"
+# 1650 "parser_cocci_menhir.mly"
                      ( (Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Exp(_1)))))::_2 )
-# 21546 "parser_cocci_menhir.ml"
+# 21547 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21570,9 +21571,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_start = 
-# 1650 "parser_cocci_menhir.mly"
+# 1651 "parser_cocci_menhir.mly"
                                              ( Ast0.wrap(Ast0.DECL(_1))::_2 )
-# 21576 "parser_cocci_menhir.ml"
+# 21577 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21600,9 +21601,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_plus_start = 
-# 1652 "parser_cocci_menhir.mly"
+# 1653 "parser_cocci_menhir.mly"
                 ( (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) _1)@_2 )
-# 21606 "parser_cocci_menhir.ml"
+# 21607 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21623,14 +21624,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 47 "parser_cocci_menhir.mly"
       (string)
-# 21627 "parser_cocci_menhir.ml"
+# 21628 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_pnrule = 
 # 226 "parser_cocci_menhir.mly"
                    ( Ast.Dep      _1 )
-# 21634 "parser_cocci_menhir.ml"
+# 21635 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21655,14 +21656,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 47 "parser_cocci_menhir.mly"
       (string)
-# 21659 "parser_cocci_menhir.ml"
+# 21660 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_pnrule = 
 # 227 "parser_cocci_menhir.mly"
                    ( Ast.AntiDep  _2 )
-# 21666 "parser_cocci_menhir.ml"
+# 21667 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21687,14 +21688,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 47 "parser_cocci_menhir.mly"
       (string)
-# 21691 "parser_cocci_menhir.ml"
+# 21692 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_pnrule = 
 # 228 "parser_cocci_menhir.mly"
                    ( Ast.EverDep  _2 )
-# 21698 "parser_cocci_menhir.ml"
+# 21699 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21719,14 +21720,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 47 "parser_cocci_menhir.mly"
       (string)
-# 21723 "parser_cocci_menhir.ml"
+# 21724 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_pnrule = 
 # 229 "parser_cocci_menhir.mly"
                    ( Ast.NeverDep _2 )
-# 21730 "parser_cocci_menhir.ml"
+# 21731 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21758,7 +21759,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_pnrule = 
 # 230 "parser_cocci_menhir.mly"
                    ( _2 )
-# 21762 "parser_cocci_menhir.ml"
+# 21763 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21780,9 +21781,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_ = 
-# 1312 "parser_cocci_menhir.mly"
+# 1313 "parser_cocci_menhir.mly"
                                                  ( _1 )
-# 21786 "parser_cocci_menhir.ml"
+# 21787 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21818,22 +21819,22 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _4 : (
 # 102 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21822 "parser_cocci_menhir.ml"
+# 21823 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr = Obj.magic _3 in
         let _2 : (
 # 102 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21828 "parser_cocci_menhir.ml"
+# 21829 "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_ = 
-# 1314 "parser_cocci_menhir.mly"
+# 1315 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.ArrayAccess (_1,P.clt2mcode "[" _2,_3,
                                       P.clt2mcode "]" _4)) )
-# 21837 "parser_cocci_menhir.ml"
+# 21838 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21865,15 +21866,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21869 "parser_cocci_menhir.ml"
+# 21870 "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_ = 
-# 1317 "parser_cocci_menhir.mly"
+# 1318 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.RecordAccess(_1, P.clt2mcode "." _2, _3)) )
-# 21877 "parser_cocci_menhir.ml"
+# 21878 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21905,16 +21906,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 104 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21909 "parser_cocci_menhir.ml"
+# 21910 "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_ = 
-# 1319 "parser_cocci_menhir.mly"
+# 1320 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.RecordPtAccess(_1, P.clt2mcode "->" _2,
                                     _3)) )
-# 21918 "parser_cocci_menhir.ml"
+# 21919 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21940,15 +21941,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 85 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21944 "parser_cocci_menhir.ml"
+# 21945 "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_ = 
-# 1322 "parser_cocci_menhir.mly"
+# 1323 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Inc _2)) )
-# 21952 "parser_cocci_menhir.ml"
+# 21953 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -21974,15 +21975,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 85 "parser_cocci_menhir.mly"
        (Data.clt)
-# 21978 "parser_cocci_menhir.ml"
+# 21979 "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_ = 
-# 1324 "parser_cocci_menhir.mly"
+# 1325 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Dec _2)) )
-# 21986 "parser_cocci_menhir.ml"
+# 21987 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22018,23 +22019,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _4 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22022 "parser_cocci_menhir.ml"
+# 22023 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr_list_option = Obj.magic _3 in
         let _2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22028 "parser_cocci_menhir.ml"
+# 22029 "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_ = 
-# 1326 "parser_cocci_menhir.mly"
+# 1327 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.FunCall(_1,P.clt2mcode "(" _2,
                              _3,
                              P.clt2mcode ")" _4)) )
-# 22038 "parser_cocci_menhir.ml"
+# 22039 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22056,9 +22057,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_postfix_expr_eexpr_invalid_ = 
-# 1312 "parser_cocci_menhir.mly"
+# 1313 "parser_cocci_menhir.mly"
                                                  ( _1 )
-# 22062 "parser_cocci_menhir.ml"
+# 22063 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22094,22 +22095,22 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _4 : (
 # 102 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22098 "parser_cocci_menhir.ml"
+# 22099 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr = Obj.magic _3 in
         let _2 : (
 # 102 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22104 "parser_cocci_menhir.ml"
+# 22105 "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_ = 
-# 1314 "parser_cocci_menhir.mly"
+# 1315 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.ArrayAccess (_1,P.clt2mcode "[" _2,_3,
                                       P.clt2mcode "]" _4)) )
-# 22113 "parser_cocci_menhir.ml"
+# 22114 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22141,15 +22142,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22145 "parser_cocci_menhir.ml"
+# 22146 "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_ = 
-# 1317 "parser_cocci_menhir.mly"
+# 1318 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.RecordAccess(_1, P.clt2mcode "." _2, _3)) )
-# 22153 "parser_cocci_menhir.ml"
+# 22154 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22181,16 +22182,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 104 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22185 "parser_cocci_menhir.ml"
+# 22186 "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_ = 
-# 1319 "parser_cocci_menhir.mly"
+# 1320 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.RecordPtAccess(_1, P.clt2mcode "->" _2,
                                     _3)) )
-# 22194 "parser_cocci_menhir.ml"
+# 22195 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22216,15 +22217,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 85 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22220 "parser_cocci_menhir.ml"
+# 22221 "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_ = 
-# 1322 "parser_cocci_menhir.mly"
+# 1323 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Inc _2)) )
-# 22228 "parser_cocci_menhir.ml"
+# 22229 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22250,15 +22251,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 85 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22254 "parser_cocci_menhir.ml"
+# 22255 "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_ = 
-# 1324 "parser_cocci_menhir.mly"
+# 1325 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Dec _2)) )
-# 22262 "parser_cocci_menhir.ml"
+# 22263 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22294,23 +22295,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _4 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22298 "parser_cocci_menhir.ml"
+# 22299 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr_list_option = Obj.magic _3 in
         let _2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22304 "parser_cocci_menhir.ml"
+# 22305 "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_ = 
-# 1326 "parser_cocci_menhir.mly"
+# 1327 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.FunCall(_1,P.clt2mcode "(" _2,
                              _3,
                              P.clt2mcode ")" _4)) )
-# 22314 "parser_cocci_menhir.ml"
+# 22315 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22332,9 +22333,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_ = 
-# 1312 "parser_cocci_menhir.mly"
+# 1313 "parser_cocci_menhir.mly"
                                                  ( _1 )
-# 22338 "parser_cocci_menhir.ml"
+# 22339 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22370,22 +22371,22 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _4 : (
 # 102 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22374 "parser_cocci_menhir.ml"
+# 22375 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr = Obj.magic _3 in
         let _2 : (
 # 102 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22380 "parser_cocci_menhir.ml"
+# 22381 "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_ = 
-# 1314 "parser_cocci_menhir.mly"
+# 1315 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.ArrayAccess (_1,P.clt2mcode "[" _2,_3,
                                       P.clt2mcode "]" _4)) )
-# 22389 "parser_cocci_menhir.ml"
+# 22390 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22417,15 +22418,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22421 "parser_cocci_menhir.ml"
+# 22422 "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_ = 
-# 1317 "parser_cocci_menhir.mly"
+# 1318 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.RecordAccess(_1, P.clt2mcode "." _2, _3)) )
-# 22429 "parser_cocci_menhir.ml"
+# 22430 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22457,16 +22458,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 104 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22461 "parser_cocci_menhir.ml"
+# 22462 "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_ = 
-# 1319 "parser_cocci_menhir.mly"
+# 1320 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.RecordPtAccess(_1, P.clt2mcode "->" _2,
                                     _3)) )
-# 22470 "parser_cocci_menhir.ml"
+# 22471 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22492,15 +22493,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 85 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22496 "parser_cocci_menhir.ml"
+# 22497 "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_ = 
-# 1322 "parser_cocci_menhir.mly"
+# 1323 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Inc _2)) )
-# 22504 "parser_cocci_menhir.ml"
+# 22505 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22526,15 +22527,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 85 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22530 "parser_cocci_menhir.ml"
+# 22531 "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_ = 
-# 1324 "parser_cocci_menhir.mly"
+# 1325 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Dec _2)) )
-# 22538 "parser_cocci_menhir.ml"
+# 22539 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22570,23 +22571,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _4 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22574 "parser_cocci_menhir.ml"
+# 22575 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr_list_option = Obj.magic _3 in
         let _2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22580 "parser_cocci_menhir.ml"
+# 22581 "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_ = 
-# 1326 "parser_cocci_menhir.mly"
+# 1327 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.FunCall(_1,P.clt2mcode "(" _2,
                              _3,
                              P.clt2mcode ")" _4)) )
-# 22590 "parser_cocci_menhir.ml"
+# 22591 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22608,9 +22609,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_postfix_expr_expr_invalid_ = 
-# 1312 "parser_cocci_menhir.mly"
+# 1313 "parser_cocci_menhir.mly"
                                                  ( _1 )
-# 22614 "parser_cocci_menhir.ml"
+# 22615 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22646,22 +22647,22 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _4 : (
 # 102 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22650 "parser_cocci_menhir.ml"
+# 22651 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr = Obj.magic _3 in
         let _2 : (
 # 102 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22656 "parser_cocci_menhir.ml"
+# 22657 "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_ = 
-# 1314 "parser_cocci_menhir.mly"
+# 1315 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.ArrayAccess (_1,P.clt2mcode "[" _2,_3,
                                       P.clt2mcode "]" _4)) )
-# 22665 "parser_cocci_menhir.ml"
+# 22666 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22693,15 +22694,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22697 "parser_cocci_menhir.ml"
+# 22698 "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_ = 
-# 1317 "parser_cocci_menhir.mly"
+# 1318 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.RecordAccess(_1, P.clt2mcode "." _2, _3)) )
-# 22705 "parser_cocci_menhir.ml"
+# 22706 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22733,16 +22734,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 104 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22737 "parser_cocci_menhir.ml"
+# 22738 "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_ = 
-# 1319 "parser_cocci_menhir.mly"
+# 1320 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.RecordPtAccess(_1, P.clt2mcode "->" _2,
                                     _3)) )
-# 22746 "parser_cocci_menhir.ml"
+# 22747 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22768,15 +22769,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 85 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22772 "parser_cocci_menhir.ml"
+# 22773 "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_ = 
-# 1322 "parser_cocci_menhir.mly"
+# 1323 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Inc _2)) )
-# 22780 "parser_cocci_menhir.ml"
+# 22781 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22802,15 +22803,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 85 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22806 "parser_cocci_menhir.ml"
+# 22807 "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_ = 
-# 1324 "parser_cocci_menhir.mly"
+# 1325 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Postfix (_1, P.clt2mcode Ast.Dec _2)) )
-# 22814 "parser_cocci_menhir.ml"
+# 22815 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22846,23 +22847,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _4 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22850 "parser_cocci_menhir.ml"
+# 22851 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr_list_option = Obj.magic _3 in
         let _2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 22856 "parser_cocci_menhir.ml"
+# 22857 "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_ = 
-# 1326 "parser_cocci_menhir.mly"
+# 1327 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.FunCall(_1,P.clt2mcode "(" _2,
                              _3,
                              P.clt2mcode ")" _4)) )
-# 22866 "parser_cocci_menhir.ml"
+# 22867 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22884,9 +22885,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_ = 
-# 1331 "parser_cocci_menhir.mly"
+# 1332 "parser_cocci_menhir.mly"
                 ( Ast0.wrap(Ast0.Ident(_1)) )
-# 22890 "parser_cocci_menhir.ml"
+# 22891 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22907,15 +22908,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 87 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 22911 "parser_cocci_menhir.ml"
+# 22912 "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_ = 
-# 1333 "parser_cocci_menhir.mly"
+# 1334 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) )
-# 22919 "parser_cocci_menhir.ml"
+# 22920 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22936,15 +22937,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 87 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 22940 "parser_cocci_menhir.ml"
+# 22941 "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_ = 
-# 1336 "parser_cocci_menhir.mly"
+# 1337 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Float x) clt)) )
-# 22948 "parser_cocci_menhir.ml"
+# 22949 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22965,15 +22966,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 87 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 22969 "parser_cocci_menhir.ml"
+# 22970 "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_ = 
-# 1339 "parser_cocci_menhir.mly"
+# 1340 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.String x) clt)) )
-# 22977 "parser_cocci_menhir.ml"
+# 22978 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -22994,15 +22995,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 87 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 22998 "parser_cocci_menhir.ml"
+# 22999 "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_ = 
-# 1342 "parser_cocci_menhir.mly"
+# 1343 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Char x) clt)) )
-# 23006 "parser_cocci_menhir.ml"
+# 23007 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23023,16 +23024,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 67 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 23027 "parser_cocci_menhir.ml"
+# 23028 "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_ = 
-# 1345 "parser_cocci_menhir.mly"
+# 1346 "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)) )
-# 23036 "parser_cocci_menhir.ml"
+# 23037 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23053,15 +23054,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 63 "parser_cocci_menhir.mly"
        (Parse_aux.expinfo)
-# 23057 "parser_cocci_menhir.ml"
+# 23058 "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_ = 
-# 1349 "parser_cocci_menhir.mly"
+# 1350 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,clt) = _1 in
      Ast0.wrap(Ast0.MetaErr(P.clt2mcode nm clt,constraints,pure)) )
-# 23065 "parser_cocci_menhir.ml"
+# 23066 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23082,16 +23083,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 67 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 23086 "parser_cocci_menhir.ml"
+# 23087 "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_ = 
-# 1352 "parser_cocci_menhir.mly"
+# 1353 "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)) )
-# 23095 "parser_cocci_menhir.ml"
+# 23096 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23112,16 +23113,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 67 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 23116 "parser_cocci_menhir.ml"
+# 23117 "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_ = 
-# 1356 "parser_cocci_menhir.mly"
+# 1357 "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)) )
-# 23125 "parser_cocci_menhir.ml"
+# 23126 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23142,16 +23143,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 67 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 23146 "parser_cocci_menhir.ml"
+# 23147 "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_ = 
-# 1360 "parser_cocci_menhir.mly"
+# 1361 "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)) )
-# 23155 "parser_cocci_menhir.ml"
+# 23156 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23182,21 +23183,21 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 23186 "parser_cocci_menhir.ml"
+# 23187 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_eexpr = Obj.magic _2 in
         let _1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 23192 "parser_cocci_menhir.ml"
+# 23193 "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_ = 
-# 1364 "parser_cocci_menhir.mly"
+# 1365 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Paren(P.clt2mcode "(" _1,_2,
                            P.clt2mcode ")" _3)) )
-# 23200 "parser_cocci_menhir.ml"
+# 23201 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23227,23 +23228,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 23231 "parser_cocci_menhir.ml"
+# 23232 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_midzero_list_eexpr_eexpr_ = Obj.magic _2 in
         let _1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 23237 "parser_cocci_menhir.ml"
+# 23238 "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_ = 
-# 1367 "parser_cocci_menhir.mly"
+# 1368 "parser_cocci_menhir.mly"
      ( let (mids,code) = _2 in
        Ast0.wrap(Ast0.DisjExpr(P.clt2mcode "(" _1,
                               code, mids,
                               P.clt2mcode ")" _3)) )
-# 23247 "parser_cocci_menhir.ml"
+# 23248 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23265,9 +23266,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_ = 
-# 1371 "parser_cocci_menhir.mly"
+# 1372 "parser_cocci_menhir.mly"
                  ( _1 )
-# 23271 "parser_cocci_menhir.ml"
+# 23272 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23289,9 +23290,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_invalid_ = 
-# 1331 "parser_cocci_menhir.mly"
+# 1332 "parser_cocci_menhir.mly"
                 ( Ast0.wrap(Ast0.Ident(_1)) )
-# 23295 "parser_cocci_menhir.ml"
+# 23296 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23312,15 +23313,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 87 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 23316 "parser_cocci_menhir.ml"
+# 23317 "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_ = 
-# 1333 "parser_cocci_menhir.mly"
+# 1334 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) )
-# 23324 "parser_cocci_menhir.ml"
+# 23325 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23341,15 +23342,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 87 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 23345 "parser_cocci_menhir.ml"
+# 23346 "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_ = 
-# 1336 "parser_cocci_menhir.mly"
+# 1337 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Float x) clt)) )
-# 23353 "parser_cocci_menhir.ml"
+# 23354 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23370,15 +23371,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 87 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 23374 "parser_cocci_menhir.ml"
+# 23375 "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_ = 
-# 1339 "parser_cocci_menhir.mly"
+# 1340 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.String x) clt)) )
-# 23382 "parser_cocci_menhir.ml"
+# 23383 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23399,15 +23400,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 87 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 23403 "parser_cocci_menhir.ml"
+# 23404 "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_ = 
-# 1342 "parser_cocci_menhir.mly"
+# 1343 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Char x) clt)) )
-# 23411 "parser_cocci_menhir.ml"
+# 23412 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23428,16 +23429,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 67 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 23432 "parser_cocci_menhir.ml"
+# 23433 "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_ = 
-# 1345 "parser_cocci_menhir.mly"
+# 1346 "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)) )
-# 23441 "parser_cocci_menhir.ml"
+# 23442 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23458,15 +23459,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 63 "parser_cocci_menhir.mly"
        (Parse_aux.expinfo)
-# 23462 "parser_cocci_menhir.ml"
+# 23463 "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_ = 
-# 1349 "parser_cocci_menhir.mly"
+# 1350 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,clt) = _1 in
      Ast0.wrap(Ast0.MetaErr(P.clt2mcode nm clt,constraints,pure)) )
-# 23470 "parser_cocci_menhir.ml"
+# 23471 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23487,16 +23488,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 67 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 23491 "parser_cocci_menhir.ml"
+# 23492 "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_ = 
-# 1352 "parser_cocci_menhir.mly"
+# 1353 "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)) )
-# 23500 "parser_cocci_menhir.ml"
+# 23501 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23517,16 +23518,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 67 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 23521 "parser_cocci_menhir.ml"
+# 23522 "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_ = 
-# 1356 "parser_cocci_menhir.mly"
+# 1357 "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)) )
-# 23530 "parser_cocci_menhir.ml"
+# 23531 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23547,16 +23548,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 67 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 23551 "parser_cocci_menhir.ml"
+# 23552 "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_ = 
-# 1360 "parser_cocci_menhir.mly"
+# 1361 "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)) )
-# 23560 "parser_cocci_menhir.ml"
+# 23561 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23587,21 +23588,21 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 23591 "parser_cocci_menhir.ml"
+# 23592 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_eexpr = Obj.magic _2 in
         let _1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 23597 "parser_cocci_menhir.ml"
+# 23598 "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_ = 
-# 1364 "parser_cocci_menhir.mly"
+# 1365 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Paren(P.clt2mcode "(" _1,_2,
                            P.clt2mcode ")" _3)) )
-# 23605 "parser_cocci_menhir.ml"
+# 23606 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23632,23 +23633,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 23636 "parser_cocci_menhir.ml"
+# 23637 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_midzero_list_eexpr_eexpr_ = Obj.magic _2 in
         let _1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 23642 "parser_cocci_menhir.ml"
+# 23643 "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_ = 
-# 1367 "parser_cocci_menhir.mly"
+# 1368 "parser_cocci_menhir.mly"
      ( let (mids,code) = _2 in
        Ast0.wrap(Ast0.DisjExpr(P.clt2mcode "(" _1,
                               code, mids,
                               P.clt2mcode ")" _3)) )
-# 23652 "parser_cocci_menhir.ml"
+# 23653 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23670,9 +23671,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_eexpr_invalid_ = 
-# 1371 "parser_cocci_menhir.mly"
+# 1372 "parser_cocci_menhir.mly"
                  ( _1 )
-# 23676 "parser_cocci_menhir.ml"
+# 23677 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23694,9 +23695,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_ = 
-# 1331 "parser_cocci_menhir.mly"
+# 1332 "parser_cocci_menhir.mly"
                 ( Ast0.wrap(Ast0.Ident(_1)) )
-# 23700 "parser_cocci_menhir.ml"
+# 23701 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23717,15 +23718,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 87 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 23721 "parser_cocci_menhir.ml"
+# 23722 "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_ = 
-# 1333 "parser_cocci_menhir.mly"
+# 1334 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) )
-# 23729 "parser_cocci_menhir.ml"
+# 23730 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23746,15 +23747,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 87 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 23750 "parser_cocci_menhir.ml"
+# 23751 "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_ = 
-# 1336 "parser_cocci_menhir.mly"
+# 1337 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Float x) clt)) )
-# 23758 "parser_cocci_menhir.ml"
+# 23759 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23775,15 +23776,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 87 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 23779 "parser_cocci_menhir.ml"
+# 23780 "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_ = 
-# 1339 "parser_cocci_menhir.mly"
+# 1340 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.String x) clt)) )
-# 23787 "parser_cocci_menhir.ml"
+# 23788 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23804,15 +23805,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 87 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 23808 "parser_cocci_menhir.ml"
+# 23809 "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_ = 
-# 1342 "parser_cocci_menhir.mly"
+# 1343 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Char x) clt)) )
-# 23816 "parser_cocci_menhir.ml"
+# 23817 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23833,16 +23834,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 67 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 23837 "parser_cocci_menhir.ml"
+# 23838 "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_ = 
-# 1345 "parser_cocci_menhir.mly"
+# 1346 "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)) )
-# 23846 "parser_cocci_menhir.ml"
+# 23847 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23863,15 +23864,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 63 "parser_cocci_menhir.mly"
        (Parse_aux.expinfo)
-# 23867 "parser_cocci_menhir.ml"
+# 23868 "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_ = 
-# 1349 "parser_cocci_menhir.mly"
+# 1350 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,clt) = _1 in
      Ast0.wrap(Ast0.MetaErr(P.clt2mcode nm clt,constraints,pure)) )
-# 23875 "parser_cocci_menhir.ml"
+# 23876 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23892,16 +23893,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 67 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 23896 "parser_cocci_menhir.ml"
+# 23897 "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_ = 
-# 1352 "parser_cocci_menhir.mly"
+# 1353 "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)) )
-# 23905 "parser_cocci_menhir.ml"
+# 23906 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23922,16 +23923,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 67 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 23926 "parser_cocci_menhir.ml"
+# 23927 "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_ = 
-# 1356 "parser_cocci_menhir.mly"
+# 1357 "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)) )
-# 23935 "parser_cocci_menhir.ml"
+# 23936 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23952,16 +23953,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 67 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 23956 "parser_cocci_menhir.ml"
+# 23957 "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_ = 
-# 1360 "parser_cocci_menhir.mly"
+# 1361 "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)) )
-# 23965 "parser_cocci_menhir.ml"
+# 23966 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -23992,21 +23993,21 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 23996 "parser_cocci_menhir.ml"
+# 23997 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_eexpr = Obj.magic _2 in
         let _1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 24002 "parser_cocci_menhir.ml"
+# 24003 "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_ = 
-# 1364 "parser_cocci_menhir.mly"
+# 1365 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Paren(P.clt2mcode "(" _1,_2,
                            P.clt2mcode ")" _3)) )
-# 24010 "parser_cocci_menhir.ml"
+# 24011 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24037,23 +24038,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 24041 "parser_cocci_menhir.ml"
+# 24042 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_midzero_list_eexpr_eexpr_ = Obj.magic _2 in
         let _1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 24047 "parser_cocci_menhir.ml"
+# 24048 "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_ = 
-# 1367 "parser_cocci_menhir.mly"
+# 1368 "parser_cocci_menhir.mly"
      ( let (mids,code) = _2 in
        Ast0.wrap(Ast0.DisjExpr(P.clt2mcode "(" _1,
                               code, mids,
                               P.clt2mcode ")" _3)) )
-# 24057 "parser_cocci_menhir.ml"
+# 24058 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24075,9 +24076,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_ = 
-# 1371 "parser_cocci_menhir.mly"
+# 1372 "parser_cocci_menhir.mly"
                  ( _1 )
-# 24081 "parser_cocci_menhir.ml"
+# 24082 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24099,9 +24100,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_expr_invalid_ = 
-# 1331 "parser_cocci_menhir.mly"
+# 1332 "parser_cocci_menhir.mly"
                 ( Ast0.wrap(Ast0.Ident(_1)) )
-# 24105 "parser_cocci_menhir.ml"
+# 24106 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24122,15 +24123,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 87 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 24126 "parser_cocci_menhir.ml"
+# 24127 "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_ = 
-# 1333 "parser_cocci_menhir.mly"
+# 1334 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Int x) clt)) )
-# 24134 "parser_cocci_menhir.ml"
+# 24135 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24151,15 +24152,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 87 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 24155 "parser_cocci_menhir.ml"
+# 24156 "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_ = 
-# 1336 "parser_cocci_menhir.mly"
+# 1337 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Float x) clt)) )
-# 24163 "parser_cocci_menhir.ml"
+# 24164 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24180,15 +24181,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 87 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 24184 "parser_cocci_menhir.ml"
+# 24185 "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_ = 
-# 1339 "parser_cocci_menhir.mly"
+# 1340 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.String x) clt)) )
-# 24192 "parser_cocci_menhir.ml"
+# 24193 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24209,15 +24210,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 87 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 24213 "parser_cocci_menhir.ml"
+# 24214 "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_ = 
-# 1342 "parser_cocci_menhir.mly"
+# 1343 "parser_cocci_menhir.mly"
      ( let (x,clt) = _1 in
      Ast0.wrap(Ast0.Constant (P.clt2mcode (Ast.Char x) clt)) )
-# 24221 "parser_cocci_menhir.ml"
+# 24222 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24238,16 +24239,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 67 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 24242 "parser_cocci_menhir.ml"
+# 24243 "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_ = 
-# 1345 "parser_cocci_menhir.mly"
+# 1346 "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)) )
-# 24251 "parser_cocci_menhir.ml"
+# 24252 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24268,15 +24269,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 63 "parser_cocci_menhir.mly"
        (Parse_aux.expinfo)
-# 24272 "parser_cocci_menhir.ml"
+# 24273 "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_ = 
-# 1349 "parser_cocci_menhir.mly"
+# 1350 "parser_cocci_menhir.mly"
      ( let (nm,constraints,pure,clt) = _1 in
      Ast0.wrap(Ast0.MetaErr(P.clt2mcode nm clt,constraints,pure)) )
-# 24280 "parser_cocci_menhir.ml"
+# 24281 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24297,16 +24298,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 67 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 24301 "parser_cocci_menhir.ml"
+# 24302 "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_ = 
-# 1352 "parser_cocci_menhir.mly"
+# 1353 "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)) )
-# 24310 "parser_cocci_menhir.ml"
+# 24311 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24327,16 +24328,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 67 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 24331 "parser_cocci_menhir.ml"
+# 24332 "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_ = 
-# 1356 "parser_cocci_menhir.mly"
+# 1357 "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)) )
-# 24340 "parser_cocci_menhir.ml"
+# 24341 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24357,16 +24358,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 67 "parser_cocci_menhir.mly"
        (Parse_aux.typed_info)
-# 24361 "parser_cocci_menhir.ml"
+# 24362 "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_ = 
-# 1360 "parser_cocci_menhir.mly"
+# 1361 "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)) )
-# 24370 "parser_cocci_menhir.ml"
+# 24371 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24397,21 +24398,21 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 24401 "parser_cocci_menhir.ml"
+# 24402 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_eexpr = Obj.magic _2 in
         let _1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 24407 "parser_cocci_menhir.ml"
+# 24408 "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_ = 
-# 1364 "parser_cocci_menhir.mly"
+# 1365 "parser_cocci_menhir.mly"
      ( Ast0.wrap(Ast0.Paren(P.clt2mcode "(" _1,_2,
                            P.clt2mcode ")" _3)) )
-# 24415 "parser_cocci_menhir.ml"
+# 24416 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24442,23 +24443,23 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 24446 "parser_cocci_menhir.ml"
+# 24447 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_midzero_list_expr_eexpr_ = Obj.magic _2 in
         let _1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 24452 "parser_cocci_menhir.ml"
+# 24453 "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_ = 
-# 1367 "parser_cocci_menhir.mly"
+# 1368 "parser_cocci_menhir.mly"
      ( let (mids,code) = _2 in
        Ast0.wrap(Ast0.DisjExpr(P.clt2mcode "(" _1,
                               code, mids,
                               P.clt2mcode ")" _3)) )
-# 24462 "parser_cocci_menhir.ml"
+# 24463 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24480,9 +24481,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_primary_expr_expr_invalid_ = 
-# 1371 "parser_cocci_menhir.mly"
+# 1372 "parser_cocci_menhir.mly"
                  ( _1 )
-# 24486 "parser_cocci_menhir.ml"
+# 24487 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24504,7 +24505,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_pure = 
 # 190 "parser_cocci_menhir.mly"
                  ( Ast0.Pure )
-# 24508 "parser_cocci_menhir.ml"
+# 24509 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24526,7 +24527,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_pure = 
 # 191 "parser_cocci_menhir.mly"
                  ( Ast0.Context )
-# 24530 "parser_cocci_menhir.ml"
+# 24531 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24552,7 +24553,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_pure = 
 # 192 "parser_cocci_menhir.mly"
                  ( Ast0.PureContext )
-# 24556 "parser_cocci_menhir.ml"
+# 24557 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24578,7 +24579,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_pure = 
 # 193 "parser_cocci_menhir.mly"
                  ( Ast0.PureContext )
-# 24582 "parser_cocci_menhir.ml"
+# 24583 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24595,7 +24596,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_pure = 
 # 194 "parser_cocci_menhir.mly"
                  ( Ast0.Impure )
-# 24599 "parser_cocci_menhir.ml"
+# 24600 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24616,14 +24617,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 59 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 24620 "parser_cocci_menhir.ml"
+# 24621 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_pure_ident = 
-# 1385 "parser_cocci_menhir.mly"
+# 1386 "parser_cocci_menhir.mly"
             ( _1 )
-# 24627 "parser_cocci_menhir.ml"
+# 24628 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24645,9 +24646,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 = 
-# 1391 "parser_cocci_menhir.mly"
+# 1392 "parser_cocci_menhir.mly"
                                  ( (None,P.id2name _1) )
-# 24651 "parser_cocci_menhir.ml"
+# 24652 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24669,9 +24670,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 = 
-# 1392 "parser_cocci_menhir.mly"
+# 1393 "parser_cocci_menhir.mly"
                                  ( _1 )
-# 24675 "parser_cocci_menhir.ml"
+# 24676 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24691,9 +24692,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 = 
-# 1393 "parser_cocci_menhir.mly"
+# 1394 "parser_cocci_menhir.mly"
                                  ( (None,"list") )
-# 24697 "parser_cocci_menhir.ml"
+# 24698 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24713,9 +24714,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 = 
-# 1394 "parser_cocci_menhir.mly"
+# 1395 "parser_cocci_menhir.mly"
                                  ( (None,"error") )
-# 24719 "parser_cocci_menhir.ml"
+# 24720 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24735,9 +24736,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 = 
-# 1395 "parser_cocci_menhir.mly"
+# 1396 "parser_cocci_menhir.mly"
                                  ( (None,"type") )
-# 24741 "parser_cocci_menhir.ml"
+# 24742 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24757,9 +24758,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 = 
-# 1396 "parser_cocci_menhir.mly"
+# 1397 "parser_cocci_menhir.mly"
                                  ( (None,"name") )
-# 24763 "parser_cocci_menhir.ml"
+# 24764 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24787,9 +24788,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_ = 
-# 1399 "parser_cocci_menhir.mly"
+# 1400 "parser_cocci_menhir.mly"
                                                     ( (i,l) )
-# 24793 "parser_cocci_menhir.ml"
+# 24794 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24817,9 +24818,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_ = 
-# 1399 "parser_cocci_menhir.mly"
+# 1400 "parser_cocci_menhir.mly"
                                                     ( (i,l) )
-# 24823 "parser_cocci_menhir.ml"
+# 24824 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24847,9 +24848,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_ = 
-# 1399 "parser_cocci_menhir.mly"
+# 1400 "parser_cocci_menhir.mly"
                                                     ( (i,l) )
-# 24853 "parser_cocci_menhir.ml"
+# 24854 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24877,9 +24878,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_ = 
-# 1399 "parser_cocci_menhir.mly"
+# 1400 "parser_cocci_menhir.mly"
                                                     ( (i,l) )
-# 24883 "parser_cocci_menhir.ml"
+# 24884 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24896,11 +24897,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 131 "parser_cocci_menhir.mly"
       (unit)
-# 24900 "parser_cocci_menhir.ml"
+# 24901 "parser_cocci_menhir.ml"
         ) = 
 # 172 "parser_cocci_menhir.mly"
         ( )
-# 24904 "parser_cocci_menhir.ml"
+# 24905 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24922,9 +24923,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_rule_elem_statement = 
-# 905 "parser_cocci_menhir.mly"
+# 906 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.Decl((Ast0.default_info(),Ast0.context_befaft()),_1)) )
-# 24928 "parser_cocci_menhir.ml"
+# 24929 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24950,15 +24951,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 24954 "parser_cocci_menhir.ml"
+# 24955 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_expr = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_rule_elem_statement = 
-# 906 "parser_cocci_menhir.mly"
+# 907 "parser_cocci_menhir.mly"
                ( P.exp_stm _1 _2 )
-# 24962 "parser_cocci_menhir.ml"
+# 24963 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -24989,20 +24990,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 24993 "parser_cocci_menhir.ml"
+# 24994 "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)
-# 24999 "parser_cocci_menhir.ml"
+# 25000 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_rule_elem_statement = 
-# 907 "parser_cocci_menhir.mly"
+# 908 "parser_cocci_menhir.mly"
                         ( P.ret_exp _1 _2 _3 )
-# 25006 "parser_cocci_menhir.ml"
+# 25007 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25028,19 +25029,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25032 "parser_cocci_menhir.ml"
+# 25033 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 57 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25037 "parser_cocci_menhir.ml"
+# 25038 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_rule_elem_statement = 
-# 908 "parser_cocci_menhir.mly"
+# 909 "parser_cocci_menhir.mly"
                   ( P.ret _1 _2 )
-# 25044 "parser_cocci_menhir.ml"
+# 25045 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25066,19 +25067,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25070 "parser_cocci_menhir.ml"
+# 25071 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25075 "parser_cocci_menhir.ml"
+# 25076 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_rule_elem_statement = 
-# 909 "parser_cocci_menhir.mly"
+# 910 "parser_cocci_menhir.mly"
                  ( P.break _1 _2 )
-# 25082 "parser_cocci_menhir.ml"
+# 25083 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25104,19 +25105,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25108 "parser_cocci_menhir.ml"
+# 25109 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25113 "parser_cocci_menhir.ml"
+# 25114 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_rule_elem_statement = 
-# 910 "parser_cocci_menhir.mly"
+# 911 "parser_cocci_menhir.mly"
                     ( P.cont _1 _2 )
-# 25120 "parser_cocci_menhir.ml"
+# 25121 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25147,24 +25148,24 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25151 "parser_cocci_menhir.ml"
+# 25152 "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 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 25157 "parser_cocci_menhir.ml"
+# 25158 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_rule_elem_statement = 
-# 912 "parser_cocci_menhir.mly"
+# 913 "parser_cocci_menhir.mly"
     ( 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)) )
-# 25168 "parser_cocci_menhir.ml"
+# 25169 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25220,18 +25221,18 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 153 "parser_cocci_menhir.mly"
       (Ast_cocci.rulename)
-# 25224 "parser_cocci_menhir.ml"
+# 25225 "parser_cocci_menhir.ml"
         ) = let nm =
           
 # 39 "standard.mly"
     ( None )
-# 25229 "parser_cocci_menhir.ml"
+# 25230 "parser_cocci_menhir.ml"
           
         in
         
 # 202 "parser_cocci_menhir.mly"
       ( P.make_cocci_rule_name_result nm d i a e ee )
-# 25235 "parser_cocci_menhir.ml"
+# 25236 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25293,19 +25294,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 153 "parser_cocci_menhir.mly"
       (Ast_cocci.rulename)
-# 25297 "parser_cocci_menhir.ml"
+# 25298 "parser_cocci_menhir.ml"
         ) = let nm =
           let x = x0 in
           
 # 41 "standard.mly"
     ( Some x )
-# 25303 "parser_cocci_menhir.ml"
+# 25304 "parser_cocci_menhir.ml"
           
         in
         
 # 202 "parser_cocci_menhir.mly"
       ( P.make_cocci_rule_name_result nm d i a e ee )
-# 25309 "parser_cocci_menhir.ml"
+# 25310 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25365,11 +25366,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 153 "parser_cocci_menhir.mly"
       (Ast_cocci.rulename)
-# 25369 "parser_cocci_menhir.ml"
+# 25370 "parser_cocci_menhir.ml"
         ) = 
 # 207 "parser_cocci_menhir.mly"
       ( P.make_generated_rule_name_result None d i a e ee )
-# 25373 "parser_cocci_menhir.ml"
+# 25374 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25411,11 +25412,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 153 "parser_cocci_menhir.mly"
       (Ast_cocci.rulename)
-# 25415 "parser_cocci_menhir.ml"
+# 25416 "parser_cocci_menhir.ml"
         ) = 
 # 209 "parser_cocci_menhir.mly"
       ( P.make_script_rule_name_result lang d )
-# 25419 "parser_cocci_menhir.ml"
+# 25420 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25459,7 +25460,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 47 "parser_cocci_menhir.mly"
       (string)
-# 25463 "parser_cocci_menhir.ml"
+# 25464 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let py : 'tv_pure_ident = Obj.magic py in
         let _startpos = _startpos_py_ in
@@ -25467,11 +25468,11 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : (
 # 159 "parser_cocci_menhir.mly"
        (string * (string * string))
-# 25471 "parser_cocci_menhir.ml"
+# 25472 "parser_cocci_menhir.ml"
         ) = 
-# 1859 "parser_cocci_menhir.mly"
+# 1860 "parser_cocci_menhir.mly"
   ( (P.id2name py, (_3, P.id2name cocci)) )
-# 25475 "parser_cocci_menhir.ml"
+# 25476 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25492,14 +25493,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let x : (
 # 87 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 25496 "parser_cocci_menhir.ml"
+# 25497 "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 ] )
-# 25503 "parser_cocci_menhir.ml"
+# 25504 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25530,14 +25531,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let x : (
 # 87 "parser_cocci_menhir.mly"
        (string * Data.clt)
-# 25534 "parser_cocci_menhir.ml"
+# 25535 "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 )
-# 25541 "parser_cocci_menhir.ml"
+# 25542 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25561,7 +25562,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_any_strict_ = 
 # 144 "standard.mly"
     ( [ x ] )
-# 25565 "parser_cocci_menhir.ml"
+# 25566 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25595,7 +25596,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_any_strict_ = 
 # 146 "standard.mly"
     ( x :: xs )
-# 25599 "parser_cocci_menhir.ml"
+# 25600 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25619,7 +25620,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_ctype_ = 
 # 144 "standard.mly"
     ( [ x ] )
-# 25623 "parser_cocci_menhir.ml"
+# 25624 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25653,7 +25654,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_ctype_ = 
 # 146 "standard.mly"
     ( x :: xs )
-# 25657 "parser_cocci_menhir.ml"
+# 25658 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25677,7 +25678,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_d_ident_ = 
 # 144 "standard.mly"
     ( [ x ] )
-# 25681 "parser_cocci_menhir.ml"
+# 25682 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25711,7 +25712,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_d_ident_ = 
 # 146 "standard.mly"
     ( x :: xs )
-# 25715 "parser_cocci_menhir.ml"
+# 25716 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25735,7 +25736,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_dexpr_ = 
 # 144 "standard.mly"
     ( [ x ] )
-# 25739 "parser_cocci_menhir.ml"
+# 25740 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25769,7 +25770,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_dexpr_ = 
 # 146 "standard.mly"
     ( x :: xs )
-# 25773 "parser_cocci_menhir.ml"
+# 25774 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25793,7 +25794,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_ident_or_const_ = 
 # 144 "standard.mly"
     ( [ x ] )
-# 25797 "parser_cocci_menhir.ml"
+# 25798 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25827,7 +25828,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_ident_or_const_ = 
 # 146 "standard.mly"
     ( x :: xs )
-# 25831 "parser_cocci_menhir.ml"
+# 25832 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25851,7 +25852,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_meta_ident_ = 
 # 144 "standard.mly"
     ( [ x ] )
-# 25855 "parser_cocci_menhir.ml"
+# 25856 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25885,7 +25886,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_meta_ident_ = 
 # 146 "standard.mly"
     ( x :: xs )
-# 25889 "parser_cocci_menhir.ml"
+# 25890 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25909,7 +25910,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_pure_ident_ = 
 # 144 "standard.mly"
     ( [ x ] )
-# 25913 "parser_cocci_menhir.ml"
+# 25914 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25943,7 +25944,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_pure_ident_ = 
 # 146 "standard.mly"
     ( x :: xs )
-# 25947 "parser_cocci_menhir.ml"
+# 25948 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -25967,7 +25968,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_ = 
 # 144 "standard.mly"
     ( [ x ] )
-# 25971 "parser_cocci_menhir.ml"
+# 25972 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26001,7 +26002,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_separated_nonempty_list_TComma_pure_ident_or_meta_ident_ = 
 # 146 "standard.mly"
     ( x :: xs )
-# 26005 "parser_cocci_menhir.ml"
+# 26006 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26025,7 +26026,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 ] )
-# 26029 "parser_cocci_menhir.ml"
+# 26030 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26059,7 +26060,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 )
-# 26063 "parser_cocci_menhir.ml"
+# 26064 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26083,7 +26084,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 ] )
-# 26087 "parser_cocci_menhir.ml"
+# 26088 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26117,7 +26118,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 )
-# 26121 "parser_cocci_menhir.ml"
+# 26122 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26141,7 +26142,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 ] )
-# 26145 "parser_cocci_menhir.ml"
+# 26146 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26175,7 +26176,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 )
-# 26179 "parser_cocci_menhir.ml"
+# 26180 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26199,7 +26200,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 ] )
-# 26203 "parser_cocci_menhir.ml"
+# 26204 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26233,7 +26234,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 )
-# 26237 "parser_cocci_menhir.ml"
+# 26238 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26255,9 +26256,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_single_statement = 
-# 920 "parser_cocci_menhir.mly"
+# 921 "parser_cocci_menhir.mly"
                                       ( _1 )
-# 26261 "parser_cocci_menhir.ml"
+# 26262 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26288,24 +26289,24 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26292 "parser_cocci_menhir.ml"
+# 26293 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_midzero_list_statement_statement_ = Obj.magic _2 in
         let _1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26298 "parser_cocci_menhir.ml"
+# 26299 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_single_statement = 
-# 924 "parser_cocci_menhir.mly"
+# 925 "parser_cocci_menhir.mly"
       ( 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)) )
-# 26309 "parser_cocci_menhir.ml"
+# 26310 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26327,9 +26328,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_statement = 
-# 847 "parser_cocci_menhir.mly"
+# 848 "parser_cocci_menhir.mly"
            ( _1 )
-# 26333 "parser_cocci_menhir.ml"
+# 26334 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26350,14 +26351,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 64 "parser_cocci_menhir.mly"
        (Parse_aux.info)
-# 26354 "parser_cocci_menhir.ml"
+# 26355 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_statement = 
-# 849 "parser_cocci_menhir.mly"
+# 850 "parser_cocci_menhir.mly"
     ( P.meta_stm _1 )
-# 26361 "parser_cocci_menhir.ml"
+# 26362 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26383,15 +26384,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26387 "parser_cocci_menhir.ml"
+# 26388 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_expr = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_statement = 
-# 851 "parser_cocci_menhir.mly"
+# 852 "parser_cocci_menhir.mly"
     ( P.exp_stm _1 _2 )
-# 26395 "parser_cocci_menhir.ml"
+# 26396 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26433,25 +26434,25 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _4 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26437 "parser_cocci_menhir.ml"
+# 26438 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr = Obj.magic _3 in
         let _2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26443 "parser_cocci_menhir.ml"
+# 26444 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 57 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26448 "parser_cocci_menhir.ml"
+# 26449 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__5_ in
         let _v : 'tv_statement = 
-# 853 "parser_cocci_menhir.mly"
+# 854 "parser_cocci_menhir.mly"
     ( P.ifthen _1 _2 _3 _4 _5 )
-# 26455 "parser_cocci_menhir.ml"
+# 26456 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26503,31 +26504,31 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _6 : (
 # 57 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26507 "parser_cocci_menhir.ml"
+# 26508 "parser_cocci_menhir.ml"
         ) = Obj.magic _6 in
         let _5 : 'tv_single_statement = Obj.magic _5 in
         let _4 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26513 "parser_cocci_menhir.ml"
+# 26514 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr = Obj.magic _3 in
         let _2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26519 "parser_cocci_menhir.ml"
+# 26520 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 57 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26524 "parser_cocci_menhir.ml"
+# 26525 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__7_ in
         let _v : 'tv_statement = 
-# 855 "parser_cocci_menhir.mly"
+# 856 "parser_cocci_menhir.mly"
     ( P.ifthenelse _1 _2 _3 _4 _5 _6 _7 )
-# 26531 "parser_cocci_menhir.ml"
+# 26532 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26589,37 +26590,37 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _8 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26593 "parser_cocci_menhir.ml"
+# 26594 "parser_cocci_menhir.ml"
         ) = Obj.magic _8 in
         let _7 : 'tv_option_eexpr_ = Obj.magic _7 in
         let _6 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26599 "parser_cocci_menhir.ml"
+# 26600 "parser_cocci_menhir.ml"
         ) = Obj.magic _6 in
         let _5 : 'tv_option_eexpr_ = Obj.magic _5 in
         let _4 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26605 "parser_cocci_menhir.ml"
+# 26606 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_option_eexpr_ = Obj.magic _3 in
         let _2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26611 "parser_cocci_menhir.ml"
+# 26612 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 57 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26616 "parser_cocci_menhir.ml"
+# 26617 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__9_ in
         let _v : 'tv_statement = 
-# 858 "parser_cocci_menhir.mly"
+# 859 "parser_cocci_menhir.mly"
     ( P.forloop _1 _2 _3 _4 _5 _6 _7 _8 _9 )
-# 26623 "parser_cocci_menhir.ml"
+# 26624 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26661,25 +26662,25 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _4 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26665 "parser_cocci_menhir.ml"
+# 26666 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr = Obj.magic _3 in
         let _2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26671 "parser_cocci_menhir.ml"
+# 26672 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 57 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26676 "parser_cocci_menhir.ml"
+# 26677 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__5_ in
         let _v : 'tv_statement = 
-# 860 "parser_cocci_menhir.mly"
+# 861 "parser_cocci_menhir.mly"
     ( P.whileloop _1 _2 _3 _4 _5 )
-# 26683 "parser_cocci_menhir.ml"
+# 26684 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26730,36 +26731,36 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _7 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26734 "parser_cocci_menhir.ml"
+# 26735 "parser_cocci_menhir.ml"
         ) = Obj.magic _7 in
         let _6 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26739 "parser_cocci_menhir.ml"
+# 26740 "parser_cocci_menhir.ml"
         ) = Obj.magic _6 in
         let _5 : 'tv_eexpr = Obj.magic _5 in
         let _4 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26745 "parser_cocci_menhir.ml"
+# 26746 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : (
 # 57 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26750 "parser_cocci_menhir.ml"
+# 26751 "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)
-# 26756 "parser_cocci_menhir.ml"
+# 26757 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__7_ in
         let _v : 'tv_statement = 
-# 862 "parser_cocci_menhir.mly"
+# 863 "parser_cocci_menhir.mly"
     ( P.doloop _1 _2 _3 _4 _5 _6 _7 )
-# 26763 "parser_cocci_menhir.ml"
+# 26764 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26801,21 +26802,21 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _4 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26805 "parser_cocci_menhir.ml"
+# 26806 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr_list_option = Obj.magic _3 in
         let _2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26811 "parser_cocci_menhir.ml"
+# 26812 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_iter_ident = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__5_ in
         let _v : 'tv_statement = 
-# 864 "parser_cocci_menhir.mly"
+# 865 "parser_cocci_menhir.mly"
     ( P.iterator _1 _2 _3 _4 _5 )
-# 26819 "parser_cocci_menhir.ml"
+# 26820 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26866,36 +26867,36 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _7 : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26870 "parser_cocci_menhir.ml"
+# 26871 "parser_cocci_menhir.ml"
         ) = Obj.magic _7 in
         let _6 : 'tv_list_case_line_ = Obj.magic _6 in
         let _5 : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26876 "parser_cocci_menhir.ml"
+# 26877 "parser_cocci_menhir.ml"
         ) = Obj.magic _5 in
         let _4 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26881 "parser_cocci_menhir.ml"
+# 26882 "parser_cocci_menhir.ml"
         ) = Obj.magic _4 in
         let _3 : 'tv_eexpr = Obj.magic _3 in
         let _2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26887 "parser_cocci_menhir.ml"
+# 26888 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 57 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26892 "parser_cocci_menhir.ml"
+# 26893 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__7_ in
         let _v : 'tv_statement = 
-# 866 "parser_cocci_menhir.mly"
+# 867 "parser_cocci_menhir.mly"
     ( P.switch _1 _2 _3 _4 _5 _6 _7 )
-# 26899 "parser_cocci_menhir.ml"
+# 26900 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26926,20 +26927,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26930 "parser_cocci_menhir.ml"
+# 26931 "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)
-# 26936 "parser_cocci_menhir.ml"
+# 26937 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_statement = 
-# 867 "parser_cocci_menhir.mly"
+# 868 "parser_cocci_menhir.mly"
                         ( P.ret_exp _1 _2 _3 )
-# 26943 "parser_cocci_menhir.ml"
+# 26944 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -26965,19 +26966,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26969 "parser_cocci_menhir.ml"
+# 26970 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 57 "parser_cocci_menhir.mly"
        (Data.clt)
-# 26974 "parser_cocci_menhir.ml"
+# 26975 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_statement = 
-# 868 "parser_cocci_menhir.mly"
+# 869 "parser_cocci_menhir.mly"
                   ( P.ret _1 _2 )
-# 26981 "parser_cocci_menhir.ml"
+# 26982 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27003,19 +27004,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27007 "parser_cocci_menhir.ml"
+# 27008 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27012 "parser_cocci_menhir.ml"
+# 27013 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_statement = 
-# 869 "parser_cocci_menhir.mly"
+# 870 "parser_cocci_menhir.mly"
                  ( P.break _1 _2 )
-# 27019 "parser_cocci_menhir.ml"
+# 27020 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27041,19 +27042,19 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27045 "parser_cocci_menhir.ml"
+# 27046 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27050 "parser_cocci_menhir.ml"
+# 27051 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_statement = 
-# 870 "parser_cocci_menhir.mly"
+# 871 "parser_cocci_menhir.mly"
                     ( P.cont _1 _2 )
-# 27057 "parser_cocci_menhir.ml"
+# 27058 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27079,15 +27080,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27083 "parser_cocci_menhir.ml"
+# 27084 "parser_cocci_menhir.ml"
         ) = Obj.magic _2 in
         let _1 : 'tv_ident = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_statement = 
-# 871 "parser_cocci_menhir.mly"
+# 872 "parser_cocci_menhir.mly"
                 ( P.label _1 _2 )
-# 27091 "parser_cocci_menhir.ml"
+# 27092 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27118,20 +27119,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27122 "parser_cocci_menhir.ml"
+# 27123 "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)
-# 27128 "parser_cocci_menhir.ml"
+# 27129 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_statement = 
-# 872 "parser_cocci_menhir.mly"
+# 873 "parser_cocci_menhir.mly"
                       ( P.goto _1 _2 _3 )
-# 27135 "parser_cocci_menhir.ml"
+# 27136 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27162,20 +27163,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27166 "parser_cocci_menhir.ml"
+# 27167 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_fun_start = Obj.magic _2 in
         let _1 : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27172 "parser_cocci_menhir.ml"
+# 27173 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_statement = 
-# 874 "parser_cocci_menhir.mly"
+# 875 "parser_cocci_menhir.mly"
     ( P.seq _1 _2 _3 )
-# 27179 "parser_cocci_menhir.ml"
+# 27180 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27202,14 +27203,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27206 "parser_cocci_menhir.ml"
+# 27207 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_w_ in
         let _v : 'tv_stm_dots = 
-# 878 "parser_cocci_menhir.mly"
+# 879 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.Dots(P.clt2mcode "..." _1, List.concat w)) )
-# 27213 "parser_cocci_menhir.ml"
+# 27214 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27245,22 +27246,22 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let c : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27249 "parser_cocci_menhir.ml"
+# 27250 "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 : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27256 "parser_cocci_menhir.ml"
+# 27257 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_c_ in
         let _v : 'tv_stm_dots = 
-# 880 "parser_cocci_menhir.mly"
+# 881 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.Nest(P.clt2mcode "<..." _1, b,
                          P.clt2mcode "...>" c, List.concat w, false)) )
-# 27264 "parser_cocci_menhir.ml"
+# 27265 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27296,22 +27297,22 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let c : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27300 "parser_cocci_menhir.ml"
+# 27301 "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 : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27307 "parser_cocci_menhir.ml"
+# 27308 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos_c_ in
         let _v : 'tv_stm_dots = 
-# 883 "parser_cocci_menhir.mly"
+# 884 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.Nest(P.clt2mcode "<+..." _1, b,
                          P.clt2mcode "...+>" c, List.concat w, true)) )
-# 27315 "parser_cocci_menhir.ml"
+# 27316 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27332,14 +27333,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let s : (
 # 53 "parser_cocci_menhir.mly"
       (Data.clt)
-# 27336 "parser_cocci_menhir.ml"
+# 27337 "parser_cocci_menhir.ml"
         ) = Obj.magic s in
         let _startpos = _startpos_s_ in
         let _endpos = _endpos_s_ in
         let _v : 'tv_storage = 
-# 805 "parser_cocci_menhir.mly"
+# 806 "parser_cocci_menhir.mly"
                         ( P.clt2mcode Ast.Static s )
-# 27343 "parser_cocci_menhir.ml"
+# 27344 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27360,14 +27361,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let s : (
 # 53 "parser_cocci_menhir.mly"
       (Data.clt)
-# 27364 "parser_cocci_menhir.ml"
+# 27365 "parser_cocci_menhir.ml"
         ) = Obj.magic s in
         let _startpos = _startpos_s_ in
         let _endpos = _endpos_s_ in
         let _v : 'tv_storage = 
-# 806 "parser_cocci_menhir.mly"
+# 807 "parser_cocci_menhir.mly"
                         ( P.clt2mcode Ast.Auto s )
-# 27371 "parser_cocci_menhir.ml"
+# 27372 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27388,14 +27389,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let s : (
 # 53 "parser_cocci_menhir.mly"
       (Data.clt)
-# 27392 "parser_cocci_menhir.ml"
+# 27393 "parser_cocci_menhir.ml"
         ) = Obj.magic s in
         let _startpos = _startpos_s_ in
         let _endpos = _endpos_s_ in
         let _v : 'tv_storage = 
-# 807 "parser_cocci_menhir.mly"
+# 808 "parser_cocci_menhir.mly"
                         ( P.clt2mcode Ast.Register s )
-# 27399 "parser_cocci_menhir.ml"
+# 27400 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27416,14 +27417,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let s : (
 # 53 "parser_cocci_menhir.mly"
       (Data.clt)
-# 27420 "parser_cocci_menhir.ml"
+# 27421 "parser_cocci_menhir.ml"
         ) = Obj.magic s in
         let _startpos = _startpos_s_ in
         let _endpos = _endpos_s_ in
         let _v : 'tv_storage = 
-# 808 "parser_cocci_menhir.mly"
+# 809 "parser_cocci_menhir.mly"
                         ( P.clt2mcode Ast.Extern s )
-# 27427 "parser_cocci_menhir.ml"
+# 27428 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27445,7 +27446,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_struct_decl = 
 # 512 "parser_cocci_menhir.mly"
                ( [] )
-# 27449 "parser_cocci_menhir.ml"
+# 27450 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27476,7 +27477,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27480 "parser_cocci_menhir.ml"
+# 27481 "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
@@ -27486,7 +27487,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
 # 514 "parser_cocci_menhir.mly"
   ( let (id,fn) = d in
         [Ast0.wrap(Ast0.UnInit(None,fn t,id,P.clt2mcode ";" pv))] )
-# 27490 "parser_cocci_menhir.ml"
+# 27491 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27547,34 +27548,34 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27551 "parser_cocci_menhir.ml"
+# 27552 "parser_cocci_menhir.ml"
         ) = Obj.magic pv in
         let rp2 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27556 "parser_cocci_menhir.ml"
+# 27557 "parser_cocci_menhir.ml"
         ) = Obj.magic rp2 in
         let p : 'tv_decl_list_name_opt_decl_ = Obj.magic p in
         let lp2 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27562 "parser_cocci_menhir.ml"
+# 27563 "parser_cocci_menhir.ml"
         ) = Obj.magic lp2 in
         let rp1 : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27567 "parser_cocci_menhir.ml"
+# 27568 "parser_cocci_menhir.ml"
         ) = Obj.magic rp1 in
         let d : 'tv_d_ident = Obj.magic d in
         let st : (
 # 99 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27573 "parser_cocci_menhir.ml"
+# 27574 "parser_cocci_menhir.ml"
         ) = Obj.magic st in
         let lp1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27578 "parser_cocci_menhir.ml"
+# 27579 "parser_cocci_menhir.ml"
         ) = Obj.magic lp1 in
         let t : 'tv_fn_ctype = Obj.magic t in
         let _startpos = _startpos_t_ in
@@ -27588,7 +27589,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))] )
-# 27592 "parser_cocci_menhir.ml"
+# 27593 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27619,7 +27620,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27623 "parser_cocci_menhir.ml"
+# 27624 "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
@@ -27629,7 +27630,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 39 "standard.mly"
     ( None )
-# 27633 "parser_cocci_menhir.ml"
+# 27634 "parser_cocci_menhir.ml"
           
         in
         
@@ -27637,7 +27638,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))] )
-# 27641 "parser_cocci_menhir.ml"
+# 27642 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27673,7 +27674,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let pv : (
 # 107 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27677 "parser_cocci_menhir.ml"
+# 27678 "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
@@ -27685,7 +27686,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           
 # 41 "standard.mly"
     ( Some x )
-# 27689 "parser_cocci_menhir.ml"
+# 27690 "parser_cocci_menhir.ml"
           
         in
         
@@ -27693,7 +27694,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))] )
-# 27697 "parser_cocci_menhir.ml"
+# 27698 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27717,7 +27718,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_struct_decl_list = 
 # 531 "parser_cocci_menhir.mly"
                           ( Ast0.wrap(Ast0.DOTS(_1)) )
-# 27721 "parser_cocci_menhir.ml"
+# 27722 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27741,7 +27742,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_struct_decl_list_start = 
 # 534 "parser_cocci_menhir.mly"
                                      ( _1 )
-# 27745 "parser_cocci_menhir.ml"
+# 27746 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27771,7 +27772,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_struct_decl_list_start = 
 # 535 "parser_cocci_menhir.mly"
                                      ( _1@_2 )
-# 27775 "parser_cocci_menhir.ml"
+# 27776 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27801,7 +27802,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _v : 'tv_struct_decl_list_start = 
 # 537 "parser_cocci_menhir.mly"
     ( (P.mkddots "..." d)::r )
-# 27805 "parser_cocci_menhir.ml"
+# 27806 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27822,14 +27823,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let s : (
 # 50 "parser_cocci_menhir.mly"
       (Data.clt)
-# 27826 "parser_cocci_menhir.ml"
+# 27827 "parser_cocci_menhir.ml"
         ) = Obj.magic s in
         let _startpos = _startpos_s_ in
         let _endpos = _endpos_s_ in
         let _v : 'tv_struct_or_union = 
 # 508 "parser_cocci_menhir.mly"
                  ( P.clt2mcode Ast.Struct s )
-# 27833 "parser_cocci_menhir.ml"
+# 27834 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27850,14 +27851,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let u : (
 # 50 "parser_cocci_menhir.mly"
       (Data.clt)
-# 27854 "parser_cocci_menhir.ml"
+# 27855 "parser_cocci_menhir.ml"
         ) = Obj.magic u in
         let _startpos = _startpos_u_ in
         let _endpos = _endpos_u_ in
         let _v : 'tv_struct_or_union = 
 # 509 "parser_cocci_menhir.mly"
                  ( P.clt2mcode Ast.Union u )
-# 27861 "parser_cocci_menhir.ml"
+# 27862 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27879,9 +27880,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_top_eexpr = 
-# 1199 "parser_cocci_menhir.mly"
+# 1200 "parser_cocci_menhir.mly"
         ( Ast0.wrap(Ast0.OTHER(Ast0.wrap(Ast0.Exp(_1)))) )
-# 27885 "parser_cocci_menhir.ml"
+# 27886 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27912,20 +27913,20 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _3 : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27916 "parser_cocci_menhir.ml"
+# 27917 "parser_cocci_menhir.ml"
         ) = Obj.magic _3 in
         let _2 : 'tv_initialize_list = Obj.magic _2 in
         let _1 : (
 # 101 "parser_cocci_menhir.mly"
        (Data.clt)
-# 27922 "parser_cocci_menhir.ml"
+# 27923 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__3_ in
         let _v : 'tv_top_init = 
-# 1637 "parser_cocci_menhir.mly"
+# 1638 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.InitList(P.clt2mcode "{" _1,_2,P.clt2mcode "}" _3)) )
-# 27929 "parser_cocci_menhir.ml"
+# 27930 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27940,9 +27941,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 = 
-# 1625 "parser_cocci_menhir.mly"
+# 1626 "parser_cocci_menhir.mly"
                                      ([])
-# 27946 "parser_cocci_menhir.ml"
+# 27947 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27968,9 +27969,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_after_dots = 
-# 1626 "parser_cocci_menhir.mly"
+# 1627 "parser_cocci_menhir.mly"
                                      (_2)
-# 27974 "parser_cocci_menhir.ml"
+# 27975 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -27998,9 +27999,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_after_dots = 
-# 1627 "parser_cocci_menhir.mly"
+# 1628 "parser_cocci_menhir.mly"
                                      ((Ast0.wrap(Ast0.Exp(_1)))::_2)
-# 28004 "parser_cocci_menhir.ml"
+# 28005 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28028,9 +28029,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_after_dots = 
-# 1628 "parser_cocci_menhir.mly"
+# 1629 "parser_cocci_menhir.mly"
                                           (_1@_2)
-# 28034 "parser_cocci_menhir.ml"
+# 28035 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28056,9 +28057,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_after_dots_init = 
-# 1616 "parser_cocci_menhir.mly"
+# 1617 "parser_cocci_menhir.mly"
                                      (_2)
-# 28062 "parser_cocci_menhir.ml"
+# 28063 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28086,9 +28087,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_after_dots_init = 
-# 1617 "parser_cocci_menhir.mly"
+# 1618 "parser_cocci_menhir.mly"
                                      ((Ast0.wrap(Ast0.Exp(_1)))::_2)
-# 28092 "parser_cocci_menhir.ml"
+# 28093 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28116,9 +28117,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_after_dots_init = 
-# 1618 "parser_cocci_menhir.mly"
+# 1619 "parser_cocci_menhir.mly"
                                           (_1@_2)
-# 28122 "parser_cocci_menhir.ml"
+# 28123 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28133,9 +28134,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 = 
-# 1621 "parser_cocci_menhir.mly"
+# 1622 "parser_cocci_menhir.mly"
                                      ([])
-# 28139 "parser_cocci_menhir.ml"
+# 28140 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28163,9 +28164,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_after_exp = 
-# 1622 "parser_cocci_menhir.mly"
+# 1623 "parser_cocci_menhir.mly"
                                      (_1::_2)
-# 28169 "parser_cocci_menhir.ml"
+# 28170 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28180,9 +28181,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 = 
-# 1631 "parser_cocci_menhir.mly"
+# 1632 "parser_cocci_menhir.mly"
                                      ([])
-# 28186 "parser_cocci_menhir.ml"
+# 28187 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28210,9 +28211,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_after_stm = 
-# 1632 "parser_cocci_menhir.mly"
+# 1633 "parser_cocci_menhir.mly"
                                      (_1::_2)
-# 28216 "parser_cocci_menhir.ml"
+# 28217 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28240,9 +28241,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_after_stm = 
-# 1633 "parser_cocci_menhir.mly"
+# 1634 "parser_cocci_menhir.mly"
                                      (_1@_2)
-# 28246 "parser_cocci_menhir.ml"
+# 28247 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28270,9 +28271,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_ = 
-# 1611 "parser_cocci_menhir.mly"
+# 1612 "parser_cocci_menhir.mly"
                                      ( _1::_2 )
-# 28276 "parser_cocci_menhir.ml"
+# 28277 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28300,9 +28301,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_ = 
-# 1612 "parser_cocci_menhir.mly"
+# 1613 "parser_cocci_menhir.mly"
                                      ( (Ast0.wrap(Ast0.Exp(_1)))::_2 )
-# 28306 "parser_cocci_menhir.ml"
+# 28307 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28330,9 +28331,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_ = 
-# 1613 "parser_cocci_menhir.mly"
+# 1614 "parser_cocci_menhir.mly"
                                           ( _1@_2 )
-# 28336 "parser_cocci_menhir.ml"
+# 28337 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28365,7 +28366,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let a0 : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28369 "parser_cocci_menhir.ml"
+# 28370 "parser_cocci_menhir.ml"
         ) = Obj.magic a0 in
         let _startpos = _startpos_a0_ in
         let _endpos = _endpos_b_ in
@@ -28373,15 +28374,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           let w = w0 in
           let a = a0 in
           
-# 888 "parser_cocci_menhir.mly"
+# 889 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.Dots(P.clt2mcode "..." a, List.concat w)) )
-# 28379 "parser_cocci_menhir.ml"
+# 28380 "parser_cocci_menhir.ml"
           
         in
         
-# 1604 "parser_cocci_menhir.mly"
+# 1605 "parser_cocci_menhir.mly"
                                              ( a::b )
-# 28385 "parser_cocci_menhir.ml"
+# 28386 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28423,14 +28424,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let c0 : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28427 "parser_cocci_menhir.ml"
+# 28428 "parser_cocci_menhir.ml"
         ) = Obj.magic c0 in
         let b0 : 'tv_nest_start = Obj.magic b0 in
         let w0 : 'tv_list_whenppdecs_ = Obj.magic w0 in
         let a0 : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28434 "parser_cocci_menhir.ml"
+# 28435 "parser_cocci_menhir.ml"
         ) = Obj.magic a0 in
         let _startpos = _startpos_a0_ in
         let _endpos = _endpos_b_ in
@@ -28440,16 +28441,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           let w = w0 in
           let a = a0 in
           
-# 892 "parser_cocci_menhir.mly"
+# 893 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.Nest(P.clt2mcode "<..." a, b,
                          P.clt2mcode "...>" c, List.concat w, false)) )
-# 28447 "parser_cocci_menhir.ml"
+# 28448 "parser_cocci_menhir.ml"
           
         in
         
-# 1605 "parser_cocci_menhir.mly"
+# 1606 "parser_cocci_menhir.mly"
                                               ( a::b )
-# 28453 "parser_cocci_menhir.ml"
+# 28454 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28491,14 +28492,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let c0 : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28495 "parser_cocci_menhir.ml"
+# 28496 "parser_cocci_menhir.ml"
         ) = Obj.magic c0 in
         let b0 : 'tv_nest_start = Obj.magic b0 in
         let w0 : 'tv_list_whenppdecs_ = Obj.magic w0 in
         let a0 : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28502 "parser_cocci_menhir.ml"
+# 28503 "parser_cocci_menhir.ml"
         ) = Obj.magic a0 in
         let _startpos = _startpos_a0_ in
         let _endpos = _endpos_b_ in
@@ -28508,16 +28509,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           let w = w0 in
           let a = a0 in
           
-# 895 "parser_cocci_menhir.mly"
+# 896 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.Nest(P.clt2mcode "<+..." a, b,
                          P.clt2mcode "...+>" c, List.concat w, true)) )
-# 28515 "parser_cocci_menhir.ml"
+# 28516 "parser_cocci_menhir.ml"
           
         in
         
-# 1605 "parser_cocci_menhir.mly"
+# 1606 "parser_cocci_menhir.mly"
                                               ( a::b )
-# 28521 "parser_cocci_menhir.ml"
+# 28522 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28553,14 +28554,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let c0 : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28557 "parser_cocci_menhir.ml"
+# 28558 "parser_cocci_menhir.ml"
         ) = Obj.magic c0 in
         let b0 : 'tv_nest_start = Obj.magic b0 in
         let w0 : 'tv_list_whenppdecs_ = Obj.magic w0 in
         let a0 : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28564 "parser_cocci_menhir.ml"
+# 28565 "parser_cocci_menhir.ml"
         ) = Obj.magic a0 in
         let _startpos = _startpos_a0_ in
         let _endpos = _endpos_c0_ in
@@ -28570,16 +28571,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           let w = w0 in
           let a = a0 in
           
-# 892 "parser_cocci_menhir.mly"
+# 893 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.Nest(P.clt2mcode "<..." a, b,
                          P.clt2mcode "...>" c, List.concat w, false)) )
-# 28577 "parser_cocci_menhir.ml"
+# 28578 "parser_cocci_menhir.ml"
           
         in
         
-# 1606 "parser_cocci_menhir.mly"
+# 1607 "parser_cocci_menhir.mly"
                                        ( [a] )
-# 28583 "parser_cocci_menhir.ml"
+# 28584 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28615,14 +28616,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let c0 : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28619 "parser_cocci_menhir.ml"
+# 28620 "parser_cocci_menhir.ml"
         ) = Obj.magic c0 in
         let b0 : 'tv_nest_start = Obj.magic b0 in
         let w0 : 'tv_list_whenppdecs_ = Obj.magic w0 in
         let a0 : (
 # 73 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28626 "parser_cocci_menhir.ml"
+# 28627 "parser_cocci_menhir.ml"
         ) = Obj.magic a0 in
         let _startpos = _startpos_a0_ in
         let _endpos = _endpos_c0_ in
@@ -28632,16 +28633,16 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
           let w = w0 in
           let a = a0 in
           
-# 895 "parser_cocci_menhir.mly"
+# 896 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.Nest(P.clt2mcode "<+..." a, b,
                          P.clt2mcode "...+>" c, List.concat w, true)) )
-# 28639 "parser_cocci_menhir.ml"
+# 28640 "parser_cocci_menhir.ml"
           
         in
         
-# 1606 "parser_cocci_menhir.mly"
+# 1607 "parser_cocci_menhir.mly"
                                        ( [a] )
-# 28645 "parser_cocci_menhir.ml"
+# 28646 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28669,9 +28670,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_seq_startne_toplevel_after_dots_init_ = 
-# 1607 "parser_cocci_menhir.mly"
+# 1608 "parser_cocci_menhir.mly"
                                      ( (Ast0.wrap(Ast0.Exp(_1)))::_2 )
-# 28675 "parser_cocci_menhir.ml"
+# 28676 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28699,9 +28700,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_toplevel_seq_startne_toplevel_after_dots_init_ = 
-# 1608 "parser_cocci_menhir.mly"
+# 1609 "parser_cocci_menhir.mly"
                                           ( _1@_2 )
-# 28705 "parser_cocci_menhir.ml"
+# 28706 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28723,9 +28724,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_typedef_ident = 
-# 1516 "parser_cocci_menhir.mly"
+# 1517 "parser_cocci_menhir.mly"
          ( Ast0.wrap(Ast0.TypeName(P.id2mcode _1)) )
-# 28729 "parser_cocci_menhir.ml"
+# 28730 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28746,15 +28747,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 64 "parser_cocci_menhir.mly"
        (Parse_aux.info)
-# 28750 "parser_cocci_menhir.ml"
+# 28751 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_typedef_ident = 
-# 1518 "parser_cocci_menhir.mly"
+# 1519 "parser_cocci_menhir.mly"
          ( let (nm,pure,clt) = _1 in
         Ast0.wrap(Ast0.MetaType(P.clt2mcode nm clt,pure)) )
-# 28758 "parser_cocci_menhir.ml"
+# 28759 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28776,9 +28777,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_ = 
-# 1288 "parser_cocci_menhir.mly"
+# 1289 "parser_cocci_menhir.mly"
                                          ( _1 )
-# 28782 "parser_cocci_menhir.ml"
+# 28783 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28805,14 +28806,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 85 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28809 "parser_cocci_menhir.ml"
+# 28810 "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_ = 
-# 1290 "parser_cocci_menhir.mly"
+# 1291 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Inc _1)) )
-# 28816 "parser_cocci_menhir.ml"
+# 28817 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28839,14 +28840,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 85 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28843 "parser_cocci_menhir.ml"
+# 28844 "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_ = 
-# 1292 "parser_cocci_menhir.mly"
+# 1293 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Dec _1)) )
-# 28850 "parser_cocci_menhir.ml"
+# 28851 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28869,14 +28870,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             MenhirLib.EngineTypes.next = _menhir_stack;
             };
           } = _menhir_stack in
-        let _2 : 'tv_unary_expr_eexpr_dot_expressions_ = Obj.magic _2 in
+        let _2 : 'tv_cast_expr_eexpr_dot_expressions_ = Obj.magic _2 in
         let _1 : 'tv_unary_op = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_eexpr_dot_expressions_ = 
-# 1294 "parser_cocci_menhir.mly"
+# 1295 "parser_cocci_menhir.mly"
       ( let mcode = _1 in Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 28880 "parser_cocci_menhir.ml"
+# 28881 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28903,15 +28904,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28907 "parser_cocci_menhir.ml"
+# 28908 "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_ = 
-# 1296 "parser_cocci_menhir.mly"
+# 1297 "parser_cocci_menhir.mly"
       ( let mcode = P.clt2mcode Ast.Not _1 in
       Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 28915 "parser_cocci_menhir.ml"
+# 28916 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28938,14 +28939,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28942 "parser_cocci_menhir.ml"
+# 28943 "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_ = 
-# 1299 "parser_cocci_menhir.mly"
+# 1300 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.SizeOfExpr (P.clt2mcode "sizeof" _1, _2)) )
-# 28949 "parser_cocci_menhir.ml"
+# 28950 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -28981,27 +28982,27 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let rp : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28985 "parser_cocci_menhir.ml"
+# 28986 "parser_cocci_menhir.ml"
         ) = Obj.magic rp in
         let t : 'tv_ctype = Obj.magic t in
         let lp : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28991 "parser_cocci_menhir.ml"
+# 28992 "parser_cocci_menhir.ml"
         ) = Obj.magic lp in
         let s : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 28996 "parser_cocci_menhir.ml"
+# 28997 "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_ = 
-# 1301 "parser_cocci_menhir.mly"
+# 1302 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.SizeOfType (P.clt2mcode "sizeof" s,
                                    P.clt2mcode "(" lp,t,
                                    P.clt2mcode ")" rp)) )
-# 29005 "parser_cocci_menhir.ml"
+# 29006 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29023,9 +29024,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_unary_expr_eexpr_invalid_ = 
-# 1288 "parser_cocci_menhir.mly"
+# 1289 "parser_cocci_menhir.mly"
                                          ( _1 )
-# 29029 "parser_cocci_menhir.ml"
+# 29030 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29052,14 +29053,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 85 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29056 "parser_cocci_menhir.ml"
+# 29057 "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_ = 
-# 1290 "parser_cocci_menhir.mly"
+# 1291 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Inc _1)) )
-# 29063 "parser_cocci_menhir.ml"
+# 29064 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29086,14 +29087,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 85 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29090 "parser_cocci_menhir.ml"
+# 29091 "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_ = 
-# 1292 "parser_cocci_menhir.mly"
+# 1293 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Dec _1)) )
-# 29097 "parser_cocci_menhir.ml"
+# 29098 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29116,14 +29117,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             MenhirLib.EngineTypes.next = _menhir_stack;
             };
           } = _menhir_stack in
-        let _2 : 'tv_unary_expr_eexpr_invalid_ = Obj.magic _2 in
+        let _2 : 'tv_cast_expr_eexpr_invalid_ = Obj.magic _2 in
         let _1 : 'tv_unary_op = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_eexpr_invalid_ = 
-# 1294 "parser_cocci_menhir.mly"
+# 1295 "parser_cocci_menhir.mly"
       ( let mcode = _1 in Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 29127 "parser_cocci_menhir.ml"
+# 29128 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29150,15 +29151,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29154 "parser_cocci_menhir.ml"
+# 29155 "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_ = 
-# 1296 "parser_cocci_menhir.mly"
+# 1297 "parser_cocci_menhir.mly"
       ( let mcode = P.clt2mcode Ast.Not _1 in
       Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 29162 "parser_cocci_menhir.ml"
+# 29163 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29185,14 +29186,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29189 "parser_cocci_menhir.ml"
+# 29190 "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_ = 
-# 1299 "parser_cocci_menhir.mly"
+# 1300 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.SizeOfExpr (P.clt2mcode "sizeof" _1, _2)) )
-# 29196 "parser_cocci_menhir.ml"
+# 29197 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29228,27 +29229,27 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let rp : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29232 "parser_cocci_menhir.ml"
+# 29233 "parser_cocci_menhir.ml"
         ) = Obj.magic rp in
         let t : 'tv_ctype = Obj.magic t in
         let lp : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29238 "parser_cocci_menhir.ml"
+# 29239 "parser_cocci_menhir.ml"
         ) = Obj.magic lp in
         let s : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29243 "parser_cocci_menhir.ml"
+# 29244 "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_ = 
-# 1301 "parser_cocci_menhir.mly"
+# 1302 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.SizeOfType (P.clt2mcode "sizeof" s,
                                    P.clt2mcode "(" lp,t,
                                    P.clt2mcode ")" rp)) )
-# 29252 "parser_cocci_menhir.ml"
+# 29253 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29270,9 +29271,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_ = 
-# 1288 "parser_cocci_menhir.mly"
+# 1289 "parser_cocci_menhir.mly"
                                          ( _1 )
-# 29276 "parser_cocci_menhir.ml"
+# 29277 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29299,14 +29300,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 85 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29303 "parser_cocci_menhir.ml"
+# 29304 "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_ = 
-# 1290 "parser_cocci_menhir.mly"
+# 1291 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Inc _1)) )
-# 29310 "parser_cocci_menhir.ml"
+# 29311 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29333,14 +29334,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 85 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29337 "parser_cocci_menhir.ml"
+# 29338 "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_ = 
-# 1292 "parser_cocci_menhir.mly"
+# 1293 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Dec _1)) )
-# 29344 "parser_cocci_menhir.ml"
+# 29345 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29363,14 +29364,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             MenhirLib.EngineTypes.next = _menhir_stack;
             };
           } = _menhir_stack in
-        let _2 : 'tv_unary_expr_eexpr_nest_expressions_ = Obj.magic _2 in
+        let _2 : 'tv_cast_expr_eexpr_nest_expressions_ = Obj.magic _2 in
         let _1 : 'tv_unary_op = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_eexpr_nest_expressions_ = 
-# 1294 "parser_cocci_menhir.mly"
+# 1295 "parser_cocci_menhir.mly"
       ( let mcode = _1 in Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 29374 "parser_cocci_menhir.ml"
+# 29375 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29397,15 +29398,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29401 "parser_cocci_menhir.ml"
+# 29402 "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_ = 
-# 1296 "parser_cocci_menhir.mly"
+# 1297 "parser_cocci_menhir.mly"
       ( let mcode = P.clt2mcode Ast.Not _1 in
       Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 29409 "parser_cocci_menhir.ml"
+# 29410 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29432,14 +29433,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29436 "parser_cocci_menhir.ml"
+# 29437 "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_ = 
-# 1299 "parser_cocci_menhir.mly"
+# 1300 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.SizeOfExpr (P.clt2mcode "sizeof" _1, _2)) )
-# 29443 "parser_cocci_menhir.ml"
+# 29444 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29475,27 +29476,27 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let rp : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29479 "parser_cocci_menhir.ml"
+# 29480 "parser_cocci_menhir.ml"
         ) = Obj.magic rp in
         let t : 'tv_ctype = Obj.magic t in
         let lp : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29485 "parser_cocci_menhir.ml"
+# 29486 "parser_cocci_menhir.ml"
         ) = Obj.magic lp in
         let s : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29490 "parser_cocci_menhir.ml"
+# 29491 "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_ = 
-# 1301 "parser_cocci_menhir.mly"
+# 1302 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.SizeOfType (P.clt2mcode "sizeof" s,
                                    P.clt2mcode "(" lp,t,
                                    P.clt2mcode ")" rp)) )
-# 29499 "parser_cocci_menhir.ml"
+# 29500 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29517,9 +29518,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_unary_expr_expr_invalid_ = 
-# 1288 "parser_cocci_menhir.mly"
+# 1289 "parser_cocci_menhir.mly"
                                          ( _1 )
-# 29523 "parser_cocci_menhir.ml"
+# 29524 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29546,14 +29547,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 85 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29550 "parser_cocci_menhir.ml"
+# 29551 "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_ = 
-# 1290 "parser_cocci_menhir.mly"
+# 1291 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Inc _1)) )
-# 29557 "parser_cocci_menhir.ml"
+# 29558 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29580,14 +29581,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 85 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29584 "parser_cocci_menhir.ml"
+# 29585 "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_ = 
-# 1292 "parser_cocci_menhir.mly"
+# 1293 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.Infix (_2, P.clt2mcode Ast.Dec _1)) )
-# 29591 "parser_cocci_menhir.ml"
+# 29592 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29610,14 +29611,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
             MenhirLib.EngineTypes.next = _menhir_stack;
             };
           } = _menhir_stack in
-        let _2 : 'tv_unary_expr_expr_invalid_ = Obj.magic _2 in
+        let _2 : 'tv_cast_expr_expr_invalid_ = Obj.magic _2 in
         let _1 : 'tv_unary_op = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_unary_expr_expr_invalid_ = 
-# 1294 "parser_cocci_menhir.mly"
+# 1295 "parser_cocci_menhir.mly"
       ( let mcode = _1 in Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 29621 "parser_cocci_menhir.ml"
+# 29622 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29644,15 +29645,15 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29648 "parser_cocci_menhir.ml"
+# 29649 "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_ = 
-# 1296 "parser_cocci_menhir.mly"
+# 1297 "parser_cocci_menhir.mly"
       ( let mcode = P.clt2mcode Ast.Not _1 in
       Ast0.wrap(Ast0.Unary(_2, mcode)) )
-# 29656 "parser_cocci_menhir.ml"
+# 29657 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29679,14 +29680,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29683 "parser_cocci_menhir.ml"
+# 29684 "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_ = 
-# 1299 "parser_cocci_menhir.mly"
+# 1300 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.SizeOfExpr (P.clt2mcode "sizeof" _1, _2)) )
-# 29690 "parser_cocci_menhir.ml"
+# 29691 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29722,27 +29723,27 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let rp : (
 # 77 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29726 "parser_cocci_menhir.ml"
+# 29727 "parser_cocci_menhir.ml"
         ) = Obj.magic rp in
         let t : 'tv_ctype = Obj.magic t in
         let lp : (
 # 76 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29732 "parser_cocci_menhir.ml"
+# 29733 "parser_cocci_menhir.ml"
         ) = Obj.magic lp in
         let s : (
 # 58 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29737 "parser_cocci_menhir.ml"
+# 29738 "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_ = 
-# 1301 "parser_cocci_menhir.mly"
+# 1302 "parser_cocci_menhir.mly"
       ( Ast0.wrap(Ast0.SizeOfType (P.clt2mcode "sizeof" s,
                                    P.clt2mcode "(" lp,t,
                                    P.clt2mcode ")" rp)) )
-# 29746 "parser_cocci_menhir.ml"
+# 29747 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29763,14 +29764,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 93 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29767 "parser_cocci_menhir.ml"
+# 29768 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_unary_op = 
-# 1305 "parser_cocci_menhir.mly"
+# 1306 "parser_cocci_menhir.mly"
                   ( P.clt2mcode Ast.GetRef _1 )
-# 29774 "parser_cocci_menhir.ml"
+# 29775 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29791,14 +29792,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 99 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29795 "parser_cocci_menhir.ml"
+# 29796 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_unary_op = 
-# 1306 "parser_cocci_menhir.mly"
+# 1307 "parser_cocci_menhir.mly"
            ( P.clt2mcode Ast.DeRef _1 )
-# 29802 "parser_cocci_menhir.ml"
+# 29803 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29819,14 +29820,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 98 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29823 "parser_cocci_menhir.ml"
+# 29824 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_unary_op = 
-# 1307 "parser_cocci_menhir.mly"
+# 1308 "parser_cocci_menhir.mly"
            ( P.clt2mcode Ast.UnPlus _1 )
-# 29830 "parser_cocci_menhir.ml"
+# 29831 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29847,14 +29848,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 98 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29851 "parser_cocci_menhir.ml"
+# 29852 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_unary_op = 
-# 1308 "parser_cocci_menhir.mly"
+# 1309 "parser_cocci_menhir.mly"
            ( P.clt2mcode Ast.UnMinus _1 )
-# 29858 "parser_cocci_menhir.ml"
+# 29859 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29875,14 +29876,14 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _1 : (
 # 99 "parser_cocci_menhir.mly"
        (Data.clt)
-# 29879 "parser_cocci_menhir.ml"
+# 29880 "parser_cocci_menhir.ml"
         ) = Obj.magic _1 in
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__1_ in
         let _v : 'tv_unary_op = 
-# 1309 "parser_cocci_menhir.mly"
+# 1310 "parser_cocci_menhir.mly"
            ( P.clt2mcode Ast.Tilde _1 )
-# 29886 "parser_cocci_menhir.ml"
+# 29887 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29910,9 +29911,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_when_start = 
-# 1730 "parser_cocci_menhir.mly"
+# 1731 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.DOTS((Ast0.wrap(Ast0.Exp(_1)))::_2)) )
-# 29916 "parser_cocci_menhir.ml"
+# 29917 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29940,9 +29941,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos__1_ in
         let _endpos = _endpos__2_ in
         let _v : 'tv_when_start = 
-# 1732 "parser_cocci_menhir.mly"
+# 1733 "parser_cocci_menhir.mly"
     ( Ast0.wrap(Ast0.DOTS(_1@_2)) )
-# 29946 "parser_cocci_menhir.ml"
+# 29947 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -29964,9 +29965,9 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct
         let _startpos = _startpos_w_ in
         let _endpos = _endpos_w_ in
         let _v : 'tv_whenppdecs = 
-# 899 "parser_cocci_menhir.mly"
+# 900 "parser_cocci_menhir.mly"
     ( w )
-# 29970 "parser_cocci_menhir.ml"
+# 29971 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -30000,9 +30001,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_ = 
-# 1798 "parser_cocci_menhir.mly"
+# 1799 "parser_cocci_menhir.mly"
                                          ( [Ast0.WhenNot w] )
-# 30006 "parser_cocci_menhir.ml"
+# 30007 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -30036,9 +30037,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_ = 
-# 1799 "parser_cocci_menhir.mly"
+# 1800 "parser_cocci_menhir.mly"
                                              ( [Ast0.WhenAlways w] )
-# 30042 "parser_cocci_menhir.ml"
+# 30043 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -30068,9 +30069,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_ = 
-# 1801 "parser_cocci_menhir.mly"
+# 1802 "parser_cocci_menhir.mly"
       ( List.map (function x -> Ast0.WhenModifier(x)) _2 )
-# 30074 "parser_cocci_menhir.ml"
+# 30075 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -30104,9 +30105,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_ = 
-# 1802 "parser_cocci_menhir.mly"
+# 1803 "parser_cocci_menhir.mly"
                                         ( [Ast0.WhenNotTrue e] )
-# 30110 "parser_cocci_menhir.ml"
+# 30111 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -30140,9 +30141,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_ = 
-# 1803 "parser_cocci_menhir.mly"
+# 1804 "parser_cocci_menhir.mly"
                                          ( [Ast0.WhenNotFalse e] )
-# 30146 "parser_cocci_menhir.ml"
+# 30147 "parser_cocci_menhir.ml"
          in
         _menhir_env.MenhirLib.EngineTypes.stack <- {
           MenhirLib.EngineTypes.state = _menhir_s;
@@ -30166,7 +30167,7 @@ let rec script_meta_main =
     (Obj.magic (MenhirInterpreter.entry 1534 lexer lexbuf) : (
 # 159 "parser_cocci_menhir.mly"
        (string * (string * string))
-# 30170 "parser_cocci_menhir.ml"
+# 30171 "parser_cocci_menhir.ml"
     ))
 
 and rule_name =
@@ -30174,7 +30175,7 @@ and rule_name =
     (Obj.magic (MenhirInterpreter.entry 1470 lexer lexbuf) : (
 # 153 "parser_cocci_menhir.mly"
       (Ast_cocci.rulename)
-# 30178 "parser_cocci_menhir.ml"
+# 30179 "parser_cocci_menhir.ml"
     ))
 
 and reinit =
@@ -30182,7 +30183,7 @@ and reinit =
     (Obj.magic (MenhirInterpreter.entry 1468 lexer lexbuf) : (
 # 131 "parser_cocci_menhir.mly"
       (unit)
-# 30186 "parser_cocci_menhir.ml"
+# 30187 "parser_cocci_menhir.ml"
     ))
 
 and plus_main =
@@ -30190,7 +30191,7 @@ and plus_main =
     (Obj.magic (MenhirInterpreter.entry 1432 lexer lexbuf) : (
 # 140 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 30194 "parser_cocci_menhir.ml"
+# 30195 "parser_cocci_menhir.ml"
     ))
 
 and plus_exp_main =
@@ -30198,7 +30199,7 @@ and plus_exp_main =
     (Obj.magic (MenhirInterpreter.entry 1423 lexer lexbuf) : (
 # 143 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 30202 "parser_cocci_menhir.ml"
+# 30203 "parser_cocci_menhir.ml"
     ))
 
 and never_used =
@@ -30206,7 +30207,7 @@ and never_used =
     (Obj.magic (MenhirInterpreter.entry 1417 lexer lexbuf) : (
 # 168 "parser_cocci_menhir.mly"
       (unit)
-# 30210 "parser_cocci_menhir.ml"
+# 30211 "parser_cocci_menhir.ml"
     ))
 
 and minus_main =
@@ -30214,7 +30215,7 @@ and minus_main =
     (Obj.magic (MenhirInterpreter.entry 1331 lexer lexbuf) : (
 # 134 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 30218 "parser_cocci_menhir.ml"
+# 30219 "parser_cocci_menhir.ml"
     ))
 
 and minus_exp_main =
@@ -30222,7 +30223,7 @@ and minus_exp_main =
     (Obj.magic (MenhirInterpreter.entry 1307 lexer lexbuf) : (
 # 137 "parser_cocci_menhir.mly"
       (Ast0_cocci.rule)
-# 30226 "parser_cocci_menhir.ml"
+# 30227 "parser_cocci_menhir.ml"
     ))
 
 and meta_main =
@@ -30230,7 +30231,7 @@ and meta_main =
     (Obj.magic (MenhirInterpreter.entry 1304 lexer lexbuf) : (
 # 157 "parser_cocci_menhir.mly"
       ((Ast_cocci.metavar,Ast_cocci.metavar) Common.either list)
-# 30234 "parser_cocci_menhir.ml"
+# 30235 "parser_cocci_menhir.ml"
     ))
 
 and iso_rule_name =
@@ -30238,7 +30239,7 @@ and iso_rule_name =
     (Obj.magic (MenhirInterpreter.entry 1300 lexer lexbuf) : (
 # 149 "parser_cocci_menhir.mly"
       (Ast_cocci.rulename)
-# 30242 "parser_cocci_menhir.ml"
+# 30243 "parser_cocci_menhir.ml"
     ))
 
 and iso_meta_main =
@@ -30246,7 +30247,7 @@ and iso_meta_main =
     (Obj.magic (MenhirInterpreter.entry 1104 lexer lexbuf) : (
 # 165 "parser_cocci_menhir.mly"
       ((Ast_cocci.metavar,Ast_cocci.metavar) Common.either list)
-# 30250 "parser_cocci_menhir.ml"
+# 30251 "parser_cocci_menhir.ml"
     ))
 
 and iso_main =
@@ -30254,7 +30255,7 @@ and iso_main =
     (Obj.magic (MenhirInterpreter.entry 10 lexer lexbuf) : (
 # 162 "parser_cocci_menhir.mly"
       (Ast0_cocci.anything list list)
-# 30258 "parser_cocci_menhir.ml"
+# 30259 "parser_cocci_menhir.ml"
     ))
 
 and include_main =
@@ -30262,7 +30263,7 @@ and include_main =
     (Obj.magic (MenhirInterpreter.entry 0 lexer lexbuf) : (
 # 146 "parser_cocci_menhir.mly"
       ((string,string) Common.either list)
-# 30266 "parser_cocci_menhir.ml"
+# 30267 "parser_cocci_menhir.ml"
     ))
 
 
index 98f6859..c93d0eb 100644 (file)
@@ -51,7 +51,7 @@ type token =
   | TPure
   | TPtrOp of (Data.clt)
   | TPtVirg of (Data.clt)
-  | TPragma of (string)
+  | TPragma of (string * Data.clt)
   | TPosition
   | TPosAny
   | TPlusFile of (string * Data.clt)
index 09fb8ad..a72182a 100644 (file)
@@ -56,7 +56,7 @@ module P = Parse_aux
 
 %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 <string * Data.clt> TIdent TTypeId TDeclarerId TIteratorId TPragma
 
 %token <Parse_aux.idinfo>     TMetaId TMetaFunc TMetaLocalFunc
 %token <Parse_aux.idinfo>     TMetaIterator TMetaDeclarer
@@ -76,7 +76,7 @@ module P = Parse_aux
 %token <Data.clt> TWhy TDotDot TBang TOPar TOPar0
 %token <Data.clt> TMid0 TCPar TCPar0
 
-%token <string>  TPragma TPathIsoFile
+%token <string>  TPathIsoFile
 %token <string * Data.clt> TIncludeL TIncludeNL
 %token <Data.clt * token> TDefine
 %token <Data.clt * token * int> TDefineParam
@@ -681,7 +681,8 @@ defineop:
     { 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
+       P.clt2mcode "("
+         (arity,line,lline,parenoff,0,[],[],Ast0.NoMetaPos) in
       function body ->
        Ast0.wrap
          (Ast0.Define
@@ -1290,7 +1291,7 @@ 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)
+  | unary_op cast_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
index 9675e49..9476554 100644 (file)
@@ -80,10 +80,10 @@ let print_around printer term = function
       print_anything "<<< " bef; printer term; print_anything ">>> " aft
 
 let print_string_befaft fn x info =
-  List.iter (function s -> print_string s; force_newline())
+  List.iter (function (s,_,_) -> print_string s; force_newline())
     info.Ast.strbef;
   fn x;
-  List.iter (function s -> force_newline(); print_string s)
+  List.iter (function (s,_,_) -> force_newline(); print_string s)
     info.Ast.straft
 
 let print_meta (r,x) = print_string r; print_string ":"; print_string x
@@ -785,6 +785,7 @@ let _ =
     | Ast.ConstVolTag(x) -> const_vol x
     | Ast.Token(x,Some info) -> print_string_befaft print_string x info
     | Ast.Token(x,None) -> print_string x
+    | Ast.Pragma(xs) -> print_between force_newline print_string xs
     | Ast.Code(x) -> let _ = top_level x in ()
     | Ast.ExprDotsTag(x) -> dots (function _ -> ()) expression x
     | Ast.ParamDotsTag(x) -> parameter_list x
index 24448ad..ea30ec3 100644 (file)
@@ -116,6 +116,7 @@ let rec propagate_types env =
     | T.BaseType(T.ShortType)
     | T.MetaType(_,_,_)
     | T.TypeName _
+    | T.EnumName _
     | T.SignedT(_,None) -> true
     | T.SignedT(_,Some ty) -> is_int_type ty
     | _ -> false in
index b295646..0772e54 100644 (file)
@@ -48,7 +48,9 @@ let meta_pos = function
 (* --------------------------------------------------------------------- *)
 (* Modified code *)
 
-let mcodekind brackets fn x info = function
+let mcodekind brackets fn x info mc =
+  List.iter (function (s,_) -> print_string s) info.Ast0.strings_before;
+  (match mc with
     Ast0.MINUS(plus_stream) ->
       let (lb,rb) =
        if !quiet
@@ -75,12 +77,7 @@ let mcodekind brackets fn x info = function
        (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.PLUS -> fn x
   | Ast0.MIXED(plus_streams) ->
       let (lb,rb) =
        if !quiet
@@ -91,11 +88,12 @@ let mcodekind brackets fn x info = function
          ("§","½"^n) in
       let (plus_streams,_,_) = !plus_streams in
       U.print_around (function x -> print_string lb; fn x; print_string rb)
-       x plus_streams
+       x plus_streams);
+  List.iter (function (s,_) -> print_string s) info.Ast0.strings_after
 
 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
+  mcodekind (Some info.Ast0.pos_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)
index f0ca9c8..6836dda 100644 (file)
@@ -504,6 +504,7 @@ let combiner bind option_default
       | Ast.CaseLineTag(case) -> case_line case
       | Ast.ConstVolTag(cv) -> option_default
       | Ast.Token(tok,info) -> option_default
+      | Ast.Pragma(str) -> option_default
       | Ast.Code(cd) -> top_level cd
       | Ast.ExprDotsTag(ed) -> expression_dots ed
       | Ast.ParamDotsTag(pd) -> parameter_dots pd
@@ -1026,6 +1027,7 @@ let rebuilder
       | Ast.CaseLineTag(case) -> Ast.CaseLineTag(case_line case)
       | Ast.ConstVolTag(cv) as x -> x
       | Ast.Token(tok,info) as x -> x
+      | Ast.Pragma(str) as x -> x
       | Ast.Code(cd) -> Ast.Code(top_level cd)
       | Ast.ExprDotsTag(ed) -> Ast.ExprDotsTag(expression_dots ed)
       | Ast.ParamDotsTag(pd) -> Ast.ParamDotsTag(parameter_dots pd)
diff --git a/popl/.#Makefile.1.5 b/popl/.#Makefile.1.5
new file mode 100644 (file)
index 0000000..2254a1e
--- /dev/null
@@ -0,0 +1,102 @@
+# Copyright 2005-2009, 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 insert_befaft.ml \
+pretty_print_popl.ml popltoctl.ml popl.ml flag_popl.ml
+
+SYSLIBS=str.cma unix.cma
+LIBS=../commons/commons.cma ../globals/globals.cma
+
+INCLUDE_PATH = -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
+CAMLC =ocamlc$(OPTBIN) -dtypes -g 
+CAMLOPT=ocamlopt$(OPTBIN)   $(OPTFLAGS)
+CAMLLEX = ocamllex$(OPTBIN)
+CAMLYACC= ocamlyacc
+CAMLDEP = ocamldep$(OPTBIN) 
+CAMLMKTOP=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)
+       $(CAMLMKTOP) -o $(TARGET).top $(SYSLIBS) $(LIBS) $(OBJS)
+
+$(LIB):  $(OBJS)
+       $(CAMLC) -a -o $(LIB) $(OBJS)
+
+clean::
+       rm -f $(LIB) $(TARGET).top
+
+
+$(OPTLIB): $(OPTOBJS)
+       $(CAMLOPT) -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:
+       $(CAMLC) $(INCLUDE_PATH) -c $<
+
+.mli.cmi:
+       $(CAMLC) $(INCLUDE_PATH) -c $<
+
+.ml.cmx:
+       $(CAMLOPT) $(INCLUDE_PATH) -c $<
+
+
+
+
+# clean rule for others files
+clean::
+       rm -f *.cm[iox] *.o *.annot
+       rm -f *~ .*~ #*# 
+
+depend: 
+       $(CAMLDEP) $(INCLUDE_PATH) *.mli *.ml > .depend
+
+#clean::
+#      rm -f .depend
+
+.depend:
+       $(CAMLDEP) $(INCLUDE_PATH) *.mli *.ml > .depend
+
+-include .depend
index 2254a1e..e7968f3 100644 (file)
@@ -20,6 +20,8 @@
 
 #note: if you add a file (a .mli or .ml), dont forget to do a   make depend
 
+-include ../Makefile.config
+
 TARGET = popl
 
 SRC = ast_popl.ml asttopopl.ml insert_quantifiers.ml insert_befaft.ml \
diff --git a/popl09/.#Makefile.1.5 b/popl09/.#Makefile.1.5
new file mode 100644 (file)
index 0000000..83c32f1
--- /dev/null
@@ -0,0 +1,101 @@
+# Copyright 2005-2009, 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_cocci -I ../parsing_c  -I ../engine
+
+#The Caml compilers.
+#for warning:  -w A 
+#for profiling:  -p -inline 0   with OCAMLOPT
+OCAMLCFLAGS ?= -g -dtypes
+OCAMLC =ocamlc$(OPTBIN) $(OCAMLCFLAGS) $(INCLUDES)
+OCAMLOPT = ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
+OCAMLDEP = ocamldep$(OPTBIN) #$(INCLUDES)
+OCAMLMKTOP=ocamlmktop -g -custom
+
+
+
+LIB=$(TARGET).cma
+OPTLIB=$(LIB:.cma=.cmxa)
+
+OBJS = $(SRC:.ml=.cmo)
+OPTOBJS = $(SRC:.ml=.cmx)
+
+all: $(LIB)
+all.opt: $(OPTLIB)
+
+$(TARGET).top: $(LIB)
+       $(OCAMLMKTOP) -o $(TARGET).top $(SYSLIBS) $(LIBS) $(OBJS)
+
+$(LIB):  $(OBJS)
+       $(OCAMLC) -a -o $(LIB) $(OBJS)
+
+clean::
+       rm -f $(LIB) $(TARGET).top
+
+
+$(OPTLIB): $(OPTOBJS)
+       $(OCAMLOPT) -a -o $(OPTLIB) $(OPTOBJS)
+
+# clean rule for LIB.opt
+clean::
+       rm -f $(OPTLIB) $(LIB:.cma=.a)  
+
+
+.SUFFIXES:
+.SUFFIXES: .ml .mli .cmo .cmi .cmx
+
+.ml.cmo:
+       $(OCAMLC) -c $<
+
+.mli.cmi:
+       $(OCAMLC) -c $<
+
+.ml.cmx:
+       $(OCAMLOPT) -c $<
+
+
+
+
+# clean rule for others files
+clean::
+       rm -f *.cm[iox] *.o *.annot
+       rm -f *~ .*~ #*# 
+
+depend: 
+       $(OCAMLDEP) *.mli *.ml > .depend
+
+#clean::
+#      rm -f .depend
+
+.depend:
+       $(OCAMLDEP) $(INCLUDE_PATH) *.mli *.ml > .depend
+
+-include .depend
diff --git a/popl09/.#Makefile.1.6 b/popl09/.#Makefile.1.6
new file mode 100644 (file)
index 0000000..f773e1a
--- /dev/null
@@ -0,0 +1,101 @@
+# Copyright 2005-2009, 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_cocci -I ../parsing_c  -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
dissimilarity index 89%
index c0c557a..687e676 100644 (file)
@@ -1,14 +1,33 @@
-asttopopl.cmi: ast_popl.cmo 
-insert_quantifiers.cmi: ast_popl.cmo 
-popltoctl.cmi: ast_popl.cmo 
-pretty_print_popl.cmi: ast_popl.cmo 
-asttopopl.cmo: ast_popl.cmo asttopopl.cmi 
-asttopopl.cmx: ast_popl.cmx asttopopl.cmi 
-insert_quantifiers.cmo: ast_popl.cmo insert_quantifiers.cmi 
-insert_quantifiers.cmx: ast_popl.cmx insert_quantifiers.cmi 
-popl.cmo: popltoctl.cmi insert_quantifiers.cmi asttopopl.cmi popl.cmi 
-popl.cmx: popltoctl.cmx insert_quantifiers.cmx asttopopl.cmx popl.cmi 
-popltoctl.cmo: flag_popl.cmo ast_popl.cmo popltoctl.cmi 
-popltoctl.cmx: flag_popl.cmx ast_popl.cmx popltoctl.cmi 
-pretty_print_popl.cmo: ast_popl.cmo pretty_print_popl.cmi 
-pretty_print_popl.cmx: ast_popl.cmx pretty_print_popl.cmi 
+asttopopl.cmi: ast_popl.cmo ../parsing_cocci/ast_cocci.cmi 
+insert_quantifiers.cmi: ast_popl.cmo 
+popl.cmi: ../ctl/wrapper_ctl.cmi ../engine/lib_engine.cmo ../ctl/ast_ctl.cmo \
+    ../parsing_cocci/ast_cocci.cmi 
+popltoctl.cmi: ../ctl/wrapper_ctl.cmi ../engine/lib_engine.cmo ast_popl.cmo \
+    ../ctl/ast_ctl.cmo ../parsing_cocci/ast_cocci.cmi 
+pretty_print_popl.cmi: ast_popl.cmo 
+ast_popl.cmo: ../parsing_cocci/ast_cocci.cmi 
+ast_popl.cmx: ../parsing_cocci/ast_cocci.cmx 
+asttopopl.cmo: ../parsing_cocci/pretty_print_cocci.cmi ast_popl.cmo \
+    ../parsing_cocci/ast_cocci.cmi asttopopl.cmi 
+asttopopl.cmx: ../parsing_cocci/pretty_print_cocci.cmx ast_popl.cmx \
+    ../parsing_cocci/ast_cocci.cmx asttopopl.cmi 
+insert_quantifiers.cmo: ../commons/common.cmi ast_popl.cmo \
+    ../parsing_cocci/ast_cocci.cmi insert_quantifiers.cmi 
+insert_quantifiers.cmx: ../commons/common.cmx ast_popl.cmx \
+    ../parsing_cocci/ast_cocci.cmx insert_quantifiers.cmi 
+popl.cmo: ../ctl/wrapper_ctl.cmi popltoctl.cmi ../engine/lib_engine.cmo \
+    insert_quantifiers.cmi asttopopl.cmi ../ctl/ast_ctl.cmo \
+    ../parsing_cocci/ast_cocci.cmi popl.cmi 
+popl.cmx: ../ctl/wrapper_ctl.cmx popltoctl.cmx ../engine/lib_engine.cmx \
+    insert_quantifiers.cmx asttopopl.cmx ../ctl/ast_ctl.cmx \
+    ../parsing_cocci/ast_cocci.cmx popl.cmi 
+popltoctl.cmo: ../ctl/wrapper_ctl.cmi ../parsing_cocci/visitor_ast.cmi \
+    ../engine/lib_engine.cmo flag_popl.cmo ast_popl.cmo ../ctl/ast_ctl.cmo \
+    ../parsing_cocci/ast_cocci.cmi popltoctl.cmi 
+popltoctl.cmx: ../ctl/wrapper_ctl.cmx ../parsing_cocci/visitor_ast.cmx \
+    ../engine/lib_engine.cmx flag_popl.cmx ast_popl.cmx ../ctl/ast_ctl.cmx \
+    ../parsing_cocci/ast_cocci.cmx popltoctl.cmi 
+pretty_print_popl.cmo: ../parsing_cocci/pretty_print_cocci.cmi ast_popl.cmo \
+    ../parsing_cocci/ast_cocci.cmi pretty_print_popl.cmi 
+pretty_print_popl.cmx: ../parsing_cocci/pretty_print_cocci.cmx ast_popl.cmx \
+    ../parsing_cocci/ast_cocci.cmx pretty_print_popl.cmi 
index 83c32f1..21bd4ae 100644 (file)
@@ -20,6 +20,7 @@
 
 #note: if you add a file (a .mli or .ml), dont forget to do a   make depend
 
+-include ../Makefile.config
 TARGET = popl
 
 SRC = ast_popl.ml asttopopl.ml insert_quantifiers.ml \
@@ -37,7 +38,7 @@ INCLUDES = -I ../commons -I ../globals \
 OCAMLCFLAGS ?= -g -dtypes
 OCAMLC =ocamlc$(OPTBIN) $(OCAMLCFLAGS) $(INCLUDES)
 OCAMLOPT = ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
-OCAMLDEP = ocamldep$(OPTBIN) #$(INCLUDES)
+OCAMLDEP = ocamldep$(OPTBIN) $(INCLUDES)
 OCAMLMKTOP=ocamlmktop -g -custom
 
 
index 1db1ae1..309aecc 100644 (file)
@@ -381,8 +381,10 @@ let pyimport_getmoduledict = fmt29call (pnf ())
 (* 28 *)
 let pyimport_addmodule = fmt28call (pnf ())
 let pyimport_importmodule = fmt28call (pnf ())
+(* - disabled, see comment in pycaml_ml.c.  - RWMJ
 (* 51 *)
 let pyimport_importmoduleex = fmt51call (pnf ())
+*)
 (* 28 *)
 let pyimport_import = fmt28call (pnf ())
 (* 14 *)
index 30217f9..87342f5 100644 (file)
@@ -173,7 +173,7 @@ value pygencall( value format, value arg ) {
     int fd;
     int x;
     int ret_int;
-    char *rvs;
+    const char *rvs;
     int fmt = Int_val(Field(format,1));
     PyObject *ob1,*ob2,*ob3;
     void *func = getcustom(Field(format,0));
@@ -1184,7 +1184,12 @@ python_func_table the_python_func_table[] = {
 { (void *)PyImport_AddModule, 28, "PyImport_AddModule" },
 { (void *)PyImport_ImportModule, 28, "PyImport_ImportModule" },
 /* 51 */
+#if 0
+    /* In Python 2.6, this because a #define so we cannot take
+     * the address of the function.  - RWMJ.
+     */
 { (void *)PyImport_ImportModuleEx, 51, "PyImport_ImportModuleEx" },
+#endif
 /* 28 */
 { (void *)PyImport_Import, 28, "PyImport_Import" },
 /* 14 */
diff --git a/python/.#Makefile.1.5 b/python/.#Makefile.1.5
new file mode 100644 (file)
index 0000000..d2a67ec
--- /dev/null
@@ -0,0 +1,146 @@
+# Copyright 2005-2009, 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.
+
+
+#############################################################################
+# Configuration section
+#############################################################################
+-include ../Makefile.config
+
+##############################################################################
+# Variables
+##############################################################################
+TARGET=coccipython
+
+SOURCES= pycocci_aux.ml pycocci.ml 
+
+INCLUDEDIRS = ../commons ../commons/ocamlextra ../globals ../pycaml \
+             ../parsing_c ../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 
+#pycaml/pycaml.cma 
+
+
+##############################################################################
+# Generic variables
+##############################################################################
+
+INCLUDES=$(INCLUDEDIRS:%=-I %) $(INCLUDESEXTRA)
+
+##############################################################################
+# Generic ocaml variables
+##############################################################################
+
+# The Caml compilers.
+OCAMLCFLAGS ?= -g -dtypes
+OCAMLC =ocamlc$(OPTBIN) $(OCAMLCFLAGS) $(INCLUDES)
+OCAMLOPT = ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
+OCAMLDEP = ocamldep$(OPTBIN) #$(INCLUDES)
+
+
+##############################################################################
+# Top rules
+##############################################################################
+
+EXEC=$(TARGET).byte
+LIB=$(TARGET).cma
+OPTLIB=$(LIB:.cma=.cmxa)
+
+CTLEXEC=$(CTLTARGET)
+
+OBJS = $(SOURCES:.ml=.cmo)
+OPTOBJS = $(OBJS:.cmo=.cmx)
+
+CTLOBJS = $(CTLSOURCES:.ml=.cmo)
+CTLOPTOBJS = $(CTLOBJS:.cmo=.cmx)
+
+
+#all: $(EXEC) $(LIB)
+all: $(LIB)
+
+all.opt: $(OPTLIB)
+
+ctl: $(CTLEXEC)
+
+
+$(LIB): $(OBJS)
+       $(OCAMLC) -a -o $(LIB) $(OBJS)
+
+clean::
+       rm -f $(LIB)
+
+
+$(OPTLIB): $(OPTOBJS) 
+       $(OCAMLOPT) -a -o $(OPTLIB) $(OPTOBJS)
+
+
+$(EXEC): $(OBJS) main.cmo $(LIBS)
+       $(OCAMLC) -o $(EXEC) $(SYSLIBS) $(LIBS) $(OBJS) main.cmo
+
+$(CTLEXEC): $(CTLOBJS) $(LIBS)
+       $(OCAMLC) -o $(CTLEXEC) $(SYSLIBS) $(LIBS) $(CTLOBJS)
+
+
+clean::
+       rm -f $(OPTLIB) $(LIB:.cma=.a)  
+       rm -f $(TARGET) rm -f $(TARGET).byte
+       rm -f $(CTLTARGET)
+
+
+#pycocci.ml: ../pycaml/pycaml.ml ../pycaml/pycaml_ml.c
+#pycocci_aux.ml:  ../pycaml/pycaml.ml ../pycaml/pycaml_ml.c
+
+rmlinks:
+       rm -f pycocci.ml pycocci_aux.ml
+
+##############################################################################
+# Generic ocaml rules
+##############################################################################
+
+.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 *~ .*~ #*# 
+
+beforedepend:
+
+depend: beforedepend
+       $(OCAMLDEP) *.mli *.ml > .depend
+
+.depend: 
+       $(OCAMLDEP) *.mli *.ml > .depend
+
+-include .depend
diff --git a/python/.#no_pycocci_aux.ml.1.2 b/python/.#no_pycocci_aux.ml.1.2
new file mode 100644 (file)
index 0000000..e4ded17
--- /dev/null
@@ -0,0 +1,76 @@
+(*
+* Copyright 2005-2009, 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
+
+let rec exprrep expr = match expr with
+  Ast_c.Ident s -> s
+| Ast_c.Constant c -> constantrep c
+| Ast_c.FunCall (e,args) -> "TODO: FunCall"
+| Ast_c.CondExpr (e1,e2,e3) -> "TODO: CondExpr"
+| Ast_c.Sequence (e1,e2) -> "TODO: Sequence"
+| Ast_c.Assignment (e1,op,e2) -> "TODO: Assignment"
+| Ast_c.Postfix (e,op) -> "TODO: Postfix"
+| Ast_c.Infix (e,op) -> "TODO: Infix"
+| Ast_c.Unary (e,op) -> "TODO: Unary"
+| Ast_c.Binary (e1,op,e2) -> "TODO: Binary"
+| Ast_c.ArrayAccess (e1,e2) -> "TODO: ArrayAccess"
+| Ast_c.RecordAccess (e1,s) -> "TODO: RecordAccess"
+| Ast_c.RecordPtAccess (e,s) -> "TODO: RecordPtAccess"
+| Ast_c.SizeOfExpr e -> "TODO: SizeOfExpr"
+| Ast_c.SizeOfType t -> "TODO: SizeOfType"
+| Ast_c.Cast (t,e) -> "TODO: Cast"
+| Ast_c.StatementExpr c -> "TODO: StatementExpr"
+| Ast_c.Constructor (t,i) -> "TODO: Constructor"
+| Ast_c.ParenExpr e -> "TODO: ParenExpr"
+and constantrep c = match c with
+  Ast_c.String (s,isWchar) -> s 
+| Ast_c.MultiString -> "TODO: MultiString"
+| Ast_c.Char (s,isWchar) -> s
+| Ast_c.Int s -> s 
+| Ast_c.Float (s,t) -> s
+
+let call_pretty f a =
+  let str = ref ([] : string list) in
+  let pr_elem info = str := (Ast_c.str_of_info info) :: !str in
+  let pr_sp _ = () in
+  f pr_elem pr_sp a;
+  String.concat " " (List.rev !str)
+
+let stringrep mvb = match mvb with
+  Ast_c.MetaIdVal        s -> s
+| Ast_c.MetaFuncVal      s -> s
+| Ast_c.MetaLocalFuncVal s -> s
+| Ast_c.MetaExprVal      ((expr,_),[il]) -> (exprrep expr)
+| Ast_c.MetaExprVal     e -> "TODO: <<MetaExprVal>>"
+| Ast_c.MetaExprListVal  expr_list -> "TODO: <<exprlist>>"
+| Ast_c.MetaTypeVal      typ -> call_pretty Pretty_print_c.pp_type_gen typ
+| Ast_c.MetaStmtVal      statement -> "TODO: stmt"
+| Ast_c.MetaParamVal     params -> "TODO: <<param>>"
+| Ast_c.MetaParamListVal params -> "TODO: <<paramlist>>"
+| Ast_c.MetaListlenVal n -> string_of_int n
+| Ast_c.MetaPosVal (pos1, pos2) -> 
+    (* Common.sprintf ("pos(%d,%d)") pos1 pos2 *)
+    "TODO: <<posval>>"
+| Ast_c.MetaPosValList positions -> "TODO: <<postvallist>>"
+
diff --git a/python/.#yes_pycocci.ml.1.2 b/python/.#yes_pycocci.ml.1.2
new file mode 100644 (file)
index 0000000..4f55845
--- /dev/null
@@ -0,0 +1,243 @@
+(*
+* Copyright 2005-2009, 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,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),
+               pystring_fromstring (Printf.sprintf "%d" col_end)))) l in
+       let pylocs = pytuple_fromarray (Array.of_list locs) in
+       let _ = build_variable py pylocs in
+       ()
+    | Some (_,binding) ->
+       let _ = build_variable py (pystring_fromstring (Pycocci_aux.stringrep binding))
+       in ()
+    ) mv;
+
+  ()
+
+let set_coccifile cocci_file =
+       cocci_file_name := cocci_file;
+       ()
+
+
+let pyrun_simplestring s = 
+  Pycaml.pyrun_simplestring s
+
+let py_isinitialized () = 
+  Pycaml.py_isinitialized ()
+
+
+let py_finalize () =
+  Pycaml.py_finalize ()
diff --git a/python/.#yes_pycocci_aux.ml.1.2 b/python/.#yes_pycocci_aux.ml.1.2
new file mode 100644 (file)
index 0000000..8c5af0b
--- /dev/null
@@ -0,0 +1,80 @@
+(*
+* Copyright 2005-2009, 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
+
+let rec exprrep expr = match expr with
+  Ast_c.Ident s -> s
+| Ast_c.Constant c -> constantrep c
+| Ast_c.FunCall (e,args) -> "TODO: FunCall"
+| Ast_c.CondExpr (e1,e2,e3) -> "TODO: CondExpr"
+| Ast_c.Sequence (e1,e2) -> "TODO: Sequence"
+| Ast_c.Assignment (e1,op,e2) -> "TODO: Assignment"
+| Ast_c.Postfix (e,op) -> "TODO: Postfix"
+| Ast_c.Infix (e,op) -> "TODO: Infix"
+| Ast_c.Unary (e,op) -> "TODO: Unary"
+| Ast_c.Binary (e1,op,e2) -> "TODO: Binary"
+| Ast_c.ArrayAccess (e1,e2) -> "TODO: ArrayAccess"
+| Ast_c.RecordAccess (e1,s) -> "TODO: RecordAccess"
+| Ast_c.RecordPtAccess (e,s) -> "TODO: RecordPtAccess"
+| Ast_c.SizeOfExpr e -> "TODO: SizeOfExpr"
+| Ast_c.SizeOfType t -> "TODO: SizeOfType"
+| Ast_c.Cast (t,e) -> "TODO: Cast"
+| Ast_c.StatementExpr c -> "TODO: StatementExpr"
+| Ast_c.Constructor (t,i) -> "TODO: Constructor"
+| Ast_c.ParenExpr e -> "TODO: ParenExpr"
+and constantrep c = match c with
+  Ast_c.String (s,isWchar) -> s 
+| Ast_c.MultiString -> "TODO: MultiString"
+| Ast_c.Char (s,isWchar) -> s
+| Ast_c.Int s -> s 
+| Ast_c.Float (s,t) -> s
+
+let call_pretty f a =
+  let str = ref ([] : string list) in
+  let pr_elem info = str := (Ast_c.str_of_info info) :: !str in
+  let pr_sp _ = () in
+  f pr_elem pr_sp a;
+  String.concat " " (List.rev !str)
+
+let stringrep mvb = match mvb with
+  Ast_c.MetaIdVal        s -> s
+| Ast_c.MetaFuncVal      s -> s
+| Ast_c.MetaLocalFuncVal s -> s
+| Ast_c.MetaExprVal      ((expr,_),[il]) -> (exprrep expr)
+| Ast_c.MetaExprVal     e -> "TODO: <<MetaExprVal>>"
+| Ast_c.MetaExprListVal  expr_list -> "TODO: <<exprlist>>"
+| Ast_c.MetaTypeVal      typ -> call_pretty Pretty_print_c.pp_type_gen typ
+| Ast_c.MetaInitVal      ini -> "TODO: <<initiliser>>"
+| Ast_c.MetaStmtVal      statement -> "TODO: stmt"
+| Ast_c.MetaParamVal     params -> "TODO: <<param>>"
+| Ast_c.MetaParamListVal params -> "TODO: <<paramlist>>"
+| Ast_c.MetaListlenVal n -> 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
+    Common.sprintf ("pos(%s,%s)") (print_pos pos1) (print_pos pos2)
+| Ast_c.MetaPosValList positions -> "TODO: <<postvallist>>"
+
diff --git a/python/.#yes_pycocci_aux.ml.1.3 b/python/.#yes_pycocci_aux.ml.1.3
new file mode 100644 (file)
index 0000000..afe3bf5
--- /dev/null
@@ -0,0 +1,80 @@
+(*
+* Copyright 2005-2009, 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
+
+let rec exprrep expr = match expr with
+  Ast_c.Ident s -> s
+| Ast_c.Constant c -> constantrep c
+| Ast_c.FunCall (e,args) -> "TODO: FunCall"
+| Ast_c.CondExpr (e1,e2,e3) -> "TODO: CondExpr"
+| Ast_c.Sequence (e1,e2) -> "TODO: Sequence"
+| Ast_c.Assignment (e1,op,e2) -> "TODO: Assignment"
+| Ast_c.Postfix (e,op) -> "TODO: Postfix"
+| Ast_c.Infix (e,op) -> "TODO: Infix"
+| Ast_c.Unary (e,op) -> "TODO: Unary"
+| Ast_c.Binary (e1,op,e2) -> "TODO: Binary"
+| Ast_c.ArrayAccess (e1,e2) -> "TODO: ArrayAccess"
+| Ast_c.RecordAccess (e1,s) -> "TODO: RecordAccess"
+| Ast_c.RecordPtAccess (e,s) -> "TODO: RecordPtAccess"
+| Ast_c.SizeOfExpr e -> "TODO: SizeOfExpr"
+| Ast_c.SizeOfType t -> "TODO: SizeOfType"
+| Ast_c.Cast (t,e) -> "TODO: Cast"
+| Ast_c.StatementExpr c -> "TODO: StatementExpr"
+| Ast_c.Constructor (t,i) -> "TODO: Constructor"
+| Ast_c.ParenExpr e -> "TODO: ParenExpr"
+and constantrep c = match c with
+  Ast_c.String (s,isWchar) -> s
+| Ast_c.MultiString sl -> String.concat "" sl
+| Ast_c.Char (s,isWchar) -> s
+| Ast_c.Int s -> s
+| Ast_c.Float (s,t) -> s
+
+let call_pretty f a =
+  let str = ref ([] : string list) in
+  let pr_elem info = str := (Ast_c.str_of_info info) :: !str in
+  let pr_sp _ = () in
+  f pr_elem pr_sp a;
+  String.concat " " (List.rev !str)
+
+let stringrep mvb = match mvb with
+  Ast_c.MetaIdVal        s -> s
+| Ast_c.MetaFuncVal      s -> s
+| Ast_c.MetaLocalFuncVal s -> s
+| Ast_c.MetaExprVal      ((expr,_),[il]) -> (exprrep expr)
+| Ast_c.MetaExprVal     e -> "TODO: <<MetaExprVal>>"
+| Ast_c.MetaExprListVal  expr_list -> "TODO: <<exprlist>>"
+| Ast_c.MetaTypeVal      typ -> call_pretty Pretty_print_c.pp_type_gen typ
+| Ast_c.MetaInitVal      ini -> "TODO: <<initiliser>>"
+| Ast_c.MetaStmtVal      statement -> "TODO: stmt"
+| Ast_c.MetaParamVal     params -> "TODO: <<param>>"
+| Ast_c.MetaParamListVal params -> "TODO: <<paramlist>>"
+| Ast_c.MetaListlenVal n -> 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
+    Common.sprintf ("pos(%s,%s)") (print_pos pos1) (print_pos pos2)
+| Ast_c.MetaPosValList positions -> "TODO: <<postvallist>>"
+
dissimilarity index 100%
index f0cf0ee..f6f1ff2 100644 (file)
@@ -1,6 +1,22 @@
-no_pycocci.cmo: pycocci_aux.cmo 
-no_pycocci.cmx: pycocci_aux.cmx 
-pycocci.cmo: pycocci_aux.cmo 
-pycocci.cmx: pycocci_aux.cmx 
-yes_pycocci.cmo: pycocci_aux.cmo 
-yes_pycocci.cmx: pycocci_aux.cmx 
+no_pycocci.cmo: pycocci_aux.cmo ../commons/common.cmi ../parsing_c/ast_c.cmo 
+no_pycocci.cmx: pycocci_aux.cmx ../commons/common.cmx ../parsing_c/ast_c.cmx 
+no_pycocci_aux.cmo: ../parsing_c/pretty_print_c.cmi ../commons/common.cmi \
+    ../parsing_c/ast_c.cmo 
+no_pycocci_aux.cmx: ../parsing_c/pretty_print_c.cmx ../commons/common.cmx \
+    ../parsing_c/ast_c.cmx 
+pycocci.cmo: pycocci_aux.cmo ../commons/common.cmi ../parsing_c/ast_c.cmo 
+pycocci.cmx: pycocci_aux.cmx ../commons/common.cmx ../parsing_c/ast_c.cmx 
+pycocci_aux.cmo: ../parsing_c/pretty_print_c.cmi ../commons/common.cmi \
+    ../parsing_c/ast_c.cmo 
+pycocci_aux.cmx: ../parsing_c/pretty_print_c.cmx ../commons/common.cmx \
+    ../parsing_c/ast_c.cmx 
+yes_pycocci.cmo: pycocci_aux.cmo ../pycaml/pycaml.cmo ../globals/flag.cmo \
+    ../commons/common.cmi ../parsing_c/ast_c.cmo 
+yes_pycocci.cmx: pycocci_aux.cmx ../pycaml/pycaml.cmx ../globals/flag.cmx \
+    ../commons/common.cmx ../parsing_c/ast_c.cmx 
+yes_pycocci_aux.cmo: ../pycaml/pycaml.cmo ../parsing_c/pretty_print_c.cmi \
+    ../commons/common.cmi ../parsing_cocci/ast_cocci.cmi \
+    ../parsing_c/ast_c.cmo 
+yes_pycocci_aux.cmx: ../pycaml/pycaml.cmx ../parsing_c/pretty_print_c.cmx \
+    ../commons/common.cmx ../parsing_cocci/ast_cocci.cmx \
+    ../parsing_c/ast_c.cmx 
index d2a67ec..9f16961 100644 (file)
@@ -55,7 +55,7 @@ INCLUDES=$(INCLUDEDIRS:%=-I %) $(INCLUDESEXTRA)
 OCAMLCFLAGS ?= -g -dtypes
 OCAMLC =ocamlc$(OPTBIN) $(OCAMLCFLAGS) $(INCLUDES)
 OCAMLOPT = ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
-OCAMLDEP = ocamldep$(OPTBIN) #$(INCLUDES)
+OCAMLDEP = ocamldep$(OPTBIN) $(INCLUDES)
 
 
 ##############################################################################
deleted file mode 100644 (file)
index af6f7132cd773bb5b2940677a41e582b1da47c7e..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,125 +0,0 @@
-import pygtk
-import gtk, gobject
-import coccilib.coccigui
-import coccilib.coccigui.coccigui
-from threading import Thread, Lock
-import time
-from copy import deepcopy
-
-class Output:
-       """In order to implement an output class for use with Coccinelle,
-       one can inherit from this class and overload register_match with
-       the same number of arguments.
-
-       include_match will be overwritten by inheriting from your actual
-       class, and thus if your class is a.b.C then Coccinelle will create
-       a Python class "class Coccinelle(a.b.C)" that hooks include_match
-       into the O'Caml internals.
-       """
-       def include_match(self, b):
-               pass
-
-       def register_match(self, include, messages):
-               pass
-
-       def combine(self, meta_variable, locations):
-               nmv = deepcopy(meta_variable)
-               nloc = [deepcopy(loc) for loc in locations]
-               nmv.location = nloc[0]
-               nmv.locations = nloc
-
-               return nmv
-
-       def finalise(self):
-               pass
-
-       def print_main(self, p) :
-               print "* TODO [[view:%s::face=ovl-face1::linb=%s::colb=%s::cole=%s][%s::%s]]" % (p[0].file,p[0].line,p[0].column,p[0].column_end,p[0].file,p[0].line)
-
-       def print_sec(self, msg, p) :
-               print "[[view:%s::face=ovl-face2::linb=%s::colb=%s::cole=%s][%s]]" % (p[0].file,p[0].line,p[0].column,p[0].column_end,msg)
-
-       def print_secs(self, msg, ps) :
-               for i in ps:
-                       print "[[view:%s::face=ovl-face2::linb=%s::colb=%s::cole=%s][%s]]" % (i.file,i.line,i.column,i.column_end,msg)
-
-class Console(Output):
-       def __init__(self):
-               pass
-
-       def register_match(self, include, messages):
-               self.include_match(include)
-               if include:
-                       for variable, message in messages:
-                               print "%s:%s:%s: %s - %s" % (variable.location.file, variable.location.line, variable.location.column, message, variable)
-
-class GtkRunner(Thread):
-       def __init__(self):
-               Thread.__init__(self)
-               self.lock = Lock()
-               self.rows = []
-
-       def add_row(self, cocci, l):
-               for i in xrange(0, len(l)):
-                       l[i] = (l[i][1], l[i][0].location.file, l[i][0].location.line, l[i][0].location.column)
-
-               self.lock.acquire()
-               try:
-                       self.rows.append((cocci, l))
-               finally:
-                       self.lock.release()
-
-       def has_row(self):
-               self.lock.acquire()
-               try:
-                       return len(self.rows) > 0
-               finally:
-                       self.lock.release()
-
-       def get_row(self):
-               self.lock.acquire()
-               try:
-                       return self.rows.pop(0)
-               finally:
-                       self.lock.release()
-
-       def update(self):
-               while self.has_row():
-                       cocci, l = self.get_row()
-                       self.gui.add_result(cocci, l)
-               gobject.timeout_add(1000, self.update)
-
-       def run(self):
-               self.gui = coccilib.coccigui.coccigui.pycocci()
-               globals()['gtk_sock'] = self.gui
-               gobject.timeout_add(1000, self.update)
-
-               gtk.gdk.threads_init()
-               gtk.gdk.threads_enter()
-
-               gtk.main()
-
-               gtk.gdk.threads_leave()
-
-               globals().pop('gtk_thread')
-               globals().pop('gtk_sock')
-
-class Gtk(Output):
-       def check_availability(self):
-               if not globals().has_key('gtk_sock'):
-                       t = GtkRunner()
-                       globals()['gtk_thread'] = t
-                       globals()['gtk_thread'].start()
-                       time.sleep(2)
-
-       def register_match(self, include, messages):
-               self.check_availability()
-
-               self.include_match(include)
-               if include:
-                       globals()['gtk_thread'].add_row(self.cocci_file, messages)
-
-       def finalise(self):
-               self.check_availability()
-
-               globals()['gtk_thread'].join()
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..9b9e839b50936fb66176dfd047543b4b008e07a0
--- /dev/null
@@ -0,0 +1 @@
+output_base.py
\ No newline at end of file
similarity index 96%
copy from python/coccilib/output.py
copy to python/coccilib/output_base.py
index af6f713..65f0473 100644 (file)
@@ -33,8 +33,8 @@ class Output:
        def finalise(self):
                pass
 
-       def print_main(self, p) :
-               print "* TODO [[view:%s::face=ovl-face1::linb=%s::colb=%s::cole=%s][%s::%s]]" % (p[0].file,p[0].line,p[0].column,p[0].column_end,p[0].file,p[0].line)
+       def print_main(self, msg, p) :
+               print "* TODO [[view:%s::face=ovl-face1::linb=%s::colb=%s::cole=%s][%s %s::%s]]" % (p[0].file,p[0].line,p[0].column,p[0].column_end,msg,p[0].file,p[0].line)
 
        def print_sec(self, msg, p) :
                print "[[view:%s::face=ovl-face2::linb=%s::colb=%s::cole=%s][%s]]" % (p[0].file,p[0].line,p[0].column,p[0].column_end,msg)
diff --git a/python/coccilib/output_trac.py b/python/coccilib/output_trac.py
new file mode 100644 (file)
index 0000000..1317064
--- /dev/null
@@ -0,0 +1,139 @@
+import pygtk
+import gtk, gobject
+import coccilib.coccigui
+import coccilib.coccigui.coccigui
+from threading import Thread, Lock
+import time
+from copy import deepcopy
+import psycopg2
+from datetime import date, datetime
+from trac.util.datefmt import to_timestamp, utc
+
+
+class Output:
+       """In order to implement an output class for use with Coccinelle,
+       one can inherit from this class and overload register_match with
+       the same number of arguments.
+
+       include_match will be overwritten by inheriting from your actual
+       class, and thus if your class is a.b.C then Coccinelle will create
+       a Python class "class Coccinelle(a.b.C)" that hooks include_match
+       into the O'Caml internals.
+       """
+       def include_match(self, b):
+               pass
+
+       def register_match(self, include, messages):
+               pass
+
+       def combine(self, meta_variable, locations):
+               nmv = deepcopy(meta_variable)
+               nloc = [deepcopy(loc) for loc in locations]
+               nmv.location = nloc[0]
+               nmv.locations = nloc
+
+               return nmv
+
+       def finalise(self):
+               pass
+
+       def print_main(self, p) :
+               print "* TODO [[view:%s::face=ovl-face1::linb=%s::colb=%s::cole=%s][%s::%s]]" % (p[0].file,p[0].line,p[0].column,p[0].column_end,p[0].file,p[0].line)
+
+       def print_sec(self, msg, p) :
+               print "[[view:%s::face=ovl-face2::linb=%s::colb=%s::cole=%s][%s]]" % (p[0].file,p[0].line,p[0].column,p[0].column_end,msg)
+
+       def print_secs(self, msg, ps) :
+               for i in ps:
+                       print "[[view:%s::face=ovl-face2::linb=%s::colb=%s::cole=%s][%s]]" % (i.file,i.line,i.column,i.column_end,msg)
+
+       def add_ticket(self, dbinfo, summary, desc) :
+               conn = psycopg2.connect(dbinfo)
+               curs = conn.cursor()
+               created = to_timestamp(datetime.now(utc))
+               curs.execute("INSERT INTO ticket \
+ (type,time,changetime,component,priority,owner,reporter,cc,version,milestone,status,summary,description, keywords) \
+ VALUES \
+ ('defect', %s, %s, 'other','major','somebody','Coccinelle','','next','','new','%s','%s', '')" % (created, created, summary, desc) )
+               conn.commit()
+
+class Console(Output):
+       def __init__(self):
+               pass
+
+       def register_match(self, include, messages):
+               self.include_match(include)
+               if include:
+                       for variable, message in messages:
+                               print "%s:%s:%s: %s - %s" % (variable.location.file, variable.location.line, variable.location.column, message, variable)
+
+class GtkRunner(Thread):
+       def __init__(self):
+               Thread.__init__(self)
+               self.lock = Lock()
+               self.rows = []
+
+       def add_row(self, cocci, l):
+               for i in xrange(0, len(l)):
+                       l[i] = (l[i][1], l[i][0].location.file, l[i][0].location.line, l[i][0].location.column)
+
+               self.lock.acquire()
+               try:
+                       self.rows.append((cocci, l))
+               finally:
+                       self.lock.release()
+
+       def has_row(self):
+               self.lock.acquire()
+               try:
+                       return len(self.rows) > 0
+               finally:
+                       self.lock.release()
+
+       def get_row(self):
+               self.lock.acquire()
+               try:
+                       return self.rows.pop(0)
+               finally:
+                       self.lock.release()
+
+       def update(self):
+               while self.has_row():
+                       cocci, l = self.get_row()
+                       self.gui.add_result(cocci, l)
+               gobject.timeout_add(1000, self.update)
+
+       def run(self):
+               self.gui = coccilib.coccigui.coccigui.pycocci()
+               globals()['gtk_sock'] = self.gui
+               gobject.timeout_add(1000, self.update)
+
+               gtk.gdk.threads_init()
+               gtk.gdk.threads_enter()
+
+               gtk.main()
+
+               gtk.gdk.threads_leave()
+
+               globals().pop('gtk_thread')
+               globals().pop('gtk_sock')
+
+class Gtk(Output):
+       def check_availability(self):
+               if not globals().has_key('gtk_sock'):
+                       t = GtkRunner()
+                       globals()['gtk_thread'] = t
+                       globals()['gtk_thread'].start()
+                       time.sleep(2)
+
+       def register_match(self, include, messages):
+               self.check_availability()
+
+               self.include_match(include)
+               if include:
+                       globals()['gtk_thread'].add_row(self.cocci_file, messages)
+
+       def finalise(self):
+               self.check_availability()
+
+               globals()['gtk_thread'].join()
index e4ded17..b8efc7c 100644 (file)
@@ -45,7 +45,7 @@ let rec exprrep expr = match expr with
 | Ast_c.ParenExpr e -> "TODO: ParenExpr"
 and constantrep c = match c with
   Ast_c.String (s,isWchar) -> s 
-| Ast_c.MultiString -> "TODO: MultiString"
+| Ast_c.MultiString -> "TODO: MultiString"
 | Ast_c.Char (s,isWchar) -> s
 | Ast_c.Int s -> s 
 | Ast_c.Float (s,t) -> s
@@ -73,4 +73,5 @@ let stringrep mvb = match mvb with
     (* Common.sprintf ("pos(%d,%d)") pos1 pos2 *)
     "TODO: <<posval>>"
 | Ast_c.MetaPosValList positions -> "TODO: <<postvallist>>"
+| Ast_c.MetaInitVal _ -> "TODO: <<metainitval>>"
 
index 4f55845..bb877d5 100644 (file)
@@ -199,7 +199,7 @@ let construct_variables mv e =
   List.iter (function (py,(r,m)) ->
     match find_binding (r,m) with
       None -> ()
-    | Some (_, Ast_c.MetaExprVal ((expr, _), info_list)) ->
+    | Some (_, Ast_c.MetaExprVal expr) ->
        let expr_repr = instantiate_Expression(expr) in
        let _ = build_variable py expr_repr in
        ()
index 8c5af0b..7d4a241 100644 (file)
@@ -24,33 +24,6 @@ open Ast_c
 open Common
 open Pycaml
 
-let rec exprrep expr = match expr with
-  Ast_c.Ident s -> s
-| Ast_c.Constant c -> constantrep c
-| Ast_c.FunCall (e,args) -> "TODO: FunCall"
-| Ast_c.CondExpr (e1,e2,e3) -> "TODO: CondExpr"
-| Ast_c.Sequence (e1,e2) -> "TODO: Sequence"
-| Ast_c.Assignment (e1,op,e2) -> "TODO: Assignment"
-| Ast_c.Postfix (e,op) -> "TODO: Postfix"
-| Ast_c.Infix (e,op) -> "TODO: Infix"
-| Ast_c.Unary (e,op) -> "TODO: Unary"
-| Ast_c.Binary (e1,op,e2) -> "TODO: Binary"
-| Ast_c.ArrayAccess (e1,e2) -> "TODO: ArrayAccess"
-| Ast_c.RecordAccess (e1,s) -> "TODO: RecordAccess"
-| Ast_c.RecordPtAccess (e,s) -> "TODO: RecordPtAccess"
-| Ast_c.SizeOfExpr e -> "TODO: SizeOfExpr"
-| Ast_c.SizeOfType t -> "TODO: SizeOfType"
-| Ast_c.Cast (t,e) -> "TODO: Cast"
-| Ast_c.StatementExpr c -> "TODO: StatementExpr"
-| Ast_c.Constructor (t,i) -> "TODO: Constructor"
-| Ast_c.ParenExpr e -> "TODO: ParenExpr"
-and constantrep c = match c with
-  Ast_c.String (s,isWchar) -> s 
-| Ast_c.MultiString -> "TODO: MultiString"
-| Ast_c.Char (s,isWchar) -> s
-| Ast_c.Int s -> s 
-| Ast_c.Float (s,t) -> s
-
 let call_pretty f a =
   let str = ref ([] : string list) in
   let pr_elem info = str := (Ast_c.str_of_info info) :: !str in
@@ -58,17 +31,20 @@ let call_pretty f a =
   f pr_elem pr_sp a;
   String.concat " " (List.rev !str)
 
+let exprrep = call_pretty Pretty_print_c.pp_expression_gen
+
 let stringrep mvb = match mvb with
   Ast_c.MetaIdVal        s -> s
 | Ast_c.MetaFuncVal      s -> s
 | Ast_c.MetaLocalFuncVal s -> s
-| Ast_c.MetaExprVal      ((expr,_),[il]) -> (exprrep expr)
-| Ast_c.MetaExprVal     e -> "TODO: <<MetaExprVal>>"
+| Ast_c.MetaExprVal      expr -> exprrep expr
 | Ast_c.MetaExprListVal  expr_list -> "TODO: <<exprlist>>"
 | Ast_c.MetaTypeVal      typ -> call_pretty Pretty_print_c.pp_type_gen typ
-| Ast_c.MetaInitVal      ini -> "TODO: <<initiliser>>"
-| Ast_c.MetaStmtVal      statement -> "TODO: stmt"
-| Ast_c.MetaParamVal     params -> "TODO: <<param>>"
+| Ast_c.MetaInitVal      ini -> call_pretty Pretty_print_c.pp_init_gen ini
+| Ast_c.MetaStmtVal      statement ->
+    call_pretty Pretty_print_c.pp_statement_gen statement
+| Ast_c.MetaParamVal     param ->
+    call_pretty Pretty_print_c.pp_param_gen param
 | Ast_c.MetaParamListVal params -> "TODO: <<paramlist>>"
 | Ast_c.MetaListlenVal n -> string_of_int n
 | Ast_c.MetaPosVal (pos1, pos2) ->
diff --git a/scripts/spatch.sh b/scripts/spatch.sh
new file mode 100644 (file)
index 0000000..18461e5
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+echo setting COCCINELLE_HOME=${COCCINELLE_HOME:=SHAREDIR}
+
+if [ ! -r $COCCINELLE_HOME/standard.iso ] ; then
+    echo "There is no standard.iso in SHAREDIR."
+    echo "Are you sure you run a properly installed version of spatch ?\n"
+else
+
+ export COCCINELLE_HOME
+ export LD_LIBRARY_PATH=$COCCINELLE_HOME:$LD_LIBRARY_PATH
+ export PYTHONPATH=$COCCINELLE_HOME/python:$PYTHONPATH
+ echo setting LD_LIBRARY_PATH=$LD_LIBRARY_PATH
+ echo setting PYTHONPATH=$PYTHONPATH
+
+fi
+
+$COCCINELLE_HOME/spatch.opt $*
+
index c1087eb..31abbe3 100644 (file)
@@ -220,7 +220,7 @@ let test_okfailed cocci_file cfiles =
             match ext with
             | "c" -> "res"
             | "h" -> "h.res"
-            | s -> pr2 ("WIERD: not a .c or .h :" ^ base ^ "." ^ s);
+            | s -> pr2 ("WEIRD: not a .c or .h :" ^ base ^ "." ^ s);
                 "" (* no extension, will compare to same file *)
           in
           let expected_res =  
@@ -333,7 +333,7 @@ let compare_with_expected outfiles =
       match ext with
       | "c" -> "res"
       | "h" -> "h.res"
-      | s -> failwith ("wierd C file, not a .c or .h :" ^ s)
+      | s -> failwith ("weird C file, not a .c or .h :" ^ s)
     in
     let expected_res =  
       Common.filename_of_dbe  (dir, base, expected_suffix) in
diff --git a/tests/addif.c b/tests/addif.c
new file mode 100644 (file)
index 0000000..b2313ab
--- /dev/null
@@ -0,0 +1,7 @@
+static int foo() {
+  return 12;
+}
+
+static int bar() {
+  return 12;
+}
diff --git a/tests/addif.cocci b/tests/addif.cocci
new file mode 100644 (file)
index 0000000..c9669fc
--- /dev/null
@@ -0,0 +1,15 @@
+@@
+identifier f;
+@@
+
++ #ifdef FOO
++ /* some comment */
++ int xxx() {
++    /* a comment by itself */
++    return 12; /* another comment */ }
++ #endif
+ int
+ f(...)
+ {
+ ...
+ }
diff --git a/tests/addif.res b/tests/addif.res
new file mode 100644 (file)
index 0000000..cfb14d3
--- /dev/null
@@ -0,0 +1,19 @@
+#ifdef FOO
+/* some comment */
+int xxx() {
+   /* a comment by itself */
+   return 12; /* another comment */ }
+#endif
+static int foo() {
+  return 12;
+}
+
+#ifdef FOO
+/* some comment */
+int xxx() {
+   /* a comment by itself */
+   return 12; /* another comment */ }
+#endif
+static int bar() {
+  return 12;
+}
diff --git a/tests/addif1.c b/tests/addif1.c
new file mode 100644 (file)
index 0000000..b2313ab
--- /dev/null
@@ -0,0 +1,7 @@
+static int foo() {
+  return 12;
+}
+
+static int bar() {
+  return 12;
+}
diff --git a/tests/addif1.cocci b/tests/addif1.cocci
new file mode 100644 (file)
index 0000000..30d8d67
--- /dev/null
@@ -0,0 +1,13 @@
+@@
+identifier f;
+@@
+
++ #ifdef FOO
++ int xxx() {
++    return 12; }
++ #endif
+ int
+ f(...)
+ {
+ ...
+ }
diff --git a/tests/addif1.res b/tests/addif1.res
new file mode 100644 (file)
index 0000000..0edaaa0
--- /dev/null
@@ -0,0 +1,15 @@
+#ifdef FOO
+int xxx() {
+   return 12; }
+#endif
+static int foo() {
+  return 12;
+}
+
+#ifdef FOO
+int xxx() {
+   return 12; }
+#endif
+static int bar() {
+  return 12;
+}
diff --git a/tests/addif2.c b/tests/addif2.c
new file mode 100644 (file)
index 0000000..b2313ab
--- /dev/null
@@ -0,0 +1,7 @@
+static int foo() {
+  return 12;
+}
+
+static int bar() {
+  return 12;
+}
diff --git a/tests/addif2.cocci b/tests/addif2.cocci
new file mode 100644 (file)
index 0000000..4a516a5
--- /dev/null
@@ -0,0 +1,12 @@
+@@
+identifier f;
+@@
+
++ #ifdef FOO
++ int /*foo*/ xxx;
++ #endif
+ int
+ f(...)
+ {
+ ...
+ }
diff --git a/tests/addif2.res b/tests/addif2.res
new file mode 100644 (file)
index 0000000..91f011b
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef FOO
+int /*foo*/ xxx;
+#endif
+static int foo() {
+  return 12;
+}
+
+#ifdef FOO
+int /*foo*/ xxx;
+#endif
+static int bar() {
+  return 12;
+}
diff --git a/tests/ifdef6a.c b/tests/ifdef6a.c
new file mode 100644 (file)
index 0000000..ab8c5ee
--- /dev/null
@@ -0,0 +1,13 @@
+#include <asm/thread_info.h>
+#include <asm/memory.h>
+#include <asm/mach/time.h>
+#include <asm/io.h>
+
+
+void init_IRQ(void)
+{
+       for (irq = 0; irq < IRQS; irq++) {
+               *desc = irq_desc;
+               uselessCall();
+       }
+}
diff --git a/tests/ifdef6a.cocci b/tests/ifdef6a.cocci
new file mode 100644 (file)
index 0000000..c82781e
--- /dev/null
@@ -0,0 +1,7 @@
+@ Exemple6@ @@
+
++ #ifdef CONFIG_NKERNEL
++ #define foo(x) f(x)
++ #endif
+
+  #include <asm/memory.h>
diff --git a/tests/ifdef6a.res b/tests/ifdef6a.res
new file mode 100644 (file)
index 0000000..c171be1
--- /dev/null
@@ -0,0 +1,16 @@
+#include <asm/thread_info.h>
+#ifdef CONFIG_NKERNEL
+#define foo(x) f(x)
+#endif
+#include <asm/memory.h>
+#include <asm/mach/time.h>
+#include <asm/io.h>
+
+
+void init_IRQ(void)
+{
+       for (irq = 0; irq < IRQS; irq++) {
+               *desc = irq_desc;
+               uselessCall();
+       }
+}
index 7b5eb80..3ef9dfc 100644 (file)
@@ -1,3 +1,5 @@
+-include ../Makefile.config
+
 PROGS=gitgrep split_patch extract_c_and_res #generate_dependencies
 
 all: $(SUBDIRS) $(PROGS)
@@ -38,7 +40,7 @@ OCAMLOPT=ocamlopt$(OPTBIN)   $(INCLUDE) $(OPTFLAGS)
 #OCAMLLEX=ocamllex$(OPTBIN) -ml
 OCAMLLEX=ocamllex$(OPTBIN)
 OCAMLYACC=ocamlyacc -v
-OCAMLDEP=ocamldep$(OPTBIN) #$(INCLUDE)
+OCAMLDEP=ocamldep$(OPTBIN) $(INCLUDE)
 OCAMLMKTOP=ocamlmktop -g -custom $(INCLUDE)
 
 split_patch: split_patch.cmo
index 5614491..9b5de44 100644 (file)
@@ -6,3 +6,6 @@ install: spatch_linux cleanup
 
 cleanup: cleanup.ml
        ocamlc -o cleanup str.cma cleanup.ml
+
+clean:
+       rm -f cleanup cleanup.cmi cleanup.cmo spatch_linux
index 4aa4b39..d18ab94 100644 (file)
@@ -14,11 +14,14 @@ let get_file l = (* l is a diff line *)
 
 let get_files prefix =
   let files = Array.to_list(Sys.readdir(Sys.getcwd())) in
-  let is_number n = try let _ = int_of_string n in true with _ -> false in
   let relevant name =
-    match Str.split (Str.regexp "\\.") name with
-      [pref;mid;ext] -> prefix = pref && is_number mid && ext = "out"
-    | _ -> false in
+    let rel_re = Str.regexp "\\(.*\\)\\.[0-9]+\\.out" in
+      if Str.string_match rel_re name 0 then
+       let pref = Str.matched_group 1 name in
+         pref = prefix
+      else
+       false
+  in
   List.filter relevant files
 
 let process_file fl =
@@ -59,11 +62,11 @@ let _ =
   Printf.printf "arg %s\n" arg;
   let arg = Filename.chop_extension arg in
   let files = get_files arg in
-  process_all_files files arg;
+  process_all_files files (arg^".out");
   let tmp_files =
     String.concat " "
       (List.map (function x -> "tmp."^x) (List.sort compare files)) in
-  let _ = Sys.command (Printf.sprintf "cat %s > tmp.%s" tmp_files arg) in
+  let _ = Sys.command (Printf.sprintf "cat %s > %s.tmp" tmp_files arg) in
   List.iter
     (function file ->
       let _ = Sys.command (Printf.sprintf "/bin/rm %s" file) in
diff --git a/tools/distributed/cleanup_script b/tools/distributed/cleanup_script
deleted file mode 100644 (file)
index 7f1e534..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/tcsh
-
-#cat ${1:r}.*.out > ${1:r}
-#/bin/rm ${1:r}.*.out
-
-~/coccinelle/tools/distributed/cleanup $1
-
index c38f9bf..ee5dabd 100644 (file)
@@ -1,60 +1,16 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/sem.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <signal.h>
 #include <string.h>
 
 #define MAX 9
 
-#define DONE_SEM 0 // index of the semaphore on which to wait for children
-
 #ifndef HOME
 #define HOME "/home/julia/coccinelle/tools/distributed/"
 #endif
 
-int sem;
-
-void inc_sem(int sem, int sem_num, int inc) {
-  struct sembuf sops;
-  sops.sem_num = sem_num;
-  sops.sem_op = inc;
-  sops.sem_flg = 0;
-  semop(sem,&sops,1);
-}
-
-void dec_sem(int sem, int sem_num) {
-  struct sembuf sops;
-  sops.sem_num = sem_num;
-  sops.sem_op = -1;
-  sops.sem_flg = 0;
-  semop(sem,&sops,1);
-}
-
-void wait_sem(int sem, int sem_num) {
-  struct sembuf sops;
-  int err;
-  sops.sem_num = sem_num;
-  sops.sem_op = 0;
-  sops.sem_flg = 0;
-  err = semop(sem,&sops,1);
-  if (err < 0) {printf("error in %d\n",sem);perror("wait_sem");}
-}
-
-void exit_sighandler(int x) {
-  semctl(sem,DONE_SEM,IPC_RMID);
-  exit(0);
-}
-
-void do_child(int sem, int id, unsigned int argc, char **argv, int max,
+void do_child(int id, unsigned int argc, char **argv, int max,
              char *script) {
-  int pid,status;
-  if (!(pid=fork())) {
-    // child
     int i;
     char **new_args = malloc(sizeof(char*) * (argc + 5));
     char string1[50],string2[50];
@@ -73,10 +29,7 @@ void do_child(int sem, int id, unsigned int argc, char **argv, int max,
     execvp(script,new_args);
     printf("tried to execute %s\n",HOME "spatch_linux_script");
     perror("exec failure");
-    exit(0);
-  }
-  wait(&status);
-  dec_sem(sem,DONE_SEM);  // indicate that this child is done
+    _exit(0);
 }
 
 void cleanup(char **argv) {
@@ -85,20 +38,12 @@ void cleanup(char **argv) {
   new_args[1] = argv[1];
   new_args[2] = NULL;
   printf ("doing cleanup on %s\n",argv[1]);
-  execvp(HOME "cleanup_script",new_args);
+  execvp(HOME "cleanup",new_args);
 }
 
 int main(unsigned int argc, char **argv) {
-  int pid, i, start=0, max;
+  int i, start=0, max;
   char script[150];
-  // initialize the semaphore
-  sem = semget(0,1/* only one sem */,(IPC_CREAT|0666));
-  if (sem < 0) { perror("semget"); exit(0); }
-  // set up signal handlers so we can delete the semaphore
-  signal(SIGTERM,exit_sighandler); // kill
-  signal(SIGHUP,exit_sighandler);  // kill -HUP  /  xterm closed
-  signal(SIGINT,exit_sighandler);  // Interrupt from keyboard
-  signal(SIGQUIT,exit_sighandler); // Quit from keyboard
   // interpret the arguments
   max = MAX;
   if (!strcmp(argv[1],"-processes")) {max = atoi(argv[2]); start = 2;}
@@ -112,19 +57,23 @@ int main(unsigned int argc, char **argv) {
     exit (0);
   }
 
-  inc_sem(sem,0,max);
-
   // run the child processes
+  int pid;
   for(i=0;i!=max;i++) {
     if (!(pid=fork())) {
       // child
-      do_child(sem,i,argc-start,&argv[start],max,script);
-      exit(0);
+      do_child(i,argc-start,&argv[start],max,script);
     }
+    else if (pid > 0) {
+  //   printf("Child born: %d\n", pid);
+    }
+    else
+       printf("*** forking error ***\n");
+  }
+  int status;
+  for(i=0;i!=max;i++) {
+       pid = wait(&status);
+  //   printf("Child dead: %d -- %d\n", pid,status);
   }
-
-  wait_sem(sem,DONE_SEM); // wait for the children to end
-  int err = semctl(sem,DONE_SEM,IPC_RMID);
-  if (err < 0) perror ("couldn't remove");
   cleanup(&argv[start]);
 }