From 5427db06e325c3c7c572e2e1ebe88a2fd211641c Mon Sep 17 00:00:00 2001 From: Coccinelle Date: Tue, 5 Jul 2011 20:01:21 +0200 Subject: [PATCH] Coccinelle release 1.0.0-rc4 ** 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 - Consider using to be a comment in C++ code. Patch submitted by Jani Monoses. ** 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. - Allow a semantic patch beginning and ending with braces to match the complete body of a function if the braces are not removed and if nothing is added before the first brace or after the last one. - Add -cache_prefix option, to specify where to put cached files. - Allow module_init(foo); to match module_init(foo) (or likewise for any declarer), when no transformation is specified on the semicolon. - Add Coccilib.exit() for ocaml code and cocci.exit() for python code, to abort the treatment of the current file. ** 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 - Improved prevention of transformations on toplevel { ... } from causing changes outside function boundaries; also outside ifs, whiles, etc. Changes are still allowed on { ... } present for other reasons. - Fix bug in include_match that caused everything to halt when all matches were discarded --- changes.txt | 14 +++ cocci.ml | 19 +++- commons/common.ml | 39 +++++-- commons/common.mli | 8 ++ docs/Coccilib.3cocci | 9 +- docs/manual/cocci-python.txt | 19 +++- docs/manual/cocci_syntax.tex | 5 + docs/manual/main_grammar.pdf | Bin 340642 -> 340829 bytes docs/manual/manual.pdf | Bin 445724 -> 445966 bytes docs/manual/options.pdf | Bin 137681 -> 137742 bytes docs/manual/spatch_options.tex | 7 +- engine/asttoctl2.ml | 177 +++++++++++++++++++----------- engine/cocci_vs_c.ml | 43 +++++++- engine/cocci_vs_c.mli | 3 +- engine/ctlcocci_integration.ml | 9 ++ engine/ctltotex.ml | 1 + engine/lib_engine.ml | 2 +- engine/pattern_c.ml | 6 + engine/pretty_print_engine.ml | 1 + engine/transformation_c.ml | 6 + globals/config.ml.in | 2 +- main.ml | 12 +- ocaml/coccilib.ml | 2 + ocaml/coccilib.mli | 2 + ocaml/run_ocamlcocci.ml | 1 + parsing_c/ast_c.ml | 3 +- parsing_c/control_flow_c_build.ml | 2 + parsing_c/flag_parsing_c.ml | 1 + parsing_c/lexer_c.mll | 3 +- parsing_c/parse_c.ml | 3 +- parsing_c/parser_c.mly | 10 +- parsing_c/pretty_print_c.ml | 15 ++- parsing_c/visitor_c.ml | 8 +- python/no_pycocci.ml | 3 + python/pycocci.mli | 1 + python/yes_pycocci.ml | 11 +- tests/SCORE_expected.sexp | 52 +++++---- tests/SCORE_expected_orig.sexp | 55 +++++----- tests/exitc.c | 6 + tests/exitc.cocci | 21 ++++ tests/exitc.res | 6 + tests/exitp.c | 6 + tests/exitp.cocci | 21 ++++ tests/exitp.res | 6 + tests/incpos.c | 5 + tests/incpos.cocci | 55 ++++++++++ tests/incpos.res | 6 + tests/incpos1.c | 4 + tests/incpos1.cocci | 55 ++++++++++ tests/incpos1.res | 5 + tests/smallfn.c | 30 +++++ tests/smallfn.cocci | 8 ++ tests/smallfn.res | 65 +++++++++++ 53 files changed, 689 insertions(+), 164 deletions(-) create mode 100644 tests/exitc.c create mode 100644 tests/exitc.cocci create mode 100644 tests/exitc.res create mode 100644 tests/exitp.c create mode 100644 tests/exitp.cocci create mode 100644 tests/exitp.res create mode 100644 tests/incpos.c create mode 100644 tests/incpos.cocci create mode 100644 tests/incpos.res create mode 100644 tests/incpos1.c create mode 100644 tests/incpos1.cocci create mode 100644 tests/incpos1.res create mode 100644 tests/smallfn.c create mode 100644 tests/smallfn.cocci create mode 100644 tests/smallfn.res diff --git a/changes.txt b/changes.txt index 6ed8ca9..13419aa 100644 --- a/changes.txt +++ b/changes.txt @@ -23,6 +23,7 @@ - Allow /* */ comments as smpl comments, not only as + code - Add support for && (label addresses) - local idexpression metavariable no longer matches static local x +- Consider using to be a comment in C++ code. Patch submitted by Jani Monoses. ** Features: - Preserve spacing before // comments when not at the beginning of a line @@ -32,6 +33,14 @@ - Support - on expression nests - Better handling of the case of a matched declaration that should only be replaced by other top level things. +- Allow a semantic patch beginning and ending with braces to match the + complete body of a function if the braces are not removed and if nothing + is added before the first brace or after the last one. +- Add -cache_prefix option, to specify where to put cached files. +- Allow module_init(foo); to match module_init(foo) (or likewise for any + declarer), when no transformation is specified on the semicolon. +- Add Coccilib.exit() for ocaml code and cocci.exit() for python code, + to abort the treatment of the current file. ** Bugfix: - Corrected parsing of script strings delimited by a single quote. Thanks @@ -58,6 +67,11 @@ - Accept removal of a single declaration, replaced by arbitrary, non-declaration code - smpl_spacing takes into account newlines, indentation +- Improved prevention of transformations on toplevel { ... } from causing + changes outside function boundaries; also outside ifs, whiles, etc. + Changes are still allowed on { ... } present for other reasons. +- Fix bug in include_match that caused everything to halt when all matches + were discarded * 0.2.5 ** Language: diff --git a/cocci.ml b/cocci.ml index ef8c893..82be548 100644 --- a/cocci.ml +++ b/cocci.ml @@ -1249,6 +1249,8 @@ let contains_binding e (_,(r,m),_) = true with Not_found -> false +exception Exited + let python_application mv ve script_vars r = let mv = List.map @@ -1264,7 +1266,9 @@ let python_application mv ve script_vars r = Pycocci.construct_variables mv ve; Pycocci.construct_script_variables script_vars; let _ = Pycocci.pyrun_simplestring (local_python_code ^r.script_code) in - if !Pycocci.inc_match + if !Pycocci.exited + then raise Exited + else if !Pycocci.inc_match then Some (Pycocci.retrieve_script_variables script_vars) else None with Pycocci.Pycocciexception -> @@ -1276,7 +1280,9 @@ let ocaml_application mv ve script_vars r = let script_vals = Run_ocamlcocci.run mv ve script_vars r.scr_rule_info.rulename r.script_code in - if !Coccilib.inc_match + if !Coccilib.exited + then raise Exited + else if !Coccilib.inc_match then Some script_vals else None with e -> (pr2 ("Failure in " ^ r.scr_rule_info.rulename); raise e) @@ -1676,6 +1682,8 @@ let rec bigloop2 rs (ccs: file_info list) = let ccs = ref ccs in let rules_that_have_ever_matched = ref [] in + (try + (* looping over the rules *) rs +> List.iter (fun r -> match r with @@ -1723,10 +1731,13 @@ let rec bigloop2 rs (ccs: file_info list) = then Common.push2 r.scr_rule_info.rulename rules_that_have_ever_matched); - es := newes (*(if newes = [] then init_es else newes)*); + (* just newes can't work, because if one does include_match false + on everything that binds a variable, then nothing is left *) + es := (*newes*) (if newes = [] then init_es else newes) | CocciRuleCocciInfo r -> apply_cocci_rule r rules_that_have_ever_matched - es ccs); + es ccs) + with Exited -> ()); if !Flag.sgrep_mode2 then begin diff --git a/commons/common.ml b/commons/common.ml index a622cee..0be087e 100644 --- a/commons/common.ml +++ b/commons/common.ml @@ -3335,19 +3335,38 @@ let cache_computation ?verbose ?use_cache a b c = let cache_computation_robust2 - file ext_cache + dest_dir file ext_cache (need_no_changed_files, need_no_changed_variables) ext_depend f = - if not (Sys.file_exists file) - then failwith ("can't find: " ^ file); - - let file_cache = (file ^ ext_cache) in - let dependencies_cache = (file ^ ext_depend) in + (if not (Sys.file_exists file) + then failwith ("can't find: " ^ file)); + let (file_cache,dependencies_cache) = + let file_cache = (file ^ ext_cache) in + let dependencies_cache = (file ^ ext_depend) in + match dest_dir with + None -> (file_cache, dependencies_cache) + | Some dir -> + let file_cache = + Filename.concat dir + (if String.get file_cache 0 =*= '/' + then String.sub file_cache 1 ((String.length file_cache) - 1) + else file_cache) in + let dependencies_cache = + Filename.concat dir + (if String.get dependencies_cache 0 =*= '/' + then + String.sub dependencies_cache 1 + ((String.length dependencies_cache) - 1) + else dependencies_cache) in + let _ = Sys.command + (Printf.sprintf "mkdir -p %s" (Filename.dirname file_cache)) in + (file_cache,dependencies_cache) in + let dependencies = (* could do md5sum too *) ((file::need_no_changed_files) +> List.map (fun f -> f, filemtime f), - need_no_changed_variables) + need_no_changed_variables) in if Sys.file_exists dependencies_cache && @@ -3363,7 +3382,11 @@ let cache_computation_robust2 let cache_computation_robust a b c d e = profile_code "Common.cache_computation_robust" (fun () -> - cache_computation_robust2 a b c d e) + cache_computation_robust2 None a b c d e) + +let cache_computation_robust_in_dir a b c d e f = + profile_code "Common.cache_computation_robust" (fun () -> + cache_computation_robust2 a b c d e f) diff --git a/commons/common.mli b/commons/common.mli index 723977b..8d56e01 100644 --- a/commons/common.mli +++ b/commons/common.mli @@ -439,6 +439,14 @@ val cache_computation_robust : (unit -> 'a) -> 'a +val cache_computation_robust_in_dir : + string option (* destination directory *) -> filename -> + string (* extension for marshalled object *) -> + (filename list * 'x) -> + string (* extension for marshalled dependencies *) -> + (unit -> 'a) -> + 'a + val once : ('a -> unit) -> ('a -> unit) diff --git a/docs/Coccilib.3cocci b/docs/Coccilib.3cocci index 7e5956d..5ed518b 100644 --- a/docs/Coccilib.3cocci +++ b/docs/Coccilib.3cocci @@ -143,13 +143,12 @@ the argument is false, discard this environment. By default, the environment is retained. .sp -.I val inc_match +.I val exit : -.B bool ref +.B unit -> unit .sp -True if the environment with respect to which the -ocaml script code is being executed is to be retained for use in -subsequent rules, and false otherwise. +If called, aborts the treatment of the current file. All previous changes +take effect. .sp .I val dir diff --git a/docs/manual/cocci-python.txt b/docs/manual/cocci-python.txt index 08ca830..45b5b1d 100644 --- a/docs/manual/cocci-python.txt +++ b/docs/manual/cocci-python.txt @@ -23,9 +23,22 @@ Here cocci is the interface class for interfacting with Coccinelle's OCaml core. Controlling environments ------------------------ -The python script will be called for each environment generated by Coccinelle with matches to the previous rules. By default, the python script drops each environment unless otherwise is indicated in the script using cocci.include_match(True). - -As a short-cut for registering information that "belongs together", the Output class also provides a register_match method that may be overridden in derived classes. This method can be called like: cocci.register_match(True, [(x, 'Array size'), (y, 'Array index size')]). Here the True is automatically passed on to include_match (so one could use False in order to drop the environment, but still print information). In the GTK frontend, this will result in the "Array index size" information being shown as a child node to the "Array size". +The python script will be called for each environment generated by +Coccinelle with matches to the previous rules. By default, the python +script keeps each environment unless otherwise is indicated in the script +using cocci.include_match(False). + +As a short-cut for registering information that "belongs together", the +Output class also provides a register_match method that may be overridden +in derived classes. This method can be called like: +cocci.register_match(True, [(x, 'Array size'), (y, 'Array index +size')]). Here the True is automatically passed on to include_match (so one +could use False in order to drop the environment, but still print +information). In the GTK frontend, this will result in the "Array index +size" information being shown as a child node to the "Array size". + +cocci.exit() simply aborts the treatment of the current file. Previously +made changes do take effect. Output methods for the python scripts ------------------------------------- diff --git a/docs/manual/cocci_syntax.tex b/docs/manual/cocci_syntax.tex index 9c7e01d..307d1b5 100644 --- a/docs/manual/cocci_syntax.tex +++ b/docs/manual/cocci_syntax.tex @@ -126,6 +126,11 @@ behavior. Using \NT{disable-iso} with the given name disables this behavior. not have to be specified in the SmPL code, but may be present in the C code. \item \KW{value\_format}: Integers in various formats, e.g., 1 and 0x1, are considered to be equivalent in the matching process. +\item \KW{optional\_declarer\_semicolon}: Some declarers (top-level terms + that look like function calls but serve to declare some variable) don't + require a semicolon. This isomorphism allows a SmPL declarer with a semicolon + to match such a C declarer, if no transformation is specified on the SmPL + semicolon. \item \KW{comm\_assoc}: An expression of the form \NT{exp} \NT{bin\_op} \KW{...}, where \NT{bin\_op} is commutative and associative, is considered to match any top-level sequence of \NT{bin\_op} operators diff --git a/docs/manual/main_grammar.pdf b/docs/manual/main_grammar.pdf index 6561629b85e942d86fd09316a26d4243cb1edfe1..5b8a6aebb6127207365b5a6ef54a5a9ffe8a1c9a 100644 GIT binary patch delta 26804 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 RV0whH1zcU5wfU{U{{am2W{Cg* delta 25656 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 diff --git a/docs/manual/manual.pdf b/docs/manual/manual.pdf index 19cfa01a6ff32ff3512d4d7b79a50fdfd556658e..2bb3cbf9f5b55849b7d3445e4a0c27daf96958af 100644 GIT binary patch delta 38610 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 diff --git a/docs/manual/options.pdf b/docs/manual/options.pdf index a8d4eb4a40c24df23d75519684179c7522b5ed67..beb5abc8e380a8a52b967f0c26ab4f83affb99a1 100644 GIT binary patch delta 12511 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 delta 12376 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 diff --git a/docs/manual/spatch_options.tex b/docs/manual/spatch_options.tex index ae7d1ac..93f38d2 100644 --- a/docs/manual/spatch_options.tex +++ b/docs/manual/spatch_options.tex @@ -256,8 +256,11 @@ is none, the constant is assumed to be a signed integer. If there is only patch/match run faster, at the cost of not finding matches that wrap around loops.} -\developer{-use\_cache} Use preparsed versions of the C files that are -stored in a cache. +\developer{-use\_cache}{Use preparsed versions of the C files that are +stored in a cache.} + +\developer{-cache\_prefix}{Specify the directory in which to store +preparsed versions of the C files. This sets {-use\_cache}} \developer{-debug\_cpp, -debug\_lexer, -debug\_etdt, -debug\_typedef}{Various options for debugging the C parser.} diff --git a/engine/asttoctl2.ml b/engine/asttoctl2.ml index b5abb46..2f856b0 100644 --- a/engine/asttoctl2.ml +++ b/engine/asttoctl2.ml @@ -167,6 +167,7 @@ let predmaker guard pred label = CTL.Pred pred 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 unsbrpred = predmaker false (Lib_engine.UnsafeBrace, 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) @@ -374,6 +375,8 @@ than dots or a nest. *) type after = After of formula | Guard of formula | Tail | End | VeryEnd +type top = Top | NotTop + let a2n = function After x -> Guard x | a -> a let print_ctl x = @@ -997,7 +1000,7 @@ let ifthen ifheader branch ((afvs,_,_,_) as aft) after (* no point to put a label on truepred etc; it is local to this construct so it must have the same label *) make_seq guard - [truepred None; recurse branch Tail new_quantified new_mquantified + [truepred None; recurse branch NotTop Tail new_quantified new_mquantified (Some (lv,used)) llabel slabel guard] in let after_pred = aftpred None in let or_cases after_branch = @@ -1072,7 +1075,7 @@ let ifthenelse ifheader branch1 els branch2 ((afvs,_,_,_) as aft) after let used = ref false in let true_branch = make_seq guard - [truepred None; recurse branch1 Tail new_quantified new_mquantified + [truepred None; recurse branch1 NotTop Tail new_quantified new_mquantified (Some (lv,used)) llabel slabel guard] in let false_branch = make_seq guard @@ -1080,7 +1083,7 @@ let ifthenelse ifheader branch1 els branch2 ((afvs,_,_,_) as aft) after quantify guard (Common.minus_set (Ast.get_fvs els) new_quantified) (header_match None guard els); - recurse branch2 Tail new_quantified new_mquantified + recurse branch2 NotTop Tail new_quantified new_mquantified (Some (lv,used)) llabel slabel guard] in let after_pred = aftpred None in let or_cases after_branch = @@ -1123,7 +1126,7 @@ let forwhile header body ((afvs,_,_,_) as aft) after let body = make_seq guard [inlooppred None; - recurse body Tail new_quantified new_mquantified + recurse body NotTop Tail new_quantified new_mquantified (Some (lv,used)) (Some (lv,used)) None guard] in let after_pred = loopfallpred None in let or_cases after_branch = ctl_or body after_branch in @@ -1610,7 +1613,7 @@ and whencond_false e label guard quantified = (* --------------------------------------------------------------------- *) (* the main translation loop *) -let rec statement_list stmt_list after quantified minus_quantified +let rec statement_list stmt_list top after quantified minus_quantified label llabel slabel dots_before guard = let isdots x = (* include Disj to be on the safe side *) @@ -1619,11 +1622,12 @@ let rec statement_list stmt_list after quantified minus_quantified 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 + let rec loop top quantified minus_quantified dots_before + label llabel slabel = function ([],_,_) -> (match after with After f -> f | _ -> CTL.True) | ([e],_,_) -> - statement e after quantified minus_quantified + statement e top after quantified minus_quantified (compute_label label e dots_before) llabel slabel guard | (e::sl,fv::fvs,mfv::mfvs) -> @@ -1636,7 +1640,7 @@ let rec statement_list stmt_list after quantified minus_quantified let new_mquantified = Common.union_set munqshared minus_quantified in quantify guard unqshared - (statement e + (statement e top (After (let (label1,llabel1,slabel1) = match Ast.unwrap e with @@ -1645,13 +1649,13 @@ let rec statement_list stmt_list after quantified minus_quantified Ast.Goto _ -> (None,None,None) | _ -> (label,llabel,slabel)) | _ -> (label,llabel,slabel) in - loop new_quantified new_mquantified (isdots e) + loop NotTop 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 + loop top 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" @@ -1659,7 +1663,7 @@ let rec statement_list stmt_list after quantified minus_quantified (* llabel is the label of the enclosing loop and slabel is the label of the enclosing switch *) -and statement stmt after quantified minus_quantified +and statement stmt top after quantified minus_quantified label llabel slabel guard = let ctl_au = ctl_au CTL.NONSTRICT in let ctl_ax = ctl_ax CTL.NONSTRICT in @@ -1849,7 +1853,7 @@ and statement stmt after quantified minus_quantified (ctl_or (if !exists = Exists then CTL.False else (aftpred label)) (quantify guard b2fvs - (statement_list body + (statement_list body NotTop (After (make_seq_after end_brace after)) new_quantified2 new_mquantified2 (Some (lv,ref true)) @@ -1890,7 +1894,7 @@ and statement stmt after quantified minus_quantified (make_match empty_rbrace) (ctl_ax (* skip the destination label *) (quantify guard b2fvs - (statement_list body End + (statement_list body NotTop End new_quantified2 new_mquantified2 None llabel slabel true guard)))] in let pattern3 = @@ -1908,7 +1912,7 @@ and statement stmt after quantified minus_quantified (* want AF even for sgrep *) (CTL.AF(CTL.FORWARD,CTL.STRICT,end_brace)))) (quantify guard b2fvs - (statement_list body Tail + (statement_list body NotTop Tail new_quantified2 new_mquantified2 None(*no label because past the goto*) llabel slabel false guard))])) in @@ -1930,12 +1934,17 @@ and statement stmt after quantified minus_quantified | Ast.Disj(stmt_dots_list) -> (* list shouldn't be empty *) (*ctl_and seems pointless, disjuncts see label too (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)) + let subformulas = + List.map + (function sl -> + statement_list sl top after quantified minus_quantified label + llabel slabel true guard) + stmt_dots_list in + let safe_subformulas = + match top with + Top -> List.map2 protect_top_level stmt_dots_list subformulas + | NotTop -> subformulas in + List.fold_left ctl_seqor CTL.False safe_subformulas | Ast.Nest(starter,stmt_dots,ender,whencode,multi,bef,aft) -> (* label in recursive call is None because label check is already @@ -1961,17 +1970,20 @@ and statement stmt after quantified minus_quantified quantify guard bfvs (let dots_pattern = - statement_list stmt_dots (a2n after) new_quantified minus_quantified + statement_list stmt_dots top (a2n after) + new_quantified minus_quantified label(*None*) llabel slabel true guard in dots_and_nests multi (Some dots_pattern) whencode bef aft dot_code after label (process_bef_aft new_quantified minus_quantified label(*None*) llabel slabel true) - (function x -> - statement_list x Tail new_quantified minus_quantified label(*None*) + (function x -> (* for when code *) + statement_list x NotTop Tail + new_quantified minus_quantified label(*None*) llabel slabel true true) - (function x -> - statement x Tail new_quantified minus_quantified label(*None*) + (function x -> (* for when code *) + statement x NotTop Tail + new_quantified minus_quantified label(*None*) llabel slabel true) guard quantified (function x -> Ast.set_fvs [] (Ast.rewrap stmt x))) @@ -1987,10 +1999,11 @@ and statement stmt after quantified minus_quantified 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 + statement_list x NotTop Tail quantified minus_quantified None llabel slabel true true) (function x -> - statement x Tail quantified minus_quantified None llabel slabel true) + statement x NotTop Tail quantified minus_quantified + None llabel slabel true) guard quantified (function x -> Ast.set_fvs [] (Ast.rewrap stmt x)) @@ -2100,7 +2113,7 @@ and statement stmt after quantified minus_quantified then (CTL.True,CTL.False) else let res = - statement_list decls Tail + statement_list decls NotTop Tail new2_quantified new2_mquantified (Some (lv,used)) llabel None false(*?*) guard in (res,res) in @@ -2129,7 +2142,7 @@ and statement stmt after quantified minus_quantified let new3_quantified = union b1fvs new2_quantified in let new3_mquantified = union mb1fvs new2_mquantified in let body = - statement_list body Tail + statement_list body NotTop Tail new3_quantified new3_mquantified (Some (lv,used)) llabel (Some (lv,used)) false(*?*) guard in quantify guard b1fvs (make_seq [case_header; body]) @@ -2236,7 +2249,7 @@ and statement stmt after quantified minus_quantified Some (CTL.AndAny (CTL.FORWARD,guard_to_strict guard,start_brace, - statement_list stmt_dots + statement_list stmt_dots NotTop (* discards match on right brace, but don't need it *) (Guard (make_seq_after end_brace after)) new_quantified3 new_mquantified3 @@ -2273,7 +2286,8 @@ and statement stmt after quantified minus_quantified Ast.WhenAlways(s) -> prev | Ast.WhenNot(sl) -> let x = - statement_list sl Tail + statement_list sl + NotTop Tail new_quantified3 new_mquantified3 label llabel slabel @@ -2291,7 +2305,7 @@ and statement stmt after quantified minus_quantified function Ast.WhenAlways(s) -> let x = - statement s Tail + statement s NotTop Tail new_quantified3 new_mquantified3 label llabel slabel true in @@ -2342,7 +2356,7 @@ and statement stmt after quantified minus_quantified make_seq [start_brace; quantify guard b3fvs - (statement_list body + (statement_list body NotTop (After (make_seq_after end_brace after)) new_quantified3 new_mquantified3 None llabel slabel false guard)] in @@ -2361,7 +2375,7 @@ and statement stmt after quantified minus_quantified | _ -> failwith "not possible" in let define_header = quantify guard hfvs (make_match header) in let body_code = - statement_list body after + statement_list body NotTop after (Common.union_set bfvs quantified) (Common.union_set mbfvs minus_quantified) None llabel slabel true guard in @@ -2383,7 +2397,7 @@ and do_between_dots stmt term after quantified minus_quantified Ast.AddingBetweenDots (brace_term,n) | Ast.DroppingBetweenDots (brace_term,n) -> let match_brace = - statement brace_term after quantified minus_quantified + statement brace_term NotTop 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 @@ -2405,11 +2419,64 @@ and process_bef_aft quantified minus_quantified label llabel slabel guard = 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 + statement s NotTop Tail quantified minus_quantified + label llabel slabel guard | Ast.Other_dots d -> - statement_list d Tail quantified minus_quantified + statement_list d NotTop Tail quantified minus_quantified label llabel slabel true guard +and protect_top_level stmt_dots formula = + 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_non_context_brace = + (* None = No danger + Some false = OK except on function braces + Some true = Never OK *) + match Ast.undots stmt_dots with + d::ds -> + (match Ast.unwrap d with + Ast.Seq(before,body,after) -> + let beforemc = + match Ast.unwrap before with + Ast.SeqStart(obr) -> Ast.get_mcodekind obr + | _ -> failwith "bad seq" in + let aftermc = + match Ast.unwrap after with + Ast.SeqEnd(cbr) -> Ast.get_mcodekind cbr + | _ -> failwith "bad seq"in + (match (beforemc,aftermc) with + (* safe cases *) + (Ast.CONTEXT(_,(Ast.NOTHING|Ast.AFTER _)), + Ast.CONTEXT(_,(Ast.NOTHING|Ast.BEFORE _))) -> None + | (Ast.MINUS(_,_,_,Ast.NOREPLACEMENT), + Ast.MINUS(_,_,_,Ast.NOREPLACEMENT)) + when List.length (Ast.undots body) = 1 -> Some false (*ok on if*) + (* unsafe, can't be allowed to match fn top *) + | _ -> Some true) + | _ -> None) + | _ -> None in + if starts_with_dots + then (* EX because there is a loop on enter/top *) + ctl_and CTL.NONSTRICT (toppred None) (ctl_ex formula) + else + match starts_with_non_context_brace with + None -> formula + | Some false -> + ctl_and CTL.NONSTRICT + (ctl_not(CTL.EX(CTL.BACKWARD,funpred None))) + formula + | Some true -> + ctl_and CTL.NONSTRICT + (ctl_not(CTL.EX(CTL.BACKWARD,unsbrpred None))) + formula + + (* --------------------------------------------------------------------- *) (* cleanup: convert AX to EX for pdots. Concretely: AX(A[...] & E[...]) becomes AX(A[...]) & EX(E[...]) @@ -2480,41 +2547,17 @@ let top_level name ((ua,pos),fua) (fuas,t) = let unopt = elim_opt.V.rebuilder_statement stmt in let unopt = preprocess_dots_e unopt in let formula = - cleanup(statement unopt VeryEnd quantified [] None None None false) in + cleanup + (statement unopt Top 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 - 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 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) in - ((function x -> CODE x), formula) + statement_list unopt Top VeryEnd quantified [] None None None + false false in + let clean_formula = cleanup (protect_top_level stmt_dots formula) in + ((function x -> CODE x), clean_formula) | Ast.ERRORWORDS(exps) -> failwith "not supported errorwords" in wrap (quantify false quantified formula) diff --git a/engine/cocci_vs_c.ml b/engine/cocci_vs_c.ml index a5e297c..ba77dbc 100644 --- a/engine/cocci_vs_c.ml +++ b/engine/cocci_vs_c.ml @@ -691,7 +691,9 @@ module type PARAM = 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) + val value_format_flag : (bool -> tin -> 'x tout) -> (tin -> 'x tout) + val optional_declarer_semicolon_flag : + (bool -> tin -> 'x tout) -> (tin -> 'x tout) end @@ -1774,7 +1776,7 @@ and (declaration: (A.mcodekind * bool * A.declaration,B.declaration) matcher) = error ii "More than one variable in the declaration, and so it cannot be transformed. Check that there is no transformation on the type or the ;" - | A.MacroDecl (sa,lpa,eas,rpa,enda), B.MacroDecl ((sb,ebs),ii) -> + | A.MacroDecl (sa,lpa,eas,rpa,enda), B.MacroDecl ((sb,ebs,true),ii) -> let (iisb, lpb, rpb, iiendb, iifakestart, iistob) = (match ii with | iisb::lpb::rpb::iiendb::iifakestart::iisto -> @@ -1797,10 +1799,41 @@ and (declaration: (A.mcodekind * bool * A.declaration,B.declaration) matcher) = return ( (mckstart, allminus, (A.MacroDecl (sa,lpa,eas,rpa,enda)) +> A.rewrap decla), - (B.MacroDecl ((sb,ebs), + (B.MacroDecl ((sb,ebs,true), [iisb;lpb;rpb;iiendb;iifakestart] ++ iistob)) )))))))) + | A.MacroDecl (sa,lpa,eas,rpa,enda), B.MacroDecl ((sb,ebs,false),ii) -> + X.optional_declarer_semicolon_flag (fun optional_declarer_semicolon -> + match mcodekind enda, optional_declarer_semicolon with + A.CONTEXT (_,A.NOTHING), true -> + let (iisb, lpb, rpb, iifakestart, iistob) = + (match ii with + | iisb::lpb::rpb::iifakestart::iisto -> + (iisb,lpb,rpb,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 -> + 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,false), + [iisb;lpb;rpb;iifakestart] ++ iistob)) + ))))))) + | _ -> fail) + | _, (B.MacroDecl _ |B.DeclList _) -> fail @@ -4131,8 +4164,9 @@ let rec (rule_elem_node: (A.rule_elem, Control_flow_c.node) matcher) = (* todo?: print a warning at least ? *) | _, F.CaseRange _ | _, F.Asm _ - | _, F.MacroTop _ -> fail2() + | _, F.MacroTop _ + -> Printf.printf "have macrotop\n"; fail2() | _, (F.IfdefEndif _|F.IfdefElse _|F.IfdefHeader _) -> fail2 () @@ -4155,4 +4189,3 @@ let rec (rule_elem_node: (A.rule_elem, Control_flow_c.node) matcher) = ) end - diff --git a/engine/cocci_vs_c.mli b/engine/cocci_vs_c.mli index f5ff82e..cf0f53c 100644 --- a/engine/cocci_vs_c.mli +++ b/engine/cocci_vs_c.mli @@ -201,7 +201,8 @@ module type PARAM = 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) - + val optional_declarer_semicolon_flag : + (bool -> tin -> 'x tout) -> (tin -> 'x tout) end diff --git a/engine/ctlcocci_integration.ml b/engine/ctlcocci_integration.ml index fbb0680..65ed6a9 100644 --- a/engine/ctlcocci_integration.ml +++ b/engine/ctlcocci_integration.ml @@ -143,6 +143,15 @@ let (labels_for_ctl: string list (* dropped isos *) -> | Lib_engine.ErrorExit, F.ErrorExit -> [nodei, (p,[])] | Lib_engine.Goto, F.Goto(_,_,_) -> [nodei, (p,[])] + | Lib_engine.UnsafeBrace, node -> + (* cases where it it not safe to put something on the outer side + of braces *) + (match node with + F.FunHeader _ | F.DoHeader _ | F.TrueNode _ | F.Else _ + | F.InLoopNode _ (* while, for *) | F.SwitchHeader _ -> + [nodei, (p,[])] + | _ -> []) + | Lib_engine.InLoop , _ -> [] | Lib_engine.TrueBranch , _ -> [] | Lib_engine.FalseBranch, _ -> [] diff --git a/engine/ctltotex.ml b/engine/ctltotex.ml index b9308be..13ec0ac 100644 --- a/engine/ctltotex.ml +++ b/engine/ctltotex.ml @@ -269,6 +269,7 @@ let pred2c = function | Lib_engine.LoopFallThrough -> ("\\msf{LoopFallThrough}",15) | Lib_engine.Return -> ("\\msf{Return}",6) | Lib_engine.FunHeader -> ("\\msf{FunHeader}",9) + | Lib_engine.UnsafeBrace -> ("\\msf{UnsafeBrace}",11) | Lib_engine.Top -> ("\\msf{Top}",3) | Lib_engine.Exit -> ("\\msf{Exit}",4) | Lib_engine.ErrorExit -> ("\\msf{ErrorExit}",9) diff --git a/engine/lib_engine.ml b/engine/lib_engine.ml index 7db4a94..5919dc9 100644 --- a/engine/lib_engine.ml +++ b/engine/lib_engine.ml @@ -34,7 +34,7 @@ type predicate = | After (* pointer to the code after an if or while *) | FallThrough | LoopFallThrough | Return (* any exit from the current function *) - | FunHeader | Top | Exit | ErrorExit | Goto + | FunHeader | UnsafeBrace | Top | Exit | ErrorExit | Goto | Paren of Ast_cocci.meta_name | Match of Ast_cocci.rule_elem | Label of Ast_cocci.meta_name diff --git a/engine/pattern_c.ml b/engine/pattern_c.ml index 122717b..bf874c9 100644 --- a/engine/pattern_c.ml +++ b/engine/pattern_c.ml @@ -34,6 +34,7 @@ type xinfo = { optional_storage_iso : bool; optional_qualifier_iso : bool; value_format_iso : bool; + optional_declarer_semicolon_iso : bool; } module XMATCH = struct @@ -536,6 +537,9 @@ module XMATCH = struct let value_format_flag f = fun tin -> f (tin.extra.value_format_iso) tin + let optional_declarer_semicolon_flag f = fun tin -> + f (tin.extra.optional_declarer_semicolon_iso) tin + (* ------------------------------------------------------------------------*) (* Tokens *) (* ------------------------------------------------------------------------*) @@ -566,6 +570,8 @@ let match_re_node2 dropped_isos a b binding0 = 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); + optional_declarer_semicolon_iso = + not(List.mem "optional_declarer_semicolon" dropped_isos); }; XMATCH.binding = []; XMATCH.binding0 = binding0; diff --git a/engine/pretty_print_engine.ml b/engine/pretty_print_engine.ml index a1b5d37..6c964c9 100644 --- a/engine/pretty_print_engine.ml +++ b/engine/pretty_print_engine.ml @@ -107,6 +107,7 @@ let rec pp_predicate = function | FallThrough -> pp "FallThrough" | LoopFallThrough -> pp "LoopFallThrough" | Return -> pp "Return" + | UnsafeBrace -> pp "UnsafeBrace" | FunHeader -> pp "FunHeader" | Top -> pp "Top" | ErrorExit -> pp "ErrorExit" diff --git a/engine/transformation_c.ml b/engine/transformation_c.ml index 6270e73..631673c 100644 --- a/engine/transformation_c.ml +++ b/engine/transformation_c.ml @@ -35,6 +35,7 @@ type xinfo = { optional_storage_iso : bool; optional_qualifier_iso : bool; value_format_iso : bool; + optional_declarer_semicolon_iso : bool; current_rule_name : string; (* used for errors *) index : int list (* witness tree indices *) } @@ -103,6 +104,9 @@ module XTRANS = struct let value_format_flag f = fun tin -> f (tin.extra.value_format_iso) tin + let optional_declarer_semicolon_flag f = fun tin -> + f (tin.extra.optional_declarer_semicolon_iso) tin + let mode = Cocci_vs_c.TransformMode (* ------------------------------------------------------------------------*) @@ -608,6 +612,8 @@ let (transform2: string (* rule name *) -> string list (* dropped_isos *) -> 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); + optional_declarer_semicolon_iso = + not(List.mem "optional_declarer_semicolon" dropped_isos); current_rule_name = rule_name; index = []; } in diff --git a/globals/config.ml.in b/globals/config.ml.in index c254ac2..b80e672 100644 --- a/globals/config.ml.in +++ b/globals/config.ml.in @@ -1,4 +1,4 @@ -let version = "1.0.0-rc3" +let version = "1.0.0-rc4" let path = try (Sys.getenv "COCCINELLE_HOME") diff --git a/main.ml b/main.ml index 81cacc7..e56383c 100644 --- a/main.ml +++ b/main.ml @@ -345,7 +345,7 @@ let short_options = [ " guess what"; "-date", Arg.Unit (fun () -> - pr2 "version: $Date: 2011/03/14 21:16:17 $"; + pr2 "version: $Date: 2011/06/23 11:11:16 $"; raise (Common.UnixExit 0) ), " guess what"; @@ -614,6 +614,11 @@ let other_options = [ [ "-use_cache", Arg.Set Flag_parsing_c.use_cache, " use .ast_raw pre-parsed cached C file"; + "-cache_prefix", + Arg.String (function s -> + Flag_parsing_c.cache_prefix := Some s; + Flag_parsing_c.use_cache := true), + " directory of cached ASTs, sets -use_cache"; (* could use Flag_parsing_c.options_pad instead *) ]; @@ -872,7 +877,7 @@ let main_action xs = groups +> List.map (function Kbuild.Group xs -> xs) ) in - + let infiles = match (!distrib_index,!distrib_max) with (None,None) -> infiles @@ -940,7 +945,8 @@ let main_action xs = (cocci_infos,res)) in let outfiles = List.concat outfiles in (match Iteration.get_pending_instance() with - None -> (x,xs,cocci_infos,outfiles) + None -> + (x,xs,cocci_infos,outfiles) | Some (files,virt_rules,virt_ids) -> if outfiles = [] or outfiles = [] or not !FC.show_diff then diff --git a/ocaml/coccilib.ml b/ocaml/coccilib.ml index 19e2e98..8b09fbf 100644 --- a/ocaml/coccilib.ml +++ b/ocaml/coccilib.ml @@ -31,4 +31,6 @@ let fcts : (string, param_type list -> string ref list -> unit) Hashtbl.t = let inc_match = ref true let include_match x = inc_match := x +let exited = ref true +let exit _ = exited := true let dir () = !Flag.dir diff --git a/ocaml/coccilib.mli b/ocaml/coccilib.mli index 7f3c10d..c79d8ef 100644 --- a/ocaml/coccilib.mli +++ b/ocaml/coccilib.mli @@ -29,4 +29,6 @@ val fcts : (string, param_type list -> string ref list -> unit) Hashtbl.t val inc_match : bool ref val include_match : bool -> unit +val exited : bool ref +val exit : unit -> unit val dir : unit -> string diff --git a/ocaml/run_ocamlcocci.ml b/ocaml/run_ocamlcocci.ml index 2c57cc9..ce5fa89 100644 --- a/ocaml/run_ocamlcocci.ml +++ b/ocaml/run_ocamlcocci.ml @@ -66,6 +66,7 @@ let run mv ve script_vars name code = (* call the function *) Coccilib.include_match true; + Coccilib.exited := false; let fn = try Hashtbl.find Coccilib.fcts name with Not_found -> failwith (Printf.sprintf "%s not found" name) in diff --git a/parsing_c/ast_c.ml b/parsing_c/ast_c.ml index a1e9760..450b5a9 100644 --- a/parsing_c/ast_c.ml +++ b/parsing_c/ast_c.ml @@ -515,7 +515,8 @@ and statement = statementbis wrap3 and declaration = | DeclList of onedecl wrap2 (* , *) list wrap (* ; fakestart sto *) (* cppext: *) - | MacroDecl of (string * argument wrap2 list) wrap (* fakestart *) + (* bool is true if there is a ; at the end *) + | MacroDecl of (string * argument wrap2 list * bool) wrap (* fakestart *) and onedecl = { v_namei: (name * v_init) option; diff --git a/parsing_c/control_flow_c_build.ml b/parsing_c/control_flow_c_build.ml index b346791..a706003 100644 --- a/parsing_c/control_flow_c_build.ml +++ b/parsing_c/control_flow_c_build.ml @@ -350,6 +350,8 @@ let rec (aux_statement: (nodei option * xinfo) -> statement -> nodei option) = let endi = !g#add_node endnode in if xi.compound_caller = Statement then + (* Problem! This edge is only created if the block does not + have return on all execution paths. *) (let afteri = !g +> add_node AfterNode lbl "[after]" in !g#add_arc ((newi, afteri), Direct); !g#add_arc ((afteri, endi), Direct)); diff --git a/parsing_c/flag_parsing_c.ml b/parsing_c/flag_parsing_c.ml index 8852ffa..9a6114d 100644 --- a/parsing_c/flag_parsing_c.ml +++ b/parsing_c/flag_parsing_c.ml @@ -193,6 +193,7 @@ let diff_lines = ref (None : string option) (* number of lines of context *) (* for parse_c *) let use_cache = ref false +let cache_prefix = ref (None : string option) let cmdline_flags_other () = [ diff --git a/parsing_c/lexer_c.mll b/parsing_c/lexer_c.mll index 0d88443..12f42d5 100644 --- a/parsing_c/lexer_c.mll +++ b/parsing_c/lexer_c.mll @@ -171,7 +171,8 @@ let keyword_table = Common.hash_of_list [ let cpp_keyword_table = Common.hash_of_list [ "new", (fun ii -> Tnew ii); - "delete",(fun ii -> Tdelete ii) ] + "delete",(fun ii -> Tdelete ii); + "using", (fun ii -> TComment ii) ] let error_radix s = ("numeric " ^ s ^ " constant contains digits beyond the radix:") diff --git a/parsing_c/parse_c.ml b/parsing_c/parse_c.ml index 5bfe014..c47afda 100644 --- a/parsing_c/parse_c.ml +++ b/parsing_c/parse_c.ml @@ -1080,7 +1080,8 @@ let parse_cache file = (* could add some of the flags of flag_parsing_c.ml *) [] in - Common.cache_computation_robust + Common.cache_computation_robust_in_dir + !Flag_parsing_c.cache_prefix file ".ast_raw" (need_no_changed_files, need_no_changed_variables) ".depend_raw" (fun () -> parse_print_error_heuristic None None file) diff --git a/parsing_c/parser_c.mly b/parsing_c/parser_c.mly index 54e22c3..e0e1831 100644 --- a/parsing_c/parser_c.mly +++ b/parsing_c/parser_c.mly @@ -1339,13 +1339,13 @@ decl2: | TMacroDecl TOPar argument_list TCPar TPtVirg { function _ -> - MacroDecl ((fst $1, $3), [snd $1;$2;$4;$5;fakeInfo()]) } + MacroDecl ((fst $1, $3, true), [snd $1;$2;$4;$5;fakeInfo()]) } | Tstatic TMacroDecl TOPar argument_list TCPar TPtVirg { function _ -> - MacroDecl ((fst $2, $4), [snd $2;$3;$5;$6;fakeInfo();$1]) } + MacroDecl ((fst $2, $4, true), [snd $2;$3;$5;$6;fakeInfo();$1]) } | Tstatic TMacroDeclConst TMacroDecl TOPar argument_list TCPar TPtVirg { function _ -> - MacroDecl ((fst $3, $5), [snd $3;$4;$6;$7;fakeInfo();$1;$2])} + MacroDecl ((fst $3, $5, true), [snd $3;$4;$6;$7;fakeInfo();$1;$2])} /*(*-----------------------------------------------------------------------*)*/ @@ -1849,13 +1849,13 @@ cpp_other: *)*/ | identifier TOPar argument_list TCPar TPtVirg { - Declaration (MacroDecl ((fst $1, $3), [snd $1;$2;$4;$5;fakeInfo()])) + Declaration(MacroDecl((fst $1, $3, true), [snd $1;$2;$4;$5;fakeInfo()])) (* old: MacroTop (fst $1, $3, [snd $1;$2;$4;$5]) *) } /*(* TCParEOL to fix the end-of-stream bug of ocamlyacc *)*/ | identifier TOPar argument_list TCParEOL - { MacroTop (fst $1, $3, [snd $1;$2;$4;fakeInfo()]) } + { Declaration (MacroDecl ((fst $1, $3, false), [snd $1;$2;$4;fakeInfo()])) } /*(* ex: EXPORT_NO_SYMBOLS; *)*/ | identifier TPtVirg { EmptyDef [snd $1;$2] } diff --git a/parsing_c/pretty_print_c.ml b/parsing_c/pretty_print_c.ml index a1bbcc1..8029f09 100644 --- a/parsing_c/pretty_print_c.ml +++ b/parsing_c/pretty_print_c.ml @@ -899,7 +899,7 @@ let mk_pretty_printers pr_elem iivirg; - | MacroDecl ((s, es), iis::lp::rp::iiend::ifakestart::iisto) -> + | MacroDecl ((s, es, true), iis::lp::rp::iiend::ifakestart::iisto) -> pr_elem ifakestart; iisto +> List.iter pr_elem; (* static and const *) pr_elem iis; @@ -913,6 +913,19 @@ let mk_pretty_printers pr_elem rp; pr_elem iiend; + | MacroDecl ((s, es, false), iis::lp::rp::ifakestart::iisto) -> + pr_elem ifakestart; + iisto +> List.iter pr_elem; (* static and const *) + pr_elem iis; + pr_elem lp; + es +> List.iter (fun (e, opt) -> + assert (List.length opt <= 1); + opt +> List.iter pr_elem; + pp_argument e; + ); + + pr_elem rp; + | (DeclList (_, _) | (MacroDecl _)) -> raise Impossible diff --git a/parsing_c/visitor_c.ml b/parsing_c/visitor_c.ml index 9d6d761..ca8841f 100644 --- a/parsing_c/visitor_c.ml +++ b/parsing_c/visitor_c.ml @@ -498,7 +498,7 @@ and vk_decl = fun bigf d -> iif ii; vk_onedecl bigf x; ); - | MacroDecl ((s, args),ii) -> + | MacroDecl ((s, args, ptvg),ii) -> iif ii; vk_argument_list bigf args; in f (k, bigf) d @@ -1291,11 +1291,11 @@ and vk_decl_s = fun bigf d -> match decl with | DeclList (xs, ii) -> DeclList (List.map aux xs, iif ii) - | MacroDecl ((s, args),ii) -> + | MacroDecl ((s, args, ptvg),ii) -> MacroDecl ((s, - args +> List.map (fun (e,ii) -> vk_argument_s bigf e, iif ii) - ), + args +> List.map (fun (e,ii) -> vk_argument_s bigf e, iif ii), + ptvg), iif ii) diff --git a/python/no_pycocci.ml b/python/no_pycocci.ml index 793ed33..7f3f485 100644 --- a/python/no_pycocci.ml +++ b/python/no_pycocci.ml @@ -62,9 +62,12 @@ let pycocci_instantiate_class fqn args = failwith "no python" (* end python interaction *) let inc_match = ref false +let exited = ref false let include_match v = failwith "no python" +let sp_exit _ = failwith "no python" + let build_method (mname, camlfunc, args) pymodule classx classdict = failwith "no python" diff --git a/python/pycocci.mli b/python/pycocci.mli index f0778bd..6c2b0c6 100644 --- a/python/pycocci.mli +++ b/python/pycocci.mli @@ -29,6 +29,7 @@ val construct_variables : val construct_script_variables : Ast_cocci.meta_name list -> unit val pyrun_simplestring : string -> int val inc_match : bool ref +val exited : bool ref val retrieve_script_variables : Ast_cocci.meta_name list -> string list exception Pycocciexception val set_coccifile : string -> unit diff --git a/python/yes_pycocci.ml b/python/yes_pycocci.ml index 6c01be9..39e0468 100644 --- a/python/yes_pycocci.ml +++ b/python/yes_pycocci.ml @@ -115,6 +115,7 @@ let pycocci_instantiate_class fqn args = (* end python interaction *) let inc_match = ref true +let exited = ref false let include_match v = let truth = pyobject_istrue (pytuple_getitem (v, 1)) in @@ -122,6 +123,10 @@ let include_match v = inc_match := truth != 0; _pycocci_none () +let sp_exit _ = + exited := true; + _pycocci_none () + 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 @@ -186,7 +191,8 @@ let pycocci_init () = coccinelle_module := pymodule_new "coccinelle"; let mx = !coccinelle_module in let (cd, cx) = build_class "Cocci" (!Flag.pyoutput) - [("include_match", include_match, (pynull())); + [("exit", sp_exit, (pynull())); + ("include_match", include_match, (pynull())); ("has_env_binding", has_environment_binding, (pynull()))] mx in pyoutputinstance := cx; pyoutputdict := cd; @@ -206,12 +212,13 @@ let added_variables = ref [] let build_classes env = let _ = pycocci_init () in inc_match := true; + exited := false; the_environment := env; let mx = !coccinelle_module in let dict = pymodule_getdict mx in List.iter (function - "include_match" | "has_env_binding" -> () + "include_match" | "has_env_binding" | "exit" -> () | name -> let v = pydict_delitemstring(dict,name) in check_int_return_value v) diff --git a/tests/SCORE_expected.sexp b/tests/SCORE_expected.sexp index 7a6e0dd..e23d249 100644 --- a/tests/SCORE_expected.sexp +++ b/tests/SCORE_expected.sexp @@ -42,9 +42,10 @@ (double_lines.res Ok) (double_switch.res Ok) (doublepos.res Ok) (doubleswitch.res Ok) (doundo.res Ok) (dowhile.res Ok) (dropf.res Ok) (dropparam.res Ok) (eb1.res Ok) (edots.res Ok) (edots_ver1.res Ok) - (empty.res Ok) (end_commas.res Ok) (endif.res Ok) (enum.res Ok) (exp.res Ok) - (expnest.res Ok) (expopt.res Ok) (expopt2.res Ok) (expopt3.res Ok) - (expopt3_ver1.res Ok) (expopt3_ver2.res Ok) (fields.res Ok) + (empty.res Ok) (end_commas.res Ok) (endif.res Ok) (enum.res Ok) + (exitc.res Ok) (exitp.res (Pb "PROBLEM\n exn = Failure(\"no python\")\n")) + (exp.res Ok) (expnest.res Ok) (expopt.res Ok) (expopt2.res Ok) + (expopt3.res Ok) (expopt3_ver1.res Ok) (expopt3_ver2.res Ok) (fields.res Ok) (fieldsmin.res Ok) (find_long.res Ok) (fix_flow_need.res Ok) (fn_todo.res Ok) (fnptr.res Ok) (fnret.res Ok) (fnty.res Ok) (four.res Ok) (foura.res Ok) (fp.res Ok) (fsh.res Ok) (fun.res Ok) @@ -61,10 +62,13 @@ (Pb "INCORRECT:diff token: x VS 12\nFile \"tests/incdir.c\", line 4, column 6, charpos = 46\n around = 'x', whole content = foo(x);\nFile \"tests/incdir.res\", line 4, column 6, charpos = 46\n around = '12', whole content = foo(12);\n\n diff (result(<) vs expected_result(>)) = \n @@ -1,5 +1,5 @@\n #include \"sub/incdir2.c\"\n \n int main () {\n - foo(x);\n + foo(12);\n }\n")) (incl.res Ok) (inclifdef.res Ok) (include.res Ok) - (incompatible_value.res Ok) (inherited.res Ok) (inherited_ver1.res Ok) - (inhmet.res Ok) (inhpos.res Ok) (initializer.res Ok) - (initializer_many_fields.res Ok) (inline.res Ok) (insdef.res Ok) - (isococci.res Ok) (isotest.res Ok) (isotest2.res Ok) (iterator.res Ok) + (incompatible_value.res Ok) + (incpos.res (Pb "PROBLEM\n exn = Failure(\"no python\")\n")) + (incpos1.res (Pb "PROBLEM\n exn = Failure(\"no python\")\n")) + (inherited.res Ok) (inherited_ver1.res Ok) (inhmet.res Ok) (inhpos.res Ok) + (initializer.res Ok) (initializer_many_fields.res Ok) (inline.res Ok) + (insdef.res Ok) (isococci.res Ok) (isotest.res Ok) (isotest2.res Ok) + (iterator.res Ok) (jloop1.res (Pb "PROBLEM\n exn = Failure(\"minus: parse error: \\n = File \\\"tests/jloop1.cocci\\\", line 10, column 3, charpos = 129\\n around = '...>', whole content = ...>\\n\")\n")) @@ -126,23 +130,23 @@ "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) (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) - (test11_ver1.res Ok) (test12.res Ok) (test2.res Ok) (test3.res Ok) - (test4.res Ok) (test5.res Ok) (test5_ver1.res Ok) (test6.res Ok) - (test7.res Ok) (test8.res Ok) (test9.res Ok) (test_s.res Ok) - (test_unsigned_meta.res Ok) (three_types.res Ok) (threea.res Ok) - (top.res Ok) (topdec.res Ok) (topdec_ver1.res Ok) (topdec_ver2.res Ok) - (toplevel_macrostmt.res Ok) (toplevel_struct.res Ok) (tup.res Ok) - (twoproto.res Ok) (ty.res Ok) (ty1.res Ok) (ty_tyexp.res Ok) (tydisj.res Ok) - (tyex.res Ok) (type.res Ok) (type1.res Ok) (type_annotated.res Ok) - (type_ver1.res Ok) + (smallfn.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) (test11_ver1.res Ok) + (test12.res Ok) (test2.res Ok) (test3.res Ok) (test4.res Ok) (test5.res Ok) + (test5_ver1.res Ok) (test6.res Ok) (test7.res Ok) (test8.res Ok) + (test9.res Ok) (test_s.res Ok) (test_unsigned_meta.res Ok) + (three_types.res Ok) (threea.res Ok) (top.res Ok) (topdec.res Ok) + (topdec_ver1.res Ok) (topdec_ver2.res Ok) (toplevel_macrostmt.res Ok) + (toplevel_struct.res Ok) (tup.res Ok) (twoproto.res Ok) (ty.res Ok) + (ty1.res Ok) (ty_tyexp.res Ok) (tydisj.res Ok) (tyex.res Ok) (type.res Ok) + (type1.res Ok) (type_annotated.res Ok) (type_ver1.res Ok) (type_ver2.res (Pb "INCORRECT:PB parsing only in generated-file\n diff (result(<) vs expected_result(>)) = \n @@ -1,5 +1,5 @@\n int foo() {\n - int[10] *x;\n + int *x[10];\n return 0;\n }\n \n")) diff --git a/tests/SCORE_expected_orig.sexp b/tests/SCORE_expected_orig.sexp index 07f0d75..95c8d2f 100644 --- a/tests/SCORE_expected_orig.sexp +++ b/tests/SCORE_expected_orig.sexp @@ -42,9 +42,10 @@ (double_lines.res Ok) (double_switch.res Ok) (doublepos.res Ok) (doubleswitch.res Ok) (doundo.res Ok) (dowhile.res Ok) (dropf.res Ok) (dropparam.res Ok) (eb1.res Ok) (edots.res Ok) (edots_ver1.res Ok) - (empty.res Ok) (end_commas.res Ok) (endif.res Ok) (enum.res Ok) (exp.res Ok) - (expnest.res Ok) (expopt.res Ok) (expopt2.res Ok) (expopt3.res Ok) - (expopt3_ver1.res Ok) (expopt3_ver2.res Ok) (fields.res Ok) + (empty.res Ok) (end_commas.res Ok) (endif.res Ok) (enum.res Ok) + (exitc.res Ok) (exitp.res (Pb "PROBLEM\n exn = Failure(\"no python\")\n")) + (exp.res Ok) (expnest.res Ok) (expopt.res Ok) (expopt2.res Ok) + (expopt3.res Ok) (expopt3_ver1.res Ok) (expopt3_ver2.res Ok) (fields.res Ok) (fieldsmin.res Ok) (find_long.res Ok) (fix_flow_need.res Ok) (fn_todo.res Ok) (fnptr.res Ok) (fnret.res Ok) (fnty.res Ok) (four.res Ok) (foura.res Ok) (fp.res Ok) (fsh.res Ok) (fun.res Ok) @@ -61,10 +62,13 @@ (Pb "INCORRECT:diff token: x VS 12\nFile \"tests/incdir.c\", line 4, column 6, charpos = 46\n around = 'x', whole content = foo(x);\nFile \"tests/incdir.res\", line 4, column 6, charpos = 46\n around = '12', whole content = foo(12);\n\n diff (result(<) vs expected_result(>)) = \n @@ -1,5 +1,5 @@\n #include \"sub/incdir2.c\"\n \n int main () {\n - foo(x);\n + foo(12);\n }\n")) (incl.res Ok) (inclifdef.res Ok) (include.res Ok) - (incompatible_value.res Ok) (inherited.res Ok) (inherited_ver1.res Ok) - (inhmet.res Ok) (inhpos.res Ok) (initializer.res Ok) - (initializer_many_fields.res Ok) (inline.res Ok) (insdef.res Ok) - (isococci.res Ok) (isotest.res Ok) (isotest2.res Ok) (iterator.res Ok) + (incompatible_value.res Ok) + (incpos.res (Pb "PROBLEM\n exn = Failure(\"no python\")\n")) + (incpos1.res (Pb "PROBLEM\n exn = Failure(\"no python\")\n")) + (inherited.res Ok) (inherited_ver1.res Ok) (inhmet.res Ok) (inhpos.res Ok) + (initializer.res Ok) (initializer_many_fields.res Ok) (inline.res Ok) + (insdef.res Ok) (isococci.res Ok) (isotest.res Ok) (isotest2.res Ok) + (iterator.res Ok) (jloop1.res (Pb "PROBLEM\n exn = Failure(\"minus: parse error: \\n = File \\\"tests/jloop1.cocci\\\", line 10, column 3, charpos = 129\\n around = '...>', whole content = ...>\\n\")\n")) @@ -126,24 +130,25 @@ "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) (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")) - (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) (test11_ver1.res Ok) (test12.res Ok) - (test2.res Ok) (test3.res Ok) (test4.res Ok) (test5.res Ok) - (test5_ver1.res Ok) (test6.res Ok) (test7.res Ok) (test8.res Ok) - (test9.res Ok) (test_s.res Ok) (test_unsigned_meta.res Ok) - (three_types.res Ok) (threea.res Ok) (top.res Ok) (topdec.res Ok) - (topdec_ver1.res Ok) (topdec_ver2.res Ok) (toplevel_macrostmt.res Ok) - (toplevel_struct.res Ok) (tup.res Ok) (twoproto.res Ok) (ty.res Ok) - (ty1.res Ok) (ty_tyexp.res Ok) (tydisj.res Ok) (tyex.res Ok) (type.res Ok) - (type1.res Ok) (type_annotated.res Ok) (type_ver1.res Ok) + (smallfn.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")) (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) + (test11_ver1.res Ok) (test12.res Ok) (test2.res Ok) (test3.res Ok) + (test4.res Ok) (test5.res Ok) (test5_ver1.res Ok) (test6.res Ok) + (test7.res Ok) (test8.res Ok) (test9.res Ok) (test_s.res Ok) + (test_unsigned_meta.res Ok) (three_types.res Ok) (threea.res Ok) + (top.res Ok) (topdec.res Ok) (topdec_ver1.res Ok) (topdec_ver2.res Ok) + (toplevel_macrostmt.res Ok) (toplevel_struct.res Ok) (tup.res Ok) + (twoproto.res Ok) (ty.res Ok) (ty1.res Ok) (ty_tyexp.res Ok) (tydisj.res Ok) + (tyex.res Ok) (type.res Ok) (type1.res Ok) (type_annotated.res Ok) + (type_ver1.res Ok) (type_ver2.res (Pb "INCORRECT:PB parsing only in generated-file\n diff (result(<) vs expected_result(>)) = \n @@ -1,5 +1,5 @@\n int foo() {\n - int[10] *x;\n + int *x[10];\n return 0;\n }\n \n")) diff --git a/tests/exitc.c b/tests/exitc.c new file mode 100644 index 0000000..06b89c3 --- /dev/null +++ b/tests/exitc.c @@ -0,0 +1,6 @@ +int main () { + f(a1); + f(a2); + f(done); + f(a4); +} diff --git a/tests/exitc.cocci b/tests/exitc.cocci new file mode 100644 index 0000000..dba50cd --- /dev/null +++ b/tests/exitc.cocci @@ -0,0 +1,21 @@ +@r@ +identifier x; +@@ + +-f(x); ++g(x); + +@script:ocaml@ +x << r.x; +@@ + +if x = "done" then + Coccilib.exit() + +@@ +identifier x; +@@ + +g(x ++ ,y + ); diff --git a/tests/exitc.res b/tests/exitc.res new file mode 100644 index 0000000..7e7ade8 --- /dev/null +++ b/tests/exitc.res @@ -0,0 +1,6 @@ +int main () { + g(a1); + g(a2); + g(done); + g(a4); +} diff --git a/tests/exitp.c b/tests/exitp.c new file mode 100644 index 0000000..06b89c3 --- /dev/null +++ b/tests/exitp.c @@ -0,0 +1,6 @@ +int main () { + f(a1); + f(a2); + f(done); + f(a4); +} diff --git a/tests/exitp.cocci b/tests/exitp.cocci new file mode 100644 index 0000000..542f11f --- /dev/null +++ b/tests/exitp.cocci @@ -0,0 +1,21 @@ +@r@ +identifier x; +@@ + +-f(x); ++g(x); + +@script:python@ +x << r.x; +@@ + +if ("%s" % x) == "done": + cocci.exit() + +@@ +identifier x; +@@ + +g(x ++ ,y + ); diff --git a/tests/exitp.res b/tests/exitp.res new file mode 100644 index 0000000..7e7ade8 --- /dev/null +++ b/tests/exitp.res @@ -0,0 +1,6 @@ +int main () { + g(a1); + g(a2); + g(done); + g(a4); +} diff --git a/tests/incpos.c b/tests/incpos.c new file mode 100644 index 0000000..531d878 --- /dev/null +++ b/tests/incpos.c @@ -0,0 +1,5 @@ +#include +#include "two" +#include +#include "four" +#include diff --git a/tests/incpos.cocci b/tests/incpos.cocci new file mode 100644 index 0000000..c7f8d76 --- /dev/null +++ b/tests/incpos.cocci @@ -0,0 +1,55 @@ +@initialize:python@ + +first = 0 +second = 0 + +@first_hdr@ +position p; +@@ + +#include <...>@p + +@script:python@ +p << first_hdr.p; +@@ + +if first == 0: + print "keeping first hdr %s" % (p[0].line) + first = int(p[0].line) +else: + print "dropping first hdr" + cocci.include_match(False) + +@second_hdr@ +position p; +@@ + +#include "..."@p + +@script:python@ +p << second_hdr.p; +@@ + +if int(p[0].line) > first and first != 0: + print "dropping second hdr" + cocci.include_match(False) +else: + if second == 0: + print "keeping second hdr %s because of %d" % (p[0].line,first) + second = int(p[0].line) + else: + print "dropping second hdr" + cocci.include_match(False) + +@done@ +position second_hdr.p; +@@ + ++#include +#include "..."@p + +@depends on never done@ +@@ + ++#include +#include <...> diff --git a/tests/incpos.res b/tests/incpos.res new file mode 100644 index 0000000..2a057cd --- /dev/null +++ b/tests/incpos.res @@ -0,0 +1,6 @@ +#include +#include +#include "two" +#include +#include "four" +#include diff --git a/tests/incpos1.c b/tests/incpos1.c new file mode 100644 index 0000000..7580e12 --- /dev/null +++ b/tests/incpos1.c @@ -0,0 +1,4 @@ +#include "two" +#include +#include "four" +#include diff --git a/tests/incpos1.cocci b/tests/incpos1.cocci new file mode 100644 index 0000000..c7f8d76 --- /dev/null +++ b/tests/incpos1.cocci @@ -0,0 +1,55 @@ +@initialize:python@ + +first = 0 +second = 0 + +@first_hdr@ +position p; +@@ + +#include <...>@p + +@script:python@ +p << first_hdr.p; +@@ + +if first == 0: + print "keeping first hdr %s" % (p[0].line) + first = int(p[0].line) +else: + print "dropping first hdr" + cocci.include_match(False) + +@second_hdr@ +position p; +@@ + +#include "..."@p + +@script:python@ +p << second_hdr.p; +@@ + +if int(p[0].line) > first and first != 0: + print "dropping second hdr" + cocci.include_match(False) +else: + if second == 0: + print "keeping second hdr %s because of %d" % (p[0].line,first) + second = int(p[0].line) + else: + print "dropping second hdr" + cocci.include_match(False) + +@done@ +position second_hdr.p; +@@ + ++#include +#include "..."@p + +@depends on never done@ +@@ + ++#include +#include <...> diff --git a/tests/incpos1.res b/tests/incpos1.res new file mode 100644 index 0000000..fb8b046 --- /dev/null +++ b/tests/incpos1.res @@ -0,0 +1,5 @@ +#include +#include "two" +#include +#include "four" +#include diff --git a/tests/smallfn.c b/tests/smallfn.c new file mode 100644 index 0000000..201e37b --- /dev/null +++ b/tests/smallfn.c @@ -0,0 +1,30 @@ +int main () { + if (y) { + one(); + } + else { + two(); + } + while (y) { + one(); + } + do { + one(); + } while(y); + switch (y) { + case 12:one(); + case 27:two(); + } +{ + one(); + } +} + +int main () { + if (y) { + one(); + } + else { + two(); + } +} diff --git a/tests/smallfn.cocci b/tests/smallfn.cocci new file mode 100644 index 0000000..42a44ab --- /dev/null +++ b/tests/smallfn.cocci @@ -0,0 +1,8 @@ +@@ +statement S; +@@ + + { + S + } ++foo(); diff --git a/tests/smallfn.res b/tests/smallfn.res new file mode 100644 index 0000000..fccb7a0 --- /dev/null +++ b/tests/smallfn.res @@ -0,0 +1,65 @@ +int main () { + if (y) { + { + one(); + foo(); + } + foo(); +} + else { + { + two(); + foo(); + } + foo(); +} +foo(); + while (y) { + { + one(); + foo(); + } + foo(); +} +foo(); + { + do { + one(); + foo(); + } + foo(); while(y); + foo(); +} + switch (y) { + case 12: + foo();one(); + foo(); + case 27: + foo();two(); + foo(); + } + foo(); +{ + one(); + foo(); + } + foo(); +} + +int main () { + if (y) { + { + one(); + foo(); + } + foo(); +} + else { + { + two(); + foo(); + } + foo(); +} +foo(); +} -- 2.20.1