(*
-* Copyright 2005-2008, Ecole des Mines de Nantes, University of Copenhagen
+* Copyright 2005-2009, 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.
*
module Ast = Ast_cocci
module Ast0 = Ast0_cocci
module V0 = Visitor_ast0
+module VT0 = Visitor_ast0_types
module CN = Context_neg
+let empty_isos = ref false
+
let get_option f = function
None -> []
| Some x -> f x
let topfn r k e = Ast0.TopTag(e) :: (k e) in
let res =
- V0.combiner bind option_default
+ V0.flat_combiner bind option_default
mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
- mcode
(donothing Ast0.dotsExpr) (donothing Ast0.dotsInit)
(donothing Ast0.dotsParam) (donothing Ast0.dotsStmt)
(donothing Ast0.dotsDecl) (donothing Ast0.dotsCase)
(donothing Ast0.ident) expression (donothing Ast0.typeC) initialiser
(donothing Ast0.param) (donothing Ast0.decl) statement
(donothing Ast0.case_line) topfn in
- res.V0.combiner_top_level e
+ res.VT0.combiner_rec_top_level e
(* --------------------------------------------------------------------- *)
(* --------------------------------------------------------------------- *)
let bind x y = x @ y in
let option_default = [] in
- let mcode (_,_,info,mcodekind,_) =
- if List.mem (info.Ast0.offset) unfavored_tokens
+ let mcode (_,_,info,mcodekind,_,_) =
+ if List.mem (info.Ast0.pos_info.Ast0.offset) unfavored_tokens
then [(Unfavored,info,mcodekind)]
else [(Favored,info,mcodekind)] in
| Ast0.CIRCLES(l) -> multibind (List.map f l)
| Ast0.STARS(l) -> multibind (List.map f l) in
- let edots r k d = dots r.V0.combiner_expression k d in
- let idots r k d = dots r.V0.combiner_initialiser k d in
- let pdots r k d = dots r.V0.combiner_parameter k d in
- let sdots r k d = dots r.V0.combiner_statement k d in
- let ddots r k d = dots r.V0.combiner_declaration k d in
- let cdots r k d = dots r.V0.combiner_case_line k d in
+ let edots r k d = dots r.VT0.combiner_rec_expression k d in
+ let idots r k d = dots r.VT0.combiner_rec_initialiser k d in
+ let pdots r k d = dots r.VT0.combiner_rec_parameter k d in
+ let sdots r k d = dots r.VT0.combiner_rec_statement k d in
+ let ddots r k d = dots r.VT0.combiner_rec_declaration k d in
+ let cdots r k d = dots r.VT0.combiner_rec_case_line k d in
(* a case for everything that has a Opt *)
(Toplevel,info,bef)::(k s)
| Ast0.Decl((info,bef),decl) -> (Decl,info,bef)::(k s)
| Ast0.Nest(starter,stmt_dots,ender,whencode,multi) ->
- mcode starter @ r.V0.combiner_statement_dots stmt_dots @ mcode ender
+ mcode starter @ r.VT0.combiner_rec_statement_dots stmt_dots @
+ mcode ender
| Ast0.Dots(d,whencode) | Ast0.Circles(d,whencode)
| Ast0.Stars(d,whencode) -> mcode d (* ignore whencode *)
| Ast0.OptStm s | Ast0.UniqueStm s ->
(* put the + code on the thing, not on the opt *)
- r.V0.combiner_statement s
+ r.VT0.combiner_rec_statement s
| _ -> do_nothing r k s in
let expression r k e =
match Ast0.unwrap e with
Ast0.NestExpr(starter,expr_dots,ender,whencode,multi) ->
mcode starter @
- r.V0.combiner_expression_dots expr_dots @ mcode ender
+ r.VT0.combiner_rec_expression_dots expr_dots @ mcode ender
| Ast0.Edots(d,whencode) | Ast0.Ecircles(d,whencode)
| Ast0.Estars(d,whencode) -> mcode d (* ignore whencode *)
| Ast0.OptExp e | Ast0.UniqueExp e ->
(* put the + code on the thing, not on the opt *)
- r.V0.combiner_expression e
+ r.VT0.combiner_rec_expression e
| _ -> do_nothing r k e in
let ident r k e =
match Ast0.unwrap e with
Ast0.OptIdent i | Ast0.UniqueIdent i ->
(* put the + code on the thing, not on the opt *)
- r.V0.combiner_ident i
+ r.VT0.combiner_rec_ident i
| _ -> do_nothing r k e in
let typeC r k e =
match Ast0.unwrap e with
Ast0.OptType t | Ast0.UniqueType t ->
(* put the + code on the thing, not on the opt *)
- r.V0.combiner_typeC t
+ r.VT0.combiner_rec_typeC t
| _ -> do_nothing r k e in
let decl r k e =
match Ast0.unwrap e with
Ast0.OptDecl d | Ast0.UniqueDecl d ->
(* put the + code on the thing, not on the opt *)
- r.V0.combiner_declaration d
+ r.VT0.combiner_rec_declaration d
| _ -> do_nothing r k e in
let initialiser r k e =
Ast0.Idots(d,whencode) -> mcode d (* ignore whencode *)
| Ast0.OptIni i | Ast0.UniqueIni i ->
(* put the + code on the thing, not on the opt *)
- r.V0.combiner_initialiser i
+ r.VT0.combiner_rec_initialiser i
| _ -> do_nothing r k e in
let param r k e =
match Ast0.unwrap e with
Ast0.OptParam p | Ast0.UniqueParam p ->
(* put the + code on the thing, not on the opt *)
- r.V0.combiner_parameter p
+ r.VT0.combiner_rec_parameter p
| _ -> do_nothing r k e in
let case_line r k e =
match Ast0.unwrap e with
Ast0.OptCase c ->
(* put the + code on the thing, not on the opt *)
- r.V0.combiner_case_line c
+ r.VT0.combiner_rec_case_line c
| _ -> do_nothing r k e in
let do_top r k (e: Ast0.top_level) = k e in
- V0.combiner bind option_default
+ V0.flat_combiner bind option_default
mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode mcode
- mcode
edots idots pdots sdots ddots cdots
ident expression typeC initialiser param decl statement case_line do_top
match e with
Ast0.DotsExprTag(e) ->
(Ast0.get_index e,
- (collect_minus_join_points e).V0.combiner_expression_dots e)
+ (collect_minus_join_points e).VT0.combiner_rec_expression_dots e)
| Ast0.DotsInitTag(e) ->
(Ast0.get_index e,
- (collect_minus_join_points e).V0.combiner_initialiser_list e)
+ (collect_minus_join_points e).VT0.combiner_rec_initialiser_list e)
| Ast0.DotsParamTag(e) ->
(Ast0.get_index e,
- (collect_minus_join_points e).V0.combiner_parameter_list e)
+ (collect_minus_join_points e).VT0.combiner_rec_parameter_list e)
| Ast0.DotsStmtTag(e) ->
(Ast0.get_index e,
- (collect_minus_join_points e).V0.combiner_statement_dots e)
+ (collect_minus_join_points e).VT0.combiner_rec_statement_dots e)
| Ast0.DotsDeclTag(e) ->
(Ast0.get_index e,
- (collect_minus_join_points e).V0.combiner_declaration_dots e)
+ (collect_minus_join_points e).VT0.combiner_rec_declaration_dots e)
| Ast0.DotsCaseTag(e) ->
(Ast0.get_index e,
- (collect_minus_join_points e).V0.combiner_case_line_dots e)
+ (collect_minus_join_points e).VT0.combiner_rec_case_line_dots e)
| Ast0.IdentTag(e) ->
(Ast0.get_index e,
- (collect_minus_join_points e).V0.combiner_ident e)
+ (collect_minus_join_points e).VT0.combiner_rec_ident e)
| Ast0.ExprTag(e) ->
(Ast0.get_index e,
- (collect_minus_join_points e).V0.combiner_expression e)
+ (collect_minus_join_points e).VT0.combiner_rec_expression e)
| Ast0.ArgExprTag(e) | Ast0.TestExprTag(e) ->
failwith "not possible - iso only"
| Ast0.TypeCTag(e) ->
(Ast0.get_index e,
- (collect_minus_join_points e).V0.combiner_typeC e)
+ (collect_minus_join_points e).VT0.combiner_rec_typeC e)
| Ast0.ParamTag(e) ->
(Ast0.get_index e,
- (collect_minus_join_points e).V0.combiner_parameter e)
+ (collect_minus_join_points e).VT0.combiner_rec_parameter e)
| Ast0.InitTag(e) ->
(Ast0.get_index e,
- (collect_minus_join_points e).V0.combiner_initialiser e)
+ (collect_minus_join_points e).VT0.combiner_rec_initialiser e)
| Ast0.DeclTag(e) ->
(Ast0.get_index e,
- (collect_minus_join_points e).V0.combiner_declaration e)
+ (collect_minus_join_points e).VT0.combiner_rec_declaration e)
| Ast0.StmtTag(e) ->
(Ast0.get_index e,
- (collect_minus_join_points e).V0.combiner_statement e)
+ (collect_minus_join_points e).VT0.combiner_rec_statement e)
| Ast0.CaseLineTag(e) ->
(Ast0.get_index e,
- (collect_minus_join_points e).V0.combiner_case_line e)
+ (collect_minus_join_points e).VT0.combiner_rec_case_line e)
| Ast0.TopTag(e) ->
(Ast0.get_index e,
- (collect_minus_join_points e).V0.combiner_top_level e)
+ (collect_minus_join_points e).VT0.combiner_rec_top_level e)
| Ast0.IsoWhenTag(_) -> failwith "only within iso phase"
| Ast0.IsoWhenTTag(_) -> failwith "only within iso phase"
| Ast0.IsoWhenFTag(_) -> failwith "only within iso phase"
let get_info = function
(Favored,info,_) | (Unfavored,info,_) | (Toplevel,info,_)
| (Decl,info,_) -> info in
- let token_start_line x = (get_info x).Ast0.logical_start in
- let token_end_line x = (get_info x).Ast0.logical_end in
- let token_real_start_line x = (get_info x).Ast0.line_start in
- let token_real_end_line x = (get_info x).Ast0.line_end in
+ let token_start_line x = (get_info x).Ast0.pos_info.Ast0.logical_start in
+ let token_end_line x = (get_info x).Ast0.pos_info.Ast0.logical_end in
+ let token_real_start_line x = (get_info x).Ast0.pos_info.Ast0.line_start in
+ let token_real_end_line x = (get_info x).Ast0.pos_info.Ast0.line_end in
List.iter
(function
(index,((_::_) as l1)) ->
(* --------------------------------------------------------------------- *)
(* collect the plus tokens *)
-let mk_baseType x = Ast.BaseTypeTag x
let mk_structUnion x = Ast.StructUnionTag x
let mk_sign x = Ast.SignTag x
let mk_ident x = Ast.IdentTag (Ast0toast.ident x)
let bind x y = x @ y in
let option_default = [] in
- let mcode fn (term,_,info,mcodekind,_) =
- match mcodekind with Ast0.PLUS -> [(info,fn term)] | _ -> [] in
+ let extract_strings info =
+ let adjust_info =
+ {info with Ast0.strings_before = []; Ast0.strings_after = []} in
+ let extract = function
+ [] -> []
+ | strings_before ->
+ let (_,first) = List.hd strings_before in
+ let (_,last) = List.hd (List.rev strings_before) in
+ let new_pos_info =
+ {Ast0.line_start = first.Ast0.line_start;
+ Ast0.line_end = last.Ast0.line_start;
+ Ast0.logical_start = first.Ast0.logical_start;
+ Ast0.logical_end = last.Ast0.logical_start;
+ Ast0.column = first.Ast0.column;
+ Ast0.offset = first.Ast0.offset} in
+ let new_info = {adjust_info with Ast0.pos_info = new_pos_info} in
+ let string = List.map (function (s,_) -> s) strings_before in
+ [(new_info, Ast.Pragma (string))] in
+ let bef = extract info.Ast0.strings_before in
+ let aft = extract info.Ast0.strings_after in
+ (bef,aft) in
+
+ let mcode fn (term,_,info,mcodekind,_,_) =
+ match mcodekind with
+ Ast0.PLUS -> [(info,fn term)]
+ | Ast0.CONTEXT _ -> let (bef,aft) = extract_strings info in bef@aft
+ | _ -> [] in
- let imcode fn (term,_,info,mcodekind,_) =
+ let imcode fn (term,_,info,mcodekind,_,_) =
match mcodekind with
Ast0.PLUS -> [(info,fn term (Ast0toast.convert_info info))]
+ | Ast0.CONTEXT _ -> let (bef,aft) = extract_strings info in bef@aft
| _ -> [] in
+ let info (i,_) = let (bef,aft) = extract_strings i in bef@aft in
+
let do_nothing fn r k e =
match Ast0.get_mcodekind e with
(Ast0.CONTEXT(_)) when not(Ast0.get_index e = root_index) -> []
| _ -> k e in
(* case for everything that is just a wrapper for a simpler thing *)
+ (* case for things with bef aft *)
let stmt r k e =
match Ast0.unwrap e with
- Ast0.Exp(exp) -> r.V0.combiner_expression exp
- | Ast0.TopExp(exp) -> r.V0.combiner_expression exp
- | Ast0.Ty(ty) -> r.V0.combiner_typeC ty
- | Ast0.TopInit(init) -> r.V0.combiner_initialiser init
- | Ast0.Decl(_,decl) -> r.V0.combiner_declaration decl
+ Ast0.Exp(exp) -> r.VT0.combiner_rec_expression exp
+ | Ast0.TopExp(exp) -> r.VT0.combiner_rec_expression exp
+ | Ast0.Ty(ty) -> r.VT0.combiner_rec_typeC ty
+ | Ast0.TopInit(init) -> r.VT0.combiner_rec_initialiser init
+ | Ast0.Decl(bef,decl) ->
+ (info bef) @ (do_nothing mk_statement r k e)
+ | Ast0.FunDecl(bef,fi,name,lp,params,rp,lbrace,body,rbrace) ->
+ (info bef) @ (do_nothing mk_statement r k e)
+ | Ast0.IfThen(iff,lp,exp,rp,branch1,aft) ->
+ (do_nothing mk_statement r k e) @ (info aft)
+ | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,aft) ->
+ (do_nothing mk_statement r k e) @ (info aft)
+ | Ast0.While(whl,lp,exp,rp,body,aft) ->
+ (do_nothing mk_statement r k e) @ (info aft)
+ | Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,aft) ->
+ (do_nothing mk_statement r k e) @ (info aft)
+ | Ast0.Iterator(nm,lp,args,rp,body,aft) ->
+ (do_nothing mk_statement r k e) @ (info aft)
| _ -> do_nothing mk_statement r k e in
(* statementTag is preferred, because it indicates that one statement is
let stmt_dots r k e =
match Ast0.unwrap e with
Ast0.DOTS([s]) | Ast0.CIRCLES([s]) | Ast0.STARS([s]) ->
- r.V0.combiner_statement s
+ r.VT0.combiner_rec_statement s
| _ -> do_nothing mk_stmtdots r k e in
let toplevel r k e =
match Ast0.unwrap e with
- Ast0.DECL(s) -> r.V0.combiner_statement s
- | Ast0.CODE(sdots) -> r.V0.combiner_statement_dots sdots
+ Ast0.DECL(s) -> r.VT0.combiner_rec_statement s
+ | Ast0.CODE(sdots) -> r.VT0.combiner_rec_statement_dots sdots
| _ -> do_nothing mk_code r k e in
let initdots r k e = k e in
- V0.combiner bind option_default
+ V0.flat_combiner bind option_default
(imcode mk_meta) (imcode mk_token) (mcode mk_constant) (mcode mk_assignOp)
(mcode mk_fixOp)
(mcode mk_unaryOp) (mcode mk_binaryOp) (mcode mk_const_vol)
- (mcode mk_baseType) (mcode mk_sign) (mcode mk_structUnion)
+ (mcode mk_sign) (mcode mk_structUnion)
(mcode mk_storage) (mcode mk_inc_file)
(do_nothing mk_exprdots) initdots
(do_nothing mk_paramdots) stmt_dots (do_nothing mk_decldots)
match e with
Ast0.DotsExprTag(e) ->
(Ast0.get_index e,
- (collect_plus_nodes e).V0.combiner_expression_dots e)
+ (collect_plus_nodes e).VT0.combiner_rec_expression_dots e)
| Ast0.DotsInitTag(e) ->
(Ast0.get_index e,
- (collect_plus_nodes e).V0.combiner_initialiser_list e)
+ (collect_plus_nodes e).VT0.combiner_rec_initialiser_list e)
| Ast0.DotsParamTag(e) ->
(Ast0.get_index e,
- (collect_plus_nodes e).V0.combiner_parameter_list e)
+ (collect_plus_nodes e).VT0.combiner_rec_parameter_list e)
| Ast0.DotsStmtTag(e) ->
(Ast0.get_index e,
- (collect_plus_nodes e).V0.combiner_statement_dots e)
+ (collect_plus_nodes e).VT0.combiner_rec_statement_dots e)
| Ast0.DotsDeclTag(e) ->
(Ast0.get_index e,
- (collect_plus_nodes e).V0.combiner_declaration_dots e)
+ (collect_plus_nodes e).VT0.combiner_rec_declaration_dots e)
| Ast0.DotsCaseTag(e) ->
(Ast0.get_index e,
- (collect_plus_nodes e).V0.combiner_case_line_dots e)
+ (collect_plus_nodes e).VT0.combiner_rec_case_line_dots e)
| Ast0.IdentTag(e) ->
(Ast0.get_index e,
- (collect_plus_nodes e).V0.combiner_ident e)
+ (collect_plus_nodes e).VT0.combiner_rec_ident e)
| Ast0.ExprTag(e) ->
(Ast0.get_index e,
- (collect_plus_nodes e).V0.combiner_expression e)
+ (collect_plus_nodes e).VT0.combiner_rec_expression e)
| Ast0.ArgExprTag(_) | Ast0.TestExprTag(_) ->
failwith "not possible - iso only"
| Ast0.TypeCTag(e) ->
(Ast0.get_index e,
- (collect_plus_nodes e).V0.combiner_typeC e)
+ (collect_plus_nodes e).VT0.combiner_rec_typeC e)
| Ast0.InitTag(e) ->
(Ast0.get_index e,
- (collect_plus_nodes e).V0.combiner_initialiser e)
+ (collect_plus_nodes e).VT0.combiner_rec_initialiser e)
| Ast0.ParamTag(e) ->
(Ast0.get_index e,
- (collect_plus_nodes e).V0.combiner_parameter e)
+ (collect_plus_nodes e).VT0.combiner_rec_parameter e)
| Ast0.DeclTag(e) ->
(Ast0.get_index e,
- (collect_plus_nodes e).V0.combiner_declaration e)
+ (collect_plus_nodes e).VT0.combiner_rec_declaration e)
| Ast0.StmtTag(e) ->
(Ast0.get_index e,
- (collect_plus_nodes e).V0.combiner_statement e)
+ (collect_plus_nodes e).VT0.combiner_rec_statement e)
| Ast0.CaseLineTag(e) ->
(Ast0.get_index e,
- (collect_plus_nodes e).V0.combiner_case_line e)
+ (collect_plus_nodes e).VT0.combiner_rec_case_line e)
| Ast0.TopTag(e) ->
(Ast0.get_index e,
- (collect_plus_nodes e).V0.combiner_top_level e)
+ (collect_plus_nodes e).VT0.combiner_rec_top_level e)
| Ast0.IsoWhenTag(_) -> failwith "only within iso phase"
| Ast0.IsoWhenTTag(_) -> failwith "only within iso phase"
| Ast0.IsoWhenFTag(_) -> failwith "only within iso phase"
Outer list: For any pair of successive elements, n and n+1, the ending
line of n is more than one less than the starting line of n+1. *)
-let logstart info = info.Ast0.logical_start
-let logend info = info.Ast0.logical_end
+let logstart info = info.Ast0.pos_info.Ast0.logical_start
+let logend info = info.Ast0.pos_info.Ast0.logical_end
let redo info start finish =
- {{info with Ast0.logical_start = start} with Ast0.logical_end = finish}
+ let new_pos_info =
+ {info.Ast0.pos_info with
+ Ast0.logical_start = start;
+ Ast0.logical_end = finish} in
+ {info with Ast0.pos_info = new_pos_info}
let rec find_neighbors (index,l) :
int * (Ast0.info * (Ast.anything list list)) list =
(* end of first argument < start/end of second argument *)
let less_than_start info1 info2 =
- info1.Ast0.logical_end < info2.Ast0.logical_start
+ info1.Ast0.pos_info.Ast0.logical_end < info2.Ast0.pos_info.Ast0.logical_start
let less_than_end info1 info2 =
- info1.Ast0.logical_end < info2.Ast0.logical_end
+ info1.Ast0.pos_info.Ast0.logical_end < info2.Ast0.pos_info.Ast0.logical_end
let greater_than_end info1 info2 =
- info1.Ast0.logical_start > info2.Ast0.logical_end
+ info1.Ast0.pos_info.Ast0.logical_start > info2.Ast0.pos_info.Ast0.logical_end
let good_start info = info.Ast0.attachable_start
let good_end info = info.Ast0.attachable_end
| Ast.StatementTag _
| Ast.Rule_elemTag _
| Ast.StmtDotsTag _
- | Ast.Code _ -> true
+ | Ast.Code _
+ | Ast.Pragma _ -> true
(* the following should definitely be false *)
| Ast.FullTypeTag _ | Ast.BaseTypeTag _ | Ast.StructUnionTag _
| Ast.SignTag _
let insert thing thinginfo into intoinfo =
let get_last l = let l = List.rev l in (List.rev(List.tl l),List.hd l) in
let get_first l = (List.hd l,List.tl l) in
- let thing_start = thinginfo.Ast0.logical_start in
- let thing_end = thinginfo.Ast0.logical_end in
- let thing_offset = thinginfo.Ast0.offset in
+ let thing_start = thinginfo.Ast0.pos_info.Ast0.logical_start in
+ let thing_end = thinginfo.Ast0.pos_info.Ast0.logical_end in
+ let thing_offset = thinginfo.Ast0.pos_info.Ast0.offset in
let into_start = intoinfo.Ast0.tline_start in
let into_end = intoinfo.Ast0.tline_end in
let into_left_offset = intoinfo.Ast0.left_offset in
let init thing info =
(thing,
- {Ast0.tline_start = info.Ast0.logical_start;
- Ast0.tline_end = info.Ast0.logical_end;
- Ast0.left_offset = info.Ast0.offset;
- Ast0.right_offset = info.Ast0.offset})
+ {Ast0.tline_start = info.Ast0.pos_info.Ast0.logical_start;
+ Ast0.tline_end = info.Ast0.pos_info.Ast0.logical_end;
+ Ast0.left_offset = info.Ast0.pos_info.Ast0.offset;
+ Ast0.right_offset = info.Ast0.pos_info.Ast0.offset})
let attachbefore (infop,p) = function
Ast0.MINUS(replacements) ->
Ast.BEFORE(bef) ->
let (bef,ti1) = insert p infop bef ti1 in
neighbors := (Ast.BEFORE(bef),ti1,ti2)
- | Ast.AFTER(aft) ->
+ | Ast.AFTER(aft) ->
let (bef,ti1) = init p infop in
neighbors := (Ast.BEFOREAFTER(bef,aft),ti1,ti2)
| Ast.BEFOREAFTER(bef,aft) ->
Ast.BEFORE(bef) ->
let (aft,ti2) = init p infop in
neighbors := (Ast.BEFOREAFTER(bef,aft),ti1,ti2)
- | Ast.AFTER(aft) ->
+ | Ast.AFTER(aft) ->
let (aft,ti2) = insert p infop aft ti2 in
neighbors := (Ast.AFTER(aft),ti1,ti2)
| Ast.BEFOREAFTER(bef,aft) ->
List.iter (function x -> attachafter x m) ps
let split_at_end info ps =
- let split_point = info.Ast0.logical_end in
+ let split_point = info.Ast0.pos_info.Ast0.logical_end in
List.partition
- (function (info,_) -> info.Ast0.logical_end < split_point)
+ (function (info,_) -> info.Ast0.pos_info.Ast0.logical_end < split_point)
ps
let allminus = function
then (attachbefore p m1; before_m1 x1 x2 rest ps)
else
failwith
- (pr "%d: no available token to attach to" infop.Ast0.line_start)
+ (pr "%d: no available token to attach to"
+ infop.Ast0.pos_info.Ast0.line_start)
else after_m1 x1 x2 rest all
and after_m1 ((f1,infom1,m1) as x1) ((f2,infom2,m2) as x2) rest = function
what it can infer from something being CONTEXT with no top-level
modifications. for the moment, we thus give an error, asking the
user to rewrite the semantic patch. *)
- if greater_than_end infop infom1
+ if greater_than_end infop infom1 or is_minus m1 or !empty_isos
then
if less_than_start infop infom2
then
then before_m2 x2 rest all
else
failwith
- (pr "%d: no available token to attach to" infop.Ast0.line_start)
+ (pr "%d: no available token to attach to"
+ infop.Ast0.pos_info.Ast0.line_start)
else after_m2 x2 rest all
else
begin
Printf.printf "between: p start %d p end %d m1 start %d m1 end %d m2 start %d m2 end %d\n"
- infop.Ast0.line_start infop.Ast0.line_end
- infom1.Ast0.line_start infom1.Ast0.line_end
- infom2.Ast0.line_start infom2.Ast0.line_end;
+ infop.Ast0.pos_info.Ast0.line_start
+ infop.Ast0.pos_info.Ast0.line_end
+ infom1.Ast0.pos_info.Ast0.line_start
+ infom1.Ast0.pos_info.Ast0.line_end
+ infom2.Ast0.pos_info.Ast0.line_start
+ infom2.Ast0.pos_info.Ast0.line_end;
Pretty_print_cocci.print_anything "" pcode;
failwith
"The semantic patch is structured in a way that may give bad results with isomorphisms. Please try to rewrite it by moving + code out from -/context terms."
end
+(* not sure this is safe. if have iso problems, consider changing this
+to always return false *)
+and is_minus = function
+ Ast0.MINUS _ -> true
+ | _ -> false
+
and before_m2 ((f2,infom2,m2) as x2) rest
(p : (Ast0.info * Ast.anything list list) list) =
match (rest,p) with
then (attach_all_before bef_m2 m2; after_m2 x2 rest aft_m2)
else
failwith
- (pr "%d: no available token to attach to" infop.Ast0.line_start)
+ (pr "%d: no available token to attach to"
+ infop.Ast0.pos_info.Ast0.line_start)
| (m::ms,_) -> before_m1 x2 m ms p
and after_m2 ((f2,infom2,m2) as x2) rest
then attach_all_after p m2
else
failwith
- (pr "%d: no available token to attach to" infop.Ast0.line_start)
+ (pr "%d: no available token to attach to"
+ infop.Ast0.pos_info.Ast0.line_start)
| (m::ms,_) -> after_m1 x2 m ms p
let merge_one : (minus_join_point * Ast0.info * 'a) list *
List.iter
(function (_,info,_) ->
Printf.printf "start %d end %d real_start %d real_end %d\n"
- info.Ast0.logical_start info.Ast0.logical_end
- info.Ast0.line_start info.Ast0.line_end)
+ info.Ast0.pos_info.Ast0.logical_start
+ info.Ast0.pos_info.Ast0.logical_end
+ info.Ast0.pos_info.Ast0.line_start
+ info.Ast0.pos_info.Ast0.line_end)
m;
Printf.printf "plus code\n";
List.iter
(function (info,p) ->
Printf.printf "start %d end %d real_start %d real_end %d\n"
- info.Ast0.logical_start info.Ast0.logical_end
- info.Ast0.line_end info.Ast0.line_end;
+ info.Ast0.pos_info.Ast0.logical_start
+ info.Ast0.pos_info.Ast0.logical_end
+ info.Ast0.pos_info.Ast0.line_end
+ info.Ast0.pos_info.Ast0.line_end;
Pretty_print_cocci.print_anything "" p;
Format.print_newline())
p;
let bind = (@) in
let option_default = [] in
- let mcode (_,_,_,mc,_) =
+ let mcode (_,_,_,mc,_,_) =
+ match mc with
+ Ast0.CONTEXT(mc) -> let (ba,_,_) = !mc in [ba]
+ | _ -> [] in
+
+ let info (_,mc) =
match mc with
Ast0.CONTEXT(mc) -> let (ba,_,_) = !mc in [ba]
| _ -> [] in
[]
| _ -> let _ = k e in [] in
+ (* a case for everything with bef or aft *)
+ let stmt r k e =
+ match Ast0.unwrap e with
+ Ast0.Decl(bef,decl) ->
+ (info bef) @ (donothing r k e)
+ | Ast0.FunDecl(bef,fi,name,lp,params,rp,lbrace,body,rbrace) ->
+ (info bef) @ (donothing r k e)
+ | Ast0.IfThen(iff,lp,exp,rp,branch1,aft) ->
+ (donothing r k e) @ (info aft)
+ | Ast0.IfThenElse(iff,lp,exp,rp,branch1,els,branch2,aft) ->
+ (donothing r k e) @ (info aft)
+ | Ast0.While(whl,lp,exp,rp,body,aft) ->
+ (donothing r k e) @ (info aft)
+ | Ast0.For(fr,lp,e1,sem1,e2,sem2,e3,rp,body,aft) ->
+ (donothing r k e) @ (info aft)
+ | Ast0.Iterator(nm,lp,args,rp,body,aft) ->
+ (donothing r k e) @ (info aft)
+ | _ -> donothing r k e in
+
let res =
- V0.combiner bind option_default
+ V0.flat_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 in
- res.V0.combiner_top_level
+ donothing donothing donothing donothing stmt donothing donothing in
+ res.VT0.combiner_rec_top_level
(* --------------------------------------------------------------------- *)
(* --------------------------------------------------------------------- *)
-let insert_plus minus plus =
+let insert_plus minus plus ei =
+ empty_isos := ei;
let minus_stream = process_minus minus in
let plus_stream = process_plus plus in
merge minus_stream plus_stream;