From: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
To: Markus Armbruster <armbru@redhat.com>,
Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-trivial@nongnu.org, peter.maydell@linaro.org, qemu-devel@nongnu.org
Subject: Re: [Qemu-trivial] [Qemu-devel] [PATCH v2] add macro file for coccinelle
Date: Tue, 8 Sep 2015 16:31:44 +0300 [thread overview]
Message-ID: <55EEE340.10607@gmail.com> (raw)
In-Reply-To: <87h9n5p3ou.fsf@blackfin.pond.sub.org>
On 09/08/2015 02:10 PM, Markus Armbruster wrote:
> Paolo Bonzini <pbonzini@redhat.com> writes:
>
>> Coccinelle chokes on some idioms from compiler.h and queue.h.
>> Extract those in a macro file, to be used with "--macro-file
>> scripts/cocci-macro-file.h".
>>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>
> I tested this as follows. Coccinelle can report on its parsing
> difficulties:
>
> $ spatch --parse-c `git-ls-files | grep '\.c$'
>
> Requires a generous ulimit -s, and produces tons of output. The
> interesting part here is the summary at the end:
>
> NB total files = 1923; perfect = 1377; pbs = 545; timeout = 0; =========> 71%
> nb good = 964472, nb passed = 14824 =========> 1.48% passed
> nb good = 964472, nb bad = 23759 =========> 97.63% good or passed
>
>
> Repeat with --macro-file scripts/cocci-macro-file.h.
>
> NB total files = 1923; perfect = 1463; pbs = 459; timeout = 0; =========> 76%
> nb good = 910559, nb passed = 15352 =========> 1.53% passed
> nb good = 910559, nb bad = 77610 =========> 92.27% good or passed
>
> The first line shows clear improvement: 86 more files are now deemed
> "perfect". I'm not sure how to read the remaining two lines.
>
> Also interesting are the "maybe 10 most problematic tokens". Before:
>
> -----------------------------------------------------------------------
> maybe 10 most problematic tokens
> -----------------------------------------------------------------------
> glue: present in 620 parsing errors
> example:
>
> #define OP_32_64(x) \
> glue(glue(case INDEX_op_, x), _i32): \
> glue(glue(case INDEX_op_, x), _i64)
> NULL: present in 507 parsing errors
> example:
> vs->dev = (QVirtioDevice *)dev;
> g_assert(dev != NULL);
> g_assert_cmphex(vs->dev->device_type, ==, QVIRTIO_SCSI_DEVICE_ID);
>
> VMStateField: present in 502 parsing errors
> example:
> .version_id = 1,
> .minimum_version_id = 1,
> .fields = (VMStateField[]) {
> VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
Hi Markus,
I talked to coccinelle maintainer some time ago about
the above C construct (fields = (VMStateField[]) {)
and sadly is not yet supported by the C parser.
If we want this we need to do it by ourselves :(
Thanks,
Marcel
> fields: present in 502 parsing errors
> example:
> .version_id = 1,
> .minimum_version_id = 1,
> .fields = (VMStateField[]) {
> VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
> minimum_version_id: present in 433 parsing errors
> example:
> .version_id = 1,
> .minimum_version_id = 1,
> .fields = (VMStateField[]) {
> VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
> uint32_t: present in 414 parsing errors
> example:
> uint32_t *bg, uint32_t *fg, \
> VncPalette **palette) { \
> uint##bpp##_t *data; \
> uint##bpp##_t c0, c1, ci; \
> env: present in 400 parsing errors
> example:
> int v = float32_compare_quiet(a, b, &env->fp_status);
> set_br(env, v != float_relation_greater, br);
> }
> version_id: present in 308 parsing errors
> example:
> .version_id = 1,
> .minimum_version_id = 1,
> .fields = (VMStateField[]) {
> VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
> x: present in 221 parsing errors
> example:
> Int128 a = expand(x);
> Int128 r = int128_rshift(a, n);
> g_assert_cmpuint(r.lo, ==, l);
> g_assert_cmpuint(r.hi, ==, h);
> a: present in 197 parsing errors
> example:
> vmstate_load_state(loading, &vmstate_skipping, &obj, 2);
> g_assert(!qemu_file_get_error(loading));
> g_assert_cmpint(obj.a, ==, 10);
> g_assert_cmpint(obj.b, ==, 20);
>
> After:
>
> -----------------------------------------------------------------------
> maybe 10 most problematic tokens
> -----------------------------------------------------------------------
> NULL: present in 506 parsing errors
> example:
> vs->dev = (QVirtioDevice *)dev;
> g_assert(dev != NULL);
> g_assert_cmphex(vs->dev->device_type, ==, QVIRTIO_SCSI_DEVICE_ID);
>
> VMStateField: present in 502 parsing errors
> example:
> .version_id = 1,
> .minimum_version_id = 1,
> .fields = (VMStateField[]) {
> VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
> fields: present in 502 parsing errors
> example:
> .version_id = 1,
> .minimum_version_id = 1,
> .fields = (VMStateField[]) {
> VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
> minimum_version_id: present in 433 parsing errors
> example:
> .version_id = 1,
> .minimum_version_id = 1,
> .fields = (VMStateField[]) {
> VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
> env: present in 376 parsing errors
> example:
> int v = float32_compare_quiet(a, b, &env->fp_status);
> set_br(env, v != float_relation_greater, br);
> }
> version_id: present in 308 parsing errors
> example:
> .version_id = 1,
> .minimum_version_id = 1,
> .fields = (VMStateField[]) {
> VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
> x: present in 221 parsing errors
> example:
> Int128 a = expand(x);
> Int128 r = int128_rshift(a, n);
> g_assert_cmpuint(r.lo, ==, l);
> g_assert_cmpuint(r.hi, ==, h);
> a: present in 197 parsing errors
> example:
> vmstate_load_state(loading, &vmstate_skipping, &obj, 2);
> g_assert(!qemu_file_get_error(loading));
> g_assert_cmpint(obj.a, ==, 10);
> g_assert_cmpint(obj.b, ==, 20);
> b: present in 164 parsing errors
> example:
> uint64_t rl, rh;
> muls64(&rl, &rh, test_s_data[i].a, test_s_data[i].b);
> g_assert_cmpuint(rl, ==, test_s_data[i].rl);
> g_assert_cmpint(rh, ==, test_s_data[i].rh);
> name: present in 150 parsing errors
> example:
> g_assert(list != NULL);
> g_assert(QTAILQ_EMPTY(&list->head));
> g_assert_cmpstr(list->name, ==, "opts_list_01");
>
> -----------------------------------------------------------------------
>
> Clearly visible is the effect of your cocci-macro-file.h's glue() .
>
>> ---
>> scripts/cocci-macro-file.h | 119 +++++++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 119 insertions(+)
>> create mode 100644 scripts/cocci-macro-file.h
>>
>> diff --git a/scripts/cocci-macro-file.h b/scripts/cocci-macro-file.h
>> new file mode 100644
>> index 0000000..eceb4be
>> --- /dev/null
>> +++ b/scripts/cocci-macro-file.h
>> @@ -0,0 +1,119 @@
>> +/* Macro file for Coccinelle
>> + *
>> + * Copyright (C) 2015 Red Hat, Inc.
>> + *
>> + * Authors:
>> + * Paolo Bonzini <pbonzini@redhat.com>
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2 or, at your
>> + * option, any later version. See the COPYING file in the top-level directory.
>> + */
>> +
>> +/* Coccinelle only does limited parsing of headers, and chokes on some idioms
>> + * defined in compiler.h and queue.h. Macros that Coccinelle must know about
>> + * in order to parse .c files must be in a separate macro file---which is
>> + * exactly what you're staring at now.
>> + *
>> + * To use this file, add the "--macro-file scripts/cocci-macro-file.h" to the
>> + * Coccinelle command line.
>> + */
>> +
>> +/* From qemu/compiler.h */
>> +#define QEMU_GNUC_PREREQ(maj, min) 1
>> +#define QEMU_NORETURN __attribute__ ((__noreturn__))
>> +#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
>> +#define QEMU_SENTINEL __attribute__((sentinel))
>> +#define QEMU_ARTIFICIAL __attribute__((always_inline, artificial))
>> +#define QEMU_PACKED __attribute__((gcc_struct, packed))
>> +
>> +#define cat(x,y) x ## y
>> +#define cat2(x,y) cat(x,y)
>
> Why not reuse glue()?
>
>> +#define QEMU_BUILD_BUG_ON(x) \
>> + typedef char cat2(qemu_build_bug_on__,__LINE__)[(x)?-1:1]
>> __attribute__((unused));
>> +
>> +#define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m)))
>> +
>> +#define xglue(x, y) x ## y
>> +#define glue(x, y) xglue(x, y)
>> +#define stringify(s) tostring(s)
>> +#define tostring(s) #s
>> +
>> +#define typeof_field(type, field) typeof(((type *)0)->field)
>> +#define type_check(t1,t2) ((t1*)0 - (t2*)0)
>> +
> [...]
>
> Preferably with cat2() replaced by glue():
> Reviewed-by: Markus Armbruster <armbru@redhat.com>
>
WARNING: multiple messages have this Message-ID (diff)
From: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
To: Markus Armbruster <armbru@redhat.com>,
Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-trivial@nongnu.org, peter.maydell@linaro.org, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [Qemu-trivial] [PATCH v2] add macro file for coccinelle
Date: Tue, 8 Sep 2015 16:31:44 +0300 [thread overview]
Message-ID: <55EEE340.10607@gmail.com> (raw)
In-Reply-To: <87h9n5p3ou.fsf@blackfin.pond.sub.org>
On 09/08/2015 02:10 PM, Markus Armbruster wrote:
> Paolo Bonzini <pbonzini@redhat.com> writes:
>
>> Coccinelle chokes on some idioms from compiler.h and queue.h.
>> Extract those in a macro file, to be used with "--macro-file
>> scripts/cocci-macro-file.h".
>>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>
> I tested this as follows. Coccinelle can report on its parsing
> difficulties:
>
> $ spatch --parse-c `git-ls-files | grep '\.c$'
>
> Requires a generous ulimit -s, and produces tons of output. The
> interesting part here is the summary at the end:
>
> NB total files = 1923; perfect = 1377; pbs = 545; timeout = 0; =========> 71%
> nb good = 964472, nb passed = 14824 =========> 1.48% passed
> nb good = 964472, nb bad = 23759 =========> 97.63% good or passed
>
>
> Repeat with --macro-file scripts/cocci-macro-file.h.
>
> NB total files = 1923; perfect = 1463; pbs = 459; timeout = 0; =========> 76%
> nb good = 910559, nb passed = 15352 =========> 1.53% passed
> nb good = 910559, nb bad = 77610 =========> 92.27% good or passed
>
> The first line shows clear improvement: 86 more files are now deemed
> "perfect". I'm not sure how to read the remaining two lines.
>
> Also interesting are the "maybe 10 most problematic tokens". Before:
>
> -----------------------------------------------------------------------
> maybe 10 most problematic tokens
> -----------------------------------------------------------------------
> glue: present in 620 parsing errors
> example:
>
> #define OP_32_64(x) \
> glue(glue(case INDEX_op_, x), _i32): \
> glue(glue(case INDEX_op_, x), _i64)
> NULL: present in 507 parsing errors
> example:
> vs->dev = (QVirtioDevice *)dev;
> g_assert(dev != NULL);
> g_assert_cmphex(vs->dev->device_type, ==, QVIRTIO_SCSI_DEVICE_ID);
>
> VMStateField: present in 502 parsing errors
> example:
> .version_id = 1,
> .minimum_version_id = 1,
> .fields = (VMStateField[]) {
> VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
Hi Markus,
I talked to coccinelle maintainer some time ago about
the above C construct (fields = (VMStateField[]) {)
and sadly is not yet supported by the C parser.
If we want this we need to do it by ourselves :(
Thanks,
Marcel
> fields: present in 502 parsing errors
> example:
> .version_id = 1,
> .minimum_version_id = 1,
> .fields = (VMStateField[]) {
> VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
> minimum_version_id: present in 433 parsing errors
> example:
> .version_id = 1,
> .minimum_version_id = 1,
> .fields = (VMStateField[]) {
> VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
> uint32_t: present in 414 parsing errors
> example:
> uint32_t *bg, uint32_t *fg, \
> VncPalette **palette) { \
> uint##bpp##_t *data; \
> uint##bpp##_t c0, c1, ci; \
> env: present in 400 parsing errors
> example:
> int v = float32_compare_quiet(a, b, &env->fp_status);
> set_br(env, v != float_relation_greater, br);
> }
> version_id: present in 308 parsing errors
> example:
> .version_id = 1,
> .minimum_version_id = 1,
> .fields = (VMStateField[]) {
> VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
> x: present in 221 parsing errors
> example:
> Int128 a = expand(x);
> Int128 r = int128_rshift(a, n);
> g_assert_cmpuint(r.lo, ==, l);
> g_assert_cmpuint(r.hi, ==, h);
> a: present in 197 parsing errors
> example:
> vmstate_load_state(loading, &vmstate_skipping, &obj, 2);
> g_assert(!qemu_file_get_error(loading));
> g_assert_cmpint(obj.a, ==, 10);
> g_assert_cmpint(obj.b, ==, 20);
>
> After:
>
> -----------------------------------------------------------------------
> maybe 10 most problematic tokens
> -----------------------------------------------------------------------
> NULL: present in 506 parsing errors
> example:
> vs->dev = (QVirtioDevice *)dev;
> g_assert(dev != NULL);
> g_assert_cmphex(vs->dev->device_type, ==, QVIRTIO_SCSI_DEVICE_ID);
>
> VMStateField: present in 502 parsing errors
> example:
> .version_id = 1,
> .minimum_version_id = 1,
> .fields = (VMStateField[]) {
> VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
> fields: present in 502 parsing errors
> example:
> .version_id = 1,
> .minimum_version_id = 1,
> .fields = (VMStateField[]) {
> VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
> minimum_version_id: present in 433 parsing errors
> example:
> .version_id = 1,
> .minimum_version_id = 1,
> .fields = (VMStateField[]) {
> VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
> env: present in 376 parsing errors
> example:
> int v = float32_compare_quiet(a, b, &env->fp_status);
> set_br(env, v != float_relation_greater, br);
> }
> version_id: present in 308 parsing errors
> example:
> .version_id = 1,
> .minimum_version_id = 1,
> .fields = (VMStateField[]) {
> VMSTATE_VBUFFER_UINT32(data, Fifo8, 1, NULL, 0, capacity),
> x: present in 221 parsing errors
> example:
> Int128 a = expand(x);
> Int128 r = int128_rshift(a, n);
> g_assert_cmpuint(r.lo, ==, l);
> g_assert_cmpuint(r.hi, ==, h);
> a: present in 197 parsing errors
> example:
> vmstate_load_state(loading, &vmstate_skipping, &obj, 2);
> g_assert(!qemu_file_get_error(loading));
> g_assert_cmpint(obj.a, ==, 10);
> g_assert_cmpint(obj.b, ==, 20);
> b: present in 164 parsing errors
> example:
> uint64_t rl, rh;
> muls64(&rl, &rh, test_s_data[i].a, test_s_data[i].b);
> g_assert_cmpuint(rl, ==, test_s_data[i].rl);
> g_assert_cmpint(rh, ==, test_s_data[i].rh);
> name: present in 150 parsing errors
> example:
> g_assert(list != NULL);
> g_assert(QTAILQ_EMPTY(&list->head));
> g_assert_cmpstr(list->name, ==, "opts_list_01");
>
> -----------------------------------------------------------------------
>
> Clearly visible is the effect of your cocci-macro-file.h's glue() .
>
>> ---
>> scripts/cocci-macro-file.h | 119 +++++++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 119 insertions(+)
>> create mode 100644 scripts/cocci-macro-file.h
>>
>> diff --git a/scripts/cocci-macro-file.h b/scripts/cocci-macro-file.h
>> new file mode 100644
>> index 0000000..eceb4be
>> --- /dev/null
>> +++ b/scripts/cocci-macro-file.h
>> @@ -0,0 +1,119 @@
>> +/* Macro file for Coccinelle
>> + *
>> + * Copyright (C) 2015 Red Hat, Inc.
>> + *
>> + * Authors:
>> + * Paolo Bonzini <pbonzini@redhat.com>
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2 or, at your
>> + * option, any later version. See the COPYING file in the top-level directory.
>> + */
>> +
>> +/* Coccinelle only does limited parsing of headers, and chokes on some idioms
>> + * defined in compiler.h and queue.h. Macros that Coccinelle must know about
>> + * in order to parse .c files must be in a separate macro file---which is
>> + * exactly what you're staring at now.
>> + *
>> + * To use this file, add the "--macro-file scripts/cocci-macro-file.h" to the
>> + * Coccinelle command line.
>> + */
>> +
>> +/* From qemu/compiler.h */
>> +#define QEMU_GNUC_PREREQ(maj, min) 1
>> +#define QEMU_NORETURN __attribute__ ((__noreturn__))
>> +#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
>> +#define QEMU_SENTINEL __attribute__((sentinel))
>> +#define QEMU_ARTIFICIAL __attribute__((always_inline, artificial))
>> +#define QEMU_PACKED __attribute__((gcc_struct, packed))
>> +
>> +#define cat(x,y) x ## y
>> +#define cat2(x,y) cat(x,y)
>
> Why not reuse glue()?
>
>> +#define QEMU_BUILD_BUG_ON(x) \
>> + typedef char cat2(qemu_build_bug_on__,__LINE__)[(x)?-1:1]
>> __attribute__((unused));
>> +
>> +#define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m)))
>> +
>> +#define xglue(x, y) x ## y
>> +#define glue(x, y) xglue(x, y)
>> +#define stringify(s) tostring(s)
>> +#define tostring(s) #s
>> +
>> +#define typeof_field(type, field) typeof(((type *)0)->field)
>> +#define type_check(t1,t2) ((t1*)0 - (t2*)0)
>> +
> [...]
>
> Preferably with cat2() replaced by glue():
> Reviewed-by: Markus Armbruster <armbru@redhat.com>
>
next prev parent reply other threads:[~2015-09-08 13:32 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-07 10:21 [Qemu-trivial] [PATCH v2] add macro file for coccinelle Paolo Bonzini
2015-09-07 10:21 ` [Qemu-devel] " Paolo Bonzini
2015-09-08 11:10 ` [Qemu-trivial] " Markus Armbruster
2015-09-08 11:10 ` Markus Armbruster
2015-09-08 12:44 ` [Qemu-trivial] " Paolo Bonzini
2015-09-08 12:44 ` Paolo Bonzini
2015-09-08 13:08 ` [Qemu-trivial] " Markus Armbruster
2015-09-08 13:08 ` Markus Armbruster
2015-09-08 13:31 ` Marcel Apfelbaum [this message]
2015-09-08 13:31 ` [Qemu-devel] [Qemu-trivial] " Marcel Apfelbaum
2015-09-08 17:30 ` [Qemu-trivial] [Qemu-devel] " John Snow
2015-09-08 17:30 ` John Snow
2015-09-08 18:35 ` [Qemu-trivial] " Markus Armbruster
2015-09-08 18:35 ` Markus Armbruster
2015-09-09 9:51 ` [Qemu-trivial] " Paolo Bonzini
2015-09-09 9:51 ` Paolo Bonzini
2015-09-10 21:23 ` [Qemu-trivial] " John Snow
2015-09-10 21:23 ` John Snow
2015-09-15 17:55 ` [Qemu-trivial] " Michael Tokarev
2015-09-15 17:55 ` [Qemu-devel] " Michael Tokarev
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=55EEE340.10607@gmail.com \
--to=marcel.apfelbaum@gmail.com \
--cc=armbru@redhat.com \
--cc=marcel@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-trivial@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.