From 446aed55e6fb9668f5094100de43c76c38e8cce7 Mon Sep 17 00:00:00 2001 From: TimePath Date: Thu, 31 Dec 2015 20:22:19 +1100 Subject: [PATCH] ##__VA_ARGS__: replace with standards compliant alternative --- qcsrc/client/main.qc | 3 +- qcsrc/common/debug.qh | 10 ++-- qcsrc/common/effects/effectinfo.qc | 7 ++- qcsrc/common/mutators/base.qh | 6 ++- qcsrc/lib/misc.qh | 7 ++- qcsrc/lib/net.qh | 3 +- qcsrc/lib/oo.qh | 25 ++++----- qcsrc/lib/p99.qh | 87 ++++++++++++++++++++++++++++++ qcsrc/lib/registry.qh | 4 +- qcsrc/lib/spawnfunc.qh | 8 ++- qcsrc/lib/vector.qh | 2 +- 11 files changed, 119 insertions(+), 43 deletions(-) create mode 100644 qcsrc/lib/p99.qh diff --git a/qcsrc/client/main.qc b/qcsrc/client/main.qc index c910f9250..a1cb0c3ee 100644 --- a/qcsrc/client/main.qc +++ b/qcsrc/client/main.qc @@ -714,8 +714,7 @@ NET_HANDLE(ENT_CLIENT_SPAWNEVENT, bool is_new) void CSQC_Ent_Update(bool isnew) { SELFPARAM(); - this.sourceLocLine = __LINE__; - this.sourceLocFile = __FILE__; + this.sourceLoc = __FILE__ ":" STR(__LINE__); int t = ReadByte(); // set up the "time" global for received entities to be correct for interpolation purposes diff --git a/qcsrc/common/debug.qh b/qcsrc/common/debug.qh index 4a75c50fd..75a76ae34 100644 --- a/qcsrc/common/debug.qh +++ b/qcsrc/common/debug.qh @@ -19,8 +19,7 @@ REGISTER_NET_TEMP(net_debug) setorigin(this, this.origin); this.debug = true; // identify server entities by this this.classname = strzone(ReadString()); - this.sourceLocFile = strzone(ReadString()); - this.sourceLocLine = ReadInt24_t(); + this.sourceLoc = strzone(ReadString()); return true; } #endif @@ -37,8 +36,7 @@ REGISTER_NET_TEMP(net_debug) WriteCoord(channel, this.origin.y); WriteCoord(channel, this.origin.z); WriteString(channel, this.classname); - WriteString(channel, this.sourceLocFile); - WriteInt24_t(channel, this.sourceLocLine); + WriteString(channel, this.sourceLoc); return true; } #endif @@ -125,8 +123,8 @@ bool autocvar_debugdraw; pos.z = 0; pos.y += ofs * sz; drawcolorcodedstring2(pos, - sprintf("%d: '%s'@%s:%d", (e.debug ? e.sv_entnum : etof(e)), - e.classname, e.sourceLocFile, e.sourceLocLine), + sprintf("%d: '%s'@%s", (e.debug ? e.sv_entnum : etof(e)), + e.classname, e.sourceLoc), sz * '1 1 0', rgb, 0.5, DRAWFLAG_NORMAL); ++ofs; } diff --git a/qcsrc/common/effects/effectinfo.qc b/qcsrc/common/effects/effectinfo.qc index f6b82a622..da9894602 100644 --- a/qcsrc/common/effects/effectinfo.qc +++ b/qcsrc/common/effects/effectinfo.qc @@ -1,4 +1,4 @@ -#define EFFECTINFO_PARSER(on) \ +#define EFFECTINFO_PARSER(on, MY) \ on(type, MY(type) \ ,{ demand(n == 1 && "type"); MY(type) = strzone(argv(1)); \ }, sprintf(" %s", (MY(type)) \ @@ -206,7 +206,6 @@ CLASS(EffectInfo, Object) #define p(f, type, default) if (this.effectinfo_##f) { s = strcat(s, "\t", "MY("#f") = ", str_##type(this.effectinfo_##f), ";\n"); } FIELDS(p) #undef p - #undef MY return strcat(s, "}\n"); } @@ -214,7 +213,7 @@ CLASS(EffectInfo, Object) string s = sprintf("effect %s\n", this.effectinfo_name); #define MY(f) this.effectinfo_##f #define p(k, isset, parse, unparse) if (isset) { s = strcat(s, "\t", #k, unparse, "\n"); } - EFFECTINFO_PARSER(p) + EFFECTINFO_PARSER(p, MY) #undef p #undef MY return s; @@ -246,7 +245,7 @@ void effectinfo_read() switch (k) { #define MY(f) info.effectinfo_##f #define p(k, isset, parse, unparse) case #k: parse break; - EFFECTINFO_PARSER(p) + EFFECTINFO_PARSER(p, MY) #undef p #undef MY default: diff --git a/qcsrc/common/mutators/base.qh b/qcsrc/common/mutators/base.qh index d4a952619..98c5dadac 100644 --- a/qcsrc/common/mutators/base.qh +++ b/qcsrc/common/mutators/base.qh @@ -132,7 +132,11 @@ void RegisterCallbacks() {}; return ret; \ } \ [[accumulate]] void RegisterHooks() { HOOK_##id = NEW(CallbackChain, #id); } -#define MUTATOR_CALLHOOK(id, ...) APPLY(__Mutator_Send_##id, 0, ##__VA_ARGS__) +#ifdef __STDC__ + #define MUTATOR_CALLHOOK(id, ...) APPLY(__Mutator_Send_##id, 0 P99_IF_EMPTY(__VA_ARGS__)()(, __VA_ARGS__)) +#else + #define MUTATOR_CALLHOOK(id, ...) APPLY(__Mutator_Send_##id, 0, ##__VA_ARGS__) +#endif enum { MUTATOR_REMOVING, diff --git a/qcsrc/lib/misc.qh b/qcsrc/lib/misc.qh index dfc3bdb2d..950000f04 100644 --- a/qcsrc/lib/misc.qh +++ b/qcsrc/lib/misc.qh @@ -11,10 +11,9 @@ #define EVAL4(...) EVAL5(EVAL5(EVAL5(__VA_ARGS__))) #define EVAL5(...) __VA_ARGS__ - #define OVERLOAD___(F, _16, _15, _14, _13, _12, _11, _10, _9, _8, _7, _6, _5, _4, _3, _2, _1, n, ...) F##_##n - #define OVERLOAD__(F, ...) OVERLOAD___(F,##__VA_ARGS__, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) - #define OVERLOAD_(...) DEFER(OVERLOAD__(__VA_ARGS__)) - #define OVERLOAD(F, ...) OVERLOAD_(F,##__VA_ARGS__)(__VA_ARGS__) + #include "p99.qh" + #define OVERLOAD(F, ...) P99_IF_EMPTY(__VA_ARGS__)(P99_PASTE2(F, _00)())(P99_PASTE3(F, _, P00_NARG(__VA_ARGS__))(__VA_ARGS__)) + #define OVERLOAD_(F, ...) P99_IF_EMPTY(__VA_ARGS__)(P99_PASTE2(F, _00)())(P99_PASTE3(F, _, P00_NARG(__VA_ARGS__))(__VA_ARGS__)) #else #define EVAL(...) __VA_ARGS__ diff --git a/qcsrc/lib/net.qh b/qcsrc/lib/net.qh index 34cd292a8..81f126b74 100644 --- a/qcsrc/lib/net.qh +++ b/qcsrc/lib/net.qh @@ -42,8 +42,7 @@ STATIC_INIT(RegisterTempEntities_renumber) { FOREACH(TempEntities, true, it.m_id [[accumulate]] NET_HANDLE(id, bool isnew) \ { \ this = self; \ - this.sourceLocFile = __FILE__; \ - this.sourceLocLine = __LINE__; \ + this.sourceLoc = __FILE__ ":" STR(__LINE__); \ if (!this) isnew = true; \ } \ REGISTER(LinkedEntities, NET, id, m_id, new_pure(net_linked_packet)) \ diff --git a/qcsrc/lib/oo.qh b/qcsrc/lib/oo.qh index cd5b568fe..7ecc745d0 100644 --- a/qcsrc/lib/oo.qh +++ b/qcsrc/lib/oo.qh @@ -27,8 +27,7 @@ .string classname; /** Location entity was spawned from in source */ -.string sourceLocFile; -.int sourceLocLine; +.string sourceLoc; entity _spawn(); #ifndef SPAWN_PURE @@ -41,12 +40,11 @@ entity spawn_pure() = #600; #define spawn_pure() _spawn() #endif -entity __spawn(string _classname, string _sourceFile, int _sourceLine, bool pure) +entity __spawn(string _classname, string _sourceLoc, bool pure) { entity this = pure ? spawn_pure() : _spawn(); this.classname = _classname; - this.sourceLocFile = _sourceFile; - this.sourceLocLine = _sourceLine; + this.sourceLoc = _sourceLoc; if (pure) { make_pure(this); #ifdef CSQC @@ -57,23 +55,23 @@ entity __spawn(string _classname, string _sourceFile, int _sourceLine, bool pure } -#define entityclass(...) EVAL_entityclass(OVERLOAD(entityclass, __VA_ARGS__)) +#define entityclass(...) EVAL_entityclass(OVERLOAD_(entityclass, __VA_ARGS__)) #define EVAL_entityclass(...) __VA_ARGS__ #define entityclass_1(name) entityclass_2(name, Object) #ifndef QCC_SUPPORT_ENTITYCLASS #define entityclass_2(name, base) typedef entity name #define class(name) - #define _new(class, pure) __spawn( #class, __FILE__, __LINE__, pure) + #define _new(class, pure) __spawn( #class, __FILE__ ":" STR(__LINE__), pure) #else #define entityclass_2(name, base) entityclass name : base {} #define class(name) [[class(name)]] - #define _new(class, pure) ((class) __spawn( #class, __FILE__, __LINE__, pure)) + #define _new(class, pure) ((class) __spawn( #class, __FILE__ ":" STR(__LINE__), pure)) #endif /** entities you care about seeing (.origin works) */ #define new(class) _new(class, false) /** purely logical entities (.origin doesn't work) */ #define new_pure(class) _new(class, true) -#define spawn() __spawn("entity", __FILE__, __LINE__, false) +#define spawn() __spawn("entity", __FILE__ ":" STR(__LINE__), false) entity _clearentity_ent; STATIC_INIT(clearentity) @@ -99,15 +97,10 @@ void clearentity(entity e) // Macros to hide this implementation detail: #ifdef __STDC__ - #define NEW_(cname, ...) \ - OVERLOAD_(spawn##cname, __VA_ARGS__) #define NEW(cname, ...) \ - NEW_(cname, new_pure(cname),##__VA_ARGS__)(new_pure(cname),##__VA_ARGS__) - - #define CONSTRUCT_(cname, ...) \ - OVERLOAD_(spawn##cname, __VA_ARGS__) + OVERLOAD_(spawn##cname, new_pure(cname) P99_IF_EMPTY(__VA_ARGS__)()(, __VA_ARGS__)) #define CONSTRUCT(cname, ...) \ - CONSTRUCT_(cname, this,##__VA_ARGS__)(this,##__VA_ARGS__) + OVERLOAD_(spawn##cname, this P99_IF_EMPTY(__VA_ARGS__)()(, __VA_ARGS__)) #else #define NEW(cname, ...) \ OVERLOAD(spawn##cname, new_pure(cname),##__VA_ARGS__) diff --git a/qcsrc/lib/p99.qh b/qcsrc/lib/p99.qh new file mode 100644 index 000000000..d3228d47c --- /dev/null +++ b/qcsrc/lib/p99.qh @@ -0,0 +1,87 @@ +/* This may look like nonsense, but it really is -*- mode: C -*- */ +/* */ +/* Except for parts copied from previous work and as explicitly stated below, */ +/* the authors and copyright holders for this work are as follows: */ +/* (C) copyright 2010-2013 Jens Gustedt, INRIA, France */ +/* (C) copyright 2013 Pierre-Nicolas Clauss */ +/* (C) copyright 2012 William Morris */ +/* */ +/* This file is free software; it is part of the P99 project. */ +/* You can redistribute it and/or modify it under the terms of the QPL as */ +/* given in the file LICENSE. It is distributed without any warranty; */ +/* without even the implied warranty of merchantability or fitness for a */ +/* particular purpose. */ +/* */ +#ifndef P99_H_ +#define P99_H_ + +#define P99_MAX_NUMBER 16 +#define P00_ARG( \ + _01, _02, _03, _04, _05, _06, _07, _08, \ + _09, _10, _11, _12, _13, _14, _15, _16, \ + _00, ...) _00 +#define P00_NARG(...) P00_ARG(__VA_ARGS__, \ + 16, 15, 14, 13, 12, 11, 10, 9, \ + 8, 7, 6, 5, 4, 3, 2, 1, \ + 0, ) +#define P99_HAS_COMMA(...) P00_ARG(__VA_ARGS__, \ + 1, 1, 1, 1, 1, 1, 1, 1, \ + 1, 1, 1, 1, 1, 1, 1, 0, \ + 0) + +#define P99_IF_EMPTY(...) P99_IF_EQ(1, P99_IS_EMPTY(__VA_ARGS__)) + // P99_HAS_COMMA(__VA_ARGS__), : test if there is just one argument, that might be empty + // P99_HAS_COMMA(P00_IS__EQ__ __VA_ARGS__), : test if P99_IS__EQ__ together with the argument adds a comma + // P99_HAS_COMMA(__VA_ARGS__ (/*empty*/)), : test if the argument together with a parenthesis adds a comma + // P99_HAS_COMMA(P00_IS__EQ__ __VA_ARGS__ (/*empty*/)) : test if placing it between P99_IS__EQ__ and the parenthesis adds a comma + #define P99_IS_EMPTY(...) \ + P00_ISEMPTY( \ + P99_HAS_COMMA(__VA_ARGS__), \ + P99_HAS_COMMA(P00_IS__EQ__ __VA_ARGS__), \ + P99_HAS_COMMA(__VA_ARGS__ (/*empty*/)), \ + P99_HAS_COMMA(P00_IS__EQ__ __VA_ARGS__ (/*empty*/)) \ + ) + #define P00_IS__EQ__(...) , + #define P00_ISEMPTY(_1, _2, _3, _4) P99_HAS_COMMA(P99_PASTE5(P00_IS_EMPTY_CASE_, _1, _2, _3, _4)) + #define P00_IS_EMPTY_CASE_0000 P00_IS_EMPTY_CASE_0000 + #define P00_IS_EMPTY_CASE_0001 , + #define P00_IS_EMPTY_CASE_0010 P00_IS_EMPTY_CASE_0010 + #define P00_IS_EMPTY_CASE_0011 P00_IS_EMPTY_CASE_0011 + #define P00_IS_EMPTY_CASE_0100 P00_IS_EMPTY_CASE_0100 + #define P00_IS_EMPTY_CASE_0101 P00_IS_EMPTY_CASE_0101 + #define P00_IS_EMPTY_CASE_0110 P00_IS_EMPTY_CASE_0110 + #define P00_IS_EMPTY_CASE_0111 P00_IS_EMPTY_CASE_0111 + #define P00_IS_EMPTY_CASE_1000 P00_IS_EMPTY_CASE_1000 + #define P00_IS_EMPTY_CASE_1001 P00_IS_EMPTY_CASE_1001 + #define P00_IS_EMPTY_CASE_1010 P00_IS_EMPTY_CASE_1010 + #define P00_IS_EMPTY_CASE_1011 P00_IS_EMPTY_CASE_1011 + #define P00_IS_EMPTY_CASE_1100 P00_IS_EMPTY_CASE_1100 + #define P00_IS_EMPTY_CASE_1101 P00_IS_EMPTY_CASE_1101 + #define P00_IS_EMPTY_CASE_1110 P00_IS_EMPTY_CASE_1110 + #define P00_IS_EMPTY_CASE_1111 P00_IS_EMPTY_CASE_1111 + + +#define P00_IF_CLAUSE(EXP) P00__IF_CLAUSE(EXP, P00_CLAUSE1, P00_CLAUSE2, ~) + #define P00__IF_CLAUSE(A, B, C, ...) C + #define P00_CLAUSE1(...) __VA_ARGS__ P00_IGNORE + #define P00_IGNORE(...) + #define P00_CLAUSE2(...) P00_IDENT + #define P00_IDENT(...) __VA_ARGS__ + + +#define P99_IF_EQ(A, B) P00_IF_CLAUSE(P99_PASTE4(P00_IS_, A, _EQ_, B)()) + #define P00_IS_0_EQ_0(...) , + #define P00_IS_1_EQ_1(...) , + + +#define P99_CAT2(_1, _2) _1 ## _2 +#define P99_PASTE2(_1, _2) \ + P99_CAT2(_1, _2) +#define P99_PASTE3(_1, _2, _3) \ + P99_PASTE2(P99_PASTE2(_1, _2), _3) +#define P99_PASTE4(_1, _2, _3, _4) \ + P99_PASTE2(P99_PASTE3(_1, _2, _3), _4) +#define P99_PASTE5(_1, _2, _3, _4, _5) \ + P99_PASTE2(P99_PASTE4(_1, _2, _3, _4), _5) + +#endif /* !P99_H_ */ diff --git a/qcsrc/lib/registry.qh b/qcsrc/lib/registry.qh index 8c0eed0ed..490ffd303 100644 --- a/qcsrc/lib/registry.qh +++ b/qcsrc/lib/registry.qh @@ -52,7 +52,7 @@ REGISTRY(Registries, BITS(8)) * @param fld The field to store the locally unique unique entity id * @param inst An expression to create a new instance, invoked for every registration */ -#define REGISTER(...) EVAL_REGISTER(OVERLOAD(REGISTER, __VA_ARGS__)) +#define REGISTER(...) EVAL_REGISTER(OVERLOAD_(REGISTER, __VA_ARGS__)) #define EVAL_REGISTER(...) __VA_ARGS__ #define REGISTER_5(registry, ns, id, fld, inst) REGISTER_4(registry, ns##_##id, fld, inst) #define REGISTER_4(registry, id, fld, inst) \ @@ -61,7 +61,7 @@ REGISTRY(Registries, BITS(8)) REGISTER_INIT_POST(id) {} \ void Register_##id() \ { \ - if (registry##_COUNT >= registry##_MAX) LOG_FATALF("Registry capacity exceeded (%s)", ftos(registry##_MAX)); \ + if (registry##_COUNT >= registry##_MAX) LOG_FATALF("Registry capacity exceeded (%d)", registry##_MAX); \ entity this = id = inst; \ this.registered_id = #id; \ REGISTRY_PUSH(registry, fld, this); \ diff --git a/qcsrc/lib/spawnfunc.qh b/qcsrc/lib/spawnfunc.qh index 7938bacde..f9c056fbd 100644 --- a/qcsrc/lib/spawnfunc.qh +++ b/qcsrc/lib/spawnfunc.qh @@ -45,10 +45,9 @@ noref bool require_spawnfunc_prefix; { \ assert(this); \ } \ - if (!this.sourceLocFile) \ + if (!this.sourceLoc) \ { \ - this.sourceLocFile = __FILE__; \ - this.sourceLocLine = __LINE__; \ + this.sourceLoc = __FILE__ ":" STR(__LINE__); \ } \ if (!this.spawnfunc_checked) \ { \ @@ -83,8 +82,7 @@ noref bool require_spawnfunc_prefix; #define FIELDS_COMMON(fld) \ FIELD_SCALAR(fld, classname) \ - FIELD_SCALAR(fld, sourceLocFile) \ - FIELD_SCALAR(fld, sourceLocLine) \ + FIELD_SCALAR(fld, sourceLoc) \ FIELD_SCALAR(fld, spawnfunc_checked) \ FIELD_VEC(fld, origin) \ /**/ diff --git a/qcsrc/lib/vector.qh b/qcsrc/lib/vector.qh index cdfe739a0..21b931e93 100644 --- a/qcsrc/lib/vector.qh +++ b/qcsrc/lib/vector.qh @@ -90,7 +90,7 @@ noref vector _vec2; #define vec2(v) (_vec2 = (v), _vec2.z = 0, _vec2) noref vector _vec3; -#define vec3(x, y, z) (_vec3_x = (x), _vec3_y = (y), _vec3_z = (z), _vec3) +#define vec3(_x, _y, _z) (_vec3.x = (_x), _vec3.y = (_y), _vec3.z = (_z), _vec3) vector rotate(vector v, float a) { -- 2.39.2