/**************************************************************************************************/ /* Copyright (C) mc2lab.com, SSE@USTC, 2014-2015 */ /* */ /* FILE NAME : menu.h */ /* PRINCIPAL AUTHOR : Ls */ /* SUBSYSTEM NAME : menu */ /* MODULE NAME : menu */ /* LANGUAGE : C */ /* TARGET ENVIRONMENT : ANY */ /* DATE OF FIRST RELEASE : 2014/08/31 */ /* DESCRIPTION : This is a menu program */ /**************************************************************************************************/ /* * Revision log: * * Created by Ls, 2015/01/18 * */ #ifndef MENU_H #define MENU_H /* add cmd to menu */ int MenuConfig(char * cmd, char * desc, int (*handler)()); /* Menu Engine Execute */ int ExecuteMenu(); #endif //MENU_H
/**************************************************************************************************/ /* Copyright (C) mc2lab.com, SSE@USTC, 2014-2015 */ /* */ /* FILE NAME : menu.c */ /* PRINCIPAL AUTHOR : Ls */ /* SUBSYSTEM NAME : menu */ /* MODULE NAME : menu */ /* LANGUAGE : C */ /* TARGET ENVIRONMENT : ANY */ /* DATE OF FIRST RELEASE : 2014/08/31 */ /* DESCRIPTION : This is a menu program */ /**************************************************************************************************/ /* * Revision log: * * Created by Ls, 2015/01/18 * */ #include <stdio.h> #include <stdlib.h> #include "linktable.h" #include "menu.h" tLinkTable * head = NULL; int Help(int argc, char *argv[]); #define CMD_MAX_LEN 1024 #define CMD_MAX_ARGV_NUM 32 #define DESC_LEN 1024 #define CMD_NUM 10 /* data struct and its operations */ typedef struct DataNode { tLinkTableNode * pNext; char* cmd; char* desc; int (*handler)(int argc, char *argv[]); } tDataNode; int SearchCondition(tLinkTableNode * pLinkTableNode, void * args) { char * cmd = (char*) args; tDataNode * pNode = (tDataNode *)pLinkTableNode; if(strcmp(pNode->cmd, cmd) == 0) { return SUCCESS; } return FAILURE; } /* find a cmd in the linklist and return the datanode pointer */ tDataNode* FindCmd(tLinkTable * head, char * cmd) { return (tDataNode*)SearchLinkTableNode(head,SearchCondition, (void *) cmd); } /* show all cmd in listlist */ int ShowAllCmd(tLinkTable * head) { tDataNode * pNode = (tDataNode*)GetLinkTableHead(head); while(pNode != NULL) { printf("%s - %s\n", pNode->cmd, pNode->desc); pNode = (tDataNode*)GetNextLinkTableNode(head,(tLinkTableNode *)pNode); } return 0; } /* add cmd to menu */ int MenuConfig(char * cmd, char *desc, int (*handler)(int argc, char *argv[])) { tDataNode * pNode = NULL; if (head == NULL) { head = CreateLinkTable(); pNode = (tDataNode *)malloc(sizeof(tDataNode)); pNode->cmd = "help"; pNode->desc = "Menu List"; pNode->handler = Help; AddLinkTableNode(head, (tLinkTableNode *)pNode); } pNode = (tDataNode *)malloc(sizeof(tDataNode)); pNode->cmd = cmd; pNode->desc = desc; pNode->handler = handler; AddLinkTableNode(head, (tLinkTableNode *)pNode); return 0; } /* Menu Engine Execute */ int ExecuteMenu() { /* cmd line begins */ while(1) { int argc = 0; char *argv[CMD_MAX_ARGV_NUM]; char cmd[CMD_MAX_LEN]; char *pcmd = NULL; printf("Input a cmd > "); //scanf("%s", cmd); pcmd = fgets(cmd, CMD_MAX_LEN, stdin); if(pcmd == NULL) { continue; } /* convert cmd to argc/argv */ // printf("%s\n", pcmd); pcmd = strtok(pcmd, " "); while(pcmd != NULL && argc < CMD_MAX_ARGV_NUM) { argv[argc++] = pcmd; // printf("%s\n", pcmd); pcmd = strtok(NULL, " "); } // if(argc == 1) // { int len = strlen(argv[argc-1]); *(argv[argc-1] + len - 1) = '\0'; // } tDataNode *p = FindCmd(head, argv[0]); if( p == NULL) { printf("This is a wrong cmd!\n "); continue; } printf("%s - %s\n", p->cmd, p->desc); if(p->handler != NULL) { p->handler(argc, argv); } } return 0; } int Help(int argc, char *argv[]) { ShowAllCmd(head); return 0; }
# # # Makefile for Menu Program # CC_PTHREAD_FLAGS = -lpthread CC_FLAGS = -c CC_OUTPUT_FLAGS = -o CC = gcc RM = rm RM_FLAGS = -f TARGET = test OBJS = linktable.o menu.o test.o all: $(OBJS) $(CC) $(CC_OUTPUT_FLAGS) $(TARGET) $(OBJS) .c.o: $(CC) $(CC_FLAGS) $< clean: $(RM) $(RM_FLAGS) $(OBJS) $(TARGET) *.bak gcc linktable.c menu.c test.c -o menu