]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cmd.c
changed most Sys_Error calls to Con_Printf with appropriate error returns
[xonotic/darkplaces.git] / cmd.c
diff --git a/cmd.c b/cmd.c
index 2e134d7885047530f1a227f5168ae765ed5c1281..0a6459743b36b8ad65f5d08ed62c749d29ddf5f0 100644 (file)
--- a/cmd.c
+++ b/cmd.c
@@ -64,19 +64,9 @@ static void Cmd_Wait_f (void)
 =============================================================================
 */
 
-static sizebuf_t       cmd_text;
-
-/*
-============
-Cbuf_Init
-============
-*/
-void Cbuf_Init (void)
-{
        // LordHavoc: inreased this from 8192 to 32768
-       SZ_Alloc (&cmd_text, 32768, "command buffer"); // space for commands and script files
-}
-
+static sizebuf_t       cmd_text;
+static qbyte           cmd_text_buf[32768];
 
 /*
 ============
@@ -214,11 +204,12 @@ quake +prog jctest.qp +cmd amlev1
 quake -nosound +cmd amlev1
 ===============
 */
+qboolean host_stuffcmdsrun = false;
 void Cmd_StuffCmds_f (void)
 {
-       int             i, j;
-       int             s;
-       char    *text, *build, c;
+       int             i, j, l;
+       // this is per command, and bounds checked (no buffer overflows)
+       char    build[2048];
 
        if (Cmd_Argc () != 1)
        {
@@ -226,56 +217,36 @@ void Cmd_StuffCmds_f (void)
                return;
        }
 
-// build the combined string to parse from
-       s = 0;
-       for (i=1 ; i<com_argc ; i++)
-       {
-               if (!com_argv[i])
-                       continue;               // NEXTSTEP nulls out -NXHost
-               s += strlen (com_argv[i]) + 1;
-       }
-       if (!s)
-               return;
-
-       text = Mem_Alloc (tempmempool, s + 1);
-       text[0] = 0;
-       for (i=1 ; i<com_argc ; i++)
-       {
-               if (!com_argv[i])
-                       continue;               // NEXTSTEP nulls out -NXHost
-               strcat (text,com_argv[i]);
-               if (i != com_argc-1)
-                       strcat (text, " ");
-       }
-
-       // pull out the commands
-       build = Mem_Alloc (tempmempool, s + 1);
-       build[0] = 0;
-
-       for (i=0 ; i<s-1 ; i++)
+       host_stuffcmdsrun = true;
+       for (i = 0;i < com_argc;i++)
        {
-               if (text[i] == '+')
+               if (com_argv[i] && com_argv[i][0] == '+' && (com_argv[i][1] < '0' || com_argv[i][1] > '9'))
                {
+                       l = 0;
+                       j = 1;
+                       while (com_argv[i][j])
+                               build[l++] = com_argv[i][j++];
                        i++;
-
-                       for (j=i ; (text[j] != '+') && (text[j] != '-') && (text[j] != 0) ; j++)
-                               ;
-
-                       c = text[j];
-                       text[j] = 0;
-
-                       strcat (build, text+i);
-                       strcat (build, "\n");
-                       text[j] = c;
-                       i = j-1;
+                       for (;i < com_argc;i++)
+                       {
+                               if (!com_argv[i])
+                                       continue;
+                               if ((com_argv[i][0] == '+' || com_argv[i][0] == '-') && (com_argv[i][1] < '0' || com_argv[i][1] > '9'))
+                                       break;
+                               if (l + strlen(com_argv[i]) + 5 > sizeof(build))
+                                       break;
+                               build[l++] = ' ';
+                               build[l++] = '\"';
+                               for (j = 0;com_argv[i][j];j++)
+                                       build[l++] = com_argv[i][j];
+                               build[l++] = '\"';
+                       }
+                       build[l++] = '\n';
+                       build[l++] = 0;
+                       Cbuf_InsertText (build);
+                       i--;
                }
        }
-
-       if (build[0])
-               Cbuf_InsertText (build);
-
-       Mem_Free (text);
-       Mem_Free (build);
 }
 
 
@@ -364,11 +335,21 @@ static void Cmd_Alias_f (void)
 
        if (!a)
        {
+               cmdalias_t *prev, *current;
+
                a = Z_Malloc (sizeof(cmdalias_t));
-               a->next = cmd_alias;
-               cmd_alias = a;
+               strlcpy (a->name, s, sizeof (a->name));
+               // insert it at the right alphanumeric position
+               for( prev = NULL, current = cmd_alias ; current && strcmp( current->name, a->name ) < 0 ; prev = current, current = current->next )
+                       ;
+               if( prev ) {
+                       prev->next = a;
+               } else {
+                       cmd_alias = a;
+               }
+               a->next = current;
        }
-       strlcpy (a->name, s, sizeof (a->name));
+
 
 // copy the rest of the command line
        cmd[0] = 0;             // start out with a null string
@@ -462,8 +443,15 @@ Cmd_Init
 */
 void Cmd_Init (void)
 {
-       cmd_mempool = Mem_AllocPool("commands");
+       cmd_mempool = Mem_AllocPool("commands", 0, NULL);
+       // space for commands and script files
+       cmd_text.data = cmd_text_buf;
+       cmd_text.maxsize = sizeof(cmd_text_buf);
+       cmd_text.cursize = 0;
+}
 
+void Cmd_Init_Commands (void)
+{
 //
 // register our commands
 //
@@ -476,6 +464,18 @@ void Cmd_Init (void)
        Cmd_AddCommand ("cmdlist", Cmd_List_f);         // Added/Modified by EvilTypeGuy eviltypeguy@qeradiant.com
        Cmd_AddCommand ("cvarlist", Cvar_List_f);       // 2000-01-09 CmdList, CvarList commands
                                                                                                // By Matthias "Maddes" Buecher
+       Cmd_AddCommand ("set", Cvar_Set_f);
+       Cmd_AddCommand ("seta", Cvar_SetA_f);
+}
+
+/*
+============
+Cmd_Shutdown
+============
+*/
+void Cmd_Shutdown(void)
+{
+       Mem_FreePool(&cmd_mempool);
 }
 
 /*
@@ -528,12 +528,18 @@ static void Cmd_TokenizeString (const char *text)
        while (1)
        {
                // skip whitespace up to a /n
-               while (*text && *text <= ' ' && *text != '\n')
+               while (*text && *text <= ' ' && *text != '\r' && *text != '\n')
                        text++;
 
-               if (*text == '\n')
+               // line endings:
+               // UNIX: \n
+               // Mac: \r
+               // Windows: \r\n
+               if (*text == '\n' || *text == '\r')
                {
                        // a newline seperates commands in the buffer
+                       if (*text == '\r' && text[1] == '\n')
+                               text++;
                        text++;
                        break;
                }
@@ -551,14 +557,16 @@ static void Cmd_TokenizeString (const char *text)
                {
                        l = strlen(com_token) + 1;
                        if (cmd_tokenizebufferpos + l > CMD_TOKENIZELENGTH)
-                               Sys_Error("Cmd_TokenizeString: ran out of %i character buffer space for command arguements\n", CMD_TOKENIZELENGTH);
+                       {
+                               Con_Printf("Cmd_TokenizeString: ran out of %i character buffer space for command arguements\n", CMD_TOKENIZELENGTH);
+                               break;
+                       }
                        strcpy (cmd_tokenizebuffer + cmd_tokenizebufferpos, com_token);
                        cmd_argv[cmd_argc] = cmd_tokenizebuffer + cmd_tokenizebufferpos;
                        cmd_tokenizebufferpos += l;
                        cmd_argc++;
                }
        }
-
 }
 
 
@@ -570,6 +578,7 @@ Cmd_AddCommand
 void Cmd_AddCommand (const char *cmd_name, xcommand_t function)
 {
        cmd_function_t *cmd;
+       cmd_function_t *prev, *current;
 
 // fail if the command is a variable name
        if (Cvar_VariableString(cmd_name)[0])
@@ -592,7 +601,16 @@ void Cmd_AddCommand (const char *cmd_name, xcommand_t function)
        cmd->name = cmd_name;
        cmd->function = function;
        cmd->next = cmd_functions;
-       cmd_functions = cmd;
+
+// insert it at the right alphanumeric position
+       for( prev = NULL, current = cmd_functions ; current && strcmp( current->name, cmd->name ) < 0 ; prev = current, current = current->next )
+               ;
+       if( prev ) {
+               prev->next = cmd;
+       } else {
+               cmd_functions = cmd;
+       }
+       cmd->next = current;
 }
 
 /*
@@ -801,36 +819,30 @@ void Cmd_ExecuteString (const char *text, cmd_source_t src)
                return;         // no tokens
        }
 
-// check functions (only after host_initialized)
-       if (host_initialized || !strcasecmp(cmd_argv[0], "exec"))
+// check functions
+       for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
        {
-               for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
+               if (!strcasecmp (cmd_argv[0],cmd->name))
                {
-                       if (!strcasecmp (cmd_argv[0],cmd->name))
-                       {
-                               cmd->function ();
-                               cmd_tokenizebufferpos = oldpos;
-                               return;
-                       }
+                       cmd->function ();
+                       cmd_tokenizebufferpos = oldpos;
+                       return;
                }
        }
 
-// check alias (only after host_initialized)
-       if (host_initialized)
+// check alias
+       for (a=cmd_alias ; a ; a=a->next)
        {
-               for (a=cmd_alias ; a ; a=a->next)
+               if (!strcasecmp (cmd_argv[0], a->name))
                {
-                       if (!strcasecmp (cmd_argv[0], a->name))
-                       {
-                               Cbuf_InsertText (a->value);
-                               cmd_tokenizebufferpos = oldpos;
-                               return;
-                       }
+                       Cbuf_InsertText (a->value);
+                       cmd_tokenizebufferpos = oldpos;
+                       return;
                }
        }
 
-// check cvars (always)
-       if (!Cvar_Command () && host_initialized)
+// check cvars
+       if (!Cvar_Command () && host_framecount > 0)
                Con_Printf("Unknown command \"%s\"\n", Cmd_Argv(0));
 
        cmd_tokenizebufferpos = oldpos;
@@ -839,17 +851,16 @@ void Cmd_ExecuteString (const char *text, cmd_source_t src)
 
 /*
 ===================
-Cmd_ForwardToServer
+Cmd_ForwardStringToServer
 
-Sends the entire command line over to the server
+Sends an entire command string over to the server, unprocessed
 ===================
 */
-void Cmd_ForwardToServer (void)
+void Cmd_ForwardStringToServer (const char *s)
 {
-       const char *s;
        if (cls.state != ca_connected)
        {
-               Con_Printf("Can't \"%s\", not connected\n", Cmd_Argv(0));
+               Con_Printf("Can't \"%s\", not connected\n", s);
                return;
        }
 
@@ -859,14 +870,27 @@ void Cmd_ForwardToServer (void)
        // LordHavoc: thanks to Fuh for bringing the pure evil of SZ_Print to my
        // attention, it has been eradicated from here, its only (former) use in
        // all of darkplaces.
-       if (strcasecmp(Cmd_Argv(0), "cmd") != 0)
-               s = va("%s %s", Cmd_Argv(0), Cmd_Argc() > 1 ? Cmd_Args() : "\n");
-       else
-               s = Cmd_Argc() > 1 ? Cmd_Args() : "\n";
        MSG_WriteByte(&cls.message, clc_stringcmd);
        SZ_Write(&cls.message, s, strlen(s) + 1);
 }
 
+/*
+===================
+Cmd_ForwardToServer
+
+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
+               s = Cmd_Argc() > 1 ? Cmd_Args() : "";
+       Cmd_ForwardStringToServer(s);
+}
+
 
 /*
 ================
@@ -882,7 +906,10 @@ int Cmd_CheckParm (const char *parm)
        int i;
 
        if (!parm)
-               Sys_Error ("Cmd_CheckParm: NULL");
+       {
+               Con_Printf ("Cmd_CheckParm: NULL");
+               return 0;
+       }
 
        for (i = 1; i < Cmd_Argc (); i++)
                if (!strcasecmp (parm, Cmd_Argv (i)))