aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2018-01-11 19:33:38 +0100
committerdec05eba <dec05eba@protonmail.com>2018-01-11 20:59:33 +0100
commitaee178901d8bd03f9e0aeb50e3a5ed7570d9f910 (patch)
tree5421f51aebca24dd14b7b09e4b310ca2f1313983
parentb2b12abc4073c981a7fd856bc5071da887f98e43 (diff)
Start with config object types, for git dependencies
-rw-r--r--include/Conf.hpp18
-rw-r--r--project.conf1
-rw-r--r--src/CmakeModule.cpp4
-rw-r--r--src/Conf.cpp98
-rw-r--r--src/Exec.cpp2
-rw-r--r--tests/src/confTest/confTest.cpp11
-rw-r--r--tests/src/confTest/gitDependency.conf9
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"