diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2022-06-08 13:40:09 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-06-08 13:40:09 -0400 |
| commit | ff2ae7e0c1b48fa222f14dc84f15d0178ed056a1 (patch) | |
| tree | c4a3ab1e3441ec40267125086e511ef05342a547 /source/core | |
| parent | 8e6e884eca5b33218a8cb2714266fb6ed4548d75 (diff) | |
Improvements around Visual Studio versions/matching versions (#2267)
* #include an absolute path didn't work - because paths were taken to always be relative.
* Use TerminatedUnownedStringSlice for literals in output C++.
* Remove Escape/Unescape functions used in slang-token-reader.cpp
Add target type of 'host-cpp' etc to map to the target types.
* Fix some corner cases around string encoding.
* Added unit test for string escaping.
Fixed some assorted escaping bugs.
* Updated test output.
* Added decode test.
* Stop using hex output, to get around 'greedy' aspect. Use octal instead.
* Added HostHostCallable
Small changes to use ArtifactDesc/Info instead of large switches.
* Fix C++ emit to handle arbitrary function export.
* Add options handling for callable without an output being specified.
* Can compile with COM interface. Added example using com interface.
* Use the IR Ptr type instead of hack in C++ emit for interfaces.
* Fix issue with outputting the COM call when ptr is used.
* Fix crash issue on compilation failure.
* Add support for __global.
* Added `ActualGlobalRate`
Added special handling around globals and COM interfaces.
Tested out in cpu-com-example.
* Fix typo in NodeBase.
* Support for accessing globals by name working.
* Check that actual global initialization is working.
* Refactor the com replacement such that it doesn't need a cache or do anything special with GlobalVar.
* Remove context.
Only create replacement if needed.
* Split out COM host-callable into a unit-test.
* host-callable com testing on C++and llvm.
* Comment around the COM ptr replacement.
* Disable com test on vs 32 bit.
Fix C++ prelude
* Disable 32 bit targets testing com host-callable.
* Use JSON parsing to locate VS version.
* Need platform detection in C++prelude.
* Fix com host callable test for LLVM.
* WIP improments finding downstream compiler version.
* Work around for not being able to include "targetConditionals.h"
* Matching semantic versioning support.
* DownstreamMatchVersion -> DownstreamCompilerMatchVersion
Small improvements.
Diffstat (limited to 'source/core')
| -rw-r--r-- | source/core/slang-semantic-version.cpp | 153 | ||||
| -rw-r--r-- | source/core/slang-semantic-version.h | 46 |
2 files changed, 199 insertions, 0 deletions
diff --git a/source/core/slang-semantic-version.cpp b/source/core/slang-semantic-version.cpp index 7f603fd9c..cc631d292 100644 --- a/source/core/slang-semantic-version.cpp +++ b/source/core/slang-semantic-version.cpp @@ -7,6 +7,8 @@ namespace Slang { +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SemanticVersion !!!!!!!!!!!!!!!!!!!!!!!!!!!!! + SlangResult SemanticVersion::parse(const UnownedStringSlice& value, char separatorChar, SemanticVersion& outVersion) { outVersion.reset(); @@ -52,4 +54,155 @@ void SemanticVersion::append(StringBuilder& buf) const } } +/* static */SemanticVersion SemanticVersion::getEarliest(const ThisType* versions, Count count) +{ + if (count <= 0) + { + return SemanticVersion(); + } + + SemanticVersion bestVersion = versions[0]; + for (const auto version : makeConstArrayView(versions + 1, count - 1)) + { + if (version < bestVersion) + { + bestVersion = version; + } + } + return bestVersion; +} + +/* static */SemanticVersion SemanticVersion::getLatest(const ThisType* versions, Count count) +{ + if (count <= 0) + { + return SemanticVersion(); + } + + SemanticVersion bestVersion = versions[0]; + for (const auto version : makeConstArrayView(versions + 1, count - 1)) + { + if (version > bestVersion) + { + bestVersion = version; + } + } + return bestVersion; +} + + + +// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! MatchSemanticVersion !!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +/* static */SemanticVersion MatchSemanticVersion::findAnyBest(const SemanticVersion* versions, Count count, const ThisType& matchVersion) +{ + // If there aren't any we are done + if (count <= 0) + { + return SemanticVersion(); + } + + // If there is only one it must be the best + if (count == 1) + { + return versions[0]; + } + + // Define a version range [start, end) + SemanticVersion start, end; + + switch (matchVersion.m_kind) + { + case Kind::Past: + { + return SemanticVersion::getEarliest(versions, count); + } + case Kind::Unknown: + case Kind::Future: + { + // If it's unknown, we just get the latest + return SemanticVersion::getLatest(versions, count); + } + case Kind::Major: + { + start = SemanticVersion(matchVersion.m_version.m_major, 0, 0); + end = SemanticVersion(matchVersion.m_version.m_major + 1, 0, 0); + break; + } + case Kind::MajorMinor: + { + start = SemanticVersion(matchVersion.m_version.m_major, matchVersion.m_version.m_minor, 0); + end = SemanticVersion(matchVersion.m_version.m_major, matchVersion.m_version.m_minor + 1, 0); + break; + } + case Kind::MajorMinorPatch: + { + start = SemanticVersion(matchVersion.m_version); + end = SemanticVersion(matchVersion.m_version.m_major, matchVersion.m_version.m_minor, matchVersion.m_version.m_patch + 1); + break; + } + default: break; + } + + List<SemanticVersion> sortedVersions; + sortedVersions.addRange(versions, count); + + // Sort into increasing values + sortedVersions.sort([&](const SemanticVersion& a, const SemanticVersion& b) -> bool { return a < b; }); + + Index startIndex = 0; + for (; startIndex < count && sortedVersions[startIndex] < start; ++startIndex); + + Index endIndex = startIndex; + for (; endIndex < count && sortedVersions[endIndex] < end; ++endIndex); + + // If we have a span of versions, get the last in the span + if (startIndex < endIndex) + { + // Get the last one + return sortedVersions[endIndex - 1]; + } + + // Get the next greatest if there is one + if (endIndex < count) + { + return sortedVersions[endIndex]; + } + + // Get the prior prior to the start + if (startIndex > 0) + { + return sortedVersions[startIndex - 1]; + } + + // All cases should be covered, but return the last one + return sortedVersions[count - 1]; +} + +void MatchSemanticVersion::append(StringBuilder& buf) const +{ + switch (m_kind) + { + default: + case Kind::Unknown: buf << "unknown"; break; + case Kind::Past: buf << "past"; break; + case Kind::Future: buf << "future"; break; + case Kind::Major: + { + buf << m_version.m_major; + break; + } + case Kind::MajorMinor: + { + buf << m_version.m_major << "." << m_version.m_minor; + break; + } + case Kind::MajorMinorPatch: + { + m_version.append(buf); + break; + } + } +} + } // namespace Slang diff --git a/source/core/slang-semantic-version.h b/source/core/slang-semantic-version.h index d33116de6..4d64627c2 100644 --- a/source/core/slang-semantic-version.h +++ b/source/core/slang-semantic-version.h @@ -47,6 +47,9 @@ struct SemanticVersion static SlangResult parse(const UnownedStringSlice& value, SemanticVersion& outVersion); static SlangResult parse(const UnownedStringSlice& value, char separatorChar, SemanticVersion& outVersion); + static ThisType getEarliest(const ThisType* versions, Count count); + static ThisType getLatest(const ThisType* versions, Count count); + void append(StringBuilder& buf) const; bool operator>(const ThisType& rhs) const { return toInteger() > rhs.toInteger(); } @@ -63,5 +66,48 @@ struct SemanticVersion uint16_t m_patch; }; +/* Adds to the semantic versioning information for an incomplete version that can be matched */ +struct MatchSemanticVersion +{ + typedef MatchSemanticVersion ThisType; + + enum class Kind + { + Unknown, ///< Not known + Past, ///< Some unknown past version + Future, ///< Some future unknown version + Major, ///< Major version is defined (minor is in effect undefined) + MajorMinor, ///< Major and minor version are defined + MajorMinorPatch, ///< All elements of semantic version are defined + }; + + /// True if has a complete version + bool hasCompleteVersion() const { return m_kind == Kind::MajorMinorPatch; } + /// True if has some version information + bool hasVersion() const { return Index(m_kind) >= Index(Kind::Major); } + + void set(Index major) { m_kind = Kind::Major; m_version = SemanticVersion(int(major), 0, 0); } + void set(Index major, Index minor) { m_kind = Kind::MajorMinor; m_version = SemanticVersion(int(major), int(minor), 0); } + void set(Index major, Index minor, Index patch) { m_kind = Kind::MajorMinorPatch; m_version = SemanticVersion(int(major), int(minor), int(patch)); } + + void append(StringBuilder& buf) const; + + static MatchSemanticVersion makeFuture() { MatchSemanticVersion version; version.m_kind = Kind::Future; return version; } + + /// Finds the 'best' version based on the versions passed. + /// Doesn't follow strict semantic rules as will attempt to return the closest 'any' in past or future + /// If none can be found, returns an empty semantic version + static SemanticVersion findAnyBest(const SemanticVersion* versions, Count count, const ThisType& matchVersion); + + MatchSemanticVersion():m_kind(Kind::Unknown) {} + MatchSemanticVersion(Kind kind, const SemanticVersion& version): + m_kind(kind), + m_version(version) + {} + + Kind m_kind; + SemanticVersion m_version; +}; + } #endif |
