Skip to content

Commit

Permalink
Adding test case and some parsing fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
larochj committed Dec 11, 2024
1 parent f85eb05 commit b91c6fb
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 22 deletions.
62 changes: 43 additions & 19 deletions src/OpenColorIO/ParseUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -693,29 +693,29 @@ bool StrEqualsCaseIgnore(const std::string & a, const std::string & b)
// Find the end of a name from a list contained in a string.
// The element of the list are separeted by ":" or ",".
// The name can be surrounded by quotes to enable name including theses symbols.
static size_t findEndOfName(const std::string & s, size_t start)
static int findEndOfName(const std::string & s, size_t start)
{
size_t currentPos = start;
size_t nameEndPos = currentPos;
int currentPos = start;
int nameEndPos = currentPos;
bool isEndFound = false;

while( !isEndFound )
{
nameEndPos = s.find_first_of("\",:", currentPos);
if(nameEndPos == std::string::npos)
if(nameEndPos == (int)std::string::npos)
{
// We reached the end of the list
nameEndPos = s.size() - 1;
nameEndPos = s.size();
isEndFound = true;
}
else if( s[nameEndPos] == '"' )
{
// We found a quote, we need to find the next one
nameEndPos = s.find_first_of("\"", nameEndPos + 1);
if(nameEndPos == std::string::npos)
if(nameEndPos == (int)std::string::npos)
{
// We reached the end of the list instead
nameEndPos = s.size() - 1;
nameEndPos = s.size();
isEndFound = true;
}
else
Expand All @@ -729,7 +729,6 @@ static size_t findEndOfName(const std::string & s, size_t start)
s[nameEndPos] == ':' )
{
// We found a symbol separating the elements, we stop here
nameEndPos--;
isEndFound = true;
}
}
Expand All @@ -739,17 +738,28 @@ static size_t findEndOfName(const std::string & s, size_t start)

StringUtils::StringVec SplitStringEnvStyle(const std::string & str)
{
StringUtils::StringVec outputvec;
const std::string s = StringUtils::Trim(str);
size_t currentPos = 0;
if( s.size() == 0 )
{
return {""};
}


StringUtils::StringVec outputvec;
int currentPos = 0;
while( s.size() > 0 &&
currentPos < s.size() - 1 )
currentPos <= (int) s.size() )
{
size_t nameEndPos = findEndOfName(s, currentPos);
outputvec.push_back(s.substr(currentPos, nameEndPos - currentPos + 1));
currentPos = nameEndPos + 2;
int nameEndPos = findEndOfName(s, currentPos);
if(nameEndPos > currentPos)
{
outputvec.push_back(s.substr(currentPos, nameEndPos - currentPos));
currentPos = nameEndPos + 1;
}
else
{
outputvec.push_back("");
currentPos += 1;
}
}

for ( auto & val : outputvec )
Expand All @@ -775,15 +785,29 @@ StringUtils::StringVec SplitStringEnvStyle(const std::string & str)
std::string JoinStringEnvStyle(const StringUtils::StringVec & outputvec)
{
std::string result;
for( const auto & val : outputvec )
const int nElement = static_cast<int>(outputvec.size());
for( int i = 0; i < nElement; ++i )
{
if( val.find_first_of(',') != std::string::npos )
// We check if the value contains a symbol that could be interpreted as a separator
// and if it is not already surrounded by quotes
if( outputvec[i].find_first_of(",:") != std::string::npos &&
outputvec[i].size() > 1 &&
outputvec[i][0] != '"' &&
outputvec[i][outputvec[i].size() - 1] != '"' )
{
result += "\"" + outputvec[i] + "\"";
if( outputvec[i] != outputvec.back() )
{
result += ", ";
}
}
else if( i == nElement - 1 )
{
result += "\"" + val + "\", ";
result += outputvec[i];
}
else
{
result += val + ", ";
result += outputvec[i] + ", ";
}
}

Expand Down
87 changes: 84 additions & 3 deletions tests/cpu/ParseUtils_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -395,30 +395,111 @@ OCIO_ADD_TEST(ParseUtils, split_string_env_style)
OCIO_CHECK_EQUAL("a", outputvec[2]);
OCIO_CHECK_EQUAL("test", outputvec[3]);
outputvec.clear();

outputvec = OCIO::SplitStringEnvStyle(" This : is : a: test ");
OCIO_CHECK_EQUAL(4, outputvec.size());
OCIO_CHECK_EQUAL("This", outputvec[0]);
OCIO_CHECK_EQUAL("is", outputvec[1]);
OCIO_CHECK_EQUAL("a", outputvec[2]);
OCIO_CHECK_EQUAL("test", outputvec[3]);
outputvec.clear();

outputvec = OCIO::SplitStringEnvStyle(" This , is , a, test ");
OCIO_CHECK_EQUAL(4, outputvec.size());
OCIO_CHECK_EQUAL("This", outputvec[0]);
OCIO_CHECK_EQUAL("is", outputvec[1]);
OCIO_CHECK_EQUAL("a", outputvec[2]);
OCIO_CHECK_EQUAL("test", outputvec[3]);
outputvec.clear();

outputvec = OCIO::SplitStringEnvStyle("This:is , a:test ");
OCIO_CHECK_EQUAL(2, outputvec.size());
OCIO_CHECK_EQUAL("This:is", outputvec[0]);
OCIO_CHECK_EQUAL("a:test", outputvec[1]);
OCIO_CHECK_EQUAL(4, outputvec.size());
OCIO_CHECK_EQUAL("This", outputvec[0]);
OCIO_CHECK_EQUAL("is", outputvec[1]);
OCIO_CHECK_EQUAL("a", outputvec[2]);
OCIO_CHECK_EQUAL("test", outputvec[3]);
outputvec.clear();

outputvec = OCIO::SplitStringEnvStyle(",,");
OCIO_CHECK_EQUAL(3, outputvec.size());
OCIO_CHECK_EQUAL("", outputvec[0]);
OCIO_CHECK_EQUAL("", outputvec[1]);
OCIO_CHECK_EQUAL("", outputvec[2]);

outputvec = OCIO::SplitStringEnvStyle(" \"This : is \": a: test ");
OCIO_CHECK_EQUAL(3, outputvec.size());
OCIO_CHECK_EQUAL("This : is ", outputvec[0]);
OCIO_CHECK_EQUAL("a", outputvec[1]);
OCIO_CHECK_EQUAL("test", outputvec[2]);

outputvec = OCIO::SplitStringEnvStyle(" This : is \": a: test ");
OCIO_CHECK_EQUAL(2, outputvec.size());
OCIO_CHECK_EQUAL("This", outputvec[0]);
OCIO_CHECK_EQUAL("is \": a: test", outputvec[1]);

outputvec = OCIO::SplitStringEnvStyle(" This : is \": a: test \"");
OCIO_CHECK_EQUAL(2, outputvec.size());
OCIO_CHECK_EQUAL("This", outputvec[0]);
OCIO_CHECK_EQUAL("is \": a: test \"" , outputvec[1]);

outputvec = OCIO::SplitStringEnvStyle(" \"This : is \", a, test ");
OCIO_CHECK_EQUAL(3, outputvec.size());
OCIO_CHECK_EQUAL("This : is ", outputvec[0]);
OCIO_CHECK_EQUAL("a", outputvec[1]);
OCIO_CHECK_EQUAL("test", outputvec[2]);

outputvec = OCIO::SplitStringEnvStyle(" \"This , is \": a: test ");
OCIO_CHECK_EQUAL(3, outputvec.size());
OCIO_CHECK_EQUAL("This , is ", outputvec[0]);
OCIO_CHECK_EQUAL("a", outputvec[1]);
OCIO_CHECK_EQUAL("test", outputvec[2]);

outputvec = OCIO::SplitStringEnvStyle(" \"This , is \": a, test ");
OCIO_CHECK_EQUAL(3, outputvec.size());
OCIO_CHECK_EQUAL("This , is ", outputvec[0]);
OCIO_CHECK_EQUAL("a", outputvec[1]);
OCIO_CHECK_EQUAL("test", outputvec[2]);

outputvec = OCIO::SplitStringEnvStyle(" This : is \": a: test ");
OCIO_CHECK_EQUAL(2, outputvec.size());
OCIO_CHECK_EQUAL("This", outputvec[0]);
OCIO_CHECK_EQUAL("is \": a: test", outputvec[1]);

outputvec = OCIO::SplitStringEnvStyle(" This : is \": a: test \"");
OCIO_CHECK_EQUAL(2, outputvec.size());
OCIO_CHECK_EQUAL("This", outputvec[0]);
OCIO_CHECK_EQUAL("is \": a: test \"" , outputvec[1]);

outputvec = OCIO::SplitStringEnvStyle(" This : is : a: test \"");
OCIO_CHECK_EQUAL(4, outputvec.size());
OCIO_CHECK_EQUAL("This", outputvec[0]);
OCIO_CHECK_EQUAL("is", outputvec[1]);
OCIO_CHECK_EQUAL("a", outputvec[2]);
OCIO_CHECK_EQUAL("test \"", outputvec[3]);
}

OCIO_ADD_TEST(ParseUtils, join_string_env_style)
{
StringUtils::StringVec outputvec {"This", "is", "a", "test"};

OCIO_CHECK_EQUAL( "This, is, a, test", OCIO::JoinStringEnvStyle(outputvec) );
outputvec.clear();


outputvec = { "This:is", "a:test" };
OCIO_CHECK_EQUAL( "\"This:is\", \"a:test\"", OCIO::JoinStringEnvStyle(outputvec) );
outputvec.clear();

outputvec = { "", "", "" };
OCIO_CHECK_EQUAL( ", , ", OCIO::JoinStringEnvStyle(outputvec) );
outputvec.clear();

outputvec = { "This : is", "a: test" };
OCIO_CHECK_EQUAL( "\"This : is\", \"a: test\"", OCIO::JoinStringEnvStyle(outputvec) );
outputvec.clear();

outputvec = { "This", "is \": a: test" };
OCIO_CHECK_EQUAL( "This, \"is \": a: test\"", OCIO::JoinStringEnvStyle(outputvec) );
}

OCIO_ADD_TEST(ParseUtils, intersect_string_vecs_case_ignore)
Expand Down

0 comments on commit b91c6fb

Please sign in to comment.