505 lines · 8.6 KB · C
RawDownload
// cmd.c -- Quake script command processing module #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; cmdalias_t *cmd_alias; int trashtest;int *trashspot; bool cmd_wait; /* * Causes execution of the remainder of the command buffer to be delayed until * next frame. This allows commands like: * bind g "impulse 5 ; +attack ; wait ; -attack ; impulse 2" */voidCmd_Wait_f(void){	cmd_wait = true;} sizebuf_t cmd_text; voidCbuf_Init(void){	SZ_Alloc(&cmd_text, 8192); // space for commands and script files} voidCbuf_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));} voidCbuf_InsertText(char *text){	char *temp;	int templen; 	// copy off any commands still remaining in the exec buffer	templen = cmd_text.cursize;	if (templen) {		temp = Z_Malloc(templen);		memmove(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); 	// add the copied off data	if (templen) {		SZ_Write(&cmd_text, temp, templen);		Z_Free(temp);	}} voidCbuf_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;		} 		memmove(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;			memmove(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;		}	}} /* * Adds command line parameters as script statements * Commands lead with a +, and continue until a - or another + * quake +prog jctest.qp +cmd amlev1 * quake -nosound +cmd amlev1 */voidCmd_StuffCmds_f(void){	int i, j;	int s;	char *text, *build, c; 	if (Cmd_Argc() != 1) {		Con_Printf("stuffcmds: execute command line parameters\n");		return;	} 	// build the combined string to parse from	s = 0;	for (i = 1; i < com_argc; i++) {		if (!com_argv[i])			continue;		s += strlen (com_argv[i]) + 1;	}	if (!s)		return; 	text = Z_Malloc(s+1);	text[0] = 0;	for (i = 1; i < com_argc; i++) {		if (!com_argv[i])			continue;		strcat(text, com_argv[i]);		if (i != com_argc-1)			strcat(text, " ");	} 	// pull out the commands	build = Z_Malloc(s+1);	build[0] = 0; 	for (i = 0; i < s-1; i++) {		if (text[i] == '+') {			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;		}	} 	if (build[0])		Cbuf_InsertText(build); 	Z_Free(text);	Z_Free(build);} voidCmd_Exec_f(void){	char *f;	int mark; 	if (Cmd_Argc() != 2) {		Con_Printf("exec <filename>: execute a script file\n");		return;	} 	mark = Hunk_LowMark();	f = (char *)COM_LoadHunkFile(Cmd_Argv(1));	if (!f) {		Con_Printf("couldn't exec %s\n", Cmd_Argv(1));		return;	}	Con_Printf("execing %s\n", Cmd_Argv(1)); 	Cbuf_InsertText(f);	Hunk_FreeToLowMark(mark);} voidCmd_Echo_f(void){	int i; 	for (i = 1; i < Cmd_Argc(); i++)		Con_Printf("%s ",Cmd_Argv(i));	Con_Printf("\n");} char *CopyString(char *in){	char *out; 	out = Z_Malloc (strlen(in)+1);	strcpy(out, in);	return out;} voidCmd_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 allready exists, reuse it	for (a = cmd_alias; a; a = a->next) {		if (!strcmp(s, a->name)) {			Z_Free (a->value);			break;		}	} 	if (!a) {		a = Z_Malloc(sizeof(cmdalias_t));		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);} typedef struct cmd_function_s{	struct cmd_function_s *next;	char *name;	xcommand_t function;} cmd_function_t; #define MAX_ARGS 80 static int cmd_argc;static char *cmd_argv[MAX_ARGS];static char *cmd_null_string = "";static char *cmd_args = NULL; cmd_source_t cmd_source; static cmd_function_t *cmd_functions; // possible commands to execute voidCmd_Init(void){	Cmd_AddCommand ("stuffcmds",Cmd_StuffCmds_f);	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);} intCmd_Argc(void){	return cmd_argc;} char *Cmd_Argv(int arg){	if (arg >= cmd_argc || arg < 0)		return cmd_null_string;	return cmd_argv[arg];} char *Cmd_Args(void){	return cmd_args;} voidCmd_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 = 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] = Z_Malloc(strlen(com_token)+1);			strcpy(cmd_argv[cmd_argc], com_token);			cmd_argc++;		}	}} voidCmd_AddCommand(char *cmd_name, xcommand_t function){	cmd_function_t *cmd; 	if (host_initialized) // because hunk allocation would get stomped		Sys_Error("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;	} 	// fail if the command already exists	for (cmd = cmd_functions; cmd; cmd = cmd->next) {		if (!strcmp(cmd_name, cmd->name)) {			Con_Printf("Cmd_AddCommand: %s already defined\n", cmd_name);			return;		}	} 	cmd = Hunk_Alloc(sizeof(cmd_function_t));	cmd->name = cmd_name;	cmd->function = function;	cmd->next = cmd_functions;	cmd_functions = cmd;} boolCmd_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;} char *Cmd_CompleteCommand(char *partial){	cmd_function_t *cmd;	int len; 	len = strlen(partial); 	if (!len)		return NULL; 	// check functions	for (cmd = cmd_functions; cmd; cmd = cmd->next)		if (!strncmp(partial, cmd->name, len))			return cmd->name; 	return NULL;} voidCmd_ExecuteString(char *text, cmd_source_t src){	cmd_function_t *cmd;	cmdalias_t *a; 	cmd_source = src;	Cmd_TokenizeString (text); 	// execute the command line	if (!Cmd_Argc())		return; // no tokens 	// check functions	for (cmd = cmd_functions; cmd; cmd = cmd->next) {		if (!strcasecmp(cmd_argv[0], cmd->name)) {			cmd->function();			return;		}	} 	// check alias	for (a = cmd_alias; a; a = a->next) {		if (!strcasecmp(cmd_argv[0], a->name)) {			Cbuf_InsertText(a->value);			return;		}	} 	// check cvars	if (!Cvar_Command())		Con_Printf ("Unknown command \"%s\"\n", Cmd_Argv(0)); } voidCmd_ForwardToServer(void){	if (cls.state != ca_connected) {		Con_Printf("Can't \"%s\", not connected\n", Cmd_Argv(0));		return;	} 	if (cls.demoplayback)		return; // not really connected 	MSG_WriteByte(&cls.message, clc_stringcmd);	if (strcasecmp(Cmd_Argv(0), "cmd") != 0) {		SZ_Print(&cls.message, Cmd_Argv(0));		SZ_Print(&cls.message, " ");	}	SZ_Print(&cls.message, Cmd_Argc() > 1 ? Cmd_Args() : "\n");} intCmd_CheckParm(char *parm){	int i; 	if (!parm)		Sys_Error("Cmd_CheckParm: NULL"); 	for (i = 1; i < Cmd_Argc(); i++) {		if (!strcasecmp(parm, Cmd_Argv(i)))

Lines 1–500 of 505.

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