Author: jkupec Date: Mon May 5 14:08:08 2008 New Revision: 9945 URL: http://svn.opensuse.org/viewcvs/zypp?rev=9945&view=rev Log: - support multiple search strings (ORed) Modified: trunk/libzypp/devel/devel.jkupec/poolquery.cc trunk/libzypp/tests/zypp/PoolQuery_test.cc trunk/libzypp/zypp/PoolQuery.cc Modified: trunk/libzypp/devel/devel.jkupec/poolquery.cc URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/devel/devel.jkupec/poolqu... ============================================================================== --- trunk/libzypp/devel/devel.jkupec/poolquery.cc (original) +++ trunk/libzypp/devel/devel.jkupec/poolquery.cc Mon May 5 14:08:08 2008 @@ -9,6 +9,7 @@ #include "zypp/RepoInfo.h" #include "zypp/Arch.h" #include "zypp/Pathname.h" +#include "zypp/base/Regex.h" using std::cout; using std::endl; @@ -46,14 +47,23 @@ int main (int argc, const char ** argv) { + // ./poolquery regex string + if (argc == 3) + { + str::regex regex(argv[1], REG_EXTENDED | REG_NOSUB | REG_NEWLINE | REG_ICASE); + cout << (str::regex_match(argv[2], regex) ? "" : "no") << "match" << endl; + } + init_pool(); PoolQuery q; - q.addAttribute(sat::SolvAttr::name, "novell"); - q.addAttribute(sat::SolvAttr::summary, "package management"); + q.addString("weather"); + q.addAttribute(sat::SolvAttr::name, "thunder"); + q.addAttribute(sat::SolvAttr::description, "storm"); + q.addKind(ResKind::package); + q.addRepo("factory"); std::for_each(q.begin(), q.end(), &result_cb); - - cout << q.size() << endl; +// cout << q.size() << endl; cout << q << endl; } Modified: trunk/libzypp/tests/zypp/PoolQuery_test.cc URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/tests/zypp/PoolQuery_test... ============================================================================== --- trunk/libzypp/tests/zypp/PoolQuery_test.cc (original) +++ trunk/libzypp/tests/zypp/PoolQuery_test.cc Mon May 5 14:08:08 2008 @@ -226,6 +226,20 @@ } +// match whole words +BOOST_AUTO_TEST_CASE(pool_query_007) +{ + cout << "****007***" << endl; + + PoolQuery q; + q.addString("zypp"); + q.addAttribute(sat::SolvAttr::name); + q.setMatchWord(); + + BOOST_CHECK(std::for_each(q.begin(), q.end(), PrintAndCount())._count == 2); +} + + // match by installed status (basically by system vs. repo) BOOST_AUTO_TEST_CASE(pool_query_050) { @@ -407,7 +421,7 @@ } ///////////////////////////////////////////////////////////////////////////// -// 4xx repo kind queries (addKind(ResKind)) +// 4xx kind queries (addKind(ResKind)) ///////////////////////////////////////////////////////////////////////////// BOOST_AUTO_TEST_CASE(pool_query_400) @@ -434,6 +448,88 @@ BOOST_CHECK(std::for_each(q.begin(), q.end(), PrintAndCount())._count == 8); } + +///////////////////////////////////////////////////////////////////////////// +// 5xx multiple string/attribute queries +///////////////////////////////////////////////////////////////////////////// + +// multiple strings for one attribute +BOOST_AUTO_TEST_CASE(pool_query_500) +{ + cout << "****500.1****" << endl; + PoolQuery q; + q.addString("zypper"); + q.addString("apt"); + q.addAttribute(sat::SolvAttr::name); + q.setMatchExact(); + // creates: ^(apt|zypper)$ + BOOST_CHECK(std::for_each(q.begin(), q.end(), PrintAndCount())._count == 8); + + cout << "****500.2****" << endl; + q.addString("*zy?p"); + q.setMatchGlob(); + // creates: ^(.*zy.p|apt|zypper)$ + BOOST_CHECK(std::for_each(q.begin(), q.end(), PrintAndCount())._count == 16); + + cout << "****500.3****" << endl; + PoolQuery q1; + q1.addString("^libsm[a-z]*[0-9]$"); + q1.addAttribute(sat::SolvAttr::name, "os.libs$"); + q1.addKind(ResKind::package); + q1.setMatchRegex(); + // creates: (^libsm[a-z]*[0-9]$|os.libs$) + BOOST_CHECK(std::for_each(q1.begin(), q1.end(), PrintAndCount())._count == 3); + + cout << "****500.4****" << endl; + PoolQuery q2; + q2.addString("thunder"); + q2.addAttribute(sat::SolvAttr::name, "sun"); + q2.addKind(ResKind::package); + q2.addRepo("factory"); + q2.setCaseSensitive(); + // creates: (sun|thunder) + BOOST_CHECK(std::for_each(q2.begin(), q2.end(), PrintAndCount())._count == 2); + + cout << "****500.5****" << endl; + PoolQuery q3; + q3.addString("zypp"); + q3.addAttribute(sat::SolvAttr::name, "zip"); + q3.addKind(ResKind::package); + q3.addRepo("factory"); + q3.setMatchWord(); + // creates: \b(zip|zypp)\b + BOOST_CHECK(std::for_each(q3.begin(), q3.end(), PrintAndCount())._count == 4); +} + +// multiple strings, multiple attributes, same strings +BOOST_AUTO_TEST_CASE(pool_query_501) +{ + cout << "****501****" << endl; + PoolQuery q; + q.addString("thunder"); + q.addString("storm"); + q.addAttribute(sat::SolvAttr::name); + q.addAttribute(sat::SolvAttr::description); + q.addKind(ResKind::package); + q.addRepo("factory"); + + BOOST_CHECK(std::for_each(q.begin(), q.end(), PrintAndCount())._count == 14); +} + +// multiple strings, multiple attributes, same strings +BOOST_AUTO_TEST_CASE(pool_query_502) +{ + cout << "****502****" << endl; + PoolQuery q; + q.addString("weather"); + q.addAttribute(sat::SolvAttr::name, "thunder"); + q.addAttribute(sat::SolvAttr::description, "storm"); + q.addKind(ResKind::package); + q.addRepo("factory"); + + BOOST_CHECK(std::for_each(q.begin(), q.end(), PrintAndCount())._count == 14); +} + /* BOOST_AUTO_TEST_CASE(pool_query_X) { Modified: trunk/libzypp/zypp/PoolQuery.cc URL: http://svn.opensuse.org/viewcvs/zypp/trunk/libzypp/zypp/PoolQuery.cc?rev=994... ============================================================================== --- trunk/libzypp/zypp/PoolQuery.cc (original) +++ trunk/libzypp/zypp/PoolQuery.cc Mon May 5 14:08:08 2008 @@ -161,6 +161,12 @@ invokeOnEach(_attrs.begin()->second.begin(), _attrs.begin()->second.end(), EmptyFilter(), MyInserter(joined)); _rcstrings = createRegex(joined); _rcattrs.insert(pair<sat::SolvAttr, string>(_attrs.begin()->first, string())); + // switch to regex for multiple strings + if (joined.size() > 1) + _cflags = (_cflags & ~SEARCH_STRINGMASK) | SEARCH_REGEX; + if ((_cflags & SEARCH_STRINGMASK) == SEARCH_REGEX) + /* We feed multiple lines eventually (e.g. authors or descriptions), so set REG_NEWLINE. */ + _regex = str::regex(_rcstrings, REG_EXTENDED | REG_NOSUB | REG_NEWLINE | (_cflags & SEARCH_NOCASE ? REG_ICASE : 0)); } // // MULTIPLE ATTRIBUTES @@ -220,6 +226,10 @@ for_(ai, _attrs.begin(), _attrs.end()) _rcattrs.insert(pair<sat::SolvAttr, string>(ai->first, string())); + // switch to regex for multiple strings + if (joined.size() > 1) + _cflags = (_cflags & ~SEARCH_STRINGMASK) | SEARCH_REGEX; + if ((_cflags & SEARCH_STRINGMASK) == SEARCH_REGEX) /* We feed multiple lines eventually (e.g. authors or descriptions), so set REG_NEWLINE. */ _regex = str::regex(_rcstrings, REG_EXTENDED | REG_NOSUB | REG_NEWLINE | (_cflags & SEARCH_NOCASE ? REG_ICASE : 0)); @@ -238,7 +248,10 @@ invokeOnEach(ai->second.begin(), ai->second.end(), EmptyFilter(), MyInserter(joined)); string s = createRegex(joined); _rcattrs.insert(pair<sat::SolvAttr, string>(ai->first, s)); - + + // switch to regex for multiple strings + if (joined.size() > 1) + _cflags = (_cflags & ~SEARCH_STRINGMASK) | SEARCH_REGEX; if ((_cflags & SEARCH_STRINGMASK) == SEARCH_REGEX) { str::regex regex(s, REG_EXTENDED | REG_NOSUB | REG_NEWLINE | (_cflags & SEARCH_NOCASE ? REG_ICASE : 0)); @@ -257,6 +270,7 @@ DBG << asString() << endl; } + /** * Converts '*' and '?' wildcards within str into their regex equivalents. */ @@ -264,8 +278,6 @@ { string regexed = str; - str::regex all("\*"); // regex to search for '*' - str::regex one("\?"); // regex to search for '?' string r_all(".*"); // regex equivalent of '*' string r_one("."); // regex equivalent of '?' string::size_type pos; @@ -278,8 +290,6 @@ for (pos = 0; (pos = regexed.find('?', pos)) != std::string::npos; ++pos) regexed = regexed.replace(pos, 1, r_one); - DBG << " -> " << regexed << endl; - return regexed; } @@ -295,10 +305,7 @@ if (container.size() == 1) { - if (_match_word) - return ".*" + WB + *container.begin() + WB + ".*"; - - return *container.begin(); + return WB + *container.begin() + WB; } // multiple strings @@ -309,21 +316,22 @@ if (use_wildcards) tmp = wildcards2regex(*it); + else + tmp = *it; if (_require_all) { - if (!(_cflags & SEARCH_STRING)) // not match exact + if ((_cflags & SEARCH_STRINGMASK) != SEARCH_STRING) // not match exact tmp += ".*" + WB + tmp; rstr = "(?=" + tmp + ")"; } else { - if (_cflags & SEARCH_STRING) // match exact + if ((_cflags & SEARCH_STRINGMASK) == SEARCH_STRING || // match exact + (_cflags & SEARCH_STRINGMASK) == SEARCH_GLOB) // match glob rstr = "^"; - else - rstr = ".*" + WB; - rstr += "(" + tmp; + rstr += WB + "(" + tmp; } ++it; @@ -332,10 +340,12 @@ { if (use_wildcards) tmp = wildcards2regex(*it); + else + tmp = *it; if (_require_all) { - if (!(_cflags & SEARCH_STRING)) // not match exact + if ((_cflags & SEARCH_STRINGMASK) != SEARCH_STRING) // not match exact tmp += ".*" + WB + tmp; rstr += "(?=" + tmp + ")"; } @@ -347,16 +357,15 @@ if (_require_all) { - if (!(_cflags & SEARCH_STRING)) // not match exact + if ((_cflags & SEARCH_STRINGMASK) != SEARCH_STRING) // not match exact rstr += WB + ".*"; } else { - rstr += ")"; - if (_cflags & SEARCH_STRING) // match exact + rstr += ")" + WB; + if ((_cflags & SEARCH_STRINGMASK) == SEARCH_STRING || // match exact + (_cflags & SEARCH_STRINGMASK) == SEARCH_GLOB) // match glob rstr += "$"; - else - rstr += WB + ".*"; } return rstr; @@ -668,6 +677,7 @@ } else regex_p = _regex.get(); + matches = ::dataiterator_match(base().get(), _flags, regex_p); } else @@ -680,8 +690,8 @@ // if (matches) /* After calling dataiterator_match (with any string matcher set) the kv.str member will be filled with something sensible. */ - /* INT << "value: " << base().get()->kv.str << endl - << " mstr: " << sstr << endl; */ + /*INT << "value: " << base().get()->kv.str << endl + << " str: " << _str << endl;*/ } } } -- To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org For additional commands, e-mail: zypp-commit+help@opensuse.org