diff --git a/src/autotests/CMakeLists.txt b/src/autotests/CMakeLists.txt index 1be328b..1511bbd 100644 --- a/src/autotests/CMakeLists.txt +++ b/src/autotests/CMakeLists.txt @@ -1,11 +1,17 @@ find_package( Qt5 ${QT_MIN_VERSION} REQUIRED Test ) add_definitions(-DAUTOTEST) ecm_add_test(commentparser.cpp ../CommentParser.cpp TEST_NAME "commentparser" LINK_LIBRARIES Qt5::Test ) + +ecm_add_test(CvsIgnorelist.cpp ../cvsignorelist.cpp + TEST_NAME "cvsignorelisttest" + LINK_LIBRARIES Qt5::Test +) + diff --git a/src/autotests/CvsIgnorelist.cpp b/src/autotests/CvsIgnorelist.cpp new file mode 100644 index 0000000..35d2d4c --- /dev/null +++ b/src/autotests/CvsIgnorelist.cpp @@ -0,0 +1,54 @@ +/** + * Copyright (C) 2019 Michael Reeves + * + * This file is part of KDiff3. + * + * KDiff3 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * KDiff3 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with KDiff3. If not, see . + */ + +#include + +#include "../cvsignorelist.h" + +class CvsIgnoreListTest : public QObject +{ + Q_OBJECT + private Q_SLOTS: + void init() + { + CvsIgnoreList test; + //sanity check defaults + QVERIFY(test.m_exactPatterns.isEmpty()); + QVERIFY(test.m_endPatterns.isEmpty()); + QVERIFY(test.m_generalPatterns.isEmpty()); + QVERIFY(test.m_startPatterns.isEmpty()); + } + + void addEntriesFromString() + { + CvsIgnoreList test; + QStringList expected; + + test.addEntriesFromString(". .. core RCSLOG tags TAGS RCS SCCS .make.state"); + expected = QStringList{".", "..", "core", "RCSLOG", "tags", "TAGS", "RCS", "SCCS", ".make.state"}; + QVERIFY(!test.m_exactPatterns.isEmpty()); + QVERIFY(test.m_exactPatterns == expected); + + } + +}; + +QTEST_MAIN(CvsIgnoreListTest); + +#include "CvsIgnorelist.moc" diff --git a/src/autotests/MocIgnoreFile.h b/src/autotests/MocIgnoreFile.h new file mode 100644 index 0000000..6adc77d --- /dev/null +++ b/src/autotests/MocIgnoreFile.h @@ -0,0 +1,35 @@ + + +#include + +#include + +typedef class MocIgnoreFile FileAccess; +typedef std::list t_DirectoryList; + +class MocIgnoreFile +{ + public: + void mocSetPath(const QString& path) { mPath = path; } + void mocSetIsLocal(bool local) { mLocal = local; } + + void addPath(const QString& txt) { Q_UNUSED(txt); } + QString absoluteFilePath() const { return mPath; } + + bool createLocalCopy() { return true; } + + bool isLocal() const { return mLocal; } + + bool exists() const { return mExists; } + QString getTempName() const { return mPath; } + + QString fileName(bool needTmp = false) const + { + Q_UNUSED(needTmp); + return ".cvsignore"; + } + + private: + QString mPath = "/test/ui/.cvsignore"; + bool mLocal = true, mExists = true; +}; diff --git a/src/cvsignorelist.cpp b/src/cvsignorelist.cpp index fa533ab..ae1ddab 100644 --- a/src/cvsignorelist.cpp +++ b/src/cvsignorelist.cpp @@ -1,189 +1,196 @@ /*************************************************************************** * class CvsIgnoreList from Cervisia cvsdir.cpp * * Copyright (C) 1999-2002 Bernd Gehrmann * * with elements from class StringMatcher * * Copyright (c) 2003 Andre Woebbeking * * Modifications for KDiff3 by Joachim Eibl * * * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "cvsignorelist.h" #include "TypeUtils.h" #include #include void CvsIgnoreList::init(FileAccess& dir, const t_DirectoryList* pDirList) { static const char* ignorestr = ". .. core RCSLOG tags TAGS RCS SCCS .make.state " ".nse_depinfo #* .#* cvslog.* ,* CVS CVS.adm .del-* *.a *.olb *.o *.obj " "*.so *.Z *~ *.old *.elc *.ln *.bak *.BAK *.orig *.rej *.exe _$* *$"; static const char* varname = "CVSIGNORE"; addEntriesFromString(QString::fromLatin1(ignorestr)); addEntriesFromFile(QDir::homePath() + "/.cvsignore"); if(qEnvironmentVariableIsSet(varname) && !qEnvironmentVariableIsEmpty(varname)) { addEntriesFromString(QString::fromLocal8Bit(qgetenv(varname))); } const bool bUseLocalCvsIgnore = cvsIgnoreExists(pDirList); if(bUseLocalCvsIgnore) { FileAccess file(dir); file.addPath(".cvsignore"); if(file.exists() && file.isLocal()) addEntriesFromFile(file.absoluteFilePath()); else { file.createLocalCopy(); addEntriesFromFile(file.getTempName()); } } } void CvsIgnoreList::addEntriesFromString(const QString& str) { QtNumberType posLast = 0; QtNumberType pos; while((pos = str.indexOf(' ', posLast)) >= 0) { if(pos > posLast) addEntry(str.mid(posLast, pos - posLast)); posLast = pos + 1; } if(posLast < str.length()) addEntry(str.mid(posLast)); } +/* + MocIgnoreFile is incapatiable with addEntriesFromFile so do nothing in AUTORUN mode +*/ void CvsIgnoreList::addEntriesFromFile(const QString& name) { + #ifdef AUTORUN + Q_UNUSED(name) + #else QFile file(name); if(file.open(QIODevice::ReadOnly)) { QTextStream stream(&file); while(!stream.atEnd()) { addEntry(stream.readLine()); } } + #endif } void CvsIgnoreList::addEntry(const QString& pattern) { if(pattern != QString("!")) { if(pattern.isEmpty()) return; // The general match is general but slow. // Special tests for '*' and '?' at the beginning or end of a pattern // allow fast checks. // Count number of '*' and '?' unsigned int nofMetaCharacters = 0; const QChar* pos; pos = pattern.unicode(); const QChar* posEnd; posEnd = pos + pattern.length(); while(pos < posEnd) { if(*pos == QChar('*') || *pos == QChar('?')) ++nofMetaCharacters; ++pos; } if(nofMetaCharacters == 0) { m_exactPatterns.append(pattern); } else if(nofMetaCharacters == 1) { if(pattern.at(0) == QChar('*')) { m_endPatterns.append(pattern.right(pattern.length() - 1)); } else if(pattern.at(pattern.length() - 1) == QChar('*')) { m_startPatterns.append(pattern.left(pattern.length() - 1)); } else { m_generalPatterns.append(pattern); } } else { m_generalPatterns.append(pattern); } } else { m_exactPatterns.clear(); m_startPatterns.clear(); m_endPatterns.clear(); m_generalPatterns.clear(); } } bool CvsIgnoreList::matches(const QString& text, bool bCaseSensitive) const { if(m_exactPatterns.indexOf(text) >= 0) { return true; } for(const QString& startPattern: m_startPatterns) { if(text.startsWith(startPattern)) { return true; } } for(const QString& endPattern: m_endPatterns) { if(text.mid(text.length() - endPattern.length()) == endPattern) //(text.endsWith(*it)) { return true; } } /* for (QValueList::const_iterator it(m_generalPatterns.begin()), itEnd(m_generalPatterns.end()); it != itEnd; ++it) { if (::fnmatch(*it, text.local8Bit(), FNM_PATHNAME) == 0) { return true; } } */ for(const QString& globStr : m_generalPatterns) { QRegExp pattern(globStr, bCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive, QRegExp::Wildcard); if(pattern.exactMatch(text)) return true; } return false; } bool CvsIgnoreList::cvsIgnoreExists(const t_DirectoryList* pDirList) { for(const FileAccess& dir : *pDirList) { if(dir.fileName() == ".cvsignore") return true; } return false; } diff --git a/src/cvsignorelist.h b/src/cvsignorelist.h index 2fb18b7..8e6801c 100644 --- a/src/cvsignorelist.h +++ b/src/cvsignorelist.h @@ -1,39 +1,47 @@ /*************************************************************************** * class CvsIgnoreList from Cervisia cvsdir.cpp * * Copyright (C) 1999-2002 Bernd Gehrmann * * with elements from class StringMatcher * * Copyright (c) 2003 Andre Woebbeking * * Modifications for KDiff3 by Joachim Eibl * * * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #ifndef CVSIGNORELIST_H #define CVSIGNORELIST_H +#ifndef AUTOTEST #include "fileaccess.h" +#else +#include "MocIgnoreFile.h" +#endif + +#include +#include class CvsIgnoreList { public: CvsIgnoreList() {} void init(FileAccess& dir, const t_DirectoryList* pDirList); bool matches(const QString& text, bool bCaseSensitive) const; private: + friend class CvsIgnoreListTest; bool cvsIgnoreExists(const t_DirectoryList* pDirList); void addEntriesFromString(const QString& str); void addEntriesFromFile(const QString& name); void addEntry(const QString& pattern); QStringList m_exactPatterns; QStringList m_startPatterns; QStringList m_endPatterns; QStringList m_generalPatterns; }; #endif