ソースを参照

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 年 前
コミット
16365f341e
3 ファイル変更67 行追加37 行削除
  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            escapeCounter;      /**< counts the characters of an escape seq */
     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        */
     bool                echoEnabled;        /**< if true the input is printed           */
     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)
 {
-
+    shellmatta_printf(handle, "%s - length: %u", arguments, length);
     return SHELLMATTA_OK;
 }
 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 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)
     {

+ 63 - 34
src/shellmatta.c

@@ -88,6 +88,8 @@ 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;
@@ -197,6 +199,11 @@ 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;
 
@@ -205,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)
@@ -239,31 +246,41 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
                         /*' -# check if length of heredoc delimiter is valid */
                         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
                         {
                             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
                 {
@@ -278,11 +295,27 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
                     }
 
                     if(     (inst->hereLength == cmdLen)
-                        &&  (0  == strncmp( inst->hereDelimiter,
+                        &&  (0  == strncmp( &inst->buffer[inst->hereDelimiterIdx],
                                             tempString,
                                             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;
                     }
                     else
@@ -295,18 +328,15 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
                 if(0u == inst->hereLength)
                 {
                     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 */
                     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 ++;
                     }
@@ -315,11 +345,11 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
                     while (NULL != cmd)
                     {
                         /** -# compare command string and length */
-                        if (    ((0 == strncmp( inst->buffer,
+                        if (    ((0 == strncmp( argumentString,
                                                 cmd->cmd,
                                                 cmdLen))
                                 && (cmdLen == strlen(cmd->cmd)))
-                            ||  ((0 == strncmp( inst->buffer,
+                            ||  ((0 == strncmp( argumentString,
                                                 cmd->cmdAlias,
                                                 cmdLen))
                                 && (cmdLen == strlen(cmd->cmdAlias))))
@@ -327,7 +357,7 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
                             inst->write("\r\n", 2u);
 
                             cmdExecuted = 1u;
-                            cmd->cmdFct(inst, inst->buffer, inst->inputCount);
+                            cmd->cmdFct(inst, argumentString, argumentLength);
                             cmd = NULL;
                         }
                         else
@@ -338,9 +368,8 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
 
                     if ((cmdExecuted == 0u) && (inst->inputCount > 0))
                     {
-                        inst->buffer[inst->inputCount] = '\0';
                         inst->write("\r\nCommand: ", 11u);
-                        inst->write(inst->buffer, inst->inputCount);
+                        inst->write(argumentString, argumentLength);
                         inst->write(" not found", 10u);
                     }
                     utils_terminateInput(inst);