Browse Source

changed heredoc support
now the input string is kept intact until the end of the input is reached
this enables the history buffer to store the complete command
Still broken:
history buffer with heredoc wont execute because the delimiter is not determined correctly
editing of multiline things

prozessorkern 5 years ago
parent
commit
16365f341e
3 changed files with 67 additions and 37 deletions
  1. 2 1
      api/shellmatta.h
  2. 2 2
      example/main.c
  3. 63 34
      src/shellmatta.c

+ 2 - 1
api/shellmatta.h

@@ -102,7 +102,8 @@ typedef struct
     uint32_t            tabCounter;         /**< counts the tabulator key presses       */
     uint32_t            tabCounter;         /**< counts the tabulator key presses       */
     uint32_t            escapeCounter;      /**< counts the characters of an escape seq */
     uint32_t            escapeCounter;      /**< counts the characters of an escape seq */
     char                escapeChars[4u];    /**< buffer to save the escape characters   */
     char                escapeChars[4u];    /**< buffer to save the escape characters   */
-    char                hereDelimiter[16u]; /**< heredoc delimiter                      */
+    uint32_t            hereStartIdx;       /**< heredoc start of "<<"                  */
+    uint32_t            hereDelimiterIdx;   /**< heredoc delimiter index in input       */
     uint32_t            hereLength;         /**< length of the heredoc delimiter        */
     uint32_t            hereLength;         /**< length of the heredoc delimiter        */
     bool                echoEnabled;        /**< if true the input is printed           */
     bool                echoEnabled;        /**< if true the input is printed           */
     bool                dirty;              /**< dirty flag to show changes             */
     bool                dirty;              /**< dirty flag to show changes             */

+ 2 - 2
example/main.c

@@ -42,7 +42,7 @@ void set_blocking (int fd, int should_block)
 
 
 static shellmatta_retCode_t doSomething(shellmatta_handle_t handle, const char *arguments, uint32_t length)
 static shellmatta_retCode_t doSomething(shellmatta_handle_t handle, const char *arguments, uint32_t length)
 {
 {
-
+    shellmatta_printf(handle, "%s - length: %u", arguments, length);
     return SHELLMATTA_OK;
     return SHELLMATTA_OK;
 }
 }
 shellmatta_cmd_t doSomethingCmd = {"doSomething", "do", "Function does something", "use me, please", doSomething, NULL};
 shellmatta_cmd_t doSomethingCmd = {"doSomething", "do", "Function does something", "use me, please", doSomething, NULL};
@@ -79,7 +79,7 @@ int main(void)
     static char historyBuffer[4096];
     static char historyBuffer[4096];
     static shellmatta_instance_t instance;
     static shellmatta_instance_t instance;
 
 
-    f = open("/dev/pts/1", O_RDWR | O_SYNC);
+    f = open("/dev/pts/3", O_RDWR | O_SYNC);
 
 
     if (f < 0)
     if (f < 0)
     {
     {

+ 63 - 34
src/shellmatta.c

@@ -88,6 +88,8 @@ shellmatta_retCode_t shellmatta_doInit(
         inst->dirty                 = false;
         inst->dirty                 = false;
         inst->tabCounter            = 0u;
         inst->tabCounter            = 0u;
         inst->escapeCounter         = 0u;
         inst->escapeCounter         = 0u;
+        inst->hereStartIdx          = 0u;
+        inst->hereDelimiterIdx      = 0u;
         inst->hereLength            = 0u;
         inst->hereLength            = 0u;
         inst->mode                  = SHELLMATTA_MODE_INSERT;
         inst->mode                  = SHELLMATTA_MODE_INSERT;
         inst->cmdList               = &helpCmd;
         inst->cmdList               = &helpCmd;
@@ -197,6 +199,11 @@ 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                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;
 
 
@@ -205,7 +212,7 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
         &&  (SHELLMATTA_MAGIC   == inst->magic))
         &&  (SHELLMATTA_MAGIC   == inst->magic))
     {
     {
         /** -# process byte wise */
         /** -# process byte wise */
-        for (uint32_t i = 0u; i < size; i++)
+        for (byteCounter = 0u; byteCounter < size; byteCounter++)
         {
         {
             /** -# handle escape sequences */
             /** -# handle escape sequences */
             if(inst->escapeCounter != 0u)
             if(inst->escapeCounter != 0u)
@@ -239,31 +246,41 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
                         /*' -# check if length of heredoc delimiter is valid */
                         /*' -# check if length of heredoc delimiter is valid */
                         if(inst->inputCount > ((uint32_t)(tempString - inst->buffer) + 2u))
                         if(inst->inputCount > ((uint32_t)(tempString - inst->buffer) + 2u))
                         {
                         {
-                            inst->hereLength = inst->inputCount - ((uint32_t)(tempString - inst->buffer) + 2u);
-
-                            if(sizeof(inst->hereDelimiter) < inst->hereLength)
+                            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->write("\r\nHeredoc delimiter too long\r\n", 30u);
-                                inst->inputCount = 0u;
-                                inst->hereLength    = 0u;
-                            }
-                            else
-                            {
-                                /** -# store delimiter and remove it from the input buffer */
-                                strncpy(inst->hereDelimiter, &(tempString[2u]), inst->hereLength);
-
-                                inst->inputCount    -= (inst->hereLength + 2u);
-                                inst->cursor        = inst->inputCount;
-                                inst->dirty = true;
-                                utils_insertChars(inst, data, 1);
-                                inst->lastNewlineIdx = inst->inputCount;
+                                inst->hereDelimiterIdx ++;
                             }
                             }
+
+                            inst->hereLength = inst->inputCount - inst->hereDelimiterIdx;
+
+                            inst->dirty = true;
+                            utils_insertChars(inst, data, 1);
+                            inst->lastNewlineIdx = inst->inputCount;
                         }
                         }
                         else
                         else
                         {
                         {
                             inst->hereLength    = 0u;
                             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
                 else
                 {
                 {
@@ -278,11 +295,27 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
                     }
                     }
 
 
                     if(     (inst->hereLength == cmdLen)
                     if(     (inst->hereLength == cmdLen)
-                        &&  (0  == strncmp( inst->hereDelimiter,
+                        &&  (0  == strncmp( &inst->buffer[inst->hereDelimiterIdx],
                                             tempString,
                                             tempString,
                                             inst->hereLength)))
                                             inst->hereLength)))
                     {
                     {
-                        inst->inputCount = inst->lastNewlineIdx;
+                        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];
+                        }
+
+                        argumentString = &(inst->buffer[inst->hereDelimiterIdx + inst->hereLength - inst->hereStartIdx]);
+                        argumentLength = inst->lastNewlineIdx - ((inst->hereDelimiterIdx + inst->hereLength) - inst->hereStartIdx);
                         inst->hereLength = 0u;
                         inst->hereLength = 0u;
                     }
                     }
                     else
                     else
@@ -295,18 +328,15 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
                 if(0u == inst->hereLength)
                 if(0u == inst->hereLength)
                 {
                 {
                     cmd                             = inst->cmdList;
                     cmd                             = inst->cmdList;
-                    inst->buffer[inst->inputCount]  = 0u;
-
-                    /** -# store the current command and reset the history buffer */
-                    inst->dirty = true;
-                    history_storeCmd(inst);
-                    history_reset(inst);
+                    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 <   inst->inputCount)
-                            &&  (' '    !=  inst->buffer[cmdLen])
-                            &&  ('\0'   !=  inst->buffer[cmdLen]))
+                    while(      (cmdLen <   argumentLength)
+                            &&  (' '    !=  argumentString[cmdLen])
+                            &&  ('\r'   !=  argumentString[cmdLen])
+                            &&  ('\n'   !=  argumentString[cmdLen])
+                            &&  ('\0'   !=  argumentString[cmdLen]))
                     {
                     {
                         cmdLen ++;
                         cmdLen ++;
                     }
                     }
@@ -315,11 +345,11 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
                     while (NULL != cmd)
                     while (NULL != cmd)
                     {
                     {
                         /** -# compare command string and length */
                         /** -# compare command string and length */
-                        if (    ((0 == strncmp( inst->buffer,
+                        if (    ((0 == strncmp( argumentString,
                                                 cmd->cmd,
                                                 cmd->cmd,
                                                 cmdLen))
                                                 cmdLen))
                                 && (cmdLen == strlen(cmd->cmd)))
                                 && (cmdLen == strlen(cmd->cmd)))
-                            ||  ((0 == strncmp( inst->buffer,
+                            ||  ((0 == strncmp( argumentString,
                                                 cmd->cmdAlias,
                                                 cmd->cmdAlias,
                                                 cmdLen))
                                                 cmdLen))
                                 && (cmdLen == strlen(cmd->cmdAlias))))
                                 && (cmdLen == strlen(cmd->cmdAlias))))
@@ -327,7 +357,7 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
                             inst->write("\r\n", 2u);
                             inst->write("\r\n", 2u);
 
 
                             cmdExecuted = 1u;
                             cmdExecuted = 1u;
-                            cmd->cmdFct(inst, inst->buffer, inst->inputCount);
+                            cmd->cmdFct(inst, argumentString, argumentLength);
                             cmd = NULL;
                             cmd = NULL;
                         }
                         }
                         else
                         else
@@ -338,9 +368,8 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
 
 
                     if ((cmdExecuted == 0u) && (inst->inputCount > 0))
                     if ((cmdExecuted == 0u) && (inst->inputCount > 0))
                     {
                     {
-                        inst->buffer[inst->inputCount] = '\0';
                         inst->write("\r\nCommand: ", 11u);
                         inst->write("\r\nCommand: ", 11u);
-                        inst->write(inst->buffer, inst->inputCount);
+                        inst->write(argumentString, argumentLength);
                         inst->write(" not found", 10u);
                         inst->write(" not found", 10u);
                     }
                     }
                     utils_terminateInput(inst);
                     utils_terminateInput(inst);