From 0708f913629519b5dbc99f68b6f3ea5ab068230c Mon Sep 17 00:00:00 2001 From: Coccinelle Date: Sun, 3 Oct 2010 13:57:41 +0200 Subject: [PATCH] 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 for the bug report. --- .#Makefile.1.122 | 462 ++ .#Makefile.1.123 | 464 ++ .#Makefile.1.125 | 467 ++ .#Makefile.1.127 | 467 ++ .#cocci.ml.1.295 | 1512 +++++++ .#main.ml.1.248 | 847 ++++ .#testing.ml.1.67 | 414 ++ .depend | 54 +- Makefile | 88 +- Makefile.config | 6 + changes.txt | 42 +- cocci.ml | 24 +- commitmsg | 44 +- commons/.depend | 7 + commons/Makefile | 10 +- commons/common.ml | 73 +- commons/common.mli | 27 +- commons/ocollection/oassoc_buffer.ml | 40 +- commons/ocollection/oassoc_cache.ml | 171 + commons/ocollection/oassoc_cache.mli | 34 + commons/ocollection/oassocbdb.ml | 22 +- commons/ocollection/oassocbdb_string.ml | 8 +- commons/ocollection/oassocdbm.ml | 18 +- configure | 68 +- credits.txt | 1 + ctl/.#Makefile.1.21 | 95 + ctl/.#Makefile.1.22 | 95 + ctl/.depend | 32 +- ctl/Makefile | 4 +- demos/ifdef_skip_tag.c | 20 + demos/macro_fix_standard.h | 5 + demos/macro_parsing_problem.c | 208 + demos/platform_ifdef.c | 12 + demos/platform_ifdef.cocci | 10 + docs/grammar/Makefile | 2 +- docs/grammar/cocci_syntax.tex | 46 +- docs/grammar/examples.tex | 24 + docs/grammar/tips.tex | 47 + docs/spatch.1 | 2 +- {emacs => editors/emacs}/cocci-ediff.el | 0 {emacs => editors/emacs}/cocci.el | 4 +- editors/vim/README | 13 + editors/vim/ftdetect/cocci.vim | 13 + editors/vim/syntax/cocci.vim | 40 + engine/.#Makefile.1.52 | 126 + engine/.#Makefile.1.53 | 126 + engine/.#Makefile.1.54 | 126 + engine/.#asttoctl.ml.1.81 | 1462 +++++++ engine/.#asttoctl2.ml.1.152 | 2340 ++++++++++ engine/.#cocci_vs_c.ml.1.28 | 3765 +++++++++++++++++ engine/.#cocci_vs_c.ml.1.29 | 3765 +++++++++++++++++ ...ib_matcher_c.ml => .#lib_matcher_c.ml.1.1} | 0 engine/.#transformation_c.ml.1.3 | 547 +++ engine/.depend | 186 +- engine/Makefile | 6 +- engine/asttoctl.ml | 2 +- engine/asttoctl2.ml | 2 +- engine/cocci_vs_c.ml | 6 +- engine/lib_matcher_c.ml | 156 - engine/lib_matcher_c.mli | 21 - engine/transformation_c.ml | 6 +- env.sh | 26 +- extra/.depend | 15 +- extra/Makefile | 4 +- globals/Makefile | 5 +- globals/config.ml | 2 +- globals/flag.ml | 2 + main.ml | 11 +- menhirlib/Makefile | 5 +- parsing_c/.depend | 212 +- parsing_c/Makefile | 10 +- parsing_c/ast_c.ml | 64 +- parsing_c/ast_to_flow.ml | 15 +- parsing_c/comment_annotater_c.ml | 140 + parsing_c/comment_annotater_c.mli | 5 + parsing_c/compare_c.ml | 13 + parsing_c/control_flow_c.ml | 13 + parsing_c/cpp_ast_c.ml | 14 +- parsing_c/flag_parsing_c.ml | 1 + parsing_c/lexer_c.mll | 16 +- parsing_c/lexer_parser.ml | 4 +- parsing_c/lib_parsing_c.ml | 30 +- parsing_c/parse_c.ml | 26 +- parsing_c/parser_c.mly | 78 +- parsing_c/parsing_hacks.ml | 162 +- parsing_c/parsing_stat.ml | 14 + parsing_c/pretty_print_c.ml | 24 +- parsing_c/test_parsing_c.ml | 32 + parsing_c/test_parsing_c.mli | 2 + parsing_c/token_c.ml | 258 ++ parsing_c/token_helpers.ml | 56 +- parsing_c/token_helpers.mli | 10 +- parsing_c/type_annoter_c.ml | 43 +- parsing_c/type_annoter_c.mli | 2 +- parsing_c/type_c.ml | 135 +- parsing_c/type_c.mli | 18 + parsing_c/unparse_c.ml | 34 +- parsing_c/unparse_cocci.ml | 45 +- parsing_c/unparse_hrule.ml | 128 +- parsing_c/visitor_c.ml | 48 +- parsing_c/visitor_c.mli | 3 + parsing_cocci/.#Makefile.1.50 | 136 + parsing_cocci/.#Makefile.1.51 | 136 + parsing_cocci/.#arity.ml.1.88 | 1074 +++++ parsing_cocci/.#ast0_cocci.ml.1.115 | 672 +++ parsing_cocci/.#ast0toast.ml.1.140 | 938 ++++ parsing_cocci/.#ast_cocci.ml.1.151 | 682 +++ parsing_cocci/.#check_meta.ml.1.88 | 539 +++ parsing_cocci/.#compute_lines.ml.1.92 | 771 ++++ parsing_cocci/.#context_neg.ml.1.104 | 1023 +++++ parsing_cocci/.#data.ml.1.38 | 151 + parsing_cocci/.#index.ml.1.60 | 221 + parsing_cocci/.#insert_plus.ml.1.74 | 952 +++++ parsing_cocci/.#iso_pattern.ml.1.152 | 2379 +++++++++++ parsing_cocci/.#lexer_cocci.mll.1.86 | 712 ++++ parsing_cocci/.#parse_aux.ml.1.27 | 482 +++ parsing_cocci/.#parse_cocci.ml.1.180 | 1628 +++++++ parsing_cocci/.#parser_cocci_menhir.mly.1.168 | 1859 ++++++++ parsing_cocci/.#parser_cocci_menhir.mly.1.169 | 1859 ++++++++ parsing_cocci/.#pretty_print_cocci.ml.1.135 | 865 ++++ parsing_cocci/.#type_infer.ml.1.60 | 384 ++ parsing_cocci/.#unparse_ast0.ml.1.118 | 667 +++ parsing_cocci/.#visitor_ast.ml.1.97 | 1061 +++++ parsing_cocci/.depend | 158 +- parsing_cocci/Makefile | 6 +- parsing_cocci/adjust_pragmas.ml | 303 ++ parsing_cocci/adjust_pragmas.mli | 1 + parsing_cocci/arity.ml | 5 +- parsing_cocci/ast0_cocci.ml | 23 +- parsing_cocci/ast0_cocci.mli | 11 +- parsing_cocci/ast0toast.ml | 13 +- parsing_cocci/ast_cocci.ml | 40 +- parsing_cocci/ast_cocci.mli | 6 +- parsing_cocci/check_meta.ml | 6 +- parsing_cocci/compute_lines.ml | 55 +- parsing_cocci/context_neg.ml | 42 +- parsing_cocci/data.ml | 3 +- parsing_cocci/data.mli | 3 +- parsing_cocci/index.ml | 12 +- parsing_cocci/insert_plus.ml | 152 +- parsing_cocci/iso_pattern.ml | 50 +- parsing_cocci/lexer_cocci.mll | 26 +- parsing_cocci/parse_aux.ml | 8 +- parsing_cocci/parse_cocci.ml | 110 +- parsing_cocci/parser_cocci_menhir.ml | 3391 +++++++-------- parsing_cocci/parser_cocci_menhir.mli | 2 +- parsing_cocci/parser_cocci_menhir.mly | 9 +- parsing_cocci/pretty_print_cocci.ml | 5 +- parsing_cocci/type_infer.ml | 1 + parsing_cocci/unparse_ast0.ml | 16 +- parsing_cocci/visitor_ast.ml | 2 + popl/.#Makefile.1.5 | 102 + popl/Makefile | 2 + popl09/.#Makefile.1.5 | 101 + popl09/.#Makefile.1.6 | 101 + popl09/.depend | 47 +- popl09/Makefile | 3 +- pycaml/pycaml.ml | 2 + pycaml/pycaml_ml.c | 7 +- python/.#Makefile.1.5 | 146 + python/.#no_pycocci_aux.ml.1.2 | 76 + python/.#yes_pycocci.ml.1.2 | 243 ++ python/.#yes_pycocci_aux.ml.1.2 | 80 + python/.#yes_pycocci_aux.ml.1.3 | 80 + python/.depend | 28 +- python/Makefile | 2 +- python/coccilib/output.py | 126 +- python/coccilib/{output.py => output_base.py} | 4 +- python/coccilib/output_trac.py | 139 + python/no_pycocci_aux.ml | 3 +- python/yes_pycocci.ml | 2 +- python/yes_pycocci_aux.ml | 40 +- scripts/spatch.sh | 20 + testing.ml | 4 +- tests/addif.c | 7 + tests/addif.cocci | 15 + tests/addif.res | 19 + tests/addif1.c | 7 + tests/addif1.cocci | 13 + tests/addif1.res | 15 + tests/addif2.c | 7 + tests/addif2.cocci | 12 + tests/addif2.res | 13 + tests/ifdef6a.c | 13 + tests/ifdef6a.cocci | 7 + tests/ifdef6a.res | 16 + tools/Makefile | 4 +- tools/distributed/Makefile | 3 + tools/distributed/cleanup.ml | 15 +- tools/distributed/cleanup_script | 7 - tools/distributed/spatch_linux.c | 83 +- 191 files changed, 42696 insertions(+), 2977 deletions(-) create mode 100644 .#Makefile.1.122 create mode 100644 .#Makefile.1.123 create mode 100644 .#Makefile.1.125 create mode 100644 .#Makefile.1.127 create mode 100644 .#cocci.ml.1.295 create mode 100644 .#main.ml.1.248 create mode 100644 .#testing.ml.1.67 rewrite .depend (100%) rewrite commitmsg (93%) create mode 100644 commons/ocollection/oassoc_cache.ml create mode 100644 commons/ocollection/oassoc_cache.mli create mode 100644 ctl/.#Makefile.1.21 create mode 100644 ctl/.#Makefile.1.22 rewrite ctl/.depend (87%) create mode 100644 demos/ifdef_skip_tag.c create mode 100644 demos/macro_fix_standard.h create mode 100644 demos/macro_parsing_problem.c create mode 100644 demos/platform_ifdef.c create mode 100644 demos/platform_ifdef.cocci create mode 100644 docs/grammar/tips.tex rename {emacs => editors/emacs}/cocci-ediff.el (100%) rename {emacs => editors/emacs}/cocci.el (100%) create mode 100644 editors/vim/README create mode 100644 editors/vim/ftdetect/cocci.vim create mode 100644 editors/vim/syntax/cocci.vim create mode 100644 engine/.#Makefile.1.52 create mode 100644 engine/.#Makefile.1.53 create mode 100644 engine/.#Makefile.1.54 create mode 100644 engine/.#asttoctl.ml.1.81 create mode 100644 engine/.#asttoctl2.ml.1.152 create mode 100644 engine/.#cocci_vs_c.ml.1.28 create mode 100644 engine/.#cocci_vs_c.ml.1.29 copy engine/{lib_matcher_c.ml => .#lib_matcher_c.ml.1.1} (100%) create mode 100644 engine/.#transformation_c.ml.1.3 rewrite engine/.depend (97%) rewrite engine/lib_matcher_c.ml (100%) rewrite engine/lib_matcher_c.mli (100%) rewrite extra/.depend (100%) rewrite parsing_c/.depend (83%) create mode 100644 parsing_c/comment_annotater_c.ml create mode 100644 parsing_c/comment_annotater_c.mli create mode 100644 parsing_c/token_c.ml create mode 100644 parsing_cocci/.#Makefile.1.50 create mode 100644 parsing_cocci/.#Makefile.1.51 create mode 100644 parsing_cocci/.#arity.ml.1.88 create mode 100644 parsing_cocci/.#ast0_cocci.ml.1.115 create mode 100644 parsing_cocci/.#ast0toast.ml.1.140 create mode 100644 parsing_cocci/.#ast_cocci.ml.1.151 create mode 100644 parsing_cocci/.#check_meta.ml.1.88 create mode 100644 parsing_cocci/.#compute_lines.ml.1.92 create mode 100644 parsing_cocci/.#context_neg.ml.1.104 create mode 100644 parsing_cocci/.#data.ml.1.38 create mode 100644 parsing_cocci/.#index.ml.1.60 create mode 100644 parsing_cocci/.#insert_plus.ml.1.74 create mode 100644 parsing_cocci/.#iso_pattern.ml.1.152 create mode 100644 parsing_cocci/.#lexer_cocci.mll.1.86 create mode 100644 parsing_cocci/.#parse_aux.ml.1.27 create mode 100644 parsing_cocci/.#parse_cocci.ml.1.180 create mode 100644 parsing_cocci/.#parser_cocci_menhir.mly.1.168 create mode 100644 parsing_cocci/.#parser_cocci_menhir.mly.1.169 create mode 100644 parsing_cocci/.#pretty_print_cocci.ml.1.135 create mode 100644 parsing_cocci/.#type_infer.ml.1.60 create mode 100644 parsing_cocci/.#unparse_ast0.ml.1.118 create mode 100644 parsing_cocci/.#visitor_ast.ml.1.97 create mode 100644 parsing_cocci/adjust_pragmas.ml create mode 100644 parsing_cocci/adjust_pragmas.mli create mode 100644 popl/.#Makefile.1.5 create mode 100644 popl09/.#Makefile.1.5 create mode 100644 popl09/.#Makefile.1.6 rewrite popl09/.depend (89%) create mode 100644 python/.#Makefile.1.5 create mode 100644 python/.#no_pycocci_aux.ml.1.2 create mode 100644 python/.#yes_pycocci.ml.1.2 create mode 100644 python/.#yes_pycocci_aux.ml.1.2 create mode 100644 python/.#yes_pycocci_aux.ml.1.3 rewrite python/.depend (100%) rewrite python/coccilib/output.py (100%) mode change 100644 => 120000 copy python/coccilib/{output.py => output_base.py} (96%) create mode 100644 python/coccilib/output_trac.py create mode 100644 scripts/spatch.sh create mode 100644 tests/addif.c create mode 100644 tests/addif.cocci create mode 100644 tests/addif.res create mode 100644 tests/addif1.c create mode 100644 tests/addif1.cocci create mode 100644 tests/addif1.res create mode 100644 tests/addif2.c create mode 100644 tests/addif2.cocci create mode 100644 tests/addif2.res create mode 100644 tests/ifdef6a.c create mode 100644 tests/ifdef6a.cocci create mode 100644 tests/ifdef6a.res delete mode 100644 tools/distributed/cleanup_script diff --git a/.#Makefile.1.122 b/.#Makefile.1.122 new file mode 100644 index 0000000..1168f58 --- /dev/null +++ b/.#Makefile.1.122 @@ -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 . +# +# 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 index 0000000..dcef57f --- /dev/null +++ b/.#Makefile.1.123 @@ -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 . +# +# 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 index 0000000..6909149 --- /dev/null +++ b/.#Makefile.1.125 @@ -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 . +# +# 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 index 0000000..59a8518 --- /dev/null +++ b/.#Makefile.1.127 @@ -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 . +# +# 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 index 0000000..1c1c45a --- /dev/null +++ b/.#cocci.ml.1.295 @@ -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 . +* +* 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 + *) + +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 index 0000000..992b6ae --- /dev/null +++ b/.#main.ml.1.248 @@ -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 . +* +* 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 [-o ] [-iso_file ] [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, + " the semantic patch file"; + + "-o", Arg.Set_string output_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, + " (default=" ^ !Config.std_iso ^")"; + "-macro_file", Arg.Set_string Config.std_h, + " (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, + " containing the Linux headers (optional)"; + + + "-dir", Arg.Set 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), + (" 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, + " improve -dir by grouping related c files"; + "-pyoutput", Arg.Set_string Flag.pyoutput, + " Sets output routine: Standard values: "; + + + "-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, + " 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), + " for profiling the CTL engine"; + "-timeout", Arg.Int (fun x -> FC.timeout := Some x), + " 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, + " 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), + " "); + (let s = "-compare_c" in s, Arg.Unit (fun () -> action := s), + " "); + ]); +] + + +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 "; + + 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 index 0000000..c1087eb --- /dev/null +++ b/.#testing.ml.1.67 @@ -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 . +* +* 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.*\"") "" 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 --- 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 diff --git a/Makefile b/Makefile index 1168f58..fd8a9c5 100644 --- 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) diff --git a/Makefile.config b/Makefile.config index c05b87e..dd601ee 100644 --- a/Makefile.config +++ b/Makefile.config @@ -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 diff --git a/changes.txt b/changes.txt index 9364c31..88141ff 100644 --- a/changes.txt +++ b/changes.txt @@ -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 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 @@ -20,13 +50,15 @@ * 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 @@ -81,17 +113,19 @@ * 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 diff --git a/cocci.ml b/cocci.ml index 1c1c45a..32bb774 100644 --- 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 = diff --git a/commitmsg b/commitmsg dissimilarity index 93% index c7d1f4f..6f7c7cc 100644 --- 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 for the bug report. diff --git a/commons/.depend b/commons/.depend index 7abe8f8..5fbb959 100644 --- a/commons/.depend +++ b/commons/.depend @@ -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 \ diff --git a/commons/Makefile b/commons/Makefile index e30d1af..baba40d 100644 --- a/commons/Makefile +++ b/commons/Makefile @@ -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. diff --git a/commons/common.ml b/commons/common.ml index 36d29b1..d080f35 100644 --- a/commons/common.ml +++ b/commons/common.ml @@ -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 diff --git a/commons/common.mli b/commons/common.mli index 21a05da..d6d9b63 100644 --- a/commons/common.mli +++ b/commons/common.mli @@ -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. *) (*****************************************************************************) diff --git a/commons/ocollection/oassoc_buffer.ml b/commons/ocollection/oassoc_buffer.ml index 345f051..85f430c 100644 --- a/commons/ocollection/oassoc_buffer.ml +++ b/commons/ocollection/oassoc_buffer.ml @@ -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 index 0000000..e62936f --- /dev/null +++ b/commons/ocollection/oassoc_cache.ml @@ -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 index 0000000..9cff0d7 --- /dev/null +++ b/commons/ocollection/oassoc_cache.mli @@ -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 diff --git a/commons/ocollection/oassocbdb.ml b/commons/ocollection/oassocbdb.ml index 6d09410..a395131 100644 --- a/commons/ocollection/oassocbdb.ml +++ b/commons/ocollection/oassocbdb.ml @@ -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; diff --git a/commons/ocollection/oassocbdb_string.ml b/commons/ocollection/oassocbdb_string.ml index 8682abf..e5bcf5b 100644 --- a/commons/ocollection/oassocbdb_string.ml +++ b/commons/ocollection/oassocbdb_string.ml @@ -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; diff --git a/commons/ocollection/oassocdbm.ml b/commons/ocollection/oassocdbm.ml index ff6531e..9a24d1f 100644 --- a/commons/ocollection/oassocdbm.ml +++ b/commons/ocollection/oassocdbm.ml @@ -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; diff --git a/configure b/configure index 9a6741c..bd012c0 100755 --- 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;`; +} + diff --git a/credits.txt b/credits.txt index c2e01b7..f50124c 100644 --- a/credits.txt +++ b/credits.txt @@ -1,4 +1,5 @@ Thanks to + - Alexander Faroy 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 index 0000000..8785901 --- /dev/null +++ b/ctl/.#Makefile.1.21 @@ -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 . +# +# 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 index 0000000..253b8cf --- /dev/null +++ b/ctl/.#Makefile.1.22 @@ -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 . +# +# 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/.depend b/ctl/.depend dissimilarity index 87% index 270088d..8733390 100644 --- a/ctl/.depend +++ b/ctl/.depend @@ -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 diff --git a/ctl/Makefile b/ctl/Makefile index 8785901..84b98d4 100644 --- a/ctl/Makefile +++ b/ctl/Makefile @@ -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 index 0000000..19765b6 --- /dev/null +++ b/demos/ifdef_skip_tag.c @@ -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 index 0000000..0d3a14f --- /dev/null +++ b/demos/macro_fix_standard.h @@ -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 index 0000000..3924396 --- /dev/null +++ b/demos/macro_parsing_problem.c @@ -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 index 0000000..9f190b3 --- /dev/null +++ b/demos/platform_ifdef.c @@ -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 index 0000000..5051b4c --- /dev/null +++ b/demos/platform_ifdef.cocci @@ -0,0 +1,10 @@ +@@ expression E; @@ + +//-alloca(E) +//+malloc(E) +- alloca ++ malloc + (E) + + + diff --git a/docs/grammar/Makefile b/docs/grammar/Makefile index 088be9e..3657fdc 100644 --- a/docs/grammar/Makefile +++ b/docs/grammar/Makefile @@ -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) diff --git a/docs/grammar/cocci_syntax.tex b/docs/grammar/cocci_syntax.tex index ed2b3fd..8dafbd9 100644 --- a/docs/grammar/cocci_syntax.tex +++ b/docs/grammar/cocci_syntax.tex @@ -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: diff --git a/docs/grammar/examples.tex b/docs/grammar/examples.tex index 704bc29..95da6e9 100644 --- a/docs/grammar/examples.tex +++ b/docs/grammar/examples.tex @@ -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 index 0000000..b7f18d5 --- /dev/null +++ b/docs/grammar/tips.tex @@ -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: diff --git a/docs/spatch.1 b/docs/spatch.1 index fdd9db0..c38cdc7 100644 --- a/docs/spatch.1 +++ b/docs/spatch.1 @@ -163,7 +163,7 @@ This manual page was written by Yoann Padioleau and Julia Lawall . .SH REPORTING BUGS -Send a mail to or +Send a mail to .SH COPYRIGHT Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen. diff --git a/emacs/cocci-ediff.el b/editors/emacs/cocci-ediff.el similarity index 100% rename from emacs/cocci-ediff.el rename to editors/emacs/cocci-ediff.el diff --git a/emacs/cocci.el b/editors/emacs/cocci.el similarity index 100% rename from emacs/cocci.el rename to editors/emacs/cocci.el index f3f6d3d..05ed60a 100644 --- a/emacs/cocci.el +++ b/editors/emacs/cocci.el @@ -73,12 +73,12 @@ "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 index 0000000..749b5ab --- /dev/null +++ b/editors/vim/README @@ -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 + + .. 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 index 0000000..fd78bea --- /dev/null +++ b/editors/vim/ftdetect/cocci.vim @@ -0,0 +1,13 @@ +" Vim filetype detection file +" Language: Cocci (SmPL) +" Author: Alexander Færøy +" 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 index 0000000..f3c9c16 --- /dev/null +++ b/editors/vim/syntax/cocci.vim @@ -0,0 +1,40 @@ +" Vim syntax file +" Language: Cocci (SmPL) +" Author: Alexander Færøy +" 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 index 0000000..c989683 --- /dev/null +++ b/engine/.#Makefile.1.52 @@ -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 . +# +# 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 index 0000000..b4f53ac --- /dev/null +++ b/engine/.#Makefile.1.53 @@ -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 . +# +# 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 index 0000000..25f7684 --- /dev/null +++ b/engine/.#Makefile.1.54 @@ -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 . +# +# 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 index 0000000..a569a97 --- /dev/null +++ b/engine/.#asttoctl.ml.1.81 @@ -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 . +* +* 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 index 0000000..865a633 --- /dev/null +++ b/engine/.#asttoctl2.ml.1.152 @@ -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 . +* +* 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 index 0000000..4b4bee4 --- /dev/null +++ b/engine/.#cocci_vs_c.ml.1.28 @@ -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 . +* +* 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 in the .cocci, need to find where is + * the '+' attached to this element, to later find the first concrete + * #include or last one in the serie of #includes in the + * .c. + *) +type include_requirement = + | IncludeMcodeBefore + | IncludeMcodeAfter + | IncludeNothing + + + +(* todo? put in semantic_c.ml *) +type info_ident = + | Function + | LocalFunction (* entails Function *) + | DontKnow + + +let term mc = A.unwrap_mcode mc +let mcodekind mc = A.get_mcodekind mc + + +let mcode_contain_plus = function + | A.CONTEXT (_,A.NOTHING) -> false + | A.CONTEXT _ -> true + | A.MINUS (_,[]) -> false + | A.MINUS (_,x::xs) -> true + | A.PLUS -> raise Impossible + +let mcode_simple_minus = function + | A.MINUS (_,[]) -> true + | _ -> false + + +(* In transformation.ml sometime I build some mcodekind myself and + * julia has put None for the pos. But there is no possible raise + * NoMatch in those cases because it is for the minusall trick or for + * the distribute, so either have to build those pos, in fact a range, + * because for the distribute have to erase a fullType with one + * mcodekind, or add an argument to tag_with_mck such as "safe" that + * don't do the check_pos. Hence this DontCarePos constructor. *) + +let minusizer = + ("fake","fake"), + {A.line = 0; column =0; A.strbef=[]; A.straft=[];}, + (A.MINUS(A.DontCarePos, [])), + A.NoMetaPos + +let generalize_mcode ia = + let (s1, i, mck, pos) = ia in + let new_mck = + match mck with + | A.PLUS -> raise Impossible + | A.CONTEXT (A.NoPos,x) -> + A.CONTEXT (A.DontCarePos,x) + | A.MINUS (A.NoPos,x) -> + A.MINUS (A.DontCarePos,x) + + | 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 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 index 0000000..75ddf8e --- /dev/null +++ b/engine/.#cocci_vs_c.ml.1.29 @@ -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 . +* +* 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 in the .cocci, need to find where is + * the '+' attached to this element, to later find the first concrete + * #include or last one in the serie of #includes in the + * .c. + *) +type include_requirement = + | IncludeMcodeBefore + | IncludeMcodeAfter + | IncludeNothing + + + +(* todo? put in semantic_c.ml *) +type info_ident = + | Function + | LocalFunction (* entails Function *) + | DontKnow + + +let term mc = A.unwrap_mcode mc +let mcodekind mc = A.get_mcodekind mc + + +let mcode_contain_plus = function + | A.CONTEXT (_,A.NOTHING) -> false + | A.CONTEXT _ -> true + | A.MINUS (_,[]) -> false + | A.MINUS (_,x::xs) -> true + | A.PLUS -> raise Impossible + +let mcode_simple_minus = function + | A.MINUS (_,[]) -> true + | _ -> false + + +(* In transformation.ml sometime I build some mcodekind myself and + * julia has put None for the pos. But there is no possible raise + * NoMatch in those cases because it is for the minusall trick or for + * the distribute, so either have to build those pos, in fact a range, + * because for the distribute have to erase a fullType with one + * mcodekind, or add an argument to tag_with_mck such as "safe" that + * don't do the check_pos. Hence this DontCarePos constructor. *) + +let minusizer = + ("fake","fake"), + {A.line = 0; column =0; A.strbef=[]; A.straft=[];}, + (A.MINUS(A.DontCarePos, [])), + A.NoMetaPos + +let generalize_mcode ia = + let (s1, i, mck, pos) = ia in + let new_mck = + match mck with + | A.PLUS -> raise Impossible + | A.CONTEXT (A.NoPos,x) -> + A.CONTEXT (A.DontCarePos,x) + | A.MINUS (A.NoPos,x) -> + A.MINUS (A.DontCarePos,x) + + | 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 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/lib_matcher_c.ml b/engine/.#lib_matcher_c.ml.1.1 similarity index 100% copy from engine/lib_matcher_c.ml copy to engine/.#lib_matcher_c.ml.1.1 diff --git a/engine/.#transformation_c.ml.1.3 b/engine/.#transformation_c.ml.1.3 new file mode 100644 index 0000000..8dc3f98 --- /dev/null +++ b/engine/.#transformation_c.ml.1.3 @@ -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 . +* +* 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) diff --git a/engine/.depend b/engine/.depend dissimilarity index 97% index 3ef9a54..8179bbb 100644 --- a/engine/.depend +++ b/engine/.depend @@ -1,45 +1,141 @@ -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 diff --git a/engine/Makefile b/engine/Makefile index c989683..15fddb0 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -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) diff --git a/engine/asttoctl.ml b/engine/asttoctl.ml index a569a97..048b389 100644 --- a/engine/asttoctl.ml +++ b/engine/asttoctl.ml @@ -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 diff --git a/engine/asttoctl2.ml b/engine/asttoctl2.ml index 865a633..10f79b1 100644 --- a/engine/asttoctl2.ml +++ b/engine/asttoctl2.ml @@ -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 diff --git a/engine/cocci_vs_c.ml b/engine/cocci_vs_c.ml index 4b4bee4..933f16e 100644 --- a/engine/cocci_vs_c.ml +++ b/engine/cocci_vs_c.ml @@ -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 diff --git a/engine/lib_matcher_c.ml b/engine/lib_matcher_c.ml dissimilarity index 100% index 87b0a72..e69de29 100644 --- a/engine/lib_matcher_c.ml +++ b/engine/lib_matcher_c.ml @@ -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 . -* -* 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"; - ) - - - - diff --git a/engine/lib_matcher_c.mli b/engine/lib_matcher_c.mli dissimilarity index 100% index 7b42611..e69de29 100644 --- a/engine/lib_matcher_c.mli +++ b/engine/lib_matcher_c.mli @@ -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 diff --git a/engine/transformation_c.ml b/engine/transformation_c.ml index 8dc3f98..44e6dfd 100644 --- a/engine/transformation_c.ml +++ b/engine/transformation_c.ml @@ -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 --- 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 diff --git a/extra/.depend b/extra/.depend dissimilarity index 100% index c3ba0c6..8c6112e 100644 --- a/extra/.depend +++ b/extra/.depend @@ -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 diff --git a/extra/Makefile b/extra/Makefile index 2dd7e18..dc26e71 100644 --- a/extra/Makefile +++ b/extra/Makefile @@ -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) diff --git a/globals/Makefile b/globals/Makefile index a235bbb..d566808 100644 --- a/globals/Makefile +++ b/globals/Makefile @@ -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) diff --git a/globals/config.ml b/globals/config.ml index 48a98ce..cf9f4a3 100644 --- a/globals/config.ml +++ b/globals/config.ml @@ -1,4 +1,4 @@ -let version = "0.1.5" +let version = "0.1.6" let path = try (Sys.getenv "COCCINELLE_HOME") diff --git a/globals/flag.ml b/globals/flag.ml index c177bca..ffc257b 100644 --- a/globals/flag.ml +++ b/globals/flag.ml @@ -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 --- 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 *) diff --git a/menhirlib/Makefile b/menhirlib/Makefile index 347c951..f98c9e4 100644 --- a/menhirlib/Makefile +++ b/menhirlib/Makefile @@ -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) diff --git a/parsing_c/.depend b/parsing_c/.depend dissimilarity index 83% index b88c717..7af0138 100644 --- a/parsing_c/.depend +++ b/parsing_c/.depend @@ -1,80 +1,132 @@ -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 diff --git a/parsing_c/Makefile b/parsing_c/Makefile index 6a38ace..68b0c5a 100644 --- a/parsing_c/Makefile +++ b/parsing_c/Makefile @@ -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) diff --git a/parsing_c/ast_c.ml b/parsing_c/ast_c.ml index 0c4e864..4f4c187 100644 --- a/parsing_c/ast_c.ml +++ b/parsing_c/ast_c.ml @@ -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 and last of #include @@ -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 diff --git a/parsing_c/ast_to_flow.ml b/parsing_c/ast_to_flow.ml index 5f6e930..7ec3cf2 100644 --- a/parsing_c/ast_to_flow.ml +++ b/parsing_c/ast_to_flow.ml @@ -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 index 0000000..d4fb2a3 --- /dev/null +++ b/parsing_c/comment_annotater_c.ml @@ -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 index 0000000..d890cb6 --- /dev/null +++ b/parsing_c/comment_annotater_c.mli @@ -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 diff --git a/parsing_c/compare_c.ml b/parsing_c/compare_c.ml index 4070927..0a5196f 100644 --- a/parsing_c/compare_c.ml +++ b/parsing_c/compare_c.ml @@ -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 diff --git a/parsing_c/control_flow_c.ml b/parsing_c/control_flow_c.ml index 2b23662..77843ae 100644 --- a/parsing_c/control_flow_c.ml +++ b/parsing_c/control_flow_c.ml @@ -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 diff --git a/parsing_c/cpp_ast_c.ml b/parsing_c/cpp_ast_c.ml index 3d711d6..ec8d3c7 100644 --- a/parsing_c/cpp_ast_c.ml +++ b/parsing_c/cpp_ast_c.ml @@ -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 ) diff --git a/parsing_c/flag_parsing_c.ml b/parsing_c/flag_parsing_c.ml index 2a01793..2ee65f7 100644 --- a/parsing_c/flag_parsing_c.ml +++ b/parsing_c/flag_parsing_c.ml @@ -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 diff --git a/parsing_c/lexer_c.mll b/parsing_c/lexer_c.mll index 531b582..7c4e312 100644 --- a/parsing_c/lexer_c.mll +++ b/parsing_c/lexer_c.mll @@ -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))} diff --git a/parsing_c/lexer_parser.ml b/parsing_c/lexer_parser.ml index 7465bab..c54b786 100644 --- a/parsing_c/lexer_parser.ml +++ b/parsing_c/lexer_parser.ml @@ -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) diff --git a/parsing_c/lib_parsing_c.ml b/parsing_c/lib_parsing_c.ml index 9e81a6d..1d328a8 100644 --- a/parsing_c/lib_parsing_c.ml +++ b/parsing_c/lib_parsing_c.ml @@ -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 + ) diff --git a/parsing_c/parse_c.ml b/parsing_c/parse_c.ml index a290261..e27a9db 100644 --- a/parsing_c/parse_c.ml +++ b/parsing_c/parse_c.ml @@ -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 = diff --git a/parsing_c/parser_c.mly b/parsing_c/parser_c.mly index b586513..f6f91d5 100644 --- a/parsing_c/parser_c.mly +++ b/parsing_c/parser_c.mly @@ -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 TCommentSkipTagStart TCommentSkipTagEnd + + /*(* appear after parsing_hack *)*/ %token TCParEOL %token TAction +/*(* TCommentMisc still useful ? obsolete ? *)*/ %token 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]) } diff --git a/parsing_c/parsing_hacks.ml b/parsing_c/parsing_hacks.ml index 4c2c111..4468f7a 100644 --- a/parsing_c/parsing_hacks.ml +++ b/parsing_c/parsing_hacks.ml @@ -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 diff --git a/parsing_c/parsing_stat.ml b/parsing_c/parsing_stat.ml index e365cff..c6270bc 100644 --- a/parsing_c/parsing_stat.ml +++ b/parsing_c/parsing_stat.ml @@ -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: diff --git a/parsing_c/pretty_print_c.ml b/parsing_c/pretty_print_c.ml index f6cd8d6..83eaef3 100644 --- a/parsing_c/pretty_print_c.ml +++ b/parsing_c/pretty_print_c.ml @@ -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() diff --git a/parsing_c/test_parsing_c.ml b/parsing_c/test_parsing_c.ml index c788da0..10ea3ab 100644 --- a/parsing_c/test_parsing_c.ml +++ b/parsing_c/test_parsing_c.ml @@ -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", " ", Common.mk_action_2_arg test_compare_c (* result is in unix code *); + "-comment_annotater_c", " ", + Common.mk_action_1_arg test_comment_annotater; "-compare_c_hardcoded", " ", Common.mk_action_0_arg test_compare_c_hardcoded; diff --git a/parsing_c/test_parsing_c.mli b/parsing_c/test_parsing_c.mli index 80f45f7..9ea5b37 100644 --- a/parsing_c/test_parsing_c.mli +++ b/parsing_c/test_parsing_c.mli @@ -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 index 0000000..d896141 --- /dev/null +++ b/parsing_c/token_c.ml @@ -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 *) +(*****************************************************************************) diff --git a/parsing_c/token_helpers.ml b/parsing_c/token_helpers.ml index 5d70ad8..65cc96a 100644 --- a/parsing_c/token_helpers.ml +++ b/parsing_c/token_helpers.ml @@ -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 + diff --git a/parsing_c/token_helpers.mli b/parsing_c/token_helpers.mli index b836ee3..bcb1fcd 100644 --- a/parsing_c/token_helpers.mli +++ b/parsing_c/token_helpers.mli @@ -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 diff --git a/parsing_c/type_annoter_c.ml b/parsing_c/type_annoter_c.ml index 3295644..e08b2c7 100644 --- a/parsing_c/type_annoter_c.ml +++ b/parsing_c/type_annoter_c.ml @@ -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 |_ -> "")); Type_c.noTypeHere - | MultiFound -> + | Multi_found -> pr2 "TAC:MultiFound"; Type_c.noTypeHere ) diff --git a/parsing_c/type_annoter_c.mli b/parsing_c/type_annoter_c.mli index 02f401e..fe61cd8 100644 --- a/parsing_c/type_annoter_c.mli +++ b/parsing_c/type_annoter_c.mli @@ -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 : diff --git a/parsing_c/type_c.ml b/parsing_c/type_c.ml index cc53391..7fc2edc 100644 --- a/parsing_c/type_c.ml +++ b/parsing_c/type_c.ml @@ -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 + + diff --git a/parsing_c/type_c.mli b/parsing_c/type_c.mli index af3b6f0..dfa6345 100644 --- a/parsing_c/type_c.mli +++ b/parsing_c/type_c.mli @@ -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 diff --git a/parsing_c/unparse_c.ml b/parsing_c/unparse_c.ml index 045c098..2a4faf6 100644 --- a/parsing_c/unparse_c.ml +++ b/parsing_c/unparse_c.ml @@ -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 diff --git a/parsing_c/unparse_cocci.ml b/parsing_c/unparse_cocci.ml index aaa631c..dccb76a 100644 --- a/parsing_c/unparse_cocci.ml +++ b/parsing_c/unparse_cocci.ml @@ -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 *) diff --git a/parsing_c/unparse_hrule.ml b/parsing_c/unparse_hrule.ml index 847fe45..060d67c 100644 --- a/parsing_c/unparse_hrule.ml +++ b/parsing_c/unparse_hrule.ml @@ -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 diff --git a/parsing_c/visitor_c.ml b/parsing_c/visitor_c.ml index 5d87d0c..258699d 100644 --- a/parsing_c/visitor_c.ml +++ b/parsing_c/visitor_c.ml @@ -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 diff --git a/parsing_c/visitor_c.mli b/parsing_c/visitor_c.mli index 1a31f84..a931e58 100644 --- a/parsing_c/visitor_c.mli +++ b/parsing_c/visitor_c.mli @@ -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 index 0000000..f710d1e --- /dev/null +++ b/parsing_cocci/.#Makefile.1.50 @@ -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 . +# +# 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 index 0000000..4028a45 --- /dev/null +++ b/parsing_cocci/.#Makefile.1.51 @@ -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 . +# +# 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 index 0000000..56213c8 --- /dev/null +++ b/parsing_cocci/.#arity.ml.1.88 @@ -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 . +* +* 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 index 0000000..fe3ba6a --- /dev/null +++ b/parsing_cocci/.#ast0_cocci.ml.1.115 @@ -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 . +* +* 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 index 0000000..274f7f9 --- /dev/null +++ b/parsing_cocci/.#ast0toast.ml.1.140 @@ -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 . +* +* 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 index 0000000..ee0a43a --- /dev/null +++ b/parsing_cocci/.#ast_cocci.ml.1.151 @@ -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 . +* +* 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 index 0000000..ff7d88e --- /dev/null +++ b/parsing_cocci/.#check_meta.ml.1.88 @@ -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 . +* +* 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 index 0000000..d93ed9e --- /dev/null +++ b/parsing_cocci/.#compute_lines.ml.1.92 @@ -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 . +* +* 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 index 0000000..67b3317 --- /dev/null +++ b/parsing_cocci/.#context_neg.ml.1.104 @@ -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 . +* +* 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 index 0000000..f6fe909 --- /dev/null +++ b/parsing_cocci/.#data.ml.1.38 @@ -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 . +* +* 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 index 0000000..a28bb8d --- /dev/null +++ b/parsing_cocci/.#index.ml.1.60 @@ -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 . +* +* 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 index 0000000..706f922 --- /dev/null +++ b/parsing_cocci/.#insert_plus.ml.1.74 @@ -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 . +* +* 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 index 0000000..2a3bb2e --- /dev/null +++ b/parsing_cocci/.#iso_pattern.ml.1.152 @@ -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 . +* +* 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 index 0000000..f02c923 --- /dev/null +++ b/parsing_cocci/.#lexer_cocci.mll.1.86 @@ -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 . +* +* 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) } +(* + | "" { 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 index 0000000..91df7e7 --- /dev/null +++ b/parsing_cocci/.#parse_aux.ml.1.27 @@ -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 . +* +* 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 index 0000000..91c0768 --- /dev/null +++ b/parsing_cocci/.#parse_cocci.ml.1.180 @@ -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 . +* +* 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.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 index 0000000..09fb8ad --- /dev/null +++ b/parsing_cocci/.#parser_cocci_menhir.mly.1.168 @@ -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 . +* +* 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 TRuleName + +%token Tchar Tshort Tint Tdouble Tfloat Tlong +%token Tvoid Tstruct Tunion Tenum +%token Tunsigned Tsigned + +%token Tstatic Tauto Tregister Textern Tinline Ttypedef +%token Tconst Tvolatile +%token Tattr + +%token TIf TElse TWhile TFor TDo TSwitch TCase TDefault TReturn +%token TBreak TContinue TGoto TSizeof TFunDecl +%token TIdent TTypeId TDeclarerId TIteratorId + +%token TMetaId TMetaFunc TMetaLocalFunc +%token TMetaIterator TMetaDeclarer +%token TMetaErr +%token TMetaParam TMetaStm TMetaStmList TMetaType +%token TMetaInit +%token TMetaParamList TMetaExpList +%token TMetaExp TMetaIdExp TMetaLocalIdExp TMetaConst +%token TMetaPos + +%token TArob TArobArob TPArob +%token TScriptData + +%token TEllipsis TOEllipsis TCEllipsis TPOEllipsis TPCEllipsis +%token TWhen TWhenTrue TWhenFalse TAny TStrict TLineEnd + +%token TWhy TDotDot TBang TOPar TOPar0 +%token TMid0 TCPar TCPar0 + +%token TPragma TPathIsoFile +%token TIncludeL TIncludeNL +%token TDefine +%token TDefineParam +%token TMinusFile TPlusFile + +%token TInc TDec + +%token TString TChar TFloat TInt + +%token TOrLog +%token TAndLog +%token TOr +%token TXor +%token TAnd +%token TEqEq TNotEq +%token TLogOp /* TInf TSup TInfEq TSupEq */ +%token TShOp /* TShl TShr */ +%token TDmOp /* TDiv TMod */ +%token TPlus TMinus +%token TMul TTilde + +%token TOBrace TCBrace TOInit +%token TOCro TCCro + +%token TPtrOp + +%token TMPtVirg +%token TEq TDot TComma TPtVirg +%token TAssign + +%token TIso TRightIso TIsoExpression TIsoStatement TIsoDeclaration TIsoType +%token TIsoTopLevel TIsoArgExpression TIsoTestExpression + +%token TInvalid + +/* operator precedence */ +%nonassoc TIf +%nonassoc TElse + +%left TOrLog +%left TAndLog +%left TOr +%left TXor +%left TAnd +%left TEqEq TNotEq +%left TLogOp /* TInf TSup TInfEq TSupEq */ +%left TShOp /* TShl TShr */ +%left TPlus TMinus +%left TMul TDmOp /* TDiv TMod */ + +%start reinit +%type reinit + +%start minus_main +%type minus_main + +%start minus_exp_main +%type minus_exp_main + +%start plus_main +%type plus_main + +%start plus_exp_main +%type plus_exp_main + +%start include_main +%type <(string,string) Common.either list> include_main + +%start iso_rule_name +%type +iso_rule_name + +%start rule_name +%type +rule_name + +%start meta_main +%type <(Ast_cocci.metavar,Ast_cocci.metavar) Common.either list> meta_main + +%start script_meta_main + +%start iso_main +%type iso_main + +%start iso_meta_main +%type <(Ast_cocci.metavar,Ast_cocci.metavar) Common.either list> iso_meta_main + +%start never_used +%type never_used + +%% + +reinit: { } +minus_main: minus_body EOF { $1 } | m=minus_body TArobArob { m } +| m=minus_body TArob { m } +plus_main: plus_body EOF { $1 } | p=plus_body TArobArob { p } +| p=plus_body TArob { p } +minus_exp_main: minus_exp_body EOF { $1 } | m=minus_exp_body TArobArob { m } +| m=minus_exp_body TArob { m } +plus_exp_main: plus_exp_body EOF { $1 } | p=plus_exp_body TArobArob { p } +| p=plus_exp_body TArob { p } +meta_main: m=metadec { m (!Ast0.rule_name) } +iso_meta_main: m=metadec { m "" } + +/***************************************************************************** +* +* +*****************************************************************************/ + +pure: + TPure { Ast0.Pure } +| TContext { Ast0.Context } +| TPure TContext { Ast0.PureContext } +| TContext TPure { Ast0.PureContext } +| /* empty */ { Ast0.Impure } + +iso_rule_name: + nm=pure_ident TArob { P.make_iso_rule_name_result (P.id2name nm) } + +rule_name: + nm=ioption(pure_ident) extends d=depends i=loption(choose_iso) + a=loption(disable) e=exists ee=is_expression TArob + { P.make_cocci_rule_name_result nm d i a e ee } + | 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 index 0000000..71ed6ef --- /dev/null +++ b/parsing_cocci/.#parser_cocci_menhir.mly.1.169 @@ -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 . +* +* 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 TRuleName + +%token Tchar Tshort Tint Tdouble Tfloat Tlong +%token Tvoid Tstruct Tunion Tenum +%token Tunsigned Tsigned + +%token Tstatic Tauto Tregister Textern Tinline Ttypedef +%token Tconst Tvolatile +%token Tattr + +%token TIf TElse TWhile TFor TDo TSwitch TCase TDefault TReturn +%token TBreak TContinue TGoto TSizeof TFunDecl +%token TIdent TTypeId TDeclarerId TIteratorId + +%token TMetaId TMetaFunc TMetaLocalFunc +%token TMetaIterator TMetaDeclarer +%token TMetaErr +%token TMetaParam TMetaStm TMetaStmList TMetaType +%token TMetaInit +%token TMetaParamList TMetaExpList +%token TMetaExp TMetaIdExp TMetaLocalIdExp TMetaConst +%token TMetaPos + +%token TArob TArobArob TPArob +%token TScriptData + +%token TEllipsis TOEllipsis TCEllipsis TPOEllipsis TPCEllipsis +%token TWhen TWhenTrue TWhenFalse TAny TStrict TLineEnd + +%token TWhy TDotDot TBang TOPar TOPar0 +%token TMid0 TCPar TCPar0 + +%token TPragma TPathIsoFile +%token TIncludeL TIncludeNL +%token TDefine +%token TDefineParam +%token TMinusFile TPlusFile + +%token TInc TDec + +%token TString TChar TFloat TInt + +%token TOrLog +%token TAndLog +%token TOr +%token TXor +%token TAnd +%token TEqEq TNotEq +%token TLogOp /* TInf TSup TInfEq TSupEq */ +%token TShOp /* TShl TShr */ +%token TDmOp /* TDiv TMod */ +%token TPlus TMinus +%token TMul TTilde + +%token TOBrace TCBrace TOInit +%token TOCro TCCro + +%token TPtrOp + +%token TMPtVirg +%token TEq TDot TComma TPtVirg +%token TAssign + +%token TIso TRightIso TIsoExpression TIsoStatement TIsoDeclaration TIsoType +%token TIsoTopLevel TIsoArgExpression TIsoTestExpression + +%token TInvalid + +/* operator precedence */ +%nonassoc TIf +%nonassoc TElse + +%left TOrLog +%left TAndLog +%left TOr +%left TXor +%left TAnd +%left TEqEq TNotEq +%left TLogOp /* TInf TSup TInfEq TSupEq */ +%left TShOp /* TShl TShr */ +%left TPlus TMinus +%left TMul TDmOp /* TDiv TMod */ + +%start reinit +%type reinit + +%start minus_main +%type minus_main + +%start minus_exp_main +%type minus_exp_main + +%start plus_main +%type plus_main + +%start plus_exp_main +%type plus_exp_main + +%start include_main +%type <(string,string) Common.either list> include_main + +%start iso_rule_name +%type +iso_rule_name + +%start rule_name +%type +rule_name + +%start meta_main +%type <(Ast_cocci.metavar,Ast_cocci.metavar) Common.either list> meta_main + +%start script_meta_main + +%start iso_main +%type iso_main + +%start iso_meta_main +%type <(Ast_cocci.metavar,Ast_cocci.metavar) Common.either list> iso_meta_main + +%start never_used +%type never_used + +%% + +reinit: { } +minus_main: minus_body EOF { $1 } | m=minus_body TArobArob { m } +| m=minus_body TArob { m } +plus_main: plus_body EOF { $1 } | p=plus_body TArobArob { p } +| p=plus_body TArob { p } +minus_exp_main: minus_exp_body EOF { $1 } | m=minus_exp_body TArobArob { m } +| m=minus_exp_body TArob { m } +plus_exp_main: plus_exp_body EOF { $1 } | p=plus_exp_body TArobArob { p } +| p=plus_exp_body TArob { p } +meta_main: m=metadec { m (!Ast0.rule_name) } +iso_meta_main: m=metadec { m "" } + +/***************************************************************************** +* +* +*****************************************************************************/ + +pure: + TPure { Ast0.Pure } +| TContext { Ast0.Context } +| TPure TContext { Ast0.PureContext } +| TContext TPure { Ast0.PureContext } +| /* empty */ { Ast0.Impure } + +iso_rule_name: + nm=pure_ident TArob { P.make_iso_rule_name_result (P.id2name nm) } + +rule_name: + nm=ioption(pure_ident) extends d=depends i=loption(choose_iso) + a=loption(disable) e=exists ee=is_expression TArob + { P.make_cocci_rule_name_result nm d i a e ee } + | 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 index 0000000..9675e49 --- /dev/null +++ b/parsing_cocci/.#pretty_print_cocci.ml.1.135 @@ -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 . +* +* 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 index 0000000..24448ad --- /dev/null +++ b/parsing_cocci/.#type_infer.ml.1.60 @@ -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 . +* +* 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 index 0000000..b295646 --- /dev/null +++ b/parsing_cocci/.#unparse_ast0.ml.1.118 @@ -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 . +* +* 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 index 0000000..f0ca9c8 --- /dev/null +++ b/parsing_cocci/.#visitor_ast.ml.1.97 @@ -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 . +* +* 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 + diff --git a/parsing_cocci/.depend b/parsing_cocci/.depend index f39c46e..aa6bc06 100644 --- a/parsing_cocci/.depend +++ b/parsing_cocci/.depend @@ -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 diff --git a/parsing_cocci/Makefile b/parsing_cocci/Makefile index f710d1e..b0044d9 100644 --- a/parsing_cocci/Makefile +++ b/parsing_cocci/Makefile @@ -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 index 0000000..d4a9f8c --- /dev/null +++ b/parsing_cocci/adjust_pragmas.ml @@ -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 index 0000000..b87cd1a --- /dev/null +++ b/parsing_cocci/adjust_pragmas.mli @@ -0,0 +1 @@ +val process : Ast0_cocci.rule -> Ast0_cocci.rule diff --git a/parsing_cocci/arity.ml b/parsing_cocci/arity.ml index 56213c8..65863ec 100644 --- a/parsing_cocci/arity.ml +++ b/parsing_cocci/arity.ml @@ -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 ... *) diff --git a/parsing_cocci/ast0_cocci.ml b/parsing_cocci/ast0_cocci.ml index fe3ba6a..462a24d 100644 --- a/parsing_cocci/ast0_cocci.ml +++ b/parsing_cocci/ast0_cocci.ml @@ -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) diff --git a/parsing_cocci/ast0_cocci.mli b/parsing_cocci/ast0_cocci.mli index 2eca940..bd78144 100644 --- a/parsing_cocci/ast0_cocci.mli +++ b/parsing_cocci/ast0_cocci.mli @@ -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 = diff --git a/parsing_cocci/ast0toast.ml b/parsing_cocci/ast0toast.ml index 274f7f9..33c0349 100644 --- a/parsing_cocci/ast0toast.ml +++ b/parsing_cocci/ast0toast.ml @@ -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 = [] diff --git a/parsing_cocci/ast_cocci.ml b/parsing_cocci/ast_cocci.ml index ee0a43a..ff69cc6 100644 --- a/parsing_cocci/ast_cocci.ml +++ b/parsing_cocci/ast_cocci.ml @@ -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 = diff --git a/parsing_cocci/ast_cocci.mli b/parsing_cocci/ast_cocci.mli index a207334..cb06c36 100644 --- a/parsing_cocci/ast_cocci.mli +++ b/parsing_cocci/ast_cocci.mli @@ -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 : diff --git a/parsing_cocci/check_meta.ml b/parsing_cocci/check_meta.ml index ff7d88e..daa2a2e 100644 --- a/parsing_cocci/check_meta.ml +++ b/parsing_cocci/check_meta.ml @@ -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 diff --git a/parsing_cocci/compute_lines.ml b/parsing_cocci/compute_lines.ml index d93ed9e..b862e75 100644 --- a/parsing_cocci/compute_lines.ml +++ b/parsing_cocci/compute_lines.ml @@ -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} diff --git a/parsing_cocci/context_neg.ml b/parsing_cocci/context_neg.ml index 67b3317..9341b33 100644 --- a/parsing_cocci/context_neg.ml +++ b/parsing_cocci/context_neg.ml @@ -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 diff --git a/parsing_cocci/data.ml b/parsing_cocci/data.ml index f6fe909..1a208c9 100644 --- a/parsing_cocci/data.ml +++ b/parsing_cocci/data.ml @@ -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 *) (* ---------------------------------------------------------------------- *) diff --git a/parsing_cocci/data.mli b/parsing_cocci/data.mli index 65c15d9..6dcb387 100644 --- a/parsing_cocci/data.mli +++ b/parsing_cocci/data.mli @@ -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 *) (* ---------------------------------------------------------------------- *) diff --git a/parsing_cocci/index.ml b/parsing_cocci/index.ml index a28bb8d..47bfe8e 100644 --- a/parsing_cocci/index.ml +++ b/parsing_cocci/index.ml @@ -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]) diff --git a/parsing_cocci/insert_plus.ml b/parsing_cocci/insert_plus.ml index 706f922..ff3c59a 100644 --- a/parsing_cocci/insert_plus.ml +++ b/parsing_cocci/insert_plus.ml @@ -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 (* --------------------------------------------------------------------- *) diff --git a/parsing_cocci/iso_pattern.ml b/parsing_cocci/iso_pattern.ml index 2a3bb2e..f4036ee 100644 --- a/parsing_cocci/iso_pattern.ml +++ b/parsing_cocci/iso_pattern.ml @@ -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 diff --git a/parsing_cocci/lexer_cocci.mll b/parsing_cocci/lexer_cocci.mll index f02c923..a9a31fb 100644 --- a/parsing_cocci/lexer_cocci.mll +++ b/parsing_cocci/lexer_cocci.mll @@ -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 + } + diff --git a/parsing_cocci/parse_aux.ml b/parsing_cocci/parse_aux.ml index 91df7e7..d2900ca 100644 --- a/parsing_cocci/parse_aux.ml +++ b/parsing_cocci/parse_aux.ml @@ -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) = diff --git a/parsing_cocci/parse_cocci.ml b/parsing_cocci/parse_cocci.ml index 91c0768..04c0afd 100644 --- a/parsing_cocci/parse_cocci.ml +++ b/parsing_cocci/parse_cocci.ml @@ -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; diff --git a/parsing_cocci/parser_cocci_menhir.ml b/parsing_cocci/parser_cocci_menhir.ml index 803d8b3..eed5248 100644 --- a/parsing_cocci/parser_cocci_menhir.ml +++ b/parsing_cocci/parser_cocci_menhir.ml @@ -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\144\000\000@\182\000\000AdE\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\000\000\008\"N\012\007t\008T\000\000\003\248\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\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\144\000\000@\182\000\000AdE\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\000\000\008\"N\012\007t\008T\000\000\003\248\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\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" )) diff --git a/parsing_cocci/parser_cocci_menhir.mli b/parsing_cocci/parser_cocci_menhir.mli index 98f6859..c93d0eb 100644 --- a/parsing_cocci/parser_cocci_menhir.mli +++ b/parsing_cocci/parser_cocci_menhir.mli @@ -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) diff --git a/parsing_cocci/parser_cocci_menhir.mly b/parsing_cocci/parser_cocci_menhir.mly index 09fb8ad..a72182a 100644 --- a/parsing_cocci/parser_cocci_menhir.mly +++ b/parsing_cocci/parser_cocci_menhir.mly @@ -56,7 +56,7 @@ module P = Parse_aux %token TIf TElse TWhile TFor TDo TSwitch TCase TDefault TReturn %token TBreak TContinue TGoto TSizeof TFunDecl -%token TIdent TTypeId TDeclarerId TIteratorId +%token TIdent TTypeId TDeclarerId TIteratorId TPragma %token TMetaId TMetaFunc TMetaLocalFunc %token TMetaIterator TMetaDeclarer @@ -76,7 +76,7 @@ module P = Parse_aux %token TWhy TDotDot TBang TOPar TOPar0 %token TMid0 TCPar TCPar0 -%token TPragma TPathIsoFile +%token TPathIsoFile %token TIncludeL TIncludeNL %token TDefine %token 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 diff --git a/parsing_cocci/pretty_print_cocci.ml b/parsing_cocci/pretty_print_cocci.ml index 9675e49..9476554 100644 --- a/parsing_cocci/pretty_print_cocci.ml +++ b/parsing_cocci/pretty_print_cocci.ml @@ -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 diff --git a/parsing_cocci/type_infer.ml b/parsing_cocci/type_infer.ml index 24448ad..ea30ec3 100644 --- a/parsing_cocci/type_infer.ml +++ b/parsing_cocci/type_infer.ml @@ -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 diff --git a/parsing_cocci/unparse_ast0.ml b/parsing_cocci/unparse_ast0.ml index b295646..0772e54 100644 --- a/parsing_cocci/unparse_ast0.ml +++ b/parsing_cocci/unparse_ast0.ml @@ -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) diff --git a/parsing_cocci/visitor_ast.ml b/parsing_cocci/visitor_ast.ml index f0ca9c8..6836dda 100644 --- a/parsing_cocci/visitor_ast.ml +++ b/parsing_cocci/visitor_ast.ml @@ -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 index 0000000..2254a1e --- /dev/null +++ b/popl/.#Makefile.1.5 @@ -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 . +# +# 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 diff --git a/popl/Makefile b/popl/Makefile index 2254a1e..e7968f3 100644 --- a/popl/Makefile +++ b/popl/Makefile @@ -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 index 0000000..83c32f1 --- /dev/null +++ b/popl09/.#Makefile.1.5 @@ -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 . +# +# 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 index 0000000..f773e1a --- /dev/null +++ b/popl09/.#Makefile.1.6 @@ -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 . +# +# 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/.depend b/popl09/.depend dissimilarity index 89% index c0c557a..687e676 100644 --- a/popl09/.depend +++ b/popl09/.depend @@ -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 diff --git a/popl09/Makefile b/popl09/Makefile index 83c32f1..21bd4ae 100644 --- a/popl09/Makefile +++ b/popl09/Makefile @@ -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 diff --git a/pycaml/pycaml.ml b/pycaml/pycaml.ml index 1db1ae1..309aecc 100644 --- a/pycaml/pycaml.ml +++ b/pycaml/pycaml.ml @@ -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 *) diff --git a/pycaml/pycaml_ml.c b/pycaml/pycaml_ml.c index 30217f9..87342f5 100644 --- a/pycaml/pycaml_ml.c +++ b/pycaml/pycaml_ml.c @@ -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 index 0000000..d2a67ec --- /dev/null +++ b/python/.#Makefile.1.5 @@ -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 . +# +# 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 index 0000000..e4ded17 --- /dev/null +++ b/python/.#no_pycocci_aux.ml.1.2 @@ -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 . +* +* 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: <>" +| Ast_c.MetaExprListVal expr_list -> "TODO: <>" +| Ast_c.MetaTypeVal typ -> call_pretty Pretty_print_c.pp_type_gen typ +| Ast_c.MetaStmtVal statement -> "TODO: stmt" +| Ast_c.MetaParamVal params -> "TODO: <>" +| Ast_c.MetaParamListVal params -> "TODO: <>" +| Ast_c.MetaListlenVal n -> string_of_int n +| Ast_c.MetaPosVal (pos1, pos2) -> + (* Common.sprintf ("pos(%d,%d)") pos1 pos2 *) + "TODO: <>" +| Ast_c.MetaPosValList positions -> "TODO: <>" + diff --git a/python/.#yes_pycocci.ml.1.2 b/python/.#yes_pycocci.ml.1.2 new file mode 100644 index 0000000..4f55845 --- /dev/null +++ b/python/.#yes_pycocci.ml.1.2 @@ -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 . +* +* 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 index 0000000..8c5af0b --- /dev/null +++ b/python/.#yes_pycocci_aux.ml.1.2 @@ -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 . +* +* 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: <>" +| Ast_c.MetaExprListVal expr_list -> "TODO: <>" +| Ast_c.MetaTypeVal typ -> call_pretty Pretty_print_c.pp_type_gen typ +| Ast_c.MetaInitVal ini -> "TODO: <>" +| Ast_c.MetaStmtVal statement -> "TODO: stmt" +| Ast_c.MetaParamVal params -> "TODO: <>" +| Ast_c.MetaParamListVal params -> "TODO: <>" +| 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: <>" + diff --git a/python/.#yes_pycocci_aux.ml.1.3 b/python/.#yes_pycocci_aux.ml.1.3 new file mode 100644 index 0000000..afe3bf5 --- /dev/null +++ b/python/.#yes_pycocci_aux.ml.1.3 @@ -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 . +* +* 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: <>" +| Ast_c.MetaExprListVal expr_list -> "TODO: <>" +| Ast_c.MetaTypeVal typ -> call_pretty Pretty_print_c.pp_type_gen typ +| Ast_c.MetaInitVal ini -> "TODO: <>" +| Ast_c.MetaStmtVal statement -> "TODO: stmt" +| Ast_c.MetaParamVal params -> "TODO: <>" +| Ast_c.MetaParamListVal params -> "TODO: <>" +| 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: <>" + diff --git a/python/.depend b/python/.depend dissimilarity index 100% index f0cf0ee..f6f1ff2 100644 --- a/python/.depend +++ b/python/.depend @@ -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 diff --git a/python/Makefile b/python/Makefile index d2a67ec..9f16961 100644 --- a/python/Makefile +++ b/python/Makefile @@ -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) ############################################################################## diff --git a/python/coccilib/output.py b/python/coccilib/output.py deleted file mode 100644 index af6f713..0000000 --- a/python/coccilib/output.py +++ /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() diff --git a/python/coccilib/output.py b/python/coccilib/output.py new file mode 120000 index 0000000..9b9e839 --- /dev/null +++ b/python/coccilib/output.py @@ -0,0 +1 @@ +output_base.py \ No newline at end of file diff --git a/python/coccilib/output.py b/python/coccilib/output_base.py similarity index 96% copy from python/coccilib/output.py copy to python/coccilib/output_base.py index af6f713..65f0473 100644 --- a/python/coccilib/output.py +++ b/python/coccilib/output_base.py @@ -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 index 0000000..1317064 --- /dev/null +++ b/python/coccilib/output_trac.py @@ -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() diff --git a/python/no_pycocci_aux.ml b/python/no_pycocci_aux.ml index e4ded17..b8efc7c 100644 --- a/python/no_pycocci_aux.ml +++ b/python/no_pycocci_aux.ml @@ -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: <>" | Ast_c.MetaPosValList positions -> "TODO: <>" +| Ast_c.MetaInitVal _ -> "TODO: <>" diff --git a/python/yes_pycocci.ml b/python/yes_pycocci.ml index 4f55845..bb877d5 100644 --- a/python/yes_pycocci.ml +++ b/python/yes_pycocci.ml @@ -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 () diff --git a/python/yes_pycocci_aux.ml b/python/yes_pycocci_aux.ml index 8c5af0b..7d4a241 100644 --- a/python/yes_pycocci_aux.ml +++ b/python/yes_pycocci_aux.ml @@ -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: <>" +| Ast_c.MetaExprVal expr -> exprrep expr | Ast_c.MetaExprListVal expr_list -> "TODO: <>" | Ast_c.MetaTypeVal typ -> call_pretty Pretty_print_c.pp_type_gen typ -| Ast_c.MetaInitVal ini -> "TODO: <>" -| Ast_c.MetaStmtVal statement -> "TODO: stmt" -| Ast_c.MetaParamVal params -> "TODO: <>" +| 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: <>" | 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 index 0000000..18461e5 --- /dev/null +++ b/scripts/spatch.sh @@ -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 $* + diff --git a/testing.ml b/testing.ml index c1087eb..31abbe3 100644 --- a/testing.ml +++ b/testing.ml @@ -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 index 0000000..b2313ab --- /dev/null +++ b/tests/addif.c @@ -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 index 0000000..c9669fc --- /dev/null +++ b/tests/addif.cocci @@ -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 index 0000000..cfb14d3 --- /dev/null +++ b/tests/addif.res @@ -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 index 0000000..b2313ab --- /dev/null +++ b/tests/addif1.c @@ -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 index 0000000..30d8d67 --- /dev/null +++ b/tests/addif1.cocci @@ -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 index 0000000..0edaaa0 --- /dev/null +++ b/tests/addif1.res @@ -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 index 0000000..b2313ab --- /dev/null +++ b/tests/addif2.c @@ -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 index 0000000..4a516a5 --- /dev/null +++ b/tests/addif2.cocci @@ -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 index 0000000..91f011b --- /dev/null +++ b/tests/addif2.res @@ -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 index 0000000..ab8c5ee --- /dev/null +++ b/tests/ifdef6a.c @@ -0,0 +1,13 @@ +#include +#include +#include +#include + + +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 index 0000000..c82781e --- /dev/null +++ b/tests/ifdef6a.cocci @@ -0,0 +1,7 @@ +@ Exemple6@ @@ + ++ #ifdef CONFIG_NKERNEL ++ #define foo(x) f(x) ++ #endif + + #include diff --git a/tests/ifdef6a.res b/tests/ifdef6a.res new file mode 100644 index 0000000..c171be1 --- /dev/null +++ b/tests/ifdef6a.res @@ -0,0 +1,16 @@ +#include +#ifdef CONFIG_NKERNEL +#define foo(x) f(x) +#endif +#include +#include +#include + + +void init_IRQ(void) +{ + for (irq = 0; irq < IRQS; irq++) { + *desc = irq_desc; + uselessCall(); + } +} diff --git a/tools/Makefile b/tools/Makefile index 7b5eb80..3ef9dfc 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -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 diff --git a/tools/distributed/Makefile b/tools/distributed/Makefile index 5614491..9b5de44 100644 --- a/tools/distributed/Makefile +++ b/tools/distributed/Makefile @@ -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 diff --git a/tools/distributed/cleanup.ml b/tools/distributed/cleanup.ml index 4aa4b39..d18ab94 100644 --- a/tools/distributed/cleanup.ml +++ b/tools/distributed/cleanup.ml @@ -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 index 7f1e534..0000000 --- a/tools/distributed/cleanup_script +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/tcsh - -#cat ${1:r}.*.out > ${1:r} -#/bin/rm ${1:r}.*.out - -~/coccinelle/tools/distributed/cleanup $1 - diff --git a/tools/distributed/spatch_linux.c b/tools/distributed/spatch_linux.c index c38f9bf..ee5dabd 100644 --- a/tools/distributed/spatch_linux.c +++ b/tools/distributed/spatch_linux.c @@ -1,60 +1,16 @@ #include #include #include -#include -#include -#include -#include -#include -#include #include #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]); } -- 2.20.1