- 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
- 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
- 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:
true
with Not_found -> false
+exception Exited
+
let python_application mv ve script_vars r =
let mv =
List.map
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 ->
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)
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
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
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 &&
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)
(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)
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
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
-------------------------------------
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
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.}
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)
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 =
(* 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 =
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
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 =
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
(* --------------------------------------------------------------------- *)
(* 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 *)
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) ->
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
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"
(* 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
(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))
(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 =
(* 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
| 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
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)))
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))
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
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])
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
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
function
Ast.WhenAlways(s) ->
let x =
- statement s Tail
+ statement s NotTop Tail
new_quantified3
new_mquantified3
label llabel slabel true in
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
| _ -> 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
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
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[...])
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)
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
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 ->
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
(* 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 ()
)
end
-
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
| 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, _ -> []
| 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)
| 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
optional_storage_iso : bool;
optional_qualifier_iso : bool;
value_format_iso : bool;
+ optional_declarer_semicolon_iso : bool;
}
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 *)
(* ------------------------------------------------------------------------*)
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;
| FallThrough -> pp "FallThrough"
| LoopFallThrough -> pp "LoopFallThrough"
| Return -> pp "Return"
+ | UnsafeBrace -> pp "UnsafeBrace"
| FunHeader -> pp "FunHeader"
| Top -> pp "Top"
| ErrorExit -> pp "ErrorExit"
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 *)
}
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
(* ------------------------------------------------------------------------*)
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
-let version = "1.0.0-rc3"
+let version = "1.0.0-rc4"
let path =
try (Sys.getenv "COCCINELLE_HOME")
" 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";
[
"-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 *)
];
groups +> List.map (function Kbuild.Group xs -> xs)
)
in
-
+
let infiles =
match (!distrib_index,!distrib_max) with
(None,None) -> infiles
(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
let inc_match = ref true
let include_match x = inc_match := x
+let exited = ref true
+let exit _ = exited := true
let dir () = !Flag.dir
val inc_match : bool ref
val include_match : bool -> unit
+val exited : bool ref
+val exit : unit -> unit
val dir : unit -> string
(* 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
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;
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));
(* for parse_c *)
let use_cache = ref false
+let cache_prefix = ref (None : string option)
let cmdline_flags_other () =
[
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:")
(* 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)
| 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])}
/*(*-----------------------------------------------------------------------*)*/
*)*/
| 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] }
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;
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
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
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)
(* 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"
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
(* 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
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
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;
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)
(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)
(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"))
"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"))
(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)
(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"))
"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"))
--- /dev/null
+int main () {
+ f(a1);
+ f(a2);
+ f(done);
+ f(a4);
+}
--- /dev/null
+@r@
+identifier x;
+@@
+
+-f(x);
++g(x);
+
+@script:ocaml@
+x << r.x;
+@@
+
+if x = "done" then
+ Coccilib.exit()
+
+@@
+identifier x;
+@@
+
+g(x
++ ,y
+ );
--- /dev/null
+int main () {
+ g(a1);
+ g(a2);
+ g(done);
+ g(a4);
+}
--- /dev/null
+int main () {
+ f(a1);
+ f(a2);
+ f(done);
+ f(a4);
+}
--- /dev/null
+@r@
+identifier x;
+@@
+
+-f(x);
++g(x);
+
+@script:python@
+x << r.x;
+@@
+
+if ("%s" % x) == "done":
+ cocci.exit()
+
+@@
+identifier x;
+@@
+
+g(x
++ ,y
+ );
--- /dev/null
+int main () {
+ g(a1);
+ g(a2);
+ g(done);
+ g(a4);
+}
--- /dev/null
+#include <one>
+#include "two"
+#include <three>
+#include "four"
+#include <five>
--- /dev/null
+@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 <foo.h>
+#include "..."@p
+
+@depends on never done@
+@@
+
++#include <foo.h>
+#include <...>
--- /dev/null
+#include <foo.h>
+#include <one>
+#include "two"
+#include <three>
+#include "four"
+#include <five>
--- /dev/null
+#include "two"
+#include <three>
+#include "four"
+#include <five>
--- /dev/null
+@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 <foo.h>
+#include "..."@p
+
+@depends on never done@
+@@
+
++#include <foo.h>
+#include <...>
--- /dev/null
+#include <foo.h>
+#include "two"
+#include <three>
+#include "four"
+#include <five>
--- /dev/null
+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();
+ }
+}
--- /dev/null
+@@
+statement S;
+@@
+
+ {
+ S
+ }
++foo();
--- /dev/null
+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();
+}