diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2022-03-28 23:58:25 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2022-03-28 23:58:25 -0700 |
commit | 2eb80c3248fc5608e6447136e06618013ac73a26 (patch) | |
tree | bd1949e2b5178d3d591dfc430790a0c7fcd36db2 | |
parent | f303567317771d66b4cff4a2cb9361647da3f3be (diff) | |
download | cppawk-2eb80c3248fc5608e6447136e06618013ac73a26.tar.gz cppawk-2eb80c3248fc5608e6447136e06618013ac73a26.tar.bz2 cppawk-2eb80c3248fc5608e6447136e06618013ac73a26.zip |
narg: 16 argument safety red zone.
-rw-r--r-- | cppawk-include/narg-priv.h | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/cppawk-include/narg-priv.h b/cppawk-include/narg-priv.h index 87fb149..7dffe9d 100644 --- a/cppawk-include/narg-priv.h +++ b/cppawk-include/narg-priv.h @@ -32,17 +32,30 @@ #include "base.h" #endif -#define __narg_34(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, \ - A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, \ - A26, A27, A28, A29, A30, A31, A32, A33, N, ...) N +#define __bad _[<"too many args"<] -#define __xnarg_34(...) __narg_34(__VA_ARGS__) +#define __narg_50(B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, \ + B14, B15, B16, N33, N32, N31, N30, N29, N28, N27, N26, N25, \ + N24, N23, N22, N21, N20, N19, N18, N17, N16, N15, N14, N13, \ + N12, N11, N10, N9, N8, N7, N6, N5, N4, N3, N2, N1, N, ...) N -#define __narg(...) __xnarg_34(__dummy, ## __VA_ARGS__, 32, 31, 30, 29, 28, \ - 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, \ - 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, \ - 3, 2, 1, 0) +#define __xnarg_50(...) __narg_50(__VA_ARGS__) +// The __bad entries create a 16 position red zone. We effectively have +// space for 48 arguments, but if there are 33-48 arguments, we do not +// return an integer count, but rather bad syntax. Beyond 48 arguments, __narg +// starts to misbehave: it starts reproducing its 49th argument as its +// expansion. Without the 16 position bad syntax red zone, there would be +// and abrupt change: the macro would be good up to 32 arguments, returning the +// 1-32 ragument count, but the 33rd argument were added, the macro would +// misbehave badly, returning the 33rd argument, causnig a potentially +// hard-to-find bug. +#define __narg(...) __xnarg_50(__dummy, ## __VA_ARGS__, __bad, __bad, __bad, \ + __bad, __bad, __bad, __bad, __bad, __bad, \ + __bad, __bad, __bad, __bad, __bad, __bad, \ + __bad, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, \ + 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, \ + 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) #define __repn_1(mac1, mac2, a1) \ mac1(a1) |