add support for unicode aware regular expressions if available

This commit is contained in:
Andrzej Rybczak
2015-05-02 15:01:01 +02:00
parent 39c331eed6
commit dafcadefaf
15 changed files with 175 additions and 115 deletions

View File

@@ -68,7 +68,7 @@ void getLocalDirectoryRecursively(std::vector<MPD::Song> &songs, const std::stri
void clearDirectory(const std::string &directory);
std::string itemToString(const MPD::Item &item);
bool browserEntryMatcher(const boost::regex &rx, const MPD::Item &item, bool filter);
bool browserEntryMatcher(const Regex::Regex &rx, const MPD::Item &item, bool filter);
}
@@ -287,8 +287,8 @@ bool Browser::allowsSearching()
void Browser::setSearchConstraint(const std::string &constraint)
{
m_search_predicate = RegexFilter<MPD::Item>(
boost::regex(constraint, Config.regex_type),
m_search_predicate = Regex::Filter<MPD::Item>(
Regex::make(constraint, Config.regex_type),
boost::bind(browserEntryMatcher, _1, _2, false)
);
}
@@ -693,11 +693,11 @@ std::string itemToString(const MPD::Item &item)
return result;
}
bool browserEntryMatcher(const boost::regex &rx, const MPD::Item &item, bool filter)
bool browserEntryMatcher(const Regex::Regex &rx, const MPD::Item &item, bool filter)
{
if (isItemParentDirectory(item))
return filter;
return boost::regex_search(itemToString(item), rx);
return Regex::search(itemToString(item), rx);
}
}

View File

@@ -79,7 +79,7 @@ private:
bool m_local_browser;
size_t m_scroll_beginning;
std::string m_current_directory;
RegexFilter<MPD::Item> m_search_predicate;
Regex::Filter<MPD::Item> m_search_predicate;
};
extern Browser *myBrowser;

View File

@@ -74,9 +74,9 @@ MPD::SongIterator getSongsFromAlbum(const AlbumEntry &album)
std::string AlbumToString(const AlbumEntry &ae);
std::string SongToString(const MPD::Song &s);
bool TagEntryMatcher(const boost::regex &rx, const MediaLibrary::PrimaryTag &tagmtime);
bool AlbumEntryMatcher(const boost::regex &rx, const NC::Menu<AlbumEntry>::Item &item, bool filter);
bool SongEntryMatcher(const boost::regex &rx, const MPD::Song &s);
bool TagEntryMatcher(const Regex::Regex &rx, const MediaLibrary::PrimaryTag &tagmtime);
bool AlbumEntryMatcher(const Regex::Regex &rx, const NC::Menu<AlbumEntry>::Item &item, bool filter);
bool SongEntryMatcher(const Regex::Regex &rx, const MPD::Song &s);
bool MoveToTag(NC::Menu<PrimaryTag> &tags, const std::string &primary_tag);
bool MoveToAlbum(NC::Menu<AlbumEntry> &albums, const std::string &primary_tag, const MPD::Song &s);
@@ -583,22 +583,22 @@ void MediaLibrary::setSearchConstraint(const std::string &constraint)
{
if (isActiveWindow(Tags))
{
m_tags_search_predicate = RegexFilter<PrimaryTag>(
boost::regex(constraint, Config.regex_type),
m_tags_search_predicate = Regex::Filter<PrimaryTag>(
Regex::make(constraint, Config.regex_type),
TagEntryMatcher
);
}
else if (isActiveWindow(Albums))
{
m_albums_search_predicate = RegexItemFilter<AlbumEntry>(
boost::regex(constraint, Config.regex_type),
m_albums_search_predicate = Regex::ItemFilter<AlbumEntry>(
Regex::make(constraint, Config.regex_type),
boost::bind(AlbumEntryMatcher, _1, _2, false)
);
}
else if (isActiveWindow(Songs))
{
m_songs_search_predicate = RegexFilter<MPD::Song>(
boost::regex(constraint, Config.regex_type),
m_songs_search_predicate = Regex::Filter<MPD::Song>(
Regex::make(constraint, Config.regex_type),
SongEntryMatcher
);
}
@@ -1065,21 +1065,21 @@ std::string SongToString(const MPD::Song &s)
);
}
bool TagEntryMatcher(const boost::regex &rx, const PrimaryTag &pt)
bool TagEntryMatcher(const Regex::Regex &rx, const PrimaryTag &pt)
{
return boost::regex_search(pt.tag(), rx);
return Regex::search(pt.tag(), rx);
}
bool AlbumEntryMatcher(const boost::regex &rx, const NC::Menu<AlbumEntry>::Item &item, bool filter)
bool AlbumEntryMatcher(const Regex::Regex &rx, const NC::Menu<AlbumEntry>::Item &item, bool filter)
{
if (item.isSeparator() || item.value().isAllTracksEntry())
return filter;
return boost::regex_search(AlbumToString(item.value()), rx);
return Regex::search(AlbumToString(item.value()), rx);
}
bool SongEntryMatcher(const boost::regex &rx, const MPD::Song &s)
bool SongEntryMatcher(const Regex::Regex &rx, const MPD::Song &s)
{
return boost::regex_search(SongToString(s), rx);
return Regex::search(SongToString(s), rx);
}
bool MoveToTag(NC::Menu<PrimaryTag> &tags, const std::string &primary_tag)

View File

@@ -148,9 +148,9 @@ private:
const int m_window_timeout;
const boost::posix_time::time_duration m_fetching_delay;
RegexFilter<PrimaryTag> m_tags_search_predicate;
RegexItemFilter<AlbumEntry> m_albums_search_predicate;
RegexFilter<MPD::Song> m_songs_search_predicate;
Regex::Filter<PrimaryTag> m_tags_search_predicate;
Regex::ItemFilter<AlbumEntry> m_albums_search_predicate;
Regex::Filter<MPD::Song> m_songs_search_predicate;
};

View File

@@ -43,7 +43,7 @@ Playlist *myPlaylist;
namespace {
std::string songToString(const MPD::Song &s);
bool playlistEntryMatcher(const boost::regex &rx, const MPD::Song &s);
bool playlistEntryMatcher(const Regex::Regex &rx, const MPD::Song &s);
}
@@ -167,8 +167,8 @@ bool Playlist::allowsSearching()
void Playlist::setSearchConstraint(const std::string &constraint)
{
m_search_predicate = RegexFilter<MPD::Song>(
boost::regex(constraint, Config.regex_type), playlistEntryMatcher
m_search_predicate = Regex::Filter<MPD::Song>(
Regex::make(constraint, Config.regex_type), playlistEntryMatcher
);
}
@@ -325,9 +325,9 @@ std::string songToString(const MPD::Song &s)
return result;
}
bool playlistEntryMatcher(const boost::regex &rx, const MPD::Song &s)
bool playlistEntryMatcher(const Regex::Regex &rx, const MPD::Song &s)
{
return boost::regex_search(songToString(s), rx);
return Regex::search(songToString(s), rx);
}
}

View File

@@ -94,7 +94,7 @@ private:
bool m_reload_total_length;
bool m_reload_remaining;
RegexFilter<MPD::Song> m_search_predicate;
Regex::Filter<MPD::Song> m_search_predicate;
};
extern Playlist *myPlaylist;

View File

@@ -51,8 +51,8 @@ size_t RightColumnStartX;
size_t RightColumnWidth;
std::string SongToString(const MPD::Song &s);
bool PlaylistEntryMatcher(const boost::regex &rx, const MPD::Playlist &playlist);
bool SongEntryMatcher(const boost::regex &rx, const MPD::Song &s);
bool PlaylistEntryMatcher(const Regex::Regex &rx, const MPD::Playlist &playlist);
bool SongEntryMatcher(const Regex::Regex &rx, const MPD::Song &s);
}
@@ -337,15 +337,15 @@ void PlaylistEditor::setSearchConstraint(const std::string &constraint)
{
if (isActiveWindow(Playlists))
{
m_playlists_search_predicate = RegexFilter<MPD::Playlist>(
boost::regex(constraint, Config.regex_type),
m_playlists_search_predicate = Regex::Filter<MPD::Playlist>(
Regex::make(constraint, Config.regex_type),
PlaylistEntryMatcher
);
}
else if (isActiveWindow(Content))
{
m_content_search_predicate = RegexFilter<MPD::Song>(
boost::regex(constraint, Config.regex_type),
m_content_search_predicate = Regex::Filter<MPD::Song>(
Regex::make(constraint, Config.regex_type),
SongEntryMatcher
);
}
@@ -513,14 +513,14 @@ std::string SongToString(const MPD::Song &s)
return result;
}
bool PlaylistEntryMatcher(const boost::regex &rx, const MPD::Playlist &playlist)
bool PlaylistEntryMatcher(const Regex::Regex &rx, const MPD::Playlist &playlist)
{
return boost::regex_search(playlist.path(), rx);
return Regex::search(playlist.path(), rx);
}
bool SongEntryMatcher(const boost::regex &rx, const MPD::Song &s)
bool SongEntryMatcher(const Regex::Regex &rx, const MPD::Song &s)
{
return boost::regex_search(SongToString(s), rx);
return Regex::search(SongToString(s), rx);
}
}

View File

@@ -92,8 +92,8 @@ private:
const int m_window_timeout;
const boost::posix_time::time_duration m_fetching_delay;
RegexFilter<MPD::Playlist> m_playlists_search_predicate;
RegexFilter<MPD::Song> m_content_search_predicate;
Regex::Filter<MPD::Playlist> m_playlists_search_predicate;
Regex::Filter<MPD::Song> m_content_search_predicate;
};
extern PlaylistEditor *myPlaylistEditor;

View File

@@ -21,18 +21,59 @@
#ifndef NCMPCPP_REGEX_FILTER_H
#define NCMPCPP_REGEX_FILTER_H
#include <boost/regex.hpp>
#include "config.h"
#ifdef BOOST_REGEX_ICU
# include <boost/regex/icu.hpp>
#else
# include <boost/regex.hpp>
#endif // BOOST_REGEX_ICU
#include <cassert>
namespace Regex {
typedef
#ifdef BOOST_REGEX_ICU
boost::u32regex
#else
boost::regex
#endif // BOOST_REGEX_ICU
Regex;
template <typename StringT>
inline Regex make(StringT &&s, boost::regex_constants::syntax_option_type flags)
{
return
# ifdef BOOST_REGEX_ICU
boost::make_u32regex
# else
boost::regex
# endif // BOOST_REGEX_ICU
(std::forward<StringT>(s), flags);
}
template <typename StringT>
inline bool search(StringT &&s, const Regex &rx)
{
return
# ifdef BOOST_REGEX_ICU
boost::u32regex_search
# else
boost::regex_search
# endif // BOOST_REGEX_ICU
(std::forward<StringT>(s), rx);
}
template <typename T>
struct RegexFilter
struct Filter
{
typedef NC::Menu<T> MenuT;
typedef typename NC::Menu<T>::Item Item;
typedef std::function<bool(const boost::regex &, const T &)> FilterFunction;
RegexFilter() { }
RegexFilter(boost::regex rx, FilterFunction filter)
typedef std::function<bool(const Regex &, const T &)> FilterFunction;
Filter() { }
Filter(Regex rx, FilterFunction filter)
: m_rx(std::move(rx)), m_filter(std::move(filter)) { }
void clear()
@@ -51,18 +92,18 @@ struct RegexFilter
}
private:
boost::regex m_rx;
Regex m_rx;
FilterFunction m_filter;
};
template <typename T> struct RegexItemFilter
template <typename T> struct ItemFilter
{
typedef NC::Menu<T> MenuT;
typedef typename NC::Menu<T>::Item Item;
typedef std::function<bool(const boost::regex &, const Item &)> FilterFunction;
typedef std::function<bool(const Regex &, const Item &)> FilterFunction;
RegexItemFilter() { }
RegexItemFilter(boost::regex rx, FilterFunction filter)
ItemFilter() { }
ItemFilter(Regex rx, FilterFunction filter)
: m_rx(std::move(rx)), m_filter(std::move(filter)) { }
void clear()
@@ -80,8 +121,10 @@ template <typename T> struct RegexItemFilter
}
private:
boost::regex m_rx;
Regex m_rx;
FilterFunction m_filter;
};
}
#endif // NCMPCPP_REGEX_FILTER_H

View File

@@ -71,7 +71,7 @@ namespace pos {
}*/
std::string SEItemToString(const SEItem &ei);
bool SEItemEntryMatcher(const boost::regex &rx, const NC::Menu<SEItem>::Item &item, bool filter);
bool SEItemEntryMatcher(const Regex::Regex &rx, const NC::Menu<SEItem>::Item &item, bool filter);
}
@@ -264,8 +264,8 @@ bool SearchEngine::allowsSearching()
void SearchEngine::setSearchConstraint(const std::string &constraint)
{
m_search_predicate = RegexItemFilter<SEItem>(
boost::regex(constraint, Config.regex_type),
m_search_predicate = Regex::ItemFilter<SEItem>(
Regex::make(constraint, Config.regex_type),
boost::bind(SEItemEntryMatcher, _1, _2, false)
);
}
@@ -401,7 +401,7 @@ void SearchEngine::Search()
return;
}
boost::regex rx[ConstraintsNumber];
Regex::Regex rx[ConstraintsNumber];
if (SearchMode != &SearchModes[2]) // match to pattern
{
for (size_t i = 0; i < ConstraintsNumber; ++i)
@@ -410,7 +410,7 @@ void SearchEngine::Search()
{
try
{
rx[i].assign(itsConstraints[i], Config.regex_type);
rx[i] = Regex::make(itsConstraints[i], Config.regex_type);
}
catch (boost::bad_expression &) { }
}
@@ -444,36 +444,36 @@ void SearchEngine::Search()
{
if (!rx[0].empty())
any_found =
boost::regex_search(s->getArtist(), rx[0])
|| boost::regex_search(s->getAlbumArtist(), rx[0])
|| boost::regex_search(s->getTitle(), rx[0])
|| boost::regex_search(s->getAlbum(), rx[0])
|| boost::regex_search(s->getName(), rx[0])
|| boost::regex_search(s->getComposer(), rx[0])
|| boost::regex_search(s->getPerformer(), rx[0])
|| boost::regex_search(s->getGenre(), rx[0])
|| boost::regex_search(s->getDate(), rx[0])
|| boost::regex_search(s->getComment(), rx[0]);
Regex::search(s->getArtist(), rx[0])
|| Regex::search(s->getAlbumArtist(), rx[0])
|| Regex::search(s->getTitle(), rx[0])
|| Regex::search(s->getAlbum(), rx[0])
|| Regex::search(s->getName(), rx[0])
|| Regex::search(s->getComposer(), rx[0])
|| Regex::search(s->getPerformer(), rx[0])
|| Regex::search(s->getGenre(), rx[0])
|| Regex::search(s->getDate(), rx[0])
|| Regex::search(s->getComment(), rx[0]);
if (found && !rx[1].empty())
found = boost::regex_search(s->getArtist(), rx[1]);
found = Regex::search(s->getArtist(), rx[1]);
if (found && !rx[2].empty())
found = boost::regex_search(s->getAlbumArtist(), rx[2]);
found = Regex::search(s->getAlbumArtist(), rx[2]);
if (found && !rx[3].empty())
found = boost::regex_search(s->getTitle(), rx[3]);
found = Regex::search(s->getTitle(), rx[3]);
if (found && !rx[4].empty())
found = boost::regex_search(s->getAlbum(), rx[4]);
found = Regex::search(s->getAlbum(), rx[4]);
if (found && !rx[5].empty())
found = boost::regex_search(s->getName(), rx[5]);
found = Regex::search(s->getName(), rx[5]);
if (found && !rx[6].empty())
found = boost::regex_search(s->getComposer(), rx[6]);
found = Regex::search(s->getComposer(), rx[6]);
if (found && !rx[7].empty())
found = boost::regex_search(s->getPerformer(), rx[7]);
found = Regex::search(s->getPerformer(), rx[7]);
if (found && !rx[8].empty())
found = boost::regex_search(s->getGenre(), rx[8]);
found = Regex::search(s->getGenre(), rx[8]);
if (found && !rx[9].empty())
found = boost::regex_search(s->getDate(), rx[9]);
found = Regex::search(s->getDate(), rx[9]);
if (found && !rx[10].empty())
found = boost::regex_search(s->getComment(), rx[10]);
found = Regex::search(s->getComment(), rx[10]);
}
else // match only if values are equal
{
@@ -539,11 +539,11 @@ std::string SEItemToString(const SEItem &ei)
return result;
}
bool SEItemEntryMatcher(const boost::regex &rx, const NC::Menu<SEItem>::Item &item, bool filter)
bool SEItemEntryMatcher(const Regex::Regex &rx, const NC::Menu<SEItem>::Item &item, bool filter)
{
if (item.isSeparator() || !item.value().isSong())
return filter;
return boost::regex_search(SEItemToString(item.value()), rx);
return Regex::search(SEItemToString(item.value()), rx);
}
}

View File

@@ -118,7 +118,7 @@ private:
void Prepare();
void Search();
RegexItemFilter<SEItem> m_search_predicate;
Regex::ItemFilter<SEItem> m_search_predicate;
const char **SearchMode;

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 SongToString(const MPD::MutableSong &s);
bool DirEntryMatcher(const boost::regex &rx, const std::pair<std::string, std::string> &dir, bool filter);
bool SongEntryMatcher(const boost::regex &rx, const MPD::MutableSong &s);
bool DirEntryMatcher(const Regex::Regex &rx, const std::pair<std::string, std::string> &dir, bool filter);
bool SongEntryMatcher(const Regex::Regex &rx, const MPD::MutableSong &s);
}
@@ -726,15 +726,15 @@ void TagEditor::setSearchConstraint(const std::string &constraint)
{
if (w == Dirs)
{
m_directories_search_predicate = RegexFilter<std::pair<std::string, std::string>>(
boost::regex(constraint, Config.regex_type),
m_directories_search_predicate = Regex::Filter<std::pair<std::string, std::string>>(
Regex::make(constraint, Config.regex_type),
boost::bind(DirEntryMatcher, _1, _2, false)
);
}
else if (w == Tags)
{
m_songs_search_predicate = RegexFilter<MPD::MutableSong>(
boost::regex(constraint, Config.regex_type),
m_songs_search_predicate = Regex::Filter<MPD::MutableSong>(
Regex::make(constraint, Config.regex_type),
SongEntryMatcher
);
}
@@ -1125,16 +1125,16 @@ std::string SongToString(const MPD::MutableSong &s)
return result.empty() ? Config.empty_tag : result;
}
bool DirEntryMatcher(const boost::regex &rx, const std::pair<std::string, std::string> &dir, bool filter)
bool DirEntryMatcher(const Regex::Regex &rx, const std::pair<std::string, std::string> &dir, bool filter)
{
if (dir.first == "." || dir.first == "..")
return filter;
return boost::regex_search(dir.first, rx);
return Regex::search(dir.first, rx);
}
bool SongEntryMatcher(const boost::regex &rx, const MPD::MutableSong &s)
bool SongEntryMatcher(const Regex::Regex &rx, const MPD::MutableSong &s)
{
return boost::regex_search(SongToString(s), rx);
return Regex::search(SongToString(s), rx);
}
}

View File

@@ -94,8 +94,8 @@ private:
std::string itsBrowsedDir;
std::string itsHighlightedDir;
RegexFilter<std::pair<std::string, std::string>> m_directories_search_predicate;
RegexFilter<MPD::MutableSong> m_songs_search_predicate;
Regex::Filter<std::pair<std::string, std::string>> m_directories_search_predicate;
Regex::Filter<MPD::MutableSong> m_songs_search_predicate;
};
extern TagEditor *myTagEditor;