Down to 8 test failures. Almost there...

This commit is contained in:
Brian Gerkey 2011-10-23 23:45:43 +00:00
parent 8fd83d8d1e
commit 3364a379e8
3 changed files with 586 additions and 98 deletions

View File

@ -67,9 +67,11 @@ static const char* SRV_GEN_GENERATED_FILE = "generated";
static const char* MANIFEST_TAG_PACKAGE = "package";
static const char* MANIFEST_TAG_ROSDEP = "rosdep";
static const char* MANIFEST_TAG_VERSIONCONTROL = "versioncontrol";
static const char* MANIFEST_TAG_EXPORT = "export";
static const char* MANIFEST_ATTR_NAME = "name";
static const char* MANIFEST_ATTR_TYPE = "type";
static const char* MANIFEST_ATTR_URL = "url";
static const char* MANIFEST_PREFIX = "${prefix}";
static const int MAX_CRAWL_DEPTH = 1000;
static const int MAX_DEPENDENCY_DEPTH = 1000;
static const double DEFAULT_MAX_CACHE_AGE = 60.0;
@ -252,7 +254,7 @@ Rosstackage::deps(const std::string& name, bool direct,
{
computeDeps(stackage);
std::vector<Stackage*> deps_vec;
gatherDeps(stackage, direct, deps_vec);
gatherDeps(stackage, direct, POSTORDER, deps_vec);
for(std::vector<Stackage*>::const_iterator it = deps_vec.begin();
it != deps_vec.end();
++it)
@ -280,7 +282,7 @@ Rosstackage::dependsOn(const std::string& name, bool direct,
{
computeDeps(it->second, true);
std::vector<Stackage*> deps_vec;
gatherDeps(it->second, direct, deps_vec);
gatherDeps(it->second, direct, POSTORDER, deps_vec);
for(std::vector<Stackage*>::const_iterator iit = deps_vec.begin();
iit != deps_vec.end();
++iit)
@ -317,7 +319,7 @@ Rosstackage::depsIndent(const std::string& name, bool direct,
std::vector<Stackage*> deps_vec;
std::tr1::unordered_set<Stackage*> deps_hash;
std::vector<std::string> indented_deps;
gatherDepsFull(stackage, direct, 0, deps_hash, deps_vec, true, indented_deps);
gatherDepsFull(stackage, direct, POSTORDER, 0, deps_hash, deps_vec, true, indented_deps);
for(std::vector<std::string>::const_iterator it = indented_deps.begin();
it != indented_deps.end();
++it)
@ -345,7 +347,7 @@ Rosstackage::depsManifests(const std::string& name, bool direct,
{
computeDeps(stackage);
std::vector<Stackage*> deps_vec;
gatherDeps(stackage, direct, deps_vec);
gatherDeps(stackage, direct, POSTORDER, deps_vec);
for(std::vector<Stackage*>::const_iterator it = deps_vec.begin();
it != deps_vec.end();
++it)
@ -376,7 +378,7 @@ Rosstackage::rosdeps(const std::string& name, bool direct,
// rosdeps include the current package
deps_vec.push_back(stackage);
if(!direct)
gatherDeps(stackage, direct, deps_vec);
gatherDeps(stackage, direct, POSTORDER, deps_vec);
for(std::vector<Stackage*>::const_iterator it = deps_vec.begin();
it != deps_vec.end();
++it)
@ -419,7 +421,7 @@ Rosstackage::vcs(const std::string& name, bool direct,
// vcs include the current package
deps_vec.push_back(stackage);
if(!direct)
gatherDeps(stackage, direct, deps_vec);
gatherDeps(stackage, direct, POSTORDER, deps_vec);
for(std::vector<Stackage*>::const_iterator it = deps_vec.begin();
it != deps_vec.end();
++it)
@ -453,6 +455,72 @@ Rosstackage::vcs(const std::string& name, bool direct,
return true;
}
bool
Rosstackage::exports(const std::string& name, const std::string& lang,
const std::string& attrib, bool deps_only,
std::vector<std::string>& flags)
{
if(!stackages_.count(name))
{
log_error("librospack", std::string("no such package ") + name);
return false;
}
Stackage* stackage = stackages_[name];
try
{
computeDeps(stackage);
std::vector<Stackage*> deps_vec;
if(!deps_only)
deps_vec.push_back(stackage);
gatherDeps(stackage, false, PREORDER, deps_vec);
for(std::vector<Stackage*>::const_iterator it = deps_vec.begin();
it != deps_vec.end();
++it)
{
rospack_tinyxml::TiXmlElement* root = get_manifest_root(*it);
for(rospack_tinyxml::TiXmlElement* ele = root->FirstChildElement(MANIFEST_TAG_EXPORT);
ele;
ele = ele->NextSiblingElement(MANIFEST_TAG_EXPORT))
{
for(rospack_tinyxml::TiXmlElement* ele2 = ele->FirstChildElement(lang);
ele2;
ele2 = ele2->NextSiblingElement(lang))
{
const char *att_str;
if((att_str = ele2->Attribute(attrib.c_str())))
{
std::string expanded_str;
if(!expandExportString(*it, att_str, expanded_str))
return false;
flags.push_back(expanded_str);
}
}
}
// We automatically point to msg_gen and msg_srv directories if
// certain files are present
fs::path msg_gen = fs::path((*it)->path_) / MSG_GEN_GENERATED_DIR;
fs::path srv_gen = fs::path((*it)->path_) / SRV_GEN_GENERATED_DIR;
if(fs::is_regular_file(msg_gen / MSG_GEN_GENERATED_FILE))
{
msg_gen /= fs::path("cpp") / "include";
flags.push_back(std::string("-I" + msg_gen.string()));
}
if(fs::is_regular_file(srv_gen / SRV_GEN_GENERATED_FILE))
{
srv_gen /= fs::path("cpp") / "include";
flags.push_back(std::string("-I" + srv_gen.string()));
}
}
}
catch(Exception& e)
{
log_error("librospack", e.what());
return false;
}
return true;
}
bool
Rosstackage::depsMsgSrv(const std::string& name, bool direct,
std::vector<std::string>& gens)
@ -467,7 +535,7 @@ Rosstackage::depsMsgSrv(const std::string& name, bool direct,
{
computeDeps(stackage);
std::vector<Stackage*> deps_vec;
gatherDeps(stackage, direct, deps_vec);
gatherDeps(stackage, direct, POSTORDER, deps_vec);
for(std::vector<Stackage*>::const_iterator it = deps_vec.begin();
it != deps_vec.end();
++it)
@ -665,16 +733,19 @@ Rosstackage::computeDeps(Stackage* stackage, bool ignore_errors)
void
Rosstackage::gatherDeps(Stackage* stackage, bool direct,
traversal_order_t order,
std::vector<Stackage*>& deps)
{
std::tr1::unordered_set<Stackage*> deps_hash;
std::vector<std::string> indented_deps;
gatherDepsFull(stackage, direct, 0, deps_hash, deps, false, indented_deps);
gatherDepsFull(stackage, direct, order, 0,
deps_hash, deps, false, indented_deps);
}
// Pre-condition: computeDeps(stackage) succeeded
void
Rosstackage::gatherDepsFull(Stackage* stackage, bool direct, int depth,
Rosstackage::gatherDepsFull(Stackage* stackage, bool direct,
traversal_order_t order, int depth,
std::tr1::unordered_set<Stackage*>& deps_hash,
std::vector<Stackage*>& deps,
bool get_indented_deps,
@ -700,12 +771,14 @@ Rosstackage::gatherDepsFull(Stackage* stackage, bool direct, int depth,
}
deps_hash.insert(*it);
if(!direct)
gatherDepsFull(*it, direct, depth+1, deps_hash, deps,
get_indented_deps, indented_deps);
// We maintain the vector because the original rospack guaranteed
// ordering in dep reporting.
if(first)
if(first && order == PREORDER)
deps.push_back(*it);
if(!direct)
gatherDepsFull(*it, direct, order, depth+1, deps_hash, deps,
get_indented_deps, indented_deps);
if(first && order == POSTORDER)
deps.push_back(*it);
}
}
@ -948,6 +1021,80 @@ Rosstackage::validateCache()
return ros_root_ok && ros_package_path_ok;
}
bool
Rosstackage::expandExportString(Stackage* stackage,
const std::string& instring,
std::string& outstring)
{
outstring = instring;
for(std::string::size_type i = outstring.find(MANIFEST_PREFIX);
i != std::string::npos;
i = outstring.find(MANIFEST_PREFIX))
{
outstring.replace(i, std::string(MANIFEST_PREFIX).length(),
stackage->path_);
}
// Do backquote substitution. E.g., if we find this string:
// `pkg-config --cflags gdk-pixbuf-2.0`
// We replace it with the result of executing the command
// contained within the backquotes (reading from its stdout), which
// might be something like:
// -I/usr/include/gtk-2.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include
// Construct and execute the string
// We do the assignment first to ensure that if backquote expansion (or
// anything else) fails, we'll get a non-zero exit status from pclose().
std::string cmd = std::string("ret=\"") + outstring + "\" && echo $ret";
// Remove embedded newlines
std::string token("\n");
for (std::string::size_type s = cmd.find(token);
s != std::string::npos;
s = cmd.find(token, s))
cmd.replace(s,token.length(),std::string(" "));
FILE* p;
if(!(p = popen(cmd.c_str(), "r")))
{
std::string errmsg =
std::string("failed to execute backquote expression ") +
cmd + " in " +
stackage->manifest_path_;
log_warn("librospack", errmsg, true);
return false;
}
else
{
char buf[8192];
memset(buf,0,sizeof(buf));
// Read the command's output
do
{
clearerr(p);
while(fgets(buf + strlen(buf),sizeof(buf)-strlen(buf)-1,p));
} while(ferror(p) && errno == EINTR);
// Close the subprocess, checking exit status
if(pclose(p) != 0)
{
std::string errmsg =
std::string("got non-zero exit status from executing backquote expression ") +
cmd + " in " +
stackage->manifest_path_;
return false;
}
else
{
// Strip trailing newline, which was added by our call to echo
buf[strlen(buf)-1] = '\0';
// Replace the backquote expression with the new text
outstring = buf;
}
}
return true;
}
/////////////////////////////////////////////////////////////
// Rospack methods
/////////////////////////////////////////////////////////////

View File

@ -45,6 +45,12 @@ typedef enum
CRAWL_DOWN
} crawl_direction_t;
typedef enum
{
POSTORDER,
PREORDER
} traversal_order_t;
class Stackage;
class Rosstackage
@ -64,8 +70,10 @@ class Rosstackage
void loadManifest(Stackage* stackage);
void computeDeps(Stackage* stackage, bool ignore_errors=false);
void gatherDeps(Stackage* stackage, bool direct,
traversal_order_t order,
std::vector<Stackage*>& deps);
void gatherDepsFull(Stackage* stackage, bool direct, int depth,
void gatherDepsFull(Stackage* stackage, bool direct,
traversal_order_t order, int depth,
std::tr1::unordered_set<Stackage*>& deps_hash,
std::vector<Stackage*>& deps,
bool get_indented_deps,
@ -74,6 +82,9 @@ class Rosstackage
bool readCache();
void writeCache();
bool validateCache();
bool expandExportString(Stackage* stackage,
const std::string& instring,
std::string& outstring);
protected:
std::tr1::unordered_map<std::string, Stackage*> stackages_;
@ -103,6 +114,9 @@ class Rosstackage
std::vector<std::string>& rosdeps);
bool vcs(const std::string& name, bool direct,
std::vector<std::string>& vcs);
bool exports(const std::string& name, const std::string& lang,
const std::string& attrib, bool deps_only,
std::vector<std::string>& flags);
void debug_dump();
};

View File

@ -27,6 +27,8 @@
#include "rp.h"
#include <boost/program_options.hpp>
#include <boost/algorithm/string.hpp>
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
@ -35,6 +37,14 @@ namespace po = boost::program_options;
const char* usage();
bool parse_args(int argc, char** argv, po::variables_map& vm);
void parse_compiler_flags(const std::string& instring,
const std::string& token,
bool select,
bool last,
std::string& outstring);
void deduplicate_tokens(const std::string& instring,
bool last,
std::string& outstring);
int
main(int argc, char** argv)
@ -50,6 +60,14 @@ main(int argc, char** argv)
std::string command;
std::string package;
bool package_given = false;
bool deps_only = false;
std::string lang;
std::string attrib;
std::string top;
std::string target;
bool zombie_only = false;
std::string length_str;
int length;
if(vm.count("command"))
command = vm["command"].as<std::string>();
if(!command.size())
@ -73,19 +91,45 @@ main(int argc, char** argv)
// try to determine package from directory context
rp.inPackage(package);
}
if(vm.count("deps-only"))
deps_only = true;
if(vm.count("lang"))
lang = vm["lang"].as<std::string>();
if(vm.count("attrib"))
attrib = vm["attrib"].as<std::string>();
if(vm.count("top"))
top = vm["top"].as<std::string>();
if(vm.count("target"))
target = vm["target"].as<std::string>();
if(vm.count("zombie-only"))
zombie_only = true;
if(vm.count("length"))
{
length_str = vm["length"].as<std::string>();
length = atoi(length_str.c_str());
}
else
{
if(zombie_only)
length = -1;
else
length = 20;
}
// COMMAND: profile
if(command == "profile")
{
if(package_given)
if(package_given || target.size() || top.size() || length_str.size() ||
zombie_only || deps_only || lang.size() || attrib.size())
{
rospack::log_error("rospack", "no package allowed");
rospack::log_error("rospack", "invalid option(s) given");
return 1;
}
rospack::log_error("rospack", "profile output not yet implemented");
// TODO
return 0;
}
// COMMAND: find [package]
else if(command == "find")
{
if(!package.size())
@ -93,20 +137,25 @@ main(int argc, char** argv)
rospack::log_error("rospack", "no package given");
return 1;
}
if(target.size() || top.size() || length_str.size() ||
zombie_only || deps_only || lang.size() || attrib.size())
{
rospack::log_error("rospack", "invalid option(s) given");
return 1;
}
std::string path;
if(!rp.find(package, path))
return 1;
else
{
printf("%s\n", path.c_str());
return 0;
}
printf("%s\n", path.c_str());
return 0;
}
// COMMAND: list
else if(command == "list")
{
if(package_given)
if(package_given || target.size() || top.size() || length_str.size() ||
zombie_only || deps_only || lang.size() || attrib.size())
{
rospack::log_error("rospack", "no package allowed");
rospack::log_error("rospack", "invalid option(s) given");
return 1;
}
std::vector<std::pair<std::string, std::string> > list;
@ -119,11 +168,13 @@ main(int argc, char** argv)
}
return 0;
}
// COMMAND: list-names
else if(command == "list-names")
{
if(package_given)
if(package_given || target.size() || top.size() || length_str.size() ||
zombie_only || deps_only || lang.size() || attrib.size())
{
rospack::log_error("rospack", "no package allowed");
rospack::log_error("rospack", "invalid option(s) given");
return 1;
}
std::vector<std::pair<std::string, std::string> > list;
@ -136,11 +187,13 @@ main(int argc, char** argv)
}
return 0;
}
// COMMAND: list-duplicates
else if(command == "list-duplicates")
{
if(package_given)
if(package_given || target.size() || top.size() || length_str.size() ||
zombie_only || deps_only || lang.size() || attrib.size())
{
rospack::log_error("rospack", "no package allowed");
rospack::log_error("rospack", "invalid option(s) given");
return 1;
}
std::vector<std::string> dups;
@ -148,29 +201,29 @@ main(int argc, char** argv)
// list-duplicates returns 0 if no duplicates
if(!dups.size())
return 0;
else
// if there are dups, list-duplicates prints them and returns non-zero
for(std::vector<std::string>::const_iterator it = dups.begin();
it != dups.end();
++it)
{
// if there are dups, list-duplicates prints them and returns non-zero
for(std::vector<std::string>::const_iterator it = dups.begin();
it != dups.end();
++it)
{
printf("%s\n", (*it).c_str());
}
return 1;
printf("%s\n", (*it).c_str());
}
return 1;
}
// COMMAND: langs
else if(command == "langs")
{
if(package_given)
if(package_given || target.size() || top.size() || length_str.size() ||
zombie_only || deps_only || lang.size() || attrib.size())
{
rospack::log_error("rospack", "no package allowed");
rospack::log_error("rospack", "invalid option(s) given");
return 1;
}
rospack::log_error("rospack",
std::string("command ") + command + " not implemented");
return 1;
}
// COMMAND: depends [package] (alias: deps)
else if(command == "depends" || command == "deps" ||
command == "depends1" || command == "deps1")
{
@ -179,18 +232,22 @@ main(int argc, char** argv)
rospack::log_error("rospack", "no package given");
return 1;
}
if(target.size() || top.size() || length_str.size() ||
zombie_only || deps_only || lang.size() || attrib.size())
{
rospack::log_error("rospack", "invalid option(s) given");
return 1;
}
std::vector<std::string> deps;
if(!rp.deps(package, (command == "depends1" || command == "deps1"), deps))
return 1;
else
{
for(std::vector<std::string>::const_iterator it = deps.begin();
it != deps.end();
++it)
printf("%s\n", it->c_str());
return 0;
}
for(std::vector<std::string>::const_iterator it = deps.begin();
it != deps.end();
++it)
printf("%s\n", it->c_str());
return 0;
}
// COMMAND: depends-manifests [package] (alias: deps-manifests)
else if(command == "depends-manifests" || command == "deps-manifests")
{
if(!package.size())
@ -198,19 +255,23 @@ main(int argc, char** argv)
rospack::log_error("rospack", "no package given");
return 1;
}
if(target.size() || top.size() || length_str.size() ||
zombie_only || deps_only || lang.size() || attrib.size())
{
rospack::log_error("rospack", "invalid option(s) given");
return 1;
}
std::vector<std::string> manifests;
if(!rp.depsManifests(package, false, manifests))
return 1;
else
{
for(std::vector<std::string>::const_iterator it = manifests.begin();
it != manifests.end();
++it)
for(std::vector<std::string>::const_iterator it = manifests.begin();
it != manifests.end();
++it)
printf("%s ", it->c_str());
printf("\n");
return 0;
}
printf("\n");
return 0;
}
// COMMAND: depends-msgsrv [package] (alias: deps-msgsrv)
else if(command == "depends-msgsrv" || command == "deps-msgsrv")
{
if(!package.size())
@ -218,19 +279,23 @@ main(int argc, char** argv)
rospack::log_error("rospack", "no package given");
return 1;
}
if(target.size() || top.size() || length_str.size() ||
zombie_only || deps_only || lang.size() || attrib.size())
{
rospack::log_error("rospack", "invalid option(s) given");
return 1;
}
std::vector<std::string> gens;
if(!rp.depsMsgSrv(package, false, gens))
return 1;
else
{
for(std::vector<std::string>::const_iterator it = gens.begin();
it != gens.end();
++it)
printf("%s ", it->c_str());
printf("\n");
return 0;
}
for(std::vector<std::string>::const_iterator it = gens.begin();
it != gens.end();
++it)
printf("%s ", it->c_str());
printf("\n");
return 0;
}
// COMMAND: depends-indent [package] (alias: deps-indent)
else if(command == "depends-indent" || command == "deps-indent")
{
if(!package.size())
@ -238,18 +303,23 @@ main(int argc, char** argv)
rospack::log_error("rospack", "no package given");
return 1;
}
if(target.size() || top.size() || length_str.size() ||
zombie_only || deps_only || lang.size() || attrib.size())
{
rospack::log_error("rospack", "invalid option(s) given");
return 1;
}
std::vector<std::string> deps;
if(!rp.depsIndent(package, false, deps))
return 1;
else
{
for(std::vector<std::string>::const_iterator it = deps.begin();
it != deps.end();
++it)
printf("%s\n", it->c_str());
return 0;
}
for(std::vector<std::string>::const_iterator it = deps.begin();
it != deps.end();
++it)
printf("%s\n", it->c_str());
return 0;
}
// COMMAND: rosdep [package] (alias: rosdeps)
// COMMAND: rosdep0 [package] (alias: rosdeps0)
else if(command == "rosdep" || command == "rosdeps" ||
command == "rosdep0" || command == "rosdeps0")
{
@ -258,18 +328,23 @@ main(int argc, char** argv)
rospack::log_error("rospack", "no package given");
return 1;
}
if(target.size() || top.size() || length_str.size() ||
zombie_only || deps_only || lang.size() || attrib.size())
{
rospack::log_error("rospack", "invalid option(s) given");
return 1;
}
std::vector<std::string> rosdeps;
if(!rp.rosdeps(package, (command == "rosdep0" || command == "rosdeps0"), rosdeps))
return 1;
else
{
for(std::vector<std::string>::const_iterator it = rosdeps.begin();
it != rosdeps.end();
++it)
printf("%s\n", it->c_str());
return 0;
}
for(std::vector<std::string>::const_iterator it = rosdeps.begin();
it != rosdeps.end();
++it)
printf("%s\n", it->c_str());
return 0;
}
// COMMAND: vcs [package]
// COMMAND: vcs0 [package]
else if(command == "vcs" || command == "vcs0")
{
if(!package.size())
@ -277,18 +352,23 @@ main(int argc, char** argv)
rospack::log_error("rospack", "no package given");
return 1;
}
if(target.size() || top.size() || length_str.size() ||
zombie_only || deps_only || lang.size() || attrib.size())
{
rospack::log_error("rospack", "invalid option(s) given");
return 1;
}
std::vector<std::string> vcs;
if(!rp.vcs(package, (command == "vcs0"), vcs))
return 1;
else
{
for(std::vector<std::string>::const_iterator it = vcs.begin();
it != vcs.end();
++it)
printf("%s\n", it->c_str());
return 0;
}
for(std::vector<std::string>::const_iterator it = vcs.begin();
it != vcs.end();
++it)
printf("%s\n", it->c_str());
return 0;
}
// COMMAND: depends-on [package]
// COMMAND: depends-on1 [package]
else if(command == "depends-on" || command == "depends-on1")
{
if(!package.size())
@ -296,23 +376,190 @@ main(int argc, char** argv)
rospack::log_error("rospack", "no package given");
return 1;
}
if(target.size() || top.size() || length_str.size() ||
zombie_only || deps_only || lang.size() || attrib.size())
{
rospack::log_error("rospack", "invalid option(s) given");
return 1;
}
std::vector<std::string> deps;
if(!rp.dependsOn(package, (command == "depends-on1"), deps))
return 1;
else
{
for(std::vector<std::string>::const_iterator it = deps.begin();
it != deps.end();
++it)
printf("%s\n", it->c_str());
return 0;
}
for(std::vector<std::string>::const_iterator it = deps.begin();
it != deps.end();
++it)
printf("%s\n", it->c_str());
return 0;
}
// COMMAND: export [--deps-only] --lang=<lang> --attrib=<attrib> [package]
else if(command == "export")
{
if(!package.size() || !lang.size() || !attrib.size())
{
rospack::log_error("rospack", "no package / lang / attrib given");
return 1;
}
if(target.size() || top.size() || length_str.size() || zombie_only)
{
rospack::log_error("rospack", "invalid option(s) given");
return 1;
}
std::vector<std::string> flags;
if(!rp.exports(package, lang, attrib, deps_only, flags))
return 1;
for(std::vector<std::string>::const_iterator it = flags.begin();
it != flags.end();
++it)
printf("%s ", it->c_str());
printf("\n");
return 0;
}
// COMMAND: plugins --attrib=<attrib> [--top=<toppkg>] [package]
else if(command == "plugins")
{
rospack::log_error("rospack",
std::string("command ") + command + " not implemented");
return 1;
}
// COMMAND: cflags-only-I [--deps-only] [package]
else if(command == "cflags-only-I")
{
if(!package.size())
{
rospack::log_error("rospack", "no package given");
return 1;
}
if(target.size() || top.size() || length_str.size() || zombie_only)
{
rospack::log_error("rospack", "invalid option(s) given");
return 1;
}
std::vector<std::string> flags;
if(!rp.exports(package, "cpp", "cflags", deps_only, flags))
return 1;
std::string combined;
for(std::vector<std::string>::const_iterator it = flags.begin();
it != flags.end();
++it)
combined.append(*it + " ");
std::string result;
parse_compiler_flags(combined, "-I", true, false, result);
printf("%s\n", result.c_str());
return 0;
}
// COMMAND: cflags-only-other [--deps-only] [package]
else if(command == "cflags-only-other")
{
if(!package.size())
{
rospack::log_error("rospack", "no package given");
return 1;
}
if(target.size() || top.size() || length_str.size() || zombie_only)
{
rospack::log_error("rospack", "invalid option(s) given");
return 1;
}
std::vector<std::string> flags;
if(!rp.exports(package, "cpp", "cflags", deps_only, flags))
return 1;
std::string combined;
for(std::vector<std::string>::const_iterator it = flags.begin();
it != flags.end();
++it)
combined.append(*it + " ");
std::string result;
parse_compiler_flags(combined, "-I", false, false, result);
printf("%s\n", result.c_str());
return 0;
}
// COMMAND: libs-only-L [--deps-only] [package]
else if(command == "libs-only-L")
{
if(!package.size())
{
rospack::log_error("rospack", "no package given");
return 1;
}
if(target.size() || top.size() || length_str.size() || zombie_only)
{
rospack::log_error("rospack", "invalid option(s) given");
return 1;
}
std::vector<std::string> flags;
if(!rp.exports(package, "cpp", "lflags", deps_only, flags))
return 1;
std::string combined;
for(std::vector<std::string>::const_iterator it = flags.begin();
it != flags.end();
++it)
combined.append(*it + " ");
std::string result;
parse_compiler_flags(combined, "-L", true, false, result);
printf("%s\n", result.c_str());
return 0;
}
// COMMAND: libs-only-l [--deps-only] [package]
else if(command == "libs-only-l")
{
if(!package.size())
{
rospack::log_error("rospack", "no package given");
return 1;
}
if(target.size() || top.size() || length_str.size() || zombie_only)
{
rospack::log_error("rospack", "invalid option(s) given");
return 1;
}
std::vector<std::string> flags;
if(!rp.exports(package, "cpp", "lflags", deps_only, flags))
return 1;
std::string combined;
for(std::vector<std::string>::const_iterator it = flags.begin();
it != flags.end();
++it)
combined.append(*it + " ");
std::string result;
parse_compiler_flags(combined, "-l", true, true, result);
printf("%s\n", result.c_str());
return 0;
}
// COMMAND: libs-only-other [--deps-only] [package]
else if(command == "libs-only-other")
{
if(!package.size())
{
rospack::log_error("rospack", "no package given");
return 1;
}
if(target.size() || top.size() || length_str.size() || zombie_only)
{
rospack::log_error("rospack", "invalid option(s) given");
return 1;
}
std::vector<std::string> flags;
if(!rp.exports(package, "cpp", "lflags", deps_only, flags))
return 1;
std::string combined;
for(std::vector<std::string>::const_iterator it = flags.begin();
it != flags.end();
++it)
combined.append(*it + " ");
std::string intermediate;
parse_compiler_flags(combined, "-L", false, false, intermediate);
std::string result;
parse_compiler_flags(intermediate, "-l", false, false, result);
printf("%s\n", result.c_str());
return 0;
}
// COMMAND: help
else if(command == "help")
{
if(package_given)
if(package_given || top.size() || length_str.size() ||
zombie_only || deps_only || lang.size() || attrib.size())
{
rospack::log_error("rospack", "no package allowed");
rospack::log_error("rospack", "invalid option(s) given");
return 1;
}
printf("%s", usage());
@ -326,6 +573,86 @@ main(int argc, char** argv)
}
}
void
deduplicate_tokens(const std::string& instring,
bool last,
std::string& outstring)
{
std::vector<std::string> vec;
std::tr1::unordered_set<std::string> set;
boost::split(vec, instring,
boost::is_any_of("\t "),
boost::token_compress_on);
if(last)
std::reverse(vec.begin(), vec.end());
std::vector<std::string> vec_out;
vec_out.resize(vec.size());
int i = 0;
for(std::vector<std::string>::const_iterator it = vec.begin();
it != vec.end();
++it)
{
if(set.find(*it) == set.end())
{
vec_out[i] = *it;
set.insert(*it);
i++;
}
}
if(last)
std::reverse(vec_out.begin(), vec_out.end());
for(std::vector<std::string>::const_iterator it = vec_out.begin();
it != vec_out.end();
++it)
outstring.append(*it + " ");
}
void
parse_compiler_flags(const std::string& instring,
const std::string& token,
bool select,
bool last,
std::string& outstring)
{
std::string intermediate;
std::vector<std::string> result_vec;
boost::split(result_vec, instring,
boost::is_any_of("\t "),
boost::token_compress_on);
for(std::vector<std::string>::const_iterator it = result_vec.begin();
it != result_vec.end();
++it)
{
// Combined into one arg
if(it->size() > token.size() && it->substr(0,token.size()) == token)
{
if(select)
intermediate.append(it->substr(token.size()) + " ");
}
// Space-separated
else if((*it) == token)
{
std::vector<std::string>::const_iterator iit = it;
if(++iit != result_vec.end())
{
if(it->size() >= token.size() && it->substr(0,token.size()) == token)
{
// skip it
}
else
{
if(select)
intermediate.append((*iit) + " ");
it = iit;
}
}
}
else if(!select)
intermediate.append((*it) + " ");
}
deduplicate_tokens(intermediate, last, outstring);
}
const char* usage()
{
return "USAGE: rospack <command> [options] [package]\n"