mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-05 20:50:43 +00:00
219 lines
4.1 KiB
C
219 lines
4.1 KiB
C
#include "defs.h"
|
|
static int cmd_argc;
|
|
static char *cmd_argv[MAX_ARGS];
|
|
static char *cmd_null_string = "";
|
|
static char *cmd_args = NULL;
|
|
static cmd_function_t *cmd_functions; // possible commands to execute
|
|
int
|
|
Cmd_Argc (void)
|
|
{
|
|
return cmd_argc;
|
|
}
|
|
|
|
char *
|
|
Cmd_Argv (int arg)
|
|
{
|
|
if (arg >= cmd_argc)
|
|
return cmd_null_string;
|
|
return cmd_argv[arg];
|
|
}
|
|
|
|
void
|
|
Cmd_TokenizeString (char *text)
|
|
{
|
|
int i;
|
|
|
|
|
|
// clear the args from the last string
|
|
for (i = 0; i < cmd_argc; i++)
|
|
free (cmd_argv[i]);
|
|
cmd_argc = 0;
|
|
cmd_args = NULL;
|
|
while (1) {
|
|
|
|
// skip whitespace up to a /n
|
|
while (*text && *text <= ' ' && *text != '\n') {
|
|
text++;
|
|
}
|
|
if (*text == '\n') { // a newline seperates commands in the
|
|
// buffer
|
|
text++;
|
|
break;
|
|
}
|
|
if (!*text)
|
|
return;
|
|
if (cmd_argc == 1)
|
|
cmd_args = text;
|
|
text = COM_Parse (text);
|
|
if (!text)
|
|
return;
|
|
if (cmd_argc < MAX_ARGS) {
|
|
cmd_argv[cmd_argc] = (char *) malloc (strlen (com_token) + 1);
|
|
strcpy (cmd_argv[cmd_argc], com_token);
|
|
cmd_argc++;
|
|
}
|
|
}} void
|
|
Cmd_AddCommand (char *cmd_name, xcommand_t function)
|
|
{
|
|
cmd_function_t *cmd;
|
|
|
|
// fail if the command already exists
|
|
for (cmd = cmd_functions; cmd; cmd = cmd->next) {
|
|
if (!strcmp (cmd_name, cmd->name)) {
|
|
printf ("Cmd_AddCommand: %s already defined\n", cmd_name);
|
|
return;
|
|
}
|
|
}
|
|
cmd = (cmd_function_t *) malloc (sizeof (cmd_function_t));
|
|
cmd->name = cmd_name;
|
|
cmd->function = function;
|
|
cmd->next = cmd_functions;
|
|
cmd_functions = cmd;
|
|
}
|
|
|
|
void
|
|
Cmd_Init ()
|
|
{
|
|
Cmd_AddCommand ("quit", Cmd_Quit_f);
|
|
Cmd_AddCommand ("list", Cmd_ServerList_f);
|
|
Cmd_AddCommand ("filter", Cmd_Filter_f);
|
|
} void
|
|
Cmd_ExecuteString (char *text)
|
|
{
|
|
cmd_function_t *cmd;
|
|
|
|
Cmd_TokenizeString (text);
|
|
|
|
// execute the command line
|
|
if (!Cmd_Argc ())
|
|
return; // no tokens
|
|
|
|
// check functions
|
|
for (cmd = cmd_functions; cmd; cmd = cmd->next) {
|
|
if (!strcmp (cmd_argv[0], cmd->name)) {
|
|
if (cmd->function)
|
|
cmd->function ();
|
|
return;
|
|
}
|
|
}
|
|
printf ("Unknown command: %s\n", cmd_argv[0]);
|
|
}
|
|
|
|
void
|
|
Cbuf_Init (void)
|
|
{
|
|
cmd_text.data = cmd_text_buf;
|
|
cmd_text.maxsize = sizeof (cmd_text_buf);
|
|
}
|
|
|
|
void
|
|
Cbuf_AddText (char *text)
|
|
{
|
|
int l;
|
|
|
|
l = strlen (text);
|
|
if (cmd_text.cursize + l >= cmd_text.maxsize) {
|
|
printf ("Cbuf_AddText: overflow\n");
|
|
return;
|
|
}
|
|
SZ_Write (&cmd_text, text, strlen (text));
|
|
}
|
|
|
|
void
|
|
Cbuf_InsertText (char *text)
|
|
{
|
|
char *temp;
|
|
int templen;
|
|
|
|
|
|
// copy off any commands still remaining in the exec buffer
|
|
templen = cmd_text.cursize;
|
|
if (templen) {
|
|
temp = (char *) malloc (templen);
|
|
memcpy (temp, cmd_text.data, templen);
|
|
SZ_Clear (&cmd_text);
|
|
}
|
|
|
|
else
|
|
temp = NULL; // shut up compiler
|
|
|
|
// add the entire text of the file
|
|
Cbuf_AddText (text);
|
|
SZ_Write (&cmd_text, "\n", 1);
|
|
|
|
// add the copied off data
|
|
if (templen) {
|
|
SZ_Write (&cmd_text, temp, templen);
|
|
free (temp);
|
|
}
|
|
}
|
|
void
|
|
Cbuf_Execute (void)
|
|
{
|
|
int i;
|
|
char *text;
|
|
char line[1024];
|
|
int quotes;
|
|
|
|
while (cmd_text.cursize) {
|
|
|
|
// find a \n or ; line break
|
|
text = (char *) cmd_text.data;
|
|
quotes = 0;
|
|
for (i = 0; i < cmd_text.cursize; i++) {
|
|
if (text[i] == '"')
|
|
quotes++;
|
|
if (!(quotes & 1) && text[i] == ';')
|
|
break; // don't break if inside a quoted
|
|
// string
|
|
if (text[i] == '\n')
|
|
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)
|
|
cmd_text.cursize = 0;
|
|
|
|
else {
|
|
i++;
|
|
cmd_text.cursize -= i;
|
|
memcpy (text, text + i, cmd_text.cursize);
|
|
}
|
|
|
|
// execute the command line
|
|
Cmd_ExecuteString (line);
|
|
}
|
|
}
|
|
qboolean
|
|
Cmd_Exists (char *cmd_name)
|
|
{
|
|
cmd_function_t *cmd;
|
|
|
|
for (cmd = cmd_functions; cmd; cmd = cmd->next) {
|
|
if (!strcmp (cmd_name, cmd->name))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
//Commands
|
|
void
|
|
Cmd_Quit_f ()
|
|
{
|
|
printf ("Shutting down.\n");
|
|
SV_Shutdown ();
|
|
Sys_Quit ();
|
|
} void
|
|
|
|
Cmd_ServerList_f ()
|
|
{
|
|
server_t *sv;
|
|
|
|
for (sv = sv_list; sv; sv = sv->next)
|
|
printf ("%s %i players\n", NET_AdrToString (sv->ip), sv->players);
|
|
}
|