diff --git a/src/ParameterParser.h b/src/ParameterParser.h index 40b19ead..008bd5f8 100644 --- a/src/ParameterParser.h +++ b/src/ParameterParser.h @@ -403,6 +403,32 @@ namespace snowcrash { } } + static size_t matchBracket(const mdp::ByteBuffer& text) { + + size_t index = 0; + + if (text.at(index) != '(') { + return std::string::npos; + } + + size_t depth = 1; + + while (depth && (index < (text.length() - 1))) { // "- 1" cause nonenclosed bracket and + + ++index; + + if (text.at(index) == '(') { + depth++; + } + else if (text.at(index) == ')') { + depth--; + } + + } + + return depth ? std::string::npos : index; + } + /** * \brief Determine the type of parameter using the signature */ @@ -477,8 +503,7 @@ namespace snowcrash { if (innerSignature.substr(0, 1) == "(") { - // We should use `matchBrackets` if the parameters are supported to be more complex - size_t endOfAttributesPos = innerSignature.find_last_of(")"); + size_t endOfAttributesPos = matchBracket(innerSignature); if (endOfAttributesPos == std::string::npos) { return NotParameterType; // Expecting close of attributes diff --git a/test/test-MSONParameterParser.cc b/test/test-MSONParameterParser.cc index 00ea54e8..a6ec0e98 100644 --- a/test/test-MSONParameterParser.cc +++ b/test/test-MSONParameterParser.cc @@ -166,3 +166,18 @@ TEST_CASE("Warn missing default value in values in new parameter syntax", "[mson REQUIRE(parameter.node.exampleValue == "Value2"); REQUIRE(parameter.node.defaultValue == "Value1"); } + +TEST_CASE("Parentheses in parameter description with new syntax", "[parameter]") +{ + mdp::ByteBuffer source = "+ id (string) - lorem (ipsum) dolor\n"; + + ParseResult parameter; + SectionParserHelper::parse(source, MSONParameterSectionType, parameter); + + REQUIRE(parameter.report.error.code == Error::OK); + REQUIRE(parameter.report.warnings.empty()); + + REQUIRE(parameter.node.name == "id"); + REQUIRE(parameter.node.type == "string"); + REQUIRE(parameter.node.description == "lorem (ipsum) dolor"); +}