⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 get_menu.c

📁 在SCO UNIX制定界面程序 可根据文件配制菜单,而不必修改源程序,非常方便
💻 C
📖 第 1 页 / 共 2 页
字号:
#include	<fcntl.h>
#include	"menu.h"
#include	"mytools.h"

#define	MAX_ADD_ITEMS	100

#define	F_ITEM_ID	0
#define	F_ITEM_NAME	1
#define	F_PROC_TYPE	2
#define	F_PROC_NAME	3
#define	F_MENU_ID	4
#define	F_SHELL		5
#define	F_HELPID	6
#define	F_PARAM		7

struct S_zmenu_item_struc {
	char	sItemId[11];		/* 菜单选择项标识号	*/
	char	sItemName[31];		/* 菜单选择项名          */
        char    cProcType;		/* 处理类型 M:子菜单 E:退出菜单 */
					/* X:shell命令;F:函数调用    */
	char	sProcName[21];		/* 激活菜单操作的函数或过程名 */
					/* 当proc_type为'F','M','E'时用 */
	char	sMenuId[11];		/* 菜单标识号(proc_type='M'时需填 */
        char	sShell[128];		/* 当proc_type='X'时,shell命令串 */
        char	sHelpID[11];		/* 帮助信息标识号 */

	int	iLine;			/* Menu.txt中的行号 */
	char	sParam[30];		/* add liujin */
} *pMenuItem;

int	iMenuItemCount;
int	iMenuCount;

/*
 * 初始处理菜单定义
 *
 * 先从文件MENU_add(view/Menu.add)中获取附加的菜单选择项定义
 * 再从文件MENU_F(view/nas.menu)中读取并分析运行时菜单结构定义
 *
 * 同时整理SMenu[],SMenuItem[]
 * 置两数组的最大下标iMenuCount,iMenuItemCount(全局变量)
 */
GetMenu(pfMenuFile, pfAddFile)
FILE	*pfMenuFile;	/* 菜单描述文件 */
FILE	*pfAddFile;	/* 附加菜单项定义文件 */
{
	int	i;
	int	iRetAdd, iRetMenu;

	/*
	 * 获取固定菜单项数
	 */
	iMenuItemCount = 0;
	for (i = 0; i < MAX_MENU_ITEMS; i++) {
		if (!strcmp(SMenuItem[i].sItemId, "I_END"))
			break;
	}
	iMenuItemCount = i;

	/*
	 * 获取固定子菜单数
	 */
	iMenuCount = 0;
	for (i = 0; i < MAX_MENUS; i++) {
		if (!strcmp(SMenu[i].sMenuId, "M_END"))
			break;
	}
	iMenuCount = i;

	if (pfAddFile != NULL) {
		/*
		 * 获取临时增加的菜单结构项
		 */
		iRetAdd = GetAddMenu(pfAddFile);
	}

	/*
	 * 获取当前使用的菜单结构安排(从文件view/nas.view)
	 */
	iRetMenu = GetActiveMenu(pfMenuFile);

	/*
	 * 只要有错就返回错
	 */
	if (iRetAdd == -1 || iRetMenu == -1)
		return(-1);
	/*
	 * 只要有警告就返回警告
	 */
	if (iRetAdd < 0 || iRetMenu < 0)
		return(-2);

	return(0);

}

/*
 * 获取临时增加的菜单结构信息
 */
GetAddMenu(fp)
FILE	*fp;
{
	char	sTmpStr[1024];
	int	iCount = 0;
	int	i, j, k, ii;
	char	c;
	char	sTmpBuffer[64];
	char	sDate[12], sTime[12];
	int	iLine = 0;
	int	iItemAddCount = 0;
	char	cErrorFlag = 0;
	char	cWarnFlag = 0;
	char	sErrorString[1024];
	char	sTmpString[128];
	int	iProcOrd;
	int	iMenuOrd;
	char	sMenuId[10];

	FILE	*pfErrorFile;

	getdatef(sDate, "-");
	gettimef(sTime, ":");
	pfErrorFile = fopen("/tmp/Menu.match.error", "w+");
	if (pfErrorFile == NULL)
		pfErrorFile = stderr;

	fprintf(pfErrorFile, "\n%s %s ****Start 附加菜单项文件(%s)分析\n\n", sDate, sTime, MENU_add);
	/*
	 * 分配菜单信息临时结构空间
	 */
	if ((pMenuItem = (struct S_zmenu_item_struc *)malloc(MAX_ADD_ITEMS * sizeof(struct S_zmenu_item_struc ))) == NULL) {
		fprintf(pfErrorFile, "Malloc memory error!\n");
		return(-1);
	}

	/*
	 * 预处理附加的菜单选择项
	 */
	i = 0;
	while (!feof(fp)) {
		if (fgets(sTmpStr, 1024, fp) == NULL)
			break;
		iLine ++;
		del_NL_CR(sTmpStr);
		del_all_space(sTmpStr);
		if (sTmpStr[0] == '\0')	/* 空行,则忽略 */
			continue;
		/* %MENU_DEFINE 标示菜单项定义开始 */
		if (!strncmp(sTmpStr, "%MENU_DEFINE", 12))
			break;
		j = 0;
		while (sTmpStr[j] != '|') {	/* 以|开头,去掉前面的字符 */
			if (sTmpStr[j] == '\0' || sTmpStr[j] == '#')
				break;
			j++;
		}
		if (sTmpStr[j] == '#')	/* 注释行,则忽略 */
			continue;
		if (sTmpStr[j] == '\0') {	/* 无|符,则忽略 */
			fprintf(pfErrorFile, "行%d: 数据格式错! (忽略)\n", iLine);
			cWarnFlag = 1;
			continue;
		}
		strcpy(sTmpStr, &sTmpStr[j]);

		iCount = zut_get_seperate(sTmpStr, '|');
		if (iCount < 8) {	/* 该行数据不完整,忽略 */ 
			if ( j > 0)
				fprintf(pfErrorFile, "行%d: 数据不完整,可能头上缺\'|\'! (忽略)\n", iLine);
			else
				fprintf(pfErrorFile, "行%d: 数据不完整! (忽略)\n", iLine);
			cWarnFlag = 1;
			continue;
		}
		sErrorString[0] = '\0';
		for (j = 0; j < iCount; j++) {
			zut_get_fld(sTmpStr, j+1, sTmpBuffer, '|');
			del_all_space(sTmpBuffer);
			switch (j) {
			case	F_ITEM_ID:
				if (strlen(sTmpBuffer) > 10) {
					sprintf(sTmpString, "\n\t第%d(ITEM_ID)域太长", j+1);
					strcat(sErrorString, sTmpString);
					cErrorFlag = 1;
					break;
				}
				strcpy(pMenuItem[i].sItemId, sTmpBuffer);
				break;
			case	F_ITEM_NAME:
				if (strlen(sTmpBuffer) > 30) {
					sprintf(sTmpString, "\n\t第%d(ITEM_NAME)域太长", j+1);
					strcat(sErrorString, sTmpString);
					cErrorFlag = 1;
					break;
				}
				strcpy(pMenuItem[i].sItemName, sTmpBuffer);
				break;
			case	F_PROC_TYPE:
				if (strlen(sTmpBuffer) > 1) {
					sprintf(sTmpString, "\n\t第%d(PROC_TYPE)域太长", j+1);
					strcat(sErrorString, sTmpString);
					cErrorFlag = 1;
					break;
				}
				if (sTmpBuffer[0] != 'F' && sTmpBuffer[0] != 'f'
				    && sTmpBuffer[0] != 'E' && sTmpBuffer[0] != 'e'
				    && sTmpBuffer[0] != 'M' && sTmpBuffer[0] != 'm'
				    && sTmpBuffer[0] != 'X' && sTmpBuffer[0] != 'x') {
					sprintf(sTmpString, "\n\t第%d(PROC_TYPE)域选择项处理类型只应为F,E,M,X", j+1);
					strcat(sErrorString, sTmpString);
					cErrorFlag = 1;
					break;
				}
				pMenuItem[i].cProcType = toupper(sTmpBuffer[0]);
				break;
			case	F_PROC_NAME:
				if (strlen(sTmpBuffer) > 30) {
					sprintf(sTmpString, "\n\t第%d(PROC_NAME)域太长", j+1);
					strcat(sErrorString, sTmpString);
					cErrorFlag = 1;
					break;
				}
				strcpy(pMenuItem[i].sProcName, sTmpBuffer);
				break;
			case	F_MENU_ID:
				if (strlen(sTmpBuffer) > 10) {
					sprintf(sTmpString, "\n\t第%d(MENU_ID)域太长", j+1);
					strcat(sErrorString, sTmpString);
					cErrorFlag = 1;
					break;
				}
				strcpy(pMenuItem[i].sMenuId, sTmpBuffer);
				break;
			case	F_SHELL:
				if (strlen(sTmpBuffer) > 127) {
					sprintf(sTmpString, "\n\t第%d(SHELL)域太长", j+1);
					strcat(sErrorString, sTmpString);
					cErrorFlag = 1;
					break;
				}
				strcpy(pMenuItem[i].sShell, sTmpBuffer);
				break;
			case	F_HELPID:
				if (strlen(sTmpBuffer) > 10) {
					sprintf(sTmpString, "\n\t第%d(HELPID)域太长", j+1);
					strcat(sErrorString, sTmpString);
					cErrorFlag = 1;
					break;
				}
				strcpy(pMenuItem[i].sHelpID, sTmpBuffer);
				break;
			case	F_PARAM:
				if (strlen(sTmpBuffer) > 30) {
					sprintf(sTmpString, "\n\t第%d(SHELL)域太长", j+1);
					strcat(sErrorString, sTmpString);
					cErrorFlag = 1;
					break;
				}
				strcpy(pMenuItem[i].sParam, sTmpBuffer);
				break;
			default:
				break;
			}
		}
		if (cErrorFlag == 1) {
			fprintf(pfErrorFile, "行%d: 以下域有错", iLine);
			fprintf(pfErrorFile, "%s\n", sErrorString);
			cWarnFlag = 1;
			continue;
		}
		pMenuItem[i].iLine = iLine;
		i++;

	}

	iItemAddCount = i;

	/*
	 * 处理附加的菜单项
	 */
#define M_MENU_ID	0
#define M_MENU_NAME	1
#define	M_ROW		2
#define	M_COL		3
#define	M_DISP_FMT	4
	i = 0;
	while (!feof(fp)) {
		if (fgets(sTmpStr, 1024, fp) == NULL)
			break;
		iLine ++;
		del_NL_CR(sTmpStr);
		del_all_space(sTmpStr);
		if (sTmpStr[0] == '\0')	/* 空行,则忽略 */
			continue;

		j = 0;
		while (sTmpStr[j] != '|') {	/* 以|开头,去掉前面的字符 */
			if (sTmpStr[j] == '\0' || sTmpStr[j] == '#')
				break;
			j++;
		}
		if (sTmpStr[j] == '#')	/* 注释行,则忽略 */
			continue;
		if (sTmpStr[j] == '\0') {	/* 无|符,则忽略 */
			fprintf(pfErrorFile, "行%d: 数据格式错! (忽略)\n", iLine);
			cWarnFlag = 1;
			continue;
		}
		strcpy(sTmpStr, &sTmpStr[j]);

		iCount = zut_get_seperate(sTmpStr, '|');
		if (iCount < 5) {	/* 该行数据不完整,忽略 */
			if ( j > 0)
				fprintf(pfErrorFile, "行%d: 数据不完整,可能头上缺\'|\'! (忽略)\n", iLine);
			else
				fprintf(pfErrorFile, "行%d: 数据不完整! (忽略)\n", iLine);
			cWarnFlag = 1;
			continue;
		}
		sErrorString[0] = '\0';
		for (j = 0; j < iCount; j++) {
			zut_get_fld(sTmpStr, j+1, sTmpBuffer, '|');
			del_all_space(sTmpBuffer);
			switch (j) {
			case	M_MENU_ID:
				if (strlen(sTmpBuffer) > 10) {
					sprintf(sTmpString, "\n\t第%d(MENU_ID)域太长", j+1);
					strcat(sErrorString, sTmpString);
					cErrorFlag = 1;
					break;
				}
				strcpy(sMenuId, sTmpBuffer);
				/*
				 * 在SMenu[]中查找sMenuId
				 */
				for (k = 0; k < iMenuCount; k++) {
					if (!strcmp(sMenuId, SMenu[k].sMenuId))
						break;
				}
				if (k < iMenuCount
					&& SMenuItem[k].cReplace != 1
					&& strcmp(G_oper_no, "00")!= 0) {
					sprintf(sErrorString, "第%d(MENU_ID)域对应的菜单项(%s)不允许更改, 此行忽略。\n",
						j+1, pMenuItem[j].sMenuId);
					cErrorFlag = 1;
					continue;
				}
				if (k == iMenuCount) {
					/*
					 * 若找不到则在后面新添一项
					 */
					strcpy(SMenu[k].sMenuId, sMenuId);
					iMenuCount++;
					if (iMenuCount >= MAX_MENUS) {
						sprintf(sErrorString, "第%d(MENU_ID)域不可再新增, 此行忽略。\n",
							j+1, pMenuItem[j].sMenuId);
						cErrorFlag = 1;
						continue;
					}
					/*
					 * 置M_END以防后用
					 */
					SMenu[iMenuCount].sMenuName[0] = '\0';
					strcpy(SMenu[iMenuCount].sMenuId, "M_END");
				}
				break;
			case	M_MENU_NAME:
				if (strlen(sTmpBuffer) > 30) {
					sprintf(sTmpString, "\n\t第%d(MENU_NAME)域太长", j+1);
					strcat(sErrorString, sTmpString);
					cErrorFlag = 1;
					break;
				}
				strcpy(SMenu[k].sMenuName, sTmpBuffer);
				break;
			case	M_ROW:
				if (strlen(sTmpBuffer) > 3) {
					sprintf(sTmpString, "\n\t第%d(M_ROW)域太长", j+1);
					strcat(sErrorString, sTmpString);
					cErrorFlag = 1;
					break;
				}
				if (atoi(sTmpBuffer) < 2 || atoi(sTmpBuffer) > 21) {
					sprintf(sTmpString, "\n\t第%d(M_ROW)域Y坐标应在2-21之间", j+1);
					strcat(sErrorString, sTmpString);
					cErrorFlag = 1;
					break;
				}
				SMenu[k].iLocateY = atoi(sTmpBuffer);
				if (SMenu[k].iLocateY % 2 != 0) {
					sprintf(sTmpString, "\n\t第%d(M_ROW)域Y坐标应为偶数", j+1);
					strcat(sErrorString, sTmpString);
					cErrorFlag = 1;
					break;
				}
				break;
			case	M_COL:
				if (strlen(sTmpBuffer) > 3) {
					sprintf(sTmpString, "\n\t第%d(M_COL)域太长", j+1);
					strcat(sErrorString, sTmpString);
					cErrorFlag = 1;
					break;
				}
				if (atoi(sTmpBuffer) < 2 || atoi(sTmpBuffer) > 70) {
					sprintf(sTmpString, "\n\t第%d(M_COL)域X坐标应在2-70之间", j+1);
					strcat(sErrorString, sTmpString);
					cErrorFlag = 1;
					break;
				}
				SMenu[k].iLocateX = atoi(sTmpBuffer);
				if (SMenu[k].iLocateX % 2 != 0) {
					sprintf(sTmpString, "\n\t第%d(M_COL)域X坐标应为偶数", j+1);
					strcat(sErrorString, sTmpString);
					cErrorFlag = 1;
					break;
				}
				break;
			case	M_DISP_FMT:
				if (sTmpBuffer[0] != 'H'
				    && sTmpBuffer[0] != 'V') {
					sprintf(sTmpString, "\n\t第%d(DISP_FMT)域显示格式只应为H(横向)或V(纵向)", j+1);
					strcat(sErrorString, sTmpString);
					cErrorFlag = 1;
					break;
				}
				SMenu[k].iDispFormat = sTmpBuffer[0];
				break;
			default:
				break;
			}
		}
		if (cErrorFlag == 1) {
			fprintf(pfErrorFile, "行%d: 以下域有错", iLine);
			fprintf(pfErrorFile, "%s\n", sErrorString);
			cWarnFlag = 1;
			continue;
		}
		/*
		 * 将子菜单选择项置为空,以后通过view/nas.menu具体定义
		 */
		SMenu[k].iMenuItemSet[0] = -1;
		i++;
	}

	/*
	 * 正式处理附加菜单选择项
	 */
	for (j = 0; j < iItemAddCount; j++) {
		iProcOrd = -1;
		iMenuOrd = -1;
		if (pMenuItem[j].cProcType == 'F') {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -