From 33cae82140fec8e21ba27d3f81a28e455bdd6bef Mon Sep 17 00:00:00 2001 From: Yamagi Burmeister Date: Wed, 14 Jul 2010 09:40:11 +0000 Subject: [PATCH] =?UTF-8?q?cmd.c=20=C3=BCberarbeitet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/cmd.c | 725 ++++++++++++++++++----------------------------- 1 file changed, 276 insertions(+), 449 deletions(-) diff --git a/src/common/cmd.c b/src/common/cmd.c index f4b1ec74..7edb672e 100644 --- a/src/common/cmd.c +++ b/src/common/cmd.c @@ -1,23 +1,30 @@ /* -Copyright (C) 1997-2001 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// cmd.c -- Quake script command processing module + * Copyright (C) 1997-2001 Id Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * ======================================================================= + * + * This file implements the command processor. Every command which is + * send vie the command line at startup, via the console and via rcon is + * processed here and send to the apropriate subsystem. + * + * ======================================================================= + */ #include "qcommon.h" @@ -25,8 +32,7 @@ void Cmd_ForwardToServer (void); #define MAX_ALIAS_NAME 32 -typedef struct cmdalias_s -{ +typedef struct cmdalias_s { struct cmdalias_s *next; char name[MAX_ALIAS_NAME]; char *value; @@ -36,298 +42,227 @@ cmdalias_t *cmd_alias; qboolean cmd_wait; -#define ALIAS_LOOP_COUNT 16 -int alias_count; // for detecting runaway loops - - -//============================================================================= +#define ALIAS_LOOP_COUNT 16 +int alias_count; /* for detecting runaway loops */ /* -============ -Cmd_Wait_f - -Causes execution of the remainder of the command buffer to be delayed until -next frame. This allows commands like: -bind g "impulse 5 ; +attack ; wait ; -attack ; impulse 2" -============ -*/ -void Cmd_Wait_f (void) -{ + * Causes execution of the remainder of the command buffer to be delayed + * until next frame. This allows commands like: bind g "impulse 5 ; + * +attack ; wait ; -attack ; impulse 2" + */ +void Cmd_Wait_f (void) { cmd_wait = true; } - -/* -============================================================================= - - COMMAND BUFFER - -============================================================================= -*/ +/* COMMAND BUFFER */ sizebuf_t cmd_text; byte cmd_text_buf[8192]; char defer_text_buf[8192]; -/* -============ -Cbuf_Init -============ -*/ -void Cbuf_Init (void) -{ +void Cbuf_Init (void) { SZ_Init (&cmd_text, cmd_text_buf, sizeof(cmd_text_buf)); } /* -============ -Cbuf_AddText - -Adds command text at the end of the buffer -============ -*/ -void Cbuf_AddText (char *text) -{ + * Adds command text at the end of the buffer + */ +void Cbuf_AddText (char *text) { int l; - + l = strlen (text); - if (cmd_text.cursize + l >= cmd_text.maxsize) - { + if (cmd_text.cursize + l >= cmd_text.maxsize) { Com_Printf ("Cbuf_AddText: overflow\n"); return; } + SZ_Write (&cmd_text, text, strlen (text)); } - /* -============ -Cbuf_InsertText - -Adds command text immediately after the current command -Adds a \n to the text -FIXME: actually change the command buffer to do less copying -============ -*/ -void Cbuf_InsertText (char *text) -{ + * Adds command text immediately after the current command + * Adds a \n to the text + */ +void Cbuf_InsertText (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) - { + + if (templen) { temp = Z_Malloc (templen); memcpy (temp, cmd_text.data, templen); SZ_Clear (&cmd_text); - } - else - temp = NULL; // shut up compiler - - // add the entire text of the file + + } else + temp = NULL; + + /* add the entire text of the file */ Cbuf_AddText (text); - - // add the copied off data - if (templen) - { + + /* add the copied off data */ + if (templen) { SZ_Write (&cmd_text, temp, templen); Z_Free (temp); } } - -/* -============ -Cbuf_CopyToDefer -============ -*/ -void Cbuf_CopyToDefer (void) -{ +void Cbuf_CopyToDefer (void) { memcpy(defer_text_buf, cmd_text_buf, cmd_text.cursize); defer_text_buf[cmd_text.cursize] = 0; cmd_text.cursize = 0; } -/* -============ -Cbuf_InsertFromDefer -============ -*/ -void Cbuf_InsertFromDefer (void) -{ +void Cbuf_InsertFromDefer (void) { Cbuf_InsertText (defer_text_buf); defer_text_buf[0] = 0; } - -/* -============ -Cbuf_ExecuteText -============ -*/ -void Cbuf_ExecuteText (int exec_when, 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"); +void Cbuf_ExecuteText (int exec_when, 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) -{ +void Cbuf_Execute (void) { int i; char *text; char line[1024]; int quotes; - alias_count = 0; // don't allow infinite alias loops + alias_count = 0; /* don't allow infinite alias loops */ - while (cmd_text.cursize) - { - // find a \n or ; line break + while (cmd_text.cursize) { + /* find a \n or ; line break */ text = (char *)cmd_text.data; quotes = 0; - for (i=0 ; i< cmd_text.cursize ; i++) - { + + 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 + break; /* don't break if inside a quoted string */ + if (text[i] == '\n') 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, alias) can insert data at the - // beginning of the text buffer + /* delete the text from the command buffer and move remaining + commands down this is necessary because commands (exec, + alias) can insert data at the beginning of the text buffer */ if (i == cmd_text.cursize) cmd_text.cursize = 0; - else - { + + else { i++; cmd_text.cursize -= i; memmove (text, text+i, cmd_text.cursize); } - // execute the command line + /* execute the command line */ Cmd_ExecuteString (line); - - if (cmd_wait) - { - // skip out while text still remains in buffer, leaving it - // for next frame + + if (cmd_wait) { + /* skip out while text still remains in buffer, + leaving it for next frame */ cmd_wait = false; break; } } } - /* -=============== -Cbuf_AddEarlyCommands - -Adds command line parameters as script statements -Commands lead with a +, and continue until another + - -Set commands are added early, so they are guaranteed to be set before -the client and server initialize for the first time. - -Other commands are added late, after all initialization is complete. -=============== -*/ -void Cbuf_AddEarlyCommands (qboolean clear) -{ + * Adds command line parameters as script statements Commands lead with + * a +, and continue until another + + * + * Set commands are added early, so they are guaranteed to be set before + * the client and server initialize for the first time. + * + * Other commands are added late, after all initialization is complete. + */ +void Cbuf_AddEarlyCommands (qboolean clear) { int i; char *s; - for (i=0 ; i : execute a script file\n"); return; } len = FS_LoadFile (Cmd_Argv(1), (void **)&f); - if (!f) - { + + if (!f) { Com_Printf ("couldn't exec %s\n",Cmd_Argv(1)); return; } + Com_Printf ("execing %s\n",Cmd_Argv(1)); - - // the file doesn't have a trailing 0, so we need to copy it off + + /* the file doesn't have a trailing 0, so we need to copy it off */ f2 = Z_Malloc(len+1); memcpy (f2, f, len); f2[len] = 0; @@ -398,149 +320,110 @@ void Cmd_Exec_f (void) FS_FreeFile (f); } - /* -=============== -Cmd_Echo_f - -Just prints the rest of the line to the console -=============== -*/ -void Cmd_Echo_f (void) -{ + * Just prints the rest of the line to the console + */ +void Cmd_Echo_f (void) { int i; - + for (i=1 ; inext) Com_Printf ("%s : %s\n", a->name, a->value); + return; } s = Cmd_Argv(1); - if (strlen(s) >= MAX_ALIAS_NAME) - { + + if (strlen(s) >= MAX_ALIAS_NAME) { Com_Printf ("Alias name is too long\n"); return; } - // if the alias already exists, reuse it - for (a = cmd_alias ; a ; a=a->next) - { - if (!strcmp(s, a->name)) - { + /* if the alias already exists, reuse it */ + for (a = cmd_alias ; a ; a=a->next) { + if (!strcmp(s, a->name)) { Z_Free (a->value); break; } } - if (!a) - { + if (!a) { a = Z_Malloc (sizeof(cmdalias_t)); a->next = cmd_alias; cmd_alias = a; } - strcpy (a->name, s); - // copy the rest of the command line - cmd[0] = 0; // start out with a null string + strcpy (a->name, s); + + /* 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++) - { + + for (i=2 ; i< c ; i++) { strcat (cmd, Cmd_Argv(i)); + if (i != (c - 1)) strcat (cmd, " "); } + strcat (cmd, "\n"); - + a->value = CopyString (cmd); } -/* -============================================================================= +/* COMMAND EXECUTION */ - COMMAND EXECUTION - -============================================================================= -*/ - -typedef struct cmd_function_s -{ +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]; +static char *cmd_null_string = ""; +static char cmd_args[MAX_STRING_CHARS]; -static int cmd_argc; -static char *cmd_argv[MAX_STRING_TOKENS]; -static char *cmd_null_string = ""; -static char cmd_args[MAX_STRING_CHARS]; +static cmd_function_t *cmd_functions; /* possible commands to execute */ -static cmd_function_t *cmd_functions; // possible commands to execute - -/* -============ -Cmd_Argc -============ -*/ -int Cmd_Argc (void) -{ +int Cmd_Argc (void) { return cmd_argc; } -/* -============ -Cmd_Argv -============ -*/ -char *Cmd_Argv (int arg) -{ +char *Cmd_Argv (int arg) { if ( (unsigned)arg >= cmd_argc ) return cmd_null_string; - return cmd_argv[arg]; + + return cmd_argv[arg]; } /* -============ -Cmd_Args - -Returns a single string containing argv(1) to argv(argc()-1) -============ -*/ -char *Cmd_Args (void) -{ + * Returns a single string containing argv(1) to argv(argc()-1) + */ +char *Cmd_Args (void) { return cmd_args; } - -/* -====================== -Cmd_MacroExpandString -====================== -*/ -char *Cmd_MacroExpandString (char *text) -{ +char *Cmd_MacroExpandString (char *text) { int i, j, count, len; qboolean inquote; char *scan; @@ -552,34 +435,37 @@ char *Cmd_MacroExpandString (char *text) scan = text; len = strlen (scan); - if (len >= MAX_STRING_CHARS) - { + + if (len >= MAX_STRING_CHARS) { Com_Printf ("Line exceeded %i chars, discarded.\n", MAX_STRING_CHARS); return NULL; } count = 0; - for (i=0 ; i= MAX_STRING_CHARS) - { + + if (len >= MAX_STRING_CHARS) { Com_Printf ("Expanded line exceeded %i chars, discarded.\n", MAX_STRING_CHARS); return NULL; } @@ -592,15 +478,13 @@ char *Cmd_MacroExpandString (char *text) scan = expanded; i--; - if (++count == 100) - { + if (++count == 100) { Com_Printf ("Macro expansion loop, discarded.\n"); return NULL; } } - if (inquote) - { + if (inquote) { Com_Printf ("Line has unmatched quote, discarded.\n"); return NULL; } @@ -608,43 +492,36 @@ char *Cmd_MacroExpandString (char *text) return scan; } - /* -============ -Cmd_TokenizeString - -Parses the given string into command line tokens. -$Cvars will be expanded unless they are in a quoted token -============ -*/ -void Cmd_TokenizeString (char *text, qboolean macroExpand) -{ + * Parses the given string into command line tokens. + * $Cvars will be expanded unless they are in a quoted token + */ +void Cmd_TokenizeString (char *text, qboolean macroExpand) { int i; const char *com_token; - // clear the args from the last string + /* clear the args from the last string */ for (i=0 ; i= 0 ; l--) if (cmd_args[l] <= ' ') cmd_args[l] = 0; + else break; } - + com_token = COM_Parse (&text); + if (!text) return; - if (cmd_argc < MAX_STRING_TOKENS) - { + if (cmd_argc < MAX_STRING_TOKENS) { cmd_argv[cmd_argc] = Z_Malloc (strlen(com_token)+1); strcpy (cmd_argv[cmd_argc], com_token); cmd_argc++; } } - + } - -/* -============ -Cmd_AddCommand -============ -*/ -void Cmd_AddCommand (char *cmd_name, xcommand_t function) -{ +void Cmd_AddCommand (char *cmd_name, xcommand_t function) { cmd_function_t *cmd; - - // fail if the command is a variable name - if (Cvar_VariableString(cmd_name)[0]) - { + + /* fail if the command is a variable name */ + if (Cvar_VariableString(cmd_name)[0]) { Cmd_RemoveCommand (cmd_name); } - - // fail if the command already exists - for (cmd=cmd_functions ; cmd ; cmd=cmd->next) - { - if (!strcmp (cmd_name, cmd->name)) - { + + /* fail if the command already exists */ + for (cmd=cmd_functions ; cmd ; cmd=cmd->next) { + if (!strcmp (cmd_name, cmd->name)) { Com_Printf ("Cmd_AddCommand: %s already defined\n", cmd_name); return; } @@ -715,45 +583,33 @@ void Cmd_AddCommand (char *cmd_name, xcommand_t function) cmd_functions = cmd; } -/* -============ -Cmd_RemoveCommand -============ -*/ -void Cmd_RemoveCommand (char *cmd_name) -{ +void Cmd_RemoveCommand (char *cmd_name) { cmd_function_t *cmd, **back; back = &cmd_functions; - while (1) - { + + while (1) { cmd = *back; - if (!cmd) - { + + if (!cmd) { Com_Printf ("Cmd_RemoveCommand: %s not added\n", cmd_name); return; } - if (!strcmp (cmd_name, cmd->name)) - { + + if (!strcmp (cmd_name, cmd->name)) { *back = cmd->next; Z_Free (cmd); return; } + back = &cmd->next; } } -/* -============ -Cmd_Exists -============ -*/ -qboolean Cmd_Exists (char *cmd_name) -{ +qboolean Cmd_Exists (char *cmd_name) { cmd_function_t *cmd; - for (cmd=cmd_functions ; cmd ; cmd=cmd->next) - { + for (cmd=cmd_functions ; cmd ; cmd=cmd->next) { if (!strcmp (cmd_name,cmd->name)) return true; } @@ -761,36 +617,30 @@ qboolean Cmd_Exists (char *cmd_name) return false; } - - -/* -============ -Cmd_CompleteCommand -============ -*/ -char *Cmd_CompleteCommand (char *partial) -{ +char *Cmd_CompleteCommand (char *partial) { cmd_function_t *cmd; int len; cmdalias_t *a; - + len = strlen(partial); - + if (!len) return NULL; - - // check for exact match + + /* check for exact match */ for (cmd=cmd_functions ; cmd ; cmd=cmd->next) if (!strcmp (partial,cmd->name)) return cmd->name; + for (a=cmd_alias ; a ; a=a->next) if (!strcmp (partial, a->name)) return a->name; - // check for partial match + /* check for partial match */ for (cmd=cmd_functions ; cmd ; cmd=cmd->next) if (!strncmp (partial,cmd->name, len)) return cmd->name; + for (a=cmd_alias ; a ; a=a->next) if (!strncmp (partial, a->name, len)) return a->name; @@ -798,96 +648,73 @@ char *Cmd_CompleteCommand (char *partial) return NULL; } - /* -============ -Cmd_ExecuteString - -A complete command line has been parsed, so try to execute it -FIXME: lookupnoadd the token to speed search? -============ -*/ -void Cmd_ExecuteString (char *text) -{ + * A complete command line has been parsed, so try to execute it + */ +void Cmd_ExecuteString (char *text) { cmd_function_t *cmd; cmdalias_t *a; Cmd_TokenizeString (text, true); - - // execute the command line - if (!Cmd_Argc()) - return; // no tokens - // check functions - for (cmd=cmd_functions ; cmd ; cmd=cmd->next) - { - if (!Q_strcasecmp (cmd_argv[0],cmd->name)) - { - if (!cmd->function) - { // forward to server command + /* execute the command line */ + if (!Cmd_Argc()) + return; /* no tokens */ + + /* check functions */ + for (cmd=cmd_functions ; cmd ; cmd=cmd->next) { + if (!Q_strcasecmp (cmd_argv[0],cmd->name)) { + if (!cmd->function) { + /* forward to server command */ Cmd_ExecuteString (va("cmd %s", text)); - } - else + + } else cmd->function (); + return; } } - // check alias - for (a=cmd_alias ; a ; a=a->next) - { - if (!Q_strcasecmp (cmd_argv[0], a->name)) - { - if (++alias_count == ALIAS_LOOP_COUNT) - { + /* check alias */ + for (a=cmd_alias ; a ; a=a->next) { + if (!Q_strcasecmp (cmd_argv[0], a->name)) { + if (++alias_count == ALIAS_LOOP_COUNT) { Com_Printf ("ALIAS_LOOP_COUNT\n"); return; } + Cbuf_InsertText (a->value); return; } } - - // check cvars + + /* check cvars */ if (Cvar_Command ()) return; - // send it as a server command if we are connected #ifndef DEDICATED_ONLY + /* send it as a server command if we are connected */ Cmd_ForwardToServer (); #endif } -/* -============ -Cmd_List_f -============ -*/ -void Cmd_List_f (void) -{ - cmd_function_t *cmd; - int i; +void Cmd_List_f (void) { + cmd_function_t *cmd; + int i; i = 0; + for (cmd=cmd_functions ; cmd ; cmd=cmd->next, i++) Com_Printf ("%s\n", cmd->name); + Com_Printf ("%i commands\n", i); } -/* -============ -Cmd_Init -============ -*/ -void Cmd_Init (void) -{ - // - // register our commands - // +void Cmd_Init (void) { + /* register our commands */ Cmd_AddCommand ("cmdlist",Cmd_List_f); Cmd_AddCommand ("exec",Cmd_Exec_f); Cmd_AddCommand ("echo",Cmd_Echo_f); Cmd_AddCommand ("alias",Cmd_Alias_f); Cmd_AddCommand ("wait", Cmd_Wait_f); } -