好久没有写代码了,为了防止手生,决定从零开始写一个Diag程序,防止手生。也希望能对C语言的初学者有一点帮助,高手嘛就见笑了。
Diag的全称是Diagnostic,就是用来测试硬件的,多用于产线生产和维修测试。特点是:
- 类Shell风格
- 命令行控制
- 没有或者有简陋的GUI
我这里写的Diag目的完成如下功能:
- 支持Shell风格的命令解析,支持环境变量
- 最简化的表结构
- 支持帮助
实际上,U-boot,CFE的名里那个解析就是满足上述要求的。在编写的过程我会参考这两份代码的某些实现,但不会全部照抄。
代码就放在优快云 Code上吧!
可以用如下命令获取:
git clone https://code.youkuaiyun.com/lishanchao/gcc.git
至于为什么是gcc.git,而不是diag.git,呵呵,不要在意细节。
好了,现在简单说一下目前的实现和接下来要添加的功能。
已实现:
目前共有6个文件,cmd.c和cmd.h是和命令结构体和命令解析、执行有关的代码。
do_sys.c 包含具体和Diag整体相关的函数,比如do_ver()打印版本,do_quit()退出程序等。
error.h 定义错误返回码
main.c 主函数
Makefile 工程管理
$ tree
.
|-- cmd.c
|-- cmd.h
|-- do_sys.c
|-- error.h
|-- main.c
`-- Makefile
0 directories, 6 files
Diag程序实质是把一个字符串和函数关联起来,所以需要实现一个结构体,包含字符串(命令名字)和函数地址(函数代码),以及函数参数。
所以,一个最简单的结构体就定义出来了:
typedef struct cmd{
char name[FUNC_NAME_LEN];
int (*func)(int argc, char **argv);
int argc;
char **argv;
} CMD;
因为我们选用了Shell风格的命令,那么函数的原型也就出来了:int do_xxxx(int argc, char **argv)
比如do_ver()的实现如下:
int do_ver(int argc, char **argv)
{
puts("version 1.0");
return 0;
}
好了,现在该有基本的查表功能了。请看cmd.c。
在cmd.c里我们定义了CMD cmdtable[]作为静态的、唯一的表。
定义了CMD* find_cmd(CMD* pcmd, char *inbuf)作为查找命令的函数,int run_cmd(CMD* pcmd)作为执行命令的函数。它们具体实现如下:
CMD cmdtable[] = {
{"ver", do_ver},
{"quit", do_quit},
};
CMD* find_cmd(CMD* pcmd, char *inbuf)
{
CMD *p = cmdtable;
for(; p != NULL; p++) {
if(strncmp(inbuf, p->name, strlen(p->name)) == 0) {
/* TODO: arguments process */
p->argc = 1;
p->argv = NULL;
return p;
}
}
return NULL;
}
int run_cmd(CMD* pcmd)
{
if(pcmd)
return pcmd->func(pcmd->argc, pcmd->argv);
else
return ERR_CMD_NOT_FOUND;
}
cmdtable简陋了点吧,参数个数和参数指针那俩还没写呢。命令查找和命令执行也简陋至极。但是这样一个简陋的框架,已经可以作假了。
请看运行结果:
serval@helsinki /cygdrive/d/source/csdn/gcc/src
$ ./diag
---Serval's DIAG---
DIAG>> ver
version 1.0
-OK-
DIAG>> ver
version 1.0
-OK-
DIAG>> quit
Quiting...
serval@helsinki /cygdrive/d/source/csdn/gcc/src
$ ./diag
---Serval's DIAG---
DIAG>> ver
version 1.0
-OK-
DIAG>> pwd
Segmentation fault (core dumped)
够唬人吧!可是目前还有一个bug:Segmentation fault (core dumped)。这个应该是find_cmd的设计有问题。
好了现在总结一下,接下来要做的功能:
- Segmentation fault的bug解掉!
- 解析参数!