From 60c4c7dadd8e7939fd65d0213b0c453601cbe788 Mon Sep 17 00:00:00 2001 From: prozessorkern Date: Sun, 8 Mar 2020 22:02:51 +0100 Subject: [PATCH] added basic interface of the shellmatta option parser + started adding a test module --- .vscode/settings.json | 5 + api/shellmatta.h | 42 +++++++ makefile | 8 +- src/shellmatta_opt.c | 103 +++++++++++++++++ src/shellmatta_opt.h | 42 +++++++ test/integrationtest/test_integration_opt.cpp | 107 ++++++++++++++++++ 6 files changed, 304 insertions(+), 3 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 src/shellmatta_opt.c create mode 100644 src/shellmatta_opt.h create mode 100644 test/integrationtest/test_integration_opt.cpp diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..1428c38 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.associations": { + "random": "cpp" + } +} \ No newline at end of file diff --git a/api/shellmatta.h b/api/shellmatta.h index 0fdc801..625f621 100644 --- a/api/shellmatta.h +++ b/api/shellmatta.h @@ -51,6 +51,34 @@ typedef enum SHELLMATTA_MODE_OVERWRITE , /**< overwrite mode */ } shellmatta_mode_t; +/** + * @brief definition of shellmatta optionparser agument type + */ +typedef enum +{ + SHELLMATTA_OPT_ARG_NONE = 0u, /**< no argument expected */ + SHELLMATTA_OPT_ARG_REQUIRED, /**< argument is required */ + SHELLMATTA_OPT_ARG_OPTIONAL, /**< argument is optional */ +} shellmatta_opt_argtype_t; + +/** + * @brief definition of shellmatta optionparser agument type + */ +typedef struct +{ + const char *paramLong; /**< long parameter string */ + const char paramShort; /**< short parameter char */ + shellmatta_opt_argtype_t argtype; /**< argument type expected */ +} shellmatta_opt_long_t; + +/** + * @brief definition of shellmatta optionparser structure + */ +typedef struct +{ + uint32_t offset; /**< current offset of the option parser */ +} shellmatta_opt_t; + /** * @brief shellmatta command function definition * @param[in] handle pointer to the instance which is calling the cmd @@ -113,6 +141,7 @@ typedef struct shellmatta_cmd_t *cmdList; /**< pointer to the first command */ bool cmdListIsConst; /**< true if the #cmdList was passed during initialization */ + shellmatta_opt_t optionParser; /**< option parser sructure */ } shellmatta_instance_t; @@ -146,6 +175,19 @@ shellmatta_retCode_t shellmatta_processData(shellmatta_handle_t handle, shellmatta_retCode_t shellmatta_write( shellmatta_handle_t handle, char *data, uint32_t length); + +shellmatta_retCode_t shellmatta_opt( shellmatta_handle_t handle, + 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); + #ifndef SHELLMATTA_STRIP_PRINTF shellmatta_retCode_t shellmatta_printf( shellmatta_handle_t handle, const char *fmt, diff --git a/makefile b/makefile index 9e9626e..8d0edcf 100644 --- a/makefile +++ b/makefile @@ -16,7 +16,8 @@ SOURCES := src/shellmatta.c \ src/shellmatta_autocomplete.c \ src/shellmatta_history.c \ src/shellmatta_utils.c \ - src/shellmatta_escape.c + src/shellmatta_escape.c \ + src/shellmatta_opt.c INCLUDES := api . @@ -36,8 +37,9 @@ 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 +INTEGRATIONTEST_SOURCES := test/integrationtest/test_main.cpp \ + test/integrationtest/test_integration.cpp \ + test/integrationtest/test_integration_opt.cpp UNITTEST_CPPOBJ := $(patsubst %.cpp,$(OBJ_DIR)%.o,$(UNITTEST_SOURCES)) diff --git a/src/shellmatta_opt.c b/src/shellmatta_opt.c new file mode 100644 index 0000000..9e4df44 --- /dev/null +++ b/src/shellmatta_opt.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2019 Stefan Strobel + * + * 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 shellmatta_opt.c + * @brief option parser implementation of the shellmatta + * @author Stefan Strobel + */ + +/** + * @addtogroup shellmatta_opt + * @{ + */ + +#include "shellmatta_opt.h" +#include "shellmatta_utils.h" +#include "shellmatta.h" +#include + +/** + * @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) + */ +shellmatta_retCode_t shellmatta_opt( shellmatta_handle_t handle, + char *optionString, + char *option, + 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 != optionString) + && (NULL != option)) + { + + } + + (void)argument; + (void)argLen; + + return ret; +} + +/** + * @brief scans the current input and parses options in getopt_long style + * @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] 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 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; +} + +/** + * @brief initializes the option parser instance + * @param[in, out] inst pointer to a shellmatta instance + */ +shellmatta_retCode_t shellmatta_opt_init(shellmatta_instance_t *inst) +{ + /*! -# initialize all relevant option parser variables */ + inst->optionParser.offset = 0u; + + return SHELLMATTA_OK; +} + +/** + * @} + */ diff --git a/src/shellmatta_opt.h b/src/shellmatta_opt.h new file mode 100644 index 0000000..f148e05 --- /dev/null +++ b/src/shellmatta_opt.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2019 Stefan Strobel + * + * 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 shellmatta_opt.h + * @brief option parser implementation of the shellmatta + * @author Stefan Strobel + */ + +/** + * @addtogroup shellmatta_opt + * @{ + */ +#ifndef _SHELLMATTA_OPT_H_ +#define _SHELLMATTA_OPT_H_ + +#include "shellmatta.h" +#include + +shellmatta_retCode_t shellmatta_opt( shellmatta_handle_t handle, + 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_init( shellmatta_instance_t *inst); + +#endif + +/** @} */ + diff --git a/test/integrationtest/test_integration_opt.cpp b/test/integrationtest/test_integration_opt.cpp new file mode 100644 index 0000000..25a47bc --- /dev/null +++ b/test/integrationtest/test_integration_opt.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2019 Stefan Strobel + * + * 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_opt.cpp + * @brief integration test implementation for the option parser of the shellmatta + * @author Stefan Strobel + */ + +#include "test/framework/catch.hpp" +extern "C" { +#include "shellmatta.h" +} +#include + +static uint32_t write_callCnt = 0u; +static char write_data[1024]; +static uint32_t write_length; + + +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 parseOpts(shellmatta_handle_t handle, const char *arguments, uint32_t length) +{ + (void) arguments; + (void) length; + char option; + char *argumentString; + uint32_t argumentLength; + + while(SHELLMATTA_OK == shellmatta_opt(handle, (char*)"abcde:f::", &option, &argumentString, &argumentLength)) + { + switch(option) + { + case 'a': + break; + case 'b': + break; + case 'c': + break; + case 'd': + break; + case 'e': + break; + case 'f': + break; + default: + break; + } + } + + return SHELLMATTA_OK; +} +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; + shellmatta_handle_t handle; + char buffer[1024]; + char historyBuffer[1024]; + //char *dummyData = (char*)"\r\nshellmatta->"; + + shellmatta_doInit( &inst, + &handle, + buffer, + sizeof(buffer), + historyBuffer, + sizeof(historyBuffer), + "shellmatta->", + NULL, + writeFct); + + write_callCnt = 0u; + memset(write_data, 0, sizeof(write_data)); + write_length = 0u; + + shellmatta_processData(handle, (char*)"parseOpts -a -e meow\r", 1); + + // CHECK( write_length == 14u); + // REQUIRE( strcmp(dummyData, write_data) == 0); + REQUIRE( 1 == 1 ); +}