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

📄 cli_cmdreg.c

📁 命令行在嵌入式系统的实现
💻 C
📖 第 1 页 / 共 5 页
字号:
    }

    return G_SUCCESS;

}

_U32 CT_RegParamToLink(CT_PARAMGROUP_P pParamLink,
                                CT_PARAMETER_P pNewParam)
{
    CT_PARAMETER_P pParam,pParam1;

    if((pParamLink == G_NULL) || (pNewParam == G_NULL))
    {
        return G_FAILURE;
    }

    pParam = pParamLink->pParam;
    if(pParam == G_NULL)
    {
        pParamLink->pParam = pNewParam;
        pParamLink->ulNumber++;
    }
    else
    {
        pParam1 = pParam;
        while(pParam != G_NULL)
        {
            if(CT_PARAM_NEED_NAME(pParam) && CT_PARAM_NEED_NAME(pNewParam))
            {
                if(CT_IS_SAME_PARAM(pParam,pNewParam))
                {
                    return G_FAILURE;
                }
            }
            pParam1 = pParam;
            pParam = pParam->pNext;
        }
        /* All parameters in link have null-parent-pointers */
        pParam1->pNext = pNewParam;
        pNewParam->pPrevious = pParam1;
        pParamLink->ulNumber++;
    }

    return G_SUCCESS;

}

/*********************************************************************/
/* 函数名称 : CLI_GlobalCmdLink()                                    */
/* 函数功能 : 全局模式的命令链接                                     */
/* 输入参数 : 无                                                     */
/* 输出参数 : 无                                                     */
/* 返回     : 成功、失败                                             */
/* 上层函数 : CLI_ProcessInit                                        */
/* 创建者   :                                                        */
/* 修改记录 :                                                        */
/*********************************************************************/
_U32 CLI_GlobalCmdLink(_VOID)
{
    _U32 ulMode;
    CT_OBJECT_P pObject, pGlbObj;

    if (m_sCliSysModes[CTM_GLOBAL].pObject == G_NULL
     || m_sCliSysModes[CTM_GLOBAL].pObject->pSubObject == G_NULL)
    {
        /* ??? LingJian_Tailor : Change form G_FAILURE to G_SUCCESS */
        return G_SUCCESS;
    }

    pGlbObj = m_sCliSysModes[CTM_GLOBAL].pObject->pSubObject;

    for (ulMode = 0; ulMode < MAX_MODE_NUM; ulMode++)
    {
        if (ulMode == CTM_GLOBAL || m_sCliSysModes[ulMode].pObject == G_NULL )
            continue;
        pObject = m_sCliSysModes[ulMode].pObject->pSubObject;
        if (pObject == G_NULL)
            continue;

        while (pObject->pNext != G_NULL)
            pObject = pObject->pNext;
        pObject->pNext = pGlbObj;
    }
    return G_SUCCESS;
}

//*********************************************************
// 自动注册开始 {{{{

/* 子功能全局变量声明 */
static _U8 m_ucPosIndex = 1;   /* 变量的绝对位置索引 */

/*lint -e715 */
_U32 CT_CmdAutoRegist
              (const _S8 *szCmd,              //命令格式化串
               _U8  ucMode,                   //命令所属模式
               CLI_OPERAT_LEVEL_T   ucLevel,  //命令使用等级
               CLI_CALLBACK_EXEC_FUN pFunc,   //命令执行函数
               _U8  ucModeChange,             //模式转换属性(非模式转换命令填CT_MC_NULL)
               _U8  ucNewMode,                //新模式的ID  (仅当上一参数为CT_MC_NEW时有意义 )
               _U32 ulHelp1,                  //第一个对象的帮助信息
               _U32 ulHelp2,                  //第二个对象的帮助信息
               _U32 ulHelp3)
{
    (_VOID)ucMode;
    return G_SUCCESS;
}
/*lint -restore */


/*-------------------------------------------------------------------*/
/* 函数名称 : CT_CmdAutoRegist                                       */
/* 功    能 : 命令自动注册函数接口                                   */
/* 输入参数 : 参数说明见函数定义                                     */
/* 输出参数 : 无                                                     */
/* 返回     : 注册成功/失败                                          */
/* 调用说明 : 调用者自己保证命令语法的正确性,详细说明可以参见命令行  */
/*            说明文档. 注册否定形式的命令,须确定该命令的肯定形式已  */
/*            经注册,如注册no timeout命令之前应该已经注册timeout命令 */
/* 典型示例 : CT_CmdAutoRegist("cmdtest user-test: <type(u1~3)>",    */
/*             CTM_DBG, CT_AL_OPERATOR,  CLI_CmdTest4, CT_MC_NULL,   */
/*             NULL_MODE, CLI_ML_NULL,  CLI_ML_NULL,  CLI_ML_NULL ); */
/*-------------------------------------------------------------------*/
_U32 CT_CmdAutoRegistWithLocfun
              (const _S8 *szCmd,              //命令格式化串
               _U8  ucMode,                   //命令所属模式
               CLI_OPERAT_LEVEL_T   ucLevel,  //命令使用等级
               CLI_CALLBACK_EXEC_FUN pLocFunc,//命令定位函数
               CLI_CALLBACK_EXEC_FUN pFunc,   //命令执行函数
               _U8  ucModeChange,             //模式转换属性(非模式转换命令填CT_MC_NULL)
               _U8  ucNewMode,                //新模式的ID  (仅当上一参数为CT_MC_NEW时有意义 )
               _U32 ulHelp1,                  //第一个对象的帮助信息
               _U32 ulHelp2,                  //第二个对象的帮助信息
               _U32 ulHelp3)
{
    _S8 szCmdString[CT_MAX_CMD_FORMAT + 1];  /* 命令的表达式可以超过命令的实际长度256,暂定上限为1000*/
    _S8 szToken[CT_MAX_CMDLEN];
    _S8 *pCurPos;
    _U32  ulRet, ulIndex = 0;
    _U32  ulHelpID[CT_MAX_OBJECT_NUM], ulCheckID = ML_NULL_STRING_SID;
    _U8   ucIsNoForm = 0;
    CT_OBJECT_P pObject[CT_MAX_OBJECT_NUM], pObj = G_NULL;
    CT_OBJECT_P pFirstObj = G_NULL;
    CT_MODE_T   *sMode;
    CT_PARAMGROUP_P *pParamLink = G_NULL;

    CLI_ASSURE_OR_FAIL(szCmd != G_NULL && EOS_StrLen(szCmd) > 0);

    /* DEBUG模式的命令只能在调试版本中存在 */
#if !CLI_DEBUG_ON
    if (ucMode == CTM_DBG)
        return G_SUCCESS;
#endif

    EOS_StrCpy(szCmdString, szCmd);
    (_VOID)_AffirmStrBeLower(szCmdString);

    /* 命令的注册语法检查 */
    if (CT_IsCmdValid(szCmdString) != G_SUCCESS)
    {
        DBG_Out(PID_CLI, CLI_DBGOUT_ERR, "\r\n CLI: 命令格式不正确:%s",szCmd);
        DBG_ASSERT(0);
        return G_FAILURE;
    }

    /* 其它参数合法性检查 */
    if (ucMode >= MAX_MODE_NUM || ucNewMode >= MAX_MODE_NUM || ucLevel > CT_AL_DEBUG)
    {
        DBG_Out(PID_CLI, CLI_DBGOUT_ERR,
            "\r\n CLI: 注册命令存在不合法参数:mode-%d, new mode-%d, level-%d", ucMode, ucNewMode, ucLevel);
        DBG_ASSERT(0);
        return G_FAILURE;
    }

    ulHelpID[0] = ulHelp1;
    ulHelpID[1] = ulHelp2;
    ulHelpID[2] = ulHelp3;

    for (ulIndex = 0; ulIndex < 3; ulIndex++)
    {
        if (ulHelpID[ulIndex] != ML_NULL_STRING_SID)
            ulCheckID = ulHelpID[ulIndex];
    }

    #ifdef PC_LINT
    ulCheckID = ulCheckID;
    #endif

    if(!EOS_StrNCmp(szCmdString, "show ", 5))
        ucLevel = CT_AL_QUERY;

    pCurPos = szCmdString;
    ulIndex = 0;
    /* 如果是否定形式的命令,则命令树中应该已经存在其肯定形式,
       因此不用再创建对象,而采取搜索对象的形式 */
    if (EOS_StrNCmp("no ", pCurPos, 3) == 0)
    {
        ucIsNoForm = 1;
        pCurPos   += 3;    //跳过"no "
        if ((sMode = CI_GetMode(ucMode)) == G_NULL)
        {
            DBG_Out(PID_CLI, CLI_DBGOUT_ERR,
                    "\r\n CLI: 该命令的肯定形式尚未注册 : %s", szCmd);
            DBG_ASSERT(0);
            return G_FAILURE;
        }
        pObj = sMode->pObject;   /* 从模式对象开始搜索 */
    }

    /* 注册对象 */
    while((ulRet = CT_GetObj(pCurPos, szToken)) != G_FAILURE)
    {
        if (ulRet == TOKEN_GET_ONLYSPACE)
        {
            pCurPos++;
            continue;
        }
        if (ulRet == TOKEN_GET_CMDNULL)
        {
            DBG_Out(PID_CLI, CLI_DBGOUT_ERR,
                    "\r\n CLI: 从:%s 中获取命令字失败 : %s", szCmd);
            DBG_ASSERT(0);
            return G_FAILURE;
        }

        pCurPos += EOS_StrLen(szToken);

        /* 注册3个以上对象的命令不成功 */
        if (ulIndex > 2)
        {
            DBG_Out(PID_CLI, CLI_DBGOUT_ERR,
                    "\r\n  CLI: 关键命令字过多 : %s!", szCmd);
            DBG_ASSERT(0);
            return G_FAILURE;
        }

        if (EOS_StrLen(szToken) >= MAX_TOKEN_SIZE)
        {
            DBG_Out(PID_CLI, CLI_DBGOUT_ERR,
                    "\r\n  CLI: 超长命令字注册 : %s!", szToken);
            DBG_ASSERT(0);
            return G_FAILURE;
        }

        /* 肯定形式的对象自动注册 */
        if (ucIsNoForm == 0)
        {
            if (ulRet == TOKEN_GET_LASTOBJ)
            {
                /* 最后一个命令对象需要处理其操作方法: 回调函数或模式转换 */
                switch (ucModeChange)
                {
                    case CT_MC_NULL:
                        /* 对于非模式转换的命令需要保证带回调函数 */
                        if (pFunc == G_NULL)
                        {
                            DBG_Out(PID_CLI, CLI_DBGOUT_ERR,
                                    "\r\n CLI: 命令(%s)\r\n      的对象(%s)没有执行操作!", szCmd, szToken);
                            DBG_ASSERT(0);
                            return G_FAILURE;
                        }
                        pObject[ulIndex] = CT_CreateObject(szToken, ucMode, ucLevel,
                                        pFunc, G_FALSE, CT_MC_NULL, G_NULL);
                        pObject[ulIndex]->action.pLocFun = pLocFunc;
                        break;
                    /* 以下是对各种模式转换类型的对象注册 */
                    case CT_MC_END:
                        pObject[ulIndex] = CT_CreateObject(szToken, ucMode, ucLevel,
                                        pFunc, G_TRUE, CT_MC_END, G_NULL);
                        break;
                    case CT_MC_EXIT:
                        pObject[ulIndex] = CT_CreateObject(szToken, ucMode, ucLevel,
                                        pFunc, G_TRUE, CT_MC_EXIT, G_NULL);
                        break;
                    case CT_MC_NEW:
                        /* 如果是转换到新模式,需要保证新模式的正确性 */
                        if (ucNewMode == NULL_MODE)
                        {
                            DBG_Out(PID_CLI, CLI_DBGOUT_ERR,
                                "\r\n CLI: 模式转换命令注册错误: 新模式ID: %d", ucNewMode);
                            DBG_ASSERT(0);
                            return G_FAILURE;
                        }

                        pObject[ulIndex] = CT_CreateObject(szToken, ucMode, ucLevel,
                                        pFunc, G_TRUE, CT_MC_NEW, G_NULL);

                        /* 如果是转换到新模式,还需要将该对象注册为新模式的模式对象*/
                        if (*pCurPos == ':' || *(pCurPos + 1) == ':')  /*这里需要改进*/
                            CT_RegModeObject(ucNewMode, pObject[ulIndex], 2);
                        else
                            CT_RegModeObject(ucNewMode, pObject[ulIndex], 0);
                        break;
                    default:
                        DBG_ASSERT(0);
                        return G_FAILURE;

                }
                pParamLink = &(pObject[ulIndex]->action.pParamLink);
            }
            else
            {
                pObject[ulIndex] = CT_CreateObject(szToken, ucMode, ucLevel,
                                G_NULL, G_FALSE, CT_MC_NULL, G_NULL);
            }
            if (pObject[ulIndex] == G_NULL)
            {
                DBG_Out(PID_CLI, CLI_DBGOUT_ERR, "\r\n CLI: 对象创建失败: %s", szCmd);
                DBG_ASSERT(0);
                return G_FAILURE;
            }

            if (ulIndex == 0)
            {
                pFirstObj = pObject[ulIndex];
            }
            else
            {
                CT_RegObject(pObject[ulIndex - 1], pObject[ulIndex]);
            }

            if (ucMode != CTM_DBG && ucMode != CTM_DIAG)
            {
                if (ulHelpID[ulIndex] == CLI_ML_NULL)
                {
                    DBG_Out(PID_CLI, CLI_DBGOUT_ERR,
                            "\r\n CLI: 命令(%s)\r\n      的对象(%s) 缺少帮助信息!", szCmd, szToken);
                    DBG_ASSERT(0);
                    return G_FAILURE;
                }
                if (((CI_IsObjectExecutable(pObject[ulIndex], HAVEACTIONS) == G_SUCCESS)
                  && (strstr(ML_DirectGetString(ML_CHS, ulHelpID[ulIndex]), HELP_FUN) == G_NULL))
                 || ((CI_IsObjectExecutable(pObject[ulIndex], HAVEACTIONS) != G_SUCCESS)
                  && (strstr(ML_DirectGetString(ML_CHS, ulHelpID[ulIndex]), HELP_FUN) != G_NULL)))
                {
                    if (EOS_StriCmp(szToken, "cm"))
                    {
                        DBG_Out(PID_CLI, CLI_DBGOUT_ERR,
                                "\r\n CLI: 命令(%s)\r\n      的对象(%s) 帮助信息格式不正确!", szCmd, szToken);
                        DBG_ASSERT(0);
                        return G_FAILURE;
                    }
                }
            }
            CT_RegCmdHelp(pObject[ulIndex], ulHelpID[ulIndex]);

        }

        /* 否定形式的命令注册: 自动查找肯定形式的命令并修改其属性 */
        /* 使之具有命令的否定形式                                 */
        else
        {
            if (ulRet == TOKEN_GET_LASTOBJ)
            {
                pObj = CT_GetSubObjByName(pObj, szToken);

                if (pObj == G_NULL)
                {
                    DBG_Out(PID_CLI, CLI_DBGOUT_ERR,
                        "\r\n CLI: 该命令的肯定形式尚未注册 : %s", szCmd);
                    DBG_ASSERT(0);
                    return G_FAILURE;
                }

                pParamLink = &(pObj->noAction.pParamLink);
                /* 设置该对象的否定属性 */
                pObj->noAction.ulMode     = pObj->action.ulMode;
                pObj->noAction.rightLevel = pObj->action.rightLevel;
                pObj->noAction.pFunction  = pFunc;
                pObj->ulNoFlag            = 1;
            }
            else
            {
                pObj = CT_GetSubObjByName(pObj, szToken);
                if (pObj == G_NULL)
                {
                    DBG_Out(PID_CLI, CLI_DBGOUT_ERR,
                        "\r\n CLI: 该命令的肯定形式尚未注册 : %s", szCmd);
                    DBG_ASSERT(0);
                    return G_FAILURE;
                }
                pObj->ulNoFlag = 1;
            }
        }

        ulIndex++;

        /* 如果已经是最后一个对象,则跳出循环 */
        if (ulRet == TOKEN_GET_LASTOBJ)
            break;
    }

    /* 注册命令到模式必须要在所有对象创建完成之后进行, */
    /* 否则无法注册具有相同对象的情况                  */
    if (ucIsNoForm == 0)
    {
        if (CT_RegObjToMode(ucMode, pFirstObj))
        {
            DBG_Out(PID_CLI, CLI_DBGOUT_ERR, "\r\n CLI: 命令注册失败: %s", szCmd);
            DBG_ASSERT(0);
        }
    }
    while (*pCurPos == KEY_SPACE)
        pCurPos++;

    if (*pCurPos != ':')
    {
//        DBG_Out(PID_CLI, CLI_DBGOUT_ERR, "\r\n【MODE-%d】:%s", ucMode, szCmdString);
        return G_SUCCESS;
    }

    while (*(++pCurPos) == KEY_SPACE)
        ;

    /* 这种情况表示分隔符后面已经没有参数链,直接返回 */
    if (*pCurPos == '\0')
    {
//        DBG_Out(PID_CLI, CLI_DBGOUT_ERR, "\r\n【MODE-%d】:%s", ucMode, szCmdString);
        return G_SUCCESS;
    }

    if (pParamLink == G_NULL)   /* 此判断不会进来,消除pc-lint告警 */
    

⌨️ 快捷键说明

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