aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-06-29 18:50:07 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-06-29 18:50:07 +0100
commitec5b581973d0b67e4453af44c29b0a5aba430f74 (patch)
treea0f8dfecacb8c9460c666964a29c8ed8012277fb
parent9f5dd6443650cc3bf322a8878d35249364ac4520 (diff)
downloadpaludis-ec5b581973d0b67e4453af44c29b0a5aba430f74.tar.gz
paludis-ec5b581973d0b67e4453af44c29b0a5aba430f74.tar.xz
cave search -tregex
Fixes: ticket:852
-rw-r--r--configure.ac3
-rw-r--r--src/clients/cave/Makefile.am7
-rw-r--r--src/clients/cave/cmd_match.cc42
-rw-r--r--src/clients/cave/cmd_search_cmdline.cc3
-rw-r--r--src/clients/cave/match_extras.cc35
-rw-r--r--src/clients/cave/match_extras.hh28
6 files changed, 116 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac
index fc17726..6e32d42 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1443,6 +1443,7 @@ fi
if echo $clients | tr ' ' '\n' | grep '^cave$' >/dev/null ; then
need_resolver=yes
+ need_pcrecpp_check=yes
fi
dnl }}}
@@ -1470,7 +1471,7 @@ dnl }}}
dnl {{{ pcrecpp check
if test "x$need_pcrecpp_check" = "xyes" ; then
PKG_CHECK_MODULES(PCRECPPDEPS, [libpcrecpp >= 7.8], [],
- [AC_MSG_ERROR([pcrecpp (http://www.pcre.org/) is required if --with-clients=inquisitio is used])])
+ [AC_MSG_ERROR([pcrecpp (http://www.pcre.org/) is required if --with-clients=inquisitio or --with-clients=cave is used])])
AC_SUBST(PCRECPPDEPS_CFLAGS)
AC_SUBST(PCRECPPDEPS_LIBS)
fi
diff --git a/src/clients/cave/Makefile.am b/src/clients/cave/Makefile.am
index 62b9ebb..0b7189e 100644
--- a/src/clients/cave/Makefile.am
+++ b/src/clients/cave/Makefile.am
@@ -165,3 +165,10 @@ EXTRA_DIST = \
DISTCLEANFILES = $(man_MANS) $(noinst_DATA)
+lib_LTLIBRARIES = libcavematchextras_@PALUDIS_PC_SLOT@.la
+
+libcavematchextras_@PALUDIS_PC_SLOT@_la_SOURCES = match_extras.cc match_extras.hh
+libcavematchextras_@PALUDIS_PC_SLOT@_la_CXXFLAGS = $(AM_CXXFLAGS) @PCRECPPDEPS_CFLAGS@
+libcavematchextras_@PALUDIS_PC_SLOT@_la_LIBADD = @PCRECPPDEPS_LIBS@
+libcavematchextras_@PALUDIS_PC_SLOT@_la_LDFLAGS = -version-info @VERSION_LIB_CURRENT@:@VERSION_LIB_REVISION@:0
+
diff --git a/src/clients/cave/cmd_match.cc b/src/clients/cave/cmd_match.cc
index 11e58fd..fac9659 100644
--- a/src/clients/cave/cmd_match.cc
+++ b/src/clients/cave/cmd_match.cc
@@ -31,6 +31,7 @@
#include <paludis/util/indirect_iterator-impl.hh>
#include <paludis/util/simple_visitor_cast.hh>
#include <paludis/util/iterator_funcs.hh>
+#include <paludis/util/instantiation_policy-impl.hh>
#include <paludis/generator.hh>
#include <paludis/filtered_generator.hh>
#include <paludis/filter.hh>
@@ -41,12 +42,16 @@
#include <paludis/mask.hh>
#include <paludis/metadata_key.hh>
#include <paludis/choice.hh>
+#include <paludis/about.hh>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <list>
#include <string.h>
+#include <dlfcn.h>
+#include <stdint.h>
+#include "config.h"
#include "command_command_line.hh"
using namespace paludis;
@@ -54,8 +59,38 @@ using namespace cave;
using std::cout;
using std::endl;
+#define STUPID_CAST(type, val) reinterpret_cast<type>(reinterpret_cast<uintptr_t>(val))
+
namespace
{
+ struct ExtrasHandle :
+ InstantiationPolicy<ExtrasHandle, instantiation_method::SingletonTag>
+ {
+ typedef bool (* MatchFunction)(const std::string &, const std::string &);
+
+ void * handle;
+ MatchFunction match_function;
+
+ ExtrasHandle() :
+ handle(0),
+ match_function(0)
+ {
+ handle = ::dlopen(("libcavematchextras_" + stringify(PALUDIS_PC_SLOT) + ".so").c_str(), RTLD_NOW | RTLD_GLOBAL);
+ if (! handle)
+ throw args::DoHelp("Regular expression match not available because dlopen said " + stringify(::dlerror()));
+
+ match_function = STUPID_CAST(MatchFunction, ::dlsym(handle, "cave_match_extras_match_regex"));
+ if (! match_function)
+ throw args::DoHelp("Regular expression match not available because dlsym said " + stringify(::dlerror()));
+ }
+
+ ~ExtrasHandle()
+ {
+ if (handle)
+ ::dlclose(handle);
+ }
+ };
+
struct MatchCommandLine :
CaveCommandCommandLine
{
@@ -94,12 +129,19 @@ namespace
return 0 == strcasecmp(text.c_str(), pattern.c_str());
}
+ bool match_regex(const std::string & text, const std::string & pattern)
+ {
+ return ExtrasHandle::get_instance()->match_function(text, pattern);
+ }
+
bool match(const std::string & text, const std::string & pattern, const std::string & algorithm)
{
if (algorithm == "text")
return match_text(text, pattern);
else if (algorithm == "exact")
return match_exact(text, pattern);
+ else if (algorithm == "regex")
+ return match_regex(text, pattern);
else
throw args::DoHelp("Unknown algoritm '" + algorithm + "'");
}
diff --git a/src/clients/cave/cmd_search_cmdline.cc b/src/clients/cave/cmd_search_cmdline.cc
index e861f53..89f58b4 100644
--- a/src/clients/cave/cmd_search_cmdline.cc
+++ b/src/clients/cave/cmd_search_cmdline.cc
@@ -36,7 +36,8 @@ SearchCommandLineMatchOptions::SearchCommandLineMatchOptions(args::ArgsHandler *
a_type(&g_pattern_options, "type", 't', "Specify which matching algorithm to use",
args::EnumArg::EnumArgOptions
("text", 't', "Match an exact text substring, ignoring case")
- ("exact", 'x', "Match only an entire exact string, ignoring case"),
+ ("exact", 'x', "Match only an entire exact string, ignoring case")
+ ("regex", 'r', "Match using pcre regular expressions, ignoring case"),
"text"
),
a_and(&g_pattern_options, "and", '&', "If multiple patterns are specified, require that "
diff --git a/src/clients/cave/match_extras.cc b/src/clients/cave/match_extras.cc
new file mode 100644
index 0000000..dacbccd
--- /dev/null
+++ b/src/clients/cave/match_extras.cc
@@ -0,0 +1,35 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2010 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "match_extras.hh"
+#include <paludis/args/do_help.hh>
+#include <pcrecpp.h>
+
+using namespace paludis;
+
+extern "C" bool
+cave_match_extras_match_regex(const std::string & text, const std::string & pattern_str)
+{
+ const pcrecpp::RE pattern(pattern_str, pcrecpp::RE_Options().set_caseless(true));
+ if (! pattern.error().empty())
+ throw args::DoHelp("Pattern '" + pattern_str + "' error: " + pattern.error());
+
+ return pattern.PartialMatch(text);
+}
+
diff --git a/src/clients/cave/match_extras.hh b/src/clients/cave/match_extras.hh
new file mode 100644
index 0000000..73812d3
--- /dev/null
+++ b/src/clients/cave/match_extras.hh
@@ -0,0 +1,28 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2010 Ciaran McCreesh
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_SRC_CLIENTS_CAVE_MATCH_EXTRAS_HH
+#define PALUDIS_GUARD_SRC_CLIENTS_CAVE_MATCH_EXTRAS_HH 1
+
+#include <paludis/util/attributes.hh>
+#include <string>
+
+extern "C" bool cave_match_extras_match_regex(const std::string &, const std::string &) PALUDIS_VISIBLE PALUDIS_ATTRIBUTE((warn_unused_result));
+
+#endif