(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-*
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-*
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
-*
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
+ * Copyright 2012, INRIA
+ * Julia Lawall, Gilles Muller
+ * Copyright 2010-2011, INRIA, University of Copenhagen
+ * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
+ * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
+ * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
+ * This file is part of Coccinelle.
+ *
+ * Coccinelle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, according to version 2 of the License.
+ *
+ * Coccinelle is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The authors reserve the right to distribute this or future versions of
+ * Coccinelle under other licenses.
+ *)
module Ast = Ast_cocci
let rec disjty ft =
match Ast.unwrap ft with
- Ast.Type(cv,ty) ->
+ Ast.Type(allminus,cv,ty) ->
let ty = disjtypeC ty in
- List.map (function ty -> Ast.rewrap ft (Ast.Type(cv,ty))) ty
+ List.map (function ty -> Ast.rewrap ft (Ast.Type(allminus,cv,ty))) ty
+ | Ast.AsType(ty,asty) -> (* as ty doesn't contain disj *)
+ let ty = disjty ty in
+ List.map (function ty -> Ast.rewrap ft (Ast.AsType(ty,asty))) ty
| Ast.DisjType(types) -> List.concat (List.map disjty types)
| Ast.OptType(ty) ->
let ty = disjty ty in
and disjtypeC bty =
match Ast.unwrap bty with
- Ast.BaseType(_,_) | Ast.ImplicitInt(_) -> [bty]
+ Ast.BaseType(_) | Ast.SignedT(_,_) -> [bty]
| Ast.Pointer(ty,star) ->
let ty = disjty ty in
List.map (function ty -> Ast.rewrap bty (Ast.Pointer(ty,star))) ty
disjmult2 (disjty ty) (disjoption disjexp size)
(function ty -> function size ->
Ast.rewrap bty (Ast.Array(ty,lb,size,rb)))
- | Ast.StructUnionName(kind,name) -> [bty]
+ | Ast.EnumName(_,_) | Ast.StructUnionName(_,_) -> [bty]
+ | Ast.EnumDef(ty,lb,ids,rb) ->
+ disjmult2 (disjty ty) (disjdots disjexp ids)
+ (function ty -> function ids ->
+ Ast.rewrap bty (Ast.EnumDef(ty,lb,ids,rb)))
| Ast.StructUnionDef(ty,lb,decls,rb) ->
disjmult2 (disjty ty) (disjdots disjdecl decls)
(function ty -> function decls ->
Ast.rewrap bty (Ast.StructUnionDef(ty,lb,decls,rb)))
| Ast.TypeName(_) | Ast.MetaType(_,_,_) -> [bty]
+and disjident e =
+ match Ast.unwrap e with
+ Ast.DisjId(id_list) -> List.concat (List.map disjident id_list)
+ | Ast.OptIdent(id) ->
+ let id = disjident id in
+ List.map (function id -> Ast.rewrap e (Ast.OptIdent(id))) id
+ | Ast.UniqueIdent(id) ->
+ let id = disjident id in
+ List.map (function id -> Ast.rewrap e (Ast.UniqueIdent(id))) id
+ | _ -> [e]
+
and disjexp e =
match Ast.unwrap e with
- Ast.Ident(_) | Ast.Constant(_) -> [e]
+ Ast.Ident(_) | Ast.Constant(_) -> [e] (* even Ident can't contain disj *)
| Ast.FunCall(fn,lp,args,rp) ->
disjmult2 (disjexp fn) (disjdots disjexp args)
(function fn -> function args ->
disjmult2 (disjexp left) (disjexp right)
(function left -> function right ->
Ast.rewrap e (Ast.Assignment(left,op,right,simple)))
+ | Ast.Sequence(left,op,right) ->
+ disjmult2 (disjexp left) (disjexp right)
+ (function left -> function right ->
+ Ast.rewrap e (Ast.Sequence(left,op,right)))
| Ast.CondExpr(exp1,why,Some exp2,colon,exp3) ->
let res = disjmult disjexp [exp1;exp2;exp3] in
List.map
| Ast.TypeExp(ty) ->
let ty = disjty ty in
List.map (function ty -> Ast.rewrap e (Ast.TypeExp(ty))) ty
+ | Ast.Constructor(lp,ty,rp,init) ->
+ disjmult2 (disjty ty) (disjini init)
+ (function ty ->
+ function exp -> Ast.rewrap e (Ast.Constructor(lp,ty,rp,init)))
| Ast.MetaErr(_,_,_,_) | Ast.MetaExpr(_,_,_,_,_,_)
| Ast.MetaExprList(_,_,_,_) | Ast.EComma(_) -> [e]
+ | Ast.AsExpr(exp,asexp) -> (* as exp doesn't contain disj *)
+ let exp = disjexp exp in
+ List.map (function exp -> Ast.rewrap e (Ast.AsExpr(exp,asexp))) exp
| Ast.DisjExpr(exp_list) -> List.concat (List.map disjexp exp_list)
- | Ast.NestExpr(expr_dots,whencode,multi) ->
+ | Ast.NestExpr(starter,expr_dots,ender,whencode,multi) ->
(* not sure what to do here, so ambiguities still possible *)
[e]
| Ast.Edots(dots,_) | Ast.Ecircles(dots,_) | Ast.Estars(dots,_) -> [e]
and disjini i =
match Ast.unwrap i with
- Ast.InitExpr(exp) ->
+ Ast.MetaInit(_,_,_) | Ast.MetaInitList(_,_,_,_) -> [i]
+ | Ast.AsInit(ini,asini) ->
+ let ini = disjini ini in
+ List.map (function ini -> Ast.rewrap i (Ast.AsInit(ini,asini))) ini
+ | Ast.InitExpr(exp) ->
let exp = disjexp exp in
List.map (function exp -> Ast.rewrap i (Ast.InitExpr(exp))) exp
- | Ast.InitList(lb,initlist,rb,whencode) ->
+ | Ast.ArInitList(lb,initlist,rb) ->
List.map
(function initlist ->
- Ast.rewrap i (Ast.InitList(lb,initlist,rb,whencode)))
+ Ast.rewrap i (Ast.ArInitList(lb,initlist,rb)))
+ (disjdots disjini initlist)
+ | Ast.StrInitList(allminus,lb,initlist,rb,whencode) ->
+ List.map
+ (function initlist ->
+ Ast.rewrap i (Ast.StrInitList(allminus,lb,initlist,rb,whencode)))
(disjmult disjini initlist)
- | Ast.InitGccDotName(dot,name,eq,ini) ->
+ | Ast.InitGccExt(designators,eq,ini) ->
+ let designators = disjmult designator designators in
let ini = disjini ini in
- List.map
- (function ini -> Ast.rewrap i (Ast.InitGccDotName(dot,name,eq,ini)))
- ini
+ disjmult2 designators ini
+ (function designators -> function ini ->
+ Ast.rewrap i (Ast.InitGccExt(designators,eq,ini)))
| Ast.InitGccName(name,eq,ini) ->
let ini = disjini ini in
List.map
(function ini -> Ast.rewrap i (Ast.InitGccName(name,eq,ini)))
ini
- | Ast.InitGccIndex(lb,exp,rb,eq,ini) ->
- disjmult2 (disjexp exp) (disjini ini)
- (function exp -> function ini ->
- Ast.rewrap i (Ast.InitGccIndex(lb,exp,rb,eq,ini)))
- | Ast.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini) ->
- disjmult3 (disjexp exp1) (disjexp exp2) (disjini ini)
- (function exp1 -> function exp2 -> function ini ->
- Ast.rewrap i (Ast.InitGccRange(lb,exp1,dots,exp2,rb,eq,ini)))
| Ast.IComma(comma) -> [i]
- | Ast.OptIni(ini) ->
+ | Ast.Idots(dots,_) -> [i]
+ | Ast.OptIni(ini) ->
let ini = disjini ini in
List.map (function ini -> Ast.rewrap i (Ast.OptIni(ini))) ini
- | Ast.UniqueIni(ini) ->
+ | Ast.UniqueIni(ini) ->
let ini = disjini ini in
List.map (function ini -> Ast.rewrap i (Ast.UniqueIni(ini))) ini
+and designator = function
+ Ast.DesignatorField(dot,id) -> [Ast.DesignatorField(dot,id)]
+ | Ast.DesignatorIndex(lb,exp,rb) ->
+ let exp = disjexp exp in
+ List.map (function exp -> Ast.DesignatorIndex(lb,exp,rb)) exp
+ | Ast.DesignatorRange(lb,min,dots,max,rb) ->
+ disjmult2 (disjexp min) (disjexp max)
+ (function min -> function max ->
+ Ast.DesignatorRange(lb,min,dots,max,rb))
+
and disjdecl d =
match Ast.unwrap d with
- Ast.Init(stg,ty,id,eq,ini,sem) ->
+ Ast.MetaDecl(_,_,_) | Ast.MetaField(_,_,_)
+ | Ast.MetaFieldList(_,_,_,_) -> [d]
+ | Ast.AsDecl(decl,asdecl) ->
+ let decl = disjdecl decl in
+ List.map (function decl -> Ast.rewrap d (Ast.AsDecl(decl,asdecl))) decl
+ | Ast.Init(stg,ty,id,eq,ini,sem) ->
disjmult2 (disjty ty) (disjini ini)
(function ty -> function ini ->
Ast.rewrap d (Ast.Init(stg,ty,id,eq,ini,sem)))
List.map
(function args -> Ast.rewrap d (Ast.MacroDecl(name,lp,args,rp,sem)))
(disjdots disjexp args)
+ | Ast.MacroDeclInit(name,lp,args,rp,eq,ini,sem) ->
+ disjmult2 (disjdots disjexp args) (disjini ini)
+ (function args -> function ini ->
+ Ast.rewrap d (Ast.MacroDeclInit(name,lp,args,rp,eq,ini,sem)))
| Ast.TyDecl(ty,sem) ->
let ty = disjty ty in
List.map (function ty -> Ast.rewrap d (Ast.TyDecl(ty,sem))) ty
let ty = disjty ty in (* disj not allowed in id *)
List.map (function ty -> Ast.rewrap d (Ast.Typedef(stg,ty,id,sem))) ty
| Ast.DisjDecl(decls) -> List.concat (List.map disjdecl decls)
- | Ast.Ddots(_,_) | Ast.MetaDecl(_,_,_) -> [d]
+ | Ast.Ddots(_,_) -> [d]
| Ast.OptDecl(decl) ->
let decl = disjdecl decl in
List.map (function decl -> Ast.rewrap d (Ast.OptDecl(decl))) decl
let orify_rule_elem_ty = generic_orify_rule_elem disjty
let orify_rule_elem_param = generic_orify_rule_elem disjparam
let orify_rule_elem_decl = generic_orify_rule_elem disjdecl
+let orify_rule_elem_ini = generic_orify_rule_elem disjini
-let disj_rule_elem r k re =
- match Ast.unwrap re with
+let rec disj_rule_elem r k re =
+ match Ast.unwrap re with
Ast.FunHeader(bef,allminus,fninfo,name,lp,params,rp) ->
generic_orify_rule_elem (disjdots disjparam) re params
(function params ->
(function decl -> Ast.rewrap re (Ast.Decl(bef,allminus,decl)))
| Ast.SeqStart(brace) -> re
| Ast.SeqEnd(brace) -> re
- | Ast.ExprStatement(exp,sem) ->
+ | Ast.ExprStatement(Some exp,sem) ->
orify_rule_elem re exp
- (function exp -> Ast.rewrap re (Ast.ExprStatement(exp,sem)))
+ (function exp -> Ast.rewrap re (Ast.ExprStatement(Some exp,sem)))
+ | Ast.ExprStatement(None,sem) -> re
| Ast.IfHeader(iff,lp,exp,rp) ->
orify_rule_elem re exp
(function exp -> Ast.rewrap re (Ast.IfHeader(iff,lp,exp,rp)))
orify_rule_elem re exp (function exp -> Ast.rewrap exp (Ast.TopExp(exp)))
| Ast.Ty(ty) ->
orify_rule_elem_ty re ty (function ty -> Ast.rewrap ty (Ast.Ty(ty)))
+ | Ast.TopInit(init) ->
+ orify_rule_elem_ini re init
+ (function init -> Ast.rewrap init (Ast.TopInit(init)))
| Ast.Include(inc,s) -> re
+ | Ast.Undef(def,id) -> re
| Ast.DefineHeader(def,id,params) -> re
| Ast.Default(def,colon) -> re
| Ast.Case(case,exp,colon) ->
orify_rule_elem re exp
(function exp -> Ast.rewrap re (Ast.Case(case,exp,colon)))
- | Ast.DisjRuleElem(_) -> failwith "not possible"
+ | Ast.DisjRuleElem(l) ->
+ (* only case lines *)
+ Ast.rewrap re(Ast.DisjRuleElem(List.map (disj_rule_elem r k) l))
let disj_all =
let mcode x = x in
let donothing r k e = k e in
V.rebuilder
mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
- mcode
- donothing donothing donothing donothing
+ donothing donothing donothing donothing donothing
donothing donothing donothing donothing donothing donothing donothing
disj_rule_elem donothing donothing donothing donothing
let doanything r k e = k e in
V.combiner bind option_default
mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
- mcode
donothing donothing donothing donothing donothing donothing donothing
donothing donothing donothing donothing donothing donothing donothing
- donothing doanything
+ donothing donothing doanything
let collect_iso_info =
let mcode x = x in
Ast.set_isos e isos in
V.rebuilder
mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
- mcode
donothing donothing donothing donothing donothing donothing donothing
+ donothing
donothing donothing donothing donothing rule_elem donothing donothing
donothing donothing
List.map
(function (mv,r) ->
match r with
- Ast.ScriptRule _ -> (mv, r)
- | Ast.CocciRule (nm, rule_info, r, isexp) ->
- let res =
- List.map
- (function x ->
- let res = disj_all.V.rebuilder_top_level x in
- if !Flag.track_iso_usage
- then collect_iso_info.V.rebuilder_top_level res
- else res)
- r in
- (mv, Ast.CocciRule (nm,rule_info,res,isexp)))
+ Ast.ScriptRule _
+ | Ast.InitialScriptRule _ | Ast.FinalScriptRule _ -> (mv, r)
+ | Ast.CocciRule (nm, rule_info, r, isexp, ruletype) ->
+ let res =
+ List.map
+ (function x ->
+ let res = disj_all.V.rebuilder_top_level x in
+ if !Flag.track_iso_usage
+ then collect_iso_info.V.rebuilder_top_level res
+ else res)
+ r in
+ (mv, Ast.CocciRule (nm,rule_info,res,isexp,ruletype)))
rules