Hi,

I might have read your answer wrongly, but I am fully satisfied with the fact 
that:
void foo(int baz)
{
  printf("foo %d",baz);
}
isn't changed to: 
void bar(int baz)
{
  printf("foo %d",baz);
}

but I don't like that
switch(foo) is changed to switch(bar)

Now if my c file only contained this:
-------------
void baz(int foo)
{
  int bar = 5;
  switch (foo) {
  case 1 :
    break ;
  case 2:
    foo(2);
    printf("two");
    break ;
  default:
    printf("baz %d", bar);
    break;
  }
}
-------------

then applying
-----
@@
@@
-foo
+bar
-----

would lead to:

---------
 void baz(int foo)
 {
   int bar = 5;
-  switch (foo) {
+  switch (bar) {
   case 1 :
     break ;
   case 2:
-    foo(2);
+    bar(2);
     printf("two");
     break ;
   default:
---------

Note that the function parameter foo in baz() aren't changed. So now the baz() 
function used the fixed bar = 5 insted of the parameter to baz() !!!

Insted using

---------
@@
expression E;
@@
-foo(E);
+bar(E);
---------

will keep it's hands of the switch(bar) statement, but it wouldn't handle the 
update of:
Func *funclist [] = { foo, baz };
to
Func *funclist [] = { bar, baz };

Btw. how do I handle variable length expressions, where I wan't to insert the 
same expression list again?
-foo(E...)
+bar(E...)

Regards,
Andreas Bach Aaen

-----Original Message-----
From: Julia Lawall [mailto:[email protected]] 
Sent: 6. januar 2010 15:00
To: Aaen, Andreas.Bach
Cc: [email protected]
Subject: Re: [Cocci] Function replacement

Presumably there is a definition or a prototype for the function, either 
locally or in a header file?

You could have one rule that matches a function declaration, eg:

@r@
identifier f;
@@

f(...) { ... }

and then use r.f in some other rule.  Unfortunately, You can't put both a 
function declaration and a function prototype in a single rule, so everything 
would have to be duplicated for the prototpe case.

This should be run with -all_includes, and -I path, where path is the include 
directory.  If you are using the -dir option and the include directory is just 
the argument_to_dir/include, then -I is not needed.

Another weak point is that coccinelle might not find the header file that 
contains the prototype.  A further refinement would be to look for calls, use 
the name of the called function as well.

julia

On Wed, 6 Jan 2010, Aaen, Andreas.Bach wrote:

> Hi,
> 
> The simple cocci rule:
> 
> --------
> @@
> @@
> -foo
> +bar
> --------
> 
> Will replace function calls of foo wityh function calls of bar - and as a 
> bonus it will also update functionpointers to bar.
> Unfortunately also other identifiers are matched.
> 
> Look at this example:
> 
> ------------
> void foo(int baz)
> {
>   printf("foo %d",baz);
> }
> 
> void baz(int foo)
> {
>   int bar = 5;
>   switch (foo) {
>   case 1 :
>     break ;
>   case 2:
>     foo(2);
>     printf("two");
>     break ;
>   default:
>     printf("baz %d", bar);
>     break;
>   }
> }
> 
> typedef void (Func)(int);
> Func *funclist [] = { foo, baz };
> 
> void buh(int bah)
> {
>   (funclist[0])(bah);
>   (funclist[1])(bah);
> }
> ------------
> 
> This will generate this patch:
> ----------
> --- switch.c    2010-01-06 14:13:39.742564000 +0100
> +++ /tmp/cocci-output-19759-1fb20a-switch.c     2010-01-06 14:15:52.000000000 
> +0100
> @@ -6,11 +6,11 @@ void foo(int baz)
>  void baz(int foo)
>  {
>    int bar = 5;
> -  switch (foo) {
> +  switch (bar) {
>    case 1 :
>      break ;
>    case 2:
> -    foo(2);
> +    bar(2);
>      printf("two");
>      break ;
>    default:
> @@ -20,7 +20,7 @@ void baz(int foo)
>  }
> 
>  typedef void (Func)(int);
> -Func *funclist [] = { foo, baz };
> +Func *funclist [] = { bar, baz };
> 
>  void buh(int bah)
>  {
> ----------
> 
> switch(foo) is changed to switch(bar). Not good. can I avoid this and still 
> get function pointers updated?
> 
> regards,
> Andreas Bach Aaen
> 


_______________________________________________
Cocci mailing list
[email protected]
http://lists.diku.dk/mailman/listinfo/cocci
(Web access from inside DIKUs LAN only)

Reply via email to