📄 cli_io.c
字号:
EOS_StrCpy(pOutput, szOutput);
/* 输出信息入列 */
pAsynDispItem = &(m_DispBase.s_AsynShowPool[m_DispBase.ulLastPos]);
pAsynDispItem->pString = pOutput;
pAsynDispItem->ulTermID = ulTermID;
m_DispBase.ulLastPos = CLI_INCCYCLE(m_DispBase.ulLastPos, ASYN_DISPLAY_NUM);
return G_SUCCESS;
}
/* 异步输出的主任务函数体*/
_VOID IO_AsynDispTask(_U32 ulArg1, _U32 ulArg2)
{
struct AsynDisplay_Element_S *pAsynDispItem;
PTerm_Data_S pTermStruct;
_U32 i, ulLen;
(_VOID)ulArg1;
(_VOID)ulArg2;
IO_DispBaseInit();
for (; ;)
{
if (m_DispBase.ulFirstPos == m_DispBase.ulLastPos)
{
CLI_DELAY(10);
continue;
}
/* 提取一条显示信息,注意内存的释放 */
pAsynDispItem = &(m_DispBase.s_AsynShowPool[m_DispBase.ulFirstPos]);
m_DispBase.ulFirstPos = CLI_INCCYCLE(m_DispBase.ulFirstPos, ASYN_DISPLAY_NUM);
if ((pAsynDispItem->ulTermID > m_ulCliMaxOnlineUser )
|| (pAsynDispItem->ulTermID == 0)
|| (pAsynDispItem->pString == G_NULL))
{
ROS_MemFree(pAsynDispItem->pString);
continue;
}
pTermStruct = m_TDTable[pAsynDispItem->ulTermID - 1].pTermStruct;
if (pTermStruct->ucTermStatus < TERM_LOGED || pTermStruct->ulTimeLeft == 0)
{
CLI_RECORD(CLI_STAT_ASYNOUT_TERM_ERR);
ROS_MemFree(pAsynDispItem->pString);
continue;
}
EOS_StrCpy(pTermStruct->szSendBuf, pAsynDispItem->pString);
CLI_SendToTerm(pTermStruct);
/* 如果该终端正处于命令编辑状态,重新显示提示符与命令编辑的内容 */
if (pTermStruct->iEditStatus == COMMAND_INPUT
&& pTermStruct->ucTermStatus < TERM_EXECCMD)
{
CI_DisplayPrompt(pTermStruct);
if ((ulLen = EOS_StrLen(pTermStruct->szEditBuf)) > (_U32)pTermStruct->iCurrentPos)
{
for (i = 0; i < ulLen - (_U32)pTermStruct->iCurrentPos; i++)
IO_OutToTerm(pTermStruct, "\x1b[1D");
}
}
else
{
IO_OutToTerm(pTermStruct, "\r\n");
}
pAsynDispItem->ulTermID = 0;
ROS_MemFree(pAsynDispItem->pString);
if (m_DispBase.ulFirstPos % 5 == 0)
{
CLI_DELAY(1);
}
}
}
/*********************************************************************/
/* 函数名称 : IO_OutToTerm() */
/* 函数功能 : 组织输出字符串,并根据终端调用函数输出 */
/* 输入参数 : pTermStruct 终端任务数据 */
/* szOutString 输出字符串 */
/* 输出参数 : 无 */
/* 返回 : 成功、失败 */
/* 上层函数 : */
/* 创建者 : */
/* 修改记录 : */
/*********************************************************************/
_U32 IO_OutToTerm(PTerm_Data_S pTermStruct, const _S8 *szOutString)
{
_S8 cTmp;
const _S8 *szOut;
const _S8 *pcTmp;
_U32 ulStrLen;
_U32 ulTmp;
CLI_ASSURE_OR_FAIL(pTermStruct != G_NULL);
if (CLI_GetCurrentTaskData() == G_NULL)
{
pTermStruct->ulDispLineCount = 0;
}
if ((pTermStruct->ulDispLineCount == CLI_INVALID
&& pTermStruct->ucTermStatus == TERM_EXECCMD)
|| pTermStruct->ucTermStatus == TERM_SLEEPING)
return G_SUCCESS;
szOut = szOutString;
/* 如果发送缓冲中还存在没有显示的内容,先显示之 */
if (pTermStruct->szSendBuf[0] != '\0')
CLI_SendToTerm(pTermStruct);
/* 如果输出的信息长度超过任务缓冲允许的范围,分段输出 */
pcTmp = szOut;
ulStrLen = EOS_StrLen(szOutString);
while (*pcTmp != '\0' && pcTmp < szOutString + ulStrLen)
{
if (*pcTmp == '\r' || *pcTmp == '\n' || pcTmp - szOut > LINE_LENGTH)
{
EOS_StrNCpy(pTermStruct->szSendBuf, szOut, (_U32)(pcTmp - szOut));
pTermStruct->szSendBuf[pcTmp - szOut] = '\0';
CLI_SendToTerm(pTermStruct);
if (*pcTmp == '\r' || *pcTmp == '\n')
szOut = pcTmp++; /* 这里需要递加,跳过接下来的\r或\n */
else
szOut += (pcTmp - szOut);
/* 显示每满一屏要作处理, 需要预留一行用作提示信息输出 */
if (++pTermStruct->ulDispLineCount >= LINE_PER_PAGE - 1)
{
pTermStruct->ulDispLineCount = 0;
/* 如果是手动分屏,需要按任意键继续 */
if (pTermStruct->ucScroll == SCROLL_MANUAL && pTermStruct->ucTermStatus == TERM_EXECCMD)
{
EOS_StrCpy(pTermStruct->szSendBuf,
"\r\n --- More ---");
CLI_SendToTerm(pTermStruct);
/*如果输入CTL_C或终端非正常状态,终止显示*/
while ((cTmp = IO_GetCharByPeek()) != G_NULL
&& cTmp != KEY_CTRL_C)
{
;
}
if ((cTmp == KEY_CTRL_C)
|| (cTmp = IO_GetChar()) == KEY_CTRL_C
|| (cTmp == G_NULL)
|| !IS_TERM_NORMAL(pTermStruct))
{
for (ulTmp = 0; ulTmp < 15; ulTmp++)
EOS_StrCat(pTermStruct->szSendBuf, "\x1b[1D");
EOS_StrCat(pTermStruct->szSendBuf, " \x1b[1A");
CLI_SendToTerm(pTermStruct);
pTermStruct->ulDispLineCount = CLI_INVALID;
return G_SUCCESS;
}
else if (cTmp == '\r' || cTmp == '\n')
{
pTermStruct->ulDispLineCount = LINE_PER_PAGE - 1;
}
for (ulTmp = 0; ulTmp < 15; ulTmp++)
EOS_StrCat(pTermStruct->szSendBuf, "\x1b[1D");
EOS_StrCat(pTermStruct->szSendBuf, " \x1b[1A");
CLI_SendToTerm(pTermStruct);
}
/* 如果是自动分屏,查看是否有键入CTRL+C试图终止,没有则继续 */
else
{
while ((cTmp = IO_GetCharByPeek()) != G_NULL
&& cTmp != KEY_CTRL_C)
{
;
}
if (cTmp == KEY_CTRL_C)
{
pTermStruct->ulDispLineCount = CLI_INVALID;
return G_SUCCESS;
}
CLI_DELAY(100);
while ((cTmp = IO_GetCharByPeek()) != G_NULL
&& cTmp != KEY_CTRL_C)
{
;
}
if (cTmp == KEY_CTRL_C)
{
pTermStruct->ulDispLineCount = CLI_INVALID;
return G_SUCCESS;
}
}
}
}
pcTmp++;
}
EOS_StrCpy(pTermStruct->szSendBuf, szOut);
return CLI_SendToTerm(pTermStruct);
}
/*-------------------------------------------------------------------*/
/* 函数名称 : IO_GetChar */
/* 功 能 : 从终端接收一个字符 */
/* 输入参数 : 无 */
/* 输出参数 : 无 */
/* 返回值 : 接收到的字符 */
/* 调用说明 : 该函数调用导致任务阻塞,直到终端有输入或超时。注意该函 */
/* 数的调用需要判断返回值,如果返回NULL则可能是终端异常, */
/* 建议程序释放当前资源,不再继续处理当前事件 */
/* 典型示例 : cTmp = IO_GetChar(); */
/*-------------------------------------------------------------------*/
_S8 IO_GetChar(_VOID)
{
_S8 cCharReceived;
PTerm_Data_S pTermStruct;
if (((pTermStruct = CLI_GetCurrentTaskData()) == G_NULL)
|| pTermStruct->iSocket == SOCKET_FOR_MML)
{
MT_ERRLOG(0);
return G_NULL;
}
if (CLI_ReceiveFromTerm(pTermStruct, pTermStruct->ulTimeLeft) != G_SUCCESS)
{
CLI_RECORD(CLI_STAT_RECEIVE_ABNORMAL);
return G_NULL;
}
cCharReceived = pTermStruct->szRecvBuf[0];
pTermStruct->szRecvBuf[0] = '\0';
pTermStruct->iRecvLen = 0;
return cCharReceived;
}
/*-------------------------------------------------------------------*/
/* 函数名称 : IO_GetChar */
/* 功 能 : 从终端接收缓冲读取一个字符 */
/* 输入参数 : 无 */
/* 输出参数 : 无 */
/* 返回值 : 读取到的字符 */
/* 调用说明 : 该调用直接读取当前终端的接收缓冲,如果无内容则返回空 */
/* 典型示例 : cTmp = IO_GetCharByPeek(); */
/*-------------------------------------------------------------------*/
_S8 IO_GetCharByPeek(_VOID)
{
_S8 cCharReceived;
PTerm_Data_S pTermStruct;
if ((pTermStruct = CLI_GetCurrentTaskData()) == G_NULL)
{
return G_NULL;
}
CLI_ReceiveFromTerm(pTermStruct, 0);
cCharReceived = pTermStruct->szRecvBuf[0];
pTermStruct->szRecvBuf[0] = '\0';
pTermStruct->iRecvLen = 0;
return cCharReceived;
}
/*-------------------------------------------------------------------*/
/* 函数名称 : IO_GetString */
/* 功 能 : 从当前终端接收一个字符串 */
/* 输入参数 : ulSize :字符串允许的最大长度 */
/* ucMode :输入模式:0-字符回显,1-星号回显 */
/* 输出参数 : szInput :接收的的输入字符串 */
/* 返回值 : 成功、失败 */
/* 调用说明 : 该调用导致终端任务阻塞,直到超时或接收到回车键. 调用者 */
/* 应对返回值进行判断, 如果失败,则认为接收到的内容无效, */
/* 导致这种情况的最大可能是终端异常,程序应当立即返回,让 */
/* 系统去识别并处理这种异常 */
/* 典型示例 : if (IO_GetString(&szUsername, 16, 0) != G_SUCCESS) */
/* return G_FAILURE; */
/*-------------------------------------------------------------------*/
_U32 IO_GetString(_S8 *szInput, _U32 ulSize, _S8 ucMode)
{
_S32 i;
PTerm_Data_S pTermStruct ;
if ( G_NULL == szInput)
{
MT_ERRLOG(0);
return G_FAILURE;
}
if (((pTermStruct = CLI_GetCurrentTaskData()) == G_NULL)
|| pTermStruct->iSocket == SOCKET_FOR_MML)
{
MT_ERRLOG(0);
return G_FAILURE;
}
/* 初始化任务数据的编辑环境变量(缺省状态下为适应命令行的输入) */
pTermStruct->iMaxLen = (_S32)ulSize ;
pTermStruct->szEditBuf[0] = '\0' ;
pTermStruct->iCurrentPos = 0 ;
if (ucMode == EN_GETSTRING_FOR_COMMAND)
{
EOS_StrCpy(pTermStruct->szInputCmd, pTermStruct->pWS->szCmdString);
if (pTermStruct->szInputCmd[strlen(pTermStruct->szInputCmd) - 1] != 0x20)
{
EOS_StrCat(pTermStruct->szInputCmd, " ");
}
EOS_StrCat(pTermStruct->szInputCmd, pTermStruct->szEditBuf);
EOS_StrCpy(pTermStruct->szEditBuf, pTermStruct->szInputCmd);
pTermStruct->iCurrentPos = (_S32)strlen(pTermStruct->szEditBuf) ;
pTermStruct->iEditStatus = COMMAND_INPUT;
}
else
pTermStruct->iEditStatus = STRING_INPUT;
for(;;)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -