package_registry.cpp
Go to the documentation of this file.
1 // Provides cached ros::package::getPath() lookups
2 // Author: Max Schwarz <max.schwarz@uni-bonn.de>
3 
4 #include "package_registry.h"
5 
6 #include <ros/package.h>
7 #include <ros/time.h>
8 
9 #include <rospack/rospack.h>
10 
11 #include <boost/filesystem.hpp>
12 #include <boost/tokenizer.hpp>
13 
14 #include <sys/types.h>
15 #include <sys/wait.h>
16 
17 namespace rosmon
18 {
19 
20 static std::map<std::string, std::string> g_cache;
22 static std::vector<std::string> g_catkin_workspaces;
23 static std::map<std::pair<std::string, std::string>, std::string> g_executableCache;
24 static bool g_initialized = false;
25 
26 namespace fs = boost::filesystem;
27 
28 static void init()
29 {
30  if(g_initialized)
31  return;
32 
33  std::vector<std::string> sp;
34  g_pack.getSearchPathFromEnv(sp);
35  g_pack.crawl(sp, false);
36 
37  // Determine stack of catkin workspaces
38  char* env_cmake = getenv("CMAKE_PREFIX_PATH");
39  if(env_cmake)
40  {
41  std::string cmakePath = env_cmake;
42  boost::char_separator<char> sep(":");
43  boost::tokenizer<boost::char_separator<char>> tok(cmakePath, sep);
44 
45  for(auto token : tok)
46  {
47  fs::path path(token);
48  if(!fs::exists(path / ".catkin"))
49  continue;
50 
51 // printf("Found catkin workspace: '%s'\n", path.string().c_str());
52  g_catkin_workspaces.push_back(path.string());
53  }
54  }
55 }
56 
57 std::string PackageRegistry::getPath(const std::string& package)
58 {
59  if(!g_initialized)
60  init();
61 
62  auto it = g_cache.find(package);
63  if(it == g_cache.end())
64  {
65  std::string path;
66  if(!g_pack.find(package, path))
67  path.clear();
68 
69  g_cache[package] = path;
70  return path;
71  }
72 
73  return it->second;
74 }
75 
76 static std::string getExecutableInPath(const fs::path& path, const std::string& name)
77 {
78  if(!fs::exists(path))
79  return std::string();
80 
81  for(fs::recursive_directory_iterator it(path); it != fs::recursive_directory_iterator(); ++it)
82  {
83  if(it->path().filename() == name
84  && fs::is_regular_file(it->path())
85  && access(it->path().c_str(), X_OK) == 0)
86  {
87  return it->path().string();
88  }
89  }
90 
91  return std::string();
92 }
93 
94 static std::string _getExecutable(const std::string& package, const std::string& name)
95 {
96  if(!g_initialized)
97  init();
98 
99  // Try catkin libexec & catkin share first
100  for(const auto& workspace : g_catkin_workspaces)
101  {
102  fs::path workspacePath(workspace);
103 
104  fs::path execPath = workspacePath / "lib" / package / name;
105  if(fs::exists(execPath) && access(execPath.c_str(), X_OK) == 0)
106  return execPath.string();
107 
108  std::string sharePath = getExecutableInPath(workspacePath / "share" / package, name);
109  if(!sharePath.empty())
110  return sharePath;
111  }
112 
113  // Crawl package directory for an appropriate executable
114  std::string packageDir = PackageRegistry::getPath(package);
115  if(!packageDir.empty())
116  return getExecutableInPath(packageDir, name);
117 
118  // Nothing found :-(
119  return std::string();
120 }
121 
122 std::string PackageRegistry::getExecutable(const std::string& package, const std::string& name)
123 {
124  std::pair<std::string, std::string> key(package, name);
125 
126  auto it = g_executableCache.find(key);
127  if(it != g_executableCache.end())
128  return it->second;
129 
130  std::string result = _getExecutable(package, name);
131  g_executableCache[key] = result;
132 
133  return result;
134 }
135 
136 std::string PackageRegistry::findPathToFile(const std::string& package, const std::string& name)
137 {
138  if(!g_initialized)
139  init();
140 
141  // Try catkin libexec & catkin share first
142  for(const auto& workspace : g_catkin_workspaces)
143  {
144  fs::path workspacePath(workspace);
145 
146  fs::path execPath = workspacePath / "lib" / package;
147  fs::path filePath = execPath / name;
148  if(fs::exists(filePath) && access(filePath.c_str(), X_OK) == 0)
149  return execPath.string();
150 
151  fs::path sharePath = workspacePath / "share" / package;
152  filePath = sharePath / name;
153  if(fs::exists(filePath) && access(filePath.c_str(), X_OK) == 0)
154  return sharePath.string();
155  }
156 
157  // Try package directory (src)
158  fs::path packageDir = PackageRegistry::getPath(package);
159  fs::path filePath = packageDir / name;
160  if(fs::exists(filePath) && access(filePath.c_str(), X_OK) == 0)
161  return packageDir.string();
162 
163  // Nothing found :-(
164  return std::string();
165 }
166 
167 }
static void init()
static std::vector< std::string > g_catkin_workspaces
static rospack::Rospack g_pack
static std::string getExecutableInPath(const fs::path &path, const std::string &name)
static bool g_initialized
static std::string getPath(const std::string &package)
static std::string findPathToFile(const std::string &package, const std::string &name)
Find path to a package file.
static std::map< std::string, std::string > g_cache
bool getSearchPathFromEnv(std::vector< std::string > &sp)
static std::map< std::pair< std::string, std::string >, std::string > g_executableCache
void crawl(std::vector< std::string > search_path, bool force)
bool find(const std::string &name, std::string &path)
static std::string _getExecutable(const std::string &package, const std::string &name)
static std::string getExecutable(const std::string &package, const std::string &name)


rosmon_core
Author(s): Max Schwarz
autogenerated on Wed Jul 10 2019 03:10:12