It is possible to iterate Coccinelle, giving the subsequent iterations a different set of virtual rules or virtual identifier bindings. And example is found in demos/iteration.cocci. The example shown there is as follows:
virtual after_start @initialize:ocaml@ let tbl = Hashtbl.create(100) let add_if_not_present from f file = try let _ = Hashtbl.find tbl (f,file) in () with Not_found -> Hashtbl.add tbl (f,file) file; let it = new iteration() in (match file with Some fl -> it#set_files [fl] | None -> ()); it#add_virtual_rule After_start; it#add_virtual_identifier Err_ptr_function f; it#register()
The virtual rule after_start is used to distinguish between the first iteration (in which it is not considered to have matched) and all others. This is done by not mentioning after_start in the command line, but adding it on each iteration.
The main code for performing the iteration is found in the function add_if_not_present, between the lines calling new iteration and register. New iteration creates a structure representing the new iteration. set_files sets the list of files to be considered on the new iteration. If this function is not called, the new iteration treats the same files as the current iteration. add_virtual_rule A has the same effect as putting -D a on the command line. Note that the first letter of the rule name is capitalized, although this is not done elsewhere. add_virtual_identifier X v has the same effect as putting -D x=v on the command line. Note again the case change. extend_virtual_identifiers() (not shown) preserves all virtual identifiers of the current iteration that are not overridden by calls to add_virtual_identifier. Finally, the call to register queues the collected information to trigger a new iteration at some time in the future.
Modification is not allowed when using iteration. Thus, it is required to use the --no-show-diff, unless the semantic patch contains *s (a semantic match rather than a semantic patch).
The remainder of the code above uses a hash table to ensure that the same information is not enqueued more than once. Coccinelle itself provides no support for this.