소스 검색

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);