tclap  1.2.1
ZshCompletionOutput.h
Go to the documentation of this file.
1 // -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
2 
3 /******************************************************************************
4  *
5  * file: ZshCompletionOutput.h
6  *
7  * Copyright (c) 2006, Oliver Kiddle
8  * All rights reverved.
9  *
10  * See the file COPYING in the top directory of this distribution for
11  * more information.
12  *
13  * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
14  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19  * DEALINGS IN THE SOFTWARE.
20  *
21  *****************************************************************************/
22 
23 #ifndef TCLAP_ZSHCOMPLETIONOUTPUT_H
24 #define TCLAP_ZSHCOMPLETIONOUTPUT_H
25 
26 #include <string>
27 #include <vector>
28 #include <list>
29 #include <iostream>
30 #include <map>
31 
32 #include <tclap/CmdLineInterface.h>
33 #include <tclap/CmdLineOutput.h>
34 #include <tclap/XorHandler.h>
35 #include <tclap/Arg.h>
36 
37 namespace TCLAP {
38 
44 {
45 
46  public:
47 
49 
55  virtual void usage(CmdLineInterface& c);
56 
62  virtual void version(CmdLineInterface& c);
63 
70  virtual void failure(CmdLineInterface& c,
71  ArgException& e );
72 
73  protected:
74 
75  void basename( std::string& s );
76  void quoteSpecialChars( std::string& s );
77 
78  std::string getMutexList( CmdLineInterface& _cmd, Arg* a );
79  void printOption( Arg* it, std::string mutex );
80  void printArg( Arg* it );
81 
82  std::map<std::string, std::string> common;
84 };
85 
87 : common(std::map<std::string, std::string>()),
88  theDelimiter('=')
89 {
90  common["host"] = "_hosts";
91  common["hostname"] = "_hosts";
92  common["file"] = "_files";
93  common["filename"] = "_files";
94  common["user"] = "_users";
95  common["username"] = "_users";
96  common["directory"] = "_directories";
97  common["path"] = "_directories";
98  common["url"] = "_urls";
99 }
100 
102 {
103  std::cout << _cmd.getVersion() << std::endl;
104 }
105 
107 {
108  std::list<Arg*> argList = _cmd.getArgList();
109  std::string progName = _cmd.getProgramName();
110  std::string xversion = _cmd.getVersion();
111  theDelimiter = _cmd.getDelimiter();
112  basename(progName);
113 
114  std::cout << "#compdef " << progName << std::endl << std::endl <<
115  "# " << progName << " version " << _cmd.getVersion() << std::endl << std::endl <<
116  "_arguments -s -S";
117 
118  for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
119  {
120  if ( (*it)->shortID().at(0) == '<' )
121  printArg((*it));
122  else if ( (*it)->getFlag() != "-" )
123  printOption((*it), getMutexList(_cmd, *it));
124  }
125 
126  std::cout << std::endl;
127 }
128 
130  ArgException& e )
131 {
132  static_cast<void>(_cmd); // unused
133  std::cout << e.what() << std::endl;
134 }
135 
136 inline void ZshCompletionOutput::quoteSpecialChars( std::string& s )
137 {
138  size_t idx = s.find_last_of(':');
139  while ( idx != std::string::npos )
140  {
141  s.insert(idx, 1, '\\');
142  idx = s.find_last_of(':', idx);
143  }
144  idx = s.find_last_of('\'');
145  while ( idx != std::string::npos )
146  {
147  s.insert(idx, "'\\'");
148  if (idx == 0)
149  idx = std::string::npos;
150  else
151  idx = s.find_last_of('\'', --idx);
152  }
153 }
154 
155 inline void ZshCompletionOutput::basename( std::string& s )
156 {
157  size_t p = s.find_last_of('/');
158  if ( p != std::string::npos )
159  {
160  s.erase(0, p + 1);
161  }
162 }
163 
165 {
166  static int count = 1;
167 
168  std::cout << " \\" << std::endl << " '";
169  if ( a->acceptsMultipleValues() )
170  std::cout << '*';
171  else
172  std::cout << count++;
173  std::cout << ':';
174  if ( !a->isRequired() )
175  std::cout << ':';
176 
177  std::cout << a->getName() << ':';
178  std::map<std::string, std::string>::iterator compArg = common.find(a->getName());
179  if ( compArg != common.end() )
180  {
181  std::cout << compArg->second;
182  }
183  else
184  {
185  std::cout << "_guard \"^-*\" " << a->getName();
186  }
187  std::cout << '\'';
188 }
189 
190 inline void ZshCompletionOutput::printOption(Arg* a, std::string mutex)
191 {
192  std::string flag = a->flagStartChar() + a->getFlag();
193  std::string name = a->nameStartString() + a->getName();
194  std::string desc = a->getDescription();
195 
196  // remove full stop and capitalisation from description as
197  // this is the convention for zsh function
198  if (!desc.compare(0, 12, "(required) "))
199  {
200  desc.erase(0, 12);
201  }
202  if (!desc.compare(0, 15, "(OR required) "))
203  {
204  desc.erase(0, 15);
205  }
206  size_t len = desc.length();
207  if (len && desc.at(--len) == '.')
208  {
209  desc.erase(len);
210  }
211  if (len)
212  {
213  desc.replace(0, 1, 1, tolower(desc.at(0)));
214  }
215 
216  std::cout << " \\" << std::endl << " '" << mutex;
217 
218  if ( a->getFlag().empty() )
219  {
220  std::cout << name;
221  }
222  else
223  {
224  std::cout << "'{" << flag << ',' << name << "}'";
225  }
226  if ( theDelimiter == '=' && a->isValueRequired() )
227  std::cout << "=-";
228  quoteSpecialChars(desc);
229  std::cout << '[' << desc << ']';
230 
231  if ( a->isValueRequired() )
232  {
233  std::string arg = a->shortID();
234  arg.erase(0, arg.find_last_of(theDelimiter) + 1);
235  if ( arg.at(arg.length()-1) == ']' )
236  arg.erase(arg.length()-1);
237  if ( arg.at(arg.length()-1) == ']' )
238  {
239  arg.erase(arg.length()-1);
240  }
241  if ( arg.at(0) == '<' )
242  {
243  arg.erase(arg.length()-1);
244  arg.erase(0, 1);
245  }
246  size_t p = arg.find('|');
247  if ( p != std::string::npos )
248  {
249  do
250  {
251  arg.replace(p, 1, 1, ' ');
252  }
253  while ( (p = arg.find_first_of('|', p)) != std::string::npos );
254  quoteSpecialChars(arg);
255  std::cout << ": :(" << arg << ')';
256  }
257  else
258  {
259  std::cout << ':' << arg;
260  std::map<std::string, std::string>::iterator compArg = common.find(arg);
261  if ( compArg != common.end() )
262  {
263  std::cout << ':' << compArg->second;
264  }
265  }
266  }
267 
268  std::cout << '\'';
269 }
270 
272 {
273  XorHandler xorHandler = _cmd.getXorHandler();
274  std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
275 
276  if (a->getName() == "help" || a->getName() == "version")
277  {
278  return "(-)";
279  }
280 
281  std::ostringstream list;
282  if ( a->acceptsMultipleValues() )
283  {
284  list << '*';
285  }
286 
287  for ( int i = 0; static_cast<unsigned int>(i) < xorList.size(); i++ )
288  {
289  for ( ArgVectorIterator it = xorList[i].begin();
290  it != xorList[i].end();
291  it++)
292  if ( a == (*it) )
293  {
294  list << '(';
295  for ( ArgVectorIterator iu = xorList[i].begin();
296  iu != xorList[i].end();
297  iu++ )
298  {
299  bool notCur = (*iu) != a;
300  bool hasFlag = !(*iu)->getFlag().empty();
301  if ( iu != xorList[i].begin() && (notCur || hasFlag) )
302  list << ' ';
303  if (hasFlag)
304  list << (*iu)->flagStartChar() << (*iu)->getFlag() << ' ';
305  if ( notCur || hasFlag )
306  list << (*iu)->nameStartString() << (*iu)->getName();
307  }
308  list << ')';
309  return list.str();
310  }
311  }
312 
313  // wasn't found in xor list
314  if (!a->getFlag().empty()) {
315  list << "(" << a->flagStartChar() << a->getFlag() << ' ' <<
316  a->nameStartString() << a->getName() << ')';
317  }
318 
319  return list.str();
320 }
321 
322 } //namespace TCLAP
323 #endif
std::vector< std::vector< Arg * > > & getXorList()
Definition: XorHandler.h:153
A virtual base class that defines the essential data for all arguments.
Definition: Arg.h:64
const char * what() const
Returns the arg id and error text.
Definition: ArgException.h:80
A simple class that defines and argument exception.
Definition: ArgException.h:36
std::string getDescription() const
Returns the argument description.
Definition: Arg.h:554
virtual std::string & getProgramName()=0
Returns the program name string.
static char flagStartChar()
Definition: Arg.h:226
virtual std::list< Arg * > & getArgList()=0
Returns the argList.
virtual char getDelimiter()=0
Returns the delimiter string.
void quoteSpecialChars(std::string &s)
const std::string & getName() const
Returns the argument name.
Definition: Arg.h:569
bool isValueRequired() const
Indicates whether a value must be specified for argument.
Definition: Arg.h:573
virtual std::string & getVersion()=0
Returns the version string.
virtual void version(CmdLineInterface &c)
Prints the version to stdout.
void printOption(Arg *it, std::string mutex)
void basename(std::string &s)
const std::string & getFlag() const
Returns the argument flag.
Definition: Arg.h:567
virtual XorHandler & getXorHandler()=0
Returns the XorHandler.
static const std::string nameStartString()
Definition: Arg.h:245
virtual void usage(CmdLineInterface &c)
Prints the usage to stdout.
virtual std::string shortID(const std::string &valueId="val") const
Returns a short ID for the usage.
Definition: Arg.h:505
std::list< Arg * >::iterator ArgListIterator
Typedef of an Arg list iterator.
Definition: Arg.h:396
The base class that manages the command line definition and passes along the parsing to the appropria...
virtual bool acceptsMultipleValues()
Use by output classes to determine whether an Arg accepts multiple values.
Definition: Arg.h:674
std::vector< Arg * >::iterator ArgVectorIterator
Typedef of an Arg vector iterator.
Definition: Arg.h:401
std::map< std::string, std::string > common
std::string getMutexList(CmdLineInterface &_cmd, Arg *a)
This class handles lists of Arg's that are to be XOR'd on the command line.
Definition: XorHandler.h:38
virtual void failure(CmdLineInterface &c, ArgException &e)
Prints (to stderr) an error message, short usage Can be overridden to produce alternative behavior...
The interface that any output object must implement.
Definition: CmdLineOutput.h:41
virtual bool isRequired() const
Indicates whether the argument is required.
Definition: Arg.h:571
A class that generates a Zsh completion function as output from the usage() method for the given CmdL...