Skip to content
58 changes: 49 additions & 9 deletions otsdaq/Macros/StringMacros.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,22 @@ const std::string StringMacros::TBD = "To-be-defined";
//==============================================================================
/// wildCardMatch
/// find needle in haystack
/// allow needle to have leading and/or trailing wildcard '*'
/// allow needle to have wildcard '*' anywhere
/// consider priority in matching, no matter the order in the haystack:
/// - 0: no match!
/// - 1: highest priority is exact match
/// - 2: next highest is partial TRAILING-wildcard match
/// - 3: next highest is partial LEADING-wildcard match
/// - 4: lowest priority is partial full-wildcard match
/// - 4: lowest priority is wildcard match (including internal '*')
/// - 5: wildcard-only match
/// return priority found by reference
bool StringMacros::wildCardMatch(const std::string& needle,
const std::string& haystack,
unsigned int* priorityIndex)
try
{
// __COUT__ << "\t\t wildCardMatch: " << needle <<
// " =in= " << haystack << " ??? " <<
// std::endl;
__COUTT__ << "\t\t wildCardMatch: " << needle << " =in= " << haystack << " ??? "
<< std::endl;

// empty needle
if(needle.size() == 0)
Expand All @@ -59,6 +59,14 @@ try
return true;
}

const bool hasWildcard = (needle.find('*') != std::string::npos);
if(!hasWildcard)
{
if(priorityIndex)
*priorityIndex = 0; // no wildcard and not exact => no match
return false;
}

// trailing wildcard
if(needle[needle.size() - 1] == '*' &&
needle.substr(0, needle.size() - 1) == haystack.substr(0, needle.size() - 1))
Expand All @@ -77,12 +85,44 @@ try
return true;
}

// leading wildcard and trailing wildcard
if(needle[0] == '*' && needle[needle.size() - 1] == '*' &&
std::string::npos != haystack.find(needle.substr(1, needle.size() - 2)))
// generic wildcard matching with '*' anywhere in needle
// '*' matches any sequence (including empty)
std::size_t patternPos = 0;
std::size_t textPos = 0;
std::size_t lastStarPattern = std::string::npos;
std::size_t lastStarTextPos = std::string::npos;
while(textPos < haystack.size())
{
if(patternPos < needle.size() && needle[patternPos] == haystack[textPos])
{
++patternPos;
++textPos;
}
else if(patternPos < needle.size() && needle[patternPos] == '*')
{
lastStarPattern = patternPos++;
lastStarTextPos = textPos;
}
else if(lastStarPattern != std::string::npos)
{
patternPos = lastStarPattern + 1;
textPos = ++lastStarTextPos;
}
else
{
if(priorityIndex)
*priorityIndex = 0; // no match
return false;
}
}

while(patternPos < needle.size() && needle[patternPos] == '*')
++patternPos;

if(patternPos == needle.size())
{
if(priorityIndex)
*priorityIndex = 4; // leading and trailing wildcard match
*priorityIndex = 4; // wildcard match
return true;
}

Expand Down
43 changes: 31 additions & 12 deletions otsdaq/TableCore/TableView.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1541,10 +1541,15 @@ std::vector<std::vector<unsigned int /*group row*/>> TableView::getGroupRowsInVe
colPriority_ != INVALID)) // if no priority column, all at same priorty [0]
retVector.push_back(std::vector<unsigned int /*group row*/>());

__COUTS__(2) << "getGroupRowsInVectors: " << groupID << " at col " << groupIdCol
<< __E__;
for(unsigned int r = 0; r < getNumberOfRows(); ++r)
if(groupID == "" || groupID == "*" || groupIdCol == INVALID ||
isEntryInGroupCol(r, groupIdCol, groupID))
{
if(groupIdCol != INVALID)
__COUTS__(2) << "Row " << r << " '" << getDataView()[r][groupIdCol]
<< "' is in group " << groupID << __E__;
// check status if needed
if(onlyStatusTrue && colStatus_ != INVALID)
{
Expand All @@ -1563,6 +1568,9 @@ std::vector<std::vector<unsigned int /*group row*/>> TableView::getGroupRowsInVe
else // assume equal priority
retVector[0].push_back(r);
}
else // already true that... if(groupIdCol != INVALID)
__COUTS__(2) << "Row " << r << " '" << getDataView()[r][groupIdCol]
<< "' is NOT in group " << groupID << __E__;

if(orderedByPriority && colPriority_ != INVALID)
{
Expand Down Expand Up @@ -1592,7 +1600,7 @@ bool TableView::removeRowFromGroup(const unsigned int& row,
const std::string& groupNeedle,
bool deleteRowIfNoGroupLeft)
{
__COUT__ << "groupNeedle " << groupNeedle << __E__;
__COUT__ << "removeRowFromGroup groupNeedle " << groupNeedle << __E__;
std::set<std::string> groupIDList;
if(!isEntryInGroupCol(row, col, groupNeedle, &groupIDList))
{
Expand All @@ -1610,7 +1618,7 @@ bool TableView::removeRowFromGroup(const unsigned int& row,
unsigned int cnt = 0;
for(const auto& groupID : groupIDList)
{
//__COUT__ << groupID << " " << groupNeedle << " " << newValue << __E__;
__COUTT__ << groupID << " " << groupNeedle << " " << newValue << __E__;
if(groupID == groupNeedle)
continue; // skip group to be removed

Expand All @@ -1622,14 +1630,15 @@ bool TableView::removeRowFromGroup(const unsigned int& row,
bool wasDeleted = false;
if(deleteRowIfNoGroupLeft && newValue == "")
{
__COUT__ << "Delete row since it no longer part of any group." << __E__;
__COUTT__ << "Delete row since it no longer part of any group." << __E__;
deleteRow(row);
wasDeleted = true;
}
else
{
setValue(newValue, row, col);

//__COUT__ << getDataView()[row][col] << __E__;
__COUTT__ << getDataView()[row][col] << __E__;
}

return wasDeleted;
} // end removeRowFromGroup()
Expand Down Expand Up @@ -1674,7 +1683,7 @@ bool TableView::isEntryInGroupCol(const unsigned int& r,
unsigned int j = 0;
bool found = false;

//__COUT__ << "groupNeedle " << groupNeedle << __E__;
__COUTT__ << "groupNeedle " << groupNeedle << __E__;

// go through the full groupString extracting groups and comparing to groupNeedle
for(; j < theDataView_[r][c].size(); ++j)
Expand All @@ -1690,10 +1699,14 @@ bool TableView::isEntryInGroupCol(const unsigned int& r,
if(groupIDList)
groupIDList->emplace(theDataView_[r][c].substr(i, j - i));

//__COUT__ << "Group found to compare: " <<
// theDataView_[r][c].substr(i,j-i) << __E__;
if(groupNeedle == theDataView_[r][c].substr(i, j - i))
__COUTT__ << "Group found to compare: " << theDataView_[r][c].substr(i, j - i)
<< __E__;
if(groupIDList ? groupNeedle == theDataView_[r][c].substr(i, j - i)
: StringMacros::wildCardMatch(
theDataView_[r][c].substr(i, j - i), groupNeedle))
{
__COUTT__ << "'" << theDataView_[r][c].substr(i, j - i)
<< "' is in group '" << groupNeedle << "'!" << __E__;
if(!groupIDList) // dont return if caller is trying to get group list
return true;
found = true;
Expand All @@ -1707,10 +1720,16 @@ bool TableView::isEntryInGroupCol(const unsigned int& r,
if(groupIDList)
groupIDList->emplace(theDataView_[r][c].substr(i, j - i));

//__COUT__ << "Group found to compare: " <<
// theDataView_[r][c].substr(i,j-i) << __E__;
if(groupNeedle == theDataView_[r][c].substr(i, j - i))
__COUTT__ << "Group found to compare: " << theDataView_[r][c].substr(i, j - i)
<< __E__;
if(groupIDList ? groupNeedle == theDataView_[r][c].substr(i, j - i)
: StringMacros::wildCardMatch(theDataView_[r][c].substr(i, j - i),
groupNeedle))
{
__COUTT__ << "'" << theDataView_[r][c].substr(i, j - i) << "' is in group '"
<< groupNeedle << "'!" << __E__;
return true;
}
}

return found;
Expand Down
Loading