diff --git a/include/QF/cmd.h b/include/QF/cmd.h index db8fc9601..5c9379c53 100644 --- a/include/QF/cmd.h +++ b/include/QF/cmd.h @@ -35,6 +35,7 @@ //@{ #include "QF/qtypes.h" +#include "QF/cbuf.h" typedef void (*xcommand_t) (void); @@ -67,6 +68,9 @@ int Cmd_ExecuteString (const char *text, cmd_source_t src); struct cbuf_s; void Cmd_StuffCmds (struct cbuf_s *cbuf); void Cmd_Exec_File (struct cbuf_s *cbuf, const char *path, int qfs); +void Cmd_AddProvider(const char *name, struct cbuf_interpreter_s *interp); +struct cbuf_interpreter_s *Cmd_GetProvider(const char *name); + extern struct cbuf_args_s *cmd_args; extern struct cvar_s *cmd_warncmd; diff --git a/libs/console/console.c b/libs/console/console.c index 2e7f56af6..5f6b3ddb8 100644 --- a/libs/console/console.c +++ b/libs/console/console.c @@ -55,6 +55,8 @@ static U inputline_t *(*const create)(int, int, char) = Con_CreateInputLine; static U void (*const display)(const char **, int) = Con_DisplayList; #undef U +static cvar_t *con_interpreter; + __attribute__ ((visibility ("default"))) void Con_Init (const char *plugin_name) @@ -68,10 +70,32 @@ Con_Init (const char *plugin_name) } } +static void +Con_Interp_f(cvar_t* var) +{ + cbuf_interpreter_t* interp = Cmd_GetProvider(var->string); + + if (con_module && interp) + { + cbuf_t *new = Cbuf_New(interp); + + if (con_module->data->console->cbuf) + { + new->down = con_module->data->console->cbuf; + new->state = CBUF_STATE_STACK; + con_module->data->console->cbuf->up = new; + } + con_module->data->console->cbuf = new; + } +} + __attribute__ ((visibility ("default"))) void Con_Init_Cvars (void) { + con_interpreter = + Cvar_Get("con_interpreter", "id", CVAR_NONE, Con_Interp_f, + "Interpreter for the interactive console"); } __attribute__ ((visibility ("default"))) diff --git a/libs/util/cmd.c b/libs/util/cmd.c index 19db78505..db5b203f4 100644 --- a/libs/util/cmd.c +++ b/libs/util/cmd.c @@ -60,12 +60,19 @@ typedef struct cmdalias_s { const char *value; } cmdalias_t; +typedef struct cmd_provider_s +{ + const char *name; + cbuf_interpreter_t* interp; +} cmd_provider_t; + static cmdalias_t *cmd_alias; VISIBLE cvar_t *cmd_warncmd; static hashtab_t *cmd_alias_hash; static hashtab_t *cmd_hash; +static hashtab_t *cmd_provider_hash; VISIBLE cbuf_args_t *cmd_args; static cbuf_t *cmd_cbuf; @@ -312,6 +319,23 @@ cmd_get_key (void *c, void *unused) return cmd->name; } +static void +cmd_provider_free (void *_a, void *unused) +{ + cmd_provider_t *p = (cmd_provider_t *) _a; + + free ((char *) p->name); + free (p); +} + +static const char * +cmd_provider_get_key (void *_a, void *unused) +{ + cmd_provider_t *p = (cmd_provider_t *) _a; + + return p->name; +} + static void Cmd_Runalias_f (void) { @@ -578,6 +602,7 @@ Cmd_Init_Hash (void) { cmd_hash = Hash_NewTable (1021, cmd_get_key, 0, 0); cmd_alias_hash = Hash_NewTable (1021, cmd_alias_get_key, cmd_alias_free, 0); + cmd_provider_hash = Hash_NewTable(1021, cmd_provider_get_key, cmd_provider_free, 0); } VISIBLE void @@ -602,6 +627,8 @@ Cmd_Init (void) cmd_warncmd = Cvar_Get ("cmd_warncmd", "0", CVAR_NONE, NULL, "Toggles the " "display of error messages for unknown commands"); cmd_cbuf = Cbuf_New (&id_interp); + + Cmd_AddProvider("id", &id_interp); } VISIBLE int @@ -647,3 +674,27 @@ Cmd_Exec_File (cbuf_t *cbuf, const char *path, int qfs) } } +VISIBLE void +Cmd_AddProvider(const char *name, cbuf_interpreter_t *interp) +{ + cmd_provider_t *p = (cmd_provider_t *) Hash_Find (cmd_provider_hash, name); + + if (!p) + { + cmd_provider_t *p = malloc(sizeof(cmd_provider_t)); + p->name = strdup(name); + p->interp = interp; + Hash_Add(cmd_provider_hash, p); + } +} + +VISIBLE cbuf_interpreter_t * +Cmd_GetProvider(const char *name) +{ + cmd_provider_t *p = (cmd_provider_t *) Hash_Find (cmd_provider_hash, name); + + if (!p) + return NULL; + else + return p->interp; +}