>
> 1)  After I change the original statement s to a new one s'  , I want
> s'.id  to be the same as s.id.  Using the   "method vinst",  I cannot do
> this.
>
> 2)   And the return type of "method vinst" is   "Cil.instr list
> Cil.visitAction"   so I cannot call ChangeTo(new_stmt) .
>


I made some changes by returning   ChangeTo([Call(None,Lval(Var
v,os),expl,loc)])     and it fixes these problems.    Does it look  correct
?

  method vinst i = (
    match i with
      |Call (None,Lval(Var v,os),expl,loc) -> (
          v.vname <- v.vname ^ "_NEW" ;
          ChangeTo([Call(None,Lval(Var v,os),expl,loc)])
        )
      |_ -> SkipChildren
  )



>
> What I intend to do eventually is changing statements "sprintf"   to
> "snprintf".   Note that I don't want to change _all_ of these sprintf
> statements but only specific ones based on their sid's.
>
> For example   I'd like to change a statement looking like
>
>  sprintf(fixed_buf,"a string\n");   where fixed_buff is an array holding
> char (e.g.,  char fixed_buff[100])
>
> to
>
>  snprintf(fixed_buf,sizeof(fixed_buf),"a string\n");
>
>
> ---------------
>
>
>
>
> class sprintfV ? file = object
>   inherit nopCilVisitor
>
>   method vstmt s = (
>     match s.skind with
>       |If (_, _, _, _) |Switch (_, _, _, _) |Block _ -> DoChildren
>       |Instr il when s.sid == WHAT_I_WANT  -> DoChildren
>       |_ -> SkipChildren
>
>   )
>
>   method vinst i = (
>     match i with
>       |Call (None,Lval(Var v,os),expl,loc) -> (
>           v.vname <- v.vname ^ "_NEW" ;
>           let new_stmt = mkStmtOneInstr (Call(None,Lval(Var
> v,os),expl,loc)) in
>           (*new_stmt.sid <- s.sid;   (* ERROR:  I cannot change the sid
> because s is no longer known*)
>           ChangeTo(new_stmt)   (*ERROR:   it expects Cil.instr list
> Cil.visitAction*)
>         )
>       |_ -> SkipChildren
>   )
> end
>
>
>
>
>
> VN -
>
>
>
> On Thu, Dec 17, 2009 at 1:58 AM, Gabriel Kerneis 
> <kern...@pps.jussieu.fr>wrote:
>
>> Hi,
>>
>> Your code might work on simple examples, but it will probably break on
>> real programms.  Could you give a real example of what you are trying to
>> do?  Don't you want to change the name of the function in it's
>> definition too?  What if there are function pointers?  All this can be
>> changed very easily, but you have to define precisely what you want.
>>
>> If you wished to rename the function everywhere (definition, use, etc.),
>> then the following very simple code would be enough:
>>
>> class testVisitor = object
>>  inherit nopCilVisitor
>>
>>   method vvdec vi =
>>    if List.mem vi.vname ["foo"; "bar"]
>>    then vi.vname <- vi.vname ^ "_new"
>>    (* No ChangeTo, imperative mutation *);
>>    SkipChildren
>>
>> end
>>
>> Back to your code.
>>
>> You should use the various methods of the cil visitor to make things
>> easier to read.  Moreover, this would have let you spot the fact that you
>> do NOT dive into Block, If, and other statements.  Therefore, you only
>> perform variable substitution in top-level instructions.  You cut the
>> Instr statement to keep only the first element: what if the function you
>> are interested in is later in the call sequence?  Check out List.map in
>> the OCaml doc, it might help you a lot.  Using ChangeTo with statements
>> can be tricky, too: this potentially breaks gotos (read the CIL API
>> documentation, this is mentionned).  One last thing: use richer patterns
>> in your match cases (see vinst below).
>>
>> class testVisitor = object
>>  inherit nopCilVisitor
>>
>>   method vinst i = match i with
>>  | Call(None, Lval (Var lv, NoOffset), es,loc) ->
>>      (* Do what you want here --- I do not understand exactly what you
>>         want *)
>>      let lv' = (* ... *) in
>>      ChangeTo (Call(None, Lval (Var lv', NoOffset), es,loc))
>>  | Call(None, _, _, _) ->
>>       debug "don't know";
>>      SkipChildren
>>   | _ -> SkipChildren
>>
>>  method vstmt s = match s.skind with
>>  | Instr [] -> SkipChildren (* this is useless, but I put it there to
>>                                show you a convenient way to remove
>>                                if/else in your code *)
>>  | Instr l ->
>>      debug "gh\n";
>>      if s.sid = WHAT_I_WANT  (* I'm not sure how you can figure out
>>                                 which sid you want, but anyway... *)
>>      then DoChildren
>>      else SkipChildren
>>  | _ -> DoChildren
>>
>> end
>>
>> Regards,
>> --
>> Gabriel
>>
>
>
------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
CIL-users mailing list
CIL-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/cil-users

Reply via email to