优秀代码赏析(c, 链表, 命令解析框架)
2013-09-06 18:06
344 查看
以下代码摘录自 vivi-20090929
#ifndef _VIVI_COMMAND_H_ #define _VIVI_COMMAND_H_ enum ParseState { PS_WHITESPACE, PS_TOKEN, PS_STRING, PS_ESCAPE }; typedef struct user_command { const char *name; void (*cmdfunc)(int argc, const char **); struct user_command *next_cmd; const char *helpstr; } user_command_t; typedef struct user_subcommand { const char *name; void (*cmdfunc)(int argc, const char **); const char *helpstr; } user_subcommand_t; /* General interfaces */ extern void add_command(user_command_t *cmd); void execcmd(int, const char **); void exec_string(char *); void execsubcmd(user_subcommand_t *, int, const char **); void print_usage(char *strhead, user_subcommand_t *); void invalid_cmd(const char *cmd_name, user_subcommand_t *cmds); int init_builtin_cmds(void); #endif /* _VIVI_COMMAND_H_ */
#include "command.h" enum ParseState stackedState; static user_command_t *head_cmd = NULL; static user_command_t *tail_cmd = NULL; /* * Parse user command line */ void parseargs(char *argstr, int *argc_p, char **argv, char** resid) { int argc = 0; char c; enum ParseState lastState = PS_WHITESPACE; /* tokenize the argstr */ while ((c = *argstr) != 0) { enum ParseState newState; if (c == ';' && lastState != PS_STRING && lastState != PS_ESCAPE) break; if (lastState == PS_ESCAPE) { newState = stackedState; } else if (lastState == PS_STRING) { if (c == '"') { newState = PS_WHITESPACE; *argstr = 0; } else { newState = PS_STRING; } } else if ((c == ' ') || (c == '\t')) { /* whitespace character */ *argstr = 0; newState = PS_WHITESPACE; } else if (c == '"') { newState = PS_STRING; *argstr++ = 0; argv[argc++] = argstr; } else if (c == '\\') { stackedState = lastState; newState = PS_ESCAPE; } else { /* token */ if (lastState == PS_WHITESPACE) { argv[argc++] = argstr; } newState = PS_TOKEN; } lastState = newState; argstr++; } argv[argc] = NULL; if (argc_p != NULL) *argc_p = argc; if (*argstr == ';') { *argstr++ = '\0'; } *resid = argstr; } void unparseargs(char *argstr, int argc, const char **argv) { int i; for (i = 0; i < argc; i++) { if (argv[i] != NULL) { strcat(argstr, " "); strcat(argstr, argv[i]); } } } /* * Genernal interface */ /* * For (main) commands */ /* add user command */ void add_command(user_command_t *cmd) { if (head_cmd == NULL) { head_cmd = tail_cmd = cmd; } else { tail_cmd->next_cmd = cmd; tail_cmd = cmd; } /*printk("Registered '%s' command\n", cmd->name);*/ } /* find command */ user_command_t *find_cmd(const char *cmdname) { user_command_t *curr; /* do da string compare for the first offset character of cmdstr against each number of the cmdlist */ curr = head_cmd; while(curr != NULL) { if (strncmp(curr->name, cmdname, strlen(cmdname)) == 0) return curr; curr = curr->next_cmd; } return NULL; } /* execute a function */ void execcmd(int argc, const char **argv) { user_command_t *cmd = find_cmd(argv[0]); if (cmd == NULL) { printk("Could not found '%s' command\n", argv[0]); printk("If you want to konw available commands, type 'help'\n"); return; } /*printk("execcmd: cmd=%s, argc=%d\n", argv[0], argc);*/ cmd->cmdfunc(argc, argv); } /* parse and execute a string */ void exec_string(char *buf) { int argc; char *argv[128]; char *resid; while (*buf) { memset(argv, 0, sizeof(argv)); parseargs(buf, &argc, argv, &resid); if (argc > 0) execcmd(argc, (const char **)argv); buf = resid; } } /* * For sub-commands */ void execsubcmd(user_subcommand_t *cmds, int argc, const char **argv) { while (cmds->name != NULL) { if (strncmp(argv[0], cmds->name, strlen(argv[0])) == 0) { /*printk("subexeccmd: cmd=%s, argc=%d\n", argv[0], argc);*/ cmds->cmdfunc(argc, argv); return; } cmds++; } printk("Could not found '%s' sub-command\n", argv[0]); } void print_usage(char *strhead, user_subcommand_t *cmds) { printk("Usage:\n"); while (cmds->name != NULL) { if (strhead) printk("%s ", strhead); if (*cmds->helpstr) printk("%s\n", cmds->helpstr); cmds++; } } void invalid_cmd(const char *cmd_name, user_subcommand_t *cmds) { printk("invalid '%s' command: wrong argumets\n", cmd_name); print_usage(" ", cmds); }
//测试代码 /* help command */ void command_help(int argc, const char **argv) { user_command_t *curr; /* help <command>. invoke <command> with 'help' as an argument */ if (argc == 2) { if (strncmp(argv[1], "help", strlen(argv[1])) == 0) { printk("Are you kidding?\n"); return; } argv[0] = argv[1]; argv[1] = "help"; execcmd(argc, argv); return; } printk("Usage:\n"); curr = head_cmd; while(curr != NULL) { printk(" %s\n", curr->helpstr); curr = curr->next_cmd; } } user_command_t help_cmd = { "help", command_help, NULL, "help [{cmds}] \t\t\t-- Help about help?" }; /* dump command */ void command_dump(int argc, const char *argv[]) { size_t num; unsigned char *p; if (argc == 3) /* size spcified */ num = strtoul(argv[2], NULL, 0, NULL); else num = 16; p = (unsigned char *)strtoul(argv[1], NULL, 0, NULL); hex_dump(p, num); } user_command_t dump_cmd = { "dump", command_dump, NULL, "dump <addr> <length> \t\t-- Display (hex dump) a range of memory." }; /* Register basic user commands */ int init_builtin_cmds(void) { add_command(&dump_cmd); add_command(&help_cmd); return 0; }
相关文章推荐
- 优秀代码赏析(C++,链表)
- 优秀代码赏析(c, 消息处理框架)
- Linux系统管理命令代码解析
- 析构函数 没定义函数体, 根据代码不同,有时候成功, 有时候 报error LNK2019: 无法解析的外部符号 和fatal error LNK1120: 1 个无法解析的外部命令
- [赏析]10个最“优秀”的代码注释
- 【框架解析】Hadoop系统分析(一)--shell命令汇总
- Java线程池框架核心代码解析
- [赏析]10个最“优秀”的代码注释
- CodeIgniter框架代码解析-index.php
- 【优秀框架记录】android解析PDF、XPS文件的第三方类库muPdf
- CTS测试框架 -- 命令解析
- Karto_slam框架与代码解析
- XML形式的配置文件解析框架以及自动代码生成(一)
- CodeIgniter框架代码解析-Common.php
- 【优秀框架记录】 json解析:GSON
- Karto_slam框架与代码解析
- AgileEAS.NET SOA 中间件平台.Net Socket通信框架-完整应用例子-在线聊天室系统-代码解析
- Android通用网络请求解析框架.3(代码实现,公共部分)
- [赏析] 10个最“优秀”的代码注释
- 闲云控制台(一)控制台命令解析框架