]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cmd.c
huge audit of dprints throughout engine, all notices of successfully
[xonotic/darkplaces.git] / cmd.c
diff --git a/cmd.c b/cmd.c
index d94857655984e47d91cd23c2fe2c0b295c13edff..c085aa8856c846bd6b4b34b849b1a03d29591d4f 100644 (file)
--- a/cmd.c
+++ b/cmd.c
@@ -24,11 +24,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #define        MAX_ALIAS_NAME  32
 // this is the largest script file that can be executed in one step
 // LordHavoc: inreased this from 8192 to 32768
-#define CMDBUFSIZE 32768
+// div0: increased this from 32k to 128k
+#define CMDBUFSIZE 131072
 // maximum number of parameters to a command
 #define        MAX_ARGS 80
 // maximum tokenizable commandline length (counting NUL terminations)
-#define CMD_TOKENIZELENGTH (MAX_INPUTLINE + 80)
+#define CMD_TOKENIZELENGTH (MAX_INPUTLINE + MAX_ARGS)
 
 typedef struct cmdalias_s
 {
@@ -181,7 +182,7 @@ void Cbuf_Execute (void)
                {
                        i++;
                        cmd_text.cursize -= i;
-                       memcpy (cmd_text.data, text+i, cmd_text.cursize);
+                       memmove (cmd_text.data, text+i, cmd_text.cursize);
                }
 
 // execute the command line
@@ -305,7 +306,7 @@ static void Cmd_Exec_f (void)
                Con_Printf("couldn't exec %s\n",Cmd_Argv(1));
                return;
        }
-       Con_DPrintf("execing %s\n",Cmd_Argv(1));
+       Con_Printf("execing %s\n",Cmd_Argv(1));
 
        // if executing default.cfg for the first time, lock the cvar defaults
        // it may seem backwards to insert this text BEFORE the default.cfg
@@ -518,19 +519,49 @@ cmd_source_t cmd_source;
 
 static cmd_function_t *cmd_functions;          // possible commands to execute
 
-static const char *Cmd_GetDirectCvarValue(const char *varname, cmdalias_t *alias)
+static const char *Cmd_GetDirectCvarValue(const char *varname, cmdalias_t *alias, qboolean *is_multiple)
 {
        cvar_t *cvar;
        long argno;
        char *endptr;
 
+       if(is_multiple)
+               *is_multiple = false;
+
        if(!varname || !*varname)
                return NULL;
 
        if(alias)
        {
                if(!strcmp(varname, "*"))
+               {
+                       if(is_multiple)
+                               *is_multiple = true;
                        return Cmd_Args();
+               }
+               else if(varname[strlen(varname) - 1] == '-')
+               {
+                       argno = strtol(varname, &endptr, 10);
+                       if(endptr == varname + strlen(varname) - 1)
+                       {
+                               // whole string is a number, apart from the -
+                               const char *p = Cmd_Args();
+                               for(; argno > 1; --argno)
+                                       if(!COM_ParseToken_Console(&p))
+                                               break;
+                               if(p)
+                               {
+                                       if(is_multiple)
+                                               *is_multiple = true;
+
+                                       // kill pre-argument whitespace
+                                       for (;*p && *p <= ' ';p++)
+                                               ;
+
+                                       return p;
+                               }
+                       }
+               }
                else
                {
                        argno = strtol(varname, &endptr, 10);
@@ -550,11 +581,63 @@ static const char *Cmd_GetDirectCvarValue(const char *varname, cmdalias_t *alias
        return NULL;
 }
 
+qboolean Cmd_QuoteString(char *out, size_t outlen, const char *in, const char *quoteset)
+{
+       qboolean quote_quot = !!strchr(quoteset, '"');
+       qboolean quote_backslash = !!strchr(quoteset, '\\');
+       qboolean quote_dollar = !!strchr(quoteset, '$');
+
+       while(*in)
+       {
+               if(*in == '"' && quote_quot)
+               {
+                       if(outlen <= 2)
+                       {
+                               *out++ = 0;
+                               return false;
+                       }
+                       *out++ = '\\'; --outlen;
+                       *out++ = '"'; --outlen;
+               }
+               else if(*in == '\\' && quote_backslash)
+               {
+                       if(outlen <= 2)
+                       {
+                               *out++ = 0;
+                               return false;
+                       }
+                       *out++ = '\\'; --outlen;
+                       *out++ = '\\'; --outlen;
+               }
+               else if(*in == '$' && quote_dollar)
+               {
+                       if(outlen <= 2)
+                       {
+                               *out++ = 0;
+                               return false;
+                       }
+                       *out++ = '$'; --outlen;
+                       *out++ = '$'; --outlen;
+               }
+               else
+               {
+                       if(outlen <= 1)
+                       {
+                               *out++ = 0;
+                               return false;
+                       }
+                       *out++ = *in; --outlen;
+               }
+               ++in;
+       }
+       *out++ = 0;
+       return true;
+}
+
 static const char *Cmd_GetCvarValue(const char *var, size_t varlen, cmdalias_t *alias)
 {
        static char varname[MAX_INPUTLINE];
        static char varval[MAX_INPUTLINE];
-       char *p;
        const char *varstr;
        char *varfunc;
 
@@ -578,14 +661,16 @@ static const char *Cmd_GetCvarValue(const char *var, size_t varlen, cmdalias_t *
 
        varstr = NULL;
 
-       // Exception: $* doesn't use the quoted form by default
-       if(!strcmp(varname, "*"))
-               varfunc = "asis";
-
        if(varname[0] == '$')
-               varstr = Cmd_GetDirectCvarValue(Cmd_GetDirectCvarValue(varname + 1, alias), alias);
+               varstr = Cmd_GetDirectCvarValue(Cmd_GetDirectCvarValue(varname + 1, alias, NULL), alias, NULL);
        else
-               varstr = Cmd_GetDirectCvarValue(varname, alias);
+       {
+               qboolean is_multiple = false;
+               // Exception: $* and $n- don't use the quoted form by default
+               varstr = Cmd_GetDirectCvarValue(varname, alias, &is_multiple);
+               if(is_multiple)
+                       varfunc = "asis";
+       }
 
        if(!varstr)
        {
@@ -599,34 +684,8 @@ static const char *Cmd_GetCvarValue(const char *var, size_t varlen, cmdalias_t *
        if(!varfunc || !strcmp(varfunc, "q")) // note: quoted form is default, use "asis" to override!
        {
                // quote it so it can be used inside double quotes
-               // we just need to replace " by \"
-               p = varval;
-               while(*varstr)
-               {
-                       if(*varstr == '"')
-                       {
-                               if(p - varval >= (ssize_t)(sizeof(varval) - 2))
-                                       break;
-                               *p++ = '\\';
-                               *p++ = '"';
-                       }
-                       else if(*varstr == '\\')
-                       {
-                               if(p - varval >= (ssize_t)(sizeof(varval) - 2))
-                                       break;
-                               *p++ = '\\';
-                               *p++ = '\\';
-                       }
-                       else
-                       {
-                               if(p - varval >= (ssize_t)(sizeof(varval) - 1))
-                                       break;
-                               *p++ = *varstr;
-                       }
-                       ++varstr;
-               }
-               *p++ = 0;
-               //Con_Printf("quoted form: %s\n", varval);
+               // we just need to replace " by \", and of course, double backslashes
+               Cmd_QuoteString(varval, sizeof(varval), varstr, "\"\\");
                return varval;
        }
        else if(!strcmp(varfunc, "asis"))
@@ -681,7 +740,8 @@ static void Cmd_PreprocessString( const char *intext, char *outtext, unsigned ma
                        //   alias parameter, where the name of the alias is $0, the first
                        //   parameter is $1 and so on; as a special case, $* inserts all
                        //   parameters, without extra quoting, so one can use $* to just
-                       //   pass all parameters around
+                       //   pass all parameters around. All parameters starting from $n
+                       //   can be referred to as $n- (so $* is equivalent to $1-).
                        //
                        // Note: when expanding an alias, cvar expansion is done in the SAME step
                        // as alias expansion so that alias parameters or cvar values containing
@@ -727,7 +787,7 @@ static void Cmd_PreprocessString( const char *intext, char *outtext, unsigned ma
                                        eat = varlen + 1;
                                }
                        } else {
-                               varlen = strspn(in, "*0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_");
+                               varlen = strspn(in, "*0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-");
                                val = Cmd_GetCvarValue(in, varlen, alias);
                                eat = varlen;
                        }
@@ -766,8 +826,6 @@ static void Cmd_ExecuteAlias (cmdalias_t *alias)
 {
        static char buffer[ MAX_INPUTLINE + 2 ];
        static char buffer2[ MAX_INPUTLINE * 2 + 2 ];
-       char *q;
-       const char *p;
        Cmd_PreprocessString( alias->value, buffer, sizeof(buffer) - 2, alias );
        // insert at start of command buffer, so that aliases execute in order
        // (fixes bug introduced by Black on 20050705)
@@ -775,14 +833,7 @@ static void Cmd_ExecuteAlias (cmdalias_t *alias)
        // Note: Cbuf_PreprocessString will be called on this string AGAIN! So we
        // have to make sure that no second variable expansion takes place, otherwise
        // alias parameters containing dollar signs can have bad effects.
-       for(p = buffer, q = buffer2; *p; )
-       {
-               if(*p == '$')
-                       *q++ = '$';
-               *q++ = *p++;
-       }
-       *q++ = 0;
-
+       Cmd_QuoteString(buffer2, sizeof(buffer2), buffer, "$");
        Cbuf_InsertText( buffer2 );
 }