|
楼主 |
发表于 2003-7-30 13:29:57
|
显示全部楼层
menu.h menu.c文件:
有些不满意的地方,比如暴露了menusize变量,一开始是因为display模块要用到,后来想想,用一个next函数比较好,还有其他一些地方也不太满意。
- #ifndef _MENU_H_
- #define _MENU_H_
- #include "menudef.h"
- int initmenu(char *);
- void destroymenu(void);
- #endif /* _MENU_H_ */
复制代码
- #include <stdio.h>
- #include <string.h>
- #include <dlfcn.h>
- #include "menu.h"
- struct MENU *menu; /* 全局菜单变量 */
- int menusize; /* 菜单大小(菜单个数) */
- char rcpath[MAXPATH]; /* 菜单配置文件路径 */
- char libpath[MAXPATH]; /* 动态库路径 */
- enum{root, sub}; /* 用于createmenu的参数 */
- static struct MENU *createmenu(int);
- static void readmenuitems();
- /* 读配置文件初始化全局变量menu,分配内存
- * 参数:menurc:配置文件名
- * 返回值:0:正确;-1:错误
- */
- int
- initmenu(char *menurc)
- {
- FILE *fp;
- char line[MAXLINE], *t;
- struct MENU *mp;
- if((fp = fopen(menurc, "r")) == NULL){
- sprintf(line, "cannot open file %s", menurc);
- perror(line);
- return(-1);
- }
- while(fgets(line, MAXLINE - 1, fp)){
- line[strlen(line) - 1] = '\0';
- if((t = strtok(line, " \t")) == NULL)
- continue;
- if(!strcasecmp(t, "rootmenu")){ /* 创建根菜单 */
- if((mp = createmenu(root)) == NULL){
- destroymenu();
- return(-1);
- }
- readmenuitems(mp, fp);
- mp->count++; /* 增加exit菜单项 */
- strcpy(mp->item[mp->count - 1].name, "exit");
- mp->item[mp->count - 1].accel = 'x';
- mp->item[mp->count - 1].options = SYSMENU | SYS_EXIT;
- }else if(strcasecmp(t, "submenu") == 0){ /* 创建子菜单 */
- if((mp = createmenu(sub)) == NULL){
- destroymenu();
- return(-1);
- }
- readmenuitems(mp, fp);
- mp->count++; /* 增加return和root菜单项 */
- strcpy(mp->item[mp->count - 1].name, "return");
- mp->item[mp->count - 1].accel = 't';
- mp->item[mp->count - 1].options = SYSMENU | SYS_RET;
- mp->count++;
- strcpy(mp->item[mp->count - 1].name, "root");
- mp->item[mp->count - 1].accel = 'r';
- mp->item[mp->count - 1].options = SYSMENU | SYS_ROOT;
- }
- }
- }
- void
- destroymenu(void)
- {
- int i, j;
- for(i = 0; i < menusize; i++)
- for(j = 0; j < menu[i].count; j++)
- if(menu[i].item[j].options == SUBMENU || menu[i].item[j].options == COMMAND)
- free(menu[i].item[j].proc);
- free(menu);
- }
- /* 创建菜单
- * 参数:type:菜单类型(root,sub)
- * 返回值:新分配菜单的指针;NULL:错误
- */
- static struct MENU *
- createmenu(int type)
- {
- char *t;
- if((menu = (struct MENU *)realloc(menu, (menusize + 1) * sizeof(struct MENU))) == NULL){
- fprintf(stderr, "realloc menu error\n");
- return(NULL);
- }
- if(type == root)
- strcpy(menu[menusize].name, "root");
- else if(type == sub){
- t = strtok(NULL, " \t");
- strcpy(menu[menusize].name, t);
- }
- menu[menusize].count = 0;
- menusize++;
- return(&menu[menusize - 1]);
- }
- /* 读配置文件初始化菜单项
- * 参数:m:包含菜单项的菜单;fp:配置文件指针
- */
- static void
- readmenuitems(struct MENU *mp, FILE *fp)
- {
- char line[MAXLINE], *name, *type, *menuname, *libname, *funcname, *command;
- int i = -1;
- char accel[] = "1234567890abcdefghijklmno"; /* 为简单起见使用指定快捷键的办法 */
- while(fgets(line, MAXLINE - 1, fp)){
- line[strlen(line) - 1] = '\0';
- if((name = strtok(line, " \t")) == NULL)
- continue;
- if(!strcasecmp(name, "endmenu"))
- break;
- ++i;
- strncpy(mp->item[i].name, name, MAXWIDTH);
- mp->count++;
- mp->item[i].accel = accel[i];
- if((type = strtok(NULL, " \t")) == NULL){
- mp->item[i].options = ERR_ITEM;
- continue;
- }
- if(!strcasecmp(type, "submenu")){
- mp->item[i].options = SUBMENU;
- if((menuname = strtok(NULL, " \t")) == NULL){
- mp->item[i].options = ERR_ITEM;
- continue;
- }
- mp->item[i].proc = (void *)malloc(strlen(menuname) + 1);
- strcpy(mp->item[i].proc, menuname);
- }else if(!strcasecmp(type, "function")){
- void *libc, (*func)();
- char *libfullname;
- mp->item[i].options = FUNCTION;
- if((libname = strtok(NULL, " \t")) == NULL){
- mp->item[i].options = ERR_ITEM;
- continue;
- }
- libfullname = (char *)malloc(strlen(libpath) + strlen(libname) + 2);
- sprintf(libfullname, "%s/%s", libpath, libname);
- if((libc = (void *)dlopen(libfullname, RTLD_LAZY)) == NULL)
- mp->item[i].options = ERR_ITEM;
- else if((funcname = strtok(NULL, " \t")) == NULL)
- mp->item[i].options = ERR_ITEM;
- else if((func = (void (*)())dlsym(libc, funcname)) == NULL)
- mp->item[i].options = ERR_ITEM;
- else
- mp->item[i].proc = func;
- free(libfullname);
- }else if(!strcasecmp(type, "command")){
- mp->item[i].options = COMMAND;
- command = type + strlen(type) + 1; /* 这里缺少错误检查 */
- mp->item[i].proc = (void *)malloc(strlen(command) + 1);
- strcpy(mp->item[i].proc, command);
- }
- }
- }
复制代码 |
|