YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
ResourceFinder.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-FileCopyrightText: 2006-2010 RobotCub Consortium
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
8
9#include <yarp/conf/dirs.h>
12
13#include <yarp/os/Bottle.h>
14#include <yarp/os/Network.h>
15#include <yarp/os/Os.h>
16#include <yarp/os/Property.h>
17#include <yarp/os/SystemClock.h>
18#include <yarp/os/Time.h>
22
23#include <cerrno>
24#include <cstdio>
25#include <cstdlib>
26#include <string>
27
28using namespace yarp::os;
29using namespace yarp::os::impl;
30namespace fs = yarp::conf::filesystem;
31
32#define RTARGET stderr
33#define RESOURCE_FINDER_CACHE_TIME 10
34
35namespace {
36#ifndef YARP_NO_DEPRECATED // since YARP 3.4
37// The log component cannot be const because we still support setVerbose and
38// setQuiet
39YARP_OS_NON_CONST_LOG_COMPONENT(RESOURCEFINDER, "yarp.os.ResourceFinder")
40#else
41YARP_OS_LOG_COMPONENT(RESOURCEFINDER, "yarp.os.ResourceFinder")
42#endif
43
44std::vector<std::string> bottle_to_vector(const Bottle& b)
45{
46 std::vector<std::string> out;
47 for (size_t i = 0; i < b.size(); ++i) {
48 out.push_back(b.get(i).asString());
49 }
50 return out;
51}
52
53Bottle vector_to_bottle(const std::vector<std::string>& v)
54{
55 Bottle out;
56 for (const auto& s : v) {
57 out.addString(s);
58 }
59 return out;
60}
61
62} // namespace
63
64static std::string getPwd()
65{
66 std::string result;
67 int len = 5;
68 char* buf = nullptr;
69 while (true) {
70 delete[] buf;
71 buf = new char[len];
72 if (buf == nullptr) {
73 break;
74 }
75 char* dir = yarp::os::getcwd(buf, len);
76 if (dir != nullptr) {
77 result = dir;
78 break;
79 }
80 if (errno != ERANGE) {
81 break;
82 }
83 len *= 2;
84 }
85 delete[] buf;
86 buf = nullptr;
87 return result;
88}
89
90
91static void appendResourceType(std::string& path,
92 const std::string& resourceType)
93{
94 if (resourceType.empty()) {
95 return;
96 }
97 std::string slash{fs::preferred_separator};
98 if (path.length() > 0) {
99 if (path[path.length() - 1] != slash[0]) {
100 path +=slash;
101 }
102 }
103 path += resourceType;
104}
105
106static void prependResourceType(std::string& path,
107 const std::string& resourceType)
108{
109 if (resourceType.empty()) {
110 return;
111 }
112 std::string slash{fs::preferred_separator};
113 path = resourceType + slash + path;
114}
115
116static void appendResourceType(std::vector<std::string>& paths,
117 const std::string& resourceType)
118{
119 for (auto& txt : paths) {
120 appendResourceType(txt, resourceType);
121 }
122}
123
124
125//---------------------------------------------------------------------------------------------------
127{
128private:
129 yarp::os::Bottle apps;
130 std::string configFilePath;
131 yarp::os::Property cache;
132 bool mainActive{false};
133 bool useNearMain{false};
134
135public:
136 bool addAppName(const std::string& appName)
137 {
138 apps.addString(appName);
139 return true;
140 }
141
143 {
144 apps.clear();
145 return true;
146 }
147
148 static std::string extractPath(const std::string& fname)
149 {
150 std::string s{fname};
151 auto n = s.rfind('/');
152#if defined(_WIN32)
153 if (n == std::string::npos) {
154 n = s.rfind('\\');
155 }
156#endif
157 if (n != std::string::npos) {
158 return s.substr(0, n);
159 }
160 return {};
161 }
162
163 bool configureProp(Property& config, int argc, char* argv[], bool skip)
164 {
165 Property p;
166 p.fromCommand(argc, argv, skip);
167
168 bool user_specified_from = p.check("from");
169
170 if (p.check("verbose")) {
171 yCWarning(RESOURCEFINDER, "The 'verbose' option is deprecated.");
172 }
173
174 yCDebug(RESOURCEFINDER, "configuring");
175
176 bool configured_normally = true;
177
178 if (p.check("context")) {
180 std::string c = p.check("context", Value("default")).asString();
181 addAppName(c.c_str());
182 yCDebug(RESOURCEFINDER, "added context %s", c.c_str());
183 }
184
185 config.fromCommand(argc, argv, skip, false);
186 if (config.check("from")) {
187 std::string from = config.check("from", Value("config.ini")).toString();
188 yCDebug(RESOURCEFINDER, "default config file specified as %s", from.c_str());
189 mainActive = true;
190 std::string corrected = findFile(config, from, nullptr);
191 mainActive = false;
192 if (!corrected.empty()) {
193 from = corrected;
194 }
195 std::string fromPath = extractPath(from.c_str());
196 configFilePath = fromPath;
197 if (!config.fromConfigFile(from, false) && user_specified_from) {
198 configured_normally = false;
199 }
200 config.fromCommand(argc, argv, skip, false);
201 }
202 return configured_normally;
203 }
204
205 bool setDefault(Property& config, const std::string& key, const yarp::os::Value& val)
206 {
207 if (!config.check(key)) {
208 config.put(key, val);
209 }
210 return true;
211 }
212
213 bool isAbsolute(const std::string& str)
214 {
215 if (str.length() > 0 && (str[0] == '/' || str[0] == '\\')) {
216 return true;
217 }
218 if (str.length() > 1) {
219 if (str[1] == ':') {
220 return true;
221 }
222 }
223 return false;
224 }
225
226 bool isRooted(const std::string& str)
227 {
228 if (isAbsolute(str)) {
229 return true;
230 }
231 if (str.length() >= 2) {
232 if (str[0] == '.' && (str[1] == '/' || str[1] == '\\')) {
233 return true;
234 }
235 } else if (str == ".") {
236 return true;
237 }
238 return false;
239 }
240
241 std::string getPath(const std::string& base1,
242 const std::string& base2,
243 const std::string& base3,
244 const std::string& name)
245 {
246 if (isAbsolute(name)) {
247 return name;
248 }
249
250 std::string s;
251 std::string slash{fs::preferred_separator};
252
253 if (!base1.empty()) {
254 s = base1;
255 s = s + slash;
256 }
257
258 if (isRooted(base2)) {
259 s = base2;
260 } else {
261 s = s + base2;
262 }
263 if (!base2.empty()) {
264 s = s + slash;
265 }
266
267 if (isRooted(base3)) {
268 s = base3;
269 } else {
270 s = s + base3;
271 }
272 if (!base3.empty()) {
273 s = s + slash;
274 }
275
276 s = s + name;
277
278 return s;
279 }
280
281 std::string check(const std::string& base1,
282 const std::string& base2,
283 const std::string& base3,
284 const std::string& name,
285 bool isDir,
286 const Bottle& doc,
287 const std::string& doc2)
288 {
289 std::string s = getPath(base1, base2, base3, name);
290
291 // check cache first
292 Bottle* prev = cache.find(s).asList();
293 if (prev != nullptr) {
294 double t = prev->get(0).asFloat64();
295 int flag = prev->get(1).asInt32();
297 if (flag != 0) {
298 return s;
299 }
300 return {};
301 }
302 }
303
304 std::string base = doc.toString();
305 yCDebug(RESOURCEFINDER, "checking [%s] (%s%s%s)", s.c_str(), base.c_str(), (base.length() == 0) ? "" : " ", doc2.c_str());
306
307 bool ok = exists(s.c_str(), isDir);
308 Value status;
309 yCAssert(RESOURCEFINDER, status.asList());
310 status.asList()->addFloat64(SystemClock::nowSystem());
311 status.asList()->addInt32(ok ? 1 : 0);
312 cache.put(s, status);
313 if (ok) {
314 yCDebug(RESOURCEFINDER, "found %s", s.c_str());
315 return s;
316 }
317 return {};
318 }
319
320 std::string findPath(Property& config, const std::string& name, const ResourceFinderOptions* externalOptions)
321 {
322 std::string fname = config.check(name, Value(name)).asString();
323 std::string result = findFileBase(config, fname, true, externalOptions);
324 return result;
325 }
326
327 std::vector<std::string> findPaths(Property& config, const std::string& name, const ResourceFinderOptions* externalOptions, bool enforcePlural = true)
328 {
329 std::string fname = config.check(name, Value(name)).asString();
330 std::vector<std::string> paths;
331 if (externalOptions != nullptr) {
332 if (externalOptions->duplicateFilesPolicy == ResourceFinderOptions::All) {
333 findFileBase(config, fname, true, paths, *externalOptions);
334 return paths;
335 }
336 }
338 if (externalOptions != nullptr) {
340 }
341 if (enforcePlural) {
342 opts.duplicateFilesPolicy = ResourceFinderOptions::All;
343 }
344 findFileBase(config, fname, true, paths, opts);
345 return paths;
346 }
347
348 std::string findPath(Property& config)
349 {
350 std::string result = findFileBase(config, "", true, nullptr);
351 if (result.empty()) {
352 result = getPwd();
353 }
354 return result;
355 }
356
357 std::string findFile(Property& config, const std::string& name, const ResourceFinderOptions* externalOptions)
358 {
359 std::string fname = config.check(name, Value(name)).asString();
360 std::string result = findFileBase(config, fname, false, externalOptions);
361 return result;
362 }
363
364 std::string findFileByName(Property& config, const std::string& fname, const ResourceFinderOptions* externalOptions)
365 {
366 std::string result = findFileBase(config, fname, false, externalOptions);
367 return result;
368 }
369
370 std::string findFileBase(Property& config, const std::string& name, bool isDir, const ResourceFinderOptions* externalOptions)
371 {
372 std::vector<std::string> output;
374 if (externalOptions == nullptr) {
376 }
377 findFileBase(config, name, isDir, output, *externalOptions);
378 return output.empty() ? std::string{} : output.at(0);
379 }
380
382 {
383 if (opts.messageFilter == ResourceFinderOptions::ShowNone) {
384 return false;
385 }
386 return true;
387 }
388
389 void findFileBase(Property& config, const std::string& name, bool isDir, std::vector<std::string>& output, const ResourceFinderOptions& opts)
390 {
391 Bottle doc;
392 size_t prelen = output.size();
393 findFileBaseInner(config, name, isDir, true, output, opts, doc, {});
394 if (output.size() != prelen) {
395 return;
396 }
397 bool justTop = (opts.duplicateFilesPolicy == ResourceFinderOptions::First);
398 if (justTop) {
399 if (canShowErrors(opts)) {
400 yCDebug(RESOURCEFINDER, "did not find %s", name.c_str());
401 }
402 }
403 }
404
405 static void addString(std::vector<std::string>& output, const std::string& txt)
406 {
407 for (const auto& str : output) {
408 if (txt == str) {
409 return;
410 }
411 }
412 output.push_back(txt);
413 }
414
415 void findFileBaseInner(Property& config, const std::string& name, bool isDir, bool allowPathd, std::vector<std::string>& output, const ResourceFinderOptions& opts, const Bottle& predoc, const std::string& reason)
416 {
417 Bottle doc;
418 doc = predoc;
419 if (!reason.empty()) {
420 doc.addString(reason);
421 }
424 std::string resourceType = opts.resourceType;
425
426 bool justTop = (opts.duplicateFilesPolicy == ResourceFinderOptions::First);
427
428 // check current directory
430 if (name.empty() && isDir) {
431 addString(output, getPwd());
432 if (justTop) {
433 return;
434 }
435 }
436 std::string str = check(getPwd(), resourceType, "", name, isDir, doc, "pwd");
437 if (!str.empty()) {
438 if (mainActive) {
439 useNearMain = true;
440 }
441 addString(output, str);
442 if (justTop) {
443 return;
444 }
445 }
446 }
447
448 if (((locs & ResourceFinderOptions::NearMainConfig) != 0) && useNearMain) {
449 if (!configFilePath.empty()) {
450 std::string str = check(configFilePath, resourceType, "", name, isDir, doc, "defaultConfigFile path");
451 if (!str.empty()) {
452 addString(output, str);
453 if (justTop) {
454 return;
455 }
456 }
457 }
458 }
459
460 if ((locs & ResourceFinderOptions::Robot) != 0) {
461 std::string slash{fs::preferred_separator};
462 bool found = false;
463 std::string robot = yarp::conf::environment::get_string("YARP_ROBOT_NAME", &found);
464 if (!found) {
465 robot = "default";
466 }
467
468 // Nested search to locate robot directory
469 std::vector<std::string> paths;
472 opts2.resourceType = "robots";
473 opts2.duplicateFilesPolicy = ResourceFinderOptions::All;
474 findFileBaseInner(config, robot, true, allowPathd, paths, opts2, doc, "robot");
475 appendResourceType(paths, resourceType);
476 for (const auto& path : paths) {
477 std::string str = check(path,
478 "",
479 "",
480 name,
481 isDir,
482 doc,
483 "robot");
484 if (!str.empty()) {
485 addString(output, str);
486 if (justTop) {
487 return;
488 }
489 }
490 }
491 }
492
493 if (((locs & ResourceFinderOptions::Context) != 0) && !useNearMain) {
494 for (size_t i = 0; i < apps.size(); i++) {
495 std::string app = apps.get(i).asString();
496
497 // New context still apparently applies only to "applications"
498 // which means we need to restrict our attention to "app"
499 // directories.
500
501 // Nested search to locate context directory
502 std::vector<std::string> paths;
504 prependResourceType(app, "contexts");
506 opts2.duplicateFilesPolicy = ResourceFinderOptions::All;
507 findFileBaseInner(config, app, true, allowPathd, paths, opts2, doc, "context");
508 appendResourceType(paths, resourceType);
509 for (const auto& path : paths) {
510 std::string str = check(path, "", "", name, isDir, doc, "context");
511 if (!str.empty()) {
512 addString(output, str);
513 if (justTop) {
514 return;
515 }
516 }
517 }
518 }
519 }
520
521 // check YARP_CONFIG_HOME
523 std::string home = yarp::conf::dirs::yarpconfighome();
524 if (!home.empty()) {
525 appendResourceType(home, resourceType);
526 std::string str = check(home, "", "", name, isDir, doc, "YARP_CONFIG_HOME");
527 if (!str.empty()) {
528 addString(output, str);
529 if (justTop) {
530 return;
531 }
532 }
533 }
534 }
535
536 // check YARP_DATA_HOME
538 std::string home = yarp::conf::dirs::yarpdatahome();
539 if (!home.empty()) {
540 appendResourceType(home, resourceType);
541 std::string str = check(home, "", "", name, isDir, doc, "YARP_DATA_HOME");
542 if (!str.empty()) {
543 addString(output, str);
544 if (justTop) {
545 return;
546 }
547 }
548 }
549 }
550
551 // check YARP_CONFIG_DIRS
554 appendResourceType(dirs, resourceType);
555 for (const auto& dir : dirs) {
556 std::string str = check(dir,
557 "",
558 "",
559 name,
560 isDir,
561 doc,
562 "YARP_CONFIG_DIRS");
563 if (!str.empty()) {
564 addString(output, str);
565 if (justTop) {
566 return;
567 }
568 }
569 }
570 }
571
572 // check YARP_DATA_DIRS
574 auto dirs = yarp::conf::dirs::yarpdatadirs();
575 appendResourceType(dirs, resourceType);
576 for (const auto& dir : dirs) {
577 std::string str = check(dir,
578 "",
579 "",
580 name,
581 isDir,
582 doc,
583 "YARP_DATA_DIRS");
584 if (!str.empty()) {
585 addString(output, str);
586 if (justTop) {
587 return;
588 }
589 }
590 }
591 }
592
594 // Nested search to locate path.d directories
595 std::vector<std::string> pathd_paths;
598 opts2.resourceType = "config";
599 findFileBaseInner(config, "path.d", true, false, pathd_paths, opts2, doc, "path.d");
600
601 for (const auto& pathd_path : pathd_paths) {
602 // check /.../path.d/*
603 // this directory is expected to contain *.ini files like this:
604 // [search BUNDLE_NAME]
605 // path /PATH1 /PATH2
606 // for example:
607 // [search icub]
608 // path /usr/share/iCub
610 pathd.fromConfigFile(pathd_path);
611 Bottle sections = pathd.findGroup("search").tail();
612 for (size_t i = 0; i < sections.size(); i++) {
613 std::string search_name = sections.get(i).asString();
614 Bottle group = pathd.findGroup(search_name);
615 auto paths_v = bottle_to_vector(group.findGroup("path").tail());
616 appendResourceType(paths_v, resourceType);
617 for (const auto& path : paths_v) {
618 std::string str = check(path, "", "", name, isDir, doc, "yarp.d");
619 if (!str.empty()) {
620 addString(output, str);
621 if (justTop) {
622 return;
623 }
624 }
625 }
626 }
627 }
628 }
629 }
630
631 bool exists(const std::string& fname, bool isDir)
632 {
633 int result = yarp::os::stat(fname.c_str());
634 if (result != 0) {
635 return false;
636 }
637 if (!isDir) {
638 // if not required to be a directory, pass anything.
639 return true;
640 }
641
642 // ACE doesn't seem to help us interpret the results of stat
643 // in a portable fashion.
644
645 // ACE on Ubuntu 9.10 has issues.
646 // Suppressing check for file here since it isn't really needed
647 // and causes a lot of problems.
648 /*
649 YARP_DIR *dir = ACE_OS::opendir(fname);
650 if (dir!=nullptr) {
651 ACE_OS::closedir(dir);
652 dir = nullptr;
653 return true;
654 }
655 return false;
656 */
657 return true;
658 }
659
660
661 std::string getContext()
662 {
663 return apps.get(0).asString();
664 }
665
667 {
668 return apps;
669 }
670
671 std::string getHomeContextPath(Property& config, const std::string& context)
672 {
673 YARP_UNUSED(config);
674 if (useNearMain) {
675 return configFilePath;
676 }
677 std::string path = getPath(yarp::conf::dirs::yarpdatahome(), "contexts", context, "");
678
679 std::string slash{fs::preferred_separator};
680 if (path.length() > 1) {
681 if (path[path.length() - 1] == slash[0]) {
682 path = path.substr(0, path.length() - slash.size());
683 }
684 }
685
686 std::string parentPath = getPath(yarp::conf::dirs::yarpdatahome(), "contexts", "", "");
687 if (yarp::os::stat(parentPath.c_str()) != 0) {
689 }
690
691 if (yarp::os::mkdir_p(path.c_str()) < 0 && errno != EEXIST) {
692 yCWarning(RESOURCEFINDER, "Could not create %s directory", path.c_str());
693 }
694 return path;
695 }
696
697 std::string getHomeRobotPath()
698 {
699 if (useNearMain) {
700 return configFilePath;
701 }
702 bool found = false;
703 std::string robot = yarp::conf::environment::get_string("YARP_ROBOT_NAME", &found);
704 if (!found) {
705 robot = "default";
706 }
707 std::string path = getPath(yarp::conf::dirs::yarpdatahome(), "robots", robot, "");
708
709 std::string slash{fs::preferred_separator};
710 if (path.length() > 1) {
711 if (path[path.length() - 1] == slash[0]) {
712 path = path.substr(0, path.length() - slash.size());
713 }
714 }
715
716 std::string parentPath = getPath(yarp::conf::dirs::yarpdatahome(), "robots", "", "");
717 if (yarp::os::stat(parentPath.c_str()) != 0) {
719 }
720
721 if (yarp::os::mkdir_p(path.c_str()) < 0 && errno != EEXIST) {
722 yCWarning(RESOURCEFINDER, "Could not create %s directory", path.c_str());
723 }
724 return path;
725 }
726};
727
728
729//---------------------------------------------------------------------------------------------------
731 Searchable(),
732 m_owned(true),
733 m_nullConfig(false),
734 m_isConfiguredFlag(false),
735 mPriv(nullptr)
736{
738 mPriv = new Private();
739}
740
743 m_owned(true),
744 m_nullConfig(false),
745 m_isConfiguredFlag(false),
746 mPriv(nullptr)
747{
749 mPriv = new Private();
750 *this = alt;
751}
752
754 Searchable(),
755 m_owned(false),
756 m_nullConfig(data.isNull()),
757 m_isConfiguredFlag(true),
758 mPriv(nullptr)
759{
761 this->mPriv = altPriv;
762 if (!data.isNull()) {
763 m_configprop.fromString(data.toString());
764 }
765}
766
768{
769 if (m_owned) {
770 delete mPriv;
771 }
772}
773
775{
776 if (&alt != this) {
777 *(mPriv) = *(alt.mPriv);
778 m_owned = true;
779 m_nullConfig = alt.m_nullConfig;
780 m_isConfiguredFlag = alt.m_isConfiguredFlag;
781 m_configprop = alt.m_configprop;
782 }
783 return *this;
784}
785
786bool ResourceFinder::configure(int argc, char* argv[], bool skipFirstArgument)
787{
788 m_isConfiguredFlag = true;
789 return mPriv->configureProp(m_configprop, argc, argv, skipFirstArgument);
790}
791
792
793bool ResourceFinder::addContext(const std::string& appName)
794{
795 if (appName[0] == '\0') {
796 return true;
797 }
798 yCDebug(RESOURCEFINDER, "adding context [%s]", appName.c_str());
799 return mPriv->addAppName(appName);
800}
801
802bool ResourceFinder::clearContext()
803{
804 yCDebug(RESOURCEFINDER, "clearing context");
805 return mPriv->clearAppNames();
806}
807
808bool ResourceFinder::setDefault(const std::string& key, const std::string& val)
809{
810 Value val2;
811 val2.fromString(val.c_str());
812 return mPriv->setDefault(m_configprop, key, val2);
813}
814
815bool ResourceFinder::setDefault(const std::string& key, std::int32_t val)
816{
817 return mPriv->setDefault(m_configprop, key, Value(val));
818}
819
820bool ResourceFinder::setDefault(const std::string& key, yarp::conf::float64_t val)
821{
822 return mPriv->setDefault(m_configprop, key, Value(val));
823}
824
825bool ResourceFinder::setDefault(const std::string& key, const yarp::os::Value& val)
826{
827 return mPriv->setDefault(m_configprop, key, val);
828}
829
830std::string ResourceFinder::findFile(const std::string& name)
831{
832 yCDebug(RESOURCEFINDER, "finding file [%s]", name.c_str());
833 return mPriv->findFile(m_configprop, name, nullptr);
834}
835
836std::string ResourceFinder::findFile(const std::string& name,
837 const ResourceFinderOptions& options)
838{
839 yCDebug(RESOURCEFINDER, "finding file [%s]", name.c_str());
840 return mPriv->findFile(m_configprop, name, &options);
841}
842
843std::string ResourceFinder::findFileByName(const std::string& name)
844{
845 yCDebug(RESOURCEFINDER, "finding file %s", name.c_str());
846 return mPriv->findFileByName(m_configprop, name, nullptr);
847}
848
849std::string ResourceFinder::findFileByName(const std::string& name,
850 const ResourceFinderOptions& options)
851{
852 yCDebug(RESOURCEFINDER, "finding file %s", name.c_str());
853 return mPriv->findFileByName(m_configprop, name, &options);
854}
855
856
857std::string ResourceFinder::findPath(const std::string& name)
858{
859 yCDebug(RESOURCEFINDER, "finding path [%s]", name.c_str());
860 return mPriv->findPath(m_configprop, name, nullptr);
861}
862
863std::string ResourceFinder::findPath(const std::string& name,
864 const ResourceFinderOptions& options)
865{
866 yCDebug(RESOURCEFINDER, "finding path [%s]", name.c_str());
867 return mPriv->findPath(m_configprop, name, &options);
868}
869
871{
872 yCDebug(RESOURCEFINDER, "finding paths [%s]", name.c_str());
873 return vector_to_bottle(mPriv->findPaths(m_configprop, name, nullptr));
874}
875
877 const ResourceFinderOptions& options)
878{
879 yCDebug(RESOURCEFINDER, "finding paths [%s]", name.c_str());
880 return vector_to_bottle(mPriv->findPaths(m_configprop, name, &options));
881}
882
884{
885 yCDebug(RESOURCEFINDER, "finding path");
886 return mPriv->findPath(m_configprop);
887}
888
889#ifndef YARP_NO_DEPRECATED // Since YARP 3.4
891{
892 RESOURCEFINDER().setMinimumPrintLevel(verbose ? yarp::os::Log::DebugType : yarp::os::Log::InfoType);
893 return true;
894}
895
897{
898 RESOURCEFINDER().setMinimumPrintLevel(quiet ? yarp::os::Log::WarningType : yarp::os::Log::InfoType);
899 return true;
900}
901#endif
902
903bool ResourceFinder::check(const std::string& key) const
904{
905 return m_configprop.check(key);
906}
907
908
909Value& ResourceFinder::find(const std::string& key) const
910{
911 return m_configprop.find(key);
912}
913
914
915Bottle& ResourceFinder::findGroup(const std::string& key) const
916{
917 return m_configprop.findGroup(key);
918}
919
920
922{
923 return m_nullConfig || m_configprop.isNull();
924}
925
926
927std::string ResourceFinder::toString() const
928{
929 return m_configprop.toString();
930}
931
933{
934 return mPriv->getContext();
935}
936
938{
939 return mPriv->getHomeContextPath(m_configprop, mPriv->getContext());
940}
941
943{
944 return mPriv->getHomeRobotPath();
945}
946
948{
949 return mPriv->getContexts();
950}
951
952
954{
955 return ResourceFinder(findGroup(key), mPriv);
956}
957
958
960{
961 static ResourceFinder instance;
962 return instance;
963}
964
966 const std::string& key,
967 const ResourceFinderOptions& options)
968{
969 std::vector<std::string> paths = mPriv->findPaths(config, key, &options, false);
970
971 for (auto it = paths.rbegin(); it != paths.rend(); ++it) {
972 const auto& path = *it;
973 config.fromConfigFile(path, false);
974 }
975
976 return !paths.empty();
977}
float t
static void appendResourceType(std::string &path, const std::string &resourceType)
static void prependResourceType(std::string &path, const std::string &resourceType)
#define RESOURCE_FINDER_CACHE_TIME
static std::string getPwd()
constexpr fs::value_type slash
Definition Run.cpp:98
bool setDefault(Property &config, const std::string &key, const yarp::os::Value &val)
bool addAppName(const std::string &appName)
std::string getPath(const std::string &base1, const std::string &base2, const std::string &base3, const std::string &name)
static void addString(std::vector< std::string > &output, const std::string &txt)
std::vector< std::string > findPaths(Property &config, const std::string &name, const ResourceFinderOptions *externalOptions, bool enforcePlural=true)
bool exists(const std::string &fname, bool isDir)
bool isRooted(const std::string &str)
std::string findFileBase(Property &config, const std::string &name, bool isDir, const ResourceFinderOptions *externalOptions)
std::string getHomeContextPath(Property &config, const std::string &context)
bool configureProp(Property &config, int argc, char *argv[], bool skip)
void findFileBase(Property &config, const std::string &name, bool isDir, std::vector< std::string > &output, const ResourceFinderOptions &opts)
std::string findPath(Property &config)
std::string check(const std::string &base1, const std::string &base2, const std::string &base3, const std::string &name, bool isDir, const Bottle &doc, const std::string &doc2)
std::string findFileByName(Property &config, const std::string &fname, const ResourceFinderOptions *externalOptions)
void findFileBaseInner(Property &config, const std::string &name, bool isDir, bool allowPathd, std::vector< std::string > &output, const ResourceFinderOptions &opts, const Bottle &predoc, const std::string &reason)
bool canShowErrors(const ResourceFinderOptions &opts) const
std::string findPath(Property &config, const std::string &name, const ResourceFinderOptions *externalOptions)
bool isAbsolute(const std::string &str)
std::string findFile(Property &config, const std::string &name, const ResourceFinderOptions *externalOptions)
static std::string extractPath(const std::string &fname)
A simple collection of objects that can be described and transmitted in a portable way.
Definition Bottle.h:64
size_type size() const
Gets the number of elements in the bottle.
Definition Bottle.cpp:251
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Definition Bottle.cpp:246
Bottle & findGroup(const std::string &key) const override
Gets a list corresponding to a given keyword.
Definition Bottle.cpp:293
Bottle tail() const
Get all but the first element of a bottle.
Definition Bottle.cpp:361
void clear()
Empties the bottle of any objects it contains.
Definition Bottle.cpp:121
void addString(const char *str)
Places a string in the bottle, at the end of the list.
Definition Bottle.cpp:170
A mini-server for performing network communication in the background.
@ DebugType
Definition Log.h:93
@ InfoType
Definition Log.h:94
@ WarningType
Definition Log.h:95
static void autoInitMinimum()
Basic system initialization, not including plugins.
Definition Network.cpp:857
A class for storing options and configuration information.
Definition Property.h:33
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
std::string toString() const override
Return a standard text representation of the content of the object.
void fromString(const std::string &txt, bool wipe=true)
Interprets a string as a list of properties.
bool fromConfigFile(const std::string &fname, bool wipe=true)
Interprets a file as a list of properties.
void put(const std::string &key, const std::string &value)
Associate the given key with the given string.
Definition Property.cpp:987
bool check(const std::string &key) const override
Check if there exists a property of the given name.
Bottle & findGroup(const std::string &key) const override
Gets a list corresponding to a given keyword.
void fromCommand(int argc, char *argv[], bool skipFirst=true, bool wipe=true)
Interprets a list of command arguments as a list of properties.
These options are loosely based on http://wiki.icub.org/wiki/YARP_ResourceFinder.
Helper class for finding config files and other external resources.
bool check(const std::string &key) const override
Check if there exists a property of the given name.
Bottle & findGroup(const std::string &key) const override
Gets a list corresponding to a given keyword.
bool configure(int argc, char *argv[], bool skipFirstArgument=true)
Sets up the ResourceFinder.
std::string getContext()
Return the default "context" or "application name" used in searching for configuration files.
std::string getHomeRobotPath()
Return the path to the "user" robot directory.
std::string findPath()
Find the first existing directory in the search path.
std::string toString() const override
Return a standard text representation of the content of the object.
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
bool isNull() const override
Checks if the object is invalid.
static ResourceFinder & getResourceFinderSingleton()
Access a ResourceFinder singleton whose lifetime will match that of the YARP library.
yarp::os::Bottle findPaths(const std::string &name)
Expand a partial path to a list of paths.
bool setDefault(const std::string &key, const std::string &val)
Provide a default value for a given key.
std::string findFileByName(const std::string &name)
Find the full path to a file.
const ResourceFinder & operator=(const ResourceFinder &alt)
bool readConfig(Property &config, const std::string &key, const ResourceFinderOptions &options)
std::string findFile(const std::string &name)
Find the full path to a file.
bool setQuiet(bool quiet=true)
Request that information be suppressed from the console.
bool setVerbose(bool verbose=true)
Request that information be printed to the console on how resources are being found.
std::string getHomeContextPath()
Return the path to the "user" context directory for the current context.
virtual ResourceFinder findNestedResourceFinder(const std::string &key)
Gets a section as a ResourceFinder object, retaining the context and configuration of the current Res...
yarp::os::Bottle getContexts()
Return the full stack of contexts used in searching for configuration files.
A base class for nested structures that can be searched.
Definition Searchable.h:31
virtual bool isNull() const
Checks if the object is invalid.
virtual std::string toString() const =0
Return a standard text representation of the content of the object.
static double nowSystem()
A single value (typically within a Bottle).
Definition Value.h:43
virtual yarp::conf::float64_t asFloat64() const
Get 64-bit floating point value.
Definition Value.cpp:222
virtual std::int32_t asInt32() const
Get 32-bit integer value.
Definition Value.cpp:204
virtual Bottle * asList() const
Get list value.
Definition Value.cpp:240
virtual std::string asString() const
Get string value.
Definition Value.cpp:234
#define yCAssert(component, x)
#define yCWarning(component,...)
#define yCDebug(component,...)
#define YARP_OS_LOG_COMPONENT(name, name_string)
#define YARP_OS_NON_CONST_LOG_COMPONENT(name, name_string)
std::string yarpdatahome()
Returns the directory where user-specific YARP data files should be written.
Definition dirs.h:254
std::vector< std::string > yarpdatadirs()
Returns the directories where YARP data files should be searched.
Definition dirs.h:274
std::vector< std::string > yarpconfigdirs()
Returns the directories where YARP configuration files should be searched.
Definition dirs.h:320
std::string yarpconfighome()
Returns the directory where user-specific YARP configuration files should be written.
Definition dirs.h:295
std::string get_string(const std::string &key, bool *found=nullptr)
Read a string from an environment variable.
Definition environment.h:66
static constexpr value_type preferred_separator
Definition filesystem.h:21
The components from which ports and connections are built.
An interface to the operating system, including Port based communication.
char * getcwd(char *buf, size_t size)
Portable wrapper for the getcwd() function.
Definition Os.cpp:105
int stat(const char *path)
Portable wrapper for the stat() function.
Definition Os.cpp:78
@ YARP_CLOCK_SYSTEM
Definition Time.h:28
int mkdir_p(const char *p, int ignoreLevels=0)
Create a directory and all parent directories needed.
Definition Os.cpp:35
#define YARP_UNUSED(var)
Definition api.h:162