On 10/22/19 3:57 PM, Michal Privoznik wrote:
For future reference and anybody interested, I've made
these changes using
coccinelle
http://coccinelle.lip6.fr/
I've used three semantic patches (aka spatch). The first one was to rename
virAsprintfQueit() to virAsprintf(). It is trivial:
$ cat virasprintf_rename.spatch
@@
@@
-virAsprintfQuiet
+virAsprintf
Runnig coccinelle is fairly easy now that Jano pushed the macro file [1]:
libvirt.git $ spatch --in-place --macro-file scripts/cocci-macro-file.h \
--sp-file virasprintf_rename.spatch --dir .
The second spatch is a bit more complicated/verbose:
$ cat virasprintf_no_return.spatch
@@
expression e1, e2, e3;
statement S;
@@
-if (virAsprintf(e1, e2, e3) < 0)
-S
+virAsprintf(e1, e2, e3);
@@
expression e1, e2, e3, e4;
statement S;
@@
-if (virAsprintf(e1, e2, e3, e4) < 0)
-S
+virAsprintf(e1, e2, e3, e4);
[this pattern continues 3 more times, each time new argument is added]
It is here that I've encountered first problems. Firstly, my spatch
skills are
not good enough (obviously), because I had to write several rules - each
one for
different number of arguments passed to virAsprintf(). But more importantly,
I've completely missed joined statements like:
if (virAsprintf() < 0 ||
virAsprintf() < 0)
goto cleanup;
On the other hand, I was left with only a few places that needed fixing.
Coccinelle did 90% of conversion and I needed to do the rest by hand,
which is a
fair trade off IMO.
Finally, the last spatch was used to rewrite code from using
virAsprintf() to
g_strdup_printf:
$ cat g_strdup_printf.spatch
@@
expression x;
@@
-virAsprintf(&x,
+x = g_strdup_printf(
...
);
Again, worked perfectly except few places where we did not pass &x but x
(which
was char **). I've tried to make an spatch for that too but didn't
succeed, so
I've fixed those places by hand.
Michal
1: Thing is, while coccinelle understands C very well, it doesn't quite
understand all those __attribute__ and other extensions. Therefore, some
macros
made it impossible for coccinelle to parse some functions (e.g. g_autofree,
g_autoptr and similar) and it did not perform requested change there then.