replace gnu regex wrapper with boost::regex

This commit is contained in:
Andrzej Rybczak
2013-04-06 16:47:03 +02:00
parent 66bd3e9782
commit 2b5f1b9fd4
12 changed files with 226 additions and 310 deletions

View File

@@ -29,7 +29,6 @@ ncmpcpp_SOURCES = \
outputs.cpp \ outputs.cpp \
playlist.cpp \ playlist.cpp \
playlist_editor.cpp \ playlist_editor.cpp \
regexes.cpp \
screen.cpp \ screen.cpp \
screen_type.cpp \ screen_type.cpp \
scrollpad.cpp \ scrollpad.cpp \
@@ -86,7 +85,6 @@ noinst_HEADERS = \
playlist_editor.h \ playlist_editor.h \
proxy_song_list.h \ proxy_song_list.h \
regex_filter.h \ regex_filter.h \
regexes.h \
screen.h \ screen.h \
screen_switcher.h \ screen_switcher.h \
screen_type.h \ screen_type.h \

View File

@@ -61,7 +61,7 @@ std::set<std::string> SupportedExtensions;
bool hasSupportedExtension(const std::string &file); bool hasSupportedExtension(const std::string &file);
std::string ItemToString(const MPD::Item &item); std::string ItemToString(const MPD::Item &item);
bool BrowserEntryMatcher(const Regex &rx, const MPD::Item &item, bool filter); bool BrowserEntryMatcher(const boost::regex &rx, const MPD::Item &item, bool filter);
} }
@@ -258,10 +258,15 @@ std::string Browser::currentFilter()
void Browser::applyFilter(const std::string &filter) void Browser::applyFilter(const std::string &filter)
{ {
w.showAll(); try
auto fun = std::bind(BrowserEntryMatcher, _1, _2, true); {
auto rx = RegexFilter<MPD::Item>(filter, Config.regex_type, fun); w.showAll();
w.filter(w.begin(), w.end(), rx); auto fun = std::bind(BrowserEntryMatcher, _1, _2, true);
auto rx = RegexFilter<MPD::Item>(
boost::regex(filter, Config.regex_type), fun);
w.filter(w.begin(), w.end(), rx);
}
catch (boost::bad_expression &) { }
} }
/***********************************************************************/ /***********************************************************************/
@@ -273,9 +278,17 @@ bool Browser::allowsSearching()
bool Browser::search(const std::string &constraint) bool Browser::search(const std::string &constraint)
{ {
auto fun = std::bind(BrowserEntryMatcher, _1, _2, false); try
auto rx = RegexFilter<MPD::Item>(constraint, Config.regex_type, fun); {
return w.search(w.begin(), w.end(), rx); auto fun = std::bind(BrowserEntryMatcher, _1, _2, false);
auto rx = RegexFilter<MPD::Item>(
boost::regex(constraint, Config.regex_type), fun);
return w.search(w.begin(), w.end(), rx);
}
catch (boost::bad_expression &)
{
return false;
}
} }
void Browser::nextFound(bool wrap) void Browser::nextFound(bool wrap)
@@ -614,11 +627,11 @@ std::string ItemToString(const MPD::Item &item)
return result; return result;
} }
bool BrowserEntryMatcher(const Regex &rx, const MPD::Item &item, bool filter) bool BrowserEntryMatcher(const boost::regex &rx, const MPD::Item &item, bool filter)
{ {
if (Browser::isParentDirectory(item)) if (Browser::isParentDirectory(item))
return filter; return filter;
return rx.match(ItemToString(item)); return boost::regex_search(ItemToString(item), rx);
} }
} }

View File

@@ -61,9 +61,9 @@ typedef MediaLibrary::AlbumEntry AlbumEntry;
std::string AlbumToString(const AlbumEntry &ae); std::string AlbumToString(const AlbumEntry &ae);
std::string SongToString(const MPD::Song &s); std::string SongToString(const MPD::Song &s);
bool TagEntryMatcher(const Regex &rx, const MediaLibrary::PrimaryTag &tagmtime); bool TagEntryMatcher(const boost::regex &rx, const MediaLibrary::PrimaryTag &tagmtime);
bool AlbumEntryMatcher(const Regex &rx, const NC::Menu<AlbumEntry>::Item &item, bool filter); bool AlbumEntryMatcher(const boost::regex &rx, const NC::Menu<AlbumEntry>::Item &item, bool filter);
bool SongEntryMatcher(const Regex &rx, const MPD::Song &s); bool SongEntryMatcher(const boost::regex &rx, const MPD::Song &s);
struct SortSongs { struct SortSongs {
typedef NC::Menu<MPD::Song>::Item SongItem; typedef NC::Menu<MPD::Song>::Item SongItem;
@@ -563,25 +563,32 @@ std::string MediaLibrary::currentFilter()
void MediaLibrary::applyFilter(const std::string &filter) void MediaLibrary::applyFilter(const std::string &filter)
{ {
if (isActiveWindow(Tags)) try
{ {
Tags.showAll(); if (isActiveWindow(Tags))
auto rx = RegexFilter<PrimaryTag>(filter, Config.regex_type, TagEntryMatcher); {
Tags.filter(Tags.begin(), Tags.end(), rx); Tags.showAll();
} auto rx = RegexFilter<PrimaryTag>(
else if (isActiveWindow(Albums)) boost::regex(filter, Config.regex_type), TagEntryMatcher);
{ Tags.filter(Tags.begin(), Tags.end(), rx);
Albums.showAll(); }
auto fun = std::bind(AlbumEntryMatcher, _1, _2, true); else if (isActiveWindow(Albums))
auto rx = RegexItemFilter<AlbumEntry>(filter, Config.regex_type, fun); {
Albums.filter(Albums.begin(), Albums.end(), rx); Albums.showAll();
} auto fun = std::bind(AlbumEntryMatcher, _1, _2, true);
else if (isActiveWindow(Songs)) auto rx = RegexItemFilter<AlbumEntry>(
{ boost::regex(filter, Config.regex_type), fun);
Songs.showAll(); Albums.filter(Albums.begin(), Albums.end(), rx);
auto rx = RegexFilter<MPD::Song>(filter, Config.regex_type, SongEntryMatcher); }
Songs.filter(Songs.begin(), Songs.end(), rx); else if (isActiveWindow(Songs))
{
Songs.showAll();
auto rx = RegexFilter<MPD::Song>(
boost::regex(filter, Config.regex_type), SongEntryMatcher);
Songs.filter(Songs.begin(), Songs.end(), rx);
}
} }
catch (boost::bad_expression &) { }
} }
/***********************************************************************/ /***********************************************************************/
@@ -593,24 +600,34 @@ bool MediaLibrary::allowsSearching()
bool MediaLibrary::search(const std::string &constraint) bool MediaLibrary::search(const std::string &constraint)
{ {
bool result = false; try
if (isActiveWindow(Tags))
{ {
auto rx = RegexFilter<PrimaryTag>(constraint, Config.regex_type, TagEntryMatcher); bool result = false;
result = Tags.search(Tags.begin(), Tags.end(), rx); if (isActiveWindow(Tags))
{
auto rx = RegexFilter<PrimaryTag>(
boost::regex(constraint, Config.regex_type), TagEntryMatcher);
result = Tags.search(Tags.begin(), Tags.end(), rx);
}
else if (isActiveWindow(Albums))
{
auto fun = std::bind(AlbumEntryMatcher, _1, _2, false);
auto rx = RegexItemFilter<AlbumEntry>(
boost::regex(constraint, Config.regex_type), fun);
result = Albums.search(Albums.begin(), Albums.end(), rx);
}
else if (isActiveWindow(Songs))
{
auto rx = RegexFilter<MPD::Song>(
boost::regex(constraint, Config.regex_type), SongEntryMatcher);
result = Songs.search(Songs.begin(), Songs.end(), rx);
}
return result;
} }
else if (isActiveWindow(Albums)) catch (boost::bad_expression &)
{ {
auto fun = std::bind(AlbumEntryMatcher, _1, _2, false); return false;
auto rx = RegexItemFilter<AlbumEntry>(constraint, Config.regex_type, fun);
result = Albums.search(Albums.begin(), Albums.end(), rx);
} }
else if (isActiveWindow(Songs))
{
auto rx = RegexFilter<MPD::Song>(constraint, Config.regex_type, SongEntryMatcher);
result = Songs.search(Songs.begin(), Songs.end(), rx);
}
return result;
} }
void MediaLibrary::nextFound(bool wrap) void MediaLibrary::nextFound(bool wrap)
@@ -1010,21 +1027,21 @@ std::string SongToString(const MPD::Song &s)
return s.toString(Config.song_library_format, Config.tags_separator); return s.toString(Config.song_library_format, Config.tags_separator);
} }
bool TagEntryMatcher(const Regex &rx, const MediaLibrary::PrimaryTag &pt) bool TagEntryMatcher(const boost::regex &rx, const MediaLibrary::PrimaryTag &pt)
{ {
return rx.match(pt.tag()); return boost::regex_search(pt.tag(), rx);
} }
bool AlbumEntryMatcher(const Regex &rx, const NC::Menu<AlbumEntry>::Item &item, bool filter) bool AlbumEntryMatcher(const boost::regex &rx, const NC::Menu<AlbumEntry>::Item &item, bool filter)
{ {
if (item.isSeparator() || item.value().isAllTracksEntry()) if (item.isSeparator() || item.value().isAllTracksEntry())
return filter; return filter;
return rx.match(AlbumToString(item.value())); return boost::regex_search(AlbumToString(item.value()), rx);
} }
bool SongEntryMatcher(const Regex &rx, const MPD::Song &s) bool SongEntryMatcher(const boost::regex &rx, const MPD::Song &s)
{ {
return rx.match(SongToString(s)); return boost::regex_search(SongToString(s), rx);
} }
} }

View File

@@ -47,7 +47,7 @@ bool Playlist::ReloadRemaining = false;
namespace {// namespace {//
std::string songToString(const MPD::Song &s); std::string songToString(const MPD::Song &s);
bool playlistEntryMatcher(const Regex &rx, const MPD::Song &s); bool playlistEntryMatcher(const boost::regex &rx, const MPD::Song &s);
} }
@@ -141,9 +141,14 @@ std::string Playlist::currentFilter()
void Playlist::applyFilter(const std::string &filter) void Playlist::applyFilter(const std::string &filter)
{ {
w.showAll(); try
auto rx = RegexFilter<MPD::Song>(filter, Config.regex_type, playlistEntryMatcher); {
w.filter(w.begin(), w.end(), rx); w.showAll();
auto rx = RegexFilter<MPD::Song>(
boost::regex(filter, Config.regex_type), playlistEntryMatcher);
w.filter(w.begin(), w.end(), rx);
}
catch (boost::bad_expression &) { }
} }
/***********************************************************************/ /***********************************************************************/
@@ -155,8 +160,16 @@ bool Playlist::allowsSearching()
bool Playlist::search(const std::string &constraint) bool Playlist::search(const std::string &constraint)
{ {
auto rx = RegexFilter<MPD::Song>(constraint, Config.regex_type, playlistEntryMatcher); try
return w.search(w.begin(), w.end(), rx); {
auto rx = RegexFilter<MPD::Song>(
boost::regex(constraint, Config.regex_type), playlistEntryMatcher);
return w.search(w.begin(), w.end(), rx);
}
catch (boost::bad_expression &)
{
return false;
}
} }
void Playlist::nextFound(bool wrap) void Playlist::nextFound(bool wrap)
@@ -343,9 +356,9 @@ std::string songToString(const MPD::Song &s)
return result; return result;
} }
bool playlistEntryMatcher(const Regex &rx, const MPD::Song &s) bool playlistEntryMatcher(const boost::regex &rx, const MPD::Song &s)
{ {
return rx.match(songToString(s)); return boost::regex_search(songToString(s), rx);
} }
} }

View File

@@ -51,8 +51,8 @@ size_t RightColumnStartX;
size_t RightColumnWidth; size_t RightColumnWidth;
std::string SongToString(const MPD::Song &s); std::string SongToString(const MPD::Song &s);
bool PlaylistEntryMatcher(const Regex &rx, const std::string &playlist); bool PlaylistEntryMatcher(const boost::regex &rx, const std::string &playlist);
bool SongEntryMatcher(const Regex &rx, const MPD::Song &s); bool SongEntryMatcher(const boost::regex &rx, const MPD::Song &s);
} }
@@ -337,18 +337,24 @@ std::string PlaylistEditor::currentFilter()
void PlaylistEditor::applyFilter(const std::string &filter) void PlaylistEditor::applyFilter(const std::string &filter)
{ {
if (isActiveWindow(Playlists)) try
{ {
Playlists.showAll(); if (isActiveWindow(Playlists))
auto rx = RegexFilter<std::string>(filter, Config.regex_type, PlaylistEntryMatcher); {
Playlists.filter(Playlists.begin(), Playlists.end(), rx); Playlists.showAll();
} auto rx = RegexFilter<std::string>(
else if (isActiveWindow(Content)) boost::regex(filter, Config.regex_type), PlaylistEntryMatcher);
{ Playlists.filter(Playlists.begin(), Playlists.end(), rx);
Content.showAll(); }
auto rx = RegexFilter<MPD::Song>(filter, Config.regex_type, SongEntryMatcher); else if (isActiveWindow(Content))
Content.filter(Content.begin(), Content.end(), rx); {
Content.showAll();
auto rx = RegexFilter<MPD::Song>(
boost::regex(filter, Config.regex_type), SongEntryMatcher);
Content.filter(Content.begin(), Content.end(), rx);
}
} }
catch (boost::bad_expression &) { }
} }
/***********************************************************************/ /***********************************************************************/
@@ -360,18 +366,27 @@ bool PlaylistEditor::allowsSearching()
bool PlaylistEditor::search(const std::string &constraint) bool PlaylistEditor::search(const std::string &constraint)
{ {
bool result = false; try
if (isActiveWindow(Playlists))
{ {
auto rx = RegexFilter<std::string>(constraint, Config.regex_type, PlaylistEntryMatcher); bool result = false;
result = Playlists.search(Playlists.begin(), Playlists.end(), rx); if (isActiveWindow(Playlists))
{
auto rx = RegexFilter<std::string>(
boost::regex(constraint, Config.regex_type), PlaylistEntryMatcher);
result = Playlists.search(Playlists.begin(), Playlists.end(), rx);
}
else if (isActiveWindow(Content))
{
auto rx = RegexFilter<MPD::Song>(
boost::regex(constraint, Config.regex_type), SongEntryMatcher);
result = Content.search(Content.begin(), Content.end(), rx);
}
return result;
} }
else if (isActiveWindow(Content)) catch (boost::bad_expression &)
{ {
auto rx = RegexFilter<MPD::Song>(constraint, Config.regex_type, SongEntryMatcher); return false;
result = Content.search(Content.begin(), Content.end(), rx);
} }
return result;
} }
void PlaylistEditor::nextFound(bool wrap) void PlaylistEditor::nextFound(bool wrap)
@@ -523,14 +538,14 @@ std::string SongToString(const MPD::Song &s)
return result; return result;
} }
bool PlaylistEntryMatcher(const Regex &rx, const std::string &playlist) bool PlaylistEntryMatcher(const boost::regex &rx, const std::string &playlist)
{ {
return rx.match(playlist); return boost::regex_search(playlist, rx);
} }
bool SongEntryMatcher(const Regex &rx, const MPD::Song &s) bool SongEntryMatcher(const boost::regex &rx, const MPD::Song &s)
{ {
return rx.match(SongToString(s)); return boost::regex_search(SongToString(s), rx);
} }
} }

View File

@@ -21,23 +21,19 @@
#ifndef NCMPCPP_REGEX_FILTER_H #ifndef NCMPCPP_REGEX_FILTER_H
#define NCMPCPP_REGEX_FILTER_H #define NCMPCPP_REGEX_FILTER_H
#include <boost/regex.hpp>
#include "menu.h" #include "menu.h"
#include "regexes.h"
template <typename T> struct RegexFilter template <typename T> struct RegexFilter
{ {
typedef NC::Menu<T> MenuT; typedef NC::Menu<T> MenuT;
typedef typename NC::Menu<T>::Item Item; typedef typename NC::Menu<T>::Item Item;
typedef std::function<bool(const Regex &, const T &)> FilterFunction; typedef std::function<bool(const boost::regex &, const T &)> FilterFunction;
RegexFilter(const std::string &regex_, int cflags, FilterFunction filter) RegexFilter(boost::regex rx, FilterFunction filter)
: m_rx(regex_, cflags), m_filter(filter) { } : m_rx(rx), m_filter(filter) { }
bool operator()(const Item &item) { bool operator()(const Item &item) {
if (m_rx.regex().empty())
return true;
if (!m_rx.compiled() || !m_rx.error().empty())
return false;
return m_filter(m_rx, item.value()); return m_filter(m_rx, item.value());
} }
@@ -46,12 +42,12 @@ template <typename T> struct RegexFilter
std::string filter; std::string filter;
auto rf = menu.getFilter().template target< RegexFilter<T> >(); auto rf = menu.getFilter().template target< RegexFilter<T> >();
if (rf) if (rf)
filter = rf->m_rx.regex(); filter = rf->m_rx.str();
return filter; return filter;
} }
private: private:
Regex m_rx; boost::regex m_rx;
FilterFunction m_filter; FilterFunction m_filter;
}; };
@@ -59,16 +55,12 @@ template <typename T> struct RegexItemFilter
{ {
typedef NC::Menu<T> MenuT; typedef NC::Menu<T> MenuT;
typedef typename NC::Menu<T>::Item Item; typedef typename NC::Menu<T>::Item Item;
typedef std::function<bool(const Regex &, const Item &)> FilterFunction; typedef std::function<bool(const boost::regex &, const Item &)> FilterFunction;
RegexItemFilter(const std::string &regex_, int cflags, FilterFunction filter) RegexItemFilter(boost::regex rx, FilterFunction filter)
: m_rx(regex_, cflags), m_filter(filter) { } : m_rx(rx), m_filter(filter) { }
bool operator()(const Item &item) { bool operator()(const Item &item) {
if (m_rx.regex().empty())
return true;
if (!m_rx.compiled() || !m_rx.error().empty())
return false;
return m_filter(m_rx, item); return m_filter(m_rx, item);
} }
@@ -77,12 +69,12 @@ template <typename T> struct RegexItemFilter
std::string filter; std::string filter;
auto rf = menu.getFilter().template target< RegexItemFilter<T> >(); auto rf = menu.getFilter().template target< RegexItemFilter<T> >();
if (rf) if (rf)
filter = rf->m_rx.regex(); filter = rf->m_rx.str();
return filter; return filter;
} }
private: private:
Regex m_rx; boost::regex m_rx;
FilterFunction m_filter; FilterFunction m_filter;
}; };

View File

@@ -1,102 +0,0 @@
/***************************************************************************
* Copyright (C) 2008-2012 by Andrzej Rybczak *
* electricityispower@gmail.com *
* *
* 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. *
* *
* This program 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., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include <cassert>
#include "regexes.h"
Regex::Regex() : m_cflags(0), m_compiled(false) { }
Regex::Regex(const std::string &regex_, int cflags)
: m_regex(regex_), m_cflags(cflags), m_compiled(false)
{
compile();
}
Regex::Regex (const Regex &rhs)
: m_regex(rhs.m_regex), m_cflags(rhs.m_cflags), m_compiled(false)
{
if (rhs.m_compiled)
compile();
}
Regex::~Regex()
{
if (m_compiled)
regfree(&m_rx);
}
const std::string &Regex::regex() const
{
return m_regex;
}
const std::string &Regex::error() const
{
return m_error;
}
bool Regex::compiled() const
{
return m_compiled;
}
bool Regex::compile()
{
if (m_compiled)
{
m_error.clear();
regfree(&m_rx);
}
int comp_res = regcomp(&m_rx, m_regex.c_str(), m_cflags);
bool result = true;
if (comp_res != 0)
{
char buf[256];
regerror(comp_res, &m_rx, buf, sizeof(buf));
m_error = buf;
result = false;
}
m_compiled = result;
return result;
}
bool Regex::compile(const std::string &regex_, int cflags)
{
m_regex = regex_;
m_cflags = cflags;
return compile();
}
bool Regex::match(const std::string &s) const
{
assert(m_compiled);
return regexec(&m_rx, s.c_str(), 0, 0, 0) == 0;
}
Regex &Regex::operator=(const Regex &rhs)
{
if (this == &rhs)
return *this;
m_regex = rhs.m_regex;
m_cflags = rhs.m_cflags;
if (rhs.m_compiled)
compile();
return *this;
}

View File

@@ -1,65 +0,0 @@
/***************************************************************************
* Copyright (C) 2008-2012 by Andrzej Rybczak *
* electricityispower@gmail.com *
* *
* 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. *
* *
* This program 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., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef NCMPCPP_REGEXES_H
#define NCMPCPP_REGEXES_H
#include <regex.h>
#include <string>
struct Regex
{
Regex();
Regex(const std::string &regex, int cflags);
Regex(const Regex &rhs);
virtual ~Regex();
/// @return regular expression
const std::string &regex() const;
/// @return compilation error (if there was any)
const std::string &error() const;
/// @return true if regular expression is compiled, false otherwise
bool compiled() const;
/// compiles regular expression
/// @result true if compilation was successful, false otherwise
bool compile();
/// compiles regular expression
/// @result true if compilation was successful, false otherwise
bool compile(const std::string &regex, int cflags);
/// tries to match compiled regex with given string
/// @return true if string was matched, false otherwise
bool match(const std::string &s) const;
Regex &operator=(const Regex &rhs);
private:
std::string m_regex;
std::string m_error;
regex_t m_rx;
int m_cflags;
bool m_compiled;
};
#endif // NCMPCPP_REGEXES_H

View File

@@ -20,6 +20,7 @@
#include <array> #include <array>
#include <iomanip> #include <iomanip>
#include <regex.h>
#include "display.h" #include "display.h"
#include "global.h" #include "global.h"
@@ -71,7 +72,7 @@ namespace pos {//
}*/ }*/
std::string SEItemToString(const SEItem &ei); std::string SEItemToString(const SEItem &ei);
bool SEItemEntryMatcher(const Regex &rx, const NC::Menu<SEItem>::Item &item, bool filter); bool SEItemEntryMatcher(const boost::regex &rx, const NC::Menu<SEItem>::Item &item, bool filter);
} }
@@ -264,10 +265,15 @@ std::string SearchEngine::currentFilter()
void SearchEngine::applyFilter(const std::string &filter) void SearchEngine::applyFilter(const std::string &filter)
{ {
w.showAll(); try
auto fun = std::bind(SEItemEntryMatcher, _1, _2, true); {
auto rx = RegexItemFilter<SEItem>(filter, Config.regex_type, fun); w.showAll();
w.filter(w.begin(), w.end(), rx); auto fun = std::bind(SEItemEntryMatcher, _1, _2, true);
auto rx = RegexItemFilter<SEItem>(
boost::regex(filter, Config.regex_type), fun);
w.filter(w.begin(), w.end(), rx);
}
catch (boost::bad_expression &) { }
} }
/***********************************************************************/ /***********************************************************************/
@@ -279,9 +285,17 @@ bool SearchEngine::allowsSearching()
bool SearchEngine::search(const std::string &constraint) bool SearchEngine::search(const std::string &constraint)
{ {
auto fun = std::bind(SEItemEntryMatcher, _1, _2, false); try
auto rx = RegexItemFilter<SEItem>(constraint, Config.regex_type, fun); {
return w.search(w.begin(), w.end(), rx); auto fun = std::bind(SEItemEntryMatcher, _1, _2, false);
auto rx = RegexItemFilter<SEItem>(
boost::regex(constraint, Config.regex_type), fun);
return w.search(w.begin(), w.end(), rx);
}
catch (boost::bad_expression &)
{
return false;
}
} }
void SearchEngine::nextFound(bool wrap) void SearchEngine::nextFound(bool wrap)
@@ -574,11 +588,11 @@ std::string SEItemToString(const SEItem &ei)
return result; return result;
} }
bool SEItemEntryMatcher(const Regex &rx, const NC::Menu<SEItem>::Item &item, bool filter) bool SEItemEntryMatcher(const boost::regex &rx, const NC::Menu<SEItem>::Item &item, bool filter)
{ {
if (item.isSeparator() || !item.value().isSong()) if (item.isSeparator() || !item.value().isSong())
return filter; return filter;
return rx.match(SEItemToString(item.value())); return boost::regex_search(SEItemToString(item.value()), rx);
} }
} }

View File

@@ -228,7 +228,7 @@ void Configuration::SetDefaults()
playlist_disable_highlight_delay = 5; playlist_disable_highlight_delay = 5;
message_delay_time = 4; message_delay_time = 4;
lyrics_db = 0; lyrics_db = 0;
regex_type = REG_ICASE; regex_type = boost::regex::icase;
lines_scrolled = 2; lines_scrolled = 2;
search_engine_default_search_mode = 0; search_engine_default_search_mode = 0;
visualizer_sync_interval = 30; visualizer_sync_interval = 30;
@@ -782,8 +782,12 @@ void Configuration::Read()
} }
else if (name == "regular_expressions") else if (name == "regular_expressions")
{ {
if (v != "basic") if (v == "none")
regex_type |= REG_EXTENDED; regex_type |= boost::regex::literal;
else if (v == "basic")
regex_type |= boost::regex::basic;
else if (v == "extended")
regex_type |= boost::regex::extended;
} }
else if (name == "lines_scrolled") else if (name == "lines_scrolled")
{ {

View File

@@ -21,6 +21,7 @@
#ifndef NCMPCPP_SETTINGS_H #ifndef NCMPCPP_SETTINGS_H
#define NCMPCPP_SETTINGS_H #define NCMPCPP_SETTINGS_H
#include <boost/regex.hpp>
#include <cassert> #include <cassert>
#include <vector> #include <vector>
#include <mpd/client.h> #include <mpd/client.h>
@@ -193,7 +194,8 @@ struct Configuration
int playlist_disable_highlight_delay; int playlist_disable_highlight_delay;
int message_delay_time; int message_delay_time;
int lyrics_db; int lyrics_db;
int regex_type;
boost::regex::flag_type regex_type;
unsigned lines_scrolled; unsigned lines_scrolled;
unsigned search_engine_default_search_mode; unsigned search_engine_default_search_mode;

View File

@@ -81,8 +81,8 @@ std::string GenerateFilename(const MPD::MutableSong &s, const std::string &patte
std::string ParseFilename(MPD::MutableSong &s, std::string mask, bool preview); std::string ParseFilename(MPD::MutableSong &s, std::string mask, bool preview);
std::string SongToString(const MPD::MutableSong &s); std::string SongToString(const MPD::MutableSong &s);
bool DirEntryMatcher(const Regex &rx, const std::pair<std::string, std::string> &dir, bool filter); bool DirEntryMatcher(const boost::regex &rx, const std::pair<std::string, std::string> &dir, bool filter);
bool SongEntryMatcher(const Regex &rx, const MPD::MutableSong &s); bool SongEntryMatcher(const boost::regex &rx, const MPD::MutableSong &s);
} }
@@ -740,19 +740,25 @@ std::string TagEditor::currentFilter()
void TagEditor::applyFilter(const std::string &filter) void TagEditor::applyFilter(const std::string &filter)
{ {
if (w == Dirs) try
{ {
Dirs->showAll(); if (w == Dirs)
auto fun = std::bind(DirEntryMatcher, _1, _2, true); {
auto rx = RegexFilter< std::pair<std::string, std::string> >(filter, Config.regex_type, fun); Dirs->showAll();
Dirs->filter(Dirs->begin(), Dirs->end(), rx); auto fun = std::bind(DirEntryMatcher, _1, _2, true);
} auto rx = RegexFilter< std::pair<std::string, std::string> >(
else if (w == Tags) boost::regex(filter, Config.regex_type), fun);
{ Dirs->filter(Dirs->begin(), Dirs->end(), rx);
Tags->showAll(); }
auto rx = RegexFilter<MPD::MutableSong>(filter, Config.regex_type, SongEntryMatcher); else if (w == Tags)
Tags->filter(Tags->begin(), Tags->end(), rx); {
Tags->showAll();
auto rx = RegexFilter<MPD::MutableSong>(
boost::regex(filter, Config.regex_type), SongEntryMatcher);
Tags->filter(Tags->begin(), Tags->end(), rx);
}
} }
catch (boost::bad_expression &) { }
} }
/***********************************************************************/ /***********************************************************************/
@@ -764,19 +770,28 @@ bool TagEditor::allowsSearching()
bool TagEditor::search(const std::string &constraint) bool TagEditor::search(const std::string &constraint)
{ {
bool result = false; try
if (w == Dirs)
{ {
auto fun = std::bind(DirEntryMatcher, _1, _2, false); bool result = false;
auto rx = RegexFilter< std::pair<std::string, std::string> >(constraint, Config.regex_type, fun); if (w == Dirs)
result = Dirs->search(Dirs->begin(), Dirs->end(), rx); {
auto fun = std::bind(DirEntryMatcher, _1, _2, false);
auto rx = RegexFilter< std::pair<std::string, std::string> >(
boost::regex(constraint, Config.regex_type), fun);
result = Dirs->search(Dirs->begin(), Dirs->end(), rx);
}
else if (w == Tags)
{
auto rx = RegexFilter<MPD::MutableSong>(
boost::regex(constraint, Config.regex_type), SongEntryMatcher);
result = Tags->search(Tags->begin(), Tags->end(), rx);
}
return result;
} }
else if (w == Tags) catch (boost::bad_expression &)
{ {
auto rx = RegexFilter<MPD::MutableSong>(constraint, Config.regex_type, SongEntryMatcher); return false;
result = Tags->search(Tags->begin(), Tags->end(), rx);
} }
return result;
} }
void TagEditor::nextFound(bool wrap) void TagEditor::nextFound(bool wrap)
@@ -1169,16 +1184,16 @@ std::string SongToString(const MPD::MutableSong &s)
return result.empty() ? Config.empty_tag : result; return result.empty() ? Config.empty_tag : result;
} }
bool DirEntryMatcher(const Regex &rx, const std::pair<std::string, std::string> &dir, bool filter) bool DirEntryMatcher(const boost::regex &rx, const std::pair<std::string, std::string> &dir, bool filter)
{ {
if (dir.first == "." || dir.first == "..") if (dir.first == "." || dir.first == "..")
return filter; return filter;
return rx.match(dir.first); return boost::regex_search(dir.first, rx);
} }
bool SongEntryMatcher(const Regex &rx, const MPD::MutableSong &s) bool SongEntryMatcher(const boost::regex &rx, const MPD::MutableSong &s)
{ {
return rx.match(SongToString(s)); return boost::regex_search(SongToString(s), rx);
} }
} }