*.o
snapper-zypp-plugin
+*.test
+*.log
+*.trs
+test-suite.log
AM_CXXFLAGS = -Wsuggest-override
snapper_zypp_plugin_SOURCES = \
snapper_zypp_plugin.cc \
+ solvable_matcher.cc solvable_matcher.h \
zypp_commit_plugin.cc zypp_commit_plugin.h \
zypp_plugin.cc zypp_plugin.h
-snapper_zypp_plugin_LDFLAGS = \
+snapper_zypp_plugin_LDADD = \
../client/libclient.la \
../snapper/libsnapper.la \
../dbus/libdbus.la \
$(JSONC_LIBS) \
-lboost_regex
+check_PROGRAMS = regex.test
+TESTS = $(check_PROGRAMS)
+regex_test_SOURCES = regex_test.cc \
+ solvable_matcher.cc solvable_matcher.h
+regex_test_LDADD = \
+ ../snapper/libsnapper.la \
+ -lboost_regex \
+ -lboost_unit_test_framework
+
endif
--- /dev/null
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MODULE regex
+
+#include <boost/test/unit_test.hpp>
+#include "solvable_matcher.h"
+
+static
+SolvableMatcher matcher(const char* regex) {
+ bool is_important = false;
+ return SolvableMatcher(regex, SolvableMatcher::Kind::REGEX, is_important);
+}
+
+BOOST_AUTO_TEST_CASE(regex)
+{
+ BOOST_CHECK(matcher("mypkg").match("mypkg"));
+ BOOST_CHECK(!matcher("mypkg").match("yourpkg"));
+}
// getppid
#include <sys/types.h>
#include <unistd.h>
-// fnmatch
-#include <fnmatch.h>
+// FIXME for userdata
#include <boost/regex.hpp>
// split
#include <boost/algorithm/string.hpp>
using snapper::CodeLocation;
#include "client/commands.h"
#include "client/errors.h"
-#include "snapper/XmlFile.h"
#include "zypp_commit_plugin.h"
+#include "solvable_matcher.h"
ostream& operator <<(ostream& os, set<string> ss) {
bool seen_first = false;
class SnapperZyppPlugin : public ZyppCommitPlugin {
public:
- struct SolvableMatcher {
- enum class Kind {
- GLOB,
- REGEX
- };
- string pattern;
- Kind kind;
- bool important;
-
- SolvableMatcher(const string& apattern, Kind akind, bool aimportant)
- : pattern(apattern)
- , kind(akind)
- , important(aimportant)
- {}
-
- bool match(const string& solvable) {
- cerr << "DEBUG:" << "match? " << solvable << " by " << ((kind == Kind::GLOB)? "GLOB '": "REGEX '") << pattern << '\'' << endl;
- bool res;
- if (kind == Kind::GLOB) {
- static const int flags = 0;
- res = fnmatch(pattern.c_str(), solvable.c_str(), flags) == 0;
- }
- else {
- // POSIX Extended Regular Expression Syntax
- boost::regex rx_pattern(pattern, boost::regex::extended);
- res = boost::regex_match(solvable, rx_pattern);
- }
- cerr << "DEBUG:" << "-> " << res << endl;
- return res;
- }
-
- static vector<SolvableMatcher> load_config(const string& cfg_filename) {
- vector<SolvableMatcher> result;
-
- cerr << "DEBUG:" << "parsing " << cfg_filename << endl;
- XmlFile config(cfg_filename);
- // FIXME test parse errors
- const xmlNode* root = config.getRootElement();
- const xmlNode* solvables_n = getChildNode(root, "solvables");
- const list<const xmlNode*> solvables_l = getChildNodes(solvables_n, "solvable");
- for (auto node: solvables_l) {
- string pattern;
- Kind kind;
- bool important = false;
-
- getAttributeValue(node, "important", important);
- string kind_s;
- getAttributeValue(node, "match", kind_s);
- getValue(node, pattern);
- if (kind_s == "w") { // w for wildcard
- kind = Kind::GLOB;
- }
- else if (kind_s == "re") { // Regular Expression
- kind = Kind::REGEX;
- }
- else {
- cerr << "ERROR:" << "Unknown match attribute '" << kind_s << "', disregarding pattern '"<< pattern << "'" << endl;
- continue;
- }
-
- result.emplace_back(SolvableMatcher(pattern, kind, important));
- }
- return result;
- }
- };
-
SnapperZyppPlugin(const ProgramOptions& opts)
: snapper_cfg(opts.snapper_config)
, dbus_conn(opts.bus)
--- /dev/null
+#include "solvable_matcher.h"
+
+#include <iostream>
+#include <vector>
+#include <string>
+using namespace std;
+
+// fnmatch
+#include <fnmatch.h>
+#include <boost/regex.hpp>
+#include "snapper/XmlFile.h"
+using namespace snapper;
+
+std::ostream& SolvableMatcher::log = std::cerr;
+
+bool SolvableMatcher::match(const string& solvable) const {
+ log << "DEBUG:"
+ << "match? " << solvable
+ << " by " << ((kind == Kind::GLOB)? "GLOB '": "REGEX '")
+ << pattern << '\'' << endl;
+ bool res;
+ if (kind == Kind::GLOB) {
+ static const int flags = 0;
+ res = fnmatch(pattern.c_str(), solvable.c_str(), flags) == 0;
+ }
+ else {
+ // POSIX Extended Regular Expression Syntax
+ boost::regex rx_pattern(pattern, boost::regex::extended);
+ res = boost::regex_match(solvable, rx_pattern);
+ }
+ log << "DEBUG:" << "-> " << res << endl;
+ return res;
+}
+
+vector<SolvableMatcher> SolvableMatcher::load_config(const string& cfg_filename) {
+ vector<SolvableMatcher> result;
+
+ log << "DEBUG:" << "parsing " << cfg_filename << endl;
+ XmlFile config(cfg_filename);
+ const xmlNode* root = config.getRootElement();
+ const xmlNode* solvables_n = getChildNode(root, "solvables");
+ const list<const xmlNode*> solvables_l = getChildNodes(solvables_n, "solvable");
+ for (auto node: solvables_l) {
+ string pattern;
+ Kind kind;
+ bool important = false;
+
+ getAttributeValue(node, "important", important);
+ string kind_s;
+ getAttributeValue(node, "match", kind_s);
+ getValue(node, pattern);
+ if (kind_s == "w") { // w for wildcard
+ kind = Kind::GLOB;
+ }
+ else if (kind_s == "re") { // Regular Expression
+ kind = Kind::REGEX;
+ }
+ else {
+ log << "ERROR:" << "Unknown match attribute '" << kind_s << "', disregarding pattern '"<< pattern << "'" << endl;
+ continue;
+ }
+
+ result.emplace_back(SolvableMatcher(pattern, kind, important));
+ }
+ return result;
+}
+
--- /dev/null
+#include <iostream>
+#include <vector>
+#include <string>
+
+struct SolvableMatcher {
+ enum class Kind {
+ GLOB,
+ REGEX
+ };
+ std::string pattern;
+ Kind kind;
+ bool important;
+
+ static std::ostream& log;
+ SolvableMatcher(const std::string& apattern, Kind akind, bool aimportant)
+ : pattern(apattern)
+ , kind(akind)
+ , important(aimportant)
+ {}
+
+ bool match(const std::string& solvable) const;
+ static std::vector<SolvableMatcher> load_config(const std::string& cfg_filename);
+};