diff --git a/api/shellmatta.h b/api/shellmatta.h index 804f2c9..8af38ac 100644 --- a/api/shellmatta.h +++ b/api/shellmatta.h @@ -123,6 +123,8 @@ typedef struct uint32_t inputCount; /**< offset of the current write operation */ uint32_t lastNewlineIdx; /**< index of the lest newline */ uint32_t cursor; /**< offset where the cursor is at */ + uint32_t stdinIdx; /**< start index of stdin in buffer */ + uint32_t stdinLength; /**< length of the stdin data */ char *historyBuffer; /**< buffer to store the last commands */ uint32_t historyBufferSize; /**< size of the history buffer */ uint32_t historyStart; /**< index of the oldest stored command */ @@ -179,6 +181,10 @@ shellmatta_retCode_t shellmatta_write( shellmatta_handle_t handle, char *data, uint32_t length); +shellmatta_retCode_t shellmatta_read( shellmatta_handle_t handle, + char **data, + uint32_t *length); + shellmatta_retCode_t shellmatta_opt( shellmatta_handle_t handle, char *optionString, char *option, diff --git a/src/shellmatta.c b/src/shellmatta.c index d6a2d1d..be004c0 100644 --- a/src/shellmatta.c +++ b/src/shellmatta.c @@ -77,6 +77,8 @@ shellmatta_retCode_t shellmatta_doInit( inst->inputCount = 0u; inst->lastNewlineIdx = 0u; inst->cursor = 0u; + inst->stdinIdx = 0u; + inst->stdinLength = 0u; inst->historyBuffer = historyBuffer; inst->historyBufferSize = historyBufferSize; inst->historyStart = 0u; @@ -137,6 +139,8 @@ shellmatta_retCode_t shellmatta_resetShell( shellmatta_handle_t handle, bool pri inst->inputCount = 0u; inst->lastNewlineIdx = 0u; inst->cursor = 0u; + inst->stdinIdx = 0u; + inst->stdinLength = 0u; inst->historyStart = 0u; inst->historyEnd = 0u; inst->historyRead = 0u; @@ -356,10 +360,7 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle, 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; @@ -371,10 +372,6 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle, /** -# process byte wise */ for (byteCounter = 0u; byteCounter < size; byteCounter++) { - /*! -# set default values for the command argument - can be overwritten by heredoc */ - argumentString = inst->buffer; - argumentLength = inst->inputCount; - /** -# handle escape sequences */ if(inst->escapeCounter != 0u) { @@ -458,23 +455,28 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle, tempString, inst->hereLength))) { - 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 function */ - for(idx = 1u; idx <= inst->hereStartIdx; idx++) + /*! -# process heredoc as stdin like input */ + /*! -# find start of heredoc data */ + inst->stdinIdx = inst->hereDelimiterIdx + inst->hereLength; + while( ('\n' == inst->buffer[inst->stdinIdx]) + || ('\r' == inst->buffer[inst->stdinIdx])) { - inst->buffer[inst->hereDelimiterIdx + inst->hereLength - idx] = inst->buffer[inst->hereStartIdx - idx]; + inst->stdinIdx ++; } + /** -# calculate length and terminate stdin string */ + inst->stdinLength = inst->lastNewlineIdx - inst->stdinIdx; + inst->buffer[inst->lastNewlineIdx] = '\0'; + + /** -# calculate length and terminate argument string */ + inst->inputCount = inst->hereStartIdx; + inst->buffer[inst->hereStartIdx] = '\0'; - argumentString = &(inst->buffer[inst->hereDelimiterIdx + inst->hereLength - inst->hereStartIdx]); - argumentLength = inst->lastNewlineIdx - ((inst->hereDelimiterIdx + inst->hereLength) - inst->hereStartIdx); + /** -# terminate heredoc session */ inst->hereLength = 0u; } else @@ -487,16 +489,15 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle, if(0u == inst->hereLength) { - cmd = inst->cmdList; - argumentString[argumentLength] = 0u; + cmd = inst->cmdList; /** -# 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])) + while( (cmdLen < inst->inputCount) + && (' ' != inst->buffer[cmdLen]) + && ('\r' != inst->buffer[cmdLen]) + && ('\n' != inst->buffer[cmdLen]) + && ('\0' != inst->buffer[cmdLen])) { cmdLen ++; } @@ -505,12 +506,12 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle, while (NULL != cmd) { /** -# compare command and alias string and length */ - if ( ((0 == strncmp( argumentString, + if ( ((0 == strncmp( inst->buffer, cmd->cmd, cmdLen)) && (cmdLen == strlen(cmd->cmd))) || ((NULL != cmd->cmdAlias) - && ((0 == strncmp( argumentString, + && ((0 == strncmp( inst->buffer, cmd->cmdAlias, cmdLen)) && (cmdLen == strlen(cmd->cmdAlias))))) @@ -518,7 +519,7 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle, utils_writeEcho(inst, "\r\n", 2u); shellmatta_opt_init(inst, cmdLen + 1u); cmdExecuted = 1u; - cmd->cmdFct(inst, argumentString, argumentLength); + cmd->cmdFct(inst, inst->buffer, inst->inputCount); cmd = NULL; } else @@ -530,7 +531,7 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle, if ((cmdExecuted == 0u) && (inst->inputCount > 0)) { inst->write("\r\nCommand: ", 11u); - inst->write(argumentString, argumentLength); + inst->write(inst->buffer, inst->inputCount); inst->write(" not found", 10u); } utils_terminateInput(inst); @@ -610,6 +611,34 @@ shellmatta_retCode_t shellmatta_write( shellmatta_handle_t handle, return ret; } +/** + * @brief reads the stdin like buffer + * @param[in] handle shellmatta instance handle + * @param[out] data pointer to pointer to store ref to the buffer + * @param[out] length size of the stdin data + * @return + */ +shellmatta_retCode_t shellmatta_read( shellmatta_handle_t handle, + char **data, + uint32_t *length) +{ + shellmatta_retCode_t ret = SHELLMATTA_USE_FAULT; + shellmatta_instance_t *inst = (shellmatta_instance_t*)handle; + + /** -# check parameters for plausibility */ + if( (NULL != inst) + && (SHELLMATTA_MAGIC == inst->magic) + && (NULL != data) + && (NULL != length)) + { + /** -# return a pointer to the data */ + *data = &(inst->buffer[inst->stdinIdx]); + *length = inst->stdinLength; + } + + return ret; +} + #ifndef SHELLMATTA_STRIP_PRINTF /** diff --git a/src/shellmatta_utils.c b/src/shellmatta_utils.c index 7d8c97e..7124272 100644 --- a/src/shellmatta_utils.c +++ b/src/shellmatta_utils.c @@ -364,6 +364,8 @@ void utils_terminateInput(shellmatta_instance_t *inst) inst->lastNewlineIdx = 0u; inst->hereLength = 0u; inst->cursor = 0u; + inst->stdinIdx = 0u; + inst->stdinLength = 0u; inst->write("\r\n", 2u); inst->write(inst->prompt, strlen(inst->prompt)); } diff --git a/test/integrationtest/test_integration.cpp b/test/integrationtest/test_integration.cpp index c3e92f1..7e039e9 100644 --- a/test/integrationtest/test_integration.cpp +++ b/test/integrationtest/test_integration.cpp @@ -9,6 +9,8 @@ static char write_data[1024]; static uint32_t write_length; static const char *doSomethingArguments; static uint32_t doSomethingLength; +static char *doSomethingStdin; +static uint32_t doSomethingStdinLength; static shellmatta_retCode_t writeFct(const char* data, uint32_t length) { @@ -28,6 +30,9 @@ static shellmatta_retCode_t doSomething(shellmatta_handle_t handle, const char * { doSomethingArguments = arguments; doSomethingLength = length; + + shellmatta_read(handle, &doSomethingStdin, &doSomethingStdinLength); + shellmatta_printf(handle, "%s - length: %u", arguments, length); return SHELLMATTA_OK; } @@ -140,8 +145,8 @@ TEST_CASE( "shellmatta heredoc test" ) { shellmatta_handle_t handle; char buffer[1024]; char historyBuffer[1024]; - char *dummyData = (char*)"do this \r\n" - "asdf\r\n" + char *dummyData = (char*)"do this "; + char *dummyStdin = (char*)"asdf\r\n" "1234"; shellmatta_doInit( &inst, @@ -162,15 +167,14 @@ TEST_CASE( "shellmatta heredoc test" ) { "asdf\r\n" "1234\r\n" "EOF\r\n" - , 34); + , 33); - - - CHECK( doSomethingLength == 20u); + CHECK( doSomethingStdinLength == 10u); + CHECK( strcmp(dummyStdin, doSomethingStdin) == 0); + CHECK( doSomethingLength == 8u); REQUIRE( strcmp(dummyData, doSomethingArguments) == 0); } - TEST_CASE( "shellmatta remove function" ) { shellmatta_instance_t inst;