]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cmd.c
changed DNS name cache expiration time to 12 hours
[xonotic/darkplaces.git] / cmd.c
diff --git a/cmd.c b/cmd.c
index 2626069c840ff27870a6b38f32dea714f3e13cc1..47892f9afb2e9e07a17e049a2a9b8b6a484a7256 100644 (file)
--- a/cmd.c
+++ b/cmd.c
@@ -132,11 +132,14 @@ void Cbuf_InsertText (const char *text)
 Cbuf_Execute
 ============
 */
+static void Cmd_PreprocessString( const char *intext, char *outtext, unsigned maxoutlen, cmdalias_t *alias );
 void Cbuf_Execute (void)
 {
+#define EXECUTESTRING_BUFFER 2048
        int i;
        char *text;
        char line[1024];
+       char preprocessed[EXECUTESTRING_BUFFER];
        int quotes;
 
        // LordHavoc: making sure the tokenizebuffer doesn't get filled up by repeated crashes
@@ -175,7 +178,8 @@ void Cbuf_Execute (void)
                }
 
 // execute the command line
-               Cmd_ExecuteString (line, src_command);
+               Cmd_PreprocessString( line, preprocessed, EXECUTESTRING_BUFFER, NULL );
+               Cmd_ExecuteString (preprocessed, src_command);
 
                if (cmd_wait)
                {       // skip out while text still remains in buffer, leaving it
@@ -387,92 +391,110 @@ typedef struct cmd_function_s
 static int cmd_argc;
 static const char *cmd_argv[MAX_ARGS];
 static const char *cmd_null_string = "";
-static const char *cmd_args = NULL;
-
+static const char *cmd_args;
 cmd_source_t cmd_source;
 
 
 static cmd_function_t *cmd_functions;          // possible commands to execute
 
 /*
-============
-Cmd_ExecuteAlias
+Cmd_PreprocessString
 
-Called for aliases and fills in the alias into the cbuffer
-============
+Preprocesses strings and replaces $*, $param#, $cvar accordingly
 */
-static void Cmd_ExecuteAlias (cmdalias_t *alias)
-{
-#define ALIAS_BUFFER 1024
-       static char buffer[ ALIAS_BUFFER + 2 ];
+static void Cmd_PreprocessString( const char *intext, char *outtext, unsigned maxoutlen, cmdalias_t *alias ) {
        const char *in;
-       char *out;
        unsigned outlen;
        int inquote;
 
-       in = alias->value;
-       out = buffer;
+       // don't crash if there's no room in the outtext buffer
+       if( maxoutlen == 0 ) {
+               return;
+       }
+       maxoutlen--; // because of \0
+
+       in = intext;
        outlen = 0;
        inquote = 0;
 
-       while( *in && outlen < ALIAS_BUFFER )
-       {
-               if( *in == '"' )
-               {
-                       inquote ^= 1;
-               }
-               else if( *in == '$' && !inquote )
-               {
-                       // $* is replaced with all formal parameters, $num is parsed as an argument (or as $num if there arent enough parameters), $bla becomes $bla and $$bla becomes $$bla
-                       // read over the $
+       while( *in && outlen < maxoutlen ) {
+               if( *in == '$' && !inquote ) {
+                       // this is some kind of expansion, see what comes after the $
                        in++;
-                       if( *in == '*' )
-                       {
+                       // replacements that can always be used:
+                       // $$ is replaced with $, to allow escaping $
+                       // $<cvarname> is replaced with the contents of the cvar
+                       //
+                       // the following can be used in aliases only:
+                       // $* is replaced with all formal parameters (including name of the alias - this probably is not desirable)
+                       // $0 is replaced with the name of this alias
+                       // $<number> is replaced with an argument to this alias (or copied as-is if no such parameter exists), can be multiple digits
+                       if( *in == '$' ) {
+                               outtext[outlen++] = *in++;
+                       } else if( *in == '*' && alias ) {
                                const char *linein = Cmd_Args();
                                // include all params
                                if (linein) {
-                                       while( *linein && outlen < ALIAS_BUFFER ) {
-                                               *out++ = *linein++;
-                                               outlen++;
+                                       while( *linein && outlen < maxoutlen ) {
+                                               outtext[outlen++] = *linein++;
                                        }
                                }
 
                                in++;
-                       } else {
+                       } else if( '0' <= *in && *in <= '9' && alias ) {
                                char *nexttoken;
                                int argnum;
 
                                argnum = strtol( in, &nexttoken, 10 );
 
-                               if( 0 < argnum && argnum < Cmd_Argc() )
-                               {
+                               if( 0 <= argnum && argnum < Cmd_Argc() ) {
                                        const char *param = Cmd_Argv( argnum );
-                                       while( *param && outlen < ALIAS_BUFFER ) {
-                                               *out++ = *param++;
-                                               outlen++;
+                                       while( *param && outlen < maxoutlen ) {
+                                               outtext[outlen++] = *param++;
                                        }
                                        in = nexttoken;
-                               }
-                               else if( argnum >= Cmd_Argc() )
-                               {
+                               } else if( argnum >= Cmd_Argc() ) {
                                        Con_Printf( "Warning: Not enough parameters passed to alias '%s', at least %i expected:\n    %s\n", alias->name, argnum, alias->value );
-                                       *out++ = '$';
-                                       outlen++;
+                                       outtext[outlen++] = '$';
                                }
-                               // not a number
-                               else if( argnum == 0 )
-                               {
-                                       *out++ = '$';
-                                       outlen++;
+                       } else {
+                               cvar_t *cvar;
+                               const char *tempin = in;
+
+                               COM_ParseTokenConsole( &tempin );
+                               if ((cvar = Cvar_FindVar(&com_token[0]))) {
+                                       const char *cvarcontent = cvar->string;
+                                       while( *cvarcontent && outlen < maxoutlen ) {
+                                               outtext[outlen++] = *cvarcontent++;
+                                       }
+                                       in = tempin;
+                               } else {
+                                       Con_Printf( "Warning: could not find cvar %s when expanding alias %s\n    %s\n", com_token, alias->name, alias->value );
+                                       outtext[outlen++] = '$';
                                }
                        }
                } else {
-                       *out++ = *in++;
-                       outlen++;
+                       if( *in == '"' ) {
+                               inquote ^= 1;
+                       }
+                       outtext[outlen++] = *in++;
                }
        }
-       *out++ = '\n';
-       *out++ = 0;
+       outtext[outlen] = 0;
+}
+
+/*
+============
+Cmd_ExecuteAlias
+
+Called for aliases and fills in the alias into the cbuffer
+============
+*/
+static void Cmd_ExecuteAlias (cmdalias_t *alias)
+{
+#define ALIAS_BUFFER 1024
+       static char buffer[ ALIAS_BUFFER + 2 ];
+       Cmd_PreprocessString( alias->value, buffer, ALIAS_BUFFER, alias );
        Cbuf_AddText( buffer );
 }
 
@@ -511,11 +533,10 @@ static void Cmd_List_f (void)
                count++;
        }
 
-       Con_Printf("%i Command%s", count, (count > 1) ? "s" : "");
        if (partial)
-               Con_Printf(" beginning with \"%s\"", partial);
-
-       Con_Print("\n\n");
+               Con_Printf("%i Command%s beginning with \"%s\"\n\n", count, (count > 1) ? "s" : "", partial);
+       else
+               Con_Printf("%i Command%s\n\n", count, (count > 1) ? "s" : "");
 }
 
 /*
@@ -600,6 +621,7 @@ Cmd_TokenizeString
 Parses the given string into command line tokens.
 ============
 */
+// AK: This function should only be called from ExcuteString because the current design is a bit of an hack
 static void Cmd_TokenizeString (const char *text)
 {
        int l;
@@ -619,7 +641,7 @@ static void Cmd_TokenizeString (const char *text)
                // Windows: \r\n
                if (*text == '\n' || *text == '\r')
                {
-                       // a newline seperates commands in the buffer
+                       // a newline separates commands in the buffer
                        if (*text == '\r' && text[1] == '\n')
                                text++;
                        text++;
@@ -630,34 +652,11 @@ static void Cmd_TokenizeString (const char *text)
                        return;
 
                if (cmd_argc == 1)
-                        cmd_args = text;
+                       cmd_args = text;
 
                if (!COM_ParseTokenConsole(&text))
                        return;
 
-               // check for $cvar
-               // (perhaps use another target buffer?)
-               if (com_token[0] == '$' && com_token[1])
-               {
-                       cvar_t *cvar;
-
-                       cvar = Cvar_FindVar(&com_token[1]);
-                       if (cvar)
-                       {
-                               strcpy(com_token, cvar->string);
-                       }
-                       else if( com_token[1] == '$' )
-                       {
-                               // remove the first $
-                               char *pos;
-
-                               for( pos = com_token ; *pos ; pos++ )
-                               {
-                                       *pos = *(pos + 1);
-                               }
-                       }
-               }
-
                if (cmd_argc < MAX_ARGS)
                {
                        l = (int)strlen(com_token) + 1;
@@ -916,6 +915,7 @@ void Cmd_ExecuteString (const char *text, cmd_source_t src)
 
        oldpos = cmd_tokenizebufferpos;
        cmd_source = src;
+
        Cmd_TokenizeString (text);
 
 // execute the command line