#include <stdlib.h>
#include <string.h>
#include "cli.h"
#include "cmdtypes.h"
#include "cmdutil.h"
#include "cmdcmo.h"
#include "cmochk.h"
#include "cmdtree.h"
#include "cmdline.h"
#include "cmdview.h"
#include "cmddisp.h"
#define NOS_FILE_ID 0x00000004
/* 命令行用户 */
static struct cmdline_s
{
struct cmdset_s *cmdsets;
int user_num;
struct cmd_user_s *cmd_users;
} g_cmdline;
/*
name : checksum
description : 针对某个地址开始完成校验和操作。那些提供给外部模块引用的指针变
量必须进行校验和,以防止外部模块输入错误的指针。
input :
addr : 被校验的起始地址
size : 被校验的字节长度
output :
return : 校验结果
author : 董健
date : 2008-01-29
history :
1. dongjian, created
*/
static unsigned long checksum(const void *const addr, unsigned long size)
{
const unsigned char *tmp_addr = (const unsigned char *)addr;
unsigned long index, checksum = 0;
for (index = 0; index < size; index++)
{
checksum += (unsigned long)(tmp_addr + index) ^ 0x0172B3E5;
}
return checksum;
}
/*
name : is_in_cmdsets
description : 检查某个命令集是否在命令行模块所保存的命令集合中。
input :
cmdsets : 命令集的集合
cmdset : 待检查命令集
return : true/false
author : 董健
date : 2008-01-29
history :
1. dongjian, created
*/
static bool is_in_cmdsets(const struct cmdset_s *const cmdsets, const struct cmdset_s *const cmdset)
{
const struct cmdset_s *tmp_cmdset = cmdsets;
for (; tmp_cmdset != 0; tmp_cmdset = tmp_cmdset->next)
{
if (tmp_cmdset == cmdset)
{
return true;
}
}
return false;
}
/*
name : alloc_cmo
description : 根据用户所注册的CMO信息生成一个CMO实体。
input :
id : CMO标识,在CMOSET保持唯一即可。
type : CMO类型,这里的类型是外部模块用户所能看到的类型
content : 根据CMO类型而生成的相应存储内容
help : CMO帮助接口,当用户在未完成命令后输入\?或\t时,CLI将调用作为候
选者出现的那些CMO的帮助接口,以获得相应的CAPTION和HELP信息
check : CMO 检查接口,检查那些已经输入或候选者是否合法,如果不合法,则
不会出现在帮助列表中或不可执行
visible : 此CMO是否可见
userhelp: 用户帮助信息,其中包含中文和英文两种模式
privilege
: CMO优先级
return : 如果分配内存成功,则返回CMO实体,否则返回NULL
author : 董健
date : 2008-01-29
history :
1. dongjian, created
*/
static struct cmo_s *alloc_cmo(unsigned long id, enum cli_cmotype_e type,
const struct content_s *const content,
cli_help_t *help, cli_check_t *check,
int visible,
const struct cli_userhelp_s *userhelp,
unsigned char privilege)
{
struct cmo_s *cmo = (struct cmo_s *)malloc(sizeof (struct cmo_s));
if (cmo != 0)
{
cmo->id = id;
cmo->type = type;
memcpy(&cmo->content, content, sizeof(struct content_s));
cmo->help = help;
cmo->check = check;
cmo->visible = visible;
cmo->userhelp = userhelp;
cmo->privilege = privilege;
cmo->next = 0;
}
return cmo;
}
/*
name : alloc_cmdset
description : 分配一个命令集实体。如果具有相同名称的命令集已经存在,那么直接
返回相应的指针句柄,否则分配一个新的实体。
input :
cmdsets : 命令集的集合
name : 待创建的命令集名称
return : 已经存在或新创建的命令集/NULL
author : 董健
date : 2008-01-29
history :
1. dongjian, created
*/
static struct cmdset_s *alloc_cmdset(struct cmdset_s **const cmdsets, const char *const name)
{
struct cmdset_s *cmdset, **tmp_cmdset = cmdsets;
for (; *tmp_cmdset != 0; tmp_cmdset = &(*tmp_cmdset)->next);
if ((cmdset = *tmp_cmdset = (struct cmdset_s *)malloc(sizeof (struct cmdset_s))) != 0)
{
strcpy(cmdset->name, name);
cmdset->cmoset_list = 0;
cmdset->inherit_tree = 0;
cmdset->private_tree = 0;
cmdset->next = 0;
}
return cmdset;
}
/*
name : is_cmo_end
description : 判断命令树中的某个节点是否为 end,即以此节点为结束节点的命令线
索是一条完整的命令。
input :
cmd_node: 命令树节点
return : true/false
author : 董健
date : 2008-01-29
history :
1. dongjian, created
*/
static bool is_cmo_end(const struct cmd_node_s *const cmd_node)
{
return ((cmd_node == 0) || cmd_node->parent->is_end);
}
/*
name : is_both_cmo_end
description : 判断两个命令树节点是否同时结束。
input :
node1 : 命令树节点1
node2 : 命令树节点2
return : true/false
author : 董健
date : 2008-01-29
history :
1. dongjian, created
*/
static bool is_both_cmo_end(const struct cmd_node_s *const node1,
const struct cmd_node_s *const node2)
{
return (node1->is_end && node2->is_end);
}
/*
name : is_cmd_clash
description : 判断两个命令树是否存在冲突,即树型存在相交,包含关系,也就是存
在相同的命令。内部采用递归逐节点匹配检查方式判断。
parameter :
branch1 : 命令树1
branch2 : 命令树2
return : true/false
author : 董健
date : 2008-01-29
history :
1. dongjian, created
*/
static bool is_cmd_clash(const struct cmd_node_s *const branch1,
const struct cmd_node_s *const branch2)
{
const struct cmd_node_s *node1, *node2;
if (((branch1 != 0) && (branch2 != 0)) && !CLI(is_cmo_clash)(branch1->cmo, branch2->cmo))
{
return false;
}
if (branch1 == branch2)
{
return true;
}
for (node1 = branch1; node1 != 0; node1 = node1->sibling)
{
for (node2 = branch2; node2 != 0; node2 = node2->sibling)
{
if (!CLI(is_cmo_clash)(node1->cmo, node2->cmo))
{
continue;
}
if (is_both_cmo_end(node1, node2))
{
return true;
}
if (is_cmd_clash(node1->eldest_child, node2->eldest_child))
{
return true;
}
}
}
return false;
}
/*
name : check_cmdtree_clash
description : 判断命令树中是否存在冲突的子树,即存在相同的命令。内部采用递归
逐节点匹配检查方式判断。
input :
root : 命令树
return : true/false
author : 董健
date : 2008-01-29
history :
1. dongjian, created
*/
static bool check_cmdtree_clash(struct cmd_node_s *const root)
{
const struct cmd_node_s *node1 = root;
for (; node1 != 0; node1 = node1->sibling)
{
const struct cmd_node_s *node2 = node1->sibling;
for (; node2 != 0; node2 = node2->sibling)
{
if (is_cmd_clash(node1, node2))
{
return true;
}
}
if (check_cmdtree_clash(node1->eldest_child))
{
return true;
}
}
return false;
}
/*
name : do_create_cmdtree
description : 根据用户输入的命令描述正则表达式生成相应的命令树。内部通过调用
BISON 语法分析生成语法树。这里不会对语法树的生成结构进