diff options
Diffstat (limited to 'src/Conf.cpp')
-rw-r--r-- | src/Conf.cpp | 226 |
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")) { |