RE: [PATCH 2/2] perf tools: Make Power7 events available for perf

From: David Laight
Date: Thu Jun 20 2013 - 07:35:23 EST


> I think we should be able to do something better using the C
> preprocessor, this is exactly the sort of thing it's good at.
>
> What I mean is something like we do with arch/powerpc/include/asm/systbl.h,
> where we define the list of syscalls once, and then include it in
> multiple places, using different macro definitions to get different
> outputs.

There is a 'neat' trick - you can pass a #define macro the
name of another #define - which is then expanded after the
initial expansion. A description I happen to have is pasted below.

David

Consider what happens when #define foo(x) x(args) is expanded: foo(bar)
clearly becomes bar(args). If we also have #define bar(args) then bar()
is expanded AFTER foo() allowing us to generate any text including args.
So we have passed the name of one #define as a parameter to a different #define.

If we replace the definition of foo with
#define foo(x) x(args1) x(args2) then foo(bar) is equivalent to
bar(args1) bar(args2).
This is useful because foo(baz) expands to baz(args1) baz(args2)
allowing us to feed the same set of arguments to more than one #define.

A simple example:
#define lights(x) x(red) x(orange) x(green)
#define xx(colour) LIGHT_##colour,
enum { lights(xx) NUM_LIGHTS };
#undef xx
#define xx(colour) #colour,
static const char light_names[] = { lights(xx) };
#undef xx

This expands to:
enum { LIGHT_red, LIGHT_orange, LIGHT_green, NUM_LIGHTS };
static const char light_names[] = { ”red”, ”orange”, ”green”, };
(We needed to add NUM_LIGHTS because a trailing comma isn’t valid in a C++ enum.)


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/