565 lines · 9.2 KB · C
RawDownload
#include "quakedef.h" void Cmd_ForwardToServer (void); #define	MAX_ALIAS_NAME	32 typedef struct cmdalias_s{	struct cmdalias_s	*next;	char	name[MAX_ALIAS_NAME];	char	*value;} cmdalias_t; static cmdalias_t	*cmd_alias; static bool	cmd_wait; //============================================================================= /*============Cmd_Wait_f Causes execution of the remainder of the command buffer to be delayed untilnext frame.  This allows commands like:bind g "impulse 5 ; +attack ; wait ; -attack ; impulse 2"============*/static void Cmd_Wait_f (void){	cmd_wait = true;} /*============================================================================= 						COMMAND BUFFER =============================================================================*/ static sizebuf_t	cmd_text; /*============Cbuf_Init============*/void Cbuf_Init (void){	SZ_Alloc (&cmd_text, 65536);		// space for commands and script files}  /*============Cbuf_AddText Adds command text at the end of the buffer============*/void Cbuf_AddText (char *text){	int		l; 	l = strlen(text); 	if (cmd_text.cursize + l >= cmd_text.maxsize)	{		Con_Printf ("Cbuf_AddText: overflow\n");		return;	} 	SZ_Write (&cmd_text, text, strlen(text));}  /*============Cbuf_InsertText Adds command text immediately after the current commandAdds a \n to the textFIXME: actually change the command buffer to do less copying============*/void Cbuf_InsertText (char *text){	char	*temp = nil;	int		templen; 	// copy off any commands still remaining in the exec buffer	templen = cmd_text.cursize;	if (templen)	{		temp = Z_Malloc (templen);		memcpy(temp, cmd_text.data, templen);		SZ_Clear (&cmd_text);	} 	// add the entire text of the file	Cbuf_AddText (text); 	// add the copied off data	if (templen)	{		SZ_Write (&cmd_text, temp, templen);		Z_Free (temp);	}} /*============Cbuf_Execute============*/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, src_command); 		if (cmd_wait)		{	// skip out while text still remains in buffer, leaving it			// for next frame			cmd_wait = false;			break;		}	}} /*============================================================================== 						SCRIPT COMMANDS ==============================================================================*/ /*===============Cmd_Exec_f===============*/void Cmd_Exec_f (void){	char	*f;	void	*mark; 	if (Cmd_Argc () != 2)	{		Con_Printf ("exec <filename> : execute a script file\n");		return;	} 	mark = Hunk_Mark ();	f = loadhunklmp(Cmd_Argv(1), nil);	if(f == nil){		Con_Printf(va("exec: %s\n", lerr()));		return;	}	Con_Printf ("execing %s\n",Cmd_Argv(1)); 	Cbuf_InsertText (f);	Hunk_FreeToMark (mark);}  /*===============Cmd_Echo_f Just prints the rest of the line to the console===============*/void Cmd_Echo_f (void){	int		i; 	for (i=1 ; i<Cmd_Argc() ; i++)		Con_Printf ("%s ",Cmd_Argv(i));	Con_Printf ("\n");} /*===============Cmd_Alias_f Creates a new command that executes a command string (possibly ; seperated)===============*/ char *CopyString (char *in){	char	*out; 	out = Z_Malloc (strlen(in)+1);	strcpy (out, in);	return out;} void Cmd_Alias_f (void){	cmdalias_t	*a;	char		cmd[1024];	int			i, c;	char		*s; 	if (Cmd_Argc() == 1)	{		Con_Printf ("Current alias commands:\n");		for (a = cmd_alias ; a ; a=a->next)			Con_Printf ("%s : %s\n", a->name, a->value);		return;	} 	s = Cmd_Argv(1);	if (strlen(s) >= MAX_ALIAS_NAME)	{		Con_Printf ("Alias name is too long\n");		return;	} 	// if the alias already exists, reuse it	for (a = cmd_alias ; a ; a=a->next)	{		if(strcmp(s, a->name) == 0)		{			Z_Free (a->value);			break;		}	} 	if (a == nil)	{		a = Z_Malloc(sizeof *a);		a->next = cmd_alias;		cmd_alias = a;	}	strcpy (a->name, s); 	// copy the rest of the command line	cmd[0] = 0;		// start out with a null string	c = Cmd_Argc();	for (i=2 ; i< c ; i++)	{		strcat (cmd, Cmd_Argv(i));		if (i != c)			strcat (cmd, " ");	}	strcat (cmd, "\n"); 	a->value = CopyString (cmd);} /*============================================================================= 					COMMAND EXECUTION =============================================================================*/ #define	MAX_ARGS		80 static	int			cmd_argc;static	char		*cmd_argv[MAX_ARGS];static	char		*cmd_null_string = "";static	char		*cmd_args = nil; cmd_source_t	cmd_source;  static	cmd_function_t	*cmd_functions;		// possible commands to execute /*============Cmd_Init============*/void Cmd_Init (void){	Cmd_AddCommand ("exec",Cmd_Exec_f);	Cmd_AddCommand ("echo",Cmd_Echo_f);	Cmd_AddCommand ("alias",Cmd_Alias_f);	Cmd_AddCommand ("cmd", Cmd_ForwardToServer);	Cmd_AddCommand ("wait", Cmd_Wait_f);} /*============Cmd_Argc============*/int		Cmd_Argc (void){	return cmd_argc;} /*============Cmd_Argv============*/char	*Cmd_Argv (int arg){	if (arg >= cmd_argc)		return cmd_null_string;	return cmd_argv[arg];} /*============Cmd_Args============*/char		*Cmd_Args (void){	return cmd_args;}  /*============Cmd_TokenizeString Parses the given string into command line tokens.============*/void Cmd_TokenizeString (char *text){	int		i; 	// clear the args from the last string	for (i=0 ; i<cmd_argc ; i++)		Z_Free (cmd_argv[i]); 	cmd_argc = 0;	cmd_args = nil; 	while (1)	{		// skip whitespace up to a /n		while (*text && *text <= ' ' && *text != '\n')		{			text++;		} 		if (*text == '\n')	// a newline seperates commands in the buffer			return; 		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] = Z_Malloc(strlen(com_token)+1);			strcpy(cmd_argv[cmd_argc], com_token);			cmd_argc++;		}	}}  /*============Cmd_AddCommand============*/cmd_function_t *Cmd_AddCommand (char *cmd_name, xcommand_t function){	cmd_function_t	*cmd; 	if (host_initialized)	// because hunk allocation would get stomped		fatal("Cmd_AddCommand after host_initialized"); 	// fail if the command is a variable name	if (Cvar_VariableString(cmd_name)[0])	{		Con_Printf ("Cmd_AddCommand: %s already defined as a var\n", cmd_name);		return nil;	} 	// fail if the command already exists	for (cmd=cmd_functions ; cmd ; cmd=cmd->next)	{		if(strcmp(cmd_name, cmd->name) == 0)		{			Con_Printf ("Cmd_AddCommand: %s already defined\n", cmd_name);			return cmd;		}	} 	cmd = Hunk_Alloc(sizeof *cmd);	cmd->name = cmd_name;	cmd->function = function;	cmd->next = cmd_functions;	cmd_functions = cmd;	return cmd;} /*============Cmd_Exists============*/bool	Cmd_Exists (char *cmd_name){	cmd_function_t	*cmd; 	for (cmd=cmd_functions ; cmd ; cmd=cmd->next)	{		if(strcmp(cmd_name, cmd->name) == 0)			return true;	} 	return false;}   /*============Cmd_CompleteCommand============*/char *Cmd_CompleteCommand (char *partial){	cmd_function_t	*cmd;	int				len; 	len = strlen(partial); 	if (!len)		return nil; 	// check functions	for (cmd=cmd_functions ; cmd ; cmd=cmd->next)		if(strncmp(partial, cmd->name, len) == 0 && !cmd->hidden)			return cmd->name; 	return nil;} /*============Cmd_ExecuteString A complete command line has been parsed, so try to execute itFIXME: lookupnoadd the token to speed search?============*/void	Cmd_ExecuteString (char *text, cmd_source_t src){	cmd_function_t	*cmd;

Lines 1–500 of 565.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t