diff options
| -rw-r--r-- | src/build/cmeta.c | 31 | ||||
| -rw-r--r-- | src/build/cmeta.h | 2 | ||||
| -rw-r--r-- | src/build/codegen.c | 57 | ||||
| -rw-r--r-- | src/con_.c | 37 | ||||
| -rw-r--r-- | src/con_.h | 18 | 
5 files changed, 94 insertions, 51 deletions
| diff --git a/src/build/cmeta.c b/src/build/cmeta.c index 7b7a767..4e1eb4a 100644 --- a/src/build/cmeta.c +++ b/src/build/cmeta.c @@ -204,16 +204,37 @@ void cmeta_includes(const struct cmeta *cm,  // AGAIN, NOTE: this doesn't *perfectly* match top level decls only in the event  // that someone writes something weird, but we just don't really care because  // we're not writing something weird. Don't write something weird! -void cmeta_conmacros(const struct cmeta *cm, void (*cb)(const char *, bool)) { +void cmeta_conmacros(const struct cmeta *cm, +		void (*cb)(const char *, bool, bool)) {  	Token *tp = (Token *)cm;  	if (!tp || !tp->next || !tp->next->next) return; // DEF_xyz, (, name  	while (tp) {  		bool isplusminus = false, isvar = false; -		if (equal(tp, "DEF_CCMD_PLUSMINUS")) isplusminus = true; +		bool unreg = false; +		// this is like the worst thing ever, but oh well it's just build time +		// XXX: tidy this up some day, though, probably +		if (equal(tp, "DEF_CCMD_PLUSMINUS")) { +			isplusminus = true; +		} +		else if (equal(tp, "DEF_CCMD_PLUSMINUS_UNREG")) { +			isplusminus = true; +			unreg = true; +		}  		else if (equal(tp, "DEF_CVAR") || equal(tp, "DEF_CVAR_MIN") ||  				equal(tp, "DEF_CVAR_MAX") || equal(tp, "DEF_CVAR_MINMAX")) {  			isvar = true;  		} +		else if (equal(tp, "DEF_CVAR_UNREG") || +				equal(tp, "DEF_CVAR_MIN_UNREG") || +				equal(tp, "DEF_CVAR_MAX_UNREG") || +				equal(tp, "DEF_CVAR_MINMAX_UNREG")) { +			isvar = true; +			unreg = true; +		} +		else if (equal(tp, "DEF_CCMD_UNREG") || +				equal(tp, "DEF_CCMD_HERE_UNREG")) { +			unreg = true; +		}  		else if (!equal(tp, "DEF_CCMD") && !equal(tp, "DEF_CCMD_HERE")) {  			tp = tp->next; continue;  		} @@ -226,20 +247,20 @@ void cmeta_conmacros(const struct cmeta *cm, void (*cb)(const char *, bool)) {  			memcpy(plusname, "PLUS_", 5);  			memcpy(plusname + sizeof("PLUS_") - 1, tp->loc, tp->len);  			plusname[sizeof("PLUS_") - 1 + tp->len] = '\0'; -			cb(plusname, false); +			cb(plusname, false, unreg);  			char *minusname = malloc(sizeof("MINUS_") + tp->len);  			if (!minusname) die1("couldn't allocate memory");  			memcpy(minusname, "MINUS_", 5);  			memcpy(minusname + sizeof("MINUS_") - 1, tp->loc, tp->len);  			minusname[sizeof("MINUS_") - 1 + tp->len] = '\0'; -			cb(minusname, false); +			cb(minusname, false, unreg);  		}  		else {  			char *name = malloc(tp->len + 1);  			if (!name) die1("couldn't allocate memory");  			memcpy(name, tp->loc, tp->len);  			name[tp->len] = '\0'; -			cb(name, isvar); +			cb(name, isvar, unreg);  		}  		tp = tp->next;  	} diff --git a/src/build/cmeta.h b/src/build/cmeta.h index 3319e3a..18ff62c 100644 --- a/src/build/cmeta.h +++ b/src/build/cmeta.h @@ -37,7 +37,7 @@ void cmeta_includes(const struct cmeta *cm,   * con_.h, passing each one in turn to the callback cb.   */  void cmeta_conmacros(const struct cmeta *cm, -		void (*cb)(const char *name, bool isvar)); +		void (*cb)(const char *name, bool isvar, bool unreg));  #endif diff --git a/src/build/codegen.c b/src/build/codegen.c index c9be0ef..38645e5 100644 --- a/src/build/codegen.c +++ b/src/build/codegen.c @@ -21,26 +21,30 @@  #include "../os.h"  #include "cmeta.h" -static const char *cmdnames[4096]; // arbitrary limit! -static int ncmdnames = 0; -static const char *varnames[4096]; // arbitrary limit! -static int nvarnames = 0; +#define MAXENT 65536 // arbitrary limit! +static struct ent { +	const char *name; +	bool unreg; +	bool isvar; // false for cmd +} ents[MAXENT]; +static int nents;  static void die(const char *s) {  	fprintf(stderr, "codegen: %s\n", s);  	exit(100);  } -#define PUT(array, ent) do { \ -	if (n##array == sizeof(array) / sizeof(*array)) { \ -		fprintf(stderr, "codegen: out of space; make " #array " bigger!\n"); \ +#define PUT(name_, isvar_, unreg_) do { \ +	if (nents == sizeof(ents) / sizeof(*ents)) { \ +		fprintf(stderr, "codegen: out of space; make ents bigger!\n"); \  		exit(1); \  	} \ -	array[n##array++] = ent; \ +	ents[nents].name = name_; \ +	ents[nents].isvar = isvar_; ents[nents++].unreg = unreg_; \  } while (0) -static void oncondef(const char *name, bool isvar) { -	if (isvar) PUT(varnames, name); else PUT(cmdnames, name); +static void oncondef(const char *name, bool isvar, bool unreg) { +	PUT(name, isvar, unreg);  }  #define _(x) \ @@ -60,31 +64,26 @@ int OS_MAIN(int argc, os_char *argv[]) {  	FILE *out = fopen(".build/include/cmdinit.gen.h", "wb");  	if (!out) die("couldn't open cmdinit.gen.h");  	H(); -	for (const char *const *pp = cmdnames; -			pp - cmdnames < ncmdnames; ++pp) { -F( "extern struct con_cmd *%s;", *pp) -	} -	for (const char *const *pp = varnames; -			pp - varnames < nvarnames; ++pp) { -F( "extern struct con_var *%s;", *pp) +	for (const struct ent *p = ents; p - ents < nents; ++p) { +F( "extern struct con_%s *%s;", p->isvar ? "var" : "cmd", p->name)  	}  _( "") -_( "static void regcmds(void (*VCALLCONV f)(void *, void *)) {") -	for (const char *const *pp = cmdnames; -			pp - cmdnames < ncmdnames; ++pp) { -F( "	f(_con_iface, %s);", *pp) -	} -	for (const char *const *pp = varnames; -			pp - varnames < nvarnames; ++pp) { -F( "	initval(%s);", *pp) -F( "	f(_con_iface, %s);", *pp) +_( "static void regcmds(void) {") +	for (const struct ent *p = ents; p - ents < nents; ++p) { +		if (p->isvar) { +F( "	initval(%s);", p->name) +		} +		if (!p->unreg) { +F( "	con_reg(%s);", p->name) +		}  	}  _( "}")  _( "")  _( "static void freevars(void) {") -	for (const char *const *pp = varnames; -			pp - varnames < nvarnames; ++pp) { -F( "	extfree(%s->strval);", *pp) +	for (const struct ent *p = ents; p - ents < nents; ++p) { +		if (p->isvar) { +F( "	extfree(%s->strval);", p->name); +		}  	}  _( "}")  	if (fflush(out) == EOF) die("couldn't fully write cmdinit.gen.h"); @@ -396,6 +396,15 @@ static void fillvts(void) {  	*pi++ = (void *)&GetSplitScreenPlayerSlot;  } +void con_reg(void *cmd_or_var) { +	if (GAMETYPE_MATCHES(Portal2)) { +		VCALL(_con_iface, RegisterConCommand_p2, cmd_or_var); +	} +	else { +		VCALL(_con_iface, RegisterConCommand, cmd_or_var); +	} +} +  bool con_init(void *(*f)(const char *, int *), int plugin_ver) {  	int ifacever; // for error messages  	if (_con_iface = f("VEngineCvar007", 0)) { @@ -409,11 +418,8 @@ bool con_init(void *(*f)(const char *, int *), int plugin_ver) {  			_con_colourmsgf = VFUNC(_con_iface, ConsoleColorPrintf_p2);  			dllid = VCALL0(_con_iface, AllocateDLLIdentifier_p2);  			_gametype_tag |= _gametype_tag_Portal2; -			fillvts(); -			regcmds(VFUNC(_con_iface, RegisterConCommand_p2)); -			return true;  		} -		if (VCALL(_con_iface, FindCommand, "l4d2_snd_adrenaline")) { +		else if (VCALL(_con_iface, FindCommand, "l4d2_snd_adrenaline")) {  			_con_colourmsgf = VFUNC(_con_iface, ConsoleColorPrintf_l4d);  			dllid = VCALL0(_con_iface, AllocateDLLIdentifier);  			// while we're here, also distinguish Survivors, the stupid Japanese @@ -428,22 +434,21 @@ bool con_init(void *(*f)(const char *, int *), int plugin_ver) {  			else {  				_gametype_tag |= _gametype_tag_L4D2;  			} -			fillvts(); -			regcmds(VFUNC(_con_iface, RegisterConCommand)); -			return true;  		} -		if (VCALL(_con_iface, FindVar, "z_difficulty")) { +		else if (VCALL(_con_iface, FindVar, "z_difficulty")) {  			_con_colourmsgf = VFUNC(_con_iface, ConsoleColorPrintf_l4d);  			dllid = VCALL0(_con_iface, AllocateDLLIdentifier);  			_gametype_tag |= _gametype_tag_L4D1; -			fillvts(); // XXX: is this all kinda dupey? maybe rearrange one day. -			regcmds(VFUNC(_con_iface, RegisterConCommand)); -			return true;  		} -		con_warn("sst: error: game \"%s\" is unsupported (using " -					"VEngineCvar007)\n", gameinfo_title); -		ifacever = 7; -		goto e; +		else { +			con_warn("sst: error: game \"%s\" is unsupported (using " +						"VEngineCvar007)\n", gameinfo_title); +			ifacever = 7; +			goto e; +		} +		fillvts(); +		regcmds(); +		return true;  	}  	if (_con_iface = f("VEngineCvar004", 0)) {  		// TODO(compat): are there any cases where 004 is incompatible? could @@ -455,7 +460,7 @@ bool con_init(void *(*f)(const char *, int *), int plugin_ver) {  		if (plugin_ver == 3) _gametype_tag |= _gametype_tag_2013;  		else _gametype_tag |= _gametype_tag_OrangeBox;  		fillvts(); -		regcmds(VFUNC(_con_iface, RegisterConCommand)); +		regcmds();  		return true;  	}  	if (f("VEngineCvar003", 0)) { @@ -293,6 +293,24 @@ extern void *_con_vtab_iconvar[];  	static void _cmdf_##name(const struct con_cmdargs *cmd) \  	/* { body here } */ +/* + * These are exactly the same as the above macros, but they don't cause the + * commands or variables to be registered on plugin load. + */ +#define DEF_CVAR_UNREG DEF_CVAR +#define DEF_CVAR_MIN_UNREG DEF_CVAR_MIN +#define DEF_CVAR_MAX_UNREG DEF_CVAR_MAX +#define DEF_CVAR_MINMAX_UNREG DEF_CVAR_MINMAX +#define DEF_CCMD_UNREG DEF_CCMD +#define DEF_CCMD_HERE_UNREG DEF_CCMD_HERE +#define DEF_CCMD_PLUSMINUS_UNREG DEF_CCMD_PLUSMINUS + +/* + * Registers a command or variable defined with the _UNREG variants of the above + * macros. Can be used to conditionally register things. + */ +void con_reg(void *cmd_or_var); +  #endif  // vi: sw=4 ts=4 noet tw=80 cc=80 | 
