From 3217f711223760aef451aa5931c5ceaa465047eb Mon Sep 17 00:00:00 2001
From: Dan Goodliffe <dan@randomdan.homeip.net>
Date: Thu, 26 May 2016 20:50:52 +0100
Subject: Updates to dependency scanner based on real world data

---
 gentoobrowse-api/service/depend.cpp       | 14 +++++-----
 gentoobrowse-api/unittests/testDepend.cpp | 46 +++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 7 deletions(-)

diff --git a/gentoobrowse-api/service/depend.cpp b/gentoobrowse-api/service/depend.cpp
index fad6b64..6851eea 100644
--- a/gentoobrowse-api/service/depend.cpp
+++ b/gentoobrowse-api/service/depend.cpp
@@ -1,7 +1,7 @@
 #include "depend.h"
 #include <boost/algorithm/string/split.hpp>
 
-Gentoo::Utils::Lexer::PatternPtr WhenUse_Begin(Gentoo::Utils::Lexer::regex("\\s*(!?[[:alnum:]-_]+)\\?\\s*\\(\\s*", G_REGEX_OPTIMIZE));
+Gentoo::Utils::Lexer::PatternPtr WhenUse_Begin(Gentoo::Utils::Lexer::regex("\\s*(!?[[:alnum:]-_@]+)\\?\\s*\\(\\s*", G_REGEX_OPTIMIZE));
 Gentoo::Utils::Lexer::PatternPtr WhenUse_End(Gentoo::Utils::Lexer::regex("\\s*\\)\\s*", G_REGEX_OPTIMIZE));
 Gentoo::Utils::Lexer::PatternPtr Or_Begin(Gentoo::Utils::Lexer::regex("\\s*\\|\\|\\s*\\(\\s*", G_REGEX_OPTIMIZE));
 Gentoo::Utils::Lexer::PatternPtr Or_Group(Gentoo::Utils::Lexer::regex("\\s*\\(\\s*", G_REGEX_OPTIMIZE));
@@ -9,8 +9,8 @@ Gentoo::Utils::Lexer::PatternPtr Or_End(Gentoo::Utils::Lexer::regex("\\s*\\)\\s*
 Gentoo::Utils::Lexer::PatternPtr AtomSpec(Gentoo::Utils::Lexer::regex("\\s*"
 		"([[:punct:]]+)?" // op
 		"([[:alnum:]-]+)\\/" // cat
-		"(((-?[[:alpha:]]+[[:digit:]]+)|[[:alpha:]_+]|(-[[:alpha:]]))+)" // package
-		"(-([0-9][.0-9]*[[:alpha:]]?\\*?(_(alpha|beta|pre|rc|p))?[[:digit:]]*(-r[[:digit:]]+)?))?" // version
+		"([[:alnum:]]*((-?[[:alpha:]_+]+[[:digit:]]+)|[[:alpha:]_+]|(-[[:alpha:]_+]))+)" // package
+		"(-([0-9][.0-9]*[[:alpha:]]?\\*?((_(alpha|beta|pre|rc|p))?[[:digit:]]*)*(-r[[:digit:]]+)?))?" // version
 		"(:([^/ []+(\\/[^ []+)?))?" // slot
 		"(\\[([^]]+)\\])?\\s*", G_REGEX_OPTIMIZE)); // use
 
@@ -53,8 +53,8 @@ namespace Portage {
 			rules.push_back({ { InitialState, InWhen, InOr }, Or_Begin, [this](auto es) {
 					es->pushState(InOr);
 				} });
-			// || (
-			rules.push_back({ { InOr }, Or_Group, [this](auto es) {
+			// (
+			rules.push_back({ { InitialState, InWhen, InOr }, Or_Group, [this](auto es) {
 					es->pushState(InOr);
 				} });
 			// )
@@ -69,8 +69,8 @@ namespace Portage {
 							*es->pattern->match(2), // category
 							*es->pattern->match(3), // package
 							iuo<std::string>(es->pattern->match(8)), // version
-							iuo<std::string>(es->pattern->match(13)), // slot
-							split<std::string>(es->pattern->match(16)) // use
+							iuo<std::string>(es->pattern->match(14)), // slot
+							split<std::string>(es->pattern->match(17)) // use
 						));
 				} });
 		}
diff --git a/gentoobrowse-api/unittests/testDepend.cpp b/gentoobrowse-api/unittests/testDepend.cpp
index 15b4cf3..646b593 100644
--- a/gentoobrowse-api/unittests/testDepend.cpp
+++ b/gentoobrowse-api/unittests/testDepend.cpp
@@ -262,3 +262,49 @@ BOOST_AUTO_TEST_CASE( annoyed1 )
 	BOOST_REQUIRE(ds[0]->use.empty());
 }
 
+BOOST_AUTO_TEST_CASE( freeciv )
+{
+	auto ds = Portage::Utils::Depend::parse("app-arch/bzip2 app-arch/xz-utils net-misc/curl sys-libs/zlib auth? ( mysql? ( virtual/mysql ) sqlite? ( dev-db/sqlite:3 ) !mysql? ( ( !sqlite? ( virtual/mysql ) ) ) ) readline? ( sys-libs/readline:0 ) dedicated? ( aimodules? ( dev-libs/libltdl:0 ) ) !dedicated? ( media-libs/libpng:0 gtk? ( x11-libs/gtk+:2 ) mapimg? ( media-gfx/imagemagick ) modpack? ( x11-libs/gtk+:2 ) nls? ( virtual/libintl ) qt5? ( dev-qt/qtcore:5 dev-qt/qtgui:5 dev-qt/qtwidgets:5 ) sdl? ( media-libs/libsdl[video] media-libs/sdl-gfx media-libs/sdl-image[png] media-libs/sdl-ttf ) server? ( aimodules? ( sys-devel/libtool:2 ) ) sound? ( media-libs/libsdl[sound] media-libs/sdl-mixer[vorbis] ) !sdl? ( !gtk? ( x11-libs/gtk+:2 ) ) ) system-lua? ( >=dev-lang/lua-5.2 ) games-misc/games-envd");
+	BOOST_REQUIRE_EQUAL(ds.size(), 27);
+}
+
+BOOST_AUTO_TEST_CASE( useWithAtSymble )
+{
+	auto ds = Portage::Utils::Depend::parse("some@thing? ( app-arch/bzip2 )");
+	BOOST_REQUIRE_EQUAL(ds.size(), 1);
+	BOOST_REQUIRE_EQUAL(ds[0]->when.size(), 1);
+	BOOST_REQUIRE_EQUAL(ds[0]->when.front(), "some@thing");
+}
+
+BOOST_AUTO_TEST_CASE( underscoreInPackage )
+{
+	auto ds = Portage::Utils::Depend::parse(">=dev-ros/costmap_2d-1.13.1");
+	BOOST_REQUIRE_EQUAL(ds.size(), 1);
+	BOOST_REQUIRE_EQUAL(ds[0]->category, "dev-ros");
+	BOOST_REQUIRE_EQUAL(ds[0]->package, "costmap_2d");
+	BOOST_REQUIRE(ds[0]->version);
+	BOOST_REQUIRE_EQUAL(*ds[0]->version, "1.13.1");
+}
+
+BOOST_AUTO_TEST_CASE( multipleSuffix )
+{
+	auto ds = Portage::Utils::Depend::parse(">=sys-fs/btrfs-progs-0.20_rc1_p358");
+	BOOST_REQUIRE_EQUAL(ds.size(), 1);
+	BOOST_REQUIRE_EQUAL(ds[0]->category, "sys-fs");
+	BOOST_REQUIRE_EQUAL(ds[0]->package, "btrfs-progs");
+	BOOST_REQUIRE(ds[0]->version);
+	BOOST_REQUIRE_EQUAL(*ds[0]->version, "0.20_rc1_p358");
+}
+
+BOOST_AUTO_TEST_CASE( thisThing )
+{
+	auto ds = Portage::Utils::Depend::parse("!<=dev-libs/9libs-1.0");
+	BOOST_REQUIRE_EQUAL(ds.size(), 1);
+	BOOST_REQUIRE(ds[0]->op);
+	BOOST_REQUIRE_EQUAL(*ds[0]->op, "!<=");
+	BOOST_REQUIRE_EQUAL(ds[0]->category, "dev-libs");
+	BOOST_REQUIRE_EQUAL(ds[0]->package, "9libs");
+	BOOST_REQUIRE(ds[0]->version);
+	BOOST_REQUIRE_EQUAL(*ds[0]->version, "1.0");
+}
+
-- 
cgit v1.2.3