Dependencies: get rid of boost-regexp (see #995)

Mostly, std::regexp can be used as a drop-in replacement.

Note: unfortunately ECMA regexps do not support lookbehind assertions.
This lookbehind is necesary here because we want to allow parsing values
from strings with additional content, which means we need explicitly to
exclude mismatches due to invalid syntax.

We can work around that issue like "either line start, or *not* one of these characters.


Alternatively we could consider to make the match more rigid,
i.e we would require the string to conain *only* the timecode spec to be parsed.
This commit is contained in:
Fischlurch 2019-06-24 02:41:02 +02:00
parent ab90d9c71d
commit 8ffab2f002
12 changed files with 53 additions and 56 deletions

View file

@ -92,8 +92,6 @@ def configure(env):
problems.append('We need the boost::system support library (including binary lib).') problems.append('We need the boost::system support library (including binary lib).')
if not conf.CheckLibWithHeader('boost_filesystem','boost/filesystem.hpp','C++'): if not conf.CheckLibWithHeader('boost_filesystem','boost/filesystem.hpp','C++'):
problems.append('We need the boost::filesystem lib (including binary lib for linking).') problems.append('We need the boost::filesystem lib (including binary lib for linking).')
if not conf.CheckLibWithHeader('boost_regex','boost/regex.hpp','C++'):
problems.append('We need the boost regular expression lib (incl. binary lib for linking).')
if not conf.CheckPkgConfig('gavl', '1.4'): if not conf.CheckPkgConfig('gavl', '1.4'):

View file

@ -1,5 +1,5 @@
Dependencies Build Dependencies
============ ==================
:Author: core-devs :Author: core-devs
:Date: 11/2015 :Date: 11/2015
:toc: :toc:
@ -66,7 +66,6 @@ Languages and Tools
- libboost-program-options-dev - libboost-program-options-dev
- libboost-program-options-dev - libboost-program-options-dev
- libboost-filesystem-dev - libboost-filesystem-dev
- libboost-regex-dev
* Script languages * Script languages
- Python (*2.7*) for build scripts - Python (*2.7*) for build scripts

View file

@ -4,14 +4,14 @@ Lumiera build system
As work progresses, we will add more information on the Lumiera build system. As work progresses, we will add more information on the Lumiera build system.
//Menu: label Build System //Menu: label Build System
//Menu: prepend child 'Dependencies' //Menu: prepend child 'BuildDependencies'
//Menu: prepend child 'SCons' //Menu: prepend child 'SCons'
build -- continuous integration -- packaging build -- continuous integration -- packaging
* link:SCons.html[Buildsystem] * link:SCons.html[Buildsystem]
* link:Dependencies.html[Dependencies] * link:BuildDependencies.html[Lumiera Build Dependencies]
* link:BuildDroneDraft.html[»Builddrone« concept from 2008] * link:BuildDroneDraft.html[»Builddrone« concept from 2008]
* Packaging: link:LumieraDebianPackage.html[Debian] RPM * Packaging: link:LumieraDebianPackage.html[Debian] RPM
* Lumiera link:../infra/debianDepot.html/[debian depot] * Lumiera link:../infra/debianDepot.html/[debian depot]

View file

@ -36,16 +36,16 @@
#include <boost/functional/hash.hpp> #include <boost/functional/hash.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/regex.hpp> #include <regex>
using lib::Literal; using lib::Literal;
using util::isnil; using util::isnil;
using boost::regex; using std::regex;
using boost::smatch; using std::smatch;
using boost::sregex_iterator; using std::sregex_iterator;
using boost::match_continuous; using std::regex_constants::match_continuous;
using boost::hash_combine; using boost::hash_combine;
using boost::lexical_cast; using boost::lexical_cast;

View file

@ -30,15 +30,14 @@
#include "lib/util.hpp" #include "lib/util.hpp"
#include "include/logging.h" #include "include/logging.h"
#include "lib/cmdline.hpp" #include "lib/cmdline.hpp"
#include "lib/format-util.hpp"
#include <boost/regex.hpp> #include <regex>
#include <boost/algorithm/string/join.hpp>
using boost::regex;
using boost::smatch;
using boost::regex_search;
using boost::algorithm::join;
using std::regex;
using std::smatch;
using std::regex_search;
using util::join;
using util::noneg; using util::noneg;
@ -64,12 +63,12 @@ namespace lib {
*/ */
Cmdline::Cmdline (const string cmdline) Cmdline::Cmdline (const string cmdline)
{ {
regex tokendef("[^ \r\n\t]+"); static regex TOKENDEF{"\\S+"};
smatch match; smatch match;
string::const_iterator it = cmdline.begin(); string::const_iterator it = cmdline.begin();
string::const_iterator end = cmdline.end(); string::const_iterator end = cmdline.end();
while (regex_search(it, end, match, tokendef)) while (regex_search(it, end, match, TOKENDEF))
{ {
string ss(match[0]); string ss(match[0]);
this->push_back(ss); this->push_back(ss);

View file

@ -27,6 +27,7 @@
** the referred data into a vector of strings. Thus `Cmdline` is a way to ** the referred data into a vector of strings. Thus `Cmdline` is a way to
** express explicitly on APIs that we are consuming commandline contents, ** express explicitly on APIs that we are consuming commandline contents,
** and, moreover, it offers a way more sane interface to deal with those. ** and, moreover, it offers a way more sane interface to deal with those.
** @see CmdlineWrapper_test
*/ */

View file

@ -31,14 +31,15 @@
#include "lib/util.hpp" #include "lib/util.hpp"
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/regex.hpp> #include <functional>
#include <regex>
#include <map> #include <map>
using std::map; using std::map;
using boost::regex; using std::regex;
using boost::smatch; using std::smatch;
using boost::regex_search; using std::regex_search;
using boost::sregex_iterator; using std::sregex_iterator;
using util::contains; using util::contains;
using util::isnil; using util::isnil;
@ -49,7 +50,7 @@ namespace lib {
namespace { // local definitions namespace { // local definitions
typedef boost::function<bool(string::value_type)> ChPredicate; using ChPredicate = std::function<bool(string::value_type)> ;
ChPredicate is_alpha = boost::algorithm::is_alpha(); ChPredicate is_alpha = boost::algorithm::is_alpha();
ChPredicate is_upper = boost::algorithm::is_upper(); ChPredicate is_upper = boost::algorithm::is_upper();
@ -79,14 +80,14 @@ namespace lib {
map<Symbol, regex> regexTable; map<Symbol, regex> regexTable;
Literal matchArgument = "\\(\\s*([\\w_\\.\\-]+)\\s*\\),?\\s*"; Literal MATCH_ARGUMENT = R"~(\(\s*([\w_\.\-]+)\s*\),?\s*)~";
regex findPredicate (string("(\\w+)")+matchArgument); const regex FIND_PREDICATE{string{"(\\w+)"} + MATCH_ARGUMENT};
inline regex& inline regex&
getTermRegex (Symbol sym) getTermRegex (Symbol sym)
{ {
if (!contains (regexTable, sym)) if (!contains (regexTable, sym))
regexTable[sym] = regex (string(sym)+matchArgument); regexTable[sym] = regex (string(sym)+MATCH_ARGUMENT);
return regexTable[sym]; return regexTable[sym];
} }
} }
@ -146,7 +147,7 @@ namespace lib {
{ {
uint cnt (0); uint cnt (0);
sregex_iterator end; sregex_iterator end;
for (sregex_iterator i (q.begin(),q.end(), findPredicate); for (sregex_iterator i (q.begin(),q.end(), FIND_PREDICATE);
i != end; ++i) i != end; ++i)
++cnt; ++cnt;
return cnt; return cnt;

View file

@ -43,6 +43,8 @@ namespace lib {
LUMIERA_ERROR_DEFINE (FILE_NOT_DIRECTORY, "path element points at a file instead of a directory"); LUMIERA_ERROR_DEFINE (FILE_NOT_DIRECTORY, "path element points at a file instead of a directory");
using std::regex;
using std::regex_replace;
const regex SearchPathSplitter::EXTRACT_PATHSPEC ("[^:]+"); const regex SearchPathSplitter::EXTRACT_PATHSPEC ("[^:]+");
@ -78,7 +80,7 @@ namespace lib {
static const string expandedOriginDir static const string expandedOriginDir
= fsys::path (findExePath()).parent_path().string() + "/"; ///////////TICKET #896 = fsys::path (findExePath()).parent_path().string() + "/"; ///////////TICKET #896
return boost::regex_replace(src, PICK_ORIGIN_TOKEN, expandedOriginDir); return regex_replace(src, PICK_ORIGIN_TOKEN, expandedOriginDir);
} }

View file

@ -37,19 +37,15 @@
#include "lib/nocopy.hpp" #include "lib/nocopy.hpp"
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/regex.hpp>
#include <string> #include <string>
#include <regex>
namespace lib { namespace lib {
using std::string; using std::string;
using boost::regex;
using boost::smatch;
using boost::regex_search;
using boost::sregex_iterator;
typedef smatch::value_type const& SubMatch; using SubMatch = std::smatch::value_type const&;
namespace error = lumiera::error; namespace error = lumiera::error;
namespace fsys = boost::filesystem; namespace fsys = boost::filesystem;
@ -77,10 +73,10 @@ namespace lib {
: util::NonCopyable : util::NonCopyable
{ {
string pathSpec_; string pathSpec_;
sregex_iterator pos_, std::sregex_iterator pos_,
end_; end_;
static const regex EXTRACT_PATHSPEC; static const std::regex EXTRACT_PATHSPEC;
public: public:
SearchPathSplitter (string const& searchPath) SearchPathSplitter (string const& searchPath)

View file

@ -36,17 +36,17 @@
#include "lib/util.hpp" #include "lib/util.hpp"
#include "lib/util-quant.hpp" #include "lib/util-quant.hpp"
#include <regex>
#include <functional> #include <functional>
#include <boost/regex.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
using std::string;
using util::unConst; using util::unConst;
using util::isSameObject; using util::isSameObject;
using util::floorwrap; using util::floorwrap;
using boost::regex; using std::string;
using boost::smatch; using std::regex;
using boost::regex_search; using std::smatch;
using std::regex_search;
using boost::lexical_cast; using boost::lexical_cast;
namespace error = lumiera::error; namespace error = lumiera::error;
@ -71,8 +71,8 @@ namespace time {
TimeValue TimeValue
Frames::parse (string const& frameNumber, QuantR frameGrid) Frames::parse (string const& frameNumber, QuantR frameGrid)
{ {
static regex frameNr_parser ("(?<![\\.\\-\\d])(-?\\d+)#"); // no leading [.-\d], number+'#' static regex frameNr_parser{"(?:^|[^\\d\\.\\-])(\\-?\\d+)#"}; // no leading [.-\d], digit+'#'
smatch match; smatch match; // note: ECMA regexp does not support lookbehind
if (regex_search (frameNumber, match, frameNr_parser)) if (regex_search (frameNumber, match, frameNr_parser))
return frameGrid.timeOf (lexical_cast<FrameCnt> (match[1])); return frameGrid.timeOf (lexical_cast<FrameCnt> (match[1]));
else else
@ -119,8 +119,8 @@ namespace time {
TimeValue TimeValue
Seconds::parse (string const& seconds, QuantR grid) Seconds::parse (string const& seconds, QuantR grid)
{ {
static regex fracSecs_parser ("(?<![\\./\\-\\d])(-?\\d+)(?:([\\-\\+]\\d+)?/(\\d+))?sec"); static regex fracSecs_parser ("(?:^|[^\\./\\d\\-])(\\-?\\d+)(?:([\\-\\+]\\d+)?/(\\d+))?sec");
//__no leading[./-\d] number [+-] number '/' number 'sec' //__no leading[./-\d] number [+-] number '/' number 'sec'
#define SUB_EXPR(N) lexical_cast<long> (match[N]) #define SUB_EXPR(N) lexical_cast<long> (match[N])
smatch match; smatch match;

View file

@ -38,7 +38,7 @@
#include "lib/util.hpp" #include "lib/util.hpp"
#include "include/logging.h" #include "include/logging.h"
#include <boost/regex.hpp> #include <regex>
using util::_Fmt; using util::_Fmt;
@ -48,9 +48,9 @@ using lib::time::Duration;
using backend_interface::MediaDesc; using backend_interface::MediaDesc;
using backend_interface::MediaAccessFacade; using backend_interface::MediaAccessFacade;
using boost::regex; using std::regex;
using boost::smatch; using std::smatch;
using boost::regex_search; using std::regex_search;
using std::dynamic_pointer_cast; using std::dynamic_pointer_cast;
namespace error = lumiera::error; namespace error = lumiera::error;
@ -66,10 +66,10 @@ namespace asset {
*/ */
string extractName (const string& path) string extractName (const string& path)
{ {
regex pathname_pattern("([^/\\.]+)(\\.\\w+)?$"); static regex PATHNAME_PATTERN("([^/\\.]+)(\\.\\w+)?$");
smatch match; smatch match;
if (regex_search (path, match, pathname_pattern)) if (regex_search (path, match, PATHNAME_PATTERN))
return util::sanitise (string (match[1])); return util::sanitise (string (match[1]));
else else
return ""; return "";

View file

@ -144,6 +144,7 @@ namespace test{
Parsing<format::Frames> ("xxx25#xxx") .should_yield (1); Parsing<format::Frames> ("xxx25#xxx") .should_yield (1);
Parsing<format::Frames> ("12 25#") .should_yield (1); Parsing<format::Frames> ("12 25#") .should_yield (1);
Parsing<format::Frames> ("12 25# 33#") .should_yield (1); // note pitfall: the first valid number is used Parsing<format::Frames> ("12 25# 33#") .should_yield (1); // note pitfall: the first valid number is used
Parsing<format::Frames> ("12 25# \n 33#") .should_yield (1);
Parsing<format::Frames> ("12\n 25# \n 33#") .should_yield (1); Parsing<format::Frames> ("12\n 25# \n 33#") .should_yield (1);
Parsing<format::Frames> ("12.25#") .should_fail(); // rejected because of leading dot (ambiguity) Parsing<format::Frames> ("12.25#") .should_fail(); // rejected because of leading dot (ambiguity)
} }