36 #include <boost/regex.hpp>
38 #include <IceUtil/Handle.h>
40 #include <SimoxUtility/algorithm/string/string_tools.h>
41 #include <SimoxUtility/simox/SimoxPath.h>
59 namespace fs = std::filesystem;
105 ArmarXDataPath::ArmarXDataPath()
112 std::string& storeAbsoluteFilename,
113 const std::vector<std::string>& additionalSearchPaths,
119 const std::filesystem::path
filename(relativeFilename);
122 if (std::filesystem::exists(
filename))
124 storeAbsoluteFilename =
filename.string();
128 const auto search = [&
filename, &storeAbsoluteFilename](
const auto& bases)
130 for (
const auto& currentPath : bases)
132 std::filesystem::path path(currentPath);
134 std::filesystem::path filenameComplete = path /
filename;
136 if (std::filesystem::exists(filenameComplete))
138 storeAbsoluteFilename = filenameComplete.string();
144 const auto searchProject = [&search](
const auto&
project)
149 return search(projectDataPaths);
152 if (search(additionalSearchPaths) || search(ArmarXDataPath_data.
dataPaths))
160 std::filesystem::path p = relativeFilename;
164 p = std::filesystem::relative(p,
"/");
166 while (p.has_parent_path())
168 if (p.parent_path() ==
".")
177 const auto pstr = p.string();
178 if (!pstr.empty() && searchProject(pstr))
199 <<
"\n in the following additional paths: " << additionalSearchPaths
200 <<
"\n or in the following data paths: "
209 const std::vector<std::string>& additionalSearchPaths,
212 std::string storeAbsoluteFilename;
213 getAbsolutePath(relativeFilename, storeAbsoluteFilename, additionalSearchPaths, verbose);
214 return storeAbsoluteFilename;
219 std::string& resultFileName,
222 const auto file_ok = [](
const std::string& f)
223 {
return std::filesystem::exists(f) && std::ifstream(f).good(); };
236 if (std::filesystem::path{queryFileName}.is_absolute() && file_ok(queryFileName))
238 resultFileName = queryFileName;
242 std::string found_file;
243 if (
getAbsolutePath(queryFileName, found_file, {}, verbose) && file_ok(found_file))
245 resultFileName = found_file;
250 std::size_t offset = 0;
251 while (offset != std::string::npos && offset < queryFileName.size())
255 static const std::string dataMarker =
"/data/";
256 offset = queryFileName.find(dataMarker, offset);
257 if (offset == std::string::npos)
261 const std::string prefix_path = queryFileName.substr(0, offset);
262 offset += dataMarker.size();
263 const std::string path_in_data = queryFileName.substr(offset);
268 found_file = simox::SimoxPath::getVirtualRobotDataDir() / path_in_data;
269 if (file_ok(found_file))
271 resultFileName = found_file;
276 if (
getAbsolutePath(path_in_data, found_file, {}, verbose) && file_ok(found_file))
278 resultFileName = found_file;
281 const std::size_t slash_offset = path_in_data.find(
"/");
282 if (slash_offset == std::string::npos)
286 const std::string package_name = path_in_data.substr(0, slash_offset);
293 resultFileName = found_file;
302 const std::string& relativeFilename)
304 std::filesystem::path fn(relativeFilename);
305 for (
auto currentProject : projects)
311 ARMARX_VERBOSE_S <<
"ArmarX Package " << currentProject <<
" has not been found!";
317 std::filesystem::path fnComplete = p / fn;
319 if (std::filesystem::exists(fnComplete))
322 return currentProject;
326 return std::string();
333 std::filesystem::path p(filepathStr);
334 std::filesystem::path result;
336 for (std::filesystem::path::iterator it = p.begin(); it != p.end(); ++it)
338 if (*it ==
".." && it != p.begin())
341 bool isSymLink =
false;
345 isSymLink = std::filesystem::is_symlink(result);
347 catch (std::filesystem::filesystem_error&)
357 else if (result.filename() ==
"..")
364 result = result.parent_path();
378 return result.string();
387 for (
auto absolutePathPart = std::filesystem::path(absolutePathString);
388 absolutePathPart != absolutePathPart.parent_path();
389 absolutePathPart = absolutePathPart.parent_path())
391 for (
const auto& dataPath : ArmarXDataPath_data.
dataPaths)
393 const std::filesystem::path p(dataPath);
395 if (std::filesystem::equivalent(p, absolutePathPart))
397 return relativeTo(p.string(), absolutePathString);
402 throw LocalException() <<
"Could not make path relative to any ArmarX data path for '"
403 << absolutePathString <<
"'. "
404 <<
"Considered the following paths: "
406 return absolutePathString;
415 fs::path from(fromStr);
417 fs::path::const_iterator fromIter = (from).begin();
418 fs::path::const_iterator toIter = (to).begin();
421 throw LocalException(
"From path is empty");
425 throw LocalException(
"To path is empty");
427 if (*fromIter != *toIter)
429 throw LocalException(
"From and to path do not have the same toplevel dir: ")
433 while (fromIter != from.end() && toIter != to.end() && (*toIter) == (*fromIter))
440 while (fromIter != from.end())
446 while (toIter != to.end())
448 finalPath /= *toIter;
452 return finalPath.string();
458 fs::path subPath(subPathStr);
461 fs::path strippedPath;
462 while (!subPath.empty())
464 if (
Contains(pathStr, subPath.string()))
469 strippedPath = subPath.filename() / strippedPath;
470 subPath = subPath.parent_path();
485 const boost::regex e(
"\\$([a-zA-Z0-9_]+)");
486 const boost::regex e2(
"\\$\\{([a-zA-Z0-9_]+)\\}");
487 boost::match_results<std::string::const_iterator> what;
489 auto replaceVars = [&](
const boost::regex& e)
491 bool found_match = boost::regex_search(
string, what, e);
494 for (
size_t i = 1; i < what.size(); i += 2)
496 std::string var = what[i];
498 auto envVar = getenv(var.c_str());
501 string = boost::regex_replace(
string, e, std::string(envVar));
514 const std::string varName,
515 const std::string& varValue)
517 string = simox::alg::replace_all(
string, std::string(
"${") + varName +
"}", varValue);
524 if (!path.empty() && path[0] ==
'~')
526 path = path.erase(0, 1);
527 auto envVar = getenv(
"HOME");
530 path = std::string(envVar) +
"/" + path;
544 std::string resolved = path;
546 if (fs::path(resolved).is_relative())
548 std::string absolute;
562 __addPaths(dataPathList);
569 for (
const auto& p : dataPathList)
579 __addPaths(dataPath);
585 if (
const char* home_path = std::getenv(
"ArmarXHome_DIR"))
587 return cleanPath(std::string(home_path));
589 return std::string();
593 ArmarXDataPath::init()
603 if (
const char* data_path = std::getenv(
"ArmarXData_DIRS"))
605 std::string pathStr(data_path);
610 if (
const char* data_path_dir = std::getenv(
"ArmarXData_DIR"))
612 std::string pathStr(data_path_dir);
619 std::vector<std::string>
626 ArmarXDataPath::__addPaths(
const std::string& pathList)
633 std::vector<std::string> separatedPaths = __separatePaths(pathList);
635 if (separatedPaths.size() == 0)
642 for (
int i = separatedPaths.size() - 1; i >= 0; i--)
645 ok =
ok & __addPath(separatedPaths[i]);
651 std::vector<std::string>
652 ArmarXDataPath::__separatePaths(
const std::string& pathList)
654 std::string delimiters =
";";
660 ArmarXDataPath::__pathIsValid(
const std::string& path)
667 std::filesystem::path p(path);
668 return std::filesystem::is_directory(p) || std::filesystem::is_symlink(p);
672 ArmarXDataPath::__addPath(
const std::string& path)
681 if (splitted.size() < 3)
687 std::string root =
"";
688 std::string
project = splitted[splitted.size() - 2];
689 std::string
data = splitted[splitted.size() - 1];
691 for (
unsigned int i = 0; i < splitted.size() - 2; ++i)
693 root +=
"/" + splitted[i];
696 std::filesystem::path p(root +
"/" +
project +
"/" +
data);
698 if (!__pathIsValid(p))
701 <<
"'. Try to capitalize project folder..." << std::endl;
705 p = std::filesystem::path(root +
"/" +
project +
"/" +
data);
706 if (!__pathIsValid(p))
709 <<
"'. Try to caps project folder..." << std::endl;
713 p = std::filesystem::path(root +
"/" +
project +
"/" +
data);
715 if (!__pathIsValid(p))
723 if (std::find(ArmarXDataPath_data.
dataPaths.begin(),
725 p) == ArmarXDataPath_data.
dataPaths.end())
728 ArmarXDataPath_data.
dataPaths.push_back(p);
739 if (application.get() !=
nullptr)
742 std::string cachePathStr;
744 cachePathStr = application->getProperty<std::string>(
"CachePath").getValue();
745 if (std::filesystem::path(cachePathStr).is_relative())
747 std::string pathPrefix;
759 (std::filesystem::path(pathPrefix) / std::filesystem::path(cachePathStr))
775 catch (LocalException& error)
784 char* env_armarx_workspace = getenv(
"ARMARX_WORKSPACE");
785 char* env_armarx_default_config_dir_name = getenv(
"ARMARX_CONFIG_DIR_NAME");
787 std::filesystem::path armarx_workspace;
788 std::filesystem::path armarx_config_dir;
790 if (env_armarx_workspace !=
nullptr)
792 armarx_workspace = std::filesystem::path(env_armarx_workspace);
796 char* home = getenv(
"HOME");
800 armarx_workspace = std::filesystem::path(home);
804 armarx_workspace =
"~/";
808 if (env_armarx_default_config_dir_name !=
nullptr)
810 armarx_config_dir = std::filesystem::path(env_armarx_default_config_dir_name);
814 if (env_armarx_workspace !=
nullptr)
816 armarx_config_dir =
"armarx_config";
821 armarx_config_dir =
".armarx";
825 return (armarx_workspace / armarx_config_dir).string();
831 if (packageName.empty())