Systemd/src/systemd/sd-bus-vtable.h

312 lines
19 KiB
C
Raw Normal View History

/* SPDX-License-Identifier: LGPL-2.1+ */
#ifndef foosdbusvtablehfoo
#define foosdbusvtablehfoo
/***
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include "_sd-common.h"
_SD_BEGIN_DECLARATIONS;
2013-11-07 03:47:42 +01:00
typedef struct sd_bus_vtable sd_bus_vtable;
#include "sd-bus.h"
enum {
2013-12-10 17:41:39 +01:00
_SD_BUS_VTABLE_START = '<',
_SD_BUS_VTABLE_END = '>',
_SD_BUS_VTABLE_METHOD = 'M',
_SD_BUS_VTABLE_SIGNAL = 'S',
_SD_BUS_VTABLE_PROPERTY = 'P',
_SD_BUS_VTABLE_WRITABLE_PROPERTY = 'W'
};
enum {
SD_BUS_VTABLE_DEPRECATED = 1ULL << 0,
SD_BUS_VTABLE_HIDDEN = 1ULL << 1,
SD_BUS_VTABLE_UNPRIVILEGED = 1ULL << 2,
SD_BUS_VTABLE_METHOD_NO_REPLY = 1ULL << 3,
SD_BUS_VTABLE_PROPERTY_CONST = 1ULL << 4,
SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE = 1ULL << 5,
SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION = 1ULL << 6,
SD_BUS_VTABLE_PROPERTY_EXPLICIT = 1ULL << 7,
SD_BUS_VTABLE_SENSITIVE = 1ULL << 8, /* covers both directions: method call + reply */
SD_BUS_VTABLE_ABSOLUTE_OFFSET = 1ULL << 9,
_SD_BUS_VTABLE_CAPABILITY_MASK = 0xFFFFULL << 40
};
2013-12-10 17:41:39 +01:00
#define SD_BUS_VTABLE_CAPABILITY(x) ((uint64_t) (((x)+1) & 0xFFFF) << 40)
enum {
_SD_BUS_VTABLE_PARAM_NAMES = 1 << 0,
};
sd-bus: add symbol to tell linker that new vtable functions are used In 856ad2a86bd9b3e264a090fcf4b0d05bfaa91030 sd_bus_add_object_vtable() and sd_bus_add_fallback_vtable() were changed to take an updated sd_bus_vtable[] array with additional 'features' and 'names' fields in the union. The commit tried to check whether the old or the new table format is used, by looking at the vtable[0].x.start.element_size field, on the assumption that the added fields caused the structure size to grow. Unfortunately, this assumption was false, and on arm32 (at least), the structure size is unchanged. In libsystemd we use symbol versioning and a major.minor.patch semantic versioning of the library name (major equals the number in the so-name). When systemd-242 was released, the minor number was (correctly) bumped, but this is not enough, because no new symbols were added or symbol versions changed. This means that programs compiled with the new systemd headers and library could be successfully linked to older versions of the library. For example rpm only looks at the so-name and the list of versioned symbols, completely ignoring the major.minor numbers in the library name. But the older library does not understand the new vtable format, and would return -EINVAL after failing the size check (on those architectures where the structure size did change, i.e. all 64 bit architectures). To force new libsystemd (with the functions that take the updated sd_bus_vtable[] format) to be used, let's pull in a dummy symbol from the table definition. This is a bit wasteful, because a dummy pointer has to be stored, but the effect is negligible. In particular, the pointer doesn't even change the size of the structure because if fits in an unused area in the union. The number stored in the new unsigned integer is not checked anywhere. If the symbol exists, we already know we have the new version of the library, so an additional check would not tell us anything. An alternative would be to make sd_bus_add_{object,fallback}_vtable() versioned symbols, using .symver linker annotations. We would provide sd_bus_add_{object,fallback}_vtable@LIBSYSTEMD_221 (for backwards compatibility) and e.g. sd_bus_add_{object,fallback}_vtable@@LIBSYSTEMD_242 (the default) with the new implementation. This would work too, but is more work. We would have to version at least those two functions. And it turns out that the .symver linker instructions have to located in the same compilation unit as the function being annotated. We first compile libsystemd.a, and then link it into libsystemd.so and various other targets, including libsystemd-shared.so, and the nss modules. If the .symver annotations were placed next to the function definitions (in bus-object.c), they would influence all targets that link libsystemd.a, and cause problems, because those functions should not be exported there. To export them only in libsystemd.so, compilation would have to be rearranged, so that the functions exported in libsystemd.so would not be present in libsystemd.a, but a separate compilation unit containg them and the .symver annotations would be linked solely into libsystemd.so. This is certainly possible, but more work than the approach in this patch. 856ad2a86bd9b3e264a090fcf4b0d05bfaa91030 has one more issue: it relies on the undefined fields in sd_bus_vtable[] array to be zeros. But the structure contains a union, and fields of the union do not have to be zero-initalized by the compiler. This means that potentially, we could have garbarge values there, for example when reading the old vtable format definition from the new function implementation. In practice this should not be an issue at all, because vtable definitions are static data and are placed in the ro-data section, which is fully initalized, so we know that those undefined areas will be zero. Things would be different if somebody defined the vtable array on the heap or on the stack. Let's just document that they should zero-intialize the unused areas in this case. The symbol checking code had to be updated because otherwise gcc warns about a cast from unsigned to a pointer.
2019-04-18 13:06:41 +02:00
extern const unsigned sd_bus_object_vtable_format;
2019-04-27 02:22:40 +02:00
/* Note: unused areas in the sd_bus_vtable[] array must be initialized to 0. The structure contains an embedded
* union, and the compiler is NOT required to initialize the unused areas of the union when the rest of the
* structure is initialized. Normally the array is defined as read-only data, in which case the linker places
* it in the BSS section, which is always fully initialized, so this is not a concern. But if the array is
* created on the stack or on the heap, care must be taken to initialize the unused areas, for examply by
sd-bus: add symbol to tell linker that new vtable functions are used In 856ad2a86bd9b3e264a090fcf4b0d05bfaa91030 sd_bus_add_object_vtable() and sd_bus_add_fallback_vtable() were changed to take an updated sd_bus_vtable[] array with additional 'features' and 'names' fields in the union. The commit tried to check whether the old or the new table format is used, by looking at the vtable[0].x.start.element_size field, on the assumption that the added fields caused the structure size to grow. Unfortunately, this assumption was false, and on arm32 (at least), the structure size is unchanged. In libsystemd we use symbol versioning and a major.minor.patch semantic versioning of the library name (major equals the number in the so-name). When systemd-242 was released, the minor number was (correctly) bumped, but this is not enough, because no new symbols were added or symbol versions changed. This means that programs compiled with the new systemd headers and library could be successfully linked to older versions of the library. For example rpm only looks at the so-name and the list of versioned symbols, completely ignoring the major.minor numbers in the library name. But the older library does not understand the new vtable format, and would return -EINVAL after failing the size check (on those architectures where the structure size did change, i.e. all 64 bit architectures). To force new libsystemd (with the functions that take the updated sd_bus_vtable[] format) to be used, let's pull in a dummy symbol from the table definition. This is a bit wasteful, because a dummy pointer has to be stored, but the effect is negligible. In particular, the pointer doesn't even change the size of the structure because if fits in an unused area in the union. The number stored in the new unsigned integer is not checked anywhere. If the symbol exists, we already know we have the new version of the library, so an additional check would not tell us anything. An alternative would be to make sd_bus_add_{object,fallback}_vtable() versioned symbols, using .symver linker annotations. We would provide sd_bus_add_{object,fallback}_vtable@LIBSYSTEMD_221 (for backwards compatibility) and e.g. sd_bus_add_{object,fallback}_vtable@@LIBSYSTEMD_242 (the default) with the new implementation. This would work too, but is more work. We would have to version at least those two functions. And it turns out that the .symver linker instructions have to located in the same compilation unit as the function being annotated. We first compile libsystemd.a, and then link it into libsystemd.so and various other targets, including libsystemd-shared.so, and the nss modules. If the .symver annotations were placed next to the function definitions (in bus-object.c), they would influence all targets that link libsystemd.a, and cause problems, because those functions should not be exported there. To export them only in libsystemd.so, compilation would have to be rearranged, so that the functions exported in libsystemd.so would not be present in libsystemd.a, but a separate compilation unit containg them and the .symver annotations would be linked solely into libsystemd.so. This is certainly possible, but more work than the approach in this patch. 856ad2a86bd9b3e264a090fcf4b0d05bfaa91030 has one more issue: it relies on the undefined fields in sd_bus_vtable[] array to be zeros. But the structure contains a union, and fields of the union do not have to be zero-initalized by the compiler. This means that potentially, we could have garbarge values there, for example when reading the old vtable format definition from the new function implementation. In practice this should not be an issue at all, because vtable definitions are static data and are placed in the ro-data section, which is fully initalized, so we know that those undefined areas will be zero. Things would be different if somebody defined the vtable array on the heap or on the stack. Let's just document that they should zero-intialize the unused areas in this case. The symbol checking code had to be updated because otherwise gcc warns about a cast from unsigned to a pointer.
2019-04-18 13:06:41 +02:00
* first memsetting the whole region to zero before filling the data in. */
struct sd_bus_vtable {
/* Please do not initialize this structure directly, use the
* macros below instead */
2013-12-10 17:41:39 +01:00
uint8_t type:8;
uint64_t flags:56;
union {
struct {
size_t element_size;
uint64_t features;
sd-bus: add symbol to tell linker that new vtable functions are used In 856ad2a86bd9b3e264a090fcf4b0d05bfaa91030 sd_bus_add_object_vtable() and sd_bus_add_fallback_vtable() were changed to take an updated sd_bus_vtable[] array with additional 'features' and 'names' fields in the union. The commit tried to check whether the old or the new table format is used, by looking at the vtable[0].x.start.element_size field, on the assumption that the added fields caused the structure size to grow. Unfortunately, this assumption was false, and on arm32 (at least), the structure size is unchanged. In libsystemd we use symbol versioning and a major.minor.patch semantic versioning of the library name (major equals the number in the so-name). When systemd-242 was released, the minor number was (correctly) bumped, but this is not enough, because no new symbols were added or symbol versions changed. This means that programs compiled with the new systemd headers and library could be successfully linked to older versions of the library. For example rpm only looks at the so-name and the list of versioned symbols, completely ignoring the major.minor numbers in the library name. But the older library does not understand the new vtable format, and would return -EINVAL after failing the size check (on those architectures where the structure size did change, i.e. all 64 bit architectures). To force new libsystemd (with the functions that take the updated sd_bus_vtable[] format) to be used, let's pull in a dummy symbol from the table definition. This is a bit wasteful, because a dummy pointer has to be stored, but the effect is negligible. In particular, the pointer doesn't even change the size of the structure because if fits in an unused area in the union. The number stored in the new unsigned integer is not checked anywhere. If the symbol exists, we already know we have the new version of the library, so an additional check would not tell us anything. An alternative would be to make sd_bus_add_{object,fallback}_vtable() versioned symbols, using .symver linker annotations. We would provide sd_bus_add_{object,fallback}_vtable@LIBSYSTEMD_221 (for backwards compatibility) and e.g. sd_bus_add_{object,fallback}_vtable@@LIBSYSTEMD_242 (the default) with the new implementation. This would work too, but is more work. We would have to version at least those two functions. And it turns out that the .symver linker instructions have to located in the same compilation unit as the function being annotated. We first compile libsystemd.a, and then link it into libsystemd.so and various other targets, including libsystemd-shared.so, and the nss modules. If the .symver annotations were placed next to the function definitions (in bus-object.c), they would influence all targets that link libsystemd.a, and cause problems, because those functions should not be exported there. To export them only in libsystemd.so, compilation would have to be rearranged, so that the functions exported in libsystemd.so would not be present in libsystemd.a, but a separate compilation unit containg them and the .symver annotations would be linked solely into libsystemd.so. This is certainly possible, but more work than the approach in this patch. 856ad2a86bd9b3e264a090fcf4b0d05bfaa91030 has one more issue: it relies on the undefined fields in sd_bus_vtable[] array to be zeros. But the structure contains a union, and fields of the union do not have to be zero-initalized by the compiler. This means that potentially, we could have garbarge values there, for example when reading the old vtable format definition from the new function implementation. In practice this should not be an issue at all, because vtable definitions are static data and are placed in the ro-data section, which is fully initalized, so we know that those undefined areas will be zero. Things would be different if somebody defined the vtable array on the heap or on the stack. Let's just document that they should zero-intialize the unused areas in this case. The symbol checking code had to be updated because otherwise gcc warns about a cast from unsigned to a pointer.
2019-04-18 13:06:41 +02:00
const unsigned *vtable_format_reference;
} start;
struct {
const char *member;
const char *signature;
const char *result;
sd_bus_message_handler_t handler;
size_t offset;
const char *names;
} method;
struct {
const char *member;
const char *signature;
const char *names;
} signal;
struct {
const char *member;
const char *signature;
sd_bus_property_get_t get;
sd_bus_property_set_t set;
size_t offset;
} property;
} x;
};
#define SD_BUS_VTABLE_START(_flags) \
{ \
.type = _SD_BUS_VTABLE_START, \
.flags = _flags, \
.x = { \
.start = { \
.element_size = sizeof(sd_bus_vtable), \
sd-bus: add symbol to tell linker that new vtable functions are used In 856ad2a86bd9b3e264a090fcf4b0d05bfaa91030 sd_bus_add_object_vtable() and sd_bus_add_fallback_vtable() were changed to take an updated sd_bus_vtable[] array with additional 'features' and 'names' fields in the union. The commit tried to check whether the old or the new table format is used, by looking at the vtable[0].x.start.element_size field, on the assumption that the added fields caused the structure size to grow. Unfortunately, this assumption was false, and on arm32 (at least), the structure size is unchanged. In libsystemd we use symbol versioning and a major.minor.patch semantic versioning of the library name (major equals the number in the so-name). When systemd-242 was released, the minor number was (correctly) bumped, but this is not enough, because no new symbols were added or symbol versions changed. This means that programs compiled with the new systemd headers and library could be successfully linked to older versions of the library. For example rpm only looks at the so-name and the list of versioned symbols, completely ignoring the major.minor numbers in the library name. But the older library does not understand the new vtable format, and would return -EINVAL after failing the size check (on those architectures where the structure size did change, i.e. all 64 bit architectures). To force new libsystemd (with the functions that take the updated sd_bus_vtable[] format) to be used, let's pull in a dummy symbol from the table definition. This is a bit wasteful, because a dummy pointer has to be stored, but the effect is negligible. In particular, the pointer doesn't even change the size of the structure because if fits in an unused area in the union. The number stored in the new unsigned integer is not checked anywhere. If the symbol exists, we already know we have the new version of the library, so an additional check would not tell us anything. An alternative would be to make sd_bus_add_{object,fallback}_vtable() versioned symbols, using .symver linker annotations. We would provide sd_bus_add_{object,fallback}_vtable@LIBSYSTEMD_221 (for backwards compatibility) and e.g. sd_bus_add_{object,fallback}_vtable@@LIBSYSTEMD_242 (the default) with the new implementation. This would work too, but is more work. We would have to version at least those two functions. And it turns out that the .symver linker instructions have to located in the same compilation unit as the function being annotated. We first compile libsystemd.a, and then link it into libsystemd.so and various other targets, including libsystemd-shared.so, and the nss modules. If the .symver annotations were placed next to the function definitions (in bus-object.c), they would influence all targets that link libsystemd.a, and cause problems, because those functions should not be exported there. To export them only in libsystemd.so, compilation would have to be rearranged, so that the functions exported in libsystemd.so would not be present in libsystemd.a, but a separate compilation unit containg them and the .symver annotations would be linked solely into libsystemd.so. This is certainly possible, but more work than the approach in this patch. 856ad2a86bd9b3e264a090fcf4b0d05bfaa91030 has one more issue: it relies on the undefined fields in sd_bus_vtable[] array to be zeros. But the structure contains a union, and fields of the union do not have to be zero-initalized by the compiler. This means that potentially, we could have garbarge values there, for example when reading the old vtable format definition from the new function implementation. In practice this should not be an issue at all, because vtable definitions are static data and are placed in the ro-data section, which is fully initalized, so we know that those undefined areas will be zero. Things would be different if somebody defined the vtable array on the heap or on the stack. Let's just document that they should zero-intialize the unused areas in this case. The symbol checking code had to be updated because otherwise gcc warns about a cast from unsigned to a pointer.
2019-04-18 13:06:41 +02:00
.features = _SD_BUS_VTABLE_PARAM_NAMES, \
.vtable_format_reference = &sd_bus_object_vtable_format, \
}, \
}, \
}
/* helper macro to format method and signal parameters, one at a time */
#define SD_BUS_PARAM(x) #x "\0"
#define SD_BUS_METHOD_WITH_NAMES_OFFSET(_member, _signature, _in_names, _result, _out_names, _handler, _offset, _flags) \
{ \
.type = _SD_BUS_VTABLE_METHOD, \
.flags = _flags, \
.x = { \
.method = { \
.member = _member, \
.signature = _signature, \
.result = _result, \
.handler = _handler, \
.offset = _offset, \
.names = _in_names _out_names, \
}, \
}, \
}
#define SD_BUS_METHOD_WITH_OFFSET(_member, _signature, _result, _handler, _offset, _flags) \
SD_BUS_METHOD_WITH_NAMES_OFFSET(_member, _signature, "", _result, "", _handler, _offset, _flags)
#define SD_BUS_METHOD_WITH_NAMES(_member, _signature, _in_names, _result, _out_names, _handler, _flags) \
SD_BUS_METHOD_WITH_NAMES_OFFSET(_member, _signature, _in_names, _result, _out_names, _handler, 0, _flags)
#define SD_BUS_METHOD(_member, _signature, _result, _handler, _flags) \
SD_BUS_METHOD_WITH_NAMES_OFFSET(_member, _signature, "", _result, "", _handler, 0, _flags)
#define SD_BUS_SIGNAL_WITH_NAMES(_member, _signature, _out_names, _flags) \
{ \
.type = _SD_BUS_VTABLE_SIGNAL, \
.flags = _flags, \
.x = { \
.signal = { \
.member = _member, \
.signature = _signature, \
.names = _out_names, \
}, \
}, \
}
#define SD_BUS_SIGNAL(_member, _signature, _flags) \
SD_BUS_SIGNAL_WITH_NAMES(_member, _signature, "", _flags)
#define SD_BUS_PROPERTY(_member, _signature, _get, _offset, _flags) \
{ \
.type = _SD_BUS_VTABLE_PROPERTY, \
.flags = _flags, \
.x = { \
.property = { \
.member = _member, \
.signature = _signature, \
.get = _get, \
.set = NULL, \
.offset = _offset, \
}, \
}, \
}
#define SD_BUS_WRITABLE_PROPERTY(_member, _signature, _get, _set, _offset, _flags) \
{ \
.type = _SD_BUS_VTABLE_WRITABLE_PROPERTY, \
.flags = _flags, \
.x = { \
.property = { \
.member = _member, \
.signature = _signature, \
.get = _get, \
.set = _set, \
.offset = _offset, \
}, \
}, \
}
#define SD_BUS_VTABLE_END \
{ \
.type = _SD_BUS_VTABLE_END, \
.flags = 0, \
.x = { { 0 } }, \
}
#define _SD_ECHO(X) X
#define _SD_CONCAT(X) #X "\0"
#define _SD_VARARGS_FOREACH_EVEN_01(FN, X, ...)
#define _SD_VARARGS_FOREACH_EVEN_02(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_01(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_03(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_02(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_04(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_03(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_05(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_04(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_06(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_05(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_07(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_06(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_08(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_07(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_09(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_08(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_10(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_09(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_11(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_10(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_12(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_11(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_13(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_12(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_14(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_13(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_15(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_14(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_16(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_15(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_17(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_16(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_18(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_17(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_19(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_18(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_20(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_19(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_21(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_20(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_22(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_21(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_23(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_22(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_24(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_23(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_25(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_24(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_26(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_25(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_27(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_26(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_28(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_27(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_29(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_28(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_30(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_29(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_31(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_30(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_32(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_31(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_33(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_32(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_34(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_33(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_35(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_34(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_36(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_35(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_37(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_36(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_38(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_37(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_39(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_38(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_40(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_39(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_41(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_40(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_42(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_41(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_43(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_42(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_44(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_43(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_45(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_44(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_46(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_45(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_47(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_46(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_48(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_47(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_49(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_48(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_50(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_49(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_SEQ(_01, _02, _03, _04, _05, _06, _07, _08, _09, _10, \
_11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
_21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
_31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
_41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
NAME, ...) NAME
#define _SD_VARARGS_FOREACH_EVEN(FN, ...) \
_SD_VARARGS_FOREACH_EVEN_SEQ(__VA_ARGS__, \
_SD_VARARGS_FOREACH_EVEN_50, _SD_VARARGS_FOREACH_EVEN_49, \
_SD_VARARGS_FOREACH_EVEN_48, _SD_VARARGS_FOREACH_EVEN_47, \
_SD_VARARGS_FOREACH_EVEN_46, _SD_VARARGS_FOREACH_EVEN_45, \
_SD_VARARGS_FOREACH_EVEN_44, _SD_VARARGS_FOREACH_EVEN_43, \
_SD_VARARGS_FOREACH_EVEN_42, _SD_VARARGS_FOREACH_EVEN_41, \
_SD_VARARGS_FOREACH_EVEN_40, _SD_VARARGS_FOREACH_EVEN_39, \
_SD_VARARGS_FOREACH_EVEN_38, _SD_VARARGS_FOREACH_EVEN_37, \
_SD_VARARGS_FOREACH_EVEN_36, _SD_VARARGS_FOREACH_EVEN_35, \
_SD_VARARGS_FOREACH_EVEN_34, _SD_VARARGS_FOREACH_EVEN_33, \
_SD_VARARGS_FOREACH_EVEN_32, _SD_VARARGS_FOREACH_EVEN_31, \
_SD_VARARGS_FOREACH_EVEN_30, _SD_VARARGS_FOREACH_EVEN_29, \
_SD_VARARGS_FOREACH_EVEN_28, _SD_VARARGS_FOREACH_EVEN_27, \
_SD_VARARGS_FOREACH_EVEN_26, _SD_VARARGS_FOREACH_EVEN_25, \
_SD_VARARGS_FOREACH_EVEN_24, _SD_VARARGS_FOREACH_EVEN_23, \
_SD_VARARGS_FOREACH_EVEN_22, _SD_VARARGS_FOREACH_EVEN_21, \
_SD_VARARGS_FOREACH_EVEN_20, _SD_VARARGS_FOREACH_EVEN_19, \
_SD_VARARGS_FOREACH_EVEN_18, _SD_VARARGS_FOREACH_EVEN_17, \
_SD_VARARGS_FOREACH_EVEN_16, _SD_VARARGS_FOREACH_EVEN_15, \
_SD_VARARGS_FOREACH_EVEN_14, _SD_VARARGS_FOREACH_EVEN_13, \
_SD_VARARGS_FOREACH_EVEN_12, _SD_VARARGS_FOREACH_EVEN_11, \
_SD_VARARGS_FOREACH_EVEN_10, _SD_VARARGS_FOREACH_EVEN_09, \
_SD_VARARGS_FOREACH_EVEN_08, _SD_VARARGS_FOREACH_EVEN_07, \
_SD_VARARGS_FOREACH_EVEN_06, _SD_VARARGS_FOREACH_EVEN_05, \
_SD_VARARGS_FOREACH_EVEN_04, _SD_VARARGS_FOREACH_EVEN_03, \
_SD_VARARGS_FOREACH_EVEN_02, _SD_VARARGS_FOREACH_EVEN_01) \
(FN, __VA_ARGS__)
#define SD_BUS_ARGS(...) __VA_ARGS__
#define SD_BUS_RESULT(...) __VA_ARGS__
#define SD_BUS_NO_ARGS SD_BUS_ARGS(NULL,)
#define SD_BUS_NO_RESULT SD_BUS_RESULT(NULL,)
#define SD_BUS_METHOD_WITH_ARGS(_member, _args, _result, _handler, _flags) \
SD_BUS_METHOD_WITH_NAMES(_member, \
_SD_VARARGS_FOREACH_EVEN(_SD_ECHO, _args), \
_SD_VARARGS_FOREACH_EVEN(_SD_CONCAT, _args, ""), \
_SD_VARARGS_FOREACH_EVEN(_SD_ECHO, _result), \
_SD_VARARGS_FOREACH_EVEN(_SD_CONCAT, _result, ""), \
_handler, _flags)
#define SD_BUS_METHOD_WITH_ARGS_OFFSET(_member, _args, _result, _handler, _offset, _flags) \
SD_BUS_METHOD_WITH_NAMES_OFFSET(_member, \
_SD_VARARGS_FOREACH_EVEN(_SD_ECHO, _args), \
_SD_VARARGS_FOREACH_EVEN(_SD_CONCAT, _args, ""), \
_SD_VARARGS_FOREACH_EVEN(_SD_ECHO, _result), \
_SD_VARARGS_FOREACH_EVEN(_SD_CONCAT, _result, ""), \
_handler, _offset, _flags)
#define SD_BUS_SIGNAL_WITH_ARGS(_member, _args, _flags) \
SD_BUS_SIGNAL_WITH_NAMES(_member, \
_SD_VARARGS_FOREACH_EVEN(_SD_ECHO, _args), \
_SD_VARARGS_FOREACH_EVEN(_SD_CONCAT, _args, ""), \
_flags)
_SD_END_DECLARATIONS;
2013-11-07 03:47:42 +01:00
#endif