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

📄 cli_term.c

📁 命令行在嵌入式系统的实现
💻 C
📖 第 1 页 / 共 5 页
字号:
/*      输出参数    :PTerm_Data_S pTermStruct  任务数据指针         */
/*      返回值      :_U32   0:  接收到一完整命令行并准备提交该命令   */
/*                         1:  只接收到一字符并准备继续接收字符     */
/*      调用函数    :CLI_CharProcess ( )                            */
/*      被调函数    :                                               */
/*==================================================================*/
_U32 CLI_EditString( PTerm_Data_S pTermStruct )
{
    _U32  ulTmp ;
    _U8   ucTmp ;

    CLI_ASSURE_OR_FAIL( G_NULL != pTermStruct );

    /* 接收到的字符串来自terminal client(串口终端) */
    if ( pTermStruct->iSocket == SOCKET_FOR_SERIAL )
    {
        for ( ulTmp = 0 ; ulTmp < (_U32)pTermStruct->iRecvLen ; ulTmp ++ )
        {
            if (pTermStruct->szRecvBuf[ ulTmp ] == '\0')
                return G_FAILURE ;
            ucTmp = (_U8)pTermStruct->szRecvBuf[ ulTmp ] ;

            if ( ! CLI_CharProcess ( pTermStruct, ucTmp ) )
                return G_SUCCESS ;
        }
    }
    /* 接收字符串来自telnet terminal client,利用telnet的有限状态机  */
    /* 对其进行处理                                                 */
    else
    {
        #if CLI_TELNET_SUPPORT
        if( G_YES == g_ul_INCLUDE_SUB_MODULE_CLI_TELNET )
        {
            DBG_ASSERT( G_NULL != g_pfn_CFG_CLI_TelnetEditString );
            return g_pfn_CFG_CLI_TelnetEditString(pTermStruct);
        }
        else
        {
            CLI_ASSURE_OR_FAIL(0);
        }
        #endif

    }

    return G_FAILURE ;
}

/*==================================================================*/
/*      函数名      :CLI_CharProcess                                */
/*      函数功能    :对单个字符进行处理包括删除,插入,特殊字符处理等 */
/*      输入参数    :PTerm_Data_S pTermStruct  任务数据指针         */
/*                   _U8 ucTmp  待处理的字符                         */
/*      输出参数    :PTerm_Data_S pTermStruct  任务数据指针         */
/*      返回值      :_U32   0:  接收到一完整命令行并准备提交该命令   */
/*                         1:  只接收到一字符并准备继续接收字符     */
/*      被调函数    :                                               */
/*==================================================================*/
_U32 CLI_CharProcess ( PTerm_Data_S pTermStruct, _U8 ucTmp )
{
    CLI_ASSURE_OR_FAIL( G_NULL != pTermStruct );

    if (pTermStruct->ucInputStatus == KEY_ESC)
    {
        if (ucTmp == '[')
        {
            pTermStruct->ucInputStatus = '[';
            return G_FAILURE;
        }
        else
            pTermStruct->ucInputStatus = G_NULL;
    }
    else if (pTermStruct->ucInputStatus == '[')
    {
        switch(ucTmp)
        {
            case 'a':
            case 'A':
                ucTmp = KEY_MOVE_P;
                break;
            case 'b':
            case 'B':
                ucTmp = KEY_MOVE_N;
                break;
            case 'd':
            case 'D':
                ucTmp = KEY_MOVE_L;
                break;
            case 'c':
            case 'C':
                ucTmp = KEY_MOVE_R;
                break;
            default:
                break;
        }
        pTermStruct->ucInputStatus = G_NULL;
    }

    if (ucTmp > 0x20 && ucTmp <= 0x7E
     && ucTmp != KEY_MOVE_L && ucTmp != KEY_MOVE_R
     && ucTmp != KEY_MOVE_P && ucTmp != KEY_MOVE_N)
    {
        CLI_CharInsert ( pTermStruct, (_S8)ucTmp ) ;
        if (pTermStruct->iEditStatus == COMMAND_INPUT && (ucTmp == '?' ))
            return G_SUCCESS ;
    }
    else
    {
        switch (ucTmp)
        {
            case KEY_CTRL_C:   /* 终止字符 */
            case KEY_CTRL_Z:
                pTermStruct->szEditBuf[0] = (_S8)ucTmp ;
                pTermStruct->szEditBuf[1] = '\0' ;
                pTermStruct->iCurrentPos = 0 ;
                return G_SUCCESS ;

            case KEY_ESC:
                pTermStruct->ucInputStatus = KEY_ESC;
                break;

            case KEY_ENTER: /* 回车换行符*/
            case KEY_RETURN:
                /* 如果是命令编辑状态,需要进行命令输入完整的相应处理 */
                if(pTermStruct->iEditStatus == COMMAND_INPUT)
                {
                    CLI_DealWitchCommand(pTermStruct);
                }
                pTermStruct->iCurrentPos = 0 ;
                return G_SUCCESS ;

            case KEY_SPACE: /* 空格 */
                /* 如果是命令编辑状态,进行命令的自动联想补全 */
                if(pTermStruct->iEditStatus == COMMAND_INPUT)
                {
                    CLI_PatchCmdWord(pTermStruct);
                }
                else   /* 否则直接插入空格 */
                {
                    CLI_CharInsert (pTermStruct, ' ');
                }
                break;

            /* 以下为编辑控制字符的处理*/
            case KEY_MOVE_L:
                /* 光标在行首,不能再左移,警告 */
                if ( pTermStruct->iCurrentPos == 0
                 || (pTermStruct->szInputCmd[0] != 0 && pTermStruct->iCurrentPos <= (_S32)strlen(pTermStruct->szInputCmd)))
                {
                    CLI_Bell ( pTermStruct ) ;
                }
                else
                {
                    _S32 iLentgh = (_S32)strlen(pTermStruct->szEditBuf);

                    // 如果是命令编辑状态,左移时删除最后一个空格,减少
                    // 用户的操作失误(如果光标不在最后,解释器将拒绝联想)
                    if (pTermStruct->iCurrentPos == iLentgh
                     && pTermStruct->szEditBuf[iLentgh - 1] == 0x20
                     && pTermStruct->iEditStatus == COMMAND_INPUT)
                    {
                        CLI_DealWithBackSpace(pTermStruct);
                    }
                    else
                    {
                        /* 光标左移一格 */
                        pTermStruct->iCurrentPos -- ;
                        CLI_MoveToCurrentPos ( pTermStruct, (_U32)pTermStruct->iCurrentPos + 1 ) ;
                    }
                }
                break;
            case KEY_MOVE_R:
                if ( (_U32)pTermStruct->iCurrentPos < (_U32)EOS_StrLen ( pTermStruct->szEditBuf ) )
                {
                    /* 将光标右移一格 */
                    pTermStruct->iCurrentPos ++ ;
                    CLI_MoveToCurrentPos ( pTermStruct, (_U32)pTermStruct->iCurrentPos - 1 ) ;
                }
                /* 光标在行首末,警告 */
                else
                    CLI_Bell ( pTermStruct ) ;
                break;
            case KEY_CTRL_W:
            case KEY_MOVE_P: //DOSKEY功能上一条命令
                if ( pTermStruct->iEditStatus == COMMAND_INPUT )
                {
                    CLI_PrevCmdDisp( pTermStruct );
                }
                else   /*非命令编辑状态不能进行DOSKEY功能*/
                {
                    CLI_Bell(pTermStruct);
                }
                break;
            case KEY_CTRL_S:
            case KEY_MOVE_N: //DOSKEY功能下一条命令
                if ( pTermStruct->iEditStatus == COMMAND_INPUT )
                {
                    CLI_NextCmdDisp( pTermStruct );
                }
                else   /*非命令编辑状态不能进行DOSKEY功能*/
                {
                    CLI_Bell(pTermStruct);
                }
                break;
            default:
                CLI_EditSpecialKey ( pTermStruct, (_S8)ucTmp ) ;
                break;

        }
    }
    return G_FAILURE;

}


/*==================================================================*/
/*      函数名      :CLI_CharInsert                                 */
/*      函数功能    :在字符串编辑缓冲的当前光标位置插入一字符       */
/*      输入参数    :PTerm_Data_S pTermStruct  任务数据指针         */
/*                   _S8 ch  待插入的字符                          */
/*      输出参数    :PTerm_Data_S pTermStruct  任务数据指针         */
/*      返回值      :无                                             */
/*      调用函数    :CLI_MoveToCurrentPos ( )                       */
/*      被调函数    :                                               */
/*==================================================================*/
_VOID CLI_CharInsert( PTerm_Data_S pTermStruct, _S8 ch )
{
    _S32  iTmp ;

    if ( pTermStruct == G_NULL )
    {
        MT_ERRLOG(0);
        return;
    }
    if ( (_U32)EOS_StrLen( pTermStruct->szEditBuf ) + 1 >= (_U32)pTermStruct->iMaxLen )
    {
        DBG_Out(PID_CLI, MT_DBGOUT_NOTE, "\r\n 编辑缓冲濒临溢出(Term-%d).", pTermStruct->ulTermId);
        CLI_Bell(pTermStruct);
        return ;
    }


    /* 将光标后的字符向右移动一格,为待插入的字符留出插入空位*/
    iTmp = (_S32)EOS_StrLen ( pTermStruct->szEditBuf ) ;
    if (pTermStruct->szEditBuf[iTmp -1] == '?')
        return;

    while ( iTmp >= pTermStruct->iCurrentPos )
    {
        pTermStruct->szEditBuf[ iTmp + 1 ]
            = pTermStruct->szEditBuf[ iTmp ] ;
        iTmp-- ;
    }

    /* 在当前光标位置出入该字符 */
    pTermStruct->szEditBuf[ pTermStruct->iCurrentPos ] = ch ;

    /* 控制用户端的屏幕显示,刷新当前光标以后的显示字符,             */
    /* 即刷新发送缓冲区                                             */
    if (pTermStruct->iSocket != SOCKET_FOR_MML)  // 对透传命令不作回显
    {
        pTermStruct->szSendBuf[ pTermStruct->iSendLen ++ ] = ch ;
    }
    if ( (_U32)EOS_StrLen( pTermStruct->szEditBuf ) - 1 > (_U32)pTermStruct->iCurrentPos )
    {
        iTmp = pTermStruct->iCurrentPos + 1 ;
        while ( pTermStruct->szEditBuf[ iTmp ] )
            pTermStruct->szSendBuf[ pTermStruct->iSendLen ++ ]
                = pTermStruct->szEditBuf[ iTmp ++ ] ;
    }
    pTermStruct->szSendBuf[ pTermStruct->iSendLen ] = '\0' ;

    /* 光标位置右移一格 */
    pTermStruct->iCurrentPos ++ ;

    /* 将光标从行末移到当前光标所在位置  */
    if ( (_U32)EOS_StrLen( pTermStruct->szEditBuf ) > (_U32)pTermStruct->iCurrentPos )
        CLI_MoveToCurrentPos ( pTermStruct, EOS_StrLen ( pTermStruct->szEditBuf ) ) ;

    return ;
}

/*==================================================================*/
/*      函数名      :CLI_EditSpecialKey                             */
/*      函数功能    :对接收到的特殊字符进行编辑处理                 */
/*      输入参数    :PTerm_Data_S pTermStruct  任务数据指针         */
/*                   _S8 ch  待处理的特殊字符                      */
/*      输出参数    :PTerm_Data_S pTermStruct  任务数据指针         */
/*      返回值      :无                                             */
/*      被调函数    :                                               */
/*==================================================================*/
_VOID CLI_EditSpecialKey( PTerm_Data_S pTermStruct, _S8 ch )
{

    if ( pTermStruct == G_NULL )
    {
        MT_ERRLOG(0);
        return;
    }

    if ( ISESC( ch ) )
    {
        CLI_Bell ( pTermStruct ) ;
    }

    else if ( ISBACKSPACE( ch ) )
    {
        /*--------------------------------------------------*/
        /* 如果用户输入了Backspace键,则对之进行处理         */
        /*--------------------------------------------------*/
        CLI_DealWithBackSpace ( pTermStruct ) ;
    }

    else if ( ISDELETE( ch ) )
    {
        /*--------------------------------------------------*/
        /* 如果用户输入了Delete键,则对之进行处理            */
        /*--------------------------------------------------*/
        CLI_DealWithDelete ( pTermStruct ) ;

    }

    else if ( ISTAB( ch ) )
    {
        CLI_Bell ( pTermStruct ) ;
    }

    else if ( ISCTRLCHAR( ch ) )
    {
        CLI_CharInsert ( pTermStruct, '^' ) ;
        CLI_CharInsert ( pTermStruct, (_S8)(ISCTRLCHAR( ch )) ) ;
    }
    else
    {
        CLI_Bell ( pTermStruct ) ;
    }
    return ;
}



/*==================================================================*/
/*      函数名      :CLI_DealWithBackSpace                          */
/*      函数功能    :对Backspace键的处理                            */
/*      输入参数    :PTerm_Data_S pTermStruct  任务数据指针         */
/*      输出参数    :PTerm_Data_S pTermStruct  任务数据指针         */
/*      返回值      :无                                             */

⌨️ 快捷键说明

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