rospack_cmdline.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008, Willow Garage, Inc.
00003  * 
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions are met:
00006  *   * Redistributions of source code must retain the above copyright notice,
00007  *     this list of conditions and the following disclaimer.
00008  *   * Redistributions in binary form must reproduce the above copyright
00009  *     notice, this list of conditions and the following disclaimer in the
00010  *     documentation and/or other materials provided with the distribution.
00011  *   * Neither the names of Stanford University or Willow Garage, Inc. nor the names of its
00012  *     contributors may be used to endorse or promote products derived from
00013  *     this software without specific prior written permission.
00014  *
00015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00025  * POSSIBILITY OF SUCH DAMAGE.
00026  */
00027 
00028 #include "rospack/rospack.h"
00029 #include "utils.h"
00030 #include "rospack_cmdline.h"
00031 
00032 #include <boost/program_options.hpp>
00033 #include <boost/algorithm/string.hpp>
00034 #include <algorithm>
00035 #include <iostream>
00036 #include <stdlib.h>
00037 #include <stdio.h>
00038 
00039 namespace po = boost::program_options;
00040 
00041 namespace rospack
00042 {
00043 
00044 bool parse_args(int argc, char** argv, 
00045                 rospack::Rosstackage& rp,
00046                 po::variables_map& vm);
00047 
00048 bool
00049 rospack_run(int argc, char** argv, rospack::Rosstackage& rp, std::string& output)
00050 {
00051   po::variables_map vm;
00052 
00053   if(!parse_args(argc, argv, rp, vm))
00054     return false;
00055 
00056   bool quiet = (vm.count("quiet")==1);
00057   rp.setQuiet(quiet);
00058 
00059   std::string command;
00060   std::string package;
00061   bool package_given = false;
00062   bool deps_only = false;
00063   std::string lang;
00064   std::string attrib;
00065   std::string top;
00066   std::string target;
00067   bool zombie_only = false;
00068   std::string length_str;
00069   int length;
00070   if(vm.count("command"))
00071     command = vm["command"].as<std::string>();
00072 
00073   if(vm.count("-h") && command.empty())
00074     command = "help";
00075 
00076   if(!command.size())
00077   {
00078     rp.logError( std::string("no command given.  Try '") + rp.getName() + " help'");
00079     return true;
00080   }
00081   // For some commands, we force a crawl.  Definitely anything that does a
00082   // depends-on calculation.
00083   bool force = false;
00084   if((command == "profile") ||
00085      (command == "depends-on") ||
00086      (command == "depends-on1") ||
00087      (command == "langs") ||
00088      (command == "list-duplicates"))
00089     force = true;
00090 
00091   if(vm.count("package"))
00092   {
00093     package = vm["package"].as<std::string>();
00094     package_given = true;
00095   }
00096   else
00097   {
00098     // try to determine package from directory context
00099     rp.inStackage(package);
00100   }
00101   if(vm.count("deps-only"))
00102     deps_only = true;
00103   if(vm.count("lang"))
00104     lang = vm["lang"].as<std::string>();
00105   if(vm.count("attrib"))
00106     attrib = vm["attrib"].as<std::string>();
00107   if(vm.count("top"))
00108     top = vm["top"].as<std::string>();
00109   if(vm.count("target"))
00110     target = vm["target"].as<std::string>();
00111   if(vm.count("zombie-only"))
00112     zombie_only = true;
00113   if(vm.count("length"))
00114   {
00115     length_str = vm["length"].as<std::string>();
00116     length = atoi(length_str.c_str());
00117   }
00118   else
00119   {
00120     if(zombie_only)
00121       length = -1;
00122     else
00123       length = 20;
00124   }
00125 
00126   // COMMAND: help
00127   if(command == "help" || vm.count("help"))
00128   {
00129     if(package_given || (command != "help" && vm.count("help"))) {
00130       if (command == "help") {
00131         command = vm["package"].as<std::string>();
00132       }
00133       output.append("Usage: rospack ");
00134       output.append(command);
00135       if(command == "help")
00136         output.append("[command]\n\nPrint help message.");
00137       else if(command == "find")
00138         output.append("\n\nPrint absolute path to the package");
00139       else if(command == "list")
00140         output.append("\n\nPrint newline-separated list <package-name> <package-dir> for all packages.");
00141       else if(command == "list-names")
00142         output.append("\n\nPrint newline-separated list of packages names for all packages.");
00143       else if(command == "list-duplicates")
00144         output.append("\n\nPrint newline-separated list of names of packages that are found more than once during the search.");
00145       else if(command == "langs")
00146         output.append("\n\nPrint space-separated list of available language-specific client libraries.");
00147       else if(command == "depends" || command == "deps")
00148         output.append("[package]\n\nPrint newline-separated, ordered list of all dependencies of the package.");
00149       else if(command == "depends1" || command == "deps1")
00150         output.append("[package]\n\nPrint newline-separated, ordered list of immediate dependencies of the package.");
00151       else if(command == "depends-manifest" || command == "deps-manifest")
00152         output.append("[package]\n\nPrint space-separated, ordered list of manifest.xml files for all dependencies of the package. Used internally by rosbuild.");
00153       else if(command == "depends-indent" || command == "deps-indent")
00154         output.append("[package]\n\nPrint newline-separated, indented list of the entire dependency chain for the package.");
00155       else if(command == "depends-why" || command == "deps-why")
00156         output.append("--target=TARGET [package]\n\nPrint newline-separated presentation of all dependency chains from the package to TARGET. ");
00157       else if(command == "depends-msgsrv" || command == "deps-msgsrv")
00158         output.append("[package]\n\nPrint space-separated list of message-generation marker files for all dependencies of the package.  Used internally by rosbuild.");
00159       else if(command == "rosdep" || command == "rosdeps")
00160         output.append("[package]\n\nPrint newline-separated list of all [rosdep] tags from the manifest.xml of the package and all of its dependencies.");
00161       else if(command == "rosdep0" || command == "rosdeps0")
00162         output.append("[package]\n\nPrint newline-separated list of all [rosdep] tags from the manifest.xml of just the package itself.");
00163       else if(command == "vcs")
00164         output.append("[package]\n\nPrint newline-separated list of all [versioncontrol] tags from the manifest.xml of the package and all of its dependencies.");
00165       else if(command == "vcs0")
00166         output.append("[package]\n\nPrint newline-separated list of all [versioncontrol] tags from the manifest.xml of just the package itself.");
00167       else if(command == "depends-on")
00168         output.append("[package]\n\nPrint newline-separated list of all packages that depend on the package. ");
00169       else if(command == "depends-on1")
00170         output.append("[package]\n\nPrint newline-separated list of all packages that directly depend on the package.");
00171       else if(command == "export")
00172         output.append("[--deps-only] --lang=<lang> --attrib=<attrib> [package]\n\nPrint Space-separated list of [export][LANGUAGE ATTRIBUTE=\"\"/][/export] values from the manifest.xml of the package and its dependencies.\n\nIf --deps-only is provided, then the package itself is excluded.");
00173       else if(command == "plugins")
00174         output.append("--attrib=<attrib> [--top=<toppkg>] [package]\n\nExamine packages that depend directly on the given package, giving name and the exported attribute with the name <attrib>\n\nIf --top=<toppkg> is given, then in addition to depending directly on the given package, to be scanned for exports, a package must also be a dependency of <toppkg>, or be <toppkg> itself.");
00175       else if(command == "cflags-only-I")
00176         output.append("[--deps-only] [package]\n\nPrint Space-separated list of [export][LANGUAGE ATTRIBUTE=\"\"/][/export] values from the manifest.xml of the package and its dependencies.\n\nIf --deps-only is provided, then the package itself is excluded.");
00177       else if(command == "cflags-only-other")
00178         output.append("[--deps-only] [package]\n\nPrint space-separated list of export/cpp/cflags that don't start with -I.\n\nIf --deps-only is provided, then the package itself is excluded.");
00179       else if(command == "libs-only-L")
00180         output.append("[--deps-only] [package]\n\nPrint space-separated list of export/cpp/libs that start with -L.\n\nIf --deps-only is provided, then the package itself is excluded.");
00181       else if(command == "libs-only-l")
00182         output.append("[--deps-only] [package]\n\nPrint space-separated list of export/cpp/libs that start with -l.\n\nIf --deps-only is provided, then the package itself is excluded.");
00183       else if(command == "libs-only-other")
00184         output.append("[--deps-only] [package]\n\nPrint space-separated list of export/cpp/libs that don't start with -l or -L.\n\nIf --deps-only is provided, then the package itself is excluded.");
00185       else if(command == "profile")
00186         output.append("[--length=<length>] [--zombie-only]\n\nForce a full crawl of package directories and report the directories that took the longest time to crawl.\n\n--length=N how many directories to display\n\n--zombie-only Only print directories that do not have any manifests.");
00187       output.append("\n");
00188     } else {
00189         output.append(rp.usage());
00190     }
00191     return true;
00192   }
00193 
00194   std::vector<std::string> search_path;
00195   if(!rp.getSearchPathFromEnv(search_path))
00196     return false;
00197 
00198   // COMMAND: profile
00199   if(command == "profile")
00200   {
00201     if(package_given || target.size() || top.size() || 
00202        deps_only || lang.size() || attrib.size())
00203     {
00204       rp.logError( "invalid option(s) given");
00205       return false;
00206     }
00207     std::vector<std::string> dirs;
00208     if(rp.profile(search_path, zombie_only, length, dirs))
00209       return false;
00210     for(std::vector<std::string>::const_iterator it = dirs.begin();
00211         it != dirs.end();
00212         ++it)
00213       output.append((*it) + "\n");
00214     return true;
00215   }
00216 
00217   // We crawl here because profile (above) does its own special crawl.
00218   rp.crawl(search_path, force);
00219   
00220   // COMMAND: find [package]
00221   if(command == "find")
00222   {
00223     if(!package.size())
00224     {
00225       rp.logError( "no package/stack given");
00226       return false;
00227     }
00228     if(target.size() || top.size() || length_str.size() || 
00229        zombie_only || deps_only || lang.size() || attrib.size())
00230     {
00231       rp.logError( "invalid option(s) given");
00232       return false;
00233     }
00234     std::string path;
00235     if(!rp.find(package, path))
00236       return false;
00237     output.append(path + "\n");
00238     return true;
00239   }
00240   // COMMAND: list
00241   else if(command == "list")
00242   {
00243     if(package_given || target.size() || top.size() || length_str.size() || 
00244        zombie_only || deps_only || lang.size() || attrib.size())
00245     {
00246       rp.logError( "invalid option(s) given");
00247       return false;
00248     }
00249     std::set<std::pair<std::string, std::string> > list;
00250     rp.list(list);
00251     for(std::set<std::pair<std::string, std::string> >::const_iterator it = list.begin();
00252         it != list.end();
00253         ++it)
00254     {
00255       output.append(it->first + " " + it->second + "\n");
00256     }
00257     return true;
00258   }
00259   // COMMAND: list-names
00260   else if(command == "list-names")
00261   {
00262     if(package_given || target.size() || top.size() || length_str.size() || 
00263        zombie_only || deps_only || lang.size() || attrib.size())
00264     {
00265       rp.logError( "invalid option(s) given");
00266       return false;
00267     }
00268     std::set<std::pair<std::string, std::string> > list;
00269     rp.list(list);
00270     for(std::set<std::pair<std::string, std::string> >::const_iterator it = list.begin();
00271         it != list.end();
00272         ++it)
00273     {
00274       output.append(it->first + "\n");
00275     }
00276     return true;
00277   }
00278   // COMMAND: list-duplicates
00279   else if(command == "list-duplicates")
00280   {
00281     if(package_given || target.size() || top.size() || length_str.size() || 
00282        zombie_only || deps_only || lang.size() || attrib.size())
00283     {
00284       rp.logError( "invalid option(s) given");
00285       return false;
00286     }
00287     std::map<std::string, std::vector<std::string> > dups;
00288     rp.listDuplicatesWithPaths(dups);
00289     // if there are dups, list-duplicates prints them and returns non-zero
00290     for(std::map<std::string, std::vector<std::string> >::const_iterator it = dups.begin();
00291         it != dups.end();
00292         ++it)
00293     {
00294       output.append(it->first + "\n");
00295       for(std::vector<std::string>::const_iterator jt = it->second.begin();
00296           jt != it->second.end();
00297           ++jt)
00298       {
00299         output.append("- " + *jt + "\n");
00300       }
00301     }
00302     return true;
00303   }
00304   // COMMAND: langs
00305   else if(rp.getName() == ROSPACK_NAME && command == "langs")
00306   {
00307     if(package_given || target.size() || top.size() || length_str.size() || 
00308        zombie_only || deps_only || lang.size() || attrib.size())
00309     {
00310       rp.logError( "invalid option(s) given");
00311       return false;
00312     }
00313     std::vector<std::string> deps;
00314     if(!rp.depsOn("roslang", true, deps))
00315       return false;
00316     const char* ros_lang_disable;
00317     if((ros_lang_disable = getenv("ROS_LANG_DISABLE")))
00318     {
00319       std::vector<std::string> disable_langs;
00320     // I can't see that boost filesystem has an elegant cross platform
00321     // representation for this anywhere like qt/python have.
00322     #if defined(WIN32)
00323       const char *path_delim = ";";
00324     #else //!defined(WIN32)
00325       const char *path_delim = ":";
00326     #endif
00327       boost::split(disable_langs, ros_lang_disable,
00328                    boost::is_any_of(path_delim),
00329                    boost::token_compress_on);
00330       std::vector<std::string>::iterator it = deps.begin();
00331       while(it != deps.end())
00332       {
00333         if(std::find(disable_langs.begin(), disable_langs.end(), *it) != 
00334            disable_langs.end())
00335           it = deps.erase(it);
00336         else
00337           ++it;
00338       }
00339     }
00340     for(std::vector<std::string>::const_iterator it = deps.begin();
00341         it != deps.end();
00342         ++it)
00343     {
00344       if(it != deps.begin())
00345         output.append(" ");
00346       output.append(*it);
00347     }
00348     output.append("\n");
00349     return true;
00350   }
00351   // COMMAND: depends [package] (alias: deps)
00352   else if(command == "depends" || command == "deps" || 
00353           command == "depends1" || command == "deps1")
00354   {
00355     if(!package.size())
00356     {
00357       rp.logError( "no package/stack given");
00358       return false;
00359     }
00360     if(target.size() || top.size() || length_str.size() || 
00361        zombie_only || deps_only || lang.size() || attrib.size())
00362     {
00363       rp.logError( "invalid option(s) given");
00364       return false;
00365     }
00366     std::vector<std::string> deps;
00367     if(!rp.deps(package, (command == "depends1" || command == "deps1"), deps))
00368       return false;
00369     for(std::vector<std::string>::const_iterator it = deps.begin();
00370         it != deps.end();
00371         ++it)
00372       output.append(*it + "\n");
00373     return true;
00374   }
00375   // COMMAND: depends-manifests [package] (alias: deps-manifests)
00376   else if(command == "depends-manifests" || command == "deps-manifests")
00377   {
00378     if(!package.size())
00379     {
00380       rp.logError( "no package/stack given");
00381       return false;
00382     }
00383     if(target.size() || top.size() || length_str.size() || 
00384        zombie_only || deps_only || lang.size() || attrib.size())
00385     {
00386       rp.logError( "invalid option(s) given");
00387       return false;
00388     }
00389     std::vector<std::string> manifests;
00390     if(!rp.depsManifests(package, false, manifests))
00391       return false;
00392     for(std::vector<std::string>::const_iterator it = manifests.begin();
00393         it != manifests.end();
00394         ++it)
00395     {
00396       if(it != manifests.begin())
00397         output.append(" ");
00398       output.append(*it);
00399     }
00400     output.append("\n");
00401     return true;
00402   }
00403   // COMMAND: depends-msgsrv [package] (alias: deps-msgsrv)
00404   else if(rp.getName() == ROSPACK_NAME && 
00405           (command == "depends-msgsrv" || command == "deps-msgsrv"))
00406   {
00407     if(!package.size())
00408     {
00409       rp.logError( "no package given");
00410       return false;
00411     }
00412     if(target.size() || top.size() || length_str.size() || 
00413        zombie_only || deps_only || lang.size() || attrib.size())
00414     {
00415       rp.logError( "invalid option(s) given");
00416       return false;
00417     }
00418     std::vector<std::string> gens;
00419     if(!rp.depsMsgSrv(package, false, gens))
00420       return false;
00421     for(std::vector<std::string>::const_iterator it = gens.begin();
00422         it != gens.end();
00423         ++it)
00424     {
00425       if(it != gens.begin())
00426         output.append(" ");
00427       output.append(*it);
00428     }
00429     output.append("\n");
00430     return true;
00431   }
00432   // COMMAND: depends-indent [package] (alias: deps-indent)
00433   else if(command == "depends-indent" || command == "deps-indent")
00434   {
00435     if(!package.size())
00436     {
00437       rp.logError( "no package/stack given");
00438       return false;
00439     }
00440     if(target.size() || top.size() || length_str.size() || 
00441        zombie_only || deps_only || lang.size() || attrib.size())
00442     {
00443       rp.logError( "invalid option(s) given");
00444       return false;
00445     }
00446     std::vector<std::string> deps;
00447     if(!rp.depsIndent(package, false, deps))
00448       return false;
00449     for(std::vector<std::string>::const_iterator it = deps.begin();
00450         it != deps.end();
00451         ++it)
00452       output.append(*it + "\n");
00453     return true;
00454   }
00455   // COMMAND: depends-why [package] (alias: deps-why)
00456   else if(command == "depends-why" || command == "deps-why")
00457   {
00458     if(!package.size() || !target.size())
00459     {
00460       rp.logError( "no package/stack or target given");
00461       return false;
00462     }
00463     if(top.size() || length_str.size() || 
00464        zombie_only || deps_only || lang.size() || attrib.size())
00465     {
00466       rp.logError( "invalid option(s) given");
00467       return false;
00468     }
00469     std::string why_output;
00470     if(!rp.depsWhy(package, target, why_output))
00471       return false;
00472     output.append(why_output);
00473     return true;
00474   }
00475   // COMMAND: rosdep [package] (alias: rosdeps)
00476   // COMMAND: rosdep0 [package] (alias: rosdeps0)
00477   else if(rp.getName() == ROSPACK_NAME && 
00478           (command == "rosdep" || command == "rosdeps" ||
00479            command == "rosdep0" || command == "rosdeps0"))
00480   {
00481     if(!package.size())
00482     {
00483       rp.logError( "no package given");
00484       return false;
00485     }
00486     if(target.size() || top.size() || length_str.size() || 
00487        zombie_only || deps_only || lang.size() || attrib.size())
00488     {
00489       rp.logError( "invalid option(s) given");
00490       return false;
00491     }
00492     std::set<std::string> rosdeps;
00493     if(!rp.rosdeps(package, (command == "rosdep0" || command == "rosdeps0"), rosdeps))
00494       return false;
00495     for(std::set<std::string>::const_iterator it = rosdeps.begin();
00496         it != rosdeps.end();
00497         ++it)
00498       output.append(*it + "\n");
00499     return true;
00500   }
00501   // COMMAND: vcs [package]
00502   // COMMAND: vcs0 [package]
00503   else if(rp.getName() == ROSPACK_NAME && 
00504           (command == "vcs" || command == "vcs0"))
00505   {
00506     if(!package.size())
00507     {
00508       rp.logError( "no package given");
00509       return false;
00510     }
00511     if(target.size() || top.size() || length_str.size() || 
00512        zombie_only || deps_only || lang.size() || attrib.size())
00513     {
00514       rp.logError( "invalid option(s) given");
00515       return false;
00516     }
00517     std::vector<std::string> vcs;
00518     if(!rp.vcs(package, (command == "vcs0"), vcs))
00519       return false;
00520     for(std::vector<std::string>::const_iterator it = vcs.begin();
00521         it != vcs.end();
00522         ++it)
00523       output.append(*it + "\n");
00524     return true;
00525   }
00526   // COMMAND: depends-on [package]
00527   // COMMAND: depends-on1 [package]
00528   else if(command == "depends-on" || command == "depends-on1")
00529   {
00530     if(!package.size())
00531     {
00532       rp.logError( "no package/stack given");
00533       return false;
00534     }
00535     if(target.size() || top.size() || length_str.size() || 
00536        zombie_only || deps_only || lang.size() || attrib.size())
00537     {
00538       rp.logError( "invalid option(s) given");
00539       return false;
00540     }
00541     std::vector<std::string> deps;
00542     if(!rp.depsOn(package, (command == "depends-on1"), deps))
00543       return false;
00544     for(std::vector<std::string>::const_iterator it = deps.begin();
00545         it != deps.end();
00546         ++it)
00547       output.append(*it + "\n");
00548     return true;
00549   }
00550   // COMMAND: export [--deps-only] --lang=<lang> --attrib=<attrib> [package]
00551   else if(rp.getName() == ROSPACK_NAME && command == "export")
00552   {
00553     if(!package.size() || !lang.size() || !attrib.size())
00554     {
00555       rp.logError( "no package / lang / attrib given");
00556       return false;
00557     }
00558     if(target.size() || top.size() || length_str.size() || zombie_only)
00559     {
00560       rp.logError( "invalid option(s) given");
00561       return false;
00562     }
00563     std::vector<std::string> flags;
00564     if(!rp.exports(package, lang, attrib, deps_only, flags))
00565       return false;
00566     for(std::vector<std::string>::const_iterator it = flags.begin();
00567         it != flags.end();
00568         ++it)
00569     {
00570       if(it != flags.begin())
00571         output.append(" ");
00572       output.append(*it);
00573     }
00574     output.append("\n");
00575     return true;
00576   }
00577   // COMMAND: plugins --attrib=<attrib> [--top=<toppkg>] [package]
00578   else if(rp.getName() == ROSPACK_NAME && command == "plugins")
00579   {
00580     if(!package.size() || !attrib.size())
00581     {
00582       rp.logError( "no package / attrib given");
00583       return false;
00584     }
00585     if(target.size() || length_str.size() || zombie_only)
00586     {
00587       rp.logError( "invalid option(s) given");
00588       return false;
00589     }
00590     std::vector<std::string> flags;
00591     if(!rp.plugins(package, attrib, top, flags))
00592       return false;
00593     for(std::vector<std::string>::const_iterator it = flags.begin();
00594         it != flags.end();
00595         ++it)
00596       output.append(*it + "\n");
00597     return true;
00598   }
00599   // COMMAND: cflags-only-I [--deps-only] [package]
00600   else if(rp.getName() == ROSPACK_NAME && command == "cflags-only-I")
00601   {
00602     if(!package.size())
00603     {
00604       rp.logError( "no package given");
00605       return false;
00606     }
00607     if(target.size() || top.size() || length_str.size() || zombie_only)
00608     {
00609       rp.logError( "invalid option(s) given");
00610       return false;
00611     }
00612     std::vector<std::pair<std::string, bool> > flags;
00613     if(!rp.cpp_exports(package, "--cflags-only-I", "cflags", deps_only, flags))
00614       return false;
00615 
00616     std::string dry_combined;
00617     std::string wet_combined;
00618     for(std::vector<std::pair<std::string, bool> >::const_iterator it = flags.begin();
00619         it != flags.end();
00620         ++it)
00621     {
00622       std::string& combined = it->second ? wet_combined : dry_combined;
00623       if(!combined.empty())
00624         combined.append(" ");
00625       combined.append(it->first);
00626     }
00627 
00628     std::string dry_result;
00629     parse_compiler_flags(dry_combined, "-I", true, false, dry_result);
00630     output.append(dry_result);
00631 
00632     std::string wet_result;
00633     parse_compiler_flags(wet_combined, "-I", true, false, wet_result);
00634     if(!dry_result.empty() && !wet_result.empty())
00635       output.append(" ");
00636     if(!rp.reorder_paths(wet_result, wet_result))
00637       return false;
00638     output.append(wet_result + "\n");
00639     return true;
00640   }
00641   // COMMAND: cflags-only-other [--deps-only] [package]
00642   else if(rp.getName() == ROSPACK_NAME && command == "cflags-only-other")
00643   {
00644     if(!package.size())
00645     {
00646       rp.logError( "no package given");
00647       return false;
00648     }
00649     if(target.size() || top.size() || length_str.size() || zombie_only)
00650     {
00651       rp.logError( "invalid option(s) given");
00652       return false;
00653     }
00654     std::vector<std::pair<std::string, bool> > flags;
00655     if(!rp.cpp_exports(package, "--cflags-only-other", "cflags", deps_only, flags))
00656       return false;
00657     std::string combined;
00658     for(std::vector<std::pair<std::string, bool> >::const_iterator it = flags.begin();
00659         it != flags.end();
00660         ++it)
00661     {
00662       if(it != flags.begin())
00663         combined.append(" ");
00664       combined.append(it->first);
00665     }
00666     std::string result;
00667     parse_compiler_flags(combined, "-I", false, false, result);
00668     output.append(result + "\n");
00669     return true;
00670   }
00671   // COMMAND: libs-only-L [--deps-only] [package]
00672   else if(rp.getName() == ROSPACK_NAME && command == "libs-only-L")
00673   {
00674     if(!package.size())
00675     {
00676       rp.logError( "no package given");
00677       return false;
00678     }
00679     if(target.size() || top.size() || length_str.size() || zombie_only)
00680     {
00681       rp.logError( "invalid option(s) given");
00682       return false;
00683     }
00684     std::vector<std::pair<std::string, bool> > flags;
00685     if(!rp.cpp_exports(package, "--libs-only-L", "lflags", deps_only, flags))
00686       return false;
00687 
00688     std::string dry_combined;
00689     std::string wet_combined;
00690     for(std::vector<std::pair<std::string, bool> >::const_iterator it = flags.begin();
00691         it != flags.end();
00692         ++it)
00693     {
00694       std::string& combined = it->second ? wet_combined : dry_combined;
00695       if(!combined.empty())
00696         combined.append(" ");
00697       combined.append(it->first);
00698     }
00699 
00700     std::string dry_result;
00701     parse_compiler_flags(dry_combined, "-L", true, false, dry_result);
00702     output.append(dry_result);
00703 
00704     std::string wet_result;
00705     parse_compiler_flags(wet_combined, "-L", true, false, wet_result);
00706     if(!dry_result.empty() && !wet_result.empty())
00707       output.append(" ");
00708     if(!rp.reorder_paths(wet_result, wet_result))
00709       return false;
00710     output.append(wet_result + "\n");
00711     return true;
00712   }
00713   // COMMAND: libs-only-l [--deps-only] [package]
00714   else if(rp.getName() == ROSPACK_NAME && command == "libs-only-l")
00715   {
00716     if(!package.size())
00717     {
00718       rp.logError( "no package given");
00719       return false;
00720     }
00721     if(target.size() || top.size() || length_str.size() || zombie_only)
00722     {
00723       rp.logError( "invalid option(s) given");
00724       return false;
00725     }
00726     std::vector<std::pair<std::string, bool> > flags;
00727     if(!rp.cpp_exports(package, "--libs-only-l", "lflags", deps_only, flags))
00728       return false;
00729     std::string combined;
00730     for(std::vector<std::pair<std::string, bool> >::const_iterator it = flags.begin();
00731         it != flags.end();
00732         ++it)
00733     {
00734       if(it != flags.begin())
00735         combined.append(" ");
00736       combined.append(it->first);
00737     }
00738     std::string result;
00739     parse_compiler_flags(combined, "-l", true, true, result);
00740     output.append(result + "\n");
00741     return true;
00742   }
00743   // COMMAND: libs-only-other [--deps-only] [package]
00744   else if(rp.getName() == ROSPACK_NAME && command == "libs-only-other")
00745   {
00746     if(!package.size())
00747     {
00748       rp.logError( "no package given");
00749       return false;
00750     }
00751     if(target.size() || top.size() || length_str.size() || zombie_only)
00752     {
00753       rp.logError( "invalid option(s) given");
00754       return false;
00755     }
00756     std::vector<std::pair<std::string, bool> > flags;
00757     if(!rp.cpp_exports(package, "--libs-only-other", "lflags", deps_only, flags))
00758       return false;
00759     std::string combined;
00760     for(std::vector<std::pair<std::string, bool> >::const_iterator it = flags.begin();
00761         it != flags.end();
00762         ++it)
00763     {
00764       if(it != flags.begin())
00765         combined.append(" ");
00766       combined.append(it->first);
00767     }
00768     std::string intermediate;
00769     parse_compiler_flags(combined, "-L", false, false, intermediate);
00770     std::string result;
00771     parse_compiler_flags(intermediate, "-l", false, false, result);
00772     output.append(result + "\n");
00773     return true;
00774   }
00775   // COMMAND: contents [stack]
00776   else if(rp.getName() == ROSSTACK_NAME && command == "contents")
00777   {
00778     if(!package.size())
00779     {
00780       rp.logError( "no stack given");
00781       return false;
00782     }
00783     if(target.size() || top.size() || length_str.size() || 
00784        zombie_only || deps_only || lang.size() || attrib.size())
00785     {
00786       rp.logError( "invalid option(s) given");
00787       return false;
00788     }
00789 
00790     std::set<std::string> packages;
00791     rp.contents(package, packages);
00792     for(std::set<std::string>::const_iterator it = packages.begin();
00793         it != packages.end();
00794         ++it)
00795       output.append(*it + "\n");
00796     return true;
00797   }
00798   // COMMAND: contains [package]
00799   else if(rp.getName() == ROSSTACK_NAME && 
00800           ((command == "contains") || (command == "contains-path")))
00801   {
00802     if(!package.size())
00803     {
00804       rp.logError( "no package given");
00805       return false;
00806     }
00807     if(target.size() || top.size() || length_str.size() || 
00808        zombie_only || deps_only || lang.size() || attrib.size())
00809     {
00810       rp.logError( "invalid option(s) given");
00811       return false;
00812     }
00813     std::string name, path;
00814     if(!rp.contains(package, name, path))
00815       return false;
00816     if(command == "contains")
00817       output.append(name + "\n");
00818     else // command == "contains-path"
00819       output.append(path + "\n");
00820     return true;
00821   }
00822   else
00823   {
00824     rp.logError(std::string("command ") + command + " not implemented");
00825     return false;
00826   }
00827 }
00828 
00829 bool
00830 parse_args(int argc, char** argv, 
00831            rospack::Rosstackage& rp, po::variables_map& vm)
00832 {
00833   po::options_description desc("Allowed options");
00834   desc.add_options()
00835           ("command", po::value<std::string>(), "command")
00836           ("package", po::value<std::string>(), "package")
00837           ("target", po::value<std::string>(), "target")
00838           ("deps-only", "deps-only")
00839           ("lang", po::value<std::string>(), "lang")
00840           ("attrib", po::value<std::string>(), "attrib")
00841           ("top", po::value<std::string>(), "top")
00842           ("length", po::value<std::string>(), "length")
00843           ("zombie-only", "zombie-only")
00844           ("help", "help")
00845           ("-h", "help")
00846           ("quiet,q", "quiet");
00847 
00848   po::positional_options_description pd;
00849   pd.add("command", 1).add("package", 1);
00850   try
00851   {
00852     po::store(po::command_line_parser(argc, argv).options(desc).positional(pd).run(), vm);
00853   }
00854   catch(boost::program_options::error e)
00855   {
00856     rp.logError( std::string("failed to parse command-line options: ") + e.what());
00857     return false;
00858   }
00859   po::notify(vm);
00860 
00861   return true;
00862 }
00863 
00864 }


rospack
Author(s): Brian Gerkey, Morgan Quigley, Dirk Thomas
autogenerated on Fri Aug 28 2015 12:41:42