Search:

SENF Extensible Network Framework

  • Home
  • Download
  • Wiki
  • BerliOS
  • ChangeLog
  • Browse SVN
  • Bug Tracker
  • Overview
  • Examples
  • HowTos
  • Glossary
  • PPI
  • Packets
  • Scheduler
  • Socket
  • Utils
  • Console
  • Daemon
  • Logger
  • Termlib
  • Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

OverloadedCommand.cc

Go to the documentation of this file.
00001 // $Id: OverloadedCommand.cc 1742 2010-11-04 14:51:56Z g0dil $
00002 //
00003 // Copyright (C) 2008
00004 // Fraunhofer (FOKUS)
00005 // Competence Center NETwork research (NET), St. Augustin, GERMANY
00006 //     Stefan Bund <g0dil@berlios.de>
00007 //
00008 // This program is free software; you can redistribute it and/or modify
00009 // it under the terms of the GNU General Public License as published by
00010 // the Free Software Foundation; either version 2 of the License, or
00011 // (at your option) any later version.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the
00020 // Free Software Foundation, Inc.,
00021 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00026 #include "OverloadedCommand.hh"
00027 //#include "OverloadedCommand.ih"
00028 
00029 // Custom includes
00030 
00031 //#include "OverloadedCommand.mpp"
00032 #define prefix_
00033 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00034 
00035 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00036 // senf::console::OverloadedCommandNode
00037 
00038 prefix_ senf::console::OverloadedCommandNode &
00039 senf::console::OverloadedCommandNode::insertOverload(DirectoryNode & dir,
00040                                                      std::string const & name,
00041                                                      CommandOverload::ptr overload)
00042 {
00043     OverloadedCommandNode & node (
00044         dir.hasChild(name)
00045         ? dynamic_cast<OverloadedCommandNode &>(dir(name))
00046         : dir.add(name, OverloadedCommandNode::create()));
00047     node.add(overload);
00048     return node;
00049 }
00050 
00051 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00052 // So soll die doku aussehen:
00053 //
00054 // Usage:
00055 //      1- foo arg1:int arg2:double
00056 //      2- foo arg3:string
00057 //      3- foo
00058 //
00059 // With:
00060 //      arg1 -   arg1-doc
00061 //      arg2 -   arg2-doc
00062 //          default: 1.23
00063 //      arg3 -   arg3-doc
00064 //
00065 // Generic documentation foo blalsdljfl laj flkajslkjs fdlkj oiwlksdj ;llkaj
00066 // sdflkja sldkfjslkdfj sdlkfj lskjdf lskjdf lksj dflkj lsdkfj lskdjf lskjkd
00067 // Generic documentation foo blalsdljfl laj flkajslkjs fdlkj oiwlksdj ;llkaj
00068 // sdflkja sldkfjslkdfj sdlkfj lskjdf lskjdf lksj dflkj lsdkfj lskdjf lskjkd
00069 // Generic documentation foo blalsdljfl laj flkajslkjs fdlkj oiwlksdj ;llkaj
00070 // sdflkja sldkfjslkdfj sdlkfj lskjdf lskjdf lksj dflkj lsdkfj lskdjf lskjkd
00071 //
00072 // Variant 1:
00073 // Variant 1 doc la;ksjf lkj sdlkfj lkjekj sdflkj ekljsdlkfj wlej
00074 // slkj dkj sldkfj lwekljsdf skldjf lskjdf l jsd
00075 //
00076 // Variant 2:
00077 // Variant 2 doc lskdfj lwkej lksjdflksjf
00078 //
00079 // Variatn 3:
00080 // Variant 3 doc slkjflw ekj lskdfj lskdjf laksdj flksj elkj aldskjf lwkejlksdj
00081 // ldkfaj wlekj slkdfj lskdjf lwkejlkasdjf
00082 
00083 prefix_ void senf::console::OverloadedCommandNode::v_help(std::ostream & os)
00084     const
00085 {
00086     typedef std::vector<ArgumentDoc> ArgumentDocs;
00087     ArgumentDocs argumentDocs;
00088     bool haveDocumentedArg (false);
00089 
00090     os << "Usage:\n";
00091     {
00092         Overloads::const_iterator i (overloads_.begin());
00093         Overloads::const_iterator const i_end (overloads_.end());
00094         unsigned index (1);
00095         for (; i != i_end; ++i, ++index) {
00096             os << "    ";
00097             if (overloads_.size() > 1) os << index << "- ";
00098             os << name();
00099             for (unsigned j (0); j < (*i)->numArguments(); ++j) {
00100                 ArgumentDoc arg;
00101                 (*i)->argumentDoc(j, arg);
00102 
00103                 os << ' ';
00104                 if (! arg.defaultValue.empty())
00105                     os << '[';
00106                 if (! arg.name.empty()) os << arg.name;
00107                 if (! arg.type.empty()) os << ':' << arg.type;
00108                 if (arg.name.empty() && arg.type.empty()) os << "...";
00109                 if (! arg.defaultValue.empty())
00110                     os << ']';
00111 
00112                 if (! arg.name.empty() || ! arg.defaultValue.empty()) {
00113                     ArgumentDocs::iterator k (argumentDocs.begin());
00114                     ArgumentDocs::iterator const k_end (argumentDocs.end());
00115                     for (; k != k_end; ++k)
00116                         if (k->name == arg.name && k->defaultValue == arg.defaultValue) {
00117                             if (! arg.doc.empty() && k->doc.empty()) {
00118                                 k->doc == arg.doc;
00119                                 haveDocumentedArg = true;
00120                             }
00121                             break;
00122                         }
00123                     if (k == k_end) {
00124                         argumentDocs.push_back(arg);
00125                         if (! arg.doc.empty())
00126                             haveDocumentedArg = true;
00127                     }
00128                 }
00129             }
00130             os << '\n';
00131         }
00132     }
00133 
00134     if (haveDocumentedArg) {
00135         os << "\n" "With:\n";
00136         ArgumentDocs::const_iterator i (argumentDocs.begin());
00137         ArgumentDocs::const_iterator const i_end (argumentDocs.end());
00138         for (; i != i_end; ++i) {
00139             if (! i->doc.empty() || ! i->defaultValue.empty()) {
00140                 os << "    "
00141                    << i->name
00142                    << std::string(i->name.length()<8 ? 8-i->name.length() : 0, ' ')
00143                    << "  "
00144                    << i->doc
00145                    << '\n';
00146                 if (! i->defaultValue.empty())
00147                     os << "        default: " << i->defaultValue << '\n';
00148             }
00149         }
00150     }
00151 
00152     if (! doc_.empty())
00153         os << "\n" << doc_ << "\n";
00154 
00155     {
00156         Overloads::const_iterator i (overloads_.begin());
00157         Overloads::const_iterator const i_end (overloads_.end());
00158         unsigned index (1);
00159         for (; i != i_end; ++i, ++index) {
00160             std::string overloadDoc ((*i)->doc());
00161             if (! overloadDoc.empty()) {
00162                 os << "\n";
00163                 if (overloads_.size() > 1)
00164                     os << "Variant " << index << ":\n";
00165                 os << overloadDoc << "\n";
00166             }
00167         }
00168     }
00169 }
00170 
00171 prefix_ std::string senf::console::OverloadedCommandNode::v_shorthelp()
00172     const
00173 {
00174     if (!shortdoc_.empty())
00175         return shortdoc_;
00176     if (!doc_.empty())
00177         return doc_.substr(0,doc_.find('\n'));
00178     Overloads::const_iterator i (overloads_.begin());
00179     Overloads::const_iterator const i_end (overloads_.end());
00180     for (; i != i_end; ++i) {
00181         std::string overloadDoc ((*i)->doc());
00182         if (! overloadDoc.empty())
00183             return overloadDoc.substr(0,overloadDoc.find('\n'));
00184     }
00185     return "";
00186 }
00187 
00188 prefix_ void senf::console::OverloadedCommandNode::v_execute(boost::any & rv,
00189                                                              std::ostream & os,
00190                                                              ParseCommandInfo const & command)
00191     const
00192 {
00193     Overloads::const_iterator i (overloads_.begin());
00194     Overloads::const_iterator const i_end (overloads_.end());
00195     SyntaxErrorException err;
00196     for (; i != i_end; ++i) {
00197         try {
00198             (**i)(rv, os, command);
00199             return;
00200         }
00201         catch (SyntaxErrorException & ex) {
00202             err = ex;
00203         };
00204     }
00205     throw err;
00206 }
00207 
00208 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00209 // senf::console::SimpleCommandOverload
00210 
00211 prefix_ unsigned senf::console::SimpleCommandOverload::v_numArguments()
00212     const
00213 {
00214     return 1;
00215 }
00216 
00217 prefix_ void senf::console::SimpleCommandOverload::v_argumentDoc(unsigned index, ArgumentDoc & doc)
00218     const
00219 {}
00220 
00221 prefix_ std::string senf::console::SimpleCommandOverload::v_doc()
00222     const
00223 {
00224     return doc_;
00225 }
00226 
00227 prefix_ void senf::console::SimpleCommandOverload::v_execute(boost::any & rv,
00228                                                              std::ostream & os,
00229                                                              ParseCommandInfo const & command)
00230     const
00231 {
00232     fn_(os, command);
00233 }
00234 
00235 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00236 #undef prefix_
00237 //#include "OverloadedCommand.mpp"
00238 
00239 
00240 // Local Variables:
00241 // mode: c++
00242 // fill-column: 100
00243 // comment-column: 40
00244 // c-file-style: "senf"
00245 // indent-tabs-mode: nil
00246 // ispell-local-dictionary: "american"
00247 // compile-command: "scons -u test"
00248 // End:

Contact: senf-dev@lists.berlios.de | © 2006-2010 Fraunhofer Institute for Open Communication Systems, Network Research