2 * Copyright 2010, INRIA, University of Copenhagen
3 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
4 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
5 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
6 * This file is part of Coccinelle.
8 * Coccinelle is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, according to version 2 of the License.
12 * Coccinelle is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
20 * The authors reserve the right to distribute this or future versions of
21 * Coccinelle under other licenses.
26 * Copyright 2010, INRIA, University of Copenhagen
27 * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
28 * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
29 * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
30 * This file is part of Coccinelle.
32 * Coccinelle is free software: you can redistribute it and/or modify
33 * it under the terms of the GNU General Public License as published by
34 * the Free Software Foundation, according to version 2 of the License.
36 * Coccinelle is distributed in the hope that it will be useful,
37 * but WITHOUT ANY WARRANTY; without even the implied warranty of
38 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 * GNU General Public License for more details.
41 * You should have received a copy of the GNU General Public License
42 * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
44 * The authors reserve the right to distribute this or future versions of
45 * Coccinelle under other licenses.
49 (*****************************************************************************)
51 (*****************************************************************************)
53 (* This module was introduced to factorize code between
54 * pattern.ml and transformation.ml. In both cases we need
55 * to "compare" a piece of C with a piece of Cocci, and depending
56 * if we want just to pattern or transform, we perform different
57 * actions on the tokens. So, the common code is in this module
58 * and the module specific actions are in pattern.ml and transformation.ml.
60 * We could have used a visitor approach as in visitor_c but I prefer
61 * this time to use a functor. The specific actions are passed
62 * via a module to the functor.
64 * If the functor is too complex too understand, you can look at
65 * the comments in pattern.ml and transformation.ml to look at
66 * how it was done before, which may help to understand how
69 * You can also look at the papers on parser combinators in haskell
70 * (cf a pearl by meijer in ICFP) to understand our monadic
71 * approach to matching/unifying.
75 (* should be used as less as possible. Most of the time the code in
76 * cocci_vs_c should be the same if we pattern or transform *)
77 type mode
= PatternMode
| TransformMode
79 (* used in both pattern and transform, in envf *)
80 val equal_metavarval
:
81 Ast_c.metavar_binding_kind
-> Ast_c.metavar_binding_kind
-> bool
83 (* for inherited metavariables. no declaration link on expressions *)
84 val equal_inh_metavarval
:
85 Ast_c.metavar_binding_kind
-> Ast_c.metavar_binding_kind
-> bool
87 (*****************************************************************************)
88 (* The parameter of the functor (the specific actions) *)
89 (*****************************************************************************)
97 (* a matcher between 'a' and 'b' take 'a' and 'b' in parameter,
98 * and "something" (tin; a state that is threaded across calls),
99 * and return a new 'a' and 'b' encapsulated in "something" (tout)
101 type ('a
, 'b
) matcher
= 'a
-> 'b
-> tin
-> ('a
* 'b
) tout
105 (* -------------------------------------------------------------------- *)
106 (* The monadic combinators *)
107 (* -------------------------------------------------------------------- *)
109 (* it kinds of take a matcher in parameter, and another matcher,
110 * and returns a matcher, so =~ matcher -> matcher -> matcher
113 (tin
-> ('a
* 'b
) tout
) ->
114 ('a
-> 'b
-> tin
-> ('c
* 'd
) tout
) ->
115 tin
-> ('c
* 'd
) tout
117 val return
: 'a
* 'b
-> tin
-> ('a
* 'b
) tout
118 val fail
: tin
-> ('a
* 'b
) tout
120 val ( >||> ) : (tin
-> 'a tout
) -> (tin
-> 'a tout
) -> tin
-> 'a tout
121 val ( >|+|> ) : (tin
-> 'a tout
) -> (tin
-> 'a tout
) -> tin
-> 'a tout
122 val ( >&&> ) : (tin
-> bool) -> (tin
-> 'a tout
) -> tin
-> 'a tout
124 (* -------------------------------------------------------------------- *)
126 (* -------------------------------------------------------------------- *)
127 val tokenf
: ('a
Ast_cocci.mcode
, Ast_c.info
) matcher
128 val tokenf_mck
: (Ast_cocci.mcodekind
, Ast_c.info
) matcher
130 (* -------------------------------------------------------------------- *)
131 (* Distr_f functions, to tag a range of tokens *)
132 (* -------------------------------------------------------------------- *)
135 (Ast_cocci.meta_name
Ast_cocci.mcode
, Ast_c.expression
) matcher
138 (Ast_cocci.meta_name
Ast_cocci.mcode
,
139 (Ast_c.argument
, Ast_c.il
) Common.either list
)
143 (Ast_cocci.meta_name
Ast_cocci.mcode
, Ast_c.fullType
) matcher
146 (Ast_cocci.meta_name
Ast_cocci.mcode
,
147 (Ast_c.parameterType
, Ast_c.il
) Common.either list
)
150 (Ast_cocci.meta_name
Ast_cocci.mcode
, Ast_c.parameterType
) matcher
153 (Ast_cocci.meta_name
Ast_cocci.mcode
, Ast_c.initialiser
) matcher
155 (Ast_cocci.meta_name
Ast_cocci.mcode
,
156 (Ast_c.initialiser
, Ast_c.il
) Common.either list
) matcher
158 (Ast_cocci.meta_name
Ast_cocci.mcode
, Ast_c.declaration
) matcher
160 (Ast_cocci.meta_name
Ast_cocci.mcode
, Ast_c.field
) matcher
163 (Ast_cocci.meta_name
Ast_cocci.mcode
, Control_flow_c.node
) matcher
165 val distrf_define_params
:
166 (Ast_cocci.meta_name
Ast_cocci.mcode
,
167 (string Ast_c.wrap
, Ast_c.il
) Common.either list
)
170 val distrf_enum_fields
:
171 (Ast_cocci.meta_name
Ast_cocci.mcode
,
172 (Ast_c.oneEnumType
, Ast_c.il
) Common.either list
) matcher
174 val distrf_struct_fields
:
175 (Ast_cocci.meta_name
Ast_cocci.mcode
, Ast_c.field list
)
179 (Ast_cocci.meta_name
Ast_cocci.mcode
,
180 (Ast_c.constant
, string) Common.either
Ast_c.wrap
)
183 (* -------------------------------------------------------------------- *)
184 (* Modifying nested expression and nested types, with Exp and Ty *)
185 (* -------------------------------------------------------------------- *)
188 (Ast_cocci.expression
, Ast_c.expression
) matcher
->
189 (Ast_cocci.expression
, Control_flow_c.node
) matcher
192 (Ast_cocci.expression
, Ast_c.expression
) matcher
->
193 (Ast_cocci.expression
, Ast_c.expression
) matcher
196 (Ast_cocci.fullType
, Ast_c.fullType
) matcher
->
197 (Ast_cocci.fullType
, Control_flow_c.node
) matcher
200 (Ast_cocci.initialiser
, Ast_c.initialiser
) matcher
->
201 (Ast_cocci.initialiser
, Control_flow_c.node
) matcher
203 (* -------------------------------------------------------------------- *)
204 (* Environment manipulation. Extract info from tin, the "something" *)
205 (* -------------------------------------------------------------------- *)
207 Ast_cocci.keep_binding
->
208 Ast_cocci.inherited
->
209 Ast_cocci.meta_name
Ast_cocci.mcode
* Ast_c.metavar_binding_kind
*
210 (* pos info, if needed *)
211 (unit -> Common.filename
* string * Ast_c.posl
* Ast_c.posl
) ->
212 (unit -> tin
-> 'x tout
) -> (tin
-> 'x tout
)
214 val check_idconstraint
:
215 ('a
-> 'b
-> bool) -> 'a
-> 'b
->
216 (unit -> tin
-> 'x tout
) -> (tin
-> 'x tout
)
218 val check_constraints_ne
:
219 ('a
, 'b
) matcher
-> 'a list
-> 'b
->
220 (unit -> tin
-> 'x tout
) -> (tin
-> 'x tout
)
222 val all_bound
: Ast_cocci.meta_name list
-> tin
-> bool
225 val optional_storage_flag
: (bool -> tin
-> 'x tout
) -> (tin
-> 'x tout
)
226 val optional_qualifier_flag
: (bool -> tin
-> 'x tout
) -> (tin
-> 'x tout
)
227 val value_format_flag
: (bool -> tin
-> 'x tout
) -> (tin
-> 'x tout
)
233 (*****************************************************************************)
234 (* The functor itself *)
235 (*****************************************************************************)
238 functor (X
: PARAM
) ->
240 type ('a
, 'b
) matcher
= 'a
-> 'b
-> X.tin
-> ('a
* 'b
) X.tout
242 val rule_elem_node
: (Ast_cocci.rule_elem
, Control_flow_c.node
) matcher
244 val expression
: (Ast_cocci.expression
, Ast_c.expression
) matcher
246 (* there are far more functions in this functor but they do not have