From 7c24c5d0de4d3584d6d2f9f3c26b4d757b0a0df2 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 10 Oct 2018 07:59:51 +0200 Subject: Fix sibs test not including parent library correctly Refactor config parsing to reduce number of changes when introducing a new platform to support --- src/Conf.cpp | 190 ++++++++++++++++++++++++++++++++++--------------------- src/Platform.cpp | 38 ++++++++++- src/main.cpp | 4 +- 3 files changed, 156 insertions(+), 76 deletions(-) (limited to 'src') diff --git a/src/Conf.cpp b/src/Conf.cpp index 38774e0..0307bc0 100644 --- a/src/Conf.cpp +++ b/src/Conf.cpp @@ -80,8 +80,12 @@ namespace sibs char *startOfIdentifier = code.base(); ++code; c = *code; + char prevChar = '\0'; while(isIdentifierChar(c)) { + if(c == '.' && prevChar == '.') + throw UnexpectedTokenException("Identifier can't have two dots in a row"); + prevChar = c; ++code; c = *code; } @@ -863,59 +867,12 @@ namespace sibs } else if(currentObject.size >= 6 && strncmp(currentObject.data, "config", 6) == 0) { - bool platformConfig = currentObject.equals(CONFIGS[CONFIG_SYSTEM_PLATFORM]); - if(currentObject.size == 6 || platformConfig) // [config] + if(currentObject.size == 6) // [config] { - 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(name.equals("include_dirs")) - { - if(value.isList()) - { - for(const StringView &includeDir : value.asList()) - { - includeDirs.emplace_back(string(includeDir.data, includeDir.size)); - } - } - else - throw ParserException("Expected " + string(currentObject.data, currentObject.size) + ".include_dirs to be a list, was a single value"); - } - else if(name.equals("ignore_dirs")) - { - if (value.isList()) - { - string projectPathUtf8 = toUtf8(projectPath); - for (const StringView &ignoreDir : value.asList()) - { - string ignoreDirFull = projectPathUtf8; - ignoreDirFull += "/"; - ignoreDirFull += string(ignoreDir.data, ignoreDir.size); - ignoreDirs.emplace_back(move(ignoreDirFull)); - } - } - else - throw ParserException("Expected " + string(currentObject.data, currentObject.size) + ".ignore_dirs to be a list, was a single value"); - } - else - failInvalidFieldUnderObject(name); + parseConfig(name, value); } else - parsePlatformBuildTypeConfigs(name, value); + parsePlatformConfig(name, value); } else if(currentObject.equals("dependencies")) { @@ -1012,6 +969,57 @@ namespace sibs throw ParserException(errMsg); } } + + void SibsConfig::parseConfig(const StringView &name, const ConfigValue &value) + { + 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(name.equals("include_dirs")) + { + if(value.isList()) + { + for(const StringView &includeDir : value.asList()) + { + includeDirs.emplace_back(string(includeDir.data, includeDir.size)); + } + } + else + throw ParserException("Expected " + string(currentObject.data, currentObject.size) + ".include_dirs to be a list, was a single value"); + } + else if(name.equals("ignore_dirs")) + { + if (value.isList()) + { + string projectPathUtf8 = toUtf8(projectPath); + for (const StringView &ignoreDir : value.asList()) + { + string ignoreDirFull = projectPathUtf8; + ignoreDirFull += "/"; + ignoreDirFull += string(ignoreDir.data, ignoreDir.size); + ignoreDirs.emplace_back(move(ignoreDirFull)); + } + } + else + throw ParserException("Expected " + string(currentObject.data, currentObject.size) + ".ignore_dirs to be a list, was a single value"); + } + else + failInvalidFieldUnderObject(name); + } void SibsConfig::parseDependencies(const StringView &name, const ConfigValue &value) { @@ -1171,39 +1179,75 @@ namespace sibs else failInvalidFieldUnderObject(fieldName); } - - void SibsConfig::parsePlatformBuildTypeConfigs(const StringView &fieldName, const ConfigValue &fieldValue) + + static bool isObjectIdentifierSymbol(char c) { - bool validConfig = false; - for(int i = 0; i < NUM_CONFIGS; ++i) + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_' || c == '-'; + } + + static StringView getNextIdentifierInObject(const StringView &objectName) + { + size_t identifierStart = -1; + for(size_t i = 0; i < objectName.size; ++i) { - const StringView &config = CONFIGS[i]; - if(currentObject.equals(config)) + char c = objectName[i]; + if(c == '.') { - validConfig = true; - switch(i) - { - case CONFIG_GENERIC_STATIC_DEBUG_PLATFORM: - case CONFIG_STATIC_DEBUG_PLATFORM: - parsePlatformConfigStaticDebug(fieldName, fieldValue); - break; - case CONFIG_GENERIC_STATIC_RELEASE_PLATFORM: - case CONFIG_STATIC_RELEASE_PLATFORM: - parsePlatformConfigStaticRelease(fieldName, fieldValue); - break; - default: - break; - } + if(identifierStart == -1) + identifierStart = i + 1; + else + return { objectName.data + identifierStart, i - identifierStart }; } } - - if(!validConfig) + + if(identifierStart == -1) + return { objectName.data + objectName.size, 0 }; + else + return { objectName.data + identifierStart, objectName.size - identifierStart }; + } + + void SibsConfig::parsePlatformConfig(const StringView &fieldName, const ConfigValue &fieldValue) + { + StringView platformName = getNextIdentifierInObject(currentObject); + Platform platform = getPlatformByName(platformName); + + if(platform == PLATFORM_INVALID) { string errMsg = "Invalid config object \""; errMsg += string(currentObject.data, currentObject.size); - errMsg += "\""; + errMsg += "\", invalid platform: "; + errMsg += string(platformName.data, platformName.size); throw ParserException(errMsg); } + + if(!isBaseForPlatform(platform, SYSTEM_PLATFORM)) + return; + + const char *start = platformName.data + platformName.size; + const char *currentObjEnd = currentObject.data + currentObject.size; + if(start < currentObjEnd) + { + size_t size = currentObjEnd - start; + StringView platformConfigType = { start, size }; + + if(size == 13 && strncmp(platformConfigType.data, ".static.debug", 13) == 0) + { + parsePlatformConfigStaticDebug(fieldName, fieldValue); + } + else if(size == 15 && strncmp(platformConfigType.data, ".static.release", 15) == 0) + { + parsePlatformConfigStaticRelease(fieldName, fieldValue); + } + else + { + string errMsg = "Invalid config object \""; + errMsg += string(currentObject.data, currentObject.size); + errMsg += "\""; + throw ParserException(errMsg); + } + } + else + parseConfig(fieldName, fieldValue); } string SibsConfig::parsePlatformConfigStatic(const StringView &fieldName, const ConfigValue &fieldValue) diff --git a/src/Platform.cpp b/src/Platform.cpp index 9b02ca5..dd81667 100644 --- a/src/Platform.cpp +++ b/src/Platform.cpp @@ -1,7 +1,31 @@ #include "../include/Platform.hpp" +#include namespace sibs { + static int countSetBits(u32 value) + { + int count = 0; + while(value) + { + count += (value & 1U); + value >>= 1U; + } + return count; + } + + // Returns -1 if no bit is set + static int getLeastSignificantBitSetPosition(u32 value) + { + for(u32 i = 0; i < sizeof(u32); ++i) + { + if(value & 1U) + return i; + value >>= 1U; + } + return -1; + } + bool containsPlatform(const std::vector &platforms, Platform platform) { for (Platform vecPlatform : platforms) @@ -33,7 +57,7 @@ namespace sibs case PLATFORM_HAIKU: return "haiku"; case PLATFORM_HAIKU32: return "haiku32"; case PLATFORM_HAIKU64: return "haiku64"; - default: return nullptr; + default: assert(false); return nullptr; } } @@ -49,4 +73,16 @@ namespace sibs { return a & b; } + + bool isBaseForPlatform(Platform base, Platform platform) + { + return base == PLATFORM_ANY || base == platform || (isSamePlatformFamily(platform, base) && countSetBits(base) < countSetBits(platform)); + } + + Platform getPlatformGenericType(Platform platform) + { + if(platform == PLATFORM_INVALID || platform == PLATFORM_ANY) + return PLATFORM_INVALID; + return (Platform)(1U << (u32)getLeastSignificantBitSetPosition(platform)); + } } diff --git a/src/main.cpp b/src/main.cpp index b05cded..b3a8f40 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -503,7 +503,7 @@ static int buildProject(int argc, const _tinydir_char_t **argv) optimizationLevel = OPT_LEV_DEBUG; if(!platformName) - platformName = SYSTEM_PLATFORM_NAME; + platformName = asString(SYSTEM_PLATFORM); string platformUtf8 = toUtf8(platformName); Platform platform = getPlatformByName(StringView(platformUtf8.data(), platformUtf8.size())); @@ -718,7 +718,7 @@ static Result newProjectCreateConf(const string &projectName, const string projectConfStr += "name = \"" + projectName + "\"\n"; projectConfStr += "type = \"" + projectType + "\"\n"; projectConfStr += "version = \"0.1.0\"\n"; - projectConfStr += "platforms = [\"" + string(SYSTEM_GENERIC_PLATFORM_NAME) + "\"]\n\n"; + projectConfStr += "platforms = [\"" + string(asString(getPlatformGenericType(SYSTEM_PLATFORM))) + "\"]\n\n"; projectConfStr += "[dependencies]\n"; FileString projectConfPath = projectPath; -- cgit v1.2.3