📄 get_menu.c
字号:
#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 + -