aboutsummaryrefslogtreecommitdiff
path: root/src/Conf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Conf.cpp')
-rw-r--r--src/Conf.cpp226
1 files changed, 199 insertions, 27 deletions
diff --git a/src/Conf.cpp b/src/Conf.cpp
index 5282bb5..4217846 100644
--- a/src/Conf.cpp
+++ b/src/Conf.cpp
@@ -24,7 +24,8 @@ namespace sibs
OPEN_BRACKET,
CLOSING_BRACKET,
EQUALS,
- STRING
+ STRING,
+ COMMA
};
const char *getTokenName(Token token)
@@ -38,6 +39,7 @@ namespace sibs
case Token::CLOSING_BRACKET: return "]";
case Token::EQUALS: return "=";
case Token::STRING: return "string";
+ case Token::COMMA: return ",";
default: return "Unknown";
}
}
@@ -61,12 +63,12 @@ namespace sibs
c = *code;
}
- if(isAlpha(c) || c == '_')
+ if(isIdentifierChar(c))
{
char *startOfIdentifier = code.base();
++code;
c = *code;
- while(isAlpha(c) || isDigit(c) || c == '_' || c == '-')
+ while(isIdentifierChar(c))
{
++code;
c = *code;
@@ -115,6 +117,11 @@ namespace sibs
++code;
return Token::STRING;
}
+ else if (c == ',')
+ {
+ ++code;
+ return Token::COMMA;
+ }
else if(c == '\0')
{
return Token::END_OF_FILE;
@@ -144,6 +151,11 @@ namespace sibs
{
return c >= '0' && c <= '9';
}
+
+ bool isIdentifierChar(u32 c)
+ {
+ return isAlpha(c) || isDigit(c) || c == '_' || c == '-' || c == '.';
+ }
private:
Token currentToken;
u8string code;
@@ -238,7 +250,7 @@ namespace sibs
}
}
- void parseConfigFieldRhs(StringView fieldName)
+ void parseConfigFieldRhs(const StringView &fieldName)
{
Token token = tokenizer.nextToken();
if(token == Token::STRING)
@@ -247,39 +259,48 @@ namespace sibs
}
else if(token == Token::OPEN_BRACKET)
{
+ parseConfigFieldRhsList(fieldName);
+ }
+ else
+ {
+ string errMsg = "Expected string on right-hand side of field '";
+ errMsg += string(fieldName.data, fieldName.size);
+ errMsg += "', got: ";
+ errMsg += getTokenName(token);
+ throw ParserException(errMsg);
+ }
+ }
+
+ void parseConfigFieldRhsList(const StringView &fieldName)
+ {
+ Token token = tokenizer.nextToken();
+ if (token == Token::CLOSING_BRACKET) return;
+
+ vector<StringView> values;
+ while (true)
+ {
+ if (token == Token::STRING)
+ values.push_back(tokenizer.getString());
+
token = tokenizer.nextToken();
- if(token == Token::STRING)
+ if (token == Token::COMMA)
{
- StringView str = tokenizer.getString();
token = tokenizer.nextToken();
- if(token == Token::CLOSING_BRACKET)
- {
- vector<StringView> values;
- values.push_back(str);
- callback->processField(fieldName, values);
- }
- else
- {
- string errMsg = "Expected ']' to close value list, got: ";
- errMsg += getTokenName(token);
- throw ParserException(errMsg);
- }
+ continue;
+ }
+ else if (token == Token::CLOSING_BRACKET)
+ {
+ break;
}
else
{
- string errMsg = "Expected string value inside list in field definition, got: ";
+ string errMsg = "Expected list value to be followed by ']' or ',', got: ";
errMsg += getTokenName(token);
throw ParserException(errMsg);
}
}
- else
- {
- string errMsg = "Expected string on right-hand side of field '";
- errMsg += string(fieldName.data, fieldName.size);
- errMsg += "', got: ";
- errMsg += getTokenName(token);
- throw ParserException(errMsg);
- }
+
+ callback->processField(fieldName, values);
}
void parseConfigObject()
@@ -330,6 +351,28 @@ namespace sibs
return Parser::parse(code, callback);
}
+ bool containsPlatform(const vector<Platform> &platforms, Platform platform)
+ {
+ for (Platform vecPlatform : platforms)
+ {
+ if (vecPlatform == platform || vecPlatform == PLATFORM_ANY)
+ return true;
+ }
+ return false;
+ }
+
+ const char* asString(Platform platform)
+ {
+ switch (platform)
+ {
+ case PLATFORM_ANY: return "any";
+ case PLATFORM_LINUX32: return "linux32";
+ case PLATFORM_LINUX64: return "linux64";
+ case PLATFORM_WIN32: return "win32";
+ case PLATFORM_WIN64: return "win64";
+ }
+ }
+
const char* asString(OptimizationLevel optLevel)
{
switch(optLevel)
@@ -361,6 +404,33 @@ namespace sibs
return defines;
}
+ void getLibFiles(const string &libPath, vector<string> &outputFiles)
+ {
+ FileString nativePath = toFileString(libPath);
+ FileType fileType = getFileType(nativePath.c_str());
+ switch (fileType)
+ {
+ case FileType::FILE_NOT_FOUND:
+ {
+ string errMsg = "Path not found: ";
+ errMsg += libPath;
+ throw ParserException(errMsg);
+ }
+ case FileType::REGULAR:
+ {
+ string errMsg = "Expected path ";
+ errMsg += libPath;
+ errMsg += " to be a directory, was a regular file";
+ throw ParserException(errMsg);
+ }
+ }
+
+ walkDirFiles(nativePath.c_str(), [&outputFiles](tinydir_file *file)
+ {
+ outputFiles.push_back(toUtf8(file->path));
+ });
+ }
+
void SibsConfig::processObject(StringView name)
{
currentObject = name;
@@ -462,6 +532,108 @@ namespace sibs
else
throw ParserException("Expected package.include_dirs to be a list, was a single value");
}
+ else if (name.equals("platforms"))
+ {
+ if (value.isList())
+ {
+ // TODO: Checking for duplicate declaration should be done in the config parser
+ if (!platforms.empty())
+ throw ParserException("Found duplicate declaration of package.platforms");
+
+ for (const StringView &platform : value.asList())
+ {
+ if (platform.equals("any"))
+ {
+ platforms.push_back(PLATFORM_ANY);
+ }
+ else if (platform.equals("linux32"))
+ {
+ platforms.push_back(PLATFORM_LINUX32);
+ }
+ else if (platform.equals("linux64"))
+ {
+ platforms.push_back(PLATFORM_LINUX64);
+ }
+ else if (platform.equals("win32"))
+ {
+ platforms.push_back(PLATFORM_WIN32);
+ }
+ else if (platform.equals("win64"))
+ {
+ platforms.push_back(PLATFORM_WIN64);
+ }
+ else
+ {
+ string errMsg = "package.platforms contains invalid platform \"";
+ errMsg += string(platform.data, platform.size);
+ errMsg += "\". Expected platform to be one of: any, linux32, linux64, win32 or win64";
+ throw ParserException(errMsg);
+ }
+ }
+ }
+ else
+ throw ParserException("Expected package.platforms to be a list, was a single value");
+ }
+ }
+ else if (currentObject.equals(CONFIG_SYSTEM_PLATFORM))
+ {
+ if (name.equals("expose_include_dirs"))
+ {
+ if (value.isList())
+ {
+ for (const StringView &includeDir : value.asList())
+ {
+ exposeIncludeDirs.emplace_back(string(includeDir.data, includeDir.size));
+ }
+ }
+ else
+ {
+ string errMsg = "Expected ";
+ errMsg += string(currentObject.data, currentObject.size);
+ errMsg += " to be a list, was a single value";
+ throw ParserException(errMsg);
+ }
+ }
+ }
+ else if (currentObject.equals(CONFIG_STATIC_DEBUG_PLATFORM))
+ {
+ if (name.equals("lib"))
+ {
+ if (value.isSingle())
+ {
+ string debugStaticLibPath = toUtf8(projectPath);
+ debugStaticLibPath += "/";
+ debugStaticLibPath += string(value.asSingle().data, value.asSingle().size);
+ getLibFiles(debugStaticLibPath, debugStaticLibs);
+ }
+ else
+ {
+ string errMsg = "Expected ";
+ errMsg += string(currentObject.data, currentObject.size);
+ errMsg += " to be a single value, was a list";
+ throw ParserException(errMsg);
+ }
+ }
+ }
+ else if (currentObject.equals(CONFIG_STATIC_RELEASE_PLATFORM))
+ {
+ if (name.equals("lib"))
+ {
+ if (value.isSingle())
+ {
+ string releaseStaticLibPath = toUtf8(projectPath);
+ releaseStaticLibPath += "/";
+ releaseStaticLibPath += string(value.asSingle().data, value.asSingle().size);
+ getLibFiles(releaseStaticLibPath, releaseStaticLibs);
+ }
+ else
+ {
+ string errMsg = "Expected ";
+ errMsg += string(currentObject.data, currentObject.size);
+ errMsg += " to be a single value, was a list";
+ throw ParserException(errMsg);
+ }
+ }
}
else if(currentObject.equals("dependencies"))
{