From cb02b09b566d6f547b5cf8b8b4b5264d05867e36 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Thu, 14 May 2026 18:40:48 -0700 Subject: [PATCH 01/35] Replaced split(), startswith() and endswith() pystring usages Signed-off-by: Mei Chu --- src/OpenColorIO/Config.cpp | 5 +++-- vendor/openfx/OCIOUtils.cpp | 11 ++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/OpenColorIO/Config.cpp b/src/OpenColorIO/Config.cpp index a8f25d5cad..0dea60bcd8 100644 --- a/src/OpenColorIO/Config.cpp +++ b/src/OpenColorIO/Config.cpp @@ -2571,7 +2571,8 @@ const char * Config::getInactiveColorSpaces() const bool Config::isInactiveColorSpace(const char * colorspace) const noexcept { StringUtils::StringVec svec; - pystring::split(getImpl()->m_inactiveColorSpaceNamesConf.c_str(), svec, ", "); + svec = StringUtils::Split(getImpl()->m_inactiveColorSpaceNamesConf.c_str(), ','); + StringUtils::Trim(svec); for (size_t i = 0; i < svec.size(); i++) { @@ -6036,7 +6037,7 @@ bool Config::isArchivable() const // 1) Path may not be absolute. pystring::os::path::isabs(normPath) || // 2) Path may not start with double dot ".." (going above working directory). - pystring::startswith(normPath, "..") || + StringUtils::StartsWith(normPath, "..") || // 3) A context variable may not be located at the start of the path. (ContainsContextVariables(path) && (StringUtils::Find(path, "$") == 0 || diff --git a/vendor/openfx/OCIOUtils.cpp b/vendor/openfx/OCIOUtils.cpp index 90f6e42527..c4a532821b 100644 --- a/vendor/openfx/OCIOUtils.cpp +++ b/vendor/openfx/OCIOUtils.cpp @@ -2,6 +2,7 @@ // Copyright Contributors to the OpenColorIO Project. #include "OCIOUtils.h" +#include "utils/StringUtils.h" namespace OCIO = OCIO_NAMESPACE; @@ -37,13 +38,13 @@ ContextMap deserializeContextStore(const std::string & contextStoreRaw) // Format: key0:value0;key1:value1;... std::vector contextPairsRaw; - pystring::split(contextStoreRaw, contextPairsRaw, ";"); + contextPairsRaw = StringUtils::Split(contextStoreRaw, ";"); for (size_t i = 0; i < contextPairsRaw.size(); i++) { std::vector contextPair; - pystring::split(contextPairsRaw[i], contextPair, ":"); - + contextPair = StringUtils::Split(contextPairsRaw[i], ":"); + if (contextPair.size() == 2) { contextMap[contextPair[0]] = contextPair[1]; @@ -437,7 +438,7 @@ void contextParamChanged(OFX::ImageEffect & instance, const std::string & paramName) { // Is changed param a context variable? - if (!pystring::startswith(paramName, "context_") + if (!StringUtils::StartsWith(paramName, "context_") || paramName == "context_store") { return; @@ -513,7 +514,7 @@ void choiceParamChanged(OFX::ImageEffect & instance, const std::string & paramName) { // Ignore sibling *_store params - if (pystring::endswith(paramName, "_store")) + if (StringUtils::EndsWith(paramName, "_store")) { return; } From 583cbb5c9bb42c311cf7651758d06f499fb47baf Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Thu, 14 May 2026 19:08:54 -0700 Subject: [PATCH 02/35] Add utils as include path for openfx build Signed-off-by: Mei Chu --- vendor/openfx/CMakeLists.txt | 1 + vendor/openfx/OCIOUtils.cpp | 1 - vendor/openfx/OCIOUtils.h | 2 ++ 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/vendor/openfx/CMakeLists.txt b/vendor/openfx/CMakeLists.txt index 2d2f880b2a..66c12f812c 100644 --- a/vendor/openfx/CMakeLists.txt +++ b/vendor/openfx/CMakeLists.txt @@ -54,6 +54,7 @@ target_include_directories(ofxplugin ${openfx_INCLUDE_DIR} ${PROJECT_SOURCE_DIR}/include/ ${PROJECT_BINARY_DIR}/include/ + ${PROJECT_SOURCE_DIR}/src/ ) target_link_libraries(ofxplugin diff --git a/vendor/openfx/OCIOUtils.cpp b/vendor/openfx/OCIOUtils.cpp index c4a532821b..e71d20dc4a 100644 --- a/vendor/openfx/OCIOUtils.cpp +++ b/vendor/openfx/OCIOUtils.cpp @@ -2,7 +2,6 @@ // Copyright Contributors to the OpenColorIO Project. #include "OCIOUtils.h" -#include "utils/StringUtils.h" namespace OCIO = OCIO_NAMESPACE; diff --git a/vendor/openfx/OCIOUtils.h b/vendor/openfx/OCIOUtils.h index 24f51a3f2d..398b3d7c31 100644 --- a/vendor/openfx/OCIOUtils.h +++ b/vendor/openfx/OCIOUtils.h @@ -9,6 +9,8 @@ #include "ofxsImageEffect.h" +#include "utils/StringUtils.h" + #include namespace OCIO = OCIO_NAMESPACE; From daf0bcf7c9c583fd528916c2cabb9afa78c14260 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Thu, 14 May 2026 19:18:08 -0700 Subject: [PATCH 03/35] Fix silly char issue Signed-off-by: Mei Chu --- vendor/openfx/OCIOUtils.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vendor/openfx/OCIOUtils.cpp b/vendor/openfx/OCIOUtils.cpp index e71d20dc4a..1750b6e324 100644 --- a/vendor/openfx/OCIOUtils.cpp +++ b/vendor/openfx/OCIOUtils.cpp @@ -37,12 +37,12 @@ ContextMap deserializeContextStore(const std::string & contextStoreRaw) // Format: key0:value0;key1:value1;... std::vector contextPairsRaw; - contextPairsRaw = StringUtils::Split(contextStoreRaw, ";"); + contextPairsRaw = StringUtils::Split(contextStoreRaw, ';'); for (size_t i = 0; i < contextPairsRaw.size(); i++) { std::vector contextPair; - contextPair = StringUtils::Split(contextPairsRaw[i], ":"); + contextPair = StringUtils::Split(contextPairsRaw[i], ':'); if (contextPair.size() == 2) { From c14c94db0cc1041240f2ab5af04616988a1938d6 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Fri, 15 May 2026 00:56:36 -0700 Subject: [PATCH 04/35] Update StringUtils Trim functionalities. Signed-off-by: Mei Chu --- src/OpenColorIO/OCIOZArchive.cpp | 2 +- .../fileformats/FileFormatIridasLook.cpp | 2 +- src/utils/StringUtils.h | 21 +++++++++++++++++ tests/utils/StringUtils_tests.cpp | 23 +++++++++++++++++++ vendor/openfx/OCIOUtils.cpp | 4 +--- 5 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/OpenColorIO/OCIOZArchive.cpp b/src/OpenColorIO/OCIOZArchive.cpp index 1caed9ecba..12d839a265 100644 --- a/src/OpenColorIO/OCIOZArchive.cpp +++ b/src/OpenColorIO/OCIOZArchive.cpp @@ -174,7 +174,7 @@ void addSupportedFiles(void * archiver, const char * path, const char * configWo std::string root, ext; pystring::os::path::splitext(root, ext, std::string(entry->d_name)); // Strip leading dot character in order to get the extension name only. - ext = pystring::lstrip(ext, "."); + ext = StringUtils::LeftTrim(ext, '.'); // Check if the extension is supported. Using logic from LoadFileUncached(). FormatRegistry & formatRegistry = FormatRegistry::GetInstance(); diff --git a/src/OpenColorIO/fileformats/FileFormatIridasLook.cpp b/src/OpenColorIO/fileformats/FileFormatIridasLook.cpp index e2c30cbf5f..d5f164a588 100755 --- a/src/OpenColorIO/fileformats/FileFormatIridasLook.cpp +++ b/src/OpenColorIO/fileformats/FileFormatIridasLook.cpp @@ -416,7 +416,7 @@ class XMLParserHelper if (pImpl->m_size) { std::string size_raw = std::string(s, len); - std::string size_clean = pystring::strip(size_raw, "'\" "); // strip quotes and space + std::string size_clean = StringUtils::Trim(size_raw, "'\" "); // strip quotes and space long int size_3d{}; diff --git a/src/utils/StringUtils.h b/src/utils/StringUtils.h index 25600a2760..d1ee19fefa 100644 --- a/src/utils/StringUtils.h +++ b/src/utils/StringUtils.h @@ -110,6 +110,14 @@ inline bool StartsWith(const std::string& str, char prefix) } // Starting from the left, trim the character. +inline std::string LeftTrim(std::string str, const std::string & prefix) +{ + size_t first_good_char = str.find_first_not_of(prefix); + if (first_good_char == std::string::npos) { return str; } + str.erase(0, first_good_char); + return str; +} + inline std::string LeftTrim(std::string str, char c) { const auto it = std::find_if(str.begin(), str.end(), [&c](char ch) { return c!=ch; }); @@ -126,6 +134,14 @@ inline std::string LeftTrim(std::string str) } // Starting from the right, trim the character. +inline std::string RightTrim(std::string str, const std::string & suffix) +{ + size_t last_good_char = str.find_last_not_of(suffix); + if (last_good_char == std::string::npos) { return str; } + str.erase(last_good_char + 1); + return str; +} + inline std::string RightTrim(std::string str, char c) { const auto it = std::find_if(str.rbegin(), str.rend(), [&c](char ch) { return c!=ch; }); @@ -149,6 +165,11 @@ inline std::string Trim(std::string str, char c) } // From the left and right, trim all the space characters i.e. space, tabulation, etc. +inline std::string Trim(std::string str, const std::string & chars) +{ + return LeftTrim(RightTrim(str, chars), chars); +} + inline std::string Trim(std::string str) { return LeftTrim(RightTrim(str)); diff --git a/tests/utils/StringUtils_tests.cpp b/tests/utils/StringUtils_tests.cpp index ccf15c7f4f..bc05cfe739 100644 --- a/tests/utils/StringUtils_tests.cpp +++ b/tests/utils/StringUtils_tests.cpp @@ -40,16 +40,39 @@ OCIO_ADD_TEST(StringUtils, trim) const std::string str = StringUtils::LeftTrim(ref); OCIO_CHECK_EQUAL(str, "lOwEr 1*& ctfG \n\n "); } + { + consst std::string str = StringUtils::LeftTrim(ref, ' '); + OCIO_CHECK_EQUAL(str, "\t\n lOwEr 1*& ctfG \n\n "); + } + // Test to validate the former pystring::lstrip() behavior. + { + consst std::string str = StringUtils::LeftTrim(ref, " \t\n "); + OCIO_CHECK_EQUAL(str, "lOwEr 1*& ctfG \n\n "); + } { const std::string str = StringUtils::RightTrim(ref); OCIO_CHECK_EQUAL(str, " \t\n lOwEr 1*& ctfG"); } + { + consst std::string str = StringUtils::RightTrim(ref, ' '); + OCIO_CHECK_EQUAL(str, " \t\n lOwEr 1*& ctfG \n\n"); + } + // Test to validate the former pystring::rstrip() behavior. + { + consst std::string str = StringUtils::RightTrim(ref, " \n\n "); + OCIO_CHECK_EQUAL(str, " \t\n lOwEr 1*& ctfG"); + } { const std::string str = StringUtils::Trim(ref); OCIO_CHECK_EQUAL(str, "lOwEr 1*& ctfG"); } + // Test to validate the former pystring::strip() behavior. + { + const std::string str = StringUtils::Trim(ref, " "); + OCIO_CHECK_EQUAL(str, "\t\n lOwEr 1*& ctfG \n\n"); + } { // Test that no assert happens when the Trim argument is not an unsigned char (see issue #1874). diff --git a/vendor/openfx/OCIOUtils.cpp b/vendor/openfx/OCIOUtils.cpp index 1750b6e324..6fc37b5c18 100644 --- a/vendor/openfx/OCIOUtils.cpp +++ b/vendor/openfx/OCIOUtils.cpp @@ -8,8 +8,6 @@ namespace OCIO = OCIO_NAMESPACE; #include #include -#include - #include "ofxsLog.h" namespace @@ -67,7 +65,7 @@ std::string serializeContextStore(const ContextMap & contextMap) contextStoreRaw = os.str(); - return pystring::rstrip(contextStoreRaw, ";"); + return StringUtils::RightTrim(contextStoreRaw, ";"); } } // namespace From ae54e4381e7ac1bb71918dbf95f87bdbe3c14b67 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Fri, 15 May 2026 15:54:16 -0700 Subject: [PATCH 05/35] Add tests and Replace Signed-off-by: Mei Chu --- src/utils/StringUtils.h | 52 ++++++++++++++++++++++--------- tests/utils/StringUtils_tests.cpp | 8 ++--- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/utils/StringUtils.h b/src/utils/StringUtils.h index d1ee19fefa..3d152d169a 100644 --- a/src/utils/StringUtils.h +++ b/src/utils/StringUtils.h @@ -270,39 +270,52 @@ inline std::string::size_type ReverseFind(const std::string & subject, const std return subject.rfind(search); } -// In place replace the 'search' substring by the 'replace' string in 'str'. -inline bool ReplaceInPlace(std::string & subject, const std::string & search, const std::string & replace) +// In place replace the 'search' substring by the 'replace' string in 'subject'. +inline bool ReplaceInPlace(std::string & subject, const std::string & search, const std::string & replace, int count) { if (search.empty()) return false; bool changed = false; - size_t pos = 0; + size_t pos = 0; + int iter = 0; while ((pos = subject.find(search, pos)) != std::string::npos) { + if ( count > -1 && iter >= count ) { break; } subject.replace(pos, search.length(), replace); pos += replace.length(); changed = true; + ++iter; } return changed; } -// Replace the 'search' substring by the 'replace' string in 'str'. -inline std::string Replace(const std::string & subject, const std::string & search, const std::string & replace) +inline bool ReplaceInPlace(std::string & subject, const std::string & search, const std::string & replace) +{ + return ReplaceInPlace(subject, search, replace, -1); +} + +// Replace the 'search' substring by the 'replace' string in 'subject'. +inline std::string Replace(const std::string & subject, const std::string & search, const std::string & replace, int count) { std::string str{subject}; - ReplaceInPlace(str, search, replace); + ReplaceInPlace(str, search, replace, count); return str; } +inline std::string Replace(const std::string & subject, const std::string & search, const std::string & replace) +{ + return Replace(subject, search, replace, -1); +} + // Check if the 'entry' is in the 'list' using a case insensitive comparison. inline bool Contain(const StringVec & list, const std::string & entry) { - const auto it = std::find_if(list.begin(), list.end(), - [entry](const std::string & ent) - { - return Compare(ent.c_str(), entry.c_str()); + const auto it = std::find_if(list.begin(), list.end(), + [entry](const std::string & ent) + { + return Compare(ent.c_str(), entry.c_str()); }); return it!=list.end(); } @@ -311,10 +324,10 @@ inline bool Contain(const StringVec & list, const std::string & entry) // It returns true if found. inline bool Remove(StringVec & list, const std::string & entry) { - const auto it = std::find_if(list.begin(), list.end(), - [entry](const std::string & ent) - { - return Compare(ent.c_str(), entry.c_str()); + const auto it = std::find_if(list.begin(), list.end(), + [entry](const std::string & ent) + { + return Compare(ent.c_str(), entry.c_str()); }); if (it!=list.end()) { @@ -325,6 +338,17 @@ inline bool Remove(StringVec & list, const std::string & entry) return false; } +inline std::string Multiply(const std::string & str, int n) +{ + // Early exits + if (n <= 0) return ""; + if (n == 1) return str; + + std::ostringstream os; + for(int i = 0; i < n; ++i) { os << str; } + return os.str(); +} + } // namespace StringUtils #endif // INCLUDED_STRINGUTILS_H diff --git a/tests/utils/StringUtils_tests.cpp b/tests/utils/StringUtils_tests.cpp index bc05cfe739..9a916bc118 100644 --- a/tests/utils/StringUtils_tests.cpp +++ b/tests/utils/StringUtils_tests.cpp @@ -41,12 +41,12 @@ OCIO_ADD_TEST(StringUtils, trim) OCIO_CHECK_EQUAL(str, "lOwEr 1*& ctfG \n\n "); } { - consst std::string str = StringUtils::LeftTrim(ref, ' '); + const std::string str = StringUtils::LeftTrim(ref, ' '); OCIO_CHECK_EQUAL(str, "\t\n lOwEr 1*& ctfG \n\n "); } // Test to validate the former pystring::lstrip() behavior. { - consst std::string str = StringUtils::LeftTrim(ref, " \t\n "); + const std::string str = StringUtils::LeftTrim(ref, " \t\n "); OCIO_CHECK_EQUAL(str, "lOwEr 1*& ctfG \n\n "); } @@ -55,12 +55,12 @@ OCIO_ADD_TEST(StringUtils, trim) OCIO_CHECK_EQUAL(str, " \t\n lOwEr 1*& ctfG"); } { - consst std::string str = StringUtils::RightTrim(ref, ' '); + const std::string str = StringUtils::RightTrim(ref, ' '); OCIO_CHECK_EQUAL(str, " \t\n lOwEr 1*& ctfG \n\n"); } // Test to validate the former pystring::rstrip() behavior. { - consst std::string str = StringUtils::RightTrim(ref, " \n\n "); + const std::string str = StringUtils::RightTrim(ref, " \n\n "); OCIO_CHECK_EQUAL(str, " \t\n lOwEr 1*& ctfG"); } From 25b9d9891378e4c1d4c91b40a6c56244c0fec0e1 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Fri, 15 May 2026 16:31:13 -0700 Subject: [PATCH 06/35] Add more Replace tests. Signed-off-by: Mei Chu --- src/utils/StringUtils.h | 7 +++++-- tests/utils/StringUtils_tests.cpp | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/utils/StringUtils.h b/src/utils/StringUtils.h index 3d152d169a..c3f78ce627 100644 --- a/src/utils/StringUtils.h +++ b/src/utils/StringUtils.h @@ -270,7 +270,7 @@ inline std::string::size_type ReverseFind(const std::string & subject, const std return subject.rfind(search); } -// In place replace the 'search' substring by the 'replace' string in 'subject'. +// In place replace the 'search' substring by the 'replace' string in 'subject'. Limited by 'count'. inline bool ReplaceInPlace(std::string & subject, const std::string & search, const std::string & replace, int count) { if (search.empty()) return false; @@ -291,12 +291,13 @@ inline bool ReplaceInPlace(std::string & subject, const std::string & search, co return changed; } +// In place replace the 'search' substring by the 'replace' string in 'subject'. inline bool ReplaceInPlace(std::string & subject, const std::string & search, const std::string & replace) { return ReplaceInPlace(subject, search, replace, -1); } -// Replace the 'search' substring by the 'replace' string in 'subject'. +// Replace the 'search' substring by the 'replace' string in 'subject'. Limited by 'count'. inline std::string Replace(const std::string & subject, const std::string & search, const std::string & replace, int count) { std::string str{subject}; @@ -304,6 +305,7 @@ inline std::string Replace(const std::string & subject, const std::string & sear return str; } +// Replace the 'search' substring by the 'replace' string in 'subject'. inline std::string Replace(const std::string & subject, const std::string & search, const std::string & replace) { return Replace(subject, search, replace, -1); @@ -338,6 +340,7 @@ inline bool Remove(StringVec & list, const std::string & entry) return false; } +// Repeat the 'str' by the 'n' value. inline std::string Multiply(const std::string & str, int n) { // Early exits diff --git a/tests/utils/StringUtils_tests.cpp b/tests/utils/StringUtils_tests.cpp index 9a916bc118..7950d8afec 100644 --- a/tests/utils/StringUtils_tests.cpp +++ b/tests/utils/StringUtils_tests.cpp @@ -175,15 +175,30 @@ OCIO_ADD_TEST(StringUtils, replace) ref = StringUtils::Replace(ref, "345 1*", "ABC"); OCIO_CHECK_EQUAL(ref, "lO12ABC& ctfG"); + ref = StringUtils::Replace(ref, "&", "^^^", 0); + OCIO_CHECK_EQUAL(ref, "lO12ABC& ctfG") + + ref = StringUtils::Replace(ref, "&", "^^^", 1); + OCIO_CHECK_EQUAL(ref, "lO12ABC^^^ ctfG") + + ref = StringUtils::Replace(ref, "^", "&", 2); + OCIO_CHECK_EQUAL(ref, "lO12ABC&&^ ctfG") + // Test a not existing subbstring. ref = StringUtils::Replace(ref, "ZY", "TO"); OCIO_CHECK_EQUAL(ref, "lO12ABC& ctfG"); + ref = StringUtils::Replace(ref, "hEllo", "TO", 1); + OCIO_CHECK_EQUAL(ref, "lO12ABC& ctfG"); + OCIO_CHECK_ASSERT(StringUtils::ReplaceInPlace(ref, "ct", "TO")); OCIO_CHECK_EQUAL(ref, "lO12ABC& TOfG"); OCIO_CHECK_ASSERT(!StringUtils::ReplaceInPlace(ref, "12345", "TO")); OCIO_CHECK_EQUAL(ref, "lO12ABC& TOfG"); + + OCIO_CHECK_ASSERT(!StringUtils::ReplaceInPlace(ref, "hEllo", "TO", 1)); + OCIO_CHECK_EQUAL(ref, "lO12ABC& TOfG"); } OCIO_ADD_TEST(StringUtils, split_whitespaces) From 2a4ee20d9b50e2f2736472d55acc17c005583ee9 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Fri, 15 May 2026 16:39:37 -0700 Subject: [PATCH 07/35] Fix test Signed-off-by: Mei Chu --- tests/utils/StringUtils_tests.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/utils/StringUtils_tests.cpp b/tests/utils/StringUtils_tests.cpp index 7950d8afec..7b6e6754b8 100644 --- a/tests/utils/StringUtils_tests.cpp +++ b/tests/utils/StringUtils_tests.cpp @@ -176,13 +176,13 @@ OCIO_ADD_TEST(StringUtils, replace) OCIO_CHECK_EQUAL(ref, "lO12ABC& ctfG"); ref = StringUtils::Replace(ref, "&", "^^^", 0); - OCIO_CHECK_EQUAL(ref, "lO12ABC& ctfG") + OCIO_CHECK_EQUAL(ref, "lO12ABC& ctfG"); ref = StringUtils::Replace(ref, "&", "^^^", 1); - OCIO_CHECK_EQUAL(ref, "lO12ABC^^^ ctfG") + OCIO_CHECK_EQUAL(ref, "lO12ABC^^^ ctfG"); ref = StringUtils::Replace(ref, "^", "&", 2); - OCIO_CHECK_EQUAL(ref, "lO12ABC&&^ ctfG") + OCIO_CHECK_EQUAL(ref, "lO12ABC&&^ ctfG"); // Test a not existing subbstring. ref = StringUtils::Replace(ref, "ZY", "TO"); From 49aba82901994add0f7e834267fab834e056e890 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Fri, 15 May 2026 16:51:03 -0700 Subject: [PATCH 08/35] Fix test Signed-off-by: Mei Chu --- tests/utils/StringUtils_tests.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/utils/StringUtils_tests.cpp b/tests/utils/StringUtils_tests.cpp index 7b6e6754b8..35800d0578 100644 --- a/tests/utils/StringUtils_tests.cpp +++ b/tests/utils/StringUtils_tests.cpp @@ -186,19 +186,19 @@ OCIO_ADD_TEST(StringUtils, replace) // Test a not existing subbstring. ref = StringUtils::Replace(ref, "ZY", "TO"); - OCIO_CHECK_EQUAL(ref, "lO12ABC& ctfG"); + OCIO_CHECK_EQUAL(ref, "lO12ABC&&^ ctfG"); ref = StringUtils::Replace(ref, "hEllo", "TO", 1); - OCIO_CHECK_EQUAL(ref, "lO12ABC& ctfG"); + OCIO_CHECK_EQUAL(ref, "lO12ABC&&^ ctfG"); OCIO_CHECK_ASSERT(StringUtils::ReplaceInPlace(ref, "ct", "TO")); - OCIO_CHECK_EQUAL(ref, "lO12ABC& TOfG"); + OCIO_CHECK_EQUAL(ref, "lO12ABC&&^ ctfG"); OCIO_CHECK_ASSERT(!StringUtils::ReplaceInPlace(ref, "12345", "TO")); - OCIO_CHECK_EQUAL(ref, "lO12ABC& TOfG"); + OCIO_CHECK_EQUAL(ref, "lO12ABC&&^ ctfG"); OCIO_CHECK_ASSERT(!StringUtils::ReplaceInPlace(ref, "hEllo", "TO", 1)); - OCIO_CHECK_EQUAL(ref, "lO12ABC& TOfG"); + OCIO_CHECK_EQUAL(ref, "lO12ABC&&^ ctfG"); } OCIO_ADD_TEST(StringUtils, split_whitespaces) From 3c293d3a966510b64c20358ff45dc98cf3e87a8f Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Fri, 15 May 2026 17:04:15 -0700 Subject: [PATCH 09/35] Fix replace test Signed-off-by: Mei Chu --- tests/utils/StringUtils_tests.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/tests/utils/StringUtils_tests.cpp b/tests/utils/StringUtils_tests.cpp index 35800d0578..13205f4249 100644 --- a/tests/utils/StringUtils_tests.cpp +++ b/tests/utils/StringUtils_tests.cpp @@ -169,6 +169,7 @@ OCIO_ADD_TEST(StringUtils, replace) { std::string ref{"lOwEr 1*& ctfG"}; + // Test Replace. ref = StringUtils::Replace(ref, "wEr", "12345"); OCIO_CHECK_EQUAL(ref, "lO12345 1*& ctfG"); @@ -184,21 +185,32 @@ OCIO_ADD_TEST(StringUtils, replace) ref = StringUtils::Replace(ref, "^", "&", 2); OCIO_CHECK_EQUAL(ref, "lO12ABC&&^ ctfG"); - // Test a not existing subbstring. + // Test Replace with non-existing subbstring. ref = StringUtils::Replace(ref, "ZY", "TO"); OCIO_CHECK_EQUAL(ref, "lO12ABC&&^ ctfG"); ref = StringUtils::Replace(ref, "hEllo", "TO", 1); OCIO_CHECK_EQUAL(ref, "lO12ABC&&^ ctfG"); + // Test ReplaceInPlace. OCIO_CHECK_ASSERT(StringUtils::ReplaceInPlace(ref, "ct", "TO")); - OCIO_CHECK_EQUAL(ref, "lO12ABC&&^ ctfG"); + OCIO_CHECK_EQUAL(ref, "lO12ABC&&^ TOfG"); + + OCIO_CHECK_ASSERT(StringUtils::ReplaceInPlace(ref, "ct", "TO", 0)); + OCIO_CHECK_EQUAL(ref, "lO12ABC&&^ TOfG"); + + OCIO_CHECK_ASSERT(!StringUtils::ReplaceInPlace(ref, "O", "P", 1)); + OCIO_CHECK_EQUAL(ref, "lP12ABC&&^ TOfG"); + // Test ReplaceInPlace with non-existing subbstring. OCIO_CHECK_ASSERT(!StringUtils::ReplaceInPlace(ref, "12345", "TO")); - OCIO_CHECK_EQUAL(ref, "lO12ABC&&^ ctfG"); + OCIO_CHECK_EQUAL(ref, "lP12ABC&&^ TOfG"); + + OCIO_CHECK_ASSERT(!StringUtils::ReplaceInPlace(ref, "hEllo", "TO", 0)); + OCIO_CHECK_EQUAL(ref, "lP12ABC&&^ TOfG"); OCIO_CHECK_ASSERT(!StringUtils::ReplaceInPlace(ref, "hEllo", "TO", 1)); - OCIO_CHECK_EQUAL(ref, "lO12ABC&&^ ctfG"); + OCIO_CHECK_EQUAL(ref, "lP12ABC&&^ TOfG"); } OCIO_ADD_TEST(StringUtils, split_whitespaces) From f44057707417abf8e7a1a8ae0d3f307498af68ff Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Fri, 15 May 2026 17:19:21 -0700 Subject: [PATCH 10/35] Fix replace test Signed-off-by: Mei Chu --- tests/utils/StringUtils_tests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/utils/StringUtils_tests.cpp b/tests/utils/StringUtils_tests.cpp index 13205f4249..8552a67c3a 100644 --- a/tests/utils/StringUtils_tests.cpp +++ b/tests/utils/StringUtils_tests.cpp @@ -196,10 +196,10 @@ OCIO_ADD_TEST(StringUtils, replace) OCIO_CHECK_ASSERT(StringUtils::ReplaceInPlace(ref, "ct", "TO")); OCIO_CHECK_EQUAL(ref, "lO12ABC&&^ TOfG"); - OCIO_CHECK_ASSERT(StringUtils::ReplaceInPlace(ref, "ct", "TO", 0)); + OCIO_CHECK_ASSERT(StringUtils::ReplaceInPlace(ref, "TO", "ct", 0)); OCIO_CHECK_EQUAL(ref, "lO12ABC&&^ TOfG"); - OCIO_CHECK_ASSERT(!StringUtils::ReplaceInPlace(ref, "O", "P", 1)); + OCIO_CHECK_ASSERT(StringUtils::ReplaceInPlace(ref, "O", "P", 1)); OCIO_CHECK_EQUAL(ref, "lP12ABC&&^ TOfG"); // Test ReplaceInPlace with non-existing subbstring. From 08dd68c742f3626a66025608ebb537fc04a008ae Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Fri, 15 May 2026 17:29:50 -0700 Subject: [PATCH 11/35] More replace test fix Signed-off-by: Mei Chu --- tests/utils/StringUtils_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/utils/StringUtils_tests.cpp b/tests/utils/StringUtils_tests.cpp index 8552a67c3a..15b9efe9b9 100644 --- a/tests/utils/StringUtils_tests.cpp +++ b/tests/utils/StringUtils_tests.cpp @@ -196,7 +196,7 @@ OCIO_ADD_TEST(StringUtils, replace) OCIO_CHECK_ASSERT(StringUtils::ReplaceInPlace(ref, "ct", "TO")); OCIO_CHECK_EQUAL(ref, "lO12ABC&&^ TOfG"); - OCIO_CHECK_ASSERT(StringUtils::ReplaceInPlace(ref, "TO", "ct", 0)); + OCIO_CHECK_ASSERT(!StringUtils::ReplaceInPlace(ref, "TO", "ct", 0)); OCIO_CHECK_EQUAL(ref, "lO12ABC&&^ TOfG"); OCIO_CHECK_ASSERT(StringUtils::ReplaceInPlace(ref, "O", "P", 1)); From 17bbc96c3587dcfbcbfe20f8b282b93266556e2c Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Sun, 17 May 2026 01:17:11 -0700 Subject: [PATCH 12/35] Replace pystring::replace in FileTransform Signed-off-by: Mei Chu --- src/OpenColorIO/transforms/FileTransform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenColorIO/transforms/FileTransform.cpp b/src/OpenColorIO/transforms/FileTransform.cpp index 6fd1549d61..d9c7e33720 100755 --- a/src/OpenColorIO/transforms/FileTransform.cpp +++ b/src/OpenColorIO/transforms/FileTransform.cpp @@ -613,7 +613,7 @@ void LoadFileUncached(FileFormat * & returnFormat, std::string root, extension; pystring::os::path::splitext(root, extension, filepath); // remove the leading '.' - extension = pystring::replace(extension,".","",1); + extension = StringUtils::Replace(extension, "." , "", 1); FormatRegistry & formatRegistry = FormatRegistry::GetInstance(); From 05eb65eb39958fd44e8ec8f860d10297541c3c03 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Sun, 17 May 2026 01:29:57 -0700 Subject: [PATCH 13/35] Test changed cicd Signed-off-by: Mei Chu --- .github/workflows/ci_workflow.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci_workflow.yml b/.github/workflows/ci_workflow.yml index 68d02377ae..3e4b4658d1 100644 --- a/.github/workflows/ci_workflow.yml +++ b/.github/workflows/ci_workflow.yml @@ -61,7 +61,8 @@ jobs: strategy: fail-fast: false matrix: - build: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + # build: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + build: [1, 2, 4, 5, 7, 8, 10, 11, 12] include: # ------------------------------------------------------------------- # VFX CY2026 (Python 3.13) From 5898c57d06c4b5ff72c46125cc11dbd71c400e3d Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Sun, 17 May 2026 01:33:00 -0700 Subject: [PATCH 14/35] Update CICD test Signed-off-by: Mei Chu --- .github/workflows/ci_workflow.yml | 54 +++++++++++++++---------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/.github/workflows/ci_workflow.yml b/.github/workflows/ci_workflow.yml index 3e4b4658d1..e8f769e630 100644 --- a/.github/workflows/ci_workflow.yml +++ b/.github/workflows/ci_workflow.yml @@ -110,20 +110,19 @@ jobs: # ------------------------------------------------------------------- # VFX CY2025 (Python 3.11) # ------------------------------------------------------------------- - - build: 9 - build-type: Debug - build-shared: 'ON' - build-docs: 'OFF' - build-openfx: 'ON' - use-simd: 'ON' - use-oiio: 'ON' - aswf-ocio-version: 2.4.2 - cxx-standard: 20 - cxx-compiler: clang++ - cc-compiler: clang - compiler-desc: Clang - vfx-cy: 2025 - install-ext-packages: MISSING + # - build: 9 + # build-type: Debug + # build-shared: 'ON' + # build-docs: 'OFF' + # build-openfx: 'ON' + # use-simd: 'ON' + # use-oiio: 'ON' + # cxx-standard: 20 + # cxx-compiler: clang++ + # cc-compiler: clang + # compiler-desc: Clang + # vfx-cy: 2025 + # install-ext-packages: MISSING - build: 8 build-type: Release build-shared: 'ON' @@ -153,20 +152,19 @@ jobs: # ------------------------------------------------------------------- # VFX CY2024 (Python 3.11) # ------------------------------------------------------------------- - - build: 6 - build-type: Debug - build-shared: 'ON' - build-docs: 'OFF' - build-openfx: 'ON' - use-simd: 'ON' - use-oiio: 'ON' - aswf-ocio-version: 2.3.2 - cxx-standard: 20 - cxx-compiler: clang++ - cc-compiler: clang - compiler-desc: Clang - vfx-cy: 2024 - install-ext-packages: MISSING + # - build: 6 + # build-type: Debug + # build-shared: 'ON' + # build-docs: 'OFF' + # build-openfx: 'ON' + # use-simd: 'ON' + # use-oiio: 'ON' + # cxx-standard: 20 + # cxx-compiler: clang++ + # cc-compiler: clang + # compiler-desc: Clang + # vfx-cy: 2024 + # install-ext-packages: MISSING - build: 5 build-type: Release build-shared: 'ON' From abaa942e17fa16506d54fd1ae6ba3a623bb8ab12 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Mon, 18 May 2026 18:30:04 -0700 Subject: [PATCH 15/35] Integrate StringUtils::Multiply Signed-off-by: Mei Chu --- src/OpenColorIO/Op.cpp | 5 ++--- tests/utils/StringUtils_tests.cpp | 13 +++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/OpenColorIO/Op.cpp b/src/OpenColorIO/Op.cpp index 7e95baecfc..88e76f5bad 100755 --- a/src/OpenColorIO/Op.cpp +++ b/src/OpenColorIO/Op.cpp @@ -4,8 +4,6 @@ #include #include -#include - #include #include "Logging.h" @@ -23,6 +21,7 @@ #include "ops/lut1d/Lut1DOp.h" #include "ops/lut3d/Lut3DOp.h" #include "ops/range/RangeOp.h" +#include "utils/StringUtils.h" namespace OCIO_NAMESPACE { @@ -478,7 +477,7 @@ std::string SerializeOpVec(const OpRcPtrVec & ops, int indent) { const OpRcPtr & op = ops[idx]; - oss << pystring::mul(" ", indent); + oss << StringUtils::Multiply(" ", indent); oss << "Op " << idx << ": " << *op << " "; oss << op->getCacheID(); diff --git a/tests/utils/StringUtils_tests.cpp b/tests/utils/StringUtils_tests.cpp index 15b9efe9b9..4751e654d7 100644 --- a/tests/utils/StringUtils_tests.cpp +++ b/tests/utils/StringUtils_tests.cpp @@ -275,3 +275,16 @@ OCIO_ADD_TEST(StringUtils, remove_contain) OCIO_CHECK_ASSERT(!StringUtils::Contain(values, "2")); } } + +OCIO_ADD_TEST(StringUtils, multiply) +{ + constexpr char ref[]{"10.0 9. 1 er\t1e-5f"}; + + OCIO_CHECK_EQUAL(StringUtils::Multiply(ref, 0), ""); + OCIO_CHECK_EQUAL(StringUtils::Multiply(ref, 1), "10.0 9. 1 er\t1e-5f"); + OCIO_CHECK_EQUAL(StringUtils::Multiply(ref, 2), "10.0 9. 1 er\t1e-5f10.0 9. 1 er\t1e-5f"); + + OCIO_CHECK_EQUAL(StringUtils::Multiply(" ", 0), ""); + OCIO_CHECK_EQUAL(StringUtils::Multiply(" ", 1), " "); + OCIO_CHECK_EQUAL(StringUtils::Multiply(" ", 2), " "); +} From 86834869d3e9322a35d817f78ab6b8fef851a589 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Mon, 18 May 2026 19:07:35 -0700 Subject: [PATCH 16/35] Small syntax update. Signed-off-by: Mei Chu --- src/OpenColorIO/transforms/FileTransform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenColorIO/transforms/FileTransform.cpp b/src/OpenColorIO/transforms/FileTransform.cpp index d9c7e33720..4c8635cd22 100755 --- a/src/OpenColorIO/transforms/FileTransform.cpp +++ b/src/OpenColorIO/transforms/FileTransform.cpp @@ -613,7 +613,7 @@ void LoadFileUncached(FileFormat * & returnFormat, std::string root, extension; pystring::os::path::splitext(root, extension, filepath); // remove the leading '.' - extension = StringUtils::Replace(extension, "." , "", 1); + extension = StringUtils::Replace(extension, ".", "", 1); FormatRegistry & formatRegistry = FormatRegistry::GetInstance(); From 067ec233a92eca3aef46fc0594389c3ff4be98f3 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Wed, 20 May 2026 20:13:09 -0700 Subject: [PATCH 17/35] Revert workflow.yml to get ready for real fix. Signed-off-by: Mei Chu --- .github/workflows/ci_workflow.yml | 57 +++++++++++++++---------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/.github/workflows/ci_workflow.yml b/.github/workflows/ci_workflow.yml index e8f769e630..676061d949 100644 --- a/.github/workflows/ci_workflow.yml +++ b/.github/workflows/ci_workflow.yml @@ -61,8 +61,7 @@ jobs: strategy: fail-fast: false matrix: - # build: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] - build: [1, 2, 4, 5, 7, 8, 10, 11, 12] + build: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] include: # ------------------------------------------------------------------- # VFX CY2026 (Python 3.13) @@ -110,19 +109,19 @@ jobs: # ------------------------------------------------------------------- # VFX CY2025 (Python 3.11) # ------------------------------------------------------------------- - # - build: 9 - # build-type: Debug - # build-shared: 'ON' - # build-docs: 'OFF' - # build-openfx: 'ON' - # use-simd: 'ON' - # use-oiio: 'ON' - # cxx-standard: 20 - # cxx-compiler: clang++ - # cc-compiler: clang - # compiler-desc: Clang - # vfx-cy: 2025 - # install-ext-packages: MISSING + - build: 9 + build-type: Debug + build-shared: 'ON' + build-docs: 'OFF' + build-openfx: 'ON' + use-simd: 'ON' + use-oiio: 'ON' + cxx-standard: 20 + cxx-compiler: clang++ + cc-compiler: clang + compiler-desc: Clang + vfx-cy: 2025 + install-ext-packages: MISSING - build: 8 build-type: Release build-shared: 'ON' @@ -152,19 +151,19 @@ jobs: # ------------------------------------------------------------------- # VFX CY2024 (Python 3.11) # ------------------------------------------------------------------- - # - build: 6 - # build-type: Debug - # build-shared: 'ON' - # build-docs: 'OFF' - # build-openfx: 'ON' - # use-simd: 'ON' - # use-oiio: 'ON' - # cxx-standard: 20 - # cxx-compiler: clang++ - # cc-compiler: clang - # compiler-desc: Clang - # vfx-cy: 2024 - # install-ext-packages: MISSING + - build: 6 + build-type: Debug + build-shared: 'ON' + build-docs: 'OFF' + build-openfx: 'ON' + use-simd: 'ON' + use-oiio: 'ON' + cxx-standard: 20 + cxx-compiler: clang++ + cc-compiler: clang + compiler-desc: Clang + vfx-cy: 2024 + install-ext-packages: MISSING - build: 5 build-type: Release build-shared: 'ON' @@ -742,4 +741,4 @@ jobs: export PATH=../../../_install/bin:$PATH ./${{ matrix.build-type }}/consumer shell: bash - working-directory: _build/tests/cmake-consumer-dist + working-directory: _build/tests/cmake-consumer-dist \ No newline at end of file From eeb90bba07310a28a5db70dfd19eae4efa244af0 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Sun, 17 May 2026 01:29:57 -0700 Subject: [PATCH 18/35] Test changed cicd Signed-off-by: Mei Chu --- .github/workflows/ci_workflow.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci_workflow.yml b/.github/workflows/ci_workflow.yml index 676061d949..9b0770a8c4 100644 --- a/.github/workflows/ci_workflow.yml +++ b/.github/workflows/ci_workflow.yml @@ -61,7 +61,8 @@ jobs: strategy: fail-fast: false matrix: - build: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + # build: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + build: [1, 2, 4, 5, 7, 8, 10, 11, 12] include: # ------------------------------------------------------------------- # VFX CY2026 (Python 3.13) From 1151a3c5077907c576b705eb03ca0564d866d974 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Sun, 17 May 2026 01:33:00 -0700 Subject: [PATCH 19/35] Update CICD test Signed-off-by: Mei Chu --- .github/workflows/ci_workflow.yml | 52 +++++++++++++++---------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/.github/workflows/ci_workflow.yml b/.github/workflows/ci_workflow.yml index 9b0770a8c4..4b40d0b0f2 100644 --- a/.github/workflows/ci_workflow.yml +++ b/.github/workflows/ci_workflow.yml @@ -110,19 +110,19 @@ jobs: # ------------------------------------------------------------------- # VFX CY2025 (Python 3.11) # ------------------------------------------------------------------- - - build: 9 - build-type: Debug - build-shared: 'ON' - build-docs: 'OFF' - build-openfx: 'ON' - use-simd: 'ON' - use-oiio: 'ON' - cxx-standard: 20 - cxx-compiler: clang++ - cc-compiler: clang - compiler-desc: Clang - vfx-cy: 2025 - install-ext-packages: MISSING + # - build: 9 + # build-type: Debug + # build-shared: 'ON' + # build-docs: 'OFF' + # build-openfx: 'ON' + # use-simd: 'ON' + # use-oiio: 'ON' + # cxx-standard: 20 + # cxx-compiler: clang++ + # cc-compiler: clang + # compiler-desc: Clang + # vfx-cy: 2025 + # install-ext-packages: MISSING - build: 8 build-type: Release build-shared: 'ON' @@ -152,19 +152,19 @@ jobs: # ------------------------------------------------------------------- # VFX CY2024 (Python 3.11) # ------------------------------------------------------------------- - - build: 6 - build-type: Debug - build-shared: 'ON' - build-docs: 'OFF' - build-openfx: 'ON' - use-simd: 'ON' - use-oiio: 'ON' - cxx-standard: 20 - cxx-compiler: clang++ - cc-compiler: clang - compiler-desc: Clang - vfx-cy: 2024 - install-ext-packages: MISSING + # - build: 6 + # build-type: Debug + # build-shared: 'ON' + # build-docs: 'OFF' + # build-openfx: 'ON' + # use-simd: 'ON' + # use-oiio: 'ON' + # cxx-standard: 20 + # cxx-compiler: clang++ + # cc-compiler: clang + # compiler-desc: Clang + # vfx-cy: 2024 + # install-ext-packages: MISSING - build: 5 build-type: Release build-shared: 'ON' From 5b9a537ff11e72fc4ee6f67c2faa3fcbef96f9bc Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Wed, 20 May 2026 20:13:09 -0700 Subject: [PATCH 20/35] Revert workflow.yml to get ready for real fix. Signed-off-by: Mei Chu --- .github/workflows/ci_workflow.yml | 55 +++++++++++++++---------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/.github/workflows/ci_workflow.yml b/.github/workflows/ci_workflow.yml index 4b40d0b0f2..676061d949 100644 --- a/.github/workflows/ci_workflow.yml +++ b/.github/workflows/ci_workflow.yml @@ -61,8 +61,7 @@ jobs: strategy: fail-fast: false matrix: - # build: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] - build: [1, 2, 4, 5, 7, 8, 10, 11, 12] + build: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] include: # ------------------------------------------------------------------- # VFX CY2026 (Python 3.13) @@ -110,19 +109,19 @@ jobs: # ------------------------------------------------------------------- # VFX CY2025 (Python 3.11) # ------------------------------------------------------------------- - # - build: 9 - # build-type: Debug - # build-shared: 'ON' - # build-docs: 'OFF' - # build-openfx: 'ON' - # use-simd: 'ON' - # use-oiio: 'ON' - # cxx-standard: 20 - # cxx-compiler: clang++ - # cc-compiler: clang - # compiler-desc: Clang - # vfx-cy: 2025 - # install-ext-packages: MISSING + - build: 9 + build-type: Debug + build-shared: 'ON' + build-docs: 'OFF' + build-openfx: 'ON' + use-simd: 'ON' + use-oiio: 'ON' + cxx-standard: 20 + cxx-compiler: clang++ + cc-compiler: clang + compiler-desc: Clang + vfx-cy: 2025 + install-ext-packages: MISSING - build: 8 build-type: Release build-shared: 'ON' @@ -152,19 +151,19 @@ jobs: # ------------------------------------------------------------------- # VFX CY2024 (Python 3.11) # ------------------------------------------------------------------- - # - build: 6 - # build-type: Debug - # build-shared: 'ON' - # build-docs: 'OFF' - # build-openfx: 'ON' - # use-simd: 'ON' - # use-oiio: 'ON' - # cxx-standard: 20 - # cxx-compiler: clang++ - # cc-compiler: clang - # compiler-desc: Clang - # vfx-cy: 2024 - # install-ext-packages: MISSING + - build: 6 + build-type: Debug + build-shared: 'ON' + build-docs: 'OFF' + build-openfx: 'ON' + use-simd: 'ON' + use-oiio: 'ON' + cxx-standard: 20 + cxx-compiler: clang++ + cc-compiler: clang + compiler-desc: Clang + vfx-cy: 2024 + install-ext-packages: MISSING - build: 5 build-type: Release build-shared: 'ON' From cf3df7c03fe4153ba45d2c1a86ca74b6acc80539 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Wed, 3 Jun 2026 22:49:03 -0700 Subject: [PATCH 21/35] Address notes to use size_t instead of int for count parameter. Signed-off-by: Mei Chu --- src/utils/StringUtils.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/utils/StringUtils.h b/src/utils/StringUtils.h index c3f78ce627..a18d3a4ba8 100644 --- a/src/utils/StringUtils.h +++ b/src/utils/StringUtils.h @@ -271,17 +271,17 @@ inline std::string::size_type ReverseFind(const std::string & subject, const std } // In place replace the 'search' substring by the 'replace' string in 'subject'. Limited by 'count'. -inline bool ReplaceInPlace(std::string & subject, const std::string & search, const std::string & replace, int count) +inline bool ReplaceInPlace(std::string & subject, const std::string & search, const std::string & replace, size_t count) { - if (search.empty()) return false; + if (search.empty() || count == 0) { return false; } bool changed = false; size_t pos = 0; - int iter = 0; + size_t iter = 0; while ((pos = subject.find(search, pos)) != std::string::npos) { - if ( count > -1 && iter >= count ) { break; } + if (iter >= count) { break; } subject.replace(pos, search.length(), replace); pos += replace.length(); changed = true; @@ -294,11 +294,11 @@ inline bool ReplaceInPlace(std::string & subject, const std::string & search, co // In place replace the 'search' substring by the 'replace' string in 'subject'. inline bool ReplaceInPlace(std::string & subject, const std::string & search, const std::string & replace) { - return ReplaceInPlace(subject, search, replace, -1); + return ReplaceInPlace(subject, search, replace, std::string::npos); } // Replace the 'search' substring by the 'replace' string in 'subject'. Limited by 'count'. -inline std::string Replace(const std::string & subject, const std::string & search, const std::string & replace, int count) +inline std::string Replace(const std::string & subject, const std::string & search, const std::string & replace, size_t count) { std::string str{subject}; ReplaceInPlace(str, search, replace, count); @@ -308,7 +308,7 @@ inline std::string Replace(const std::string & subject, const std::string & sear // Replace the 'search' substring by the 'replace' string in 'subject'. inline std::string Replace(const std::string & subject, const std::string & search, const std::string & replace) { - return Replace(subject, search, replace, -1); + return Replace(subject, search, replace, std::string::npos); } // Check if the 'entry' is in the 'list' using a case insensitive comparison. @@ -341,14 +341,14 @@ inline bool Remove(StringVec & list, const std::string & entry) } // Repeat the 'str' by the 'n' value. -inline std::string Multiply(const std::string & str, int n) +inline std::string Multiply(const std::string & str, size_t n) { // Early exits if (n <= 0) return ""; if (n == 1) return str; std::ostringstream os; - for(int i = 0; i < n; ++i) { os << str; } + for(size_t i = 0; i < n; ++i) { os << str; } return os.str(); } From 34090ea0cc70eef42ff9fe1cb169e46f98c15998 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Wed, 3 Jun 2026 23:41:17 -0700 Subject: [PATCH 22/35] Add Repeat() function to prepare to replace Multiply(). Signed-off-by: Mei Chu --- src/utils/StringUtils.h | 36 +++++++++++++++++++++++++++---- tests/utils/StringUtils_tests.cpp | 13 +++++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/utils/StringUtils.h b/src/utils/StringUtils.h index a18d3a4ba8..47f9562e55 100644 --- a/src/utils/StringUtils.h +++ b/src/utils/StringUtils.h @@ -340,18 +340,46 @@ inline bool Remove(StringVec & list, const std::string & entry) return false; } -// Repeat the 'str' by the 'n' value. +// Multiply the 'str' by the 'n' value. inline std::string Multiply(const std::string & str, size_t n) { - // Early exits - if (n <= 0) return ""; - if (n == 1) return str; + // Early exit and match pystring::mul behaviour. + if (n == 0) { return ""; } + if (n == 1) { return str; } std::ostringstream os; for(size_t i = 0; i < n; ++i) { os << str; } return os.str(); } +// Repeat the 'str' by the 'n' value. +inline std::string Repeat(const std::string & str, size_t n) +{ + // Early exit and match pystring::mul behaviour. + if (n == 0) { return {}; } + if (n == 1) { return str; } + const auto str_size = str.size(); + + // Check for overflow if n is greater than maximum repeatable amount via string max_size. + // New behaviour compared to pystring::mul and StringUtil::Multiply. + // limits.h says size_t max size is 18446744073709551615. + if (n > str.max_size() / str_size) { return {}; } + + std::string result; + result.reserve(str_size * n); + result = str; + size_t current = 1; + while (current * 2 <= n) { + result += result; + current *= 2; + } + const auto remaining = n - current; + if (remaining > 0) { + result += std::string_view(result.data(), str_size * remaining); + } + return result; +} + } // namespace StringUtils #endif // INCLUDED_STRINGUTILS_H diff --git a/tests/utils/StringUtils_tests.cpp b/tests/utils/StringUtils_tests.cpp index 4751e654d7..a1ee2e1fba 100644 --- a/tests/utils/StringUtils_tests.cpp +++ b/tests/utils/StringUtils_tests.cpp @@ -288,3 +288,16 @@ OCIO_ADD_TEST(StringUtils, multiply) OCIO_CHECK_EQUAL(StringUtils::Multiply(" ", 1), " "); OCIO_CHECK_EQUAL(StringUtils::Multiply(" ", 2), " "); } + +OCIO_ADD_TEST(StringUtils, repeat) +{ + constexpr char ref[]{"10.0 9. 1 er\t1e-5f"}; + + OCIO_CHECK_EQUAL(StringUtils::Repeat(ref, 0), ""); + OCIO_CHECK_EQUAL(StringUtils::Repeat(ref, 1), "10.0 9. 1 er\t1e-5f"); + OCIO_CHECK_EQUAL(StringUtils::Repeat(ref, 2), "10.0 9. 1 er\t1e-5f10.0 9. 1 er\t1e-5f"); + + OCIO_CHECK_EQUAL(StringUtils::Repeat(" ", 0), ""); + OCIO_CHECK_EQUAL(StringUtils::Repeat(" ", 1), " "); + OCIO_CHECK_EQUAL(StringUtils::Repeat(" ", 2), " "); +} \ No newline at end of file From 7e2a767bbc287308d4aba3041c6dbdebdffe74a1 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Wed, 3 Jun 2026 23:56:15 -0700 Subject: [PATCH 23/35] Use Repeat() in Op::SerializeOpVec. Add more tests Signed-off-by: Mei Chu --- src/OpenColorIO/Op.cpp | 2 +- src/utils/StringUtils.h | 2 +- tests/utils/StringUtils_tests.cpp | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/OpenColorIO/Op.cpp b/src/OpenColorIO/Op.cpp index 88e76f5bad..4975b68ec7 100755 --- a/src/OpenColorIO/Op.cpp +++ b/src/OpenColorIO/Op.cpp @@ -477,7 +477,7 @@ std::string SerializeOpVec(const OpRcPtrVec & ops, int indent) { const OpRcPtr & op = ops[idx]; - oss << StringUtils::Multiply(" ", indent); + oss << StringUtils::Repeat(" ", indent); oss << "Op " << idx << ": " << *op << " "; oss << op->getCacheID(); diff --git a/src/utils/StringUtils.h b/src/utils/StringUtils.h index 47f9562e55..daa5442669 100644 --- a/src/utils/StringUtils.h +++ b/src/utils/StringUtils.h @@ -360,7 +360,7 @@ inline std::string Repeat(const std::string & str, size_t n) if (n == 1) { return str; } const auto str_size = str.size(); - // Check for overflow if n is greater than maximum repeatable amount via string max_size. + // Check for overflow if n is greater than maximum allowable repeat with string max_size. // New behaviour compared to pystring::mul and StringUtil::Multiply. // limits.h says size_t max size is 18446744073709551615. if (n > str.max_size() / str_size) { return {}; } diff --git a/tests/utils/StringUtils_tests.cpp b/tests/utils/StringUtils_tests.cpp index a1ee2e1fba..eb2e5d5f24 100644 --- a/tests/utils/StringUtils_tests.cpp +++ b/tests/utils/StringUtils_tests.cpp @@ -296,6 +296,7 @@ OCIO_ADD_TEST(StringUtils, repeat) OCIO_CHECK_EQUAL(StringUtils::Repeat(ref, 0), ""); OCIO_CHECK_EQUAL(StringUtils::Repeat(ref, 1), "10.0 9. 1 er\t1e-5f"); OCIO_CHECK_EQUAL(StringUtils::Repeat(ref, 2), "10.0 9. 1 er\t1e-5f10.0 9. 1 er\t1e-5f"); + OCIO_CHECK_EQUAL(StringUtils::Repeat(ref, 18446744073709551615), ""); OCIO_CHECK_EQUAL(StringUtils::Repeat(" ", 0), ""); OCIO_CHECK_EQUAL(StringUtils::Repeat(" ", 1), " "); From c1ef162747c922255b797975cf32d870f581ce99 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Thu, 4 Jun 2026 00:05:53 -0700 Subject: [PATCH 24/35] Remove the limit test for Repeat. Signed-off-by: Mei Chu --- tests/utils/StringUtils_tests.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/utils/StringUtils_tests.cpp b/tests/utils/StringUtils_tests.cpp index eb2e5d5f24..a1ee2e1fba 100644 --- a/tests/utils/StringUtils_tests.cpp +++ b/tests/utils/StringUtils_tests.cpp @@ -296,7 +296,6 @@ OCIO_ADD_TEST(StringUtils, repeat) OCIO_CHECK_EQUAL(StringUtils::Repeat(ref, 0), ""); OCIO_CHECK_EQUAL(StringUtils::Repeat(ref, 1), "10.0 9. 1 er\t1e-5f"); OCIO_CHECK_EQUAL(StringUtils::Repeat(ref, 2), "10.0 9. 1 er\t1e-5f10.0 9. 1 er\t1e-5f"); - OCIO_CHECK_EQUAL(StringUtils::Repeat(ref, 18446744073709551615), ""); OCIO_CHECK_EQUAL(StringUtils::Repeat(" ", 0), ""); OCIO_CHECK_EQUAL(StringUtils::Repeat(" ", 1), " "); From 7356d30f908037e7ae7bac309c5e145c24d08d76 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Fri, 5 Jun 2026 22:24:02 -0700 Subject: [PATCH 25/35] Update Repeat and Multiply accordingly. Signed-off-by: Mei Chu --- src/utils/StringUtils.h | 9 ++++----- tests/cpu/ops/noop/NoOps_tests.cpp | 2 ++ tests/utils/StringUtils_tests.cpp | 10 +++++++++- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/utils/StringUtils.h b/src/utils/StringUtils.h index daa5442669..a790d7624b 100644 --- a/src/utils/StringUtils.h +++ b/src/utils/StringUtils.h @@ -347,6 +347,8 @@ inline std::string Multiply(const std::string & str, size_t n) if (n == 0) { return ""; } if (n == 1) { return str; } + if (str.empty()) { return ""; } + std::ostringstream os; for(size_t i = 0; i < n; ++i) { os << str; } return os.str(); @@ -358,12 +360,9 @@ inline std::string Repeat(const std::string & str, size_t n) // Early exit and match pystring::mul behaviour. if (n == 0) { return {}; } if (n == 1) { return str; } - const auto str_size = str.size(); - // Check for overflow if n is greater than maximum allowable repeat with string max_size. - // New behaviour compared to pystring::mul and StringUtil::Multiply. - // limits.h says size_t max size is 18446744073709551615. - if (n > str.max_size() / str_size) { return {}; } + if (str.empty()) { return {}; } + const auto str_size = str.size(); std::string result; result.reserve(str_size * n); diff --git a/tests/cpu/ops/noop/NoOps_tests.cpp b/tests/cpu/ops/noop/NoOps_tests.cpp index 9f23640ed5..3c3a3cb0fa 100644 --- a/tests/cpu/ops/noop/NoOps_tests.cpp +++ b/tests/cpu/ops/noop/NoOps_tests.cpp @@ -242,6 +242,8 @@ OCIO_ADD_TEST(NoOps, partition_gpu_ops) OCIO_CHECK_NO_THROW( AssertPartitionIntegrity(gpuPreOps, gpuLatticeOps, gpuPostOps) ); + std::cerr << "gpuPreOps" << std::endl; + std::cerr << SerializeOpVec(gpuPreOps, 4) << std::endl; /* std::cerr << "gpuPreOps" << std::endl; std::cerr << SerializeOpVec(gpuPreOps, 4) << std::endl; diff --git a/tests/utils/StringUtils_tests.cpp b/tests/utils/StringUtils_tests.cpp index a1ee2e1fba..26ca987b73 100644 --- a/tests/utils/StringUtils_tests.cpp +++ b/tests/utils/StringUtils_tests.cpp @@ -131,7 +131,7 @@ OCIO_ADD_TEST(StringUtils, split) // Something important to notice and preserve. { - // Note: StringUtils::Split() is mainly used to parse some string content enumerating + // Note: StringUtils::Split() is mainly used to parse some string content enumerating // a list of substrings (i.e. separator could be a space, comma, etc). In that use case, // a string like ",," must return three entries. Refer to 'looks' parsing for example. // However, StringUtils::SplitByLines() is mainly used to read some file content where @@ -287,6 +287,10 @@ OCIO_ADD_TEST(StringUtils, multiply) OCIO_CHECK_EQUAL(StringUtils::Multiply(" ", 0), ""); OCIO_CHECK_EQUAL(StringUtils::Multiply(" ", 1), " "); OCIO_CHECK_EQUAL(StringUtils::Multiply(" ", 2), " "); + + OCIO_CHECK_EQUAL(StringUtils::Multiply("", 0), ""); + OCIO_CHECK_EQUAL(StringUtils::Multiply("", 1), ""); + OCIO_CHECK_EQUAL(StringUtils::Multiply("", 2), ""); } OCIO_ADD_TEST(StringUtils, repeat) @@ -300,4 +304,8 @@ OCIO_ADD_TEST(StringUtils, repeat) OCIO_CHECK_EQUAL(StringUtils::Repeat(" ", 0), ""); OCIO_CHECK_EQUAL(StringUtils::Repeat(" ", 1), " "); OCIO_CHECK_EQUAL(StringUtils::Repeat(" ", 2), " "); + + OCIO_CHECK_EQUAL(StringUtils::Repeat("", 0), ""); + OCIO_CHECK_EQUAL(StringUtils::Repeat("", 1), ""); + OCIO_CHECK_EQUAL(StringUtils::Repeat("", 2), ""); } \ No newline at end of file From 91c004401cbd9764bfe8278b9d2e36fbd7c95139 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Fri, 5 Jun 2026 22:55:35 -0700 Subject: [PATCH 26/35] Add SerializeOpVec output prefix check. Signed-off-by: Mei Chu --- tests/cpu/Op_tests.cpp | 3 +++ tests/cpu/ops/noop/NoOps_tests.cpp | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/cpu/Op_tests.cpp b/tests/cpu/Op_tests.cpp index d6c1fb3c00..417b9c1db5 100644 --- a/tests/cpu/Op_tests.cpp +++ b/tests/cpu/Op_tests.cpp @@ -514,4 +514,7 @@ OCIO_ADD_TEST(OpRcPtrVec, serialize) // Serialize not optimized OpVec i.e. contains some NoOps. OCIO_CHECK_NO_THROW(OCIO::SerializeOpVec(ops)); + + // Check Serialize output's prefix for indentation. + OCIO_CHECK_EQUAL(std::string_view(SerializeOpVec(ops, 4), 7), " Op "); } diff --git a/tests/cpu/ops/noop/NoOps_tests.cpp b/tests/cpu/ops/noop/NoOps_tests.cpp index 3c3a3cb0fa..9f23640ed5 100644 --- a/tests/cpu/ops/noop/NoOps_tests.cpp +++ b/tests/cpu/ops/noop/NoOps_tests.cpp @@ -242,8 +242,6 @@ OCIO_ADD_TEST(NoOps, partition_gpu_ops) OCIO_CHECK_NO_THROW( AssertPartitionIntegrity(gpuPreOps, gpuLatticeOps, gpuPostOps) ); - std::cerr << "gpuPreOps" << std::endl; - std::cerr << SerializeOpVec(gpuPreOps, 4) << std::endl; /* std::cerr << "gpuPreOps" << std::endl; std::cerr << SerializeOpVec(gpuPreOps, 4) << std::endl; From 52e222526e75d7cfdc0e293e08021d7244330313 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Fri, 5 Jun 2026 23:06:34 -0700 Subject: [PATCH 27/35] Fix test Signed-off-by: Mei Chu --- tests/cpu/Op_tests.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/cpu/Op_tests.cpp b/tests/cpu/Op_tests.cpp index 417b9c1db5..f6130742a8 100644 --- a/tests/cpu/Op_tests.cpp +++ b/tests/cpu/Op_tests.cpp @@ -516,5 +516,6 @@ OCIO_ADD_TEST(OpRcPtrVec, serialize) OCIO_CHECK_NO_THROW(OCIO::SerializeOpVec(ops)); // Check Serialize output's prefix for indentation. - OCIO_CHECK_EQUAL(std::string_view(SerializeOpVec(ops, 4), 7), " Op "); + std::string_view ops_serialized(SerializeOpVec(ops, 4); + OCIO_CHECK_EQUAL(ops_serialized, 7), " Op "); } From 4accce0d4f39470bd612bb1ddded209a2aa8e188 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Fri, 5 Jun 2026 23:13:53 -0700 Subject: [PATCH 28/35] Fix test Signed-off-by: Mei Chu --- tests/cpu/Op_tests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cpu/Op_tests.cpp b/tests/cpu/Op_tests.cpp index f6130742a8..07d0872d04 100644 --- a/tests/cpu/Op_tests.cpp +++ b/tests/cpu/Op_tests.cpp @@ -516,6 +516,6 @@ OCIO_ADD_TEST(OpRcPtrVec, serialize) OCIO_CHECK_NO_THROW(OCIO::SerializeOpVec(ops)); // Check Serialize output's prefix for indentation. - std::string_view ops_serialized(SerializeOpVec(ops, 4); - OCIO_CHECK_EQUAL(ops_serialized, 7), " Op "); + std::string_view ops_serialized(SerializeOpVec(ops, 4), 7); + OCIO_CHECK_EQUAL(ops_serialized, " Op "); } From ba06cfb5933f8beb5838002be823352cbfc49d28 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Fri, 5 Jun 2026 23:21:01 -0700 Subject: [PATCH 29/35] Fix test Signed-off-by: Mei Chu --- tests/cpu/Op_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cpu/Op_tests.cpp b/tests/cpu/Op_tests.cpp index 07d0872d04..23d2dc4491 100644 --- a/tests/cpu/Op_tests.cpp +++ b/tests/cpu/Op_tests.cpp @@ -516,6 +516,6 @@ OCIO_ADD_TEST(OpRcPtrVec, serialize) OCIO_CHECK_NO_THROW(OCIO::SerializeOpVec(ops)); // Check Serialize output's prefix for indentation. - std::string_view ops_serialized(SerializeOpVec(ops, 4), 7); + std::string_view ops_serialized(OCIO::SerializeOpVec(ops, 4), 7); OCIO_CHECK_EQUAL(ops_serialized, " Op "); } From 7e0850428572caff0695dc4d8daf102d8818190e Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Fri, 5 Jun 2026 23:33:15 -0700 Subject: [PATCH 30/35] Fix test Signed-off-by: Mei Chu --- tests/cpu/Op_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cpu/Op_tests.cpp b/tests/cpu/Op_tests.cpp index 23d2dc4491..26d600bdac 100644 --- a/tests/cpu/Op_tests.cpp +++ b/tests/cpu/Op_tests.cpp @@ -516,6 +516,6 @@ OCIO_ADD_TEST(OpRcPtrVec, serialize) OCIO_CHECK_NO_THROW(OCIO::SerializeOpVec(ops)); // Check Serialize output's prefix for indentation. - std::string_view ops_serialized(OCIO::SerializeOpVec(ops, 4), 7); + std::string ops_serialized = std::string_view(OCIO::SerializeOpVec(ops, 4), 7); OCIO_CHECK_EQUAL(ops_serialized, " Op "); } From fe5900ba4154933c5920eae855d588a648cef335 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Fri, 5 Jun 2026 23:43:29 -0700 Subject: [PATCH 31/35] Fix test Signed-off-by: Mei Chu --- tests/cpu/Op_tests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cpu/Op_tests.cpp b/tests/cpu/Op_tests.cpp index 26d600bdac..88e6c4bae4 100644 --- a/tests/cpu/Op_tests.cpp +++ b/tests/cpu/Op_tests.cpp @@ -516,6 +516,6 @@ OCIO_ADD_TEST(OpRcPtrVec, serialize) OCIO_CHECK_NO_THROW(OCIO::SerializeOpVec(ops)); // Check Serialize output's prefix for indentation. - std::string ops_serialized = std::string_view(OCIO::SerializeOpVec(ops, 4), 7); - OCIO_CHECK_EQUAL(ops_serialized, " Op "); + std::string ops_serialized = OCIO::SerializeOpVec(ops, 4); + OCIO_CHECK_EQUAL(std::string_view(ops_serialized, 7), " Op "); } From 9362118f7bd4d05fbc28dd11f0cd376caaf43d34 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Sat, 6 Jun 2026 00:01:25 -0700 Subject: [PATCH 32/35] Fix test Signed-off-by: Mei Chu --- tests/cpu/Op_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cpu/Op_tests.cpp b/tests/cpu/Op_tests.cpp index 88e6c4bae4..599857bae0 100644 --- a/tests/cpu/Op_tests.cpp +++ b/tests/cpu/Op_tests.cpp @@ -517,5 +517,5 @@ OCIO_ADD_TEST(OpRcPtrVec, serialize) // Check Serialize output's prefix for indentation. std::string ops_serialized = OCIO::SerializeOpVec(ops, 4); - OCIO_CHECK_EQUAL(std::string_view(ops_serialized, 7), " Op "); + OCIO_CHECK_EQUAL(std::string_view(ops_serialized.data(), 7), " Op "); } From c1cce9bdb3c757bde97cb511fbb05070d49a3c70 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Sat, 6 Jun 2026 00:51:48 -0700 Subject: [PATCH 33/35] Op::SerializeOpVec switch to size_t Signed-off-by: Mei Chu --- src/OpenColorIO/Op.cpp | 2 +- src/OpenColorIO/Op.h | 2 +- src/utils/StringUtils.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OpenColorIO/Op.cpp b/src/OpenColorIO/Op.cpp index 4975b68ec7..4e832c1db1 100755 --- a/src/OpenColorIO/Op.cpp +++ b/src/OpenColorIO/Op.cpp @@ -469,7 +469,7 @@ std::ostream& operator<< (std::ostream & os, const Op & op) return os; } -std::string SerializeOpVec(const OpRcPtrVec & ops, int indent) +std::string SerializeOpVec(const OpRcPtrVec & ops, size_t indent) { std::ostringstream oss; diff --git a/src/OpenColorIO/Op.h b/src/OpenColorIO/Op.h index 895c426d80..fb0b95a2ee 100644 --- a/src/OpenColorIO/Op.h +++ b/src/OpenColorIO/Op.h @@ -409,7 +409,7 @@ class OpRcPtrVec }; -std::string SerializeOpVec(const OpRcPtrVec & ops, int indent=0); +std::string SerializeOpVec(const OpRcPtrVec & ops, size_t indent=0); void CreateOpVecFromOpData(OpRcPtrVec & ops, const ConstOpDataRcPtr & opData, diff --git a/src/utils/StringUtils.h b/src/utils/StringUtils.h index a790d7624b..6792351a9a 100644 --- a/src/utils/StringUtils.h +++ b/src/utils/StringUtils.h @@ -347,7 +347,7 @@ inline std::string Multiply(const std::string & str, size_t n) if (n == 0) { return ""; } if (n == 1) { return str; } - if (str.empty()) { return ""; } + if (str.empty()) { return str; } std::ostringstream os; for(size_t i = 0; i < n; ++i) { os << str; } @@ -361,7 +361,7 @@ inline std::string Repeat(const std::string & str, size_t n) if (n == 0) { return {}; } if (n == 1) { return str; } - if (str.empty()) { return {}; } + if (str.empty()) { return str; } const auto str_size = str.size(); std::string result; From 5fdbad74fd00d13befff8eed9749d0f72928e15b Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Fri, 3 Jul 2026 16:28:47 -0700 Subject: [PATCH 34/35] Not changing ci_workflow.yml Signed-off-by: Mei Chu --- .github/workflows/ci_workflow.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_workflow.yml b/.github/workflows/ci_workflow.yml index 676061d949..c234aef2ca 100644 --- a/.github/workflows/ci_workflow.yml +++ b/.github/workflows/ci_workflow.yml @@ -741,4 +741,4 @@ jobs: export PATH=../../../_install/bin:$PATH ./${{ matrix.build-type }}/consumer shell: bash - working-directory: _build/tests/cmake-consumer-dist \ No newline at end of file + working-directory: _build/tests/cmake-consumer-dist From b4f0b474afd1054a0d3b1b8b7649329bb82c1a11 Mon Sep 17 00:00:00 2001 From: Mei Chu Date: Thu, 16 Jul 2026 00:24:25 -0700 Subject: [PATCH 35/35] Update CICD. Think I messed up on the rebase last commit. Signed-off-by: Mei Chu --- .github/workflows/ci_workflow.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci_workflow.yml b/.github/workflows/ci_workflow.yml index c234aef2ca..68d02377ae 100644 --- a/.github/workflows/ci_workflow.yml +++ b/.github/workflows/ci_workflow.yml @@ -116,6 +116,7 @@ jobs: build-openfx: 'ON' use-simd: 'ON' use-oiio: 'ON' + aswf-ocio-version: 2.4.2 cxx-standard: 20 cxx-compiler: clang++ cc-compiler: clang @@ -158,6 +159,7 @@ jobs: build-openfx: 'ON' use-simd: 'ON' use-oiio: 'ON' + aswf-ocio-version: 2.3.2 cxx-standard: 20 cxx-compiler: clang++ cc-compiler: clang