command line and config file parsing ala OT

This commit is contained in:
Bill Currie 2000-05-21 09:49:25 +00:00
parent 6bb69779a4
commit ce25c13a65
4 changed files with 228 additions and 114 deletions

View file

@ -112,6 +112,9 @@ void Cmd_ForwardToServer (void);
void Cmd_StuffCmds_f (void); void Cmd_StuffCmds_f (void);
void Cbuf_Execute_Sets (void);
void Cmd_Exec_File (char *path);
extern char com_token[1024]; extern char com_token[1024];
char *COM_Parse (char *data); char *COM_Parse (char *data);

View file

@ -67,12 +67,15 @@
#endif #endif
#include "cl_slist.h" #include "cl_slist.h"
extern cvar_t *fs_basepath;
extern cvar_t *fs_sharepath;
// we need to declare some mouse variables here, because the menu system // we need to declare some mouse variables here, because the menu system
// references them even when on a unix system. // references them even when on a unix system.
qboolean noclip_anglehack; // remnant from old quake qboolean noclip_anglehack; // remnant from old quake
cvar_t *fs_globalcfg;
/* cvar_t rcon_password = {"rcon_password", "", false}; /* cvar_t rcon_password = {"rcon_password", "", false};
CVAR_FIXME */ CVAR_FIXME */
cvar_t *rcon_password; cvar_t *rcon_password;
@ -1683,7 +1686,8 @@ void Host_Init (quakeparms_t *parms)
host_parms = *parms; host_parms = *parms;
if (parms->memsize < MINIMUM_MEMORY) if (parms->memsize < MINIMUM_MEMORY)
Sys_Error ("Only %4.1f megs of memory reported, can't execute game", parms->memsize / (float)0x100000); Sys_Error ("Only %4.1f megs of memory reported, can't execute game",
parms->memsize / (float)0x100000);
Memory_Init (parms->membase, parms->memsize); Memory_Init (parms->membase, parms->memsize);
Cvar_Init (); Cvar_Init ();
@ -1692,13 +1696,37 @@ void Host_Init (quakeparms_t *parms)
Cbuf_Init (); Cbuf_Init ();
Cmd_Init (); Cmd_Init ();
cl_Cmd_Init (); cl_Cmd_Init ();
V_Init ();
// execute +set as early as possible
Cmd_StuffCmds_f ();
Cbuf_Execute_Sets ();
// execute the global configuration file if it exists
// would have been nice if Cmd_Exec_f could have been used, but it
// only reads from within the quake file system, and changing that is
// probably Not A Good Thing (tm).
fs_globalcfg = Cvar_Get("fs_globalcfg", FS_GLOBALCFG,
CVAR_ROM, "global configuration file");
Cmd_Exec_File (fs_globalcfg->string);
Cbuf_Execute_Sets ();
V_Init ();
CL_InitCvars (); CL_InitCvars ();
SCR_InitCvars (); SCR_InitCvars ();
VID_InitCvars (); VID_InitCvars ();
COM_Init (); COM_Init ();
// reparse the command line for + commands other than set
// (sets still done, but it doesn't matter)
Cmd_StuffCmds_f ();
Cbuf_Execute ();
// make these read-only
fs_basepath = Cvar_Get ("fs_basepath", fs_basepath->string, CVAR_ROM,
"the location of your game directories");
fs_sharepath = Cvar_Get ("fs_sharepath", fs_sharepath->string,
CVAR_ROM, "read-only game directories");
Host_FixupModelNames(); Host_FixupModelNames();
NET_Init (PORT_CLIENT); NET_Init (PORT_CLIENT);

View file

@ -1,7 +1,7 @@
/* /*
cmd.c cmd.c
(description) Quake script command processing module
Copyright (C) 1996-1997 Id Software, Inc. Copyright (C) 1996-1997 Id Software, Inc.
@ -41,6 +41,7 @@
#include "commdef.h" #include "commdef.h"
#include <string.h> #include <string.h>
#include <ctype.h>
void Cmd_ForwardToServer (void); void Cmd_ForwardToServer (void);
@ -57,10 +58,7 @@ cmdalias_t *cmd_alias;
qboolean cmd_wait; qboolean cmd_wait;
/* cvar_t cl_warncmd = {"cl_warncmd", "0"}; cvar_t *cl_warncmd;
CVAR_FIXME */
cvar_t *cl_warncmd;
//============================================================================= //=============================================================================
/* /*
@ -109,7 +107,7 @@ Adds command text at the end of the buffer
void Cbuf_AddText (char *text) void Cbuf_AddText (char *text)
{ {
int l; int l;
l = strlen (text); l = strlen (text);
if (cmd_text.cursize + l >= cmd_text.maxsize) if (cmd_text.cursize + l >= cmd_text.maxsize)
@ -145,7 +143,7 @@ void Cbuf_InsertText (char *text)
} }
else else
temp = NULL; // shut up compiler temp = NULL; // shut up compiler
// add the entire text of the file // add the entire text of the file
Cbuf_AddText (text); Cbuf_AddText (text);
SZ_Write (&cmd_text, "\n", 1); SZ_Write (&cmd_text, "\n", 1);
@ -157,54 +155,56 @@ void Cbuf_InsertText (char *text)
} }
} }
/* static void
============ extract_line(char *line)
Cbuf_Execute
============
*/
void Cbuf_Execute (void)
{ {
int i; int i;
char *text; char *text;
char line[1024]; int quotes;
int quotes;
while (cmd_text.cursize)
{
// find a \n or ; line break
text = (char *)cmd_text.data;
quotes = 0; // find a \n or ; line break
for (i=0 ; i< cmd_text.cursize ; i++) text = (char *)cmd_text.data;
{ quotes = 0;
if (text[i] == '"') for (i=0 ; i< cmd_text.cursize ; i++) {
quotes++; if (text[i] == '"')
if ( !(quotes&1) && text[i] == ';') quotes++;
break; // don't break if inside a quoted string if ( !(quotes&1) && text[i] == ';')
if (text[i] == '\n') break; // don't break if inside a quoted string
break; if (text[i] == '\n' || text[i] == '\r')
} 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
if (i == cmd_text.cursize) memcpy (line, text, i);
cmd_text.cursize = 0; line[i] = '\0';
else // delete the text from the command buffer and move remaining commands down
{ // this is necessary because commands (exec, alias) can insert data at the
i++; // beginning of the text buffer
cmd_text.cursize -= i;
memcpy (text, text+i, cmd_text.cursize);
}
// execute the command line if (i == cmd_text.cursize)
cmd_text.cursize = 0;
else {
i++;
cmd_text.cursize -= i;
memcpy (text, text+i, cmd_text.cursize);
}
}
/*
Cbuf_Execute
*/
void
Cbuf_Execute (void)
{
char line[1024] = {0};
while (cmd_text.cursize) {
extract_line (line);
// execute the command line
//Con_DPrintf("+%s\n",line),
Cmd_ExecuteString (line); Cmd_ExecuteString (line);
if (cmd_wait) if (cmd_wait)
{ // skip out while text still remains in buffer, leaving it { // skip out while text still remains in buffer, leaving it
// for next frame // for next frame
@ -213,6 +213,25 @@ void Cbuf_Execute (void)
} }
} }
} }
/*
Cbuf_Execute
*/
void
Cbuf_Execute_Sets (void)
{
char line[1024] = {0};
while (cmd_text.cursize) {
extract_line (line);
// execute the command line
if (strncmp(line,"set",3)==0
&& isspace((int) line[3]))
//Con_DPrintf("+%s\n",line),
Cmd_ExecuteString (line);
}
}
/* /*
============================================================================== ==============================================================================
@ -236,60 +255,74 @@ void Cmd_StuffCmds_f (void)
{ {
int i, j; int i, j;
int s; int s;
char *text, *build, c; char *build, c;
// build the combined string to parse from s = strlen (com_cmdline);
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) if (!s)
return; return;
text = Z_Malloc (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 // pull out the commands
build = Z_Malloc (s+1); build = Z_Malloc (s+1);
build[0] = 0; build[0] = 0;
for (i=0 ; i<s-1 ; i++) for (i=0 ; i<s-1 ; i++)
{ {
if (text[i] == '+') if (com_cmdline[i] == '+')
{ {
i++; i++;
for (j=i ; (text[j] != '+') && (text[j] != '-') && (text[j] != 0) ; j++) for (j=i ; ((com_cmdline[j] != '+')
&& (com_cmdline[j] != '-')
&& (com_cmdline[j] != 0)) ; j++)
; ;
c = text[j]; c = com_cmdline[j];
text[j] = 0; com_cmdline[j] = 0;
strcat (build, text+i); strcat (build, com_cmdline+i);
strcat (build, "\n"); strcat (build, "\n");
text[j] = c; com_cmdline[j] = c;
i = j-1; i = j-1;
} }
} }
//Con_Printf("[\n%s]\n",build);
if (build[0]) if (build[0])
Cbuf_InsertText (build); Cbuf_InsertText (build);
Z_Free (text);
Z_Free (build); Z_Free (build);
} }
/*
Cmd_Exec_File
*/
void
Cmd_Exec_File (char *path)
{
char *f;
int mark;
int len;
char base[32];
QFile *file;
if ((file = Qopen (path, "r")) != NULL) {
// extract the filename base name for hunk tag
COM_FileBase (path, base);
len = COM_filelength (file);
mark = Hunk_LowMark ();
f = (char *)Hunk_AllocName (len+1, base);
if (f) {
f[len] = 0;
Qread (file, f, len);
Qclose (file);
Cbuf_InsertText (f);
}
Hunk_FreeToLowMark (mark);
}
}
/* /*
=============== ===============
@ -315,11 +348,9 @@ void Cmd_Exec_f (void)
Con_Printf ("couldn't exec %s\n",Cmd_Argv(1)); Con_Printf ("couldn't exec %s\n",Cmd_Argv(1));
return; return;
} }
/* if (!Cvar_Command () && (cl_warncmd.value || developer.value))
CVAR_FIXME */
if (!Cvar_Command () && (cl_warncmd->value || developer->value)) if (!Cvar_Command () && (cl_warncmd->value || developer->value))
Con_Printf ("execing %s\n",Cmd_Argv(1)); Con_Printf ("execing %s\n",Cmd_Argv(1));
Cbuf_InsertText (f); Cbuf_InsertText (f);
Hunk_FreeToLowMark (mark); Hunk_FreeToLowMark (mark);
} }
@ -335,7 +366,7 @@ Just prints the rest of the line to the console
void Cmd_Echo_f (void) void Cmd_Echo_f (void)
{ {
int i; int i;
for (i=1 ; i<Cmd_Argc() ; i++) for (i=1 ; i<Cmd_Argc() ; i++)
Con_Printf ("%s ",Cmd_Argv(i)); Con_Printf ("%s ",Cmd_Argv(i));
Con_Printf ("\n"); Con_Printf ("\n");
@ -352,7 +383,7 @@ Creates a new command that executes a command string (possibly ; seperated)
char *CopyString (char *in) char *CopyString (char *in)
{ {
char *out; char *out;
out = Z_Malloc (strlen(in)+1); out = Z_Malloc (strlen(in)+1);
strcpy (out, in); strcpy (out, in);
return out; return out;
@ -396,7 +427,7 @@ void Cmd_Alias_f (void)
a->next = cmd_alias; a->next = cmd_alias;
cmd_alias = a; cmd_alias = a;
} }
strcpy (a->name, s); strcpy (a->name, s);
// copy the rest of the command line // copy the rest of the command line
cmd[0] = 0; // start out with a null string cmd[0] = 0; // start out with a null string
@ -408,10 +439,45 @@ void Cmd_Alias_f (void)
strcat (cmd, " "); strcat (cmd, " ");
} }
strcat (cmd, "\n"); strcat (cmd, "\n");
a->value = CopyString (cmd); a->value = CopyString (cmd);
} }
void Cmd_UnAlias_f (void)
{
cmdalias_t *a, *prev;
char *s;
if (Cmd_Argc() != 2)
{
Con_Printf ("unalias <alias>: erase an existing alias\n");
return;
}
s = Cmd_Argv(1);
if (strlen(s) >= MAX_ALIAS_NAME)
{
Con_Printf ("Alias name is too long\n");
return;
}
prev = cmd_alias;
for (a = cmd_alias ; a ; a = a->next)
{
if (!strcmp(s, a->name))
{
Z_Free (a->value);
prev->next = a->next;
if (a == cmd_alias)
cmd_alias = a->next;
Z_Free (a);
return;
}
prev = a;
}
Con_Printf ("Unknown alias \"%s\"\n", s);
}
/* /*
============================================================================= =============================================================================
@ -458,7 +524,7 @@ char *Cmd_Argv (int arg)
{ {
if ( arg >= cmd_argc ) if ( arg >= cmd_argc )
return cmd_null_string; return cmd_null_string;
return cmd_argv[arg]; return cmd_argv[arg];
} }
/* /*
@ -486,14 +552,14 @@ Parses the given string into command line tokens.
void Cmd_TokenizeString (char *text) void Cmd_TokenizeString (char *text)
{ {
int i; int i;
// clear the args from the last string // clear the args from the last string
for (i=0 ; i<cmd_argc ; i++) for (i=0 ; i<cmd_argc ; i++)
Z_Free (cmd_argv[i]); Z_Free (cmd_argv[i]);
cmd_argc = 0; cmd_argc = 0;
cmd_args = NULL; cmd_args = NULL;
while (1) while (1)
{ {
// skip whitespace up to a /n // skip whitespace up to a /n
@ -501,7 +567,7 @@ void Cmd_TokenizeString (char *text)
{ {
text++; text++;
} }
if (*text == '\n') if (*text == '\n')
{ // a newline seperates commands in the buffer { // a newline seperates commands in the buffer
text++; text++;
@ -510,10 +576,10 @@ void Cmd_TokenizeString (char *text)
if (!*text) if (!*text)
return; return;
if (cmd_argc == 1) if (cmd_argc == 1)
cmd_args = text; cmd_args = text;
text = COM_Parse (text); text = COM_Parse (text);
if (!text) if (!text)
return; return;
@ -525,7 +591,7 @@ void Cmd_TokenizeString (char *text)
cmd_argc++; cmd_argc++;
} }
} }
} }
@ -537,17 +603,17 @@ Cmd_AddCommand
void Cmd_AddCommand (char *cmd_name, xcommand_t function) void Cmd_AddCommand (char *cmd_name, xcommand_t function)
{ {
cmd_function_t *cmd; cmd_function_t *cmd;
if (host_initialized) // because hunk allocation would get stomped if (host_initialized) // because hunk allocation would get stomped
Sys_Error ("Cmd_AddCommand after host_initialized"); Sys_Error ("Cmd_AddCommand after host_initialized");
// fail if the command is a variable name // fail if the command is a variable name
if (Cvar_VariableString(cmd_name)[0]) if (Cvar_VariableString(cmd_name)[0])
{ {
Con_Printf ("Cmd_AddCommand: %s already defined as a var\n", cmd_name); Con_Printf ("Cmd_AddCommand: %s already defined as a var\n", cmd_name);
return; return;
} }
// fail if the command already exists // fail if the command already exists
for (cmd=cmd_functions ; cmd ; cmd=cmd->next) for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
{ {
@ -595,12 +661,12 @@ char *Cmd_CompleteCommand (char *partial)
cmd_function_t *cmd; cmd_function_t *cmd;
int len; int len;
cmdalias_t *a; cmdalias_t *a;
len = strlen(partial); len = strlen(partial);
if (!len) if (!len)
return NULL; return NULL;
// check for exact match // check for exact match
for (cmd=cmd_functions ; cmd ; cmd=cmd->next) for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
if (!strcmp (partial,cmd->name)) if (!strcmp (partial,cmd->name))
@ -628,13 +694,13 @@ A complete command line has been parsed, so try to execute it
FIXME: lookupnoadd the token to speed search? FIXME: lookupnoadd the token to speed search?
============ ============
*/ */
void Cmd_ExecuteString (char *text) void Cmd_ExecuteString (char *text)
{ {
cmd_function_t *cmd; cmd_function_t *cmd;
cmdalias_t *a; cmdalias_t *a;
Cmd_TokenizeString (text); Cmd_TokenizeString (text);
// execute the command line // execute the command line
if (!Cmd_Argc()) if (!Cmd_Argc())
return; // no tokens return; // no tokens
@ -652,6 +718,10 @@ void Cmd_ExecuteString (char *text)
} }
} }
// Tonik: check cvars
if (Cvar_Command())
return;
// check alias // check alias
for (a=cmd_alias ; a ; a=a->next) for (a=cmd_alias ; a ; a=a->next)
{ {
@ -662,12 +732,9 @@ void Cmd_ExecuteString (char *text)
} }
} }
// check cvars if (cl_warncmd->value || developer->value)
/* if (!Cvar_Command () && (cl_warncmd.value || developer.value))
CVAR_FIXME */
if (!Cvar_Command () && (cl_warncmd->value || developer->value))
Con_Printf ("Unknown command \"%s\"\n", Cmd_Argv(0)); Con_Printf ("Unknown command \"%s\"\n", Cmd_Argv(0));
} }
@ -683,14 +750,14 @@ where the given parameter apears, or 0 if not present
int Cmd_CheckParm (char *parm) int Cmd_CheckParm (char *parm)
{ {
int i; int i;
if (!parm) if (!parm)
Sys_Error ("Cmd_CheckParm: NULL"); Sys_Error ("Cmd_CheckParm: NULL");
for (i = 1; i < Cmd_Argc (); i++) for (i = 1; i < Cmd_Argc (); i++)
if (! strcasecmp (parm, Cmd_Argv (i))) if (! strcasecmp (parm, Cmd_Argv (i)))
return i; return i;
return 0; return 0;
} }
@ -721,6 +788,7 @@ void Cmd_Init (void)
Cmd_AddCommand ("exec",Cmd_Exec_f); Cmd_AddCommand ("exec",Cmd_Exec_f);
Cmd_AddCommand ("echo",Cmd_Echo_f); Cmd_AddCommand ("echo",Cmd_Echo_f);
Cmd_AddCommand ("alias",Cmd_Alias_f); Cmd_AddCommand ("alias",Cmd_Alias_f);
Cmd_AddCommand ("unalias",Cmd_UnAlias_f);
Cmd_AddCommand ("wait", Cmd_Wait_f); Cmd_AddCommand ("wait", Cmd_Wait_f);
Cmd_AddCommand ("cmdlist", Cmd_CmdList_f); Cmd_AddCommand ("cmdlist", Cmd_CmdList_f);
} }

View file

@ -59,6 +59,8 @@ netadr_t master_adr[MAX_MASTERS]; // address of group servers
client_t *host_client; // current client client_t *host_client; // current client
cvar_t *fs_globalcfg;
/* cvar_t sv_mintic = {"sv_mintic","0.03"}; // bound the size of the /* cvar_t sv_mintic = {"sv_mintic","0.03"}; // bound the size of the
CVAR_FIXME */ CVAR_FIXME */
cvar_t *sv_mintic; // bound the size of the cvar_t *sv_mintic; // bound the size of the
@ -1860,6 +1862,19 @@ void SV_Init (quakeparms_t *parms)
Cbuf_Init (); Cbuf_Init ();
Cmd_Init (); Cmd_Init ();
// execute +set as early as possible
Cmd_StuffCmds_f ();
Cbuf_Execute_Sets ();
// execute the global configuration file if it exists
// would have been nice if Cmd_Exec_f could have been used, but it
// only reads from within the quake file system, and changing that is
// probably Not A Good Thing (tm).
fs_globalcfg = Cvar_Get("fs_globalcfg", FS_GLOBALCFG,
CVAR_ROM, "global configuration file");
Cmd_Exec_File (fs_globalcfg->string);
Cbuf_Execute_Sets ();
COM_Init (); COM_Init ();
PR_Init (); PR_Init ();