ZshCompletionOutput.h
Go to the documentation of this file.
00001 // -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
00002 
00003 /****************************************************************************** 
00004  * 
00005  *  file:  ZshCompletionOutput.h
00006  * 
00007  *  Copyright (c) 2006, Oliver Kiddle
00008  *  All rights reverved.
00009  * 
00010  *  See the file COPYING in the top directory of this distribution for
00011  *  more information.
00012  *  
00013  *  THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS 
00014  *  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
00015  *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
00016  *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
00017  *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
00018  *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
00019  *  DEALINGS IN THE SOFTWARE.
00020  *  
00021  *****************************************************************************/ 
00022 
00023 #ifndef TCLAP_ZSHCOMPLETIONOUTPUT_H
00024 #define TCLAP_ZSHCOMPLETIONOUTPUT_H
00025 
00026 #include <string>
00027 #include <vector>
00028 #include <list>
00029 #include <iostream>
00030 #include <map>
00031 
00032 #include <tclap/CmdLineInterface.h>
00033 #include <tclap/CmdLineOutput.h>
00034 #include <tclap/XorHandler.h>
00035 #include <tclap/Arg.h>
00036 
00037 namespace TCLAP {
00038 
00043 class ZshCompletionOutput : public CmdLineOutput
00044 {
00045 
00046         public:
00047 
00048                 ZshCompletionOutput();
00049 
00055                 virtual void usage(CmdLineInterface& c);
00056 
00062                 virtual void version(CmdLineInterface& c);
00063 
00070                 virtual void failure(CmdLineInterface& c,
00071                                                      ArgException& e );
00072 
00073         protected:
00074 
00075                 void basename( std::string& s );
00076                 void quoteSpecialChars( std::string& s );
00077 
00078                 std::string getMutexList( CmdLineInterface& _cmd, Arg* a );
00079                 void printOption( Arg* it, std::string mutex );
00080                 void printArg( Arg* it );
00081 
00082                 std::map<std::string, std::string> common;
00083                 char theDelimiter;
00084 };
00085 
00086 ZshCompletionOutput::ZshCompletionOutput()
00087 : common(std::map<std::string, std::string>()),
00088   theDelimiter('=')
00089 {
00090         common["host"] = "_hosts";
00091         common["hostname"] = "_hosts";
00092         common["file"] = "_files";
00093         common["filename"] = "_files";
00094         common["user"] = "_users";
00095         common["username"] = "_users";
00096         common["directory"] = "_directories";
00097         common["path"] = "_directories";
00098         common["url"] = "_urls";
00099 }
00100 
00101 inline void ZshCompletionOutput::version(CmdLineInterface& _cmd)
00102 {
00103         std::cout << _cmd.getVersion() << std::endl;
00104 }
00105 
00106 inline void ZshCompletionOutput::usage(CmdLineInterface& _cmd )
00107 {
00108         std::list<Arg*> argList = _cmd.getArgList();
00109         std::string progName = _cmd.getProgramName();
00110         std::string xversion = _cmd.getVersion();
00111         theDelimiter = _cmd.getDelimiter();
00112         basename(progName);
00113 
00114         std::cout << "#compdef " << progName << std::endl << std::endl <<
00115                 "# " << progName << " version " << _cmd.getVersion() << std::endl << std::endl <<
00116                 "_arguments -s -S";
00117 
00118         for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
00119         {
00120                 if ( (*it)->shortID().at(0) == '<' )
00121                         printArg((*it));
00122                 else if ( (*it)->getFlag() != "-" )
00123                         printOption((*it), getMutexList(_cmd, *it));
00124         }
00125 
00126         std::cout << std::endl;
00127 }
00128 
00129 inline void ZshCompletionOutput::failure( CmdLineInterface& _cmd,
00130                                                 ArgException& e )
00131 {
00132         static_cast<void>(_cmd); // unused
00133         std::cout << e.what() << std::endl;
00134 }
00135 
00136 inline void ZshCompletionOutput::quoteSpecialChars( std::string& s )
00137 {
00138         size_t idx = s.find_last_of(':');
00139         while ( idx != std::string::npos )
00140         {
00141                 s.insert(idx, 1, '\\');
00142                 idx = s.find_last_of(':', idx);
00143         }
00144         idx = s.find_last_of('\'');
00145         while ( idx != std::string::npos )
00146         {
00147                 s.insert(idx, "'\\'");
00148                 if (idx == 0)
00149                         idx = std::string::npos;
00150                 else
00151                         idx = s.find_last_of('\'', --idx);
00152         }
00153 }
00154 
00155 inline void ZshCompletionOutput::basename( std::string& s )
00156 {
00157         size_t p = s.find_last_of('/');
00158         if ( p != std::string::npos )
00159         {
00160                 s.erase(0, p + 1);
00161         }
00162 }
00163 
00164 inline void ZshCompletionOutput::printArg(Arg* a)
00165 {
00166         static int count = 1;
00167 
00168         std::cout << " \\" << std::endl << "  '";
00169         if ( a->acceptsMultipleValues() )
00170                 std::cout << '*';
00171         else
00172                 std::cout << count++;
00173         std::cout << ':';
00174         if ( !a->isRequired() )
00175                 std::cout << ':';
00176 
00177         std::cout << a->getName() << ':';
00178         std::map<std::string, std::string>::iterator compArg = common.find(a->getName());
00179         if ( compArg != common.end() )
00180         {
00181                 std::cout << compArg->second;
00182         }
00183         else
00184         {
00185                 std::cout << "_guard \"^-*\" " << a->getName();
00186         }
00187         std::cout << '\'';
00188 }
00189 
00190 inline void ZshCompletionOutput::printOption(Arg* a, std::string mutex)
00191 {
00192         std::string flag = a->flagStartChar() + a->getFlag();
00193         std::string name = a->nameStartString() + a->getName();
00194         std::string desc = a->getDescription();
00195 
00196         // remove full stop and capitalisation from description as
00197         // this is the convention for zsh function
00198         if (!desc.compare(0, 12, "(required)  "))
00199         {
00200                 desc.erase(0, 12);
00201         }
00202         if (!desc.compare(0, 15, "(OR required)  "))
00203         {
00204                 desc.erase(0, 15);
00205         }
00206         size_t len = desc.length();
00207         if (len && desc.at(--len) == '.')
00208         {
00209                 desc.erase(len);
00210         }
00211         if (len)
00212         {
00213                 desc.replace(0, 1, 1, tolower(desc.at(0)));
00214         }
00215 
00216         std::cout << " \\" << std::endl << "  '" << mutex;
00217 
00218         if ( a->getFlag().empty() )
00219         {
00220                 std::cout << name;
00221         }
00222         else
00223         {
00224                 std::cout << "'{" << flag << ',' << name << "}'";
00225         }
00226         if ( theDelimiter == '=' && a->isValueRequired() )
00227                 std::cout << "=-";
00228         quoteSpecialChars(desc);
00229         std::cout << '[' << desc << ']';
00230 
00231         if ( a->isValueRequired() )
00232         {
00233                 std::string arg = a->shortID();
00234                 arg.erase(0, arg.find_last_of(theDelimiter) + 1);
00235                 if ( arg.at(arg.length()-1) == ']' )
00236                         arg.erase(arg.length()-1);
00237                 if ( arg.at(arg.length()-1) == ']' )
00238                 {
00239                         arg.erase(arg.length()-1);
00240                 }
00241                 if ( arg.at(0) == '<' )
00242                 {
00243                         arg.erase(arg.length()-1);
00244                         arg.erase(0, 1);
00245                 }
00246                 size_t p = arg.find('|');
00247                 if ( p != std::string::npos )
00248                 {
00249                         do
00250                         {
00251                                 arg.replace(p, 1, 1, ' ');
00252                         }
00253                         while ( (p = arg.find_first_of('|', p)) != std::string::npos );
00254                         quoteSpecialChars(arg);
00255                         std::cout << ": :(" << arg << ')';
00256                 }
00257                 else
00258                 {
00259                         std::cout << ':' << arg;
00260                         std::map<std::string, std::string>::iterator compArg = common.find(arg);
00261                         if ( compArg != common.end() )
00262                         {
00263                                 std::cout << ':' << compArg->second;
00264                         }
00265                 }
00266         }
00267 
00268         std::cout << '\'';
00269 }
00270 
00271 inline std::string ZshCompletionOutput::getMutexList( CmdLineInterface& _cmd, Arg* a)
00272 {
00273         XorHandler xorHandler = _cmd.getXorHandler();
00274         std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
00275         
00276         if (a->getName() == "help" || a->getName() == "version")
00277         {
00278                 return "(-)";
00279         }
00280 
00281         std::ostringstream list;
00282         if ( a->acceptsMultipleValues() )
00283         {
00284                 list << '*';
00285         }
00286 
00287         for ( int i = 0; static_cast<unsigned int>(i) < xorList.size(); i++ )
00288         {
00289                 for ( ArgVectorIterator it = xorList[i].begin();
00290                         it != xorList[i].end();
00291                         it++)
00292                 if ( a == (*it) )
00293                 {
00294                         list << '(';
00295                         for ( ArgVectorIterator iu = xorList[i].begin();
00296                                 iu != xorList[i].end();
00297                                 iu++ )
00298                         {
00299                                 bool notCur = (*iu) != a;
00300                                 bool hasFlag = !(*iu)->getFlag().empty();
00301                                 if ( iu != xorList[i].begin() && (notCur || hasFlag) )
00302                                         list << ' ';
00303                                 if (hasFlag)
00304                                         list << (*iu)->flagStartChar() << (*iu)->getFlag() << ' ';
00305                                 if ( notCur || hasFlag )
00306                                         list << (*iu)->nameStartString() << (*iu)->getName();
00307                         }
00308                         list << ')';
00309                         return list.str();
00310                 }
00311         }
00312         
00313         // wasn't found in xor list
00314         if (!a->getFlag().empty()) {
00315                 list << "(" << a->flagStartChar() << a->getFlag() << ' ' <<
00316                         a->nameStartString() << a->getName() << ')';
00317         }
00318         
00319         return list.str();
00320 }
00321 
00322 } //namespace TCLAP
00323 #endif


mapstitch
Author(s): Philipp M. Scholl
autogenerated on Mon Oct 6 2014 02:09:53