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
|
||||
resolve (fs::path iniSpec)
|
||||
{
|
||||
string searchpath = iniSpec.parent_path().string(); ///////////TICKET #896
|
||||
string searchpath = iniSpec.parent_path().generic_string();
|
||||
return resolveModulePath (iniSpec.filename(), searchpath);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
#include "include/config-facade.h"
|
||||
#include "common/appstate.hpp"
|
||||
#include "lib/searchpath.hpp"
|
||||
#include "lib/iter-explorer.hpp"
|
||||
#include "lib/format-util.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
|
@ -130,18 +132,11 @@ extern "C" { /* ==== implementation C interface for accessing setup.ini =======
|
|||
|
||||
const char*
|
||||
lumiera_get_plugin_path_default ()
|
||||
{
|
||||
static string pathSpec;
|
||||
if (isnil (pathSpec))
|
||||
{
|
||||
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() +":";
|
||||
}
|
||||
|
||||
{ // Meyer's Singleton...
|
||||
static string pathSpec = []{ string pluginPath = Config::get (KEY_PLUGIN_PATH);
|
||||
return "plugin.path=" // syntax expected by lumiera_config_setdefault
|
||||
+ util::join (SearchPathSplitter{pluginPath}, ":");
|
||||
}();
|
||||
return cStr(pathSpec);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/searchpath.hpp"
|
||||
#include "lib/format-string.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
|
||||
|
||||
|
|
@ -31,10 +32,11 @@
|
|||
|
||||
namespace lib {
|
||||
|
||||
using util::_Fmt;
|
||||
using std::regex;
|
||||
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,
|
||||
|
|
@ -57,9 +59,9 @@ namespace lib {
|
|||
string
|
||||
replaceMagicLinkerTokens (string const& src)
|
||||
{
|
||||
static const regex PICK_ORIGIN_TOKEN ("\\$?ORIGIN/?");
|
||||
static const regex PICK_ORIGIN_TOKEN{"\\$?ORIGIN/?", regex::optimize};
|
||||
static const string expandedOriginDir
|
||||
= findExePath().parent_path().string() + "/"; ///////////TICKET #896
|
||||
= findExePath().parent_path().generic_string() + "/";
|
||||
|
||||
return regex_replace (src, PICK_ORIGIN_TOKEN, expandedOriginDir);
|
||||
}
|
||||
|
|
@ -72,20 +74,21 @@ namespace lib {
|
|||
resolveModulePath (fs::path moduleName, string searchPath)
|
||||
{
|
||||
fs::path modulePathName (moduleName);
|
||||
SearchPathSplitter searchLocation(searchPath); ///////////TICKET #896
|
||||
SearchPathSplitter searchLocation(searchPath);
|
||||
|
||||
while (not fs::exists (modulePathName))
|
||||
{
|
||||
// try / continue search path
|
||||
if (searchLocation.isValid())
|
||||
modulePathName = fs::path() / searchLocation.next() / moduleName;
|
||||
else
|
||||
throw error::Config ("Module \""+moduleName.string()+"\" not found" /////TICKET #896
|
||||
+ (searchPath.empty()? ".":" in search path: "+searchPath));
|
||||
if (not searchLocation)
|
||||
throw error::Config{_Fmt{"Module %s not found%s"}
|
||||
% moduleName
|
||||
%(searchPath.empty()? ".":" in search path: "+searchPath)};
|
||||
modulePathName = *searchLocation / moduleName;
|
||||
++searchLocation;
|
||||
}
|
||||
|
||||
TRACE (config, "found module %s", modulePathName.string().c_str());
|
||||
return modulePathName.string(); ///////////TICKET #896
|
||||
TRACE (config, "found module %s", cStr(modulePathName.generic_string()));
|
||||
return modulePathName.generic_string();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "lib/file.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
|
||||
namespace lib {
|
||||
|
|
@ -56,42 +57,35 @@ namespace lib {
|
|||
* This iterator class dissects a ':'-separated path list. The individual
|
||||
* components may use the symbol \c $ORIGIN to refer to the directory
|
||||
* holding the current executable.
|
||||
* @note #next picks the current component and advances the iteration.
|
||||
*/
|
||||
class SearchPathSplitter
|
||||
: util::NonCopyable
|
||||
: public util::RegexSearchIter
|
||||
{
|
||||
string pathSpec_;
|
||||
std::sregex_iterator pos_,
|
||||
end_;
|
||||
|
||||
static const std::regex EXTRACT_PATHSPEC;
|
||||
static const regex ACCEPT_PATHELEMENT;
|
||||
|
||||
public:
|
||||
SearchPathSplitter (string const& searchPath)
|
||||
: pathSpec_(replaceMagicLinkerTokens (searchPath))
|
||||
, pos_(pathSpec_.begin(),pathSpec_.end(), EXTRACT_PATHSPEC)
|
||||
, end_()
|
||||
SearchPathSplitter() = default;
|
||||
SearchPathSplitter (string& searchPath) ///< @warning search path string must exist somewhere else
|
||||
: RegexSearchIter{searchPath, ACCEPT_PATHELEMENT}
|
||||
{ }
|
||||
|
||||
explicit operator bool() const { return isValid(); }
|
||||
LIFT_PARENT_INCREMENT_OPERATOR (std::sregex_iterator);
|
||||
ENABLE_USE_IN_STD_RANGE_FOR_LOOPS (SearchPathSplitter);
|
||||
|
||||
bool
|
||||
isValid() const
|
||||
{
|
||||
return pos_ != end_;
|
||||
}
|
||||
using value_type = std::string;
|
||||
using reference = value_type&;
|
||||
using pointer = value_type*;
|
||||
|
||||
string
|
||||
next ()
|
||||
operator*() const
|
||||
{
|
||||
if (!isValid())
|
||||
throw error::Logic ("Search path exhausted."
|
||||
,LERR_(ITER_EXHAUST));
|
||||
|
||||
string currentPathElement = pos_->str();
|
||||
++pos_;
|
||||
return currentPathElement;
|
||||
string pathElm = util::RegexSearchIter::operator*()[2];
|
||||
pathElm = boost::algorithm::trim_right_copy(pathElm);
|
||||
return replaceMagicLinkerTokens (pathElm);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -103,7 +97,7 @@ namespace lib {
|
|||
* SearchPathSplitter, until encountering an existing file with the
|
||||
* given name.
|
||||
* @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 = "");
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#include <boost/lexical_cast.hpp>
|
||||
#include <typeinfo>
|
||||
#include <cstdlib>
|
||||
#include <utility>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
|
|
@ -49,7 +50,7 @@
|
|||
|
||||
namespace lib {
|
||||
namespace test{
|
||||
|
||||
|
||||
using lib::Literal;
|
||||
using std::string;
|
||||
using lib::rani;
|
||||
|
|
@ -327,8 +328,13 @@ namespace test{
|
|||
class ExpectString
|
||||
: public std::string
|
||||
{
|
||||
public:
|
||||
using std::string::string;
|
||||
|
||||
ExpectString(std::string && s) : std::string{std::move(s)}{ }
|
||||
ExpectString(std::string const& s) : std::string{s} { }
|
||||
|
||||
|
||||
template<typename X>
|
||||
friend bool
|
||||
operator== (X const& x, ExpectString const& expected)
|
||||
|
|
|
|||
|
|
@ -262,10 +262,10 @@ namespace workspace {
|
|||
return true;
|
||||
|
||||
// Try to resolve the icon via the configured search path
|
||||
lib::SearchPathSplitter iconLocations (iconSearchPath_);
|
||||
while (iconLocations)
|
||||
lib::SearchPathSplitter iconLocations{iconSearchPath_};
|
||||
for (auto const& location : iconLocations)
|
||||
if (addNonThemeIconSource (icon_set
|
||||
,iconLocations.next()
|
||||
,location
|
||||
,icon_name
|
||||
,size
|
||||
,wildcard))
|
||||
|
|
|
|||
|
|
@ -624,17 +624,17 @@ END
|
|||
|
||||
|
||||
TEST "Search path walking" SearchPathSplitter_test <<END
|
||||
out-lit: ➢➢a
|
||||
out-lit: ➢➢a
|
||||
out-lit: ➢➢a
|
||||
out-lit: ➢➢b
|
||||
out-lit: ➢➢a
|
||||
out-lit: ➢➢b
|
||||
out-lit: ➢➢c
|
||||
out: ➢➢.d.
|
||||
out-lit: ➢➢ e f
|
||||
out-lit: ➢➢/usr/bin
|
||||
out-lit: ➢➢/usr/lib
|
||||
out-lit: ▶a◀
|
||||
out-lit: ▶a◀
|
||||
out-lit: ▶a◀
|
||||
out-lit: ▶b◀
|
||||
out-lit: ▶a◀
|
||||
out-lit: ▶b◀
|
||||
out-lit: ▶c◀
|
||||
out-lit: ▶d◀
|
||||
out-lit: ▶e f◀
|
||||
out-lit: ▶/usr/bin◀
|
||||
out-lit: ▶/usr/lib◀
|
||||
return: 0
|
||||
END
|
||||
|
||||
|
|
|
|||
|
|
@ -20,11 +20,12 @@
|
|||
#include "lib/test/test-helper.hpp"
|
||||
#include "lib/format-cout.hpp"
|
||||
#include "lib/file.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include "lib/searchpath.hpp"
|
||||
|
||||
|
||||
|
||||
using util::isnil;
|
||||
|
||||
namespace lib {
|
||||
namespace test {
|
||||
|
|
@ -54,20 +55,21 @@ namespace test {
|
|||
walk ("a:");
|
||||
walk (":a");
|
||||
walk ("a:b");
|
||||
walk (":a:b:c:");
|
||||
walk (" d : e f");
|
||||
walk (":a:b\n:c:");
|
||||
walk (" d : e f ");
|
||||
walk ("/usr/bin:/usr/lib");
|
||||
|
||||
SearchPathSplitter sp("");
|
||||
VERIFY_ERROR (ITER_EXHAUST, sp.next() );
|
||||
SearchPathSplitter sp{};
|
||||
CHECK (not sp);
|
||||
VERIFY_ERROR (ITER_EXHAUST, *sp );
|
||||
}
|
||||
|
||||
void
|
||||
walk (string spec)
|
||||
{
|
||||
SearchPathSplitter path(spec);
|
||||
while (path)
|
||||
cout << "➢➢" << path.next() << endl;
|
||||
SearchPathSplitter path{spec};
|
||||
for (auto const& pathElm : path)
|
||||
cout <<"▶"<< pathElm <<"◀"<< endl;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -78,11 +80,15 @@ namespace test {
|
|||
fs::path exePath{findExePath()};
|
||||
string expected{exePath.parent_path() / "modules"};
|
||||
|
||||
SearchPathSplitter sp("xyz:$ORIGIN/modules:abc");
|
||||
CHECK ("xyz" == sp.next());
|
||||
CHECK (sp.next() == expected);
|
||||
CHECK ("abc" == sp.next());
|
||||
CHECK (!sp.isValid());
|
||||
string searchSpec = "xyz:$ORIGIN/modules:abc";
|
||||
SearchPathSplitter sp{searchSpec};
|
||||
CHECK (*sp == "xyz"_expect);
|
||||
++sp;
|
||||
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
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</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>
|
||||
|
|
@ -161391,8 +161390,8 @@ Since then others have made contributions, see the log for the history.</font></
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1742175611912" ID="ID_16098937" MODIFIED="1742175617591" TEXT="etwas aufräumen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1742175621250" ID="ID_1886919024" MODIFIED="1742175634845" TEXT="boost-filesystem loswerden!">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1742175621250" FOLDED="true" ID="ID_1886919024" MODIFIED="1745860228467" TEXT="boost-filesystem loswerden!">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<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="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 CREATED="1745800050780" ID="ID_53680199" MODIFIED="1745800058623" TEXT="Impl. verwendet SearchPatchSplitter">
|
||||
<node CREATED="1745800059996" ID="ID_1732566176" MODIFIED="1745800114759" TEXT="dies ist ein »Iterator« — aber kein Lumiera Forward Iterator">
|
||||
<node COLOR="#435e98" CREATED="1745800050780" ID="ID_53680199" MODIFIED="1745860206848" TEXT="Impl. verwendet SearchPatchSplitter">
|
||||
<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>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<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>
|
||||
</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 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>
|
||||
|
|
|
|||
Loading…
Reference in a new issue