changed heredoc to exchange data via a stdin like interface with a read function fix #39

This commit is contained in:
prozessorkern 2020-03-22 20:37:00 +01:00
parent 5a00f22e31
commit 17bb88d292
4 changed files with 75 additions and 34 deletions

View File

@ -123,6 +123,8 @@ typedef struct
uint32_t inputCount; /**< offset of the current write operation */ uint32_t inputCount; /**< offset of the current write operation */
uint32_t lastNewlineIdx; /**< index of the lest newline */ uint32_t lastNewlineIdx; /**< index of the lest newline */
uint32_t cursor; /**< offset where the cursor is at */ 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 */ char *historyBuffer; /**< buffer to store the last commands */
uint32_t historyBufferSize; /**< size of the history buffer */ uint32_t historyBufferSize; /**< size of the history buffer */
uint32_t historyStart; /**< index of the oldest stored command */ uint32_t historyStart; /**< index of the oldest stored command */
@ -179,6 +181,10 @@ shellmatta_retCode_t shellmatta_write( shellmatta_handle_t handle,
char *data, char *data,
uint32_t length); 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, shellmatta_retCode_t shellmatta_opt( shellmatta_handle_t handle,
char *optionString, char *optionString,
char *option, char *option,

View File

@ -77,6 +77,8 @@ shellmatta_retCode_t shellmatta_doInit(
inst->inputCount = 0u; inst->inputCount = 0u;
inst->lastNewlineIdx = 0u; inst->lastNewlineIdx = 0u;
inst->cursor = 0u; inst->cursor = 0u;
inst->stdinIdx = 0u;
inst->stdinLength = 0u;
inst->historyBuffer = historyBuffer; inst->historyBuffer = historyBuffer;
inst->historyBufferSize = historyBufferSize; inst->historyBufferSize = historyBufferSize;
inst->historyStart = 0u; inst->historyStart = 0u;
@ -137,6 +139,8 @@ shellmatta_retCode_t shellmatta_resetShell( shellmatta_handle_t handle, bool pri
inst->inputCount = 0u; inst->inputCount = 0u;
inst->lastNewlineIdx = 0u; inst->lastNewlineIdx = 0u;
inst->cursor = 0u; inst->cursor = 0u;
inst->stdinIdx = 0u;
inst->stdinLength = 0u;
inst->historyStart = 0u; inst->historyStart = 0u;
inst->historyEnd = 0u; inst->historyEnd = 0u;
inst->historyRead = 0u; inst->historyRead = 0u;
@ -356,10 +360,7 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle,
uint8_t cmdExecuted = 0u; uint8_t cmdExecuted = 0u;
uint32_t cmdLen; uint32_t cmdLen;
char *tempString; char *tempString;
char *argumentString;
uint32_t argumentLength;
uint32_t byteCounter; uint32_t byteCounter;
uint32_t idx;
shellmatta_retCode_t ret = SHELLMATTA_OK; shellmatta_retCode_t ret = SHELLMATTA_OK;
shellmatta_instance_t *inst = (shellmatta_instance_t*)handle; shellmatta_instance_t *inst = (shellmatta_instance_t*)handle;
@ -371,10 +372,6 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle,
/** -# process byte wise */ /** -# process byte wise */
for (byteCounter = 0u; byteCounter < size; byteCounter++) 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 */ /** -# handle escape sequences */
if(inst->escapeCounter != 0u) if(inst->escapeCounter != 0u)
{ {
@ -458,23 +455,28 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle,
tempString, tempString,
inst->hereLength))) inst->hereLength)))
{ {
argumentLength = inst->lastNewlineIdx;
/** -# store the current command and reset the history buffer */ /** -# store the current command and reset the history buffer */
inst->dirty = true; inst->dirty = true;
history_storeCmd(inst); history_storeCmd(inst);
history_reset(inst); history_reset(inst);
/*! -# process heredoc as stdin like input */
/* TODO it is difficult to store the complete command in the history buffer if it is restructured before... /*! -# find start of heredoc data */
* So this should be an extra function that can be called after parsing the command and before calling the command function */ inst->stdinIdx = inst->hereDelimiterIdx + inst->hereLength;
for(idx = 1u; idx <= inst->hereStartIdx; idx++) 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]); /** -# terminate heredoc session */
argumentLength = inst->lastNewlineIdx - ((inst->hereDelimiterIdx + inst->hereLength) - inst->hereStartIdx);
inst->hereLength = 0u; inst->hereLength = 0u;
} }
else else
@ -487,16 +489,15 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle,
if(0u == inst->hereLength) if(0u == inst->hereLength)
{ {
cmd = inst->cmdList; cmd = inst->cmdList;
argumentString[argumentLength] = 0u;
/** -# determine the cmd len (chars until first space or \0 is found */ /** -# determine the cmd len (chars until first space or \0 is found */
cmdLen = 0u; cmdLen = 0u;
while( (cmdLen < argumentLength) while( (cmdLen < inst->inputCount)
&& (' ' != argumentString[cmdLen]) && (' ' != inst->buffer[cmdLen])
&& ('\r' != argumentString[cmdLen]) && ('\r' != inst->buffer[cmdLen])
&& ('\n' != argumentString[cmdLen]) && ('\n' != inst->buffer[cmdLen])
&& ('\0' != argumentString[cmdLen])) && ('\0' != inst->buffer[cmdLen]))
{ {
cmdLen ++; cmdLen ++;
} }
@ -505,12 +506,12 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle,
while (NULL != cmd) while (NULL != cmd)
{ {
/** -# compare command and alias string and length */ /** -# compare command and alias string and length */
if ( ((0 == strncmp( argumentString, if ( ((0 == strncmp( inst->buffer,
cmd->cmd, cmd->cmd,
cmdLen)) cmdLen))
&& (cmdLen == strlen(cmd->cmd))) && (cmdLen == strlen(cmd->cmd)))
|| ((NULL != cmd->cmdAlias) || ((NULL != cmd->cmdAlias)
&& ((0 == strncmp( argumentString, && ((0 == strncmp( inst->buffer,
cmd->cmdAlias, cmd->cmdAlias,
cmdLen)) cmdLen))
&& (cmdLen == strlen(cmd->cmdAlias))))) && (cmdLen == strlen(cmd->cmdAlias)))))
@ -518,7 +519,7 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle,
utils_writeEcho(inst, "\r\n", 2u); utils_writeEcho(inst, "\r\n", 2u);
shellmatta_opt_init(inst, cmdLen + 1u); shellmatta_opt_init(inst, cmdLen + 1u);
cmdExecuted = 1u; cmdExecuted = 1u;
cmd->cmdFct(inst, argumentString, argumentLength); cmd->cmdFct(inst, inst->buffer, inst->inputCount);
cmd = NULL; cmd = NULL;
} }
else else
@ -530,7 +531,7 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle,
if ((cmdExecuted == 0u) && (inst->inputCount > 0)) if ((cmdExecuted == 0u) && (inst->inputCount > 0))
{ {
inst->write("\r\nCommand: ", 11u); inst->write("\r\nCommand: ", 11u);
inst->write(argumentString, argumentLength); inst->write(inst->buffer, inst->inputCount);
inst->write(" not found", 10u); inst->write(" not found", 10u);
} }
utils_terminateInput(inst); utils_terminateInput(inst);
@ -610,6 +611,34 @@ shellmatta_retCode_t shellmatta_write( shellmatta_handle_t handle,
return ret; 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 #ifndef SHELLMATTA_STRIP_PRINTF
/** /**

View File

@ -364,6 +364,8 @@ void utils_terminateInput(shellmatta_instance_t *inst)
inst->lastNewlineIdx = 0u; inst->lastNewlineIdx = 0u;
inst->hereLength = 0u; inst->hereLength = 0u;
inst->cursor = 0u; inst->cursor = 0u;
inst->stdinIdx = 0u;
inst->stdinLength = 0u;
inst->write("\r\n", 2u); inst->write("\r\n", 2u);
inst->write(inst->prompt, strlen(inst->prompt)); inst->write(inst->prompt, strlen(inst->prompt));
} }

View File

@ -9,6 +9,8 @@ static char write_data[1024];
static uint32_t write_length; static uint32_t write_length;
static const char *doSomethingArguments; static const char *doSomethingArguments;
static uint32_t doSomethingLength; static uint32_t doSomethingLength;
static char *doSomethingStdin;
static uint32_t doSomethingStdinLength;
static shellmatta_retCode_t writeFct(const char* data, uint32_t length) 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; doSomethingArguments = arguments;
doSomethingLength = length; doSomethingLength = length;
shellmatta_read(handle, &doSomethingStdin, &doSomethingStdinLength);
shellmatta_printf(handle, "%s - length: %u", arguments, length); shellmatta_printf(handle, "%s - length: %u", arguments, length);
return SHELLMATTA_OK; return SHELLMATTA_OK;
} }
@ -140,8 +145,8 @@ TEST_CASE( "shellmatta heredoc test" ) {
shellmatta_handle_t handle; shellmatta_handle_t handle;
char buffer[1024]; char buffer[1024];
char historyBuffer[1024]; char historyBuffer[1024];
char *dummyData = (char*)"do this \r\n" char *dummyData = (char*)"do this ";
"asdf\r\n" char *dummyStdin = (char*)"asdf\r\n"
"1234"; "1234";
shellmatta_doInit( &inst, shellmatta_doInit( &inst,
@ -162,15 +167,14 @@ TEST_CASE( "shellmatta heredoc test" ) {
"asdf\r\n" "asdf\r\n"
"1234\r\n" "1234\r\n"
"EOF\r\n" "EOF\r\n"
, 34); , 33);
CHECK( doSomethingStdinLength == 10u);
CHECK( strcmp(dummyStdin, doSomethingStdin) == 0);
CHECK( doSomethingLength == 20u); CHECK( doSomethingLength == 8u);
REQUIRE( strcmp(dummyData, doSomethingArguments) == 0); REQUIRE( strcmp(dummyData, doSomethingArguments) == 0);
} }
TEST_CASE( "shellmatta remove function" ) { TEST_CASE( "shellmatta remove function" ) {
shellmatta_instance_t inst; shellmatta_instance_t inst;