On Tue, 8 May 2012, [email protected] wrote:


Just found that it also cannot handle macro definitions, such as:

#define MY_MACRO_WRAPPER(x) my_mutex_lock(X)

Normally, Coccinelle does not unfold macro definitions. This allows you to write patterns in terms of macro names and ensures that it can reconstruct code that looks like the original. It does make some effort to take macro definitions into account when they have an impact on the control flow (ie a macro that contains a return), but that is not your problem here.

One solution for you would be to match the macro definition as well. You can say:

@r@
identifier f;
@@

#define f(x) my_mutex_lock(x)

@@
identifier r.f;
@@

-f
+newname
 (...)

For this, coccinelle has to be able to find the macro definition when it is processing the C code file that is using the macro. If the macro can be defined in a header file, you will need the argument --all-includes to spatch, so that it includes the header files mentioned in the C file, or --recursive-includes if you think files included by other include files will be needed. There are several options for this, because parsing the header files can be very time consuming.

On the other hand, if you only expected the right hand side of the macro definition to be transformed, then that should have been done.

For #ifdefs, normally coccinelle transforms code within #ifdefs. If it does not in your case, it means that it was not able to parse the containing function for some reason. If you are working on something other than Linux, you may want to start by running

spatch -parse_c directroy_name

Then it will try to parse everything and give a list of the most common problems. Most of the problems are related to macros. For example, your software might have an annotation UNUSED that coccinelle will not know what to do with. You can make a file called macros.h that contains definitions for these macros. For example, in your macros.h you could put

#define UNUSED

which will cause UNUSED to be ignored. It will, however, not be possible to match against UNUSED either, or to transform it, so it is best to do this only when it is necessary. The corresponding file for Linux is probably in:

/usr/local/share/coccinelle/standard.h

Mostly you just put normal macro definitions, but it is also possible to simply indicate that a macro call does not need a semicolon at the end, with the notation #define macroname MACROSTATEMENT

Then when you run spatch, you can give the argument --macro-file-builtins macros.h

julia


 

It this same as expectation? Is it possible make it works?

 

Thanks,

Xuezhao

From: Liu, Xuezhao
Sent: 2012年5月8日 17:47
To: [email protected]
Cc: Liu, Xuezhao
Subject: one question for using coccinelle - cannot handle code in "#ifdef
... #endif" section

 

Hi,

 

Thanks for bring up a good tool – coccinelle.

 

I did a simple test just now and found a problem, seems it cannot
parse/handle the code in some “#ifdef … #endif” sections.

 

The details is below:

I have a project with many source files, I want to replace “my_mutex_lock”
function call to “mutext_lock”.

I wrote a simple rule(test.spatch) for it:

@@ expression X; @@

- my_mutex_lock(X)

+ mutex_lock(X)

 

And I apply the semantic patch by “spatch -dir ~/my_dir --sp-file
test.spatch -in_place -include_headers”.

 

After it is done, I checked that most “my_mutex_lock” function calls are
replaced by  “mutext_lock” successfully, but some are not.

The failure cases seem to be in some “#ifdef … #endif” sections, such as

#ifdef MY_MACRO_A

my_mutex_lock(x);

#endif

The “my_mutex_lock” in the above case cannot be detected by coccinelle, it
kept unchanged.

 

Is there any method to workaround it?

 

Thanks,

Xuezhao


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

Reply via email to