]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cmd.c
migrated a lot of error handling out of R_Shadow_RenderLighting and into the loading...
[xonotic/darkplaces.git] / cmd.c
diff --git a/cmd.c b/cmd.c
index 41c38794562dbf90b5ab7bfec9a135bb3dad0274..24ef95292c81079bb01fb00598620739bbcdbbf7 100644 (file)
--- a/cmd.c
+++ b/cmd.c
@@ -151,8 +151,8 @@ void Cbuf_Execute (void)
                for (i=0 ; i< cmd_text.cursize ; i++)
                {
                        if (text[i] == '"')
-                               quotes++;
-                       if ( !(quotes&1) &&  text[i] == ';')
+                               quotes ^= 1;
+                       if ( !quotes &&  text[i] == ';')
                                break;  // don't break if inside a quoted string
                        if (text[i] == '\r' || text[i] == '\n')
                                break;
@@ -394,6 +394,86 @@ cmd_source_t cmd_source;
 
 static cmd_function_t *cmd_functions;          // possible commands to execute
 
+/*
+============
+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 ];
+       const char *in;
+       char *out;
+       unsigned outlen;
+       int inquote;
+
+       in = alias->value;
+       out = buffer;
+       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 $
+                       in++;
+                       if( *in == '*' )
+                       {
+                               const char *linein = Cmd_Args();
+                               // include all params
+                               while( *linein && outlen < ALIAS_BUFFER ) {
+                                       *out++ = *linein++;
+                                       outlen++;
+                               }
+
+                               in++;
+                       } else {
+                               char *nexttoken;
+                               int argnum;
+
+                               argnum = strtol( in, &nexttoken, 10 );
+
+                               if( 0 < argnum && argnum < Cmd_Argc() )
+                               {
+                                       const char *param = Cmd_Argv( argnum );
+                                       while( *param && outlen < ALIAS_BUFFER ) {
+                                               *out++ = *param++;
+                                               outlen++;
+                                       }
+                                       in = nexttoken;
+                               }
+                               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++;
+                               }
+                               // not a number
+                               else if( argnum == 0 )
+                               {
+                                       *out++ = '$';
+                                       outlen++;
+                               }
+                       }
+               } else {
+                       *out++ = *in++;
+                       outlen++;
+               }
+       }
+       *out++ = '\n';
+       *out++ = 0;
+       Cbuf_AddText( buffer );
+}
+
 /*
 ========
 Cmd_List
@@ -553,6 +633,29 @@ static void Cmd_TokenizeString (const char *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;
@@ -581,7 +684,7 @@ void Cmd_AddCommand (const char *cmd_name, xcommand_t function)
        cmd_function_t *prev, *current;
 
 // fail if the command is a variable name
-       if (Cvar_VariableString(cmd_name)[0])
+       if (Cvar_FindVar( cmd_name ))
        {
                Con_Printf("Cmd_AddCommand: %s already defined as a var\n", cmd_name);
                return;
@@ -836,7 +939,7 @@ void Cmd_ExecuteString (const char *text, cmd_source_t src)
        {
                if (!strcasecmp (cmd_argv[0], a->name))
                {
-                       Cbuf_InsertText (a->value);
+                       Cmd_ExecuteAlias(a);
                        cmd_tokenizebufferpos = oldpos;
                        return;
                }
@@ -885,10 +988,19 @@ 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
+       if (!strcasecmp(Cmd_Argv(0), "cmd"))
+       {
+               // we want to strip off "cmd", so just send the args
                s = Cmd_Argc() > 1 ? Cmd_Args() : "";
+       }
+       else
+       {
+               // we need to keep the command name, so send Cmd_Argv(0), a space and then Cmd_Args()
+               s = va("%s %s", Cmd_Argv(0), Cmd_Argc() > 1 ? Cmd_Args() : "");
+       }
+       // don't send an empty forward message if the user tries "cmd" by itself
+       if (!s || !*s)
+               return;
        Cmd_ForwardStringToServer(s);
 }