added busy mode and test

a command can now return SHELLMATTA_BUSY
This will be passed back to the caller of processData
afterwards the instance has to be called with the same parameters
The shellmatta will then just call the busy command until it finishes
as soon as the command returns != SHELLMATTA_BUSY the instance will continue processing the rest of the input data
This commit is contained in:
prozessorkern
2020-03-28 11:26:50 +01:00
parent 3b99ad2a56
commit d7962a54dc
5 changed files with 218 additions and 30 deletions

View File

@@ -75,6 +75,7 @@ shellmatta_retCode_t shellmatta_doInit(
inst->buffer = buffer;
inst->bufferSize = bufferSize;
inst->inputCount = 0u;
inst->byteCounter = 0u;
inst->lastNewlineIdx = 0u;
inst->cursor = 0u;
inst->stdinIdx = 0u;
@@ -98,6 +99,7 @@ shellmatta_retCode_t shellmatta_doInit(
inst->mode = SHELLMATTA_MODE_INSERT;
inst->cmdList = &(inst->helpCmd);
inst->continuousCmd = NULL;
inst->busyCmd = NULL;
inst->cmdListIsConst = false;
/** -# copy the help command structure to this instance */
@@ -139,7 +141,9 @@ shellmatta_retCode_t shellmatta_resetShell( shellmatta_handle_t handle, bool pri
&& (SHELLMATTA_MAGIC == inst->magic))
{
inst->inputCount = 0u;
inst->byteCounter = 0u;
inst->continuousCmd = NULL;
inst->busyCmd = NULL;
inst->lastNewlineIdx = 0u;
inst->cursor = 0u;
inst->stdinIdx = 0u;
@@ -368,7 +372,6 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle,
uint8_t cmdExecuted = 0u;
uint32_t cmdLen;
char *tempString;
uint32_t byteCounter;
shellmatta_retCode_t ret = SHELLMATTA_OK;
shellmatta_retCode_t cmdRet;
@@ -378,19 +381,53 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle,
if( (NULL != inst)
&& (SHELLMATTA_MAGIC == inst->magic))
{
/** -# in busy mode - keep calling this command */
if(NULL != inst->busyCmd)
{
/** -# just call the function until it is not busy anymore */
cmdRet = inst->busyCmd->cmdFct(handle, inst->buffer, inst->inputCount);
if(SHELLMATTA_BUSY != cmdRet)
{
utils_terminateInput(inst);
}
else if(SHELLMATTA_CONTINUE == cmdRet)
{
inst->continuousCmd = inst->busyCmd;
inst->busyCmd = NULL;
}
else
{
ret = cmdRet;
}
}
/** -# process byte wise */
for (byteCounter = 0u; byteCounter < size; byteCounter++)
for (; (inst->byteCounter < size) && (NULL == inst->busyCmd); inst->byteCounter++)
{
/** -# in continuous mode - pass data directly to the command */
if(NULL != inst->continuousCmd)
{
/** -# copy data and call command function */
inst->buffer[inst->stdinIdx] = data[byteCounter];
inst->buffer[inst->stdinIdx] = data[inst->byteCounter];
inst->stdinLength = 1u;
cmdRet = inst->continuousCmd->cmdFct(inst, inst->buffer, inst->inputCount);
cmdRet = inst->continuousCmd->cmdFct(handle, inst->buffer, inst->inputCount);
/** -# check if continuous mode is canceled */
if(('\x03' == data[byteCounter]) || (SHELLMATTA_CONTINUE != cmdRet))
/** -# check if continuous mode is canceled or interrupted by busy mode */
if(SHELLMATTA_BUSY == cmdRet)
{
inst->busyCmd = inst->busyCmd;
inst->continuousCmd = NULL;
}
else if(('\x03' == data[inst->byteCounter]))
{
utils_terminateInput(inst);
}
else if(SHELLMATTA_CONTINUE == cmdRet)
{
/** -# do nothing - continue */
}
else
{
utils_terminateInput(inst);
}
@@ -398,10 +435,10 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle,
/** -# handle escape sequences */
else if(inst->escapeCounter != 0u)
{
escape_handleSequence(inst, *data);
escape_handleSequence(inst, data[inst->byteCounter]);
}
/** -# handle delimiter as start of processing the command */
else if (inst->delimiter == *data)
else if (inst->delimiter == data[inst->byteCounter])
{
if(0u == inst->hereLength)
{
@@ -434,7 +471,7 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle,
inst->hereLength = inst->inputCount - inst->hereDelimiterIdx;
inst->dirty = true;
utils_insertChars(inst, data, 1);
utils_insertChars(inst, &data[inst->byteCounter], 1u);
inst->lastNewlineIdx = inst->inputCount;
}
else
@@ -505,9 +542,9 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle,
}
else
{
/** -# the party goes on - print the \r and add a \n to satisfy most terminals */
/** -# the party goes on - just print the delimiter and store the position */
inst->lastNewlineIdx = inst->inputCount;
utils_insertChars(inst, data, 1u);
utils_insertChars(inst, &data[inst->byteCounter], 1u);
}
}
@@ -543,14 +580,25 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle,
utils_writeEcho(inst, "\r\n", 2u);
shellmatta_opt_init(inst, cmdLen + 1u);
cmdExecuted = 1u;
cmdRet = cmd->cmdFct(inst, inst->buffer, inst->inputCount);
if(SHELLMATTA_CONTINUE == cmdRet)
{
inst->continuousCmd = cmd;
cmdRet = cmd->cmdFct(handle, inst->buffer, inst->inputCount);
/** -# initialize stdin buffer */
inst->stdinIdx = inst->inputCount + 1u;
inst->stdinLength = 0u;
switch(cmdRet)
{
case SHELLMATTA_CONTINUE:
/** -# initialize stdin buffer and continuous cmd */
inst->stdinIdx = inst->inputCount + 1u;
inst->stdinLength = 0u;
inst->continuousCmd = cmd;
break;
case SHELLMATTA_BUSY:
inst->busyCmd = cmd;
ret = cmdRet;
break;
default:
/* nothing to do - everything ok */
break;
}
cmd = NULL;
}
@@ -568,7 +616,8 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle,
}
/** -# terminate this session if no continuous mode is requested */
if(NULL == inst->continuousCmd)
if( (NULL == inst->continuousCmd)
&& (NULL == inst->busyCmd))
{
utils_terminateInput(inst);
}
@@ -576,49 +625,53 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle,
}
/** -# ignore newline as first character (to be compatible to
* terminals sending newline after return */
else if((0u == inst->inputCount) && ('\n' == *data))
else if((0u == inst->inputCount) && ('\n' == data[inst->byteCounter]))
{
/* do nothing */
}
/** -# check for tabulator key - auto complete */
else if('\t' == *data)
else if('\t' == data[inst->byteCounter])
{
inst->dirty = true;
autocomplete_run(inst);
}
/** -# check for cancel -
* terminate current input and print prompt again */
else if('\x03' == *data)
else if('\x03' == data[inst->byteCounter])
{
inst->dirty = false;
history_reset(inst);
utils_terminateInput(inst);
}
/** -# check for backspace */
else if( ('\b' == *data)
|| ('\x7f' == *data))
else if( ('\b' == data[inst->byteCounter])
|| ('\x7f' == data[inst->byteCounter]))
{
inst->dirty = true;
utils_removeChars(inst, 1u, true);
}
/** -# check for start of escape sequence */
else if('\x1b' == *data)
else if('\x1b' == data[inst->byteCounter])
{
inst->escapeCounter = 1u;
}
else
{
inst->dirty = true;
utils_insertChars(inst, data, 1);
utils_insertChars(inst, &data[inst->byteCounter], 1u);
}
/** -# reset tab counter on not a tab */
if ('\t' != *data)
if ('\t' != data[inst->byteCounter])
{
inst->tabCounter = 0u;
}
}
data ++;
/*! -# initialize the byte buffer if processing of the input is finished */
if(ret != SHELLMATTA_BUSY)
{
inst->byteCounter = 0u;
}
}
else

View File

@@ -367,6 +367,7 @@ void utils_terminateInput(shellmatta_instance_t *inst)
inst->stdinIdx = 0u;
inst->stdinLength = 0u;
inst->continuousCmd = NULL;
inst->busyCmd = NULL;
inst->write("\r\n", 2u);
inst->write(inst->prompt, strlen(inst->prompt));
}