All of lore.kernel.org
 help / color / mirror / Atom feed
* [Cocci] Adding missing parameter to function if missing
@ 2016-07-06 13:54 Frédéric LEROY (ext)
  2016-07-06 16:23 ` Julia Lawall
  2016-07-06 16:50 ` [Cocci] Adding " SF Markus Elfring
  0 siblings, 2 replies; 9+ messages in thread
From: Frédéric LEROY (ext) @ 2016-07-06 13:54 UTC (permalink / raw)
  To: cocci

Hi, 

I am new to coccinelle and I have trouble to use it.
What I want to do is add a missing parameter to a function call (bar)
and add this parameter to the function prototype calling it if missing.

Example : 

f1(void *arg) {
	bar(anything);
}

f2(my_type foo, void *arg) {
	bar(anything);
}

=> 

f1(my_type foo, void *arg) {
	bar (foo, anything);
}

f2(my_type foo, void *arg) {
	bar (foo, anything);
}

I tried several ways to do it without success. If I add a negative depends on rule, it won't work.

Here is the c test file :

--------8<--------8<--------8<--------8<--------8<
static void f1(void *args) {
    bar(anything);
}

static void f2(my_type *foo, void *args) {
    bar(anything);
}

static void f3(my_type *foo, void *args) {
}

static void f4(void *args) {
}

static void f5(void *args) {
    int b;
    bar(anything);
    b = 5;
    bar(anything);
}

static void f6(my_type *foo, void *args) {
    int b;
    bar(anything);
    b = 5;
    bar(anything);
}
--------8<--------8<--------8<--------8<--------8<

And here my spatch:

--------8<--------8<--------8<--------8<--------8<
@@
expression E;
@@

- bar(E);
+ bar(foo, E);

@fn_with_user@
identifier fn, foo;
typedef my_type;
parameter list pl;
expression E; 
@@

fn(my_type *foo, pl) {
<+... 
bar(foo, E);
...+> 
}

@ test depends on !fn_with_user@
identifier fn_with_user.fn;
parameter list pl;
expression E;
@@    

fn(
+ my_type *foo,
pl) {
<+...
bar(foo, E);
...+>
}
--------8<--------8<--------8<--------8<--------8<

Could you help me ?

Sincerely,

Fr?d?ric Leroy

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Cocci] Adding missing parameter to function if missing
  2016-07-06 13:54 [Cocci] Adding missing parameter to function if missing Frédéric LEROY (ext)
@ 2016-07-06 16:23 ` Julia Lawall
  2016-07-07 12:18   ` Frédéric LEROY (ext)
  2016-07-06 16:50 ` [Cocci] Adding " SF Markus Elfring
  1 sibling, 1 reply; 9+ messages in thread
From: Julia Lawall @ 2016-07-06 16:23 UTC (permalink / raw)
  To: cocci

> @ test depends on !fn_with_user@
> identifier fn_with_user.fn;
> parameter list pl;
> expression E;
> @@
>
> fn(
> + my_type *foo,
> pl) {
> <+...
> bar(foo, E);
> ...+>
> }

This rule is contradictory.  You say that the rule fn_with_user should not
have matched, but you want to match the identifier fn_with_user.fn.
Instead, you should match fn first, then have one rule that matches the
case you don't want, and then finally the case that you do want:

@barfn@
identifier fn;
@@

fn(...) {
<+...
bar(...);
...+>
}

@fn_with_user@
identifier barfn.fn, foo;
typedef my_type;
parameter list pl;
expression E;
@@

fn(my_type *foo, pl) {
<+...
bar(foo, E);
...+>
}

@ test depends on !fn_with_user@
identifier barfn.fn;
parameter list pl;
expression E;
@@

fn(
+ my_type *foo,
pl) {
<+...
bar(foo, E);
...+>
}

When you match barfn, you create an environment for each possible value of
fn.  This is then passed through the next two rules, where it records
whether the rule fn_with_user matches.  There is a separate environment for
each match of barfn.

julia

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Cocci] Adding parameter to function if missing
  2016-07-06 13:54 [Cocci] Adding missing parameter to function if missing Frédéric LEROY (ext)
  2016-07-06 16:23 ` Julia Lawall
@ 2016-07-06 16:50 ` SF Markus Elfring
  2016-07-07 11:54   ` Frédéric LEROY (ext)
  1 sibling, 1 reply; 9+ messages in thread
From: SF Markus Elfring @ 2016-07-06 16:50 UTC (permalink / raw)
  To: cocci

> I am new to coccinelle and I have trouble to use it.

Which software versions do you try out here?


> What I want to do is add a missing parameter to a function call (bar)

This is usual.


> and add this parameter to the function prototype calling it if missing.

I imagine that there are further software development challenges to consider
for such a source code transformation in header files.


> I tried several ways to do it without success. If I add a negative depends on rule, it won't work.

Do you get an error message?


> @fn_with_user@
> identifier fn, foo;
> typedef my_type;

How do you think about the SmPL specification "type my_type;" here?


> parameter list pl;
> expression E; 
> @@
> 
> fn(my_type *foo, pl) {
> <+... 
> bar(foo, E);
> ...+> 
> }
> 
> @ test depends on !fn_with_user@
> identifier fn_with_user.fn;

Will it make sense to add the SmPL specification "type fn_with_user.my_type;" here?


> parameter list pl;
> expression E;
> @@    
> 
> fn(
> + my_type *foo,
> pl) {
> <+...
> bar(foo, E);

Would you like to merge this place with your first SmPL rule?

 bar(
+    foo,
     E);


> Could you help me ?

I hope so.

Regards,
Markus

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Cocci] Adding parameter to function if missing
  2016-07-06 16:50 ` [Cocci] Adding " SF Markus Elfring
@ 2016-07-07 11:54   ` Frédéric LEROY (ext)
  2016-07-07 15:43     ` SF Markus Elfring
  0 siblings, 1 reply; 9+ messages in thread
From: Frédéric LEROY (ext) @ 2016-07-07 11:54 UTC (permalink / raw)
  To: cocci

Hello Markus,

> -----Message d'origine-----
> De?: SF Markus Elfring [mailto:elfring at users.sourceforge.net]
> Envoy??: mercredi 6 juillet 2016 18:51
> ??: Fr?d?ric LEROY (ext)
> Cc?: Coccinelle
> Objet?: Re: [Cocci] Adding parameter to function if missing
> 
> > I am new to coccinelle and I have trouble to use it.
> 
> Which software versions do you try out here?

Either 1.0.0 from Ubuntu 15.10 or 1.0.4 from Ubuntu 16.04

> I imagine that there are further software development challenges to
> consider for such a source code transformation in header files.

You are right, I learn spatch to make work on a bigger software.
I narrowed my problem with a simple example.

> > I tried several ways to do it without success. If I add a negative depends on
> rule, it won't work.
> 
> Do you get an error message?

Not much :
    init_defs_builtins: /usr/share/coccinelle/standard.h
    warning: line 32: foo, previously declared as a metavariable, is used as an identifier
    HANDLING: test.c
    diff = 
    --- test.c
    +++ /tmp/cocci-output-7971-016dcc-test.c
    @@ -1,9 +1,9 @@
     void f1(void *args) {
    -    bar(anything);
    +    bar(foo, anything);
     }
    [...]
All call are replaced and no header are modified.

> > @fn_with_user@
> > identifier fn, foo;
> > typedef my_type;
> 
> How do you think about the SmPL specification "type my_type;" here?
 
I used typedef to not redeclare it on following rules.
I just did a quick test, but I have the same output.
 
> > parameter list pl;
> > expression E;
> > @@
> >
> > fn(my_type *foo, pl) {
> > <+...
> > bar(foo, E);
> > ...+>
> > }
> >
> > @ test depends on !fn_with_user@
> > identifier fn_with_user.fn;
> 
> Will it make sense to add the SmPL specification "type
> fn_with_user.my_type;" here?

Removing typedef and using type gave me the same result.

> > parameter list pl;
> > expression E;
> > @@
> >
> > fn(
> > + my_type *foo,
> > pl) {
> > <+...
> > bar(foo, E);
> 
> Would you like to merge this place with your first SmPL rule?

Thanks, I make a version which works:

@ rule2 @
identifier fn;
expression E;
typedef my_type;
parameter list pl;
@@

 fn(my_type foo, pl) {
   <+...
- bar(E);
+ bar(foo, E);
  ...+>
}

@ rule4 @
identifier fn;
expression E;
identifier p;
@@

- fn(void) {
+ fn(my_type foo) {
   <+...
- bar(E);
+ bar(foo, E);
  ...+>
}

@ rule3 @
identifier fn;
expression E;
parameter list pl;
@@

- fn(pl) {
+ fn(my_type foo, pl) {
   <+...
- bar(E);
+ bar(foo, E);
  ...+>
}

> > Could you help me ?
> I hope so.

Thank you Markus :)

Regards,

Fr?d?ric Leroy

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Cocci] Adding missing parameter to function if missing
  2016-07-06 16:23 ` Julia Lawall
@ 2016-07-07 12:18   ` Frédéric LEROY (ext)
  2016-07-07 16:14     ` [Cocci] Adding " SF Markus Elfring
  2016-07-07 17:09     ` [Cocci] Adding missing " Julia Lawall
  0 siblings, 2 replies; 9+ messages in thread
From: Frédéric LEROY (ext) @ 2016-07-07 12:18 UTC (permalink / raw)
  To: cocci

Hello Julia,

> > @ test depends on !fn_with_user@
> > identifier fn_with_user.fn;
> > parameter list pl;
> [...]
> 
> This rule is contradictory.  You say that the rule fn_with_user should not have
> matched, but you want to match the identifier fn_with_user.fn.
> Instead, you should match fn first, then have one rule that matches the case
> you don't want, and then finally the case that you do want:

I was desesperate to the point to try everything ;-)

> When you match barfn, you create an environment for each possible value
> of fn.  This is then passed through the next two rules, where it records
> whether the rule fn_with_user matches.  There is a separate environment for
> each match of barfn.

Understood.

I have narrowed the issue with the help of --debug to this part :

@fn_with_user@
identifier barfn.fn, foo;
typedef my_type;
parameter list pl;
expression E;
@@

fn(my_type *foo, pl) {
<+...
bar(foo, E);
...+>
}

I was confusing between the type name 'my_type' and type value 'my_type'.

What I would to do is something like that :

@fn_with_user@
identifier fn, foo;
typedef T = "my_type"; // '= ...' is not correct
parameter list pl;
@@

fn(T *foo, pl) {
<+...
bar(...);
...+>
}

But I don't know how to link 'my_type' value to type T ...
I am sure that I am missing something obvious there :(

Sincerely,

Fr?d?ric Leroy

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Cocci] Adding parameter to function if missing
  2016-07-07 11:54   ` Frédéric LEROY (ext)
@ 2016-07-07 15:43     ` SF Markus Elfring
  0 siblings, 0 replies; 9+ messages in thread
From: SF Markus Elfring @ 2016-07-07 15:43 UTC (permalink / raw)
  To: cocci

>     +++ /tmp/cocci-output-7971-016dcc-test.c
>     @@ -1,9 +1,9 @@
>      void f1(void *args) {
>     -    bar(anything);
>     +    bar(foo, anything);
>      }
>     [...]
> All call are replaced and no header are modified.

Would you like to achieve such source code transformations also in header files?


>> Will it make sense to add the SmPL specification "type
>> fn_with_user.my_type;" here?
> 
> Removing typedef and using type gave me the same result.

I suggest to reconsider also the relevance of the prefix "fn_with_user.".
Will such a references to a previous SmPL rule matter in your use cases
a bit more occasionally?


> - fn(void) {
> + fn(my_type foo) {
>    <+...
> - bar(E);
> + bar(foo, E);
>   ...+>
> }

How do you think about to use a shorter change variant?

 fn(
-   void
+   my_type foo
   )
 {
 <+...
 bar(
+    foo,
     E);
 ...+>
 }

Regards,
Markus

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Cocci] Adding parameter to function if missing
  2016-07-07 12:18   ` Frédéric LEROY (ext)
@ 2016-07-07 16:14     ` SF Markus Elfring
  2016-07-08 10:46       ` Frédéric LEROY (ext)
  2016-07-07 17:09     ` [Cocci] Adding missing " Julia Lawall
  1 sibling, 1 reply; 9+ messages in thread
From: SF Markus Elfring @ 2016-07-07 16:14 UTC (permalink / raw)
  To: cocci

> I was confusing between the type name 'my_type' and type value 'my_type'.
> 
> What I would to do is something like that :
> 
> @fn_with_user@
> identifier fn, foo;
> typedef T = "my_type"; // '= ...' is not correct

Does such a specification indicate that you want to make a detail
better configurable?


> parameter list pl;
> @@
> 
> fn(T *foo, pl) {
> <+...
> bar(...);
> ...+>
> }
> 
> But I don't know how to link 'my_type' value to type T ...

Do you imagine to apply another parameter?

Is the functionality around "virtual" in the semantic patch language
relevant here?
http://coccinelle.lip6.fr/docs/main_grammar001.html


> I am sure that I am missing something obvious there :(

I hope that a better understanding can be achieved for special aspects
of your use case.

Regards,
Markus

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Cocci] Adding missing parameter to function if missing
  2016-07-07 12:18   ` Frédéric LEROY (ext)
  2016-07-07 16:14     ` [Cocci] Adding " SF Markus Elfring
@ 2016-07-07 17:09     ` Julia Lawall
  1 sibling, 0 replies; 9+ messages in thread
From: Julia Lawall @ 2016-07-07 17:09 UTC (permalink / raw)
  To: cocci



On Thu, 7 Jul 2016, Fr?d?ric LEROY (ext) wrote:

> Hello Julia,
>
> > > @ test depends on !fn_with_user@
> > > identifier fn_with_user.fn;
> > > parameter list pl;
> > [...]
> >
> > This rule is contradictory.  You say that the rule fn_with_user should not have
> > matched, but you want to match the identifier fn_with_user.fn.
> > Instead, you should match fn first, then have one rule that matches the case
> > you don't want, and then finally the case that you do want:
>
> I was desesperate to the point to try everything ;-)
>
> > When you match barfn, you create an environment for each possible value
> > of fn.  This is then passed through the next two rules, where it records
> > whether the rule fn_with_user matches.  There is a separate environment for
> > each match of barfn.
>
> Understood.
>
> I have narrowed the issue with the help of --debug to this part :
>
> @fn_with_user@
> identifier barfn.fn, foo;
> typedef my_type;

Te typedef here is fine, if you want the type to be called my_type.

> parameter list pl;
> expression E;
> @@
>
> fn(my_type *foo, pl) {
> <+...
> bar(foo, E);
> ...+>
> }
>
> I was confusing between the type name 'my_type' and type value 'my_type'.
>
> What I would to do is something like that :
>
> @fn_with_user@
> identifier fn, foo;
> typedef T = "my_type"; // '= ...' is not correct

I'm not sure to understand what is the point of this.

> parameter list pl;
> @@
>
> fn(T *foo, pl) {
> <+...
> bar(...);
> ...+>
> }
>
> But I don't know how to link 'my_type' value to type T ...
> I am sure that I am missing something obvious there :(

Was it not working with the code I suggested?

julia

> Sincerely,
>
> Fr?d?ric Leroy
>
>
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Cocci] Adding parameter to function if missing
  2016-07-07 16:14     ` [Cocci] Adding " SF Markus Elfring
@ 2016-07-08 10:46       ` Frédéric LEROY (ext)
  0 siblings, 0 replies; 9+ messages in thread
From: Frédéric LEROY (ext) @ 2016-07-08 10:46 UTC (permalink / raw)
  To: cocci

Hi Markus 

> > I was confusing between the type name 'my_type' and type value
> 'my_type'.
> [...]
> > But I don't know how to link 'my_type' value to type T ...
> > I am sure that I am missing something obvious there :(
> 
> Is the functionality around "virtual" in the semantic patch language relevant
> here?
> http://coccinelle.lip6.fr/docs/main_grammar001.html

This is exactly what I missed
Thanks Markus !

Fr?d?ric

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2016-07-08 10:46 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-07-06 13:54 [Cocci] Adding missing parameter to function if missing Frédéric LEROY (ext)
2016-07-06 16:23 ` Julia Lawall
2016-07-07 12:18   ` Frédéric LEROY (ext)
2016-07-07 16:14     ` [Cocci] Adding " SF Markus Elfring
2016-07-08 10:46       ` Frédéric LEROY (ext)
2016-07-07 17:09     ` [Cocci] Adding missing " Julia Lawall
2016-07-06 16:50 ` [Cocci] Adding " SF Markus Elfring
2016-07-07 11:54   ` Frédéric LEROY (ext)
2016-07-07 15:43     ` SF Markus Elfring

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.