prozessorkern 4 роки тому
батько
коміт
785d73306d

+ 1 - 1
.vscode/launch.json

@@ -9,7 +9,7 @@
             "type": "cppdbg",
             "request": "launch",
             "program": "${workspaceFolder}/output/example/example",
-            "args": ["/dev/pts/3"],
+            "args": ["/dev/pts/4"],
             "stopAtEntry": false,
             "cwd": "${workspaceFolder}",
             "environment": [],

+ 10 - 7
api/shellmatta.h

@@ -39,7 +39,8 @@ typedef enum
     SHELLMATTA_ERROR            ,   /**< error occured                  */
     SHELLMATTA_CONTINUE         ,   /**< the function is not over       */
     SHELLMATTA_USE_FAULT        ,   /**< parameter error - wrong usage  */
-    SHELLMATTA_DUPLICATE            /**< duplicate command              */
+    SHELLMATTA_DUPLICATE        ,   /**< duplicate command              */
+    SHELLMATTA_BUSY                 /**< command is busy keep calling   */
 } shellmatta_retCode_t;
 
 /**
@@ -121,6 +122,7 @@ typedef struct
     char                *buffer;            /**< input buffer                           */
     uint32_t            bufferSize;         /**< size of the input buffer               */
     uint32_t            inputCount;         /**< offset of the current write operation  */
+    uint32_t            byteCounter;        /**< counter used to loop over input data   */
     uint32_t            lastNewlineIdx;     /**< index of the lest newline              */
     uint32_t            cursor;             /**< offset where the cursor is at          */
     uint32_t            stdinIdx;           /**< start index of stdin in buffer         */
@@ -146,6 +148,7 @@ typedef struct
     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      */
+    shellmatta_cmd_t    *busyCmd;           /**< command to be polled (busy mode)       */
     bool                cmdListIsConst;     /**< true if the #cmdList was passed during
                                                  initialization                         */
     shellmatta_opt_t    optionParser;       /**< option parser sructure                 */
@@ -189,16 +192,16 @@ shellmatta_retCode_t shellmatta_read(       shellmatta_handle_t handle,
                                             uint32_t            *length);
 
 shellmatta_retCode_t shellmatta_opt(        shellmatta_handle_t handle,
-                                            char                *optionString,
+                                            const char          *optionString,
                                             char                *option,
                                             char                **argument,
                                             uint32_t            *argLen);
 
-shellmatta_retCode_t shellmatta_opt_long(   shellmatta_handle_t     handle,
-                                            shellmatta_opt_long_t   *longOptions,
-                                            char                    *option,
-                                            char                    **argument,
-                                            uint32_t                *argLen);
+shellmatta_retCode_t shellmatta_opt_long(   shellmatta_handle_t         handle,
+                                            const shellmatta_opt_long_t *longOptions,
+                                            char                        *option,
+                                            char                        **argument,
+                                            uint32_t                    *argLen);
 
 #ifndef SHELLMATTA_STRIP_PRINTF
 shellmatta_retCode_t shellmatta_printf(     shellmatta_handle_t handle,

+ 71 - 33
example/main.c

@@ -1,19 +1,23 @@
 /*
- * main.c
+ * Copyright (c) 2019 Stefan Strobel <stefan.strobel@shimatta.net>
  *
- *  Created on: Jun 10, 2019
- *      Author: stefan
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  */
 
+/**
+ * @file    main.c
+ * @brief   main module to demonstrate use of the shellmatta.
+ * @author  Stefan Strobel <stefan.strobel@shimatta.net>
+ */
 
 #include "shellmatta.h"
 #include <stdint.h>
 #include <stdio.h>
-#include <ncurses.h>
 #include <stdbool.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <termios.h>
 #include <string.h>
 #include <errno.h>
 
@@ -22,24 +26,6 @@ static bool exitRequest = false;
 int f;
 shellmatta_handle_t handle;
 
-void set_blocking (int fd, int should_block)
-{
-        struct termios tty;
-        memset (&tty, 0, sizeof tty);
-        if (tcgetattr (fd, &tty) != 0)
-        {
-                printf ("error %d from tggetattr", errno);
-                return;
-        }
-
-        tty.c_cc[VMIN]  = should_block ? 1 : 0;
-        tty.c_cc[VTIME] = 5;            // 0.5 seconds read timeout
-
-        if (tcsetattr (fd, TCSANOW, &tty) != 0)
-            printf ("error %d setting term attributes", errno);
-}
-
-
 static shellmatta_retCode_t doSomething(shellmatta_handle_t handle, const char *arguments, uint32_t length)
 {
     shellmatta_printf(handle, "%s - length: %u", arguments, length);
@@ -101,23 +87,47 @@ shellmatta_cmd_t emptyCommand = {"empty", NULL, NULL, NULL, empty, NULL};
 
 static shellmatta_retCode_t reset(shellmatta_handle_t handle, const char *arguments, uint32_t length)
 {
+    shellmatta_retCode_t ret;
     (void)arguments;
     (void)length;
+    char option;
+    char *argument;
+    uint32_t argLen;
+    bool printPrompt = false;
 
-    if(0 == strncmp(arguments, "prompt", length))
+    static const shellmatta_opt_long_t options[] = 
     {
-        shellmatta_resetShell(handle, true);
-    }
-    else
+        {"prompt",  'p',    SHELLMATTA_OPT_ARG_REQUIRED},
+        {NULL,      '\0',   SHELLMATTA_OPT_ARG_NONE}
+    };
+
+    ret = shellmatta_opt_long(handle, options, &option, &argument, &argLen);
+    while(SHELLMATTA_OK == ret)
     {
-        shellmatta_resetShell(handle, false);
+        switch(option)
+        {
+            case 'p':
+                if(NULL != argument)
+                {
+                    if(0 == strncmp("true", argument, 4u))
+                    {
+                        printPrompt = true;
+                    }
+                }
+                break;
+            default:
+                shellmatta_printf(handle, "Unknown option: %c\r\n", option);
+                break;
+        }
+        ret = shellmatta_opt_long(handle, options, &option, &argument, &argLen);
     }
 
+    shellmatta_resetShell(handle, printPrompt);
     shellmatta_configure(handle, SHELLMATTA_MODE_INSERT, true, '\r');
 
     return SHELLMATTA_OK;
 }
-shellmatta_cmd_t resetCommand = {"reset", NULL, "resets the shellmatta instance", "reset [prompt]", reset, NULL};
+shellmatta_cmd_t resetCommand = {"reset", NULL, "resets the shellmatta instance", "reset [--prompt true/false]", reset, NULL};
 
 static shellmatta_retCode_t continuous(shellmatta_handle_t handle, const char *arguments, uint32_t length)
 {
@@ -143,6 +153,28 @@ static shellmatta_retCode_t continuous(shellmatta_handle_t handle, const char *a
 }
 shellmatta_cmd_t continuousCommand = {"continuous", "cont", "prints continously all input bytes", "continuous", continuous, NULL};
 
+static shellmatta_retCode_t busy(shellmatta_handle_t handle, const char *arguments, uint32_t length)
+{
+    (void)arguments;
+    (void)length;
+    static uint32_t callCnt = 0u;
+    shellmatta_retCode_t ret = SHELLMATTA_BUSY;
+
+    if(callCnt < 10u)
+    {
+        callCnt ++;
+        shellmatta_printf(handle, "%s - length %u - callCnt %u\r\n", arguments, length, callCnt);
+    }
+    else
+    {
+        callCnt = 0u;
+        ret = SHELLMATTA_OK;
+    }
+
+    return ret;
+}
+shellmatta_cmd_t busyCommand = {"busy", NULL, NULL, NULL, busy, NULL};
+
 
 shellmatta_retCode_t writeFct(const char* data, uint32_t length)
 {
@@ -171,8 +203,6 @@ int main(int argc, char **argv)
         return f;
     }
 
-    set_blocking (f, 1);
-
     shellmatta_doInit(  &instance,
                         &handle,
                         buffer,
@@ -189,18 +219,26 @@ int main(int argc, char **argv)
     shellmatta_addCmd(handle, &emptyCommand);
     shellmatta_addCmd(handle, &resetCommand);
     shellmatta_addCmd(handle, &continuousCommand);
+    shellmatta_addCmd(handle, &busyCommand);
 
     while(exitRequest == false)
     {
         char c;
-
+        shellmatta_retCode_t ret;
         int res = 0;
         res = read (f, &c, 1);
 
         fprintf(stdout, "0x%02x \n", c);
         fflush(stdout);
 
-        shellmatta_processData(handle, &c, res);
+        do
+        {
+            ret = shellmatta_processData(handle, &c, res);
+            if(SHELLMATTA_BUSY == ret)
+            {
+                sleep(1);
+            }
+        } while(SHELLMATTA_BUSY == ret);
     }
 
     close(f);

+ 2 - 1
makefile

@@ -41,7 +41,8 @@ UNITTEST_SOURCES := test/unittest/test_main.cpp
 INTEGRATIONTEST_SOURCES :=  test/integrationtest/test_main.cpp                  \
                             test/integrationtest/test_integration.cpp           \
                             test/integrationtest/test_integration_opt.cpp       \
-                            test/integrationtest/test_integration_optLong.cpp
+                            test/integrationtest/test_integration_optLong.cpp   \
+                            test/integrationtest/test_integration_busy.cpp
 
 UNITTEST_CPPOBJ  := $(patsubst %.cpp,$(OBJ_DIR)%.o,$(UNITTEST_SOURCES))
 

+ 81 - 28
src/shellmatta.c

@@ -75,6 +75,7 @@ shellmatta_retCode_t shellmatta_doInit(
         inst->buffer                = buffer;
         inst->bufferSize            = bufferSize;
         inst->inputCount            = 0u;
+        inst->byteCounter           = 0u;
         inst->lastNewlineIdx        = 0u;
         inst->cursor                = 0u;
         inst->stdinIdx              = 0u;
@@ -98,6 +99,7 @@ shellmatta_retCode_t shellmatta_doInit(
         inst->mode                  = SHELLMATTA_MODE_INSERT;
         inst->cmdList               = &(inst->helpCmd);
         inst->continuousCmd         = NULL;
+        inst->busyCmd               = NULL;
         inst->cmdListIsConst        = false;
 
         /** -# copy the help command structure to this instance */
@@ -139,7 +141,9 @@ shellmatta_retCode_t shellmatta_resetShell( shellmatta_handle_t handle, bool pri
         &&  (SHELLMATTA_MAGIC == inst->magic))
     {
         inst->inputCount            = 0u;
+        inst->byteCounter           = 0u;
         inst->continuousCmd         = NULL;
+        inst->busyCmd               = NULL;
         inst->lastNewlineIdx        = 0u;
         inst->cursor                = 0u;
         inst->stdinIdx              = 0u;
@@ -368,7 +372,6 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
     uint8_t                 cmdExecuted = 0u;
     uint32_t                cmdLen;
     char                    *tempString;
-    uint32_t                byteCounter;
 
     shellmatta_retCode_t    ret = SHELLMATTA_OK;
     shellmatta_retCode_t    cmdRet;
@@ -378,19 +381,53 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
     if(     (NULL               != inst)
         &&  (SHELLMATTA_MAGIC   == inst->magic))
     {
+        /** -# in busy mode - keep calling this command */
+        if(NULL != inst->busyCmd)
+        {
+            /** -# just call the function until it is not busy anymore */
+            cmdRet = inst->busyCmd->cmdFct(handle, inst->buffer, inst->inputCount);
+
+            if(SHELLMATTA_BUSY != cmdRet)
+            {
+                utils_terminateInput(inst);
+            }
+            else if(SHELLMATTA_CONTINUE == cmdRet)
+            {
+                inst->continuousCmd = inst->busyCmd;
+                inst->busyCmd       = NULL;
+            }
+            else
+            {
+                ret = cmdRet;
+            }
+        }
+
         /** -# process byte wise */
-        for (byteCounter = 0u; byteCounter < size; byteCounter++)
+        for (; (inst->byteCounter < size) && (NULL == inst->busyCmd); inst->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->buffer[inst->stdinIdx]    = data[inst->byteCounter];
                 inst->stdinLength               = 1u;
-                cmdRet = inst->continuousCmd->cmdFct(inst, inst->buffer, inst->inputCount);
+                cmdRet = inst->continuousCmd->cmdFct(handle, inst->buffer, inst->inputCount);
                 
-                /** -# check if continuous mode is canceled */
-                if(('\x03' == data[byteCounter]) || (SHELLMATTA_CONTINUE != cmdRet))
+                /** -# check if continuous mode is canceled or interrupted by busy mode */
+                if(SHELLMATTA_BUSY == cmdRet)
+                {
+                    inst->busyCmd       = inst->busyCmd;
+                    inst->continuousCmd = NULL;
+                }
+                else if(('\x03' == data[inst->byteCounter]))
+                {
+                    utils_terminateInput(inst);
+                }
+                else if(SHELLMATTA_CONTINUE == cmdRet)
+                {
+                    /** -# do nothing - continue */
+                }
+                else
                 {
                     utils_terminateInput(inst);
                 }
@@ -398,10 +435,10 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
             /** -# handle escape sequences */
             else if(inst->escapeCounter != 0u)
             {
-                escape_handleSequence(inst, *data);
+                escape_handleSequence(inst, data[inst->byteCounter]);
             }
             /** -# handle delimiter as start of processing the command */
-            else if (inst->delimiter == *data)
+            else if (inst->delimiter == data[inst->byteCounter])
             {
                 if(0u == inst->hereLength)
                 {
@@ -434,7 +471,7 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
                             inst->hereLength = inst->inputCount - inst->hereDelimiterIdx;
 
                             inst->dirty = true;
-                            utils_insertChars(inst, data, 1);
+                            utils_insertChars(inst, &data[inst->byteCounter], 1u);
                             inst->lastNewlineIdx = inst->inputCount;
                         }
                         else
@@ -505,9 +542,9 @@ 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 - just print the delimiter and store the position */
                         inst->lastNewlineIdx = inst->inputCount;
-                        utils_insertChars(inst, data, 1u);
+                        utils_insertChars(inst, &data[inst->byteCounter], 1u);
                     }
                 }
 
@@ -543,14 +580,25 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
                             utils_writeEcho(inst, "\r\n", 2u);
                             shellmatta_opt_init(inst, cmdLen + 1u);
                             cmdExecuted = 1u;
-                            cmdRet = cmd->cmdFct(inst, inst->buffer, inst->inputCount);
-                            if(SHELLMATTA_CONTINUE == cmdRet)
-                            {
-                                inst->continuousCmd = cmd;
+                            cmdRet = cmd->cmdFct(handle, inst->buffer, inst->inputCount);
 
-                                /** -# initialize stdin buffer */
-                                inst->stdinIdx      = inst->inputCount + 1u;
-                                inst->stdinLength   = 0u;
+                            switch(cmdRet)
+                            {
+                                case SHELLMATTA_CONTINUE:
+                                    /** -# initialize stdin buffer and continuous cmd */
+                                    inst->stdinIdx      = inst->inputCount + 1u;
+                                    inst->stdinLength   = 0u;
+                                    inst->continuousCmd = cmd;
+                                    break;
+                                
+                                case SHELLMATTA_BUSY:
+                                    inst->busyCmd   = cmd;
+                                    ret             = cmdRet;
+                                    break;
+
+                                default:
+                                    /* nothing to do - everything ok */
+                                    break;
                             }
                             cmd = NULL;
                         }
@@ -568,7 +616,8 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
                     }
 
                     /** -# terminate this session if no continuous mode is requested */
-                    if(NULL == inst->continuousCmd)
+                    if(     (NULL == inst->continuousCmd)
+                        &&  (NULL == inst->busyCmd))
                     {
                         utils_terminateInput(inst);
                     }
@@ -576,49 +625,53 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t     handle,
             }
             /** -# ignore newline as first character (to be compatible to
              * terminals sending newline after return */
-            else if((0u == inst->inputCount) && ('\n' == *data))
+            else if((0u == inst->inputCount) && ('\n' == data[inst->byteCounter]))
             {
                 /* do nothing */
             }
             /** -# check for tabulator key - auto complete */
-            else if('\t' == *data)
+            else if('\t' == data[inst->byteCounter])
             {
                 inst->dirty = true;
                 autocomplete_run(inst);
             }
             /** -# check for cancel -
              *      terminate current input and print prompt again */
-            else if('\x03' == *data)
+            else if('\x03' == data[inst->byteCounter])
             {
                 inst->dirty = false;
                 history_reset(inst);
                 utils_terminateInput(inst);
             }
             /** -# check for backspace */
-            else if(    ('\b'   == *data)
-                    ||  ('\x7f' == *data))
+            else if(    ('\b'   == data[inst->byteCounter])
+                    ||  ('\x7f' == data[inst->byteCounter]))
             {
                 inst->dirty = true;
                 utils_removeChars(inst, 1u, true);
             }
             /** -# check for start of escape sequence */
-            else if('\x1b' == *data)
+            else if('\x1b' == data[inst->byteCounter])
             {
                 inst->escapeCounter = 1u;
             }
             else
             {
                 inst->dirty = true;
-                utils_insertChars(inst, data, 1);
+                utils_insertChars(inst, &data[inst->byteCounter], 1u);
             }
 
             /** -# reset tab counter on not a tab */
-            if ('\t' != *data)
+            if ('\t' != data[inst->byteCounter])
             {
                 inst->tabCounter = 0u;
             }
+        }
 
-            data ++;
+        /*! -# initialize the byte buffer if processing of the input is finished */
+        if(ret != SHELLMATTA_BUSY)
+        {
+            inst->byteCounter = 0u;
         }
     }
     else

+ 14 - 14
src/shellmatta_opt.c

@@ -124,7 +124,7 @@ static char peekNextHunk(shellmatta_instance_t *inst)
  *                              #SHELLMATTA_ERROR   - format error or option unknown
  */
 static shellmatta_retCode_t parseShortOpt(  shellmatta_instance_t       *inst,
-                                            char                        *optionString,
+                                            const char                  *optionString,
                                             char                        *option,
                                             shellmatta_opt_argtype_t    *argtype)
 {
@@ -186,7 +186,7 @@ static shellmatta_retCode_t parseShortOpt(  shellmatta_instance_t       *inst,
  *                              #SHELLMATTA_ERROR   - format error or option unknown
  */
 static shellmatta_retCode_t parseLongOpt(   shellmatta_instance_t       *inst,
-                                            shellmatta_opt_long_t       *longOptions,
+                                            const shellmatta_opt_long_t *longOptions,
                                             char                        *option,
                                             shellmatta_opt_argtype_t    *argtype)
 {
@@ -253,12 +253,12 @@ static shellmatta_retCode_t parseLongOpt(   shellmatta_instance_t       *inst,
  * @return      errorcode       #SHELLMATTA_OK      - no error - keep on calling
  *                              #SHELLMATTA_ERROR   - error occured - e.g. argument missing
  */
-static shellmatta_retCode_t shellmatta_opt_int( shellmatta_handle_t     handle,
-                                                char                    *optionString,
-                                                shellmatta_opt_long_t   *longOptions,
-                                                char                    *option,
-                                                char                    **argument,
-                                                uint32_t                *argLen)
+static shellmatta_retCode_t shellmatta_opt_int( shellmatta_handle_t         handle,
+                                                const char                  *optionString,
+                                                const shellmatta_opt_long_t *longOptions,
+                                                char                        *option,
+                                                char                        **argument,
+                                                uint32_t                    *argLen)
 {
     shellmatta_retCode_t        ret     = SHELLMATTA_USE_FAULT;
     shellmatta_instance_t       *inst   = (shellmatta_instance_t*)handle;
@@ -370,7 +370,7 @@ static shellmatta_retCode_t shellmatta_opt_int( shellmatta_handle_t     handle,
  *                              #SHELLMATTA_ERROR   - error occured - e.g. argument missing
  */
 shellmatta_retCode_t shellmatta_opt(        shellmatta_handle_t handle,
-                                            char                *optionString,
+                                            const char          *optionString,
                                             char                *option,
                                             char                **argument,
                                             uint32_t            *argLen)
@@ -391,11 +391,11 @@ shellmatta_retCode_t shellmatta_opt(        shellmatta_handle_t handle,
  * @param[out]  argument        pointer to store the argument string to (can be NULL)
  * @param[out]  argLen          pointer to store the argument lengh to (can be NULL)
  */
-shellmatta_retCode_t shellmatta_opt_long(   shellmatta_handle_t     handle,
-                                            shellmatta_opt_long_t   *longOptions,
-                                            char                    *option,
-                                            char                    **argument,
-                                            uint32_t                *argLen)
+shellmatta_retCode_t shellmatta_opt_long(   shellmatta_handle_t         handle,
+                                            const shellmatta_opt_long_t *longOptions,
+                                            char                        *option,
+                                            char                        **argument,
+                                            uint32_t                    *argLen)
 {
     return shellmatta_opt_int(  handle,
                                 NULL,

+ 6 - 6
src/shellmatta_opt.h

@@ -23,16 +23,16 @@
 #include <stdint.h>
 
 shellmatta_retCode_t shellmatta_opt(        shellmatta_handle_t handle,
-                                            char                *optionString,
+                                            const char          *optionString,
                                             char                *option,
                                             char                **argument,
                                             uint32_t            *argLen);
 
-shellmatta_retCode_t shellmatta_opt_long(   shellmatta_handle_t     handle,
-                                            shellmatta_opt_long_t   *longOptions,
-                                            char                    *option,
-                                            char                    **argument,
-                                            uint32_t                *argLen);
+shellmatta_retCode_t shellmatta_opt_long(   shellmatta_handle_t         handle,
+                                            const shellmatta_opt_long_t *longOptions,
+                                            char                        *option,
+                                            char                        **argument,
+                                            uint32_t                    *argLen);
 
 shellmatta_retCode_t shellmatta_opt_init(   shellmatta_instance_t   *inst,
                                             uint32_t argStart);

+ 1 - 0
src/shellmatta_utils.c

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

+ 130 - 0
test/integrationtest/test_integration_busy.cpp

@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2019 Stefan Strobel <stefan.strobel@shimatta.net>
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+/**
+ * @file    test_integration_busy.cpp
+ * @brief   integration test implementation for the cmd busy function
+ * @author  Stefan Strobel <stefan.strobel@shimatta.net>
+ */
+
+#include "test/framework/catch.hpp"
+extern "C" {
+#include "shellmatta.h"
+}
+#include <string.h>
+
+static uint32_t write_callCnt = 0u;
+static char write_data[1024];
+static uint32_t write_length;
+static uint32_t busyCallCnt;
+static uint32_t notBusyCallCnt;
+
+static shellmatta_retCode_t writeFct(const char* data, uint32_t length)
+{
+    write_callCnt ++;
+    while((length > 0) && (write_length < sizeof(write_data)))
+    {
+        write_data[write_length] = *data;
+        data ++;
+        length --;
+        write_length ++;
+    }
+
+    return SHELLMATTA_OK;
+}
+
+static shellmatta_retCode_t busyCmdFct(shellmatta_handle_t handle, const char *arguments, uint32_t length)
+{
+    (void)      handle;
+    (void)      arguments;
+    (void)      length;
+    shellmatta_retCode_t ret        = SHELLMATTA_BUSY;
+    static const char   *callArgs   = NULL;
+    static uint32_t     callLength  = 0u;;
+
+    if(busyCallCnt < 10u)
+    {
+        if(NULL == callArgs)
+        {
+            callArgs    = arguments;
+            callLength  = length;
+        }
+        else
+        {
+            CHECK(callArgs      == arguments);
+            CHECK(callLength    == length);
+        }
+
+        busyCallCnt ++;
+    }
+    else
+    {
+        ret = SHELLMATTA_OK;
+    }
+
+    return ret;
+}
+shellmatta_cmd_t busyCmd = {(char*)"busy", (char*)"b", NULL, NULL, busyCmdFct, NULL};
+
+
+static shellmatta_retCode_t notBusyCmdFct(shellmatta_handle_t handle, const char *arguments, uint32_t length)
+{
+    (void)      handle;
+    (void)      arguments;
+    (void)      length;
+
+    notBusyCallCnt ++;
+
+    return SHELLMATTA_OK;
+}
+shellmatta_cmd_t notBusyCmd = {(char*)"notBusy", (char*)"n", NULL, NULL, notBusyCmdFct, NULL};
+
+
+TEST_CASE( "shellmatta busy 1" ) {
+
+    shellmatta_retCode_t ret;
+    shellmatta_instance_t inst;
+    shellmatta_handle_t handle;
+    char buffer[1024];
+    char historyBuffer[1024];
+    char *dummyData =   (char*) "busy and some arguments\r\n"
+                                "\r\nshellmatta->notBusy and some arguments\r\n"
+                                "\r\nshellmatta->";
+
+    shellmatta_doInit(  &inst,
+                        &handle,
+                        buffer,
+                        sizeof(buffer),
+                        historyBuffer,
+                        sizeof(historyBuffer),
+                        "shellmatta->",
+                        NULL,
+                        writeFct);
+
+    busyCallCnt = 0u;
+    notBusyCallCnt = 0u;
+    write_callCnt = 0u;
+    memset(write_data, 0, sizeof(write_data));
+    write_length = 0u;
+
+    shellmatta_addCmd(handle, &busyCmd);
+    shellmatta_addCmd(handle, &notBusyCmd);
+
+    do
+    {
+        ret = shellmatta_processData(handle, (char*)"busy and some arguments\r"
+                                                    "notBusy and some arguments\r", 51);
+
+    } while (SHELLMATTA_BUSY == ret);
+    
+
+    CHECK( 10u  == busyCallCnt);
+    CHECK( 1u   == notBusyCallCnt );
+    CHECK( write_length == strlen(dummyData));
+    REQUIRE( strcmp(dummyData, write_data) == 0);
+}