aboutsummaryrefslogtreecommitdiffstats
path: root/code/qcommon/cmd.c.save
diff options
context:
space:
mode:
authorzakk <zakk@edf5b092-35ff-0310-97b2-ce42778d08ea>2005-08-26 17:39:27 +0000
committerzakk <zakk@edf5b092-35ff-0310-97b2-ce42778d08ea>2005-08-26 17:39:27 +0000
commit6bf20c78f5b69d40bcc4931df93d29198435ab67 (patch)
treee3eda937a05d7db42de725b7013bd0344b987f34 /code/qcommon/cmd.c.save
parent872d4d7f55af706737ffb361bb76ad13e7496770 (diff)
downloadioquake3-aero-6bf20c78f5b69d40bcc4931df93d29198435ab67.tar.gz
ioquake3-aero-6bf20c78f5b69d40bcc4931df93d29198435ab67.zip
newlines fixed
git-svn-id: svn://svn.icculus.org/quake3/trunk@6 edf5b092-35ff-0310-97b2-ce42778d08ea
Diffstat (limited to 'code/qcommon/cmd.c.save')
-rwxr-xr-xcode/qcommon/cmd.c.save1272
1 files changed, 636 insertions, 636 deletions
diff --git a/code/qcommon/cmd.c.save b/code/qcommon/cmd.c.save
index 0bf9602..47f8eb9 100755
--- a/code/qcommon/cmd.c.save
+++ b/code/qcommon/cmd.c.save
@@ -1,636 +1,636 @@
-// cmd.c -- Quake script command processing module
-
-#include "../game/q_shared.h"
-#include "qcommon.h"
-
-#define MAX_CMD_BUFFER 8192
-int cmd_wait;
-msg_t cmd_text;
-byte cmd_text_buf[MAX_CMD_BUFFER];
-char cmd_defer_text_buf[MAX_CMD_BUFFER];
-
-
-//=============================================================================
-
-/*
-============
-Cmd_Wait_f
-
-Causes execution of the remainder of the command buffer to be delayed until
-next frame. This allows commands like:
-bind g "cmd use rocket ; +attack ; wait ; -attack ; cmd use blaster"
-============
-*/
-void Cmd_Wait_f( void ) {
- if ( Cmd_Argc() == 2 ) {
- cmd_wait = atoi( Cmd_Argv( 1 ) );
- } else {
- cmd_wait = 1;
- }
-}
-
-
-/*
-=============================================================================
-
- COMMAND BUFFER
-
-=============================================================================
-*/
-
-/*
-============
-Cbuf_Init
-============
-*/
-void Cbuf_Init (void)
-{
- MSG_Init (&cmd_text, cmd_text_buf, sizeof(cmd_text_buf));
-}
-
-/*
-============
-Cbuf_AddText
-
-Adds command text at the end of the buffer, does NOT add a final \n
-============
-*/
-void Cbuf_AddText( const char *text ) {
- int l;
-
- l = strlen (text);
-
- if (cmd_text.cursize + l >= cmd_text.maxsize)
- {
- Com_Printf ("Cbuf_AddText: overflow\n");
- return;
- }
- MSG_WriteData (&cmd_text, text, strlen (text));
-}
-
-
-/*
-============
-Cbuf_InsertText
-
-Adds command text immediately after the current command
-Adds a \n to the text
-============
-*/
-void Cbuf_InsertText( const char *text ) {
- int len;
- int i;
-
- len = strlen( text ) + 1;
- if ( len + cmd_text.cursize > cmd_text.maxsize ) {
- Com_Printf( "Cbuf_InsertText overflowed\n" );
- return;
- }
-
- // move the existing command text
- for ( i = cmd_text.cursize - 1 ; i >= 0 ; i-- ) {
- cmd_text.data[ i + len ] = cmd_text.data[ i ];
- }
-
- // copy the new text in
- memcpy( cmd_text.data, text, len - 1 );
-
- // add a \n
- cmd_text.data[ len - 1 ] = '\n';
-
- cmd_text.cursize += len;
-}
-
-
-/*
-============
-Cbuf_ExecuteText
-============
-*/
-void Cbuf_ExecuteText (int exec_when, const char *text)
-{
- switch (exec_when)
- {
- case EXEC_NOW:
- Cmd_ExecuteString (text);
- break;
- case EXEC_INSERT:
- Cbuf_InsertText (text);
- break;
- case EXEC_APPEND:
- Cbuf_AddText (text);
- break;
- default:
- Com_Error (ERR_FATAL, "Cbuf_ExecuteText: bad exec_when");
- }
-}
-
-/*
-============
-Cbuf_Execute
-============
-*/
-void Cbuf_Execute (void)
-{
- int i;
- char *text;
- char line[MAX_CMD_BUFFER];
- int quotes;
-
- while (cmd_text.cursize)
- {
- if ( cmd_wait ) {
- // skip out while text still remains in buffer, leaving it
- // for next frame
- cmd_wait--;
- break;
- }
-
- // find a \n or ; line break
- text = (char *)cmd_text.data;
-
- quotes = 0;
- for (i=0 ; i< cmd_text.cursize ; i++)
- {
- if (text[i] == '"')
- quotes++;
- if ( !(quotes&1) && text[i] == ';')
- break; // don't break if inside a quoted string
- if (text[i] == '\n' || text[i] == '\r' )
- break;
- }
-
-
- memcpy (line, text, i);
- line[i] = 0;
-
-// delete the text from the command buffer and move remaining commands down
-// this is necessary because commands (exec) can insert data at the
-// beginning of the text buffer
-
- if (i == cmd_text.cursize)
- cmd_text.cursize = 0;
- else
- {
- i++;
- cmd_text.cursize -= i;
- memmove (text, text+i, cmd_text.cursize);
- text[cmd_text.cursize] = 0;
- }
-
-// execute the command line
- Cmd_ExecuteString (line);
- }
-}
-
-
-/*
-==============================================================================
-
- SCRIPT COMMANDS
-
-==============================================================================
-*/
-
-
-/*
-===============
-Cmd_Exec_f
-===============
-*/
-void Cmd_Exec_f( void ) {
- fileHandle_t f;
- int len;
- char filename[MAX_QPATH];
- char *buffer;
-
- if (Cmd_Argc () != 2) {
- Com_Printf ("exec <filename> : execute a script file\n");
- return;
- }
-
- Q_strncpyz( filename, Cmd_Argv(1), sizeof( filename ) );
- COM_DefaultExtension( filename, sizeof( filename ), ".cfg" );
- len = FS_FOpenFileRead( filename, &f, qfalse );
- if ( len <= 0 ) {
- Com_Printf ("Couldn't read %s.\n", filename );
- return;
- }
-
- buffer = Z_Malloc(len+1);
-
- if (FS_Read(buffer, len, f) == len) {
- FS_FCloseFile( f );
- buffer[len] = 0;
- Com_Printf ("execing %s\n",Cmd_Argv(1));
- Cbuf_InsertText (buffer);
- }
- else {
- Com_Printf ("couldn't exec %s\n",Cmd_Argv(1));
- }
-
- Z_Free(buffer);
-}
-
-
-/*
-===============
-Cmd_Vstr_f
-
-Inserts the current value of a variable as command text
-===============
-*/
-void Cmd_Vstr_f( void ) {
- char *v;
-
- if (Cmd_Argc () != 2) {
- Com_Printf ("vstr <variablename> : execute a variable command\n");
- return;
- }
-
- v = Cvar_VariableString( Cmd_Argv( 1 ) );
- Cbuf_InsertText( va("%s\n", v ) );
-}
-
-
-/*
-===============
-Cmd_Echo_f
-
-Just prints the rest of the line to the console
-===============
-*/
-void Cmd_Echo_f (void)
-{
- int i;
-
- for (i=1 ; i<Cmd_Argc() ; i++)
- Com_Printf ("%s ",Cmd_Argv(i));
- Com_Printf ("\n");
-}
-
-
-/*
-=============================================================================
-
- COMMAND EXECUTION
-
-=============================================================================
-*/
-
-typedef struct cmd_function_s
-{
- struct cmd_function_s *next;
- char *name;
- xcommand_t function;
-} cmd_function_t;
-
-
-static int cmd_argc;
-static char *cmd_argv[MAX_STRING_TOKENS]; // points into cmd_tokenized
-static char cmd_tokenized[MAX_STRING_CHARS+MAX_STRING_TOKENS]; // will have 0 bytes inserted
-
-static cmd_function_t *cmd_functions; // possible commands to execute
-
-/*
-============
-Cmd_Argc
-============
-*/
-int Cmd_Argc( void ) {
- return cmd_argc;
-}
-
-/*
-============
-Cmd_Argv
-============
-*/
-char *Cmd_Argv( int arg ) {
- if ( (unsigned)arg >= cmd_argc ) {
- return "";
- }
- return cmd_argv[arg];
-}
-
-/*
-============
-Cmd_ArgvBuffer
-
-The interpreted versions use this because
-they can't have pointers returned to them
-============
-*/
-void Cmd_ArgvBuffer( int arg, char *buffer, int bufferLength ) {
- Q_strncpyz( buffer, Cmd_Argv( arg ), bufferLength );
-}
-
-
-/*
-============
-Cmd_Args
-
-Returns a single string containing argv(1) to argv(argc()-1)
-============
-*/
-char *Cmd_Args( void ) {
- static char cmd_args[MAX_STRING_CHARS];
- int i;
-
- cmd_args[0] = 0;
- for ( i = 1 ; i < cmd_argc ; i++ ) {
- strcat( cmd_args, cmd_argv[i] );
- if ( i != cmd_argc ) {
- strcat( cmd_args, " " );
- }
- }
-
- return cmd_args;
-}
-
-
-/*
-============
-Cmd_ArgsBuffer
-
-The interpreted versions use this because
-they can't have pointers returned to them
-============
-*/
-void Cmd_ArgsBuffer( char *buffer, int bufferLength ) {
- Q_strncpyz( buffer, Cmd_Args(), bufferLength );
-}
-
-
-/*
-============
-Cmd_TokenizeString
-
-Parses the given string into command line tokens.
-The text is copied to a seperate buffer and 0 characters
-are inserted in the apropriate place, The argv array
-will point into this temporary buffer.
-============
-*/
-void Cmd_TokenizeString( const char *text_in ) {
- const char *text;
- char *textOut;
-
- // clear previous args
- cmd_argc = 0;
-
- if ( !text_in ) {
- return;
- }
-
- text = text_in;
- textOut = cmd_tokenized;
-
- while ( 1 ) {
- if ( cmd_argc == MAX_STRING_TOKENS ) {
- return; // this is usually something malicious
- }
-
- while ( 1 ) {
- // skip whitespace
- while ( *text && *text <= ' ' ) {
- text++;
- }
- if ( !*text ) {
- return; // all tokens parsed
- }
-
- // skip // comments
- if ( text[0] == '/' && text[1] == '/' ) {
- return; // all tokens parsed
- }
-
- // skip /* */ comments
- if ( text[0] == '/' && text[1] =='*' ) {
- while ( *text && ( text[0] != '*' || text[1] != '/' ) ) {
- text++;
- }
- if ( !*text ) {
- return; // all tokens parsed
- }
- text += 2;
- } else {
- break; // we are ready to parse a token
- }
- }
-
- // handle quoted strings
- if ( *text == '"' ) {
- cmd_argv[cmd_argc] = textOut;
- cmd_argc++;
- text++;
- while ( *text && *text != '"' ) {
- *textOut++ = *text++;
- }
- *textOut++ = 0;
- if ( !*text ) {
- return; // all tokens parsed
- }
- text++;
- continue;
- }
-
- // regular token
- cmd_argv[cmd_argc] = textOut;
- cmd_argc++;
-
- // skip until whitespace, quote, or command
- while ( *text > ' ' ) {
- if ( text[0] == '"' ) {
- break;
- }
-
- if ( text[0] == '/' && text[1] == '/' ) {
- break;
- }
-
- // skip /* */ comments
- if ( text[0] == '/' && text[1] =='*' ) {
- break;
- }
-
- *textOut++ = *text++;
- }
-
- *textOut++ = 0;
-
- if ( !*text ) {
- return; // all tokens parsed
- }
- }
-
-}
-
-
-/*
-============
-Cmd_AddCommand
-============
-*/
-void Cmd_AddCommand( const char *cmd_name, xcommand_t function ) {
- cmd_function_t *cmd;
-
- // fail if the command already exists
- for ( cmd = cmd_functions ; cmd ; cmd=cmd->next ) {
- if ( !strcmp( cmd_name, cmd->name ) ) {
- // allow completion-only commands to be silently doubled
- if ( function != NULL ) {
- Com_Printf ("Cmd_AddCommand: %s already defined\n", cmd_name);
- }
- return;
- }
- }
-
- cmd = Z_Malloc (sizeof(cmd_function_t));
- cmd->name = CopyString( cmd_name );
- cmd->function = function;
- cmd->next = cmd_functions;
- cmd_functions = cmd;
-}
-
-/*
-============
-Cmd_RemoveCommand
-============
-*/
-void Cmd_RemoveCommand( const char *cmd_name ) {
- cmd_function_t *cmd, **back;
-
- back = &cmd_functions;
- while( 1 ) {
- cmd = *back;
- if ( !cmd ) {
- // command wasn't active
- return;
- }
- if ( !strcmp( cmd_name, cmd->name ) ) {
- *back = cmd->next;
- Z_Free (cmd);
- return;
- }
- back = &cmd->next;
- }
-}
-
-
-/*
-============
-Cmd_CommandCompletion
-============
-*/
-void Cmd_CommandCompletion( void(*callback)(const char *s) ) {
- cmd_function_t *cmd;
-
- for (cmd=cmd_functions ; cmd ; cmd=cmd->next) {
- callback( cmd->name );
- }
-}
-
-
-/*
-============
-Cmd_ExecuteString
-
-A complete command line has been parsed, so try to execute it
-============
-*/
-void Cmd_ExecuteString( const char *text ) {
- cmd_function_t *cmd, **prev;
-
- // execute the command line
- Cmd_TokenizeString( text );
- if ( !Cmd_Argc() ) {
- return; // no tokens
- }
-
- // check registered command functions
- for ( prev = &cmd_functions ; *prev ; prev = &cmd->next ) {
- cmd = *prev;
- if ( !Q_stricmp( cmd_argv[0],cmd->name ) ) {
- // rearrange the links so that the command will be
- // near the head of the list next time it is used
- *prev = cmd->next;
- cmd->next = cmd_functions;
- cmd_functions = cmd;
-
- // perform the action
- if ( !cmd->function ) {
- // let the cgame or game handle it
- break;
- } else {
- cmd->function ();
- }
- return;
- }
- }
-
- // check cvars
- if ( Cvar_Command() ) {
- return;
- }
-
- // check client game commands
- if ( com_cl_running && com_cl_running->integer && CL_GameCommand() ) {
- return;
- }
-
- // check server game commands
- if ( com_sv_running && com_sv_running->integer && SV_GameCommand() ) {
- return;
- }
-
- // check ui commands
- if ( com_cl_running && com_cl_running->integer && UI_GameCommand() ) {
- return;
- }
-
- // send it as a server command if we are connected
- // this will usually result in a chat message
- CL_ForwardCommandToServer ();
-}
-
-/*
-============
-Cmd_List_f
-============
-*/
-void Cmd_List_f (void)
-{
- cmd_function_t *cmd;
- int i;
- char *match;
-
- if ( Cmd_Argc() > 1 ) {
- match = Cmd_Argv( 1 );
- } else {
- match = NULL;
- }
-
- i = 0;
- for (cmd=cmd_functions ; cmd ; cmd=cmd->next) {
- if (match && !Com_Filter(match, cmd->name, qfalse)) continue;
-
- Com_Printf ("%s\n", cmd->name);
- i++;
- }
- Com_Printf ("%i commands\n", i);
-}
-
-/*
-============
-Cmd_Init
-============
-*/
-void Cmd_Init (void) {
- Cmd_AddCommand ("cmdlist",Cmd_List_f);
- Cmd_AddCommand ("exec",Cmd_Exec_f);
- Cmd_AddCommand ("vstr",Cmd_Vstr_f);
- Cmd_AddCommand ("echo",Cmd_Echo_f);
- Cmd_AddCommand ("wait", Cmd_Wait_f);
-}
-
+// cmd.c -- Quake script command processing module
+
+#include "../game/q_shared.h"
+#include "qcommon.h"
+
+#define MAX_CMD_BUFFER 8192
+int cmd_wait;
+msg_t cmd_text;
+byte cmd_text_buf[MAX_CMD_BUFFER];
+char cmd_defer_text_buf[MAX_CMD_BUFFER];
+
+
+//=============================================================================
+
+/*
+============
+Cmd_Wait_f
+
+Causes execution of the remainder of the command buffer to be delayed until
+next frame. This allows commands like:
+bind g "cmd use rocket ; +attack ; wait ; -attack ; cmd use blaster"
+============
+*/
+void Cmd_Wait_f( void ) {
+ if ( Cmd_Argc() == 2 ) {
+ cmd_wait = atoi( Cmd_Argv( 1 ) );
+ } else {
+ cmd_wait = 1;
+ }
+}
+
+
+/*
+=============================================================================
+
+ COMMAND BUFFER
+
+=============================================================================
+*/
+
+/*
+============
+Cbuf_Init
+============
+*/
+void Cbuf_Init (void)
+{
+ MSG_Init (&cmd_text, cmd_text_buf, sizeof(cmd_text_buf));
+}
+
+/*
+============
+Cbuf_AddText
+
+Adds command text at the end of the buffer, does NOT add a final \n
+============
+*/
+void Cbuf_AddText( const char *text ) {
+ int l;
+
+ l = strlen (text);
+
+ if (cmd_text.cursize + l >= cmd_text.maxsize)
+ {
+ Com_Printf ("Cbuf_AddText: overflow\n");
+ return;
+ }
+ MSG_WriteData (&cmd_text, text, strlen (text));
+}
+
+
+/*
+============
+Cbuf_InsertText
+
+Adds command text immediately after the current command
+Adds a \n to the text
+============
+*/
+void Cbuf_InsertText( const char *text ) {
+ int len;
+ int i;
+
+ len = strlen( text ) + 1;
+ if ( len + cmd_text.cursize > cmd_text.maxsize ) {
+ Com_Printf( "Cbuf_InsertText overflowed\n" );
+ return;
+ }
+
+ // move the existing command text
+ for ( i = cmd_text.cursize - 1 ; i >= 0 ; i-- ) {
+ cmd_text.data[ i + len ] = cmd_text.data[ i ];
+ }
+
+ // copy the new text in
+ memcpy( cmd_text.data, text, len - 1 );
+
+ // add a \n
+ cmd_text.data[ len - 1 ] = '\n';
+
+ cmd_text.cursize += len;
+}
+
+
+/*
+============
+Cbuf_ExecuteText
+============
+*/
+void Cbuf_ExecuteText (int exec_when, const char *text)
+{
+ switch (exec_when)
+ {
+ case EXEC_NOW:
+ Cmd_ExecuteString (text);
+ break;
+ case EXEC_INSERT:
+ Cbuf_InsertText (text);
+ break;
+ case EXEC_APPEND:
+ Cbuf_AddText (text);
+ break;
+ default:
+ Com_Error (ERR_FATAL, "Cbuf_ExecuteText: bad exec_when");
+ }
+}
+
+/*
+============
+Cbuf_Execute
+============
+*/
+void Cbuf_Execute (void)
+{
+ int i;
+ char *text;
+ char line[MAX_CMD_BUFFER];
+ int quotes;
+
+ while (cmd_text.cursize)
+ {
+ if ( cmd_wait ) {
+ // skip out while text still remains in buffer, leaving it
+ // for next frame
+ cmd_wait--;
+ break;
+ }
+
+ // find a \n or ; line break
+ text = (char *)cmd_text.data;
+
+ quotes = 0;
+ for (i=0 ; i< cmd_text.cursize ; i++)
+ {
+ if (text[i] == '"')
+ quotes++;
+ if ( !(quotes&1) && text[i] == ';')
+ break; // don't break if inside a quoted string
+ if (text[i] == '\n' || text[i] == '\r' )
+ break;
+ }
+
+
+ memcpy (line, text, i);
+ line[i] = 0;
+
+// delete the text from the command buffer and move remaining commands down
+// this is necessary because commands (exec) can insert data at the
+// beginning of the text buffer
+
+ if (i == cmd_text.cursize)
+ cmd_text.cursize = 0;
+ else
+ {
+ i++;
+ cmd_text.cursize -= i;
+ memmove (text, text+i, cmd_text.cursize);
+ text[cmd_text.cursize] = 0;
+ }
+
+// execute the command line
+ Cmd_ExecuteString (line);
+ }
+}
+
+
+/*
+==============================================================================
+
+ SCRIPT COMMANDS
+
+==============================================================================
+*/
+
+
+/*
+===============
+Cmd_Exec_f
+===============
+*/
+void Cmd_Exec_f( void ) {
+ fileHandle_t f;
+ int len;
+ char filename[MAX_QPATH];
+ char *buffer;
+
+ if (Cmd_Argc () != 2) {
+ Com_Printf ("exec <filename> : execute a script file\n");
+ return;
+ }
+
+ Q_strncpyz( filename, Cmd_Argv(1), sizeof( filename ) );
+ COM_DefaultExtension( filename, sizeof( filename ), ".cfg" );
+ len = FS_FOpenFileRead( filename, &f, qfalse );
+ if ( len <= 0 ) {
+ Com_Printf ("Couldn't read %s.\n", filename );
+ return;
+ }
+
+ buffer = Z_Malloc(len+1);
+
+ if (FS_Read(buffer, len, f) == len) {
+ FS_FCloseFile( f );
+ buffer[len] = 0;
+ Com_Printf ("execing %s\n",Cmd_Argv(1));
+ Cbuf_InsertText (buffer);
+ }
+ else {
+ Com_Printf ("couldn't exec %s\n",Cmd_Argv(1));
+ }
+
+ Z_Free(buffer);
+}
+
+
+/*
+===============
+Cmd_Vstr_f
+
+Inserts the current value of a variable as command text
+===============
+*/
+void Cmd_Vstr_f( void ) {
+ char *v;
+
+ if (Cmd_Argc () != 2) {
+ Com_Printf ("vstr <variablename> : execute a variable command\n");
+ return;
+ }
+
+ v = Cvar_VariableString( Cmd_Argv( 1 ) );
+ Cbuf_InsertText( va("%s\n", v ) );
+}
+
+
+/*
+===============
+Cmd_Echo_f
+
+Just prints the rest of the line to the console
+===============
+*/
+void Cmd_Echo_f (void)
+{
+ int i;
+
+ for (i=1 ; i<Cmd_Argc() ; i++)
+ Com_Printf ("%s ",Cmd_Argv(i));
+ Com_Printf ("\n");
+}
+
+
+/*
+=============================================================================
+
+ COMMAND EXECUTION
+
+=============================================================================
+*/
+
+typedef struct cmd_function_s
+{
+ struct cmd_function_s *next;
+ char *name;
+ xcommand_t function;
+} cmd_function_t;
+
+
+static int cmd_argc;
+static char *cmd_argv[MAX_STRING_TOKENS]; // points into cmd_tokenized
+static char cmd_tokenized[MAX_STRING_CHARS+MAX_STRING_TOKENS]; // will have 0 bytes inserted
+
+static cmd_function_t *cmd_functions; // possible commands to execute
+
+/*
+============
+Cmd_Argc
+============
+*/
+int Cmd_Argc( void ) {
+ return cmd_argc;
+}
+
+/*
+============
+Cmd_Argv
+============
+*/
+char *Cmd_Argv( int arg ) {
+ if ( (unsigned)arg >= cmd_argc ) {
+ return "";
+ }
+ return cmd_argv[arg];
+}
+
+/*
+============
+Cmd_ArgvBuffer
+
+The interpreted versions use this because
+they can't have pointers returned to them
+============
+*/
+void Cmd_ArgvBuffer( int arg, char *buffer, int bufferLength ) {
+ Q_strncpyz( buffer, Cmd_Argv( arg ), bufferLength );
+}
+
+
+/*
+============
+Cmd_Args
+
+Returns a single string containing argv(1) to argv(argc()-1)
+============
+*/
+char *Cmd_Args( void ) {
+ static char cmd_args[MAX_STRING_CHARS];
+ int i;
+
+ cmd_args[0] = 0;
+ for ( i = 1 ; i < cmd_argc ; i++ ) {
+ strcat( cmd_args, cmd_argv[i] );
+ if ( i != cmd_argc ) {
+ strcat( cmd_args, " " );
+ }
+ }
+
+ return cmd_args;
+}
+
+
+/*
+============
+Cmd_ArgsBuffer
+
+The interpreted versions use this because
+they can't have pointers returned to them
+============
+*/
+void Cmd_ArgsBuffer( char *buffer, int bufferLength ) {
+ Q_strncpyz( buffer, Cmd_Args(), bufferLength );
+}
+
+
+/*
+============
+Cmd_TokenizeString
+
+Parses the given string into command line tokens.
+The text is copied to a seperate buffer and 0 characters
+are inserted in the apropriate place, The argv array
+will point into this temporary buffer.
+============
+*/
+void Cmd_TokenizeString( const char *text_in ) {
+ const char *text;
+ char *textOut;
+
+ // clear previous args
+ cmd_argc = 0;
+
+ if ( !text_in ) {
+ return;
+ }
+
+ text = text_in;
+ textOut = cmd_tokenized;
+
+ while ( 1 ) {
+ if ( cmd_argc == MAX_STRING_TOKENS ) {
+ return; // this is usually something malicious
+ }
+
+ while ( 1 ) {
+ // skip whitespace
+ while ( *text && *text <= ' ' ) {
+ text++;
+ }
+ if ( !*text ) {
+ return; // all tokens parsed
+ }
+
+ // skip // comments
+ if ( text[0] == '/' && text[1] == '/' ) {
+ return; // all tokens parsed
+ }
+
+ // skip /* */ comments
+ if ( text[0] == '/' && text[1] =='*' ) {
+ while ( *text && ( text[0] != '*' || text[1] != '/' ) ) {
+ text++;
+ }
+ if ( !*text ) {
+ return; // all tokens parsed
+ }
+ text += 2;
+ } else {
+ break; // we are ready to parse a token
+ }
+ }
+
+ // handle quoted strings
+ if ( *text == '"' ) {
+ cmd_argv[cmd_argc] = textOut;
+ cmd_argc++;
+ text++;
+ while ( *text && *text != '"' ) {
+ *textOut++ = *text++;
+ }
+ *textOut++ = 0;
+ if ( !*text ) {
+ return; // all tokens parsed
+ }
+ text++;
+ continue;
+ }
+
+ // regular token
+ cmd_argv[cmd_argc] = textOut;
+ cmd_argc++;
+
+ // skip until whitespace, quote, or command
+ while ( *text > ' ' ) {
+ if ( text[0] == '"' ) {
+ break;
+ }
+
+ if ( text[0] == '/' && text[1] == '/' ) {
+ break;
+ }
+
+ // skip /* */ comments
+ if ( text[0] == '/' && text[1] =='*' ) {
+ break;
+ }
+
+ *textOut++ = *text++;
+ }
+
+ *textOut++ = 0;
+
+ if ( !*text ) {
+ return; // all tokens parsed
+ }
+ }
+
+}
+
+
+/*
+============
+Cmd_AddCommand
+============
+*/
+void Cmd_AddCommand( const char *cmd_name, xcommand_t function ) {
+ cmd_function_t *cmd;
+
+ // fail if the command already exists
+ for ( cmd = cmd_functions ; cmd ; cmd=cmd->next ) {
+ if ( !strcmp( cmd_name, cmd->name ) ) {
+ // allow completion-only commands to be silently doubled
+ if ( function != NULL ) {
+ Com_Printf ("Cmd_AddCommand: %s already defined\n", cmd_name);
+ }
+ return;
+ }
+ }
+
+ cmd = Z_Malloc (sizeof(cmd_function_t));
+ cmd->name = CopyString( cmd_name );
+ cmd->function = function;
+ cmd->next = cmd_functions;
+ cmd_functions = cmd;
+}
+
+/*
+============
+Cmd_RemoveCommand
+============
+*/
+void Cmd_RemoveCommand( const char *cmd_name ) {
+ cmd_function_t *cmd, **back;
+
+ back = &cmd_functions;
+ while( 1 ) {
+ cmd = *back;
+ if ( !cmd ) {
+ // command wasn't active
+ return;
+ }
+ if ( !strcmp( cmd_name, cmd->name ) ) {
+ *back = cmd->next;
+ Z_Free (cmd);
+ return;
+ }
+ back = &cmd->next;
+ }
+}
+
+
+/*
+============
+Cmd_CommandCompletion
+============
+*/
+void Cmd_CommandCompletion( void(*callback)(const char *s) ) {
+ cmd_function_t *cmd;
+
+ for (cmd=cmd_functions ; cmd ; cmd=cmd->next) {
+ callback( cmd->name );
+ }
+}
+
+
+/*
+============
+Cmd_ExecuteString
+
+A complete command line has been parsed, so try to execute it
+============
+*/
+void Cmd_ExecuteString( const char *text ) {
+ cmd_function_t *cmd, **prev;
+
+ // execute the command line
+ Cmd_TokenizeString( text );
+ if ( !Cmd_Argc() ) {
+ return; // no tokens
+ }
+
+ // check registered command functions
+ for ( prev = &cmd_functions ; *prev ; prev = &cmd->next ) {
+ cmd = *prev;
+ if ( !Q_stricmp( cmd_argv[0],cmd->name ) ) {
+ // rearrange the links so that the command will be
+ // near the head of the list next time it is used
+ *prev = cmd->next;
+ cmd->next = cmd_functions;
+ cmd_functions = cmd;
+
+ // perform the action
+ if ( !cmd->function ) {
+ // let the cgame or game handle it
+ break;
+ } else {
+ cmd->function ();
+ }
+ return;
+ }
+ }
+
+ // check cvars
+ if ( Cvar_Command() ) {
+ return;
+ }
+
+ // check client game commands
+ if ( com_cl_running && com_cl_running->integer && CL_GameCommand() ) {
+ return;
+ }
+
+ // check server game commands
+ if ( com_sv_running && com_sv_running->integer && SV_GameCommand() ) {
+ return;
+ }
+
+ // check ui commands
+ if ( com_cl_running && com_cl_running->integer && UI_GameCommand() ) {
+ return;
+ }
+
+ // send it as a server command if we are connected
+ // this will usually result in a chat message
+ CL_ForwardCommandToServer ();
+}
+
+/*
+============
+Cmd_List_f
+============
+*/
+void Cmd_List_f (void)
+{
+ cmd_function_t *cmd;
+ int i;
+ char *match;
+
+ if ( Cmd_Argc() > 1 ) {
+ match = Cmd_Argv( 1 );
+ } else {
+ match = NULL;
+ }
+
+ i = 0;
+ for (cmd=cmd_functions ; cmd ; cmd=cmd->next) {
+ if (match && !Com_Filter(match, cmd->name, qfalse)) continue;
+
+ Com_Printf ("%s\n", cmd->name);
+ i++;
+ }
+ Com_Printf ("%i commands\n", i);
+}
+
+/*
+============
+Cmd_Init
+============
+*/
+void Cmd_Init (void) {
+ Cmd_AddCommand ("cmdlist",Cmd_List_f);
+ Cmd_AddCommand ("exec",Cmd_Exec_f);
+ Cmd_AddCommand ("vstr",Cmd_Vstr_f);
+ Cmd_AddCommand ("echo",Cmd_Echo_f);
+ Cmd_AddCommand ("wait", Cmd_Wait_f);
+}
+