1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2025-04-04 12:40:12 +02:00
CommandStation-EX/DCCEXParserMacros.h
2025-03-14 16:36:21 +00:00

38 lines
1.4 KiB
C

// Macro for printing a single argument
#define ZZARG(arg) \
auto arg=p[_xix]; (void)arg;\
if ( #arg[0]<='Z' && p[_xix]!=CONCAT(#arg,_hk)) break; \
_xix++;
#define FOR_EACH_IMPL_1(x) ZZARG(x)
#define FOR_EACH_IMPL_2(x, ...) ZZARG(x) FOR_EACH_IMPL_1(__VA_ARGS__)
#define FOR_EACH_IMPL_3(x, ...) ZZARG(x) FOR_EACH_IMPL_2(__VA_ARGS__)
#define FOR_EACH_IMPL_4(x, ...) ZZARG(x) FOR_EACH_IMPL_3(__VA_ARGS__)
#define FOR_EACH_IMPL_5(x, ...) ZZARG(x) FOR_EACH_IMPL_4(__VA_ARGS__)
#define FOR_EACH_IMPL_6(x, ...) ZZARG(x) FOR_EACH_IMPL_5(__VA_ARGS__)
// Add more levels if needed...
// Step 1: Count the number of arguments
#define FOR_EACH_NARG(...) FOR_EACH_NARG_(__VA_ARGS__, 6, 5, 4, 3, 2, 1)
#define FOR_EACH_NARG_(_1, _2, _3, _4, _5, _6,N, ...) N
// Step 2: Force proper expansion (extra indirection to resolve `##`)
#define EXPAND(x) x
#define CONCAT(a, b) a##b
// Step 3: Dispatch to the correct implementation
#define FOR_EACH_IMPL(count, ...) EXPAND(CONCAT(FOR_EACH_IMPL_, count))(__VA_ARGS__)
// Step 4: Main macro to process arguments
#define FOR_EACH(...) FOR_EACH_IMPL(FOR_EACH_NARG(__VA_ARGS__), __VA_ARGS__)
#define ZZ(op,...) return true; }\
if (opcode==#op[0] && params==FOR_EACH_NARG(__VA_ARGS__)) for (auto _xix=0;;) { \
FOR_EACH(__VA_ARGS__)
#define ZZBEGIN if (false) {
#define ZZEND return true; } return false;
#define CHECK(x) if (!(x)) return false;
#define EXPECT_CALLBACK CHECK(stashCallback(stream, p, ringStream)