diff --git a/otsdaq/Macros/StringMacros.cc b/otsdaq/Macros/StringMacros.cc
index 093546561..2c320b723 100644
--- a/otsdaq/Macros/StringMacros.cc
+++ b/otsdaq/Macros/StringMacros.cc
@@ -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)
@@ -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))
@@ -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;
}
diff --git a/otsdaq/TableCore/TableView.cc b/otsdaq/TableCore/TableView.cc
index bf9b0c71e..3ec722fb5 100644
--- a/otsdaq/TableCore/TableView.cc
+++ b/otsdaq/TableCore/TableView.cc
@@ -1541,10 +1541,15 @@ std::vector> TableView::getGroupRowsInVe
colPriority_ != INVALID)) // if no priority column, all at same priorty [0]
retVector.push_back(std::vector());
+ __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)
{
@@ -1563,6 +1568,9 @@ std::vector> 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)
{
@@ -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 groupIDList;
if(!isEntryInGroupCol(row, col, groupNeedle, &groupIDList))
{
@@ -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
@@ -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()
@@ -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)
@@ -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;
@@ -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;