234 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			234 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <string.h>
 | 
						|
#include <kwrap/type.h>
 | 
						|
#include <kwrap/cmdsys.h>
 | 
						|
#include <kwrap/examsys.h>
 | 
						|
#include <kwrap/task.h>
 | 
						|
#include <kwrap/flag.h>
 | 
						|
#include <kwrap/debug.h>
 | 
						|
 | 
						|
#define MAX_ARGS 32
 | 
						|
 | 
						|
#define FLGEXAMSYS_IDLE  FLGPTN_BIT(0)
 | 
						|
#define FLGEXAMSYS_RUN   FLGPTN_BIT(1)
 | 
						|
#define FLGEXAMSYS_POLLING FLGPTN_BIT(2)
 | 
						|
#define FLGEXAMSYS_ITEM_WAIT FLGPTN_BIT(3)         //indicate script item is waiting key or command string
 | 
						|
#define FLGEXAMSYS_ITEM_WAIT_DONE FLGPTN_BIT(4)    //indicate script item recevied key
 | 
						|
#define FLGEXAMSYS_ITEM_WAIT_POLLING FLGPTN_BIT(5) //for check if idle then run
 | 
						|
 | 
						|
extern const char __EXAMFUNCTAB_BEGIN__[] __attribute__((weak));
 | 
						|
extern const char __EXAMFUNCTAB_END__[] __attribute__((weak));
 | 
						|
 | 
						|
static THREAD_HANDLE m_examsys_thread;
 | 
						|
static ID examsys_flag_id = 0;
 | 
						|
static char buf[256] = {0};
 | 
						|
static char item_input[128] = {0};
 | 
						|
 | 
						|
static int list_all_cmd(void)
 | 
						|
{
 | 
						|
	NVT_EXAMSYS_ENTRY *t;
 | 
						|
	int cnt = 0;
 | 
						|
 | 
						|
	//printf("list command set: 0x%x-0x%x\n",(unsigned int)__EXAMFUNCTAB_BEGIN__,(unsigned int)__EXAMFUNCTAB_END__);
 | 
						|
 | 
						|
	for (t = (NVT_EXAMSYS_ENTRY *)__EXAMFUNCTAB_BEGIN__; t != (NVT_EXAMSYS_ENTRY *)__EXAMFUNCTAB_END__; t++) {
 | 
						|
		//printf("%s: 0x%x\n", t->name, (unsigned int)t->p_main);
 | 
						|
		printf("%s\n", t->name);
 | 
						|
		cnt++;
 | 
						|
	}
 | 
						|
 | 
						|
	return cnt;
 | 
						|
}
 | 
						|
 | 
						|
static int parsecmd(char *cmdline, char **cmdname, char **cmdarg)
 | 
						|
{
 | 
						|
	char *pstr, *cmd, *pstrend;
 | 
						|
	char *arg;
 | 
						|
 | 
						|
	pstr = cmdline;
 | 
						|
	pstrend = cmdline + strlen(cmdline);
 | 
						|
	while (*pstr == ' ' || *pstr == '\t' || *pstr == '\r' || *pstr == '\n') {
 | 
						|
		pstr++;
 | 
						|
	}
 | 
						|
	arg = strchr(pstr, ' ');
 | 
						|
	if (arg) {
 | 
						|
		while (*arg == ' ' || *arg == '\t' || *arg == '\r' || *arg == '\n') {
 | 
						|
			arg++;
 | 
						|
		}
 | 
						|
		*cmdarg = arg;
 | 
						|
	} else {
 | 
						|
		*cmdarg = pstrend;
 | 
						|
	}
 | 
						|
 | 
						|
	cmd = strtok(pstr, " \t\n");
 | 
						|
 | 
						|
	if (!cmd) {
 | 
						|
		return FALSE;
 | 
						|
	}
 | 
						|
	*cmdname = cmd;
 | 
						|
 | 
						|
	//printf("parsecmd: cmd=\"%s\", arg=\"%s\"\n", *cmdname, *cmdarg);
 | 
						|
 | 
						|
	return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static int run_func(char *name, NVT_EXAMSYS_MAIN prun_func, char *args)
 | 
						|
{
 | 
						|
	int ret;
 | 
						|
	char *cmdLine;
 | 
						|
	int _argc = 0;
 | 
						|
	char *_argv[MAX_ARGS];
 | 
						|
	char *param;
 | 
						|
 | 
						|
	cmdLine = strdup(args);
 | 
						|
 | 
						|
	if (cmdLine == NULL) {
 | 
						|
		printf("examsys failed to strdup.\n");
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	param = strtok(cmdLine, " \t\n");
 | 
						|
	_argv[_argc++] = name;
 | 
						|
	while (param && _argc < MAX_ARGS) {
 | 
						|
		_argv[_argc++] = param;
 | 
						|
		param = strtok(NULL, " \t\n");
 | 
						|
	}
 | 
						|
	if (_argc < MAX_ARGS) {
 | 
						|
		_argv[_argc] = NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	ret = prun_func(_argc, _argv);
 | 
						|
 | 
						|
	free(cmdLine);
 | 
						|
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
static int find_and_runcmd(char *cmdname, char *cmdarg)
 | 
						|
{
 | 
						|
	NVT_EXAMSYS_ENTRY *t;
 | 
						|
 | 
						|
	for (t = (NVT_EXAMSYS_ENTRY *)__EXAMFUNCTAB_BEGIN__; t != (NVT_EXAMSYS_ENTRY *)__EXAMFUNCTAB_END__; t++) {
 | 
						|
		if (strcmp(cmdname, t->name) == 0) {
 | 
						|
			run_func(cmdname, t->p_main, cmdarg);
 | 
						|
			return TRUE;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
int nvt_examsys_runcmd(char *str)
 | 
						|
{
 | 
						|
	int err = -1;
 | 
						|
	char *cmdstr, *cmdname, *cmdarg;
 | 
						|
 | 
						|
	if (str[0] == '?' || strncmp(str, "ls", 3) == 0) {
 | 
						|
		list_all_cmd();
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
 | 
						|
	//fix color end on linux should be in front of \n
 | 
						|
	printf(DBG_COLOR_CYAN "\rexam: '%s' -begin%s\n", str, DBG_COLOR_END);
 | 
						|
	cmdstr = strdup(str);
 | 
						|
 | 
						|
	if (cmdstr == NULL) {
 | 
						|
		printf("examsys failed to strdup.\n");
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	if (parsecmd(cmdstr, &cmdname, &cmdarg)) {
 | 
						|
		if (find_and_runcmd(cmdname, cmdarg)) {
 | 
						|
			err = 1;
 | 
						|
		} else {
 | 
						|
			printf("parsecmd: cmd=\"%s\", arg=\"%s\"\n", cmdname, cmdarg);
 | 
						|
			printf("command not found!\n");
 | 
						|
			err = 0;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	free(cmdstr);
 | 
						|
	printf(DBG_COLOR_CYAN "exam: '%s' -end%s\n", str, DBG_COLOR_END);
 | 
						|
	return err;
 | 
						|
}
 | 
						|
 | 
						|
int nvt_examsys_runcmd_bk(char *str)
 | 
						|
{
 | 
						|
	FLGPTN ptn = 0;
 | 
						|
 | 
						|
	vos_flag_set(examsys_flag_id, FLGEXAMSYS_POLLING);
 | 
						|
	vos_flag_wait_interruptible(&ptn, examsys_flag_id, FLGEXAMSYS_POLLING | FLGEXAMSYS_IDLE, TWF_ORW | TWF_CLR);
 | 
						|
 | 
						|
	if ((ptn & FLGEXAMSYS_IDLE) == 0) {
 | 
						|
		// check if waiting key
 | 
						|
		vos_flag_set(examsys_flag_id, FLGEXAMSYS_ITEM_WAIT_POLLING);
 | 
						|
		vos_flag_wait_interruptible(&ptn, examsys_flag_id, FLGEXAMSYS_ITEM_WAIT_POLLING | FLGEXAMSYS_ITEM_WAIT, TWF_ORW | TWF_CLR);
 | 
						|
 | 
						|
		if ((ptn & FLGEXAMSYS_ITEM_WAIT) == 0) {
 | 
						|
			printf("command '%s' is running\n", buf);
 | 
						|
		} else {
 | 
						|
			strncpy(item_input, str, sizeof(item_input) - 3);
 | 
						|
			strcat(item_input, "\r\n");
 | 
						|
			vos_flag_set(examsys_flag_id, FLGEXAMSYS_ITEM_WAIT_DONE);
 | 
						|
		}
 | 
						|
		return 0;
 | 
						|
	}
 | 
						|
 | 
						|
	strncpy(buf, str, sizeof(buf) - 1);
 | 
						|
	vos_flag_set(examsys_flag_id, FLGEXAMSYS_RUN);
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
char *nvt_examsys_fgets(char *str, int n, FILE *stream)
 | 
						|
{
 | 
						|
	FLGPTN ptn;
 | 
						|
 | 
						|
	if (vos_task_get_handle() == m_examsys_thread) {
 | 
						|
		vos_flag_set(examsys_flag_id, FLGEXAMSYS_ITEM_WAIT);
 | 
						|
		vos_flag_wait_interruptible(&ptn, examsys_flag_id, FLGEXAMSYS_ITEM_WAIT_DONE, TWF_ORW | TWF_CLR);
 | 
						|
		strncpy(str, item_input, n);
 | 
						|
	} else {
 | 
						|
		fgets(str, n, stream);
 | 
						|
	}
 | 
						|
	return item_input;
 | 
						|
}
 | 
						|
 | 
						|
char nvt_examsys_getchar(void)
 | 
						|
{
 | 
						|
	char ch;
 | 
						|
	FLGPTN ptn;
 | 
						|
 | 
						|
	if (vos_task_get_handle() == m_examsys_thread) {
 | 
						|
		vos_flag_set(examsys_flag_id, FLGEXAMSYS_ITEM_WAIT);
 | 
						|
		vos_flag_wait_interruptible(&ptn, examsys_flag_id, FLGEXAMSYS_ITEM_WAIT_DONE, TWF_ORW | TWF_CLR);
 | 
						|
		ch = item_input[0];
 | 
						|
	} else {
 | 
						|
		ch = (char)getchar();
 | 
						|
	}
 | 
						|
	return ch;
 | 
						|
}
 | 
						|
 | 
						|
static void nvt_examsys_tsk(void *p_param)
 | 
						|
{
 | 
						|
	FLGPTN ptn;
 | 
						|
	//coverity[no_escape]
 | 
						|
	while (1) {
 | 
						|
		vos_flag_set(examsys_flag_id, FLGEXAMSYS_IDLE);
 | 
						|
		vos_flag_wait_interruptible(&ptn, examsys_flag_id, FLGEXAMSYS_RUN, TWF_ORW | TWF_CLR);
 | 
						|
 | 
						|
		if (strlen(buf) > 0) {
 | 
						|
			nvt_examsys_runcmd(buf);
 | 
						|
			printf("$ ");
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
int nvt_examsys_init(void)
 | 
						|
{
 | 
						|
	m_examsys_thread = vos_task_create(nvt_examsys_tsk, NULL, "nvt_examsys_tsk", VK_TASK_LOWEST_PRIORITY-5, 16 * 1024);
 | 
						|
	vos_flag_create(&examsys_flag_id, NULL, "examsys_flag_id");
 | 
						|
	vos_flag_clr(examsys_flag_id, 0);
 | 
						|
	vos_task_resume(m_examsys_thread);
 | 
						|
	nvt_cmdsys_regsys('$', nvt_examsys_runcmd_bk);
 | 
						|
	return 0;
 | 
						|
}
 |