Clean-up: reimplement the SeachPathSplitter
...to be more compliant to the »Lumiera Forward Iterator« concept. This can be easily achieved by inheriting from util::RegexSearchIter, similar to the example in CSV.hpp Regarding #896, I changed the string rendering to use fs::path::generic_string where appropriate, which means that we're using the normalised path rendering
This commit is contained in:
parent
c5292dd0dd
commit
998e225490
9 changed files with 97 additions and 84 deletions
|
|
@ -54,7 +54,7 @@ namespace lumiera {
|
||||||
string
|
string
|
||||||
resolve (fs::path iniSpec)
|
resolve (fs::path iniSpec)
|
||||||
{
|
{
|
||||||
string searchpath = iniSpec.parent_path().string(); ///////////TICKET #896
|
string searchpath = iniSpec.parent_path().generic_string();
|
||||||
return resolveModulePath (iniSpec.filename(), searchpath);
|
return resolveModulePath (iniSpec.filename(), searchpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@
|
||||||
#include "include/config-facade.h"
|
#include "include/config-facade.h"
|
||||||
#include "common/appstate.hpp"
|
#include "common/appstate.hpp"
|
||||||
#include "lib/searchpath.hpp"
|
#include "lib/searchpath.hpp"
|
||||||
|
#include "lib/iter-explorer.hpp"
|
||||||
|
#include "lib/format-util.hpp"
|
||||||
#include "lib/util.hpp"
|
#include "lib/util.hpp"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
@ -130,18 +132,11 @@ extern "C" { /* ==== implementation C interface for accessing setup.ini =======
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
lumiera_get_plugin_path_default ()
|
lumiera_get_plugin_path_default ()
|
||||||
{
|
{ // Meyer's Singleton...
|
||||||
static string pathSpec;
|
static string pathSpec = []{ string pluginPath = Config::get (KEY_PLUGIN_PATH);
|
||||||
if (isnil (pathSpec))
|
return "plugin.path=" // syntax expected by lumiera_config_setdefault
|
||||||
{
|
+ util::join (SearchPathSplitter{pluginPath}, ":");
|
||||||
pathSpec += "plugin.path="; // syntax expected by lumiera_config_setdefault
|
}();
|
||||||
|
|
||||||
// fetch plugin search path from setup.ini and expand any $ORIGIN token
|
|
||||||
SearchPathSplitter pathElement(Config::get (KEY_PLUGIN_PATH));
|
|
||||||
while (pathElement)
|
|
||||||
pathSpec += pathElement.next() +":";
|
|
||||||
}
|
|
||||||
|
|
||||||
return cStr(pathSpec);
|
return cStr(pathSpec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "lib/error.hpp"
|
#include "lib/error.hpp"
|
||||||
#include "lib/searchpath.hpp"
|
#include "lib/searchpath.hpp"
|
||||||
|
#include "lib/format-string.hpp"
|
||||||
#include "lib/symbol.hpp"
|
#include "lib/symbol.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -31,10 +32,11 @@
|
||||||
|
|
||||||
namespace lib {
|
namespace lib {
|
||||||
|
|
||||||
|
using util::_Fmt;
|
||||||
using std::regex;
|
using std::regex;
|
||||||
using std::regex_replace;
|
using std::regex_replace;
|
||||||
|
|
||||||
const regex SearchPathSplitter::EXTRACT_PATHSPEC ("[^:]+");
|
const regex SearchPathSplitter::ACCEPT_PATHELEMENT{"(^|:)\\s*([^:]+)", regex::optimize};
|
||||||
|
|
||||||
|
|
||||||
/** @internal helper to figure out the installation directory,
|
/** @internal helper to figure out the installation directory,
|
||||||
|
|
@ -57,9 +59,9 @@ namespace lib {
|
||||||
string
|
string
|
||||||
replaceMagicLinkerTokens (string const& src)
|
replaceMagicLinkerTokens (string const& src)
|
||||||
{
|
{
|
||||||
static const regex PICK_ORIGIN_TOKEN ("\\$?ORIGIN/?");
|
static const regex PICK_ORIGIN_TOKEN{"\\$?ORIGIN/?", regex::optimize};
|
||||||
static const string expandedOriginDir
|
static const string expandedOriginDir
|
||||||
= findExePath().parent_path().string() + "/"; ///////////TICKET #896
|
= findExePath().parent_path().generic_string() + "/";
|
||||||
|
|
||||||
return regex_replace (src, PICK_ORIGIN_TOKEN, expandedOriginDir);
|
return regex_replace (src, PICK_ORIGIN_TOKEN, expandedOriginDir);
|
||||||
}
|
}
|
||||||
|
|
@ -72,20 +74,21 @@ namespace lib {
|
||||||
resolveModulePath (fs::path moduleName, string searchPath)
|
resolveModulePath (fs::path moduleName, string searchPath)
|
||||||
{
|
{
|
||||||
fs::path modulePathName (moduleName);
|
fs::path modulePathName (moduleName);
|
||||||
SearchPathSplitter searchLocation(searchPath); ///////////TICKET #896
|
SearchPathSplitter searchLocation(searchPath);
|
||||||
|
|
||||||
while (not fs::exists (modulePathName))
|
while (not fs::exists (modulePathName))
|
||||||
{
|
{
|
||||||
// try / continue search path
|
// try / continue search path
|
||||||
if (searchLocation.isValid())
|
if (not searchLocation)
|
||||||
modulePathName = fs::path() / searchLocation.next() / moduleName;
|
throw error::Config{_Fmt{"Module %s not found%s"}
|
||||||
else
|
% moduleName
|
||||||
throw error::Config ("Module \""+moduleName.string()+"\" not found" /////TICKET #896
|
%(searchPath.empty()? ".":" in search path: "+searchPath)};
|
||||||
+ (searchPath.empty()? ".":" in search path: "+searchPath));
|
modulePathName = *searchLocation / moduleName;
|
||||||
|
++searchLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE (config, "found module %s", modulePathName.string().c_str());
|
TRACE (config, "found module %s", cStr(modulePathName.generic_string()));
|
||||||
return modulePathName.string(); ///////////TICKET #896
|
return modulePathName.generic_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
#include "lib/file.hpp"
|
#include "lib/file.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace lib {
|
namespace lib {
|
||||||
|
|
@ -56,42 +57,35 @@ namespace lib {
|
||||||
* This iterator class dissects a ':'-separated path list. The individual
|
* This iterator class dissects a ':'-separated path list. The individual
|
||||||
* components may use the symbol \c $ORIGIN to refer to the directory
|
* components may use the symbol \c $ORIGIN to refer to the directory
|
||||||
* holding the current executable.
|
* holding the current executable.
|
||||||
* @note #next picks the current component and advances the iteration.
|
|
||||||
*/
|
*/
|
||||||
class SearchPathSplitter
|
class SearchPathSplitter
|
||||||
: util::NonCopyable
|
: public util::RegexSearchIter
|
||||||
{
|
{
|
||||||
string pathSpec_;
|
static const regex ACCEPT_PATHELEMENT;
|
||||||
std::sregex_iterator pos_,
|
|
||||||
end_;
|
|
||||||
|
|
||||||
static const std::regex EXTRACT_PATHSPEC;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SearchPathSplitter (string const& searchPath)
|
SearchPathSplitter() = default;
|
||||||
: pathSpec_(replaceMagicLinkerTokens (searchPath))
|
SearchPathSplitter (string& searchPath) ///< @warning search path string must exist somewhere else
|
||||||
, pos_(pathSpec_.begin(),pathSpec_.end(), EXTRACT_PATHSPEC)
|
: RegexSearchIter{searchPath, ACCEPT_PATHELEMENT}
|
||||||
, end_()
|
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
explicit operator bool() const { return isValid(); }
|
LIFT_PARENT_INCREMENT_OPERATOR (std::sregex_iterator);
|
||||||
|
ENABLE_USE_IN_STD_RANGE_FOR_LOOPS (SearchPathSplitter);
|
||||||
|
|
||||||
bool
|
using value_type = std::string;
|
||||||
isValid() const
|
using reference = value_type&;
|
||||||
{
|
using pointer = value_type*;
|
||||||
return pos_ != end_;
|
|
||||||
}
|
|
||||||
|
|
||||||
string
|
string
|
||||||
next ()
|
operator*() const
|
||||||
{
|
{
|
||||||
if (!isValid())
|
if (!isValid())
|
||||||
throw error::Logic ("Search path exhausted."
|
throw error::Logic ("Search path exhausted."
|
||||||
,LERR_(ITER_EXHAUST));
|
,LERR_(ITER_EXHAUST));
|
||||||
|
|
||||||
string currentPathElement = pos_->str();
|
string pathElm = util::RegexSearchIter::operator*()[2];
|
||||||
++pos_;
|
pathElm = boost::algorithm::trim_right_copy(pathElm);
|
||||||
return currentPathElement;
|
return replaceMagicLinkerTokens (pathElm);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -103,7 +97,7 @@ namespace lib {
|
||||||
* SearchPathSplitter, until encountering an existing file with the
|
* SearchPathSplitter, until encountering an existing file with the
|
||||||
* given name.
|
* given name.
|
||||||
* @return the absolute pathname of the module file found
|
* @return the absolute pathname of the module file found
|
||||||
* @throws error::Config when the resolution fails
|
* @throws error::Config when the resolution fails
|
||||||
*/
|
*/
|
||||||
string resolveModulePath (fs::path moduleName, string searchPath = "");
|
string resolveModulePath (fs::path moduleName, string searchPath = "");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <utility>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
@ -49,7 +50,7 @@
|
||||||
|
|
||||||
namespace lib {
|
namespace lib {
|
||||||
namespace test{
|
namespace test{
|
||||||
|
|
||||||
using lib::Literal;
|
using lib::Literal;
|
||||||
using std::string;
|
using std::string;
|
||||||
using lib::rani;
|
using lib::rani;
|
||||||
|
|
@ -327,8 +328,13 @@ namespace test{
|
||||||
class ExpectString
|
class ExpectString
|
||||||
: public std::string
|
: public std::string
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
using std::string::string;
|
using std::string::string;
|
||||||
|
|
||||||
|
ExpectString(std::string && s) : std::string{std::move(s)}{ }
|
||||||
|
ExpectString(std::string const& s) : std::string{s} { }
|
||||||
|
|
||||||
|
|
||||||
template<typename X>
|
template<typename X>
|
||||||
friend bool
|
friend bool
|
||||||
operator== (X const& x, ExpectString const& expected)
|
operator== (X const& x, ExpectString const& expected)
|
||||||
|
|
|
||||||
|
|
@ -262,10 +262,10 @@ namespace workspace {
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Try to resolve the icon via the configured search path
|
// Try to resolve the icon via the configured search path
|
||||||
lib::SearchPathSplitter iconLocations (iconSearchPath_);
|
lib::SearchPathSplitter iconLocations{iconSearchPath_};
|
||||||
while (iconLocations)
|
for (auto const& location : iconLocations)
|
||||||
if (addNonThemeIconSource (icon_set
|
if (addNonThemeIconSource (icon_set
|
||||||
,iconLocations.next()
|
,location
|
||||||
,icon_name
|
,icon_name
|
||||||
,size
|
,size
|
||||||
,wildcard))
|
,wildcard))
|
||||||
|
|
|
||||||
|
|
@ -624,17 +624,17 @@ END
|
||||||
|
|
||||||
|
|
||||||
TEST "Search path walking" SearchPathSplitter_test <<END
|
TEST "Search path walking" SearchPathSplitter_test <<END
|
||||||
out-lit: ➢➢a
|
out-lit: ▶a◀
|
||||||
out-lit: ➢➢a
|
out-lit: ▶a◀
|
||||||
out-lit: ➢➢a
|
out-lit: ▶a◀
|
||||||
out-lit: ➢➢b
|
out-lit: ▶b◀
|
||||||
out-lit: ➢➢a
|
out-lit: ▶a◀
|
||||||
out-lit: ➢➢b
|
out-lit: ▶b◀
|
||||||
out-lit: ➢➢c
|
out-lit: ▶c◀
|
||||||
out: ➢➢.d.
|
out-lit: ▶d◀
|
||||||
out-lit: ➢➢ e f
|
out-lit: ▶e f◀
|
||||||
out-lit: ➢➢/usr/bin
|
out-lit: ▶/usr/bin◀
|
||||||
out-lit: ➢➢/usr/lib
|
out-lit: ▶/usr/lib◀
|
||||||
return: 0
|
return: 0
|
||||||
END
|
END
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,12 @@
|
||||||
#include "lib/test/test-helper.hpp"
|
#include "lib/test/test-helper.hpp"
|
||||||
#include "lib/format-cout.hpp"
|
#include "lib/format-cout.hpp"
|
||||||
#include "lib/file.hpp"
|
#include "lib/file.hpp"
|
||||||
|
#include "lib/util.hpp"
|
||||||
|
|
||||||
#include "lib/searchpath.hpp"
|
#include "lib/searchpath.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
using util::isnil;
|
||||||
|
|
||||||
namespace lib {
|
namespace lib {
|
||||||
namespace test {
|
namespace test {
|
||||||
|
|
@ -54,20 +55,21 @@ namespace test {
|
||||||
walk ("a:");
|
walk ("a:");
|
||||||
walk (":a");
|
walk (":a");
|
||||||
walk ("a:b");
|
walk ("a:b");
|
||||||
walk (":a:b:c:");
|
walk (":a:b\n:c:");
|
||||||
walk (" d : e f");
|
walk (" d : e f ");
|
||||||
walk ("/usr/bin:/usr/lib");
|
walk ("/usr/bin:/usr/lib");
|
||||||
|
|
||||||
SearchPathSplitter sp("");
|
SearchPathSplitter sp{};
|
||||||
VERIFY_ERROR (ITER_EXHAUST, sp.next() );
|
CHECK (not sp);
|
||||||
|
VERIFY_ERROR (ITER_EXHAUST, *sp );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
walk (string spec)
|
walk (string spec)
|
||||||
{
|
{
|
||||||
SearchPathSplitter path(spec);
|
SearchPathSplitter path{spec};
|
||||||
while (path)
|
for (auto const& pathElm : path)
|
||||||
cout << "➢➢" << path.next() << endl;
|
cout <<"▶"<< pathElm <<"◀"<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -78,11 +80,15 @@ namespace test {
|
||||||
fs::path exePath{findExePath()};
|
fs::path exePath{findExePath()};
|
||||||
string expected{exePath.parent_path() / "modules"};
|
string expected{exePath.parent_path() / "modules"};
|
||||||
|
|
||||||
SearchPathSplitter sp("xyz:$ORIGIN/modules:abc");
|
string searchSpec = "xyz:$ORIGIN/modules:abc";
|
||||||
CHECK ("xyz" == sp.next());
|
SearchPathSplitter sp{searchSpec};
|
||||||
CHECK (sp.next() == expected);
|
CHECK (*sp == "xyz"_expect);
|
||||||
CHECK ("abc" == sp.next());
|
++sp;
|
||||||
CHECK (!sp.isValid());
|
CHECK (*sp == ExpectString{expected});
|
||||||
|
++sp;
|
||||||
|
CHECK (*sp == "abc"_expect);
|
||||||
|
++sp;
|
||||||
|
CHECK (isnil (sp));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -158172,8 +158172,7 @@ unsigned int ThreadIdAsInt = *static_cast<unsigned int*>(static_cast<vo
|
||||||
d.h. je nachdem, was man machen möchte: Skalieren, Positionieren, Farbraum-Mapping
|
d.h. je nachdem, was man machen möchte: Skalieren, Positionieren, Farbraum-Mapping
|
||||||
</p>
|
</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html></richcontent>
|
||||||
</richcontent>
|
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1745790970318" ID="ID_89388403" MODIFIED="1745790990806" TEXT="Device-Driver für Video-Controller und X-Server müssen XV unterstützen"/>
|
<node CREATED="1745790970318" ID="ID_89388403" MODIFIED="1745790990806" TEXT="Device-Driver für Video-Controller und X-Server müssen XV unterstützen"/>
|
||||||
</node>
|
</node>
|
||||||
|
|
@ -161391,8 +161390,8 @@ Since then others have made contributions, see the log for the history.</font></
|
||||||
</node>
|
</node>
|
||||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1742175611912" ID="ID_16098937" MODIFIED="1742175617591" TEXT="etwas aufräumen">
|
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1742175611912" ID="ID_16098937" MODIFIED="1742175617591" TEXT="etwas aufräumen">
|
||||||
<icon BUILTIN="flag-yellow"/>
|
<icon BUILTIN="flag-yellow"/>
|
||||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1742175621250" ID="ID_1886919024" MODIFIED="1742175634845" TEXT="boost-filesystem loswerden!">
|
<node COLOR="#338800" CREATED="1742175621250" FOLDED="true" ID="ID_1886919024" MODIFIED="1745860228467" TEXT="boost-filesystem loswerden!">
|
||||||
<icon BUILTIN="flag-yellow"/>
|
<icon BUILTIN="button_ok"/>
|
||||||
<node CREATED="1744754918427" ID="ID_368377472" MODIFIED="1745799970522" TEXT="lib/searchpath.hpp">
|
<node CREATED="1744754918427" ID="ID_368377472" MODIFIED="1745799970522" TEXT="lib/searchpath.hpp">
|
||||||
<linktarget COLOR="#a9b4c1" DESTINATION="ID_368377472" ENDARROW="Default" ENDINCLINATION="47;6;" ID="Arrow_ID_1410738800" SOURCE="ID_883309222" STARTARROW="None" STARTINCLINATION="54;6;"/>
|
<linktarget COLOR="#a9b4c1" DESTINATION="ID_368377472" ENDARROW="Default" ENDINCLINATION="47;6;" ID="Arrow_ID_1410738800" SOURCE="ID_883309222" STARTARROW="None" STARTINCLINATION="54;6;"/>
|
||||||
<linktarget COLOR="#a9b4c1" DESTINATION="ID_368377472" ENDARROW="Default" ENDINCLINATION="107;14;" ID="Arrow_ID_1432393919" SOURCE="ID_1713220396" STARTARROW="None" STARTINCLINATION="74;7;"/>
|
<linktarget COLOR="#a9b4c1" DESTINATION="ID_368377472" ENDARROW="Default" ENDINCLINATION="107;14;" ID="Arrow_ID_1432393919" SOURCE="ID_1713220396" STARTARROW="None" STARTINCLINATION="74;7;"/>
|
||||||
|
|
@ -161439,19 +161438,29 @@ Since then others have made contributions, see the log for the history.</font></
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1745800050780" ID="ID_53680199" MODIFIED="1745800058623" TEXT="Impl. verwendet SearchPatchSplitter">
|
<node COLOR="#435e98" CREATED="1745800050780" ID="ID_53680199" MODIFIED="1745860206848" TEXT="Impl. verwendet SearchPatchSplitter">
|
||||||
<node CREATED="1745800059996" ID="ID_1732566176" MODIFIED="1745800114759" TEXT="dies ist ein »Iterator« — aber kein Lumiera Forward Iterator">
|
<icon BUILTIN="messagebox_warning"/>
|
||||||
|
<node CREATED="1745800193650" ID="ID_490272268" MODIFIED="1745850089541" TEXT="nimmt einen boost::fsys::path in den ctor"/>
|
||||||
|
<node CREATED="1745800146421" ID="ID_274063300" MODIFIED="1745800186494" TEXT="wird noch vewendet von configfacade.cpp und ui-style.cpp"/>
|
||||||
|
<node COLOR="#338800" CREATED="1745800059996" ID="ID_1732566176" MODIFIED="1745860210862" TEXT="dies ist ein »Iterator« — aber kein Lumiera Forward Iterator">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head>
|
||||||
|
|
||||||
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
...das war vermutlich mein erster Versuch, eine Iterator-Klasse in C++ zu bauen.
|
...das war vermutlich mein erster Versuch, eine Iterator-Klasse in C++ zu bauen — hatte mich dabei offensichtlich an Java orientiert
|
||||||
</p>
|
</p>
|
||||||
</body>
|
</body>
|
||||||
</html></richcontent>
|
</html>
|
||||||
|
</richcontent>
|
||||||
|
<icon BUILTIN="button_ok"/>
|
||||||
|
<node CREATED="1745850122914" ID="ID_1543137724" MODIFIED="1745850144722" TEXT="inzwischen können „wir“ das vieeel besser"/>
|
||||||
|
<node CREATED="1745850145440" ID="ID_1260012350" MODIFIED="1745850185900" TEXT="der RegexpSearchIter bietet sich da gradezu an (⟶ siehe CSV.hpp)"/>
|
||||||
|
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1745859667169" ID="ID_161905722" MODIFIED="1745859694033" TEXT="Vorsicht: Regexp-Search verweist in bestehenden String">
|
||||||
|
<icon BUILTIN="clanbomber"/>
|
||||||
|
</node>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1745800146421" ID="ID_274063300" MODIFIED="1745800186494" TEXT="wird noch vewendet von configfacade.cpp und ui-style.cpp"/>
|
|
||||||
<node CREATED="1745800193650" ID="ID_490272268" MODIFIED="1745800204496" TEXT="nimmt einen boost::fsys::path in den ctor"/>
|
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue