tclap  1.2.5
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  * Copyright (c) 2017 Google Inc.
9  * All rights reserved.
10  *
11  * See the file COPYING in the top directory of this distribution for
12  * more information.
13  *
14  * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  *
22  *****************************************************************************/
23 
24 #ifndef TCLAP_ZSHCOMPLETIONOUTPUT_H
25 #define TCLAP_ZSHCOMPLETIONOUTPUT_H
26 
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30 
31 #include <string>
32 #include <vector>
33 #include <list>
34 #include <iostream>
35 #include <map>
36 
37 #include <tclap/CmdLineInterface.h>
38 #include <tclap/CmdLineOutput.h>
39 #include <tclap/XorHandler.h>
40 #include <tclap/Arg.h>
41 #include <tclap/sstream.h>
42 
43 namespace TCLAP {
44 
50 {
51 
52  public:
53 
55 
61  virtual void usage(CmdLineInterface& c);
62 
68  virtual void version(CmdLineInterface& c);
69 
76  virtual void failure(CmdLineInterface& c,
77  ArgException& e );
78 
79  protected:
80 
81  void basename( std::string& s );
82  void quoteSpecialChars( std::string& s );
83 
84  std::string getMutexList( CmdLineInterface& _cmd, Arg* a );
85  void printOption( Arg* it, std::string mutex );
86  void printArg( Arg* it );
87 
88  std::map<std::string, std::string> common;
90 };
91 
93 : common(std::map<std::string, std::string>()),
94  theDelimiter('=')
95 {
96  common["host"] = "_hosts";
97  common["hostname"] = "_hosts";
98  common["file"] = "_files";
99  common["filename"] = "_files";
100  common["user"] = "_users";
101  common["username"] = "_users";
102  common["directory"] = "_directories";
103  common["path"] = "_directories";
104  common["url"] = "_urls";
105 }
106 
108 {
109  std::cout << _cmd.getVersion() << std::endl;
110 }
111 
113 {
114  std::list<Arg*> argList = _cmd.getArgList();
115  std::string progName = _cmd.getProgramName();
116  std::string xversion = _cmd.getVersion();
117  theDelimiter = _cmd.getDelimiter();
118  basename(progName);
119 
120  std::cout << "#compdef " << progName << std::endl << std::endl <<
121  "# " << progName << " version " << _cmd.getVersion() << std::endl << std::endl <<
122  "_arguments -s -S";
123 
124  for (ArgListIterator it = argList.begin(); it != argList.end(); it++)
125  {
126  if ( (*it)->shortID().at(0) == '<' )
127  printArg((*it));
128  else if ( (*it)->getFlag() != "-" )
129  printOption((*it), getMutexList(_cmd, *it));
130  }
131 
132  std::cout << std::endl;
133 }
134 
136  ArgException& e )
137 {
138  static_cast<void>(_cmd); // unused
139  std::cout << e.what() << std::endl;
140 }
141 
142 inline void ZshCompletionOutput::quoteSpecialChars( std::string& s )
143 {
144  size_t idx = s.find_last_of(':');
145  while ( idx != std::string::npos )
146  {
147  s.insert(idx, 1, '\\');
148  idx = s.find_last_of(':', idx);
149  }
150  idx = s.find_last_of('\'');
151  while ( idx != std::string::npos )
152  {
153  s.insert(idx, "'\\'");
154  if (idx == 0)
155  idx = std::string::npos;
156  else
157  idx = s.find_last_of('\'', --idx);
158  }
159 }
160 
161 inline void ZshCompletionOutput::basename( std::string& s )
162 {
163  size_t p = s.find_last_of('/');
164  if ( p != std::string::npos )
165  {
166  s.erase(0, p + 1);
167  }
168 }
169 
171 {
172  static int count = 1;
173 
174  std::cout << " \\" << std::endl << " '";
175  if ( a->acceptsMultipleValues() )
176  std::cout << '*';
177  else
178  std::cout << count++;
179  std::cout << ':';
180  if ( !a->isRequired() )
181  std::cout << ':';
182 
183  std::cout << a->getName() << ':';
184  std::map<std::string, std::string>::iterator compArg = common.find(a->getName());
185  if ( compArg != common.end() )
186  {
187  std::cout << compArg->second;
188  }
189  else
190  {
191  std::cout << "_guard \"^-*\" " << a->getName();
192  }
193  std::cout << '\'';
194 }
195 
196 inline void ZshCompletionOutput::printOption(Arg* a, std::string mutex)
197 {
198  std::string flag = a->flagStartChar() + a->getFlag();
199  std::string name = a->nameStartString() + a->getName();
200  std::string desc = a->getDescription();
201 
202  // remove full stop and capitalization from description as
203  // this is the convention for zsh function
204  if (!desc.compare(0, 12, "(required) "))
205  {
206  desc.erase(0, 12);
207  }
208  if (!desc.compare(0, 15, "(OR required) "))
209  {
210  desc.erase(0, 15);
211  }
212  size_t len = desc.length();
213  if (len && desc.at(--len) == '.')
214  {
215  desc.erase(len);
216  }
217  if (len)
218  {
219  desc.replace(0, 1, 1, tolower(desc.at(0)));
220  }
221 
222  std::cout << " \\" << std::endl << " '" << mutex;
223 
224  if ( a->getFlag().empty() )
225  {
226  std::cout << name;
227  }
228  else
229  {
230  std::cout << "'{" << flag << ',' << name << "}'";
231  }
232  if ( theDelimiter == '=' && a->isValueRequired() )
233  std::cout << "=-";
234  quoteSpecialChars(desc);
235  std::cout << '[' << desc << ']';
236 
237  if ( a->isValueRequired() )
238  {
239  std::string arg = a->shortID();
240  // Example arg: "[-A <integer>] ..."
241  size_t pos = arg.rfind(" ...");
242 
243  if (pos != std::string::npos) {
244  arg.erase(pos);
245  }
246 
247  arg.erase(0, arg.find_last_of(theDelimiter) + 1);
248  if ( arg.at(arg.length()-1) == ']' )
249  arg.erase(arg.length()-1);
250  if ( arg.at(arg.length()-1) == ']' )
251  {
252  arg.erase(arg.length()-1);
253  }
254  if ( arg.at(0) == '<' )
255  {
256  arg.erase(arg.length()-1);
257  arg.erase(0, 1);
258  }
259  size_t p = arg.find('|');
260  if ( p != std::string::npos )
261  {
262  do
263  {
264  arg.replace(p, 1, 1, ' ');
265  }
266  while ( (p = arg.find_first_of('|', p)) != std::string::npos );
267  quoteSpecialChars(arg);
268  std::cout << ": :(" << arg << ')';
269  }
270  else
271  {
272  std::cout << ':' << arg;
273  std::map<std::string, std::string>::iterator compArg = common.find(arg);
274  if ( compArg != common.end() )
275  {
276  std::cout << ':' << compArg->second;
277  }
278  }
279  }
280 
281  std::cout << '\'';
282 }
283 
285 {
286  XorHandler xorHandler = _cmd.getXorHandler();
287  std::vector< std::vector<Arg*> > xorList = xorHandler.getXorList();
288 
289  if (a->getName() == "help" || a->getName() == "version")
290  {
291  return "(-)";
292  }
293 
294  ostringstream list;
295  if ( a->acceptsMultipleValues() )
296  {
297  list << '*';
298  }
299 
300  for ( int i = 0; static_cast<unsigned int>(i) < xorList.size(); i++ )
301  {
302  for ( ArgVectorIterator it = xorList[i].begin();
303  it != xorList[i].end();
304  it++)
305  if ( a == (*it) )
306  {
307  list << '(';
308  for ( ArgVectorIterator iu = xorList[i].begin();
309  iu != xorList[i].end();
310  iu++ )
311  {
312  bool notCur = (*iu) != a;
313  bool hasFlag = !(*iu)->getFlag().empty();
314  if ( iu != xorList[i].begin() && (notCur || hasFlag) )
315  list << ' ';
316  if (hasFlag)
317  list << (*iu)->flagStartChar() << (*iu)->getFlag() << ' ';
318  if ( notCur || hasFlag )
319  list << (*iu)->nameStartString() << (*iu)->getName();
320  }
321  list << ')';
322  return list.str();
323  }
324  }
325 
326  // wasn't found in xor list
327  if (!a->getFlag().empty()) {
328  list << "(" << a->flagStartChar() << a->getFlag() << ' ' <<
329  a->nameStartString() << a->getName() << ')';
330  }
331 
332  return list.str();
333 }
334 
335 } //namespace TCLAP
336 #endif
A virtual base class that defines the essential data for all arguments.
Definition: Arg.h:55
const char * what() const
Returns the arg id and error text.
Definition: ArgException.h:81
A simple class that defines and argument exception.
Definition: ArgException.h:37
std::string getDescription() const
Returns the argument description.
Definition: Arg.h:545
virtual std::string & getProgramName()=0
Returns the program name string.
static char flagStartChar()
Definition: Arg.h:217
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:560
bool isValueRequired() const
Indicates whether a value must be specified for argument.
Definition: Arg.h:564
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:558
virtual XorHandler & getXorHandler()=0
Returns the XorHandler.
const std::vector< std::vector< Arg * > > & getXorList() const
Definition: XorHandler.h:155
static const std::string nameStartString()
Definition: Arg.h:236
std::vector< Arg * >::const_iterator ArgVectorIterator
Typedef of an Arg vector iterator.
Definition: Arg.h:392
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:496
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:665
std::ostringstream ostringstream
Definition: sstream.h:38
std::list< Arg * >::const_iterator ArgListIterator
Typedef of an Arg list iterator.
Definition: Arg.h:387
std::map< std::string, std::string > common
Definition: Arg.h:48
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:40
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:44
virtual bool isRequired() const
Indicates whether the argument is required.
Definition: Arg.h:562
A class that generates a Zsh completion function as output from the usage() method for the given CmdL...