aboutsummaryrefslogtreecommitdiff
path: root/src/Conf.cpp
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2017-12-31 05:24:40 +0100
committerdec05eba <dec05eba@protonmail.com>2017-12-31 05:26:07 +0100
commit017ec45e94204f977dcd7b04c8035d48f230ded3 (patch)
tree7778ecc069f05fb527329f36876ed13a17a48ab3 /src/Conf.cpp
parent7a5910121ab0ad2ea8a4a60e5b6599b7255e5a5e (diff)
Sibs can now build itself on windows
Fixed several bugs. The windows implementation IS QUICK AND DIRTY! It links things as static even if you wish to link as dynamic etc..... NEED TO FIX THIS !!!
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"))
{