⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if.c

📁 umon bootloader source code, support mips cpu.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* if.c:
 *	This file started off as the file for the "if" command in the monitor,
 *	and has since grown into the file that contains the commands that only
 *	make sense if they are used in scripts; hence, a prerequisite to these
 *	commands is that TFS is included in the build.
 *	It also contains the script runner portion of TFS.  The name of this
 *	file should have been changed to tfsscript.c!
 *	
 *	if:
 *	Supports the monitor's ability to do conditional branching within
 *	scripts executed through TFS.
 *
 *	goto:
 *	Tag based jumping in a script.
 *
 *	item:
 *	A simple way to process a list (similar to KSH's 'for' construct).
 *
 *	General notice:
 *	This code is part of a boot-monitor package developed as a generic base
 *	platform for embedded system designs.  As such, it is likely to be
 *	distributed to various projects beyond the control of the original
 *	author.  Please notify the author of any enhancements made or bugs found
 *	so that all may benefit from the changes.  In addition, notification back
 *	to the author will allow the new user to pick up changes that may have
 *	been made by other users after this version of the code was distributed.
 *
 *	Note1: the majority of this code was edited with 4-space tabs.
 *	Note2: as more and more contributions are accepted, the term "author"
 *		   is becoming a mis-representation of credit.
 *
 *	Original author:	Ed Sutter
 *	Email:				esutter@lucent.com
 *	Phone:				908-582-2351
 */
#include "config.h"
#include "genlib.h"
#include "stddefs.h"
#include "tfs.h"
#include "tfsprivate.h"
#include "ether.h"
#include "cli.h"

#if INCLUDE_TFSSCRIPT

/* Subroutine variables:
 * The definition of MAXGOSUBDEPTH (15) determines the maximum number
 * of subroutines that can be nested within any one script invocation.
 * ReturnToTellTbl[]
 *  Used by script runner to keep track of the location in the file that
 *  the subroutine is supposed to return to.
 * ReturnToDepth
 *  The current subroutine nesting depth of the script runner.
 */
#define MAXGOSUBDEPTH	15
static int	ReturnToDepth;
static long	ReturnToTellTbl[MAXGOSUBDEPTH+1];
static int	CurrentScriptfdTbl[TFS_MAXOPEN+1];

/* ScriptIsRunning:
 * Non-zero if a script is active, else zero.
 */
static int	ScriptIsRunning;

/* ScriptGotoTag:
 * Points to the string that is the most recent target of
 * a goto or gosub command.
 */
static char	*ScriptGotoTag;

/* ScriptExitFlag:
 * If non-zero, then the script must exit.  
 * The 'exit' command will set this to either EXIT_SCRIPT (normal case)
 * or 'EXIT_SCRIPT | REMOVE_SCRIPT' if the -r option of exit was used.
 */
int	ScriptExitFlag;

/*****************************************************************************/

/* If:
 *	A simple test/action statement.
 *	Currently, the only action supported is "goto tag". 
 *	Syntax:
 *		if ARG1 compar ARG2 {action} [else action]
 *		if -t TEST {action} [else action]
 */
char *IfHelp[] = {
	"Conditional branching",
	"-[t:v] [{arg1} {compar} {arg2}] {action} [else action]",
#if INCLUDE_VERBOSEHELP
	" Options:",
	" -t{test} see below",
	" -v       verbose mode (print TRUE or FALSE result)",
	" Notes:",
	" * Numerical/logical/string compare:",
	"   seq sne sin gt lt le ge eq ne and or xor",
	" * Action:",
	"   goto tag | gosub tag | exit | return",
	" * Other tests (-t args):",
	"   gc, ngc, iscmp {filename}",
#endif
	0,
};

int
If(int argc, char *argv[])
{
	int		opt, arg, true, if_else, offset, verbose;
	void	(*iffunc)(), (*elsefunc)();
	long	var1, var2;
	char	*testtype, *arg1, *arg2, *iftag, *elsetag;

	verbose = 0;
	testtype = 0;
	while((opt=getopt(argc,argv,"vt:")) != -1) {
		switch(opt) {
		case 'v':
			verbose = 1;
			break;
		case 't':
			testtype = optarg;
			break;
		default:
			return(CMD_PARAM_ERROR);
		}
	}

	elsetag = 0;
	elsefunc = 0;
	offset = true = if_else = 0;

	/* First see if there is an 'else' present... */
	for (arg=optind;arg<argc;arg++) {
		if (!strcmp(argv[arg],"else")) {
			if_else = 1;
			break;
		}
	}

	if (if_else) {
		elsetag = argv[argc-1];
		if (!strcmp(argv[argc-1],"exit")) {
			offset = 2;
			elsefunc = exitscript;
		}
		else if (!strcmp(argv[argc-1],"return")) {
			offset = 2;
			elsefunc = gosubret;
		}
		else if (!strcmp(argv[argc-2],"goto")) {
			offset = 3;
			elsefunc = gototag;
		}
		else if (!strcmp(argv[argc-2],"gosub")) {
			offset = 3;
			elsefunc = gosubtag;
		}
		else
			return(CMD_PARAM_ERROR);
	}
	
	iftag = argv[argc-offset-1];
	if (!strcmp(argv[argc-offset-1],"exit"))
		iffunc = exitscript;
	else if (!strcmp(argv[argc-offset-1],"return"))
		iffunc = gosubret;
	else if (!strcmp(argv[argc-offset-2],"goto"))
		iffunc = gototag;
	else if (!strcmp(argv[argc-offset-2],"gosub"))
		iffunc = gosubtag;
	else
		return(CMD_PARAM_ERROR);

	if (testtype) {
		if (!strcmp(testtype,"gc")) {
			if (gotachar())
				true=1;
		}
		else if (!strcmp(testtype,"ngc")) {
			if (!gotachar())
				true=1;
		}
		else if (!strcmp(testtype,"iscmp")) {
			TFILE *tfp;

			tfp = tfsstat(argv[optind]);
			if (tfp) {
				if (TFS_ISCPRS(tfp))
					true=1;
			}
			else
				printf("'%s' not found\n",argv[optind]);
		}
		else
			return(CMD_PARAM_ERROR);
	}
	else {
		arg1 = argv[optind];
		testtype = argv[optind+1];
		arg2 = argv[optind+2];

		var1 = strtoul(arg1,(char **)0,0);
		var2 = strtoul(arg2,(char **)0,0);

		if (!strcmp(testtype,"gt")) {
			if (var1 > var2)
				true = 1;
		}
		else if (!strcmp(testtype,"lt")) {
			if (var1 < var2)
				true = 1;
		}
		else if (!strcmp(testtype,"le")) {
			if (var1 <= var2)
				true = 1;
		}
		else if (!strcmp(testtype,"ge")) {
			if (var1 >= var2)
				true = 1;
		}
		else if (!strcmp(testtype,"eq")) {
			if (var1 == var2)
				true = 1;
		}
		else if (!strcmp(testtype,"ne")) {
			if (var1 != var2)
				true = 1;
		}
		else if (!strcmp(testtype,"and")) {
			if (var1 & var2)
				true = 1;
		}
		else if (!strcmp(testtype,"xor")) {
			if (var1 ^ var2)
				true = 1;
		}
		else if (!strcmp(testtype,"or")) {
			if (var1 | var2)
				true = 1;
		}
		else if (!strcmp(testtype,"seq")) {
			if (!strcmp(arg1,arg2))
				true = 1;
		}
		else if (!strcmp(testtype,"sin")) {
			if (strstr(arg2,arg1))
				true = 1;
		}
		else if (!strcmp(testtype,"sne")) {
			if (strcmp(arg1,arg2))
				true = 1;
		}
		else
			return(CMD_PARAM_ERROR);
	}
	
	/* If the true flag is set, call the 'if' function.
	 * If the true flag is clear, and "else" was found on the command
	 * line, then call the 'else' function...
	 */
	if (true) {
		if (verbose)
			printf("TRUE\n");
		iffunc(iftag);
	}
	else {
		if (verbose)
			printf("FALSE\n");
		if (if_else)
			elsefunc(elsetag);
	}

	return(CMD_SUCCESS);
}

int
InAScript(void)
{
	if (ScriptIsRunning)
		return(1);
	else {
		printf("Invalid from outside a script\n");
		return(0);
	}
}

void
exitscript(char *ignored)
{
	if (InAScript()) {
		ScriptExitFlag = EXIT_SCRIPT;
	}
}


char *ExitHelp[] = {
	"Exit a script",
	"-[r]",
#if INCLUDE_VERBOSEHELP
	"Options:",
	" -r   remove script after exit",
#endif
	0,
};

int
Exit(int argc, char *argv[])
{
	ScriptExitFlag = EXIT_SCRIPT;
	if ((argc == 2) && (!strcmp(argv[1],"-r")))
		ScriptExitFlag |= REMOVE_SCRIPT;
	return(CMD_SUCCESS);
}

char *GotoHelp[] = {
	"Branch to file tag",
	"{tagname}",
	0,
};

int
Goto(int argc, char *argv[])
{
	if (argc != 2)
		return(CMD_PARAM_ERROR);
	gototag(argv[1]);
	return(CMD_SUCCESS);
}


char *GosubHelp[] = {
	"Call a subroutine",
	"{tagname}",
	0,
};

int
Gosub(int argc, char *argv[])
{
	if (argc != 2)
		return(CMD_PARAM_ERROR);
	gosubtag(argv[1]);
	return(CMD_SUCCESS);
}

char *ReturnHelp[] = {
	"Return from subroutine",
	"",
	0,
};

int
Return(int argc, char *argv[])
{
	if (argc != 1)
		return(CMD_PARAM_ERROR);
	gosubret(0);
	return(CMD_SUCCESS);
}

/* Item:
 *	This is a simple replacement for the KSH "for" construct...
 *	It allows the user to build a list of strings and retrieve one at a time.
 *	Basically, the items can be thought of as a table.  The value of idx
 *	(starting with 1) is used to index into the list of items and place
 *	that item in the shell variable "var".
 *	Syntax:
 *		item {idx} {var} {item1} {item2} {item3} ....
 */
char *ItemHelp[] = {
	"Extract an item from a list",
	"{idx} {stor_var} [item1] [item2] ...",

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -