BASIS  version 1.2.3 (revision 2104)
CmdLine.cxx
Go to the documentation of this file.
00001 /**
00002  * @file  CmdLine.cxx
00003  * @brief Manages command line definition and parsing of arguments.
00004  *
00005  * Copyright (c) 2011 University of Pennsylvania. All rights reserved.<br />
00006  * See https://www.cbica.upenn.edu/sbia/software/license.html or COPYING file.
00007  *
00008  * Contact: SBIA Group <sbia-software at uphs.upenn.edu>
00009  */
00010 
00011 
00012 #include <set>
00013 
00014 #include <sbia/tclap/Arg.h>
00015 #include <sbia/tclap/ArgException.h>
00016 #include <sbia/tclap/StdOutput.h>
00017 #include <sbia/tclap/Visitor.h>
00018 #include <sbia/tclap/VersionVisitor.h>
00019 #include <sbia/tclap/XorHandler.h>
00020 
00021 #include <sbia/basis/path.h>   // get_executable_name()
00022 #include <sbia/basis/except.h> // BASIS_THROW, runtime_error
00023 
00024 #include <sbia/basis/CmdLine.h>
00025 
00026 
00027 // acceptable in .cxx file
00028 using namespace std;
00029 
00030 
00031 namespace sbia
00032 {
00033 
00034 namespace basis
00035 {
00036 
00037 
00038 // ===========================================================================
00039 // class: StdOutput
00040 // ===========================================================================
00041 
00042 /**
00043  * @brief Prints help, version information, and command-line errors.
00044  */
00045 class StdOutput : public TCLAP::StdOutput
00046 {
00047     // -----------------------------------------------------------------------
00048     // construction / destruction
00049 public:
00050 
00051     /**
00052      * @brief Constructor.
00053      *
00054      * @param [in] cmd The command-line with additional attributes
00055      *                 for which the output is generated.
00056      */
00057     StdOutput(CmdLine* cmd);
00058 
00059     // -----------------------------------------------------------------------
00060     // interface functions
00061 public:
00062 
00063     /**
00064      * @brief Prints a short help, i.e., usage information.
00065      */
00066     virtual void usage(TCLAP::CmdLineInterface&);
00067 
00068     /**
00069      * @brief Prints the full help.
00070      */
00071     virtual void help(TCLAP::CmdLineInterface&);
00072 
00073     /**
00074      * @brief Prints the version information.
00075      */
00076     virtual void version(TCLAP::CmdLineInterface&);
00077 
00078     /**
00079      * @brief Prints an error message.
00080      *
00081      * @param [in] e The exception that caused the failure.
00082      */
00083     virtual void failure(TCLAP::CmdLineInterface&, TCLAP::ArgException& e);
00084 
00085     /**
00086      * @brief Get corresponding command-line object.
00087      *
00088      * @returns Command-line with additional attributes for which the
00089      *          output is generated.
00090      */
00091     CmdLine* getCmdLine() { return _cmd; }
00092 
00093     // -----------------------------------------------------------------------
00094     // helpers
00095 protected:
00096 
00097     /**
00098      * @brief Determine whether an argument has a label or not.
00099      *
00100      * @param [in] arg Command-line argument.
00101      *
00102      * @returns Whether the given argument is a positional argument.
00103      */
00104     bool isUnlabeledArg(TCLAP::Arg* arg) const;
00105 
00106     /**
00107      * @brief Get string describing type of argument value.
00108      *
00109      * @param [in] arg Command-line argument.
00110      *
00111      * @returns String describing type of argument value.
00112      */
00113     string getTypeDescription(TCLAP::Arg* arg) const;
00114 
00115     /**
00116      * @brief Get argument usage string.
00117      *
00118      * @param [in] arg Command-line argument.
00119      * @param [in] all Whether to include also optional short flags.
00120      *
00121      * @returns Short argument description.
00122      */
00123     string getArgumentID(TCLAP::Arg* arg, bool all = false) const;
00124 
00125     /**
00126      * @brief Prints help of command-line argument.
00127      *
00128      * @param [in] os              Output stream.
00129      * @param [in] arg             Command-line argument.
00130      * @param [in] indentFirstLine Whether first line should be indented.
00131      */
00132     void printArgumentHelp(ostream& os, TCLAP::Arg* arg, bool indentFirstLine = true) const;
00133 
00134     /**
00135      * Prints usage information, i.e., synopsis.
00136      *
00137      * @param [in] os      Output stream.
00138      * @param [in] heading Enable/disable output of section heading.
00139      */
00140     void printUsage(ostream& os, bool heading = true) const;
00141 
00142     /**
00143      * @brief Prints program description.
00144      *
00145      * @param [in] os Output stream.
00146      */
00147     void printDescription(ostream& os) const;
00148 
00149     /**
00150      * @brief Prints command-line arguments.
00151      *
00152      * @param [in] os  Output stream.
00153      * @param [in] all Enable/disable help output of all arguments or only
00154      *                 the more important arguments.
00155      */
00156     void printArguments(ostream& os, bool all) const;
00157 
00158     /**
00159      * @brief Print example usage.
00160      *
00161      * @param [in] os Output stream.
00162      */
00163     void printExample(ostream& os) const;
00164 
00165     /**
00166      * @brief Print contact information.
00167      *
00168      * @param [in] os Output stream.
00169      */
00170     void printContact(ostream& os) const;
00171 
00172     // -----------------------------------------------------------------------
00173     // member variables
00174 protected:
00175 
00176     CmdLine*    _cmd;     ///< The command-line with additional attributes.
00177     set<string> _stdargs; ///< Names of standard arguments.
00178 
00179 }; // class StdOutput
00180 
00181 // ---------------------------------------------------------------------------
00182 // construction
00183 // ---------------------------------------------------------------------------
00184 
00185 // ---------------------------------------------------------------------------
00186 StdOutput::StdOutput(CmdLine* cmd)
00187 :
00188     _cmd(cmd)
00189 {
00190     _stdargs.insert("ignore_rest");
00191     _stdargs.insert("verbose");
00192     _stdargs.insert("help");
00193     _stdargs.insert("helpshort");
00194     _stdargs.insert("helpxml");
00195     _stdargs.insert("helpman");
00196     _stdargs.insert("version");
00197 }
00198 
00199 // ---------------------------------------------------------------------------
00200 // interface functions
00201 // ---------------------------------------------------------------------------
00202 
00203 // ---------------------------------------------------------------------------
00204 void StdOutput::usage(TCLAP::CmdLineInterface&)
00205 {
00206     cout << endl;
00207     printUsage(cout, false);
00208     //printArguments(cout, false);
00209     cout << endl;
00210 }
00211 
00212 // ---------------------------------------------------------------------------
00213 void StdOutput::help(TCLAP::CmdLineInterface&)
00214 {
00215     cout << endl;
00216     printUsage(cout);
00217     printDescription(cout);
00218     printArguments(cout, true);
00219     printExample(cout);
00220     printContact(cout);
00221     cout << endl;
00222 }
00223 
00224 // ---------------------------------------------------------------------------
00225 void StdOutput::version(TCLAP::CmdLineInterface&)
00226 {
00227     std::string name      = _cmd->getProgramName();
00228     std::string project   = _cmd->getProjectName();
00229     std::string version   = _cmd->getVersion();
00230     std::string copyright = _cmd->getCopyright();
00231     std::string license   = _cmd->getLicense();
00232 
00233     // print version information
00234     cout << name;
00235     if (!project.empty()) cout << " (" << project << ")";
00236     cout << " " << version;
00237     cout << endl;
00238     // print copyright and license information
00239     if (!copyright.empty()) cout << copyright << endl;
00240     if (!license.empty()) cout << license << endl;
00241 }
00242 
00243 // ---------------------------------------------------------------------------
00244 void StdOutput::failure(TCLAP::CmdLineInterface&, TCLAP::ArgException& e)
00245 {
00246     if (!e.argId().empty() && e.argId() != " ") cerr << e.argId() << ", ";
00247     cerr << e.error() << endl;
00248     cerr << "See --help for a list of available and required arguments." << endl;
00249     throw TCLAP::ExitException(1);
00250 }
00251 
00252 // ---------------------------------------------------------------------------
00253 // helpers
00254 // ---------------------------------------------------------------------------
00255 
00256 // ---------------------------------------------------------------------------
00257 inline bool StdOutput::isUnlabeledArg(TCLAP::Arg* arg) const
00258 {
00259     const string id = arg->longID();
00260     string::size_type pos = id.find(TCLAP::Arg::nameStartString() + arg->getName());
00261     return pos == string::npos;
00262 }
00263 
00264 // ---------------------------------------------------------------------------
00265 inline string StdOutput::getTypeDescription(TCLAP::Arg* arg) const
00266 {
00267     string typedesc = arg->shortID();
00268     string::size_type start = typedesc.find ('<');
00269     string::size_type end   = typedesc.rfind('>');
00270     if (start != string::npos && end != string::npos) {
00271         return typedesc.substr(start + 1, end - start - 1);
00272     } else {
00273         return "";
00274     }
00275 }
00276 
00277 // ---------------------------------------------------------------------------
00278 inline string StdOutput::getArgumentID(TCLAP::Arg* arg, bool all) const
00279 {
00280     string id;
00281     const bool option = !isUnlabeledArg(arg);
00282     if (option) {
00283         if (all && arg->getFlag() != "") {
00284             id += TCLAP::Arg::flagStartString() + arg->getFlag();
00285             id += "  ";
00286         }
00287         id += TCLAP::Arg::nameStartString() + arg->getName();
00288     }
00289     if (arg->isValueRequired()) {
00290         if (option) id += TCLAP::Arg::delimiter();
00291         id += getTypeDescription(arg);
00292     }
00293     return id;
00294 }
00295 
00296 // ---------------------------------------------------------------------------
00297 inline
00298 void StdOutput
00299 ::printArgumentHelp(ostream& os, TCLAP::Arg* arg, bool indentFirstLine) const
00300 {
00301     string id   = getArgumentID(arg, true);
00302     string desc = arg->getDescription();
00303     if (desc.compare (0, 12, "(required)  ")    == 0) desc.erase(0, 12);
00304     if (desc.compare (0, 15, "(OR required)  ") == 0) desc.erase(0, 15);
00305     if (indentFirstLine) spacePrint(os, id, 75, 8, 0);
00306     else                 spacePrint(os, id, 75, 0, 8);
00307     if (!desc.empty()) {
00308         spacePrint(os, desc, 75, 15, 0);
00309     }
00310 }
00311 
00312 // ---------------------------------------------------------------------------
00313 void StdOutput::printUsage(ostream& os, bool heading) const
00314 {
00315     string                        exec_name  = get_executable_name();
00316     list<TCLAP::Arg*>             args       = _cmd->getArgList();
00317     TCLAP::XorHandler             xorhandler = _cmd->getXorHandler();
00318     vector< vector<TCLAP::Arg*> > xors       = xorhandler.getXorList();
00319 
00320     // separate into argument groups
00321     vector< vector<TCLAP::Arg*> > reqxors;
00322     vector< vector<TCLAP::Arg*> > optxors;
00323     for (int i = 0; static_cast<unsigned int>(i) < xors.size(); i++) {
00324         if (xors[i].size() > 0) {
00325             if (xors[i][0]->isRequired()) reqxors.push_back(xors[i]);
00326             else                           optxors.push_back(xors[i]);
00327         }
00328     }
00329     list<TCLAP::Arg*> reqargs;
00330     list<TCLAP::Arg*> optargs;
00331     for (TCLAP::ArgListIterator it = args.begin(); it != args.end(); it++) {
00332         if (_stdargs.find((*it)->getName()) == _stdargs.end()
00333                 && !xorhandler.contains((*it))) {
00334             if ((*it)->isRequired()) {
00335                 reqargs.push_front(*it);
00336             } else {
00337                 optargs.push_front(*it);
00338             }
00339         }
00340     }
00341 
00342     // executable name
00343     string s = exec_name;
00344     string id;
00345     // optional arguments
00346     for (int i = 0; static_cast<unsigned int>(i) < optxors.size(); i++) {
00347         s += " [";
00348         for (TCLAP::ArgVectorIterator it = optxors[i].begin();
00349                 it != optxors[i].end(); it++) {
00350             id = getArgumentID(*it);
00351             s += id;
00352             if ((*it)->acceptsMultipleValues() && id.find("...") == string::npos) {
00353                 s += "...";
00354             }
00355             s += "|";
00356         }
00357         s[s.length() - 1] = ']';
00358     }
00359     for (TCLAP::ArgListIterator it = optargs.begin(); it != optargs.end(); it++) {
00360         id = getArgumentID(*it);
00361         s += " [";
00362         s += id;
00363         s += "]";
00364         if ((*it)->acceptsMultipleValues() && id.find("...") == string::npos) {
00365             s += "...";
00366         }
00367     }
00368     // required arguments
00369     for (int i = 0; static_cast<unsigned int>(i) < reqxors.size(); i++) {
00370         s += " (";
00371         for (TCLAP::ArgVectorIterator it = reqxors[i].begin();
00372                 it != reqxors[i].end(); it++) {
00373             id = getArgumentID(*it);
00374             s += id;
00375             if ((*it)->acceptsMultipleValues() && id.find("...") == string::npos) {
00376                 s += "...";
00377             }
00378             s += "|";
00379         }
00380         s[s.length() - 1] = ')';
00381     }
00382     for (TCLAP::ArgListIterator it = reqargs.begin(); it != reqargs.end(); it++) {
00383         id = getArgumentID(*it);
00384         s += " ";
00385         s += id;
00386         if ((*it)->acceptsMultipleValues() && id.find("...") == string::npos) {
00387             s += "...";
00388         }
00389     }
00390 
00391     // print usage with proper number of columns
00392     // if the program name is too long, then adjust the second line offset 
00393     if (heading) {
00394         os << "SYNOPSIS" << endl;
00395     }
00396     int offset = static_cast<int>(exec_name.length()) + 1;
00397     if (offset > 75 / 2) offset = 8;
00398     spacePrint(os, s, 75, 4, offset);
00399     spacePrint(os, exec_name + " [-h|--help|--helpshort|--helpxml|--helpman|--version]", 75, 4, 0);
00400 }
00401 
00402 // ---------------------------------------------------------------------------
00403 void StdOutput::printDescription(ostream& os) const
00404 {
00405     if (_cmd->getMessage() != "") {
00406         os << endl;
00407         os << "DESCRIPTION" << endl;
00408         spacePrint(os, _cmd->getMessage(), 75, 4, 0);
00409     }
00410 }
00411 
00412 // ---------------------------------------------------------------------------
00413 void StdOutput::printArguments(ostream& os, bool all) const
00414 {
00415     list<TCLAP::Arg*>             args       = _cmd->getArgList();
00416     TCLAP::XorHandler             xorhandler = _cmd->getXorHandler();
00417     vector< vector<TCLAP::Arg*> > xors       = xorhandler.getXorList();
00418 
00419     // separate into argument groups
00420     vector< vector<TCLAP::Arg*> > reqxors;
00421     vector< vector<TCLAP::Arg*> > optxors;
00422     for (int i = 0; static_cast<unsigned int>(i) < xors.size(); i++) {
00423         if (xors[i].size() > 0) {
00424             if (xors[i][0]->isRequired()) reqxors.push_back(xors[i]);
00425             else                          optxors.push_back(xors[i]);
00426         }
00427     }
00428     list<TCLAP::Arg*> reqargs;
00429     list<TCLAP::Arg*> optargs;
00430     list<TCLAP::Arg*> stdargs;
00431     for (TCLAP::ArgListIterator it = args.begin(); it != args.end(); it++) {
00432         if (_stdargs.find((*it)->getName()) != _stdargs.end()) {
00433             stdargs.push_front(*it);
00434         } else if (!xorhandler.contains((*it))) {
00435             if ((*it)->isRequired()) {
00436                 reqargs.push_front(*it);
00437             } else {
00438                 optargs.push_front(*it);
00439             }
00440         }
00441     }
00442 
00443     // return if command has no arguments
00444     if (xors.empty() && reqargs.empty() && optargs.empty()) {
00445         return;
00446     }
00447 
00448     os << endl;
00449     os << "OPTIONS" << endl;
00450 
00451     // required arguments
00452     if (!reqxors.empty() || !reqargs.empty()) {
00453         os << "    Required arguments:" << endl;
00454         for (int i = 0; static_cast<unsigned int>(i) < reqxors.size(); i++) {
00455             if (i > 0) os << endl;
00456             for (TCLAP::ArgVectorIterator it = reqxors[i].begin();
00457                     it != reqxors[i].end(); it++) {
00458                 if (it != reqxors[i].begin()) {
00459                     os << "     or ";
00460                     printArgumentHelp(os, *it, false);
00461                 } else {
00462                     printArgumentHelp(os, *it);
00463                 }
00464             }
00465         }
00466         for (TCLAP::ArgListIterator it = reqargs.begin(); it != reqargs.end(); it++) {
00467             if (!reqxors.empty() || it != reqargs.begin()) os << endl;
00468             printArgumentHelp(os, *it);
00469         }
00470     }
00471 
00472     // optional arguments
00473     if (!optxors.empty() || !optargs.empty()) {
00474         if (!reqxors.empty() || !reqargs.empty()) {
00475             os << endl;
00476         }
00477         os << "    Optional arguments:" << endl;
00478         for (int i = 0; static_cast<unsigned int>(i) < optxors.size(); i++) {
00479             if (i > 0) os << endl;
00480             for (TCLAP::ArgVectorIterator it = optxors[i].begin();
00481                     it != optxors[i].end(); it++) {
00482                 if (it != optxors[i].begin()) {
00483                     os << "     or ";
00484                     printArgumentHelp(os, *it, false);
00485                 } else {
00486                     printArgumentHelp(os, *it);
00487                 }
00488             }
00489         }
00490         for (TCLAP::ArgListIterator it = optargs.begin(); it != optargs.end(); it++) {
00491             if (!optxors.empty() || it != optargs.begin()) os << endl;
00492             printArgumentHelp(os, *it);
00493         }
00494     }
00495 
00496     // standard arguments
00497     if (all && !stdargs.empty()) {
00498         if (!xors.empty() || !reqargs.empty() || !optargs.empty()) {
00499             os << endl;
00500         }
00501         os << "    Standard arguments:" << endl;
00502         for (TCLAP::ArgListIterator it = stdargs.begin(); it != stdargs.end(); it++) {
00503             if (it != stdargs.begin()) os << endl;
00504             printArgumentHelp(os, *it);
00505         }
00506     }
00507 }
00508 
00509 // ---------------------------------------------------------------------------
00510 void StdOutput::printExample(ostream& os) const
00511 {
00512     const string exec_name = get_executable_name();
00513     const vector<string>& examples = _cmd->getExamples();
00514 
00515     if (!examples.empty()) {
00516         os << endl;
00517         os << "EXAMPLE" << endl;
00518         for (vector<string>::const_iterator it = examples.begin();
00519                 it != examples.end(); ++it) {
00520             if (it != examples.begin()) os << endl;
00521             string example = *it;
00522             string::size_type pos = 0;
00523             while ((pos = example.find("EXECNAME", pos)) != string::npos) {
00524                 example.replace(pos, 8, exec_name);
00525             }
00526             spacePrint(os, example, 75, 4, 4);
00527         }
00528     }
00529 }
00530 
00531 // ---------------------------------------------------------------------------
00532 void StdOutput::printContact(ostream& os) const
00533 {
00534     if (_cmd->getContact() != "") {
00535         os << endl;
00536         os << "CONTACT" << endl;
00537         spacePrint(os, _cmd->getContact(), 75, 4, 0);
00538     }
00539 }
00540 
00541 // ===========================================================================
00542 // class: HelpVisitor
00543 // ===========================================================================
00544 
00545 /**
00546  * @brief Displays either full help or usage only.
00547  */
00548 class HelpVisitor: public TCLAP::Visitor
00549 {
00550     // -----------------------------------------------------------------------
00551     // construction / destruction
00552 public:
00553 
00554     /**
00555      * @brief Constructor.
00556      *
00557      * @param [in] out The object which handles the output.
00558      * @param [in] all Enable/disable full help output.
00559      */
00560     HelpVisitor(StdOutput* out, bool all = true)
00561     :
00562         Visitor(),
00563         _out(out),
00564         _all(all)
00565     { }
00566 
00567     // -----------------------------------------------------------------------
00568     // interface function
00569 public:
00570 
00571     /**
00572      * @brief Print help.
00573      */
00574     void visit()
00575     {
00576         if (_all) _out->help (*(_out->getCmdLine()));
00577         else      _out->usage(*(_out->getCmdLine()));
00578         // exit
00579         throw TCLAP::ExitException(0); 
00580     }
00581 
00582     // -----------------------------------------------------------------------
00583     // member variables
00584 protected:
00585 
00586     StdOutput* _out; ///< Object handling the output.
00587     bool       _all; ///< Enable/disable full help output.
00588 
00589     // -----------------------------------------------------------------------
00590     // unsupported
00591 private:
00592 
00593     HelpVisitor(const HelpVisitor&);            ///< Not implemented.
00594     HelpVisitor& operator=(const HelpVisitor&); ///< Not implemented.
00595 
00596 }; // class HelpVisitor
00597 
00598 // ===========================================================================
00599 // class: XmlVisitor
00600 // ===========================================================================
00601 
00602 /**
00603  * @brief Outputs the command-line interface in XML format.
00604  */
00605 class XmlVisitor: public TCLAP::Visitor
00606 {
00607     // -----------------------------------------------------------------------
00608     // construction / destruction
00609 public:
00610 
00611     /**
00612      * @brief Constructor.
00613      */
00614     XmlVisitor()
00615     :
00616         Visitor()
00617     { }
00618 
00619     // -----------------------------------------------------------------------
00620     // interface function
00621 public:
00622 
00623     /**
00624      * @brief Print help.
00625      */
00626     void visit()
00627     {
00628         cerr << "Not implemented yet! Use --help instead." << endl;
00629         // exit
00630         throw TCLAP::ExitException(0); 
00631     }
00632 
00633     // -----------------------------------------------------------------------
00634     // member variables
00635 protected:
00636 
00637 
00638     // -----------------------------------------------------------------------
00639     // unsupported
00640 private:
00641 
00642     XmlVisitor(const XmlVisitor&);            ///< Not implemented.
00643     XmlVisitor& operator=(const XmlVisitor&); ///< Not implemented.
00644 
00645 }; // class XmlVisitor
00646 
00647 // ===========================================================================
00648 // class: ManPageVisitor
00649 // ===========================================================================
00650 
00651 /**
00652  * @brief Displays man page and exits.
00653  */
00654 class ManPageVisitor: public TCLAP::Visitor
00655 {
00656     // -----------------------------------------------------------------------
00657     // construction / destruction
00658 public:
00659 
00660     /**
00661      * @brief Constructor.
00662      */
00663     ManPageVisitor()
00664     :
00665         Visitor()
00666     { }
00667 
00668     // -----------------------------------------------------------------------
00669     // interface function
00670 public:
00671 
00672     /**
00673      * @brief Print help.
00674      */
00675     void visit()
00676     {
00677         cerr << "Not implemented yet! Use --help instead." << endl;
00678         // exit
00679         throw TCLAP::ExitException(0);
00680     }
00681 
00682     // -----------------------------------------------------------------------
00683     // member variables
00684 protected:
00685 
00686 
00687     // -----------------------------------------------------------------------
00688     // unsupported
00689 private:
00690 
00691     ManPageVisitor(const ManPageVisitor&);            ///< Not implemented.
00692     ManPageVisitor& operator=(const ManPageVisitor&); ///< Not implemented.
00693 
00694 }; // class ManPageVisitor
00695 
00696 // ===========================================================================
00697 // class: CmdLine
00698 // ===========================================================================
00699 
00700 // ---------------------------------------------------------------------------
00701 CmdLine::CmdLine(const std::string& name,
00702                  const std::string& project,
00703                  const std::string& description,
00704                  const std::string& example,
00705                  const std::string& version,
00706                  const std::string& copyright,
00707                  const std::string& license,
00708                  const std::string& contact,
00709                  bool               stdargs)
00710 :
00711     TCLAP::CmdLine(description, ' ', version, false),
00712     _name(name),
00713     _project(project),
00714     _copyright(copyright),
00715     _license(license),
00716     _contact(contact)
00717 {
00718     if (example != "") _examples.push_back(example);
00719     setup(stdargs);
00720 }
00721 
00722 // ---------------------------------------------------------------------------
00723 CmdLine::CmdLine(const std::string&              name,
00724                  const std::string&              project,
00725                  const std::string&              description,
00726                  const std::vector<std::string>& examples,
00727                  const std::string&              version,
00728                  const std::string&              copyright,
00729                  const std::string&              license,
00730                  const std::string&              contact,
00731                  bool                            stdargs)
00732 :
00733     TCLAP::CmdLine(description, ' ', version, false),
00734     _name(name),
00735     _project(project),
00736     _examples(examples),
00737     _copyright(copyright),
00738     _license(license),
00739     _contact(contact)
00740 {
00741     setup(stdargs);
00742 }
00743 
00744 // ---------------------------------------------------------------------------
00745 void CmdLine::setup(bool stdargs)
00746 {
00747     // replace output handler
00748     StdOutput* output = new StdOutput(this);
00749     if (_output) delete _output;
00750     _output = output;
00751 
00752     // remove arguments added by TCLAP::CmdLine (ignore)
00753     ClearContainer(_argDeleteOnExitList);
00754     ClearContainer(_visitorDeleteOnExitList);
00755     TCLAP::CmdLine::_argList.clear();
00756 
00757     // add standard arguments
00758     TCLAP::Visitor* v;
00759 
00760     v = new TCLAP::IgnoreRestVisitor();
00761     SwitchArg* ignore  = new SwitchArg(
00762               TCLAP::Arg::flagStartString(), TCLAP::Arg::ignoreNameString(),
00763               "Ignores the rest of the labeled arguments.",
00764               false, v);
00765     add(ignore);
00766     deleteOnExit(ignore);
00767     deleteOnExit(v);
00768 
00769     if (stdargs) {
00770         v = new HelpVisitor(output, true);
00771         TCLAP::SwitchArg* help = new TCLAP::SwitchArg(
00772                 "h", "help", "Display help and exit.", false, v);
00773         add(help);
00774         deleteOnExit(help);
00775         deleteOnExit(v);
00776 
00777         v = new HelpVisitor(output, false);
00778         TCLAP::SwitchArg* helpshort = new TCLAP::SwitchArg(
00779                 "", "helpshort", "Display short help and exit.", false, v);
00780         add(helpshort);
00781         deleteOnExit(helpshort);
00782         deleteOnExit(v);
00783 
00784         v = new XmlVisitor();
00785         TCLAP::SwitchArg* helpxml = new TCLAP::SwitchArg(
00786                 "", "helpxml", "Display help in XML format and exit.", false, v);
00787         add(helpxml);
00788         deleteOnExit(helpxml);
00789         deleteOnExit(v);
00790 
00791         v = new ManPageVisitor();
00792         TCLAP::SwitchArg* helpman = new TCLAP::SwitchArg(
00793                 "", "helpman", "Display help as man page and exit.", false, v);
00794         add(helpman);
00795         deleteOnExit(helpman);
00796         deleteOnExit(v);
00797 
00798         v = new TCLAP::VersionVisitor(this, &_output);
00799         TCLAP::SwitchArg* vers = new TCLAP::SwitchArg(
00800                 "", "version", "Display version information and exit.", false, v);
00801         add(vers);
00802         deleteOnExit(vers);
00803         deleteOnExit(v);
00804     }
00805 }
00806 
00807 // Note: The following methods are mainly overwritten to include the
00808 //       documentation in the API documentation of the BASIS class.
00809 
00810 // -----------------------------------------------------------------------
00811 void CmdLine::add(Arg& a)
00812 {
00813     TCLAP::CmdLine::add(a);
00814 }
00815 
00816 // -----------------------------------------------------------------------
00817 void CmdLine::add(Arg* a)
00818 {
00819     TCLAP::CmdLine::add(a);
00820 }
00821 
00822 // -----------------------------------------------------------------------
00823 void CmdLine::xorAdd(Arg& a, Arg& b)
00824 {
00825     vector<TCLAP::Arg*> xors;
00826     xors.push_back(&a);
00827     xors.push_back(&b);
00828     xorAdd(xors);
00829 }
00830 
00831 // -----------------------------------------------------------------------
00832 void CmdLine::xorAdd(std::vector<Arg*>& xors)
00833 {
00834     TCLAP::CmdLine::_xorHandler.add(xors);
00835 
00836     bool required = false;
00837     for (TCLAP::ArgVectorIterator it = xors.begin(); it != xors.end(); ++it) {
00838         if ((*it)->isRequired()) required = true;
00839     }
00840     for (TCLAP::ArgVectorIterator it = xors.begin(); it != xors.end(); ++it) {
00841         if (required) (*it)->forceRequired();
00842         (*it)->setRequireLabel("OR required");
00843         add( *it );
00844     }
00845 }
00846 
00847 // -----------------------------------------------------------------------
00848 void CmdLine::parse(int argc, const char* const* argv)
00849 {
00850     TCLAP::CmdLine::parse(argc, argv);
00851 }
00852 
00853 // -----------------------------------------------------------------------
00854 void CmdLine::parse(std::vector<std::string>& args)
00855 {
00856     TCLAP::CmdLine::parse(args);
00857 }
00858 
00859 
00860 } // namespace basis
00861 
00862 } // namespace sbia