diff options
author | dec05eba <dec05eba@protonmail.com> | 2018-01-11 19:33:38 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2018-01-11 20:59:33 +0100 |
commit | aee178901d8bd03f9e0aeb50e3a5ed7570d9f910 (patch) | |
tree | 5421f51aebca24dd14b7b09e4b310ca2f1313983 | |
parent | b2b12abc4073c981a7fd856bc5071da887f98e43 (diff) |
Start with config object types, for git dependencies
-rw-r--r-- | include/Conf.hpp | 18 | ||||
-rw-r--r-- | project.conf | 1 | ||||
-rw-r--r-- | src/CmakeModule.cpp | 4 | ||||
-rw-r--r-- | src/Conf.cpp | 98 | ||||
-rw-r--r-- | src/Exec.cpp | 2 | ||||
-rw-r--r-- | tests/src/confTest/confTest.cpp | 11 | ||||
-rw-r--r-- | tests/src/confTest/gitDependency.conf | 9 |
7 files changed, 134 insertions, 9 deletions
diff --git a/include/Conf.hpp b/include/Conf.hpp index 0b97960..90f150a 100644 --- a/include/Conf.hpp +++ b/include/Conf.hpp @@ -21,7 +21,8 @@ namespace sibs { NONE, SINGLE, - LIST + LIST, + OBJECT }; ConfigValue() : type(Type::NONE) {} @@ -38,9 +39,17 @@ namespace sibs { } + + ConfigValue(const std::unordered_map<std::string, StringView> &_map) : + type(Type::OBJECT), + map(_map) + { + + } bool isSingle() const { return type == Type::SINGLE; } bool isList() const { return type == Type::LIST; } + bool isObject() const { return type == Type::OBJECT; } StringView asSingle() const { @@ -53,9 +62,16 @@ namespace sibs assert(isList()); return values; } + + const std::unordered_map<std::string, StringView>& asObject() const + { + assert(isObject()); + return map; + } private: Type type; std::vector<StringView> values; + std::unordered_map<std::string, StringView> map; }; class Parser; diff --git a/project.conf b/project.conf index 2271dbe..029cb9e 100644 --- a/project.conf +++ b/project.conf @@ -10,3 +10,4 @@ ignore_dirs = ["cmake", "cmake-build-debug", "build"] [dependencies] libcurl = "7.57.0" libarchive = "3.3.2" +libgit2 = "0.26.0" diff --git a/src/CmakeModule.cpp b/src/CmakeModule.cpp index 8606a42..106f2c6 100644 --- a/src/CmakeModule.cpp +++ b/src/CmakeModule.cpp @@ -181,10 +181,10 @@ namespace sibs { string buildPathUtf8 = toUtf8(buildPath); nprintf("Searching for libraries generate by cmake in build path: %s\n", buildPathUtf8.c_str()); - walkDirFiles(buildPath.c_str(), + walkDirFilesRecursive(buildPath.c_str(), [&config, &staticLinkerFlagCallbackFunc, &dynamicLinkerFlagCallbackFunc](tinydir_file *file) { - if(_tinydir_strcmp(file->extension, CONFIG_DYNAMIC_LIB_FILE_EXTENSION) == 0) + if(_tinydir_strcmp(file->extension, CONFIG_DYNAMIC_LIB_FILE_EXTENSION) == 0 || _tinydir_strcmp(file->extension, CONFIG_STATIC_LIB_FILE_EXTENSION) == 0) { string libFileUtf8 = toUtf8(file->path); nprintf("Library generated by cmake: %s\n", libFileUtf8.c_str()); diff --git a/src/Conf.cpp b/src/Conf.cpp index e8af27a..93ec6e7 100644 --- a/src/Conf.cpp +++ b/src/Conf.cpp @@ -25,6 +25,8 @@ namespace sibs IDENTIFIER, OPEN_BRACKET, CLOSING_BRACKET, + OPEN_BRACE, + CLOSING_BRACE, EQUALS, STRING, COMMA @@ -39,6 +41,8 @@ namespace sibs case Token::IDENTIFIER: return "identifier"; case Token::OPEN_BRACKET: return "["; case Token::CLOSING_BRACKET: return "]"; + case Token::OPEN_BRACE: return "{"; + case Token::CLOSING_BRACE: return "}"; case Token::EQUALS: return "="; case Token::STRING: return "string"; case Token::COMMA: return ","; @@ -50,7 +54,6 @@ namespace sibs { public: Tokenizer(const char *_code) : - currentToken(Token::NONE), code((char*)_code) { @@ -90,6 +93,16 @@ namespace sibs ++code; return Token::CLOSING_BRACKET; } + else if(c == '{') + { + ++code; + return Token::OPEN_BRACE; + } + else if(c == '}') + { + ++code; + return Token::CLOSING_BRACE; + } else if(c == '=') { ++code; @@ -172,9 +185,7 @@ namespace sibs return isAlpha(c) || isDigit(c) || c == '_' || c == '-' || c == '.'; } private: - Token currentToken; u8string code; - union { StringView identifier; @@ -276,6 +287,10 @@ namespace sibs { parseConfigFieldRhsList(fieldName); } + else if(token == Token::OPEN_BRACE) + { + parseConfigFieldRhsObject(fieldName); + } else { string errMsg = "Expected string on right-hand side of field '"; @@ -288,14 +303,24 @@ namespace sibs void parseConfigFieldRhsList(const StringView &fieldName) { + vector<StringView> values; Token token = tokenizer.nextToken(); - if (token == Token::CLOSING_BRACKET) return; + if (token == Token::CLOSING_BRACKET) + { + callback->processField(fieldName, values); + return; + } - vector<StringView> values; while (true) { if (token == Token::STRING) values.push_back(tokenizer.getString()); + else + { + string errMsg = "Expected list to contain string, got: "; + errMsg += getTokenName(token); + throw ParserException(errMsg); + } token = tokenizer.nextToken(); if (token == Token::COMMA) @@ -317,6 +342,69 @@ namespace sibs callback->processField(fieldName, values); } + + void parseConfigFieldRhsObject(const StringView &fieldName) + { + unordered_map<string, StringView> fields; + Token token = tokenizer.nextToken(); + if (token == Token::CLOSING_BRACE) + { + callback->processField(fieldName, fields); + return; + } + + while (true) + { + if (token == Token::IDENTIFIER) + { + StringView objectKey = tokenizer.getIdentifier(); + token = tokenizer.nextToken(); + if(token == Token::EQUALS) + { + token = tokenizer.nextToken(); + if (token == Token::STRING) + fields[string(objectKey.data, objectKey.size)] = tokenizer.getString(); + else + { + string errMsg = "Expected object field value to be a string, got: "; + errMsg += getTokenName(token); + throw ParserException(errMsg); + } + } + else + { + string errMsg = "Expected object key to be followed by '=', got: "; + errMsg += getTokenName(token); + throw ParserException(errMsg); + } + } + else + { + string errMsg = "Expected object to contain key, got: "; + errMsg += getTokenName(token); + throw ParserException(errMsg); + } + + token = tokenizer.nextToken(); + if (token == Token::COMMA) + { + token = tokenizer.nextToken(); + continue; + } + else if (token == Token::CLOSING_BRACE) + { + break; + } + else + { + string errMsg = "Expected object field to be followed by '}' or ',', got: "; + errMsg += getTokenName(token); + throw ParserException(errMsg); + } + } + + callback->processField(fieldName, fields); + } void parseConfigObject() { diff --git a/src/Exec.cpp b/src/Exec.cpp index e0ae306..2eac8bc 100644 --- a/src/Exec.cpp +++ b/src/Exec.cpp @@ -99,4 +99,4 @@ namespace sibs } } #endif -}
\ No newline at end of file +} diff --git a/tests/src/confTest/confTest.cpp b/tests/src/confTest/confTest.cpp index f3d9e2b..d24c460 100644 --- a/tests/src/confTest/confTest.cpp +++ b/tests/src/confTest/confTest.cpp @@ -104,3 +104,14 @@ TEST_CASE("parse config - define dynamic") REQUIRE(sibsConfig.getDefinedValue("BUILD_STATIC") == "0"); REQUIRE(sibsConfig.getDefinedValue("DEFINE_TYPE") == "DYNAMIC"); } + +TEST_CASE("parse config - git dependency") +{ + SibsConfig sibsConfig(Compiler::GCC, TINYDIR_STRING("tests/src/confTest"), OPT_LEV_DEBUG, false); + Result<bool> result = Config::readFromFile(TINYDIR_STRING("tests/src/confTest/gitDependency.conf"), sibsConfig); + if(result.isErr()) + { + fprintf(stderr, "%s", result.getErrMsg().c_str()); + exit(1); + } +} diff --git a/tests/src/confTest/gitDependency.conf b/tests/src/confTest/gitDependency.conf new file mode 100644 index 0000000..d18b267 --- /dev/null +++ b/tests/src/confTest/gitDependency.conf @@ -0,0 +1,9 @@ +[package] +name = "confTest" +version = "0.1.0" +type = "library" +platforms = ["linux64", "win64"] + +[dependencies] +xxhash = { git = "https://github.com/DEC05EBA/xxHash.git", branch = "master" } +catch2 = "1.0.0" |