|
@@ -74,6 +74,7 @@ shellmatta_retCode_t shellmatta_doInit(
|
|
|
inst->buffer = buffer;
|
|
|
inst->bufferSize = bufferSize;
|
|
|
inst->inputCount = 0u;
|
|
|
+ inst->lastNewlineIdx = 0u;
|
|
|
inst->cursor = 0u;
|
|
|
inst->historyBuffer = historyBuffer;
|
|
|
inst->historyBufferSize = historyBufferSize;
|
|
@@ -87,6 +88,9 @@ shellmatta_retCode_t shellmatta_doInit(
|
|
|
inst->dirty = false;
|
|
|
inst->tabCounter = 0u;
|
|
|
inst->escapeCounter = 0u;
|
|
|
+ inst->hereStartIdx = 0u;
|
|
|
+ inst->hereDelimiterIdx = 0u;
|
|
|
+ inst->hereLength = 0u;
|
|
|
inst->mode = SHELLMATTA_MODE_INSERT;
|
|
|
inst->cmdList = &helpCmd;
|
|
|
inst->cmdListIsConst = false;
|
|
@@ -194,6 +198,12 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle,
|
|
|
shellmatta_cmd_t *cmd;
|
|
|
uint8_t cmdExecuted = 0u;
|
|
|
uint32_t cmdLen;
|
|
|
+ char *tempString;
|
|
|
+ char *argumentString;
|
|
|
+ uint32_t argumentLength;
|
|
|
+ uint32_t byteCounter;
|
|
|
+ uint32_t idx;
|
|
|
+
|
|
|
shellmatta_retCode_t ret = SHELLMATTA_OK;
|
|
|
shellmatta_instance_t *inst = (shellmatta_instance_t*)handle;
|
|
|
|
|
@@ -202,7 +212,7 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle,
|
|
|
&& (SHELLMATTA_MAGIC == inst->magic))
|
|
|
{
|
|
|
/** -# process byte wise */
|
|
|
- for (uint32_t i = 0u; i < size; i++)
|
|
|
+ for (byteCounter = 0u; byteCounter < size; byteCounter++)
|
|
|
{
|
|
|
/** -# handle escape sequences */
|
|
|
if(inst->escapeCounter != 0u)
|
|
@@ -218,56 +228,153 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle,
|
|
|
/** -# handle return as start of processing the command */
|
|
|
else if ('\r' == *data)
|
|
|
{
|
|
|
- cmd = inst->cmdList;
|
|
|
- inst->buffer[inst->inputCount] = 0u;
|
|
|
+ if(0u == inst->hereLength)
|
|
|
+ {
|
|
|
+ /**
|
|
|
+ * \dot
|
|
|
+ * digraph heredocParser {
|
|
|
+ * start -> wait [ label="<< in first line - store delimiter" ];
|
|
|
+ * wait -> wait [ label="delimiter not detected" ];
|
|
|
+ * wait -> end [ label="delimiter found - remove all heredoc stuff and send the input to the command" ];
|
|
|
+ * }
|
|
|
+ * \enddot */
|
|
|
|
|
|
- /** -# store the current command and reset the history buffer */
|
|
|
- inst->dirty = true;
|
|
|
- history_storeCmd(inst);
|
|
|
- history_reset(inst);
|
|
|
+ /** -# check for heredoc */
|
|
|
+ tempString = strstr(inst->buffer, "<<");
|
|
|
+ if(NULL != tempString)
|
|
|
+ {
|
|
|
+ /*' -# check if length of heredoc delimiter is valid */
|
|
|
+ if(inst->inputCount > ((uint32_t)(tempString - inst->buffer) + 2u))
|
|
|
+ {
|
|
|
+ inst->hereStartIdx = (uint32_t)(tempString - inst->buffer);
|
|
|
+ inst->hereDelimiterIdx = inst->hereStartIdx + 2u;
|
|
|
+ while((inst->hereDelimiterIdx < inst->inputCount)
|
|
|
+ && ( ('\0' == inst->buffer[inst->hereDelimiterIdx])
|
|
|
+ || (' ' == inst->buffer[inst->hereDelimiterIdx])))
|
|
|
+ {
|
|
|
+ inst->hereDelimiterIdx ++;
|
|
|
+ }
|
|
|
|
|
|
- /** -# determine the cmd len (chars until first space or \0 is found */
|
|
|
- cmdLen = 0u;
|
|
|
- while( (cmdLen < inst->inputCount)
|
|
|
- && (' ' != inst->buffer[cmdLen])
|
|
|
- && ('\0' != inst->buffer[cmdLen]))
|
|
|
- {
|
|
|
- cmdLen ++;
|
|
|
- }
|
|
|
+ inst->hereLength = inst->inputCount - inst->hereDelimiterIdx;
|
|
|
|
|
|
- /** -# search for a matching command */
|
|
|
- while (NULL != cmd)
|
|
|
+ inst->dirty = true;
|
|
|
+ utils_insertChars(inst, data, 1);
|
|
|
+ inst->lastNewlineIdx = inst->inputCount;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ inst->hereLength = 0u;
|
|
|
+
|
|
|
+ /** -# store the current command and reset the history buffer */
|
|
|
+ inst->dirty = true;
|
|
|
+ history_storeCmd(inst);
|
|
|
+ history_reset(inst);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ argumentString = inst->buffer;
|
|
|
+ argumentLength = inst->inputCount;
|
|
|
+
|
|
|
+ /** -# store the current command and reset the history buffer */
|
|
|
+ inst->dirty = true;
|
|
|
+ history_storeCmd(inst);
|
|
|
+ history_reset(inst);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
{
|
|
|
- /** -# compare command string and length */
|
|
|
- if ( ((0 == strncmp( inst->buffer,
|
|
|
- cmd->cmd,
|
|
|
- cmdLen))
|
|
|
- && (cmdLen == strlen(cmd->cmd)))
|
|
|
- || ((0 == strncmp( inst->buffer,
|
|
|
- cmd->cmdAlias,
|
|
|
- cmdLen))
|
|
|
- && (cmdLen == strlen(cmd->cmdAlias))))
|
|
|
+ tempString = &inst->buffer[inst->lastNewlineIdx];
|
|
|
+ cmdLen = inst->inputCount - inst->lastNewlineIdx;
|
|
|
+
|
|
|
+ /** -# skip newline characters before comparison */
|
|
|
+ while(('\n' == *tempString) || ('\r' == *tempString))
|
|
|
+ {
|
|
|
+ tempString ++;
|
|
|
+ cmdLen --;
|
|
|
+ }
|
|
|
+
|
|
|
+ if( (inst->hereLength == cmdLen)
|
|
|
+ && (0 == strncmp( &inst->buffer[inst->hereDelimiterIdx],
|
|
|
+ tempString,
|
|
|
+ inst->hereLength)))
|
|
|
{
|
|
|
- inst->write("\r\n", 2u);
|
|
|
+ argumentLength = inst->lastNewlineIdx;
|
|
|
+
|
|
|
+ /** -# store the current command and reset the history buffer */
|
|
|
+ inst->dirty = true;
|
|
|
+ history_storeCmd(inst);
|
|
|
+ history_reset(inst);
|
|
|
+
|
|
|
+
|
|
|
+ /* TODO it is difficult to store the complete command in the history buffer if it is restructured before...
|
|
|
+ * So this should be an extra function that can be called after parsing the command and before calling the command funktion */
|
|
|
+ for(idx = 1u; idx <= inst->hereStartIdx; idx++)
|
|
|
+ {
|
|
|
+ inst->buffer[inst->hereDelimiterIdx + inst->hereLength - idx] = inst->buffer[inst->hereStartIdx - idx];
|
|
|
+ }
|
|
|
|
|
|
- cmdExecuted = 1u;
|
|
|
- cmd->cmdFct(inst, inst->buffer, inst->inputCount);
|
|
|
- cmd = NULL;
|
|
|
+ argumentString = &(inst->buffer[inst->hereDelimiterIdx + inst->hereLength - inst->hereStartIdx]);
|
|
|
+ argumentLength = inst->lastNewlineIdx - ((inst->hereDelimiterIdx + inst->hereLength) - inst->hereStartIdx);
|
|
|
+ inst->hereLength = 0u;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- cmd = cmd->next;
|
|
|
+ inst->lastNewlineIdx = inst->inputCount;
|
|
|
+ utils_insertChars(inst, data, 1);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if ((cmdExecuted == 0u) && (inst->inputCount > 0))
|
|
|
+ if(0u == inst->hereLength)
|
|
|
{
|
|
|
- inst->buffer[inst->inputCount] = '\0';
|
|
|
- inst->write("\r\nCommand: ", 11u);
|
|
|
- inst->write(inst->buffer, inst->inputCount);
|
|
|
- inst->write(" not found", 10u);
|
|
|
+ cmd = inst->cmdList;
|
|
|
+ argumentString[argumentLength] = 0u;
|
|
|
+
|
|
|
+ /** -# determine the cmd len (chars until first space or \0 is found */
|
|
|
+ cmdLen = 0u;
|
|
|
+ while( (cmdLen < argumentLength)
|
|
|
+ && (' ' != argumentString[cmdLen])
|
|
|
+ && ('\r' != argumentString[cmdLen])
|
|
|
+ && ('\n' != argumentString[cmdLen])
|
|
|
+ && ('\0' != argumentString[cmdLen]))
|
|
|
+ {
|
|
|
+ cmdLen ++;
|
|
|
+ }
|
|
|
+
|
|
|
+ /** -# search for a matching command */
|
|
|
+ while (NULL != cmd)
|
|
|
+ {
|
|
|
+ /** -# compare command string and length */
|
|
|
+ if ( ((0 == strncmp( argumentString,
|
|
|
+ cmd->cmd,
|
|
|
+ cmdLen))
|
|
|
+ && (cmdLen == strlen(cmd->cmd)))
|
|
|
+ || ((0 == strncmp( argumentString,
|
|
|
+ cmd->cmdAlias,
|
|
|
+ cmdLen))
|
|
|
+ && (cmdLen == strlen(cmd->cmdAlias))))
|
|
|
+ {
|
|
|
+ inst->write("\r\n", 2u);
|
|
|
+
|
|
|
+ cmdExecuted = 1u;
|
|
|
+ cmd->cmdFct(inst, argumentString, argumentLength);
|
|
|
+ cmd = NULL;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ cmd = cmd->next;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((cmdExecuted == 0u) && (inst->inputCount > 0))
|
|
|
+ {
|
|
|
+ inst->write("\r\nCommand: ", 11u);
|
|
|
+ inst->write(argumentString, argumentLength);
|
|
|
+ inst->write(" not found", 10u);
|
|
|
+ }
|
|
|
+ utils_terminateInput(inst);
|
|
|
}
|
|
|
- utils_terminateInput(inst);
|
|
|
+
|
|
|
}
|
|
|
/** -# check for tabulator key - auto complete */
|
|
|
else if('\t' == *data)
|