Ver Fonte

added continuous mode support fix #3
If a command returns SHELLMATTA_CONTINUE all received data is passed to this command until it returns != SHELLMATTA_CONTINUE or a cancel is received
The data is passed stdin like and can be read byte by byte vie shellmatta_read
The stdin buffer is overwritten witch each new char

prozessorkern há 4 anos atrás
pai
commit
5e84f1b022
7 ficheiros alterados com 115 adições e 52 exclusões
  1. 1 0
      api/shellmatta.h
  2. 25 0
      example/main.c
  3. 54 18
      src/shellmatta.c
  4. 1 1
      src/shellmatta_history.c
  5. 26 26
      src/shellmatta_opt.c
  6. 1 0
      src/shellmatta_utils.c
  7. 7 7
      src/shellmatta_utils.h

+ 1 - 0
api/shellmatta.h

@@ -144,6 +144,7 @@ typedef struct
     shellmatta_write_t  write;              /**< pointer to write function              */
     shellmatta_cmd_t    helpCmd;            /**< help command structure                 */
     shellmatta_cmd_t    *cmdList;           /**< pointer to the first command           */
+    shellmatta_cmd_t    *continuousCmd;     /**< command to be called continuously      */
     bool                cmdListIsConst;     /**< true if the #cmdList was passed during
                                                  initialization                         */
     shellmatta_opt_t    optionParser;       /**< option parser sructure                 */

+ 25 - 0
example/main.c

@@ -119,6 +119,30 @@ static shellmatta_retCode_t reset(shellmatta_handle_t handle, const char *argume
 }
 shellmatta_cmd_t resetCommand = {"reset", NULL, "resets the shellmatta instance", "reset [prompt]", reset, NULL};
 
+static shellmatta_retCode_t continuous(shellmatta_handle_t handle, const char *arguments, uint32_t length)
+{
+    (void)arguments;
+    (void)length;
+
+    shellmatta_retCode_t ret = SHELLMATTA_CONTINUE;
+    uint32_t stdinLength;
+    char *stdinData;
+
+    shellmatta_read(handle, &stdinData, &stdinLength);
+    if(NULL != stdinData)
+    {
+        if('x' == stdinData[0u])
+        {
+            ret = SHELLMATTA_OK;
+        }
+
+        stdinData[0u] ++;
+        shellmatta_write(handle, stdinData, stdinLength);
+    }
+    return ret;
+}
+shellmatta_cmd_t continuousCommand = {"continuous", "cont", "prints continously all input bytes", "continuous", continuous, NULL};
+
 
 shellmatta_retCode_t writeFct(const char* data, uint32_t length)
 {
@@ -164,6 +188,7 @@ int main(int argc, char **argv)
     shellmatta_addCmd(handle, &removeCommand);
     shellmatta_addCmd(handle, &emptyCommand);
     shellmatta_addCmd(handle, &resetCommand);
+    shellmatta_addCmd(handle, &continuousCommand);
 
     while(exitRequest == false)
     {

+ 54 - 18
src/shellmatta.c

@@ -96,9 +96,10 @@ shellmatta_retCode_t shellmatta_doInit(
         inst->hereLength            = 0u;
         inst->mode                  = SHELLMATTA_MODE_INSERT;
         inst->cmdList               = &(inst->helpCmd);
+        inst->continuousCmd         = NULL;
         inst->cmdListIsConst        = false;
 
-        /*! -# copy the help command structure to this instance */
+        /** -# copy the help command structure to this instance */
         memcpy(&(inst->helpCmd), &helpCmd, sizeof(shellmatta_cmd_t));
 
         if(NULL != cmdList)
@@ -132,11 +133,12 @@ shellmatta_retCode_t shellmatta_resetShell( shellmatta_handle_t handle, bool pri
     shellmatta_instance_t *inst = (shellmatta_instance_t *)handle;
     shellmatta_retCode_t ret = SHELLMATTA_OK;
 
-    /*! -# check if the instance is plausible */
+    /** -# check if the instance is plausible */
     if(     (NULL != handle)
         &&  (SHELLMATTA_MAGIC == inst->magic))
     {
         inst->inputCount            = 0u;
+        inst->continuousCmd         = NULL;
         inst->lastNewlineIdx        = 0u;
         inst->cursor                = 0u;
         inst->stdinIdx              = 0u;
@@ -276,25 +278,25 @@ shellmatta_retCode_t shellmatta_removeCmd(shellmatta_handle_t handle, shellmatta
         tempCmd     = inst->cmdList;
         prevCmd     = NULL;
 
-        /*! -# loop through command list */
+        /** -# loop through command list */
         while(NULL != tempCmd)
         {
-            /*! -# compare command strings to find the command to delete */
+            /** -# compare command strings to find the command to delete */
             if (0 == strcmp(   tempCmd->cmd,
                                 cmd->cmd)
                     && (strlen(tempCmd->cmd) == strlen(cmd->cmd)))
             {
-                /*! -# first command removed */
+                /** -# first command removed */
                 if(NULL == prevCmd)
                 {
                     inst->cmdList = tempCmd->next;
                 }
-                /*! -# last command removed */
+                /** -# last command removed */
                 else if(NULL == tempCmd->next)
                 {
                     prevCmd->next = NULL;
                 }
-                /*! -# command removed from the middle of the list */
+                /** -# command removed from the middle of the list */
                 else
                 {
                     prevCmd->next = tempCmd->next;
@@ -363,6 +365,7 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
     uint32_t                byteCounter;
 
     shellmatta_retCode_t    ret = SHELLMATTA_OK;
+    shellmatta_retCode_t    cmdRet;
     shellmatta_instance_t   *inst = (shellmatta_instance_t*)handle;
 
     /** -# check parameters for plausibility  */
@@ -372,8 +375,22 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
         /** -# process byte wise */
         for (byteCounter = 0u; byteCounter < size; 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->stdinLength               = 1u;
+                cmdRet = inst->continuousCmd->cmdFct(inst, inst->buffer, inst->inputCount);
+                
+                /** -# check if continuous mode is canceled */
+                if(('\x03' == data[byteCounter]) || (SHELLMATTA_CONTINUE != cmdRet))
+                {
+                    utils_terminateInput(inst);
+                }
+            }
             /** -# handle escape sequences */
-            if(inst->escapeCounter != 0u)
+            else if(inst->escapeCounter != 0u)
             {
                 escape_handleSequence(inst, *data);
             }
@@ -460,8 +477,8 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
                         history_storeCmd(inst);
                         history_reset(inst);
 
-                        /*! -# process heredoc as stdin like input  */
-                        /*! -# find start of heredoc data           */
+                        /** -# 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]))
@@ -481,7 +498,7 @@ 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 - print the \r and add a \n to satisfy most terminals */
                         inst->lastNewlineIdx = inst->inputCount;
                         utils_insertChars(inst, data, 1u);
                     }
@@ -519,7 +536,15 @@ 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, inst->buffer, inst->inputCount);
+                            cmdRet = cmd->cmdFct(inst, inst->buffer, inst->inputCount);
+                            if(SHELLMATTA_CONTINUE == cmdRet)
+                            {
+                                inst->continuousCmd = cmd;
+
+                                /** -# initialize stdin buffer */
+                                inst->stdinIdx      = inst->inputCount + 1u;
+                                inst->stdinLength   = 0u;
+                            }
                             cmd = NULL;
                         }
                         else
@@ -534,9 +559,13 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
                         inst->write(inst->buffer, inst->inputCount);
                         inst->write(" not found", 10u);
                     }
-                    utils_terminateInput(inst);
-                }
 
+                    /** -# terminate this session if no continuous mode is requested */
+                    if(NULL == inst->continuousCmd)
+                    {
+                        utils_terminateInput(inst);
+                    }
+                }
             }
             /** -# check for tabulator key - auto complete */
             else if('\t' == *data)
@@ -546,7 +575,7 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
             }
             /** -# check for cancel -
              *      terminate current input and print prompt again */
-            else if(3 == *data)
+            else if('\x03' == *data)
             {
                 inst->dirty = false;
                 history_reset(inst);
@@ -614,7 +643,7 @@ shellmatta_retCode_t shellmatta_write(  shellmatta_handle_t handle,
 /**
  * @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]  data    stdin data or NULL
  * @param[out]  length  size of the stdin data
  * @return
  */
@@ -631,8 +660,15 @@ shellmatta_retCode_t shellmatta_read(   shellmatta_handle_t handle,
         &&  (NULL               != data)
         &&  (NULL               != length))
     {
-        /** -# return a pointer to the data */
-        *data   = &(inst->buffer[inst->stdinIdx]);
+        /** -# return a pointer to the data or NULL */
+        if(0u == inst->stdinLength)
+        {
+            *data = NULL;
+        }
+        else
+        {
+            *data = &(inst->buffer[inst->stdinIdx]);
+        }
         *length = inst->stdinLength;
     }
 

+ 1 - 1
src/shellmatta_history.c

@@ -205,7 +205,7 @@ void history_restoreCmd(shellmatta_instance_t *inst)
 
     ret = getHistoryByte(inst, &byte);
 
-    /*! -# delete the input if there is data in the history buffer */
+    /** -# delete the input if there is data in the history buffer */
     if(true == ret)
     {
         utils_clearInput(inst);

+ 26 - 26
src/shellmatta_opt.c

@@ -36,7 +36,7 @@ static shellmatta_retCode_t findNextHunk(shellmatta_instance_t *inst)
     uint32_t exeptionOffset = 0u;
     char quotation = '\0';  /* holds the current quotation mark if any */
 
-    /*! -# find beginning of next hunk */
+    /** -# find beginning of next hunk */
     while(  (newOffset  < inst->inputCount)
         &&     ((' '        == inst->buffer[newOffset])
             ||  ('\0'       == inst->buffer[newOffset])))
@@ -46,21 +46,21 @@ static shellmatta_retCode_t findNextHunk(shellmatta_instance_t *inst)
 
     inst->optionParser.offset = newOffset;
 
-    /*! -# determine length */
+    /** -# determine length */
     while((newOffset < inst->inputCount)
         && (((' ' != inst->buffer[newOffset]) && ('\0' != inst->buffer[newOffset])) || '\0' != quotation))
     {
-        /*! -# check for new quotation */
+        /** -# check for new quotation */
         if((('\'' == inst->buffer[newOffset]) || ('"' == inst->buffer[newOffset])) && (quotation == '\0'))
         {
             quotation = inst->buffer[newOffset];
             exeptionOffset ++;
         }
-        /*! -# check if quotation has ended */
+        /** -# check if quotation has ended */
         else if(quotation == inst->buffer[newOffset])
         {
             exeptionOffset ++;
-            /*!  -# check if quotation is excaped */
+            /** -# check if quotation is excaped */
             if('\\' != inst->buffer[newOffset - 1u])
             {
                 quotation = '\0';
@@ -72,7 +72,7 @@ static shellmatta_retCode_t findNextHunk(shellmatta_instance_t *inst)
         }
         else
         {
-            /*! -# shift back chars */
+            /** -# shift back chars */
             if(0u != exeptionOffset)
             {
                 inst->buffer[newOffset - exeptionOffset] = inst->buffer[newOffset];
@@ -84,7 +84,7 @@ static shellmatta_retCode_t findNextHunk(shellmatta_instance_t *inst)
     inst->optionParser.nextOffset   = newOffset;
     inst->optionParser.len          = newOffset - inst->optionParser.offset - exeptionOffset;
 
-    /*! -# add terminating 0 */
+    /** -# add terminating 0 */
     inst->buffer[inst->optionParser.offset + inst->optionParser.len] = '\0';
 
     if((inst->optionParser.offset < inst->inputCount) && (0u != inst->optionParser.len) && ('\0' == quotation))
@@ -104,7 +104,7 @@ static char peekNextHunk(shellmatta_instance_t *inst)
 {
     uint32_t newOffset = inst->optionParser.nextOffset;
 
-    /*! -# find beginning of next hunk */
+    /** -# find beginning of next hunk */
     while(  (newOffset  < inst->inputCount)
         &&     ((' '        == inst->buffer[newOffset])
             ||  ('\0'       == inst->buffer[newOffset])))
@@ -132,22 +132,22 @@ static shellmatta_retCode_t parseShortOpt(  shellmatta_instance_t       *inst,
     char *buffer = &inst->buffer[inst->optionParser.offset];
     uint32_t i;
 
-    /*! -# check for correct syntax */
+    /** -# check for correct syntax */
     if((2u == inst->optionParser.len) && ('-' == buffer[0u]) && ('-' != buffer[1u]) && ('\0' != buffer[1u]))
     {
         *option = '\0';
 
-        /*! -# search for option character in option string */
+        /** -# search for option character in option string */
         for(i = 0u; ('\0' != optionString[i]) && ('\0' == *option); i ++)
         {
             if(buffer[1u] == optionString[i])
             {
                 ret = SHELLMATTA_OK;
 
-                /*! -# return found option character */
+                /** -# return found option character */
                 *option = buffer[1u];
 
-                /*! -# check if an argument is required or optional */
+                /** -# check if an argument is required or optional */
                 if(':' == optionString[i + 1u])
                 {
                     *argtype = SHELLMATTA_OPT_ARG_REQUIRED;
@@ -163,7 +163,7 @@ static shellmatta_retCode_t parseShortOpt(  shellmatta_instance_t       *inst,
             }
         }
     }
-    /*! -# skip "--" */
+    /** -# skip "--" */
     else if((2u == inst->optionParser.len) && ('-' == buffer[0u]) && ('-' == buffer[1u]))
     {
         ret = SHELLMATTA_CONTINUE;
@@ -194,39 +194,39 @@ static shellmatta_retCode_t parseLongOpt(   shellmatta_instance_t       *inst,
     char *buffer = &inst->buffer[inst->optionParser.offset];
     uint32_t i;
 
-    /*! -# check for correct syntax for short options */
+    /** -# check for correct syntax for short options */
     if((2u == inst->optionParser.len) && ('-' == buffer[0u]) && ('-' != buffer[1u]) && ('\0' != buffer[1u]))
     {
-        /*! -# search for option character in option list */
+        /** -# search for option character in option list */
         for(i = 0u; ('\0' != longOptions[i].paramShort) && ('\0' == *option); i ++)
         {
             if(buffer[1u] == longOptions[i].paramShort)
             {
                 ret = SHELLMATTA_OK;
 
-                /*! -# return found option character */
+                /** -# return found option character */
                 *option     = longOptions[i].paramShort;
                 *argtype    = longOptions[i].argtype;
             }
         }
     }
-    /*! -# check for correct syntax for long options */
+    /** -# check for correct syntax for long options */
     else if((3u <= inst->optionParser.len) && ('-' == buffer[0u]) && ('-' == buffer[1u]))
     {
-        /*! -# search for long option in option list */
+        /** -# search for long option in option list */
         for(i = 0u; ('\0' != longOptions[i].paramShort) && ('\0' == *option); i ++)
         {
             if(0 == strcmp(&buffer[2u], longOptions[i].paramLong))
             {
                 ret = SHELLMATTA_OK;
 
-                /*! -# return found option character */
+                /** -# return found option character */
                 *option     = longOptions[i].paramShort;
                 *argtype    = longOptions[i].argtype;
             }
         }
     }
-    /*! -# ignore "--" */
+    /** -# ignore "--" */
     else if((2u == inst->optionParser.len) && ('-' == buffer[0u]) && ('-' == buffer[1u]))
     {
         *option = '\0';
@@ -279,13 +279,13 @@ static shellmatta_retCode_t shellmatta_opt_int( shellmatta_handle_t     handle,
             *argLen = 0u;
         }
 
-        /*! -# do this until we find a not skipable argument */
+        /** -# do this until we find a not skipable argument */
         do
         {
             ret = findNextHunk(inst);
             if(SHELLMATTA_OK == ret)
             {
-                /*! -# call the matching parse function */
+                /** -# call the matching parse function */
                 if(NULL != optionString)
                 {
                     ret = parseShortOpt(inst, optionString, option, &argtype);
@@ -299,7 +299,7 @@ static shellmatta_retCode_t shellmatta_opt_int( shellmatta_handle_t     handle,
                     ret = SHELLMATTA_USE_FAULT;
                 }
 
-                /*! -# when no option is found return this as raw argument */
+                /** -# when no option is found return this as raw argument */
                 if(SHELLMATTA_ERROR == ret)
                 {
                     if(NULL != argument)
@@ -314,7 +314,7 @@ static shellmatta_retCode_t shellmatta_opt_int( shellmatta_handle_t     handle,
                 }
                 else if(SHELLMATTA_USE_FAULT == ret)
                 {
-                    /*! -# nothing to do - just return errorcode */
+                    /** -# nothing to do - just return errorcode */
                 }
                 else
                 {
@@ -333,7 +333,7 @@ static shellmatta_retCode_t shellmatta_opt_int( shellmatta_handle_t     handle,
                             }
                             break;
                         case SHELLMATTA_OPT_ARG_OPTIONAL:
-                            /*! -# treat anything not starting with '-' as argument */
+                            /** -# treat anything not starting with '-' as argument */
                             if('-' != peekNextHunk(inst))
                             {
                                 ret = findNextHunk(inst);
@@ -412,7 +412,7 @@ shellmatta_retCode_t shellmatta_opt_long(   shellmatta_handle_t     handle,
  */
 shellmatta_retCode_t shellmatta_opt_init(shellmatta_instance_t *inst, uint32_t argStart)
 {
-    /*! -# initialize all relevant option parser variables */
+    /** -# initialize all relevant option parser variables */
     inst->optionParser.nextOffset = argStart;
 
     return SHELLMATTA_OK;

+ 1 - 0
src/shellmatta_utils.c

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

+ 7 - 7
src/shellmatta_utils.h

@@ -40,12 +40,12 @@ extern const shellmatta_cmd_t helpCmd;
 
 #define SHELLMATTA_MAGIC    0x5101E110u
 
-/*! \brief overwritable output buffer size */
+/** \brief overwritable output buffer size */
 #ifndef SHELLMATTA_OUTPUT_BUFFER_SIZE
 #define SHELLMATTA_OUTPUT_BUFFER_SIZE   128u
 #endif
 
-/*! @defgroup Shellmatta Help command overwrites
+/** @defgroup Shellmatta Help command overwrites
  *  @{
  *  overwritable help command parameters - the help command is built in and cannot be removed, but you can change
  *  the command, alias and help texts by defining them in your build process  
@@ -57,18 +57,18 @@ extern const shellmatta_cmd_t helpCmd;
  *  e.g. use _-DSHELLMATTA_HELP_ALIAS=\"?\"_ as compile option to change the alias to ?
  */
 #ifndef SHELLMATTA_HELP_COMMAND
-#define SHELLMATTA_HELP_COMMAND     (char*)"help"                   /*!< help command               */
+#define SHELLMATTA_HELP_COMMAND     (char*)"help"                   /**< help command               */
 #endif
 #ifndef SHELLMATTA_HELP_ALIAS
-#define SHELLMATTA_HELP_ALIAS       (char*)"h"                      /*!< help command alias         */
+#define SHELLMATTA_HELP_ALIAS       (char*)"h"                      /**< help command alias         */
 #endif
 #ifndef SHELLMATTA_HELP_HELP_TEXT
-#define SHELLMATTA_HELP_HELP_TEXT   (char*)"Print this help text"   /*!< help command help text     */
+#define SHELLMATTA_HELP_HELP_TEXT   (char*)"Print this help text"   /**< help command help text     */
 #endif
 #ifndef SHELLMATTA_HELP_USAGE_TEXT
-#define SHELLMATTA_HELP_USAGE_TEXT  (char*)"help"                   /*!< help command usage text    */
+#define SHELLMATTA_HELP_USAGE_TEXT  (char*)"help"                   /**< help command usage text    */
 #endif
-/*!
+/**
  *  @}
  */