Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkCommandLineParser.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 /*=========================================================================
17 
18  Library: CTK
19 
20  Copyright (c) Kitware Inc.
21 
22  Licensed under the Apache License, Version 2.0 (the "License");
23  you may not use this file except in compliance with the License.
24  You may obtain a copy of the License at
25 
26  http://www.apache.org/licenses/LICENSE-2.0.txt
27 
28  Unless required by applicable law or agreed to in writing, software
29  distributed under the License is distributed on an "AS IS" BASIS,
30  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31  See the License for the specific language governing permissions and
32  limitations under the License.
33 
34 =========================================================================*/
35 
36 // STL includes
37 #include <iostream>
38 #include <stdexcept>
39 
40 // MITK includes
41 #include "mitkCommandLineParser.h"
42 
43 using namespace std;
44 
45 namespace
46 {
47  // --------------------------------------------------------------------------
48  class CommandLineParserArgumentDescription
49  {
50  public:
51  CommandLineParserArgumentDescription(const string &longArg,
52  const string &longArgPrefix,
53  const string &shortArg,
54  const string &shortArgPrefix,
56  const string &argHelp,
57  const string &argLabel,
58  const us::Any &defaultValue,
59  bool ignoreRest,
60  bool deprecated,
61  bool optional,
62  string &argGroup,
63  string &groupDescription)
64  : LongArg(longArg),
65  LongArgPrefix(longArgPrefix),
66  ShortArg(shortArg),
67  ShortArgPrefix(shortArgPrefix),
68  ArgHelp(argHelp),
69  ArgLabel(argLabel),
70  ArgGroup(argGroup),
71  ArgGroupDescription(groupDescription),
72  IgnoreRest(ignoreRest),
73  NumberOfParametersToProcess(0),
74  Deprecated(deprecated),
75  Optional(optional),
76  DefaultValue(defaultValue),
77  Value(type),
78  ValueType(type)
79  {
80  Value = defaultValue;
81 
82  switch (type)
83  {
85  {
86  NumberOfParametersToProcess = 1;
87  }
88  break;
90  {
91  NumberOfParametersToProcess = 0;
92  }
93  break;
95  {
96  NumberOfParametersToProcess = -1;
97  }
98  break;
100  {
101  NumberOfParametersToProcess = 1;
102  }
103  break;
105  {
106  NumberOfParametersToProcess = 1;
107  }
108  break;
109 
112  {
113  NumberOfParametersToProcess = 1;
114  }
115  break;
116 
119  {
120  NumberOfParametersToProcess = 1;
121  }
122  break;
124  {
125  NumberOfParametersToProcess = 1;
126  }
127  break;
128 
129  default:
130  std::cout << "Type not supported: " << static_cast<int>(type);
131  }
132  }
133 
134  ~CommandLineParserArgumentDescription() {}
135  bool addParameter(const string &value);
136 
137  string helpText();
138 
139  string LongArg;
140  string LongArgPrefix;
141  string ShortArg;
142  string ShortArgPrefix;
143  string ArgHelp;
144  string ArgLabel;
145  string ArgGroup;
146  string ArgGroupDescription;
147  bool IgnoreRest;
148  int NumberOfParametersToProcess;
149  bool Deprecated;
150  bool Optional;
151 
152  us::Any DefaultValue;
153  us::Any Value;
155  };
156 
157  // --------------------------------------------------------------------------
158  bool CommandLineParserArgumentDescription::addParameter(const string &value)
159  {
160  switch (ValueType)
161  {
163  {
164  Value = value;
165  }
166  break;
168  {
169  if (value.compare("true") == 0)
170  Value = true;
171  else
172  Value = false;
173  }
174  break;
176  {
177  try
178  {
181  list.push_back(value);
182  Value = list;
183  }
184  catch (...)
185  {
187  list.push_back(value);
188  Value = list;
189  }
190  }
191  break;
193  {
194  stringstream ss(value);
195  int i;
196  ss >> i;
197  Value = i;
198  }
199  break;
201  {
202  stringstream ss(value);
203  float f;
204  ss >> f;
205  Value = f;
206  }
207  break;
208 
211  {
212  Value = value;
213  }
214  break;
215 
219  {
220  Value = value;
221  }
222  break;
223 
224  default:
225  return false;
226  }
227 
228  return true;
229  }
230 
231  // --------------------------------------------------------------------------
232  string CommandLineParserArgumentDescription::helpText()
233  {
234  string text;
235 
236  string shortAndLongArg;
237  if (!this->ShortArg.empty())
238  {
239  shortAndLongArg = " ";
240  shortAndLongArg += this->ShortArgPrefix;
241  shortAndLongArg += this->ShortArg;
242  }
243 
244  if (!this->LongArg.empty())
245  {
246  if (this->ShortArg.empty())
247  shortAndLongArg.append(" ");
248  else
249  shortAndLongArg.append(", ");
250 
251  shortAndLongArg += this->LongArgPrefix;
252  shortAndLongArg += this->LongArg;
253  }
254 
255  text = text + shortAndLongArg + ", " + this->ArgHelp;
256 
257  if (this->Optional)
258  text += " (optional)";
259 
260  if (!this->DefaultValue.Empty())
261  {
262  text = text + ", (default: " + this->DefaultValue.ToString() + ")";
263  }
264  text += "\n";
265  return text;
266  }
267 }
268 
269 // --------------------------------------------------------------------------
270 // ctkCommandLineParser::ctkInternal class
271 
272 // --------------------------------------------------------------------------
273 class mitkCommandLineParser::ctkInternal
274 {
275 public:
276  ctkInternal() : Debug(false), FieldWidth(0), StrictMode(false) {}
277  ~ctkInternal() {}
278  CommandLineParserArgumentDescription *argumentDescription(const string &argument);
279 
280  vector<CommandLineParserArgumentDescription *> ArgumentDescriptionList;
281  map<string, CommandLineParserArgumentDescription *> ArgNameToArgumentDescriptionMap;
282  map<string, vector<CommandLineParserArgumentDescription *>> GroupToArgumentDescriptionListMap;
283 
284  StringContainerType UnparsedArguments;
285  StringContainerType ProcessedArguments;
286  string ErrorString;
287  bool Debug;
288  string::size_type FieldWidth;
289  string LongPrefix;
290  string ShortPrefix;
291  string CurrentGroup;
292  string DisableQSettingsLongArg;
293  string DisableQSettingsShortArg;
294  bool StrictMode;
295 };
296 
297 // --------------------------------------------------------------------------
298 // ctkCommandLineParser::ctkInternal methods
299 
300 // --------------------------------------------------------------------------
301 CommandLineParserArgumentDescription *mitkCommandLineParser::ctkInternal::argumentDescription(const string &argument)
302 {
303  string unprefixedArg = argument;
304 
305  if (!LongPrefix.empty() && argument.compare(0, LongPrefix.size(), LongPrefix) == 0)
306  {
307  // Case when (ShortPrefix + UnPrefixedArgument) matches LongPrefix
308  if (argument == LongPrefix && !ShortPrefix.empty() && argument.compare(0, ShortPrefix.size(), ShortPrefix) == 0)
309  {
310  unprefixedArg = argument.substr(ShortPrefix.size(), argument.size());
311  }
312  else
313  {
314  unprefixedArg = argument.substr(LongPrefix.size(), argument.size());
315  }
316  }
317  else if (!ShortPrefix.empty() && argument.compare(0, ShortPrefix.size(), ShortPrefix) == 0)
318  {
319  unprefixedArg = argument.substr(ShortPrefix.size(), argument.size());
320  }
321  else if (!LongPrefix.empty() && !ShortPrefix.empty())
322  {
323  return nullptr;
324  }
325 
326  if (ArgNameToArgumentDescriptionMap.count(unprefixedArg))
327  {
328  return this->ArgNameToArgumentDescriptionMap[unprefixedArg];
329  }
330  return nullptr;
331 }
332 
333 // --------------------------------------------------------------------------
334 // ctkCommandLineParser methods
335 
336 // --------------------------------------------------------------------------
338 {
339  this->Internal = new ctkInternal();
340  this->Category = string();
341  this->Title = string();
342  this->Contributor = string();
343  this->Description = string();
344  this->ParameterGroupName = "Parameters";
345  this->ParameterGroupDescription = "Parameters";
346 }
347 
348 // --------------------------------------------------------------------------
350 {
351  delete this->Internal;
352 }
353 
354 // --------------------------------------------------------------------------
355 map<string, us::Any> mitkCommandLineParser::parseArguments(const StringContainerType &arguments, bool *ok)
356 {
357  // Reset
358  this->Internal->UnparsedArguments.clear();
359  this->Internal->ProcessedArguments.clear();
360  this->Internal->ErrorString.clear();
361  // foreach (CommandLineParserArgumentDescription* desc, this->Internal->ArgumentDescriptionList)
362  for (unsigned int i = 0; i < Internal->ArgumentDescriptionList.size(); i++)
363  {
364  CommandLineParserArgumentDescription *desc = Internal->ArgumentDescriptionList.at(i);
365  desc->Value = us::Any(desc->ValueType);
366  if (!desc->DefaultValue.Empty())
367  {
368  desc->Value = desc->DefaultValue;
369  }
370  }
371  bool error = false;
372  bool ignoreRest = false;
373  CommandLineParserArgumentDescription *currentArgDesc = nullptr;
374  vector<CommandLineParserArgumentDescription *> parsedArgDescriptions;
375  for (unsigned int i = 1; i < arguments.size(); ++i)
376  {
377  string argument = arguments.at(i);
378 
379  if (this->Internal->Debug)
380  {
381  std::cout << "Processing" << argument;
382  }
383  if (!argument.compare("--xml") || !argument.compare("-xml") || !argument.compare("--XML") ||
384  !argument.compare("-XML"))
385  {
386  this->generateXmlOutput();
387  return map<string, us::Any>();
388  }
389 
390  // should argument be ignored ?
391  if (ignoreRest)
392  {
393  if (this->Internal->Debug)
394  {
395  std::cout << " Skipping: IgnoreRest flag was been set";
396  }
397  this->Internal->UnparsedArguments.push_back(argument);
398  continue;
399  }
400 
401  // Skip if the argument does not start with the defined prefix
402  if (!(argument.compare(0, Internal->LongPrefix.size(), Internal->LongPrefix) == 0 ||
403  argument.compare(0, Internal->ShortPrefix.size(), Internal->ShortPrefix) == 0))
404  {
405  if (this->Internal->StrictMode)
406  {
407  this->Internal->ErrorString = "Unknown argument ";
408  this->Internal->ErrorString += argument;
409  error = true;
410  break;
411  }
412  if (this->Internal->Debug)
413  {
414  std::cout << " Skipping: It does not start with the defined prefix";
415  }
416  this->Internal->UnparsedArguments.push_back(argument);
417  continue;
418  }
419 
420  // Skip if argument has already been parsed ...
421  bool alreadyProcessed = false;
422  for (auto alreadyHandledArgument : Internal->ProcessedArguments)
423  if (argument.compare(alreadyHandledArgument) == 0)
424  {
425  alreadyProcessed = true;
426  break;
427  }
428 
429  if (alreadyProcessed)
430  {
431  if (this->Internal->StrictMode)
432  {
433  this->Internal->ErrorString = "Argument ";
434  this->Internal->ErrorString += argument;
435  this->Internal->ErrorString += " already processed !";
436  error = true;
437  break;
438  }
439  if (this->Internal->Debug)
440  {
441  std::cout << " Skipping: Already processed !";
442  }
443  continue;
444  }
445 
446  // Retrieve corresponding argument description
447  currentArgDesc = this->Internal->argumentDescription(argument);
448 
449  // Is there a corresponding argument description ?
450  if (currentArgDesc)
451  {
452  // If the argument is deprecated, print the help text but continue processing
453  if (currentArgDesc->Deprecated)
454  {
455  std::cout << "Deprecated argument " << argument << ": " << currentArgDesc->ArgHelp;
456  }
457  else
458  {
459  parsedArgDescriptions.push_back(currentArgDesc);
460  }
461 
462  this->Internal->ProcessedArguments.push_back(currentArgDesc->ShortArg);
463  this->Internal->ProcessedArguments.push_back(currentArgDesc->LongArg);
464  int numberOfParametersToProcess = currentArgDesc->NumberOfParametersToProcess;
465  ignoreRest = currentArgDesc->IgnoreRest;
466  if (this->Internal->Debug && ignoreRest)
467  {
468  std::cout << " IgnoreRest flag is True";
469  }
470 
471  // Is the number of parameters associated with the argument being processed known ?
472  if (numberOfParametersToProcess == 0)
473  {
474  currentArgDesc->addParameter("true");
475  }
476  else if (numberOfParametersToProcess > 0)
477  {
478  string missingParameterError = "Argument %1 has %2 value(s) associated whereas exacly %3 are expected.";
479  for (int j = 1; j <= numberOfParametersToProcess; ++j)
480  {
481  if (i + j >= arguments.size())
482  {
483  // this->Internal->ErrorString =
484  // missingParameterError.arg(argument).arg(j-1).arg(numberOfParametersToProcess);
485  // if (this->Internal->Debug) { std::cout << this->Internal->ErrorString; }
486  if (ok)
487  {
488  *ok = false;
489  }
490  return map<string, us::Any>();
491  }
492  string parameter = arguments.at(i + j);
493  if (this->Internal->Debug)
494  {
495  std::cout << " Processing parameter" << j << ", value:" << parameter;
496  }
497  if (this->argumentAdded(parameter))
498  {
499  // this->Internal->ErrorString =
500  // missingParameterError.arg(argument).arg(j-1).arg(numberOfParametersToProcess);
501  // if (this->Internal->Debug) { std::cout << this->Internal->ErrorString; }
502  if (ok)
503  {
504  *ok = false;
505  }
506  return map<string, us::Any>();
507  }
508  if (!currentArgDesc->addParameter(parameter))
509  {
510  // this->Internal->ErrorString = string(
511  // "Value(s) associated with argument %1 are incorrect. %2").
512  // arg(argument).arg(currentArgDesc->ExactMatchFailedMessage);
513  // if (this->Internal->Debug) { std::cout << this->Internal->ErrorString; }
514  if (ok)
515  {
516  *ok = false;
517  }
518  return map<string, us::Any>();
519  }
520  }
521  // Update main loop increment
522  i = i + numberOfParametersToProcess;
523  }
524  else if (numberOfParametersToProcess == -1)
525  {
526  if (this->Internal->Debug)
527  {
528  std::cout << " Proccessing StringList ...";
529  }
530  int j = 1;
531  while (j + i < arguments.size())
532  {
533  if (this->argumentAdded(arguments.at(j + i)))
534  {
535  if (this->Internal->Debug)
536  {
537  std::cout << " No more parameter for" << argument;
538  }
539  break;
540  }
541  string parameter = arguments.at(j + i);
542 
543  if (parameter.compare(0, Internal->LongPrefix.size(), Internal->LongPrefix) == 0 ||
544  parameter.compare(0, Internal->ShortPrefix.size(), Internal->ShortPrefix) == 0)
545  {
546  j--;
547  break;
548  }
549 
550  if (this->Internal->Debug)
551  {
552  std::cout << " Processing parameter" << j << ", value:" << parameter;
553  }
554  if (!currentArgDesc->addParameter(parameter))
555  {
556  // this->Internal->ErrorString = string(
557  // "Value(s) associated with argument %1 are incorrect. %2").
558  // arg(argument).arg(currentArgDesc->ExactMatchFailedMessage);
559  // if (this->Internal->Debug) { std::cout << this->Internal->ErrorString; }
560  if (ok)
561  {
562  *ok = false;
563  }
564  return map<string, us::Any>();
565  }
566  j++;
567  }
568  // Update main loop increment
569  i = i + j;
570  }
571  }
572  else
573  {
574  if (this->Internal->StrictMode)
575  {
576  this->Internal->ErrorString = "Unknown argument ";
577  this->Internal->ErrorString += argument;
578  error = true;
579  break;
580  }
581  if (this->Internal->Debug)
582  {
583  std::cout << " Skipping: Unknown argument";
584  }
585  this->Internal->UnparsedArguments.push_back(argument);
586  }
587  }
588 
589  if (ok)
590  {
591  *ok = !error;
592  }
593 
594  map<string, us::Any> parsedArguments;
595 
596  int obligatoryArgs = 0;
597  vector<CommandLineParserArgumentDescription *>::iterator it;
598  for (it = Internal->ArgumentDescriptionList.begin(); it != Internal->ArgumentDescriptionList.end(); ++it)
599  {
600  CommandLineParserArgumentDescription *desc = *it;
601 
602  if (!desc->Optional)
603  obligatoryArgs++;
604  }
605 
606  int parsedObligatoryArgs = 0;
607  for (it = parsedArgDescriptions.begin(); it != parsedArgDescriptions.end(); ++it)
608  {
609  CommandLineParserArgumentDescription *desc = *it;
610 
611  string key;
612  if (!desc->LongArg.empty())
613  {
614  key = desc->LongArg;
615  }
616  else
617  {
618  key = desc->ShortArg;
619  }
620 
621  if (!desc->Optional)
622  parsedObligatoryArgs++;
623 
624  std::pair<string, us::Any> elem;
625  elem.first = key;
626  elem.second = desc->Value;
627  parsedArguments.insert(elem);
628  }
629 
630  if (obligatoryArgs > parsedObligatoryArgs)
631  {
632  parsedArguments.clear();
633  cout << helpText();
634  }
635 
636  return parsedArguments;
637 }
638 
639 // -------------------------------------------------------------------------
640 map<string, us::Any> mitkCommandLineParser::parseArguments(int argc, char **argv, bool *ok)
641 {
642  StringContainerType arguments;
643 
644  // Create a StringContainerType of arguments
645  for (int i = 0; i < argc; ++i)
646  arguments.push_back(argv[i]);
647 
648  return this->parseArguments(arguments, ok);
649 }
650 
651 // -------------------------------------------------------------------------
653 {
654  return this->Internal->ErrorString;
655 }
656 
657 // -------------------------------------------------------------------------
659 {
660  return this->Internal->UnparsedArguments;
661 }
662 
663 // --------------------------------------------------------------------------
664 void mitkCommandLineParser::addArgument(const string &longarg,
665  const string &shortarg,
666  Type type,
667  const string &argLabel,
668  const string &argHelp,
669  const us::Any &defaultValue,
670  bool optional,
671  bool ignoreRest,
672  bool deprecated)
673 {
674  if (longarg.empty() && shortarg.empty())
675  {
676  return;
677  }
678 
679  /* Make sure it's not already added */
680  bool added = (this->Internal->ArgNameToArgumentDescriptionMap.count(longarg) != 0);
681  if (added)
682  {
683  return;
684  }
685 
686  added = (this->Internal->ArgNameToArgumentDescriptionMap.count(shortarg) != 0);
687  if (added)
688  {
689  return;
690  }
691 
692  auto argDesc = new CommandLineParserArgumentDescription(longarg,
693  this->Internal->LongPrefix,
694  shortarg,
695  this->Internal->ShortPrefix,
696  type,
697  argHelp,
698  argLabel,
699  defaultValue,
700  ignoreRest,
701  deprecated,
702  optional,
703  ParameterGroupName,
704  ParameterGroupDescription);
705 
706  std::string::size_type argWidth = 0;
707  if (!longarg.empty())
708  {
709  this->Internal->ArgNameToArgumentDescriptionMap[longarg] = argDesc;
710  argWidth += longarg.size() + this->Internal->LongPrefix.size();
711  }
712  if (!shortarg.empty())
713  {
714  this->Internal->ArgNameToArgumentDescriptionMap[shortarg] = argDesc;
715  argWidth += shortarg.size() + this->Internal->ShortPrefix.size() + 2;
716  }
717  argWidth += 5;
718 
719  // Set the field width for the arguments
720  if (argWidth > this->Internal->FieldWidth)
721  {
722  this->Internal->FieldWidth = argWidth;
723  }
724 
725  this->Internal->ArgumentDescriptionList.push_back(argDesc);
726  this->Internal->GroupToArgumentDescriptionListMap[this->Internal->CurrentGroup].push_back(argDesc);
727 }
728 
729 // --------------------------------------------------------------------------
731  const string &shortarg,
732  const string &argLabel,
733  const string &argHelp)
734 {
735  addArgument(longarg, shortarg, StringList, argLabel, argHelp, us::Any(), false, true, false);
736 }
737 
738 // --------------------------------------------------------------------------
739 std::string::size_type mitkCommandLineParser::fieldWidth() const
740 {
741  return this->Internal->FieldWidth;
742 }
743 
744 // --------------------------------------------------------------------------
745 void mitkCommandLineParser::beginGroup(const string &description)
746 {
747  this->Internal->CurrentGroup = description;
748 }
749 
750 // --------------------------------------------------------------------------
752 {
753  this->Internal->CurrentGroup.clear();
754 }
755 
756 // --------------------------------------------------------------------------
758 {
759  string text;
760  vector<CommandLineParserArgumentDescription *> deprecatedArgs;
761 
762  text = "Command Line Utility *" + Title + "* in Category *" + Category + "*\n";
763  text += Description + "\n";
764  text += Contributor + "\n\n";
765  text += "Use --xml to generate an XML description parsable as a CTK Command Line Module Plugin.\n";
766 
767  // Loop over grouped argument descriptions
768  map<string, vector<CommandLineParserArgumentDescription *>>::iterator it;
769  for (it = Internal->GroupToArgumentDescriptionListMap.begin();
770  it != Internal->GroupToArgumentDescriptionListMap.end();
771  ++it)
772  {
773  if (!(*it).first.empty())
774  {
775  text = text + "\n" + (*it).first + "\n";
776  }
777 
778  vector<CommandLineParserArgumentDescription *>::iterator it2;
779  for (it2 = (*it).second.begin(); it2 != (*it).second.end(); ++it2)
780  {
781  CommandLineParserArgumentDescription *argDesc = *it2;
782  if (argDesc->Deprecated)
783  {
784  deprecatedArgs.push_back(argDesc);
785  }
786  else
787  {
788  text += argDesc->helpText();
789  }
790  }
791  }
792 
793  if (!deprecatedArgs.empty())
794  {
795  text += "\nDeprecated arguments:\n";
796  vector<CommandLineParserArgumentDescription *>::iterator it2;
797  for (it2 = deprecatedArgs.begin(); it2 != deprecatedArgs.end(); ++it2)
798  {
799  CommandLineParserArgumentDescription *argDesc = *it2;
800  text += argDesc->helpText();
801  }
802  }
803 
804  return text;
805 }
806 
807 // --------------------------------------------------------------------------
808 bool mitkCommandLineParser::argumentAdded(const string &argument) const
809 {
810  return (this->Internal->ArgNameToArgumentDescriptionMap.count(argument) != 0);
811 }
812 
813 // --------------------------------------------------------------------------
814 bool mitkCommandLineParser::argumentParsed(const string &argument) const
815 {
816  for (unsigned int i = 0; i < Internal->ProcessedArguments.size(); i++)
817  if (argument.compare(Internal->ProcessedArguments.at(i)) == 0)
818  return true;
819  return false;
820 }
821 
822 // --------------------------------------------------------------------------
823 void mitkCommandLineParser::setArgumentPrefix(const string &longPrefix, const string &shortPrefix)
824 {
825  this->Internal->LongPrefix = longPrefix;
826  this->Internal->ShortPrefix = shortPrefix;
827 }
828 
829 // --------------------------------------------------------------------------
831 {
832  this->Internal->StrictMode = strictMode;
833 }
834 
836 {
837  std::stringstream xml;
838 
839  xml << "<executable>" << endl;
840  xml << "<category>" << Category << "</category>" << endl;
841  xml << "<title>" << Title << "</title>" << endl;
842  xml << "<description>" << Description << "</description>" << endl;
843  xml << "<contributor>" << Contributor << "</contributor>" << endl;
844  xml << "<parameters>" << endl;
845 
846  std::vector<CommandLineParserArgumentDescription *>::iterator it;
847 
848  std::string lastParameterGroup = "";
849  for (it = this->Internal->ArgumentDescriptionList.begin(); it != this->Internal->ArgumentDescriptionList.end(); it++)
850  {
851  std::string type;
852  switch ((*it)->ValueType)
853  {
855  type = "string";
856  break;
857 
859  type = "boolean";
860  break;
861 
863  type = "string-vector";
864  break;
865 
867  type = "integer";
868  break;
869 
871  type = "float";
872  break;
873 
876  type = "directory";
877  break;
878 
880  type = "image";
881  break;
882 
885  type = "file";
886  break;
887  }
888 
889  if (lastParameterGroup.compare((*it)->ArgGroup))
890  {
891  if (it != this->Internal->ArgumentDescriptionList.begin())
892  {
893  xml << "</parameters>" << endl;
894  xml << "<parameters>" << endl;
895  }
896  xml << "<label>" << (*it)->ArgGroup << "</label>" << endl;
897  xml << "<description>" << (*it)->ArgGroupDescription << "</description>" << endl;
898  lastParameterGroup = (*it)->ArgGroup;
899  }
900 
901  // Skip help item, as it's no use in GUI
902  if ((*it)->ShortArg == "h")
903  continue;
904 
905  xml << "<" << type << ">" << endl;
906  xml << "<name>" << (*it)->LongArg << "</name>" << endl;
907  xml << "<description>" << (*it)->ArgHelp << "</description>" << endl;
908  xml << "<label>" << (*it)->ArgLabel << "</label>" << endl;
909  if (!(*it)->DefaultValue.Empty())
910  xml << "<default>" << (*it)->DefaultValue.ToString() << "</default>" << endl;
911 
912  xml << "<longflag>" << (*it)->LongArg << "</longflag>" << endl;
913  xml << "<flag>" << (*it)->ShortArg << "</flag>" << endl;
914 
915  if ((*it)->ValueType == mitkCommandLineParser::InputDirectory ||
916  (*it)->ValueType == mitkCommandLineParser::InputFile || (*it)->ValueType == mitkCommandLineParser::InputImage)
917  {
918  xml << "<channel>input</channel>" << endl;
919  }
920  else if ((*it)->ValueType == mitkCommandLineParser::OutputDirectory ||
921  (*it)->ValueType == mitkCommandLineParser::OutputFile)
922  {
923  xml << "<channel>output</channel>" << endl;
924  }
925  xml << "</" << type << ">" << endl;
926  }
927 
928  xml << "</parameters>" << endl;
929  xml << "</executable>" << endl;
930 
931  cout << xml.str();
932 }
933 
935 {
936  Title = title;
937 }
939 {
940  Contributor = contributor;
941 }
942 
944 {
945  Category = category;
946 }
947 
949 {
950  Description = description;
951 }
952 
953 void mitkCommandLineParser::changeParameterGroup(string name, string tooltip)
954 {
955  ParameterGroupName = name;
956  ParameterGroupDescription = tooltip;
957 }
void changeParameterGroup(std::string name, std::string tooltip)
bool argumentParsed(const std::string &argument) const
void setStrictModeEnabled(bool strictMode)
void setContributor(std::string contributor)
STL namespace.
ValueType * any_cast(Any *operand)
Definition: usAny.h:377
std::map< std::string, us::Any > parseArguments(const StringContainerType &arguments, bool *ok=nullptr)
std::string errorString() const
void addArgument(const std::string &longarg, const std::string &shortarg, Type type, const std::string &argLabel, const std::string &argHelp=std::string(), const us::Any &defaultValue=us::Any(), bool optional=true, bool ignoreRest=false, bool deprecated=false)
bool argumentAdded(const std::string &argument) const
ValueType
Type of the value held by a Value object.
Definition: jsoncpp.h:345
Definition: usAny.h:163
void setCategory(std::string category)
std::vector< std::string > StringList
void setArgumentPrefix(const std::string &longPrefix, const std::string &shortPrefix)
void addDeprecatedArgument(const std::string &longarg, const std::string &shortarg, const std::string &argLabel, const std::string &argHelp)
const StringContainerType & unparsedArguments() const
std::string::size_type fieldWidth() const
std::string helpText() const
std::vector< std::string > StringContainerType
void setTitle(std::string title)
void setDescription(std::string description)
void beginGroup(const std::string &description)