============
Cbuf_LinkString
-Copies a command string into a buffer node
+Copies a command string into a buffer node.
+The input should not be null-terminated, the output will be.
============
*/
static void Cbuf_LinkString(cmd_state_t *cmd, llist_t *head, cmd_input_t *existing, const char *text, qbool leavepending, unsigned int cmdsize)
}
cbuf->size += cmdsize;
- strlcpy(&node->text[offset], text, cmdsize + 1); // always sets the last char to \0
+ dp_ustr2stp(&node->text[offset], node->length + 1, text, cmdsize);
//Con_Printf("^5Cbuf_LinkString(): %s `^7%s^5`\n", node->pending ? "append" : "new", &node->text[offset]);
node->pending = leavepending;
}
if (cbuf->size + l > cbuf->maxsize)
{
- Con_Printf(CON_WARN "Cbuf_AddText: input too large, %zuKB ought to be enough for anybody.\n", cbuf->maxsize / 1024);
+ Con_Printf(CON_WARN "Cbuf_AddText: input too large, %luKB ought to be enough for anybody.\n", (unsigned long)(cbuf->maxsize / 1024));
return;
}
if (cbuf->size + l > cbuf->maxsize)
{
- Con_Printf(CON_WARN "Cbuf_InsertText: input too large, %zuKB ought to be enough for anybody.\n", cbuf->maxsize / 1024);
+ Con_Printf(CON_WARN "Cbuf_InsertText: input too large, %luKB ought to be enough for anybody.\n", (unsigned long)(cbuf->maxsize / 1024));
return;
}
============
*/
extern qbool prvm_runawaycheck;
-static qbool Cmd_PreprocessString(cmd_state_t *cmd, const char *intext, char *outtext, unsigned maxoutlen, cmd_alias_t *alias );
void Cbuf_Execute (cmd_buf_t *cbuf)
{
cmd_input_t *current;
- char preprocessed[MAX_INPUTLINE];
- char *firstchar;
unsigned int i = 0;
// LadyHavoc: making sure the tokenizebuffer doesn't get filled up by repeated crashes
*/
current->pending = false;
+ Cmd_PreprocessAndExecuteString(current->source, current->text, current->length, src_local, false);
cbuf->size -= current->length;
-
- firstchar = current->text;
- while(*firstchar && ISWHITESPACE(*firstchar))
- ++firstchar;
- if((strncmp(firstchar, "alias", 5) || !ISWHITESPACE(firstchar[5])) &&
- (strncmp(firstchar, "bind", 4) || !ISWHITESPACE(firstchar[4])) &&
- (strncmp(firstchar, "in_bind", 7) || !ISWHITESPACE(firstchar[7])))
- {
- if(Cmd_PreprocessString(current->source, current->text, preprocessed, sizeof(preprocessed), NULL ))
- Cmd_ExecuteString(current->source, preprocessed, src_local, false);
- }
- else
- {
- Cmd_ExecuteString (current->source, current->text, src_local, false);
- }
-
// Recycle memory so using WASD doesn't cause a malloc and free
List_Move_Tail(¤t->list, &cbuf->free);
- current = NULL;
-
if (cbuf->wait)
{
/*
cmd_alias_t *prev, *current;
a = (cmd_alias_t *)Z_Malloc (sizeof(cmd_alias_t));
- strlcpy (a->name, s, sizeof (a->name));
+ dp_strlcpy (a->name, s, sizeof (a->name));
// insert it at the right alphanumeric position
for( prev = NULL, current = cmd->userdefined->alias ; current && strcmp( current->name, a->name ) < 0 ; prev = current, current = current->next )
;
for (i=2 ; i < c ; i++)
{
if (i != 2)
- strlcat (line, " ", sizeof (line));
- strlcat (line, Cmd_Argv(cmd, i), sizeof (line));
+ dp_strlcat (line, " ", sizeof (line));
+ dp_strlcat (line, Cmd_Argv(cmd, i), sizeof (line));
}
- strlcat (line, "\n", sizeof (line));
+ dp_strlcat (line, "\n", sizeof (line));
alloclen = strlen (line) + 1;
if(alloclen >= 2)
return varstr;
}
-/*
+/**
Cmd_PreprocessString
Preprocesses strings and replaces $*, $param#, $cvar accordingly. Also strips comments.
+Returns the number of bytes written to *outtext excluding the \0 terminator.
*/
-static qbool Cmd_PreprocessString(cmd_state_t *cmd, const char *intext, char *outtext, unsigned maxoutlen, cmd_alias_t *alias ) {
+static size_t Cmd_PreprocessString(cmd_state_t *cmd, const char *intext, char *outtext, unsigned maxoutlen, cmd_alias_t *alias)
+{
const char *in;
size_t eat, varlen;
unsigned outlen;
// don't crash if there's no room in the outtext buffer
if( maxoutlen == 0 ) {
- return false;
+ return 0;
}
maxoutlen--; // because of \0
{
val = Cmd_GetCvarValue(cmd, in + 1, varlen, alias);
if(!val)
- return false;
+ return 0;
eat = varlen + 2;
}
else
varlen = strspn(in, "#*0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-");
val = Cmd_GetCvarValue(cmd, in, varlen, alias);
if(!val)
- return false;
+ return 0;
eat = varlen;
}
if(val)
else
outtext[outlen++] = *in++;
}
- outtext[outlen] = 0;
- return true;
+ outtext[outlen] = '\0';
+ return outlen;
}
/*
Cbuf_InsertText(cmd, buffer2);
}
+void Cmd_PreprocessAndExecuteString(cmd_state_t *cmd, const char *text, size_t textlen, cmd_source_t src, qbool lockmutex)
+{
+ char preprocessed[MAX_INPUTLINE];
+ size_t preprocessed_len;
+ const char *firstchar;
+
+ firstchar = text;
+ while(*firstchar && ISWHITESPACE(*firstchar))
+ ++firstchar;
+ if((strncmp(firstchar, "alias", 5) || !ISWHITESPACE(firstchar[5]))
+ && (strncmp(firstchar, "bind", 4) || !ISWHITESPACE(firstchar[4]))
+ && (strncmp(firstchar, "in_bind", 7) || !ISWHITESPACE(firstchar[7])))
+ {
+ if((preprocessed_len = Cmd_PreprocessString(cmd, text, preprocessed, sizeof(preprocessed), NULL)))
+ Cmd_ExecuteString(cmd, preprocessed, preprocessed_len, src, lockmutex);
+ }
+ else
+ Cmd_ExecuteString(cmd, text, textlen, src, lockmutex);
+}
+
/*
========
Cmd_List
* implement that behavior that doesn't involve an #ifdef, or
* making a mess of hooks.
*/
-qbool Cmd_Callback(cmd_state_t *cmd, cmd_function_t *func, const char *text, cmd_source_t src)
+qbool Cmd_Callback(cmd_state_t *cmd, cmd_function_t *func)
{
if (func->function)
func->function(cmd);
return true;
}
-qbool Cmd_CL_Callback(cmd_state_t *cmd, cmd_function_t *func, const char *text, cmd_source_t src)
+qbool Cmd_CL_Callback(cmd_state_t *cmd, cmd_function_t *func, const char *text, size_t textlen, cmd_source_t src)
{
// TODO: Assign these functions to QC commands directly?
if(func->qcfunc)
{
- if(((func->flags & CF_CLIENT) && CL_VM_ConsoleCommand(text)) ||
- ((func->flags & CF_SERVER) && SV_VM_ConsoleCommand(text)))
+ if(((func->flags & CF_CLIENT) && CL_VM_ConsoleCommand(text, textlen)) ||
+ ((func->flags & CF_SERVER) && SV_VM_ConsoleCommand(text, textlen)))
return true;
if (func->overridden) // If this QC command overrides an engine command,
return true;
}
}
- return Cmd_Callback(cmd, func, text, src);
+ return Cmd_Callback(cmd, func);
}
-qbool Cmd_SV_Callback(cmd_state_t *cmd, cmd_function_t *func, const char *text, cmd_source_t src)
+qbool Cmd_SV_Callback(cmd_state_t *cmd, cmd_function_t *func, const char *text, size_t textlen, cmd_source_t src)
{
if(func->qcfunc && (func->flags & CF_SERVER))
- return SV_VM_ConsoleCommand(text);
+ return SV_VM_ConsoleCommand(text, textlen);
else if (src == src_client)
{
if((func->flags & CF_CHEAT) && !sv_cheats.integer)
FIXME: lookupnoadd the token to speed search?
============
*/
-void Cmd_ExecuteString (cmd_state_t *cmd, const char *text, cmd_source_t src, qbool lockmutex)
+void Cmd_ExecuteString(cmd_state_t *cmd, const char *text, size_t textlen, cmd_source_t src, qbool lockmutex)
{
int oldpos;
cmd_function_t *func;
// check functions
for (func = cmd->userdefined->qc_functions; func; func = func->next)
if (!strcasecmp(cmd->argv[0], func->name))
- if(cmd->Handle(cmd, func, text, src))
+ if(cmd->Handle(cmd, func, text, textlen, src))
goto functions_done;
for (func = cmd->engine_functions; func; func=func->next)
if (!strcasecmp (cmd->argv[0], func->name))
- if(cmd->Handle(cmd, func, text, src))
+ if(cmd->Handle(cmd, func, text, textlen, src))
goto functions_done;
functions_done:
goto done;
// check cvars
- if (!Cvar_Command(cmd) && host.framecount > 0)
+ // Xonotic is still maintained so we don't want to hide problems from getting fixed
+ if (!Cvar_Command(cmd) && (host.framecount > 0 || gamemode == GAME_XONOTIC))
Con_Printf(CON_WARN "Unknown command \"%s\"\n", Cmd_Argv(cmd, 0));
done:
cmd->cbuf->tokenizebufferpos = oldpos;