typedef struct cmdalias_s
{
- struct cmdalias_s *next;
- char name[MAX_ALIAS_NAME];
- char *value;
+ struct cmdalias_s *next;
+ char name[MAX_ALIAS_NAME];
+ char *value;
} cmdalias_t;
static cmdalias_t *cmd_alias;
static mempool_t *cmd_mempool;
+#define CMD_TOKENIZELENGTH 4096
+static char cmd_tokenizebuffer[CMD_TOKENIZELENGTH];
+static int cmd_tokenizebufferpos = 0;
+
//=============================================================================
/*
=============================================================================
*/
+ // LordHavoc: inreased this from 8192 to 32768
static sizebuf_t cmd_text;
+static qbyte cmd_text_buf[32768];
/*
============
*/
void Cbuf_Init (void)
{
- // LordHavoc: inreased this from 8192 to 32768
- SZ_Alloc (&cmd_text, 32768, "command buffer"); // space for commands and script files
+ // space for commands and script files
+ cmd_text.data = cmd_text_buf;
+ cmd_text.maxsize = sizeof(cmd_text_buf);
+ cmd_text.cursize = 0;
}
+/*
+============
+Cbuf_Shutdown
+============
+*/
+void Cbuf_Shutdown (void)
+{
+}
/*
============
Adds command text at the end of the buffer
============
*/
-void Cbuf_AddText (char *text)
+void Cbuf_AddText (const char *text)
{
int l;
if (cmd_text.cursize + l >= cmd_text.maxsize)
{
- Con_Printf ("Cbuf_AddText: overflow\n");
+ Con_Print("Cbuf_AddText: overflow\n");
return;
}
FIXME: actually change the command buffer to do less copying
============
*/
-void Cbuf_InsertText (char *text)
+void Cbuf_InsertText (const char *text)
{
char *temp;
int templen;
-// copy off any commands still remaining in the exec buffer
+ // copy off any commands still remaining in the exec buffer
templen = cmd_text.cursize;
if (templen)
{
- temp = Z_Malloc (templen);
+ temp = Mem_Alloc (tempmempool, templen);
memcpy (temp, cmd_text.data, templen);
SZ_Clear (&cmd_text);
}
else
- temp = NULL; // shut up compiler
+ temp = NULL;
-// add the entire text of the file
+ // add the entire text of the file
Cbuf_AddText (text);
-// add the copied off data
- if (templen)
+ // add the copied off data
+ if (temp != NULL)
{
SZ_Write (&cmd_text, temp, templen);
- Z_Free (temp);
+ Mem_Free (temp);
}
}
*/
void Cbuf_Execute (void)
{
- int i;
- char *text;
- char line[1024];
- int quotes;
+ int i;
+ char *text;
+ char line[1024];
+ int quotes;
+
+ // LordHavoc: making sure the tokenizebuffer doesn't get filled up by repeated crashes
+ cmd_tokenizebufferpos = 0;
while (cmd_text.cursize)
{
quotes++;
if ( !(quotes&1) && text[i] == ';')
break; // don't break if inside a quoted string
- if (text[i] == '\n')
+ if (text[i] == '\r' || text[i] == '\n')
break;
}
{
i++;
cmd_text.cursize -= i;
- memcpy (text, text+i, cmd_text.cursize);
+ memcpy (cmd_text.data, text+i, cmd_text.cursize);
}
// execute the command line
*/
void Cmd_StuffCmds_f (void)
{
- int i, j;
- int s;
- char *text, *build, c;
+ int i, j, l;
+ // this is per command, and bounds checked (no buffer overflows)
+ char build[2048];
if (Cmd_Argc () != 1)
{
- Con_Printf ("stuffcmds : execute command line parameters\n");
- return;
- }
-
-// build the combined string to parse from
- s = 0;
- for (i=1 ; i<com_argc ; i++)
- {
- if (!com_argv[i])
- continue; // NEXTSTEP nulls out -NXHost
- s += strlen (com_argv[i]) + 1;
- }
- if (!s)
+ Con_Print("stuffcmds : execute command line parameters\n");
return;
-
- text = Z_Malloc (s+1);
- text[0] = 0;
- for (i=1 ; i<com_argc ; i++)
- {
- if (!com_argv[i])
- continue; // NEXTSTEP nulls out -NXHost
- strcat (text,com_argv[i]);
- if (i != com_argc-1)
- strcat (text, " ");
}
-// pull out the commands
- build = Z_Malloc (s+1);
- build[0] = 0;
-
- for (i=0 ; i<s-1 ; i++)
+ for (i = 0;i < com_argc;i++)
{
- if (text[i] == '+')
+ if (com_argv[i] && com_argv[i][0] == '+' && (com_argv[i][1] < '0' || com_argv[i][1] > '9'))
{
+ l = 0;
+ j = 1;
+ while (com_argv[i][j])
+ build[l++] = com_argv[i][j++];
i++;
-
- for (j=i ; (text[j] != '+') && (text[j] != '-') && (text[j] != 0) ; j++)
- ;
-
- c = text[j];
- text[j] = 0;
-
- strcat (build, text+i);
- strcat (build, "\n");
- text[j] = c;
- i = j-1;
+ for (;i < com_argc;i++)
+ {
+ if (!com_argv[i])
+ continue;
+ if ((com_argv[i][0] == '+' || com_argv[i][0] == '-') && (com_argv[i][1] < '0' || com_argv[i][1] > '9'))
+ break;
+ if (l + strlen(com_argv[i]) + 5 > sizeof(build))
+ break;
+ build[l++] = ' ';
+ build[l++] = '\"';
+ for (j = 0;com_argv[i][j];j++)
+ build[l++] = com_argv[i][j];
+ build[l++] = '\"';
+ }
+ build[l++] = '\n';
+ build[l++] = 0;
+ Cbuf_InsertText (build);
+ i--;
}
}
-
- if (build[0])
- Cbuf_InsertText (build);
-
- Z_Free (text);
- Z_Free (build);
}
*/
static void Cmd_Exec_f (void)
{
- char *f;
+ char *f;
if (Cmd_Argc () != 2)
{
- Con_Printf ("exec <filename> : execute a script file\n");
+ Con_Print("exec <filename> : execute a script file\n");
return;
}
- f = (char *)COM_LoadFile (Cmd_Argv(1), false);
+ f = (char *)FS_LoadFile (Cmd_Argv(1), tempmempool, false);
if (!f)
{
- Con_Printf ("couldn't exec %s\n",Cmd_Argv(1));
+ Con_Printf("couldn't exec %s\n",Cmd_Argv(1));
return;
}
- Con_Printf ("execing %s\n",Cmd_Argv(1));
+ Con_DPrintf("execing %s\n",Cmd_Argv(1));
Cbuf_InsertText (f);
Mem_Free(f);
int i;
for (i=1 ; i<Cmd_Argc() ; i++)
- Con_Printf ("%s ",Cmd_Argv(i));
- Con_Printf ("\n");
+ Con_Printf("%s ",Cmd_Argv(i));
+ Con_Print("\n");
}
/*
Creates a new command that executes a command string (possibly ; seperated)
===============
*/
-
-static char *CopyString (char *in)
-{
- char *out;
-
- out = Z_Malloc (strlen(in)+1);
- strcpy (out, in);
- return out;
-}
-
static void Cmd_Alias_f (void)
{
cmdalias_t *a;
char cmd[1024];
int i, c;
- char *s;
+ const char *s;
if (Cmd_Argc() == 1)
{
- Con_Printf ("Current alias commands:\n");
+ Con_Print("Current alias commands:\n");
for (a = cmd_alias ; a ; a=a->next)
- Con_Printf ("%s : %s\n", a->name, a->value);
+ Con_Printf("%s : %s\n", a->name, a->value);
return;
}
s = Cmd_Argv(1);
if (strlen(s) >= MAX_ALIAS_NAME)
{
- Con_Printf ("Alias name is too long\n");
+ Con_Print("Alias name is too long\n");
return;
}
a->next = cmd_alias;
cmd_alias = a;
}
- strcpy (a->name, s);
+ strlcpy (a->name, s, sizeof (a->name));
// copy the rest of the command line
cmd[0] = 0; // start out with a null string
c = Cmd_Argc();
for (i=2 ; i< c ; i++)
{
- strcat (cmd, Cmd_Argv(i));
+ strlcat (cmd, Cmd_Argv(i), sizeof (cmd));
if (i != c)
- strcat (cmd, " ");
+ strlcat (cmd, " ", sizeof (cmd));
}
- strcat (cmd, "\n");
+ strlcat (cmd, "\n", sizeof (cmd));
- a->value = CopyString (cmd);
+ a->value = Z_Malloc (strlen (cmd) + 1);
+ strcpy (a->value, cmd);
}
/*
typedef struct cmd_function_s
{
- struct cmd_function_s *next;
- char *name;
- xcommand_t function;
+ struct cmd_function_s *next;
+ const char *name;
+ xcommand_t function;
} cmd_function_t;
#define MAX_ARGS 80
static int cmd_argc;
-static char *cmd_argv[MAX_ARGS];
-static char *cmd_null_string = "";
-static char *cmd_args = NULL;
+static const char *cmd_argv[MAX_ARGS];
+static const char *cmd_null_string = "";
+static const char *cmd_args = NULL;
cmd_source_t cmd_source;
*/
static void Cmd_List_f (void)
{
- cmd_function_t *cmd;
- char *partial;
- int len;
- int count;
+ cmd_function_t *cmd;
+ const char *partial;
+ int len, count;
- if (Cmd_Argc() > 1) {
+ if (Cmd_Argc() > 1)
+ {
partial = Cmd_Argv (1);
len = strlen(partial);
- } else {
+ }
+ else
+ {
partial = NULL;
len = 0;
}
count = 0;
- for (cmd = cmd_functions; cmd; cmd = cmd->next) {
+ for (cmd = cmd_functions; cmd; cmd = cmd->next)
+ {
if (partial && strncmp(partial, cmd->name, len))
continue;
- Con_Printf ("%s\n", cmd->name);
+ Con_Printf("%s\n", cmd->name);
count++;
}
- Con_Printf ("%i Command%s", count, (count > 1) ? "s" : "");
+ Con_Printf("%i Command%s", count, (count > 1) ? "s" : "");
if (partial)
Con_Printf(" beginning with \"%s\"", partial);
- Con_Printf ("\n\n");
+ Con_Print("\n\n");
}
/*
*/
void Cmd_Init (void)
{
- cmd_mempool = Mem_AllocPool("commands");
+ cmd_mempool = Mem_AllocPool("commands", 0, NULL);
//
// register our commands
Cmd_AddCommand ("cmdlist", Cmd_List_f); // Added/Modified by EvilTypeGuy eviltypeguy@qeradiant.com
Cmd_AddCommand ("cvarlist", Cvar_List_f); // 2000-01-09 CmdList, CvarList commands
// By Matthias "Maddes" Buecher
+ Cmd_AddCommand ("set", Cvar_Set_f);
+ Cmd_AddCommand ("seta", Cvar_SetA_f);
+}
+
+/*
+============
+Cmd_Shutdown
+============
+*/
+void Cmd_Shutdown(void)
+{
+ Mem_FreePool(&cmd_mempool);
}
/*
Cmd_Argv
============
*/
-char *Cmd_Argv (int arg)
+const char *Cmd_Argv (int arg)
{
if (arg >= cmd_argc )
return cmd_null_string;
Cmd_Args
============
*/
-char *Cmd_Args (void)
+const char *Cmd_Args (void)
{
return cmd_args;
}
-#define CMD_TOKENIZELENGTH 4096
-char cmd_tokenizebuffer[CMD_TOKENIZELENGTH];
-
/*
============
Cmd_TokenizeString
Parses the given string into command line tokens.
============
*/
-static void Cmd_TokenizeString (char *text)
+static void Cmd_TokenizeString (const char *text)
{
int l;
- int pos;
- pos = 0;
cmd_argc = 0;
cmd_args = NULL;
while (1)
{
-// skip whitespace up to a /n
- while (*text && *text <= ' ' && *text != '\n')
- {
+ // skip whitespace up to a /n
+ while (*text && *text <= ' ' && *text != '\r' && *text != '\n')
text++;
- }
- if (*text == '\n')
- { // a newline seperates commands in the buffer
+ // line endings:
+ // UNIX: \n
+ // Mac: \r
+ // Windows: \r\n
+ if (*text == '\n' || *text == '\r')
+ {
+ // a newline seperates commands in the buffer
+ if (*text == '\r' && text[1] == '\n')
+ text++;
text++;
break;
}
if (cmd_argc == 1)
cmd_args = text;
- text = COM_Parse (text);
- if (!text)
+ if (!COM_ParseTokenConsole(&text))
return;
if (cmd_argc < MAX_ARGS)
{
l = strlen(com_token) + 1;
- if (pos + l > CMD_TOKENIZELENGTH)
+ if (cmd_tokenizebufferpos + l > CMD_TOKENIZELENGTH)
Sys_Error("Cmd_TokenizeString: ran out of %i character buffer space for command arguements\n", CMD_TOKENIZELENGTH);
- cmd_argv[cmd_argc] = cmd_tokenizebuffer + pos;
- pos += l;
- strcpy (cmd_argv[cmd_argc], com_token);
+ strcpy (cmd_tokenizebuffer + cmd_tokenizebufferpos, com_token);
+ cmd_argv[cmd_argc] = cmd_tokenizebuffer + cmd_tokenizebufferpos;
+ cmd_tokenizebufferpos += l;
cmd_argc++;
}
}
Cmd_AddCommand
============
*/
-void Cmd_AddCommand (char *cmd_name, xcommand_t function)
+void Cmd_AddCommand (const char *cmd_name, xcommand_t function)
{
- cmd_function_t *cmd;
+ cmd_function_t *cmd;
// fail if the command is a variable name
if (Cvar_VariableString(cmd_name)[0])
{
- Con_Printf ("Cmd_AddCommand: %s already defined as a var\n", cmd_name);
+ Con_Printf("Cmd_AddCommand: %s already defined as a var\n", cmd_name);
return;
}
{
if (!strcmp (cmd_name, cmd->name))
{
- Con_Printf ("Cmd_AddCommand: %s already defined\n", cmd_name);
+ Con_Printf("Cmd_AddCommand: %s already defined\n", cmd_name);
return;
}
}
Cmd_Exists
============
*/
-qboolean Cmd_Exists (char *cmd_name)
+qboolean Cmd_Exists (const char *cmd_name)
{
cmd_function_t *cmd;
Cmd_CompleteCommand
============
*/
-char *Cmd_CompleteCommand (char *partial)
+const char *Cmd_CompleteCommand (const char *partial)
{
- cmd_function_t *cmd;
- int len;
+ cmd_function_t *cmd;
+ int len;
len = strlen(partial);
Thanks to taniwha
*/
-int Cmd_CompleteCountPossible (char *partial)
+int Cmd_CompleteCountPossible (const char *partial)
{
- cmd_function_t *cmd;
- int len;
- int h;
+ cmd_function_t *cmd;
+ int len, h;
h = 0;
len = strlen(partial);
Thanks to taniwha
*/
-char **Cmd_CompleteBuildList (char *partial)
+const char **Cmd_CompleteBuildList (const char *partial)
{
- cmd_function_t *cmd;
- int len = 0;
- int bpos = 0;
- int sizeofbuf = (Cmd_CompleteCountPossible (partial) + 1) * sizeof (char *);
- char **buf;
+ cmd_function_t *cmd;
+ int len = 0;
+ int bpos = 0;
+ int sizeofbuf = (Cmd_CompleteCountPossible (partial) + 1) * sizeof (const char *);
+ const char **buf;
len = strlen(partial);
- buf = Mem_Alloc(tempmempool, sizeofbuf + sizeof (char *));
+ buf = Mem_Alloc(tempmempool, sizeofbuf + sizeof (const char *));
// Loop through the alias list and print all matches
for (cmd = cmd_functions; cmd; cmd = cmd->next)
if (!strncasecmp(partial, cmd->name, len))
Thanks to taniwha
*/
-char *Cmd_CompleteAlias (char * partial)
+const char *Cmd_CompleteAlias (const char *partial)
{
- cmdalias_t *alias;
- int len;
+ cmdalias_t *alias;
+ int len;
len = strlen(partial);
Thanks to taniwha
*/
-int Cmd_CompleteAliasCountPossible (char *partial)
+int Cmd_CompleteAliasCountPossible (const char *partial)
{
cmdalias_t *alias;
int len;
Thanks to taniwha
*/
-char **Cmd_CompleteAliasBuildList (char *partial)
+const char **Cmd_CompleteAliasBuildList (const char *partial)
{
- cmdalias_t *alias;
- int len = 0;
- int bpos = 0;
- int sizeofbuf = (Cmd_CompleteAliasCountPossible (partial) + 1) * sizeof (char *);
- char **buf;
+ cmdalias_t *alias;
+ int len = 0;
+ int bpos = 0;
+ int sizeofbuf = (Cmd_CompleteAliasCountPossible (partial) + 1) * sizeof (const char *);
+ const char **buf;
len = strlen(partial);
- buf = Mem_Alloc(tempmempool, sizeofbuf + sizeof (char *));
+ buf = Mem_Alloc(tempmempool, sizeofbuf + sizeof (const char *));
// Loop through the alias list and print all matches
for (alias = cmd_alias; alias; alias = alias->next)
if (!strncasecmp(partial, alias->name, len))
FIXME: lookupnoadd the token to speed search?
============
*/
-void Cmd_ExecuteString (char *text, cmd_source_t src)
+void Cmd_ExecuteString (const char *text, cmd_source_t src)
{
- cmd_function_t *cmd;
- cmdalias_t *a;
+ int oldpos;
+ cmd_function_t *cmd;
+ cmdalias_t *a;
+ oldpos = cmd_tokenizebufferpos;
cmd_source = src;
Cmd_TokenizeString (text);
// execute the command line
if (!Cmd_Argc())
+ {
+ cmd_tokenizebufferpos = oldpos;
return; // no tokens
+ }
-// check functions
- for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
+// check functions (only after host_initialized)
+ if (host_initialized || !strcasecmp(cmd_argv[0], "exec") || !strcasecmp(cmd_argv[0], "set") || !strcasecmp(cmd_argv[0], "seta"))
{
- if (!Q_strcasecmp (cmd_argv[0],cmd->name))
+ for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
{
- cmd->function ();
- return;
+ if (!strcasecmp (cmd_argv[0],cmd->name))
+ {
+ cmd->function ();
+ cmd_tokenizebufferpos = oldpos;
+ return;
+ }
}
}
-// check alias
- for (a=cmd_alias ; a ; a=a->next)
+// check alias (only after host_initialized)
+ if (host_initialized)
{
- if (!Q_strcasecmp (cmd_argv[0], a->name))
+ for (a=cmd_alias ; a ; a=a->next)
{
- Cbuf_InsertText (a->value);
- return;
+ if (!strcasecmp (cmd_argv[0], a->name))
+ {
+ Cbuf_InsertText (a->value);
+ cmd_tokenizebufferpos = oldpos;
+ return;
+ }
}
}
-// check cvars
- if (!Cvar_Command ())
- Con_Printf ("Unknown command \"%s\"\n", Cmd_Argv(0));
+// check cvars (always)
+ if (!Cvar_Command () && host_initialized)
+ Con_Printf("Unknown command \"%s\"\n", Cmd_Argv(0));
+
+ cmd_tokenizebufferpos = oldpos;
}
/*
===================
-Cmd_ForwardToServer
+Cmd_ForwardStringToServer
-Sends the entire command line over to the server
+Sends an entire command string over to the server, unprocessed
===================
*/
-void Cmd_ForwardToServer (void)
+void Cmd_ForwardStringToServer (const char *s)
{
if (cls.state != ca_connected)
{
- Con_Printf ("Can't \"%s\", not connected\n", Cmd_Argv(0));
+ Con_Printf("Can't \"%s\", not connected\n", s);
return;
}
if (cls.demoplayback)
return; // not really connected
- MSG_WriteByte (&cls.message, clc_stringcmd);
- if (Q_strcasecmp(Cmd_Argv(0), "cmd") != 0)
- {
- SZ_Print (&cls.message, Cmd_Argv(0));
- SZ_Print (&cls.message, " ");
- }
- if (Cmd_Argc() > 1)
- SZ_Print (&cls.message, Cmd_Args());
+ // LordHavoc: thanks to Fuh for bringing the pure evil of SZ_Print to my
+ // attention, it has been eradicated from here, its only (former) use in
+ // all of darkplaces.
+ MSG_WriteByte(&cls.message, clc_stringcmd);
+ SZ_Write(&cls.message, s, strlen(s) + 1);
+}
+
+/*
+===================
+Cmd_ForwardToServer
+
+Sends the entire command line over to the server
+===================
+*/
+void Cmd_ForwardToServer (void)
+{
+ const char *s;
+ if (strcasecmp(Cmd_Argv(0), "cmd"))
+ s = va("%s %s", Cmd_Argv(0), Cmd_Argc() > 1 ? Cmd_Args() : "");
else
- SZ_Print (&cls.message, "\n");
+ s = Cmd_Argc() > 1 ? Cmd_Args() : "";
+ Cmd_ForwardStringToServer(s);
}
================
*/
-int Cmd_CheckParm (char *parm)
+int Cmd_CheckParm (const char *parm)
{
int i;
Sys_Error ("Cmd_CheckParm: NULL");
for (i = 1; i < Cmd_Argc (); i++)
- if (!Q_strcasecmp (parm, Cmd_Argv (i)))
+ if (!strcasecmp (parm, Cmd_Argv (i)))
return i;
return 0;