Browse Source

added long option parser fix #1

prozessorkern 4 years ago
parent
commit
2d130e2ee1

+ 14 - 2
.vscode/tasks.json

@@ -1,6 +1,4 @@
 {
-    // See https://go.microsoft.com/fwlink/?LinkId=733558
-    // for the documentation about the tasks.json format
     "version": "2.0.0",
     "tasks": [
         {
@@ -51,6 +49,20 @@
                 "kind": "test",
                 "isDefault": true
             }
+        },
+        {
+            "type": "shell",
+            "label": "gcc build active file",
+            "command": "/usr/bin/gcc",
+            "args": [
+                "-g",
+                "${file}",
+                "-o",
+                "${fileDirname}/${fileBasenameNoExtension}"
+            ],
+            "options": {
+                "cwd": "/usr/bin"
+            }
         }
     ]
 }

+ 4 - 3
makefile

@@ -38,9 +38,10 @@ UNITTEST_SOURCES := test/unittest/test_main.cpp
                     test/unittest/shellmatta_history/test_appendHistoryByte.cpp         \
                     test/unittest/shellmatta/test_shellmatta_doInit.cpp
 
-INTEGRATIONTEST_SOURCES :=  test/integrationtest/test_main.cpp              \
-                            test/integrationtest/test_integration.cpp       \
-                            test/integrationtest/test_integration_opt.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
 
 UNITTEST_CPPOBJ  := $(patsubst %.cpp,$(OBJ_DIR)%.o,$(UNITTEST_SOURCES))
 

+ 201 - 75
src/shellmatta_opt.c

@@ -119,7 +119,7 @@ static char peekNextHunk(shellmatta_instance_t *inst)
  * @param[in]   handle          shellmatta handle
  * @param[in]   optionString    option string e.g. "cd:e::"
  * @param[out]  option          pointer to store the detected option to
- * @param[out]  argtype         pointer to store the argument string to (can be NULL)
+ * @param[out]  argtype         pointer to var of type #shellmatta_opt_argtype_t != NULL
  * @return      errorcode       #SHELLMATTA_OK      - option parsable and found in option String
  *                              #SHELLMATTA_ERROR   - format error or option unknown
  */
@@ -135,30 +135,103 @@ static shellmatta_retCode_t parseShortOpt(  shellmatta_instance_t       *inst,
     /*! -# 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 */
-        for(i = 0u; ('\0' != optionString[i]) && (buffer[1u] != optionString[i]); i ++);
-        
-        if(buffer[1u] == optionString[i])
+        for(i = 0u; ('\0' != optionString[i]) && ('\0' == *option); i ++)
         {
-            /*! -# return found option character */
-            *option = buffer[1u];
-            ret = SHELLMATTA_OK;
-
-            /*! -# check if an argument is required or optional */
-            if(':' == optionString[i + 1u])
+            if(buffer[1u] == optionString[i])
             {
-                *argtype = SHELLMATTA_OPT_ARG_REQUIRED;
-                if(':' == optionString[i + 2u])
+                ret = SHELLMATTA_OK;
+
+                /*! -# return found option character */
+                *option = buffer[1u];
+
+                /*! -# check if an argument is required or optional */
+                if(':' == optionString[i + 1u])
+                {
+                    *argtype = SHELLMATTA_OPT_ARG_REQUIRED;
+                    if(':' == optionString[i + 2u])
+                    {
+                        *argtype = SHELLMATTA_OPT_ARG_OPTIONAL;
+                    }
+                }
+                else
                 {
-                    *argtype = SHELLMATTA_OPT_ARG_OPTIONAL;
+                    *argtype = SHELLMATTA_OPT_ARG_NONE;
                 }
             }
-            else
+        }
+    }
+    /*! -# skip "--" */
+    else if((2u == inst->optionParser.len) && ('-' == buffer[0u]) && ('-' == buffer[1u]))
+    {
+        ret = SHELLMATTA_CONTINUE;
+    }
+    else
+    {
+        *option = '\0';
+    }
+
+    return ret;
+}
+
+/**
+ * @brief       tries to parse the current input hunk and check if this is a configured option
+ * @param[in]   handle          shellmatta handle
+ * @param[in]   longOptions     option structure - pointer to array of type #shellmatta_opt_long_t
+ * @param[out]  option          pointer to store the detected option to
+ * @param[out]  argtype         pointer to var of type #shellmatta_opt_argtype_t != NULL
+ * @return      errorcode       #SHELLMATTA_OK      - option parsable and found in option String
+ *                              #SHELLMATTA_ERROR   - format error or option unknown
+ */
+static shellmatta_retCode_t parseLongOpt(   shellmatta_instance_t       *inst,
+                                            shellmatta_opt_long_t       *longOptions,
+                                            char                        *option,
+                                            shellmatta_opt_argtype_t    *argtype)
+{
+    shellmatta_retCode_t ret = SHELLMATTA_ERROR;
+    char *buffer = &inst->buffer[inst->optionParser.offset];
+    uint32_t i;
+
+    /*! -# 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 */
+        for(i = 0u; ('\0' != longOptions[i].paramShort) && ('\0' == *option); i ++)
+        {
+            if(buffer[1u] == longOptions[i].paramShort)
             {
-                *argtype = SHELLMATTA_OPT_ARG_NONE;
+                ret = SHELLMATTA_OK;
+
+                /*! -# return found option character */
+                *option     = longOptions[i].paramShort;
+                *argtype    = longOptions[i].argtype;
             }
         }
     }
+    /*! -# check for correct syntax for long options */
+    else if((3u <= inst->optionParser.len) && ('-' == buffer[0u]) && ('-' == buffer[1u]))
+    {
+        /*! -# 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 */
+                *option     = longOptions[i].paramShort;
+                *argtype    = longOptions[i].argtype;
+            }
+        }
+    }
+    /*! -# ignore "--" */
+    else if((2u == inst->optionParser.len) && ('-' == buffer[0u]) && ('-' == buffer[1u]))
+    {
+        *option = '\0';
+        ret = SHELLMATTA_CONTINUE;
+    }
     else
     {
         *option = '\0';
@@ -168,20 +241,24 @@ static shellmatta_retCode_t parseShortOpt(  shellmatta_instance_t       *inst,
 }
 
 /**
- * @brief       scans the current input and parses options in getopt style
+ * @brief       Scans the current input and parses options in getopt style - pass either optionString or longOptions
+ *              This is an internal funtion to handle both getopt styles and remove duplicated code...
+ *              The standard functions are just wrapper around this one.
  * @param[in]   handle          shellmatta handle
  * @param[in]   optionString    option string e.g. "cd:e::"
+ * @param[in]   longOptions     option structure - pointer to array of type #shellmatta_opt_long_t
  * @param[out]  option          pointer to store the detected option to
  * @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)
  * @return      errorcode       #SHELLMATTA_OK      - no error - keep on calling
  *                              #SHELLMATTA_ERROR   - error occured - e.g. argument missing
  */
-shellmatta_retCode_t shellmatta_opt(        shellmatta_handle_t handle,
-                                            char                *optionString,
-                                            char                *option,
-                                            char                **argument,
-                                            uint32_t            *argLen)
+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)
 {
     shellmatta_retCode_t        ret     = SHELLMATTA_USE_FAULT;
     shellmatta_instance_t       *inst   = (shellmatta_instance_t*)handle;
@@ -190,63 +267,122 @@ shellmatta_retCode_t shellmatta_opt(        shellmatta_handle_t handle,
     /** -# check parameters for plausibility  */
     if(     (NULL               != inst)
         &&  (SHELLMATTA_MAGIC   == inst->magic)
-        &&  (NULL               != optionString)
         &&  (NULL               != option))
     {
         *option     = '\0';
-        *argument   = NULL;
-        *argLen     = 0u;
-
-        ret = findNextHunk(inst);
-        if(SHELLMATTA_OK == ret)
+        if(NULL != argument)
+        {
+            *argument = NULL;
+        }
+        if(NULL != argLen)
         {
-            ret = parseShortOpt(inst, optionString, option, &argtype);
+            *argLen = 0u;
+        }
 
-            /*! -# when no option is found return this as raw argument */
-            if(SHELLMATTA_ERROR == ret)
-            {
-                *argument   = &(inst->buffer[inst->optionParser.offset]);
-                *argLen     = inst->optionParser.len;
-                ret         = SHELLMATTA_OK;
-            }
-            else
+        /*! -# do this until we find a not skipable argument */
+        do
+        {
+            ret = findNextHunk(inst);
+            if(SHELLMATTA_OK == ret)
             {
-                switch(argtype)
+                /*! -# call the matching parse function */
+                if(NULL != optionString)
+                {
+                    ret = parseShortOpt(inst, optionString, option, &argtype);
+                }
+                else if(NULL != longOptions)
+                {
+                    ret = parseLongOpt(inst, longOptions, option, &argtype);
+                }
+                else
+                {
+                    ret = SHELLMATTA_USE_FAULT;
+                }
+
+                /*! -# when no option is found return this as raw argument */
+                if(SHELLMATTA_ERROR == ret)
+                {
+                    if(NULL != argument)
+                    {
+                        *argument = &(inst->buffer[inst->optionParser.offset]);
+                    }
+                    if(NULL != argLen)
+                    {
+                        *argLen = inst->optionParser.len;
+                    }
+                    ret = SHELLMATTA_OK;
+                }
+                else if(SHELLMATTA_USE_FAULT == ret)
                 {
-                    case SHELLMATTA_OPT_ARG_REQUIRED:
-                        ret = findNextHunk(inst);
-                        if(SHELLMATTA_OK == ret)
-                        {
-                            *argument   = &(inst->buffer[inst->optionParser.offset]);
-                            *argLen     = inst->optionParser.len;
-                        }
-                        break;
-                    case SHELLMATTA_OPT_ARG_OPTIONAL:
-                        /*! -# treat anything not starting with '-' as argument */
-                        if('-' != peekNextHunk(inst))
-                        {
+                    /*! -# nothing to do - just return errorcode */
+                }
+                else
+                {
+                    switch(argtype)
+                    {
+                        case SHELLMATTA_OPT_ARG_REQUIRED:
                             ret = findNextHunk(inst);
+                            if((NULL == argument) || (NULL == argLen))
+                            {
+                                ret = SHELLMATTA_USE_FAULT;
+                            }
                             if(SHELLMATTA_OK == ret)
                             {
                                 *argument   = &(inst->buffer[inst->optionParser.offset]);
                                 *argLen     = inst->optionParser.len;
                             }
-                        }
-                        break;
-                    default:
-                        /* nothing to do */
-                        break;
+                            break;
+                        case SHELLMATTA_OPT_ARG_OPTIONAL:
+                            /*! -# treat anything not starting with '-' as argument */
+                            if('-' != peekNextHunk(inst))
+                            {
+                                ret = findNextHunk(inst);
+                                if((NULL == argument) || (NULL == argLen))
+                                {
+                                    ret = SHELLMATTA_USE_FAULT;
+                                }
+                                if(SHELLMATTA_OK == ret)
+                                {
+                                    *argument   = &(inst->buffer[inst->optionParser.offset]);
+                                    *argLen     = inst->optionParser.len;
+                                }
+                            }
+                            break;
+                        default:
+                            /* nothing to do */
+                            break;
+                    }
                 }
             }
-        }
+        } while(SHELLMATTA_CONTINUE == ret);
     }
-
-    (void)argument;
-    (void)argLen;
-
     return ret;
 }
 
+/**
+ * @brief       scans the current input and parses options in getopt style
+ * @param[in]   handle          shellmatta handle
+ * @param[in]   optionString    option string e.g. "cd:e::"
+ * @param[out]  option          pointer to store the detected option to
+ * @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)
+ * @return      errorcode       #SHELLMATTA_OK      - no error - keep on calling
+ *                              #SHELLMATTA_ERROR   - error occured - e.g. argument missing
+ */
+shellmatta_retCode_t shellmatta_opt(        shellmatta_handle_t handle,
+                                            char                *optionString,
+                                            char                *option,
+                                            char                **argument,
+                                            uint32_t            *argLen)
+{
+    return shellmatta_opt_int(  handle,
+                                optionString,
+                                NULL,
+                                option,
+                                argument,
+                                argLen);
+}
+
 /**
  * @brief       scans the current input and parses options in getopt_long style
  * @param[in]   handle          shellmatta handle
@@ -261,22 +397,12 @@ shellmatta_retCode_t shellmatta_opt_long(   shellmatta_handle_t     handle,
                                             char                    **argument,
                                             uint32_t                *argLen)
 {
-    shellmatta_retCode_t    ret     = SHELLMATTA_USE_FAULT;
-    shellmatta_instance_t   *inst   = (shellmatta_instance_t*)handle;
-
-    /** -# check parameters for plausibility  */
-    if(     (NULL               != inst)
-        &&  (SHELLMATTA_MAGIC   == inst->magic)
-        &&  (NULL               != longOptions)
-        &&  (NULL               != option))
-    {
-        
-    }
-
-    (void)argument;
-    (void)argLen;
-
-    return ret;
+    return shellmatta_opt_int(  handle,
+                                NULL,
+                                longOptions,
+                                option,
+                                argument,
+                                argLen);
 }
 
 /**

+ 6 - 6
src/shellmatta_utils.c

@@ -347,12 +347,12 @@ static shellmatta_retCode_t helpCmdFct(shellmatta_handle_t handle, const char *a
 
     return ret;
 }
-shellmatta_cmd_t helpCmd = {  SHELLMATTA_HELP_COMMAND
-                            , SHELLMATTA_HELP_ALIAS
-                            , SHELLMATTA_HELP_HELP_TEXT
-                            , SHELLMATTA_HELP_USAGE_TEXT
-                            , helpCmdFct
-                            , NULL};
+const shellmatta_cmd_t helpCmd = {SHELLMATTA_HELP_COMMAND
+                                , SHELLMATTA_HELP_ALIAS
+                                , SHELLMATTA_HELP_HELP_TEXT
+                                , SHELLMATTA_HELP_USAGE_TEXT
+                                , helpCmdFct
+                                , NULL};
 
 /**
  * @brief       terminates an input and prints the prompt again

+ 1 - 1
src/shellmatta_utils.h

@@ -36,7 +36,7 @@
         (fct)((buffer), (cnt));                 \
     }
 
-extern shellmatta_cmd_t helpCmd;
+extern const shellmatta_cmd_t helpCmd;
 
 #define SHELLMATTA_MAGIC    0x5101E110u
 

+ 40 - 8
test/integrationtest/test_integration_opt.cpp

@@ -140,13 +140,6 @@ static shellmatta_retCode_t parseOpts(shellmatta_handle_t handle, const char *ar
 }
 shellmatta_cmd_t parseOptsCmd = {(char*)"parseOpts", (char*)"opt", NULL, NULL, parseOpts, NULL};
 
-static shellmatta_retCode_t empty(shellmatta_handle_t handle, const char *arguments, uint32_t length)
-{
-    shellmatta_printf(handle, "empty - %s - length: %u", arguments, length);
-    return SHELLMATTA_OK;
-}
-shellmatta_cmd_t emptyCmd = {(char*)"empty", NULL, NULL, NULL, empty, NULL};
-
 TEST_CASE( "shellmatta option parser 1" ) {
 
     shellmatta_instance_t inst;
@@ -181,6 +174,45 @@ TEST_CASE( "shellmatta option parser 1" ) {
     CHECK(((NULL != argE) && (0u == memcmp(argE, "meow", 4))));
     CHECK( lenE == 4u );
     CHECK( (cntB == 0u && cntC == 0u && cntD == 0u && cntF == 0u && cntDef == 0u) );
-    CHECK( write_length == 56u);
+    CHECK( write_length == strlen(dummyData));
     REQUIRE( strcmp(dummyData, write_data) == 0);
 }
+
+TEST_CASE( "shellmatta option parser 2 - ignore \"--\"" ) {
+
+    shellmatta_instance_t inst;
+    shellmatta_handle_t handle;
+    char buffer[1024];
+    char historyBuffer[1024];
+    char *dummyData =   (char*)"parseOpts -a -e meow --\r\nparseOpts - cnt: 2\r\n\r\nshellmatta->";
+
+    shellmatta_doInit(  &inst,
+                        &handle,
+                        buffer,
+                        sizeof(buffer),
+                        historyBuffer,
+                        sizeof(historyBuffer),
+                        "shellmatta->",
+                        NULL,
+                        writeFct);
+
+    initTestcase();
+    write_callCnt = 0u;
+    memset(write_data, 0, sizeof(write_data));
+    write_length = 0u;
+
+    shellmatta_addCmd(handle, &parseOptsCmd);
+
+    shellmatta_processData(handle, (char*)"parseOpts -a -e meow --\r", 24);
+
+    CHECK( cntA == 1u );
+    CHECK( NULL == argA);
+    CHECK( 0u == lenA );
+    CHECK( cntE == 1u );
+    CHECK(((NULL != argE) && (0u == memcmp(argE, "meow", 4))));
+    CHECK( lenE == 4u );
+    CHECK( (cntB == 0u && cntC == 0u && cntD == 0u && cntF == 0u && cntDef == 0u) );
+    CHECK( write_length == strlen(dummyData));
+    REQUIRE( strcmp(dummyData, write_data) == 0);
+}
+

+ 229 - 0
test/integrationtest/test_integration_optLong.cpp

@@ -0,0 +1,229 @@
+/*
+ * 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_optLong.cpp
+ * @brief   integration test implementation for the long option parser of the shellmatta
+ * @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 cntA = 0u;
+static uint32_t cntB = 0u;
+static uint32_t cntC = 0u;
+static uint32_t cntD = 0u;
+static uint32_t cntE = 0u;
+static uint32_t cntF = 0u;
+static uint32_t cntDef = 0u;
+static char *argA = NULL;
+static char *argB = NULL;
+static char *argC = NULL;
+static char *argD = NULL;
+static char *argE = NULL;
+static char *argF = NULL;
+static char *argDef = NULL;
+static uint32_t lenA = 0u;
+static uint32_t lenB = 0u;
+static uint32_t lenC = 0u;
+static uint32_t lenD = 0u;
+static uint32_t lenE = 0u;
+static uint32_t lenF = 0u;
+static uint32_t lenDef = 0u;
+
+static void initTestcase(void)
+{
+    cntA = 0u;
+    cntB = 0u;
+    cntC = 0u;
+    cntD = 0u;
+    cntE = 0u;
+    cntF = 0u;
+    cntDef = 0u;
+    argA = NULL;
+    argB = NULL;
+    argC = NULL;
+    argD = NULL;
+    argE = NULL;
+    argF = NULL;
+    argDef = NULL;
+    lenA = 0u;
+    lenB = 0u;
+    lenC = 0u;
+    lenD = 0u;
+    lenE = 0u;
+    lenF = 0u;
+    lenDef = 0u;
+}
+
+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 parseOptsLong(shellmatta_handle_t handle, const char *arguments, uint32_t length)
+{
+    (void)      arguments;
+    (void)      length;
+    char        option;
+    char        *argumentString;
+    uint32_t    argumentLength;
+    uint32_t    optionCount = 0u;
+
+    shellmatta_opt_long_t longOptions[] = {
+        {"auto",    'a',    SHELLMATTA_OPT_ARG_NONE},
+        {"build",   'b',    SHELLMATTA_OPT_ARG_NONE},
+        {"cat",     'c',    SHELLMATTA_OPT_ARG_NONE},
+        {"doom",    'd',    SHELLMATTA_OPT_ARG_NONE},
+        {"erase",   'e',    SHELLMATTA_OPT_ARG_REQUIRED},
+        {"fuck",    'f',    SHELLMATTA_OPT_ARG_OPTIONAL},
+        {NULL,      '\0',   SHELLMATTA_OPT_ARG_NONE}
+    };
+
+    while(SHELLMATTA_OK == shellmatta_opt_long(handle, longOptions, &option, &argumentString, &argumentLength))
+    {
+        optionCount ++;
+        switch(option)
+        {
+            case 'a':
+                cntA ++;
+                argA = argumentString;
+                lenA = argumentLength;
+                break;
+            case 'b':
+                cntB ++;
+                argB = argumentString;
+                lenB = argumentLength;
+                break;
+            case 'c':
+                cntC ++;
+                argC = argumentString;
+                lenC = argumentLength;
+                break;
+            case 'd':
+                cntD ++;
+                argD = argumentString;
+                lenD = argumentLength;
+                break;
+            case 'e':
+                cntE ++;
+                argE = argumentString;
+                lenE = argumentLength;
+                break;
+            case 'f':
+                cntF ++;
+                argF = argumentString;
+                lenF = argumentLength;
+                break;
+            default:
+                cntDef ++;
+                argDef = argumentString;
+                lenDef = argumentLength;
+                break;
+        }
+    }
+
+    shellmatta_printf(handle, "parseOpts - cnt: %u\r\n", optionCount);
+
+    return SHELLMATTA_OK;
+}
+shellmatta_cmd_t parseOptsLongCmd = {(char*)"parseOpts", (char*)"opt", NULL, NULL, parseOptsLong, NULL};
+
+TEST_CASE( "shellmatta long option parser 1" ) {
+
+    shellmatta_instance_t inst;
+    shellmatta_handle_t handle;
+    char buffer[1024];
+    char historyBuffer[1024];
+    char *dummyData =   (char*)"parseOpts -a -e meow\r\nparseOpts - cnt: 2\r\n\r\nshellmatta->";
+
+    shellmatta_doInit(  &inst,
+                        &handle,
+                        buffer,
+                        sizeof(buffer),
+                        historyBuffer,
+                        sizeof(historyBuffer),
+                        "shellmatta->",
+                        NULL,
+                        writeFct);
+
+    initTestcase();
+    write_callCnt = 0u;
+    memset(write_data, 0, sizeof(write_data));
+    write_length = 0u;
+
+    shellmatta_addCmd(handle, &parseOptsLongCmd);
+
+    shellmatta_processData(handle, (char*)"parseOpts -a -e meow\r", 21);
+
+    CHECK( cntA == 1u );
+    CHECK( NULL == argA);
+    CHECK( 0u == lenA );
+    CHECK( cntE == 1u );
+    CHECK(((NULL != argE) && (0u == memcmp(argE, "meow", 4))));
+    CHECK( lenE == 4u );
+    CHECK( (cntB == 0u && cntC == 0u && cntD == 0u && cntF == 0u && cntDef == 0u) );
+    CHECK( write_length == strlen(dummyData));
+    REQUIRE( strcmp(dummyData, write_data) == 0);
+}
+
+TEST_CASE( "shellmatta long option parser 2" ) {
+
+    shellmatta_instance_t inst;
+    shellmatta_handle_t handle;
+    char buffer[1024];
+    char historyBuffer[1024];
+    char *dummyData =   (char*)"parseOpts --auto --erase meow -- --lalelu -u\r\nparseOpts - cnt: 4\r\n\r\nshellmatta->";
+
+    shellmatta_doInit(  &inst,
+                        &handle,
+                        buffer,
+                        sizeof(buffer),
+                        historyBuffer,
+                        sizeof(historyBuffer),
+                        "shellmatta->",
+                        NULL,
+                        writeFct);
+
+    initTestcase();
+    write_callCnt = 0u;
+    memset(write_data, 0, sizeof(write_data));
+    write_length = 0u;
+
+    shellmatta_addCmd(handle, &parseOptsLongCmd);
+
+    shellmatta_processData(handle, (char*)"parseOpts --auto --erase meow -- --lalelu -u\r", 45);
+
+    CHECK( cntA == 1u );
+    CHECK( NULL == argA);
+    CHECK( 0u == lenA );
+    CHECK( cntE == 1u );
+    CHECK(((NULL != argE) && (0u == memcmp(argE, "meow", 4))));
+    CHECK( lenE == 4u );
+    CHECK( (cntB == 0u && cntC == 0u && cntD == 0u && cntF == 0u) );
+    CHECK( cntDef == 2u );
+    CHECK( lenDef == 2u );
+    CHECK( write_length == strlen(dummyData));
+    REQUIRE( strcmp(dummyData, write_data) == 0);
+}