From 65038c617fe3e5d7a284059fbfa78dddfbb9b9c4 Mon Sep 17 00:00:00 2001 From: Coccinelle Date: Mon, 6 Jun 2011 11:36:19 +0200 Subject: [PATCH] Coccinelle release 1.0.0-rc3 ** Language: - Addition of initializer list metavariables. Thanks to Michael Stefaniuc for noticing the need for them. - Allow multiple position variables per token - ++ can now be associated with - code - Allow /* */ comments as smpl comments, not only as + code - Add support for && (label addresses) - local idexpression metavariable no longer matches static local x ** Features: - Preserve spacing before // comments when not at the beginning of a line - Adjusted parsing of endif to put it after jump code - Improve warning message when using -use_cache - More helpful initial value for exported variables in python - Support - on expression nests - Better handling of the case of a matched declaration that should only be replaced by other top level things. ** Bugfix: - Corrected parsing of script strings delimited by a single quote. Thanks to Eugeniy Meshcheryakov for reporting the problem. - Improved indentation of added ifdefs. - Allow added comments and #ifdefs to precede other added code. Thanks to Jani Monoses for noticing the problem. - Corrected failure to due missing ocamlfind. Thanks to Derek M. Jones for reporting the problem. - Allow fake nodes to be - in the allminus case, to drop tokens related to a function definition or forward declaration but before the first code mentioned in the semantic patch. - Drop __init etc when deleting a whole function. - Cause appropriate newlines to be preserved when multiple matches (trees) contain adjacent modifications derived from the same SmPL code. - check_meta takes into account fresh identifier seed information. - Types for worth-trying optimization should not be followed by space - Improved filtering of result of matching atomic patterns - Drop positions before creating function prototype rules - Adjust position of { introduced by adding multiple statements in a single-statement position - Drop newline after function call ( when all arguments on that line are eliminated - Accept removal of a single declaration, replaced by arbitrary, non-declaration code - smpl_spacing takes into account newlines, indentation --- Makefile | 3 + Makefile.release | 4 +- changes.txt | 13 +- cocci.ml | 94 +++++++----- ctl/.depend | 25 ---- ctl/ctl_engine.ml | 27 ++-- docs/Coccilib.3cocci | 2 +- docs/manual/macros.tex | 2 +- docs/manual/main_grammar.pdf | Bin 340542 -> 340642 bytes docs/manual/manual.pdf | Bin 445720 -> 445724 bytes docs/manual/options.pdf | Bin 137540 -> 137681 bytes engine/asttoctl2.ml | 39 ++--- engine/asttoctl2.mli | 5 +- engine/asttomember.ml | 2 +- engine/cocci_vs_c.ml | 3 +- engine/ctltotex.mli | 6 +- globals/config.ml.in | 2 +- parsing_c/lexer_parser.ml | 3 +- parsing_c/unparse_c.ml | 71 +++++++-- parsing_c/unparse_cocci.ml | 2 +- parsing_c/unparse_hrule.ml | 2 +- parsing_cocci/.depend | 206 -------------------------- parsing_cocci/arity.ml | 5 +- parsing_cocci/ast0_cocci.ml | 5 +- parsing_cocci/ast0_cocci.mli | 3 +- parsing_cocci/ast0toast.ml | 7 +- parsing_cocci/ast_cocci.ml | 2 +- parsing_cocci/ast_cocci.mli | 2 +- parsing_cocci/check_meta.ml | 5 +- parsing_cocci/compute_lines.ml | 6 +- parsing_cocci/context_neg.ml | 26 ++-- parsing_cocci/function_prototypes.ml | 44 ++++-- parsing_cocci/index.ml | 5 +- parsing_cocci/insert_plus.ml | 4 +- parsing_cocci/iso_pattern.ml | 4 +- parsing_cocci/parse_cocci.ml | 16 +- parsing_cocci/parser_cocci_menhir.ml | 16 +- parsing_cocci/parser_cocci_menhir.mly | 16 +- parsing_cocci/pretty_print_cocci.ml | 2 +- parsing_cocci/single_statement.ml | 2 +- parsing_cocci/top_level.ml | 76 ++++++---- parsing_cocci/top_level.mli | 5 +- parsing_cocci/unparse_ast0.ml | 4 +- parsing_cocci/visitor_ast.ml | 4 +- parsing_cocci/visitor_ast0.ml | 7 +- popl/popl.mli | 2 +- popl/popltoctl.ml | 2 +- popl/popltoctl.mli | 2 +- popl09/.depend | 35 ----- popl09/popl.mli | 2 +- popl09/popltoctl.ml | 2 +- popl09/popltoctl.mli | 2 +- python/.depend | 12 -- scripts/coccicheck/configure | 3 + tests/SCORE_expected.sexp | 18 +-- tests/SCORE_expected_orig.sexp | 10 +- tests/addfield.c | 9 ++ tests/addfield.cocci | 10 ++ tests/addfield.res | 11 ++ tests/spacing.c | 8 + tests/spacing.cocci | 24 +++ tests/spacing.res | 19 +++ tests/top.cocci | 1 + 63 files changed, 448 insertions(+), 501 deletions(-) delete mode 100644 ctl/.depend delete mode 100644 parsing_cocci/.depend delete mode 100644 popl09/.depend delete mode 100644 python/.depend create mode 100644 tests/addfield.c create mode 100644 tests/addfield.cocci create mode 100644 tests/addfield.res create mode 100644 tests/spacing.c create mode 100644 tests/spacing.cocci create mode 100644 tests/spacing.res diff --git a/Makefile b/Makefile index fa0db61..ad9a778 100644 --- a/Makefile +++ b/Makefile @@ -323,6 +323,7 @@ install-common: mkdir -p $(DESTDIR)$(SHAREDIR)/globals mkdir -p $(DESTDIR)$(SHAREDIR)/parsing_c mkdir -p $(DESTDIR)$(MANDIR)/man1 + mkdir -p $(DESTDIR)$(MANDIR)/man3 $(INSTALL_DATA) standard.h $(DESTDIR)$(SHAREDIR) $(INSTALL_DATA) standard.iso $(DESTDIR)$(SHAREDIR) $(INSTALL_DATA) ocaml/coccilib.cmi $(DESTDIR)$(SHAREDIR)/ocaml/ @@ -330,6 +331,7 @@ install-common: $(INSTALL_DATA) commons/*.cmi $(DESTDIR)$(SHAREDIR)/commons/ $(INSTALL_DATA) globals/iteration.cmi $(DESTDIR)$(SHAREDIR)/globals/ $(INSTALL_DATA) docs/spatch.1 $(DESTDIR)$(MANDIR)/man1/ + $(INSTALL_DATA) docs/Coccilib.3cocci $(DESTDIR)$(MANDIR)/man3/ @if [ $(FEATURE_PYTHON) -eq 1 ]; then $(MAKE) install-python; fi install-bash: @@ -409,6 +411,7 @@ uninstall: rmdir $(DESTDIR)$(SHAREDIR)/ocaml rmdir $(DESTDIR)$(SHAREDIR) rm -f $(DESTDIR)$(MANDIR)/man1/spatch.1 + rm -f $(DESTDIR)$(MANDIR)/man3/Coccilib.3cocci uninstall-bash: rm -f $(DESTDIR)$(BASH_COMPLETION_DIR)/spatch diff --git a/Makefile.release b/Makefile.release index eec6b57..576f0ce 100644 --- a/Makefile.release +++ b/Makefile.release @@ -6,7 +6,7 @@ PACKAGE=$(PRJNAME)-$(VERSION) CCPACKAGE=coccicheck-$(CCVERSION) -EXCLUDE=debian +EXCLUDE=$(PACKAGE)/debian .depend BINSRC=spatch env.sh env.csh standard.h standard.iso \ *.txt \ @@ -15,7 +15,7 @@ BINSRC=spatch env.sh env.csh standard.h standard.iso \ demos/* BINSRC-PY=$(BINSRC) $(PYLIB) python/coccilib/ -EXCL=$(EXCLUDE:%=--exclude=$(PACKAGE)/%) +EXCL=$(EXCLUDE:%=--exclude=%) BINSRC2=$(BINSRC:%=$(PACKAGE)/%) BINSRC2-PY=$(BINSRC-PY:%=$(PACKAGE)/%) diff --git a/changes.txt b/changes.txt index 84e71b5..6ed8ca9 100644 --- a/changes.txt +++ b/changes.txt @@ -28,9 +28,10 @@ - Preserve spacing before // comments when not at the beginning of a line - Adjusted parsing of endif to put it after jump code - Improve warning message when using -use_cache -- Allow - nest expressions - More helpful initial value for exported variables in python - Support - on expression nests +- Better handling of the case of a matched declaration that should only + be replaced by other top level things. ** Bugfix: - Corrected parsing of script strings delimited by a single quote. Thanks @@ -48,7 +49,15 @@ contain adjacent modifications derived from the same SmPL code. - check_meta takes into account fresh identifier seed information. - Types for worth-trying optimization should not be followed by space -- Improved pretty printing when the first parameter of a function is dropped +- Improved filtering of result of matching atomic patterns +- Drop positions before creating function prototype rules +- Adjust position of { introduced by adding multiple statements in a + single-statement position +- Drop newline after function call ( when all arguments on that line are + eliminated +- Accept removal of a single declaration, replaced by arbitrary, + non-declaration code +- smpl_spacing takes into account newlines, indentation * 0.2.5 ** Language: diff --git a/cocci.ml b/cocci.ml index ff638fb..ef8c893 100644 --- a/cocci.ml +++ b/cocci.ml @@ -335,6 +335,12 @@ let show_or_not_diff a b = let show_or_not_ctl_tex2 astcocci ctls = if !Flag_cocci.show_ctl_tex then begin + let ctls = + List.map + (List.map + (function ((Asttoctl2.NONDECL ctl | Asttoctl2.CODE ctl),x) -> + (ctl,x))) + ctls in Ctltotex.totex ("/tmp/__cocci_ctl.tex") astcocci ctls; Common.command2 ("cd /tmp; latex __cocci_ctl.tex; " ^ "dvips __cocci_ctl.dvi -o __cocci_ctl.ps;" ^ @@ -380,7 +386,7 @@ let show_or_not_ctl_text2 ctl ast rulenb = ); pr "CTL = "; - let (ctl,_) = ctl in + let ((Asttoctl2.CODE ctl | Asttoctl2.NONDECL ctl),_) = ctl in adjust_pp_with_indent (fun () -> Format.force_newline(); Pretty_print_engine.pp_ctlcocci @@ -843,7 +849,7 @@ type toplevel_cocci_info_script_rule = { } type toplevel_cocci_info_cocci_rule = { - ctl: Lib_engine.ctlcocci * (CCI.pred list list); + ctl: Asttoctl2.top_formula * (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 *) @@ -1607,47 +1613,57 @@ and process_a_generated_a_env_a_toplevel rule env ccs = (* 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; + show_or_not_celem "trying" c.ast_c; + Flag.currentfile := Some (f ^ ":" ^get_celem c.ast_c); + match (r.ctl,c.ast_c) with + ((Asttoctl2.NONDECL ctl,t),Ast_c.Declaration _) -> None + | ((Asttoctl2.NONDECL ctl,t), _) + | ((Asttoctl2.CODE ctl,t), _) -> + let ctl = (ctl,t) in (* ctl and other info *) + 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.rule_info.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.rule_info.was_matched := true; - - if not (null trans_info) && - not (!Flag.sgrep_mode2 && not !Flag_cocci.show_diff) - 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.rule_info.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 - ) + let model_ctl = + CCI.model_for_ctl r.dropped_isos (Common.some c.flow) e + in CCI.mysat model_ctl ctl (r.rule_info.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.rule_info.was_matched := true; + + if not (null trans_info) && + not (!Flag.sgrep_mode2 && not !Flag_cocci.show_diff) + 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.rule_info.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" diff --git a/ctl/.depend b/ctl/.depend deleted file mode 100644 index 9e82586..0000000 --- a/ctl/.depend +++ /dev/null @@ -1,25 +0,0 @@ -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 -ast_ctl.cmo: -ast_ctl.cmx: -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 -flag_ctl.cmo: -flag_ctl.cmx: -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/ctl_engine.ml b/ctl/ctl_engine.ml index 4577176..776dcc6 100644 --- a/ctl/ctl_engine.ml +++ b/ctl/ctl_engine.ml @@ -1525,19 +1525,20 @@ let satLabel label required p = (List.map (function (st,th,_) -> (st,th)) triples); triples else setify(label p) in - normalize - (if !pREQUIRED_ENV_OPT - then - foldl - (function rest -> - function ((s,th,_) as t) -> - if List.for_all - (List.exists (function th' -> not(conj_subst th th' = None))) - required - then t::rest - else rest) - [] triples - else triples) + (* normalize first; conj_subst relies on sorting *) + let ntriples = normalize triples in + if !pREQUIRED_ENV_OPT + then + foldl + (function rest -> + function ((s,th,_) as t) -> + if List.for_all + (List.exists (function th' -> not(conj_subst th th' = None))) + required + then t::rest + else rest) + [] ntriples + else ntriples let get_required_states l = if !pREQUIRED_STATES_OPT && not !Flag_ctl.partial_match diff --git a/docs/Coccilib.3cocci b/docs/Coccilib.3cocci index f7733a7..7e5956d 100644 --- a/docs/Coccilib.3cocci +++ b/docs/Coccilib.3cocci @@ -1,6 +1,6 @@ .\" -*- nroff -*- .\" Please adjust this date whenever revising the manpage. -.TH SPATCH 1 "may 18, 2011" +.TH COCCILIB 3COCCI "May 18, 2011" .\" see http://www.fnal.gov/docs/products/ups/ReferenceManual/html/manpages.html .\" see http://www.linuxjournal.com/article/1158 diff --git a/docs/manual/macros.tex b/docs/manual/macros.tex index d3f7fc8..887b09d 100644 --- a/docs/manual/macros.tex +++ b/docs/manual/macros.tex @@ -4,5 +4,5 @@ \newcommand{\cpp}{\texttt{cpp}\xspace} -\newcommand{\cocciversion}{0.2.5\xspace} +\newcommand{\cocciversion}{1.0.0-rc3\xspace} diff --git a/docs/manual/main_grammar.pdf b/docs/manual/main_grammar.pdf index cf6ef04705d6ca8ff6166863aabca02668468c9d..6561629b85e942d86fd09316a26d4243cb1edfe1 100644 GIT binary patch delta 43410 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 delta 43362 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𝔚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 B=d%C+ delta 30894 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 r4*Ev}y#c6qc1Rc>GAJ9A9n}4R|8GcX( diff --git a/docs/manual/options.pdf b/docs/manual/options.pdf index 58df7031fca1c2784c1bb362f4bd963fbc9e32f9..a8d4eb4a40c24df23d75519684179c7522b5ed67 100644 GIT binary patch delta 11763 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 Rs0-{u7S}a5cbV#{`+sC{!o2_h delta 11800 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 diff --git a/engine/asttoctl2.ml b/engine/asttoctl2.ml index 05bf39c..b5abb46 100644 --- a/engine/asttoctl2.ml +++ b/engine/asttoctl2.ml @@ -37,8 +37,8 @@ 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 +type formula = Lib_engine.ctlcocci +type top_formula = NONDECL of Lib_engine.ctlcocci | CODE of Lib_engine.ctlcocci let union = Common.union_set let intersect l1 l2 = List.filter (function x -> List.mem x l2) l1 @@ -2473,13 +2473,15 @@ let top_level name ((ua,pos),fua) (fuas,t) = used_after := ua; saved := Ast.get_saved t; let quantified = Common.minus_set (Common.union_set ua fuas) pos in - quantify false quantified - (match Ast.unwrap t with + let (wrap,formula) = + match Ast.unwrap t with Ast.FILEINFO(old_file,new_file) -> failwith "not supported fileinfo" - | Ast.DECL(stmt) -> + | Ast.NONDECL(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) + let formula = + cleanup(statement unopt VeryEnd quantified [] None None None false) in + ((function x -> NONDECL x), formula) | Ast.CODE(stmt_dots) -> let unopt = elim_opt.V.rebuilder_statement_dots stmt_dots in let unopt = preprocess_dots unopt in @@ -2501,17 +2503,20 @@ let top_level name ((ua,pos),fua) (fuas,t) = let res = statement_list unopt VeryEnd quantified [] None None None false false in - cleanup - (if starts_with_dots - then + let formula = + 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") + 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) in + ((function x -> CODE x), formula) + | Ast.ERRORWORDS(exps) -> failwith "not supported errorwords" in + wrap (quantify false quantified formula) (* --------------------------------------------------------------------- *) (* Entry points *) @@ -2544,7 +2549,7 @@ let asttoctl r used_after positions = Ast.ScriptRule _ | Ast.InitialScriptRule _ | Ast.FinalScriptRule _ -> [] | 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] + | Ast.CocciRule (a,b,c,_,Ast_cocci.Generated) -> [CODE CTL.True] let pp_cocci_predicate (pred,modif) = Pretty_print_engine.pp_predicate pred diff --git a/engine/asttoctl2.mli b/engine/asttoctl2.mli index a6732d7..4a71f6a 100644 --- a/engine/asttoctl2.mli +++ b/engine/asttoctl2.mli @@ -23,8 +23,7 @@ type cocci_predicate = Lib_engine.predicate * Ast_cocci.meta_name Ast_ctl.modif -type formula = - (cocci_predicate,Ast_cocci.meta_name, Wrapper_ctl.info) Ast_ctl.generic_ctl +type top_formula = NONDECL of Lib_engine.ctlcocci | CODE of Lib_engine.ctlcocci val asttoctl : Ast_cocci.rule -> @@ -32,7 +31,7 @@ val asttoctl : Ast_cocci.meta_name list list (* fresh used after *) * Ast_cocci.meta_name list list (* fresh used after seeds *)) -> Ast_cocci.meta_name list list (* positions *) -> - formula list + top_formula list val pp_cocci_predicate : cocci_predicate -> unit diff --git a/engine/asttomember.ml b/engine/asttomember.ml index 1c4a90c..f65a100 100644 --- a/engine/asttomember.ml +++ b/engine/asttomember.ml @@ -270,7 +270,7 @@ and case_line testfn mcode tail case = let top_level testfn mcode t : 'a list list = match Ast.unwrap t with Ast.FILEINFO(old_file,new_file) -> failwith "not supported fileinfo" - | Ast.DECL(stmt) -> statement testfn mcode false stmt + | Ast.NONDECL(stmt) -> statement testfn mcode false stmt | Ast.CODE(stmt_dots) -> statement_list testfn mcode false stmt_dots | Ast.ERRORWORDS(exps) -> failwith "not supported errorwords" diff --git a/engine/cocci_vs_c.ml b/engine/cocci_vs_c.ml index aa3849e..a5e297c 100644 --- a/engine/cocci_vs_c.ml +++ b/engine/cocci_vs_c.ml @@ -738,6 +738,7 @@ 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) +let metavar2ndots (_,info,mcodekind,pos) = ("<+...",info,mcodekind,pos) let satisfies_regexpconstraint c id : bool = match c with @@ -1345,7 +1346,7 @@ let rec (expression: (A.expression, Ast_c.expression) matcher) = X.distrf_e (dots2metavar starter) eb >>= (fun mcode eb -> return ( (A.NestExpr - (metavar2dots mcode, + (metavar2ndots mcode, A.rewrap exps (A.DOTS [exp]),ender,None,true)) +> wa, eb ) diff --git a/engine/ctltotex.mli b/engine/ctltotex.mli index a403d62..a6de606 100644 --- a/engine/ctltotex.mli +++ b/engine/ctltotex.mli @@ -25,7 +25,5 @@ val totex : string -> Ast_cocci.rule list -> - ((Lib_engine.predicate * Ast_cocci.meta_name Ast_ctl.modif, - Ast_cocci.meta_name,Wrapper_ctl.info) - Ast_ctl.generic_ctl * 'a) list list -> - unit + (Lib_engine.ctlcocci * 'a) list list -> + unit diff --git a/globals/config.ml.in b/globals/config.ml.in index 26b2e40..c254ac2 100644 --- a/globals/config.ml.in +++ b/globals/config.ml.in @@ -1,4 +1,4 @@ -let version = "1.0.0-rc2" +let version = "1.0.0-rc3" let path = try (Sys.getenv "COCCINELLE_HOME") diff --git a/parsing_c/lexer_parser.ml b/parsing_c/lexer_parser.ml index cd19ee3..c32677d 100644 --- a/parsing_c/lexer_parser.ml +++ b/parsing_c/lexer_parser.ml @@ -57,7 +57,8 @@ type identkind = TypeDefI | IdentI let (_typedef : (string, identkind) Common.scoped_h_env ref) = ref (Common.empty_scoped_h_env ()) -let is_typedef s = if !_handle_typedef || !_always_look_typedef then +let is_typedef s = + if !_handle_typedef || !_always_look_typedef then (match (Common.optionise (fun () -> Common.lookup_h_env s !_typedef)) with | Some TypeDefI -> true | Some IdentI -> false diff --git a/parsing_c/unparse_c.ml b/parsing_c/unparse_c.ml index 2996d18..5b0670a 100644 --- a/parsing_c/unparse_c.ml +++ b/parsing_c/unparse_c.ml @@ -767,7 +767,7 @@ let adjust_after_paren toks = else x :: search_paren xs | x::xs -> x :: search_paren xs and search_minus seen_minus xs = - let (spaces, rest) = Common.span is_space xs in + let (spaces, rest) = Common.span is_whitespace xs in (* only delete spaces if something is actually deleted *) match rest with ((T2(_,Min _,_)) as a)::rerest -> (* minus *) @@ -779,6 +779,24 @@ let adjust_after_paren toks = | _ -> if seen_minus then rest else xs in (* drop trailing space *) search_paren toks +(* this is for the case where braces are added around an if branch *) +let paren_then_brace toks = + let rec search_paren = function + [] -> [] + | ((T2(_,Ctx,_)) as x)::xs -> + if List.mem (str_of_token2 x) [")"] + then x :: search_paren(search_plus xs) + else x :: search_paren xs + | x::xs -> x :: search_paren xs + and search_plus xs = + let (spaces, rest) = Common.span is_whitespace xs in + match rest with + (* move the brace up to the previous line *) + ((Cocci2("{",_,_,_,_)) as x) :: (((Cocci2 _) :: _) as rest) -> + (C2 " ") :: x :: spaces @ rest + | _ -> xs in + search_paren toks + let is_ident_like s = s ==~ Common.regexp_alpha let rec drop_space_at_endline = function @@ -830,6 +848,15 @@ let rec add_space xs = something should be done to add newlines too, rather than printing them explicitly in unparse_cocci. *) x::C2 (String.make (lcoly-rcolx) ' ')::add_space (y::xs) + | (Cocci2(sx,lnx,_,rcolx,_) as x)::((Cocci2(sy,lny,lcoly,_,_)) as y)::xs + when !Flag_parsing_c.spacing = Flag_parsing_c.SMPL && + not (lnx = -1) && lnx < lny && not (rcolx = -1) -> + (* this only works within a line. could consider whether + something should be done to add newlines too, rather than + printing them explicitly in unparse_cocci. *) + x::C2 (String.make (lny-lnx) '\n'):: + C2 (String.make (lcoly-1) ' '):: (* -1 is for the + *) + add_space (y::xs) | ((T2(_,Ctx,_)) as x)::((Cocci2 _) as y)::xs -> (* add space on boundary *) let sx = str_of_token2 x in let sy = str_of_token2 y in @@ -954,7 +981,7 @@ let new_tabbing a = let rec adjust_indentation xs = - let _current_tabbing = ref "" in + let _current_tabbing = ref ([] : string list) in let tabbing_unit = ref None in let string_of_list l = String.concat "" (List.map string_of_char l) in @@ -972,15 +999,18 @@ let rec adjust_indentation xs = | (o::os,n::ns) -> loop (os,ns) in (* could check for equality *) loop (old_tab,new_tab) in +(* let remtab tu current_tab = let current_tab = List.rev(list_of_string current_tab) in let rec loop = function ([],new_tab) -> string_of_list (List.rev new_tab) - | (_,[]) -> "" (*weird; 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 *) + | (_,ns) -> (-* mismatch; remove what we can *-) string_of_list (List.rev ns) in loop (tu,current_tab) in +*) let rec find_first_tab started = function [] -> () @@ -1018,27 +1048,36 @@ let rec adjust_indentation xs = | ((T2 (Parser_c.TCommentNewline s, _, _)) as x)::xs when balanced 0 (fst(Common.span (function x -> not(is_newline x)) xs)) -> let old_tabbing = !_current_tabbing in - str_of_token2 x +> new_tabbing +> (fun s -> _current_tabbing := s); + str_of_token2 x +> new_tabbing +> (fun s -> _current_tabbing := [s]); (* only trust the indentation after the first { *) (if started - then adjust_tabbing_unit old_tabbing !_current_tabbing); + then + adjust_tabbing_unit + (String.concat "" old_tabbing) + (String.concat "" !_current_tabbing)); let coccis_rest = Common.span all_coccis xs in (match coccis_rest with (_::_,((T2 (tok,_,_)) as y)::_) when str_of_token2 y =$= "}" -> (* the case where cocci code has been added before a close } *) x::aux started (Indent_cocci2::xs) | _ -> x::aux started xs) + | Indent_cocci2::((Cocci2(sy,lny,lcoly,_,_)) as y)::xs + when !Flag_parsing_c.spacing = Flag_parsing_c.SMPL -> + let tu = String.make (lcoly-1) ' ' in + _current_tabbing := tu::(!_current_tabbing); + C2 (tu)::aux started (y::xs) | Indent_cocci2::xs -> (match !tabbing_unit with None -> aux started xs | Some (tu,_) -> - _current_tabbing := (!_current_tabbing)^tu; - Cocci2 (tu,-1,-1,-1,None)::aux started xs) + _current_tabbing := tu::(!_current_tabbing); + (* can't be C2, for later phases *) + Cocci2 (tu,-1,-1,-1,None)::aux started xs) | Unindent_cocci2(permanent)::xs -> - (match !tabbing_unit with - None -> aux started xs - | Some (_,tu) -> - _current_tabbing := remtab tu (!_current_tabbing); + (match !_current_tabbing with + [] -> aux started xs + | _::new_tabbing -> + _current_tabbing := new_tabbing; aux started xs) (* border between existing code and cocci code *) | ((T2 (tok,_,_)) as x)::((Cocci2("\n",_,_,_,_)) as y)::xs @@ -1052,7 +1091,8 @@ let rec adjust_indentation xs = | ((Cocci2("{",_,_,_,_)) as a)::xs -> a::aux true xs | ((Cocci2("\n",_,_,_,_)) as x)::xs -> (* dont inline in expr because of weird eval order of ocaml *) - let s = !_current_tabbing in + let s = String.concat "" !_current_tabbing in + (* can't be C2, for later phases *) x::Cocci2 (s,-1,-1,-1,None)::aux started xs | x::xs -> x::aux started xs in (aux false xs,!tabbing_unit) @@ -1225,7 +1265,7 @@ let pp_program2 xs outfile = drop_expanded(drop_fake(drop_minus toks)) else (* phase2: can now start to filter and adjust *) - let (toks,tu) = adjust_indentation toks in + (let (toks,tu) = adjust_indentation toks in let toks = adjust_before_semicolon toks in(*before remove minus*) let toks = adjust_after_paren toks in(*also before remove minus*) let toks = drop_space_at_endline toks in @@ -1235,8 +1275,9 @@ let pp_program2 xs outfile = (* assert Origin + Cocci + C and no minus *) let toks = add_space toks in let toks = add_newlines toks tu in + let toks = paren_then_brace toks in let toks = fix_tokens toks in - toks in + toks) in (* in theory here could reparse and rework the ast! or * apply some SP. Not before cos julia may have generated diff --git a/parsing_c/unparse_cocci.ml b/parsing_c/unparse_cocci.ml index 80f052e..d7d5912 100644 --- a/parsing_c/unparse_cocci.ml +++ b/parsing_c/unparse_cocci.ml @@ -995,7 +995,7 @@ and case_line arity c = let top_level t = match Ast.unwrap t with Ast.FILEINFO(old_file,new_file) -> raise CantBeInPlus - | Ast.DECL(stmt) -> statement "" stmt + | Ast.NONDECL(stmt) -> statement "" stmt | Ast.CODE(stmt_dots) -> dots force_newline (statement "") stmt_dots | Ast.ERRORWORDS(exps) -> raise CantBeInPlus in diff --git a/parsing_c/unparse_hrule.ml b/parsing_c/unparse_hrule.ml index b4d506c..4d182a9 100644 --- a/parsing_c/unparse_hrule.ml +++ b/parsing_c/unparse_hrule.ml @@ -448,7 +448,7 @@ let pp_rule local_metas ast env srcfile = Ast.CocciRule(_,_,[body],_,_) -> (* could extend to use attributes *) (body, match Ast.unwrap body with - Ast.DECL(s) -> [[Ast.StatementTag s]] + Ast.NONDECL(s) -> [[Ast.StatementTag s]] | Ast.CODE(ss) -> [[Ast.StmtDotsTag ss]] | _ -> error body "bad rule body") | _ -> failwith "bad rule" in diff --git a/parsing_cocci/.depend b/parsing_cocci/.depend deleted file mode 100644 index ff3ef36..0000000 --- a/parsing_cocci/.depend +++ /dev/null @@ -1,206 +0,0 @@ -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 -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: ../commons/common.cmi ast0_cocci.cmi -data.cmi: type_cocci.cmi ../commons/common.cmi ast_cocci.cmi ast0_cocci.cmi -disjdistr.cmi: ast_cocci.cmi -free_vars.cmi: ast_cocci.cmi -function_prototypes.cmi: ast_cocci.cmi ast0_cocci.cmi -get_constants.cmi: ast_cocci.cmi -get_constants2.cmi: ast_cocci.cmi -id_utils.cmi: get_constants2.cmi -index.cmi: ast0_cocci.cmi -insert_plus.cmi: ast0_cocci.cmi -iso_compile.cmi: iso_pattern.cmi -iso_pattern.cmi: visitor_ast0_types.cmo ast_cocci.cmi ast0_cocci.cmi -merge.cmi: ast_cocci.cmi ast0_cocci.cmi -parse_cocci.cmi: get_constants2.cmi ast_cocci.cmi -plus.cmi: ast_cocci.cmi -pretty_print_cocci.cmi: ast_cocci.cmi -safe_for_multi_decls.cmi: ast_cocci.cmi -simple_assignments.cmi: ast0_cocci.cmi -single_statement.cmi: ast0_cocci.cmi -test_exps.cmi: ast0_cocci.cmi -top_level.cmi: ast0_cocci.cmi -type_cocci.cmi: -type_infer.cmi: ast0_cocci.cmi -unify_ast.cmi: ast_cocci.cmi -unitary_ast0.cmi: ast0_cocci.cmi -unparse_ast0.cmi: ast0_cocci.cmi -visitor_ast.cmi: ast_cocci.cmi -visitor_ast0.cmi: visitor_ast0_types.cmo ast_cocci.cmi ast0_cocci.cmi -adjacency.cmo: visitor_ast0_types.cmo visitor_ast0.cmi ast0_cocci.cmi \ - adjacency.cmi -adjacency.cmx: visitor_ast0_types.cmx visitor_ast0.cmx ast0_cocci.cmx \ - adjacency.cmi -adjust_pragmas.cmo: visitor_ast0_types.cmo visitor_ast0.cmi ast_cocci.cmi \ - ast0_cocci.cmi adjust_pragmas.cmi -adjust_pragmas.cmx: visitor_ast0_types.cmx visitor_ast0.cmx ast_cocci.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 ../globals/flag.cmo ../commons/common.cmi \ - ast_cocci.cmi ast0_cocci.cmi -ast0_cocci.cmx: type_cocci.cmx ../globals/flag.cmx ../commons/common.cmx \ - ast_cocci.cmx ast0_cocci.cmi -ast0toast.cmo: visitor_ast0_types.cmo visitor_ast0.cmi type_cocci.cmi \ - ../globals/flag.cmo ../commons/ocamlextra/dumper.cmi ast_cocci.cmi \ - ast0_cocci.cmi ast0toast.cmi -ast0toast.cmx: visitor_ast0_types.cmx visitor_ast0.cmx type_cocci.cmx \ - ../globals/flag.cmx ../commons/ocamlextra/dumper.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_types.cmo visitor_ast0.cmi type_cocci.cmi \ - ../commons/common.cmi ast_cocci.cmi ast0_cocci.cmi check_meta.cmi -check_meta.cmx: visitor_ast0_types.cmx visitor_ast0.cmx type_cocci.cmx \ - ../commons/common.cmx ast_cocci.cmx ast0_cocci.cmx check_meta.cmi -comm_assoc.cmo: visitor_ast0_types.cmo visitor_ast0.cmi unparse_ast0.cmi \ - ../globals/flag.cmo ast_cocci.cmi ast0_cocci.cmi comm_assoc.cmi -comm_assoc.cmx: visitor_ast0_types.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_types.cmo visitor_ast0.cmi unparse_ast0.cmi \ - index.cmi ../globals/flag.cmo compute_lines.cmi ../commons/common.cmi \ - ast_cocci.cmi ast0_cocci.cmi context_neg.cmi -context_neg.cmx: visitor_ast0_types.cmx visitor_ast0.cmx unparse_ast0.cmx \ - index.cmx ../globals/flag.cmx compute_lines.cmx ../commons/common.cmx \ - ast_cocci.cmx ast0_cocci.cmx context_neg.cmi -data.cmo: type_cocci.cmi ../commons/common.cmi ast_cocci.cmi ast0_cocci.cmi \ - data.cmi -data.cmx: type_cocci.cmx ../commons/common.cmx ast_cocci.cmx ast0_cocci.cmx \ - data.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 -flag_parsing_cocci.cmo: -flag_parsing_cocci.cmx: -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_types.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_types.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 ../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 -id_utils.cmo: get_constants2.cmi ../commons/common.cmi id_utils.cmi -id_utils.cmx: get_constants2.cmx ../commons/common.cmx id_utils.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_types.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_types.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_types.cmo visitor_ast0.cmi \ - ../commons/common.cmi ast_cocci.cmi ast0_cocci.cmi iso_compile.cmi -iso_compile.cmx: visitor_ast0_types.cmx visitor_ast0.cmx \ - ../commons/common.cmx ast_cocci.cmx ast0_cocci.cmx iso_compile.cmi -iso_pattern.cmo: visitor_ast0_types.cmo visitor_ast0.cmi unparse_ast0.cmi \ - type_cocci.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_types.cmx visitor_ast0.cmx unparse_ast0.cmx \ - type_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 -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 ../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_types.cmo visitor_ast0.cmi unitary_ast0.cmi \ - type_infer.cmi test_exps.cmi single_statement.cmi simple_assignments.cmi \ - semantic_cocci.cmo safe_for_multi_decls.cmi pretty_print_cocci.cmi \ - parse_aux.cmo iso_pattern.cmi iso_compile.cmi insert_plus.cmi \ - get_constants2.cmi function_prototypes.cmi free_vars.cmi \ - flag_parsing_cocci.cmo ../globals/flag.cmo \ - ../commons/ocamlextra/dumper.cmi disjdistr.cmi data.cmi context_neg.cmi \ - 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 \ - adjacency.cmi parse_cocci.cmi -parse_cocci.cmx: visitor_ast0_types.cmx visitor_ast0.cmx unitary_ast0.cmx \ - type_infer.cmx test_exps.cmx single_statement.cmx simple_assignments.cmx \ - semantic_cocci.cmx safe_for_multi_decls.cmx pretty_print_cocci.cmx \ - parse_aux.cmx iso_pattern.cmx iso_compile.cmx insert_plus.cmx \ - get_constants2.cmx function_prototypes.cmx free_vars.cmx \ - flag_parsing_cocci.cmx ../globals/flag.cmx \ - ../commons/ocamlextra/dumper.cmx disjdistr.cmx data.cmx context_neg.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 \ - adjacency.cmx parse_cocci.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 ../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 -safe_for_multi_decls.cmo: visitor_ast.cmi ast_cocci.cmi \ - safe_for_multi_decls.cmi -safe_for_multi_decls.cmx: visitor_ast.cmx ast_cocci.cmx \ - safe_for_multi_decls.cmi -semantic_cocci.cmo: -semantic_cocci.cmx: -simple_assignments.cmo: visitor_ast0_types.cmo visitor_ast0.cmi \ - ../globals/flag.cmo ../commons/common.cmi ast_cocci.cmi ast0_cocci.cmi \ - simple_assignments.cmi -simple_assignments.cmx: visitor_ast0_types.cmx visitor_ast0.cmx \ - ../globals/flag.cmx ../commons/common.cmx ast_cocci.cmx ast0_cocci.cmx \ - simple_assignments.cmi -single_statement.cmo: visitor_ast0_types.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_types.cmx visitor_ast0.cmx iso_pattern.cmx \ - flag_parsing_cocci.cmx compute_lines.cmx ast_cocci.cmx ast0_cocci.cmx \ - single_statement.cmi -test_exps.cmo: visitor_ast0_types.cmo visitor_ast0.cmi ast_cocci.cmi \ - ast0_cocci.cmi test_exps.cmi -test_exps.cmx: visitor_ast0_types.cmx visitor_ast0.cmx ast_cocci.cmx \ - ast0_cocci.cmx test_exps.cmi -top_level.cmo: ast0_cocci.cmi top_level.cmi -top_level.cmx: ast0_cocci.cmx top_level.cmi -type_cocci.cmo: type_cocci.cmi -type_cocci.cmx: type_cocci.cmi -type_infer.cmo: visitor_ast0_types.cmo visitor_ast0.cmi type_cocci.cmi \ - ast_cocci.cmi ast0_cocci.cmi type_infer.cmi -type_infer.cmx: visitor_ast0_types.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_types.cmo visitor_ast0.cmi ../globals/flag.cmo \ - ast_cocci.cmi ast0_cocci.cmi unitary_ast0.cmi -unitary_ast0.cmx: visitor_ast0_types.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 \ - ast_cocci.cmi ast0_cocci.cmi unparse_ast0.cmi -unparse_ast0.cmx: type_cocci.cmx pretty_print_cocci.cmx ../commons/common.cmx \ - ast_cocci.cmx ast0_cocci.cmx unparse_ast0.cmi -visitor_ast.cmo: ast_cocci.cmi ast0_cocci.cmi visitor_ast.cmi -visitor_ast.cmx: ast_cocci.cmx ast0_cocci.cmx visitor_ast.cmi -visitor_ast0.cmo: visitor_ast0_types.cmo ast_cocci.cmi ast0_cocci.cmi \ - visitor_ast0.cmi -visitor_ast0.cmx: visitor_ast0_types.cmx ast_cocci.cmx ast0_cocci.cmx \ - visitor_ast0.cmi -visitor_ast0_types.cmo: ast_cocci.cmi ast0_cocci.cmi -visitor_ast0_types.cmx: ast_cocci.cmx ast0_cocci.cmx diff --git a/parsing_cocci/arity.ml b/parsing_cocci/arity.ml index c2ced71..16f6141 100644 --- a/parsing_cocci/arity.ml +++ b/parsing_cocci/arity.ml @@ -1108,10 +1108,11 @@ let top_level tgt t = 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.NONDECL(stmt) -> + Ast0.NONDECL(statement tgt stmt) | Ast0.CODE(rule_elem_dots) -> Ast0.CODE(concat_dots (statement tgt) rule_elem_dots) + | Ast0.TOPCODE(rule_elem_dots) -> fail t "eliminated by top_level" | Ast0.ERRORWORDS(exps) -> Ast0.ERRORWORDS(List.map (top_expression false Ast0.NONE) exps) | Ast0.OTHER(_) -> fail t "eliminated by top_level") diff --git a/parsing_cocci/ast0_cocci.ml b/parsing_cocci/ast0_cocci.ml index 00eb537..b724c68 100644 --- a/parsing_cocci/ast0_cocci.ml +++ b/parsing_cocci/ast0_cocci.ml @@ -402,7 +402,8 @@ and meta_pos = (* Top-level code *) and base_top_level = - DECL of statement + NONDECL of statement + | TOPCODE of statement dots | CODE of statement dots | FILEINFO of string mcode (* old file *) * string mcode (* new file *) | ERRORWORDS of expression list @@ -572,7 +573,7 @@ let rec ast0_type_to_type ty = | Pointer(ty,_) -> TC.Pointer(ast0_type_to_type ty) | FunctionPointer(ty,_,_,_,_,params,_) -> TC.FunctionPointer(ast0_type_to_type ty) - | FunctionType _ -> failwith "not supported" + | FunctionType _ -> TC.Unknown (*failwith "not supported"*) | Array(ety,_,_,_) -> TC.Array(ast0_type_to_type ety) | EnumName(su,Some tag) -> (match unwrap tag with diff --git a/parsing_cocci/ast0_cocci.mli b/parsing_cocci/ast0_cocci.mli index d8d98a6..be53d5a 100644 --- a/parsing_cocci/ast0_cocci.mli +++ b/parsing_cocci/ast0_cocci.mli @@ -391,7 +391,8 @@ and meta_pos = (* Top-level code *) and base_top_level = - DECL of statement + NONDECL of statement (* cannot match all of a top-level declaration *) + | TOPCODE of statement dots | CODE of statement dots | FILEINFO of string mcode (* old file *) * string mcode (* new file *) | ERRORWORDS of expression list diff --git a/parsing_cocci/ast0toast.ml b/parsing_cocci/ast0toast.ml index b05d7e7..40afef3 100644 --- a/parsing_cocci/ast0toast.ml +++ b/parsing_cocci/ast0toast.ml @@ -1078,11 +1078,10 @@ and top_level t = (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.NONDECL(stmt) -> Ast.NONDECL(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") + | Ast0.OTHER(_) | Ast0.TOPCODE(_) -> failwith "eliminated by top_level") (* --------------------------------------------------------------------- *) (* Entry point for minus code *) diff --git a/parsing_cocci/ast_cocci.ml b/parsing_cocci/ast_cocci.ml index c95eab5..3fe0de4 100644 --- a/parsing_cocci/ast_cocci.ml +++ b/parsing_cocci/ast_cocci.ml @@ -565,7 +565,7 @@ and inc_elem = | IncDots and base_top_level = - DECL of statement + NONDECL of statement | CODE of statement dots | FILEINFO of string mcode (* old file *) * string mcode (* new file *) | ERRORWORDS of expression list diff --git a/parsing_cocci/ast_cocci.mli b/parsing_cocci/ast_cocci.mli index 9726fb0..217a75d 100644 --- a/parsing_cocci/ast_cocci.mli +++ b/parsing_cocci/ast_cocci.mli @@ -537,7 +537,7 @@ and inc_elem = | IncDots and base_top_level = - DECL of statement + NONDECL of statement (* cannot match all of a top-level declaration *) | CODE of statement dots | FILEINFO of string mcode (* old file *) * string mcode (* new file *) | ERRORWORDS of expression list diff --git a/parsing_cocci/check_meta.ml b/parsing_cocci/check_meta.ml index 2e9850a..ba64535 100644 --- a/parsing_cocci/check_meta.ml +++ b/parsing_cocci/check_meta.ml @@ -452,8 +452,9 @@ and case_line old_metas table minus c = 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.NONDECL(stmt) -> statement old_metas table minus stmt + | Ast0.CODE(stmt_dots) | Ast0.TOPCODE(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 *) diff --git a/parsing_cocci/compute_lines.ml b/parsing_cocci/compute_lines.ml index 6c2c566..291a1a9 100644 --- a/parsing_cocci/compute_lines.ml +++ b/parsing_cocci/compute_lines.ml @@ -1092,13 +1092,13 @@ and statement_dots x = dots is_stm_dots None statement x 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.NONDECL(stmt) -> + let stmt = statement stmt in mkres t (Ast0.NONDECL(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" + | Ast0.OTHER(_) | Ast0.TOPCODE(_) -> failwith "eliminated by top_level" (* --------------------------------------------------------------------- *) (* Entry points *) diff --git a/parsing_cocci/context_neg.ml b/parsing_cocci/context_neg.ml index b1cfe9b..11e310d 100644 --- a/parsing_cocci/context_neg.ml +++ b/parsing_cocci/context_neg.ml @@ -741,7 +741,7 @@ let equal_case_line c1 c2 = let rec equal_top_level t1 t2 = match (Ast0.unwrap t1,Ast0.unwrap t2) with - (Ast0.DECL(_),Ast0.DECL(_)) -> true + (Ast0.NONDECL(_),Ast0.NONDECL(_)) -> 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 @@ -861,10 +861,11 @@ let plus_table = let iscode t = match Ast0.unwrap t with - Ast0.DECL(_) -> true + Ast0.NONDECL(_) -> true | Ast0.FILEINFO(_) -> true | Ast0.ERRORWORDS(_) -> false | Ast0.CODE(_) -> true + | Ast0.TOPCODE(_) | Ast0.OTHER(_) -> failwith "unexpected top level code" (* ------------------------------------------------------------------- *) @@ -878,7 +879,7 @@ let concat = function [] -> [] | x::rest -> (match Ast0.unwrap x with - Ast0.DECL(s) -> let stms = loop rest in s::stms + Ast0.NONDECL(s) -> let stms = loop rest in s::stms | Ast0.CODE(ss) -> let stms = loop rest in (match Ast0.unwrap ss with @@ -968,6 +969,8 @@ let rec is_toplevel s = | Ast0.Define(_,_,_,_) -> true | _ -> false +(* consider code and topcode to be the same; difference handled +in top_level.ml *) let check_compatible m p = let fail _ = failwith @@ -975,17 +978,21 @@ let check_compatible m p = "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)) -> + (Ast0.NONDECL(decl1),Ast0.NONDECL(decl2)) -> if not (is_decl decl1 && is_decl decl2) then fail() - | (Ast0.DECL(decl1),Ast0.CODE(code2)) -> + | (Ast0.NONDECL(decl1),Ast0.CODE(code2)) -> + (* This is probably the only important case. We don't want to + replace top-level declarations by arbitrary code. *) 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)) -> + if !Flag.make_hrule = None && v1 && not v2 + then fail() + | (Ast0.CODE(code1),Ast0.NONDECL(decl2)) -> let v1 = List.for_all is_toplevel (Ast0.undots code1) in let v2 = is_decl decl2 in - if v1 && not v2 then fail() + 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 @@ -1003,7 +1010,8 @@ let check_compatible m p = 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() + if !Flag.make_hrule = None && v1 && not v2 + then fail() | (Ast0.FILEINFO(_,_),Ast0.FILEINFO(_,_)) -> () | (Ast0.OTHER(_),Ast0.OTHER(_)) -> () | _ -> fail() diff --git a/parsing_cocci/function_prototypes.ml b/parsing_cocci/function_prototypes.ml index 7ecb83d..2f2225a 100644 --- a/parsing_cocci/function_prototypes.ml +++ b/parsing_cocci/function_prototypes.ml @@ -76,16 +76,30 @@ let collect_function (stm : Ast0.statement) = let collect_functions stmt_dots = List.concat (List.map collect_function (Ast0.undots stmt_dots)) +let drop_positions = + let mcode (term,arity,info,mc,_,adj) = + (term,arity,info,mc,ref [],adj) in + let donothing r k e = k e in + let res = + V0.flat_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 in + res.VT0.rebuilder_rec_statement + let get_all_functions rule = let res = match Ast0.unwrap rule with - Ast0.DECL(stmt) -> collect_function stmt + Ast0.NONDECL(stmt) -> collect_function stmt | Ast0.CODE(rule_elem_dots) -> collect_functions rule_elem_dots | _ -> [] in List.map (function (nm,def,vl) -> (nm, - (def,(Iso_pattern.rebuild_mcode None).VT0.rebuilder_rec_statement vl))) + (def, + drop_positions + ((Iso_pattern.rebuild_mcode None).VT0.rebuilder_rec_statement vl)))) res (* --------------------------------------------------------------------- *) @@ -343,21 +357,20 @@ let no_names dec = | _ -> dec) | _ -> dec +let mkcode proto = + Ast0.copywrap proto (Ast0.CODE(Ast0.copywrap proto (Ast0.DOTS [proto]))) + let merge mproto pproto = - let mproto = - Compute_lines.compute_lines true - [Ast0.copywrap mproto (Ast0.DECL mproto)] in - let pproto = - Compute_lines.compute_lines true - [Ast0.copywrap pproto (Ast0.DECL pproto)] in + let mproto = Compute_lines.compute_lines true [mkcode mproto] in + let pproto = Compute_lines.compute_lines true [mkcode pproto] in let (m,p) = List.split(Context_neg.context_neg mproto pproto) in Insert_plus.insert_plus m p true (* no isos for protos *); (* convert to ast so that the + code will fall down to the tokens - and off the artificially added Ast0.DECL *) + and off the artificially added Ast0.CODE *) let mproto = Ast0toast.ast0toast_toplevel (List.hd mproto) in (* clean up the wrapping added above *) match Ast.unwrap mproto with - Ast.DECL mproto -> mproto + Ast.CODE mproto -> List.hd (Ast.undots mproto) | _ -> failwith "not possible" let make_rule rule_name = function @@ -385,10 +398,10 @@ let reinsert mdefs minus = List.map (function x -> match Ast0.unwrap x with - Ast0.DECL(stmt) -> + Ast0.NONDECL(stmt) -> (match Ast0.unwrap stmt with Ast0.FunDecl(_,fninfo,name,lp,params,rp,lbrace,body,rbrace) -> - (try Ast0.rewrap x (Ast0.DECL(List.assoc name table)) + (try Ast0.rewrap x (Ast0.NONDECL(List.assoc name table)) with Not_found -> x) | _ -> x) | Ast0.CODE(rule_elem_dots) -> @@ -405,6 +418,9 @@ let rec split4 = function | (a,b,c,d)::rest -> let (ax,bx,cx,dx) = split4 rest in (a::ax,b::bx,c::cx,d::dx) +let mk_ast_code proto = + Ast.rewrap proto (Ast.CODE(Ast.rewrap proto (Ast.DOTS [proto]))) + let process rule_name rule_metavars dropped_isos minus plus ruletype = let minus_functions = List.concat (List.map get_all_functions minus) in match minus_functions with @@ -430,7 +446,7 @@ let process rule_name rule_metavars dropped_isos minus plus ruletype = Ast.CocciRule ("proto for "^rule_name, (Ast.Dep rule_name,dropped_isos,Ast.Forall), - [Ast.rewrap x (Ast.DECL x)], + [mk_ast_code x], [false],ruletype))) | x::_ -> let drules = @@ -439,6 +455,6 @@ let process rule_name rule_metavars dropped_isos minus plus ruletype = Ast.CocciRule ("proto for "^rule_name, (Ast.Dep rule_name,dropped_isos,Ast.Forall), - [Ast.rewrap x (Ast.DECL (Ast.rewrap x (Ast.Disj drules)))], + [mk_ast_code (Ast.rewrap x (Ast.Disj drules))], [false],ruletype) in ((mdef_metavars,minus),Some(metavars,res)) diff --git a/parsing_cocci/index.ml b/parsing_cocci/index.ml index f4ee7cb..a6aea02 100644 --- a/parsing_cocci/index.ml +++ b/parsing_cocci/index.ml @@ -23,7 +23,7 @@ (* create an index for each constructor *) -(* current max is 153 *) +(* current max is 154 *) (* doesn't really work - requires that identical terms with no token subterms (eg dots) not appear on the same line *) @@ -222,10 +222,11 @@ let case_line c = let top_level t = match Ast0.unwrap t with - Ast0.DECL(stmt) -> [90] + Ast0.NONDECL(stmt) -> [90] | Ast0.FILEINFO(old_file,new_file) -> [92] | Ast0.CODE(stmt_dots) -> [94] | Ast0.ERRORWORDS(exps) -> [95] | Ast0.OTHER(_) -> [96] + | Ast0.TOPCODE(_) -> [154] (* 99-101 already used *) diff --git a/parsing_cocci/insert_plus.ml b/parsing_cocci/insert_plus.ml index c664b07..74854aa 100644 --- a/parsing_cocci/insert_plus.ml +++ b/parsing_cocci/insert_plus.ml @@ -529,7 +529,7 @@ let collect_plus_nodes root = let toplevel r k e = match Ast0.unwrap e with - Ast0.DECL(s) -> r.VT0.combiner_rec_statement s + Ast0.NONDECL(s) -> r.VT0.combiner_rec_statement s | Ast0.CODE(sdots) -> r.VT0.combiner_rec_statement_dots sdots | _ -> do_nothing mk_code r k e in @@ -789,10 +789,8 @@ let attachbefore (infop,c,p) = function (match repl with Ast.NOREPLACEMENT -> let (bef,ti) = init p infop in - Printf.printf "attachbefore 1 %s\n" (it2c c); replacements := (Ast.REPLACEMENT(bef,c),ti) | Ast.REPLACEMENT(repl,it) -> - Printf.printf "attachbefore 2 %s %s\n" (it2c c) (it2c it); let it = Ast.lub_count it c in let (bef,ti) = insert p infop repl ti in replacements := (Ast.REPLACEMENT(bef,it),ti)) diff --git a/parsing_cocci/iso_pattern.ml b/parsing_cocci/iso_pattern.ml index 3bd0ef6..bdbb350 100644 --- a/parsing_cocci/iso_pattern.ml +++ b/parsing_cocci/iso_pattern.ml @@ -2421,7 +2421,7 @@ let transform_stmt (metavars,alts,name) 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) -> + Ast0.NONDECL(declstm) -> (try let strip alts = List.map @@ -2434,7 +2434,7 @@ let transform_top (metavars,alts,name) e = | _ -> raise (Failure ""))) alts in let (count,mv,s) = transform_stmt (metavars,strip alts,name) declstm in - (count,mv,Ast0.rewrap e (Ast0.DECL(s))) + (count,mv,Ast0.rewrap e (Ast0.NONDECL(s))) with Failure _ -> (0,[],e)) | Ast0.CODE(stmts) -> let (count,mv,res) = diff --git a/parsing_cocci/parse_cocci.ml b/parsing_cocci/parse_cocci.ml index a18abbc..f721e53 100644 --- a/parsing_cocci/parse_cocci.ml +++ b/parsing_cocci/parse_cocci.ml @@ -1709,11 +1709,25 @@ let parse file = then (* not actually used for anything, except context_neg *) List.map (Iso_pattern.rebuild_mcode None).VT0.rebuilder_rec_top_level - minus_res + (Top_level.top_level false 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 + let plus_res = Top_level.top_level false plus_res in + (* minus code has to be CODE if the + code is CODE, otherwise + doesn't matter if + code is CODE or DECL or TOPCODE *) + let minus_res = + let any_code = + List.exists + (function x -> + match Ast0.unwrap x with Ast0.CODE _ -> true | _ -> false) + plus_res in + if any_code + then Top_level.top_level true minus_res + else Top_level.top_level false minus_res in + let minus_res = Top_level.clean minus_res in + let plus_res = Top_level.clean plus_res in (* Unparse_ast0.unparse plus_res; Printf.printf "after plus parse\n"; diff --git a/parsing_cocci/parser_cocci_menhir.ml b/parsing_cocci/parser_cocci_menhir.ml index a5cd51a..0dc8361 100644 --- a/parsing_cocci/parser_cocci_menhir.ml +++ b/parsing_cocci/parser_cocci_menhir.ml @@ -23270,7 +23270,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 816 "parser_cocci_menhir.mly" ( match f@b(*@ew*) with [] -> raise (Semantic_cocci.Semantic "minus slice can't be empty") - | code -> Top_level.top_level code ) + | code -> code ) # 23275 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { @@ -23302,7 +23302,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct # 830 "parser_cocci_menhir.mly" ( match f@[b](*@ew*) with [] -> raise (Semantic_cocci.Semantic "minus slice can't be empty") - | code -> Top_level.top_level code ) + | code -> code ) # 23307 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { @@ -23518,7 +23518,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _endpos = _endpos__1_ in let _v : 'tv_minus_start = # 2078 "parser_cocci_menhir.mly" - ( [Ast0.wrap(Ast0.DECL(_1))] ) + ( [Ast0.wrap(Ast0.OTHER(_1))] ) # 23523 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { @@ -28257,7 +28257,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _endpos = _endpos__2_ in let _v : 'tv_plus_after_dots = # 2149 "parser_cocci_menhir.mly" - ( Ast0.wrap(Ast0.DECL(_1))::_2 ) + ( Ast0.wrap(Ast0.OTHER(_1))::_2 ) # 28262 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { @@ -28411,7 +28411,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _endpos = _endpos__2_ in let _v : 'tv_plus_after_stm = # 2156 "parser_cocci_menhir.mly" - ( Ast0.wrap(Ast0.DECL(_1))::_2 ) + ( Ast0.wrap(Ast0.OTHER(_1))::_2 ) # 28416 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { @@ -28471,7 +28471,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _endpos = _endpos_b_ in let _v : 'tv_plus_body = # 824 "parser_cocci_menhir.mly" - ( Top_level.top_level (f@b(*@ew*)) ) + ( f@b(*@ew*) ) # 28476 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { @@ -28501,7 +28501,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _endpos = _endpos_b_ in let _v : 'tv_plus_exp_body = # 838 "parser_cocci_menhir.mly" - ( Top_level.top_level (f@[b](*@ew*)) ) + ( f@[b](*@ew*) ) # 28506 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { @@ -28831,7 +28831,7 @@ module MenhirInterpreter = MenhirLib.TableInterpreter.Make (struct let _endpos = _endpos__2_ in let _v : 'tv_plus_start = # 2136 "parser_cocci_menhir.mly" - ( Ast0.wrap(Ast0.DECL(_1))::_2 ) + ( Ast0.wrap(Ast0.OTHER(_1))::_2 ) # 28836 "parser_cocci_menhir.ml" in _menhir_env.MenhirLib.EngineTypes.stack <- { diff --git a/parsing_cocci/parser_cocci_menhir.mly b/parsing_cocci/parser_cocci_menhir.mly index fb706ab..ef6df83 100644 --- a/parsing_cocci/parser_cocci_menhir.mly +++ b/parsing_cocci/parser_cocci_menhir.mly @@ -815,13 +815,13 @@ minus_body: /*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 } + | code -> code } plus_body: f=loption(filespec) b=loption(plus_start) /*ew=loption(error_words)*/ - { Top_level.top_level (f@b(*@ew*)) } + { f@b(*@ew*) } minus_exp_body: f=loption(filespec) @@ -829,13 +829,13 @@ minus_exp_body: /*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 } + | code -> code } plus_exp_body: f=loption(filespec) b=top_eexpr /*ew=loption(error_words)*/ - { Top_level.top_level (f@[b](*@ew*)) } + { f@[b](*@ew*) } filespec: TMinusFile TPlusFile @@ -2075,7 +2075,7 @@ when_body_sequence. /* doesn't allow only ... */ minus_start: - fundecl { [Ast0.wrap(Ast0.DECL($1))] } + fundecl { [Ast0.wrap(Ast0.OTHER($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) @@ -2133,7 +2133,7 @@ plus_start: { (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 } +| fundecl plus_after_stm { Ast0.wrap(Ast0.OTHER($1))::$2 } | decl_statement_expr plus_after_stm { (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) $1)@$2 } @@ -2146,14 +2146,14 @@ plus_after_dots: | 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 } +| fundecl plus_after_stm { Ast0.wrap(Ast0.OTHER($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 } +| fundecl plus_after_stm { Ast0.wrap(Ast0.OTHER($1))::$2 } | decl_statement plus_after_stm { (List.map (function x -> Ast0.wrap(Ast0.OTHER(x))) $1)@$2 } diff --git a/parsing_cocci/pretty_print_cocci.ml b/parsing_cocci/pretty_print_cocci.ml index 74f792a..ac84a5e 100644 --- a/parsing_cocci/pretty_print_cocci.ml +++ b/parsing_cocci/pretty_print_cocci.ml @@ -791,7 +791,7 @@ let top_level t = 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.NONDECL(stmt) -> statement "" stmt | Ast.CODE(stmt_dots) -> dots force_newline (statement "") stmt_dots | Ast.ERRORWORDS(exps) -> diff --git a/parsing_cocci/single_statement.ml b/parsing_cocci/single_statement.ml index d3bfde8..a5ed9dc 100644 --- a/parsing_cocci/single_statement.ml +++ b/parsing_cocci/single_statement.ml @@ -660,7 +660,7 @@ and statement_dots dots_before dots_after d = let top_level t = Ast0.rewrap t (match Ast0.unwrap t with - Ast0.DECL(stmt_dots) -> Ast0.DECL(statement true true stmt_dots) + Ast0.NONDECL(stmt_dots) -> Ast0.NONDECL(statement true true stmt_dots) | Ast0.CODE(stmt_dots) -> Ast0.CODE(statement_dots true true stmt_dots) | t -> t) diff --git a/parsing_cocci/top_level.ml b/parsing_cocci/top_level.ml index 6dd7eed..a9e7a2a 100644 --- a/parsing_cocci/top_level.ml +++ b/parsing_cocci/top_level.ml @@ -45,56 +45,76 @@ let top_dots l = then Ast0.wrap (Ast0.STARS(l)) else Ast0.wrap (Ast0.DOTS(l)) -let scan_code l = - let statements = ref false in +let rec is_decl s = + match Ast0.unwrap s with + Ast0.Decl(_,e) -> true + | _ -> false + +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_toplevel s = + match Ast0.unwrap s with + Ast0.Decl(_,e) -> true + | Ast0.FunDecl(_,_,_,_,_,_,_,_,_) -> true + | Ast0.Disj(_,stmts,_,_) -> isall is_toplevel stmts + | Ast0.ExprStatement(Some fc,_) -> false + | Ast0.Include(_,_) -> true + | Ast0.Undef(_,_) -> true + | Ast0.Define(_,_,_,_) -> true + | _ -> false + +let scan_code must_be_code l = let rec loop = function [] -> ([],[]) | (x::xs) as all -> - (match Ast0.unwrap x with - (Ast0.OTHER(code)) -> - (match Ast0.unwrap code with - Ast0.Decl(_) -> - let (front,rest) = loop xs in - (code::front,rest) - | _ -> - statements := true; - let (front,rest) = loop xs in - (code::front,rest)) - | _ -> ([],all)) in + (match Ast0.unwrap x with + (Ast0.OTHER(code)) -> + let (front,rest) = loop xs in + (code::front,rest) + | _ -> ([],all)) in match loop l with ([],_) as res -> res | (code,rest) -> - if !statements = true - then ([Ast0.wrap(Ast0.CODE(top_dots code))],rest) - else - (List.map - (function d -> - match Ast0.unwrap d with - Ast0.Decl(bef,x) -> Ast0.wrap (Ast0.DECL(d)) - | _ -> failwith "impossible") - code, - rest) + (match code with + | [x] when is_decl x && must_be_code -> + ([Ast0.wrap(Ast0.NONDECL x)],rest) + | _ when List.for_all is_toplevel code -> + ([Ast0.wrap(Ast0.TOPCODE(top_dots code))],rest) + | _ -> + ([Ast0.wrap(Ast0.CODE(top_dots code))],rest)) let rec scan_top_decl = function [] -> ([],[]) | ((topdecl::rest) as all) -> (match Ast0.unwrap topdecl with Ast0.OTHER(_) -> ([],all) - | _ -> let (front,rest) = scan_top_decl rest in (topdecl::front,rest)) + | _ -> + let (front,rest) = scan_top_decl rest + in (topdecl::front,rest)) (* for debugging *) let l2c l = match Ast0.unwrap l with - Ast0.DECL(_) -> "decl" + Ast0.NONDECL(_) -> "decl" | Ast0.CODE(_) -> "code" + | Ast0.TOPCODE(_) -> "code" | Ast0.FILEINFO(_,_) -> "fileinfo" | Ast0.ERRORWORDS(_) -> "errorwords" | Ast0.OTHER(_) -> "other" -let rec top_level l = - match scan_code l with +let rec top_level must_be_code l = + match scan_code must_be_code l with (code,[]) -> code | (code,rest) -> (match scan_top_decl rest with (top_decls,[]) -> code@top_decls - | (top_decls,rest) -> code @ top_decls @ (top_level rest)) + | (top_decls,rest) -> code @ top_decls @ (top_level must_be_code rest)) + +let clean l = + List.map + (function tl -> + match Ast0.unwrap tl with + Ast0.TOPCODE x -> Ast0.rewrap tl (Ast0.CODE x) + | _ -> tl) + l diff --git a/parsing_cocci/top_level.mli b/parsing_cocci/top_level.mli index 289f997..da2f172 100644 --- a/parsing_cocci/top_level.mli +++ b/parsing_cocci/top_level.mli @@ -22,4 +22,7 @@ *) -val top_level : Ast0_cocci.rule -> Ast0_cocci.rule +val top_level : + bool (* true if must be code *) -> Ast0_cocci.rule -> Ast0_cocci.rule + +val clean : Ast0_cocci.rule -> Ast0_cocci.rule diff --git a/parsing_cocci/unparse_ast0.ml b/parsing_cocci/unparse_ast0.ml index 105476b..9ac3697 100644 --- a/parsing_cocci/unparse_ast0.ml +++ b/parsing_cocci/unparse_ast0.ml @@ -631,8 +631,8 @@ let top_level t = 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) -> + | Ast0.NONDECL(stmt) -> statement "" stmt + | Ast0.CODE(stmt_dots) | Ast0.TOPCODE(stmt_dots) -> dots force_newline (statement "") stmt_dots | Ast0.ERRORWORDS(exps) -> print_string "error words = ["; diff --git a/parsing_cocci/visitor_ast.ml b/parsing_cocci/visitor_ast.ml index 799b3f2..f5519f3 100644 --- a/parsing_cocci/visitor_ast.ml +++ b/parsing_cocci/visitor_ast.ml @@ -485,7 +485,7 @@ let combiner bind option_default 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.NONDECL(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 @@ -1010,7 +1010,7 @@ let rebuilder (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.NONDECL(stmt) -> Ast.NONDECL(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 diff --git a/parsing_cocci/visitor_ast0.ml b/parsing_cocci/visitor_ast0.ml index 81b445d..175153a 100644 --- a/parsing_cocci/visitor_ast0.ml +++ b/parsing_cocci/visitor_ast0.ml @@ -839,12 +839,15 @@ let visitor mode bind option_default let (old_file_n,old_file) = string_mcode old_file in let (new_file_n,new_file) = string_mcode new_file in (bind old_file_n new_file_n,Ast0.FILEINFO(old_file,new_file)) - | Ast0.DECL(statement_dots) -> + | Ast0.NONDECL(statement_dots) -> let (n,statement_dots) = statement statement_dots in - (n,Ast0.DECL(statement_dots)) + (n,Ast0.NONDECL(statement_dots)) | Ast0.CODE(stmt_dots) -> let (stmt_dots_n,stmt_dots) = statement_dots stmt_dots in (stmt_dots_n, Ast0.CODE(stmt_dots)) + | Ast0.TOPCODE(stmt_dots) -> + let (stmt_dots_n,stmt_dots) = statement_dots stmt_dots in + (stmt_dots_n, Ast0.TOPCODE(stmt_dots)) | Ast0.ERRORWORDS(exps) -> let (n,exps) = map_split_bind expression exps in (n, Ast0.ERRORWORDS(exps)) diff --git a/popl/popl.mli b/popl/popl.mli index 1185a79..7716982 100644 --- a/popl/popl.mli +++ b/popl/popl.mli @@ -26,4 +26,4 @@ type cocci_predicate = Lib_engine.predicate * Ast_cocci.meta_name Ast_ctl.modif type formula = (cocci_predicate,Ast_cocci.meta_name, Wrapper_ctl.info) Ast_ctl.generic_ctl -val popl : Ast_cocci.rule -> formula list +val popl : Ast_cocci.rule -> Asttoctl2.top_formula list diff --git a/popl/popltoctl.ml b/popl/popltoctl.ml index 590d071..7bb9787 100644 --- a/popl/popltoctl.ml +++ b/popl/popltoctl.ml @@ -201,4 +201,4 @@ and guard_ctl_dots keep_wit = function (* --------------------------------------------------------------------- *) -let toctl sl = ctl_seq true ctl_true sl +let toctl sl = Asttoctl2.CODE (ctl_seq true ctl_true sl) diff --git a/popl/popltoctl.mli b/popl/popltoctl.mli index c8dd49e..a65c5ca 100644 --- a/popl/popltoctl.mli +++ b/popl/popltoctl.mli @@ -26,4 +26,4 @@ type cocci_predicate = Lib_engine.predicate * Ast_cocci.meta_name Ast_ctl.modif type formula = (cocci_predicate,Ast_cocci.meta_name, Wrapper_ctl.info) Ast_ctl.generic_ctl -val toctl : Ast_popl.sequence -> formula +val toctl : Ast_popl.sequence -> Asttoctl2.top_formula diff --git a/popl09/.depend b/popl09/.depend deleted file mode 100644 index c88af14..0000000 --- a/popl09/.depend +++ /dev/null @@ -1,35 +0,0 @@ -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 -flag_popl.cmo: -flag_popl.cmx: -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/popl.mli b/popl09/popl.mli index 1185a79..7716982 100644 --- a/popl09/popl.mli +++ b/popl09/popl.mli @@ -26,4 +26,4 @@ type cocci_predicate = Lib_engine.predicate * Ast_cocci.meta_name Ast_ctl.modif type formula = (cocci_predicate,Ast_cocci.meta_name, Wrapper_ctl.info) Ast_ctl.generic_ctl -val popl : Ast_cocci.rule -> formula list +val popl : Ast_cocci.rule -> Asttoctl2.top_formula list diff --git a/popl09/popltoctl.ml b/popl09/popltoctl.ml index a2a5c4a..6fe9963 100644 --- a/popl09/popltoctl.ml +++ b/popl09/popltoctl.ml @@ -236,4 +236,4 @@ and do_between_dots keep_wit ba term after = (* --------------------------------------------------------------------- *) -let toctl sl = ctl_seq true ctl_true sl +let toctl sl = Asttoctl2.CODE (ctl_seq true ctl_true sl) diff --git a/popl09/popltoctl.mli b/popl09/popltoctl.mli index c8dd49e..a65c5ca 100644 --- a/popl09/popltoctl.mli +++ b/popl09/popltoctl.mli @@ -26,4 +26,4 @@ type cocci_predicate = Lib_engine.predicate * Ast_cocci.meta_name Ast_ctl.modif type formula = (cocci_predicate,Ast_cocci.meta_name, Wrapper_ctl.info) Ast_ctl.generic_ctl -val toctl : Ast_popl.sequence -> formula +val toctl : Ast_popl.sequence -> Asttoctl2.top_formula diff --git a/python/.depend b/python/.depend deleted file mode 100644 index facc6d2..0000000 --- a/python/.depend +++ /dev/null @@ -1,12 +0,0 @@ -pycocci.cmi: ../parsing_cocci/ast_cocci.cmi ../parsing_c/ast_c.cmo -pycocci_aux.cmi: ../parsing_c/ast_c.cmo -no_pycocci.cmo: pycocci_aux.cmi ../commons/common.cmi ../parsing_c/ast_c.cmo -no_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_cocci/ast_cocci.cmi ../parsing_c/ast_c.cmo pycocci_aux.cmi -pycocci_aux.cmx: ../parsing_c/pretty_print_c.cmx ../commons/common.cmx \ - ../parsing_cocci/ast_cocci.cmx ../parsing_c/ast_c.cmx pycocci_aux.cmi -yes_pycocci.cmo: pycocci_aux.cmi ../globals/flag.cmo ../commons/common.cmi \ - ../parsing_c/ast_c.cmo -yes_pycocci.cmx: pycocci_aux.cmx ../globals/flag.cmx ../commons/common.cmx \ - ../parsing_c/ast_c.cmx diff --git a/scripts/coccicheck/configure b/scripts/coccicheck/configure index 1b7e105..fdb4b16 100755 --- a/scripts/coccicheck/configure +++ b/scripts/coccicheck/configure @@ -97,5 +97,8 @@ clean: distclean: rm -rf \$(RESULTS) +maintclean: distclean + rm Makefile + depend: update EOF diff --git a/tests/SCORE_expected.sexp b/tests/SCORE_expected.sexp index 1a4a3f0..7a6e0dd 100644 --- a/tests/SCORE_expected.sexp +++ b/tests/SCORE_expected.sexp @@ -1,9 +1,9 @@ ((a.res Ok) (a3d.res Ok) (a_and_e.res Ok) (a_and_e_ver1.res Ok) (ab.res Ok) (addaft.res Ok) (addbefore.res Ok) (addbeforeafter.res Ok) (addelse.res Ok) - (addif.res Ok) (addif1.res Ok) (addif2.res Ok) (addtoo.res Ok) - (after_if.res Ok) (anon.res Ok) (ar.res Ok) (arg.res Ok) (argument.res Ok) - (arparam.res Ok) (array_init.res Ok) (array_size.res Ok) (arraysz.res Ok) - (attradd.res Ok) (b1.res Ok) (b2.res Ok) + (addfield.res Ok) (addif.res Ok) (addif1.res Ok) (addif2.res Ok) + (addtoo.res Ok) (after_if.res Ok) (anon.res Ok) (ar.res Ok) (arg.res Ok) + (argument.res Ok) (arparam.res Ok) (array_init.res Ok) (array_size.res Ok) + (arraysz.res Ok) (attradd.res Ok) (b1.res Ok) (b2.res Ok) (bad_iso_example.res (Pb "INCORRECT:diff token: ( VS x\nFile \"tests/bad_iso_example.c\", line 2, column 6, charpos = 19\n around = '(', whole content = if ((x = 3)) return;\nFile \"tests/bad_iso_example.res\", line 2, column 6, charpos = 19\n around = 'x', whole content = if (x) return;\n\n diff (result(<) vs expected_result(>)) = \n @@ -1,4 +1,4 @@\n int main() {\n - if ((x = 3)) return;\n + if (x) return;\n }\n \n")) @@ -126,11 +126,11 @@ "INCORRECT:diff token: init_MUTEX VS mutex_init\nFile \"tests/serio.c\", line 7, column 1, charpos = 130\n around = 'init_MUTEX', whole content = \tinit_MUTEX(&serio->drv_sem);\nFile \"tests/serio.res\", line 7, column 1, charpos = 130\n around = 'mutex_init', whole content = \tmutex_init(&serio->new_lock);\n\n diff (result(<) vs expected_result(>)) = \n @@ -4,5 +4,5 @@\n \n static void serio_init_port(struct serio *serio)\n {\n -\tinit_MUTEX(&serio->drv_sem);\n +\tmutex_init(&serio->new_lock);\n }\n")) (shared_brace.res Ok) (signed.res Ok) (sis.res Ok) (sizeof.res Ok) (sizeof_julia.res Ok) (sizeptr.res Ok) (sizestar.res Ok) (skip.res Ok) - (sp.res Ok) (spaces.res Ok) (spl.res Ok) (static.res Ok) (stm1.res Ok) - (stm10.res Ok) (stm10_ver1.res Ok) (stm2.res Ok) (stm3.res Ok) (stm4.res Ok) - (stm5.res Ok) (stm6.res Ok) (stm7.res Ok) (stm8.res Ok) (stmt.res Ok) - (str_init.res Ok) (strangeorder.res Ok) (strid.res Ok) (strid2.res Ok) - (string.res Ok) (struct.res Ok) (struct_metavar.res Ok) + (sp.res Ok) (spaces.res Ok) (spacing.res Ok) (spl.res Ok) (static.res Ok) + (stm1.res Ok) (stm10.res Ok) (stm10_ver1.res Ok) (stm2.res Ok) (stm3.res Ok) + (stm4.res Ok) (stm5.res Ok) (stm6.res Ok) (stm7.res Ok) (stm8.res Ok) + (stmt.res Ok) (str_init.res Ok) (strangeorder.res Ok) (strid.res Ok) + (strid2.res Ok) (string.res Ok) (struct.res Ok) (struct_metavar.res Ok) (struct_typedef.res Ok) (structfoo.res Ok) (substruct.res Ok) (sw.res Ok) (switch.res Ok) (switchdecl.res Ok) (td.res Ok) (tern.res Ok) (test0.res Ok) (test1.res Ok) (test10.res Ok) (test10_ver1.res Ok) (test11.res Ok) diff --git a/tests/SCORE_expected_orig.sexp b/tests/SCORE_expected_orig.sexp index 1f260db..07f0d75 100644 --- a/tests/SCORE_expected_orig.sexp +++ b/tests/SCORE_expected_orig.sexp @@ -1,9 +1,9 @@ ((a.res Ok) (a3d.res Ok) (a_and_e.res Ok) (a_and_e_ver1.res Ok) (ab.res Ok) (addaft.res Ok) (addbefore.res Ok) (addbeforeafter.res Ok) (addelse.res Ok) - (addif.res Ok) (addif1.res Ok) (addif2.res Ok) (addtoo.res Ok) - (after_if.res Ok) (anon.res Ok) (ar.res Ok) (arg.res Ok) (argument.res Ok) - (arparam.res Ok) (array_init.res Ok) (array_size.res Ok) (arraysz.res Ok) - (attradd.res Ok) (b1.res Ok) (b2.res Ok) + (addfield.res Ok) (addif.res Ok) (addif1.res Ok) (addif2.res Ok) + (addtoo.res Ok) (after_if.res Ok) (anon.res Ok) (ar.res Ok) (arg.res Ok) + (argument.res Ok) (arparam.res Ok) (array_init.res Ok) (array_size.res Ok) + (arraysz.res Ok) (attradd.res Ok) (b1.res Ok) (b2.res Ok) (bad_iso_example.res (Pb "INCORRECT:diff token: ( VS x\nFile \"tests/bad_iso_example.c\", line 2, column 6, charpos = 19\n around = '(', whole content = if ((x = 3)) return;\nFile \"tests/bad_iso_example.res\", line 2, column 6, charpos = 19\n around = 'x', whole content = if (x) return;\n\n diff (result(<) vs expected_result(>)) = \n @@ -1,4 +1,4 @@\n int main() {\n - if ((x = 3)) return;\n + if (x) return;\n }\n \n")) @@ -126,7 +126,7 @@ "INCORRECT:diff token: init_MUTEX VS mutex_init\nFile \"tests/serio.c\", line 7, column 1, charpos = 130\n around = 'init_MUTEX', whole content = \tinit_MUTEX(&serio->drv_sem);\nFile \"tests/serio.res\", line 7, column 1, charpos = 130\n around = 'mutex_init', whole content = \tmutex_init(&serio->new_lock);\n\n diff (result(<) vs expected_result(>)) = \n @@ -4,5 +4,5 @@\n \n static void serio_init_port(struct serio *serio)\n {\n -\tinit_MUTEX(&serio->drv_sem);\n +\tmutex_init(&serio->new_lock);\n }\n")) (shared_brace.res Ok) (signed.res Ok) (sis.res Ok) (sizeof.res Ok) (sizeof_julia.res Ok) (sizeptr.res Ok) (sizestar.res Ok) (skip.res Ok) - (sp.res Ok) (spaces.res Ok) (spl.res Ok) (static.res Ok) + (sp.res Ok) (spaces.res Ok) (spacing.res Ok) (spl.res Ok) (static.res Ok) (stm1.res (Pb "PROBLEM\n exn = Failure(\"no python\")\n")) (stm10.res Ok) (stm10_ver1.res Ok) (stm2.res Ok) (stm3.res Ok) (stm4.res Ok) (stm5.res Ok) (stm6.res Ok) (stm7.res (Pb "PROBLEM\n exn = Failure(\"no python\")\n")) diff --git a/tests/addfield.c b/tests/addfield.c new file mode 100644 index 0000000..64e75df --- /dev/null +++ b/tests/addfield.c @@ -0,0 +1,9 @@ +@@ +identifier I; +expression E; +@@ + +struct i2c_client I = { + .name = E, + .foo = 16 +}; diff --git a/tests/addfield.cocci b/tests/addfield.cocci new file mode 100644 index 0000000..d407075 --- /dev/null +++ b/tests/addfield.cocci @@ -0,0 +1,10 @@ +@@ +identifier I; +expression E; +@@ + +struct i2c_client I = { +- .name = E, +..., ++ .dev = { .name = E, }, +}; diff --git a/tests/addfield.res b/tests/addfield.res new file mode 100644 index 0000000..168c1a0 --- /dev/null +++ b/tests/addfield.res @@ -0,0 +1,11 @@ +@@ +identifier I; +expression E; +@@ + +struct i2c_client I = { + .foo = 16, + .dev = { + .name = E, + }, +}; diff --git a/tests/spacing.c b/tests/spacing.c new file mode 100644 index 0000000..10eba55 --- /dev/null +++ b/tests/spacing.c @@ -0,0 +1,8 @@ +typedef int *foo; + +int f(int x) { + one(); + if (x) { + two(); + } +} diff --git a/tests/spacing.cocci b/tests/spacing.cocci new file mode 100644 index 0000000..a7f81bf --- /dev/null +++ b/tests/spacing.cocci @@ -0,0 +1,24 @@ +@@ +@@ + typedef int *foo; ++void *bar(int *baz) ++{ ++ return baz; ++} + +@@ +identifier f,x; +@@ + f(int x) { ... } ++void *bar(int *baz) ++{ ++ return baz; ++} + +@@ +@@ + +two(); ++if (y) { ++ test(); ++} diff --git a/tests/spacing.res b/tests/spacing.res new file mode 100644 index 0000000..e3b4949 --- /dev/null +++ b/tests/spacing.res @@ -0,0 +1,19 @@ +typedef int *foo; + +void *bar(int *baz) { +return baz; +} + +int f(int x) { + one(); + if (x) { + two(); + if (y) { + test(); + } + } +} + +void *bar(int *baz) { + return baz; +} diff --git a/tests/top.cocci b/tests/top.cocci index 9b073c1..0eda2cb 100644 --- a/tests/top.cocci +++ b/tests/top.cocci @@ -1,5 +1,6 @@ @@ declarer name MODULE_PARM; +declarer name module_param; @@ - MODULE_PARM(...); -- 2.20.1