|
|
|
@ -5,7 +5,11 @@
|
|
|
|
|
#include <tqregexp.h>
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
|
|
|
|
|
|
#if __has_include( <features.h> ) // C++17
|
|
|
|
|
#pragma message "Using features.h to check for __GLIBC__"
|
|
|
|
|
#include <features.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef __GLIBC__
|
|
|
|
|
#include <fnmatch.h>
|
|
|
|
|
#pragma message "TSM using GLIBC fnmatch() for wildcard matching"
|
|
|
|
@ -13,8 +17,6 @@
|
|
|
|
|
|
|
|
|
|
//================================================================================================
|
|
|
|
|
|
|
|
|
|
namespace TSM {
|
|
|
|
|
|
|
|
|
|
class AuxData
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
@ -34,15 +36,11 @@ AuxData::AuxData()
|
|
|
|
|
fnmatchFlags = FNM_EXTMATCH; // Bash shell option 'extglob'
|
|
|
|
|
#endif
|
|
|
|
|
matchEngine = nullptr;
|
|
|
|
|
patternConverted = "";
|
|
|
|
|
patternConverted = TQString::null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // End of namespace TSM
|
|
|
|
|
|
|
|
|
|
//================================================================================================
|
|
|
|
|
|
|
|
|
|
using namespace TSM;
|
|
|
|
|
|
|
|
|
|
typedef TQValueVector<AuxData> AuxDataList;
|
|
|
|
|
|
|
|
|
|
class TDEStringMatcher::TDEStringMatcherPrivate {
|
|
|
|
@ -59,11 +57,11 @@ public:
|
|
|
|
|
|
|
|
|
|
void TDEStringMatcher::TDEStringMatcherPrivate::clearAll()
|
|
|
|
|
{
|
|
|
|
|
m_matchSpecString = "";
|
|
|
|
|
m_matchSpecString = TQString::null;
|
|
|
|
|
m_matchSpecList.clear();
|
|
|
|
|
for ( size_t index = 0 ; index < m_auxData.count() ; index++ ) {
|
|
|
|
|
if ( m_auxData[index].matchEngine != nullptr ) {
|
|
|
|
|
TSMTRACE << "Freeing match engine " << m_auxData[index].matchEngine << endl;
|
|
|
|
|
TSMTRACE << "Freeing regex match engine " << m_auxData[index].matchEngine << endl;
|
|
|
|
|
delete m_auxData[index].matchEngine;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -95,7 +93,7 @@ const TQString TDEStringMatcher::getMatchSpecString() const
|
|
|
|
|
return d->m_matchSpecString;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const MatchSpecList TDEStringMatcher::getMatchSpecs() const
|
|
|
|
|
const TDEStringMatcher::MatchSpecList TDEStringMatcher::getMatchSpecs() const
|
|
|
|
|
{
|
|
|
|
|
return d->m_matchSpecList;
|
|
|
|
|
}
|
|
|
|
@ -120,7 +118,7 @@ bool TDEStringMatcher::setMatchSpecs( MatchSpecList newMatchSpecList )
|
|
|
|
|
workArea.clearAll();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if ( matchSpec.pattern.find( TQChar(PatterStringDivider) ) >= 0 ) {
|
|
|
|
|
if ( matchSpec.pattern.find( TQChar(PatternStringDivider) ) >= 0 ) {
|
|
|
|
|
TSMTRACE << " Error: pattern contains reserved separator character" << endl;
|
|
|
|
|
workArea.clearAll();
|
|
|
|
|
return false;
|
|
|
|
@ -170,7 +168,7 @@ bool TDEStringMatcher::setMatchSpecs( MatchSpecList newMatchSpecList )
|
|
|
|
|
case ANCHandling::EQUIVALENCE :
|
|
|
|
|
inferredOptionString += TQChar('e');
|
|
|
|
|
auxWork.isCaseSensitive = true;
|
|
|
|
|
auxWork.patternConverted = TDEGlobal::equivChars()->replaceChars( auxWork.patternConverted, true );
|
|
|
|
|
auxWork.patternConverted = TEquivChars::replaceChars( auxWork.patternConverted, true );
|
|
|
|
|
TSMTRACE << " Converted match pattern '" << before << "' to equivalent '" << auxWork.patternConverted << "'" << endl;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
@ -191,7 +189,8 @@ bool TDEStringMatcher::setMatchSpecs( MatchSpecList newMatchSpecList )
|
|
|
|
|
|
|
|
|
|
switch ( matchSpec.patternType ) {
|
|
|
|
|
case PatternType::WILDCARD :
|
|
|
|
|
#ifdef __GLIBC__ // Test wildcard expression using a subject matter expert
|
|
|
|
|
#ifdef __GLIBC__
|
|
|
|
|
// Test wildcard expression using a subject matter expert
|
|
|
|
|
result = fnmatch(
|
|
|
|
|
auxWork.patternConverted.local8Bit().data(),
|
|
|
|
|
auxWork.patternConverted.local8Bit().data(),
|
|
|
|
@ -207,7 +206,10 @@ bool TDEStringMatcher::setMatchSpecs( MatchSpecList newMatchSpecList )
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
#endif // Otherwise we will test wildcard expression as one converted to a regex
|
|
|
|
|
#else
|
|
|
|
|
// Wildcard expression was converted to regex during earlier PatternType
|
|
|
|
|
// processing and will be subsequently validated as such.
|
|
|
|
|
#endif
|
|
|
|
|
case PatternType::REGEX :
|
|
|
|
|
// Prepare regex
|
|
|
|
|
rxWork.setPattern( auxWork.patternConverted );
|
|
|
|
@ -237,7 +239,7 @@ bool TDEStringMatcher::setMatchSpecs( MatchSpecList newMatchSpecList )
|
|
|
|
|
// All proposed match specifications are good, update everything accordingly
|
|
|
|
|
|
|
|
|
|
workArea.m_matchSpecList = newMatchSpecList;
|
|
|
|
|
workArea.m_matchSpecString = newMatchSpecs.join( TQChar(PatterStringDivider) );
|
|
|
|
|
workArea.m_matchSpecString = newMatchSpecs.join( TQChar(PatternStringDivider) );
|
|
|
|
|
d->clearAll();
|
|
|
|
|
*d = workArea;
|
|
|
|
|
//-Debug: TSMTRACE << " Notifying slots of pattern change" << endl;
|
|
|
|
@ -273,7 +275,7 @@ bool TDEStringMatcher::setMatchSpecs( TQString newMatchSpecString )
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TQStringList newMatchSpecs = TQStringList::split( PatterStringDivider, newMatchSpecString, true );
|
|
|
|
|
TQStringList newMatchSpecs = TQStringList::split( PatternStringDivider, newMatchSpecString, true );
|
|
|
|
|
|
|
|
|
|
if ( newMatchSpecs.count() % 2 != 0 ) {
|
|
|
|
|
TSMTRACE << " Error: match specification string must contain an even number of components" << endl;
|
|
|
|
@ -361,7 +363,7 @@ bool TDEStringMatcher::setMatchSpecs( TQString newMatchSpecString )
|
|
|
|
|
break;
|
|
|
|
|
case ANCHandling::EQUIVALENCE :
|
|
|
|
|
auxWork.isCaseSensitive = true;
|
|
|
|
|
auxWork.patternConverted = TDEGlobal::equivChars()->replaceChars( auxWork.patternConverted, true );
|
|
|
|
|
auxWork.patternConverted = TEquivChars::replaceChars( auxWork.patternConverted, true );
|
|
|
|
|
TSMTRACE << " Converted match pattern '" << before << "' to equivalent '" << auxWork.patternConverted << "'" << endl;
|
|
|
|
|
break;
|
|
|
|
|
default: break;
|
|
|
|
@ -404,7 +406,7 @@ bool TDEStringMatcher::setMatchSpecs( TQString newMatchSpecString )
|
|
|
|
|
if ( rxWork.isValid() ) {
|
|
|
|
|
auxWork.matchEngine = new TQRegExp;
|
|
|
|
|
*auxWork.matchEngine = rxWork;
|
|
|
|
|
TSMTRACE << " AuxData: Allocated regex engine " << auxWork.matchEngine << "for pattern: " << auxWork.matchEngine->pattern() << endl;
|
|
|
|
|
TSMTRACE << " AuxData: Allocated regex engine " << auxWork.matchEngine << " for pattern: " << auxWork.matchEngine->pattern() << endl;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
TSMTRACE << " Error: invalid regex syntax" << endl;
|
|
|
|
@ -457,7 +459,8 @@ bool TDEStringMatcher::matchAny( const TQString& stringToMatch ) const
|
|
|
|
|
|
|
|
|
|
if ( d->m_matchSpecList[index].ancHandling == ANCHandling::EQUIVALENCE ) {
|
|
|
|
|
if ( equivalentString.isEmpty() ) {
|
|
|
|
|
equivalentString = TDEGlobal::equivChars()->replaceChars( stringToMatch, false ) ;
|
|
|
|
|
//TBR equivalentString = TDEGlobal::equivChars()->replaceChars( stringToMatch, false ) ;
|
|
|
|
|
equivalentString = TEquivChars::replaceChars( stringToMatch, false ) ;
|
|
|
|
|
}
|
|
|
|
|
matchWhat = equivalentString;
|
|
|
|
|
}
|
|
|
|
@ -508,7 +511,8 @@ bool TDEStringMatcher::matchAll( const TQString& stringToMatch ) const
|
|
|
|
|
|
|
|
|
|
if ( d->m_matchSpecList[index].ancHandling == ANCHandling::EQUIVALENCE ) {
|
|
|
|
|
if ( equivalentString.isEmpty() ) {
|
|
|
|
|
equivalentString = TDEGlobal::equivChars()->replaceChars( stringToMatch, false ) ;
|
|
|
|
|
//TBR equivalentString = TDEGlobal::equivChars()->replaceChars( stringToMatch, false ) ;
|
|
|
|
|
equivalentString = TEquivChars::replaceChars( stringToMatch, false ) ;
|
|
|
|
|
}
|
|
|
|
|
matchWhat = equivalentString;
|
|
|
|
|
}
|
|
|
|
|