nt9856x/code/vos/source/examsys.c
2023-03-28 15:07:53 +08:00

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;
}