Metavariables for Scripts

## 3 Metavariables for Scripts

Metavariables for scripts can only be inherited from transformation rules. In the spirit of scripting languages such as Python that use dynamic typing, metavariables for scripts do not include type declarations. A script is only run if all metavariables are bound, either by inheritance or by a default value given with =.

script_metavariables | ::= | @ script: language [rulename] [depends on dep] @ script_metadecl * @@
| | | @ initialize: language [depends on dep] @ script_virt_metadecl * @@
| | | @ finalize: language [depends on dep] @ script_virt_metadecl * @@
language | ::= | python
| | | ocaml
script_metadecl | ::= | id << rulename_id.id ;
| | | id << rulename_id.id = "..." ;
| | | id << rulename_id.id = [] ;
| | | id ;
script_virt_metadecl | ::= | id << virtual.id ;

Currently, the only scripting languages that are supported are Python and OCaml, indicated using python and ocaml, respectively. The set of available scripting languages may be extended at some point.

Script rules declared with initialize are run before the treatment of any file. Script rules declared with finalize are run when the treatment of all of the files has completed. There can be at most one of each per scripting language. Initialize and finalize script rules do not have access to SmPL metavariables. Nevertheless, a finalize script rule can access any variables initialized by the other script rules, allowing information to be transmitted from the matching process to the finalize rule.

Initialize and finalize rules do have access to virtual metavariables, using the usual syntax. As for other scripting language rules, the rule is not run (and essentially does not exist) if some of the required virtual metavariables are not bound. In OCaml, a warning is printed in this case. An example is found in demos/initvirt.cocci.

A script metavariable that does not specify an origin, using <<, is newly declared by the script. This metavariable should be assigned to a string and can be inherited by subsequent rules as an identifier. In Python, the assignment of such a metavariable x should refer to the metavariable as coccinelle.x. Examples are in the files demos/pythontococci.cocci and demos/camltococci.cocci.

In an OCaml script, the following extended form of script_metadecl may be used:

script_metadecl’ | ::= | (id,id) << rulename_id.id ;
| | | id << rulename_id.id ;
| | | id ;

In a declaration of the form (id,id) << rulename_id.id ;, the left component of (id,id) receives a string representation of the value of the inherited metavariable while the right component receives its abstract syntax tree. The file parsing_c/ast_c.ml in the Coccinelle implementation gives some information about the structure of the abstract syntax tree. Either the left or right component may be replaced by `_`, indicating that the string representation or abstract syntax trees representation is not wanted, respectively.

The abstract syntax tree of a metavariable declared using metavariable is not available.

Script metavariables can have default values. This is only allowed if the abstract syntax tree of the metavariable is not requested. The default value of a position metavariable is written as []. The default value of any other kind of metavariable is a string. There is no control that the string actually represents the kind of term represented by the metavariable. Normally, a script rule is only applied if all of the metavariables have values. If default values are provided, then the script rule is only applied if all of the metavariables for which there are no default values have values. See demos/defaultscript.cocci for examples of the use of this feature.